From: Greg Kroah-Hartman Date: Fri, 17 Apr 2015 12:26:20 +0000 (+0200) Subject: 3.19-stable patches X-Git-Tag: v3.10.75~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a882f22961c920ef32d5e4734223efd050a51e6f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.19-stable patches added patches: ath9k-fix-tracking-of-enabled-ap-beacons.patch can-flexcan-deferred-on-regulator-return-eprobe_defer.patch can-flexcan-fix-bus-off-error-state-handling.patch cpuidle-acpi-do-not-overwrite-name-and-description-of-c0.patch cpuidle-remove-state_count-field-from-struct-cpuidle_device.patch dmaengine-edma-fix-memory-leak-when-terminating-running-transfers.patch dmaengine-omap-dma-fix-memory-leak-when-terminating-running-transfer.patch firmware-dmi_scan-prevent-dmi_num-integer-overflow.patch iio-adc-vf610-use-adc-clock-within-specification.patch iio-bmc150-change-sampling-frequency.patch iio-core-fix-double-free.patch iio-imu-use-iio_trigger_get-for-indio_dev-trig-assignment.patch iio-inv_mpu6050-clear-timestamps-fifo-while-resetting-hardware-fifo.patch usb-xhci-apply-xhci_avoid_bei-quirk-to-all-intel-xhci-controllers.patch usb-xhci-handle-config-error-change-cec-in-xhci-driver.patch x86-reboot-add-asrock-q1900dc-itx-mainboard-reboot-quirk.patch --- diff --git a/queue-3.19/ath9k-fix-tracking-of-enabled-ap-beacons.patch b/queue-3.19/ath9k-fix-tracking-of-enabled-ap-beacons.patch new file mode 100644 index 00000000000..1c6d2b81e2f --- /dev/null +++ b/queue-3.19/ath9k-fix-tracking-of-enabled-ap-beacons.patch @@ -0,0 +1,86 @@ +From 1cf48f22c98ae24a49a3f1b6900e4c9a9a0fcc62 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 12 Mar 2015 17:17:18 +0100 +Subject: ath9k: fix tracking of enabled AP beacons + +From: Felix Fietkau + +commit 1cf48f22c98ae24a49a3f1b6900e4c9a9a0fcc62 upstream. + +sc->nbcnvifs tracks assigned beacon slots, not enabled beacons. +Therefore, it cannot be used to decide if cur_conf->enable_beacon (bool) +should be updated, or if beacons have been enabled already. +With the current code (depending on the order of calls), beacons often +do not get enabled in an AP+STA setup. +To fix tracking of enabled beacons, convert cur_conf->enable_beacon to a +bitmask of enabled beacon slots. + +Signed-off-by: Felix Fietkau +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/beacon.c | 20 ++++++++++++-------- + drivers/net/wireless/ath/ath9k/common.h | 2 +- + 2 files changed, 13 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/beacon.c ++++ b/drivers/net/wireless/ath/ath9k/beacon.c +@@ -219,12 +219,15 @@ void ath9k_beacon_remove_slot(struct ath + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_vif *avp = (void *)vif->drv_priv; + struct ath_buf *bf = avp->av_bcbuf; ++ struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon; + + ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", + avp->av_bslot); + + tasklet_disable(&sc->bcon_tasklet); + ++ cur_conf->enable_beacon &= ~BIT(avp->av_bslot); ++ + if (bf && bf->bf_mpdu) { + struct sk_buff *skb = bf->bf_mpdu; + dma_unmap_single(sc->dev, bf->bf_buf_addr, +@@ -521,8 +524,7 @@ static bool ath9k_allow_beacon_config(st + } + + if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { +- if ((vif->type != NL80211_IFTYPE_AP) || +- (sc->nbcnvifs > 1)) { ++ if (vif->type != NL80211_IFTYPE_AP) { + ath_dbg(common, CONFIG, + "An AP interface is already present !\n"); + return false; +@@ -616,12 +618,14 @@ void ath9k_beacon_config(struct ath_soft + * enabling/disabling SWBA. + */ + if (changed & BSS_CHANGED_BEACON_ENABLED) { +- if (!bss_conf->enable_beacon && +- (sc->nbcnvifs <= 1)) { +- cur_conf->enable_beacon = false; +- } else if (bss_conf->enable_beacon) { +- cur_conf->enable_beacon = true; +- ath9k_cache_beacon_config(sc, ctx, bss_conf); ++ bool enabled = cur_conf->enable_beacon; ++ ++ if (!bss_conf->enable_beacon) { ++ cur_conf->enable_beacon &= ~BIT(avp->av_bslot); ++ } else { ++ cur_conf->enable_beacon |= BIT(avp->av_bslot); ++ if (!enabled) ++ ath9k_cache_beacon_config(sc, ctx, bss_conf); + } + } + +--- a/drivers/net/wireless/ath/ath9k/common.h ++++ b/drivers/net/wireless/ath/ath9k/common.h +@@ -54,7 +54,7 @@ struct ath_beacon_config { + u16 dtim_period; + u16 bmiss_timeout; + u8 dtim_count; +- bool enable_beacon; ++ u8 enable_beacon; + bool ibss_creator; + u32 nexttbtt; + u32 intval; diff --git a/queue-3.19/can-flexcan-deferred-on-regulator-return-eprobe_defer.patch b/queue-3.19/can-flexcan-deferred-on-regulator-return-eprobe_defer.patch new file mode 100644 index 00000000000..77c25a1b494 --- /dev/null +++ b/queue-3.19/can-flexcan-deferred-on-regulator-return-eprobe_defer.patch @@ -0,0 +1,62 @@ +From 555828ef45f825d6ee06559f0304163550eed380 Mon Sep 17 00:00:00 2001 +From: Andreas Werner +Date: Sun, 22 Mar 2015 17:35:52 +0100 +Subject: can: flexcan: Deferred on Regulator return EPROBE_DEFER + +From: Andreas Werner + +commit 555828ef45f825d6ee06559f0304163550eed380 upstream. + +Return EPROBE_DEFER if Regulator returns EPROBE_DEFER + +If the Flexcan driver is built into kernel and a regulator is used to +enable the CAN transceiver, the Flexcan driver may not use the regulator. + +When initializing the Flexcan device with a regulator defined in the device +tree, but not initialized, the regulator subsystem returns EPROBE_DEFER, hence +the Flexcan init fails. + +The solution for this is to return EPROBE_DEFER if regulator is not initialized +and wait until the regulator is initialized. + +Signed-off-by: Andreas Werner +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/flexcan.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -1158,12 +1158,19 @@ static int flexcan_probe(struct platform + const struct flexcan_devtype_data *devtype_data; + struct net_device *dev; + struct flexcan_priv *priv; ++ struct regulator *reg_xceiver; + struct resource *mem; + struct clk *clk_ipg = NULL, *clk_per = NULL; + void __iomem *base; + int err, irq; + u32 clock_freq = 0; + ++ reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); ++ if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ else if (IS_ERR(reg_xceiver)) ++ reg_xceiver = NULL; ++ + if (pdev->dev.of_node) + of_property_read_u32(pdev->dev.of_node, + "clock-frequency", &clock_freq); +@@ -1225,9 +1232,7 @@ static int flexcan_probe(struct platform + priv->pdata = dev_get_platdata(&pdev->dev); + priv->devtype_data = devtype_data; + +- priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); +- if (IS_ERR(priv->reg_xceiver)) +- priv->reg_xceiver = NULL; ++ priv->reg_xceiver = reg_xceiver; + + netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); + diff --git a/queue-3.19/can-flexcan-fix-bus-off-error-state-handling.patch b/queue-3.19/can-flexcan-fix-bus-off-error-state-handling.patch new file mode 100644 index 00000000000..4a5168a1f2d --- /dev/null +++ b/queue-3.19/can-flexcan-fix-bus-off-error-state-handling.patch @@ -0,0 +1,38 @@ +From 258ce80e19211f06c97a562a71308ec21a9ab98f Mon Sep 17 00:00:00 2001 +From: Andri Yngvason +Date: Tue, 17 Mar 2015 13:03:09 +0000 +Subject: can: flexcan: fix bus-off error state handling. + +From: Andri Yngvason + +commit 258ce80e19211f06c97a562a71308ec21a9ab98f upstream. + +Making sure that the bus-off state gets passed to can_change_state(). + +Signed-off-by: Andri Yngvason +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/flexcan.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -593,13 +593,12 @@ static int flexcan_poll_state(struct net + rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? + CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; + new_state = max(tx_state, rx_state); +- } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) { ++ } else { + __flexcan_get_berr_counter(dev, &bec); +- new_state = CAN_STATE_ERROR_PASSIVE; ++ new_state = flt == FLEXCAN_ESR_FLT_CONF_PASSIVE ? ++ CAN_STATE_ERROR_PASSIVE : CAN_STATE_BUS_OFF; + rx_state = bec.rxerr >= bec.txerr ? new_state : 0; + tx_state = bec.rxerr <= bec.txerr ? new_state : 0; +- } else { +- new_state = CAN_STATE_BUS_OFF; + } + + /* state hasn't changed */ diff --git a/queue-3.19/cpuidle-acpi-do-not-overwrite-name-and-description-of-c0.patch b/queue-3.19/cpuidle-acpi-do-not-overwrite-name-and-description-of-c0.patch new file mode 100644 index 00000000000..73e3795d549 --- /dev/null +++ b/queue-3.19/cpuidle-acpi-do-not-overwrite-name-and-description-of-c0.patch @@ -0,0 +1,38 @@ +From c7e8bdf5872c5a8f5a6494e16fe839c38a0d3d3d Mon Sep 17 00:00:00 2001 +From: Thomas Schlichter +Date: Tue, 31 Mar 2015 20:24:39 +0200 +Subject: cpuidle: ACPI: do not overwrite name and description of C0 + +From: Thomas Schlichter + +commit c7e8bdf5872c5a8f5a6494e16fe839c38a0d3d3d upstream. + +Fix a bug that leads to showing the name and description of C-state C0 +as "" in sysfs after the ACPI C-states changed (e.g. after AC->DC +or DC->AC +transition). + +The function poll_idle_init() in drivers/cpuidle/driver.c initializes the +state 0 during cpuidle_register_driver(), so we better do not overwrite it +again with '\0' during acpi_processor_cst_has_changed(). + +Signed-off-by: Thomas Schlichter +Reviewed-by: Bartlomiej Zolnierkiewicz +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/processor_idle.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -962,7 +962,7 @@ static int acpi_processor_setup_cpuidle_ + return -EINVAL; + + drv->safe_state_index = -1; +- for (i = 0; i < CPUIDLE_STATE_MAX; i++) { ++ for (i = CPUIDLE_DRIVER_STATE_START; i < CPUIDLE_STATE_MAX; i++) { + drv->states[i].name[0] = '\0'; + drv->states[i].desc[0] = '\0'; + } diff --git a/queue-3.19/cpuidle-remove-state_count-field-from-struct-cpuidle_device.patch b/queue-3.19/cpuidle-remove-state_count-field-from-struct-cpuidle_device.patch new file mode 100644 index 00000000000..038746b910a --- /dev/null +++ b/queue-3.19/cpuidle-remove-state_count-field-from-struct-cpuidle_device.patch @@ -0,0 +1,86 @@ +From d75e4af14e228bbe3f86e29bcecb8e6be98d4e04 Mon Sep 17 00:00:00 2001 +From: Bartlomiej Zolnierkiewicz +Date: Tue, 31 Mar 2015 20:15:09 +0200 +Subject: cpuidle: remove state_count field from struct cpuidle_device + +From: Bartlomiej Zolnierkiewicz + +commit d75e4af14e228bbe3f86e29bcecb8e6be98d4e04 upstream. + +Thomas Schlichter reports the following issue on his Samsung NC20: + +"The C-states C1 and C2 to the OS when connected to AC, and additionally + provides the C3 C-state when disconnected from AC. However, the number + of C-states shown in sysfs is fixed to the number of C-states present + at boot. + If I boot with AC connected, I always only see the C-states up to C2 + even if I disconnect AC. + + The reason is commit 130a5f692425 (ACPI / cpuidle: remove dev->state_count + setting). It removes the update of dev->state_count, but sysfs uses + exactly this variable to show the C-states. + + The fix is to use drv->state_count in sysfs. As this is currently the + last user of dev->state_count, this variable can be completely removed." + +Remove dev->state_count as per the above. + +Reported-by: Thomas Schlichter +Signed-off-by: Bartlomiej Zolnierkiewicz +Signed-off-by: Kyungmin Park +Acked-by: Daniel Lezcano +[ rjw: Changelog ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpuidle/cpuidle.c | 3 --- + drivers/cpuidle/sysfs.c | 5 +++-- + include/linux/cpuidle.h | 1 - + 3 files changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -297,9 +297,6 @@ int cpuidle_enable_device(struct cpuidle + if (!dev->registered) + return -EINVAL; + +- if (!dev->state_count) +- dev->state_count = drv->state_count; +- + ret = cpuidle_add_device_sysfs(dev); + if (ret) + return ret; +--- a/drivers/cpuidle/sysfs.c ++++ b/drivers/cpuidle/sysfs.c +@@ -401,7 +401,7 @@ static int cpuidle_add_state_sysfs(struc + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); + + /* state statistics */ +- for (i = 0; i < device->state_count; i++) { ++ for (i = 0; i < drv->state_count; i++) { + kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); + if (!kobj) + goto error_state; +@@ -433,9 +433,10 @@ error_state: + */ + static void cpuidle_remove_state_sysfs(struct cpuidle_device *device) + { ++ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); + int i; + +- for (i = 0; i < device->state_count; i++) ++ for (i = 0; i < drv->state_count; i++) + cpuidle_free_state_kobj(device, i); + } + +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -68,7 +68,6 @@ struct cpuidle_device { + unsigned int cpu; + + int last_residency; +- int state_count; + struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; + struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; + struct cpuidle_driver_kobj *kobj_driver; diff --git a/queue-3.19/dmaengine-edma-fix-memory-leak-when-terminating-running-transfers.patch b/queue-3.19/dmaengine-edma-fix-memory-leak-when-terminating-running-transfers.patch new file mode 100644 index 00000000000..f160c1c1267 --- /dev/null +++ b/queue-3.19/dmaengine-edma-fix-memory-leak-when-terminating-running-transfers.patch @@ -0,0 +1,51 @@ +From 5ca9e7ce6eebec53362ff779264143860ccf68cd Mon Sep 17 00:00:00 2001 +From: Petr Kulhavy +Date: Fri, 27 Mar 2015 13:35:51 +0200 +Subject: dmaengine: edma: fix memory leak when terminating running transfers + +From: Petr Kulhavy + +commit 5ca9e7ce6eebec53362ff779264143860ccf68cd upstream. + +If edma_terminate_all() was called while a transfer was running (i.e. after +edma_execute() but before edma_callback()) the echan->edesc was not freed. + +This was due to the fact that a running transfer is on none of the +vchan lists: desc_submitted, desc_issued, desc_completed (edma_execute() +removes it from the desc_issued list), so the vchan_dma_desc_free_list() +called at the end of edma_terminate_all() didn't find it and didn't free it. + +This bug was found on an AM1808 based hardware (very similar to da850evm, +however using the second MMC/SD controller), where intense operations on the SD +card wasted the device 128MB RAM within a couple of days. + +Peter Ujfalusi: +The issue is even more severe since it affects cyclic (audio) transfers as +well. In this case starting/stopping audio will results memory leak. + +Signed-off-by: Petr Kulhavy +Signed-off-by: Peter Ujfalusi +CC: +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/edma.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/dma/edma.c ++++ b/drivers/dma/edma.c +@@ -258,6 +258,13 @@ static int edma_terminate_all(struct edm + */ + if (echan->edesc) { + int cyclic = echan->edesc->cyclic; ++ ++ /* ++ * free the running request descriptor ++ * since it is not in any of the vdesc lists ++ */ ++ edma_desc_free(&echan->edesc->vdesc); ++ + echan->edesc = NULL; + edma_stop(echan->ch_num); + /* Move the cyclic channel back to default queue */ diff --git a/queue-3.19/dmaengine-omap-dma-fix-memory-leak-when-terminating-running-transfer.patch b/queue-3.19/dmaengine-omap-dma-fix-memory-leak-when-terminating-running-transfer.patch new file mode 100644 index 00000000000..72e7cfe1d2f --- /dev/null +++ b/queue-3.19/dmaengine-omap-dma-fix-memory-leak-when-terminating-running-transfer.patch @@ -0,0 +1,40 @@ +From 02d88b735f5a60f04dbf6d051b76e1877a0d0844 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi +Date: Fri, 27 Mar 2015 13:35:52 +0200 +Subject: dmaengine: omap-dma: Fix memory leak when terminating running transfer + +From: Peter Ujfalusi + +commit 02d88b735f5a60f04dbf6d051b76e1877a0d0844 upstream. + +In omap_dma_start_desc the vdesc->node is removed from the virt-dma +framework managed lists (to be precise from the desc_issued list). +If a terminate_all comes before the transfer finishes the omap_desc will +not be freed up because it is not in any of the lists and we stopped the +DMA channel so the transfer will not going to complete. +There is no special sequence for leaking memory when using cyclic (audio) +transfer: with every start and stop of a cyclic transfer the driver leaks +struct omap_desc worth of memory. + +Free up the allocated memory directly in omap_dma_terminate_all() since the +framework will not going to do that for us. + +Signed-off-by: Peter Ujfalusi +CC: +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/omap-dma.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/dma/omap-dma.c ++++ b/drivers/dma/omap-dma.c +@@ -978,6 +978,7 @@ static int omap_dma_terminate_all(struct + * c->desc is NULL and exit.) + */ + if (c->desc) { ++ omap_dma_desc_free(&c->desc->vd); + c->desc = NULL; + /* Avoid stopping the dma twice */ + if (!c->paused) diff --git a/queue-3.19/firmware-dmi_scan-prevent-dmi_num-integer-overflow.patch b/queue-3.19/firmware-dmi_scan-prevent-dmi_num-integer-overflow.patch new file mode 100644 index 00000000000..6f05af28b4d --- /dev/null +++ b/queue-3.19/firmware-dmi_scan-prevent-dmi_num-integer-overflow.patch @@ -0,0 +1,77 @@ +From bfbaafae8519d82d10da6abe75f5766dd5b20475 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Fri, 20 Mar 2015 09:59:47 +0100 +Subject: firmware: dmi_scan: Prevent dmi_num integer overflow + +From: Jean Delvare + +commit bfbaafae8519d82d10da6abe75f5766dd5b20475 upstream. + +dmi_num is a u16, dmi_len is a u32, so this construct: + + dmi_num = dmi_len / 4; + +would result in an integer overflow for a DMI table larger than +256 kB. I've never see such a large table so far, but SMBIOS 3.0 +makes it possible so maybe we'll see such tables in the future. + +So instead of faking a structure count when the entry point does +not provide it, adjust the loop condition in dmi_table() to properly +deal with the case where dmi_num is not set. + +This bug was introduced with the initial SMBIOS 3.0 support in commit +fc43026278b2 ("dmi: add support for SMBIOS 3.0 64-bit entry point"). + +Signed-off-by: Jean Delvare +Cc: Matt Fleming +Cc: Ivan Khoronzhuk +Acked-by: Ard Biesheuvel +Signed-off-by: Matt Fleming +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/dmi_scan.c | 22 +++++++--------------- + 1 file changed, 7 insertions(+), 15 deletions(-) + +--- a/drivers/firmware/dmi_scan.c ++++ b/drivers/firmware/dmi_scan.c +@@ -86,10 +86,13 @@ static void dmi_table(u8 *buf, u32 len, + int i = 0; + + /* +- * Stop when we see all the items the table claimed to have +- * OR we run off the end of the table (also happens) ++ * Stop when we have seen all the items the table claimed to have ++ * (SMBIOS < 3.0 only) OR we reach an end-of-table marker OR we run ++ * off the end of the table (should never happen but sometimes does ++ * on bogus implementations.) + */ +- while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { ++ while ((!num || i < num) && ++ (data - buf + sizeof(struct dmi_header)) <= len) { + const struct dmi_header *dm = (const struct dmi_header *)data; + + /* +@@ -529,21 +532,10 @@ static int __init dmi_smbios3_present(co + if (memcmp(buf, "_SM3_", 5) == 0 && + buf[6] < 32 && dmi_checksum(buf, buf[6])) { + dmi_ver = get_unaligned_be16(buf + 7); ++ dmi_num = 0; /* No longer specified */ + dmi_len = get_unaligned_le32(buf + 12); + dmi_base = get_unaligned_le64(buf + 16); + +- /* +- * The 64-bit SMBIOS 3.0 entry point no longer has a field +- * containing the number of structures present in the table. +- * Instead, it defines the table size as a maximum size, and +- * relies on the end-of-table structure type (#127) to be used +- * to signal the end of the table. +- * So let's define dmi_num as an upper bound as well: each +- * structure has a 4 byte header, so dmi_len / 4 is an upper +- * bound for the number of structures in the table. +- */ +- dmi_num = dmi_len / 4; +- + if (dmi_walk_early(dmi_decode) == 0) { + pr_info("SMBIOS %d.%d present.\n", + dmi_ver >> 8, dmi_ver & 0xFF); diff --git a/queue-3.19/iio-adc-vf610-use-adc-clock-within-specification.patch b/queue-3.19/iio-adc-vf610-use-adc-clock-within-specification.patch new file mode 100644 index 00000000000..6d32007bfba --- /dev/null +++ b/queue-3.19/iio-adc-vf610-use-adc-clock-within-specification.patch @@ -0,0 +1,187 @@ +From f54e9f2be312a4e71b54aea865b2e33ccb95ef0c Mon Sep 17 00:00:00 2001 +From: Stefan Agner +Date: Tue, 24 Mar 2015 13:47:47 +0100 +Subject: iio: adc: vf610: use ADC clock within specification + +From: Stefan Agner + +commit f54e9f2be312a4e71b54aea865b2e33ccb95ef0c upstream. + +Depending on conversion mode used, the ADC clock (ADCK) needs +to be below a maximum frequency. According to Vybrid's data +sheet this is 20MHz for the low power conversion mode. + +The ADC clock is depending on input clock, which is the bus +clock by default. Vybrid SoC are typically clocked at at 400MHz +or 500MHz, which leads to 66MHz or 83MHz bus clock respectively. +Hence, a divider of 8 is required to stay below the specified +maximum clock of 20MHz. + +Due to the different bus clock speeds, the resulting sampling +frequency is not static. Hence use the ADC clock and calculate +the actual available sampling frequency dynamically. + +This fixes bogous values observed on some 500MHz clocked Vybrid +SoC. The resulting value usually showed Bit 9 being stuck at 1, +or 0, which lead to a value of +/-512. + +Signed-off-by: Stefan Agner +Acked-by: Fugang Duan +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/vf610_adc.c | 91 +++++++++++++++++++++++++++++--------------- + 1 file changed, 61 insertions(+), 30 deletions(-) + +--- a/drivers/iio/adc/vf610_adc.c ++++ b/drivers/iio/adc/vf610_adc.c +@@ -141,9 +141,13 @@ struct vf610_adc { + struct regulator *vref; + struct vf610_adc_feature adc_feature; + ++ u32 sample_freq_avail[5]; ++ + struct completion completion; + }; + ++static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; ++ + #define VF610_ADC_CHAN(_idx, _chan_type) { \ + .type = (_chan_type), \ + .indexed = 1, \ +@@ -180,35 +184,47 @@ static const struct iio_chan_spec vf610_ + /* sentinel */ + }; + +-/* +- * ADC sample frequency, unit is ADCK cycles. +- * ADC clk source is ipg clock, which is the same as bus clock. +- * +- * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder) +- * SFCAdder: fixed to 6 ADCK cycles +- * AverageNum: 1, 4, 8, 16, 32 samples for hardware average. +- * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode +- * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles +- * +- * By default, enable 12 bit resolution mode, clock source +- * set to ipg clock, So get below frequency group: +- */ +-static const u32 vf610_sample_freq_avail[5] = +-{1941176, 559332, 286957, 145374, 73171}; ++static inline void vf610_adc_calculate_rates(struct vf610_adc *info) ++{ ++ unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk); ++ int i; ++ ++ /* ++ * Calculate ADC sample frequencies ++ * Sample time unit is ADCK cycles. ADCK clk source is ipg clock, ++ * which is the same as bus clock. ++ * ++ * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder) ++ * SFCAdder: fixed to 6 ADCK cycles ++ * AverageNum: 1, 4, 8, 16, 32 samples for hardware average. ++ * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode ++ * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles ++ */ ++ adck_rate = ipg_rate / info->adc_feature.clk_div; ++ for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++) ++ info->sample_freq_avail[i] = ++ adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3)); ++} + + static inline void vf610_adc_cfg_init(struct vf610_adc *info) + { ++ struct vf610_adc_feature *adc_feature = &info->adc_feature; ++ + /* set default Configuration for ADC controller */ +- info->adc_feature.clk_sel = VF610_ADCIOC_BUSCLK_SET; +- info->adc_feature.vol_ref = VF610_ADCIOC_VR_VREF_SET; ++ adc_feature->clk_sel = VF610_ADCIOC_BUSCLK_SET; ++ adc_feature->vol_ref = VF610_ADCIOC_VR_VREF_SET; ++ ++ adc_feature->calibration = true; ++ adc_feature->ovwren = true; + +- info->adc_feature.calibration = true; +- info->adc_feature.ovwren = true; ++ adc_feature->res_mode = 12; ++ adc_feature->sample_rate = 1; ++ adc_feature->lpm = true; + +- info->adc_feature.clk_div = 1; +- info->adc_feature.res_mode = 12; +- info->adc_feature.sample_rate = 1; +- info->adc_feature.lpm = true; ++ /* Use a save ADCK which is below 20MHz on all devices */ ++ adc_feature->clk_div = 8; ++ ++ vf610_adc_calculate_rates(info); + } + + static void vf610_adc_cfg_post_set(struct vf610_adc *info) +@@ -290,12 +306,10 @@ static void vf610_adc_cfg_set(struct vf6 + + cfg_data = readl(info->regs + VF610_REG_ADC_CFG); + +- /* low power configuration */ + cfg_data &= ~VF610_ADC_ADLPC_EN; + if (adc_feature->lpm) + cfg_data |= VF610_ADC_ADLPC_EN; + +- /* disable high speed */ + cfg_data &= ~VF610_ADC_ADHSC_EN; + + writel(cfg_data, info->regs + VF610_REG_ADC_CFG); +@@ -435,10 +449,27 @@ static irqreturn_t vf610_adc_isr(int irq + return IRQ_HANDLED; + } + +-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1941176, 559332, 286957, 145374, 73171"); ++static ssize_t vf610_show_samp_freq_avail(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct vf610_adc *info = iio_priv(dev_to_iio_dev(dev)); ++ size_t len = 0; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(info->sample_freq_avail); i++) ++ len += scnprintf(buf + len, PAGE_SIZE - len, ++ "%u ", info->sample_freq_avail[i]); ++ ++ /* replace trailing space by newline */ ++ buf[len - 1] = '\n'; ++ ++ return len; ++} ++ ++static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(vf610_show_samp_freq_avail); + + static struct attribute *vf610_attributes[] = { +- &iio_const_attr_sampling_frequency_available.dev_attr.attr, ++ &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + NULL + }; + +@@ -502,7 +533,7 @@ static int vf610_read_raw(struct iio_dev + return IIO_VAL_FRACTIONAL_LOG2; + + case IIO_CHAN_INFO_SAMP_FREQ: +- *val = vf610_sample_freq_avail[info->adc_feature.sample_rate]; ++ *val = info->sample_freq_avail[info->adc_feature.sample_rate]; + *val2 = 0; + return IIO_VAL_INT; + +@@ -525,9 +556,9 @@ static int vf610_write_raw(struct iio_de + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + for (i = 0; +- i < ARRAY_SIZE(vf610_sample_freq_avail); ++ i < ARRAY_SIZE(info->sample_freq_avail); + i++) +- if (val == vf610_sample_freq_avail[i]) { ++ if (val == info->sample_freq_avail[i]) { + info->adc_feature.sample_rate = i; + vf610_adc_sample_set(info); + return 0; diff --git a/queue-3.19/iio-bmc150-change-sampling-frequency.patch b/queue-3.19/iio-bmc150-change-sampling-frequency.patch new file mode 100644 index 00000000000..ea94bdfdfef --- /dev/null +++ b/queue-3.19/iio-bmc150-change-sampling-frequency.patch @@ -0,0 +1,56 @@ +From 0ba8da961bd868c67a8dae3dbbee145514515e9c Mon Sep 17 00:00:00 2001 +From: Sathyanarayanan Kuppuswamy +Date: Tue, 3 Mar 2015 18:17:56 +0200 +Subject: iio: bmc150: change sampling frequency + +From: Sathyanarayanan Kuppuswamy + +commit 0ba8da961bd868c67a8dae3dbbee145514515e9c upstream. + +Currently driver reports device bandwidth list as available +sampling frequency. But sampling frequency is actually twice +the device bandwidth. This patch fixes this issue. + +Signed-off-by: Sathyanarayanan Kuppuswamy +Signed-off-by: Octavian Purdila +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/accel/bmc150-accel.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/iio/accel/bmc150-accel.c ++++ b/drivers/iio/accel/bmc150-accel.c +@@ -168,14 +168,14 @@ static const struct { + int val; + int val2; + u8 bw_bits; +-} bmc150_accel_samp_freq_table[] = { {7, 810000, 0x08}, +- {15, 630000, 0x09}, +- {31, 250000, 0x0A}, +- {62, 500000, 0x0B}, +- {125, 0, 0x0C}, +- {250, 0, 0x0D}, +- {500, 0, 0x0E}, +- {1000, 0, 0x0F} }; ++} bmc150_accel_samp_freq_table[] = { {15, 620000, 0x08}, ++ {31, 260000, 0x09}, ++ {62, 500000, 0x0A}, ++ {125, 0, 0x0B}, ++ {250, 0, 0x0C}, ++ {500, 0, 0x0D}, ++ {1000, 0, 0x0E}, ++ {2000, 0, 0x0F} }; + + static const struct { + int bw_bits; +@@ -840,7 +840,7 @@ static int bmc150_accel_validate_trigger + } + + static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( +- "7.810000 15.630000 31.250000 62.500000 125 250 500 1000"); ++ "15.620000 31.260000 62.50000 125 250 500 1000 2000"); + + static struct attribute *bmc150_accel_attributes[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, diff --git a/queue-3.19/iio-core-fix-double-free.patch b/queue-3.19/iio-core-fix-double-free.patch new file mode 100644 index 00000000000..bdd4963a5fc --- /dev/null +++ b/queue-3.19/iio-core-fix-double-free.patch @@ -0,0 +1,72 @@ +From c1b03ab5e886760bdd38c9c7a27af149046ffe01 Mon Sep 17 00:00:00 2001 +From: Martin Fuzzey +Date: Thu, 19 Feb 2015 15:17:44 +0100 +Subject: iio: core: Fix double free. + +From: Martin Fuzzey + +commit c1b03ab5e886760bdd38c9c7a27af149046ffe01 upstream. + +When an error occurred during event registration memory was freed twice +resulting in kernel memory corruption and a crash in unrelated code. + +The problem was caused by + iio_device_unregister_eventset() + iio_device_unregister_sysfs() + +being called twice, once on the error path and then +again via iio_dev_release(). + +Fix this by making these two functions idempotent so they +may be called multiple times. + +The problem was observed before applying + 78b33216 iio:core: Handle error when mask type is not separate + +Signed-off-by: Martin Fuzzey +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/industrialio-core.c | 5 +++-- + drivers/iio/industrialio-event.c | 1 + + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -832,8 +832,7 @@ static int iio_device_add_channel_sysfs( + * @attr_list: List of IIO device attributes + * + * This function frees the memory allocated for each of the IIO device +- * attributes in the list. Note: if you want to reuse the list after calling +- * this function you have to reinitialize it using INIT_LIST_HEAD(). ++ * attributes in the list. + */ + void iio_free_chan_devattr_list(struct list_head *attr_list) + { +@@ -841,6 +840,7 @@ void iio_free_chan_devattr_list(struct l + + list_for_each_entry_safe(p, n, attr_list, l) { + kfree(p->dev_attr.attr.name); ++ list_del(&p->l); + kfree(p); + } + } +@@ -921,6 +921,7 @@ static void iio_device_unregister_sysfs( + + iio_free_chan_devattr_list(&indio_dev->channel_attr_list); + kfree(indio_dev->chan_attr_group.attrs); ++ indio_dev->chan_attr_group.attrs = NULL; + } + + static void iio_dev_release(struct device *device) +--- a/drivers/iio/industrialio-event.c ++++ b/drivers/iio/industrialio-event.c +@@ -493,6 +493,7 @@ int iio_device_register_eventset(struct + error_free_setup_event_lines: + iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list); + kfree(indio_dev->event_interface); ++ indio_dev->event_interface = NULL; + return ret; + } + diff --git a/queue-3.19/iio-imu-use-iio_trigger_get-for-indio_dev-trig-assignment.patch b/queue-3.19/iio-imu-use-iio_trigger_get-for-indio_dev-trig-assignment.patch new file mode 100644 index 00000000000..590890adf56 --- /dev/null +++ b/queue-3.19/iio-imu-use-iio_trigger_get-for-indio_dev-trig-assignment.patch @@ -0,0 +1,37 @@ +From 4ce7ca89d6e8eae9e201cd0e972ba323f33e2fb4 Mon Sep 17 00:00:00 2001 +From: Darshana Padmadas +Date: Sat, 28 Mar 2015 12:07:14 +0530 +Subject: iio: imu: Use iio_trigger_get for indio_dev->trig assignment + +From: Darshana Padmadas + +commit 4ce7ca89d6e8eae9e201cd0e972ba323f33e2fb4 upstream. + +This patch uses iio_trigger_get to increment the reference +count of trigger device, to avoid incorrect assignment. +Can result in a null pointer dereference during removal if the +trigger has been changed before removal. + +This patch refers to a similar situation encountered through the +following discussion: +http://www.spinics.net/lists/linux-iio/msg13669.html + +Signed-off-by: Darshana Padmadas +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/imu/adis_trigger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/imu/adis_trigger.c ++++ b/drivers/iio/imu/adis_trigger.c +@@ -60,7 +60,7 @@ int adis_probe_trigger(struct adis *adis + iio_trigger_set_drvdata(adis->trig, adis); + ret = iio_trigger_register(adis->trig); + +- indio_dev->trig = adis->trig; ++ indio_dev->trig = iio_trigger_get(adis->trig); + if (ret) + goto error_free_irq; + diff --git a/queue-3.19/iio-inv_mpu6050-clear-timestamps-fifo-while-resetting-hardware-fifo.patch b/queue-3.19/iio-inv_mpu6050-clear-timestamps-fifo-while-resetting-hardware-fifo.patch new file mode 100644 index 00000000000..95646112f09 --- /dev/null +++ b/queue-3.19/iio-inv_mpu6050-clear-timestamps-fifo-while-resetting-hardware-fifo.patch @@ -0,0 +1,76 @@ +From 4dac0a8eefd55bb1f157d1a5a084531334a2d74c Mon Sep 17 00:00:00 2001 +From: Viorel Suman +Date: Wed, 18 Feb 2015 20:05:21 +0200 +Subject: iio: inv_mpu6050: Clear timestamps fifo while resetting hardware fifo + +From: Viorel Suman + +commit 4dac0a8eefd55bb1f157d1a5a084531334a2d74c upstream. + +A hardware fifo reset always imply an invalidation of the +existing timestamps, so we'll clear timestamps fifo on +successfull hardware fifo reset. + +Signed-off-by: Viorel Suman +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c ++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +@@ -24,6 +24,16 @@ + #include + #include "inv_mpu_iio.h" + ++static void inv_clear_kfifo(struct inv_mpu6050_state *st) ++{ ++ unsigned long flags; ++ ++ /* take the spin lock sem to avoid interrupt kick in */ ++ spin_lock_irqsave(&st->time_stamp_lock, flags); ++ kfifo_reset(&st->timestamps); ++ spin_unlock_irqrestore(&st->time_stamp_lock, flags); ++} ++ + int inv_reset_fifo(struct iio_dev *indio_dev) + { + int result; +@@ -50,6 +60,10 @@ int inv_reset_fifo(struct iio_dev *indio + INV_MPU6050_BIT_FIFO_RST); + if (result) + goto reset_fifo_fail; ++ ++ /* clear timestamps fifo */ ++ inv_clear_kfifo(st); ++ + /* enable interrupt */ + if (st->chip_config.accl_fifo_enable || + st->chip_config.gyro_fifo_enable) { +@@ -83,16 +97,6 @@ reset_fifo_fail: + return result; + } + +-static void inv_clear_kfifo(struct inv_mpu6050_state *st) +-{ +- unsigned long flags; +- +- /* take the spin lock sem to avoid interrupt kick in */ +- spin_lock_irqsave(&st->time_stamp_lock, flags); +- kfifo_reset(&st->timestamps); +- spin_unlock_irqrestore(&st->time_stamp_lock, flags); +-} +- + /** + * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt. + */ +@@ -184,7 +188,6 @@ end_session: + flush_fifo: + /* Flush HW and SW FIFOs. */ + inv_reset_fifo(indio_dev); +- inv_clear_kfifo(st); + mutex_unlock(&indio_dev->mlock); + iio_trigger_notify_done(indio_dev->trig); + diff --git a/queue-3.19/series b/queue-3.19/series index 39c2a85b50a..f5be8bb8161 100644 --- a/queue-3.19/series +++ b/queue-3.19/series @@ -54,3 +54,19 @@ usb-keyspan_pda-add-new-device-id.patch usb-ftdi_sio-added-custom-pid-for-synapse-wireless-product.patch usb-ftdi_sio-use-jtag-quirk-for-snap-connect-e10.patch defer-processing-of-req_preempt-requests-for-blocked-devices.patch +iio-inv_mpu6050-clear-timestamps-fifo-while-resetting-hardware-fifo.patch +iio-core-fix-double-free.patch +iio-bmc150-change-sampling-frequency.patch +iio-adc-vf610-use-adc-clock-within-specification.patch +iio-imu-use-iio_trigger_get-for-indio_dev-trig-assignment.patch +dmaengine-edma-fix-memory-leak-when-terminating-running-transfers.patch +dmaengine-omap-dma-fix-memory-leak-when-terminating-running-transfer.patch +ath9k-fix-tracking-of-enabled-ap-beacons.patch +x86-reboot-add-asrock-q1900dc-itx-mainboard-reboot-quirk.patch +can-flexcan-fix-bus-off-error-state-handling.patch +can-flexcan-deferred-on-regulator-return-eprobe_defer.patch +firmware-dmi_scan-prevent-dmi_num-integer-overflow.patch +cpuidle-remove-state_count-field-from-struct-cpuidle_device.patch +cpuidle-acpi-do-not-overwrite-name-and-description-of-c0.patch +usb-xhci-handle-config-error-change-cec-in-xhci-driver.patch +usb-xhci-apply-xhci_avoid_bei-quirk-to-all-intel-xhci-controllers.patch diff --git a/queue-3.19/usb-xhci-apply-xhci_avoid_bei-quirk-to-all-intel-xhci-controllers.patch b/queue-3.19/usb-xhci-apply-xhci_avoid_bei-quirk-to-all-intel-xhci-controllers.patch new file mode 100644 index 00000000000..550f71fdc00 --- /dev/null +++ b/queue-3.19/usb-xhci-apply-xhci_avoid_bei-quirk-to-all-intel-xhci-controllers.patch @@ -0,0 +1,56 @@ +From 227a4fd801c8a9fa2c4700ab98ec1aec06e3b44d Mon Sep 17 00:00:00 2001 +From: Lu Baolu +Date: Mon, 23 Mar 2015 18:27:42 +0200 +Subject: usb: xhci: apply XHCI_AVOID_BEI quirk to all Intel xHCI controllers + +From: Lu Baolu + +commit 227a4fd801c8a9fa2c4700ab98ec1aec06e3b44d upstream. + +When a device with an isochronous endpoint is plugged into the Intel +xHCI host controller, and the driver submits multiple frames per URB, +the xHCI driver will set the Block Event Interrupt (BEI) flag on all +but the last TD for the URB. This causes the host controller to place +an event on the event ring, but not send an interrupt. When the last +TD for the URB completes, BEI is cleared, and we get an interrupt for +the whole URB. + +However, under Intel xHCI host controllers, if the event ring is full +of events from transfers with BEI set, an "Event Ring is Full" event +will be posted to the last entry of the event ring, but no interrupt +is generated. Host will cease all transfer and command executions and +wait until software completes handling the pending events in the event +ring. That means xHC stops, but event of "event ring is full" is not +notified. As the result, the xHC looks like dead to user. + +This patch is to apply XHCI_AVOID_BEI quirk to Intel xHC devices. And +it should be backported to kernels as old as 3.0, that contains the +commit 69e848c2090a ("Intel xhci: Support EHCI/xHCI port switching."). + +Signed-off-by: Lu Baolu +Tested-by: Alistair Grant +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -115,6 +115,7 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + xhci->quirks |= XHCI_LPM_SUPPORT; + xhci->quirks |= XHCI_INTEL_HOST; ++ xhci->quirks |= XHCI_AVOID_BEI; + } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) { +@@ -130,7 +131,6 @@ static void xhci_pci_quirks(struct devic + * PPT chipsets. + */ + xhci->quirks |= XHCI_SPURIOUS_REBOOT; +- xhci->quirks |= XHCI_AVOID_BEI; + } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { diff --git a/queue-3.19/usb-xhci-handle-config-error-change-cec-in-xhci-driver.patch b/queue-3.19/usb-xhci-handle-config-error-change-cec-in-xhci-driver.patch new file mode 100644 index 00000000000..00f80320ecc --- /dev/null +++ b/queue-3.19/usb-xhci-handle-config-error-change-cec-in-xhci-driver.patch @@ -0,0 +1,78 @@ +From 9425183d177aa4a2f09d01a74925124f0778b595 Mon Sep 17 00:00:00 2001 +From: Lu Baolu +Date: Mon, 23 Mar 2015 18:27:41 +0200 +Subject: usb: xhci: handle Config Error Change (CEC) in xhci driver + +From: Lu Baolu + +commit 9425183d177aa4a2f09d01a74925124f0778b595 upstream. + +Linux xHCI driver doesn't report and handle port cofig error change. +If Port Configure Error for root hub port occurs, CEC bit in PORTSC +would be set by xHC and remains 1. This happends when the root port +fails to configure its link partner, e.g. the port fails to exchange +port capabilities information using Port Capability LMPs. + +Then the Port Status Change Events will be blocked until all status +change bits(CEC is one of the change bits) are cleared('0') (refer to +xHCI spec 4.19.2). Otherwise, the port status change event for this +root port will not be generated anymore, then root port would look +like dead for user and can't be recovered until a Host Controller +Reset(HCRST). + +This patch is to check CEC bit in PORTSC in xhci_get_port_status() +and set a Config Error in the return status if CEC is set. This will +cause a ClearPortFeature request, where CEC bit is cleared in +xhci_clear_port_change_bit(). + +[The commit log is based on initial Marvell patch posted at +http://marc.info/?l=linux-kernel&m=142323612321434&w=2] + +Reported-by: Gregory CLEMENT +Signed-off-by: Lu Baolu +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -387,6 +387,10 @@ static void xhci_clear_port_change_bit(s + status = PORT_PLC; + port_change_bit = "link state"; + break; ++ case USB_PORT_FEAT_C_PORT_CONFIG_ERROR: ++ status = PORT_CEC; ++ port_change_bit = "config error"; ++ break; + default: + /* Should never happen */ + return; +@@ -588,6 +592,8 @@ static u32 xhci_get_port_status(struct u + status |= USB_PORT_STAT_C_LINK_STATE << 16; + if ((raw_port_status & PORT_WRC)) + status |= USB_PORT_STAT_C_BH_RESET << 16; ++ if ((raw_port_status & PORT_CEC)) ++ status |= USB_PORT_STAT_C_CONFIG_ERROR << 16; + } + + if (hcd->speed != HCD_USB3) { +@@ -1005,6 +1011,7 @@ int xhci_hub_control(struct usb_hcd *hcd + case USB_PORT_FEAT_C_OVER_CURRENT: + case USB_PORT_FEAT_C_ENABLE: + case USB_PORT_FEAT_C_PORT_LINK_STATE: ++ case USB_PORT_FEAT_C_PORT_CONFIG_ERROR: + xhci_clear_port_change_bit(xhci, wValue, wIndex, + port_array[wIndex], temp); + break; +@@ -1069,7 +1076,7 @@ int xhci_hub_status_data(struct usb_hcd + */ + status = bus_state->resuming_ports; + +- mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC; ++ mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; + + spin_lock_irqsave(&xhci->lock, flags); + /* For each port, did anything change? If so, set that bit in buf. */ diff --git a/queue-3.19/x86-reboot-add-asrock-q1900dc-itx-mainboard-reboot-quirk.patch b/queue-3.19/x86-reboot-add-asrock-q1900dc-itx-mainboard-reboot-quirk.patch new file mode 100644 index 00000000000..945b4bc14a7 --- /dev/null +++ b/queue-3.19/x86-reboot-add-asrock-q1900dc-itx-mainboard-reboot-quirk.patch @@ -0,0 +1,60 @@ +From 80313b3078fcd2ca51970880d90757f05879a193 Mon Sep 17 00:00:00 2001 +From: Stefan Lippers-Hollmann +Date: Mon, 30 Mar 2015 22:44:27 +0200 +Subject: x86/reboot: Add ASRock Q1900DC-ITX mainboard reboot quirk + +From: Stefan Lippers-Hollmann + +commit 80313b3078fcd2ca51970880d90757f05879a193 upstream. + +The ASRock Q1900DC-ITX mainboard (Baytrail-D) hangs randomly in +both BIOS and UEFI mode while rebooting unless reboot=pci is +used. Add a quirk to reboot via the pci method. + +The problem is very intermittent and hard to debug, it might succeed +rebooting just fine 40 times in a row - but fails half a dozen times +the next day. It seems to be slightly less common in BIOS CSM mode +than native UEFI (with the CSM disabled), but it does happen in either +mode. Since I've started testing this patch in late january, rebooting +has been 100% reliable. + +Most of the time it already hangs during POST, but occasionally it +might even make it through the bootloader and the kernel might even +start booting, but then hangs before the mode switch. The same symptoms +occur with grub-efi, gummiboot and grub-pc, just as well as (at least) +kernel 3.16-3.19 and 4.0-rc6 (I haven't tried older kernels than 3.16). +Upgrading to the most current mainboard firmware of the ASRock +Q1900DC-ITX, version 1.20, does not improve the situation. + +( Searching the web seems to suggest that other Bay Trail-D mainboards + might be affected as well. ) +-- +Signed-off-by: Stefan Lippers-Hollmann +Cc: Matt Fleming +Link: http://lkml.kernel.org/r/20150330224427.0fb58e42@mir +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/reboot.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -183,6 +183,16 @@ static struct dmi_system_id __initdata r + }, + }, + ++ /* ASRock */ ++ { /* Handle problems with rebooting on ASRock Q1900DC-ITX */ ++ .callback = set_pci_reboot, ++ .ident = "ASRock Q1900DC-ITX", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASRock"), ++ DMI_MATCH(DMI_BOARD_NAME, "Q1900DC-ITX"), ++ }, ++ }, ++ + /* ASUS */ + { /* Handle problems with rebooting on ASUS P4S800 */ + .callback = set_bios_reboot,