diff options
Diffstat (limited to 'arch/mips')
71 files changed, 2316 insertions, 1325 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9905e2e85de..83aa5fb8e8f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -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 diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 9f78ada83b3..55dd7c88851 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c @@ -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; } diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c index c52af8821da..f91c43a7d5d 100644 --- a/arch/mips/alchemy/devboards/bcsr.c +++ b/arch/mips/alchemy/devboards/bcsr.c @@ -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) diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c index 4ec2642c568..a6484b60642 100644 --- a/arch/mips/ar7/irq.c +++ b/arch/mips/ar7/irq.c @@ -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 = { diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 1bf7f719ba5..7c02bc948a3 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -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); } diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index 3be87f2422f..1691531aa34 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c @@ -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 = { diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index cb41954fc32..8d9a5fc607e 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -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; diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index ed90a8deabc..ef31d98c4fb 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c @@ -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 + diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c index 3a96799eb65..9b1207ae225 100644 --- a/arch/mips/emma/markeins/irq.c +++ b/arch/mips/emma/markeins/irq.c @@ -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) diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index b003ed52ed1..0ec01294b06 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -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) - -#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) +static inline int smtc_handle_on_other_cpu(unsigned int irq) +{ + int ret = handle_on_other_cpu(irq); + + 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 diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h new file mode 100644 index 00000000000..a80801b094b --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h @@ -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 */ diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h new file mode 100644 index 00000000000..156f320c69e --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h @@ -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__ */ diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h index 603eb737b4a..692c1b658b9 100644 --- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.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) diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h new file mode 100644 index 00000000000..4c9348df9df --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h @@ -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_*/ diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 396e402fbe2..ca61e846ab0 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.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" diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 550725b881d..dae22c1d2c8 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -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__ diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index 35b3e2f0af0..40f7c6b1e26 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -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) diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 2c0e107966a..bc18daaa8f8 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -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) diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 88e6aeda5bf..bd2fc29b95e 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c @@ -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; diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c index 7d33ff83580..dcc5593a938 100644 --- a/arch/mips/jz4740/irq.c +++ b/arch/mips/jz4740/irq.c @@ -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); } diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index c58176cc796..e221662bb80 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -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 */ diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 1774271af84..43cd9628251 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c @@ -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 }; diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c index 42ef81461bf..7fd176fa367 100644 --- a/arch/mips/kernel/irq-gt641xx.c +++ b/arch/mips/kernel/irq-gt641xx.c @@ -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) diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 6a8cd28133d..fc800cd9947 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -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 { @@ -75,15 +83,6 @@ static void edge_mask_and_ack_msc_irq(unsigned int 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. */ void ll_msc_irq(void) @@ -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, }; diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 9731e8b4786..fd24fd98b04 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -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) diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index b7e4025b58a..ca463ec9bad 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -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; diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 4f93db58a79..1b68ebe1b45 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -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(); } diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 0262abe0912..fd945c56bc3 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -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) diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c index 95a96f69172..526e1581549 100644 --- a/arch/mips/kernel/irq_txx9.c +++ b/arch/mips/kernel/irq_txx9.c @@ -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) diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index fbaabad0e6e..7f5468b38d4 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -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 diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3f417928320..a2e1fcbc41d 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -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 diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f08ece6d8ac..b2c7624995b 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -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 diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 78d768a3e19..049a9c8c49a 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -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 diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 39c08254b0f..f7e2c7807d7 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -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 */ diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 1353fb135ed..670e3e70d19 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -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) diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index 2dc2a4cc632..1549361696a 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -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 = { diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c index 5da30b6a65b..30df47258c2 100644 --- a/arch/mips/mipssim/sim_smtc.c +++ b/arch/mips/mipssim/sim_smtc.c @@ -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(); } diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c index 192cfd2a539..e67891521ac 100644 --- a/arch/mips/mti-malta/malta-smtc.c +++ b/arch/mips/mti-malta/malta-smtc.c @@ -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 */ diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig index 8d798497c61..bbd76082fa8 100644 --- a/arch/mips/pmc-sierra/Kconfig +++ b/arch/mips/pmc-sierra/Kconfig @@ -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 diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile index e107f79b149..cefba7733b7 100644 --- a/arch/mips/pmc-sierra/msp71xx/Makefile +++ b/arch/mips/pmc-sierra/msp71xx/Makefile @@ -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 diff --git a/arch/mips/pmc-sierra/msp71xx/msp_eth.c b/arch/mips/pmc-sierra/msp71xx/msp_eth.c new file mode 100644 index 00000000000..c584df393de --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_eth.c @@ -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); diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c index 734d598a2e3..4531c4a514b 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c @@ -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 } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c index 07e71ff2433..352f29d9226 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c @@ -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) + +/* + * Convenience Macro. Should be somewhere generic. + */ +#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) { + const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG; + volatile u32 dummy_read; - /* 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)); + wmb(); + dummy_read = __raw_readl(cic_mem); + dummy_read++; } -static inline void mask_msp_cic_irq(unsigned int irq) +static void unmask_cic_irq(struct irq_data *d) { - /* 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)); + volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; + int vpe; +#ifdef CONFIG_SMP + unsigned int mtflags; + unsigned long flags; + + /* + * 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 + + vpe = get_current_vpe(); + LOCK_VPE(flags, mtflags); + cic_msk_reg[vpe] |= (1 << (d->irq - MSP_CIC_INTBASE)); + UNLOCK_VPE(flags, mtflags); + cic_wmb(); } -/* - * 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. - */ -static inline void ack_msp_cic_irq(unsigned int irq) +static void mask_cic_irq(struct irq_data *d) { - mask_msp_cic_irq(irq); - + 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. - */ - - /* 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)); + * 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(); + } } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c new file mode 100644 index 00000000000..f9b9dcdfa9d --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c @@ -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(); + } +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c index 61f39023234..8f51e4adc43 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c @@ -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) diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index a54e85b3cf2..fb37a10e030 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c @@ -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 diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c new file mode 100644 index 00000000000..43a9e26e1c6 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c @@ -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 */ diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smtc.c b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c new file mode 100644 index 00000000000..c8dcc1c01e1 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c @@ -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, +}; diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c index 01df84ce31e..8b42f307a7a 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_time.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c @@ -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; } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c index 0ee01e359dd..9a1aef89bd4 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_usb.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c @@ -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, }, + [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, + }, +}; + +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 */ -static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32); +#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 struct platform_device msp_usbdev_device = { - .name = "msp71xx_udc", - .id = 0, +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 = { - .dma_mask = &msp_usbdev_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), + .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, }, - .num_resources = ARRAY_SIZE(msp_usbdev_resources), - .resource = msp_usbdev_resources, }; -#endif /* CONFIG_USB_GADGET */ -#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) -static struct platform_device *msp_devs[1]; -#endif +#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 */ 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 */ diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c index 941916f8aaf..b226bcb0a2f 100644 --- a/arch/mips/pnx833x/common/interrupts.c +++ b/arch/mips/pnx833x/common/interrupts.c @@ -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) -{ - unsigned long flags; - unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; - - raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - - irqflags[pic_irq] = 0; /* not started */ - pnx833x_hard_disable_pic_irq(pic_irq); - - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); -} - -static void pnx833x_enable_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); - - irqflags[pic_irq] &= ~IRQFLAG_DISABLED; - if (irqflags[pic_irq] == IRQFLAG_STARTED) - pnx833x_hard_enable_pic_irq(pic_irq); - + pnx833x_hard_enable_pic_irq(pic_irq); raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); } -static void pnx833x_disable_pic_irq(unsigned int irq) +static void pnx833x_disable_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); - - 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) -{ - 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) +static void pnx833x_enable_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_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 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) +static int pnx833x_set_type_gpio_irq(struct irq_data *d, 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) diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c index cfed5051dc6..dbdc35c3531 100644 --- a/arch/mips/pnx8550/common/int.c +++ b/arch/mips/pnx8550/common/int.c @@ -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 */ diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c index e5538243415..6f1c8ef6a71 100644 --- a/arch/mips/powertv/asic/irq_asic.c +++ b/arch/mips/powertv/asic/irq_asic.c @@ -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) diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c index ea6cec3c1e0..b32a768da89 100644 --- a/arch/mips/rb532/irq.c +++ b/arch/mips/rb532/irq.c @@ -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) diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 383f11d7f44..e6e64750e90 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -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) diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 6a123ea72de..f2d09d7700d 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -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) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index d6802d6d1f8..c01f558a2a0 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -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) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index eb40824b172..e0a3ce4a8d4 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -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) diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 044bbe462c2..89e8188a466 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -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) { diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 12ac04a658e..fd269ea8d8a 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -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) { diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index bbe7187879f..72b94155778 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c @@ -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, }; /* diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 8c92c73bc71..cfcc68abc5b 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c @@ -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, }; /* diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index dc9874553be..0846e99a6ef 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c @@ -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) diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index 0e6f42c2bbc..f05d8e59330 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c @@ -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) diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c index 3886ad77cba..93b6edbedd6 100644 --- a/arch/mips/txx9/generic/irq_tx4939.c +++ b/arch/mips/txx9/generic/irq_tx4939.c @@ -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) diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c index 0a7f8e3b9fd..92a5c1b400f 100644 --- a/arch/mips/txx9/jmr3927/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c @@ -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) diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index c4b54d20efd..7c0a048b307 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -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,41 +127,47 @@ static int toshiba_rbtx4927_irq_nested(int sw_irq) return RBTX4927_IRQ_IOC + __fls8(level3); } -static void __init toshiba_rbtx4927_irq_ioc_init(void) -{ - int i; - - /* mask all IOC interrupts */ - writeb(0, rbtx4927_imask_addr); - /* clear SoftInt interrupts */ - writeb(0, rbtx4927_softint_addr); - - for (i = RBTX4927_IRQ_IOC; - i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, - handle_level_irq); - set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); -} - -static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d) { unsigned char v; v = readb(rbtx4927_imask_addr); - v |= (1 << (irq - RBTX4927_IRQ_IOC)); + v |= (1 << (d->irq - RBTX4927_IRQ_IOC)); writeb(v, rbtx4927_imask_addr); } -static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d) { unsigned char v; v = readb(rbtx4927_imask_addr); - v &= ~(1 << (irq - RBTX4927_IRQ_IOC)); + 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; + + /* mask all IOC interrupts */ + writeb(0, rbtx4927_imask_addr); + /* clear SoftInt interrupts */ + writeb(0, rbtx4927_softint_addr); + + for (i = RBTX4927_IRQ_IOC; + i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) + set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, + handle_level_irq); + set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); +} static int rbtx4927_irq_dispatch(int pending) { diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c index 67a73a8065e..2ec4fe1b167 100644 --- a/arch/mips/txx9/rbtx4938/irq.c +++ b/arch/mips/txx9/rbtx4938/irq.c @@ -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; diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c index 57fa740a720..70074632fb9 100644 --- a/arch/mips/txx9/rbtx4939/irq.c +++ b/arch/mips/txx9/rbtx4939/irq.c @@ -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, }; diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 6153b6a05cc..f53156bb9aa 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -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; diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 0975eb72d38..9ff7f397c0e 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c @@ -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); } |