diff mbox

[2/2] powerpc/85xx: handle the eLBC error interrupt if it exist in dts

Message ID 1389076061-20159-1-git-send-email-dongsheng.wang@freescale.com (mailing list archive)
State Accepted
Commit a655f724df2c0e1634477c7e89da81477a691c0f
Delegated to: Scott Wood
Headers show

Commit Message

Dongsheng Wang Jan. 7, 2014, 6:27 a.m. UTC
From: Wang Dongsheng <dongsheng.wang@freescale.com>

On P3041, P1020, P1021, P1022, P1023 eLBC event interrupts are routed
to Int9(P3041) & Int3(P102x) while ELBC error interrupts are routed to
Int0, 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>

Comments

Scott Wood Jan. 7, 2014, 6:58 a.m. UTC | #1
On Tue, 2014-01-07 at 14:27 +0800, Dongsheng Wang wrote:
> From: Wang Dongsheng <dongsheng.wang@freescale.com>

AFAICT this patch was originally written by Shaohui Xie.

> On P3041, P1020, P1021, P1022, P1023 eLBC event interrupts are routed
> to Int9(P3041) & Int3(P102x) while ELBC error interrupts are routed to
> Int0, we need to call request_irq for each.

For p3041 I thought that was only on early silicon revs that we don't
support anymore.

As for p102x, have you tested that this is actually what happens?  How
would we distinguish eLBC errors from other error sources, given that
there's no EISR0?  Do we just hope that no other error interrupts
happen?

-Scott
Dongsheng Wang Jan. 7, 2014, 10:01 a.m. UTC | #2
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Tuesday, January 07, 2014 2:58 PM
> To: Wang Dongsheng-B40534
> Cc: linuxppc-dev@lists.ozlabs.org; Xie Shaohui-B21989; Kumar Gala
> Subject: Re: [PATCH 2/2] powerpc/85xx: handle the eLBC error interrupt if it
> exist in dts
> 
> On Tue, 2014-01-07 at 14:27 +0800, Dongsheng Wang wrote:
> > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> AFAICT this patch was originally written by Shaohui Xie.
> 
> > On P3041, P1020, P1021, P1022, P1023 eLBC event interrupts are routed
> > to Int9(P3041) & Int3(P102x) while ELBC error interrupts are routed to
> > Int0, we need to call request_irq for each.
> 
> For p3041 I thought that was only on early silicon revs that we don't
> support anymore.
> 
> As for p102x, have you tested that this is actually what happens?  How
> would we distinguish eLBC errors from other error sources, given that
> there's no EISR0?  Do we just hope that no other error interrupts
> happen?
Yes, I tested. The interrupt is shard eLBC interrupt handler could check the error.
This patch is fix "nobody cared" the error interrupt. After sleep resume the lbc
will get a chip select error.

-Dongsheng

> 
> -Scott
>
Scott Wood Jan. 7, 2014, 8:45 p.m. UTC | #3
On Tue, 2014-01-07 at 04:01 -0600, Wang Dongsheng-B40534 wrote:
> 
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Tuesday, January 07, 2014 2:58 PM
> > To: Wang Dongsheng-B40534
> > Cc: linuxppc-dev@lists.ozlabs.org; Xie Shaohui-B21989; Kumar Gala
> > Subject: Re: [PATCH 2/2] powerpc/85xx: handle the eLBC error interrupt if it
> > exist in dts
> > 
> > On Tue, 2014-01-07 at 14:27 +0800, Dongsheng Wang wrote:
> > > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> > 
> > AFAICT this patch was originally written by Shaohui Xie.
> > 
> > > On P3041, P1020, P1021, P1022, P1023 eLBC event interrupts are routed
> > > to Int9(P3041) & Int3(P102x) while ELBC error interrupts are routed to
> > > Int0, we need to call request_irq for each.
> > 
> > For p3041 I thought that was only on early silicon revs that we don't
> > support anymore.
> > 
> > As for p102x, have you tested that this is actually what happens?  How
> > would we distinguish eLBC errors from other error sources, given that
> > there's no EISR0?  Do we just hope that no other error interrupts
> > happen?
> Yes, I tested. The interrupt is shard eLBC interrupt handler could check the error.
> This patch is fix "nobody cared" the error interrupt. After sleep resume the lbc
> will get a chip select error.

s/no other error interrupts happen/no other error interrupts for which
we don't have a handler registered or which don't even have an
associated status register happen/

