提交 62d00867 编写于 作者: L Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (49 commits)
  MIPS: JZ4740: Set nand ecc offsets for the qi_lb60 board
  MIPS: JZ4740: qi_lb60: Add gpio-charger device
  MIPS: Wire up syncfs(2).
  MIPS: Hook up name_to_handle_at, open_by_handle_at and clock_adjtime syscalls.
  MIPS: VR41xx: Convert to new irq_chip functions
  MIPS: TXx9: Convert to new irq_chip functions
  MIPS: SNI: Convert to new irq_chip functions
  MIPS: Sibyte: Convert to new irq_chip functions
  MIPS: IP32: Convert to new irq_chip functions
  MIPS: IP27: Convert to new irq_chip functions
  MIPS: IP22/IP28: Convert to new irq_chip functions
  MIPS: RB532: Convert to new irq_chip functions
  MIPS: PowerTV: Convert to new irq_chip functions
  MIPS: PNX8550: Convert to new irq_chip functions
  MIPS: PNX83xx: Convert to new irq_chip functions
  MIPS: msp71xx: Convert to new irq_chip functions
  MIPS: Loongson: Convert to new irq_chip functions
  MIPS: Use generic show_interrupts()
  MIPS: SMTC: Cleanup the hook mess and use irq_data
  MIPS: SMTC: Use irq_data in smtc_forward_irq()
  ...
