Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 284742
b: refs/heads/master
c: 37c42a7
h: refs/heads/master
v: v3
  • Loading branch information
Maxime Bizon authored and Ralf Baechle committed Dec 7, 2011
1 parent a33b60e commit 63d67f9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f61cced99347783c1f3a7464e88b855a5ca6c227
refs/heads/master: 37c42a741f6c2c76dc5e61650e5d66dd20540aaf
104 changes: 67 additions & 37 deletions trunk/arch/mips/bcm63xx/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,32 @@ static void __dispatch_internal(void) __maybe_unused;
#ifdef CONFIG_BCM63XX_CPU_6338
#define irq_stat_reg PERF_IRQSTAT_6338_REG
#define irq_mask_reg PERF_IRQMASK_6338_REG
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
#define irq_stat_reg PERF_IRQSTAT_6345_REG
#define irq_mask_reg PERF_IRQMASK_6345_REG
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
#define irq_stat_reg PERF_IRQSTAT_6348_REG
#define irq_mask_reg PERF_IRQMASK_6348_REG
#define dispatch_internal __dispatch_internal
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
#define irq_stat_reg PERF_IRQSTAT_6358_REG
#define irq_mask_reg PERF_IRQMASK_6358_REG
#define dispatch_internal __dispatch_internal
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE)
#endif

#define dispatch_internal __dispatch_internal
Expand All @@ -51,6 +65,8 @@ static inline void bcm63xx_init_irq(void)

static u32 irq_stat_addr, irq_mask_addr;
static void (*dispatch_internal)(void);
static int is_ext_irq_cascaded;
static unsigned int ext_irq_start, ext_irq_end;

static void bcm63xx_init_irq(void)
{
Expand All @@ -73,6 +89,9 @@ static void bcm63xx_init_irq(void)
case BCM6358_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6358_REG;
irq_mask_addr += PERF_IRQMASK_6358_REG;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
break;
default:
BUG();
Expand All @@ -84,7 +103,11 @@ static void bcm63xx_init_irq(void)

static inline void handle_internal(int intbit)
{
do_IRQ(intbit + IRQ_INTERNAL_BASE);
if (is_ext_irq_cascaded &&
intbit >= ext_irq_start && intbit <= ext_irq_end)
do_IRQ(intbit - ext_irq_start + IRQ_EXTERNAL_BASE);
else
do_IRQ(intbit + IRQ_INTERNAL_BASE);
}

/*
Expand Down Expand Up @@ -128,94 +151,93 @@ asmlinkage void plat_irq_dispatch(void)
do_IRQ(7);
if (cause & CAUSEF_IP2)
dispatch_internal();
if (cause & CAUSEF_IP3)
do_IRQ(IRQ_EXT_0);
if (cause & CAUSEF_IP4)
do_IRQ(IRQ_EXT_1);
if (cause & CAUSEF_IP5)
do_IRQ(IRQ_EXT_2);
if (cause & CAUSEF_IP6)
do_IRQ(IRQ_EXT_3);
if (!is_ext_irq_cascaded) {
if (cause & CAUSEF_IP3)
do_IRQ(IRQ_EXT_0);
if (cause & CAUSEF_IP4)
do_IRQ(IRQ_EXT_1);
if (cause & CAUSEF_IP5)
do_IRQ(IRQ_EXT_2);
if (cause & CAUSEF_IP6)
do_IRQ(IRQ_EXT_3);
}
} while (1);
}

/*
* internal IRQs operations: only mask/unmask on PERF irq mask
* register.
*/
static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
static void internal_irq_mask(unsigned int irq)
{
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
u32 mask;

mask = bcm_readl(irq_mask_addr);
mask &= ~(1 << irq);
bcm_writel(mask, irq_mask_addr);
}

static void bcm63xx_internal_irq_unmask(struct irq_data *d)
static void internal_irq_unmask(unsigned int irq)
{
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
u32 mask;

mask = bcm_readl(irq_mask_addr);
mask |= (1 << irq);
bcm_writel(mask, irq_mask_addr);
}

static void bcm63xx_internal_irq_mask(struct irq_data *d)
{
internal_irq_mask(d->irq - IRQ_INTERNAL_BASE);
}

static void bcm63xx_internal_irq_unmask(struct irq_data *d)
{
internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE);
}

