aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
diff options
context:
space:
mode:
authorKrzysztof Hałasa <khc@pm.waw.pl>2009-05-23 17:36:03 -0400
committerKrzysztof Hałasa <khc@pm.waw.pl>2009-05-23 17:36:03 -0400
commitd4c9e9fc97515588529e7fe48c7d5725292c6734 (patch)
tree5aff48af11301201752b615ecc8ce3b6789204a9 /arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
parent61a5ccc85a98f5eced89a3fda19b0ee708535c1b (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.c67
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
52static 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
76static 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
52static irqreturn_t qmgr_irq(int irq, void *pdev) 95static 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)
236static int qmgr_init(void) 279static 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