......@@ -22,6 +22,7 @@ config MIPS
select HAVE_DMA_API_DEBUG
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select HAVE_ARCH_JUMP_LABEL
menu "Machine selection"
......@@ -862,6 +863,9 @@ config GPIO_TXX9
config CFE
bool
config ARCH_DMA_ADDR_T_64BIT
def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT
config DMA_COHERENT
bool
......
......@@ -39,7 +39,7 @@
#include <asm/mach-pb1x00/pb1000.h>
#endif
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
/* NOTE on interrupt priorities: The original writers of this code said:
*
......@@ -218,17 +218,17 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = {
};
static void au1x_ic0_unmask(unsigned int irq_nr)
static void au1x_ic0_unmask(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_MASKSET);
au_writel(1 << bit, IC0_WAKESET);
au_sync();
}
static void au1x_ic1_unmask(unsigned int irq_nr)
static void au1x_ic1_unmask(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_MASKSET);
au_writel(1 << bit, IC1_WAKESET);
......@@ -236,31 +236,31 @@ static void au1x_ic1_unmask(unsigned int irq_nr)
* nowhere in the current kernel sources is it disabled. --mlau
*/
#if defined(CONFIG_MIPS_PB1000)
if (irq_nr == AU1000_GPIO15_INT)
if (d->irq == AU1000_GPIO15_INT)
au_writel(0x4000, PB1000_MDR); /* enable int */
#endif
au_sync();
}
static void au1x_ic0_mask(unsigned int irq_nr)
static void au1x_ic0_mask(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_WAKECLR);
au_sync();
}
static void au1x_ic1_mask(unsigned int irq_nr)
static void au1x_ic1_mask(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_MASKCLR);
au_writel(1 << bit, IC1_WAKECLR);
au_sync();
}
static void au1x_ic0_ack(unsigned int irq_nr)
static void au1x_ic0_ack(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
/*
* This may assume that we don't get interrupts from
......@@ -271,9 +271,9 @@ static void au1x_ic0_ack(unsigned int irq_nr)
au_sync();
}
static void au1x_ic1_ack(unsigned int irq_nr)
static void au1x_ic1_ack(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
/*
* This may assume that we don't get interrupts from
......@@ -284,9 +284,9 @@ static void au1x_ic1_ack(unsigned int irq_nr)
au_sync();
}
static void au1x_ic0_maskack(unsigned int irq_nr)
static void au1x_ic0_maskack(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_WAKECLR);
au_writel(1 << bit, IC0_MASKCLR);
......@@ -295,9 +295,9 @@ static void au1x_ic0_maskack(unsigned int irq_nr)
au_sync();
}
static void au1x_ic1_maskack(unsigned int irq_nr)
static void au1x_ic1_maskack(struct irq_data *d)
{
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_WAKECLR);
au_writel(1 << bit, IC1_MASKCLR);
......@@ -306,9 +306,9 @@ static void au1x_ic1_maskack(unsigned int irq_nr)
au_sync();
}
static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
{
int bit = irq - AU1000_INTC1_INT_BASE;
int bit = d->irq - AU1000_INTC1_INT_BASE;
unsigned long wakemsk, flags;
/* only GPIO 0-7 can act as wakeup source. Fortunately these
......@@ -336,28 +336,30 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
*/
static struct irq_chip au1x_ic0_chip = {
.name = "Alchemy-IC0",
.ack = au1x_ic0_ack,
.mask = au1x_ic0_mask,
.mask_ack = au1x_ic0_maskack,
.unmask = au1x_ic0_unmask,
.set_type = au1x_ic_settype,
.irq_ack = au1x_ic0_ack,
.irq_mask = au1x_ic0_mask,
.irq_mask_ack = au1x_ic0_maskack,
.irq_unmask = au1x_ic0_unmask,
.irq_set_type = au1x_ic_settype,
};
static struct irq_chip au1x_ic1_chip = {
.name = "Alchemy-IC1",
.ack = au1x_ic1_ack,
.mask = au1x_ic1_mask,
.mask_ack = au1x_ic1_maskack,
.unmask = au1x_ic1_unmask,
.set_type = au1x_ic_settype,
.set_wake = au1x_ic1_setwake,
.irq_ack = au1x_ic1_ack,
.irq_mask = au1x_ic1_mask,
.irq_mask_ack = au1x_ic1_maskack,
.irq_unmask = au1x_ic1_unmask,
.irq_set_type = au1x_ic_settype,
.irq_set_wake = au1x_ic1_setwake,
};
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
{
struct irq_chip *chip;
unsigned long icr[6];
unsigned int bit, ic;
unsigned int bit, ic, irq = d->irq;
irq_flow_handler_t handler = NULL;
unsigned char *name = NULL;
int ret;
if (irq >= AU1000_INTC1_INT_BASE) {
......@@ -387,47 +389,47 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[0]);
set_irq_chip_and_handler_name(irq, chip,
handle_edge_irq, "riseedge");
handler = handle_edge_irq;
name = "riseedge";
break;
case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[3]);
set_irq_chip_and_handler_name(irq, chip,
handle_edge_irq, "falledge");
handler = handle_edge_irq;
name = "falledge";
break;
case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[0]);
set_irq_chip_and_handler_name(irq, chip,
handle_edge_irq, "bothedge");
handler = handle_edge_irq;
name = "bothedge";
break;
case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
au_writel(1 << bit, icr[2]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[0]);
set_irq_chip_and_handler_name(irq, chip,
handle_level_irq, "hilevel");
handler = handle_level_irq;
name = "hilevel";
break;
case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
au_writel(1 << bit, icr[2]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[3]);
set_irq_chip_and_handler_name(irq, chip,
handle_level_irq, "lowlevel");
handler = handle_level_irq;
name = "lowlevel";
break;
case IRQ_TYPE_NONE: /* 0:0:0 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[3]);
/* set at least chip so we can call set_irq_type() on it */
set_irq_chip(irq, chip);
break;
default:
ret = -EINVAL;
}
__irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
au_sync();
return ret;
......@@ -504,11 +506,11 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
*/
for (i = AU1000_INTC0_INT_BASE;
(i < AU1000_INTC0_INT_BASE + 32); i++)
au1x_ic_settype(i, IRQ_TYPE_NONE);
au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
for (i = AU1000_INTC1_INT_BASE;
(i < AU1000_INTC1_INT_BASE + 32); i++)
au1x_ic_settype(i, IRQ_TYPE_NONE);
au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
/*
* Initialize IC0, which is fixed per processor.
......@@ -526,7 +528,7 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
au_writel(1 << bit, IC0_ASSIGNSET);
}
au1x_ic_settype(irq_nr, map->im_type);
au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
++map;
}
......
......@@ -97,26 +97,26 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
* CPLD generates tons of spurious interrupts (at least on my DB1200).
* -- mlau
*/
static void bcsr_irq_mask(unsigned int irq_nr)
static void bcsr_irq_mask(struct irq_data *d)
{
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
unsigned short v = 1 << (d->irq - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
wmb();
}
static void bcsr_irq_maskack(unsigned int irq_nr)
static void bcsr_irq_maskack(struct irq_data *d)
{
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
unsigned short v = 1 << (d->irq - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */
wmb();
}
static void bcsr_irq_unmask(unsigned int irq_nr)
static void bcsr_irq_unmask(struct irq_data *d)
{
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
unsigned short v = 1 << (d->irq - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
wmb();
......@@ -124,9 +124,9 @@ static void bcsr_irq_unmask(unsigned int irq_nr)
static struct irq_chip bcsr_irq_type = {
.name = "CPLD",
.mask = bcsr_irq_mask,
.mask_ack = bcsr_irq_maskack,
.unmask = bcsr_irq_unmask,
.irq_mask = bcsr_irq_mask,
.irq_mask_ack = bcsr_irq_maskack,
.irq_unmask = bcsr_irq_unmask,
};
void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
......
......@@ -49,51 +49,51 @@
static int ar7_irq_base;
static void ar7_unmask_irq(unsigned int irq)
static void ar7_unmask_irq(struct irq_data *d)
{
writel(1 << ((irq - ar7_irq_base) % 32),
REG(ESR_OFFSET(irq - ar7_irq_base)));
writel(1 << ((d->irq - ar7_irq_base) % 32),
REG(ESR_OFFSET(d->irq - ar7_irq_base)));
}
static void ar7_mask_irq(unsigned int irq)
static void ar7_mask_irq(struct irq_data *d)
{
writel(1 << ((irq - ar7_irq_base) % 32),
REG(ECR_OFFSET(irq - ar7_irq_base)));
writel(1 << ((d->irq - ar7_irq_base) % 32),
REG(ECR_OFFSET(d->irq - ar7_irq_base)));
}
static void ar7_ack_irq(unsigned int irq)
static void ar7_ack_irq(struct irq_data *d)
{
writel(1 << ((irq - ar7_irq_base) % 32),
REG(CR_OFFSET(irq - ar7_irq_base)));
writel(1 << ((d->irq - ar7_irq_base) % 32),
REG(CR_OFFSET(d->irq - ar7_irq_base)));
}
static void ar7_unmask_sec_irq(unsigned int irq)
static void ar7_unmask_sec_irq(struct irq_data *d)
{
writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
}
static void ar7_mask_sec_irq(unsigned int irq)
static void ar7_mask_sec_irq(struct irq_data *d)
{
writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
}
static void ar7_ack_sec_irq(unsigned int irq)
static void ar7_ack_sec_irq(struct irq_data *d)
{
writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
}
static struct irq_chip ar7_irq_type = {
.name = "AR7",
.unmask = ar7_unmask_irq,
.mask = ar7_mask_irq,
.ack = ar7_ack_irq
.irq_unmask = ar7_unmask_irq,
.irq_mask = ar7_mask_irq,
.irq_ack = ar7_ack_irq
};
static struct irq_chip ar7_sec_irq_type = {
.name = "AR7",
.unmask = ar7_unmask_sec_irq,
.mask = ar7_mask_sec_irq,
.ack = ar7_ack_sec_irq,
.irq_unmask = ar7_unmask_sec_irq,
.irq_mask = ar7_mask_sec_irq,
.irq_ack = ar7_ack_sec_irq,
};
static struct irqaction ar7_cascade_action = {
......
......@@ -62,13 +62,12 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
spurious_interrupt();
}
static void ar71xx_misc_irq_unmask(unsigned int irq)
static void ar71xx_misc_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
void __iomem *base = ath79_reset_base;
u32 t;
irq -= ATH79_MISC_IRQ_BASE;
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
......@@ -76,13 +75,12 @@ static void ar71xx_misc_irq_unmask(unsigned int irq)
__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
}
static void ar71xx_misc_irq_mask(unsigned int irq)
static void ar71xx_misc_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
void __iomem *base = ath79_reset_base;
u32 t;
irq -= ATH79_MISC_IRQ_BASE;
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
......@@ -90,13 +88,12 @@ static void ar71xx_misc_irq_mask(unsigned int irq)
__raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
}
static void ar724x_misc_irq_ack(unsigned int irq)
static void ar724x_misc_irq_ack(struct irq_data *d)
{
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
void __iomem *base = ath79_reset_base;
u32 t;
irq -= ATH79_MISC_IRQ_BASE;
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
......@@ -106,8 +103,8 @@ static void ar724x_misc_irq_ack(unsigned int irq)
static struct irq_chip ath79_misc_irq_chip = {
.name = "MISC",
.unmask = ar71xx_misc_irq_unmask,
.mask = ar71xx_misc_irq_mask,
.irq_unmask = ar71xx_misc_irq_unmask,
.irq_mask = ar71xx_misc_irq_mask,
};
static void __init ath79_misc_irq_init(void)
......@@ -119,15 +116,14 @@ static void __init ath79_misc_irq_init(void)
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
if (soc_is_ar71xx() || soc_is_ar913x())
ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
else if (soc_is_ar724x())
ath79_misc_irq_chip.ack = ar724x_misc_irq_ack;
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
else
BUG();
for (i = ATH79_MISC_IRQ_BASE;
i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
irq_desc[i].status = IRQ_DISABLED;
set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
handle_level_irq);
}
......
......@@ -76,88 +76,80 @@ asmlinkage void plat_irq_dispatch(void)
* internal IRQs operations: only mask/unmask on PERF irq mask
* register.
*/
static inline void bcm63xx_internal_irq_mask(unsigned int irq)
static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
u32 mask;
irq -= IRQ_INTERNAL_BASE;
mask = bcm_perf_readl(PERF_IRQMASK_REG);
mask &= ~(1 << irq);
bcm_perf_writel(mask, PERF_IRQMASK_REG);
}
static void bcm63xx_internal_irq_unmask(unsigned int irq)
static void bcm63xx_internal_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
u32 mask;
irq -= IRQ_INTERNAL_BASE;
mask = bcm_perf_readl(PERF_IRQMASK_REG);
mask |= (1 << irq);
bcm_perf_writel(mask, PERF_IRQMASK_REG);
}
static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
{
bcm63xx_internal_irq_unmask(irq);
return 0;
}
/*
* external IRQs operations: mask/unmask and clear on PERF external
* irq control register.
*/
static void bcm63xx_external_irq_mask(unsigned int irq)
static void bcm63xx_external_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
u32 reg;
irq -= IRQ_EXT_BASE;
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
reg &= ~EXTIRQ_CFG_MASK(irq);
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
}
static void bcm63xx_external_irq_unmask(unsigned int irq)
static void bcm63xx_external_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
u32 reg;
irq -= IRQ_EXT_BASE;
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
reg |= EXTIRQ_CFG_MASK(irq);
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
}
static void bcm63xx_external_irq_clear(unsigned int irq)
static void bcm63xx_external_irq_clear(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
u32 reg;
irq -= IRQ_EXT_BASE;
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
reg |= EXTIRQ_CFG_CLEAR(irq);
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
}
static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
{
set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
irq_enable_hazard();
bcm63xx_external_irq_unmask(irq);
bcm63xx_external_irq_unmask(d);
return 0;
}
static void bcm63xx_external_irq_shutdown(unsigned int irq)
static void bcm63xx_external_irq_shutdown(struct irq_data *d)
{
bcm63xx_external_irq_mask(irq);
clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
bcm63xx_external_irq_mask(d);
clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
irq_disable_hazard();
}
static int bcm63xx_external_irq_set_type(unsigned int irq,
static int bcm63xx_external_irq_set_type(struct irq_data *d,
unsigned int flow_type)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
u32 reg;
struct irq_desc *desc = irq_desc + irq;
irq -= IRQ_EXT_BASE;
flow_type &= IRQ_TYPE_SENSE_MASK;
......@@ -199,37 +191,32 @@ static int bcm63xx_external_irq_set_type(unsigned int irq,
}
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
desc->status |= IRQ_LEVEL;
desc->handle_irq = handle_level_irq;
} else {
desc->handle_irq = handle_edge_irq;
}
irqd_set_trigger_type(d, flow_type);
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
__irq_set_handler_locked(d->irq, handle_level_irq);
else
__irq_set_handler_locked(d->irq, handle_edge_irq);
return 0;
return IRQ_SET_MASK_OK_NOCOPY;
}
static struct irq_chip bcm63xx_internal_irq_chip = {
.name = "bcm63xx_ipic",
.startup = bcm63xx_internal_irq_startup,
.shutdown = bcm63xx_internal_irq_mask,
.mask = bcm63xx_internal_irq_mask,
.mask_ack = bcm63xx_internal_irq_mask,
.unmask = bcm63xx_internal_irq_unmask,
.irq_mask = bcm63xx_internal_irq_mask,
.irq_unmask = bcm63xx_internal_irq_unmask,
};
static struct irq_chip bcm63xx_external_irq_chip = {
.name = "bcm63xx_epic",
.startup = bcm63xx_external_irq_startup,
.shutdown = bcm63xx_external_irq_shutdown,
.irq_startup = bcm63xx_external_irq_startup,
.irq_shutdown = bcm63xx_external_irq_shutdown,
.ack = bcm63xx_external_irq_clear,
.irq_ack = bcm63xx_external_irq_clear,
.mask = bcm63xx_external_irq_mask,
.unmask = bcm63xx_external_irq_unmask,
.irq_mask = bcm63xx_external_irq_mask,
.irq_unmask = bcm63xx_external_irq_unmask,
.set_type = bcm63xx_external_irq_set_type,
.irq_set_type = bcm63xx_external_irq_set_type,
};
static struct irqaction cpu_ip2_cascade_action = {
......
......@@ -17,80 +17,48 @@
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/ioasic_ints.h>
static int ioasic_irq_base;
static inline void unmask_ioasic_irq(unsigned int irq)
static void unmask_ioasic_irq(struct irq_data *d)
{
u32 simr;
simr = ioasic_read(IO_REG_SIMR);
simr |= (1 << (irq - ioasic_irq_base));
simr |= (1 << (d->irq - ioasic_irq_base));
ioasic_write(IO_REG_SIMR, simr);
}
static inline void mask_ioasic_irq(unsigned int irq)
static void mask_ioasic_irq(struct irq_data *d)
{
u32 simr;
simr = ioasic_read(IO_REG_SIMR);
simr &= ~(1 << (irq - ioasic_irq_base));
simr &= ~(1 << (d->irq - ioasic_irq_base));
ioasic_write(IO_REG_SIMR, simr);
}
static inline void clear_ioasic_irq(unsigned int irq)
static void ack_ioasic_irq(struct irq_data *d)
{
u32 sir;
sir = ~(1 << (irq - ioasic_irq_base));
ioasic_write(IO_REG_SIR, sir);
}
static inline void ack_ioasic_irq(unsigned int irq)
{
mask_ioasic_irq(irq);
mask_ioasic_irq(d);
fast_iob();
}
static inline void end_ioasic_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
unmask_ioasic_irq(irq);
}
static struct irq_chip ioasic_irq_type = {
.name = "IO-ASIC",
.ack = ack_ioasic_irq,
.mask = mask_ioasic_irq,
.mask_ack = ack_ioasic_irq,
.unmask = unmask_ioasic_irq,
.irq_ack = ack_ioasic_irq,
.irq_mask = mask_ioasic_irq,
.irq_mask_ack = ack_ioasic_irq,
.irq_unmask = unmask_ioasic_irq,
};
#define unmask_ioasic_dma_irq unmask_ioasic_irq
#define mask_ioasic_dma_irq mask_ioasic_irq
#define ack_ioasic_dma_irq ack_ioasic_irq
static inline void end_ioasic_dma_irq(unsigned int irq)
{
clear_ioasic_irq(irq);
fast_iob();
end_ioasic_irq(irq);
}
static struct irq_chip ioasic_dma_irq_type = {
.name = "IO-ASIC-DMA",
.ack = ack_ioasic_dma_irq,
.mask = mask_ioasic_dma_irq,
.mask_ack = ack_ioasic_dma_irq,
.unmask = unmask_ioasic_dma_irq,
.end = end_ioasic_dma_irq,
.irq_ack = ack_ioasic_irq,
.irq_mask = mask_ioasic_irq,
.irq_mask_ack = ack_ioasic_irq,
.irq_unmask = unmask_ioasic_irq,
};
void __init init_ioasic_irqs(int base)
{
int i;
......
......@@ -27,43 +27,40 @@
*/
u32 cached_kn02_csr;
static int kn02_irq_base;
static inline void unmask_kn02_irq(unsigned int irq)
static void unmask_kn02_irq(struct irq_data *d)
{
volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
KN02_CSR);
cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
cached_kn02_csr |= (1 << (d->irq - kn02_irq_base + 16));
*csr = cached_kn02_csr;
}
static inline void mask_kn02_irq(unsigned int irq)
static void mask_kn02_irq(struct irq_data *d)
{
volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
KN02_CSR);
cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
cached_kn02_csr &= ~(1 << (d->irq - kn02_irq_base + 16));
*csr = cached_kn02_csr;
}
static void ack_kn02_irq(unsigned int irq)
static void ack_kn02_irq(struct irq_data *d)
{
mask_kn02_irq(irq);
mask_kn02_irq(d);
iob();
}
static struct irq_chip kn02_irq_type = {
.name = "KN02-CSR",
.ack = ack_kn02_irq,
.mask = mask_kn02_irq,
.mask_ack = ack_kn02_irq,
.unmask = unmask_kn02_irq,
.irq_ack = ack_kn02_irq,
.irq_mask = mask_kn02_irq,
.irq_mask_ack = ack_kn02_irq,
.irq_unmask = unmask_kn02_irq,
};
void __init init_kn02_irqs(int base)
{
volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
......
......@@ -34,13 +34,10 @@
#include <asm/emma/emma2rh.h>
static void emma2rh_irq_enable(unsigned int irq)
static void emma2rh_irq_enable(struct irq_data *d)
{
u32 reg_value;
u32 reg_bitmask;
u32 reg_index;
irq -= EMMA2RH_IRQ_BASE;
unsigned int irq = d->irq - EMMA2RH_IRQ_BASE;
u32 reg_value, reg_bitmask, reg_index;
reg_index = EMMA2RH_BHIF_INT_EN_0 +
(EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32);
......@@ -49,13 +46,10 @@ static void emma2rh_irq_enable(unsigned int irq)
emma2rh_out32(reg_index, reg_value | reg_bitmask);
}
static void emma2rh_irq_disable(unsigned int irq)
static void emma2rh_irq_disable(struct irq_data *d)
{
u32 reg_value;
u32 reg_bitmask;
u32 reg_index;
irq -= EMMA2RH_IRQ_BASE;
unsigned int irq = d->irq - EMMA2RH_IRQ_BASE;
u32 reg_value, reg_bitmask, reg_index;
reg_index = EMMA2RH_BHIF_INT_EN_0 +
(EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32);
......@@ -66,10 +60,8 @@ static void emma2rh_irq_disable(unsigned int irq)
struct irq_chip emma2rh_irq_controller = {
.name = "emma2rh_irq",
.ack = emma2rh_irq_disable,
.mask = emma2rh_irq_disable,
.mask_ack = emma2rh_irq_disable,
.unmask = emma2rh_irq_enable,
.irq_mask = emma2rh_irq_disable,
.irq_unmask = emma2rh_irq_enable,
};
void emma2rh_irq_init(void)
......@@ -82,23 +74,21 @@ void emma2rh_irq_init(void)
handle_level_irq, "level");
}
static void emma2rh_sw_irq_enable(unsigned int irq)
static void emma2rh_sw_irq_enable(struct irq_data *d)
{
unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE;
u32 reg;
irq -= EMMA2RH_SW_IRQ_BASE;
reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
reg |= 1 << irq;
emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
}
static void emma2rh_sw_irq_disable(unsigned int irq)
static void emma2rh_sw_irq_disable(struct irq_data *d)
{
unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE;
u32 reg;
irq -= EMMA2RH_SW_IRQ_BASE;
reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
reg &= ~(1 << irq);
emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
......@@ -106,10 +96,8 @@ static void emma2rh_sw_irq_disable(unsigned int irq)
struct irq_chip emma2rh_sw_irq_controller = {
.name = "emma2rh_sw_irq",
.ack = emma2rh_sw_irq_disable,
.mask = emma2rh_sw_irq_disable,
.mask_ack = emma2rh_sw_irq_disable,
.unmask = emma2rh_sw_irq_enable,
.irq_mask = emma2rh_sw_irq_disable,
.irq_unmask = emma2rh_sw_irq_enable,
};
void emma2rh_sw_irq_init(void)
......@@ -122,39 +110,38 @@ void emma2rh_sw_irq_init(void)
handle_level_irq, "level");
}
static void emma2rh_gpio_irq_enable(unsigned int irq)
static void emma2rh_gpio_irq_enable(struct irq_data *d)
{
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
u32 reg;
irq -= EMMA2RH_GPIO_IRQ_BASE;
reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
reg |= 1 << irq;
emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
}
static void emma2rh_gpio_irq_disable(unsigned int irq)
static void emma2rh_gpio_irq_disable(struct irq_data *d)
{
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
u32 reg;
irq -= EMMA2RH_GPIO_IRQ_BASE;
reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
reg &= ~(1 << irq);
emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
}
static void emma2rh_gpio_irq_ack(unsigned int irq)
static void emma2rh_gpio_irq_ack(struct irq_data *d)
{
irq -= EMMA2RH_GPIO_IRQ_BASE;
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
}
static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
static void emma2rh_gpio_irq_mask_ack(struct irq_data *d)
{
unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
u32 reg;
irq -= EMMA2RH_GPIO_IRQ_BASE;
emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
......@@ -164,10 +151,10 @@ static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
struct irq_chip emma2rh_gpio_irq_controller = {
.name = "emma2rh_gpio_irq",
.ack = emma2rh_gpio_irq_ack,
.mask = emma2rh_gpio_irq_disable,
.mask_ack = emma2rh_gpio_irq_mask_ack,
.unmask = emma2rh_gpio_irq_enable,
.irq_ack = emma2rh_gpio_irq_ack,
.irq_mask = emma2rh_gpio_irq_disable,
.irq_mask_ack = emma2rh_gpio_irq_mask_ack,
.irq_unmask = emma2rh_gpio_irq_enable,
};
void emma2rh_gpio_irq_init(void)
......
......@@ -55,9 +55,9 @@ static inline void smtc_im_ack_irq(unsigned int irq)
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
#include <linux/cpumask.h>
extern int plat_set_irq_affinity(unsigned int irq,
const struct cpumask *affinity);
extern void smtc_forward_irq(unsigned int irq);
extern int plat_set_irq_affinity(struct irq_data *d,
const struct cpumask *affinity, bool force);
extern void smtc_forward_irq(struct irq_data *d);
/*
* IRQ affinity hook invoked at the beginning of interrupt dispatch
......@@ -70,51 +70,53 @@ extern void smtc_forward_irq(unsigned int irq);
* cpumask implementations, this version is optimistically assuming
* that cpumask.h macro overhead is reasonable during interrupt dispatch.
*/
#define IRQ_AFFINITY_HOOK(irq) \
do { \
if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\
smtc_forward_irq(irq); \
irq_exit(); \
return; \
} \
} while (0)
static inline int handle_on_other_cpu(unsigned int irq)
{
struct irq_data *d = irq_get_irq_data(irq);
if (cpumask_test_cpu(smp_processor_id(), d->affinity))
return 0;
smtc_forward_irq(d);
return 1;
}
#else /* Not doing SMTC affinity */
#define IRQ_AFFINITY_HOOK(irq) do { } while (0)
static inline int handle_on_other_cpu(unsigned int irq) { return 0; }
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
static inline void smtc_im_backstop(unsigned int irq)
{
if (irq_hwmask[irq] & 0x0000ff00)
write_c0_tccontext(read_c0_tccontext() &
~(irq_hwmask[irq] & 0x0000ff00));
}
/*
* Clear interrupt mask handling "backstop" if irq_hwmask
* entry so indicates. This implies that the ack() or end()
* functions will take over re-enabling the low-level mask.
* Otherwise it will be done on return from exception.
*/
#define __DO_IRQ_SMTC_HOOK(irq) \
do { \
IRQ_AFFINITY_HOOK(irq); \
if (irq_hwmask[irq] & 0x0000ff00) \
write_c0_tccontext(read_c0_tccontext() & \
~(irq_hwmask[irq] & 0x0000ff00)); \
} while (0)
#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
......
/*
* 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 */
/*
*
* Macros for external SMP-safe access to the PMC MSP71xx reference
* board GPIO pins
*
* Copyright 2010 PMC-Sierra, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MSP_GPIO_MACROS_H__
#define __MSP_GPIO_MACROS_H__
#include <msp_regops.h>
#include <msp_regs.h>
#ifdef CONFIG_PMC_MSP7120_GW
#define MSP_NUM_GPIOS 20
#else
#define MSP_NUM_GPIOS 28
#endif
/* -- GPIO Enumerations -- */
enum msp_gpio_data {
MSP_GPIO_LO = 0,
MSP_GPIO_HI = 1,
MSP_GPIO_NONE, /* Special - Means pin is out of range */
MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */
};
enum msp_gpio_mode {
MSP_GPIO_INPUT = 0x0,
/* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */
MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */
MSP_GPIO_OUTPUT = 0x8,
MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */
MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */
MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */
MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */
};
/* -- Static Tables -- */
/* Maps pins to data register */
static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
/* GPIO 0 and 1 on the first register */
GPIO_DATA1_REG, GPIO_DATA1_REG,
/* GPIO 2, 3, 4, and 5 on the second register */
GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
/* GPIO 6, 7, 8, and 9 on the third register */
GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
GPIO_DATA4_REG, GPIO_DATA4_REG,
/* GPIO 16 - 23 on the first strange EXTENDED register */
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
/* GPIO 24 - 27 on the second strange EXTENDED register */
EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
EXTENDED_GPIO2_REG,
};
/* Maps pins to mode register */
static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
/* GPIO 0 and 1 on the first register */
GPIO_CFG1_REG, GPIO_CFG1_REG,
/* GPIO 2, 3, 4, and 5 on the second register */
GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
/* GPIO 6, 7, 8, and 9 on the third register */
GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
GPIO_CFG4_REG, GPIO_CFG4_REG,
/* GPIO 16 - 23 on the first strange EXTENDED register */
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
/* GPIO 24 - 27 on the second strange EXTENDED register */
EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
EXTENDED_GPIO2_REG,
};
/* Maps 'basic' pins to relative offset from 0 per register */
static int MSP_GPIO_OFFSET[] = {
/* GPIO 0 and 1 on the first register */
0, 0,
/* GPIO 2, 3, 4, and 5 on the second register */
2, 2, 2, 2,
/* GPIO 6, 7, 8, and 9 on the third register */
6, 6, 6, 6,
/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
10, 10, 10, 10, 10, 10,
};
/* Maps MODE to allowed pin mask */
static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
0xffffffff, /* Mode 0 - INPUT */
0x00000, /* Mode 1 - INTERRUPT */
0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/
0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */
0xffffffff, /* Mode 8 - OUTPUT */
0x0000f, /* Mode 9 - UART_OUTPUT/
PERF_TIMERA (GPIO 0, 1, 2, 3) */
0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */
0x00000, /* Mode b - Not really a mode! */
};
/* -- Bit masks -- */
/* This gives you the 'register relative offset gpio' number */
#define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio])
/* These take the 'register relative offset gpio' number */
#define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio)
#define BASIC_MODE_REG_VALUE(mode, ogpio) \
(mode << BASIC_MODE_REG_SHIFT(ogpio))
#define BASIC_MODE_REG_MASK(ogpio) \
BASIC_MODE_REG_VALUE(0xf, ogpio)
#define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4)
#define BASIC_MODE_REG_FROM_REG(data, ogpio) \
((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))
/* These take the actual GPIO number (0 through 15) */
#define BASIC_DATA_MASK(gpio) \
BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE_MASK(gpio) \
BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE(mode, gpio) \
BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE_SHIFT(gpio) \
BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
#define BASIC_MODE_FROM_REG(data, gpio) \
BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))
/*
* Each extended GPIO register is 32 bits long and is responsible for up to
* eight GPIOs. The least significant 16 bits contain the set and clear bit
* pair for each of the GPIOs. The most significant 16 bits contain the
* disable and enable bit pair for each of the GPIOs. For example, the
* extended GPIO reg for GPIOs 16-23 is as follows:
*
* 31: GPIO23_DISABLE
* ...
* 19: GPIO17_DISABLE
* 18: GPIO17_ENABLE
* 17: GPIO16_DISABLE
* 16: GPIO16_ENABLE
* ...
* 3: GPIO17_SET
* 2: GPIO17_CLEAR
* 1: GPIO16_SET
* 0: GPIO16_CLEAR
*/
/* This gives the 'register relative offset gpio' number */
#define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24)
/* These take the 'register relative offset gpio' number */
#define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16))
#define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16))
#define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2))
#define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2))
/* These take the actual GPIO number (16 through 27) */
#define EXTENDED_DISABLE(gpio) \
EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_ENABLE(gpio) \
EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_SET(gpio) \
EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_CLR(gpio) \
EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))
#define EXTENDED_FULL_MASK (0xffffffff)
/* -- API inline-functions -- */
/*
* Gets the current value of the specified pin
*/
static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio)
{
u32 pinhi_mask = 0, pinhi_mask2 = 0;
if (gpio >= MSP_NUM_GPIOS)
return MSP_GPIO_NONE;
if (gpio < 16) {
pinhi_mask = BASIC_DATA_MASK(gpio);
} else {
/*
* Two cases are possible with the EXTENDED register:
* - In output mode (ENABLED flag set), check the CLR bit
* - In input mode (ENABLED flag not set), check the SET bit
*/
pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio);
pinhi_mask2 = EXTENDED_SET(gpio);
}
if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) ||
(*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2))
return MSP_GPIO_HI;
else
return MSP_GPIO_LO;
}
/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio)
{
if (gpio >= MSP_NUM_GPIOS)
return;
if (gpio < 16) {
if (data == MSP_GPIO_TOGGLE)
toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio],
BASIC_DATA_MASK(gpio));
else if (data == MSP_GPIO_HI)
set_reg32(MSP_GPIO_DATA_REGISTER[gpio],
BASIC_DATA_MASK(gpio));
else
clear_reg32(MSP_GPIO_DATA_REGISTER[gpio],
BASIC_DATA_MASK(gpio));
} else {
if (data == MSP_GPIO_TOGGLE) {
/* Special ugly case:
* We have to read the CLR bit.
* If set, we write the CLR bit.
* If not, we write the SET bit.
*/
u32 tmpdata;
custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio],
tmpdata);
if (tmpdata & EXTENDED_CLR(gpio))
tmpdata = EXTENDED_CLR(gpio);
else
tmpdata = EXTENDED_SET(gpio);
custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio],
tmpdata);
} else {
u32 newdata;
if (data == MSP_GPIO_HI)
newdata = EXTENDED_SET(gpio);
else
newdata = EXTENDED_CLR(gpio);
set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio],
EXTENDED_FULL_MASK, newdata);
}
}
}
/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_hi(unsigned int gpio)
{
msp_gpio_pin_set(MSP_GPIO_HI, gpio);
}
/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_lo(unsigned int gpio)
{
msp_gpio_pin_set(MSP_GPIO_LO, gpio);
}
/* Sets the specified pin to the opposite value */
static inline void msp_gpio_pin_toggle(unsigned int gpio)
{
msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio);
}
/* Gets the mode of the specified pin */
static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
{
enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN;
uint32_t data;
if (gpio >= MSP_NUM_GPIOS)
return retval;
data = *MSP_GPIO_MODE_REGISTER[gpio];
if (gpio < 16) {
retval = BASIC_MODE_FROM_REG(data, gpio);
} else {
/* Extended pins can only be either INPUT or OUTPUT */
if (data & EXTENDED_ENABLE(gpio))
retval = MSP_GPIO_OUTPUT;
else
retval = MSP_GPIO_INPUT;
}
return retval;
}
/*
* Sets the specified mode on the requested pin
* Returns 0 on success, or -1 if that mode is not allowed on this pin
*/
static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio)
{
u32 modemask, newmode;
if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode])
return -1;
if (gpio >= MSP_NUM_GPIOS)
return -1;
if (gpio < 16) {
modemask = BASIC_MODE_MASK(gpio);
newmode = BASIC_MODE(mode, gpio);
} else {
modemask = EXTENDED_FULL_MASK;
if (mode == MSP_GPIO_INPUT)
newmode = EXTENDED_DISABLE(gpio);
else
newmode = EXTENDED_ENABLE(gpio);
}
/* Do the set atomically */
set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode);
return 0;
}
#endif /* __MSP_GPIO_MACROS_H__ */
......@@ -91,12 +91,10 @@
/* MAC C device registers */
#define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000)
/* ADSL2 device registers */
#define MSP_USB_BASE (MSP_MSB_BASE + 0xB40000)
/* USB device registers */
#define MSP_USB_BASE_START (MSP_MSB_BASE + 0xB40100)
/* USB device registers */
#define MSP_USB_BASE_END (MSP_MSB_BASE + 0xB401FF)
/* USB device registers */
#define MSP_USB0_BASE (MSP_MSB_BASE + 0xB00000)
/* USB0 device registers */
#define MSP_USB1_BASE (MSP_MSB_BASE + 0x300000)
/* USB1 device registers */
#define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000)
/* CPU interface registers */
......@@ -319,8 +317,11 @@
#define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184)
/* CPU/SLP Error status 1 */
#define EXTENDED_GPIO_REG regptr(MSP_SLP_BASE + 0x188)
/* Extended GPIO register */
/* Extended GPIO registers */
#define EXTENDED_GPIO1_REG regptr(MSP_SLP_BASE + 0x188)
#define EXTENDED_GPIO2_REG regptr(MSP_SLP_BASE + 0x18c)
#define EXTENDED_GPIO_REG EXTENDED_GPIO1_REG
/* Backward-compatibility */
/* System Error registers */
#define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190)
......
/******************************************************************
* Copyright (c) 2000-2007 PMC-Sierra INC.
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
* 02139, USA.
*
* PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
* SOFTWARE.
*/
#ifndef MSP_USB_H_
#define MSP_USB_H_
#ifdef CONFIG_MSP_HAS_DUAL_USB
#define NUM_USB_DEVS 2
#else
#define NUM_USB_DEVS 1
#endif
/* Register spaces for USB host 0 */
#define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0)
#define MSP_USB0_MAB_END (MSP_USB0_BASE + 0x17)
#define MSP_USB0_ID_START (MSP_USB0_BASE + 0x40000)
#define MSP_USB0_ID_END (MSP_USB0_BASE + 0x4008f)
#define MSP_USB0_HS_START (MSP_USB0_BASE + 0x40100)
#define MSP_USB0_HS_END (MSP_USB0_BASE + 0x401FF)
/* Register spaces for USB host 1 */
#define MSP_USB1_MAB_START (MSP_USB1_BASE + 0x0)
#define MSP_USB1_MAB_END (MSP_USB1_BASE + 0x17)
#define MSP_USB1_ID_START (MSP_USB1_BASE + 0x40000)
#define MSP_USB1_ID_END (MSP_USB1_BASE + 0x4008f)
#define MSP_USB1_HS_START (MSP_USB1_BASE + 0x40100)
#define MSP_USB1_HS_END (MSP_USB1_BASE + 0x401ff)
/* USB Identification registers */
struct msp_usbid_regs {
u32 id; /* 0x0: Identification register */
u32 hwgen; /* 0x4: General HW params */
u32 hwhost; /* 0x8: Host HW params */
u32 hwdev; /* 0xc: Device HW params */
u32 hwtxbuf; /* 0x10: Tx buffer HW params */
u32 hwrxbuf; /* 0x14: Rx buffer HW params */
u32 reserved[26];
u32 timer0_load; /* 0x80: General-purpose timer 0 load*/
u32 timer0_ctrl; /* 0x84: General-purpose timer 0 control */
u32 timer1_load; /* 0x88: General-purpose timer 1 load*/
u32 timer1_ctrl; /* 0x8c: General-purpose timer 1 control */
};
/* MSBus to AMBA registers */
struct msp_mab_regs {
u32 isr; /* 0x0: Interrupt status */
u32 imr; /* 0x4: Interrupt mask */
u32 thcr0; /* 0x8: Transaction header capture 0 */
u32 thcr1; /* 0xc: Transaction header capture 1 */
u32 int_stat; /* 0x10: Interrupt status summary */
u32 phy_cfg; /* 0x14: USB phy config */
};
/* EHCI registers */
struct msp_usbhs_regs {
u32 hciver; /* 0x0: Version and offset to operational regs */
u32 hcsparams; /* 0x4: Host control structural parameters */
u32 hccparams; /* 0x8: Host control capability parameters */
u32 reserved0[5];
u32 dciver; /* 0x20: Device interface version */
u32 dccparams; /* 0x24: Device control capability parameters */
u32 reserved1[6];
u32 cmd; /* 0x40: USB command */
u32 sts; /* 0x44: USB status */
u32 int_ena; /* 0x48: USB interrupt enable */
u32 frindex; /* 0x4c: Frame index */
u32 reserved3;
union {
struct {
u32 flb_addr; /* 0x54: Frame list base address */
u32 next_async_addr; /* 0x58: next asynchronous addr */
u32 ttctrl; /* 0x5c: embedded transaction translator
async buffer status */
u32 burst_size; /* 0x60: Controller burst size */
u32 tx_fifo_ctrl; /* 0x64: Tx latency FIFO tuning */
u32 reserved0[4];
u32 endpt_nak; /* 0x78: Endpoint NAK */
u32 endpt_nak_ena; /* 0x7c: Endpoint NAK enable */
u32 cfg_flag; /* 0x80: Config flag */
u32 port_sc1; /* 0x84: Port status & control 1 */
u32 reserved1[7];
u32 otgsc; /* 0xa4: OTG status & control */
u32 mode; /* 0xa8: USB controller mode */
} host;
struct {
u32 dev_addr; /* 0x54: Device address */
u32 endpt_list_addr; /* 0x58: Endpoint list address */
u32 reserved0[7];
u32 endpt_nak; /* 0x74 */
u32 endpt_nak_ctrl; /* 0x78 */
u32 cfg_flag; /* 0x80 */
u32 port_sc1; /* 0x84: Port status & control 1 */
u32 reserved[7];
u32 otgsc; /* 0xa4: OTG status & control */
u32 mode; /* 0xa8: USB controller mode */
u32 endpt_setup_stat; /* 0xac */
u32 endpt_prime; /* 0xb0 */
u32 endpt_flush; /* 0xb4 */
u32 endpt_stat; /* 0xb8 */
u32 endpt_complete; /* 0xbc */
u32 endpt_ctrl0; /* 0xc0 */
u32 endpt_ctrl1; /* 0xc4 */
u32 endpt_ctrl2; /* 0xc8 */
u32 endpt_ctrl3; /* 0xcc */
} device;
} u;
};
/*
* Container for the more-generic platform_device.
* This exists mainly as a way to map the non-standard register
* spaces and make them accessible to the USB ISR.
*/
struct mspusb_device {
struct msp_mab_regs __iomem *mab_regs;
struct msp_usbid_regs __iomem *usbid_regs;
struct msp_usbhs_regs __iomem *usbhs_regs;
struct platform_device dev;
};
#define to_mspusb_device(x) container_of((x), struct mspusb_device, dev)
#define TO_HOST_ID(x) ((x) & 0x3)
#endif /*MSP_USB_H_*/
......@@ -245,16 +245,16 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
__asm__ __volatile__(
" .set noreorder # arch_read_lock \n"
"1: ll %1, %2 \n"
" bltz %1, 2f \n"
" bltz %1, 3f \n"
" addu %1, 1 \n"
" sc %1, %0 \n"
"2: sc %1, %0 \n"
" beqz %1, 1b \n"
" nop \n"
" .subsection 2 \n"
"2: ll %1, %2 \n"
" bltz %1, 2b \n"
"3: ll %1, %2 \n"
" bltz %1, 3b \n"
" addu %1, 1 \n"
" b 1b \n"
" b 2b \n"
" nop \n"
" .previous \n"
" .set reorder \n"
......@@ -324,16 +324,16 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
__asm__ __volatile__(
" .set noreorder # arch_write_lock \n"
"1: ll %1, %2 \n"
" bnez %1, 2f \n"
" bnez %1, 3f \n"
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqz %1, 2f \n"
"2: sc %1, %0 \n"
" beqz %1, 3f \n"
" nop \n"
" .subsection 2 \n"
"2: ll %1, %2 \n"
" bnez %1, 2b \n"
"3: ll %1, %2 \n"
" bnez %1, 3b \n"
" lui %1, 0x8000 \n"
" b 1b \n"
" b 2b \n"
" nop \n"
" .previous \n"
" .set reorder \n"
......
......@@ -359,16 +359,20 @@
#define __NR_fanotify_init (__NR_Linux + 336)
#define __NR_fanotify_mark (__NR_Linux + 337)
#define __NR_prlimit64 (__NR_Linux + 338)
#define __NR_name_to_handle_at (__NR_Linux + 339)
#define __NR_open_by_handle_at (__NR_Linux + 340)
#define __NR_clock_adjtime (__NR_Linux + 341)
#define __NR_syncfs (__NR_Linux + 342)
/*
* Offset of the last Linux o32 flavoured syscall
*/
#define __NR_Linux_syscalls 338
#define __NR_Linux_syscalls 342
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
#define __NR_O32_Linux_syscalls 338
#define __NR_O32_Linux_syscalls 342
#if _MIPS_SIM == _MIPS_SIM_ABI64
......@@ -674,16 +678,20 @@
#define __NR_fanotify_init (__NR_Linux + 295)
#define __NR_fanotify_mark (__NR_Linux + 296)
#define __NR_prlimit64 (__NR_Linux + 297)
#define __NR_name_to_handle_at (__NR_Linux + 298)
#define __NR_open_by_handle_at (__NR_Linux + 299)
#define __NR_clock_adjtime (__NR_Linux + 300)
#define __NR_syncfs (__NR_Linux + 301)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
#define __NR_Linux_syscalls 297
#define __NR_Linux_syscalls 301
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
#define __NR_64_Linux_syscalls 297
#define __NR_64_Linux_syscalls 301
#if _MIPS_SIM == _MIPS_SIM_NABI32
......@@ -994,16 +1002,20 @@
#define __NR_fanotify_init (__NR_Linux + 300)
#define __NR_fanotify_mark (__NR_Linux + 301)
#define __NR_prlimit64 (__NR_Linux + 302)
#define __NR_name_to_handle_at (__NR_Linux + 303)
#define __NR_open_by_handle_at (__NR_Linux + 304)
#define __NR_clock_adjtime (__NR_Linux + 305)
#define __NR_clock_adjtime (__NR_Linux + 306)
/*
* Offset of the last N32 flavoured syscall
*/
#define __NR_Linux_syscalls 302
#define __NR_Linux_syscalls 306
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
#define __NR_N32_Linux_syscalls 302
#define __NR_N32_Linux_syscalls 306
#ifdef __KERNEL__
......
......@@ -23,9 +23,9 @@
static DEFINE_RAW_SPINLOCK(r4030_lock);
static void enable_r4030_irq(unsigned int irq)
static void enable_r4030_irq(struct irq_data *d)
{
unsigned int mask = 1 << (irq - JAZZ_IRQ_START);
unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START);
unsigned long flags;
raw_spin_lock_irqsave(&r4030_lock, flags);
......@@ -34,9 +34,9 @@ static void enable_r4030_irq(unsigned int irq)
raw_spin_unlock_irqrestore(&r4030_lock, flags);
}
void disable_r4030_irq(unsigned int irq)
void disable_r4030_irq(struct irq_data *d)
{
unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START));
unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START));
unsigned long flags;
raw_spin_lock_irqsave(&r4030_lock, flags);
......@@ -47,10 +47,8 @@ void disable_r4030_irq(unsigned int irq)
static struct irq_chip r4030_irq_type = {
.name = "R4030",
.ack = disable_r4030_irq,
.mask = disable_r4030_irq,
.mask_ack = disable_r4030_irq,
.unmask = enable_r4030_irq,
.irq_mask = disable_r4030_irq,
.irq_unmask = enable_r4030_irq,
};
void __init init_r4030_ints(void)
......
......@@ -23,6 +23,7 @@
#include <linux/spi/spi_gpio.h>
#include <linux/power_supply.h>
#include <linux/power/jz4740-battery.h>
#include <linux/power/gpio-charger.h>
#include <asm/mach-jz4740/jz4740_fb.h>
#include <asm/mach-jz4740/jz4740_mmc.h>
......@@ -49,14 +50,14 @@ static bool is_avt2;
/* NAND */
static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
/* .eccbytes = 36,
.eccbytes = 36,
.eccpos = {
6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41
},*/
},
.oobfree = {
{ .offset = 2, .length = 4 },
{ .offset = 42, .length = 22 }
......@@ -85,7 +86,7 @@ static struct mtd_partition qi_lb60_partitions_1gb[] = {
};
static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
/* .eccbytes = 72,
.eccbytes = 72,
.eccpos = {
12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27,
......@@ -96,7 +97,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82, 83
},*/
},
.oobfree = {
{ .offset = 2, .length = 10 },
{ .offset = 84, .length = 44 },
......@@ -396,6 +397,28 @@ static struct platform_device qi_lb60_pwm_beeper = {
},
};
/* charger */
static char *qi_lb60_batteries[] = {
"battery",
};
static struct gpio_charger_platform_data qi_lb60_charger_pdata = {
.name = "usb",
.type = POWER_SUPPLY_TYPE_USB,
.gpio = JZ_GPIO_PORTD(28),
.gpio_active_low = 1,
.supplied_to = qi_lb60_batteries,
.num_supplicants = ARRAY_SIZE(qi_lb60_batteries),
};
static struct platform_device qi_lb60_charger_device = {
.name = "gpio-charger",
.dev = {
.platform_data = &qi_lb60_charger_pdata,
},
};
static struct platform_device *jz_platform_devices[] __initdata = {
&jz4740_udc_device,
&jz4740_mmc_device,
......@@ -410,6 +433,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&jz4740_adc_device,
&qi_lb60_gpio_keys,
&qi_lb60_pwm_beeper,
&qi_lb60_charger_device,
};
static void __init board_gpio_setup(void)
......
......@@ -86,7 +86,6 @@ struct jz_gpio_chip {
spinlock_t lock;
struct gpio_chip gpio_chip;
struct irq_chip irq_chip;
struct sys_device sysdev;
};
......@@ -102,9 +101,9 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g
return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
}
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq)
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
{
return get_irq_chip_data(irq);
return irq_data_get_irq_chip_data(data);
}
static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
......@@ -325,62 +324,52 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(gpio_irq);
};
static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
writel(IRQ_TO_BIT(irq), chip->base + reg);
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
writel(IRQ_TO_BIT(data->irq), chip->base + reg);
}
static void jz_gpio_irq_mask(unsigned int irq)
static void jz_gpio_irq_mask(struct irq_data *data)
{
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET);
};
static void jz_gpio_irq_unmask(unsigned int irq)
static void jz_gpio_irq_unmask(struct irq_data *data)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
jz_gpio_check_trigger_both(chip, irq);
jz_gpio_check_trigger_both(chip, data->irq);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR);
};
/* TODO: Check if function is gpio */
static unsigned int jz_gpio_irq_startup(unsigned int irq)
static unsigned int jz_gpio_irq_startup(struct irq_data *data)
{
struct irq_desc *desc = irq_to_desc(irq);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
desc->status &= ~IRQ_MASKED;
jz_gpio_irq_unmask(irq);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
jz_gpio_irq_unmask(data);
return 0;
}
static void jz_gpio_irq_shutdown(unsigned int irq)
static void jz_gpio_irq_shutdown(struct irq_data *data)
{
struct irq_desc *desc = irq_to_desc(irq);
jz_gpio_irq_mask(irq);
desc->status |= IRQ_MASKED;
jz_gpio_irq_mask(data);
/* Set direction to input */
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
}
static void jz_gpio_irq_ack(unsigned int irq)
static void jz_gpio_irq_ack(struct irq_data *data)
{
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR);
};
static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
struct irq_desc *desc = irq_to_desc(irq);
jz_gpio_irq_mask(irq);
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
unsigned int irq = data->irq;
if (flow_type == IRQ_TYPE_EDGE_BOTH) {
uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
......@@ -395,45 +384,54 @@ static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
switch (flow_type) {
case IRQ_TYPE_EDGE_RISING:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
break;
case IRQ_TYPE_EDGE_FALLING:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
break;
case IRQ_TYPE_LEVEL_HIGH:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
break;
case IRQ_TYPE_LEVEL_LOW:
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
break;
default:
return -EINVAL;
}
if (!(desc->status & IRQ_MASKED))
jz_gpio_irq_unmask(irq);
return 0;
}
static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on)
static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
spin_lock(&chip->lock);
if (on)
chip->wakeup |= IRQ_TO_BIT(irq);
chip->wakeup |= IRQ_TO_BIT(data->irq);
else
chip->wakeup &= ~IRQ_TO_BIT(irq);
chip->wakeup &= ~IRQ_TO_BIT(data->irq);
spin_unlock(&chip->lock);
set_irq_wake(chip->irq, on);
return 0;
}
static struct irq_chip jz_gpio_irq_chip = {
.name = "GPIO",
.irq_mask = jz_gpio_irq_mask,
.irq_unmask = jz_gpio_irq_unmask,
.irq_ack = jz_gpio_irq_ack,
.irq_startup = jz_gpio_irq_startup,
.irq_shutdown = jz_gpio_irq_shutdown,
.irq_set_type = jz_gpio_irq_set_type,
.irq_set_wake = jz_gpio_irq_set_wake,
.flags = IRQCHIP_SET_TYPE_MASKED,
};
/*
* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
......@@ -452,16 +450,6 @@ static struct lock_class_key gpio_lock_class;
.base = JZ4740_GPIO_BASE_ ## _bank, \
.ngpio = JZ4740_GPIO_NUM_ ## _bank, \
}, \
.irq_chip = { \
.name = "GPIO Bank " # _bank, \
.mask = jz_gpio_irq_mask, \
.unmask = jz_gpio_irq_unmask, \
.ack = jz_gpio_irq_ack, \
.startup = jz_gpio_irq_startup, \
.shutdown = jz_gpio_irq_shutdown, \
.set_type = jz_gpio_irq_set_type, \
.set_wake = jz_gpio_irq_set_wake, \
}, \
}
static struct jz_gpio_chip jz4740_gpio_chips[] = {
......@@ -526,9 +514,10 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class);
irq_set_lockdep_class(irq, &gpio_lock_class);
set_irq_chip_data(irq, chip);
set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq);
set_irq_chip_and_handler(irq, &jz_gpio_irq_chip,
handle_level_irq);
}
return 0;
......
......@@ -43,32 +43,37 @@ static uint32_t jz_intc_saved;
#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
static void intc_irq_unmask(unsigned int irq)
static inline unsigned long intc_irq_bit(struct irq_data *data)
{
writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
return (unsigned long)irq_data_get_irq_chip_data(data);
}
static void intc_irq_mask(unsigned int irq)
static void intc_irq_unmask(struct irq_data *data)
{
writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK);
writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
}
static int intc_irq_set_wake(unsigned int irq, unsigned int on)
static void intc_irq_mask(struct irq_data *data)
{
writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK);
}
static int intc_irq_set_wake(struct irq_data *data, unsigned int on)
{
if (on)
jz_intc_wakeup |= IRQ_BIT(irq);
jz_intc_wakeup |= intc_irq_bit(data);
else
jz_intc_wakeup &= ~IRQ_BIT(irq);
jz_intc_wakeup &= ~intc_irq_bit(data);
return 0;
}
static struct irq_chip intc_irq_type = {
.name = "INTC",
.mask = intc_irq_mask,
.mask_ack = intc_irq_mask,
.unmask = intc_irq_unmask,
.set_wake = intc_irq_set_wake,
.irq_mask = intc_irq_mask,
.irq_mask_ack = intc_irq_mask,
.irq_unmask = intc_irq_unmask,
.irq_set_wake = intc_irq_set_wake,
};
static irqreturn_t jz4740_cascade(int irq, void *data)
......@@ -95,8 +100,11 @@ void __init arch_init_irq(void)
jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
/* Mask all irqs */
writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
intc_irq_mask(i);
set_irq_chip_data(i, (void *)IRQ_BIT(i));
set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
}
......
......@@ -31,19 +31,19 @@
static int i8259A_auto_eoi = -1;
DEFINE_RAW_SPINLOCK(i8259A_lock);
static void disable_8259A_irq(unsigned int irq);
static void enable_8259A_irq(unsigned int irq);
static void mask_and_ack_8259A(unsigned int irq);
static void disable_8259A_irq(struct irq_data *d);
static void enable_8259A_irq(struct irq_data *d);
static void mask_and_ack_8259A(struct irq_data *d);
static void init_8259A(int auto_eoi);
static struct irq_chip i8259A_chip = {
.name = "XT-PIC",
.mask = disable_8259A_irq,
.disable = disable_8259A_irq,
.unmask = enable_8259A_irq,
.mask_ack = mask_and_ack_8259A,
.name = "XT-PIC",
.irq_mask = disable_8259A_irq,
.irq_disable = disable_8259A_irq,
.irq_unmask = enable_8259A_irq,
.irq_mask_ack = mask_and_ack_8259A,
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
.set_affinity = plat_set_irq_affinity,
.irq_set_affinity = plat_set_irq_affinity,
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
};
......@@ -59,12 +59,11 @@ static unsigned int cached_irq_mask = 0xffff;
#define cached_master_mask (cached_irq_mask)
#define cached_slave_mask (cached_irq_mask >> 8)
static void disable_8259A_irq(unsigned int irq)
static void disable_8259A_irq(struct irq_data *d)
{
unsigned int mask;
unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
unsigned long flags;
irq -= I8259A_IRQ_BASE;
mask = 1 << irq;
raw_spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask |= mask;
......@@ -75,12 +74,11 @@ static void disable_8259A_irq(unsigned int irq)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
static void enable_8259A_irq(unsigned int irq)
static void enable_8259A_irq(struct irq_data *d)
{
unsigned int mask;
unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
unsigned long flags;
irq -= I8259A_IRQ_BASE;
mask = ~(1 << irq);
raw_spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask &= mask;
......@@ -145,12 +143,11 @@ static inline int i8259A_irq_real(unsigned int irq)
* first, _then_ send the EOI, and the order of EOI
* to the two 8259s is important!
*/
static void mask_and_ack_8259A(unsigned int irq)
static void mask_and_ack_8259A(struct irq_data *d)
{
unsigned int irqmask;
unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE;
unsigned long flags;
irq -= I8259A_IRQ_BASE;
irqmask = 1 << irq;
raw_spin_lock_irqsave(&i8259A_lock, flags);
/*
......@@ -290,9 +287,9 @@ static void init_8259A(int auto_eoi)
* In AEOI mode we just have to mask the interrupt
* when acking.
*/
i8259A_chip.mask_ack = disable_8259A_irq;
i8259A_chip.irq_mask_ack = disable_8259A_irq;
else
i8259A_chip.mask_ack = mask_and_ack_8259A;
i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
udelay(100); /* wait for 8259A to initialize */
......
......@@ -87,17 +87,10 @@ unsigned int gic_get_int(void)
return i;
}
static unsigned int gic_irq_startup(unsigned int irq)
static void gic_irq_ack(struct irq_data *d)
{
irq -= _irqbase;
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_SET_INTR_MASK(irq);
return 0;
}
unsigned int irq = d->irq - _irqbase;
static void gic_irq_ack(unsigned int irq)
{
irq -= _irqbase;
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_CLR_INTR_MASK(irq);
......@@ -105,16 +98,16 @@ static void gic_irq_ack(unsigned int irq)
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
}
static void gic_mask_irq(unsigned int irq)
static void gic_mask_irq(struct irq_data *d)
{
irq -= _irqbase;
unsigned int irq = d->irq - _irqbase;
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_CLR_INTR_MASK(irq);
}
static void gic_unmask_irq(unsigned int irq)
static void gic_unmask_irq(struct irq_data *d)
{
irq -= _irqbase;
unsigned int irq = d->irq - _irqbase;
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_SET_INTR_MASK(irq);
}
......@@ -123,13 +116,14 @@ static void gic_unmask_irq(unsigned int irq)
static DEFINE_SPINLOCK(gic_lock);
static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
bool force)
{
unsigned int irq = d->irq - _irqbase;
cpumask_t tmp = CPU_MASK_NONE;
unsigned long flags;
int i;
irq -= _irqbase;
pr_debug("%s(%d) called\n", __func__, irq);
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp))
......@@ -147,23 +141,22 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
}
cpumask_copy(irq_desc[irq].affinity, cpumask);
cpumask_copy(d->affinity, cpumask);
spin_unlock_irqrestore(&gic_lock, flags);
return 0;
return IRQ_SET_MASK_OK_NOCOPY;
}
#endif
static struct irq_chip gic_irq_controller = {
.name = "MIPS GIC",
.startup = gic_irq_startup,
.ack = gic_irq_ack,
.mask = gic_mask_irq,
.mask_ack = gic_mask_irq,
.unmask = gic_unmask_irq,
.eoi = gic_unmask_irq,
.name = "MIPS GIC",
.irq_ack = gic_irq_ack,
.irq_mask = gic_mask_irq,
.irq_mask_ack = gic_mask_irq,
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_unmask_irq,
#ifdef CONFIG_SMP
.set_affinity = gic_set_affinity,
.irq_set_affinity = gic_set_affinity,
#endif
};
......
......@@ -29,64 +29,64 @@
static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
static void ack_gt641xx_irq(unsigned int irq)
static void ack_gt641xx_irq(struct irq_data *d)
{
unsigned long flags;
u32 cause;
raw_spin_lock_irqsave(&gt641xx_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(&gt641xx_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(&gt641xx_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(&gt641xx_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(&gt641xx_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(&gt641xx_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(&gt641xx_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(&gt641xx_irq_lock, flags);
}
static struct irq_chip gt641xx_irq_chip = {
.name = "GT641xx",
.ack = ack_gt641xx_irq,
.mask = mask_gt641xx_irq,
.mask_ack = mask_ack_gt641xx_irq,
.unmask = unmask_gt641xx_irq,
.irq_ack = ack_gt641xx_irq,
.irq_mask = mask_gt641xx_irq,
.irq_mask_ack = mask_ack_gt641xx_irq,
.irq_unmask = unmask_gt641xx_irq,
};
void gt641xx_irq_dispatch(void)
......
......@@ -28,8 +28,10 @@ static unsigned long _icctrl_msc;
static unsigned int irq_base;
/* mask off an interrupt */
static inline void mask_msc_irq(unsigned int irq)
static inline void mask_msc_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
if (irq < (irq_base + 32))
MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base));
else
......@@ -37,8 +39,10 @@ static inline void mask_msc_irq(unsigned int irq)
}
/* unmask an interrupt */
static inline void unmask_msc_irq(unsigned int irq)
static inline void unmask_msc_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
if (irq < (irq_base + 32))
MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base));
else
......@@ -48,9 +52,11 @@ static inline void unmask_msc_irq(unsigned int irq)
/*
* Masks and ACKs an IRQ
*/
static void level_mask_and_ack_msc_irq(unsigned int irq)
static void level_mask_and_ack_msc_irq(struct irq_data *d)
{
mask_msc_irq(irq);
unsigned int irq = d->irq;
mask_msc_irq(d);
if (!cpu_has_veic)
MSCIC_WRITE(MSC01_IC_EOI, 0);
/* This actually needs to be a call into platform code */
......@@ -60,9 +66,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
/*
* Masks and ACKs an IRQ
*/
static void edge_mask_and_ack_msc_irq(unsigned int irq)
static void edge_mask_and_ack_msc_irq(struct irq_data *d)
{
mask_msc_irq(irq);
unsigned int irq = d->irq;
mask_msc_irq(d);
if (!cpu_has_veic)
MSCIC_WRITE(MSC01_IC_EOI, 0);
else {
......@@ -74,15 +82,6 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq)
smtc_im_ack_irq(irq);
}
/*
* End IRQ processing
*/
static void end_msc_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
unmask_msc_irq(irq);
}
/*
* Interrupt handler for interrupts coming from SOC-it.
*/
......@@ -107,22 +106,20 @@ static void msc_bind_eic_interrupt(int irq, int set)
static struct irq_chip msc_levelirq_type = {
.name = "SOC-it-Level",
.ack = level_mask_and_ack_msc_irq,
.mask = mask_msc_irq,
.mask_ack = level_mask_and_ack_msc_irq,
.unmask = unmask_msc_irq,
.eoi = unmask_msc_irq,
.end = end_msc_irq,
.irq_ack = level_mask_and_ack_msc_irq,
.irq_mask = mask_msc_irq,
.irq_mask_ack = level_mask_and_ack_msc_irq,
.irq_unmask = unmask_msc_irq,
.irq_eoi = unmask_msc_irq,
};
static struct irq_chip msc_edgeirq_type = {
.name = "SOC-it-Edge",
.ack = edge_mask_and_ack_msc_irq,
.mask = mask_msc_irq,
.mask_ack = edge_mask_and_ack_msc_irq,
.unmask = unmask_msc_irq,
.eoi = unmask_msc_irq,
.end = end_msc_irq,
.irq_ack = edge_mask_and_ack_msc_irq,
.irq_mask = mask_msc_irq,
.irq_mask_ack = edge_mask_and_ack_msc_irq,
.irq_unmask = unmask_msc_irq,
.irq_eoi = unmask_msc_irq,
};
......
......@@ -18,23 +18,23 @@
#include <asm/mipsregs.h>
#include <asm/system.h>
static inline void unmask_rm7k_irq(unsigned int irq)
static inline void unmask_rm7k_irq(struct irq_data *d)
{
set_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
set_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE));
}
static inline void mask_rm7k_irq(unsigned int irq)
static inline void mask_rm7k_irq(struct irq_data *d)
{
clear_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE));
clear_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE));
}
static struct irq_chip rm7k_irq_controller = {
.name = "RM7000",
.ack = mask_rm7k_irq,
.mask = mask_rm7k_irq,
.mask_ack = mask_rm7k_irq,
.unmask = unmask_rm7k_irq,
.eoi = unmask_rm7k_irq
.irq_ack = mask_rm7k_irq,
.irq_mask = mask_rm7k_irq,
.irq_mask_ack = mask_rm7k_irq,
.irq_unmask = unmask_rm7k_irq,
.irq_eoi = unmask_rm7k_irq
};
void __init rm7k_cpu_irq_init(void)
......
......@@ -19,22 +19,22 @@
#include <asm/mipsregs.h>
#include <asm/system.h>
static inline void unmask_rm9k_irq(unsigned int irq)
static inline void unmask_rm9k_irq(struct irq_data *d)
{
set_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
}
static inline void mask_rm9k_irq(unsigned int irq)
static inline void mask_rm9k_irq(struct irq_data *d)
{
clear_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE));
clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
}
static inline void rm9k_cpu_irq_enable(unsigned int irq)
static inline void rm9k_cpu_irq_enable(struct irq_data *d)
{
unsigned long flags;
local_irq_save(flags);
unmask_rm9k_irq(irq);
unmask_rm9k_irq(d);
local_irq_restore(flags);
}
......@@ -43,50 +43,47 @@ static inline void rm9k_cpu_irq_enable(unsigned int irq)
*/
static void local_rm9k_perfcounter_irq_startup(void *args)
{
unsigned int irq = (unsigned int) args;
rm9k_cpu_irq_enable(irq);
rm9k_cpu_irq_enable(args);
}
static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d)
{
on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 1);
on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1);
return 0;
}
static void local_rm9k_perfcounter_irq_shutdown(void *args)
{
unsigned int irq = (unsigned int) args;
unsigned long flags;
local_irq_save(flags);
mask_rm9k_irq(irq);
mask_rm9k_irq(args);
local_irq_restore(flags);
}
static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
static void rm9k_perfcounter_irq_shutdown(struct irq_data *d)
{
on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 1);
on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1);
}
static struct irq_chip rm9k_irq_controller = {
.name = "RM9000",
.ack = mask_rm9k_irq,
.mask = mask_rm9k_irq,
.mask_ack = mask_rm9k_irq,
.unmask = unmask_rm9k_irq,
.eoi = unmask_rm9k_irq
.irq_ack = mask_rm9k_irq,
.irq_mask = mask_rm9k_irq,
.irq_mask_ack = mask_rm9k_irq,
.irq_unmask = unmask_rm9k_irq,
.irq_eoi = unmask_rm9k_irq
};
static struct irq_chip rm9k_perfcounter_irq = {
.name = "RM9000",
.startup = rm9k_perfcounter_irq_startup,
.shutdown = rm9k_perfcounter_irq_shutdown,
.ack = mask_rm9k_irq,
.mask = mask_rm9k_irq,
.mask_ack = mask_rm9k_irq,
.unmask = unmask_rm9k_irq,
.irq_startup = rm9k_perfcounter_irq_startup,
.irq_shutdown = rm9k_perfcounter_irq_shutdown,
.irq_ack = mask_rm9k_irq,
.irq_mask = mask_rm9k_irq,
.irq_mask_ack = mask_rm9k_irq,
.irq_unmask = unmask_rm9k_irq,
};
unsigned int rm9000_perfcount_irq;
......
......@@ -81,48 +81,9 @@ void ack_bad_irq(unsigned int irq)
atomic_t irq_err_count;
/*
* Generic, controller-independent functions:
*/
int show_interrupts(struct seq_file *p, void *v)
int arch_show_interrupts(struct seq_file *p, int prec)
{
int i = *(loff_t *) v, j;
struct irqaction * action;
unsigned long flags;
if (i == 0) {
seq_printf(p, " ");
for_each_online_cpu(j)
seq_printf(p, "CPU%d ", j);
seq_putc(p, '\n');
}
if (i < NR_IRQS) {
raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
if (!action)
goto skip;
seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
seq_printf(p, ", %s", action->name);
seq_putc(p, '\n');
skip:
raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
seq_putc(p, '\n');
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
}
seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
return 0;
}
......@@ -183,8 +144,8 @@ void __irq_entry do_IRQ(unsigned int irq)
{
irq_enter();
check_stack_overflow();
__DO_IRQ_SMTC_HOOK(irq);
generic_handle_irq(irq);
if (!smtc_handle_on_other_cpu(irq))
generic_handle_irq(irq);
irq_exit();
}
......@@ -197,7 +158,7 @@ void __irq_entry do_IRQ(unsigned int irq)
void __irq_entry do_IRQ_no_affinity(unsigned int irq)
{
irq_enter();
__NO_AFFINITY_IRQ_SMTC_HOOK(irq);
smtc_im_backstop(irq);
generic_handle_irq(irq);
irq_exit();
}
......
......@@ -37,42 +37,38 @@
#include <asm/mipsmtregs.h>
#include <asm/system.h>
static inline void unmask_mips_irq(unsigned int irq)
static inline void unmask_mips_irq(struct irq_data *d)
{
set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
irq_enable_hazard();
}
static inline void mask_mips_irq(unsigned int irq)
static inline void mask_mips_irq(struct irq_data *d)
{
clear_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
irq_disable_hazard();
}
static struct irq_chip mips_cpu_irq_controller = {
.name = "MIPS",
.ack = mask_mips_irq,
.mask = mask_mips_irq,
.mask_ack = mask_mips_irq,
.unmask = unmask_mips_irq,
.eoi = unmask_mips_irq,
.irq_ack = mask_mips_irq,
.irq_mask = mask_mips_irq,
.irq_mask_ack = mask_mips_irq,
.irq_unmask = unmask_mips_irq,
.irq_eoi = unmask_mips_irq,
};
/*
* Basically the same as above but taking care of all the MT stuff
*/
#define unmask_mips_mt_irq unmask_mips_irq
#define mask_mips_mt_irq mask_mips_irq
static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
{
unsigned int vpflags = dvpe();
clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
evpe(vpflags);
unmask_mips_mt_irq(irq);
unmask_mips_irq(d);
return 0;
}
......@@ -80,22 +76,22 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq)
* While we ack the interrupt interrupts are disabled and thus we don't need
* to deal with concurrency issues. Same for mips_cpu_irq_end.
*/
static void mips_mt_cpu_irq_ack(unsigned int irq)
static void mips_mt_cpu_irq_ack(struct irq_data *d)
{
unsigned int vpflags = dvpe();
clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE));
clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
evpe(vpflags);
mask_mips_mt_irq(irq);
mask_mips_irq(d);
}
static struct irq_chip mips_mt_cpu_irq_controller = {
.name = "MIPS",
.startup = mips_mt_cpu_irq_startup,
.ack = mips_mt_cpu_irq_ack,
.mask = mask_mips_mt_irq,
.mask_ack = mips_mt_cpu_irq_ack,
.unmask = unmask_mips_mt_irq,
.eoi = unmask_mips_mt_irq,
.irq_startup = mips_mt_cpu_irq_startup,
.irq_ack = mips_mt_cpu_irq_ack,
.irq_mask = mask_mips_irq,
.irq_mask_ack = mips_mt_cpu_irq_ack,
.irq_unmask = unmask_mips_irq,
.irq_eoi = unmask_mips_irq,
};
void __init mips_cpu_irq_init(void)
......
......@@ -63,9 +63,9 @@ static struct {
unsigned char mode;
} txx9irq[TXx9_MAX_IR] __read_mostly;
static void txx9_irq_unmask(unsigned int irq)
static void txx9_irq_unmask(struct irq_data *d)
{
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
......@@ -79,9 +79,9 @@ static void txx9_irq_unmask(unsigned int irq)
#endif
}
static inline void txx9_irq_mask(unsigned int irq)
static inline void txx9_irq_mask(struct irq_data *d)
{
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
......@@ -99,19 +99,19 @@ static inline void txx9_irq_mask(unsigned int irq)
#endif
}
static void txx9_irq_mask_ack(unsigned int irq)
static void txx9_irq_mask_ack(struct irq_data *d)
{
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
txx9_irq_mask(irq);
txx9_irq_mask(d);
/* clear edge detection */
if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
__raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
}
static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
unsigned int irq_nr = irq - TXX9_IRQ_BASE;
unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
u32 cr;
u32 __iomem *crp;
int ofs;
......@@ -139,11 +139,11 @@ static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
static struct irq_chip txx9_irq_chip = {
.name = "TXX9",
.ack = txx9_irq_mask_ack,
.mask = txx9_irq_mask,
.mask_ack = txx9_irq_mask_ack,
.unmask = txx9_irq_unmask,
.set_type = txx9_irq_set_type,
.irq_ack = txx9_irq_mask_ack,
.irq_mask = txx9_irq_mask,
.irq_mask_ack = txx9_irq_mask_ack,
.irq_unmask = txx9_irq_unmask,
.irq_set_type = txx9_irq_set_type,
};
void __init txx9_irq_init(unsigned long baseaddr)
......
......@@ -586,6 +586,10 @@ einval: li v0, -ENOSYS
sys sys_fanotify_init 2
sys sys_fanotify_mark 6
sys sys_prlimit64 4
sys sys_name_to_handle_at 5
sys sys_open_by_handle_at 3 /* 4340 */
sys sys_clock_adjtime 2
sys sys_syncfs 1
.endm
/* We pre-compute the number of _instruction_ bytes needed to
......
......@@ -425,4 +425,8 @@ sys_call_table:
PTR sys_fanotify_init /* 5295 */
PTR sys_fanotify_mark
PTR sys_prlimit64
PTR sys_name_to_handle_at
PTR sys_open_by_handle_at
PTR sys_clock_adjtime /* 5300 */
PTR sys_syncfs
.size sys_call_table,.-sys_call_table
......@@ -425,4 +425,8 @@ EXPORT(sysn32_call_table)
PTR sys_fanotify_init /* 6300 */
PTR sys_fanotify_mark
PTR sys_prlimit64
PTR sys_name_to_handle_at
PTR sys_open_by_handle_at
PTR compat_sys_clock_adjtime /* 6305 */
PTR sys_syncfs
.size sysn32_call_table,.-sysn32_call_table
......@@ -543,4 +543,8 @@ sys_call_table:
PTR sys_fanotify_init
PTR sys_32_fanotify_mark
PTR sys_prlimit64
PTR sys_name_to_handle_at
PTR compat_sys_open_by_handle_at /* 4340 */
PTR compat_sys_clock_adjtime
PTR sys_syncfs
.size sys_call_table,.-sys_call_table
......@@ -677,8 +677,9 @@ void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity)
*/
}
void smtc_forward_irq(unsigned int irq)
void smtc_forward_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
int target;
/*
......@@ -692,7 +693,7 @@ void smtc_forward_irq(unsigned int irq)
* and efficiency, we just pick the easiest one to find.
*/
target = cpumask_first(irq_desc[irq].affinity);
target = cpumask_first(d->affinity);
/*
* We depend on the platform code to have correctly processed
......@@ -707,12 +708,10 @@ void smtc_forward_irq(unsigned int irq)
*/
/* If no one is eligible, service locally */
if (target >= NR_CPUS) {
if (target >= NR_CPUS)
do_IRQ_no_affinity(irq);
return;
}
smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
else
smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
}
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
......
......@@ -32,24 +32,24 @@ static volatile int *lasat_int_status;
static volatile int *lasat_int_mask;
static volatile int lasat_int_mask_shift;
void disable_lasat_irq(unsigned int irq_nr)
void disable_lasat_irq(struct irq_data *d)
{
irq_nr -= LASAT_IRQ_BASE;
unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
*lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
}
void enable_lasat_irq(unsigned int irq_nr)
void enable_lasat_irq(struct irq_data *d)
{
irq_nr -= LASAT_IRQ_BASE;
unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
*lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
}
static struct irq_chip lasat_irq_type = {
.name = "Lasat",
.ack = disable_lasat_irq,
.mask = disable_lasat_irq,
.mask_ack = disable_lasat_irq,
.unmask = enable_lasat_irq,
.irq_mask = disable_lasat_irq,
.irq_unmask = enable_lasat_irq,
};
static inline int ls1bit32(unsigned int x)
......
......@@ -16,24 +16,22 @@
#include <loongson.h>
static inline void bonito_irq_enable(unsigned int irq)
static inline void bonito_irq_enable(struct irq_data *d)
{
LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE));
LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE));
mmiowb();
}
static inline void bonito_irq_disable(unsigned int irq)
static inline void bonito_irq_disable(struct irq_data *d)
{
LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE));
LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE));
mmiowb();
}
static struct irq_chip bonito_irq_type = {
.name = "bonito_irq",
.ack = bonito_irq_disable,
.mask = bonito_irq_disable,
.mask_ack = bonito_irq_disable,
.unmask = bonito_irq_enable,
.name = "bonito_irq",
.irq_mask = bonito_irq_disable,
.irq_unmask = bonito_irq_enable,
};
static struct irqaction __maybe_unused dma_timeout_irqaction = {
......
......@@ -27,6 +27,7 @@
#include <asm/atomic.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/smtc.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/smtc_ipi.h>
......@@ -57,8 +58,6 @@ static inline void ssmtc_send_ipi_mask(const struct cpumask *mask,
*/
static void __cpuinit ssmtc_init_secondary(void)
{
void smtc_init_secondary(void);
smtc_init_secondary();
}
......
......@@ -34,7 +34,6 @@ static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action)
*/
static void __cpuinit msmtc_init_secondary(void)
{
void smtc_init_secondary(void);
int myvpe;
/* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
......@@ -114,7 +113,8 @@ struct plat_smp_ops msmtc_smp_ops = {
*/
int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
bool force)
{
cpumask_t tmask;
int cpu = 0;
......@@ -144,7 +144,7 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
cpu_clear(cpu, tmask);
}
cpumask_copy(irq_desc[irq].affinity, &tmask);
cpumask_copy(d->affinity, &tmask);
if (cpus_empty(tmask))
/*
......@@ -155,8 +155,8 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
"IRQ affinity leaves no legal CPU for IRQ %d\n", irq);
/* Do any generic SMTC IRQ affinity setup */
smtc_set_irq_affinity(irq, tmask);
smtc_set_irq_affinity(d->irq, tmask);
return 0;
return IRQ_SET_MASK_OK_NOCOPY;
}
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
......@@ -23,6 +23,8 @@ config PMC_MSP7120_GW
select SYS_SUPPORTS_MULTITHREADING
select IRQ_MSP_CIC
select HW_HAS_PCI
select MSP_HAS_USB
select MSP_ETH
config PMC_MSP7120_FPGA
bool "PMC-Sierra MSP7120 FPGA"
......@@ -35,3 +37,16 @@ endchoice
config HYPERTRANSPORT
bool "Hypertransport Support for PMC-Sierra Yosemite"
depends on PMC_YOSEMITE
config MSP_HAS_USB
boolean
depends on PMC_MSP
config MSP_ETH
boolean
select MSP_HAS_MAC
depends on PMC_MSP
config MSP_HAS_MAC
boolean
depends on PMC_MSP
......@@ -6,7 +6,9 @@ obj-y += msp_prom.o msp_setup.o msp_irq.o \
obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o
obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
obj-$(CONFIG_PCI) += msp_pci.o
obj-$(CONFIG_MSPETH) += msp_eth.o
obj-$(CONFIG_USB_MSP71XX) += msp_usb.o
obj-$(CONFIG_MSP_HAS_MAC) += msp_eth.o
obj-$(CONFIG_MSP_HAS_USB) += msp_usb.o
obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o
obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o
/*
* The setup file for ethernet related hardware on PMC-Sierra MSP processors.
*
* Copyright 2010 PMC-Sierra, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <msp_regs.h>
#include <msp_int.h>
#include <msp_gpio_macros.h>
#define MSP_ETHERNET_GPIO0 14
#define MSP_ETHERNET_GPIO1 15
#define MSP_ETHERNET_GPIO2 16
#ifdef CONFIG_MSP_HAS_TSMAC
#define MSP_TSMAC_SIZE 0x10020
#define MSP_TSMAC_ID "pmc_tsmac"
static struct resource msp_tsmac0_resources[] = {
[0] = {
.start = MSP_MAC0_BASE,
.end = MSP_MAC0_BASE + MSP_TSMAC_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MSP_INT_MAC0,
.end = MSP_INT_MAC0,
.flags = IORESOURCE_IRQ,
},
};
static struct resource msp_tsmac1_resources[] = {
[0] = {
.start = MSP_MAC1_BASE,
.end = MSP_MAC1_BASE + MSP_TSMAC_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MSP_INT_MAC1,
.end = MSP_INT_MAC1,
.flags = IORESOURCE_IRQ,
},
};
static struct resource msp_tsmac2_resources[] = {
[0] = {
.start = MSP_MAC2_BASE,
.end = MSP_MAC2_BASE + MSP_TSMAC_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MSP_INT_SAR,
.end = MSP_INT_SAR,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device tsmac_device[] = {
[0] = {
.name = MSP_TSMAC_ID,
.id = 0,
.num_resources = ARRAY_SIZE(msp_tsmac0_resources),
.resource = msp_tsmac0_resources,
},
[1] = {
.name = MSP_TSMAC_ID,
.id = 1,
.num_resources = ARRAY_SIZE(msp_tsmac1_resources),
.resource = msp_tsmac1_resources,
},
[2] = {
.name = MSP_TSMAC_ID,
.id = 2,
.num_resources = ARRAY_SIZE(msp_tsmac2_resources),
.resource = msp_tsmac2_resources,
},
};
#define msp_eth_devs tsmac_device
#else
/* If it is not TSMAC assume MSP_ETH (100Mbps) */
#define MSP_ETH_ID "pmc_mspeth"
#define MSP_ETH_SIZE 0xE0
static struct resource msp_eth0_resources[] = {
[0] = {
.start = MSP_MAC0_BASE,
.end = MSP_MAC0_BASE + MSP_ETH_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MSP_INT_MAC0,
.end = MSP_INT_MAC0,
.flags = IORESOURCE_IRQ,
},
};
static struct resource msp_eth1_resources[] = {
[0] = {
.start = MSP_MAC1_BASE,
.end = MSP_MAC1_BASE + MSP_ETH_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MSP_INT_MAC1,
.end = MSP_INT_MAC1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device mspeth_device[] = {
[0] = {
.name = MSP_ETH_ID,
.id = 0,
.num_resources = ARRAY_SIZE(msp_eth0_resources),
.resource = msp_eth0_resources,
},
[1] = {
.name = MSP_ETH_ID,
.id = 1,
.num_resources = ARRAY_SIZE(msp_eth1_resources),
.resource = msp_eth1_resources,
},
};
#define msp_eth_devs mspeth_device
#endif
int __init msp_eth_setup(void)
{
int i, ret = 0;
/* Configure the GPIO and take the ethernet PHY out of reset */
msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO0);
msp_gpio_pin_hi(MSP_ETHERNET_GPIO0);
#ifdef CONFIG_MSP_HAS_TSMAC
/* 3 phys on boards with TSMAC */
msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO1);
msp_gpio_pin_hi(MSP_ETHERNET_GPIO1);
msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO2);
msp_gpio_pin_hi(MSP_ETHERNET_GPIO2);
#endif
for (i = 0; i < ARRAY_SIZE(msp_eth_devs); i++) {
ret = platform_device_register(&msp_eth_devs[i]);
printk(KERN_INFO "device: %d, return value = %d\n", i, ret);
if (ret) {
platform_device_unregister(&msp_eth_devs[i]);
break;
}
}
if (ret)
printk(KERN_WARNING "Could not initialize "
"MSPETH device structures.\n");
return ret;
}
subsys_initcall(msp_eth_setup);
......@@ -19,8 +19,6 @@
#include <msp_int.h>
extern void msp_int_handle(void);
/* SLP bases systems */
extern void msp_slp_irq_init(void);
extern void msp_slp_irq_dispatch(void);
......@@ -29,6 +27,18 @@ extern void msp_slp_irq_dispatch(void);
extern void msp_cic_irq_init(void);
extern void msp_cic_irq_dispatch(void);
/* VSMP support init */
extern void msp_vsmp_int_init(void);
/* vectored interrupt implementation */
/* SW0/1 interrupts are used for SMP/SMTC */
static inline void mac0_int_dispatch(void) { do_IRQ(MSP_INT_MAC0); }
static inline void mac1_int_dispatch(void) { do_IRQ(MSP_INT_MAC1); }
static inline void mac2_int_dispatch(void) { do_IRQ(MSP_INT_SAR); }
static inline void usb_int_dispatch(void) { do_IRQ(MSP_INT_USB); }
static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); }
/*
* The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded
* hierarchical system. The first level are the direct MIPS interrupts
......@@ -96,29 +106,57 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
do_IRQ(MSP_INT_SW1);
}
static struct irqaction cascade_msp = {
static struct irqaction cic_cascade_msp = {
.handler = no_action,
.name = "MSP cascade"
.name = "MSP CIC cascade"
};
static struct irqaction per_cascade_msp = {
.handler = no_action,
.name = "MSP PER cascade"
};
void __init arch_init_irq(void)
{
/* assume we'll be using vectored interrupt mode except in UP mode*/
#ifdef CONFIG_MIPS_MT
BUG_ON(!cpu_has_vint);
#endif
/* initialize the 1st-level CPU based interrupt controller */
mips_cpu_irq_init();
#ifdef CONFIG_IRQ_MSP_CIC
msp_cic_irq_init();
#ifdef CONFIG_MIPS_MT
set_vi_handler(MSP_INT_CIC, msp_cic_irq_dispatch);
set_vi_handler(MSP_INT_MAC0, mac0_int_dispatch);
set_vi_handler(MSP_INT_MAC1, mac1_int_dispatch);
set_vi_handler(MSP_INT_SAR, mac2_int_dispatch);
set_vi_handler(MSP_INT_USB, usb_int_dispatch);
set_vi_handler(MSP_INT_SEC, sec_int_dispatch);
#ifdef CONFIG_MIPS_MT_SMP
msp_vsmp_int_init();
#elif defined CONFIG_MIPS_MT_SMTC
/*Set hwmask for all platform devices */
irq_hwmask[MSP_INT_MAC0] = C_IRQ0;
irq_hwmask[MSP_INT_MAC1] = C_IRQ1;
irq_hwmask[MSP_INT_USB] = C_IRQ2;
irq_hwmask[MSP_INT_SAR] = C_IRQ3;
irq_hwmask[MSP_INT_SEC] = C_IRQ5;
#endif /* CONFIG_MIPS_MT_SMP */
#endif /* CONFIG_MIPS_MT */
/* setup the cascaded interrupts */
setup_irq(MSP_INT_CIC, &cascade_msp);
setup_irq(MSP_INT_PER, &cascade_msp);
setup_irq(MSP_INT_CIC, &cic_cascade_msp);
setup_irq(MSP_INT_PER, &per_cascade_msp);
#else
/* setup the 2nd-level SLP register based interrupt controller */
/* VSMP /SMTC support support is not enabled for SLP */
msp_slp_irq_init();
/* setup the cascaded SLP/PER interrupts */
setup_irq(MSP_INT_SLP, &cascade_msp);
setup_irq(MSP_INT_PER, &cascade_msp);
setup_irq(MSP_INT_SLP, &cic_cascade_msp);
setup_irq(MSP_INT_PER, &per_cascade_msp);
#endif
}
/*
* 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();
}
}
/*
* Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
*
* This file define the irq handler for MSP PER subsystem interrupts.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <msp_cic_int.h>
#include <msp_regs.h>
/*
* Convenience Macro. Should be somewhere generic.
*/
#define get_current_vpe() \
((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
#ifdef CONFIG_SMP
/*
* The PER registers must be protected from concurrent access.
*/
static DEFINE_SPINLOCK(per_lock);
#endif
/* ensure writes to per are completed */
static inline void per_wmb(void)
{
const volatile void __iomem *per_mem = PER_INT_MSK_REG;
volatile u32 dummy_read;
wmb();
dummy_read = __raw_readl(per_mem);
dummy_read++;
}
static inline void unmask_per_irq(struct irq_data *d)
{
#ifdef CONFIG_SMP
unsigned long flags;
spin_lock_irqsave(&per_lock, flags);
*PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
spin_unlock_irqrestore(&per_lock, flags);
#else
*PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
#endif
per_wmb();
}
static inline void mask_per_irq(struct irq_data *d)
{
#ifdef CONFIG_SMP
unsigned long flags;
spin_lock_irqsave(&per_lock, flags);
*PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
spin_unlock_irqrestore(&per_lock, flags);
#else
*PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
#endif
per_wmb();
}
static inline void msp_per_irq_ack(struct irq_data *d)
{
mask_per_irq(d);
/*
* In the PER interrupt controller, only bits 11 and 10
* are write-to-clear, (SPI TX complete, SPI RX complete).
* It does nothing for any others.
*/
*PER_INT_STS_REG = (1 << (d->irq - MSP_PER_INTBASE));
}
#ifdef CONFIG_SMP
static int msp_per_irq_set_affinity(struct irq_data *d,
const struct cpumask *affinity, bool force)
{
/* WTF is this doing ????? */
unmask_per_irq(d);
return 0;
}
#endif
static struct irq_chip msp_per_irq_controller = {
.name = "MSP_PER",
.irq_enable = unmask_per_irq.
.irq_disable = mask_per_irq,
.irq_ack = msp_per_irq_ack,
#ifdef CONFIG_SMP
.irq_set_affinity = msp_per_irq_set_affinity,
#endif
};
void __init msp_per_irq_init(void)
{
int i;
/* Mask/clear interrupts. */
*PER_INT_MSK_REG = 0x00000000;
*PER_INT_STS_REG = 0xFFFFFFFF;
/* initialize all the IRQ descriptors */
for (i = MSP_PER_INTBASE; i < MSP_PER_INTBASE + 32; i++) {
irq_set_chip(i, &msp_per_irq_controller);
#ifdef CONFIG_MIPS_MT_SMTC
irq_hwmask[i] = C_IRQ4;
#endif
}
}
void msp_per_irq_dispatch(void)
{
u32 per_mask = *PER_INT_MSK_REG;
u32 per_status = *PER_INT_STS_REG;
u32 pending;
pending = per_status & per_mask;
if (pending) {
do_IRQ(ffs(pending) + MSP_PER_INTBASE - 1);
} else {
spurious_interrupt();
}
}
......@@ -21,8 +21,10 @@
#include <msp_slp_int.h>
#include <msp_regs.h>
static inline void unmask_msp_slp_irq(unsigned int irq)
static inline void unmask_msp_slp_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
/* check for PER interrupt range */
if (irq < MSP_PER_INTBASE)
*SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
......@@ -30,8 +32,10 @@ static inline void unmask_msp_slp_irq(unsigned int irq)
*PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
}
static inline void mask_msp_slp_irq(unsigned int irq)
static inline void mask_msp_slp_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
/* check for PER interrupt range */
if (irq < MSP_PER_INTBASE)
*SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
......@@ -43,8 +47,10 @@ static inline void mask_msp_slp_irq(unsigned int irq)
* While we ack the interrupt interrupts are disabled and thus we don't need
* to deal with concurrency issues. Same for msp_slp_irq_end.
*/
static inline void ack_msp_slp_irq(unsigned int irq)
static inline void ack_msp_slp_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
/* check for PER interrupt range */
if (irq < MSP_PER_INTBASE)
*SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
......@@ -54,9 +60,9 @@ static inline void ack_msp_slp_irq(unsigned int irq)
static struct irq_chip msp_slp_irq_controller = {
.name = "MSP_SLP",
.ack = ack_msp_slp_irq,
.mask = mask_msp_slp_irq,
.unmask = unmask_msp_slp_irq,
.irq_ack = ack_msp_slp_irq,
.irq_mask = mask_msp_slp_irq,
.irq_unmask = unmask_msp_slp_irq,
};
void __init msp_slp_irq_init(void)
......
......@@ -146,6 +146,8 @@ void __init plat_mem_setup(void)
pm_power_off = msp_power_off;
}
extern struct plat_smp_ops msp_smtc_smp_ops;
void __init prom_init(void)
{
unsigned long family;
......@@ -226,6 +228,14 @@ void __init prom_init(void)
*/
msp_serial_setup();
#ifdef CONFIG_MIPS_MT_SMP
register_smp_ops(&vsmp_smp_ops);
#endif
#ifdef CONFIG_MIPS_MT_SMTC
register_smp_ops(&msp_smtc_smp_ops);
#endif
#ifdef CONFIG_PMCTWILED
/*
* Setup LED states before the subsys_initcall loads other
......
/*
* 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 */
/*
* MSP71xx Platform-specific hooks for SMP operation
*/
#include <linux/irq.h>
#include <linux/init.h>
#include <asm/mipsmtregs.h>
#include <asm/mipsregs.h>
#include <asm/smtc.h>
#include <asm/smtc_ipi.h>
/* VPE/SMP Prototype implements platform interfaces directly */
/*
* Cause the specified action to be performed on a targeted "CPU"
*/
static void msp_smtc_send_ipi_single(int cpu, unsigned int action)
{
/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
}
static void msp_smtc_send_ipi_mask(const struct cpumask *mask,
unsigned int action)
{
unsigned int i;
for_each_cpu(i, mask)
msp_smtc_send_ipi_single(i, action);
}
/*
* Post-config but pre-boot cleanup entry point
*/
static void __cpuinit msp_smtc_init_secondary(void)
{
int myvpe;
/* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
myvpe = read_c0_tcbind() & TCBIND_CURVPE;
if (myvpe > 0)
change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
STATUSF_IP6 | STATUSF_IP7);
smtc_init_secondary();
}
/*
* Platform "CPU" startup hook
*/
static void __cpuinit msp_smtc_boot_secondary(int cpu,
struct task_struct *idle)
{
smtc_boot_secondary(cpu, idle);
}
/*
* SMP initialization finalization entry point
*/
static void __cpuinit msp_smtc_smp_finish(void)
{
smtc_smp_finish();
}
/*
* Hook for after all CPUs are online
*/
static void msp_smtc_cpus_done(void)
{
}
/*
* Platform SMP pre-initialization
*
* As noted above, we can assume a single CPU for now
* but it may be multithreaded.
*/
static void __init msp_smtc_smp_setup(void)
{
/*
* we won't get the definitive value until
* we've run smtc_prepare_cpus later, but
*/
if (read_c0_config3() & (1 << 2))
smp_num_siblings = smtc_build_cpu_map(0);
}
static void __init msp_smtc_prepare_cpus(unsigned int max_cpus)
{
smtc_prepare_cpus(max_cpus);
}
struct plat_smp_ops msp_smtc_smp_ops = {
.send_ipi_single = msp_smtc_send_ipi_single,
.send_ipi_mask = msp_smtc_send_ipi_mask,
.init_secondary = msp_smtc_init_secondary,
.smp_finish = msp_smtc_smp_finish,
.cpus_done = msp_smtc_cpus_done,
.boot_secondary = msp_smtc_boot_secondary,
.smp_setup = msp_smtc_smp_setup,
.prepare_cpus = msp_smtc_prepare_cpus,
};
......@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/ptrace.h>
#include <asm/cevt-r4k.h>
#include <asm/mipsregs.h>
#include <asm/time.h>
......@@ -36,6 +37,12 @@
#include <msp_int.h>
#include <msp_regs.h>
#define get_current_vpe() \
((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
static struct irqaction timer_vpe1;
static int tim_installed;
void __init plat_time_init(void)
{
char *endp, *s;
......@@ -83,5 +90,12 @@ void __init plat_time_init(void)
unsigned int __cpuinit get_c0_compare_int(void)
{
return MSP_INT_VPE0_TIMER;
/* MIPS_MT modes may want timer for second VPE */
if ((get_current_vpe()) && !tim_installed) {
memcpy(&timer_vpe1, &c0_compare_irqaction, sizeof(timer_vpe1));
setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
tim_installed++;
}
return get_current_vpe() ? MSP_INT_VPE1_TIMER : MSP_INT_VPE0_TIMER;
}
/*
* 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 */
......@@ -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)
......
......@@ -114,8 +114,10 @@ static inline void unmask_gic_int(unsigned int irq_nr)
PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
}
static inline void mask_irq(unsigned int irq_nr)
static inline void mask_irq(struct irq_data *d)
{
unsigned int irq_nr = d->irq;
if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
modify_cp0_intmask(1 << irq_nr, 0);
} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
......@@ -129,8 +131,10 @@ static inline void mask_irq(unsigned int irq_nr)
}
}
static inline void unmask_irq(unsigned int irq_nr)
static inline void unmask_irq(struct irq_data *d)
{
unsigned int irq_nr = d->irq;
if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
modify_cp0_intmask(0, 1 << irq_nr);
} else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
......@@ -157,10 +161,8 @@ int pnx8550_set_gic_priority(int irq, int priority)
static struct irq_chip level_irq_type = {
.name = "PNX Level IRQ",
.ack = mask_irq,
.mask = mask_irq,
.mask_ack = mask_irq,
.unmask = unmask_irq,
.irq_mask = mask_irq,
.irq_unmask = unmask_irq,
};
static struct irqaction gic_action = {
......@@ -180,10 +182,8 @@ void __init arch_init_irq(void)
int i;
int configPR;
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++)
set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
mask_irq(i); /* mask the irq just in case */
}
/* init of GIC/IPC interrupts */
/* should be done before cp0 since cp0 init enables the GIC int */
......
......@@ -21,9 +21,10 @@
#include <asm/mach-powertv/asic_regs.h>
static inline void unmask_asic_irq(unsigned int irq)
static inline void unmask_asic_irq(struct irq_data *d)
{
unsigned long enable_bit;
unsigned int irq = d->irq;
enable_bit = (1 << (irq & 0x1f));
......@@ -45,9 +46,10 @@ static inline void unmask_asic_irq(unsigned int irq)
}
}
static inline void mask_asic_irq(unsigned int irq)
static inline void mask_asic_irq(struct irq_data *d)
{
unsigned long disable_mask;
unsigned int irq = d->irq;
disable_mask = ~(1 << (irq & 0x1f));
......@@ -71,11 +73,8 @@ static inline void mask_asic_irq(unsigned int irq)
static struct irq_chip asic_irq_chip = {
.name = "ASIC Level",
.ack = mask_asic_irq,
.mask = mask_asic_irq,
.mask_ack = mask_asic_irq,
.unmask = unmask_asic_irq,
.eoi = unmask_asic_irq,
.irq_mask = mask_asic_irq,
.irq_unmask = unmask_asic_irq,
};
void __init asic_irq_init(void)
......
......@@ -111,10 +111,10 @@ static inline void ack_local_irq(unsigned int ip)
clear_c0_cause(ipnum);
}
static void rb532_enable_irq(unsigned int irq_nr)
static void rb532_enable_irq(struct irq_data *d)
{
unsigned int group, intr_bit, irq_nr = d->irq;
int ip = irq_nr - GROUP0_IRQ_BASE;
unsigned int group, intr_bit;
volatile unsigned int *addr;
if (ip < 0)
......@@ -132,10 +132,10 @@ static void rb532_enable_irq(unsigned int irq_nr)
}
}
static void rb532_disable_irq(unsigned int irq_nr)
static void rb532_disable_irq(struct irq_data *d)
{
unsigned int group, intr_bit, mask, irq_nr = d->irq;
int ip = irq_nr - GROUP0_IRQ_BASE;
unsigned int group, intr_bit, mask;
volatile unsigned int *addr;
if (ip < 0) {
......@@ -163,18 +163,18 @@ static void rb532_disable_irq(unsigned int irq_nr)
}
}
static void rb532_mask_and_ack_irq(unsigned int irq_nr)
static void rb532_mask_and_ack_irq(struct irq_data *d)
{
rb532_disable_irq(irq_nr);
ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
rb532_disable_irq(d);
ack_local_irq(group_to_ip(irq_to_group(d->irq)));
}
static int rb532_set_type(unsigned int irq_nr, unsigned type)
static int rb532_set_type(struct irq_data *d, unsigned type)
{
int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE;
int group = irq_to_group(irq_nr);
int gpio = d->irq - GPIO_MAPPED_IRQ_BASE;
int group = irq_to_group(d->irq);
if (group != GPIO_MAPPED_IRQ_GROUP || irq_nr > (GROUP4_IRQ_BASE + 13))
if (group != GPIO_MAPPED_IRQ_GROUP || d->irq > (GROUP4_IRQ_BASE + 13))
return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
switch (type) {
......@@ -193,11 +193,11 @@ static int rb532_set_type(unsigned int irq_nr, unsigned type)
static struct irq_chip rc32434_irq_type = {
.name = "RB532",
.ack = rb532_disable_irq,
.mask = rb532_disable_irq,
.mask_ack = rb532_mask_and_ack_irq,
.unmask = rb532_enable_irq,
.set_type = rb532_set_type,
.irq_ack = rb532_disable_irq,
.irq_mask = rb532_disable_irq,
.irq_mask_ack = rb532_mask_and_ack_irq,
.irq_unmask = rb532_enable_irq,
.irq_set_type = rb532_set_type,
};
void __init arch_init_irq(void)
......
......@@ -31,88 +31,80 @@ static char lc3msk_to_irqnr[256];
extern int ip22_eisa_init(void);
static void enable_local0_irq(unsigned int irq)
static void enable_local0_irq(struct irq_data *d)
{
/* don't allow mappable interrupt to be enabled from setup_irq,
* we have our own way to do so */
if (irq != SGI_MAP_0_IRQ)
sgint->imask0 |= (1 << (irq - SGINT_LOCAL0));
if (d->irq != SGI_MAP_0_IRQ)
sgint->imask0 |= (1 << (d->irq - SGINT_LOCAL0));
}
static void disable_local0_irq(unsigned int irq)
static void disable_local0_irq(struct irq_data *d)
{
sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
sgint->imask0 &= ~(1 << (d->irq - SGINT_LOCAL0));
}
static struct irq_chip ip22_local0_irq_type = {
.name = "IP22 local 0",
.ack = disable_local0_irq,
.mask = disable_local0_irq,
.mask_ack = disable_local0_irq,
.unmask = enable_local0_irq,
.irq_mask = disable_local0_irq,
.irq_unmask = enable_local0_irq,
};
static void enable_local1_irq(unsigned int irq)
static void enable_local1_irq(struct irq_data *d)
{
/* don't allow mappable interrupt to be enabled from setup_irq,
* we have our own way to do so */
if (irq != SGI_MAP_1_IRQ)
sgint->imask1 |= (1 << (irq - SGINT_LOCAL1));
if (d->irq != SGI_MAP_1_IRQ)
sgint->imask1 |= (1 << (d->irq - SGINT_LOCAL1));
}
static void disable_local1_irq(unsigned int irq)
static void disable_local1_irq(struct irq_data *d)
{
sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
sgint->imask1 &= ~(1 << (d->irq - SGINT_LOCAL1));
}
static struct irq_chip ip22_local1_irq_type = {
.name = "IP22 local 1",
.ack = disable_local1_irq,
.mask = disable_local1_irq,
.mask_ack = disable_local1_irq,
.unmask = enable_local1_irq,
.irq_mask = disable_local1_irq,
.irq_unmask = enable_local1_irq,
};
static void enable_local2_irq(unsigned int irq)
static void enable_local2_irq(struct irq_data *d)
{
sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
sgint->cmeimask0 |= (1 << (d->irq - SGINT_LOCAL2));
}
static void disable_local2_irq(unsigned int irq)
static void disable_local2_irq(struct irq_data *d)
{
sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
sgint->cmeimask0 &= ~(1 << (d->irq - SGINT_LOCAL2));
if (!sgint->cmeimask0)
sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
}
static struct irq_chip ip22_local2_irq_type = {
.name = "IP22 local 2",
.ack = disable_local2_irq,
.mask = disable_local2_irq,
.mask_ack = disable_local2_irq,
.unmask = enable_local2_irq,
.irq_mask = disable_local2_irq,
.irq_unmask = enable_local2_irq,
};
static void enable_local3_irq(unsigned int irq)
static void enable_local3_irq(struct irq_data *d)
{
sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
sgint->cmeimask1 |= (1 << (d->irq - SGINT_LOCAL3));
}
static void disable_local3_irq(unsigned int irq)
static void disable_local3_irq(struct irq_data *d)
{
sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
sgint->cmeimask1 &= ~(1 << (d->irq - SGINT_LOCAL3));
if (!sgint->cmeimask1)
sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
}
static struct irq_chip ip22_local3_irq_type = {
.name = "IP22 local 3",
.ack = disable_local3_irq,
.mask = disable_local3_irq,
.mask_ack = disable_local3_irq,
.unmask = enable_local3_irq,
.irq_mask = disable_local3_irq,
.irq_unmask = enable_local3_irq,
};
static void indy_local0_irqdispatch(void)
......
......@@ -240,7 +240,7 @@ static int intr_disconnect_level(int cpu, int bit)
}
/* Startup one of the (PCI ...) IRQs routes over a bridge. */
static unsigned int startup_bridge_irq(unsigned int irq)
static unsigned int startup_bridge_irq(struct irq_data *d)
{
struct bridge_controller *bc;
bridgereg_t device;
......@@ -248,16 +248,16 @@ static unsigned int startup_bridge_irq(unsigned int irq)
int pin, swlevel;
cpuid_t cpu;
pin = SLOT_FROM_PCI_IRQ(irq);
bc = IRQ_TO_BRIDGE(irq);
pin = SLOT_FROM_PCI_IRQ(d->irq);
bc = IRQ_TO_BRIDGE(d->irq);
bridge = bc->base;
pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin);
pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
swlevel = find_level(&cpu, irq);
swlevel = find_level(&cpu, d->irq);
bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
bridge->b_int_enable |= (1 << pin);
bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
......@@ -288,53 +288,51 @@ static unsigned int startup_bridge_irq(unsigned int irq)
}
/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
static void shutdown_bridge_irq(unsigned int irq)
static void shutdown_bridge_irq(struct irq_data *d)
{
struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
bridge_t *bridge = bc->base;
int pin, swlevel;
cpuid_t cpu;
pr_debug("bridge_shutdown: irq 0x%x\n", irq);
pin = SLOT_FROM_PCI_IRQ(irq);
pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
pin = SLOT_FROM_PCI_IRQ(d->irq);
/*
* map irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
swlevel = find_level(&cpu, irq);
swlevel = find_level(&cpu, d->irq);
intr_disconnect_level(cpu, swlevel);
bridge->b_int_enable &= ~(1 << pin);
bridge->b_wid_tflush;
}
static inline void enable_bridge_irq(unsigned int irq)
static inline void enable_bridge_irq(struct irq_data *d)
{
cpuid_t cpu;
int swlevel;
swlevel = find_level(&cpu, irq); /* Criminal offence */
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
intr_connect_level(cpu, swlevel);
}
static inline void disable_bridge_irq(unsigned int irq)
static inline void disable_bridge_irq(struct irq_data *d)
{
cpuid_t cpu;
int swlevel;
swlevel = find_level(&cpu, irq); /* Criminal offence */
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
intr_disconnect_level(cpu, swlevel);
}
static struct irq_chip bridge_irq_type = {
.name = "bridge",
.startup = startup_bridge_irq,
.shutdown = shutdown_bridge_irq,
.ack = disable_bridge_irq,
.mask = disable_bridge_irq,
.mask_ack = disable_bridge_irq,
.unmask = enable_bridge_irq,
.irq_startup = startup_bridge_irq,
.irq_shutdown = shutdown_bridge_irq,
.irq_mask = disable_bridge_irq,
.irq_unmask = enable_bridge_irq,
};
void __devinit register_bridge_irq(unsigned int irq)
......
......@@ -36,21 +36,18 @@
#include <asm/sn/sn0/hubio.h>
#include <asm/pci/bridge.h>
static void enable_rt_irq(unsigned int irq)
static void enable_rt_irq(struct irq_data *d)
{
}
static void disable_rt_irq(unsigned int irq)
static void disable_rt_irq(struct irq_data *d)
{
}
static struct irq_chip rt_irq_type = {
.name = "SN HUB RT timer",
.ack = disable_rt_irq,
.mask = disable_rt_irq,
.mask_ack = disable_rt_irq,
.unmask = enable_rt_irq,
.eoi = enable_rt_irq,
.irq_mask = disable_rt_irq,
.irq_unmask = enable_rt_irq,
};
static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
......
......@@ -130,70 +130,48 @@ static struct irqaction cpuerr_irq = {
static uint64_t crime_mask;
static inline void crime_enable_irq(unsigned int irq)
static inline void crime_enable_irq(struct irq_data *d)
{
unsigned int bit = irq - CRIME_IRQ_BASE;
unsigned int bit = d->irq - CRIME_IRQ_BASE;
crime_mask |= 1 << bit;
crime->imask = crime_mask;
}
static inline void crime_disable_irq(unsigned int irq)
static inline void crime_disable_irq(struct irq_data *d)
{
unsigned int bit = irq - CRIME_IRQ_BASE;
unsigned int bit = d->irq - CRIME_IRQ_BASE;
crime_mask &= ~(1 << bit);
crime->imask = crime_mask;
flush_crime_bus();
}
static void crime_level_mask_and_ack_irq(unsigned int irq)
{
crime_disable_irq(irq);
}
static void crime_level_end_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
crime_enable_irq(irq);
}
static struct irq_chip crime_level_interrupt = {
.name = "IP32 CRIME",
.ack = crime_level_mask_and_ack_irq,
.mask = crime_disable_irq,
.mask_ack = crime_level_mask_and_ack_irq,
.unmask = crime_enable_irq,
.end = crime_level_end_irq,
.irq_mask = crime_disable_irq,
.irq_unmask = crime_enable_irq,
};
static void crime_edge_mask_and_ack_irq(unsigned int irq)
static void crime_edge_mask_and_ack_irq(struct irq_data *d)
{
unsigned int bit = irq - CRIME_IRQ_BASE;
unsigned int bit = d->irq - CRIME_IRQ_BASE;
uint64_t crime_int;
/* Edge triggered interrupts must be cleared. */
crime_int = crime->hard_int;
crime_int &= ~(1 << bit);
crime->hard_int = crime_int;
crime_disable_irq(irq);
}
static void crime_edge_end_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
crime_enable_irq(irq);
crime_disable_irq(d);
}
static struct irq_chip crime_edge_interrupt = {
.name = "IP32 CRIME",
.ack = crime_edge_mask_and_ack_irq,
.mask = crime_disable_irq,
.mask_ack = crime_edge_mask_and_ack_irq,
.unmask = crime_enable_irq,
.end = crime_edge_end_irq,
.irq_ack = crime_edge_mask_and_ack_irq,
.irq_mask = crime_disable_irq,
.irq_mask_ack = crime_edge_mask_and_ack_irq,
.irq_unmask = crime_enable_irq,
};
/*
......@@ -204,37 +182,28 @@ static struct irq_chip crime_edge_interrupt = {
static unsigned long macepci_mask;
static void enable_macepci_irq(unsigned int irq)
static void enable_macepci_irq(struct irq_data *d)
{
macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
mace->pci.control = macepci_mask;
crime_mask |= 1 << (irq - CRIME_IRQ_BASE);
crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
crime->imask = crime_mask;
}
static void disable_macepci_irq(unsigned int irq)
static void disable_macepci_irq(struct irq_data *d)
{
crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE));
crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
crime->imask = crime_mask;
flush_crime_bus();
macepci_mask &= ~MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ);
macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
mace->pci.control = macepci_mask;
flush_mace_bus();
}
static void end_macepci_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_macepci_irq(irq);
}
static struct irq_chip ip32_macepci_interrupt = {
.name = "IP32 MACE PCI",
.ack = disable_macepci_irq,
.mask = disable_macepci_irq,
.mask_ack = disable_macepci_irq,
.unmask = enable_macepci_irq,
.end = end_macepci_irq,
.irq_mask = disable_macepci_irq,
.irq_unmask = enable_macepci_irq,
};
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
......@@ -276,13 +245,13 @@ static struct irq_chip ip32_macepci_interrupt = {
static unsigned long maceisa_mask;
static void enable_maceisa_irq(unsigned int irq)
static void enable_maceisa_irq(struct irq_data *d)
{
unsigned int crime_int = 0;
pr_debug("maceisa enable: %u\n", irq);
pr_debug("maceisa enable: %u\n", d->irq);
switch (irq) {
switch (d->irq) {
case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
crime_int = MACE_AUDIO_INT;
break;
......@@ -296,15 +265,15 @@ static void enable_maceisa_irq(unsigned int irq)
pr_debug("crime_int %08x enabled\n", crime_int);
crime_mask |= crime_int;
crime->imask = crime_mask;
maceisa_mask |= 1 << (irq - MACEISA_AUDIO_SW_IRQ);
maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
mace->perif.ctrl.imask = maceisa_mask;
}
static void disable_maceisa_irq(unsigned int irq)
static void disable_maceisa_irq(struct irq_data *d)
{
unsigned int crime_int = 0;
maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
if (!(maceisa_mask & MACEISA_AUDIO_INT))
crime_int |= MACE_AUDIO_INT;
if (!(maceisa_mask & MACEISA_MISC_INT))
......@@ -318,76 +287,57 @@ static void disable_maceisa_irq(unsigned int irq)
flush_mace_bus();
}
static void mask_and_ack_maceisa_irq(unsigned int irq)
static void mask_and_ack_maceisa_irq(struct irq_data *d)
{
unsigned long mace_int;
/* edge triggered */
mace_int = mace->perif.ctrl.istat;
mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
mace->perif.ctrl.istat = mace_int;
disable_maceisa_irq(irq);
}
static void end_maceisa_irq(unsigned irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_maceisa_irq(irq);
disable_maceisa_irq(d);
}
static struct irq_chip ip32_maceisa_level_interrupt = {
.name = "IP32 MACE ISA",
.ack = disable_maceisa_irq,
.mask = disable_maceisa_irq,
.mask_ack = disable_maceisa_irq,
.unmask = enable_maceisa_irq,
.end = end_maceisa_irq,
.irq_mask = disable_maceisa_irq,
.irq_unmask = enable_maceisa_irq,
};
static struct irq_chip ip32_maceisa_edge_interrupt = {
.name = "IP32 MACE ISA",
.ack = mask_and_ack_maceisa_irq,
.mask = disable_maceisa_irq,
.mask_ack = mask_and_ack_maceisa_irq,
.unmask = enable_maceisa_irq,
.end = end_maceisa_irq,
.irq_ack = mask_and_ack_maceisa_irq,
.irq_mask = disable_maceisa_irq,
.irq_mask_ack = mask_and_ack_maceisa_irq,
.irq_unmask = enable_maceisa_irq,
};
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
* bits 0-3 and 7 in the CRIME register.
*/
static void enable_mace_irq(unsigned int irq)
static void enable_mace_irq(struct irq_data *d)
{
unsigned int bit = irq - CRIME_IRQ_BASE;
unsigned int bit = d->irq - CRIME_IRQ_BASE;
crime_mask |= (1 << bit);
crime->imask = crime_mask;
}
static void disable_mace_irq(unsigned int irq)
static void disable_mace_irq(struct irq_data *d)
{
unsigned int bit = irq - CRIME_IRQ_BASE;
unsigned int bit = d->irq - CRIME_IRQ_BASE;
crime_mask &= ~(1 << bit);
crime->imask = crime_mask;
flush_crime_bus();
}
static void end_mace_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_mace_irq(irq);
}
static struct irq_chip ip32_mace_interrupt = {
.name = "IP32 MACE",
.ack = disable_mace_irq,
.mask = disable_mace_irq,
.mask_ack = disable_mace_irq,
.unmask = enable_mace_irq,
.end = end_mace_irq,
.irq_mask = disable_mace_irq,
.irq_unmask = enable_mace_irq,
};
static void ip32_unknown_interrupt(void)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -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,
};
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册