diff options
author | Shaohui Xie <Shaohui.Xie@freescale.com> | 2014-01-07 01:27:41 -0500 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-01-10 18:19:27 -0500 |
commit | a655f724df2c0e1634477c7e89da81477a691c0f (patch) | |
tree | b0ecfb9a8e9cdd1c24bd0ce1cdc4851263641994 /arch/powerpc/sysdev/fsl_lbc.c | |
parent | 297649b9f516a840d56bc2df6dda5a6f9c50cea5 (diff) |
powerpc/85xx: handle the eLBC error interrupt if it exists in dts
On P1020, P1021, P1022, and P1023, eLBC event interrupts are routed
to internal interrupt 3 while ELBC error interrupts are routed to
internal interrupt 0. We need to call request_irq for each.
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
[scottwood@freescale.com: reworded commit message and fixed author]
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/sysdev/fsl_lbc.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_lbc.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 6bc5a546d49f..d631022ffb4b 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c | |||
@@ -214,10 +214,14 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data) | |||
214 | struct fsl_lbc_ctrl *ctrl = data; | 214 | struct fsl_lbc_ctrl *ctrl = data; |
215 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 215 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
216 | u32 status; | 216 | u32 status; |
217 | unsigned long flags; | ||
217 | 218 | ||
219 | spin_lock_irqsave(&fsl_lbc_lock, flags); | ||
218 | status = in_be32(&lbc->ltesr); | 220 | status = in_be32(&lbc->ltesr); |
219 | if (!status) | 221 | if (!status) { |
222 | spin_unlock_irqrestore(&fsl_lbc_lock, flags); | ||
220 | return IRQ_NONE; | 223 | return IRQ_NONE; |
224 | } | ||
221 | 225 | ||
222 | out_be32(&lbc->ltesr, LTESR_CLEAR); | 226 | out_be32(&lbc->ltesr, LTESR_CLEAR); |
223 | out_be32(&lbc->lteatr, 0); | 227 | out_be32(&lbc->lteatr, 0); |
@@ -260,6 +264,7 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data) | |||
260 | if (status & ~LTESR_MASK) | 264 | if (status & ~LTESR_MASK) |
261 | dev_err(ctrl->dev, "Unknown error: " | 265 | dev_err(ctrl->dev, "Unknown error: " |
262 | "LTESR 0x%08X\n", status); | 266 | "LTESR 0x%08X\n", status); |
267 | spin_unlock_irqrestore(&fsl_lbc_lock, flags); | ||
263 | return IRQ_HANDLED; | 268 | return IRQ_HANDLED; |
264 | } | 269 | } |
265 | 270 | ||
@@ -298,8 +303,8 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) | |||
298 | goto err; | 303 | goto err; |
299 | } | 304 | } |
300 | 305 | ||
301 | fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); | 306 | fsl_lbc_ctrl_dev->irq[0] = irq_of_parse_and_map(dev->dev.of_node, 0); |
302 | if (fsl_lbc_ctrl_dev->irq == NO_IRQ) { | 307 | if (!fsl_lbc_ctrl_dev->irq[0]) { |
303 | dev_err(&dev->dev, "failed to get irq resource\n"); | 308 | dev_err(&dev->dev, "failed to get irq resource\n"); |
304 | ret = -ENODEV; | 309 | ret = -ENODEV; |
305 | goto err; | 310 | goto err; |
@@ -311,20 +316,34 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) | |||
311 | if (ret < 0) | 316 | if (ret < 0) |
312 | goto err; | 317 | goto err; |
313 | 318 | ||
314 | ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0, | 319 | ret = request_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_irq, 0, |
315 | "fsl-lbc", fsl_lbc_ctrl_dev); | 320 | "fsl-lbc", fsl_lbc_ctrl_dev); |
316 | if (ret != 0) { | 321 | if (ret != 0) { |
317 | dev_err(&dev->dev, "failed to install irq (%d)\n", | 322 | dev_err(&dev->dev, "failed to install irq (%d)\n", |
318 | fsl_lbc_ctrl_dev->irq); | 323 | fsl_lbc_ctrl_dev->irq[0]); |
319 | ret = fsl_lbc_ctrl_dev->irq; | 324 | ret = fsl_lbc_ctrl_dev->irq[0]; |
320 | goto err; | 325 | goto err; |
321 | } | 326 | } |
322 | 327 | ||
328 | fsl_lbc_ctrl_dev->irq[1] = irq_of_parse_and_map(dev->dev.of_node, 1); | ||
329 | if (fsl_lbc_ctrl_dev->irq[1]) { | ||
330 | ret = request_irq(fsl_lbc_ctrl_dev->irq[1], fsl_lbc_ctrl_irq, | ||
331 | IRQF_SHARED, "fsl-lbc-err", fsl_lbc_ctrl_dev); | ||
332 | if (ret) { | ||
333 | dev_err(&dev->dev, "failed to install irq (%d)\n", | ||
334 | fsl_lbc_ctrl_dev->irq[1]); | ||
335 | ret = fsl_lbc_ctrl_dev->irq[1]; | ||
336 | goto err1; | ||
337 | } | ||
338 | } | ||
339 | |||
323 | /* Enable interrupts for any detected events */ | 340 | /* Enable interrupts for any detected events */ |
324 | out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE); | 341 | out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE); |
325 | 342 | ||
326 | return 0; | 343 | return 0; |
327 | 344 | ||
345 | err1: | ||
346 | free_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_dev); | ||
328 | err: | 347 | err: |
329 | iounmap(fsl_lbc_ctrl_dev->regs); | 348 | iounmap(fsl_lbc_ctrl_dev->regs); |
330 | kfree(fsl_lbc_ctrl_dev); | 349 | kfree(fsl_lbc_ctrl_dev); |