mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 01:04:08 +08:00
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (49 commits) MIPS: JZ4740: Set nand ecc offsets for the qi_lb60 board MIPS: JZ4740: qi_lb60: Add gpio-charger device MIPS: Wire up syncfs(2). MIPS: Hook up name_to_handle_at, open_by_handle_at and clock_adjtime syscalls. MIPS: VR41xx: Convert to new irq_chip functions MIPS: TXx9: Convert to new irq_chip functions MIPS: SNI: Convert to new irq_chip functions MIPS: Sibyte: Convert to new irq_chip functions MIPS: IP32: Convert to new irq_chip functions MIPS: IP27: Convert to new irq_chip functions MIPS: IP22/IP28: Convert to new irq_chip functions MIPS: RB532: Convert to new irq_chip functions MIPS: PowerTV: Convert to new irq_chip functions MIPS: PNX8550: Convert to new irq_chip functions MIPS: PNX83xx: Convert to new irq_chip functions MIPS: msp71xx: Convert to new irq_chip functions MIPS: Loongson: Convert to new irq_chip functions MIPS: Use generic show_interrupts() MIPS: SMTC: Cleanup the hook mess and use irq_data MIPS: SMTC: Use irq_data in smtc_forward_irq() ...
This commit is contained in:
commit
62d0086751
@ -22,6 +22,7 @@ config MIPS
|
||||
select HAVE_DMA_API_DEBUG
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_IRQ_SHOW
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
|
||||
menu "Machine selection"
|
||||
@ -862,6 +863,9 @@ config GPIO_TXX9
|
||||
config CFE
|
||||
bool
|
||||
|
||||
config ARCH_DMA_ADDR_T_64BIT
|
||||
def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT
|
||||
|
||||
config DMA_COHERENT
|
||||
bool
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <asm/mach-pb1x00/pb1000.h>
|
||||
#endif
|
||||
|
||||
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
|
||||
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
|
||||
|
||||
/* NOTE on interrupt priorities: The original writers of this code said:
|
||||
*
|
||||
@ -218,17 +218,17 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = {
|
||||
};
|
||||
|
||||
|
||||
static void au1x_ic0_unmask(unsigned int irq_nr)
|
||||
static void au1x_ic0_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
|
||||
au_writel(1 << bit, IC0_MASKSET);
|
||||
au_writel(1 << bit, IC0_WAKESET);
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic1_unmask(unsigned int irq_nr)
|
||||
static void au1x_ic1_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
|
||||
au_writel(1 << bit, IC1_MASKSET);
|
||||
au_writel(1 << bit, IC1_WAKESET);
|
||||
|
||||
@ -236,31 +236,31 @@ static void au1x_ic1_unmask(unsigned int irq_nr)
|
||||
* nowhere in the current kernel sources is it disabled. --mlau
|
||||
*/
|
||||
#if defined(CONFIG_MIPS_PB1000)
|
||||
if (irq_nr == AU1000_GPIO15_INT)
|
||||
if (d->irq == AU1000_GPIO15_INT)
|
||||
au_writel(0x4000, PB1000_MDR); /* enable int */
|
||||
#endif
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic0_mask(unsigned int irq_nr)
|
||||
static void au1x_ic0_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
|
||||
au_writel(1 << bit, IC0_MASKCLR);
|
||||
au_writel(1 << bit, IC0_WAKECLR);
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic1_mask(unsigned int irq_nr)
|
||||
static void au1x_ic1_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
|
||||
au_writel(1 << bit, IC1_MASKCLR);
|
||||
au_writel(1 << bit, IC1_WAKECLR);
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic0_ack(unsigned int irq_nr)
|
||||
static void au1x_ic0_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
|
||||
|
||||
/*
|
||||
* This may assume that we don't get interrupts from
|
||||
@ -271,9 +271,9 @@ static void au1x_ic0_ack(unsigned int irq_nr)
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic1_ack(unsigned int irq_nr)
|
||||
static void au1x_ic1_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
|
||||
|
||||
/*
|
||||
* This may assume that we don't get interrupts from
|
||||
@ -284,9 +284,9 @@ static void au1x_ic1_ack(unsigned int irq_nr)
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic0_maskack(unsigned int irq_nr)
|
||||
static void au1x_ic0_maskack(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
|
||||
|
||||
au_writel(1 << bit, IC0_WAKECLR);
|
||||
au_writel(1 << bit, IC0_MASKCLR);
|
||||
@ -295,9 +295,9 @@ static void au1x_ic0_maskack(unsigned int irq_nr)
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static void au1x_ic1_maskack(unsigned int irq_nr)
|
||||
static void au1x_ic1_maskack(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
|
||||
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
|
||||
|
||||
au_writel(1 << bit, IC1_WAKECLR);
|
||||
au_writel(1 << bit, IC1_MASKCLR);
|
||||
@ -306,9 +306,9 @@ static void au1x_ic1_maskack(unsigned int irq_nr)
|
||||
au_sync();
|
||||
}
|
||||
|
||||
static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
|
||||
static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
|
||||
{
|
||||
int bit = irq - AU1000_INTC1_INT_BASE;
|
||||
int bit = d->irq - AU1000_INTC1_INT_BASE;
|
||||
unsigned long wakemsk, flags;
|
||||
|
||||
/* only GPIO 0-7 can act as wakeup source. Fortunately these
|
||||
@ -336,28 +336,30 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
|
||||
*/
|
||||
static struct irq_chip au1x_ic0_chip = {
|
||||
.name = "Alchemy-IC0",
|
||||
.ack = au1x_ic0_ack,
|
||||
.mask = au1x_ic0_mask,
|
||||
.mask_ack = au1x_ic0_maskack,
|
||||
.unmask = au1x_ic0_unmask,
|
||||
.set_type = au1x_ic_settype,
|
||||
.irq_ack = au1x_ic0_ack,
|
||||
.irq_mask = au1x_ic0_mask,
|
||||
.irq_mask_ack = au1x_ic0_maskack,
|
||||
.irq_unmask = au1x_ic0_unmask,
|
||||
.irq_set_type = au1x_ic_settype,
|
||||
};
|
||||
|
||||
static struct irq_chip au1x_ic1_chip = {
|
||||
.name = "Alchemy-IC1",
|
||||
.ack = au1x_ic1_ack,
|
||||
.mask = au1x_ic1_mask,
|
||||
.mask_ack = au1x_ic1_maskack,
|
||||
.unmask = au1x_ic1_unmask,
|
||||
.set_type = au1x_ic_settype,
|
||||
.set_wake = au1x_ic1_setwake,
|
||||
.irq_ack = au1x_ic1_ack,
|
||||
.irq_mask = au1x_ic1_mask,
|
||||
.irq_mask_ack = au1x_ic1_maskack,
|
||||
.irq_unmask = au1x_ic1_unmask,
|
||||
.irq_set_type = au1x_ic_settype,
|
||||
.irq_set_wake = au1x_ic1_setwake,
|
||||
};
|
||||
|
||||
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
|
||||
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
struct irq_chip *chip;
|
||||
unsigned long icr[6];
|
||||
unsigned int bit, ic;
|
||||
unsigned int bit, ic, irq = d->irq;
|
||||
irq_flow_handler_t handler = NULL;
|
||||
unsigned char *name = NULL;
|
||||
int ret;
|
||||
|
||||
if (irq >= AU1000_INTC1_INT_BASE) {
|
||||
@ -387,47 +389,47 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
|
||||
au_writel(1 << bit, icr[5]);
|
||||
au_writel(1 << bit, icr[4]);
|
||||
au_writel(1 << bit, icr[0]);
|
||||
set_irq_chip_and_handler_name(irq, chip,
|
||||
handle_edge_irq, "riseedge");
|
||||
handler = handle_edge_irq;
|
||||
name = "riseedge";
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
|
||||
au_writel(1 << bit, icr[5]);
|
||||
au_writel(1 << bit, icr[1]);
|
||||
au_writel(1 << bit, icr[3]);
|
||||
set_irq_chip_and_handler_name(irq, chip,
|
||||
handle_edge_irq, "falledge");
|
||||
handler = handle_edge_irq;
|
||||
name = "falledge";
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
|
||||
au_writel(1 << bit, icr[5]);
|
||||
au_writel(1 << bit, icr[1]);
|
||||
au_writel(1 << bit, icr[0]);
|
||||
set_irq_chip_and_handler_name(irq, chip,
|
||||
handle_edge_irq, "bothedge");
|
||||
handler = handle_edge_irq;
|
||||
name = "bothedge";
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
|
||||
au_writel(1 << bit, icr[2]);
|
||||
au_writel(1 << bit, icr[4]);
|
||||
au_writel(1 << bit, icr[0]);
|
||||
set_irq_chip_and_handler_name(irq, chip,
|
||||
handle_level_irq, "hilevel");
|
||||
handler = handle_level_irq;
|
||||
name = "hilevel";
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
|
||||
au_writel(1 << bit, icr[2]);
|
||||
au_writel(1 << bit, icr[1]);
|
||||
au_writel(1 << bit, icr[3]);
|
||||
set_irq_chip_and_handler_name(irq, chip,
|
||||
handle_level_irq, "lowlevel");
|
||||
handler = handle_level_irq;
|
||||
name = "lowlevel";
|
||||
break;
|
||||
case IRQ_TYPE_NONE: /* 0:0:0 */
|
||||
au_writel(1 << bit, icr[5]);
|
||||
au_writel(1 << bit, icr[4]);
|
||||
au_writel(1 << bit, icr[3]);
|
||||
/* set at least chip so we can call set_irq_type() on it */
|
||||
set_irq_chip(irq, chip);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
__irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
|
||||
|
||||
au_sync();
|
||||
|
||||
return ret;
|
||||
@ -504,11 +506,11 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
|
||||
*/
|
||||
for (i = AU1000_INTC0_INT_BASE;
|
||||
(i < AU1000_INTC0_INT_BASE + 32); i++)
|
||||
au1x_ic_settype(i, IRQ_TYPE_NONE);
|
||||
au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
|
||||
|
||||
for (i = AU1000_INTC1_INT_BASE;
|
||||
(i < AU1000_INTC1_INT_BASE + 32); i++)
|
||||
au1x_ic_settype(i, IRQ_TYPE_NONE);
|
||||
au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
|
||||
|
||||
/*
|
||||
* Initialize IC0, which is fixed per processor.
|
||||
@ -526,7 +528,7 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
|
||||
au_writel(1 << bit, IC0_ASSIGNSET);
|
||||
}
|
||||
|
||||
au1x_ic_settype(irq_nr, map->im_type);
|
||||
au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
|
||||
++map;
|
||||
}
|
||||
|
||||
|
@ -97,26 +97,26 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
|
||||
* CPLD generates tons of spurious interrupts (at least on my DB1200).
|
||||
* -- mlau
|
||||
*/
|
||||
static void bcsr_irq_mask(unsigned int irq_nr)
|
||||
static void bcsr_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
|
||||
unsigned short v = 1 << (d->irq - bcsr_csc_base);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
|
||||
wmb();
|
||||
}
|
||||
|
||||
static void bcsr_irq_maskack(unsigned int irq_nr)
|
||||
static void bcsr_irq_maskack(struct irq_data *d)
|
||||
{
|
||||
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
|
||||
unsigned short v = 1 << (d->irq - bcsr_csc_base);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */
|
||||
wmb();
|
||||
}
|
||||
|
||||
static void bcsr_irq_unmask(unsigned int irq_nr)
|
||||
static void bcsr_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
|
||||
unsigned short v = 1 << (d->irq - bcsr_csc_base);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
|
||||
__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
|
||||
wmb();
|
||||
@ -124,9 +124,9 @@ static void bcsr_irq_unmask(unsigned int irq_nr)
|
||||
|
||||
static struct irq_chip bcsr_irq_type = {
|
||||
.name = "CPLD",
|
||||
.mask = bcsr_irq_mask,
|
||||
.mask_ack = bcsr_irq_maskack,
|
||||
.unmask = bcsr_irq_unmask,
|
||||
.irq_mask = bcsr_irq_mask,
|
||||
.irq_mask_ack = bcsr_irq_maskack,
|
||||
.irq_unmask = bcsr_irq_unmask,
|
||||
};
|
||||
|
||||
void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
|
||||
|
@ -49,51 +49,51 @@
|
||||
|
||||
static int ar7_irq_base;
|
||||
|
||||
static void ar7_unmask_irq(unsigned int irq)
|
||||
static void ar7_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << ((irq - ar7_irq_base) % 32),
|
||||
REG(ESR_OFFSET(irq - ar7_irq_base)));
|
||||
writel(1 << ((d->irq - ar7_irq_base) % 32),
|
||||
REG(ESR_OFFSET(d->irq - ar7_irq_base)));
|
||||
}
|
||||
|
||||
static void ar7_mask_irq(unsigned int irq)
|
||||
static void ar7_mask_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << ((irq - ar7_irq_base) % 32),
|
||||
REG(ECR_OFFSET(irq - ar7_irq_base)));
|
||||
writel(1 << ((d->irq - ar7_irq_base) % 32),
|
||||
REG(ECR_OFFSET(d->irq - ar7_irq_base)));
|
||||
}
|
||||
|
||||
static void ar7_ack_irq(unsigned int irq)
|
||||
static void ar7_ack_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << ((irq - ar7_irq_base) % 32),
|
||||
REG(CR_OFFSET(irq - ar7_irq_base)));
|
||||
writel(1 << ((d->irq - ar7_irq_base) % 32),
|
||||
REG(CR_OFFSET(d->irq - ar7_irq_base)));
|
||||
}
|
||||
|
||||
static void ar7_unmask_sec_irq(unsigned int irq)
|
||||
static void ar7_unmask_sec_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
|
||||
writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
|
||||
}
|
||||
|
||||
static void ar7_mask_sec_irq(unsigned int irq)
|
||||
static void ar7_mask_sec_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
|
||||
writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
|
||||
}
|
||||
|
||||
static void ar7_ack_sec_irq(unsigned int irq)
|
||||
static void ar7_ack_sec_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
|
||||
writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
|
||||
}
|
||||
|
||||
static struct irq_chip ar7_irq_type = {
|
||||
.name = "AR7",
|
||||
.unmask = ar7_unmask_irq,
|
||||
.mask = ar7_mask_irq,
|
||||
.ack = ar7_ack_irq
|
||||
.irq_unmask = ar7_unmask_irq,
|
||||
.irq_mask = ar7_mask_irq,
|
||||
.irq_ack = ar7_ack_irq
|
||||
};
|
||||
|
||||
static struct irq_chip ar7_sec_irq_type = {
|
||||
.name = "AR7",
|
||||
.unmask = ar7_unmask_sec_irq,
|
||||
.mask = ar7_mask_sec_irq,
|
||||
.ack = ar7_ack_sec_irq,
|
||||
.irq_unmask = ar7_unmask_sec_irq,
|
||||
.irq_mask = ar7_mask_sec_irq,
|
||||
.irq_ack = ar7_ack_sec_irq,
|
||||
};
|
||||
|
||||
static struct irqaction ar7_cascade_action = {
|
||||
|
@ -62,13 +62,12 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
spurious_interrupt();
|
||||
}
|
||||
|
||||
static void ar71xx_misc_irq_unmask(unsigned int irq)
|
||||
static void ar71xx_misc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
|
||||
void __iomem *base = ath79_reset_base;
|
||||
u32 t;
|
||||
|
||||
irq -= ATH79_MISC_IRQ_BASE;
|
||||
|
||||
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
|
||||
@ -76,13 +75,12 @@ static void ar71xx_misc_irq_unmask(unsigned int irq)
|
||||
__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
}
|
||||
|
||||
static void ar71xx_misc_irq_mask(unsigned int irq)
|
||||
static void ar71xx_misc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
|
||||
void __iomem *base = ath79_reset_base;
|
||||
u32 t;
|
||||
|
||||
irq -= ATH79_MISC_IRQ_BASE;
|
||||
|
||||
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
|
||||
@ -90,13 +88,12 @@ static void ar71xx_misc_irq_mask(unsigned int irq)
|
||||
__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
|
||||
}
|
||||
|
||||
static void ar724x_misc_irq_ack(unsigned int irq)
|
||||
static void ar724x_misc_irq_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
|
||||
void __iomem *base = ath79_reset_base;
|
||||
u32 t;
|
||||
|
||||
irq -= ATH79_MISC_IRQ_BASE;
|
||||
|
||||
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
|
||||
__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
|
||||
|
||||
@ -106,8 +103,8 @@ static void ar724x_misc_irq_ack(unsigned int irq)
|
||||
|
||||
static struct irq_chip ath79_misc_irq_chip = {
|
||||
.name = "MISC",
|
||||
.unmask = ar71xx_misc_irq_unmask,
|
||||
.mask = ar71xx_misc_irq_mask,
|
||||
.irq_unmask = ar71xx_misc_irq_unmask,
|
||||
.irq_mask = ar71xx_misc_irq_mask,
|
||||
};
|
||||
|
||||
static void __init ath79_misc_irq_init(void)
|
||||
@ -119,15 +116,14 @@ static void __init ath79_misc_irq_init(void)
|
||||
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
|
||||
|
||||
if (soc_is_ar71xx() || soc_is_ar913x())
|
||||
ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
|
||||
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
|
||||
else if (soc_is_ar724x())
|
||||
ath79_misc_irq_chip.ack = ar724x_misc_irq_ack;
|
||||
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
|
||||
else
|
||||
BUG();
|
||||
|
||||
for (i = ATH79_MISC_IRQ_BASE;
|
||||
i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
|
||||
irq_desc[i].status = IRQ_DISABLED;
|
||||
set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
|
||||
handle_level_irq);
|
||||
}
|
||||
|
@ -76,88 +76,80 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
* internal IRQs operations: only mask/unmask on PERF irq mask
|
||||
* register.
|
||||
*/
|
||||
static inline void bcm63xx_internal_irq_mask(unsigned int irq)
|
||||
static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
|
||||
u32 mask;
|
||||
|
||||
irq -= IRQ_INTERNAL_BASE;
|
||||
mask = bcm_perf_readl(PERF_IRQMASK_REG);
|
||||
mask &= ~(1 << irq);
|
||||
bcm_perf_writel(mask, PERF_IRQMASK_REG);
|
||||
}
|
||||
|
||||
static void bcm63xx_internal_irq_unmask(unsigned int irq)
|
||||
static void bcm63xx_internal_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
|
||||
u32 mask;
|
||||
|
||||
irq -= IRQ_INTERNAL_BASE;
|
||||
mask = bcm_perf_readl(PERF_IRQMASK_REG);
|
||||
mask |= (1 << irq);
|
||||
bcm_perf_writel(mask, PERF_IRQMASK_REG);
|
||||
}
|
||||
|
||||
static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
|
||||
{
|
||||
bcm63xx_internal_irq_unmask(irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* external IRQs operations: mask/unmask and clear on PERF external
|
||||
* irq control register.
|
||||
*/
|
||||
static void bcm63xx_external_irq_mask(unsigned int irq)
|
||||
static void bcm63xx_external_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_EXT_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= IRQ_EXT_BASE;
|
||||
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
|
||||
reg &= ~EXTIRQ_CFG_MASK(irq);
|
||||
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
|
||||
}
|
||||
|
||||
static void bcm63xx_external_irq_unmask(unsigned int irq)
|
||||
static void bcm63xx_external_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_EXT_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= IRQ_EXT_BASE;
|
||||
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
|
||||
reg |= EXTIRQ_CFG_MASK(irq);
|
||||
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
|
||||
}
|
||||
|
||||
static void bcm63xx_external_irq_clear(unsigned int irq)
|
||||
static void bcm63xx_external_irq_clear(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_EXT_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= IRQ_EXT_BASE;
|
||||
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
|
||||
reg |= EXTIRQ_CFG_CLEAR(irq);
|
||||
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
|
||||
}
|
||||
|
||||
static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
|
||||
static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
|
||||
{
|
||||
set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
|
||||
set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
|
||||
irq_enable_hazard();
|
||||
bcm63xx_external_irq_unmask(irq);
|
||||
bcm63xx_external_irq_unmask(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bcm63xx_external_irq_shutdown(unsigned int irq)
|
||||
static void bcm63xx_external_irq_shutdown(struct irq_data *d)
|
||||
{
|
||||
bcm63xx_external_irq_mask(irq);
|
||||
clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
|
||||
bcm63xx_external_irq_mask(d);
|
||||
clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
|
||||
irq_disable_hazard();
|
||||
}
|
||||
|
||||
static int bcm63xx_external_irq_set_type(unsigned int irq,
|
||||
static int bcm63xx_external_irq_set_type(struct irq_data *d,
|
||||
unsigned int flow_type)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_EXT_BASE;
|
||||
u32 reg;
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
|
||||
irq -= IRQ_EXT_BASE;
|
||||
|
||||
flow_type &= IRQ_TYPE_SENSE_MASK;
|
||||
|
||||
@ -199,37 +191,32 @@ static int bcm63xx_external_irq_set_type(unsigned int irq,
|
||||
}
|
||||
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
|
||||
|
||||
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
|
||||
desc->status |= IRQ_LEVEL;
|
||||
desc->handle_irq = handle_level_irq;
|
||||
} else {
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
}
|
||||
irqd_set_trigger_type(d, flow_type);
|
||||
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
|
||||
__irq_set_handler_locked(d->irq, handle_level_irq);
|
||||
else
|
||||
__irq_set_handler_locked(d->irq, handle_edge_irq);
|
||||
|
||||
return 0;
|
||||
return IRQ_SET_MASK_OK_NOCOPY;
|
||||
}
|
||||
|
||||
static struct irq_chip bcm63xx_internal_irq_chip = {
|
||||
.name = "bcm63xx_ipic",
|
||||
.startup = bcm63xx_internal_irq_startup,
|
||||
.shutdown = bcm63xx_internal_irq_mask,
|
||||
|
||||
.mask = bcm63xx_internal_irq_mask,
|
||||
.mask_ack = bcm63xx_internal_irq_mask,
|
||||
.unmask = bcm63xx_internal_irq_unmask,
|
||||
.irq_mask = bcm63xx_internal_irq_mask,
|
||||
.irq_unmask = bcm63xx_internal_irq_unmask,
|
||||
};
|
||||
|
||||
static struct irq_chip bcm63xx_external_irq_chip = {
|
||||
.name = "bcm63xx_epic",
|
||||
.startup = bcm63xx_external_irq_startup,
|
||||
.shutdown = bcm63xx_external_irq_shutdown,
|
||||
.irq_startup = bcm63xx_external_irq_startup,
|
||||
.irq_shutdown = bcm63xx_external_irq_shutdown,
|
||||
|
||||
.ack = bcm63xx_external_irq_clear,
|
||||
.irq_ack = bcm63xx_external_irq_clear,
|
||||
|
||||
.mask = bcm63xx_external_irq_mask,
|
||||
.unmask = bcm63xx_external_irq_unmask,
|
||||
.irq_mask = bcm63xx_external_irq_mask,
|
||||
.irq_unmask = bcm63xx_external_irq_unmask,
|
||||
|
||||
.set_type = bcm63xx_external_irq_set_type,
|
||||
.irq_set_type = bcm63xx_external_irq_set_type,
|
||||
};
|
||||
|
||||
static struct irqaction cpu_ip2_cascade_action = {
|
||||
|
@ -17,80 +17,48 @@
|
||||
#include <asm/dec/ioasic_addrs.h>
|
||||
#include <asm/dec/ioasic_ints.h>
|
||||
|
||||
|
||||
static int ioasic_irq_base;
|
||||
|
||||
|
||||
static inline void unmask_ioasic_irq(unsigned int irq)
|
||||
static void unmask_ioasic_irq(struct irq_data *d)
|
||||
{
|
||||
u32 simr;
|
||||
|
||||
simr = ioasic_read(IO_REG_SIMR);
|
||||
simr |= (1 << (irq - ioasic_irq_base));
|
||||
simr |= (1 << (d->irq - ioasic_irq_base));
|
||||
ioasic_write(IO_REG_SIMR, simr);
|
||||
}
|
||||
|
||||
static inline void mask_ioasic_irq(unsigned int irq)
|
||||
static void mask_ioasic_irq(struct irq_data *d)
|
||||
{
|
||||
u32 simr;
|
||||
|
||||
simr = ioasic_read(IO_REG_SIMR);
|
||||
simr &= ~(1 << (irq - ioasic_irq_base));
|
||||
simr &= ~(1 << (d->irq - ioasic_irq_base));
|
||||
ioasic_write(IO_REG_SIMR, simr);
|
||||
}
|
||||
|
||||
static inline void clear_ioasic_irq(unsigned int irq)
|
||||
static void ack_ioasic_irq(struct irq_data *d)
|
||||
{
|
||||
u32 sir;
|
||||
|
||||
sir = ~(1 << (irq - ioasic_irq_base));
|
||||
ioasic_write(IO_REG_SIR, sir);
|
||||
}
|
||||
|
||||
static inline void ack_ioasic_irq(unsigned int irq)
|
||||
{
|
||||
mask_ioasic_irq(irq);
|
||||
mask_ioasic_irq(d);
|
||||
fast_iob();
|
||||
}
|
||||
|
||||
static inline void end_ioasic_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
unmask_ioasic_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip ioasic_irq_type = {
|
||||
.name = "IO-ASIC",
|
||||
.ack = ack_ioasic_irq,
|
||||
.mask = mask_ioasic_irq,
|
||||
.mask_ack = ack_ioasic_irq,
|
||||
.unmask = unmask_ioasic_irq,
|
||||
.irq_ack = ack_ioasic_irq,
|
||||
.irq_mask = mask_ioasic_irq,
|
||||
.irq_mask_ack = ack_ioasic_irq,
|
||||
.irq_unmask = unmask_ioasic_irq,
|
||||
};
|
||||
|
||||
|
||||
#define unmask_ioasic_dma_irq unmask_ioasic_irq
|
||||
|
||||
#define mask_ioasic_dma_irq mask_ioasic_irq
|
||||
|
||||
#define ack_ioasic_dma_irq ack_ioasic_irq
|
||||
|
||||
static inline void end_ioasic_dma_irq(unsigned int irq)
|
||||
{
|
||||
clear_ioasic_irq(irq);
|
||||
fast_iob();
|
||||
end_ioasic_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip ioasic_dma_irq_type = {
|
||||
.name = "IO-ASIC-DMA",
|
||||
.ack = ack_ioasic_dma_irq,
|
||||
.mask = mask_ioasic_dma_irq,
|
||||
.mask_ack = ack_ioasic_dma_irq,
|
||||
.unmask = unmask_ioasic_dma_irq,
|
||||
.end = end_ioasic_dma_irq,
|
||||
.irq_ack = ack_ioasic_irq,
|
||||
.irq_mask = mask_ioasic_irq,
|
||||
.irq_mask_ack = ack_ioasic_irq,
|
||||
.irq_unmask = unmask_ioasic_irq,
|
||||
};
|
||||
|
||||
|
||||
void __init init_ioasic_irqs(int base)
|
||||
{
|
||||
int i;
|
||||
|
@ -27,43 +27,40 @@
|
||||
*/
|
||||
u32 cached_kn02_csr;
|
||||
|
||||
|
||||
static int kn02_irq_base;
|
||||
|
||||
|
||||
static inline void unmask_kn02_irq(unsigned int irq)
|
||||
static void unmask_kn02_irq(struct irq_data *d)
|
||||
{
|
||||
volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
|
||||
KN02_CSR);
|
||||
|
||||
cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
|
||||
cached_kn02_csr |= (1 << (d->irq - kn02_irq_base + 16));
|
||||
*csr = cached_kn02_csr;
|
||||
}
|
||||
|
||||
static inline void mask_kn02_irq(unsigned int irq)
|
||||
static void mask_kn02_irq(struct irq_data *d)
|
||||
{
|
||||
volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
|
||||
KN02_CSR);
|
||||
|
||||
cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
|
||||
cached_kn02_csr &= ~(1 << (d->irq - kn02_irq_base + 16));
|
||||
*csr = cached_kn02_csr;
|
||||
}
|
||||
|
||||
static void ack_kn02_irq(unsigned int irq)
|
||||
static void ack_kn02_irq(struct irq_data *d)
|
||||
{
|
||||
mask_kn02_irq(irq);
|
||||
mask_kn02_irq(d);
|
||||
iob();
|
||||
}
|
||||
|
||||
static struct irq_chip kn02_irq_type = {
|
||||
.name = "KN02-CSR",
|
||||
.ack = ack_kn02_irq,
|
||||
.mask = mask_kn02_irq,
|
||||
.mask_ack = ack_kn02_irq,
|
||||
.unmask = unmask_kn02_irq,
|
||||
.irq_ack = ack_kn02_irq,
|
||||
.irq_mask = mask_kn02_irq,
|
||||
.irq_mask_ack = ack_kn02_irq,
|
||||
.irq_unmask = unmask_kn02_irq,
|
||||
};
|
||||
|
||||
|
||||
void __init init_kn02_irqs(int base)
|
||||
{
|
||||
volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
|
||||
|
@ -34,13 +34,10 @@
|
||||
|
||||
#include <asm/emma/emma2rh.h>
|
||||
|
||||
static void emma2rh_irq_enable(unsigned int irq)
|
||||
static void emma2rh_irq_enable(struct irq_data *d)
|
||||
{
|
||||
u32 reg_value;
|
||||
u32 reg_bitmask;
|
||||
u32 reg_index;
|
||||
|
||||
irq -= EMMA2RH_IRQ_BASE;
|
||||
unsigned int irq = d->irq - EMMA2RH_IRQ_BASE;
|
||||
u32 reg_value, reg_bitmask, reg_index;
|
||||
|
||||
reg_index = EMMA2RH_BHIF_INT_EN_0 +
|
||||
(EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32);
|
||||
@ -49,13 +46,10 @@ static void emma2rh_irq_enable(unsigned int irq)
|
||||
emma2rh_out32(reg_index, reg_value | reg_bitmask);
|
||||
}
|
||||
|
||||
static void emma2rh_irq_disable(unsigned int irq)
|
||||
static void emma2rh_irq_disable(struct irq_data *d)
|
||||
{
|
||||
u32 reg_value;
|
||||
u32 reg_bitmask;
|
||||
u32 reg_index;
|
||||
|
||||
irq -= EMMA2RH_IRQ_BASE;
|
||||
unsigned int irq = d->irq - EMMA2RH_IRQ_BASE;
|
||||
u32 reg_value, reg_bitmask, reg_index;
|
||||
|
||||
reg_index = EMMA2RH_BHIF_INT_EN_0 +
|
||||
(EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32);
|
||||
@ -66,10 +60,8 @@ static void emma2rh_irq_disable(unsigned int irq)
|
||||
|
||||
struct irq_chip emma2rh_irq_controller = {
|
||||
.name = "emma2rh_irq",
|
||||
.ack = emma2rh_irq_disable,
|
||||
.mask = emma2rh_irq_disable,
|
||||
.mask_ack = emma2rh_irq_disable,
|
||||
.unmask = emma2rh_irq_enable,
|
||||
.irq_mask = emma2rh_irq_disable,
|
||||
.irq_unmask = emma2rh_irq_enable,
|
||||
};
|
||||
|
||||
void emma2rh_irq_init(void)
|
||||
@ -82,23 +74,21 @@ void emma2rh_irq_init(void)
|
||||
handle_level_irq, "level");
|
||||
}
|
||||
|
||||
static void emma2rh_sw_irq_enable(unsigned int irq)
|
||||
static void emma2rh_sw_irq_enable(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= EMMA2RH_SW_IRQ_BASE;
|
||||
|
||||
reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
|
||||
reg |= 1 << irq;
|
||||
emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
|
||||
}
|
||||
|
||||
static void emma2rh_sw_irq_disable(unsigned int irq)
|
||||
static void emma2rh_sw_irq_disable(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= EMMA2RH_SW_IRQ_BASE;
|
||||
|
||||
reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
|
||||
reg &= ~(1 << irq);
|
||||
emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
|
||||
@ -106,10 +96,8 @@ static void emma2rh_sw_irq_disable(unsigned int irq)
|
||||
|
||||
struct irq_chip emma2rh_sw_irq_controller = {
|
||||
.name = "emma2rh_sw_irq",
|
||||
.ack = emma2rh_sw_irq_disable,
|
||||
.mask = emma2rh_sw_irq_disable,
|
||||
.mask_ack = emma2rh_sw_irq_disable,
|
||||
.unmask = emma2rh_sw_irq_enable,
|
||||
.irq_mask = emma2rh_sw_irq_disable,
|
||||
.irq_unmask = emma2rh_sw_irq_enable,
|
||||
};
|
||||
|
||||
void emma2rh_sw_irq_init(void)
|
||||
@ -122,39 +110,38 @@ void emma2rh_sw_irq_init(void)
|
||||
handle_level_irq, "level");
|
||||
}
|
||||
|
||||
static void emma2rh_gpio_irq_enable(unsigned int irq)
|
||||
static void emma2rh_gpio_irq_enable(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= EMMA2RH_GPIO_IRQ_BASE;
|
||||
|
||||
reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
|
||||
reg |= 1 << irq;
|
||||
emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
|
||||
}
|
||||
|
||||
static void emma2rh_gpio_irq_disable(unsigned int irq)
|
||||
static void emma2rh_gpio_irq_disable(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= EMMA2RH_GPIO_IRQ_BASE;
|
||||
|
||||
reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
|
||||
reg &= ~(1 << irq);
|
||||
emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
|
||||
}
|
||||
|
||||
static void emma2rh_gpio_irq_ack(unsigned int irq)
|
||||
static void emma2rh_gpio_irq_ack(struct irq_data *d)
|
||||
{
|
||||
irq -= EMMA2RH_GPIO_IRQ_BASE;
|
||||
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
|
||||
|
||||
emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
|
||||
}
|
||||
|
||||
static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
|
||||
static void emma2rh_gpio_irq_mask_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
|
||||
u32 reg;
|
||||
|
||||
irq -= EMMA2RH_GPIO_IRQ_BASE;
|
||||
emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
|
||||
|
||||
reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
|
||||
@ -164,10 +151,10 @@ static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
|
||||
|
||||
struct irq_chip emma2rh_gpio_irq_controller = {
|
||||
.name = "emma2rh_gpio_irq",
|
||||
.ack = emma2rh_gpio_irq_ack,
|
||||
.mask = emma2rh_gpio_irq_disable,
|
||||
.mask_ack = emma2rh_gpio_irq_mask_ack,
|
||||
.unmask = emma2rh_gpio_irq_enable,
|
||||
.irq_ack = emma2rh_gpio_irq_ack,
|
||||
.irq_mask = emma2rh_gpio_irq_disable,
|
||||
.irq_mask_ack = emma2rh_gpio_irq_mask_ack,
|
||||
.irq_unmask = emma2rh_gpio_irq_enable,
|
||||
};
|
||||
|
||||
void emma2rh_gpio_irq_init(void)
|
||||
|
@ -55,9 +55,9 @@ static inline void smtc_im_ack_irq(unsigned int irq)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
extern int plat_set_irq_affinity(unsigned int irq,
|
||||
const struct cpumask *affinity);
|
||||
extern void smtc_forward_irq(unsigned int irq);
|
||||
extern int plat_set_irq_affinity(struct irq_data *d,
|
||||
const struct cpumask *affinity, bool force);
|
||||
extern void smtc_forward_irq(struct irq_data *d);
|
||||
|
||||
/*
|
||||
* IRQ affinity hook invoked at the beginning of interrupt dispatch
|
||||
@ -70,51 +70,53 @@ extern void smtc_forward_irq(unsigned int irq);
|
||||
* cpumask implementations, this version is optimistically assuming
|
||||
* that cpumask.h macro overhead is reasonable during interrupt dispatch.
|
||||
*/
|
||||
#define IRQ_AFFINITY_HOOK(irq) \
|
||||
do { \
|
||||
if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\
|
||||
smtc_forward_irq(irq); \
|
||||
irq_exit(); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
static inline int handle_on_other_cpu(unsigned int irq)
|
||||
{
|
||||
struct irq_data *d = irq_get_irq_data(irq);
|
||||
|
||||
if (cpumask_test_cpu(smp_processor_id(), d->affinity))
|
||||
return 0;
|
||||
smtc_forward_irq(d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* Not doing SMTC affinity */
|
||||
|
||||
#define IRQ_AFFINITY_HOOK(irq) do { } while (0)
|
||||
static inline int handle_on_other_cpu(unsigned int irq) { return 0; }
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
|
||||
|
||||
static inline void smtc_im_backstop(unsigned int irq)
|
||||
{
|
||||
if (irq_hwmask[irq] & 0x0000ff00)
|
||||
write_c0_tccontext(read_c0_tccontext() &
|
||||
~(irq_hwmask[irq] & 0x0000ff00));
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear interrupt mask handling "backstop" if irq_hwmask
|
||||
* entry so indicates. This implies that the ack() or end()
|
||||
* functions will take over re-enabling the low-level mask.
|
||||
* Otherwise it will be done on return from exception.
|
||||
*/
|
||||
#define __DO_IRQ_SMTC_HOOK(irq) \
|
||||
do { \
|
||||
IRQ_AFFINITY_HOOK(irq); \
|
||||
if (irq_hwmask[irq] & 0x0000ff00) \
|
||||
write_c0_tccontext(read_c0_tccontext() & \
|
||||
~(irq_hwmask[irq] & 0x0000ff00)); \
|
||||
} while (0)
|
||||
static inline int smtc_handle_on_other_cpu(unsigned int irq)
|
||||
{
|
||||
int ret = handle_on_other_cpu(irq);
|
||||
|
||||
#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) \
|
||||
do { \
|
||||
if (irq_hwmask[irq] & 0x0000ff00) \
|
||||
write_c0_tccontext(read_c0_tccontext() & \
|
||||
~(irq_hwmask[irq] & 0x0000ff00)); \
|
||||
} while (0)
|
||||
if (!ret)
|
||||
smtc_im_backstop(irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define __DO_IRQ_SMTC_HOOK(irq) \
|
||||
do { \
|
||||
IRQ_AFFINITY_HOOK(irq); \
|
||||
} while (0)
|
||||
#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) do { } while (0)
|
||||
static inline void smtc_im_backstop(unsigned int irq) { }
|
||||
static inline int smtc_handle_on_other_cpu(unsigned int irq)
|
||||
{
|
||||
return handle_on_other_cpu(irq);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org)
|
||||
*/
|
||||
#ifndef __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H
|
||||
#define __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H
|
||||
|
||||
#define cpu_has_mips16 1
|
||||
#define cpu_has_dsp 1
|
||||
#define cpu_has_mipsmt 1
|
||||
#define cpu_has_fpu 0
|
||||
|
||||
#define cpu_has_mips32r1 0
|
||||
#define cpu_has_mips32r2 1
|
||||
#define cpu_has_mips64r1 0
|
||||
#define cpu_has_mips64r2 0
|
||||
|
||||
#endif /* __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H */
|
343
arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h
Normal file
343
arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h
Normal file
@ -0,0 +1,343 @@
|
||||
/*
|
||||
*
|
||||
* Macros for external SMP-safe access to the PMC MSP71xx reference
|
||||
* board GPIO pins
|
||||
*
|
||||
* Copyright 2010 PMC-Sierra, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MSP_GPIO_MACROS_H__
|
||||
#define __MSP_GPIO_MACROS_H__
|
||||
|
||||
#include <msp_regops.h>
|
||||
#include <msp_regs.h>
|
||||
|
||||
#ifdef CONFIG_PMC_MSP7120_GW
|
||||
#define MSP_NUM_GPIOS 20
|
||||
#else
|
||||
#define MSP_NUM_GPIOS 28
|
||||
#endif
|
||||
|
||||
/* -- GPIO Enumerations -- */
|
||||
enum msp_gpio_data {
|
||||
MSP_GPIO_LO = 0,
|
||||
MSP_GPIO_HI = 1,
|
||||
MSP_GPIO_NONE, /* Special - Means pin is out of range */
|
||||
MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */
|
||||
};
|
||||
|
||||
enum msp_gpio_mode {
|
||||
MSP_GPIO_INPUT = 0x0,
|
||||
/* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */
|
||||
MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */
|
||||
MSP_GPIO_OUTPUT = 0x8,
|
||||
MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */
|
||||
MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */
|
||||
MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */
|
||||
MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */
|
||||
};
|
||||
|
||||
/* -- Static Tables -- */
|
||||
|
||||
/* Maps pins to data register */
|
||||
static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
|
||||
/* GPIO 0 and 1 on the first register */
|
||||
GPIO_DATA1_REG, GPIO_DATA1_REG,
|
||||
/* GPIO 2, 3, 4, and 5 on the second register */
|
||||
GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
|
||||
/* GPIO 6, 7, 8, and 9 on the third register */
|
||||
GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
|
||||
/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
|
||||
GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
|
||||
GPIO_DATA4_REG, GPIO_DATA4_REG,
|
||||
/* GPIO 16 - 23 on the first strange EXTENDED register */
|
||||
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
|
||||
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
|
||||
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
|
||||
/* GPIO 24 - 27 on the second strange EXTENDED register */
|
||||
EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
|
||||
EXTENDED_GPIO2_REG,
|
||||
};
|
||||
|
||||
/* Maps pins to mode register */
|
||||
static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
|
||||
/* GPIO 0 and 1 on the first register */
|
||||
GPIO_CFG1_REG, GPIO_CFG1_REG,
|
||||
/* GPIO 2, 3, 4, and 5 on the second register */
|
||||
GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
|
||||
/* GPIO 6, 7, 8, and 9 on the third register */
|
||||
GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
|
||||
/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
|
||||
GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
|
||||
GPIO_CFG4_REG, GPIO_CFG4_REG,
|
||||
/* GPIO 16 - 23 on the first strange EXTENDED register */
|
||||
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
|
||||
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
|
||||
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
|
||||
/* GPIO 24 - 27 on the second strange EXTENDED register */
|
||||
EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
|
||||
EXTENDED_GPIO2_REG,
|
||||
};
|
||||
|
||||
/* Maps 'basic' pins to relative offset from 0 per register */
|
||||
static int MSP_GPIO_OFFSET[] = {
|
||||
/* GPIO 0 and 1 on the first register */
|
||||
0, 0,
|
||||
/* GPIO 2, 3, 4, and 5 on the second register */
|
||||
2, 2, 2, 2,
|
||||
/* GPIO 6, 7, 8, and 9 on the third register */
|
||||
6, 6, 6, 6,
|
||||
/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
|
||||
10, 10, 10, 10, 10, 10,
|
||||
};
|
||||
|
||||
/* Maps MODE to allowed pin mask */
|
||||
static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
|
||||
0xffffffff, /* Mode 0 - INPUT */
|
||||
0x00000, /* Mode 1 - INTERRUPT */
|
||||
0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/
|
||||
0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */
|
||||
0xffffffff, /* Mode 8 - OUTPUT */
|
||||
0x0000f, /* Mode 9 - UART_OUTPUT/
|
||||
PERF_TIMERA (GPIO 0, 1, 2, 3) */
|
||||
0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */
|
||||
0x00000, /* Mode b - Not really a mode! */
|
||||
};
|
||||
|
||||
/* -- Bit masks -- */
|
||||
|
||||
/* This gives you the 'register relative offset gpio' number */
|
||||
#define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio])
|
||||
|
||||
/* These take the 'register relative offset gpio' number */
|
||||
#define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio)
|
||||
#define BASIC_MODE_REG_VALUE(mode, ogpio) \
|
||||
(mode << BASIC_MODE_REG_SHIFT(ogpio))
|
||||
#define BASIC_MODE_REG_MASK(ogpio) \
|
||||
BASIC_MODE_REG_VALUE(0xf, ogpio)
|
||||
#define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4)
|
||||
#define BASIC_MODE_REG_FROM_REG(data, ogpio) \
|
||||
((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))
|
||||
|
||||
/* These take the actual GPIO number (0 through 15) */
|
||||
#define BASIC_DATA_MASK(gpio) \
|
||||
BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
|
||||
#define BASIC_MODE_MASK(gpio) \
|
||||
BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
|
||||
#define BASIC_MODE(mode, gpio) \
|
||||
BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
|
||||
#define BASIC_MODE_SHIFT(gpio) \
|
||||
BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
|
||||
#define BASIC_MODE_FROM_REG(data, gpio) \
|
||||
BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))
|
||||
|
||||
/*
|
||||
* Each extended GPIO register is 32 bits long and is responsible for up to
|
||||
* eight GPIOs. The least significant 16 bits contain the set and clear bit
|
||||
* pair for each of the GPIOs. The most significant 16 bits contain the
|
||||
* disable and enable bit pair for each of the GPIOs. For example, the
|
||||
* extended GPIO reg for GPIOs 16-23 is as follows:
|
||||
*
|
||||
* 31: GPIO23_DISABLE
|
||||
* ...
|
||||
* 19: GPIO17_DISABLE
|
||||
* 18: GPIO17_ENABLE
|
||||
* 17: GPIO16_DISABLE
|
||||
* 16: GPIO16_ENABLE
|
||||
* ...
|
||||
* 3: GPIO17_SET
|
||||
* 2: GPIO17_CLEAR
|
||||
* 1: GPIO16_SET
|
||||
* 0: GPIO16_CLEAR
|
||||
*/
|
||||
|
||||
/* This gives the 'register relative offset gpio' number */
|
||||
#define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24)
|
||||
|
||||
/* These take the 'register relative offset gpio' number */
|
||||
#define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16))
|
||||
#define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16))
|
||||
#define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2))
|
||||
#define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2))
|
||||
|
||||
/* These take the actual GPIO number (16 through 27) */
|
||||
#define EXTENDED_DISABLE(gpio) \
|
||||
EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
|
||||
#define EXTENDED_ENABLE(gpio) \
|
||||
EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
|
||||
#define EXTENDED_SET(gpio) \
|
||||
EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
|
||||
#define EXTENDED_CLR(gpio) \
|
||||
EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))
|
||||
|
||||
#define EXTENDED_FULL_MASK (0xffffffff)
|
||||
|
||||
/* -- API inline-functions -- */
|
||||
|
||||
/*
|
||||
* Gets the current value of the specified pin
|
||||
*/
|
||||
static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio)
|
||||
{
|
||||
u32 pinhi_mask = 0, pinhi_mask2 = 0;
|
||||
|
||||
if (gpio >= MSP_NUM_GPIOS)
|
||||
return MSP_GPIO_NONE;
|
||||
|
||||
if (gpio < 16) {
|
||||
pinhi_mask = BASIC_DATA_MASK(gpio);
|
||||
} else {
|
||||
/*
|
||||
* Two cases are possible with the EXTENDED register:
|
||||
* - In output mode (ENABLED flag set), check the CLR bit
|
||||
* - In input mode (ENABLED flag not set), check the SET bit
|
||||
*/
|
||||
pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio);
|
||||
pinhi_mask2 = EXTENDED_SET(gpio);
|
||||
}
|
||||
if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) ||
|
||||
(*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2))
|
||||
return MSP_GPIO_HI;
|
||||
else
|
||||
return MSP_GPIO_LO;
|
||||
}
|
||||
|
||||
/* Sets the specified pin to the specified value */
|
||||
static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio)
|
||||
{
|
||||
if (gpio >= MSP_NUM_GPIOS)
|
||||
return;
|
||||
|
||||
if (gpio < 16) {
|
||||
if (data == MSP_GPIO_TOGGLE)
|
||||
toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio],
|
||||
BASIC_DATA_MASK(gpio));
|
||||
else if (data == MSP_GPIO_HI)
|
||||
set_reg32(MSP_GPIO_DATA_REGISTER[gpio],
|
||||
BASIC_DATA_MASK(gpio));
|
||||
else
|
||||
clear_reg32(MSP_GPIO_DATA_REGISTER[gpio],
|
||||
BASIC_DATA_MASK(gpio));
|
||||
} else {
|
||||
if (data == MSP_GPIO_TOGGLE) {
|
||||
/* Special ugly case:
|
||||
* We have to read the CLR bit.
|
||||
* If set, we write the CLR bit.
|
||||
* If not, we write the SET bit.
|
||||
*/
|
||||
u32 tmpdata;
|
||||
|
||||
custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio],
|
||||
tmpdata);
|
||||
if (tmpdata & EXTENDED_CLR(gpio))
|
||||
tmpdata = EXTENDED_CLR(gpio);
|
||||
else
|
||||
tmpdata = EXTENDED_SET(gpio);
|
||||
custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio],
|
||||
tmpdata);
|
||||
} else {
|
||||
u32 newdata;
|
||||
|
||||
if (data == MSP_GPIO_HI)
|
||||
newdata = EXTENDED_SET(gpio);
|
||||
else
|
||||
newdata = EXTENDED_CLR(gpio);
|
||||
set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio],
|
||||
EXTENDED_FULL_MASK, newdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sets the specified pin to the specified value */
|
||||
static inline void msp_gpio_pin_hi(unsigned int gpio)
|
||||
{
|
||||
msp_gpio_pin_set(MSP_GPIO_HI, gpio);
|
||||
}
|
||||
|
||||
/* Sets the specified pin to the specified value */
|
||||
static inline void msp_gpio_pin_lo(unsigned int gpio)
|
||||
{
|
||||
msp_gpio_pin_set(MSP_GPIO_LO, gpio);
|
||||
}
|
||||
|
||||
/* Sets the specified pin to the opposite value */
|
||||
static inline void msp_gpio_pin_toggle(unsigned int gpio)
|
||||
{
|
||||
msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio);
|
||||
}
|
||||
|
||||
/* Gets the mode of the specified pin */
|
||||
static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
|
||||
{
|
||||
enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN;
|
||||
uint32_t data;
|
||||
|
||||
if (gpio >= MSP_NUM_GPIOS)
|
||||
return retval;
|
||||
|
||||
data = *MSP_GPIO_MODE_REGISTER[gpio];
|
||||
|
||||
if (gpio < 16) {
|
||||
retval = BASIC_MODE_FROM_REG(data, gpio);
|
||||
} else {
|
||||
/* Extended pins can only be either INPUT or OUTPUT */
|
||||
if (data & EXTENDED_ENABLE(gpio))
|
||||
retval = MSP_GPIO_OUTPUT;
|
||||
else
|
||||
retval = MSP_GPIO_INPUT;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the specified mode on the requested pin
|
||||
* Returns 0 on success, or -1 if that mode is not allowed on this pin
|
||||
*/
|
||||
static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio)
|
||||
{
|
||||
u32 modemask, newmode;
|
||||
|
||||
if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode])
|
||||
return -1;
|
||||
|
||||
if (gpio >= MSP_NUM_GPIOS)
|
||||
return -1;
|
||||
|
||||
if (gpio < 16) {
|
||||
modemask = BASIC_MODE_MASK(gpio);
|
||||
newmode = BASIC_MODE(mode, gpio);
|
||||
} else {
|
||||
modemask = EXTENDED_FULL_MASK;
|
||||
if (mode == MSP_GPIO_INPUT)
|
||||
newmode = EXTENDED_DISABLE(gpio);
|
||||
else
|
||||
newmode = EXTENDED_ENABLE(gpio);
|
||||
}
|
||||
/* Do the set atomically */
|
||||
set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __MSP_GPIO_MACROS_H__ */
|
@ -91,12 +91,10 @@
|
||||
/* MAC C device registers */
|
||||
#define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000)
|
||||
/* ADSL2 device registers */
|
||||
#define MSP_USB_BASE (MSP_MSB_BASE + 0xB40000)
|
||||
/* USB device registers */
|
||||
#define MSP_USB_BASE_START (MSP_MSB_BASE + 0xB40100)
|
||||
/* USB device registers */
|
||||
#define MSP_USB_BASE_END (MSP_MSB_BASE + 0xB401FF)
|
||||
/* USB device registers */
|
||||
#define MSP_USB0_BASE (MSP_MSB_BASE + 0xB00000)
|
||||
/* USB0 device registers */
|
||||
#define MSP_USB1_BASE (MSP_MSB_BASE + 0x300000)
|
||||
/* USB1 device registers */
|
||||
#define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000)
|
||||
/* CPU interface registers */
|
||||
|
||||
@ -319,8 +317,11 @@
|
||||
#define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184)
|
||||
/* CPU/SLP Error status 1 */
|
||||
|
||||
#define EXTENDED_GPIO_REG regptr(MSP_SLP_BASE + 0x188)
|
||||
/* Extended GPIO register */
|
||||
/* Extended GPIO registers */
|
||||
#define EXTENDED_GPIO1_REG regptr(MSP_SLP_BASE + 0x188)
|
||||
#define EXTENDED_GPIO2_REG regptr(MSP_SLP_BASE + 0x18c)
|
||||
#define EXTENDED_GPIO_REG EXTENDED_GPIO1_REG
|
||||
/* Backward-compatibility */
|
||||
|
||||
/* System Error registers */
|
||||
#define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190)
|
||||
|
144
arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h
Normal file
144
arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h
Normal file
@ -0,0 +1,144 @@
|
||||
/******************************************************************
|
||||
* Copyright (c) 2000-2007 PMC-Sierra INC.
|
||||
*
|
||||
* This program is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU General
|
||||
* Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
* 02139, USA.
|
||||
*
|
||||
* PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
|
||||
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MSP_USB_H_
|
||||
#define MSP_USB_H_
|
||||
|
||||
#ifdef CONFIG_MSP_HAS_DUAL_USB
|
||||
#define NUM_USB_DEVS 2
|
||||
#else
|
||||
#define NUM_USB_DEVS 1
|
||||
#endif
|
||||
|
||||
/* Register spaces for USB host 0 */
|
||||
#define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0)
|
||||
#define MSP_USB0_MAB_END (MSP_USB0_BASE + 0x17)
|
||||
#define MSP_USB0_ID_START (MSP_USB0_BASE + 0x40000)
|
||||
#define MSP_USB0_ID_END (MSP_USB0_BASE + 0x4008f)
|
||||
#define MSP_USB0_HS_START (MSP_USB0_BASE + 0x40100)
|
||||
#define MSP_USB0_HS_END (MSP_USB0_BASE + 0x401FF)
|
||||
|
||||
/* Register spaces for USB host 1 */
|
||||
#define MSP_USB1_MAB_START (MSP_USB1_BASE + 0x0)
|
||||
#define MSP_USB1_MAB_END (MSP_USB1_BASE + 0x17)
|
||||
#define MSP_USB1_ID_START (MSP_USB1_BASE + 0x40000)
|
||||
#define MSP_USB1_ID_END (MSP_USB1_BASE + 0x4008f)
|
||||
#define MSP_USB1_HS_START (MSP_USB1_BASE + 0x40100)
|
||||
#define MSP_USB1_HS_END (MSP_USB1_BASE + 0x401ff)
|
||||
|
||||
/* USB Identification registers */
|
||||
struct msp_usbid_regs {
|
||||
u32 id; /* 0x0: Identification register */
|
||||
u32 hwgen; /* 0x4: General HW params */
|
||||
u32 hwhost; /* 0x8: Host HW params */
|
||||
u32 hwdev; /* 0xc: Device HW params */
|
||||
u32 hwtxbuf; /* 0x10: Tx buffer HW params */
|
||||
u32 hwrxbuf; /* 0x14: Rx buffer HW params */
|
||||
u32 reserved[26];
|
||||
u32 timer0_load; /* 0x80: General-purpose timer 0 load*/
|
||||
u32 timer0_ctrl; /* 0x84: General-purpose timer 0 control */
|
||||
u32 timer1_load; /* 0x88: General-purpose timer 1 load*/
|
||||
u32 timer1_ctrl; /* 0x8c: General-purpose timer 1 control */
|
||||
};
|
||||
|
||||
/* MSBus to AMBA registers */
|
||||
struct msp_mab_regs {
|
||||
u32 isr; /* 0x0: Interrupt status */
|
||||
u32 imr; /* 0x4: Interrupt mask */
|
||||
u32 thcr0; /* 0x8: Transaction header capture 0 */
|
||||
u32 thcr1; /* 0xc: Transaction header capture 1 */
|
||||
u32 int_stat; /* 0x10: Interrupt status summary */
|
||||
u32 phy_cfg; /* 0x14: USB phy config */
|
||||
};
|
||||
|
||||
/* EHCI registers */
|
||||
struct msp_usbhs_regs {
|
||||
u32 hciver; /* 0x0: Version and offset to operational regs */
|
||||
u32 hcsparams; /* 0x4: Host control structural parameters */
|
||||
u32 hccparams; /* 0x8: Host control capability parameters */
|
||||
u32 reserved0[5];
|
||||
u32 dciver; /* 0x20: Device interface version */
|
||||
u32 dccparams; /* 0x24: Device control capability parameters */
|
||||
u32 reserved1[6];
|
||||
u32 cmd; /* 0x40: USB command */
|
||||
u32 sts; /* 0x44: USB status */
|
||||
u32 int_ena; /* 0x48: USB interrupt enable */
|
||||
u32 frindex; /* 0x4c: Frame index */
|
||||
u32 reserved3;
|
||||
union {
|
||||
struct {
|
||||
u32 flb_addr; /* 0x54: Frame list base address */
|
||||
u32 next_async_addr; /* 0x58: next asynchronous addr */
|
||||
u32 ttctrl; /* 0x5c: embedded transaction translator
|
||||
async buffer status */
|
||||
u32 burst_size; /* 0x60: Controller burst size */
|
||||
u32 tx_fifo_ctrl; /* 0x64: Tx latency FIFO tuning */
|
||||
u32 reserved0[4];
|
||||
u32 endpt_nak; /* 0x78: Endpoint NAK */
|
||||
u32 endpt_nak_ena; /* 0x7c: Endpoint NAK enable */
|
||||
u32 cfg_flag; /* 0x80: Config flag */
|
||||
u32 port_sc1; /* 0x84: Port status & control 1 */
|
||||
u32 reserved1[7];
|
||||
u32 otgsc; /* 0xa4: OTG status & control */
|
||||
u32 mode; /* 0xa8: USB controller mode */
|
||||
} host;
|
||||
|
||||
struct {
|
||||
u32 dev_addr; /* 0x54: Device address */
|
||||
u32 endpt_list_addr; /* 0x58: Endpoint list address */
|
||||
u32 reserved0[7];
|
||||
u32 endpt_nak; /* 0x74 */
|
||||
u32 endpt_nak_ctrl; /* 0x78 */
|
||||
u32 cfg_flag; /* 0x80 */
|
||||
u32 port_sc1; /* 0x84: Port status & control 1 */
|
||||
u32 reserved[7];
|
||||
u32 otgsc; /* 0xa4: OTG status & control */
|
||||
u32 mode; /* 0xa8: USB controller mode */
|
||||
u32 endpt_setup_stat; /* 0xac */
|
||||
u32 endpt_prime; /* 0xb0 */
|
||||
u32 endpt_flush; /* 0xb4 */
|
||||
u32 endpt_stat; /* 0xb8 */
|
||||
u32 endpt_complete; /* 0xbc */
|
||||
u32 endpt_ctrl0; /* 0xc0 */
|
||||
u32 endpt_ctrl1; /* 0xc4 */
|
||||
u32 endpt_ctrl2; /* 0xc8 */
|
||||
u32 endpt_ctrl3; /* 0xcc */
|
||||
} device;
|
||||
} u;
|
||||
};
|
||||
/*
|
||||
* Container for the more-generic platform_device.
|
||||
* This exists mainly as a way to map the non-standard register
|
||||
* spaces and make them accessible to the USB ISR.
|
||||
*/
|
||||
struct mspusb_device {
|
||||
struct msp_mab_regs __iomem *mab_regs;
|
||||
struct msp_usbid_regs __iomem *usbid_regs;
|
||||
struct msp_usbhs_regs __iomem *usbhs_regs;
|
||||
struct platform_device dev;
|
||||
};
|
||||
|
||||
#define to_mspusb_device(x) container_of((x), struct mspusb_device, dev)
|
||||
#define TO_HOST_ID(x) ((x) & 0x3)
|
||||
#endif /*MSP_USB_H_*/
|
@ -245,16 +245,16 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
|
||||
__asm__ __volatile__(
|
||||
" .set noreorder # arch_read_lock \n"
|
||||
"1: ll %1, %2 \n"
|
||||
" bltz %1, 2f \n"
|
||||
" bltz %1, 3f \n"
|
||||
" addu %1, 1 \n"
|
||||
" sc %1, %0 \n"
|
||||
"2: sc %1, %0 \n"
|
||||
" beqz %1, 1b \n"
|
||||
" nop \n"
|
||||
" .subsection 2 \n"
|
||||
"2: ll %1, %2 \n"
|
||||
" bltz %1, 2b \n"
|
||||
"3: ll %1, %2 \n"
|
||||
" bltz %1, 3b \n"
|
||||
" addu %1, 1 \n"
|
||||
" b 1b \n"
|
||||
" b 2b \n"
|
||||
" nop \n"
|
||||
" .previous \n"
|
||||
" .set reorder \n"
|
||||
@ -324,16 +324,16 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
|
||||
__asm__ __volatile__(
|
||||
" .set noreorder # arch_write_lock \n"
|
||||
"1: ll %1, %2 \n"
|
||||
" bnez %1, 2f \n"
|
||||
" bnez %1, 3f \n"
|
||||
" lui %1, 0x8000 \n"
|
||||
" sc %1, %0 \n"
|
||||
" beqz %1, 2f \n"
|
||||
"2: sc %1, %0 \n"
|
||||
" beqz %1, 3f \n"
|
||||
" nop \n"
|
||||
" .subsection 2 \n"
|
||||
"2: ll %1, %2 \n"
|
||||
" bnez %1, 2b \n"
|
||||
"3: ll %1, %2 \n"
|
||||
" bnez %1, 3b \n"
|
||||
" lui %1, 0x8000 \n"
|
||||
" b 1b \n"
|
||||
" b 2b \n"
|
||||
" nop \n"
|
||||
" .previous \n"
|
||||
" .set reorder \n"
|
||||
|
@ -359,16 +359,20 @@
|
||||
#define __NR_fanotify_init (__NR_Linux + 336)
|
||||
#define __NR_fanotify_mark (__NR_Linux + 337)
|
||||
#define __NR_prlimit64 (__NR_Linux + 338)
|
||||
#define __NR_name_to_handle_at (__NR_Linux + 339)
|
||||
#define __NR_open_by_handle_at (__NR_Linux + 340)
|
||||
#define __NR_clock_adjtime (__NR_Linux + 341)
|
||||
#define __NR_syncfs (__NR_Linux + 342)
|
||||
|
||||
/*
|
||||
* Offset of the last Linux o32 flavoured syscall
|
||||
*/
|
||||
#define __NR_Linux_syscalls 338
|
||||
#define __NR_Linux_syscalls 342
|
||||
|
||||
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
|
||||
|
||||
#define __NR_O32_Linux 4000
|
||||
#define __NR_O32_Linux_syscalls 338
|
||||
#define __NR_O32_Linux_syscalls 342
|
||||
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
|
||||
@ -674,16 +678,20 @@
|
||||
#define __NR_fanotify_init (__NR_Linux + 295)
|
||||
#define __NR_fanotify_mark (__NR_Linux + 296)
|
||||
#define __NR_prlimit64 (__NR_Linux + 297)
|
||||
#define __NR_name_to_handle_at (__NR_Linux + 298)
|
||||
#define __NR_open_by_handle_at (__NR_Linux + 299)
|
||||
#define __NR_clock_adjtime (__NR_Linux + 300)
|
||||
#define __NR_syncfs (__NR_Linux + 301)
|
||||
|
||||
/*
|
||||
* Offset of the last Linux 64-bit flavoured syscall
|
||||
*/
|
||||
#define __NR_Linux_syscalls 297
|
||||
#define __NR_Linux_syscalls 301
|
||||
|
||||
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
|
||||
|
||||
#define __NR_64_Linux 5000
|
||||
#define __NR_64_Linux_syscalls 297
|
||||
#define __NR_64_Linux_syscalls 301
|
||||
|
||||
#if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
|
||||
@ -994,16 +1002,20 @@
|
||||
#define __NR_fanotify_init (__NR_Linux + 300)
|
||||
#define __NR_fanotify_mark (__NR_Linux + 301)
|
||||
#define __NR_prlimit64 (__NR_Linux + 302)
|
||||
#define __NR_name_to_handle_at (__NR_Linux + 303)
|
||||
#define __NR_open_by_handle_at (__NR_Linux + 304)
|
||||
#define __NR_clock_adjtime (__NR_Linux + 305)
|
||||
#define __NR_clock_adjtime (__NR_Linux + 306)
|
||||
|
||||
/*
|
||||
* Offset of the last N32 flavoured syscall
|
||||
*/
|
||||
#define __NR_Linux_syscalls 302
|
||||
#define __NR_Linux_syscalls 306
|
||||
|
||||
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
|
||||
|
||||
#define __NR_N32_Linux 6000
|
||||
#define __NR_N32_Linux_syscalls 302
|
||||
#define __NR_N32_Linux_syscalls 306
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(r4030_lock);
|
||||
|
||||
static void enable_r4030_irq(unsigned int irq)
|
||||
static void enable_r4030_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - JAZZ_IRQ_START);
|
||||
unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&r4030_lock, flags);
|
||||
@ -34,9 +34,9 @@ static void enable_r4030_irq(unsigned int irq)
|
||||
raw_spin_unlock_irqrestore(&r4030_lock, flags);
|
||||
}
|
||||
|
||||
void disable_r4030_irq(unsigned int irq)
|
||||
void disable_r4030_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START));
|
||||
unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START));
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&r4030_lock, flags);
|
||||
@ -47,10 +47,8 @@ void disable_r4030_irq(unsigned int irq)
|
||||
|
||||
static struct irq_chip r4030_irq_type = {
|
||||
.name = "R4030",
|
||||
.ack = disable_r4030_irq,
|
||||
.mask = disable_r4030_irq,
|
||||
.mask_ack = disable_r4030_irq,
|
||||
.unmask = enable_r4030_irq,
|
||||
.irq_mask = disable_r4030_irq,
|
||||
.irq_unmask = enable_r4030_irq,
|
||||
};
|
||||
|
||||
void __init init_r4030_ints(void)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/spi/spi_gpio.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/power/jz4740-battery.h>
|
||||
#include <linux/power/gpio-charger.h>
|
||||
|
||||
#include <asm/mach-jz4740/jz4740_fb.h>
|
||||
#include <asm/mach-jz4740/jz4740_mmc.h>
|
||||
@ -49,14 +50,14 @@ static bool is_avt2;
|
||||
|
||||
/* NAND */
|
||||
static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
|
||||
/* .eccbytes = 36,
|
||||
.eccbytes = 36,
|
||||
.eccpos = {
|
||||
6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21,
|
||||
22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37,
|
||||
38, 39, 40, 41
|
||||
},*/
|
||||
},
|
||||
.oobfree = {
|
||||
{ .offset = 2, .length = 4 },
|
||||
{ .offset = 42, .length = 22 }
|
||||
@ -85,7 +86,7 @@ static struct mtd_partition qi_lb60_partitions_1gb[] = {
|
||||
};
|
||||
|
||||
static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
|
||||
/* .eccbytes = 72,
|
||||
.eccbytes = 72,
|
||||
.eccpos = {
|
||||
12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27,
|
||||
@ -96,7 +97,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
|
||||
60, 61, 62, 63, 64, 65, 66, 67,
|
||||
68, 69, 70, 71, 72, 73, 74, 75,
|
||||
76, 77, 78, 79, 80, 81, 82, 83
|
||||
},*/
|
||||
},
|
||||
.oobfree = {
|
||||
{ .offset = 2, .length = 10 },
|
||||
{ .offset = 84, .length = 44 },
|
||||
@ -396,6 +397,28 @@ static struct platform_device qi_lb60_pwm_beeper = {
|
||||
},
|
||||
};
|
||||
|
||||
/* charger */
|
||||
static char *qi_lb60_batteries[] = {
|
||||
"battery",
|
||||
};
|
||||
|
||||
static struct gpio_charger_platform_data qi_lb60_charger_pdata = {
|
||||
.name = "usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.gpio = JZ_GPIO_PORTD(28),
|
||||
.gpio_active_low = 1,
|
||||
.supplied_to = qi_lb60_batteries,
|
||||
.num_supplicants = ARRAY_SIZE(qi_lb60_batteries),
|
||||
};
|
||||
|
||||
static struct platform_device qi_lb60_charger_device = {
|
||||
.name = "gpio-charger",
|
||||
.dev = {
|
||||
.platform_data = &qi_lb60_charger_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device *jz_platform_devices[] __initdata = {
|
||||
&jz4740_udc_device,
|
||||
&jz4740_mmc_device,
|
||||
@ -410,6 +433,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
|
||||
&jz4740_adc_device,
|
||||
&qi_lb60_gpio_keys,
|
||||
&qi_lb60_pwm_beeper,
|
||||
&qi_lb60_charger_device,
|
||||
};
|
||||
|
||||
static void __init board_gpio_setup(void)
|
||||
|
@ -86,7 +86,6 @@ struct jz_gpio_chip {
|
||||
spinlock_t lock;
|
||||
|
||||
struct gpio_chip gpio_chip;
|
||||
struct irq_chip irq_chip;
|
||||
struct sys_device sysdev;
|
||||
};
|
||||
|
||||
@ -102,9 +101,9 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g
|
||||
return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
|
||||
}
|
||||
|
||||
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq)
|
||||
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
|
||||
{
|
||||
return get_irq_chip_data(irq);
|
||||
return irq_data_get_irq_chip_data(data);
|
||||
}
|
||||
|
||||
static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
|
||||
@ -325,62 +324,52 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
|
||||
generic_handle_irq(gpio_irq);
|
||||
};
|
||||
|
||||
static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
|
||||
static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
|
||||
{
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
|
||||
writel(IRQ_TO_BIT(irq), chip->base + reg);
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
|
||||
writel(IRQ_TO_BIT(data->irq), chip->base + reg);
|
||||
}
|
||||
|
||||
static void jz_gpio_irq_mask(unsigned int irq)
|
||||
static void jz_gpio_irq_mask(struct irq_data *data)
|
||||
{
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET);
|
||||
};
|
||||
|
||||
static void jz_gpio_irq_unmask(unsigned int irq)
|
||||
static void jz_gpio_irq_unmask(struct irq_data *data)
|
||||
{
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
|
||||
|
||||
jz_gpio_check_trigger_both(chip, irq);
|
||||
jz_gpio_check_trigger_both(chip, data->irq);
|
||||
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR);
|
||||
};
|
||||
|
||||
/* TODO: Check if function is gpio */
|
||||
static unsigned int jz_gpio_irq_startup(unsigned int irq)
|
||||
static unsigned int jz_gpio_irq_startup(struct irq_data *data)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
|
||||
|
||||
desc->status &= ~IRQ_MASKED;
|
||||
jz_gpio_irq_unmask(irq);
|
||||
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
|
||||
jz_gpio_irq_unmask(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jz_gpio_irq_shutdown(unsigned int irq)
|
||||
static void jz_gpio_irq_shutdown(struct irq_data *data)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
|
||||
jz_gpio_irq_mask(irq);
|
||||
desc->status |= IRQ_MASKED;
|
||||
jz_gpio_irq_mask(data);
|
||||
|
||||
/* Set direction to input */
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
|
||||
}
|
||||
|
||||
static void jz_gpio_irq_ack(unsigned int irq)
|
||||
static void jz_gpio_irq_ack(struct irq_data *data)
|
||||
{
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR);
|
||||
};
|
||||
|
||||
static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||
static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
|
||||
{
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
|
||||
jz_gpio_irq_mask(irq);
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
|
||||
unsigned int irq = data->irq;
|
||||
|
||||
if (flow_type == IRQ_TYPE_EDGE_BOTH) {
|
||||
uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
|
||||
@ -395,45 +384,54 @@ static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||
|
||||
switch (flow_type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
|
||||
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
|
||||
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(desc->status & IRQ_MASKED))
|
||||
jz_gpio_irq_unmask(irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on)
|
||||
static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
|
||||
{
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
|
||||
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
|
||||
spin_lock(&chip->lock);
|
||||
if (on)
|
||||
chip->wakeup |= IRQ_TO_BIT(irq);
|
||||
chip->wakeup |= IRQ_TO_BIT(data->irq);
|
||||
else
|
||||
chip->wakeup &= ~IRQ_TO_BIT(irq);
|
||||
chip->wakeup &= ~IRQ_TO_BIT(data->irq);
|
||||
spin_unlock(&chip->lock);
|
||||
|
||||
set_irq_wake(chip->irq, on);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip jz_gpio_irq_chip = {
|
||||
.name = "GPIO",
|
||||
.irq_mask = jz_gpio_irq_mask,
|
||||
.irq_unmask = jz_gpio_irq_unmask,
|
||||
.irq_ack = jz_gpio_irq_ack,
|
||||
.irq_startup = jz_gpio_irq_startup,
|
||||
.irq_shutdown = jz_gpio_irq_shutdown,
|
||||
.irq_set_type = jz_gpio_irq_set_type,
|
||||
.irq_set_wake = jz_gpio_irq_set_wake,
|
||||
.flags = IRQCHIP_SET_TYPE_MASKED,
|
||||
};
|
||||
|
||||
/*
|
||||
* This lock class tells lockdep that GPIO irqs are in a different
|
||||
* category than their parents, so it won't report false recursion.
|
||||
@ -452,16 +450,6 @@ static struct lock_class_key gpio_lock_class;
|
||||
.base = JZ4740_GPIO_BASE_ ## _bank, \
|
||||
.ngpio = JZ4740_GPIO_NUM_ ## _bank, \
|
||||
}, \
|
||||
.irq_chip = { \
|
||||
.name = "GPIO Bank " # _bank, \
|
||||
.mask = jz_gpio_irq_mask, \
|
||||
.unmask = jz_gpio_irq_unmask, \
|
||||
.ack = jz_gpio_irq_ack, \
|
||||
.startup = jz_gpio_irq_startup, \
|
||||
.shutdown = jz_gpio_irq_shutdown, \
|
||||
.set_type = jz_gpio_irq_set_type, \
|
||||
.set_wake = jz_gpio_irq_set_wake, \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct jz_gpio_chip jz4740_gpio_chips[] = {
|
||||
@ -526,9 +514,10 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
|
||||
set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
|
||||
|
||||
for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
|
||||
lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class);
|
||||
irq_set_lockdep_class(irq, &gpio_lock_class);
|
||||
set_irq_chip_data(irq, chip);
|
||||
set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq);
|
||||
set_irq_chip_and_handler(irq, &jz_gpio_irq_chip,
|
||||
handle_level_irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -43,32 +43,37 @@ static uint32_t jz_intc_saved;
|
||||
|
||||
#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
|
||||
|
||||
static void intc_irq_unmask(unsigned int irq)
|
||||
static inline unsigned long intc_irq_bit(struct irq_data *data)
|
||||
{
|
||||
writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
|
||||
return (unsigned long)irq_data_get_irq_chip_data(data);
|
||||
}
|
||||
|
||||
static void intc_irq_mask(unsigned int irq)
|
||||
static void intc_irq_unmask(struct irq_data *data)
|
||||
{
|
||||
writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK);
|
||||
writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
|
||||
}
|
||||
|
||||
static int intc_irq_set_wake(unsigned int irq, unsigned int on)
|
||||
static void intc_irq_mask(struct irq_data *data)
|
||||
{
|
||||
writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK);
|
||||
}
|
||||
|
||||
static int intc_irq_set_wake(struct irq_data *data, unsigned int on)
|
||||
{
|
||||
if (on)
|
||||
jz_intc_wakeup |= IRQ_BIT(irq);
|
||||
jz_intc_wakeup |= intc_irq_bit(data);
|
||||
else
|
||||
jz_intc_wakeup &= ~IRQ_BIT(irq);
|
||||
jz_intc_wakeup &= ~intc_irq_bit(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip intc_irq_type = {
|
||||
.name = "INTC",
|
||||
.mask = intc_irq_mask,
|
||||
.mask_ack = intc_irq_mask,
|
||||
.unmask = intc_irq_unmask,
|
||||
.set_wake = intc_irq_set_wake,
|
||||
.irq_mask = intc_irq_mask,
|
||||
.irq_mask_ack = intc_irq_mask,
|
||||
.irq_unmask = intc_irq_unmask,
|
||||
.irq_set_wake = intc_irq_set_wake,
|
||||
};
|
||||
|
||||
static irqreturn_t jz4740_cascade(int irq, void *data)
|
||||
@ -95,8 +100,11 @@ void __init arch_init_irq(void)
|
||||
|
||||
jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
|
||||
|
||||
/* Mask all irqs */
|
||||
writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
|
||||
|
||||
for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
|
||||
intc_irq_mask(i);
|
||||
set_irq_chip_data(i, (void *)IRQ_BIT(i));
|
||||
set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
|
||||
}
|
||||
|
||||
|
@ -31,19 +31,19 @@
|
||||
|
||||
static int i8259A_auto_eoi = -1;
|
||||
DEFINE_RAW_SPINLOCK(i8259A_lock);
|
||||
static void disable_8259A_irq(unsigned int irq);
|
||||
static void enable_8259A_irq(unsigned int irq);
|
||||
static void mask_and_ack_8259A(unsigned int irq);
|
||||
static void disable_8259A_irq(struct irq_data *d);
|
||||
static void enable_8259A_irq(struct irq_data *d);
|
||||
static void mask_and_ack_8259A(struct irq_data *d);
|
||||
static void init_8259A(int auto_eoi);
|
||||
|
||||
static struct irq_chip i8259A_chip = {
|
||||
.name = "XT-PIC",
|
||||
.mask = disable_8259A_irq,
|
||||
.disable = disable_8259A_irq,
|
||||
.unmask = enable_8259A_irq,
|
||||
.mask_ack = mask_and_ack_8259A,
|
||||
.name = "XT-PIC",
|
||||
.irq_mask = disable_8259A_irq,
|
||||
.irq_disable = disable_8259A_irq,
|
||||
.irq_unmask = enable_8259A_irq,
|
||||
.irq_mask_ack = mask_and_ack_8259A,
|
||||
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
|
||||
.set_affinity = plat_set_irq_affinity,
|
||||
.irq_set_affinity = plat_set_irq_affinity,
|
||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||
};
|
||||
|
||||
@ -59,12 +59,11 @@ static unsigned int cached_irq_mask = 0xffff;
|
||||
#define cached_master_mask (cached_irq_mask)
|
||||
#define cached_slave_mask (cached_irq_mask >> 8)
|
||||
|
||||
static void disable_8259A_irq(unsigned int irq)
|
||||
static void disable_8259A_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
|
||||
irq -= I8259A_IRQ_BASE;
|
||||
mask = 1 << irq;
|
||||
raw_spin_lock_irqsave(&i8259A_lock, flags);
|
||||
cached_irq_mask |= mask;
|
||||
@ -75,12 +74,11 @@ static void disable_8259A_irq(unsigned int irq)
|
||||
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
|
||||
}
|
||||
|
||||
static void enable_8259A_irq(unsigned int irq)
|
||||
static void enable_8259A_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
|
||||
irq -= I8259A_IRQ_BASE;
|
||||
mask = ~(1 << irq);
|
||||
raw_spin_lock_irqsave(&i8259A_lock, flags);
|
||||
cached_irq_mask &= mask;
|
||||
@ -145,12 +143,11 @@ static inline int i8259A_irq_real(unsigned int irq)
|
||||
* first, _then_ send the EOI, and the order of EOI
|
||||
* to the two 8259s is important!
|
||||
*/
|
||||
static void mask_and_ack_8259A(unsigned int irq)
|
||||
static void mask_and_ack_8259A(struct irq_data *d)
|
||||
{
|
||||
unsigned int irqmask;
|
||||
unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
|
||||
irq -= I8259A_IRQ_BASE;
|
||||
irqmask = 1 << irq;
|
||||
raw_spin_lock_irqsave(&i8259A_lock, flags);
|
||||
/*
|
||||
@ -290,9 +287,9 @@ static void init_8259A(int auto_eoi)
|
||||
* In AEOI mode we just have to mask the interrupt
|
||||
* when acking.
|
||||
*/
|
||||
i8259A_chip.mask_ack = disable_8259A_irq;
|
||||
i8259A_chip.irq_mask_ack = disable_8259A_irq;
|
||||
else
|
||||
i8259A_chip.mask_ack = mask_and_ack_8259A;
|
||||
i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
|
||||
|
||||
udelay(100); /* wait for 8259A to initialize */
|
||||
|
||||
|
@ -87,17 +87,10 @@ unsigned int gic_get_int(void)
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned int gic_irq_startup(unsigned int irq)
|
||||
static void gic_irq_ack(struct irq_data *d)
|
||||
{
|
||||
irq -= _irqbase;
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_SET_INTR_MASK(irq);
|
||||
return 0;
|
||||
}
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
|
||||
static void gic_irq_ack(unsigned int irq)
|
||||
{
|
||||
irq -= _irqbase;
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_CLR_INTR_MASK(irq);
|
||||
|
||||
@ -105,16 +98,16 @@ static void gic_irq_ack(unsigned int irq)
|
||||
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
|
||||
}
|
||||
|
||||
static void gic_mask_irq(unsigned int irq)
|
||||
static void gic_mask_irq(struct irq_data *d)
|
||||
{
|
||||
irq -= _irqbase;
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_CLR_INTR_MASK(irq);
|
||||
}
|
||||
|
||||
static void gic_unmask_irq(unsigned int irq)
|
||||
static void gic_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
irq -= _irqbase;
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_SET_INTR_MASK(irq);
|
||||
}
|
||||
@ -123,13 +116,14 @@ static void gic_unmask_irq(unsigned int irq)
|
||||
|
||||
static DEFINE_SPINLOCK(gic_lock);
|
||||
|
||||
static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
|
||||
bool force)
|
||||
{
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
cpumask_t tmp = CPU_MASK_NONE;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
irq -= _irqbase;
|
||||
pr_debug("%s(%d) called\n", __func__, irq);
|
||||
cpumask_and(&tmp, cpumask, cpu_online_mask);
|
||||
if (cpus_empty(tmp))
|
||||
@ -147,23 +141,22 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
|
||||
|
||||
}
|
||||
cpumask_copy(irq_desc[irq].affinity, cpumask);
|
||||
cpumask_copy(d->affinity, cpumask);
|
||||
spin_unlock_irqrestore(&gic_lock, flags);
|
||||
|
||||
return 0;
|
||||
return IRQ_SET_MASK_OK_NOCOPY;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct irq_chip gic_irq_controller = {
|
||||
.name = "MIPS GIC",
|
||||
.startup = gic_irq_startup,
|
||||
.ack = gic_irq_ack,
|
||||
.mask = gic_mask_irq,
|
||||
.mask_ack = gic_mask_irq,
|
||||
.unmask = gic_unmask_irq,
|
||||
.eoi = gic_unmask_irq,
|
||||
.name = "MIPS GIC",
|
||||
.irq_ack = gic_irq_ack,
|
||||
.irq_mask = gic_mask_irq,
|
||||
.irq_mask_ack = gic_mask_irq,
|
||||
.irq_unmask = gic_unmask_irq,
|
||||
.irq_eoi = gic_unmask_irq,
|
||||
#ifdef CONFIG_SMP
|
||||
.set_affinity = gic_set_affinity,
|
||||
.irq_set_affinity = gic_set_affinity,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -29,64 +29,64 @@
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
|
||||
|
||||
static void ack_gt641xx_irq(unsigned int irq)
|
||||
static void ack_gt641xx_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 cause;
|
||||
|
||||
raw_spin_lock_irqsave(>641xx_irq_lock, flags);
|
||||
cause = GT_READ(GT_INTRCAUSE_OFS);
|
||||
cause &= ~GT641XX_IRQ_TO_BIT(irq);
|
||||
cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
|
||||
GT_WRITE(GT_INTRCAUSE_OFS, cause);
|
||||
raw_spin_unlock_irqrestore(>641xx_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void mask_gt641xx_irq(unsigned int irq)
|
||||
static void mask_gt641xx_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 mask;
|
||||
|
||||
raw_spin_lock_irqsave(>641xx_irq_lock, flags);
|
||||
mask = GT_READ(GT_INTRMASK_OFS);
|
||||
mask &= ~GT641XX_IRQ_TO_BIT(irq);
|
||||
mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
|
||||
GT_WRITE(GT_INTRMASK_OFS, mask);
|
||||
raw_spin_unlock_irqrestore(>641xx_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void mask_ack_gt641xx_irq(unsigned int irq)
|
||||
static void mask_ack_gt641xx_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 cause, mask;
|
||||
|
||||
raw_spin_lock_irqsave(>641xx_irq_lock, flags);
|
||||
mask = GT_READ(GT_INTRMASK_OFS);
|
||||
mask &= ~GT641XX_IRQ_TO_BIT(irq);
|
||||
mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
|
||||
GT_WRITE(GT_INTRMASK_OFS, mask);
|
||||
|
||||
cause = GT_READ(GT_INTRCAUSE_OFS);
|
||||
cause &= ~GT641XX_IRQ_TO_BIT(irq);
|
||||
cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
|
||||
GT_WRITE(GT_INTRCAUSE_OFS, cause);
|
||||
raw_spin_unlock_irqrestore(>641xx_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void unmask_gt641xx_irq(unsigned int irq)
|
||||
static void unmask_gt641xx_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 mask;
|
||||
|
||||
raw_spin_lock_irqsave(>641xx_irq_lock, flags);
|
||||
mask = GT_READ(GT_INTRMASK_OFS);
|
||||
mask |= GT641XX_IRQ_TO_BIT(irq);
|
||||
mask |= GT641XX_IRQ_TO_BIT(d->irq);
|
||||
GT_WRITE(GT_INTRMASK_OFS, mask);
|
||||
raw_spin_unlock_irqrestore(>641xx_irq_lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip gt641xx_irq_chip = {
|
||||
.name = "GT641xx",
|
||||
.ack = ack_gt641xx_irq,
|
||||
.mask = mask_gt641xx_irq,
|
||||
.mask_ack = mask_ack_gt641xx_irq,
|
||||
.unmask = unmask_gt641xx_irq,
|
||||
.irq_ack = ack_gt641xx_irq,
|
||||
.irq_mask = mask_gt641xx_irq,
|
||||
.irq_mask_ack = mask_ack_gt641xx_irq,
|
||||
.irq_unmask = unmask_gt641xx_irq,
|
||||
};
|
||||
|
||||
void gt641xx_irq_dispatch(void)
|
||||
|
@ -28,8 +28,10 @@ static unsigned long _icctrl_msc;
|
||||
static unsigned int irq_base;
|
||||
|
||||
/* mask off an interrupt */
|
||||
static inline void mask_msc_irq(unsigned int irq)
|
||||
static inline void mask_msc_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
if (irq < (irq_base + 32))
|
||||
MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base));
|
||||
else
|
||||
@ -37,8 +39,10 @@ static inline void mask_msc_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
/* unmask an interrupt */
|
||||
static inline void unmask_msc_irq(unsigned int irq)
|
||||
static inline void unmask_msc_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
if (irq < (irq_base + 32))
|
||||
MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base));
|
||||
else
|
||||
@ -48,9 +52,11 @@ static inline void unmask_msc_irq(unsigned int irq)
|
||||
/*
|
||||
* Masks and ACKs an IRQ
|
||||
*/
|
||||
static void level_mask_and_ack_msc_irq(unsigned int irq)
|
||||
static void level_mask_and_ack_msc_irq(struct irq_data *d)
|
||||
{
|
||||
mask_msc_irq(irq);
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
mask_msc_irq(d);
|
||||
if (!cpu_has_veic)
|
||||
MSCIC_WRITE(MSC01_IC_EOI, 0);
|
||||
/* This actually needs to be a call into platform code */
|
||||
@ -60,9 +66,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
|
||||
/*
|
||||
* Masks and ACKs an IRQ
|
||||
*/
|
||||
static void edge_mask_and_ack_msc_irq(unsigned int irq)
|
||||
static void edge_mask_and_ack_msc_irq(struct irq_data *d)
|
||||
{
|
||||
mask_msc_irq(irq);
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
mask_msc_irq(d);
|
||||
if (!cpu_has_veic)
|
||||
MSCIC_WRITE(MSC01_IC_EOI, 0);
|
||||
else {
|
||||
@ -74,15 +82,6 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq)
|
||||
smtc_im_ack_irq(irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* End IRQ processing
|
||||
*/
|
||||
static void end_msc_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
unmask_msc_irq(irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler for interrupts coming from SOC-it.
|
||||
*/
|
||||
@ -107,22 +106,20 @@ static void msc_bind_eic_interrupt(int irq, int set)
|
||||
|
||||
static struct irq_chip msc_levelirq_type = {
|
||||
.name = "SOC-it-Level",
|
||||
.ack = level_mask_and_ack_msc_irq,
|
||||
.mask = mask_msc_irq,
|
||||
.mask_ack = level_mask_and_ack_msc_irq,
|
||||
.unmask = unmask_msc_irq,
|
||||
.eoi = unmask_msc_irq,
|
||||
.end = end_msc_irq,
|
||||
.irq_ack = level_mask_and_ack_msc_irq,
|
||||
.irq_mask = mask_msc_irq,
|
||||
.irq_mask_ack = level_mask_and_ack_msc_irq,
|
||||
.irq_unmask = unmask_msc_irq,
|
||||
.irq_eoi = unmask_msc_irq,
|
||||
};
|
||||
|
||||
static struct irq_chip msc_edgeirq_type = {
|
||||
.name = "SOC-it-Edge",
|
||||
.ack = edge_mask_and_ack_msc_irq,
|
||||
.mask = mask_msc_irq,
|
||||
.mask_ack = edge_mask_and_ack_msc_irq,
|
||||
.unmask = unmask_msc_irq,
|
||||
.eoi = unmask_msc_irq,
|
||||
.end = end_msc_irq,
|
||||
.irq_ack = edge_mask_and_ack_msc_irq,
|
||||
.irq_mask = mask_msc_irq,
|
||||
.irq_mask_ack = edge_mask_and_ack_msc_irq,
|
||||
.irq_unmask = unmask_msc_irq,
|
||||
.irq_eoi = unmask_msc_irq,
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,23 +18,23 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static inline void unmask_rm7k_irq(unsigned int irq)
|
||||
static inline void unmask_rm7k_irq(struct irq_data *d)
|
||||
{
|
||||
set_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
|
||||
set_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE));
|
||||
}
|
||||
|
||||
static inline void mask_rm7k_irq(unsigned int irq)
|
||||
static inline void mask_rm7k_irq(struct irq_data *d)
|
||||
{
|
||||
clear_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
|
||||
clear_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE));
|
||||
}
|
||||
|
||||
static struct irq_chip rm7k_irq_controller = {
|
||||
.name = "RM7000",
|
||||
.ack = mask_rm7k_irq,
|
||||
.mask = mask_rm7k_irq,
|
||||
.mask_ack = mask_rm7k_irq,
|
||||
.unmask = unmask_rm7k_irq,
|
||||
.eoi = unmask_rm7k_irq
|
||||
.irq_ack = mask_rm7k_irq,
|
||||
.irq_mask = mask_rm7k_irq,
|
||||
.irq_mask_ack = mask_rm7k_irq,
|
||||
.irq_unmask = unmask_rm7k_irq,
|
||||
.irq_eoi = unmask_rm7k_irq
|
||||
};
|
||||
|
||||
void __init rm7k_cpu_irq_init(void)
|
||||
|
@ -19,22 +19,22 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static inline void unmask_rm9k_irq(unsigned int irq)
|
||||
static inline void unmask_rm9k_irq(struct irq_data *d)
|
||||
{
|
||||
set_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
|
||||
set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
|
||||
}
|
||||
|
||||
static inline void mask_rm9k_irq(unsigned int irq)
|
||||
static inline void mask_rm9k_irq(struct irq_data *d)
|
||||
{
|
||||
clear_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
|
||||
clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
|
||||
}
|
||||
|
||||
static inline void rm9k_cpu_irq_enable(unsigned int irq)
|
||||
static inline void rm9k_cpu_irq_enable(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
unmask_rm9k_irq(irq);
|
||||
unmask_rm9k_irq(d);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
@ -43,50 +43,47 @@ static inline void rm9k_cpu_irq_enable(unsigned int irq)
|
||||
*/
|
||||
static void local_rm9k_perfcounter_irq_startup(void *args)
|
||||
{
|
||||
unsigned int irq = (unsigned int) args;
|
||||
|
||||
rm9k_cpu_irq_enable(irq);
|
||||
rm9k_cpu_irq_enable(args);
|
||||
}
|
||||
|
||||
static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
|
||||
static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d)
|
||||
{
|
||||
on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 1);
|
||||
on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void local_rm9k_perfcounter_irq_shutdown(void *args)
|
||||
{
|
||||
unsigned int irq = (unsigned int) args;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
mask_rm9k_irq(irq);
|
||||
mask_rm9k_irq(args);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
|
||||
static void rm9k_perfcounter_irq_shutdown(struct irq_data *d)
|
||||
{
|
||||
on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 1);
|
||||
on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1);
|
||||
}
|
||||
|
||||
static struct irq_chip rm9k_irq_controller = {
|
||||
.name = "RM9000",
|
||||
.ack = mask_rm9k_irq,
|
||||
.mask = mask_rm9k_irq,
|
||||
.mask_ack = mask_rm9k_irq,
|
||||
.unmask = unmask_rm9k_irq,
|
||||
.eoi = unmask_rm9k_irq
|
||||
.irq_ack = mask_rm9k_irq,
|
||||
.irq_mask = mask_rm9k_irq,
|
||||
.irq_mask_ack = mask_rm9k_irq,
|
||||
.irq_unmask = unmask_rm9k_irq,
|
||||
.irq_eoi = unmask_rm9k_irq
|
||||
};
|
||||
|
||||
static struct irq_chip rm9k_perfcounter_irq = {
|
||||
.name = "RM9000",
|
||||
.startup = rm9k_perfcounter_irq_startup,
|
||||
.shutdown = rm9k_perfcounter_irq_shutdown,
|
||||
.ack = mask_rm9k_irq,
|
||||
.mask = mask_rm9k_irq,
|
||||
.mask_ack = mask_rm9k_irq,
|
||||
.unmask = unmask_rm9k_irq,
|
||||
.irq_startup = rm9k_perfcounter_irq_startup,
|
||||
.irq_shutdown = rm9k_perfcounter_irq_shutdown,
|
||||
.irq_ack = mask_rm9k_irq,
|
||||
.irq_mask = mask_rm9k_irq,
|
||||
.irq_mask_ack = mask_rm9k_irq,
|
||||
.irq_unmask = unmask_rm9k_irq,
|
||||
};
|
||||
|
||||
unsigned int rm9000_perfcount_irq;
|
||||
|
@ -81,48 +81,9 @@ void ack_bad_irq(unsigned int irq)
|
||||
|
||||
atomic_t irq_err_count;
|
||||
|
||||
/*
|
||||
* Generic, controller-independent functions:
|
||||
*/
|
||||
|
||||
int show_interrupts(struct seq_file *p, void *v)
|
||||
int arch_show_interrupts(struct seq_file *p, int prec)
|
||||
{
|
||||
int i = *(loff_t *) v, j;
|
||||
struct irqaction * action;
|
||||
unsigned long flags;
|
||||
|
||||
if (i == 0) {
|
||||
seq_printf(p, " ");
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "CPU%d ", j);
|
||||
seq_putc(p, '\n');
|
||||
}
|
||||
|
||||
if (i < NR_IRQS) {
|
||||
raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
|
||||
action = irq_desc[i].action;
|
||||
if (!action)
|
||||
goto skip;
|
||||
seq_printf(p, "%3d: ", i);
|
||||
#ifndef CONFIG_SMP
|
||||
seq_printf(p, "%10u ", kstat_irqs(i));
|
||||
#else
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
|
||||
#endif
|
||||
seq_printf(p, " %14s", irq_desc[i].chip->name);
|
||||
seq_printf(p, " %s", action->name);
|
||||
|
||||
for (action=action->next; action; action = action->next)
|
||||
seq_printf(p, ", %s", action->name);
|
||||
|
||||
seq_putc(p, '\n');
|
||||
skip:
|
||||
raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
|
||||
} else if (i == NR_IRQS) {
|
||||
seq_putc(p, '\n');
|
||||
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
|
||||
}
|
||||
seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -183,8 +144,8 @@ void __irq_entry do_IRQ(unsigned int irq)
|
||||
{
|
||||
irq_enter();
|
||||
check_stack_overflow();
|
||||
__DO_IRQ_SMTC_HOOK(irq);
|
||||
generic_handle_irq(irq);
|
||||
if (!smtc_handle_on_other_cpu(irq))
|
||||
generic_handle_irq(irq);
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
@ -197,7 +158,7 @@ void __irq_entry do_IRQ(unsigned int irq)
|
||||
void __irq_entry do_IRQ_no_affinity(unsigned int irq)
|
||||
{
|
||||
irq_enter();
|
||||
__NO_AFFINITY_IRQ_SMTC_HOOK(irq);
|
||||
smtc_im_backstop(irq);
|
||||
generic_handle_irq(irq);
|
||||
irq_exit();
|
||||
}
|
||||
|
@ -37,42 +37,38 @@
|
||||
#include <asm/mipsmtregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static inline void unmask_mips_irq(unsigned int irq)
|
||||
static inline void unmask_mips_irq(struct irq_data *d)
|
||||
{
|
||||
set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
|
||||
set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
|
||||
irq_enable_hazard();
|
||||
}
|
||||
|
||||
static inline void mask_mips_irq(unsigned int irq)
|
||||
static inline void mask_mips_irq(struct irq_data *d)
|
||||
{
|
||||
clear_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
|
||||
clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
|
||||
irq_disable_hazard();
|
||||
}
|
||||
|
||||
static struct irq_chip mips_cpu_irq_controller = {
|
||||
.name = "MIPS",
|
||||
.ack = mask_mips_irq,
|
||||
.mask = mask_mips_irq,
|
||||
.mask_ack = mask_mips_irq,
|
||||
.unmask = unmask_mips_irq,
|
||||
.eoi = unmask_mips_irq,
|
||||
.irq_ack = mask_mips_irq,
|
||||
.irq_mask = mask_mips_irq,
|
||||
.irq_mask_ack = mask_mips_irq,
|
||||
.irq_unmask = unmask_mips_irq,
|
||||
.irq_eoi = unmask_mips_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
* Basically the same as above but taking care of all the MT stuff
|
||||
*/
|
||||
|
||||
#define unmask_mips_mt_irq unmask_mips_irq
|
||||
#define mask_mips_mt_irq mask_mips_irq
|
||||
|
||||
static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
|
||||
static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
|
||||
{
|
||||
unsigned int vpflags = dvpe();
|
||||
|
||||
clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
|
||||
clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
|
||||
evpe(vpflags);
|
||||
unmask_mips_mt_irq(irq);
|
||||
|
||||
unmask_mips_irq(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -80,22 +76,22 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
|
||||
* While we ack the interrupt interrupts are disabled and thus we don't need
|
||||
* to deal with concurrency issues. Same for mips_cpu_irq_end.
|
||||
*/
|
||||
static void mips_mt_cpu_irq_ack(unsigned int irq)
|
||||
static void mips_mt_cpu_irq_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int vpflags = dvpe();
|
||||
clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
|
||||
clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
|
||||
evpe(vpflags);
|
||||
mask_mips_mt_irq(irq);
|
||||
mask_mips_irq(d);
|
||||
}
|
||||
|
||||
static struct irq_chip mips_mt_cpu_irq_controller = {
|
||||
.name = "MIPS",
|
||||
.startup = mips_mt_cpu_irq_startup,
|
||||
.ack = mips_mt_cpu_irq_ack,
|
||||
.mask = mask_mips_mt_irq,
|
||||
.mask_ack = mips_mt_cpu_irq_ack,
|
||||
.unmask = unmask_mips_mt_irq,
|
||||
.eoi = unmask_mips_mt_irq,
|
||||
.irq_startup = mips_mt_cpu_irq_startup,
|
||||
.irq_ack = mips_mt_cpu_irq_ack,
|
||||
.irq_mask = mask_mips_irq,
|
||||
.irq_mask_ack = mips_mt_cpu_irq_ack,
|
||||
.irq_unmask = unmask_mips_irq,
|
||||
.irq_eoi = unmask_mips_irq,
|
||||
};
|
||||
|
||||
void __init mips_cpu_irq_init(void)
|
||||
|
@ -63,9 +63,9 @@ static struct {
|
||||
unsigned char mode;
|
||||
} txx9irq[TXx9_MAX_IR] __read_mostly;
|
||||
|
||||
static void txx9_irq_unmask(unsigned int irq)
|
||||
static void txx9_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
|
||||
int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
|
||||
|
||||
@ -79,9 +79,9 @@ static void txx9_irq_unmask(unsigned int irq)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void txx9_irq_mask(unsigned int irq)
|
||||
static inline void txx9_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
|
||||
int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
|
||||
|
||||
@ -99,19 +99,19 @@ static inline void txx9_irq_mask(unsigned int irq)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void txx9_irq_mask_ack(unsigned int irq)
|
||||
static void txx9_irq_mask_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
|
||||
txx9_irq_mask(irq);
|
||||
txx9_irq_mask(d);
|
||||
/* clear edge detection */
|
||||
if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
|
||||
__raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
|
||||
}
|
||||
|
||||
static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||
static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
u32 cr;
|
||||
u32 __iomem *crp;
|
||||
int ofs;
|
||||
@ -139,11 +139,11 @@ static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||
|
||||
static struct irq_chip txx9_irq_chip = {
|
||||
.name = "TXX9",
|
||||
.ack = txx9_irq_mask_ack,
|
||||
.mask = txx9_irq_mask,
|
||||
.mask_ack = txx9_irq_mask_ack,
|
||||
.unmask = txx9_irq_unmask,
|
||||
.set_type = txx9_irq_set_type,
|
||||
.irq_ack = txx9_irq_mask_ack,
|
||||
.irq_mask = txx9_irq_mask,
|
||||
.irq_mask_ack = txx9_irq_mask_ack,
|
||||
.irq_unmask = txx9_irq_unmask,
|
||||
.irq_set_type = txx9_irq_set_type,
|
||||
};
|
||||
|
||||
void __init txx9_irq_init(unsigned long baseaddr)
|
||||
|
@ -586,6 +586,10 @@ einval: li v0, -ENOSYS
|
||||
sys sys_fanotify_init 2
|
||||
sys sys_fanotify_mark 6
|
||||
sys sys_prlimit64 4
|
||||
sys sys_name_to_handle_at 5
|
||||
sys sys_open_by_handle_at 3 /* 4340 */
|
||||
sys sys_clock_adjtime 2
|
||||
sys sys_syncfs 1
|
||||
.endm
|
||||
|
||||
/* We pre-compute the number of _instruction_ bytes needed to
|
||||
|
@ -425,4 +425,8 @@ sys_call_table:
|
||||
PTR sys_fanotify_init /* 5295 */
|
||||
PTR sys_fanotify_mark
|
||||
PTR sys_prlimit64
|
||||
PTR sys_name_to_handle_at
|
||||
PTR sys_open_by_handle_at
|
||||
PTR sys_clock_adjtime /* 5300 */
|
||||
PTR sys_syncfs
|
||||
.size sys_call_table,.-sys_call_table
|
||||
|
@ -425,4 +425,8 @@ EXPORT(sysn32_call_table)
|
||||
PTR sys_fanotify_init /* 6300 */
|
||||
PTR sys_fanotify_mark
|
||||
PTR sys_prlimit64
|
||||
PTR sys_name_to_handle_at
|
||||
PTR sys_open_by_handle_at
|
||||
PTR compat_sys_clock_adjtime /* 6305 */
|
||||
PTR sys_syncfs
|
||||
.size sysn32_call_table,.-sysn32_call_table
|
||||
|
@ -543,4 +543,8 @@ sys_call_table:
|
||||
PTR sys_fanotify_init
|
||||
PTR sys_32_fanotify_mark
|
||||
PTR sys_prlimit64
|
||||
PTR sys_name_to_handle_at
|
||||
PTR compat_sys_open_by_handle_at /* 4340 */
|
||||
PTR compat_sys_clock_adjtime
|
||||
PTR sys_syncfs
|
||||
.size sys_call_table,.-sys_call_table
|
||||
|
@ -677,8 +677,9 @@ void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity)
|
||||
*/
|
||||
}
|
||||
|
||||
void smtc_forward_irq(unsigned int irq)
|
||||
void smtc_forward_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
int target;
|
||||
|
||||
/*
|
||||
@ -692,7 +693,7 @@ void smtc_forward_irq(unsigned int irq)
|
||||
* and efficiency, we just pick the easiest one to find.
|
||||
*/
|
||||
|
||||
target = cpumask_first(irq_desc[irq].affinity);
|
||||
target = cpumask_first(d->affinity);
|
||||
|
||||
/*
|
||||
* We depend on the platform code to have correctly processed
|
||||
@ -707,12 +708,10 @@ void smtc_forward_irq(unsigned int irq)
|
||||
*/
|
||||
|
||||
/* If no one is eligible, service locally */
|
||||
if (target >= NR_CPUS) {
|
||||
if (target >= NR_CPUS)
|
||||
do_IRQ_no_affinity(irq);
|
||||
return;
|
||||
}
|
||||
|
||||
smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
|
||||
else
|
||||
smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||
|
@ -32,24 +32,24 @@ static volatile int *lasat_int_status;
|
||||
static volatile int *lasat_int_mask;
|
||||
static volatile int lasat_int_mask_shift;
|
||||
|
||||
void disable_lasat_irq(unsigned int irq_nr)
|
||||
void disable_lasat_irq(struct irq_data *d)
|
||||
{
|
||||
irq_nr -= LASAT_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
|
||||
|
||||
*lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
|
||||
}
|
||||
|
||||
void enable_lasat_irq(unsigned int irq_nr)
|
||||
void enable_lasat_irq(struct irq_data *d)
|
||||
{
|
||||
irq_nr -= LASAT_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
|
||||
|
||||
*lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
|
||||
}
|
||||
|
||||
static struct irq_chip lasat_irq_type = {
|
||||
.name = "Lasat",
|
||||
.ack = disable_lasat_irq,
|
||||
.mask = disable_lasat_irq,
|
||||
.mask_ack = disable_lasat_irq,
|
||||
.unmask = enable_lasat_irq,
|
||||
.irq_mask = disable_lasat_irq,
|
||||
.irq_unmask = enable_lasat_irq,
|
||||
};
|
||||
|
||||
static inline int ls1bit32(unsigned int x)
|
||||
|
@ -16,24 +16,22 @@
|
||||
|
||||
#include <loongson.h>
|
||||
|
||||
static inline void bonito_irq_enable(unsigned int irq)
|
||||
static inline void bonito_irq_enable(struct irq_data *d)
|
||||
{
|
||||
LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE));
|
||||
LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE));
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
static inline void bonito_irq_disable(unsigned int irq)
|
||||
static inline void bonito_irq_disable(struct irq_data *d)
|
||||
{
|
||||
LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE));
|
||||
LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE));
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
static struct irq_chip bonito_irq_type = {
|
||||
.name = "bonito_irq",
|
||||
.ack = bonito_irq_disable,
|
||||
.mask = bonito_irq_disable,
|
||||
.mask_ack = bonito_irq_disable,
|
||||
.unmask = bonito_irq_enable,
|
||||
.name = "bonito_irq",
|
||||
.irq_mask = bonito_irq_disable,
|
||||
.irq_unmask = bonito_irq_enable,
|
||||
};
|
||||
|
||||
static struct irqaction __maybe_unused dma_timeout_irqaction = {
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/smtc.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/smtc_ipi.h>
|
||||
@ -57,8 +58,6 @@ static inline void ssmtc_send_ipi_mask(const struct cpumask *mask,
|
||||
*/
|
||||
static void __cpuinit ssmtc_init_secondary(void)
|
||||
{
|
||||
void smtc_init_secondary(void);
|
||||
|
||||
smtc_init_secondary();
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,6 @@ static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action)
|
||||
*/
|
||||
static void __cpuinit msmtc_init_secondary(void)
|
||||
{
|
||||
void smtc_init_secondary(void);
|
||||
int myvpe;
|
||||
|
||||
/* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
|
||||
@ -114,7 +113,8 @@ struct plat_smp_ops msmtc_smp_ops = {
|
||||
*/
|
||||
|
||||
|
||||
int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||
int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
|
||||
bool force)
|
||||
{
|
||||
cpumask_t tmask;
|
||||
int cpu = 0;
|
||||
@ -144,7 +144,7 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||
if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
|
||||
cpu_clear(cpu, tmask);
|
||||
}
|
||||
cpumask_copy(irq_desc[irq].affinity, &tmask);
|
||||
cpumask_copy(d->affinity, &tmask);
|
||||
|
||||
if (cpus_empty(tmask))
|
||||
/*
|
||||
@ -155,8 +155,8 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||
"IRQ affinity leaves no legal CPU for IRQ %d\n", irq);
|
||||
|
||||
/* Do any generic SMTC IRQ affinity setup */
|
||||
smtc_set_irq_affinity(irq, tmask);
|
||||
smtc_set_irq_affinity(d->irq, tmask);
|
||||
|
||||
return 0;
|
||||
return IRQ_SET_MASK_OK_NOCOPY;
|
||||
}
|
||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||
|
@ -23,6 +23,8 @@ config PMC_MSP7120_GW
|
||||
select SYS_SUPPORTS_MULTITHREADING
|
||||
select IRQ_MSP_CIC
|
||||
select HW_HAS_PCI
|
||||
select MSP_HAS_USB
|
||||
select MSP_ETH
|
||||
|
||||
config PMC_MSP7120_FPGA
|
||||
bool "PMC-Sierra MSP7120 FPGA"
|
||||
@ -35,3 +37,16 @@ endchoice
|
||||
config HYPERTRANSPORT
|
||||
bool "Hypertransport Support for PMC-Sierra Yosemite"
|
||||
depends on PMC_YOSEMITE
|
||||
|
||||
config MSP_HAS_USB
|
||||
boolean
|
||||
depends on PMC_MSP
|
||||
|
||||
config MSP_ETH
|
||||
boolean
|
||||
select MSP_HAS_MAC
|
||||
depends on PMC_MSP
|
||||
|
||||
config MSP_HAS_MAC
|
||||
boolean
|
||||
depends on PMC_MSP
|
||||
|
@ -6,7 +6,9 @@ obj-y += msp_prom.o msp_setup.o msp_irq.o \
|
||||
obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o
|
||||
obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
|
||||
obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
|
||||
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o
|
||||
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
|
||||
obj-$(CONFIG_PCI) += msp_pci.o
|
||||
obj-$(CONFIG_MSPETH) += msp_eth.o
|
||||
obj-$(CONFIG_USB_MSP71XX) += msp_usb.o
|
||||
obj-$(CONFIG_MSP_HAS_MAC) += msp_eth.o
|
||||
obj-$(CONFIG_MSP_HAS_USB) += msp_usb.o
|
||||
obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o
|
||||
obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o
|
||||
|
187
arch/mips/pmc-sierra/msp71xx/msp_eth.c
Normal file
187
arch/mips/pmc-sierra/msp71xx/msp_eth.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* The setup file for ethernet related hardware on PMC-Sierra MSP processors.
|
||||
*
|
||||
* Copyright 2010 PMC-Sierra, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <msp_regs.h>
|
||||
#include <msp_int.h>
|
||||
#include <msp_gpio_macros.h>
|
||||
|
||||
|
||||
#define MSP_ETHERNET_GPIO0 14
|
||||
#define MSP_ETHERNET_GPIO1 15
|
||||
#define MSP_ETHERNET_GPIO2 16
|
||||
|
||||
#ifdef CONFIG_MSP_HAS_TSMAC
|
||||
#define MSP_TSMAC_SIZE 0x10020
|
||||
#define MSP_TSMAC_ID "pmc_tsmac"
|
||||
|
||||
static struct resource msp_tsmac0_resources[] = {
|
||||
[0] = {
|
||||
.start = MSP_MAC0_BASE,
|
||||
.end = MSP_MAC0_BASE + MSP_TSMAC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_MAC0,
|
||||
.end = MSP_INT_MAC0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource msp_tsmac1_resources[] = {
|
||||
[0] = {
|
||||
.start = MSP_MAC1_BASE,
|
||||
.end = MSP_MAC1_BASE + MSP_TSMAC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_MAC1,
|
||||
.end = MSP_INT_MAC1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
static struct resource msp_tsmac2_resources[] = {
|
||||
[0] = {
|
||||
.start = MSP_MAC2_BASE,
|
||||
.end = MSP_MAC2_BASE + MSP_TSMAC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_SAR,
|
||||
.end = MSP_INT_SAR,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device tsmac_device[] = {
|
||||
[0] = {
|
||||
.name = MSP_TSMAC_ID,
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(msp_tsmac0_resources),
|
||||
.resource = msp_tsmac0_resources,
|
||||
},
|
||||
[1] = {
|
||||
.name = MSP_TSMAC_ID,
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(msp_tsmac1_resources),
|
||||
.resource = msp_tsmac1_resources,
|
||||
},
|
||||
[2] = {
|
||||
.name = MSP_TSMAC_ID,
|
||||
.id = 2,
|
||||
.num_resources = ARRAY_SIZE(msp_tsmac2_resources),
|
||||
.resource = msp_tsmac2_resources,
|
||||
},
|
||||
};
|
||||
#define msp_eth_devs tsmac_device
|
||||
|
||||
#else
|
||||
/* If it is not TSMAC assume MSP_ETH (100Mbps) */
|
||||
#define MSP_ETH_ID "pmc_mspeth"
|
||||
#define MSP_ETH_SIZE 0xE0
|
||||
static struct resource msp_eth0_resources[] = {
|
||||
[0] = {
|
||||
.start = MSP_MAC0_BASE,
|
||||
.end = MSP_MAC0_BASE + MSP_ETH_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_MAC0,
|
||||
.end = MSP_INT_MAC0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource msp_eth1_resources[] = {
|
||||
[0] = {
|
||||
.start = MSP_MAC1_BASE,
|
||||
.end = MSP_MAC1_BASE + MSP_ETH_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_MAC1,
|
||||
.end = MSP_INT_MAC1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct platform_device mspeth_device[] = {
|
||||
[0] = {
|
||||
.name = MSP_ETH_ID,
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(msp_eth0_resources),
|
||||
.resource = msp_eth0_resources,
|
||||
},
|
||||
[1] = {
|
||||
.name = MSP_ETH_ID,
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(msp_eth1_resources),
|
||||
.resource = msp_eth1_resources,
|
||||
},
|
||||
|
||||
};
|
||||
#define msp_eth_devs mspeth_device
|
||||
|
||||
#endif
|
||||
int __init msp_eth_setup(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
/* Configure the GPIO and take the ethernet PHY out of reset */
|
||||
msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO0);
|
||||
msp_gpio_pin_hi(MSP_ETHERNET_GPIO0);
|
||||
|
||||
#ifdef CONFIG_MSP_HAS_TSMAC
|
||||
/* 3 phys on boards with TSMAC */
|
||||
msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO1);
|
||||
msp_gpio_pin_hi(MSP_ETHERNET_GPIO1);
|
||||
|
||||
msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO2);
|
||||
msp_gpio_pin_hi(MSP_ETHERNET_GPIO2);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(msp_eth_devs); i++) {
|
||||
ret = platform_device_register(&msp_eth_devs[i]);
|
||||
printk(KERN_INFO "device: %d, return value = %d\n", i, ret);
|
||||
if (ret) {
|
||||
platform_device_unregister(&msp_eth_devs[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
printk(KERN_WARNING "Could not initialize "
|
||||
"MSPETH device structures.\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
subsys_initcall(msp_eth_setup);
|
@ -19,8 +19,6 @@
|
||||
|
||||
#include <msp_int.h>
|
||||
|
||||
extern void msp_int_handle(void);
|
||||
|
||||
/* SLP bases systems */
|
||||
extern void msp_slp_irq_init(void);
|
||||
extern void msp_slp_irq_dispatch(void);
|
||||
@ -29,6 +27,18 @@ extern void msp_slp_irq_dispatch(void);
|
||||
extern void msp_cic_irq_init(void);
|
||||
extern void msp_cic_irq_dispatch(void);
|
||||
|
||||
/* VSMP support init */
|
||||
extern void msp_vsmp_int_init(void);
|
||||
|
||||
/* vectored interrupt implementation */
|
||||
|
||||
/* SW0/1 interrupts are used for SMP/SMTC */
|
||||
static inline void mac0_int_dispatch(void) { do_IRQ(MSP_INT_MAC0); }
|
||||
static inline void mac1_int_dispatch(void) { do_IRQ(MSP_INT_MAC1); }
|
||||
static inline void mac2_int_dispatch(void) { do_IRQ(MSP_INT_SAR); }
|
||||
static inline void usb_int_dispatch(void) { do_IRQ(MSP_INT_USB); }
|
||||
static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); }
|
||||
|
||||
/*
|
||||
* The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded
|
||||
* hierarchical system. The first level are the direct MIPS interrupts
|
||||
@ -96,29 +106,57 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
|
||||
do_IRQ(MSP_INT_SW1);
|
||||
}
|
||||
|
||||
static struct irqaction cascade_msp = {
|
||||
static struct irqaction cic_cascade_msp = {
|
||||
.handler = no_action,
|
||||
.name = "MSP cascade"
|
||||
.name = "MSP CIC cascade"
|
||||
};
|
||||
|
||||
static struct irqaction per_cascade_msp = {
|
||||
.handler = no_action,
|
||||
.name = "MSP PER cascade"
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
/* assume we'll be using vectored interrupt mode except in UP mode*/
|
||||
#ifdef CONFIG_MIPS_MT
|
||||
BUG_ON(!cpu_has_vint);
|
||||
#endif
|
||||
/* initialize the 1st-level CPU based interrupt controller */
|
||||
mips_cpu_irq_init();
|
||||
|
||||
#ifdef CONFIG_IRQ_MSP_CIC
|
||||
msp_cic_irq_init();
|
||||
#ifdef CONFIG_MIPS_MT
|
||||
set_vi_handler(MSP_INT_CIC, msp_cic_irq_dispatch);
|
||||
set_vi_handler(MSP_INT_MAC0, mac0_int_dispatch);
|
||||
set_vi_handler(MSP_INT_MAC1, mac1_int_dispatch);
|
||||
set_vi_handler(MSP_INT_SAR, mac2_int_dispatch);
|
||||
set_vi_handler(MSP_INT_USB, usb_int_dispatch);
|
||||
set_vi_handler(MSP_INT_SEC, sec_int_dispatch);
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
msp_vsmp_int_init();
|
||||
#elif defined CONFIG_MIPS_MT_SMTC
|
||||
/*Set hwmask for all platform devices */
|
||||
irq_hwmask[MSP_INT_MAC0] = C_IRQ0;
|
||||
irq_hwmask[MSP_INT_MAC1] = C_IRQ1;
|
||||
irq_hwmask[MSP_INT_USB] = C_IRQ2;
|
||||
irq_hwmask[MSP_INT_SAR] = C_IRQ3;
|
||||
irq_hwmask[MSP_INT_SEC] = C_IRQ5;
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMP */
|
||||
#endif /* CONFIG_MIPS_MT */
|
||||
/* setup the cascaded interrupts */
|
||||
setup_irq(MSP_INT_CIC, &cascade_msp);
|
||||
setup_irq(MSP_INT_PER, &cascade_msp);
|
||||
setup_irq(MSP_INT_CIC, &cic_cascade_msp);
|
||||
setup_irq(MSP_INT_PER, &per_cascade_msp);
|
||||
|
||||
#else
|
||||
/* setup the 2nd-level SLP register based interrupt controller */
|
||||
/* VSMP /SMTC support support is not enabled for SLP */
|
||||
msp_slp_irq_init();
|
||||
|
||||
/* setup the cascaded SLP/PER interrupts */
|
||||
setup_irq(MSP_INT_SLP, &cascade_msp);
|
||||
setup_irq(MSP_INT_PER, &cascade_msp);
|
||||
setup_irq(MSP_INT_SLP, &cic_cascade_msp);
|
||||
setup_irq(MSP_INT_PER, &per_cascade_msp);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
/*
|
||||
* This file define the irq handler for MSP SLM subsystem interrupts.
|
||||
* Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
|
||||
*
|
||||
* Copyright 2005-2007 PMC-Sierra, Inc, derived from irq_cpu.c
|
||||
* Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
|
||||
* This file define the irq handler for MSP CIC subsystem interrupts.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@ -16,119 +15,203 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include <msp_cic_int.h>
|
||||
#include <msp_regs.h>
|
||||
|
||||
/*
|
||||
* NOTE: We are only enabling support for VPE0 right now.
|
||||
* External API
|
||||
*/
|
||||
extern void msp_per_irq_init(void);
|
||||
extern void msp_per_irq_dispatch(void);
|
||||
|
||||
static inline void unmask_msp_cic_irq(unsigned int irq)
|
||||
{
|
||||
|
||||
/* check for PER interrupt range */
|
||||
if (irq < MSP_PER_INTBASE)
|
||||
*CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE));
|
||||
else
|
||||
*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
|
||||
}
|
||||
|
||||
static inline void mask_msp_cic_irq(unsigned int irq)
|
||||
{
|
||||
/* check for PER interrupt range */
|
||||
if (irq < MSP_PER_INTBASE)
|
||||
*CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE));
|
||||
else
|
||||
*PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
|
||||
}
|
||||
|
||||
/*
|
||||
* While we ack the interrupt interrupts are disabled and thus we don't need
|
||||
* to deal with concurrency issues. Same for msp_cic_irq_end.
|
||||
* Convenience Macro. Should be somewhere generic.
|
||||
*/
|
||||
static inline void ack_msp_cic_irq(unsigned int irq)
|
||||
#define get_current_vpe() \
|
||||
((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#define LOCK_VPE(flags, mtflags) \
|
||||
do { \
|
||||
local_irq_save(flags); \
|
||||
mtflags = dmt(); \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_VPE(flags, mtflags) \
|
||||
do { \
|
||||
emt(mtflags); \
|
||||
local_irq_restore(flags);\
|
||||
} while (0)
|
||||
|
||||
#define LOCK_CORE(flags, mtflags) \
|
||||
do { \
|
||||
local_irq_save(flags); \
|
||||
mtflags = dvpe(); \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_CORE(flags, mtflags) \
|
||||
do { \
|
||||
evpe(mtflags); \
|
||||
local_irq_restore(flags);\
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define LOCK_VPE(flags, mtflags)
|
||||
#define UNLOCK_VPE(flags, mtflags)
|
||||
#endif
|
||||
|
||||
/* ensure writes to cic are completed */
|
||||
static inline void cic_wmb(void)
|
||||
{
|
||||
mask_msp_cic_irq(irq);
|
||||
const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG;
|
||||
volatile u32 dummy_read;
|
||||
|
||||
wmb();
|
||||
dummy_read = __raw_readl(cic_mem);
|
||||
dummy_read++;
|
||||
}
|
||||
|
||||
static void unmask_cic_irq(struct irq_data *d)
|
||||
{
|
||||
volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG;
|
||||
int vpe;
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned int mtflags;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* only really necessary for 18, 16-14 and sometimes 3:0 (since
|
||||
* these can be edge sensitive) but it doesn't hurt for the others.
|
||||
*/
|
||||
* Make sure we have IRQ affinity. It may have changed while
|
||||
* we were processing the IRQ.
|
||||
*/
|
||||
if (!cpumask_test_cpu(smp_processor_id(), d->affinity))
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* check for PER interrupt range */
|
||||
if (irq < MSP_PER_INTBASE)
|
||||
*CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE));
|
||||
else
|
||||
*PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
|
||||
vpe = get_current_vpe();
|
||||
LOCK_VPE(flags, mtflags);
|
||||
cic_msk_reg[vpe] |= (1 << (d->irq - MSP_CIC_INTBASE));
|
||||
UNLOCK_VPE(flags, mtflags);
|
||||
cic_wmb();
|
||||
}
|
||||
|
||||
static void mask_cic_irq(struct irq_data *d)
|
||||
{
|
||||
volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG;
|
||||
int vpe = get_current_vpe();
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long flags, mtflags;
|
||||
#endif
|
||||
LOCK_VPE(flags, mtflags);
|
||||
cic_msk_reg[vpe] &= ~(1 << (d->irq - MSP_CIC_INTBASE));
|
||||
UNLOCK_VPE(flags, mtflags);
|
||||
cic_wmb();
|
||||
}
|
||||
static void msp_cic_irq_ack(struct irq_data *d)
|
||||
{
|
||||
mask_cic_irq(d);
|
||||
/*
|
||||
* Only really necessary for 18, 16-14 and sometimes 3:0
|
||||
* (since these can be edge sensitive) but it doesn't
|
||||
* hurt for the others
|
||||
*/
|
||||
*CIC_STS_REG = (1 << (d->irq - MSP_CIC_INTBASE));
|
||||
smtc_im_ack_irq(d->irq);
|
||||
}
|
||||
|
||||
/*Note: Limiting to VSMP . Not tested in SMTC */
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
static int msp_cic_irq_set_affinity(struct irq_data *d,
|
||||
const struct cpumask *cpumask, bool force)
|
||||
{
|
||||
int cpu;
|
||||
unsigned long flags;
|
||||
unsigned int mtflags;
|
||||
unsigned long imask = (1 << (irq - MSP_CIC_INTBASE));
|
||||
volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG;
|
||||
|
||||
/* timer balancing should be disabled in kernel code */
|
||||
BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER);
|
||||
|
||||
LOCK_CORE(flags, mtflags);
|
||||
/* enable if any of each VPE's TCs require this IRQ */
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpumask_test_cpu(cpu, cpumask))
|
||||
cic_mask[cpu] |= imask;
|
||||
else
|
||||
cic_mask[cpu] &= ~imask;
|
||||
|
||||
}
|
||||
|
||||
UNLOCK_CORE(flags, mtflags);
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct irq_chip msp_cic_irq_controller = {
|
||||
.name = "MSP_CIC",
|
||||
.ack = ack_msp_cic_irq,
|
||||
.mask = ack_msp_cic_irq,
|
||||
.mask_ack = ack_msp_cic_irq,
|
||||
.unmask = unmask_msp_cic_irq,
|
||||
.irq_mask = mask_cic_irq,
|
||||
.irq_mask_ack = msp_cic_irq_ack,
|
||||
.irq_unmask = unmask_cic_irq,
|
||||
.irq_ack = msp_cic_irq_ack,
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
.irq_set_affinity = msp_cic_irq_set_affinity,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void __init msp_cic_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Mask/clear interrupts. */
|
||||
*CIC_VPE0_MSK_REG = 0x00000000;
|
||||
*PER_INT_MSK_REG = 0x00000000;
|
||||
*CIC_VPE1_MSK_REG = 0x00000000;
|
||||
*CIC_STS_REG = 0xFFFFFFFF;
|
||||
*PER_INT_STS_REG = 0xFFFFFFFF;
|
||||
|
||||
#if defined(CONFIG_PMC_MSP7120_GW) || \
|
||||
defined(CONFIG_PMC_MSP7120_EVAL)
|
||||
/*
|
||||
* The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI.
|
||||
* These inputs map to EXT_INT_POL[6:4] inside the CIC.
|
||||
* They are to be active low, level sensitive.
|
||||
*/
|
||||
* The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI.
|
||||
* These inputs map to EXT_INT_POL[6:4] inside the CIC.
|
||||
* They are to be active low, level sensitive.
|
||||
*/
|
||||
*CIC_EXT_CFG_REG &= 0xFFFF8F8F;
|
||||
#endif
|
||||
|
||||
/* initialize all the IRQ descriptors */
|
||||
for (i = MSP_CIC_INTBASE; i < MSP_PER_INTBASE + 32; i++)
|
||||
for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) {
|
||||
set_irq_chip_and_handler(i, &msp_cic_irq_controller,
|
||||
handle_level_irq);
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/* Mask of CIC interrupt */
|
||||
irq_hwmask[i] = C_IRQ4;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the PER interrupt sub-system */
|
||||
msp_per_irq_init();
|
||||
}
|
||||
|
||||
/* CIC masked by CIC vector processing before dispatch called */
|
||||
void msp_cic_irq_dispatch(void)
|
||||
{
|
||||
u32 pending;
|
||||
int intbase;
|
||||
|
||||
intbase = MSP_CIC_INTBASE;
|
||||
pending = *CIC_STS_REG & *CIC_VPE0_MSK_REG;
|
||||
|
||||
/* check for PER interrupt */
|
||||
if (pending == (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) {
|
||||
intbase = MSP_PER_INTBASE;
|
||||
pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
|
||||
}
|
||||
|
||||
/* check for spurious interrupt */
|
||||
if (pending == 0x00000000) {
|
||||
printk(KERN_ERR
|
||||
"Spurious %s interrupt? status %08x, mask %08x\n",
|
||||
(intbase == MSP_CIC_INTBASE) ? "CIC" : "PER",
|
||||
(intbase == MSP_CIC_INTBASE) ?
|
||||
*CIC_STS_REG : *PER_INT_STS_REG,
|
||||
(intbase == MSP_CIC_INTBASE) ?
|
||||
*CIC_VPE0_MSK_REG : *PER_INT_MSK_REG);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for the timer and dispatch it first */
|
||||
if ((intbase == MSP_CIC_INTBASE) &&
|
||||
(pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))))
|
||||
volatile u32 *cic_msk_reg = (volatile u32 *)CIC_VPE0_MSK_REG;
|
||||
u32 cic_mask;
|
||||
u32 pending;
|
||||
int cic_status = *CIC_STS_REG;
|
||||
cic_mask = cic_msk_reg[get_current_vpe()];
|
||||
pending = cic_status & cic_mask;
|
||||
if (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))) {
|
||||
do_IRQ(MSP_INT_VPE0_TIMER);
|
||||
else
|
||||
do_IRQ(ffs(pending) + intbase - 1);
|
||||
} else if (pending & (1 << (MSP_INT_VPE1_TIMER - MSP_CIC_INTBASE))) {
|
||||
do_IRQ(MSP_INT_VPE1_TIMER);
|
||||
} else if (pending & (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) {
|
||||
msp_per_irq_dispatch();
|
||||
} else if (pending) {
|
||||
do_IRQ(ffs(pending) + MSP_CIC_INTBASE - 1);
|
||||
} else{
|
||||
spurious_interrupt();
|
||||
}
|
||||
}
|
||||
|
135
arch/mips/pmc-sierra/msp71xx/msp_irq_per.c
Normal file
135
arch/mips/pmc-sierra/msp71xx/msp_irq_per.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
|
||||
*
|
||||
* This file define the irq handler for MSP PER subsystem interrupts.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include <msp_cic_int.h>
|
||||
#include <msp_regs.h>
|
||||
|
||||
|
||||
/*
|
||||
* Convenience Macro. Should be somewhere generic.
|
||||
*/
|
||||
#define get_current_vpe() \
|
||||
((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* The PER registers must be protected from concurrent access.
|
||||
*/
|
||||
|
||||
static DEFINE_SPINLOCK(per_lock);
|
||||
#endif
|
||||
|
||||
/* ensure writes to per are completed */
|
||||
|
||||
static inline void per_wmb(void)
|
||||
{
|
||||
const volatile void __iomem *per_mem = PER_INT_MSK_REG;
|
||||
volatile u32 dummy_read;
|
||||
|
||||
wmb();
|
||||
dummy_read = __raw_readl(per_mem);
|
||||
dummy_read++;
|
||||
}
|
||||
|
||||
static inline void unmask_per_irq(struct irq_data *d)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&per_lock, flags);
|
||||
*PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
|
||||
spin_unlock_irqrestore(&per_lock, flags);
|
||||
#else
|
||||
*PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
|
||||
#endif
|
||||
per_wmb();
|
||||
}
|
||||
|
||||
static inline void mask_per_irq(struct irq_data *d)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&per_lock, flags);
|
||||
*PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
|
||||
spin_unlock_irqrestore(&per_lock, flags);
|
||||
#else
|
||||
*PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
|
||||
#endif
|
||||
per_wmb();
|
||||
}
|
||||
|
||||
static inline void msp_per_irq_ack(struct irq_data *d)
|
||||
{
|
||||
mask_per_irq(d);
|
||||
/*
|
||||
* In the PER interrupt controller, only bits 11 and 10
|
||||
* are write-to-clear, (SPI TX complete, SPI RX complete).
|
||||
* It does nothing for any others.
|
||||
*/
|
||||
*PER_INT_STS_REG = (1 << (d->irq - MSP_PER_INTBASE));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int msp_per_irq_set_affinity(struct irq_data *d,
|
||||
const struct cpumask *affinity, bool force)
|
||||
{
|
||||
/* WTF is this doing ????? */
|
||||
unmask_per_irq(d);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct irq_chip msp_per_irq_controller = {
|
||||
.name = "MSP_PER",
|
||||
.irq_enable = unmask_per_irq.
|
||||
.irq_disable = mask_per_irq,
|
||||
.irq_ack = msp_per_irq_ack,
|
||||
#ifdef CONFIG_SMP
|
||||
.irq_set_affinity = msp_per_irq_set_affinity,
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init msp_per_irq_init(void)
|
||||
{
|
||||
int i;
|
||||
/* Mask/clear interrupts. */
|
||||
*PER_INT_MSK_REG = 0x00000000;
|
||||
*PER_INT_STS_REG = 0xFFFFFFFF;
|
||||
/* initialize all the IRQ descriptors */
|
||||
for (i = MSP_PER_INTBASE; i < MSP_PER_INTBASE + 32; i++) {
|
||||
irq_set_chip(i, &msp_per_irq_controller);
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
irq_hwmask[i] = C_IRQ4;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void msp_per_irq_dispatch(void)
|
||||
{
|
||||
u32 per_mask = *PER_INT_MSK_REG;
|
||||
u32 per_status = *PER_INT_STS_REG;
|
||||
u32 pending;
|
||||
|
||||
pending = per_status & per_mask;
|
||||
if (pending) {
|
||||
do_IRQ(ffs(pending) + MSP_PER_INTBASE - 1);
|
||||
} else {
|
||||
spurious_interrupt();
|
||||
}
|
||||
}
|
@ -21,8 +21,10 @@
|
||||
#include <msp_slp_int.h>
|
||||
#include <msp_regs.h>
|
||||
|
||||
static inline void unmask_msp_slp_irq(unsigned int irq)
|
||||
static inline void unmask_msp_slp_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
/* check for PER interrupt range */
|
||||
if (irq < MSP_PER_INTBASE)
|
||||
*SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
|
||||
@ -30,8 +32,10 @@ static inline void unmask_msp_slp_irq(unsigned int irq)
|
||||
*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
|
||||
}
|
||||
|
||||
static inline void mask_msp_slp_irq(unsigned int irq)
|
||||
static inline void mask_msp_slp_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
/* check for PER interrupt range */
|
||||
if (irq < MSP_PER_INTBASE)
|
||||
*SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
|
||||
@ -43,8 +47,10 @@ static inline void mask_msp_slp_irq(unsigned int irq)
|
||||
* While we ack the interrupt interrupts are disabled and thus we don't need
|
||||
* to deal with concurrency issues. Same for msp_slp_irq_end.
|
||||
*/
|
||||
static inline void ack_msp_slp_irq(unsigned int irq)
|
||||
static inline void ack_msp_slp_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
/* check for PER interrupt range */
|
||||
if (irq < MSP_PER_INTBASE)
|
||||
*SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
|
||||
@ -54,9 +60,9 @@ static inline void ack_msp_slp_irq(unsigned int irq)
|
||||
|
||||
static struct irq_chip msp_slp_irq_controller = {
|
||||
.name = "MSP_SLP",
|
||||
.ack = ack_msp_slp_irq,
|
||||
.mask = mask_msp_slp_irq,
|
||||
.unmask = unmask_msp_slp_irq,
|
||||
.irq_ack = ack_msp_slp_irq,
|
||||
.irq_mask = mask_msp_slp_irq,
|
||||
.irq_unmask = unmask_msp_slp_irq,
|
||||
};
|
||||
|
||||
void __init msp_slp_irq_init(void)
|
||||
|
@ -146,6 +146,8 @@ void __init plat_mem_setup(void)
|
||||
pm_power_off = msp_power_off;
|
||||
}
|
||||
|
||||
extern struct plat_smp_ops msp_smtc_smp_ops;
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
unsigned long family;
|
||||
@ -226,6 +228,14 @@ void __init prom_init(void)
|
||||
*/
|
||||
msp_serial_setup();
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
register_smp_ops(&vsmp_smp_ops);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
register_smp_ops(&msp_smtc_smp_ops);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PMCTWILED
|
||||
/*
|
||||
* Setup LED states before the subsys_initcall loads other
|
||||
|
77
arch/mips/pmc-sierra/msp71xx/msp_smp.c
Normal file
77
arch/mips/pmc-sierra/msp71xx/msp_smp.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
|
||||
* Copyright (C) 2001 Ralf Baechle
|
||||
* Copyright (C) 2010 PMC-Sierra, Inc.
|
||||
*
|
||||
* VSMP support for MSP platforms . Derived from malta vsmp support.
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
#include <linux/smp.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */
|
||||
#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */
|
||||
|
||||
|
||||
static void ipi_resched_dispatch(void)
|
||||
{
|
||||
do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ);
|
||||
}
|
||||
|
||||
static void ipi_call_dispatch(void)
|
||||
{
|
||||
do_IRQ(MIPS_CPU_IPI_CALL_IRQ);
|
||||
}
|
||||
|
||||
static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
smp_call_function_interrupt();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction irq_resched = {
|
||||
.handler = ipi_resched_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_PERCPU,
|
||||
.name = "IPI_resched"
|
||||
};
|
||||
|
||||
static struct irqaction irq_call = {
|
||||
.handler = ipi_call_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_PERCPU,
|
||||
.name = "IPI_call"
|
||||
};
|
||||
|
||||
void __init arch_init_ipiirq(int irq, struct irqaction *action)
|
||||
{
|
||||
setup_irq(irq, action);
|
||||
set_irq_handler(irq, handle_percpu_irq);
|
||||
}
|
||||
|
||||
void __init msp_vsmp_int_init(void)
|
||||
{
|
||||
set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
|
||||
set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
|
||||
arch_init_ipiirq(MIPS_CPU_IPI_RESCHED_IRQ, &irq_resched);
|
||||
arch_init_ipiirq(MIPS_CPU_IPI_CALL_IRQ, &irq_call);
|
||||
}
|
||||
#endif /* CONFIG_MIPS_MT_SMP */
|
105
arch/mips/pmc-sierra/msp71xx/msp_smtc.c
Normal file
105
arch/mips/pmc-sierra/msp71xx/msp_smtc.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* MSP71xx Platform-specific hooks for SMP operation
|
||||
*/
|
||||
#include <linux/irq.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mipsmtregs.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/smtc.h>
|
||||
#include <asm/smtc_ipi.h>
|
||||
|
||||
/* VPE/SMP Prototype implements platform interfaces directly */
|
||||
|
||||
/*
|
||||
* Cause the specified action to be performed on a targeted "CPU"
|
||||
*/
|
||||
|
||||
static void msp_smtc_send_ipi_single(int cpu, unsigned int action)
|
||||
{
|
||||
/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
|
||||
smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
|
||||
}
|
||||
|
||||
static void msp_smtc_send_ipi_mask(const struct cpumask *mask,
|
||||
unsigned int action)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for_each_cpu(i, mask)
|
||||
msp_smtc_send_ipi_single(i, action);
|
||||
}
|
||||
|
||||
/*
|
||||
* Post-config but pre-boot cleanup entry point
|
||||
*/
|
||||
static void __cpuinit msp_smtc_init_secondary(void)
|
||||
{
|
||||
int myvpe;
|
||||
|
||||
/* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
|
||||
myvpe = read_c0_tcbind() & TCBIND_CURVPE;
|
||||
if (myvpe > 0)
|
||||
change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
|
||||
STATUSF_IP6 | STATUSF_IP7);
|
||||
smtc_init_secondary();
|
||||
}
|
||||
|
||||
/*
|
||||
* Platform "CPU" startup hook
|
||||
*/
|
||||
static void __cpuinit msp_smtc_boot_secondary(int cpu,
|
||||
struct task_struct *idle)
|
||||
{
|
||||
smtc_boot_secondary(cpu, idle);
|
||||
}
|
||||
|
||||
/*
|
||||
* SMP initialization finalization entry point
|
||||
*/
|
||||
static void __cpuinit msp_smtc_smp_finish(void)
|
||||
{
|
||||
smtc_smp_finish();
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook for after all CPUs are online
|
||||
*/
|
||||
|
||||
static void msp_smtc_cpus_done(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Platform SMP pre-initialization
|
||||
*
|
||||
* As noted above, we can assume a single CPU for now
|
||||
* but it may be multithreaded.
|
||||
*/
|
||||
|
||||
static void __init msp_smtc_smp_setup(void)
|
||||
{
|
||||
/*
|
||||
* we won't get the definitive value until
|
||||
* we've run smtc_prepare_cpus later, but
|
||||
*/
|
||||
|
||||
if (read_c0_config3() & (1 << 2))
|
||||
smp_num_siblings = smtc_build_cpu_map(0);
|
||||
}
|
||||
|
||||
static void __init msp_smtc_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
smtc_prepare_cpus(max_cpus);
|
||||
}
|
||||
|
||||
struct plat_smp_ops msp_smtc_smp_ops = {
|
||||
.send_ipi_single = msp_smtc_send_ipi_single,
|
||||
.send_ipi_mask = msp_smtc_send_ipi_mask,
|
||||
.init_secondary = msp_smtc_init_secondary,
|
||||
.smp_finish = msp_smtc_smp_finish,
|
||||
.cpus_done = msp_smtc_cpus_done,
|
||||
.boot_secondary = msp_smtc_boot_secondary,
|
||||
.smp_setup = msp_smtc_smp_setup,
|
||||
.prepare_cpus = msp_smtc_prepare_cpus,
|
||||
};
|
@ -29,6 +29,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
#include <asm/cevt-r4k.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
@ -36,6 +37,12 @@
|
||||
#include <msp_int.h>
|
||||
#include <msp_regs.h>
|
||||
|
||||
#define get_current_vpe() \
|
||||
((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
|
||||
|
||||
static struct irqaction timer_vpe1;
|
||||
static int tim_installed;
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
char *endp, *s;
|
||||
@ -83,5 +90,12 @@ void __init plat_time_init(void)
|
||||
|
||||
unsigned int __cpuinit get_c0_compare_int(void)
|
||||
{
|
||||
return MSP_INT_VPE0_TIMER;
|
||||
/* MIPS_MT modes may want timer for second VPE */
|
||||
if ((get_current_vpe()) && !tim_installed) {
|
||||
memcpy(&timer_vpe1, &c0_compare_irqaction, sizeof(timer_vpe1));
|
||||
setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
|
||||
tim_installed++;
|
||||
}
|
||||
|
||||
return get_current_vpe() ? MSP_INT_VPE1_TIMER : MSP_INT_VPE0_TIMER;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The setup file for USB related hardware on PMC-Sierra MSP processors.
|
||||
*
|
||||
* Copyright 2006-2007 PMC-Sierra, Inc.
|
||||
* Copyright 2006 PMC-Sierra, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@ -23,8 +23,8 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -34,40 +34,56 @@
|
||||
#include <msp_regs.h>
|
||||
#include <msp_int.h>
|
||||
#include <msp_prom.h>
|
||||
#include <msp_usb.h>
|
||||
|
||||
|
||||
#if defined(CONFIG_USB_EHCI_HCD)
|
||||
static struct resource msp_usbhost_resources [] = {
|
||||
[0] = {
|
||||
.start = MSP_USB_BASE_START,
|
||||
.end = MSP_USB_BASE_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
static struct resource msp_usbhost0_resources[] = {
|
||||
[0] = { /* EHCI-HS operational and capabilities registers */
|
||||
.start = MSP_USB0_HS_START,
|
||||
.end = MSP_USB0_HS_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_USB,
|
||||
.end = MSP_INT_USB,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
.start = MSP_INT_USB,
|
||||
.end = MSP_INT_USB,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = { /* MSBus-to-AMBA bridge register space */
|
||||
.start = MSP_USB0_MAB_START,
|
||||
.end = MSP_USB0_MAB_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[3] = { /* Identification and general hardware parameters */
|
||||
.start = MSP_USB0_ID_START,
|
||||
.end = MSP_USB0_ID_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static u64 msp_usbhost_dma_mask = DMA_BIT_MASK(32);
|
||||
static u64 msp_usbhost0_dma_mask = 0xffffffffUL;
|
||||
|
||||
static struct platform_device msp_usbhost_device = {
|
||||
.name = "pmcmsp-ehci",
|
||||
.id = 0,
|
||||
static struct mspusb_device msp_usbhost0_device = {
|
||||
.dev = {
|
||||
.dma_mask = &msp_usbhost_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.name = "pmcmsp-ehci",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &msp_usbhost0_dma_mask,
|
||||
.coherent_dma_mask = 0xffffffffUL,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(msp_usbhost0_resources),
|
||||
.resource = msp_usbhost0_resources,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(msp_usbhost_resources),
|
||||
.resource = msp_usbhost_resources,
|
||||
};
|
||||
#endif /* CONFIG_USB_EHCI_HCD */
|
||||
|
||||
#if defined(CONFIG_USB_GADGET)
|
||||
static struct resource msp_usbdev_resources [] = {
|
||||
[0] = {
|
||||
.start = MSP_USB_BASE,
|
||||
.end = MSP_USB_BASE_END,
|
||||
/* MSP7140/MSP82XX has two USB2 hosts. */
|
||||
#ifdef CONFIG_MSP_HAS_DUAL_USB
|
||||
static u64 msp_usbhost1_dma_mask = 0xffffffffUL;
|
||||
|
||||
static struct resource msp_usbhost1_resources[] = {
|
||||
[0] = { /* EHCI-HS operational and capabilities registers */
|
||||
.start = MSP_USB1_HS_START,
|
||||
.end = MSP_USB1_HS_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
@ -75,76 +91,173 @@ static struct resource msp_usbdev_resources [] = {
|
||||
.end = MSP_INT_USB,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static struct platform_device msp_usbdev_device = {
|
||||
.name = "msp71xx_udc",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &msp_usbdev_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
[2] = { /* MSBus-to-AMBA bridge register space */
|
||||
.start = MSP_USB1_MAB_START,
|
||||
.end = MSP_USB1_MAB_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[3] = { /* Identification and general hardware parameters */
|
||||
.start = MSP_USB1_ID_START,
|
||||
.end = MSP_USB1_ID_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(msp_usbdev_resources),
|
||||
.resource = msp_usbdev_resources,
|
||||
};
|
||||
|
||||
static struct mspusb_device msp_usbhost1_device = {
|
||||
.dev = {
|
||||
.name = "pmcmsp-ehci",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.dma_mask = &msp_usbhost1_dma_mask,
|
||||
.coherent_dma_mask = 0xffffffffUL,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(msp_usbhost1_resources),
|
||||
.resource = msp_usbhost1_resources,
|
||||
},
|
||||
};
|
||||
#endif /* CONFIG_MSP_HAS_DUAL_USB */
|
||||
#endif /* CONFIG_USB_EHCI_HCD */
|
||||
|
||||
#if defined(CONFIG_USB_GADGET)
|
||||
static struct resource msp_usbdev0_resources[] = {
|
||||
[0] = { /* EHCI-HS operational and capabilities registers */
|
||||
.start = MSP_USB0_HS_START,
|
||||
.end = MSP_USB0_HS_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_USB,
|
||||
.end = MSP_INT_USB,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = { /* MSBus-to-AMBA bridge register space */
|
||||
.start = MSP_USB0_MAB_START,
|
||||
.end = MSP_USB0_MAB_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[3] = { /* Identification and general hardware parameters */
|
||||
.start = MSP_USB0_ID_START,
|
||||
.end = MSP_USB0_ID_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static u64 msp_usbdev_dma_mask = 0xffffffffUL;
|
||||
|
||||
/* This may need to be converted to a mspusb_device, too. */
|
||||
static struct mspusb_device msp_usbdev0_device = {
|
||||
.dev = {
|
||||
.name = "msp71xx_udc",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &msp_usbdev_dma_mask,
|
||||
.coherent_dma_mask = 0xffffffffUL,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(msp_usbdev0_resources),
|
||||
.resource = msp_usbdev0_resources,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MSP_HAS_DUAL_USB
|
||||
static struct resource msp_usbdev1_resources[] = {
|
||||
[0] = { /* EHCI-HS operational and capabilities registers */
|
||||
.start = MSP_USB1_HS_START,
|
||||
.end = MSP_USB1_HS_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = MSP_INT_USB,
|
||||
.end = MSP_INT_USB,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = { /* MSBus-to-AMBA bridge register space */
|
||||
.start = MSP_USB1_MAB_START,
|
||||
.end = MSP_USB1_MAB_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[3] = { /* Identification and general hardware parameters */
|
||||
.start = MSP_USB1_ID_START,
|
||||
.end = MSP_USB1_ID_END,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
/* This may need to be converted to a mspusb_device, too. */
|
||||
static struct mspusb_device msp_usbdev1_device = {
|
||||
.dev = {
|
||||
.name = "msp71xx_udc",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &msp_usbdev_dma_mask,
|
||||
.coherent_dma_mask = 0xffffffffUL,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(msp_usbdev1_resources),
|
||||
.resource = msp_usbdev1_resources,
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* CONFIG_MSP_HAS_DUAL_USB */
|
||||
#endif /* CONFIG_USB_GADGET */
|
||||
|
||||
#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
|
||||
static struct platform_device *msp_devs[1];
|
||||
#endif
|
||||
|
||||
|
||||
static int __init msp_usb_setup(void)
|
||||
{
|
||||
#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
|
||||
char *strp;
|
||||
char envstr[32];
|
||||
unsigned int val = 0;
|
||||
int result = 0;
|
||||
char *strp;
|
||||
char envstr[32];
|
||||
struct platform_device *msp_devs[NUM_USB_DEVS];
|
||||
unsigned int val;
|
||||
|
||||
/* construct environment name usbmode */
|
||||
/* set usbmode <host/device> as pmon environment var */
|
||||
/*
|
||||
* construct environment name usbmode
|
||||
* set usbmode <host/device> as pmon environment var
|
||||
* Could this perhaps be integrated into the "features" env var?
|
||||
* Use the features key "U", and follow with "H" for host-mode,
|
||||
* "D" for device-mode. If it works for Ethernet, why not USB...
|
||||
* -- hammtrev, 2007/03/22
|
||||
*/
|
||||
snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
|
||||
|
||||
#if defined(CONFIG_USB_EHCI_HCD)
|
||||
/* default to host mode */
|
||||
/* set default host mode */
|
||||
val = 1;
|
||||
#endif
|
||||
|
||||
/* get environment string */
|
||||
strp = prom_getenv((char *)&envstr[0]);
|
||||
if (strp) {
|
||||
/* compare string */
|
||||
if (!strcmp(strp, "device"))
|
||||
val = 0;
|
||||
}
|
||||
|
||||
if (val) {
|
||||
#if defined(CONFIG_USB_EHCI_HCD)
|
||||
/* get host mode device */
|
||||
msp_devs[0] = &msp_usbhost_device;
|
||||
ppfinit("platform add USB HOST done %s.\n",
|
||||
msp_devs[0]->name);
|
||||
|
||||
result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
|
||||
#endif /* CONFIG_USB_EHCI_HCD */
|
||||
}
|
||||
msp_devs[0] = &msp_usbhost0_device.dev;
|
||||
ppfinit("platform add USB HOST done %s.\n", msp_devs[0]->name);
|
||||
#ifdef CONFIG_MSP_HAS_DUAL_USB
|
||||
msp_devs[1] = &msp_usbhost1_device.dev;
|
||||
ppfinit("platform add USB HOST done %s.\n", msp_devs[1]->name);
|
||||
#endif
|
||||
#else
|
||||
ppfinit("%s: echi_hcd not supported\n", __FILE__);
|
||||
#endif /* CONFIG_USB_EHCI_HCD */
|
||||
} else {
|
||||
#if defined(CONFIG_USB_GADGET)
|
||||
else {
|
||||
/* get device mode structure */
|
||||
msp_devs[0] = &msp_usbdev_device;
|
||||
ppfinit("platform add USB DEVICE done %s.\n",
|
||||
msp_devs[0]->name);
|
||||
|
||||
result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
|
||||
msp_devs[0] = &msp_usbdev0_device.dev;
|
||||
ppfinit("platform add USB DEVICE done %s.\n"
|
||||
, msp_devs[0]->name);
|
||||
#ifdef CONFIG_MSP_HAS_DUAL_USB
|
||||
msp_devs[1] = &msp_usbdev1_device.dev;
|
||||
ppfinit("platform add USB DEVICE done %s.\n"
|
||||
, msp_devs[1]->name);
|
||||
#endif
|
||||
#else
|
||||
ppfinit("%s: usb_gadget not supported\n", __FILE__);
|
||||
#endif /* CONFIG_USB_GADGET */
|
||||
}
|
||||
#endif /* CONFIG_USB_GADGET */
|
||||
#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */
|
||||
/* add device */
|
||||
platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
|
||||
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(msp_usb_setup);
|
||||
#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */
|
||||
|
@ -152,10 +152,6 @@ static inline void pnx833x_hard_disable_pic_irq(unsigned int irq)
|
||||
PNX833X_PIC_INT_REG(irq) = 0;
|
||||
}
|
||||
|
||||
static int irqflags[PNX833X_PIC_NUM_IRQ]; /* initialized by zeroes */
|
||||
#define IRQFLAG_STARTED 1
|
||||
#define IRQFLAG_DISABLED 2
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
|
||||
|
||||
static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
|
||||
@ -164,108 +160,54 @@ static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
|
||||
unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
|
||||
|
||||
raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
|
||||
|
||||
irqflags[pic_irq] = IRQFLAG_STARTED; /* started, not disabled */
|
||||
pnx833x_hard_enable_pic_irq(pic_irq);
|
||||
|
||||
raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pnx833x_shutdown_pic_irq(unsigned int irq)
|
||||
static void pnx833x_enable_pic_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
|
||||
unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE;
|
||||
|
||||
raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
|
||||
pnx833x_hard_enable_pic_irq(pic_irq);
|
||||
raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
irqflags[pic_irq] = 0; /* not started */
|
||||
static void pnx833x_disable_pic_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE;
|
||||
|
||||
raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
|
||||
pnx833x_hard_disable_pic_irq(pic_irq);
|
||||
|
||||
raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void pnx833x_enable_pic_irq(unsigned int irq)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
|
||||
|
||||
raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
|
||||
|
||||
irqflags[pic_irq] &= ~IRQFLAG_DISABLED;
|
||||
if (irqflags[pic_irq] == IRQFLAG_STARTED)
|
||||
pnx833x_hard_enable_pic_irq(pic_irq);
|
||||
|
||||
raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void pnx833x_disable_pic_irq(unsigned int irq)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
|
||||
|
||||
raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
|
||||
|
||||
irqflags[pic_irq] |= IRQFLAG_DISABLED;
|
||||
pnx833x_hard_disable_pic_irq(pic_irq);
|
||||
|
||||
raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void pnx833x_ack_pic_irq(unsigned int irq)
|
||||
{
|
||||
}
|
||||
|
||||
static void pnx833x_end_pic_irq(unsigned int irq)
|
||||
{
|
||||
}
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
|
||||
|
||||
static unsigned int pnx833x_startup_gpio_irq(unsigned int irq)
|
||||
static void pnx833x_enable_gpio_irq(struct irq_data *d)
|
||||
{
|
||||
int pin = irq - PNX833X_GPIO_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
pnx833x_gpio_enable_irq(pin);
|
||||
raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pnx833x_enable_gpio_irq(unsigned int irq)
|
||||
{
|
||||
int pin = irq - PNX833X_GPIO_IRQ_BASE;
|
||||
int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
pnx833x_gpio_enable_irq(pin);
|
||||
raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void pnx833x_disable_gpio_irq(unsigned int irq)
|
||||
static void pnx833x_disable_gpio_irq(struct irq_data *d)
|
||||
{
|
||||
int pin = irq - PNX833X_GPIO_IRQ_BASE;
|
||||
int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
pnx833x_gpio_disable_irq(pin);
|
||||
raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
static void pnx833x_ack_gpio_irq(unsigned int irq)
|
||||
static int pnx833x_set_type_gpio_irq(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
}
|
||||
|
||||
static void pnx833x_end_gpio_irq(unsigned int irq)
|
||||
{
|
||||
int pin = irq - PNX833X_GPIO_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
pnx833x_gpio_clear_irq(pin);
|
||||
raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
|
||||
}
|
||||
|
||||
static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
|
||||
{
|
||||
int pin = irq - PNX833X_GPIO_IRQ_BASE;
|
||||
int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
|
||||
int gpio_mode;
|
||||
|
||||
switch (flow_type) {
|
||||
@ -296,23 +238,15 @@ static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type)
|
||||
|
||||
static struct irq_chip pnx833x_pic_irq_type = {
|
||||
.name = "PNX-PIC",
|
||||
.startup = pnx833x_startup_pic_irq,
|
||||
.shutdown = pnx833x_shutdown_pic_irq,
|
||||
.enable = pnx833x_enable_pic_irq,
|
||||
.disable = pnx833x_disable_pic_irq,
|
||||
.ack = pnx833x_ack_pic_irq,
|
||||
.end = pnx833x_end_pic_irq
|
||||
.irq_enable = pnx833x_enable_pic_irq,
|
||||
.irq_disable = pnx833x_disable_pic_irq,
|
||||
};
|
||||
|
||||
static struct irq_chip pnx833x_gpio_irq_type = {
|
||||
.name = "PNX-GPIO",
|
||||
.startup = pnx833x_startup_gpio_irq,
|
||||
.shutdown = pnx833x_disable_gpio_irq,
|
||||
.enable = pnx833x_enable_gpio_irq,
|
||||
.disable = pnx833x_disable_gpio_irq,
|
||||
.ack = pnx833x_ack_gpio_irq,
|
||||
.end = pnx833x_end_gpio_irq,
|
||||
.set_type = pnx833x_set_type_gpio_irq
|
||||
.irq_enable = pnx833x_enable_gpio_irq,
|
||||
.irq_disable = pnx833x_disable_gpio_irq,
|
||||
.irq_set_type = pnx833x_set_type_gpio_irq,
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
|
@ -114,8 +114,10 @@ static inline void unmask_gic_int(unsigned int irq_nr)
|
||||
PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
|
||||
}
|
||||
|
||||
static inline void mask_irq(unsigned int irq_nr)
|
||||
static inline void mask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = d->irq;
|
||||
|
||||
if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
|
||||
modify_cp0_intmask(1 << irq_nr, 0);
|
||||
} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
|
||||
@ -129,8 +131,10 @@ static inline void mask_irq(unsigned int irq_nr)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void unmask_irq(unsigned int irq_nr)
|
||||
static inline void unmask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = d->irq;
|
||||
|
||||
if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
|
||||
modify_cp0_intmask(0, 1 << irq_nr);
|
||||
} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
|
||||
@ -157,10 +161,8 @@ int pnx8550_set_gic_priority(int irq, int priority)
|
||||
|
||||
static struct irq_chip level_irq_type = {
|
||||
.name = "PNX Level IRQ",
|
||||
.ack = mask_irq,
|
||||
.mask = mask_irq,
|
||||
.mask_ack = mask_irq,
|
||||
.unmask = unmask_irq,
|
||||
.irq_mask = mask_irq,
|
||||
.irq_unmask = unmask_irq,
|
||||
};
|
||||
|
||||
static struct irqaction gic_action = {
|
||||
@ -180,10 +182,8 @@ void __init arch_init_irq(void)
|
||||
int i;
|
||||
int configPR;
|
||||
|
||||
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
|
||||
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++)
|
||||
set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
|
||||
mask_irq(i); /* mask the irq just in case */
|
||||
}
|
||||
|
||||
/* init of GIC/IPC interrupts */
|
||||
/* should be done before cp0 since cp0 init enables the GIC int */
|
||||
|
@ -21,9 +21,10 @@
|
||||
|
||||
#include <asm/mach-powertv/asic_regs.h>
|
||||
|
||||
static inline void unmask_asic_irq(unsigned int irq)
|
||||
static inline void unmask_asic_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long enable_bit;
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
enable_bit = (1 << (irq & 0x1f));
|
||||
|
||||
@ -45,9 +46,10 @@ static inline void unmask_asic_irq(unsigned int irq)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mask_asic_irq(unsigned int irq)
|
||||
static inline void mask_asic_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long disable_mask;
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
disable_mask = ~(1 << (irq & 0x1f));
|
||||
|
||||
@ -71,11 +73,8 @@ static inline void mask_asic_irq(unsigned int irq)
|
||||
|
||||
static struct irq_chip asic_irq_chip = {
|
||||
.name = "ASIC Level",
|
||||
.ack = mask_asic_irq,
|
||||
.mask = mask_asic_irq,
|
||||
.mask_ack = mask_asic_irq,
|
||||
.unmask = unmask_asic_irq,
|
||||
.eoi = unmask_asic_irq,
|
||||
.irq_mask = mask_asic_irq,
|
||||
.irq_unmask = unmask_asic_irq,
|
||||
};
|
||||
|
||||
void __init asic_irq_init(void)
|
||||
|
@ -111,10 +111,10 @@ static inline void ack_local_irq(unsigned int ip)
|
||||
clear_c0_cause(ipnum);
|
||||
}
|
||||
|
||||
static void rb532_enable_irq(unsigned int irq_nr)
|
||||
static void rb532_enable_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int group, intr_bit, irq_nr = d->irq;
|
||||
int ip = irq_nr - GROUP0_IRQ_BASE;
|
||||
unsigned int group, intr_bit;
|
||||
volatile unsigned int *addr;
|
||||
|
||||
if (ip < 0)
|
||||
@ -132,10 +132,10 @@ static void rb532_enable_irq(unsigned int irq_nr)
|
||||
}
|
||||
}
|
||||
|
||||
static void rb532_disable_irq(unsigned int irq_nr)
|
||||
static void rb532_disable_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int group, intr_bit, mask, irq_nr = d->irq;
|
||||
int ip = irq_nr - GROUP0_IRQ_BASE;
|
||||
unsigned int group, intr_bit, mask;
|
||||
volatile unsigned int *addr;
|
||||
|
||||
if (ip < 0) {
|
||||
@ -163,18 +163,18 @@ static void rb532_disable_irq(unsigned int irq_nr)
|
||||
}
|
||||
}
|
||||
|
||||
static void rb532_mask_and_ack_irq(unsigned int irq_nr)
|
||||
static void rb532_mask_and_ack_irq(struct irq_data *d)
|
||||
{
|
||||
rb532_disable_irq(irq_nr);
|
||||
ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
|
||||
rb532_disable_irq(d);
|
||||
ack_local_irq(group_to_ip(irq_to_group(d->irq)));
|
||||
}
|
||||
|
||||
static int rb532_set_type(unsigned int irq_nr, unsigned type)
|
||||
static int rb532_set_type(struct irq_data *d, unsigned type)
|
||||
{
|
||||
int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE;
|
||||
int group = irq_to_group(irq_nr);
|
||||
int gpio = d->irq - GPIO_MAPPED_IRQ_BASE;
|
||||
int group = irq_to_group(d->irq);
|
||||
|
||||
if (group != GPIO_MAPPED_IRQ_GROUP || irq_nr > (GROUP4_IRQ_BASE + 13))
|
||||
if (group != GPIO_MAPPED_IRQ_GROUP || d->irq > (GROUP4_IRQ_BASE + 13))
|
||||
return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
|
||||
|
||||
switch (type) {
|
||||
@ -193,11 +193,11 @@ static int rb532_set_type(unsigned int irq_nr, unsigned type)
|
||||
|
||||
static struct irq_chip rc32434_irq_type = {
|
||||
.name = "RB532",
|
||||
.ack = rb532_disable_irq,
|
||||
.mask = rb532_disable_irq,
|
||||
.mask_ack = rb532_mask_and_ack_irq,
|
||||
.unmask = rb532_enable_irq,
|
||||
.set_type = rb532_set_type,
|
||||
.irq_ack = rb532_disable_irq,
|
||||
.irq_mask = rb532_disable_irq,
|
||||
.irq_mask_ack = rb532_mask_and_ack_irq,
|
||||
.irq_unmask = rb532_enable_irq,
|
||||
.irq_set_type = rb532_set_type,
|
||||
};
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
|
@ -31,88 +31,80 @@ static char lc3msk_to_irqnr[256];
|
||||
|
||||
extern int ip22_eisa_init(void);
|
||||
|
||||
static void enable_local0_irq(unsigned int irq)
|
||||
static void enable_local0_irq(struct irq_data *d)
|
||||
{
|
||||
/* don't allow mappable interrupt to be enabled from setup_irq,
|
||||
* we have our own way to do so */
|
||||
if (irq != SGI_MAP_0_IRQ)
|
||||
sgint->imask0 |= (1 << (irq - SGINT_LOCAL0));
|
||||
if (d->irq != SGI_MAP_0_IRQ)
|
||||
sgint->imask0 |= (1 << (d->irq - SGINT_LOCAL0));
|
||||
}
|
||||
|
||||
static void disable_local0_irq(unsigned int irq)
|
||||
static void disable_local0_irq(struct irq_data *d)
|
||||
{
|
||||
sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
|
||||
sgint->imask0 &= ~(1 << (d->irq - SGINT_LOCAL0));
|
||||
}
|
||||
|
||||
static struct irq_chip ip22_local0_irq_type = {
|
||||
.name = "IP22 local 0",
|
||||
.ack = disable_local0_irq,
|
||||
.mask = disable_local0_irq,
|
||||
.mask_ack = disable_local0_irq,
|
||||
.unmask = enable_local0_irq,
|
||||
.irq_mask = disable_local0_irq,
|
||||
.irq_unmask = enable_local0_irq,
|
||||
};
|
||||
|
||||
static void enable_local1_irq(unsigned int irq)
|
||||
static void enable_local1_irq(struct irq_data *d)
|
||||
{
|
||||
/* don't allow mappable interrupt to be enabled from setup_irq,
|
||||
* we have our own way to do so */
|
||||
if (irq != SGI_MAP_1_IRQ)
|
||||
sgint->imask1 |= (1 << (irq - SGINT_LOCAL1));
|
||||
if (d->irq != SGI_MAP_1_IRQ)
|
||||
sgint->imask1 |= (1 << (d->irq - SGINT_LOCAL1));
|
||||
}
|
||||
|
||||
static void disable_local1_irq(unsigned int irq)
|
||||
static void disable_local1_irq(struct irq_data *d)
|
||||
{
|
||||
sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
|
||||
sgint->imask1 &= ~(1 << (d->irq - SGINT_LOCAL1));
|
||||
}
|
||||
|
||||
static struct irq_chip ip22_local1_irq_type = {
|
||||
.name = "IP22 local 1",
|
||||
.ack = disable_local1_irq,
|
||||
.mask = disable_local1_irq,
|
||||
.mask_ack = disable_local1_irq,
|
||||
.unmask = enable_local1_irq,
|
||||
.irq_mask = disable_local1_irq,
|
||||
.irq_unmask = enable_local1_irq,
|
||||
};
|
||||
|
||||
static void enable_local2_irq(unsigned int irq)
|
||||
static void enable_local2_irq(struct irq_data *d)
|
||||
{
|
||||
sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
|
||||
sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
|
||||
sgint->cmeimask0 |= (1 << (d->irq - SGINT_LOCAL2));
|
||||
}
|
||||
|
||||
static void disable_local2_irq(unsigned int irq)
|
||||
static void disable_local2_irq(struct irq_data *d)
|
||||
{
|
||||
sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
|
||||
sgint->cmeimask0 &= ~(1 << (d->irq - SGINT_LOCAL2));
|
||||
if (!sgint->cmeimask0)
|
||||
sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
|
||||
}
|
||||
|
||||
static struct irq_chip ip22_local2_irq_type = {
|
||||
.name = "IP22 local 2",
|
||||
.ack = disable_local2_irq,
|
||||
.mask = disable_local2_irq,
|
||||
.mask_ack = disable_local2_irq,
|
||||
.unmask = enable_local2_irq,
|
||||
.irq_mask = disable_local2_irq,
|
||||
.irq_unmask = enable_local2_irq,
|
||||
};
|
||||
|
||||
static void enable_local3_irq(unsigned int irq)
|
||||
static void enable_local3_irq(struct irq_data *d)
|
||||
{
|
||||
sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
|
||||
sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
|
||||
sgint->cmeimask1 |= (1 << (d->irq - SGINT_LOCAL3));
|
||||
}
|
||||
|
||||
static void disable_local3_irq(unsigned int irq)
|
||||
static void disable_local3_irq(struct irq_data *d)
|
||||
{
|
||||
sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
|
||||
sgint->cmeimask1 &= ~(1 << (d->irq - SGINT_LOCAL3));
|
||||
if (!sgint->cmeimask1)
|
||||
sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
|
||||
}
|
||||
|
||||
static struct irq_chip ip22_local3_irq_type = {
|
||||
.name = "IP22 local 3",
|
||||
.ack = disable_local3_irq,
|
||||
.mask = disable_local3_irq,
|
||||
.mask_ack = disable_local3_irq,
|
||||
.unmask = enable_local3_irq,
|
||||
.irq_mask = disable_local3_irq,
|
||||
.irq_unmask = enable_local3_irq,
|
||||
};
|
||||
|
||||
static void indy_local0_irqdispatch(void)
|
||||
|
@ -240,7 +240,7 @@ static int intr_disconnect_level(int cpu, int bit)
|
||||
}
|
||||
|
||||
/* Startup one of the (PCI ...) IRQs routes over a bridge. */
|
||||
static unsigned int startup_bridge_irq(unsigned int irq)
|
||||
static unsigned int startup_bridge_irq(struct irq_data *d)
|
||||
{
|
||||
struct bridge_controller *bc;
|
||||
bridgereg_t device;
|
||||
@ -248,16 +248,16 @@ static unsigned int startup_bridge_irq(unsigned int irq)
|
||||
int pin, swlevel;
|
||||
cpuid_t cpu;
|
||||
|
||||
pin = SLOT_FROM_PCI_IRQ(irq);
|
||||
bc = IRQ_TO_BRIDGE(irq);
|
||||
pin = SLOT_FROM_PCI_IRQ(d->irq);
|
||||
bc = IRQ_TO_BRIDGE(d->irq);
|
||||
bridge = bc->base;
|
||||
|
||||
pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin);
|
||||
pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
|
||||
/*
|
||||
* "map" irq to a swlevel greater than 6 since the first 6 bits
|
||||
* of INT_PEND0 are taken
|
||||
*/
|
||||
swlevel = find_level(&cpu, irq);
|
||||
swlevel = find_level(&cpu, d->irq);
|
||||
bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
|
||||
bridge->b_int_enable |= (1 << pin);
|
||||
bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
|
||||
@ -288,53 +288,51 @@ static unsigned int startup_bridge_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
|
||||
static void shutdown_bridge_irq(unsigned int irq)
|
||||
static void shutdown_bridge_irq(struct irq_data *d)
|
||||
{
|
||||
struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
|
||||
struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
|
||||
bridge_t *bridge = bc->base;
|
||||
int pin, swlevel;
|
||||
cpuid_t cpu;
|
||||
|
||||
pr_debug("bridge_shutdown: irq 0x%x\n", irq);
|
||||
pin = SLOT_FROM_PCI_IRQ(irq);
|
||||
pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
|
||||
pin = SLOT_FROM_PCI_IRQ(d->irq);
|
||||
|
||||
/*
|
||||
* map irq to a swlevel greater than 6 since the first 6 bits
|
||||
* of INT_PEND0 are taken
|
||||
*/
|
||||
swlevel = find_level(&cpu, irq);
|
||||
swlevel = find_level(&cpu, d->irq);
|
||||
intr_disconnect_level(cpu, swlevel);
|
||||
|
||||
bridge->b_int_enable &= ~(1 << pin);
|
||||
bridge->b_wid_tflush;
|
||||
}
|
||||
|
||||
static inline void enable_bridge_irq(unsigned int irq)
|
||||
static inline void enable_bridge_irq(struct irq_data *d)
|
||||
{
|
||||
cpuid_t cpu;
|
||||
int swlevel;
|
||||
|
||||
swlevel = find_level(&cpu, irq); /* Criminal offence */
|
||||
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
|
||||
intr_connect_level(cpu, swlevel);
|
||||
}
|
||||
|
||||
static inline void disable_bridge_irq(unsigned int irq)
|
||||
static inline void disable_bridge_irq(struct irq_data *d)
|
||||
{
|
||||
cpuid_t cpu;
|
||||
int swlevel;
|
||||
|
||||
swlevel = find_level(&cpu, irq); /* Criminal offence */
|
||||
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
|
||||
intr_disconnect_level(cpu, swlevel);
|
||||
}
|
||||
|
||||
static struct irq_chip bridge_irq_type = {
|
||||
.name = "bridge",
|
||||
.startup = startup_bridge_irq,
|
||||
.shutdown = shutdown_bridge_irq,
|
||||
.ack = disable_bridge_irq,
|
||||
.mask = disable_bridge_irq,
|
||||
.mask_ack = disable_bridge_irq,
|
||||
.unmask = enable_bridge_irq,
|
||||
.irq_startup = startup_bridge_irq,
|
||||
.irq_shutdown = shutdown_bridge_irq,
|
||||
.irq_mask = disable_bridge_irq,
|
||||
.irq_unmask = enable_bridge_irq,
|
||||
};
|
||||
|
||||
void __devinit register_bridge_irq(unsigned int irq)
|
||||
|
@ -36,21 +36,18 @@
|
||||
#include <asm/sn/sn0/hubio.h>
|
||||
#include <asm/pci/bridge.h>
|
||||
|
||||
static void enable_rt_irq(unsigned int irq)
|
||||
static void enable_rt_irq(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static void disable_rt_irq(unsigned int irq)
|
||||
static void disable_rt_irq(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static struct irq_chip rt_irq_type = {
|
||||
.name = "SN HUB RT timer",
|
||||
.ack = disable_rt_irq,
|
||||
.mask = disable_rt_irq,
|
||||
.mask_ack = disable_rt_irq,
|
||||
.unmask = enable_rt_irq,
|
||||
.eoi = enable_rt_irq,
|
||||
.irq_mask = disable_rt_irq,
|
||||
.irq_unmask = enable_rt_irq,
|
||||
};
|
||||
|
||||
static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
|
||||
|
@ -130,70 +130,48 @@ static struct irqaction cpuerr_irq = {
|
||||
|
||||
static uint64_t crime_mask;
|
||||
|
||||
static inline void crime_enable_irq(unsigned int irq)
|
||||
static inline void crime_enable_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq - CRIME_IRQ_BASE;
|
||||
unsigned int bit = d->irq - CRIME_IRQ_BASE;
|
||||
|
||||
crime_mask |= 1 << bit;
|
||||
crime->imask = crime_mask;
|
||||
}
|
||||
|
||||
static inline void crime_disable_irq(unsigned int irq)
|
||||
static inline void crime_disable_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq - CRIME_IRQ_BASE;
|
||||
unsigned int bit = d->irq - CRIME_IRQ_BASE;
|
||||
|
||||
crime_mask &= ~(1 << bit);
|
||||
crime->imask = crime_mask;
|
||||
flush_crime_bus();
|
||||
}
|
||||
|
||||
static void crime_level_mask_and_ack_irq(unsigned int irq)
|
||||
{
|
||||
crime_disable_irq(irq);
|
||||
}
|
||||
|
||||
static void crime_level_end_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
crime_enable_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip crime_level_interrupt = {
|
||||
.name = "IP32 CRIME",
|
||||
.ack = crime_level_mask_and_ack_irq,
|
||||
.mask = crime_disable_irq,
|
||||
.mask_ack = crime_level_mask_and_ack_irq,
|
||||
.unmask = crime_enable_irq,
|
||||
.end = crime_level_end_irq,
|
||||
.irq_mask = crime_disable_irq,
|
||||
.irq_unmask = crime_enable_irq,
|
||||
};
|
||||
|
||||
static void crime_edge_mask_and_ack_irq(unsigned int irq)
|
||||
static void crime_edge_mask_and_ack_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq - CRIME_IRQ_BASE;
|
||||
unsigned int bit = d->irq - CRIME_IRQ_BASE;
|
||||
uint64_t crime_int;
|
||||
|
||||
/* Edge triggered interrupts must be cleared. */
|
||||
|
||||
crime_int = crime->hard_int;
|
||||
crime_int &= ~(1 << bit);
|
||||
crime->hard_int = crime_int;
|
||||
|
||||
crime_disable_irq(irq);
|
||||
}
|
||||
|
||||
static void crime_edge_end_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
crime_enable_irq(irq);
|
||||
crime_disable_irq(d);
|
||||
}
|
||||
|
||||
static struct irq_chip crime_edge_interrupt = {
|
||||
.name = "IP32 CRIME",
|
||||
.ack = crime_edge_mask_and_ack_irq,
|
||||
.mask = crime_disable_irq,
|
||||
.mask_ack = crime_edge_mask_and_ack_irq,
|
||||
.unmask = crime_enable_irq,
|
||||
.end = crime_edge_end_irq,
|
||||
.irq_ack = crime_edge_mask_and_ack_irq,
|
||||
.irq_mask = crime_disable_irq,
|
||||
.irq_mask_ack = crime_edge_mask_and_ack_irq,
|
||||
.irq_unmask = crime_enable_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -204,37 +182,28 @@ static struct irq_chip crime_edge_interrupt = {
|
||||
|
||||
static unsigned long macepci_mask;
|
||||
|
||||
static void enable_macepci_irq(unsigned int irq)
|
||||
static void enable_macepci_irq(struct irq_data *d)
|
||||
{
|
||||
macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
|
||||
macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
|
||||
mace->pci.control = macepci_mask;
|
||||
crime_mask |= 1 << (irq - CRIME_IRQ_BASE);
|
||||
crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
|
||||
crime->imask = crime_mask;
|
||||
}
|
||||
|
||||
static void disable_macepci_irq(unsigned int irq)
|
||||
static void disable_macepci_irq(struct irq_data *d)
|
||||
{
|
||||
crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE));
|
||||
crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
|
||||
crime->imask = crime_mask;
|
||||
flush_crime_bus();
|
||||
macepci_mask &= ~MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
|
||||
macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
|
||||
mace->pci.control = macepci_mask;
|
||||
flush_mace_bus();
|
||||
}
|
||||
|
||||
static void end_macepci_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_macepci_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip ip32_macepci_interrupt = {
|
||||
.name = "IP32 MACE PCI",
|
||||
.ack = disable_macepci_irq,
|
||||
.mask = disable_macepci_irq,
|
||||
.mask_ack = disable_macepci_irq,
|
||||
.unmask = enable_macepci_irq,
|
||||
.end = end_macepci_irq,
|
||||
.irq_mask = disable_macepci_irq,
|
||||
.irq_unmask = enable_macepci_irq,
|
||||
};
|
||||
|
||||
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
|
||||
@ -276,13 +245,13 @@ static struct irq_chip ip32_macepci_interrupt = {
|
||||
|
||||
static unsigned long maceisa_mask;
|
||||
|
||||
static void enable_maceisa_irq(unsigned int irq)
|
||||
static void enable_maceisa_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int crime_int = 0;
|
||||
|
||||
pr_debug("maceisa enable: %u\n", irq);
|
||||
pr_debug("maceisa enable: %u\n", d->irq);
|
||||
|
||||
switch (irq) {
|
||||
switch (d->irq) {
|
||||
case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
|
||||
crime_int = MACE_AUDIO_INT;
|
||||
break;
|
||||
@ -296,15 +265,15 @@ static void enable_maceisa_irq(unsigned int irq)
|
||||
pr_debug("crime_int %08x enabled\n", crime_int);
|
||||
crime_mask |= crime_int;
|
||||
crime->imask = crime_mask;
|
||||
maceisa_mask |= 1 << (irq - MACEISA_AUDIO_SW_IRQ);
|
||||
maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
|
||||
mace->perif.ctrl.imask = maceisa_mask;
|
||||
}
|
||||
|
||||
static void disable_maceisa_irq(unsigned int irq)
|
||||
static void disable_maceisa_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int crime_int = 0;
|
||||
|
||||
maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
|
||||
maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
|
||||
if (!(maceisa_mask & MACEISA_AUDIO_INT))
|
||||
crime_int |= MACE_AUDIO_INT;
|
||||
if (!(maceisa_mask & MACEISA_MISC_INT))
|
||||
@ -318,76 +287,57 @@ static void disable_maceisa_irq(unsigned int irq)
|
||||
flush_mace_bus();
|
||||
}
|
||||
|
||||
static void mask_and_ack_maceisa_irq(unsigned int irq)
|
||||
static void mask_and_ack_maceisa_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned long mace_int;
|
||||
|
||||
/* edge triggered */
|
||||
mace_int = mace->perif.ctrl.istat;
|
||||
mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
|
||||
mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
|
||||
mace->perif.ctrl.istat = mace_int;
|
||||
|
||||
disable_maceisa_irq(irq);
|
||||
}
|
||||
|
||||
static void end_maceisa_irq(unsigned irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
enable_maceisa_irq(irq);
|
||||
disable_maceisa_irq(d);
|
||||
}
|
||||
|
||||
static struct irq_chip ip32_maceisa_level_interrupt = {
|
||||
.name = "IP32 MACE ISA",
|
||||
.ack = disable_maceisa_irq,
|
||||
.mask = disable_maceisa_irq,
|
||||
.mask_ack = disable_maceisa_irq,
|
||||
.unmask = enable_maceisa_irq,
|
||||
.end = end_maceisa_irq,
|
||||
.irq_mask = disable_maceisa_irq,
|
||||
.irq_unmask = enable_maceisa_irq,
|
||||
};
|
||||
|
||||
static struct irq_chip ip32_maceisa_edge_interrupt = {
|
||||
.name = "IP32 MACE ISA",
|
||||
.ack = mask_and_ack_maceisa_irq,
|
||||
.mask = disable_maceisa_irq,
|
||||
.mask_ack = mask_and_ack_maceisa_irq,
|
||||
.unmask = enable_maceisa_irq,
|
||||
.end = end_maceisa_irq,
|
||||
.irq_ack = mask_and_ack_maceisa_irq,
|
||||
.irq_mask = disable_maceisa_irq,
|
||||
.irq_mask_ack = mask_and_ack_maceisa_irq,
|
||||
.irq_unmask = enable_maceisa_irq,
|
||||
};
|
||||
|
||||
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
|
||||
* bits 0-3 and 7 in the CRIME register.
|
||||
*/
|
||||
|
||||
static void enable_mace_irq(unsigned int irq)
|
||||
static void enable_mace_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq - CRIME_IRQ_BASE;
|
||||
unsigned int bit = d->irq - CRIME_IRQ_BASE;
|
||||
|
||||
crime_mask |= (1 << bit);
|
||||
crime->imask = crime_mask;
|
||||
}
|
||||
|
||||
static void disable_mace_irq(unsigned int irq)
|
||||
static void disable_mace_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int bit = irq - CRIME_IRQ_BASE;
|
||||
unsigned int bit = d->irq - CRIME_IRQ_BASE;
|
||||
|
||||
crime_mask &= ~(1 << bit);
|
||||
crime->imask = crime_mask;
|
||||
flush_crime_bus();
|
||||
}
|
||||
|
||||
static void end_mace_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_mace_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip ip32_mace_interrupt = {
|
||||
.name = "IP32 MACE",
|
||||
.ack = disable_mace_irq,
|
||||
.mask = disable_mace_irq,
|
||||
.mask_ack = disable_mace_irq,
|
||||
.unmask = enable_mace_irq,
|
||||
.end = end_mace_irq,
|
||||
.irq_mask = disable_mace_irq,
|
||||
.irq_unmask = enable_mace_irq,
|
||||
};
|
||||
|
||||
static void ip32_unknown_interrupt(void)
|
||||
|
@ -44,31 +44,10 @@
|
||||
* for interrupt lines
|
||||
*/
|
||||
|
||||
|
||||
static void end_bcm1480_irq(unsigned int irq);
|
||||
static void enable_bcm1480_irq(unsigned int irq);
|
||||
static void disable_bcm1480_irq(unsigned int irq);
|
||||
static void ack_bcm1480_irq(unsigned int irq);
|
||||
#ifdef CONFIG_SMP
|
||||
static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern unsigned long ht_eoi_space;
|
||||
#endif
|
||||
|
||||
static struct irq_chip bcm1480_irq_type = {
|
||||
.name = "BCM1480-IMR",
|
||||
.ack = ack_bcm1480_irq,
|
||||
.mask = disable_bcm1480_irq,
|
||||
.mask_ack = ack_bcm1480_irq,
|
||||
.unmask = enable_bcm1480_irq,
|
||||
.end = end_bcm1480_irq,
|
||||
#ifdef CONFIG_SMP
|
||||
.set_affinity = bcm1480_set_affinity
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Store the CPU id (not the logical number) */
|
||||
int bcm1480_irq_owner[BCM1480_NR_IRQS];
|
||||
|
||||
@ -109,12 +88,13 @@ void bcm1480_unmask_irq(int cpu, int irq)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||
static int bcm1480_set_affinity(struct irq_data *d, const struct cpumask *mask,
|
||||
bool force)
|
||||
{
|
||||
unsigned int irq_dirty, irq = d->irq;
|
||||
int i = 0, old_cpu, cpu, int_on, k;
|
||||
u64 cur_ints;
|
||||
unsigned long flags;
|
||||
unsigned int irq_dirty;
|
||||
|
||||
i = cpumask_first(mask);
|
||||
|
||||
@ -156,21 +136,25 @@ static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void disable_bcm1480_irq(unsigned int irq)
|
||||
static void disable_bcm1480_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
|
||||
}
|
||||
|
||||
static void enable_bcm1480_irq(unsigned int irq)
|
||||
static void enable_bcm1480_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
|
||||
}
|
||||
|
||||
|
||||
static void ack_bcm1480_irq(unsigned int irq)
|
||||
static void ack_bcm1480_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_dirty, irq = d->irq;
|
||||
u64 pending;
|
||||
unsigned int irq_dirty;
|
||||
int k;
|
||||
|
||||
/*
|
||||
@ -217,14 +201,15 @@ static void ack_bcm1480_irq(unsigned int irq)
|
||||
bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
|
||||
}
|
||||
|
||||
|
||||
static void end_bcm1480_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
|
||||
bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_chip bcm1480_irq_type = {
|
||||
.name = "BCM1480-IMR",
|
||||
.irq_mask_ack = ack_bcm1480_irq,
|
||||
.irq_mask = disable_bcm1480_irq,
|
||||
.irq_unmask = enable_bcm1480_irq,
|
||||
#ifdef CONFIG_SMP
|
||||
.irq_set_affinity = bcm1480_set_affinity
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init init_bcm1480_irqs(void)
|
||||
{
|
||||
|
@ -43,31 +43,10 @@
|
||||
* for interrupt lines
|
||||
*/
|
||||
|
||||
|
||||
static void end_sb1250_irq(unsigned int irq);
|
||||
static void enable_sb1250_irq(unsigned int irq);
|
||||
static void disable_sb1250_irq(unsigned int irq);
|
||||
static void ack_sb1250_irq(unsigned int irq);
|
||||
#ifdef CONFIG_SMP
|
||||
static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIBYTE_HAS_LDT
|
||||
extern unsigned long ldt_eoi_space;
|
||||
#endif
|
||||
|
||||
static struct irq_chip sb1250_irq_type = {
|
||||
.name = "SB1250-IMR",
|
||||
.ack = ack_sb1250_irq,
|
||||
.mask = disable_sb1250_irq,
|
||||
.mask_ack = ack_sb1250_irq,
|
||||
.unmask = enable_sb1250_irq,
|
||||
.end = end_sb1250_irq,
|
||||
#ifdef CONFIG_SMP
|
||||
.set_affinity = sb1250_set_affinity
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Store the CPU id (not the logical number) */
|
||||
int sb1250_irq_owner[SB1250_NR_IRQS];
|
||||
|
||||
@ -102,9 +81,11 @@ void sb1250_unmask_irq(int cpu, int irq)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||
static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask,
|
||||
bool force)
|
||||
{
|
||||
int i = 0, old_cpu, cpu, int_on;
|
||||
unsigned int irq = d->irq;
|
||||
u64 cur_ints;
|
||||
unsigned long flags;
|
||||
|
||||
@ -142,21 +123,17 @@ static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void disable_sb1250_irq(unsigned int irq)
|
||||
static void enable_sb1250_irq(struct irq_data *d)
|
||||
{
|
||||
sb1250_mask_irq(sb1250_irq_owner[irq], irq);
|
||||
}
|
||||
unsigned int irq = d->irq;
|
||||
|
||||
static void enable_sb1250_irq(unsigned int irq)
|
||||
{
|
||||
sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
|
||||
}
|
||||
|
||||
|
||||
static void ack_sb1250_irq(unsigned int irq)
|
||||
static void ack_sb1250_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq;
|
||||
#ifdef CONFIG_SIBYTE_HAS_LDT
|
||||
u64 pending;
|
||||
|
||||
@ -199,14 +176,14 @@ static void ack_sb1250_irq(unsigned int irq)
|
||||
sb1250_mask_irq(sb1250_irq_owner[irq], irq);
|
||||
}
|
||||
|
||||
|
||||
static void end_sb1250_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
|
||||
sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_chip sb1250_irq_type = {
|
||||
.name = "SB1250-IMR",
|
||||
.irq_mask_ack = ack_sb1250_irq,
|
||||
.irq_unmask = enable_sb1250_irq,
|
||||
#ifdef CONFIG_SMP
|
||||
.irq_set_affinity = sb1250_set_affinity
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init init_sb1250_irqs(void)
|
||||
{
|
||||
|
@ -168,33 +168,22 @@ static u32 a20r_ack_hwint(void)
|
||||
return status;
|
||||
}
|
||||
|
||||
static inline void unmask_a20r_irq(unsigned int irq)
|
||||
static inline void unmask_a20r_irq(struct irq_data *d)
|
||||
{
|
||||
set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
|
||||
set_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE));
|
||||
irq_enable_hazard();
|
||||
}
|
||||
|
||||
static inline void mask_a20r_irq(unsigned int irq)
|
||||
static inline void mask_a20r_irq(struct irq_data *d)
|
||||
{
|
||||
clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE));
|
||||
clear_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE));
|
||||
irq_disable_hazard();
|
||||
}
|
||||
|
||||
static void end_a20r_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
|
||||
a20r_ack_hwint();
|
||||
unmask_a20r_irq(irq);
|
||||
}
|
||||
}
|
||||
|
||||
static struct irq_chip a20r_irq_type = {
|
||||
.name = "A20R",
|
||||
.ack = mask_a20r_irq,
|
||||
.mask = mask_a20r_irq,
|
||||
.mask_ack = mask_a20r_irq,
|
||||
.unmask = unmask_a20r_irq,
|
||||
.end = end_a20r_irq,
|
||||
.irq_mask = mask_a20r_irq,
|
||||
.irq_unmask = unmask_a20r_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -194,33 +194,24 @@ static struct pci_controller sni_controller = {
|
||||
.io_map_base = SNI_PORT_BASE
|
||||
};
|
||||
|
||||
static void enable_pcimt_irq(unsigned int irq)
|
||||
static void enable_pcimt_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
|
||||
unsigned int mask = 1 << (d->irq - PCIMT_IRQ_INT2);
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL |= mask;
|
||||
}
|
||||
|
||||
void disable_pcimt_irq(unsigned int irq)
|
||||
void disable_pcimt_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
|
||||
unsigned int mask = ~(1 << (d->irq - PCIMT_IRQ_INT2));
|
||||
|
||||
*(volatile u8 *) PCIMT_IRQSEL &= mask;
|
||||
}
|
||||
|
||||
static void end_pcimt_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_pcimt_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip pcimt_irq_type = {
|
||||
.name = "PCIMT",
|
||||
.ack = disable_pcimt_irq,
|
||||
.mask = disable_pcimt_irq,
|
||||
.mask_ack = disable_pcimt_irq,
|
||||
.unmask = enable_pcimt_irq,
|
||||
.end = end_pcimt_irq,
|
||||
.irq_mask = disable_pcimt_irq,
|
||||
.irq_unmask = enable_pcimt_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -156,33 +156,24 @@ static struct pci_controller sni_pcit_controller = {
|
||||
.io_map_base = SNI_PORT_BASE
|
||||
};
|
||||
|
||||
static void enable_pcit_irq(unsigned int irq)
|
||||
static void enable_pcit_irq(struct irq_data *d)
|
||||
{
|
||||
u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
|
||||
u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
|
||||
|
||||
*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
|
||||
}
|
||||
|
||||
void disable_pcit_irq(unsigned int irq)
|
||||
void disable_pcit_irq(struct irq_data *d)
|
||||
{
|
||||
u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24);
|
||||
u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
|
||||
|
||||
*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
|
||||
}
|
||||
|
||||
void end_pcit_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_pcit_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip pcit_irq_type = {
|
||||
.name = "PCIT",
|
||||
.ack = disable_pcit_irq,
|
||||
.mask = disable_pcit_irq,
|
||||
.mask_ack = disable_pcit_irq,
|
||||
.unmask = enable_pcit_irq,
|
||||
.end = end_pcit_irq,
|
||||
.irq_mask = disable_pcit_irq,
|
||||
.irq_unmask = enable_pcit_irq,
|
||||
};
|
||||
|
||||
static void pcit_hwint1(void)
|
||||
|
@ -155,12 +155,11 @@ static __iomem u8 *rm200_pic_slave;
|
||||
#define cached_master_mask (rm200_cached_irq_mask)
|
||||
#define cached_slave_mask (rm200_cached_irq_mask >> 8)
|
||||
|
||||
static void sni_rm200_disable_8259A_irq(unsigned int irq)
|
||||
static void sni_rm200_disable_8259A_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
|
||||
irq -= RM200_I8259A_IRQ_BASE;
|
||||
mask = 1 << irq;
|
||||
raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
|
||||
rm200_cached_irq_mask |= mask;
|
||||
@ -171,12 +170,11 @@ static void sni_rm200_disable_8259A_irq(unsigned int irq)
|
||||
raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
|
||||
}
|
||||
|
||||
static void sni_rm200_enable_8259A_irq(unsigned int irq)
|
||||
static void sni_rm200_enable_8259A_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
|
||||
irq -= RM200_I8259A_IRQ_BASE;
|
||||
mask = ~(1 << irq);
|
||||
raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
|
||||
rm200_cached_irq_mask &= mask;
|
||||
@ -210,12 +208,11 @@ static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
|
||||
* first, _then_ send the EOI, and the order of EOI
|
||||
* to the two 8259s is important!
|
||||
*/
|
||||
void sni_rm200_mask_and_ack_8259A(unsigned int irq)
|
||||
void sni_rm200_mask_and_ack_8259A(struct irq_data *d)
|
||||
{
|
||||
unsigned int irqmask;
|
||||
unsigned int irqmask, irq = d->irq - RM200_I8259A_IRQ_BASE;
|
||||
unsigned long flags;
|
||||
|
||||
irq -= RM200_I8259A_IRQ_BASE;
|
||||
irqmask = 1 << irq;
|
||||
raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
|
||||
/*
|
||||
@ -285,9 +282,9 @@ spurious_8259A_irq:
|
||||
|
||||
static struct irq_chip sni_rm200_i8259A_chip = {
|
||||
.name = "RM200-XT-PIC",
|
||||
.mask = sni_rm200_disable_8259A_irq,
|
||||
.unmask = sni_rm200_enable_8259A_irq,
|
||||
.mask_ack = sni_rm200_mask_and_ack_8259A,
|
||||
.irq_mask = sni_rm200_disable_8259A_irq,
|
||||
.irq_unmask = sni_rm200_enable_8259A_irq,
|
||||
.irq_mask_ack = sni_rm200_mask_and_ack_8259A,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -429,33 +426,24 @@ void __init sni_rm200_i8259_irqs(void)
|
||||
#define SNI_RM200_INT_START 24
|
||||
#define SNI_RM200_INT_END 28
|
||||
|
||||
static void enable_rm200_irq(unsigned int irq)
|
||||
static void enable_rm200_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
|
||||
unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
|
||||
|
||||
*(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
|
||||
}
|
||||
|
||||
void disable_rm200_irq(unsigned int irq)
|
||||
void disable_rm200_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (irq - SNI_RM200_INT_START);
|
||||
unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
|
||||
|
||||
*(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
|
||||
}
|
||||
|
||||
void end_rm200_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
||||
enable_rm200_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip rm200_irq_type = {
|
||||
.name = "RM200",
|
||||
.ack = disable_rm200_irq,
|
||||
.mask = disable_rm200_irq,
|
||||
.mask_ack = disable_rm200_irq,
|
||||
.unmask = enable_rm200_irq,
|
||||
.end = end_rm200_irq,
|
||||
.irq_mask = disable_rm200_irq,
|
||||
.irq_unmask = enable_rm200_irq,
|
||||
};
|
||||
|
||||
static void sni_rm200_hwint(void)
|
||||
|
@ -50,9 +50,9 @@ static struct {
|
||||
unsigned char mode;
|
||||
} tx4939irq[TX4939_NUM_IR] __read_mostly;
|
||||
|
||||
static void tx4939_irq_unmask(unsigned int irq)
|
||||
static void tx4939_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
u32 __iomem *lvlp;
|
||||
int ofs;
|
||||
if (irq_nr < 32) {
|
||||
@ -68,9 +68,9 @@ static void tx4939_irq_unmask(unsigned int irq)
|
||||
lvlp);
|
||||
}
|
||||
|
||||
static inline void tx4939_irq_mask(unsigned int irq)
|
||||
static inline void tx4939_irq_mask(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
u32 __iomem *lvlp;
|
||||
int ofs;
|
||||
if (irq_nr < 32) {
|
||||
@ -87,11 +87,11 @@ static inline void tx4939_irq_mask(unsigned int irq)
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
static void tx4939_irq_mask_ack(unsigned int irq)
|
||||
static void tx4939_irq_mask_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
|
||||
tx4939_irq_mask(irq);
|
||||
tx4939_irq_mask(d);
|
||||
if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
|
||||
irq_nr--;
|
||||
/* clear edge detection */
|
||||
@ -101,9 +101,9 @@ static void tx4939_irq_mask_ack(unsigned int irq)
|
||||
}
|
||||
}
|
||||
|
||||
static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||
static int tx4939_irq_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
|
||||
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
|
||||
u32 cr;
|
||||
u32 __iomem *crp;
|
||||
int ofs;
|
||||
@ -145,11 +145,11 @@ static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||
|
||||
static struct irq_chip tx4939_irq_chip = {
|
||||
.name = "TX4939",
|
||||
.ack = tx4939_irq_mask_ack,
|
||||
.mask = tx4939_irq_mask,
|
||||
.mask_ack = tx4939_irq_mask_ack,
|
||||
.unmask = tx4939_irq_unmask,
|
||||
.set_type = tx4939_irq_set_type,
|
||||
.irq_ack = tx4939_irq_mask_ack,
|
||||
.irq_mask = tx4939_irq_mask,
|
||||
.irq_mask_ack = tx4939_irq_mask_ack,
|
||||
.irq_unmask = tx4939_irq_unmask,
|
||||
.irq_set_type = tx4939_irq_set_type,
|
||||
};
|
||||
|
||||
static int tx4939_irq_set_pri(int irc_irq, int new_pri)
|
||||
|
@ -47,20 +47,20 @@
|
||||
* CP0_STATUS is a thread's resource (saved/restored on context switch).
|
||||
* So disable_irq/enable_irq MUST handle IOC/IRC registers.
|
||||
*/
|
||||
static void mask_irq_ioc(unsigned int irq)
|
||||
static void mask_irq_ioc(struct irq_data *d)
|
||||
{
|
||||
/* 0: mask */
|
||||
unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
|
||||
unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;
|
||||
unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
|
||||
unsigned int bit = 1 << irq_nr;
|
||||
jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
|
||||
/* flush write buffer */
|
||||
(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
|
||||
}
|
||||
static void unmask_irq_ioc(unsigned int irq)
|
||||
static void unmask_irq_ioc(struct irq_data *d)
|
||||
{
|
||||
/* 0: mask */
|
||||
unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
|
||||
unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;
|
||||
unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
|
||||
unsigned int bit = 1 << irq_nr;
|
||||
jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
|
||||
@ -95,10 +95,8 @@ static int jmr3927_irq_dispatch(int pending)
|
||||
|
||||
static struct irq_chip jmr3927_irq_ioc = {
|
||||
.name = "jmr3927_ioc",
|
||||
.ack = mask_irq_ioc,
|
||||
.mask = mask_irq_ioc,
|
||||
.mask_ack = mask_irq_ioc,
|
||||
.unmask = unmask_irq_ioc,
|
||||
.irq_mask = mask_irq_ioc,
|
||||
.irq_unmask = unmask_irq_ioc,
|
||||
};
|
||||
|
||||
void __init jmr3927_irq_setup(void)
|
||||
|
@ -117,18 +117,6 @@
|
||||
#include <asm/txx9/generic.h>
|
||||
#include <asm/txx9/rbtx4927.h>
|
||||
|
||||
static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
|
||||
static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
|
||||
|
||||
#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
|
||||
static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
|
||||
.name = TOSHIBA_RBTX4927_IOC_NAME,
|
||||
.ack = toshiba_rbtx4927_irq_ioc_disable,
|
||||
.mask = toshiba_rbtx4927_irq_ioc_disable,
|
||||
.mask_ack = toshiba_rbtx4927_irq_ioc_disable,
|
||||
.unmask = toshiba_rbtx4927_irq_ioc_enable,
|
||||
};
|
||||
|
||||
static int toshiba_rbtx4927_irq_nested(int sw_irq)
|
||||
{
|
||||
u8 level3;
|
||||
@ -139,6 +127,32 @@ static int toshiba_rbtx4927_irq_nested(int sw_irq)
|
||||
return RBTX4927_IRQ_IOC + __fls8(level3);
|
||||
}
|
||||
|
||||
static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = readb(rbtx4927_imask_addr);
|
||||
v |= (1 << (d->irq - RBTX4927_IRQ_IOC));
|
||||
writeb(v, rbtx4927_imask_addr);
|
||||
}
|
||||
|
||||
static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = readb(rbtx4927_imask_addr);
|
||||
v &= ~(1 << (d->irq - RBTX4927_IRQ_IOC));
|
||||
writeb(v, rbtx4927_imask_addr);
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
|
||||
static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
|
||||
.name = TOSHIBA_RBTX4927_IOC_NAME,
|
||||
.irq_mask = toshiba_rbtx4927_irq_ioc_disable,
|
||||
.irq_unmask = toshiba_rbtx4927_irq_ioc_enable,
|
||||
};
|
||||
|
||||
static void __init toshiba_rbtx4927_irq_ioc_init(void)
|
||||
{
|
||||
int i;
|
||||
@ -155,26 +169,6 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void)
|
||||
set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
|
||||
}
|
||||
|
||||
static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = readb(rbtx4927_imask_addr);
|
||||
v |= (1 << (irq - RBTX4927_IRQ_IOC));
|
||||
writeb(v, rbtx4927_imask_addr);
|
||||
}
|
||||
|
||||
static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = readb(rbtx4927_imask_addr);
|
||||
v &= ~(1 << (irq - RBTX4927_IRQ_IOC));
|
||||
writeb(v, rbtx4927_imask_addr);
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
|
||||
static int rbtx4927_irq_dispatch(int pending)
|
||||
{
|
||||
int irq;
|
||||
|
@ -69,18 +69,6 @@
|
||||
#include <asm/txx9/generic.h>
|
||||
#include <asm/txx9/rbtx4938.h>
|
||||
|
||||
static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
|
||||
static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
|
||||
|
||||
#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
|
||||
static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
|
||||
.name = TOSHIBA_RBTX4938_IOC_NAME,
|
||||
.ack = toshiba_rbtx4938_irq_ioc_disable,
|
||||
.mask = toshiba_rbtx4938_irq_ioc_disable,
|
||||
.mask_ack = toshiba_rbtx4938_irq_ioc_disable,
|
||||
.unmask = toshiba_rbtx4938_irq_ioc_enable,
|
||||
};
|
||||
|
||||
static int toshiba_rbtx4938_irq_nested(int sw_irq)
|
||||
{
|
||||
u8 level3;
|
||||
@ -92,41 +80,33 @@ static int toshiba_rbtx4938_irq_nested(int sw_irq)
|
||||
return RBTX4938_IRQ_IOC + __fls8(level3);
|
||||
}
|
||||
|
||||
static void __init
|
||||
toshiba_rbtx4938_irq_ioc_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = RBTX4938_IRQ_IOC;
|
||||
i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
|
||||
set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
|
||||
handle_level_irq);
|
||||
|
||||
set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
|
||||
}
|
||||
|
||||
static void
|
||||
toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
|
||||
static void toshiba_rbtx4938_irq_ioc_enable(struct irq_data *d)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = readb(rbtx4938_imask_addr);
|
||||
v |= (1 << (irq - RBTX4938_IRQ_IOC));
|
||||
v |= (1 << (d->irq - RBTX4938_IRQ_IOC));
|
||||
writeb(v, rbtx4938_imask_addr);
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
static void
|
||||
toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
|
||||
static void toshiba_rbtx4938_irq_ioc_disable(struct irq_data *d)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = readb(rbtx4938_imask_addr);
|
||||
v &= ~(1 << (irq - RBTX4938_IRQ_IOC));
|
||||
v &= ~(1 << (d->irq - RBTX4938_IRQ_IOC));
|
||||
writeb(v, rbtx4938_imask_addr);
|
||||
mmiowb();
|
||||
}
|
||||
|
||||
#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
|
||||
static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
|
||||
.name = TOSHIBA_RBTX4938_IOC_NAME,
|
||||
.irq_mask = toshiba_rbtx4938_irq_ioc_disable,
|
||||
.irq_unmask = toshiba_rbtx4938_irq_ioc_enable,
|
||||
};
|
||||
|
||||
static int rbtx4938_irq_dispatch(int pending)
|
||||
{
|
||||
int irq;
|
||||
@ -146,6 +126,18 @@ static int rbtx4938_irq_dispatch(int pending)
|
||||
return irq;
|
||||
}
|
||||
|
||||
static void __init toshiba_rbtx4938_irq_ioc_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = RBTX4938_IRQ_IOC;
|
||||
i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
|
||||
set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
|
||||
handle_level_irq);
|
||||
|
||||
set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
|
||||
}
|
||||
|
||||
void __init rbtx4938_irq_setup(void)
|
||||
{
|
||||
txx9_irq_dispatch = rbtx4938_irq_dispatch;
|
||||
|
@ -19,16 +19,16 @@
|
||||
* RBTX4939 IOC controller definition
|
||||
*/
|
||||
|
||||
static void rbtx4939_ioc_irq_unmask(unsigned int irq)
|
||||
static void rbtx4939_ioc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
int ioc_nr = irq - RBTX4939_IRQ_IOC;
|
||||
int ioc_nr = d->irq - RBTX4939_IRQ_IOC;
|
||||
|
||||
writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr);
|
||||
}
|
||||
|
||||
static void rbtx4939_ioc_irq_mask(unsigned int irq)
|
||||
static void rbtx4939_ioc_irq_mask(struct irq_data *d)
|
||||
{
|
||||
int ioc_nr = irq - RBTX4939_IRQ_IOC;
|
||||
int ioc_nr = d->irq - RBTX4939_IRQ_IOC;
|
||||
|
||||
writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr);
|
||||
mmiowb();
|
||||
@ -36,10 +36,8 @@ static void rbtx4939_ioc_irq_mask(unsigned int irq)
|
||||
|
||||
static struct irq_chip rbtx4939_ioc_irq_chip = {
|
||||
.name = "IOC",
|
||||
.ack = rbtx4939_ioc_irq_mask,
|
||||
.mask = rbtx4939_ioc_irq_mask,
|
||||
.mask_ack = rbtx4939_ioc_irq_mask,
|
||||
.unmask = rbtx4939_ioc_irq_unmask,
|
||||
.irq_mask = rbtx4939_ioc_irq_mask,
|
||||
.irq_unmask = rbtx4939_ioc_irq_unmask,
|
||||
};
|
||||
|
||||
|
||||
|
@ -154,7 +154,7 @@ static inline uint16_t icu2_clear(uint8_t offset, uint16_t clear)
|
||||
|
||||
void vr41xx_enable_piuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + PIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(PIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4111 ||
|
||||
@ -169,7 +169,7 @@ EXPORT_SYMBOL(vr41xx_enable_piuint);
|
||||
|
||||
void vr41xx_disable_piuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + PIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(PIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4111 ||
|
||||
@ -184,7 +184,7 @@ EXPORT_SYMBOL(vr41xx_disable_piuint);
|
||||
|
||||
void vr41xx_enable_aiuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + AIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(AIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4111 ||
|
||||
@ -199,7 +199,7 @@ EXPORT_SYMBOL(vr41xx_enable_aiuint);
|
||||
|
||||
void vr41xx_disable_aiuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + AIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(AIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4111 ||
|
||||
@ -214,7 +214,7 @@ EXPORT_SYMBOL(vr41xx_disable_aiuint);
|
||||
|
||||
void vr41xx_enable_kiuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + KIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(KIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4111 ||
|
||||
@ -229,7 +229,7 @@ EXPORT_SYMBOL(vr41xx_enable_kiuint);
|
||||
|
||||
void vr41xx_disable_kiuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + KIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(KIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4111 ||
|
||||
@ -244,7 +244,7 @@ EXPORT_SYMBOL(vr41xx_disable_kiuint);
|
||||
|
||||
void vr41xx_enable_macint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + ETHERNET_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||
@ -256,7 +256,7 @@ EXPORT_SYMBOL(vr41xx_enable_macint);
|
||||
|
||||
void vr41xx_disable_macint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + ETHERNET_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||
@ -268,7 +268,7 @@ EXPORT_SYMBOL(vr41xx_disable_macint);
|
||||
|
||||
void vr41xx_enable_dsiuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + DSIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(DSIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||
@ -280,7 +280,7 @@ EXPORT_SYMBOL(vr41xx_enable_dsiuint);
|
||||
|
||||
void vr41xx_disable_dsiuint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + DSIU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(DSIU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||
@ -292,7 +292,7 @@ EXPORT_SYMBOL(vr41xx_disable_dsiuint);
|
||||
|
||||
void vr41xx_enable_firint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + FIR_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(FIR_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||
@ -304,7 +304,7 @@ EXPORT_SYMBOL(vr41xx_enable_firint);
|
||||
|
||||
void vr41xx_disable_firint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + FIR_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(FIR_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||
@ -316,7 +316,7 @@ EXPORT_SYMBOL(vr41xx_disable_firint);
|
||||
|
||||
void vr41xx_enable_pciint(void)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + PCI_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(PCI_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -332,7 +332,7 @@ EXPORT_SYMBOL(vr41xx_enable_pciint);
|
||||
|
||||
void vr41xx_disable_pciint(void)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + PCI_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(PCI_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -348,7 +348,7 @@ EXPORT_SYMBOL(vr41xx_disable_pciint);
|
||||
|
||||
void vr41xx_enable_scuint(void)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + SCU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(SCU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -364,7 +364,7 @@ EXPORT_SYMBOL(vr41xx_enable_scuint);
|
||||
|
||||
void vr41xx_disable_scuint(void)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + SCU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(SCU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -380,7 +380,7 @@ EXPORT_SYMBOL(vr41xx_disable_scuint);
|
||||
|
||||
void vr41xx_enable_csiint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + CSI_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(CSI_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -396,7 +396,7 @@ EXPORT_SYMBOL(vr41xx_enable_csiint);
|
||||
|
||||
void vr41xx_disable_csiint(uint16_t mask)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + CSI_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(CSI_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -412,7 +412,7 @@ EXPORT_SYMBOL(vr41xx_disable_csiint);
|
||||
|
||||
void vr41xx_enable_bcuint(void)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + BCU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(BCU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -428,7 +428,7 @@ EXPORT_SYMBOL(vr41xx_enable_bcuint);
|
||||
|
||||
void vr41xx_disable_bcuint(void)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + BCU_IRQ;
|
||||
struct irq_desc *desc = irq_to_desc(BCU_IRQ);
|
||||
unsigned long flags;
|
||||
|
||||
if (current_cpu_type() == CPU_VR4122 ||
|
||||
@ -442,45 +442,41 @@ void vr41xx_disable_bcuint(void)
|
||||
|
||||
EXPORT_SYMBOL(vr41xx_disable_bcuint);
|
||||
|
||||
static void disable_sysint1_irq(unsigned int irq)
|
||||
static void disable_sysint1_irq(struct irq_data *d)
|
||||
{
|
||||
icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
|
||||
icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
|
||||
}
|
||||
|
||||
static void enable_sysint1_irq(unsigned int irq)
|
||||
static void enable_sysint1_irq(struct irq_data *d)
|
||||
{
|
||||
icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
|
||||
icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
|
||||
}
|
||||
|
||||
static struct irq_chip sysint1_irq_type = {
|
||||
.name = "SYSINT1",
|
||||
.ack = disable_sysint1_irq,
|
||||
.mask = disable_sysint1_irq,
|
||||
.mask_ack = disable_sysint1_irq,
|
||||
.unmask = enable_sysint1_irq,
|
||||
.irq_mask = disable_sysint1_irq,
|
||||
.irq_unmask = enable_sysint1_irq,
|
||||
};
|
||||
|
||||
static void disable_sysint2_irq(unsigned int irq)
|
||||
static void disable_sysint2_irq(struct irq_data *d)
|
||||
{
|
||||
icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
|
||||
icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
|
||||
}
|
||||
|
||||
static void enable_sysint2_irq(unsigned int irq)
|
||||
static void enable_sysint2_irq(struct irq_data *d)
|
||||
{
|
||||
icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
|
||||
icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
|
||||
}
|
||||
|
||||
static struct irq_chip sysint2_irq_type = {
|
||||
.name = "SYSINT2",
|
||||
.ack = disable_sysint2_irq,
|
||||
.mask = disable_sysint2_irq,
|
||||
.mask_ack = disable_sysint2_irq,
|
||||
.unmask = enable_sysint2_irq,
|
||||
.irq_mask = disable_sysint2_irq,
|
||||
.irq_unmask = enable_sysint2_irq,
|
||||
};
|
||||
|
||||
static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
uint16_t intassign0, intassign1;
|
||||
unsigned int pin;
|
||||
|
||||
@ -540,7 +536,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
|
||||
|
||||
static inline int set_sysint2_assign(unsigned int irq, unsigned char assign)
|
||||
{
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
uint16_t intassign2, intassign3;
|
||||
unsigned int pin;
|
||||
|
||||
|
@ -62,7 +62,6 @@ EXPORT_SYMBOL_GPL(cascade_irq);
|
||||
static void irq_dispatch(unsigned int irq)
|
||||
{
|
||||
irq_cascade_t *cascade;
|
||||
struct irq_desc *desc;
|
||||
|
||||
if (irq >= NR_IRQS) {
|
||||
atomic_inc(&irq_err_count);
|
||||
@ -71,14 +70,16 @@ static void irq_dispatch(unsigned int irq)
|
||||
|
||||
cascade = irq_cascade + irq;
|
||||
if (cascade->get_irq != NULL) {
|
||||
unsigned int source_irq = irq;
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
struct irq_data *idata = irq_desc_get_irq_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
int ret;
|
||||
desc = irq_desc + source_irq;
|
||||
if (desc->chip->mask_ack)
|
||||
desc->chip->mask_ack(source_irq);
|
||||
|
||||
if (chip->irq_mask_ack)
|
||||
chip->irq_mask_ack(idata);
|
||||
else {
|
||||
desc->chip->mask(source_irq);
|
||||
desc->chip->ack(source_irq);
|
||||
chip->irq_mask(idata);
|
||||
chip->irq_ack(idata);
|
||||
}
|
||||
ret = cascade->get_irq(irq);
|
||||
irq = ret;
|
||||
@ -86,8 +87,8 @@ static void irq_dispatch(unsigned int irq)
|
||||
atomic_inc(&irq_err_count);
|
||||
else
|
||||
irq_dispatch(irq);
|
||||
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
|
||||
desc->chip->unmask(source_irq);
|
||||
if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
|
||||
chip->irq_unmask(idata);
|
||||
} else
|
||||
do_IRQ(irq);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user