Source
x
static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
/*
* SPEAr platform shared irq layer source file
*
* Copyright (C) 2009-2012 ST Microelectronics
* Viresh Kumar <vireshk@kernel.org>
*
* Copyright (C) 2012 ST Microelectronics
* Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
/*
* struct spear_shirq: shared irq structure
*
* base: Base register address
* status_reg: Status register offset for chained interrupt handler
* mask_reg: Mask register offset for irq chip
* mask: Mask to apply to the status register
* virq_base: Base virtual interrupt number
* nr_irqs: Number of interrupts handled by this block
* offset: Bit offset of the first interrupt
* irq_chip: Interrupt controller chip used for this instance,
* if NULL group is disabled, but accounted
*/
struct spear_shirq {
void __iomem *base;
u32 status_reg;
u32 mask_reg;
u32 mask;
u32 virq_base;
u32 nr_irqs;
u32 offset;
struct irq_chip *irq_chip;
};
/* spear300 shared irq registers offsets and masks */
static DEFINE_RAW_SPINLOCK(shirq_lock);
static void shirq_irq_mask(struct irq_data *d)
{
struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
u32 val, shift = d->irq - shirq->virq_base + shirq->offset;
u32 __iomem *reg = shirq->base + shirq->mask_reg;
raw_spin_lock(&shirq_lock);
val = readl(reg) & ~(0x1 << shift);
writel(val, reg);
raw_spin_unlock(&shirq_lock);
}
static void shirq_irq_unmask(struct irq_data *d)
{
struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
u32 val, shift = d->irq - shirq->virq_base + shirq->offset;
u32 __iomem *reg = shirq->base + shirq->mask_reg;
raw_spin_lock(&shirq_lock);
val = readl(reg) | (0x1 << shift);
writel(val, reg);
raw_spin_unlock(&shirq_lock);
}
static struct irq_chip shirq_chip = {
.name = "spear-shirq",
.irq_mask = shirq_irq_mask,
.irq_unmask = shirq_irq_unmask,
};
static struct spear_shirq spear300_shirq_ras1 = {
.offset = 0,
.nr_irqs = 9,
.mask = ((0x1 << 9) - 1) << 0,
.irq_chip = &shirq_chip,