0001
0002
0003
0004
0005
0006
0007
0008 #define DEBUG
0009
0010 #include <linux/delay.h>
0011 #include <linux/kernel.h>
0012 #include <linux/init.h>
0013 #include <linux/of.h>
0014
0015 #include <asm/opal.h>
0016 #include <asm/nvram.h>
0017 #include <asm/machdep.h>
0018
0019 static unsigned int nvram_size;
0020
0021 static ssize_t opal_nvram_size(void)
0022 {
0023 return nvram_size;
0024 }
0025
0026 static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index)
0027 {
0028 s64 rc;
0029 int off;
0030
0031 if (*index >= nvram_size)
0032 return 0;
0033 off = *index;
0034 if ((off + count) > nvram_size)
0035 count = nvram_size - off;
0036 rc = opal_read_nvram(__pa(buf), count, off);
0037 if (rc != OPAL_SUCCESS)
0038 return -EIO;
0039 *index += count;
0040 return count;
0041 }
0042
0043
0044
0045
0046
0047 static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
0048 {
0049 s64 rc = OPAL_BUSY;
0050 int off;
0051
0052 if (*index >= nvram_size)
0053 return 0;
0054 off = *index;
0055 if ((off + count) > nvram_size)
0056 count = nvram_size - off;
0057
0058 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
0059 rc = opal_write_nvram(__pa(buf), count, off);
0060 if (rc == OPAL_BUSY_EVENT) {
0061 if (in_interrupt() || irqs_disabled())
0062 mdelay(OPAL_BUSY_DELAY_MS);
0063 else
0064 msleep(OPAL_BUSY_DELAY_MS);
0065 opal_poll_events(NULL);
0066 } else if (rc == OPAL_BUSY) {
0067 if (in_interrupt() || irqs_disabled())
0068 mdelay(OPAL_BUSY_DELAY_MS);
0069 else
0070 msleep(OPAL_BUSY_DELAY_MS);
0071 }
0072 }
0073
0074 if (rc)
0075 return -EIO;
0076
0077 *index += count;
0078 return count;
0079 }
0080
0081 static int __init opal_nvram_init_log_partitions(void)
0082 {
0083
0084 nvram_scan_partitions();
0085 nvram_init_oops_partition(0);
0086 return 0;
0087 }
0088 machine_arch_initcall(powernv, opal_nvram_init_log_partitions);
0089
0090 void __init opal_nvram_init(void)
0091 {
0092 struct device_node *np;
0093 const __be32 *nbytes_p;
0094
0095 np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram");
0096 if (np == NULL)
0097 return;
0098
0099 nbytes_p = of_get_property(np, "#bytes", NULL);
0100 if (!nbytes_p) {
0101 of_node_put(np);
0102 return;
0103 }
0104 nvram_size = be32_to_cpup(nbytes_p);
0105
0106 pr_info("OPAL nvram setup, %u bytes\n", nvram_size);
0107 of_node_put(np);
0108
0109 ppc_md.nvram_read = opal_nvram_read;
0110 ppc_md.nvram_write = opal_nvram_write;
0111 ppc_md.nvram_size = opal_nvram_size;
0112 }
0113