0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/fs.h>
0011 #include <linux/init.h>
0012 #include <linux/kernel.h>
0013 #include <linux/of_address.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/types.h>
0016
0017 #include <asm/machdep.h>
0018 #include <asm/nvram.h>
0019
0020 static void __iomem *mmio_nvram_start;
0021 static long mmio_nvram_len;
0022 static DEFINE_SPINLOCK(mmio_nvram_lock);
0023
0024 static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index)
0025 {
0026 unsigned long flags;
0027
0028 if (*index >= mmio_nvram_len)
0029 return 0;
0030 if (*index + count > mmio_nvram_len)
0031 count = mmio_nvram_len - *index;
0032
0033 spin_lock_irqsave(&mmio_nvram_lock, flags);
0034
0035 memcpy_fromio(buf, mmio_nvram_start + *index, count);
0036
0037 spin_unlock_irqrestore(&mmio_nvram_lock, flags);
0038
0039 *index += count;
0040 return count;
0041 }
0042
0043 static unsigned char mmio_nvram_read_val(int addr)
0044 {
0045 unsigned long flags;
0046 unsigned char val;
0047
0048 if (addr >= mmio_nvram_len)
0049 return 0xff;
0050
0051 spin_lock_irqsave(&mmio_nvram_lock, flags);
0052
0053 val = ioread8(mmio_nvram_start + addr);
0054
0055 spin_unlock_irqrestore(&mmio_nvram_lock, flags);
0056
0057 return val;
0058 }
0059
0060 static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index)
0061 {
0062 unsigned long flags;
0063
0064 if (*index >= mmio_nvram_len)
0065 return 0;
0066 if (*index + count > mmio_nvram_len)
0067 count = mmio_nvram_len - *index;
0068
0069 spin_lock_irqsave(&mmio_nvram_lock, flags);
0070
0071 memcpy_toio(mmio_nvram_start + *index, buf, count);
0072
0073 spin_unlock_irqrestore(&mmio_nvram_lock, flags);
0074
0075 *index += count;
0076 return count;
0077 }
0078
0079 static void mmio_nvram_write_val(int addr, unsigned char val)
0080 {
0081 unsigned long flags;
0082
0083 if (addr < mmio_nvram_len) {
0084 spin_lock_irqsave(&mmio_nvram_lock, flags);
0085
0086 iowrite8(val, mmio_nvram_start + addr);
0087
0088 spin_unlock_irqrestore(&mmio_nvram_lock, flags);
0089 }
0090 }
0091
0092 static ssize_t mmio_nvram_get_size(void)
0093 {
0094 return mmio_nvram_len;
0095 }
0096
0097 int __init mmio_nvram_init(void)
0098 {
0099 struct device_node *nvram_node;
0100 unsigned long nvram_addr;
0101 struct resource r;
0102 int ret;
0103
0104 nvram_node = of_find_node_by_type(NULL, "nvram");
0105 if (!nvram_node)
0106 nvram_node = of_find_compatible_node(NULL, NULL, "nvram");
0107 if (!nvram_node) {
0108 printk(KERN_WARNING "nvram: no node found in device-tree\n");
0109 return -ENODEV;
0110 }
0111
0112 ret = of_address_to_resource(nvram_node, 0, &r);
0113 if (ret) {
0114 printk(KERN_WARNING "nvram: failed to get address (err %d)\n",
0115 ret);
0116 goto out;
0117 }
0118 nvram_addr = r.start;
0119 mmio_nvram_len = resource_size(&r);
0120 if ( (!mmio_nvram_len) || (!nvram_addr) ) {
0121 printk(KERN_WARNING "nvram: address or length is 0\n");
0122 ret = -EIO;
0123 goto out;
0124 }
0125
0126 mmio_nvram_start = ioremap(nvram_addr, mmio_nvram_len);
0127 if (!mmio_nvram_start) {
0128 printk(KERN_WARNING "nvram: failed to ioremap\n");
0129 ret = -ENOMEM;
0130 goto out;
0131 }
0132
0133 printk(KERN_INFO "mmio NVRAM, %luk at 0x%lx mapped to %p\n",
0134 mmio_nvram_len >> 10, nvram_addr, mmio_nvram_start);
0135
0136 ppc_md.nvram_read_val = mmio_nvram_read_val;
0137 ppc_md.nvram_write_val = mmio_nvram_write_val;
0138 ppc_md.nvram_read = mmio_nvram_read;
0139 ppc_md.nvram_write = mmio_nvram_write;
0140 ppc_md.nvram_size = mmio_nvram_get_size;
0141
0142 out:
0143 of_node_put(nvram_node);
0144 return ret;
0145 }