netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* pull-request: can 2013-11-27
@ 2013-11-27 21:11 Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 1/4] can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value Marc Kleine-Budde
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Marc Kleine-Budde @ 2013-11-27 21:11 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-can, kernel

Hello David,

this is an extention of my pull request from 2013-11-25, it includes an
additional patch.

This series consists of a patch by Oliver Hartkopp which fixes some corner
cases in the interrupt handler of the sja1000 driver. Then there are two
patches for the c_can dirver. One by me, which fixes a runtime pm related
"scheduling while atomic" error and patch by Holger Bechtold that fixes the
calculation of the transmitted bytes.

The fourth patch (the additional one) is by me, it corrects the clock usage in
the flexcan driver.

regards,
Marc

---

The following changes since commit 2c7a9dc1641664173211c4ebc5db510a08684c46:

  be2net: Avoid programming permenant MAC by BE3-R VFs (2013-11-23 15:11:07 -0800)

are available in the git repository at:

  git://gitorious.org/linux-can/linux-can.git fixes-for-3.13-20131127

for you to fetch changes up to 1a3e5173f5e72cbf7f0c8927b33082e361c16d72:

  can: flexcan: use correct clock as base for bit rate calculation (2013-11-26 15:39:47 +0100)

----------------------------------------------------------------
Holger Bechtold (1):
      can: c_can: fix calculation of transmitted bytes on tx complete

Marc Kleine-Budde (2):
      can: c_can: don't call pm_runtime_get_sync() from interrupt context
      can: flexcan: use correct clock as base for bit rate calculation

Oliver Hartkopp (1):
      can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value

 drivers/net/can/c_can/c_can.c     | 22 ++++++++++++++++------
 drivers/net/can/flexcan.c         |  2 +-
 drivers/net/can/sja1000/sja1000.c | 17 +++++++++--------
 3 files changed, 26 insertions(+), 15 deletions(-)



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value
  2013-11-27 21:11 pull-request: can 2013-11-27 Marc Kleine-Budde
@ 2013-11-27 21:11 ` Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 2/4] can: c_can: don't call pm_runtime_get_sync() from interrupt context Marc Kleine-Budde
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Marc Kleine-Budde @ 2013-11-27 21:11 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-can, kernel, Oliver Hartkopp, linux-stable,
	Marc Kleine-Budde

From: Oliver Hartkopp <socketcan@hartkopp.net>

This patch fixes the issue that the sja1000_interrupt() function may have
returned IRQ_NONE without processing the optional pre_irq() and post_irq()
function before. Further the irq processing counter 'n' is moved to the end of
the while statement to return correct IRQ_[NONE|HANDLED] values at error
conditions.

Reported-by: Wolfgang Grandegger <wg@grandegger.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/sja1000/sja1000.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 7164a99..f17c301 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -494,20 +494,20 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 	uint8_t isrc, status;
 	int n = 0;
 
-	/* Shared interrupts and IRQ off? */
-	if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
-		return IRQ_NONE;
-
 	if (priv->pre_irq)
 		priv->pre_irq(priv);
 
+	/* Shared interrupts and IRQ off? */
+	if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
+		goto out;
+
 	while ((isrc = priv->read_reg(priv, SJA1000_IR)) &&
 	       (n < SJA1000_MAX_IRQ)) {
-		n++;
+
 		status = priv->read_reg(priv, SJA1000_SR);
 		/* check for absent controller due to hw unplug */
 		if (status == 0xFF && sja1000_is_absent(priv))
-			return IRQ_NONE;
+			goto out;
 
 		if (isrc & IRQ_WUI)
 			netdev_warn(dev, "wakeup interrupt\n");
@@ -535,7 +535,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 				status = priv->read_reg(priv, SJA1000_SR);
 				/* check for absent controller */
 				if (status == 0xFF && sja1000_is_absent(priv))
-					return IRQ_NONE;
+					goto out;
 			}
 		}
 		if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
@@ -543,8 +543,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 			if (sja1000_err(dev, isrc, status))
 				break;
 		}
+		n++;
 	}
-
+out:
 	if (priv->post_irq)
 		priv->post_irq(priv);
 
-- 
1.8.5.rc0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] can: c_can: don't call pm_runtime_get_sync() from interrupt context
  2013-11-27 21:11 pull-request: can 2013-11-27 Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 1/4] can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value Marc Kleine-Budde
@ 2013-11-27 21:11 ` Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 3/4] can: c_can: fix calculation of transmitted bytes on tx complete Marc Kleine-Budde
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Marc Kleine-Budde @ 2013-11-27 21:11 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-can, kernel, Marc Kleine-Budde, Andrew Glen,
	linux-stable

