root/arch/powerpc/sysdev/mmio_nvram.c

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

DEFINITIONS

This source file includes following definitions.
  1. mmio_nvram_read
  2. mmio_nvram_read_val
  3. mmio_nvram_write
  4. mmio_nvram_write_val
  5. mmio_nvram_get_size
  6. mmio_nvram_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * memory mapped NVRAM
   4  *
   5  * (C) Copyright IBM Corp. 2005
   6  *
   7  * Authors : Utz Bacher <utz.bacher@de.ibm.com>
   8  */
   9 
  10 #include <linux/fs.h>
  11 #include <linux/init.h>
  12 #include <linux/kernel.h>
  13 #include <linux/spinlock.h>
  14 #include <linux/types.h>
  15 
  16 #include <asm/machdep.h>
  17 #include <asm/nvram.h>
  18 #include <asm/prom.h>
  19 
  20 static void __iomem *mmio_nvram_start;
  21 static long mmio_nvram_len;
  22 static DEFINE_SPINLOCK(mmio_nvram_lock);
  23 
  24 static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index)
  25 {
  26         unsigned long flags;
  27 
  28         if (*index >= mmio_nvram_len)
  29                 return 0;
  30         if (*index + count > mmio_nvram_len)
  31                 count = mmio_nvram_len - *index;
  32 
  33         spin_lock_irqsave(&mmio_nvram_lock, flags);
  34 
  35         memcpy_fromio(buf, mmio_nvram_start + *index, count);
  36 
  37         spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  38         
  39         *index += count;
  40         return count;
  41 }
  42 
  43 static unsigned char mmio_nvram_read_val(int addr)
  44 {
  45         unsigned long flags;
  46         unsigned char val;
  47 
  48         if (addr >= mmio_nvram_len)
  49                 return 0xff;
  50 
  51         spin_lock_irqsave(&mmio_nvram_lock, flags);
  52 
  53         val = ioread8(mmio_nvram_start + addr);
  54 
  55         spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  56 
  57         return val;
  58 }
  59 
  60 static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index)
  61 {
  62         unsigned long flags;
  63 
  64         if (*index >= mmio_nvram_len)
  65                 return 0;
  66         if (*index + count > mmio_nvram_len)
  67                 count = mmio_nvram_len - *index;
  68 
  69         spin_lock_irqsave(&mmio_nvram_lock, flags);
  70 
  71         memcpy_toio(mmio_nvram_start + *index, buf, count);
  72 
  73         spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  74         
  75         *index += count;
  76         return count;
  77 }
  78 
  79 static void mmio_nvram_write_val(int addr, unsigned char val)
  80 {
  81         unsigned long flags;
  82 
  83         if (addr < mmio_nvram_len) {
  84                 spin_lock_irqsave(&mmio_nvram_lock, flags);
  85 
  86                 iowrite8(val, mmio_nvram_start + addr);
  87 
  88                 spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  89         }
  90 }
  91 
  92 static ssize_t mmio_nvram_get_size(void)
  93 {
  94         return mmio_nvram_len;
  95 }
  96 
  97 int __init mmio_nvram_init(void)
  98 {
  99         struct device_node *nvram_node;
 100         unsigned long nvram_addr;
 101         struct resource r;
 102         int ret;
 103 
 104         nvram_node = of_find_node_by_type(NULL, "nvram");
 105         if (!nvram_node)
 106                 nvram_node = of_find_compatible_node(NULL, NULL, "nvram");
 107         if (!nvram_node) {
 108                 printk(KERN_WARNING "nvram: no node found in device-tree\n");
 109                 return -ENODEV;
 110         }
 111 
 112         ret = of_address_to_resource(nvram_node, 0, &r);
 113         if (ret) {
 114                 printk(KERN_WARNING "nvram: failed to get address (err %d)\n",
 115                        ret);
 116                 goto out;
 117         }
 118         nvram_addr = r.start;
 119         mmio_nvram_len = resource_size(&r);
 120         if ( (!mmio_nvram_len) || (!nvram_addr) ) {
 121                 printk(KERN_WARNING "nvram: address or length is 0\n");
 122                 ret = -EIO;
 123                 goto out;
 124         }
 125 
 126         mmio_nvram_start = ioremap(nvram_addr, mmio_nvram_len);
 127         if (!mmio_nvram_start) {
 128                 printk(KERN_WARNING "nvram: failed to ioremap\n");
 129                 ret = -ENOMEM;
 130                 goto out;
 131         }
 132 
 133         printk(KERN_INFO "mmio NVRAM, %luk at 0x%lx mapped to %p\n",
 134                mmio_nvram_len >> 10, nvram_addr, mmio_nvram_start);
 135 
 136         ppc_md.nvram_read_val   = mmio_nvram_read_val;
 137         ppc_md.nvram_write_val  = mmio_nvram_write_val;
 138         ppc_md.nvram_read       = mmio_nvram_read;
 139         ppc_md.nvram_write      = mmio_nvram_write;
 140         ppc_md.nvram_size       = mmio_nvram_get_size;
 141 
 142 out:
 143         of_node_put(nvram_node);
 144         return ret;
 145 }

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