diff options
author | Krzysztof Hałasa <khc@pm.waw.pl> | 2009-05-23 17:36:03 -0400 |
---|---|---|
committer | Krzysztof Hałasa <khc@pm.waw.pl> | 2009-05-23 17:36:03 -0400 |
commit | d4c9e9fc97515588529e7fe48c7d5725292c6734 (patch) | |
tree | 5aff48af11301201752b615ecc8ce3b6789204a9 /arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | |
parent | 61a5ccc85a98f5eced89a3fda19b0ee708535c1b (diff) |
IXP42x: Add QMgr support for IXP425 rev. A0 processors.
Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
Diffstat (limited to 'arch/arm/mach-ixp4xx/ixp4xx_qmgr.c')
-rw-r--r-- | arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index 7531bfdb7b4e..6e6dc4c78a10 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | |||
@@ -49,6 +49,49 @@ void qmgr_set_irq(unsigned int queue, int src, | |||
49 | } | 49 | } |
50 | 50 | ||
51 | 51 | ||
52 | static irqreturn_t qmgr_irq1_a0(int irq, void *pdev) | ||
53 | { | ||
54 | int i, ret = 0; | ||
55 | |||
56 | /* ACK - it may clear any bits so don't rely on it */ | ||
57 | __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]); | ||
58 | |||
59 | for (i = 0; i < HALF_QUEUES; i++) { | ||
60 | u32 src, stat; | ||
61 | if (!(qmgr_regs->irqen[0] & BIT(i))) | ||
62 | continue; | ||
63 | src = qmgr_regs->irqsrc[i >> 3]; | ||
64 | stat = qmgr_regs->stat1[i >> 3]; | ||
65 | if (src & 4) /* the IRQ condition is inverted */ | ||
66 | stat = ~stat; | ||
67 | if (stat & BIT(src & 3)) { | ||
68 | irq_handlers[i](irq_pdevs[i]); | ||
69 | ret = IRQ_HANDLED; | ||
70 | } | ||
71 | } | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | |||
76 | static irqreturn_t qmgr_irq2_a0(int irq, void *pdev) | ||
77 | { | ||
78 | int i, ret = 0; | ||
79 | u32 req_bitmap; | ||
80 | |||
81 | /* ACK - it may clear any bits so don't rely on it */ | ||
82 | __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]); | ||
83 | |||
84 | req_bitmap = qmgr_regs->irqen[1] & qmgr_regs->statne_h; | ||
85 | for (i = 0; i < HALF_QUEUES; i++) { | ||
86 | if (!(req_bitmap & BIT(i))) | ||
87 | continue; | ||
88 | irq_handlers[HALF_QUEUES + i](irq_pdevs[HALF_QUEUES + i]); | ||
89 | ret = IRQ_HANDLED; | ||
90 | } | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | |||
52 | static irqreturn_t qmgr_irq(int irq, void *pdev) | 95 | static irqreturn_t qmgr_irq(int irq, void *pdev) |
53 | { | 96 | { |
54 | int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1); | 97 | int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1); |
@@ -236,6 +279,8 @@ void qmgr_release_queue(unsigned int queue) | |||
236 | static int qmgr_init(void) | 279 | static int qmgr_init(void) |
237 | { | 280 | { |
238 | int i, err; | 281 | int i, err; |
282 | irq_handler_t handler1, handler2; | ||
283 | |||
239 | mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS, | 284 | mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS, |
240 | IXP4XX_QMGR_REGION_SIZE, | 285 | IXP4XX_QMGR_REGION_SIZE, |
241 | "IXP4xx Queue Manager"); | 286 | "IXP4xx Queue Manager"); |
@@ -265,19 +310,25 @@ static int qmgr_init(void) | |||
265 | for (i = 0; i < QUEUES; i++) | 310 | for (i = 0; i < QUEUES; i++) |
266 | __raw_writel(0, &qmgr_regs->sram[i]); | 311 | __raw_writel(0, &qmgr_regs->sram[i]); |
267 | 312 | ||
268 | err = request_irq(IRQ_IXP4XX_QM1, qmgr_irq, 0, | 313 | if (cpu_is_ixp42x_rev_a0()) { |
269 | "IXP4xx Queue Manager", NULL); | 314 | handler1 = qmgr_irq1_a0; |
315 | handler2 = qmgr_irq2_a0; | ||
316 | } else | ||
317 | handler1 = handler2 = qmgr_irq; | ||
318 | |||
319 | err = request_irq(IRQ_IXP4XX_QM1, handler1, 0, "IXP4xx Queue Manager", | ||
320 | NULL); | ||
270 | if (err) { | 321 | if (err) { |
271 | printk(KERN_ERR "qmgr: failed to request IRQ%i\n", | 322 | printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n", |
272 | IRQ_IXP4XX_QM1); | 323 | IRQ_IXP4XX_QM1, err); |
273 | goto error_irq; | 324 | goto error_irq; |
274 | } | 325 | } |
275 | 326 | ||
276 | err = request_irq(IRQ_IXP4XX_QM2, qmgr_irq, 0, | 327 | err = request_irq(IRQ_IXP4XX_QM2, handler2, 0, "IXP4xx Queue Manager", |
277 | "IXP4xx Queue Manager", NULL); | 328 | NULL); |
278 | if (err) { | 329 | if (err) { |
279 | printk(KERN_ERR "qmgr: failed to request IRQ%i\n", | 330 | printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n", |
280 | IRQ_IXP4XX_QM2); | 331 | IRQ_IXP4XX_QM2, err); |
281 | goto error_irq2; | 332 | goto error_irq2; |
282 | } | 333 | } |
283 | 334 | ||