The c_can driver contians a callpath (c_can_poll -> c_can_state_change ->
c_can_get_berr_counter) which may call pm_runtime_get_sync() from the IRQ
handler, which is not allowed and results in "BUG: scheduling while atomic".

This problem is fixed by introducing __c_can_get_berr_counter, which will not
call pm_runtime_get_sync().

Reported-by: Andrew Glen <AGlen@bepmarine.com>
Tested-by: Andrew Glen <AGlen@bepmarine.com>
Signed-off-by: Andrew Glen <AGlen@bepmarine.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/c_can/c_can.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index e3fc07c..e59c42b 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -712,22 +712,31 @@ static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
 	return 0;
 }
 
-static int c_can_get_berr_counter(const struct net_device *dev,
-					struct can_berr_counter *bec)
+static int __c_can_get_berr_counter(const struct net_device *dev,
+				    struct can_berr_counter *bec)
 {
 	unsigned int reg_err_counter;
 	struct c_can_priv *priv = netdev_priv(dev);
 
-	c_can_pm_runtime_get_sync(priv);
-
 	reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
 	bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
 				ERR_CNT_REC_SHIFT;
 	bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
 
+	return 0;
+}
+
+static int c_can_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct c_can_priv *priv = netdev_priv(dev);
+	int err;
+
+	c_can_pm_runtime_get_sync(priv);
+	err = __c_can_get_berr_counter(dev, bec);
 	c_can_pm_runtime_put_sync(priv);
 