-Scott
Dongsheng Wang Jan. 8, 2014, 7:12 a.m. UTC | #4
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Wednesday, January 08, 2014 4:45 AM
> To: Wang Dongsheng-B40534
> Cc: linuxppc-dev@lists.ozlabs.org; Xie Shaohui-B21989; Kumar Gala
> Subject: Re: [PATCH 2/2] powerpc/85xx: handle the eLBC error interrupt if it
> exist in dts
> 
> On Tue, 2014-01-07 at 04:01 -0600, Wang Dongsheng-B40534 wrote:
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Tuesday, January 07, 2014 2:58 PM
> > > To: Wang Dongsheng-B40534
> > > Cc: linuxppc-dev@lists.ozlabs.org; Xie Shaohui-B21989; Kumar Gala
> > > Subject: Re: [PATCH 2/2] powerpc/85xx: handle the eLBC error interrupt if it
> > > exist in dts
> > >
> > > On Tue, 2014-01-07 at 14:27 +0800, Dongsheng Wang wrote:
> > > > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> > >
> > > AFAICT this patch was originally written by Shaohui Xie.
> > >
> > > > On P3041, P1020, P1021, P1022, P1023 eLBC event interrupts are routed
> > > > to Int9(P3041) & Int3(P102x) while ELBC error interrupts are routed to
> > > > Int0, we need to call request_irq for each.
> > >
> > > For p3041 I thought that was only on early silicon revs that we don't
> > > support anymore.
> > >
> > > As for p102x, have you tested that this is actually what happens?  How
> > > would we distinguish eLBC errors from other error sources, given that
> > > there's no EISR0?  Do we just hope that no other error interrupts
> > > happen?
> > Yes, I tested. The interrupt is shard eLBC interrupt handler could check the
> error.
> > This patch is fix "nobody cared" the error interrupt. After sleep resume the
> lbc
> > will get a chip select error.
> 
> s/no other error interrupts happen/no other error interrupts for which
> we don't have a handler registered or which don't even have an
> associated status register happen/
> 
If the ip-block does not handle their error interrupt is a ip-block issue that.
Since the use of this shared interrupt must maintain their status, once there
is no deal shared interrupt, it will affect the other ip-block.
diff mbox

Patch

diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h
index 420b453..067fb0d 100644
--- a/arch/powerpc/include/asm/fsl_lbc.h
+++ b/arch/powerpc/include/asm/fsl_lbc.h
@@ -285,7 +285,7 @@  struct fsl_lbc_ctrl {
 	/* device info */
 	struct device			*dev;
 	struct fsl_lbc_regs __iomem	*regs;
-	int				irq;
+	int				irq[2];
 	wait_queue_head_t		irq_wait;
 	spinlock_t			lock;
 	void				*nand;
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 6bc5a54..d631022 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)
 	struct fsl_lbc_ctrl *ctrl = data;
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 	u32 status;
+	unsigned long flags;
 
+	spin_lock_irqsave(&fsl_lbc_lock, flags);
 	status = in_be32(&lbc->ltesr);
-	if (!status)
+	if (!status) {
+		spin_unlock_irqrestore(&fsl_lbc_lock, flags);
 		return IRQ_NONE;
+	}
 
 	out_be32(&lbc->ltesr, LTESR_CLEAR);
 	out_be32(&lbc->lteatr, 0);
@@ -260,6 +264,7 @@  static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
 	if (status & ~LTESR_MASK)
 		dev_err(ctrl->dev, "Unknown error: "
 			"LTESR 0x%08X\n", status);
+	spin_unlock_irqrestore(&fsl_lbc_lock, flags);
 	return IRQ_HANDLED;
 }
 
@@ -298,8 +303,8 @@  static int fsl_lbc_ctrl_probe(struct platform_device *dev)
 		goto err;
 	}
 
-	fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0);
-	if (fsl_lbc_ctrl_dev->irq == NO_IRQ) {
+	fsl_lbc_ctrl_dev->irq[0] = irq_of_parse_and_map(dev->dev.of_node, 0);
+	if (!fsl_lbc_ctrl_dev->irq[0]) {
 		dev_err(&dev->dev, "failed to get irq resource\n");
 		ret = -ENODEV;
 		goto err;
@@ -311,20 +316,34 @@  static int fsl_lbc_ctrl_probe(struct platform_device *dev)
 	if (ret < 0)
 		goto err;
 
-	ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0,
+	ret = request_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_irq, 0,
 				"fsl-lbc", fsl_lbc_ctrl_dev);
 	if (ret != 0) {
 		dev_err(&dev->dev, "failed to install irq (%d)\n",
-			fsl_lbc_ctrl_dev->irq);
-		ret = fsl_lbc_ctrl_dev->irq;
+			fsl_lbc_ctrl_dev->irq[0]);
+		ret = fsl_lbc_ctrl_dev->irq[0];
 		goto err;
 	}
 
+	fsl_lbc_ctrl_dev->irq[1] = irq_of_parse_and_map(dev->dev.of_node, 1);
+	if (fsl_lbc_ctrl_dev->irq[1]) {
+		ret = request_irq(fsl_lbc_ctrl_dev->irq[1], fsl_lbc_ctrl_irq,
+				IRQF_SHARED, "fsl-lbc-err", fsl_lbc_ctrl_dev);
+		if (ret) {
+			dev_err(&dev->dev, "failed to install irq (%d)\n",
+					fsl_lbc_ctrl_dev->irq[1]);
+			ret = fsl_lbc_ctrl_dev->irq[1];
+			goto err1;
+		}
+	}
+
 	/* Enable interrupts for any detected events */
 	out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE);
 
 	return 0;
 
+err1:
+	free_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_dev);
 err:
 	iounmap(fsl_lbc_ctrl_dev->regs);
 	kfree(fsl_lbc_ctrl_dev);