root/drivers/sh/intc/access.c

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

DEFINITIONS

This source file includes following definitions.
  1. intc_phys_to_virt
  2. intc_get_reg
  3. intc_set_field_from_handle
  4. intc_get_field_from_handle
  5. test_8
  6. test_16
  7. test_32
  8. write_8
  9. write_16
  10. write_32
  11. modify_8
  12. modify_16
  13. modify_32
  14. intc_mode_field
  15. intc_mode_zero
  16. intc_mode_prio

   1 /*
   2  * Common INTC2 register accessors
   3  *
   4  * Copyright (C) 2007, 2008 Magnus Damm
   5  * Copyright (C) 2009, 2010 Paul Mundt
   6  *
   7  * This file is subject to the terms and conditions of the GNU General Public
   8  * License.  See the file "COPYING" in the main directory of this archive
   9  * for more details.
  10  */
  11 #include <linux/io.h>
  12 #include "internals.h"
  13 
  14 unsigned long intc_phys_to_virt(struct intc_desc_int *d, unsigned long address)
  15 {
  16         struct intc_window *window;
  17         int k;
  18 
  19         /* scan through physical windows and convert address */
  20         for (k = 0; k < d->nr_windows; k++) {
  21                 window = d->window + k;
  22 
  23                 if (address < window->phys)
  24                         continue;
  25 
  26                 if (address >= (window->phys + window->size))
  27                         continue;
  28 
  29                 address -= window->phys;
  30                 address += (unsigned long)window->virt;
  31 
  32                 return address;
  33         }
  34 
  35         /* no windows defined, register must be 1:1 mapped virt:phys */
  36         return address;
  37 }
  38 
  39 unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address)
  40 {
  41         unsigned int k;
  42 
  43         address = intc_phys_to_virt(d, address);
  44 
  45         for (k = 0; k < d->nr_reg; k++) {
  46                 if (d->reg[k] == address)
  47                         return k;
  48         }
  49 
  50         BUG();
  51         return 0;
  52 }
  53 
  54 unsigned int intc_set_field_from_handle(unsigned int value,
  55                                         unsigned int field_value,
  56                                         unsigned int handle)
  57 {
  58         unsigned int width = _INTC_WIDTH(handle);
  59         unsigned int shift = _INTC_SHIFT(handle);
  60 
  61         value &= ~(((1 << width) - 1) << shift);
  62         value |= field_value << shift;
  63         return value;
  64 }
  65 
  66 unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle)
  67 {
  68         unsigned int width = _INTC_WIDTH(handle);
  69         unsigned int shift = _INTC_SHIFT(handle);
  70         unsigned int mask = ((1 << width) - 1) << shift;
  71 
  72         return (value & mask) >> shift;
  73 }
  74 
  75 static unsigned long test_8(unsigned long addr, unsigned long h,
  76                             unsigned long ignore)
  77 {
  78         void __iomem *ptr = (void __iomem *)addr;
  79         return intc_get_field_from_handle(__raw_readb(ptr), h);
  80 }
  81 
  82 static unsigned long test_16(unsigned long addr, unsigned long h,
  83                              unsigned long ignore)
  84 {
  85         void __iomem *ptr = (void __iomem *)addr;
  86         return intc_get_field_from_handle(__raw_readw(ptr), h);
  87 }
  88 
  89 static unsigned long test_32(unsigned long addr, unsigned long h,
  90                              unsigned long ignore)
  91 {
  92         void __iomem *ptr = (void __iomem *)addr;
  93         return intc_get_field_from_handle(__raw_readl(ptr), h);
  94 }
  95 
  96 static unsigned long write_8(unsigned long addr, unsigned long h,
  97                              unsigned long data)
  98 {
  99         void __iomem *ptr = (void __iomem *)addr;
 100         __raw_writeb(intc_set_field_from_handle(0, data, h), ptr);
 101         (void)__raw_readb(ptr); /* Defeat write posting */
 102         return 0;
 103 }
 104 
 105 static unsigned long write_16(unsigned long addr, unsigned long h,
 106                               unsigned long data)
 107 {
 108         void __iomem *ptr = (void __iomem *)addr;
 109         __raw_writew(intc_set_field_from_handle(0, data, h), ptr);
 110         (void)__raw_readw(ptr); /* Defeat write posting */
 111         return 0;
 112 }
 113 
 114 static unsigned long write_32(unsigned long addr, unsigned long h,
 115                               unsigned long data)
 116 {
 117         void __iomem *ptr = (void __iomem *)addr;
 118         __raw_writel(intc_set_field_from_handle(0, data, h), ptr);
 119         (void)__raw_readl(ptr); /* Defeat write posting */
 120         return 0;
 121 }
 122 
 123 static unsigned long modify_8(unsigned long addr, unsigned long h,
 124                               unsigned long data)
 125 {
 126         void __iomem *ptr = (void __iomem *)addr;
 127         unsigned long flags;
 128         unsigned int value;
 129         local_irq_save(flags);
 130         value = intc_set_field_from_handle(__raw_readb(ptr), data, h);
 131         __raw_writeb(value, ptr);
 132         (void)__raw_readb(ptr); /* Defeat write posting */
 133         local_irq_restore(flags);
 134         return 0;
 135 }
 136 
 137 static unsigned long modify_16(unsigned long addr, unsigned long h,
 138                                unsigned long data)
 139 {
 140         void __iomem *ptr = (void __iomem *)addr;
 141         unsigned long flags;
 142         unsigned int value;
 143         local_irq_save(flags);
 144         value = intc_set_field_from_handle(__raw_readw(ptr), data, h);
 145         __raw_writew(value, ptr);
 146         (void)__raw_readw(ptr); /* Defeat write posting */
 147         local_irq_restore(flags);
 148         return 0;
 149 }
 150 
 151 static unsigned long modify_32(unsigned long addr, unsigned long h,
 152                                unsigned long data)
 153 {
 154         void __iomem *ptr = (void __iomem *)addr;
 155         unsigned long flags;
 156         unsigned int value;
 157         local_irq_save(flags);
 158         value = intc_set_field_from_handle(__raw_readl(ptr), data, h);
 159         __raw_writel(value, ptr);
 160         (void)__raw_readl(ptr); /* Defeat write posting */
 161         local_irq_restore(flags);
 162         return 0;
 163 }
 164 
 165 static unsigned long intc_mode_field(unsigned long addr,
 166                                      unsigned long handle,
 167                                      unsigned long (*fn)(unsigned long,
 168                                                 unsigned long,
 169                                                 unsigned long),
 170                                      unsigned int irq)
 171 {
 172         return fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1));
 173 }
 174 
 175 static unsigned long intc_mode_zero(unsigned long addr,
 176                                     unsigned long handle,
 177                                     unsigned long (*fn)(unsigned long,
 178                                                unsigned long,
 179                                                unsigned long),
 180                                     unsigned int irq)
 181 {
 182         return fn(addr, handle, 0);
 183 }
 184 
 185 static unsigned long intc_mode_prio(unsigned long addr,
 186                                     unsigned long handle,
 187                                     unsigned long (*fn)(unsigned long,
 188                                                unsigned long,
 189                                                unsigned long),
 190                                     unsigned int irq)
 191 {
 192         return fn(addr, handle, intc_get_prio_level(irq));
 193 }
 194 
 195 unsigned long (*intc_reg_fns[])(unsigned long addr,
 196                                 unsigned long h,
 197                                 unsigned long data) = {
 198         [REG_FN_TEST_BASE + 0] = test_8,
 199         [REG_FN_TEST_BASE + 1] = test_16,
 200         [REG_FN_TEST_BASE + 3] = test_32,
 201         [REG_FN_WRITE_BASE + 0] = write_8,
 202         [REG_FN_WRITE_BASE + 1] = write_16,
 203         [REG_FN_WRITE_BASE + 3] = write_32,
 204         [REG_FN_MODIFY_BASE + 0] = modify_8,
 205         [REG_FN_MODIFY_BASE + 1] = modify_16,
 206         [REG_FN_MODIFY_BASE + 3] = modify_32,
 207 };
 208 
 209 unsigned long (*intc_enable_fns[])(unsigned long addr,
 210                                    unsigned long handle,
 211                                    unsigned long (*fn)(unsigned long,
 212                                             unsigned long,
 213                                             unsigned long),
 214                                    unsigned int irq) = {
 215         [MODE_ENABLE_REG] = intc_mode_field,
 216         [MODE_MASK_REG] = intc_mode_zero,
 217         [MODE_DUAL_REG] = intc_mode_field,
 218         [MODE_PRIO_REG] = intc_mode_prio,
 219         [MODE_PCLR_REG] = intc_mode_prio,
 220 };
 221 
 222 unsigned long (*intc_disable_fns[])(unsigned long addr,
 223                                     unsigned long handle,
 224                                     unsigned long (*fn)(unsigned long,
 225                                              unsigned long,
 226                                              unsigned long),
 227                                     unsigned int irq) = {
 228         [MODE_ENABLE_REG] = intc_mode_zero,
 229         [MODE_MASK_REG] = intc_mode_field,
 230         [MODE_DUAL_REG] = intc_mode_field,
 231         [MODE_PRIO_REG] = intc_mode_zero,
 232         [MODE_PCLR_REG] = intc_mode_field,
 233 };
 234 
 235 unsigned long (*intc_enable_noprio_fns[])(unsigned long addr,
 236                                           unsigned long handle,
 237                                           unsigned long (*fn)(unsigned long,
 238                                                 unsigned long,
 239                                                 unsigned long),
 240                                           unsigned int irq) = {
 241         [MODE_ENABLE_REG] = intc_mode_field,
 242         [MODE_MASK_REG] = intc_mode_zero,
 243         [MODE_DUAL_REG] = intc_mode_field,
 244         [MODE_PRIO_REG] = intc_mode_field,
 245         [MODE_PCLR_REG] = intc_mode_field,
 246 };

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