mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 02:50:43 +00:00
genirq: Generic chip: Allow irqchip drivers to override irq_reg_{readl,writel}
Currently, these I/O accessors always assume little endian 32-bit registers (readl/writel). On some systems the IRQ registers need to be accessed in BE mode or using 16-bit loads/stores, so we will provide a way to override the default behavior. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Acked-by: Arnd Bergmann <arnd@arndb.de> Link: https://lkml.kernel.org/r/1415342669-30640-4-git-send-email-cernekee@gmail.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
This commit is contained in:
parent
332fd7c4fe
commit
2b28037632
1 changed files with 12 additions and 2 deletions
|
@ -686,6 +686,8 @@ struct irq_chip_type {
|
|||
* struct irq_chip_generic - Generic irq chip data structure
|
||||
* @lock: Lock to protect register and cache data access
|
||||
* @reg_base: Register base address (virtual)
|
||||
* @reg_readl: Alternate I/O accessor (defaults to readl if NULL)
|
||||
* @reg_writel: Alternate I/O accessor (defaults to writel if NULL)
|
||||
* @irq_base: Interrupt base nr for this chip
|
||||
* @irq_cnt: Number of interrupts handled by this chip
|
||||
* @mask_cache: Cached mask register shared between all chip types
|
||||
|
@ -710,6 +712,8 @@ struct irq_chip_type {
|
|||
struct irq_chip_generic {
|
||||
raw_spinlock_t lock;
|
||||
void __iomem *reg_base;
|
||||
u32 (*reg_readl)(void __iomem *addr);
|
||||
void (*reg_writel)(u32 val, void __iomem *addr);
|
||||
unsigned int irq_base;
|
||||
unsigned int irq_cnt;
|
||||
u32 mask_cache;
|
||||
|
@ -818,13 +822,19 @@ static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
|
|||
static inline void irq_reg_writel(struct irq_chip_generic *gc,
|
||||
u32 val, int reg_offset)
|
||||
{
|
||||
writel(val, gc->reg_base + reg_offset);
|
||||
if (gc->reg_writel)
|
||||
gc->reg_writel(val, gc->reg_base + reg_offset);
|
||||
else
|
||||
writel(val, gc->reg_base + reg_offset);
|
||||
}
|
||||
|
||||
static inline u32 irq_reg_readl(struct irq_chip_generic *gc,
|
||||
int reg_offset)
|
||||
{
|
||||
return readl(gc->reg_base + reg_offset);
|
||||
if (gc->reg_readl)
|
||||
return gc->reg_readl(gc->reg_base + reg_offset);
|
||||
else
|
||||
return readl(gc->reg_base + reg_offset);
|
||||
}
|
||||
|
||||
#endif /* _LINUX_IRQ_H */
|
||||
|
|
Loading…
Reference in a new issue