aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartyn Welch <martyn.welch@gefanuc.com>2009-08-13 04:03:02 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-09-11 02:02:11 -0400
commitd331d8305cba713605854aab63a000fb892353a7 (patch)
tree5ee6cea2fe656d5772d79245e296c13b36f60456
parent1d6ed32226326a6e6cd67cd9ee4294bcbb0c9a15 (diff)
powerpc/nvram: Enable use Generic NVRAM driver for different size chips
Remove the reliance on a staticly defined NVRAM size, allowing platforms to support NVRAMs with sizes differing from the standard. A fall back value is provided for platforms not supporting this extension. Signed-off-by: Martyn Welch <martyn.welch@gefanuc.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/nvram.h3
-rw-r--r--arch/powerpc/kernel/setup_32.c8
-rw-r--r--drivers/char/generic_nvram.c27
3 files changed, 31 insertions, 7 deletions
diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h
index efde5ac82f7b..6c587eddee59 100644
--- a/arch/powerpc/include/asm/nvram.h
+++ b/arch/powerpc/include/asm/nvram.h
@@ -107,6 +107,9 @@ extern void pmac_xpram_write(int xpaddr, u8 data);
107/* Synchronize NVRAM */ 107/* Synchronize NVRAM */
108extern void nvram_sync(void); 108extern void nvram_sync(void);
109 109
110/* Determine NVRAM size */
111extern ssize_t nvram_get_size(void);
112
110/* Normal access to NVRAM */ 113/* Normal access to NVRAM */
111extern unsigned char nvram_read_byte(int i); 114extern unsigned char nvram_read_byte(int i);
112extern void nvram_write_byte(unsigned char c, int i); 115extern void nvram_write_byte(unsigned char c, int i);
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index e1e3059cf34b..53bcf3d792db 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -210,6 +210,14 @@ void nvram_write_byte(unsigned char val, int addr)
210} 210}
211EXPORT_SYMBOL(nvram_write_byte); 211EXPORT_SYMBOL(nvram_write_byte);
212 212
213ssize_t nvram_get_size(void)
214{
215 if (ppc_md.nvram_size)
216 return ppc_md.nvram_size();
217 return -1;
218}
219EXPORT_SYMBOL(nvram_get_size);
220
213void nvram_sync(void) 221void nvram_sync(void)
214{ 222{
215 if (ppc_md.nvram_sync) 223 if (ppc_md.nvram_sync)
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index a00869c650d5..ef31738c2cbe 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -2,7 +2,7 @@
2 * Generic /dev/nvram driver for architectures providing some 2 * Generic /dev/nvram driver for architectures providing some
3 * "generic" hooks, that is : 3 * "generic" hooks, that is :
4 * 4 *
5 * nvram_read_byte, nvram_write_byte, nvram_sync 5 * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
6 * 6 *
7 * Note that an additional hook is supported for PowerMac only 7 * Note that an additional hook is supported for PowerMac only
8 * for getting the nvram "partition" informations 8 * for getting the nvram "partition" informations
@@ -28,6 +28,8 @@
28 28
29#define NVRAM_SIZE 8192 29#define NVRAM_SIZE 8192
30 30
31static ssize_t nvram_len;
32
31static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) 33static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
32{ 34{
33 lock_kernel(); 35 lock_kernel();
@@ -36,7 +38,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
36 offset += file->f_pos; 38 offset += file->f_pos;
37 break; 39 break;
38 case 2: 40 case 2:
39 offset += NVRAM_SIZE; 41 offset += nvram_len;
40 break; 42 break;
41 } 43 }
42 if (offset < 0) { 44 if (offset < 0) {
@@ -56,9 +58,9 @@ static ssize_t read_nvram(struct file *file, char __user *buf,
56 58
57 if (!access_ok(VERIFY_WRITE, buf, count)) 59 if (!access_ok(VERIFY_WRITE, buf, count))
58 return -EFAULT; 60 return -EFAULT;
59 if (*ppos >= NVRAM_SIZE) 61 if (*ppos >= nvram_len)
60 return 0; 62 return 0;
61 for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) 63 for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
62 if (__put_user(nvram_read_byte(i), p)) 64 if (__put_user(nvram_read_byte(i), p))
63 return -EFAULT; 65 return -EFAULT;
64 *ppos = i; 66 *ppos = i;
@@ -74,9 +76,9 @@ static ssize_t write_nvram(struct file *file, const char __user *buf,
74 76
75 if (!access_ok(VERIFY_READ, buf, count)) 77 if (!access_ok(VERIFY_READ, buf, count))
76 return -EFAULT; 78 return -EFAULT;
77 if (*ppos >= NVRAM_SIZE) 79 if (*ppos >= nvram_len)
78 return 0; 80 return 0;
79 for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) { 81 for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
80 if (__get_user(c, p)) 82 if (__get_user(c, p))
81 return -EFAULT; 83 return -EFAULT;
82 nvram_write_byte(c, i); 84 nvram_write_byte(c, i);
@@ -133,9 +135,20 @@ static struct miscdevice nvram_dev = {
133 135
134int __init nvram_init(void) 136int __init nvram_init(void)
135{ 137{
138 int ret = 0;
139
136 printk(KERN_INFO "Generic non-volatile memory driver v%s\n", 140 printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
137 NVRAM_VERSION); 141 NVRAM_VERSION);
138 return misc_register(&nvram_dev); 142 ret = misc_register(&nvram_dev);
143 if (ret != 0)
144 goto out;
145
146 nvram_len = nvram_get_size();
147 if (nvram_len < 0)
148 nvram_len = NVRAM_SIZE;
149
150out:
151 return ret;
139} 152}
140 153
141void __exit nvram_cleanup(void) 154void __exit nvram_cleanup(void)