-	return 0;
+	return err;
 }
 
 /*
@@ -872,7 +881,7 @@ static int c_can_handle_state_change(struct net_device *dev,
 	if (unlikely(!skb))
 		return 0;
 
-	c_can_get_berr_counter(dev, &bec);
+	__c_can_get_berr_counter(dev, &bec);
 	reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
 	rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
 				ERR_CNT_RP_SHIFT;
-- 
1.8.5.rc0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] can: c_can: fix calculation of transmitted bytes on tx complete
  2013-11-27 21:11 pull-request: can 2013-11-27 Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 1/4] can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 2/4] can: c_can: don't call pm_runtime_get_sync() from interrupt context Marc Kleine-Budde
@ 2013-11-27 21:11 ` Marc Kleine-Budde
  2013-11-27 21:11 ` [PATCH 4/4] can: flexcan: use correct clock as base for bit rate calculation Marc Kleine-Budde
  2013-11-28 23:42 ` pull-request: can 2013-11-27 David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Marc Kleine-Budde @ 2013-11-27 21:11 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-can, kernel, Holger Bechtold, Marc Kleine-Budde

From: Holger Bechtold <Holger.Bechtold@gmx.net>

The number of bytes transmitted was not updated correctly, if several CAN
messages (with different length) were transmitted in one 'bunch'. Thus
programs like 'ifconfig' showed wrong transmit byte counts. Reason was, that
the message object whose DLC is to be read was not necessarily the active one
at the time when

    priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, 0)) & IF_MCONT_DLC_MASK;

was executed.

Signed-off-by: Holger Bechtold <Holger.Bechtold@gmx.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/c_can/c_can.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index e59c42b..77061ee 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -763,6 +763,7 @@ static void c_can_do_tx(struct net_device *dev)
 		if (!(val & (1 << (msg_obj_no - 1)))) {
 			can_get_echo_skb(dev,
 					msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
+			c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL);
 			stats->tx_bytes += priv->read_reg(priv,
 					C_CAN_IFACE(MSGCTRL_REG, 0))
 					& IF_MCONT_DLC_MASK;
-- 
1.8.5.rc0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] can: flexcan: use correct clock as base for bit rate calculation
  2013-11-27 21:11 pull-request: can 2013-11-27 Marc Kleine-Budde
                   ` (2 preceding siblings ...)
  2013-11-27 21:11 ` [PATCH 3/4] can: c_can: fix calculation of transmitted bytes on tx complete Marc Kleine-Budde
@ 2013-11-27 21:11 ` Marc Kleine-Budde
  2013-11-28 23:42 ` pull-request: can 2013-11-27 David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Marc Kleine-Budde @ 2013-11-27 21:11 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-can, kernel, Marc Kleine-Budde, linux-stable

The flexcan IP core uses the peripheral clock ("per") as basic clock for the
bit timing calculation. However the driver uses the the wrong clock ("ipg").
This leads to wrong bit rates if the rates on both clock are different.

This patch fixes the problem by using the correct clock for the bit rate
calculation.

Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/flexcan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index ae08cf1..aaed97b 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -1020,13 +1020,13 @@ static int flexcan_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "no ipg clock defined\n");
 			return PTR_ERR(clk_ipg);
 		}
-		clock_freq = clk_get_rate(clk_ipg);
 
 		clk_per = devm_clk_get(&pdev->dev, "per");
 		if (IS_ERR(clk_per)) {
 			dev_err(&pdev->dev, "no per clock defined\n");
 			return PTR_ERR(clk_per);
 		}
+		clock_freq = clk_get_rate(clk_per);
 	}
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.8.5.rc0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: pull-request: can 2013-11-27
  2013-11-27 21:11 pull-request: can 2013-11-27 Marc Kleine-Budde
                   ` (3 preceding siblings ...)
  2013-11-27 21:11 ` [PATCH 4/4] can: flexcan: use correct clock as base for bit rate calculation Marc Kleine-Budde
@ 2013-11-28 23:42 ` David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2013-11-28 23:42 UTC (permalink / raw)
  To: mkl; +Cc: netdev, linux-can, kernel

From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Wed, 27 Nov 2013 22:11:31 +0100

> this is an extention of my pull request from 2013-11-25, it includes an
> additional patch.
> 
> This series consists of a patch by Oliver Hartkopp which fixes some corner
> cases in the interrupt handler of the sja1000 driver. Then there are two
> patches for the c_can dirver. One by me, which fixes a runtime pm related
> "scheduling while atomic" error and patch by Holger Bechtold that fixes the
> calculation of the transmitted bytes.
> 
> The fourth patch (the additional one) is by me, it corrects the clock usage in
> the flexcan driver.

Pulled, thanks Marc.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-11-28 23:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-27 21:11 pull-request: can 2013-11-27 Marc Kleine-Budde
2013-11-27 21:11 ` [PATCH 1/4] can: sja1000: fix {pre,post}_irq() handling and IRQ handler return value Marc Kleine-Budde
2013-11-27 21:11 ` [PATCH 2/4] can: c_can: don't call pm_runtime_get_sync() from interrupt context Marc Kleine-Budde
2013-11-27 21:11 ` [PATCH 3/4] can: c_can: fix calculation of transmitted bytes on tx complete Marc Kleine-Budde
2013-11-27 21:11 ` [PATCH 4/4] can: flexcan: use correct clock as base for bit rate calculation Marc Kleine-Budde
2013-11-28 23:42 ` pull-request: can 2013-11-27 David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).