/*
* external IRQs operations: mask/unmask and clear on PERF external
* irq control register.
*/
static void bcm63xx_external_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg;

reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
reg &= ~EXTIRQ_CFG_MASK(irq);
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
if (is_ext_irq_cascaded)
internal_irq_mask(irq + ext_irq_start);
}

static void bcm63xx_external_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg;

reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
reg |= EXTIRQ_CFG_MASK(irq);
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
if (is_ext_irq_cascaded)
internal_irq_unmask(irq + ext_irq_start);
}

static void bcm63xx_external_irq_clear(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg;

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(struct irq_data *d)
{
set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
irq_enable_hazard();
bcm63xx_external_irq_unmask(d);
return 0;
}

static void bcm63xx_external_irq_shutdown(struct irq_data *d)
{
bcm63xx_external_irq_mask(d);
clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
irq_disable_hazard();
}

static int bcm63xx_external_irq_set_type(struct irq_data *d,
unsigned int flow_type)
{
unsigned int irq = d->irq - IRQ_EXT_BASE;
unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
u32 reg;

flow_type &= IRQ_TYPE_SENSE_MASK;
Expand Down Expand Up @@ -275,9 +297,6 @@ static struct irq_chip bcm63xx_internal_irq_chip = {

static struct irq_chip bcm63xx_external_irq_chip = {
.name = "bcm63xx_epic",
.irq_startup = bcm63xx_external_irq_startup,
.irq_shutdown = bcm63xx_external_irq_shutdown,

.irq_ack = bcm63xx_external_irq_clear,

.irq_mask = bcm63xx_external_irq_mask,
Expand All @@ -292,6 +311,12 @@ static struct irqaction cpu_ip2_cascade_action = {
.flags = IRQF_NO_THREAD,
};

static struct irqaction cpu_ext_cascade_action = {
.handler = no_action,
.name = "cascade_extirq",
.flags = IRQF_NO_THREAD,
};

void __init arch_init_irq(void)
{
int i;
Expand All @@ -302,9 +327,14 @@ void __init arch_init_irq(void)
irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
handle_level_irq);

for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
for (i = IRQ_EXTERNAL_BASE; i < IRQ_EXTERNAL_BASE + 4; ++i)
irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
handle_edge_irq);

setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
if (!is_ext_irq_cascaded) {
for (i = 3; i < 7; ++i)
setup_irq(MIPS_CPU_IRQ_BASE + i, &cpu_ext_cascade_action);
}

setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
}
12 changes: 5 additions & 7 deletions trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@

#include <bcm63xx_cpu.h>

#define IRQ_MIPS_BASE 0
#define IRQ_INTERNAL_BASE 8

#define IRQ_EXT_BASE (IRQ_MIPS_BASE + 3)
#define IRQ_EXT_0 (IRQ_EXT_BASE + 0)
#define IRQ_EXT_1 (IRQ_EXT_BASE + 1)
#define IRQ_EXT_2 (IRQ_EXT_BASE + 2)
#define IRQ_EXT_3 (IRQ_EXT_BASE + 3)
#define IRQ_EXTERNAL_BASE 100
#define IRQ_EXT_0 (IRQ_EXTERNAL_BASE + 0)
#define IRQ_EXT_1 (IRQ_EXTERNAL_BASE + 1)
#define IRQ_EXT_2 (IRQ_EXTERNAL_BASE + 2)
#define IRQ_EXT_3 (IRQ_EXTERNAL_BASE + 3)

#endif /* ! BCM63XX_IRQ_H_ */
7 changes: 7 additions & 0 deletions trunk/arch/mips/include/asm/mach-bcm63xx/irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef __ASM_MACH_BCM63XX_IRQ_H
#define __ASM_MACH_BCM63XX_IRQ_H

#define NR_IRQS 128
#define MIPS_CPU_IRQ_BASE 0

#endif

0 comments on commit 63d67f9

Please sign in to comment.