root/arch/powerpc/platforms/powermac/nvram.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. core99_nvram_read_byte
  2. core99_nvram_write_byte
  3. core99_nvram_read
  4. core99_nvram_write
  5. core99_nvram_size
  6. ppc32_nvram_size
  7. direct_nvram_read_byte
  8. direct_nvram_write_byte
  9. indirect_nvram_read_byte
  10. indirect_nvram_write_byte
  11. pmu_nvram_complete
  12. pmu_nvram_read_byte
  13. pmu_nvram_write_byte
  14. chrp_checksum
  15. core99_calc_adler
  16. core99_check
  17. sm_erase_bank
  18. sm_write_bank
  19. amd_erase_bank
  20. amd_write_bank
  21. lookup_partitions
  22. core99_nvram_sync
  23. core99_nvram_setup
  24. pmac_nvram_init
  25. pmac_get_partition
  26. pmac_xpram_read
  27. pmac_xpram_write

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
   4  *
   5  *  Todo: - add support for the OF persistent properties
   6  */
   7 #include <linux/export.h>
   8 #include <linux/kernel.h>
   9 #include <linux/stddef.h>
  10 #include <linux/string.h>
  11 #include <linux/nvram.h>
  12 #include <linux/init.h>
  13 #include <linux/delay.h>
  14 #include <linux/errno.h>
  15 #include <linux/adb.h>
  16 #include <linux/pmu.h>
  17 #include <linux/memblock.h>
  18 #include <linux/completion.h>
  19 #include <linux/spinlock.h>
  20 #include <asm/sections.h>
  21 #include <asm/io.h>
  22 #include <asm/prom.h>
  23 #include <asm/machdep.h>
  24 #include <asm/nvram.h>
  25 
  26 #include "pmac.h"
  27 
  28 #define DEBUG
  29 
  30 #ifdef DEBUG
  31 #define DBG(x...) printk(x)
  32 #else
  33 #define DBG(x...)
  34 #endif
  35 
  36 #define NVRAM_SIZE              0x2000  /* 8kB of non-volatile RAM */
  37 
  38 #define CORE99_SIGNATURE        0x5a
  39 #define CORE99_ADLER_START      0x14
  40 
  41 /* On Core99, nvram is either a sharp, a micron or an AMD flash */
  42 #define SM_FLASH_STATUS_DONE    0x80
  43 #define SM_FLASH_STATUS_ERR     0x38
  44 
  45 #define SM_FLASH_CMD_ERASE_CONFIRM      0xd0
  46 #define SM_FLASH_CMD_ERASE_SETUP        0x20
  47 #define SM_FLASH_CMD_RESET              0xff
  48 #define SM_FLASH_CMD_WRITE_SETUP        0x40
  49 #define SM_FLASH_CMD_CLEAR_STATUS       0x50
  50 #define SM_FLASH_CMD_READ_STATUS        0x70
  51 
  52 /* CHRP NVRAM header */
  53 struct chrp_header {
  54   u8            signature;
  55   u8            cksum;
  56   u16           len;
  57   char          name[12];
  58   u8            data[0];
  59 };
  60 
  61 struct core99_header {
  62   struct chrp_header    hdr;
  63   u32                   adler;
  64   u32                   generation;
  65   u32                   reserved[2];
  66 };
  67 
  68 /*
  69  * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
  70  */
  71 static int nvram_naddrs;
  72 static volatile unsigned char __iomem *nvram_data;
  73 static int is_core_99;
  74 static int core99_bank = 0;
  75 static int nvram_partitions[3];
  76 // XXX Turn that into a sem
  77 static DEFINE_RAW_SPINLOCK(nv_lock);
  78 
  79 static int (*core99_write_bank)(int bank, u8* datas);
  80 static int (*core99_erase_bank)(int bank);
  81 
  82 static char *nvram_image;
  83 
  84 
  85 static unsigned char core99_nvram_read_byte(int addr)
  86 {
  87         if (nvram_image == NULL)
  88                 return 0xff;
  89         return nvram_image[addr];
  90 }
  91 
  92 static void core99_nvram_write_byte(int addr, unsigned char val)
  93 {
  94         if (nvram_image == NULL)
  95                 return;
  96         nvram_image[addr] = val;
  97 }
  98 
  99 static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
 100 {
 101         int i;
 102 
 103         if (nvram_image == NULL)
 104                 return -ENODEV;
 105         if (*index > NVRAM_SIZE)
 106                 return 0;
 107 
 108         i = *index;
 109         if (i + count > NVRAM_SIZE)
 110                 count = NVRAM_SIZE - i;
 111 
 112         memcpy(buf, &nvram_image[i], count);
 113         *index = i + count;
 114         return count;
 115 }
 116 
 117 static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
 118 {
 119         int i;
 120 
 121         if (nvram_image == NULL)
 122                 return -ENODEV;
 123         if (*index > NVRAM_SIZE)
 124                 return 0;
 125 
 126         i = *index;
 127         if (i + count > NVRAM_SIZE)
 128                 count = NVRAM_SIZE - i;
 129 
 130         memcpy(&nvram_image[i], buf, count);
 131         *index = i + count;
 132         return count;
 133 }
 134 
 135 static ssize_t core99_nvram_size(void)
 136 {
 137         if (nvram_image == NULL)
 138                 return -ENODEV;
 139         return NVRAM_SIZE;
 140 }
 141 
 142 #ifdef CONFIG_PPC32
 143 static volatile unsigned char __iomem *nvram_addr;
 144 static int nvram_mult;
 145 
 146 static ssize_t ppc32_nvram_size(void)
 147 {
 148         return NVRAM_SIZE;
 149 }
 150 
 151 static unsigned char direct_nvram_read_byte(int addr)
 152 {
 153         return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
 154 }
 155 
 156 static void direct_nvram_write_byte(int addr, unsigned char val)
 157 {
 158         out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
 159 }
 160 
 161 
 162 static unsigned char indirect_nvram_read_byte(int addr)
 163 {
 164         unsigned char val;
 165         unsigned long flags;
 166 
 167         raw_spin_lock_irqsave(&nv_lock, flags);
 168         out_8(nvram_addr, addr >> 5);
 169         val = in_8(&nvram_data[(addr & 0x1f) << 4]);
 170         raw_spin_unlock_irqrestore(&nv_lock, flags);
 171 
 172         return val;
 173 }
 174 
 175 static void indirect_nvram_write_byte(int addr, unsigned char val)
 176 {
 177         unsigned long flags;
 178 
 179         raw_spin_lock_irqsave(&nv_lock, flags);
 180         out_8(nvram_addr, addr >> 5);
 181         out_8(&nvram_data[(addr & 0x1f) << 4], val);
 182         raw_spin_unlock_irqrestore(&nv_lock, flags);
 183 }
 184 
 185 
 186 #ifdef CONFIG_ADB_PMU
 187 
 188 static void pmu_nvram_complete(struct adb_request *req)
 189 {
 190         if (req->arg)
 191                 complete((struct completion *)req->arg);
 192 }
 193 
 194 static unsigned char pmu_nvram_read_byte(int addr)
 195 {
 196         struct adb_request req;
 197         DECLARE_COMPLETION_ONSTACK(req_complete);
 198         
 199         req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
 200         if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
 201                         (addr >> 8) & 0xff, addr & 0xff))
 202                 return 0xff;
 203         if (system_state == SYSTEM_RUNNING)
 204                 wait_for_completion(&req_complete);
 205         while (!req.complete)
 206                 pmu_poll();
 207         return req.reply[0];
 208 }
 209 
 210 static void pmu_nvram_write_byte(int addr, unsigned char val)
 211 {
 212         struct adb_request req;
 213         DECLARE_COMPLETION_ONSTACK(req_complete);
 214         
 215         req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
 216         if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
 217                         (addr >> 8) & 0xff, addr & 0xff, val))
 218                 return;
 219         if (system_state == SYSTEM_RUNNING)
 220                 wait_for_completion(&req_complete);
 221         while (!req.complete)
 222                 pmu_poll();
 223 }
 224 
 225 #endif /* CONFIG_ADB_PMU */
 226 #endif /* CONFIG_PPC32 */
 227 
 228 static u8 chrp_checksum(struct chrp_header* hdr)
 229 {
 230         u8 *ptr;
 231         u16 sum = hdr->signature;
 232         for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
 233                 sum += *ptr;
 234         while (sum > 0xFF)
 235                 sum = (sum & 0xFF) + (sum>>8);
 236         return sum;
 237 }
 238 
 239 static u32 core99_calc_adler(u8 *buffer)
 240 {
 241         int cnt;
 242         u32 low, high;
 243 
 244         buffer += CORE99_ADLER_START;
 245         low = 1;
 246         high = 0;
 247         for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
 248                 if ((cnt % 5000) == 0) {
 249                         high  %= 65521UL;
 250                         high %= 65521UL;
 251                 }
 252                 low += buffer[cnt];
 253                 high += low;
 254         }
 255         low  %= 65521UL;
 256         high %= 65521UL;
 257 
 258         return (high << 16) | low;
 259 }
 260 
 261 static u32 core99_check(u8* datas)
 262 {
 263         struct core99_header* hdr99 = (struct core99_header*)datas;
 264 
 265         if (hdr99->hdr.signature != CORE99_SIGNATURE) {
 266                 DBG("Invalid signature\n");
 267                 return 0;
 268         }
 269         if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
 270                 DBG("Invalid checksum\n");
 271                 return 0;
 272         }
 273         if (hdr99->adler != core99_calc_adler(datas)) {
 274                 DBG("Invalid adler\n");
 275                 return 0;
 276         }
 277         return hdr99->generation;
 278 }
 279 
 280 static int sm_erase_bank(int bank)
 281 {
 282         int stat;
 283         unsigned long timeout;
 284 
 285         u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 286 
 287         DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
 288 
 289         out_8(base, SM_FLASH_CMD_ERASE_SETUP);
 290         out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
 291         timeout = 0;
 292         do {
 293                 if (++timeout > 1000000) {
 294                         printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
 295                         break;
 296                 }
 297                 out_8(base, SM_FLASH_CMD_READ_STATUS);
 298                 stat = in_8(base);
 299         } while (!(stat & SM_FLASH_STATUS_DONE));
 300 
 301         out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
 302         out_8(base, SM_FLASH_CMD_RESET);
 303 
 304         if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
 305                 printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
 306                 return -ENXIO;
 307         }
 308         return 0;
 309 }
 310 
 311 static int sm_write_bank(int bank, u8* datas)
 312 {
 313         int i, stat = 0;
 314         unsigned long timeout;
 315 
 316         u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 317 
 318         DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
 319 
 320         for (i=0; i<NVRAM_SIZE; i++) {
 321                 out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
 322                 udelay(1);
 323                 out_8(base+i, datas[i]);
 324                 timeout = 0;
 325                 do {
 326                         if (++timeout > 1000000) {
 327                                 printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
 328                                 break;
 329                         }
 330                         out_8(base, SM_FLASH_CMD_READ_STATUS);
 331                         stat = in_8(base);
 332                 } while (!(stat & SM_FLASH_STATUS_DONE));
 333                 if (!(stat & SM_FLASH_STATUS_DONE))
 334                         break;
 335         }
 336         out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
 337         out_8(base, SM_FLASH_CMD_RESET);
 338         if (memcmp(base, datas, NVRAM_SIZE)) {
 339                 printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
 340                 return -ENXIO;
 341         }
 342         return 0;
 343 }
 344 
 345 static int amd_erase_bank(int bank)
 346 {
 347         int stat = 0;
 348         unsigned long timeout;
 349 
 350         u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 351 
 352         DBG("nvram: AMD Erasing bank %d...\n", bank);
 353 
 354         /* Unlock 1 */
 355         out_8(base+0x555, 0xaa);
 356         udelay(1);
 357         /* Unlock 2 */
 358         out_8(base+0x2aa, 0x55);
 359         udelay(1);
 360 
 361         /* Sector-Erase */
 362         out_8(base+0x555, 0x80);
 363         udelay(1);
 364         out_8(base+0x555, 0xaa);
 365         udelay(1);
 366         out_8(base+0x2aa, 0x55);
 367         udelay(1);
 368         out_8(base, 0x30);
 369         udelay(1);
 370 
 371         timeout = 0;
 372         do {
 373                 if (++timeout > 1000000) {
 374                         printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
 375                         break;
 376                 }
 377                 stat = in_8(base) ^ in_8(base);
 378         } while (stat != 0);
 379         
 380         /* Reset */
 381         out_8(base, 0xf0);
 382         udelay(1);
 383 
 384         if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
 385                 printk(KERN_ERR "nvram: AMD flash erase failed !\n");
 386                 return -ENXIO;
 387         }
 388         return 0;
 389 }
 390 
 391 static int amd_write_bank(int bank, u8* datas)
 392 {
 393         int i, stat = 0;
 394         unsigned long timeout;
 395 
 396         u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 397 
 398         DBG("nvram: AMD Writing bank %d...\n", bank);
 399 
 400         for (i=0; i<NVRAM_SIZE; i++) {
 401                 /* Unlock 1 */
 402                 out_8(base+0x555, 0xaa);
 403                 udelay(1);
 404                 /* Unlock 2 */
 405                 out_8(base+0x2aa, 0x55);
 406                 udelay(1);
 407 
 408                 /* Write single word */
 409                 out_8(base+0x555, 0xa0);
 410                 udelay(1);
 411                 out_8(base+i, datas[i]);
 412                 
 413                 timeout = 0;
 414                 do {
 415                         if (++timeout > 1000000) {
 416                                 printk(KERN_ERR "nvram: AMD flash write timeout !\n");
 417                                 break;
 418                         }
 419                         stat = in_8(base) ^ in_8(base);
 420                 } while (stat != 0);
 421                 if (stat != 0)
 422                         break;
 423         }
 424 
 425         /* Reset */
 426         out_8(base, 0xf0);
 427         udelay(1);
 428 
 429         if (memcmp(base, datas, NVRAM_SIZE)) {
 430                 printk(KERN_ERR "nvram: AMD flash write failed !\n");
 431                 return -ENXIO;
 432         }
 433         return 0;
 434 }
 435 
 436 static void __init lookup_partitions(void)
 437 {
 438         u8 buffer[17];
 439         int i, offset;
 440         struct chrp_header* hdr;
 441 
 442         if (pmac_newworld) {
 443                 nvram_partitions[pmac_nvram_OF] = -1;
 444                 nvram_partitions[pmac_nvram_XPRAM] = -1;
 445                 nvram_partitions[pmac_nvram_NR] = -1;
 446                 hdr = (struct chrp_header *)buffer;
 447 
 448                 offset = 0;
 449                 buffer[16] = 0;
 450                 do {
 451                         for (i=0;i<16;i++)
 452                                 buffer[i] = ppc_md.nvram_read_val(offset+i);
 453                         if (!strcmp(hdr->name, "common"))
 454                                 nvram_partitions[pmac_nvram_OF] = offset + 0x10;
 455                         if (!strcmp(hdr->name, "APL,MacOS75")) {
 456                                 nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
 457                                 nvram_partitions[pmac_nvram_NR] = offset + 0x110;
 458                         }
 459                         offset += (hdr->len * 0x10);
 460                 } while(offset < NVRAM_SIZE);
 461         } else {
 462                 nvram_partitions[pmac_nvram_OF] = 0x1800;
 463                 nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
 464                 nvram_partitions[pmac_nvram_NR] = 0x1400;
 465         }
 466         DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
 467         DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
 468         DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
 469 }
 470 
 471 static void core99_nvram_sync(void)
 472 {
 473         struct core99_header* hdr99;
 474         unsigned long flags;
 475 
 476         if (!is_core_99 || !nvram_data || !nvram_image)
 477                 return;
 478 
 479         raw_spin_lock_irqsave(&nv_lock, flags);
 480         if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
 481                 NVRAM_SIZE))
 482                 goto bail;
 483 
 484         DBG("Updating nvram...\n");
 485 
 486         hdr99 = (struct core99_header*)nvram_image;
 487         hdr99->generation++;
 488         hdr99->hdr.signature = CORE99_SIGNATURE;
 489         hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
 490         hdr99->adler = core99_calc_adler(nvram_image);
 491         core99_bank = core99_bank ? 0 : 1;
 492         if (core99_erase_bank)
 493                 if (core99_erase_bank(core99_bank)) {
 494                         printk("nvram: Error erasing bank %d\n", core99_bank);
 495                         goto bail;
 496                 }
 497         if (core99_write_bank)
 498                 if (core99_write_bank(core99_bank, nvram_image))
 499                         printk("nvram: Error writing bank %d\n", core99_bank);
 500  bail:
 501         raw_spin_unlock_irqrestore(&nv_lock, flags);
 502 
 503 #ifdef DEBUG
 504         mdelay(2000);
 505 #endif
 506 }
 507 
 508 static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
 509 {
 510         int i;
 511         u32 gen_bank0, gen_bank1;
 512 
 513         if (nvram_naddrs < 1) {
 514                 printk(KERN_ERR "nvram: no address\n");
 515                 return -EINVAL;
 516         }
 517         nvram_image = memblock_alloc(NVRAM_SIZE, SMP_CACHE_BYTES);
 518         if (!nvram_image)
 519                 panic("%s: Failed to allocate %u bytes\n", __func__,
 520                       NVRAM_SIZE);
 521         nvram_data = ioremap(addr, NVRAM_SIZE*2);
 522         nvram_naddrs = 1; /* Make sure we get the correct case */
 523 
 524         DBG("nvram: Checking bank 0...\n");
 525 
 526         gen_bank0 = core99_check((u8 *)nvram_data);
 527         gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
 528         core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
 529 
 530         DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
 531         DBG("nvram: Active bank is: %d\n", core99_bank);
 532 
 533         for (i=0; i<NVRAM_SIZE; i++)
 534                 nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
 535 
 536         ppc_md.nvram_read_val   = core99_nvram_read_byte;
 537         ppc_md.nvram_write_val  = core99_nvram_write_byte;
 538         ppc_md.nvram_read       = core99_nvram_read;
 539         ppc_md.nvram_write      = core99_nvram_write;
 540         ppc_md.nvram_size       = core99_nvram_size;
 541         ppc_md.nvram_sync       = core99_nvram_sync;
 542         ppc_md.machine_shutdown = core99_nvram_sync;
 543         /* 
 544          * Maybe we could be smarter here though making an exclusive list
 545          * of known flash chips is a bit nasty as older OF didn't provide us
 546          * with a useful "compatible" entry. A solution would be to really
 547          * identify the chip using flash id commands and base ourselves on
 548          * a list of known chips IDs
 549          */
 550         if (of_device_is_compatible(dp, "amd-0137")) {
 551                 core99_erase_bank = amd_erase_bank;
 552                 core99_write_bank = amd_write_bank;
 553         } else {
 554                 core99_erase_bank = sm_erase_bank;
 555                 core99_write_bank = sm_write_bank;
 556         }
 557         return 0;
 558 }
 559 
 560 int __init pmac_nvram_init(void)
 561 {
 562         struct device_node *dp;
 563         struct resource r1, r2;
 564         unsigned int s1 = 0, s2 = 0;
 565         int err = 0;
 566 
 567         nvram_naddrs = 0;
 568 
 569         dp = of_find_node_by_name(NULL, "nvram");
 570         if (dp == NULL) {
 571                 printk(KERN_ERR "Can't find NVRAM device\n");
 572                 return -ENODEV;
 573         }
 574 
 575         /* Try to obtain an address */
 576         if (of_address_to_resource(dp, 0, &r1) == 0) {
 577                 nvram_naddrs = 1;
 578                 s1 = resource_size(&r1);
 579                 if (of_address_to_resource(dp, 1, &r2) == 0) {
 580                         nvram_naddrs = 2;
 581                         s2 = resource_size(&r2);
 582                 }
 583         }
 584 
 585         is_core_99 = of_device_is_compatible(dp, "nvram,flash");
 586         if (is_core_99) {
 587                 err = core99_nvram_setup(dp, r1.start);
 588                 goto bail;
 589         }
 590 
 591 #ifdef CONFIG_PPC32
 592         if (machine_is(chrp) && nvram_naddrs == 1) {
 593                 nvram_data = ioremap(r1.start, s1);
 594                 nvram_mult = 1;
 595                 ppc_md.nvram_read_val   = direct_nvram_read_byte;
 596                 ppc_md.nvram_write_val  = direct_nvram_write_byte;
 597                 ppc_md.nvram_size       = ppc32_nvram_size;
 598         } else if (nvram_naddrs == 1) {
 599                 nvram_data = ioremap(r1.start, s1);
 600                 nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
 601                 ppc_md.nvram_read_val   = direct_nvram_read_byte;
 602                 ppc_md.nvram_write_val  = direct_nvram_write_byte;
 603                 ppc_md.nvram_size       = ppc32_nvram_size;
 604         } else if (nvram_naddrs == 2) {
 605                 nvram_addr = ioremap(r1.start, s1);
 606                 nvram_data = ioremap(r2.start, s2);
 607                 ppc_md.nvram_read_val   = indirect_nvram_read_byte;
 608                 ppc_md.nvram_write_val  = indirect_nvram_write_byte;
 609                 ppc_md.nvram_size       = ppc32_nvram_size;
 610         } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 611 #ifdef CONFIG_ADB_PMU
 612                 nvram_naddrs = -1;
 613                 ppc_md.nvram_read_val   = pmu_nvram_read_byte;
 614                 ppc_md.nvram_write_val  = pmu_nvram_write_byte;
 615                 ppc_md.nvram_size       = ppc32_nvram_size;
 616 #endif /* CONFIG_ADB_PMU */
 617         } else {
 618                 printk(KERN_ERR "Incompatible type of NVRAM\n");
 619                 err = -ENXIO;
 620         }
 621 #endif /* CONFIG_PPC32 */
 622 bail:
 623         of_node_put(dp);
 624         if (err == 0)
 625                 lookup_partitions();
 626         return err;
 627 }
 628 
 629 int pmac_get_partition(int partition)
 630 {
 631         return nvram_partitions[partition];
 632 }
 633 
 634 u8 pmac_xpram_read(int xpaddr)
 635 {
 636         int offset = pmac_get_partition(pmac_nvram_XPRAM);
 637 
 638         if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
 639                 return 0xff;
 640 
 641         return ppc_md.nvram_read_val(xpaddr + offset);
 642 }
 643 
 644 void pmac_xpram_write(int xpaddr, u8 data)
 645 {
 646         int offset = pmac_get_partition(pmac_nvram_XPRAM);
 647 
 648         if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
 649                 return;
 650 
 651         ppc_md.nvram_write_val(xpaddr + offset, data);
 652 }
 653 
 654 EXPORT_SYMBOL(pmac_get_partition);
 655 EXPORT_SYMBOL(pmac_xpram_read);
 656 EXPORT_SYMBOL(pmac_xpram_write);

/* [<][>][^][v][top][bottom][index][help] */