Commit 62d00867 authored by Linus Torvalds's avatar 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()
  ...
parents be4d250a c8fb4022
......@@ -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 */
This diff is collapsed.
......@@ -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)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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,
};
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment