Date:2011-03-04 18:28:36 (9 years 3 months ago)
Author:Lars C.
Commit:7437e228a82b3fcf28d79e79c3c2fa2d8c9977fe
Message:Add support for more then one irq bank and move initialization into sub-archs.

Files: arch/mips/include/asm/mach-jz47xx/irq.h (1 diff)
arch/mips/jz47xx/irq.c (5 diffs)
arch/mips/jz47xx/jz4740/Makefile (1 diff)
arch/mips/jz47xx/jz4740/irq.c (1 diff)

Change Details

arch/mips/include/asm/mach-jz47xx/irq.h
2222/* 1st-level interrupts */
2323#define JZ47XX_IRQ(x) (JZ47XX_IRQ_BASE + (x))
2424
25extern void __init jz47xx_intc_init(unsigned int num_banks);
26
2527#endif
arch/mips/jz47xx/irq.c
3131
3232#include <jz4740/base.h>
3333
34static unsigned int jz_intc_num_banks;
3435static void __iomem *jz_intc_base;
35static uint32_t jz_intc_wakeup;
36static uint32_t jz_intc_saved;
36static uint32_t jz_intc_wakeup[2];
37static uint32_t jz_intc_saved[2];
3738
3839#define JZ_REG_INTC_STATUS 0x00
3940#define JZ_REG_INTC_MASK 0x04
...... 
4142#define JZ_REG_INTC_CLEAR_MASK 0x0c
4243#define JZ_REG_INTC_PENDING 0x10
4344
44#define IRQ_BIT(x) BIT((x) - JZ47XX_IRQ_BASE)
45#define IRQ_BIT(x) BIT(((x) - JZ47XX_IRQ_BASE) & 0x1f)
4546
46static inline unsigned long intc_irq_bit(struct irq_data *data)
47static inline unsigned int intc_irq_bit(struct irq_data *data)
4748{
48    return (unsigned long)irq_data_get_irq_chip_data(data);
49    return (unsigned int)irq_data_get_irq_chip_data(data);
4950}
5051
5152static void intc_irq_unmask(struct irq_data *data)
5253{
53    writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
54    unsigned int offset = (data->irq - JZ47XX_IRQ_BASE) & ~0x1f;
55
56    writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK + offset);
5457}
5558
5659static void intc_irq_mask(struct irq_data *data)
5760{
58    writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK);
61    unsigned int offset = (data->irq - JZ47XX_IRQ_BASE) & ~0x1f;
62    writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK + offset);
5963}
6064
6165static int intc_irq_set_wake(struct irq_data *data, unsigned int on)
6266{
67    unsigned int bank = (data->irq - JZ47XX_IRQ_BASE) >> 5;
6368    if (on)
64        jz_intc_wakeup |= intc_irq_bit(data);
69        jz_intc_wakeup[bank] |= intc_irq_bit(data);
6570    else
66        jz_intc_wakeup &= ~intc_irq_bit(data);
71        jz_intc_wakeup[bank] &= ~intc_irq_bit(data);
6772
6873    return 0;
6974}
...... 
7984static irqreturn_t jz4740_cascade(int irq, void *data)
8085{
8186    uint32_t irq_reg;
87    unsigned int i;
8288
83    irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
89    for (i = 0; i < jz_intc_num_banks; ++i) {
90        irq_reg = readl(jz_intc_base + i * 0x20 + JZ_REG_INTC_PENDING);
8491
85    if (irq_reg)
86        generic_handle_irq(__fls(irq_reg) + JZ47XX_IRQ_BASE);
92        if (irq_reg) {
93            generic_handle_irq(__fls(irq_reg) + JZ47XX_IRQ_BASE + i * 0x20);
94            break;
95        }
96    }
8797
8898    return IRQ_HANDLED;
8999}
...... 
93103    .name = "JZ4740 cascade interrupt",
94104};
95105
96void __init arch_init_irq(void)
106void __init jz47xx_intc_init(unsigned int num_banks)
97107{
98108    int i;
99109    mips_cpu_irq_init();
100110
101    jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
111    jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x20 * num_banks);
112    jz_intc_num_banks = num_banks;
102113
103114    /* Mask all irqs */
104    writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
115    for (i = 0; i < num_banks; ++i) {
116        writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK + i * 0x20);
117    }
105118
106    for (i = JZ47XX_IRQ_BASE; i < JZ47XX_IRQ_BASE + 32; i++) {
119    for (i = JZ47XX_IRQ_BASE; i < JZ47XX_IRQ_BASE + 32 * num_banks; i++) {
107120        set_irq_chip_data(i, (void *)IRQ_BIT(i));
108121        set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
109122    }
...... 
124137
125138void jz4740_intc_suspend(void)
126139{
127    jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
128    writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
129    writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
140    unsigned int offset;
141    unsigned int i;
142
143    for (i = 0; i < jz_intc_num_banks; ++i) {
144        offset = i * 0x20;
145
146        jz_intc_saved[i] = readl(jz_intc_base + JZ_REG_INTC_MASK + offset);
147        writel(~jz_intc_wakeup[i], jz_intc_base + JZ_REG_INTC_SET_MASK + offset);
148        writel(jz_intc_wakeup[i], jz_intc_base + JZ_REG_INTC_CLEAR_MASK + offset);
149    }
130150}
131151
132152void jz4740_intc_resume(void)
133153{
134    writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
135    writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
154    unsigned int offset;
155    unsigned int i;
156
157    for (i = 0; i < jz_intc_num_banks; ++i) {
158        offset = i * 0x20;
159
160        writel(~jz_intc_saved[i], jz_intc_base + JZ_REG_INTC_CLEAR_MASK + offset);
161        writel(jz_intc_saved[i], jz_intc_base + JZ_REG_INTC_SET_MASK + offset);
162    }
136163}
137164
138165#ifdef CONFIG_DEBUG_FS
arch/mips/jz47xx/jz4740/Makefile
11
2obj-y += clock.o platform.o time.o gpio.o
2obj-y += clock.o platform.o time.o gpio.o irq.o
33
44obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
55obj-$(CONFIG_JZ4740_N516) += board-n516.o board-n516-display.o
arch/mips/jz47xx/jz4740/irq.c
1#include <linux/init.h>
2#include <asm/mach-jz47xx/irq.h>
3
4void __init arch_init_irq(void)
5{
6    jz47xx_intc_init(1);
7}

Archive Download the corresponding diff file



interactive