From 969a8bfdca7a106f4b21c98eeb86cece5c7459d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 27 Jul 2018 11:46:02 +0200 Subject: [PATCH] 4.9-stable patches added patches: can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch can-xilinx_can-fix-power-management-handling.patch can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch driver-core-partially-revert-driver-core-correct-device-s-shutdown-order.patch exec-avoid-gcc-8-warning-for-get_task_comm.patch turn-off-wattribute-alias.patch usb-cdc_acm-add-quirk-for-castles-vega3000.patch usb-core-handle-hub-c_port_over_current-condition.patch usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch --- ...evice-dropping-off-bus-on-rx-overrun.patch | 41 +++ ...ct-clear-of-non-processed-interrupts.patch | 54 +++ ...nx_can-fix-power-management-handling.patch | 178 ++++++++++ ...om-error-states-not-being-propagated.patch | 234 ++++++++++++ ...p-if-rxnemp-is-asserted-without-rxok.patch | 98 +++++ ...overflow-interrupt-not-being-enabled.patch | 37 ++ ...ames-in-tx-fifo-to-fix-tx-accounting.patch | 335 ++++++++++++++++++ ...core-correct-device-s-shutdown-order.patch | 70 ++++ ...void-gcc-8-warning-for-get_task_comm.patch | 84 +++++ queue-4.9/series | 13 + queue-4.9/turn-off-wattribute-alias.patch | 62 ++++ ...c_acm-add-quirk-for-castles-vega3000.patch | 33 ++ ...le-hub-c_port_over_current-condition.patch | 49 +++ ...-return-delayed-status-when-len-is-0.patch | 54 +++ 14 files changed, 1342 insertions(+) create mode 100644 queue-4.9/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch create mode 100644 queue-4.9/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch create mode 100644 queue-4.9/can-xilinx_can-fix-power-management-handling.patch create mode 100644 queue-4.9/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch create mode 100644 queue-4.9/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch create mode 100644 queue-4.9/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch create mode 100644 queue-4.9/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch create mode 100644 queue-4.9/driver-core-partially-revert-driver-core-correct-device-s-shutdown-order.patch create mode 100644 queue-4.9/exec-avoid-gcc-8-warning-for-get_task_comm.patch create mode 100644 queue-4.9/turn-off-wattribute-alias.patch create mode 100644 queue-4.9/usb-cdc_acm-add-quirk-for-castles-vega3000.patch create mode 100644 queue-4.9/usb-core-handle-hub-c_port_over_current-condition.patch create mode 100644 queue-4.9/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch diff --git a/queue-4.9/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch b/queue-4.9/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch new file mode 100644 index 00000000000..e5971db807c --- /dev/null +++ b/queue-4.9/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch @@ -0,0 +1,41 @@ +From 2574fe54515ed3487405de329e4e9f13d7098c10 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Tue, 7 Feb 2017 13:23:04 +0200 +Subject: can: xilinx_can: fix device dropping off bus on RX overrun + +From: Anssi Hannula + +commit 2574fe54515ed3487405de329e4e9f13d7098c10 upstream. + +The xilinx_can driver performs a software reset when an RX overrun is +detected. This causes the device to enter Configuration mode where no +messages are received or transmitted. + +The documentation does not mention any need to perform a reset on an RX +overrun, and testing by inducing an RX overflow also indicated that the +device continues to work just fine without a reset. + +Remove the software reset. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -696,7 +696,6 @@ static void xcan_err_interrupt(struct ne + if (isr & XCAN_IXR_RXOFLW_MASK) { + stats->rx_over_errors++; + stats->rx_errors++; +- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK); + if (skb) { + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; diff --git a/queue-4.9/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch b/queue-4.9/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch new file mode 100644 index 00000000000..f6fd191e3a0 --- /dev/null +++ b/queue-4.9/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch @@ -0,0 +1,54 @@ +From 2f4f0f338cf453bfcdbcf089e177c16f35f023c8 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 26 Feb 2018 14:39:59 +0200 +Subject: can: xilinx_can: fix incorrect clear of non-processed interrupts + +From: Anssi Hannula + +commit 2f4f0f338cf453bfcdbcf089e177c16f35f023c8 upstream. + +xcan_interrupt() clears ERROR|RXOFLV|BSOFF|ARBLST interrupts if any of +them is asserted. This does not take into account that some of them +could have been asserted between interrupt status read and interrupt +clear, therefore clearing them without handling them. + +Fix the code to only clear those interrupts that it knows are asserted +and therefore going to be processed in xcan_err_interrupt(). + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: Michal Simek +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -938,6 +938,7 @@ static irqreturn_t xcan_interrupt(int ir + struct net_device *ndev = (struct net_device *)dev_id; + struct xcan_priv *priv = netdev_priv(ndev); + u32 isr, ier; ++ u32 isr_errors; + + /* Get the interrupt status from Xilinx CAN */ + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); +@@ -956,11 +957,10 @@ static irqreturn_t xcan_interrupt(int ir + xcan_tx_interrupt(ndev, isr); + + /* Check for the type of error interrupt and Processing it */ +- if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | +- XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK)) { +- priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_ERROR_MASK | +- XCAN_IXR_RXOFLW_MASK | XCAN_IXR_BSOFF_MASK | +- XCAN_IXR_ARBLST_MASK)); ++ isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | ++ XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK); ++ if (isr_errors) { ++ priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors); + xcan_err_interrupt(ndev, isr); + } + diff --git a/queue-4.9/can-xilinx_can-fix-power-management-handling.patch b/queue-4.9/can-xilinx_can-fix-power-management-handling.patch new file mode 100644 index 00000000000..e26106e04bb --- /dev/null +++ b/queue-4.9/can-xilinx_can-fix-power-management-handling.patch @@ -0,0 +1,178 @@ +From 8ebd83bdb027f29870d96649dba18b91581ea829 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 17 May 2018 15:41:19 +0300 +Subject: can: xilinx_can: fix power management handling + +From: Anssi Hannula + +commit 8ebd83bdb027f29870d96649dba18b91581ea829 upstream. + +There are several issues with the suspend/resume handling code of the +driver: + +- The device is attached and detached in the runtime_suspend() and + runtime_resume() callbacks if the interface is running. However, + during xcan_chip_start() the interface is considered running, + causing the resume handler to incorrectly call netif_start_queue() + at the beginning of xcan_chip_start(), and on xcan_chip_start() error + return the suspend handler detaches the device leaving the user + unable to bring-up the device anymore. + +- The device is not brought properly up on system resume. A reset is + done and the code tries to determine the bus state after that. + However, after reset the device is always in Configuration mode + (down), so the state checking code does not make sense and + communication will also not work. + +- The suspend callback tries to set the device to sleep mode (low-power + mode which monitors the bus and brings the device back to normal mode + on activity), but then immediately disables the clocks (possibly + before the device reaches the sleep mode), which does not make sense + to me. If a clean shutdown is wanted before disabling clocks, we can + just bring it down completely instead of only sleep mode. + +Reorganize the PM code so that only the clock logic remains in the +runtime PM callbacks and the system PM callbacks contain the device +bring-up/down logic. This makes calling the runtime PM callbacks during +e.g. xcan_chip_start() safe. + +The system PM callbacks now simply call common code to start/stop the +HW if the interface was running, replacing the broken code from before. + +xcan_chip_stop() is updated to use the common reset code so that it will +wait for the reset to complete. Reset also disables all interrupts so do +not do that separately. + +Also, the device_may_wakeup() checks are removed as the driver does not +have wakeup support. + +Tested on Zynq-7000 integrated CAN. + +Signed-off-by: Anssi Hannula +Cc: Michal Simek +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 69 +++++++++++++++++-------------------------- + 1 file changed, 28 insertions(+), 41 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -811,13 +811,9 @@ static irqreturn_t xcan_interrupt(int ir + static void xcan_chip_stop(struct net_device *ndev) + { + struct xcan_priv *priv = netdev_priv(ndev); +- u32 ier; + + /* Disable interrupts and leave the can in configuration mode */ +- ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier &= ~XCAN_INTR_ALL; +- priv->write_reg(priv, XCAN_IER_OFFSET, ier); +- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK); ++ set_reset_mode(ndev); + priv->can.state = CAN_STATE_STOPPED; + } + +@@ -950,10 +946,15 @@ static const struct net_device_ops xcan_ + */ + static int __maybe_unused xcan_suspend(struct device *dev) + { +- if (!device_may_wakeup(dev)) +- return pm_runtime_force_suspend(dev); ++ struct net_device *ndev = dev_get_drvdata(dev); + +- return 0; ++ if (netif_running(ndev)) { ++ netif_stop_queue(ndev); ++ netif_device_detach(ndev); ++ xcan_chip_stop(ndev); ++ } ++ ++ return pm_runtime_force_suspend(dev); + } + + /** +@@ -965,11 +966,27 @@ static int __maybe_unused xcan_suspend(s + */ + static int __maybe_unused xcan_resume(struct device *dev) + { +- if (!device_may_wakeup(dev)) +- return pm_runtime_force_resume(dev); ++ struct net_device *ndev = dev_get_drvdata(dev); ++ int ret; + +- return 0; ++ ret = pm_runtime_force_resume(dev); ++ if (ret) { ++ dev_err(dev, "pm_runtime_force_resume failed on resume\n"); ++ return ret; ++ } ++ ++ if (netif_running(ndev)) { ++ ret = xcan_chip_start(ndev); ++ if (ret) { ++ dev_err(dev, "xcan_chip_start failed on resume\n"); ++ return ret; ++ } ++ ++ netif_device_attach(ndev); ++ netif_start_queue(ndev); ++ } + ++ return 0; + } + + /** +@@ -984,14 +1001,6 @@ static int __maybe_unused xcan_runtime_s + struct net_device *ndev = dev_get_drvdata(dev); + struct xcan_priv *priv = netdev_priv(ndev); + +- if (netif_running(ndev)) { +- netif_stop_queue(ndev); +- netif_device_detach(ndev); +- } +- +- priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_SLEEP_MASK); +- priv->can.state = CAN_STATE_SLEEPING; +- + clk_disable_unprepare(priv->bus_clk); + clk_disable_unprepare(priv->can_clk); + +@@ -1010,7 +1019,6 @@ static int __maybe_unused xcan_runtime_r + struct net_device *ndev = dev_get_drvdata(dev); + struct xcan_priv *priv = netdev_priv(ndev); + int ret; +- u32 isr, status; + + ret = clk_prepare_enable(priv->bus_clk); + if (ret) { +@@ -1024,27 +1032,6 @@ static int __maybe_unused xcan_runtime_r + return ret; + } + +- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK); +- isr = priv->read_reg(priv, XCAN_ISR_OFFSET); +- status = priv->read_reg(priv, XCAN_SR_OFFSET); +- +- if (netif_running(ndev)) { +- if (isr & XCAN_IXR_BSOFF_MASK) { +- priv->can.state = CAN_STATE_BUS_OFF; +- priv->write_reg(priv, XCAN_SRR_OFFSET, +- XCAN_SRR_RESET_MASK); +- } else if ((status & XCAN_SR_ESTAT_MASK) == +- XCAN_SR_ESTAT_MASK) { +- priv->can.state = CAN_STATE_ERROR_PASSIVE; +- } else if (status & XCAN_SR_ERRWRN_MASK) { +- priv->can.state = CAN_STATE_ERROR_WARNING; +- } else { +- priv->can.state = CAN_STATE_ERROR_ACTIVE; +- } +- netif_device_attach(ndev); +- netif_start_queue(ndev); +- } +- + return 0; + } + diff --git a/queue-4.9/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch b/queue-4.9/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch new file mode 100644 index 00000000000..47a960b1f7e --- /dev/null +++ b/queue-4.9/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch @@ -0,0 +1,234 @@ +From 877e0b75947e2c7acf5624331bb17ceb093c98ae Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Wed, 8 Feb 2017 13:13:40 +0200 +Subject: can: xilinx_can: fix recovery from error states not being propagated + +From: Anssi Hannula + +commit 877e0b75947e2c7acf5624331bb17ceb093c98ae upstream. + +The xilinx_can driver contains no mechanism for propagating recovery +from CAN_STATE_ERROR_WARNING and CAN_STATE_ERROR_PASSIVE. + +Add such a mechanism by factoring the handling of +XCAN_STATE_ERROR_PASSIVE and XCAN_STATE_ERROR_WARNING out of +xcan_err_interrupt and checking for recovery after RX and TX if the +interface is in one of those states. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 155 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 127 insertions(+), 28 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -2,6 +2,7 @@ + * + * Copyright (C) 2012 - 2014 Xilinx, Inc. + * Copyright (C) 2009 PetaLogix. All rights reserved. ++ * Copyright (C) 2017 Sandvik Mining and Construction Oy + * + * Description: + * This driver is developed for Axi CAN IP and for Zynq CANPS Controller. +@@ -530,6 +531,123 @@ static int xcan_rx(struct net_device *nd + } + + /** ++ * xcan_current_error_state - Get current error state from HW ++ * @ndev: Pointer to net_device structure ++ * ++ * Checks the current CAN error state from the HW. Note that this ++ * only checks for ERROR_PASSIVE and ERROR_WARNING. ++ * ++ * Return: ++ * ERROR_PASSIVE or ERROR_WARNING if either is active, ERROR_ACTIVE ++ * otherwise. ++ */ ++static enum can_state xcan_current_error_state(struct net_device *ndev) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ u32 status = priv->read_reg(priv, XCAN_SR_OFFSET); ++ ++ if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) ++ return CAN_STATE_ERROR_PASSIVE; ++ else if (status & XCAN_SR_ERRWRN_MASK) ++ return CAN_STATE_ERROR_WARNING; ++ else ++ return CAN_STATE_ERROR_ACTIVE; ++} ++ ++/** ++ * xcan_set_error_state - Set new CAN error state ++ * @ndev: Pointer to net_device structure ++ * @new_state: The new CAN state to be set ++ * @cf: Error frame to be populated or NULL ++ * ++ * Set new CAN error state for the device, updating statistics and ++ * populating the error frame if given. ++ */ ++static void xcan_set_error_state(struct net_device *ndev, ++ enum can_state new_state, ++ struct can_frame *cf) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ u32 ecr = priv->read_reg(priv, XCAN_ECR_OFFSET); ++ u32 txerr = ecr & XCAN_ECR_TEC_MASK; ++ u32 rxerr = (ecr & XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT; ++ ++ priv->can.state = new_state; ++ ++ if (cf) { ++ cf->can_id |= CAN_ERR_CRTL; ++ cf->data[6] = txerr; ++ cf->data[7] = rxerr; ++ } ++ ++ switch (new_state) { ++ case CAN_STATE_ERROR_PASSIVE: ++ priv->can.can_stats.error_passive++; ++ if (cf) ++ cf->data[1] = (rxerr > 127) ? ++ CAN_ERR_CRTL_RX_PASSIVE : ++ CAN_ERR_CRTL_TX_PASSIVE; ++ break; ++ case CAN_STATE_ERROR_WARNING: ++ priv->can.can_stats.error_warning++; ++ if (cf) ++ cf->data[1] |= (txerr > rxerr) ? ++ CAN_ERR_CRTL_TX_WARNING : ++ CAN_ERR_CRTL_RX_WARNING; ++ break; ++ case CAN_STATE_ERROR_ACTIVE: ++ if (cf) ++ cf->data[1] |= CAN_ERR_CRTL_ACTIVE; ++ break; ++ default: ++ /* non-ERROR states are handled elsewhere */ ++ WARN_ON(1); ++ break; ++ } ++} ++ ++/** ++ * xcan_update_error_state_after_rxtx - Update CAN error state after RX/TX ++ * @ndev: Pointer to net_device structure ++ * ++ * If the device is in a ERROR-WARNING or ERROR-PASSIVE state, check if ++ * the performed RX/TX has caused it to drop to a lesser state and set ++ * the interface state accordingly. ++ */ ++static void xcan_update_error_state_after_rxtx(struct net_device *ndev) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ enum can_state old_state = priv->can.state; ++ enum can_state new_state; ++ ++ /* changing error state due to successful frame RX/TX can only ++ * occur from these states ++ */ ++ if (old_state != CAN_STATE_ERROR_WARNING && ++ old_state != CAN_STATE_ERROR_PASSIVE) ++ return; ++ ++ new_state = xcan_current_error_state(ndev); ++ ++ if (new_state != old_state) { ++ struct sk_buff *skb; ++ struct can_frame *cf; ++ ++ skb = alloc_can_err_skb(ndev, &cf); ++ ++ xcan_set_error_state(ndev, new_state, skb ? cf : NULL); ++ ++ if (skb) { ++ struct net_device_stats *stats = &ndev->stats; ++ ++ stats->rx_packets++; ++ stats->rx_bytes += cf->can_dlc; ++ netif_rx(skb); ++ } ++ } ++} ++ ++/** + * xcan_err_interrupt - error frame Isr + * @ndev: net_device pointer + * @isr: interrupt status register value +@@ -544,16 +662,12 @@ static void xcan_err_interrupt(struct ne + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf; + struct sk_buff *skb; +- u32 err_status, status, txerr = 0, rxerr = 0; ++ u32 err_status; + + skb = alloc_can_err_skb(ndev, &cf); + + err_status = priv->read_reg(priv, XCAN_ESR_OFFSET); + priv->write_reg(priv, XCAN_ESR_OFFSET, err_status); +- txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK; +- rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) & +- XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT); +- status = priv->read_reg(priv, XCAN_SR_OFFSET); + + if (isr & XCAN_IXR_BSOFF_MASK) { + priv->can.state = CAN_STATE_BUS_OFF; +@@ -563,28 +677,10 @@ static void xcan_err_interrupt(struct ne + can_bus_off(ndev); + if (skb) + cf->can_id |= CAN_ERR_BUSOFF; +- } else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) { +- priv->can.state = CAN_STATE_ERROR_PASSIVE; +- priv->can.can_stats.error_passive++; +- if (skb) { +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] = (rxerr > 127) ? +- CAN_ERR_CRTL_RX_PASSIVE : +- CAN_ERR_CRTL_TX_PASSIVE; +- cf->data[6] = txerr; +- cf->data[7] = rxerr; +- } +- } else if (status & XCAN_SR_ERRWRN_MASK) { +- priv->can.state = CAN_STATE_ERROR_WARNING; +- priv->can.can_stats.error_warning++; +- if (skb) { +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] |= (txerr > rxerr) ? +- CAN_ERR_CRTL_TX_WARNING : +- CAN_ERR_CRTL_RX_WARNING; +- cf->data[6] = txerr; +- cf->data[7] = rxerr; +- } ++ } else { ++ enum can_state new_state = xcan_current_error_state(ndev); ++ ++ xcan_set_error_state(ndev, new_state, skb ? cf : NULL); + } + + /* Check for Arbitration lost interrupt */ +@@ -714,8 +810,10 @@ static int xcan_rx_poll(struct napi_stru + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } + +- if (work_done) ++ if (work_done) { + can_led_event(ndev, CAN_LED_EVENT_RX); ++ xcan_update_error_state_after_rxtx(ndev); ++ } + + if (work_done < quota) { + napi_complete(napi); +@@ -746,6 +844,7 @@ static void xcan_tx_interrupt(struct net + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } + can_led_event(ndev, CAN_LED_EVENT_TX); ++ xcan_update_error_state_after_rxtx(ndev); + netif_wake_queue(ndev); + } + diff --git a/queue-4.9/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch b/queue-4.9/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch new file mode 100644 index 00000000000..127d78a89e5 --- /dev/null +++ b/queue-4.9/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch @@ -0,0 +1,98 @@ +From 32852c561bffd613d4ed7ec464b1e03e1b7b6c5c Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Tue, 7 Feb 2017 17:01:14 +0200 +Subject: can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK + +From: Anssi Hannula + +commit 32852c561bffd613d4ed7ec464b1e03e1b7b6c5c upstream. + +If the device gets into a state where RXNEMP (RX FIFO not empty) +interrupt is asserted without RXOK (new frame received successfully) +interrupt being asserted, xcan_rx_poll() will continue to try to clear +RXNEMP without actually reading frames from RX FIFO. If the RX FIFO is +not empty, the interrupt will not be cleared and napi_schedule() will +just be called again. + +This situation can occur when: + +(a) xcan_rx() returns without reading RX FIFO due to an error condition. +The code tries to clear both RXOK and RXNEMP but RXNEMP will not clear +due to a frame still being in the FIFO. The frame will never be read +from the FIFO as RXOK is no longer set. + +(b) A frame is received between xcan_rx_poll() reading interrupt status +and clearing RXOK. RXOK will be cleared, but RXNEMP will again remain +set as the new message is still in the FIFO. + +I'm able to trigger case (b) by flooding the bus with frames under load. + +There does not seem to be any benefit in using both RXNEMP and RXOK in +the way the driver does, and the polling example in the reference manual +(UG585 v1.10 18.3.7 Read Messages from RxFIFO) also says that either +RXOK or RXNEMP can be used for detecting incoming messages. + +Fix the issue and simplify the RX processing by only using RXNEMP +without RXOK. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -101,7 +101,7 @@ enum xcan_reg { + #define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\ + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \ + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \ +- XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK) ++ XCAN_IXR_ARBLST_MASK) + + /* CAN register bit shift - XCAN___SHIFT */ + #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ +@@ -709,15 +709,7 @@ static int xcan_rx_poll(struct napi_stru + + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) { +- if (isr & XCAN_IXR_RXOK_MASK) { +- priv->write_reg(priv, XCAN_ICR_OFFSET, +- XCAN_IXR_RXOK_MASK); +- work_done += xcan_rx(ndev); +- } else { +- priv->write_reg(priv, XCAN_ICR_OFFSET, +- XCAN_IXR_RXNEMP_MASK); +- break; +- } ++ work_done += xcan_rx(ndev); + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK); + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } +@@ -728,7 +720,7 @@ static int xcan_rx_poll(struct napi_stru + if (work_done < quota) { + napi_complete(napi); + ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK); ++ ier |= XCAN_IXR_RXNEMP_MASK; + priv->write_reg(priv, XCAN_IER_OFFSET, ier); + } + return work_done; +@@ -800,9 +792,9 @@ static irqreturn_t xcan_interrupt(int ir + } + + /* Check for the type of receive interrupt and Processing it */ +- if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) { ++ if (isr & XCAN_IXR_RXNEMP_MASK) { + ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK); ++ ier &= ~XCAN_IXR_RXNEMP_MASK; + priv->write_reg(priv, XCAN_IER_OFFSET, ier); + napi_schedule(&priv->napi); + } diff --git a/queue-4.9/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch b/queue-4.9/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch new file mode 100644 index 00000000000..078010ad134 --- /dev/null +++ b/queue-4.9/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch @@ -0,0 +1,37 @@ +From 83997997252f5d3fc7f04abc24a89600c2b504ab Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 26 Feb 2018 14:27:13 +0200 +Subject: can: xilinx_can: fix RX overflow interrupt not being enabled + +From: Anssi Hannula + +commit 83997997252f5d3fc7f04abc24a89600c2b504ab upstream. + +RX overflow interrupt (RXOFLW) is disabled even though xcan_interrupt() +processes it. This means that an RX overflow interrupt will only be +processed when another interrupt gets asserted (e.g. for RX/TX). + +Fix that by enabling the RXOFLW interrupt. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: Michal Simek +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -104,7 +104,7 @@ enum xcan_reg { + #define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\ + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \ + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \ +- XCAN_IXR_ARBLST_MASK) ++ XCAN_IXR_RXOFLW_MASK | XCAN_IXR_ARBLST_MASK) + + /* CAN register bit shift - XCAN___SHIFT */ + #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ diff --git a/queue-4.9/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch b/queue-4.9/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch new file mode 100644 index 00000000000..423dbece3b3 --- /dev/null +++ b/queue-4.9/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch @@ -0,0 +1,335 @@ +From 620050d9c2be15c47017ba95efe59e0832e99a56 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 23 Feb 2017 14:50:03 +0200 +Subject: can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting + +From: Anssi Hannula + +commit 620050d9c2be15c47017ba95efe59e0832e99a56 upstream. + +The xilinx_can driver assumes that the TXOK interrupt only clears after +it has been acknowledged as many times as there have been successfully +sent frames. + +However, the documentation does not mention such behavior, instead +saying just that the interrupt is cleared when the clear bit is set. + +Similarly, testing seems to also suggest that it is immediately cleared +regardless of the amount of frames having been sent. Performing some +heavy TX load and then going back to idle has the tx_head drifting +further away from tx_tail over time, steadily reducing the amount of +frames the driver keeps in the TX FIFO (but not to zero, as the TXOK +interrupt always frees up space for 1 frame from the driver's +perspective, so frames continue to be sent) and delaying the local echo +frames. + +The TX FIFO tracking is also otherwise buggy as it does not account for +TX FIFO being cleared after software resets, causing + BUG!, TX FIFO full when queue awake! +messages to be output. + +There does not seem to be any way to accurately track the state of the +TX FIFO for local echo support while using the full TX FIFO. + +The Zynq version of the HW (but not the soft-AXI version) has watermark +programming support and with it an additional TX-FIFO-empty interrupt +bit. + +Modify the driver to only put 1 frame into TX FIFO at a time on soft-AXI +and 2 frames at a time on Zynq. On Zynq the TXFEMP interrupt bit is used +to detect whether 1 or 2 frames have been sent at interrupt processing +time. + +Tested with the integrated CAN on Zynq-7000 SoC. The 1-frame-FIFO mode +was also tested. + +An alternative way to solve this would be to drop local echo support but +keep using the full TX FIFO. + +v2: Add FIFO space check before TX queue wake with locking to +synchronize with queue stop. This avoids waking the queue when xmit() +had just filled it. + +v3: Keep local echo support and reduce the amount of frames in FIFO +instead as suggested by Marc Kleine-Budde. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 139 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 123 insertions(+), 16 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -26,8 +26,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -119,6 +121,7 @@ enum xcan_reg { + /** + * struct xcan_priv - This definition define CAN driver instance + * @can: CAN private data structure. ++ * @tx_lock: Lock for synchronizing TX interrupt handling + * @tx_head: Tx CAN packets ready to send on the queue + * @tx_tail: Tx CAN packets successfully sended on the queue + * @tx_max: Maximum number packets the driver can send +@@ -133,6 +136,7 @@ enum xcan_reg { + */ + struct xcan_priv { + struct can_priv can; ++ spinlock_t tx_lock; + unsigned int tx_head; + unsigned int tx_tail; + unsigned int tx_max; +@@ -160,6 +164,11 @@ static const struct can_bittiming_const + .brp_inc = 1, + }; + ++#define XCAN_CAP_WATERMARK 0x0001 ++struct xcan_devtype_data { ++ unsigned int caps; ++}; ++ + /** + * xcan_write_reg_le - Write a value to the device register little endian + * @priv: Driver private data structure +@@ -239,6 +248,10 @@ static int set_reset_mode(struct net_dev + usleep_range(500, 10000); + } + ++ /* reset clears FIFOs */ ++ priv->tx_head = 0; ++ priv->tx_tail = 0; ++ + return 0; + } + +@@ -393,6 +406,7 @@ static int xcan_start_xmit(struct sk_buf + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf = (struct can_frame *)skb->data; + u32 id, dlc, data[2] = {0, 0}; ++ unsigned long flags; + + if (can_dropped_invalid_skb(ndev, skb)) + return NETDEV_TX_OK; +@@ -440,6 +454,9 @@ static int xcan_start_xmit(struct sk_buf + data[1] = be32_to_cpup((__be32 *)(cf->data + 4)); + + can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max); ++ ++ spin_lock_irqsave(&priv->tx_lock, flags); ++ + priv->tx_head++; + + /* Write the Frame to Xilinx CAN TX FIFO */ +@@ -455,10 +472,16 @@ static int xcan_start_xmit(struct sk_buf + stats->tx_bytes += cf->can_dlc; + } + ++ /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */ ++ if (priv->tx_max > 1) ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK); ++ + /* Check if the TX buffer is full */ + if ((priv->tx_head - priv->tx_tail) == priv->tx_max) + netif_stop_queue(ndev); + ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ + return NETDEV_TX_OK; + } + +@@ -832,19 +855,71 @@ static void xcan_tx_interrupt(struct net + { + struct xcan_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; ++ unsigned int frames_in_fifo; ++ int frames_sent = 1; /* TXOK => at least 1 frame was sent */ ++ unsigned long flags; ++ int retries = 0; ++ ++ /* Synchronize with xmit as we need to know the exact number ++ * of frames in the FIFO to stay in sync due to the TXFEMP ++ * handling. ++ * This also prevents a race between netif_wake_queue() and ++ * netif_stop_queue(). ++ */ ++ spin_lock_irqsave(&priv->tx_lock, flags); ++ ++ frames_in_fifo = priv->tx_head - priv->tx_tail; ++ ++ if (WARN_ON_ONCE(frames_in_fifo == 0)) { ++ /* clear TXOK anyway to avoid getting back here */ ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ return; ++ } ++ ++ /* Check if 2 frames were sent (TXOK only means that at least 1 ++ * frame was sent). ++ */ ++ if (frames_in_fifo > 1) { ++ WARN_ON(frames_in_fifo > priv->tx_max); ++ ++ /* Synchronize TXOK and isr so that after the loop: ++ * (1) isr variable is up-to-date at least up to TXOK clear ++ * time. This avoids us clearing a TXOK of a second frame ++ * but not noticing that the FIFO is now empty and thus ++ * marking only a single frame as sent. ++ * (2) No TXOK is left. Having one could mean leaving a ++ * stray TXOK as we might process the associated frame ++ * via TXFEMP handling as we read TXFEMP *after* TXOK ++ * clear to satisfy (1). ++ */ ++ while ((isr & XCAN_IXR_TXOK_MASK) && !WARN_ON(++retries == 100)) { ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ isr = priv->read_reg(priv, XCAN_ISR_OFFSET); ++ } + +- while ((priv->tx_head - priv->tx_tail > 0) && +- (isr & XCAN_IXR_TXOK_MASK)) { ++ if (isr & XCAN_IXR_TXFEMP_MASK) { ++ /* nothing in FIFO anymore */ ++ frames_sent = frames_in_fifo; ++ } ++ } else { ++ /* single frame in fifo, just clear TXOK */ + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ } ++ ++ while (frames_sent--) { + can_get_echo_skb(ndev, priv->tx_tail % + priv->tx_max); + priv->tx_tail++; + stats->tx_packets++; +- isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } ++ ++ netif_wake_queue(ndev); ++ ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ + can_led_event(ndev, CAN_LED_EVENT_TX); + xcan_update_error_state_after_rxtx(ndev); +- netif_wake_queue(ndev); + } + + /** +@@ -1138,6 +1213,18 @@ static const struct dev_pm_ops xcan_dev_ + SET_RUNTIME_PM_OPS(xcan_runtime_suspend, xcan_runtime_resume, NULL) + }; + ++static const struct xcan_devtype_data xcan_zynq_data = { ++ .caps = XCAN_CAP_WATERMARK, ++}; ++ ++/* Match table for OF platform binding */ ++static const struct of_device_id xcan_of_match[] = { ++ { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data }, ++ { .compatible = "xlnx,axi-can-1.00.a", }, ++ { /* end of list */ }, ++}; ++MODULE_DEVICE_TABLE(of, xcan_of_match); ++ + /** + * xcan_probe - Platform registration call + * @pdev: Handle to the platform device structure +@@ -1152,8 +1239,10 @@ static int xcan_probe(struct platform_de + struct resource *res; /* IO mem resources */ + struct net_device *ndev; + struct xcan_priv *priv; ++ const struct of_device_id *of_id; ++ int caps = 0; + void __iomem *addr; +- int ret, rx_max, tx_max; ++ int ret, rx_max, tx_max, tx_fifo_depth; + + /* Get the virtual base address for the device */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -1163,7 +1252,8 @@ static int xcan_probe(struct platform_de + goto err; + } + +- ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", &tx_max); ++ ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", ++ &tx_fifo_depth); + if (ret < 0) + goto err; + +@@ -1171,6 +1261,30 @@ static int xcan_probe(struct platform_de + if (ret < 0) + goto err; + ++ of_id = of_match_device(xcan_of_match, &pdev->dev); ++ if (of_id) { ++ const struct xcan_devtype_data *devtype_data = of_id->data; ++ ++ if (devtype_data) ++ caps = devtype_data->caps; ++ } ++ ++ /* There is no way to directly figure out how many frames have been ++ * sent when the TXOK interrupt is processed. If watermark programming ++ * is supported, we can have 2 frames in the FIFO and use TXFEMP ++ * to determine if 1 or 2 frames have been sent. ++ * Theoretically we should be able to use TXFWMEMP to determine up ++ * to 3 frames, but it seems that after putting a second frame in the ++ * FIFO, with watermark at 2 frames, it can happen that TXFWMEMP (less ++ * than 2 frames in FIFO) is set anyway with no TXOK (a frame was ++ * sent), which is not a sensible state - possibly TXFWMEMP is not ++ * completely synchronized with the rest of the bits? ++ */ ++ if (caps & XCAN_CAP_WATERMARK) ++ tx_max = min(tx_fifo_depth, 2); ++ else ++ tx_max = 1; ++ + /* Create a CAN device instance */ + ndev = alloc_candev(sizeof(struct xcan_priv), tx_max); + if (!ndev) +@@ -1185,6 +1299,7 @@ static int xcan_probe(struct platform_de + CAN_CTRLMODE_BERR_REPORTING; + priv->reg_base = addr; + priv->tx_max = tx_max; ++ spin_lock_init(&priv->tx_lock); + + /* Get IRQ for the device */ + ndev->irq = platform_get_irq(pdev, 0); +@@ -1249,9 +1364,9 @@ static int xcan_probe(struct platform_de + + pm_runtime_put(&pdev->dev); + +- netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n", ++ netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth: actual %d, using %d\n", + priv->reg_base, ndev->irq, priv->can.clock.freq, +- priv->tx_max); ++ tx_fifo_depth, priv->tx_max); + + return 0; + +@@ -1285,14 +1400,6 @@ static int xcan_remove(struct platform_d + return 0; + } + +-/* Match table for OF platform binding */ +-static const struct of_device_id xcan_of_match[] = { +- { .compatible = "xlnx,zynq-can-1.0", }, +- { .compatible = "xlnx,axi-can-1.00.a", }, +- { /* end of list */ }, +-}; +-MODULE_DEVICE_TABLE(of, xcan_of_match); +- + static struct platform_driver xcan_driver = { + .probe = xcan_probe, + .remove = xcan_remove, diff --git a/queue-4.9/driver-core-partially-revert-driver-core-correct-device-s-shutdown-order.patch b/queue-4.9/driver-core-partially-revert-driver-core-correct-device-s-shutdown-order.patch new file mode 100644 index 00000000000..3752df0f61c --- /dev/null +++ b/queue-4.9/driver-core-partially-revert-driver-core-correct-device-s-shutdown-order.patch @@ -0,0 +1,70 @@ +From 722e5f2b1eec7de61117b7c0a7914761e3da2eda Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Tue, 10 Jul 2018 14:51:33 +0200 +Subject: driver core: Partially revert "driver core: correct device's shutdown order" + +From: Rafael J. Wysocki + +commit 722e5f2b1eec7de61117b7c0a7914761e3da2eda upstream. + +Commit 52cdbdd49853 (driver core: correct device's shutdown order) +introduced a regression by breaking device shutdown on some systems. + +Namely, the devices_kset_move_last() call in really_probe() added by +that commit is a mistake as it may cause parents to follow children +in the devices_kset list which then causes shutdown to fail. For +example, if a device has children before really_probe() is called +for it (which is not uncommon), that call will cause it to be +reordered after the children in the devices_kset list and the +ordering of that list will not reflect the correct device shutdown +order any more. + +Also it causes the devices_kset list to be constantly reordered +until all drivers have been probed which is totally pointless +overhead in the majority of cases and it only covered an issue +with system shutdown, while system-wide suspend/resume potentially +had the same issue on the affected platforms (which was not covered). + +Moreover, the shutdown issue originally addressed by the change in +really_probe() made by commit 52cdbdd49853 is not present in 4.18-rc +any more, since dra7 started to use the sdhci-omap driver which +doesn't disable any regulators during shutdown, so the really_probe() +part of commit 52cdbdd49853 can be safely reverted. [The original +issue was related to the omap_hsmmc driver used by dra7 previously.] + +For the above reasons, revert the really_probe() modifications made +by commit 52cdbdd49853. + +The other code changes made by commit 52cdbdd49853 are useful and +they need not be reverted. + +Fixes: 52cdbdd49853 (driver core: correct device's shutdown order) +Link: https://lore.kernel.org/lkml/CAFgQCTt7VfqM=UyCnvNFxrSw8Z6cUtAi3HUwR4_xPAc03SgHjQ@mail.gmail.com/ +Reported-by: Pingfan Liu +Tested-by: Pingfan Liu +Reviewed-by: Kishon Vijay Abraham I +Signed-off-by: Rafael J. Wysocki +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/dd.c | 8 -------- + 1 file changed, 8 deletions(-) + +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -363,14 +363,6 @@ re_probe: + goto probe_failed; + } + +- /* +- * Ensure devices are listed in devices_kset in correct order +- * It's important to move Dev to the end of devices_kset before +- * calling .probe, because it could be recursive and parent Dev +- * should always go first +- */ +- devices_kset_move_last(dev); +- + if (dev->bus->probe) { + ret = dev->bus->probe(dev); + if (ret) diff --git a/queue-4.9/exec-avoid-gcc-8-warning-for-get_task_comm.patch b/queue-4.9/exec-avoid-gcc-8-warning-for-get_task_comm.patch new file mode 100644 index 00000000000..7ae72255aab --- /dev/null +++ b/queue-4.9/exec-avoid-gcc-8-warning-for-get_task_comm.patch @@ -0,0 +1,84 @@ +From 3756f6401c302617c5e091081ca4d26ab604bec5 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 14 Dec 2017 15:32:41 -0800 +Subject: exec: avoid gcc-8 warning for get_task_comm + +From: Arnd Bergmann + +commit 3756f6401c302617c5e091081ca4d26ab604bec5 upstream. + +gcc-8 warns about using strncpy() with the source size as the limit: + + fs/exec.c:1223:32: error: argument to 'sizeof' in 'strncpy' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess] + +This is indeed slightly suspicious, as it protects us from source +arguments without NUL-termination, but does not guarantee that the +destination is terminated. + +This keeps the strncpy() to ensure we have properly padded target +buffer, but ensures that we use the correct length, by passing the +actual length of the destination buffer as well as adding a build-time +check to ensure it is exactly TASK_COMM_LEN. + +There are only 23 callsites which I all reviewed to ensure this is +currently the case. We could get away with doing only the check or +passing the right length, but it doesn't hurt to do both. + +Link: http://lkml.kernel.org/r/20171205151724.1764896-1-arnd@arndb.de +Signed-off-by: Arnd Bergmann +Suggested-by: Kees Cook +Acked-by: Kees Cook +Acked-by: Ingo Molnar +Cc: Alexander Viro +Cc: Peter Zijlstra +Cc: Serge Hallyn +Cc: James Morris +Cc: Aleksa Sarai +Cc: "Eric W. Biederman" +Cc: Frederic Weisbecker +Cc: Thomas Gleixner +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exec.c | 7 +++---- + include/linux/sched.h | 6 +++++- + 2 files changed, 8 insertions(+), 5 deletions(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1228,15 +1228,14 @@ killed: + return -EAGAIN; + } + +-char *get_task_comm(char *buf, struct task_struct *tsk) ++char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk) + { +- /* buf must be at least sizeof(tsk->comm) in size */ + task_lock(tsk); +- strncpy(buf, tsk->comm, sizeof(tsk->comm)); ++ strncpy(buf, tsk->comm, buf_size); + task_unlock(tsk); + return buf; + } +-EXPORT_SYMBOL_GPL(get_task_comm); ++EXPORT_SYMBOL_GPL(__get_task_comm); + + /* + * These functions flushes out all traces of the currently running executable +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -2999,7 +2999,11 @@ static inline void set_task_comm(struct + { + __set_task_comm(tsk, from, false); + } +-extern char *get_task_comm(char *to, struct task_struct *tsk); ++extern char *__get_task_comm(char *to, size_t len, struct task_struct *tsk); ++#define get_task_comm(buf, tsk) ({ \ ++ BUILD_BUG_ON(sizeof(buf) != TASK_COMM_LEN); \ ++ __get_task_comm(buf, sizeof(buf), tsk); \ ++}) + + #ifdef CONFIG_SMP + void scheduler_ipi(void); diff --git a/queue-4.9/series b/queue-4.9/series index 566d3280879..78610fa1edc 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -18,3 +18,16 @@ tcp-free-batches-of-packets-in-tcp_prune_ofo_queue.patch tcp-avoid-collapses-in-tcp_prune_queue-if-possible.patch tcp-detect-malicious-patterns-in-tcp_collapse_ofo_queue.patch tcp-call-tcp_drop-from-tcp_data_queue_ofo.patch +usb-cdc_acm-add-quirk-for-castles-vega3000.patch +usb-core-handle-hub-c_port_over_current-condition.patch +usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch +driver-core-partially-revert-driver-core-correct-device-s-shutdown-order.patch +can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch +can-xilinx_can-fix-power-management-handling.patch +can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch +can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch +can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch +can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch +can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch +turn-off-wattribute-alias.patch +exec-avoid-gcc-8-warning-for-get_task_comm.patch diff --git a/queue-4.9/turn-off-wattribute-alias.patch b/queue-4.9/turn-off-wattribute-alias.patch new file mode 100644 index 00000000000..4345a4ddf51 --- /dev/null +++ b/queue-4.9/turn-off-wattribute-alias.patch @@ -0,0 +1,62 @@ +From arnd@arndb.de Fri Jul 27 11:18:04 2018 +From: Arnd Bergmann +Date: Thu, 26 Jul 2018 10:13:22 +0200 +Subject: turn off -Wattribute-alias +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, Arnd Bergmann , Michal Marek , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org +Message-ID: <20180726081358.3829157-1-arnd@arndb.de> + +From: Arnd Bergmann + +Starting with gcc-8.1, we get a warning about all system call definitions, +which use an alias between functions with incompatible prototypes, e.g.: + +In file included from ../mm/process_vm_access.c:19: +../include/linux/syscalls.h:211:18: warning: 'sys_process_vm_readv' alias between functions of incompatible types 'long int(pid_t, const struct iovec *, long unsigned int, const struct iovec *, long unsigned int, long unsigned int)' {aka 'long int(int, const struct iovec *, long unsigned int, const struct iovec *, long unsigned int, long unsigned int)'} and 'long int(long int, long int, long int, long int, long int, long int)' [-Wattribute-alias] + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + ^~~ +../include/linux/syscalls.h:207:2: note: in expansion of macro '__SYSCALL_DEFINEx' + __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) + ^~~~~~~~~~~~~~~~~ +../include/linux/syscalls.h:201:36: note: in expansion of macro 'SYSCALL_DEFINEx' + #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) + ^~~~~~~~~~~~~~~ +../mm/process_vm_access.c:300:1: note: in expansion of macro 'SYSCALL_DEFINE6' + SYSCALL_DEFINE6(process_vm_readv, pid_t, pid, const struct iovec __user *, lvec, + ^~~~~~~~~~~~~~~ +../include/linux/syscalls.h:215:18: note: aliased declaration here + asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + ^~~ +../include/linux/syscalls.h:207:2: note: in expansion of macro '__SYSCALL_DEFINEx' + __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) + ^~~~~~~~~~~~~~~~~ +../include/linux/syscalls.h:201:36: note: in expansion of macro 'SYSCALL_DEFINEx' + #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) + ^~~~~~~~~~~~~~~ +../mm/process_vm_access.c:300:1: note: in expansion of macro 'SYSCALL_DEFINE6' + SYSCALL_DEFINE6(process_vm_readv, pid_t, pid, const struct iovec __user *, lvec, + +This is really noisy and does not indicate a real problem. In the latest +mainline kernel, this was addressed by commit bee20031772a ("disable +-Wattribute-alias warning for SYSCALL_DEFINEx()"), which seems too invasive +to backport. + +This takes a much simpler approach and just disables the warning across the +kernel. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 1 + + 1 file changed, 1 insertion(+) + +--- a/Makefile ++++ b/Makefile +@@ -635,6 +635,7 @@ KBUILD_CFLAGS += $(call cc-disable-warni + KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) + KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow) + KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context) ++KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias) + + ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION + KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,) diff --git a/queue-4.9/usb-cdc_acm-add-quirk-for-castles-vega3000.patch b/queue-4.9/usb-cdc_acm-add-quirk-for-castles-vega3000.patch new file mode 100644 index 00000000000..d3b033c6209 --- /dev/null +++ b/queue-4.9/usb-cdc_acm-add-quirk-for-castles-vega3000.patch @@ -0,0 +1,33 @@ +From 1445cbe476fc3dd09c0b380b206526a49403c071 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Tue, 10 Jul 2018 08:28:49 +0200 +Subject: usb: cdc_acm: Add quirk for Castles VEGA3000 + +From: Lubomir Rintel + +commit 1445cbe476fc3dd09c0b380b206526a49403c071 upstream. + +The device (a POS terminal) implements CDC ACM, but has not union +descriptor. + +Signed-off-by: Lubomir Rintel +Acked-by: Oliver Neukum +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1785,6 +1785,9 @@ static const struct usb_device_id acm_id + { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ + .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ + }, ++ { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */ ++ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ ++ }, + + { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ + .driver_info = CLEAR_HALT_CONDITIONS, diff --git a/queue-4.9/usb-core-handle-hub-c_port_over_current-condition.patch b/queue-4.9/usb-core-handle-hub-c_port_over_current-condition.patch new file mode 100644 index 00000000000..5153b406168 --- /dev/null +++ b/queue-4.9/usb-core-handle-hub-c_port_over_current-condition.patch @@ -0,0 +1,49 @@ +From 249a32b7eeb3edb6897dd38f89651a62163ac4ed Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Thu, 19 Jul 2018 14:39:37 -0500 +Subject: usb: core: handle hub C_PORT_OVER_CURRENT condition + +From: Bin Liu + +commit 249a32b7eeb3edb6897dd38f89651a62163ac4ed upstream. + +Based on USB2.0 Spec Section 11.12.5, + + "If a hub has per-port power switching and per-port current limiting, + an over-current on one port may still cause the power on another port + to fall below specific minimums. In this case, the affected port is + placed in the Power-Off state and C_PORT_OVER_CURRENT is set for the + port, but PORT_OVER_CURRENT is not set." + +so let's check C_PORT_OVER_CURRENT too for over current condition. + +Fixes: 08d1dec6f405 ("usb:hub set hub->change_bits when over-current happens") +Cc: +Tested-by: Alessandro Antenucci +Signed-off-by: Bin Liu +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1139,10 +1139,14 @@ static void hub_activate(struct usb_hub + + if (!udev || udev->state == USB_STATE_NOTATTACHED) { + /* Tell hub_wq to disconnect the device or +- * check for a new connection ++ * check for a new connection or over current condition. ++ * Based on USB2.0 Spec Section 11.12.5, ++ * C_PORT_OVER_CURRENT could be set while ++ * PORT_OVER_CURRENT is not. So check for any of them. + */ + if (udev || (portstatus & USB_PORT_STAT_CONNECTION) || +- (portstatus & USB_PORT_STAT_OVERCURRENT)) ++ (portstatus & USB_PORT_STAT_OVERCURRENT) || ++ (portchange & USB_PORT_STAT_C_OVERCURRENT)) + set_bit(port1, hub->change_bits); + + } else if (portstatus & USB_PORT_STAT_ENABLE) { diff --git a/queue-4.9/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch b/queue-4.9/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch new file mode 100644 index 00000000000..63b96014d9b --- /dev/null +++ b/queue-4.9/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch @@ -0,0 +1,54 @@ +From 4d644abf25698362bd33d17c9ddc8f7122c30f17 Mon Sep 17 00:00:00 2001 +From: Jerry Zhang +Date: Mon, 2 Jul 2018 12:48:08 -0700 +Subject: usb: gadget: f_fs: Only return delayed status when len is 0 + +From: Jerry Zhang + +commit 4d644abf25698362bd33d17c9ddc8f7122c30f17 upstream. + +Commit 1b9ba000 ("Allow function drivers to pause control +transfers") states that USB_GADGET_DELAYED_STATUS is only +supported if data phase is 0 bytes. + +It seems that when the length is not 0 bytes, there is no +need to explicitly delay the data stage since the transfer +is not completed until the user responds. However, when the +length is 0, there is no data stage and the transfer is +finished once setup() returns, hence there is a need to +explicitly delay completion. + +This manifests as the following bugs: + +Prior to 946ef68ad4e4 ('Let setup() return +USB_GADGET_DELAYED_STATUS'), when setup is 0 bytes, ffs +would require user to queue a 0 byte request in order to +clear setup state. However, that 0 byte request was actually +not needed and would hang and cause errors in other setup +requests. + +After the above commit, 0 byte setups work since the gadget +now accepts empty queues to ep0 to clear the delay, but all +other setups hang. + +Fixes: 946ef68ad4e4 ("Let setup() return USB_GADGET_DELAYED_STATUS") +Signed-off-by: Jerry Zhang +Cc: stable +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -3243,7 +3243,7 @@ static int ffs_func_setup(struct usb_fun + __ffs_event_add(ffs, FUNCTIONFS_SETUP); + spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); + +- return USB_GADGET_DELAYED_STATUS; ++ return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0; + } + + static bool ffs_func_req_match(struct usb_function *f, -- 2.47.3