From 0ccf091d1fbc1f99bb7f93bff8cf346769a9b0cd Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 10 Jun 2014 11:05:43 +0200 Subject: HID: sensor-hub: make dyn_callback_lock IRQ-safe dyn_callback_lock is being taken from IRQ context through hid_irq_in() -> hid_input_report() -> sensor_hub_raw_event() -> sensor_hub_get_callback(), therefore anyone else acquiring it needs to disable IRQs to disable deadlocks. Reported-by: Alexander Holler Tested-by: Alexander Holler Reported-by: Reyad Attiyat Signed-off-by: Jiri Kosina --- drivers/hid/hid-sensor-hub.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index a8d5c8faf8cf..13ce4e3aebf4 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -159,17 +159,18 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, { struct hid_sensor_hub_callbacks_list *callback; struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); + unsigned long flags; - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) if (callback->usage_id == usage_id && callback->hsdev == hsdev) { - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return -EINVAL; } callback = kzalloc(sizeof(*callback), GFP_ATOMIC); if (!callback) { - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return -ENOMEM; } callback->hsdev = hsdev; @@ -177,7 +178,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, callback->usage_id = usage_id; callback->priv = NULL; list_add_tail(&callback->list, &pdata->dyn_callback_list); - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } @@ -188,8 +189,9 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, { struct hid_sensor_hub_callbacks_list *callback; struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev); + unsigned long flags; - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) if (callback->usage_id == usage_id && callback->hsdev == hsdev) { @@ -197,7 +199,7 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev, kfree(callback); break; } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } @@ -378,15 +380,16 @@ static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message) { struct sensor_hub_data *pdata = hid_get_drvdata(hdev); struct hid_sensor_hub_callbacks_list *callback; + unsigned long flags; hid_dbg(hdev, " sensor_hub_suspend\n"); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) { if (callback->usage_callback->suspend) callback->usage_callback->suspend( callback->hsdev, callback->priv); } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } @@ -395,15 +398,16 @@ static int sensor_hub_resume(struct hid_device *hdev) { struct sensor_hub_data *pdata = hid_get_drvdata(hdev); struct hid_sensor_hub_callbacks_list *callback; + unsigned long flags; hid_dbg(hdev, " sensor_hub_resume\n"); - spin_lock(&pdata->dyn_callback_lock); + spin_lock_irqsave(&pdata->dyn_callback_lock, flags); list_for_each_entry(callback, &pdata->dyn_callback_list, list) { if (callback->usage_callback->resume) callback->usage_callback->resume( callback->hsdev, callback->priv); } - spin_unlock(&pdata->dyn_callback_lock); + spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return 0; } -- cgit v1.2.3 From 4732aee97b2b05adb472bd7a9ff31af95cbfe62a Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Tue, 10 Jun 2014 20:04:58 +0800 Subject: HID: sensor-hub: introduce Kconfig dependency on IOMEM When NO_IOMEM is enabled (e.g. score architecture), some drivers which need HAS_IOMEM need notice about it, or it will report related warning: warning: (GPIO_SCH && GPIO_ICH && GPIO_VX855 && GPIO_RDC321X && IE6XX_WDT && RADIO_WL1273 && HID_SENSOR_HUB && MFD_NVEC) selects MFD_CORE which has unmet direct dependencies (HAS_IOMEM) Signed-off-by: Chen Gang Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- drivers/phy/Kconfig | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 800c8b60f7a2..5e79c6ad914f 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -810,7 +810,7 @@ config HID_ZYDACRON config HID_SENSOR_HUB tristate "HID Sensors framework support" - depends on HID + depends on HID && HAS_IOMEM select MFD_CORE default n ---help--- diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 16a2f067c242..fcdfe7c0e4a7 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -122,6 +122,7 @@ config PHY_SUN4I_USB config PHY_SAMSUNG_USB2 tristate "Samsung USB 2.0 PHY driver" + depends on HAS_IOMEM select GENERIC_PHY select MFD_SYSCON help -- cgit v1.2.3 From a278e26830a2aa6dee1bd4f0ed5ff2bdea4d8887 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jun 2014 21:03:18 +0200 Subject: HID: rmi: Protect PM-only functions by #ifdef CONFIG_PM If CONFIG_PM=n: drivers/hid/hid-rmi.c:432: warning: ‘rmi_post_reset’ defined but not used drivers/hid/hid-rmi.c:437: warning: ‘rmi_post_resume’ defined but not used Signed-off-by: Geert Uytterhoeven Signed-off-by: Jiri Kosina --- drivers/hid/hid-rmi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 2451c7e5febd..578bbe65902b 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c @@ -428,6 +428,7 @@ static int rmi_raw_event(struct hid_device *hdev, return 0; } +#ifdef CONFIG_PM static int rmi_post_reset(struct hid_device *hdev) { return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); @@ -437,6 +438,7 @@ static int rmi_post_resume(struct hid_device *hdev) { return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); } +#endif /* CONFIG_PM */ #define RMI4_MAX_PAGE 0xff #define RMI4_PAGE_SIZE 0x0100 -- cgit v1.2.3 From e61f487fd596ce570e87ccfdc0a7fc9fa87aced9 Mon Sep 17 00:00:00 2001 From: Chew, Chiau Ee Date: Fri, 13 Jun 2014 23:57:25 +0800 Subject: spi/pxa2xx: fix incorrect SW mode chipselect setting for BayTrail LPSS SPI It was observed that after module removal followed by insertion, the SW mode chipselect is not properly set. Thus causing transfer failure due to incorrect CS toggling. Signed-off-by: Chew, Chiau Ee Acked-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index a98df7eeb42d..fe792106bdc5 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -118,6 +118,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data) */ orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); + /* Test SPI_CS_CONTROL_SW_MODE bit enabling */ value = orig | SPI_CS_CONTROL_SW_MODE; writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); @@ -126,10 +127,13 @@ static void lpss_ssp_setup(struct driver_data *drv_data) goto detection_done; } - value &= ~SPI_CS_CONTROL_SW_MODE; + orig = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); + + /* Test SPI_CS_CONTROL_SW_MODE bit disabling */ + value = orig & ~SPI_CS_CONTROL_SW_MODE; writel(value, drv_data->ioaddr + offset + SPI_CS_CONTROL); value = readl(drv_data->ioaddr + offset + SPI_CS_CONTROL); - if (value != orig) { + if (value != (orig & ~SPI_CS_CONTROL_SW_MODE)) { offset = 0x800; goto detection_done; } -- cgit v1.2.3 From 25f8a7cc5856f1c697c9aee88b0a898fcb6d788c Mon Sep 17 00:00:00 2001 From: Jürg Billeter Date: Mon, 16 Jun 2014 16:39:29 +0200 Subject: spi: sh-sci: fix use-after-free in sh_sci_spi_remove() setbits() uses sp->membase. Signed-off-by: Jürg Billeter Acked-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-sh-sci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index 1f56ef651d1a..b83dd733684c 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c @@ -175,9 +175,9 @@ static int sh_sci_spi_remove(struct platform_device *dev) { struct sh_sci_spi *sp = platform_get_drvdata(dev); - iounmap(sp->membase); - setbits(sp, PIN_INIT, 0); spi_bitbang_stop(&sp->bitbang); + setbits(sp, PIN_INIT, 0); + iounmap(sp->membase); spi_master_put(sp->bitbang.master); return 0; } -- cgit v1.2.3 From acbd573354bb7b7b7a3891018a39f4b3976b0c43 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Tue, 17 Jun 2014 15:07:55 +0300 Subject: libahci_platform: Fail when PHY required but PHY support disabled ahci_platform_get_resources handles resource management for platform AHCI drivers, including getting a possible PHY from the device tree. Since not all drivers need a PHY, it ignores -ENODEV and -ENOSYS from devm_get_phy. However, when the PHY subsystem is mistakenly disabled, -ENOSYS can be returned even when a PHY is needed. This patch modifies the -ENOSYS case to check if a "phys" device tree node exists. If it exists, then clearly the PHY subsystem is mistakenly disabled and the driver cannot work, ahci_platform_get_resources will fail and propagate the error. Signed-off-by: Mikko Perttunen Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- drivers/ata/libahci_platform.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 3a5b4ed25a4f..b0077589f065 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -250,8 +250,13 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev) if (IS_ERR(hpriv->phy)) { rc = PTR_ERR(hpriv->phy); switch (rc) { - case -ENODEV: case -ENOSYS: + /* No PHY support. Check if PHY is required. */ + if (of_find_property(dev->of_node, "phys", NULL)) { + dev_err(dev, "couldn't get sata-phy: ENOSYS\n"); + goto err_out; + } + case -ENODEV: /* continue normally */ hpriv->phy = NULL; break; -- cgit v1.2.3 From d066c946a866268c14a120b33e7226e899981998 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 17 Jun 2014 15:40:13 -0600 Subject: PCI: Fix unaligned access in AF transaction pending test pci_wait_for_pending() uses word access, so we shouldn't be passing an offset that is only byte aligned. Use the control register offset instead, shifting the mask to match. Fixes: d0b4cc4e3270 ("PCI: Wrong register used to check pending traffic") Fixes: 157e876ffe0b ("PCI: Add pci_wait_for_pending() (refactor pci_wait_for_pending_transaction()) Reported-by: Ben Hutchings Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas Acked-by: Gavin Shan CC: stable@vger.kernel.org # v3.14+--- drivers/pci/pci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 63a54a340863..1c8592b0e146 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3135,8 +3135,13 @@ static int pci_af_flr(struct pci_dev *dev, int probe) if (probe) return 0; - /* Wait for Transaction Pending bit clean */ - if (pci_wait_for_pending(dev, pos + PCI_AF_STATUS, PCI_AF_STATUS_TP)) + /* + * Wait for Transaction Pending bit to clear. A word-aligned test + * is used, so we use the conrol offset rather than status and shift + * the test bit to match. + */ + if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL, + PCI_AF_STATUS_TP << 8)) goto clear; dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n"); -- cgit v1.2.3 From 1c65df3d7b1b311a73f5636a4ad6611f067baf1e Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 18 Jun 2014 13:44:18 +0200 Subject: floppy: format block0 read error message properly In case reading of block 0 fails, line without trailing newline is printed causing dmesg to look horrible. Signed-off-by: Jiri Kosina --- drivers/block/floppy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 8e767bb7995e..f0c95df1f14a 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3774,7 +3774,7 @@ static void floppy_rb0_cb(struct bio *bio, int err) int drive = cbdata->drive; if (err) { - pr_info("floppy: error %d while reading block 0", err); + pr_info("floppy: error %d while reading block 0\n", err); set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); } complete(&cbdata->complete); -- cgit v1.2.3 From bd07894e217b174361711320be50c8308456096d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 30 May 2014 15:50:52 +0530 Subject: pinctrl: sunxi: Fix potential null pointer dereference kzalloc can fail. Add a null check to avoid null pointer dereference error while accessing the pointer later. Signed-off-by: Sachin Kamat Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index f1ca75e6d7b1..5f38c7f67834 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -211,6 +211,10 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, configlen++; pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL); + if (!pinconfig) { + kfree(*map); + return -ENOMEM; + } if (!of_property_read_u32(node, "allwinner,drive", &val)) { u16 strength = (val + 1) * 10; -- cgit v1.2.3 From 6c7ee8905d54e66d01902c59490bbc99d87d4efb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 16 Jun 2014 12:32:33 +0300 Subject: clk: ti: apll: not allocating enough data There is a cut and paste bug here which will lead to memory corruption because we don't allocate enough data. Fixes: 4d008589e271 ('CLK: TI: APLL: add support for omap2 aplls') Signed-off-by: Dan Carpenter Signed-off-by: Tero Kristo --- drivers/clk/ti/apll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index 5428c9c547cd..18dbaf128a39 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -338,7 +338,7 @@ static void __init of_omap2_apll_setup(struct device_node *node) const char *parent_name; u32 val; - ad = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + ad = kzalloc(sizeof(*ad), GFP_KERNEL); clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); init = kzalloc(sizeof(*init), GFP_KERNEL); -- cgit v1.2.3 From 8d2f9e8eca807479c83c8f765b6859838da618eb Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 19 May 2014 19:25:48 +0800 Subject: clk: ti: dra7: return error code in failure case Add a returned error code in the MAX_APLL_WAIT_TRIES case. Remove the updating of the return variable r to 0 if MAX_APLL_WAIT_TRIES is not yet reached, because r is already 0 at this point. Signed-off-by: Julia Lawall Signed-off-by: Tero Kristo --- drivers/clk/ti/apll.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index 18dbaf128a39..72d97279eae1 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -77,13 +77,11 @@ static int dra7_apll_enable(struct clk_hw *hw) if (i == MAX_APLL_WAIT_TRIES) { pr_warn("clock: %s failed transition to '%s'\n", clk_name, (state) ? "locked" : "bypassed"); - } else { + r = -EBUSY; + } else pr_debug("clock: %s transition to '%s' in %d loops\n", clk_name, (state) ? "locked" : "bypassed", i); - r = 0; - } - return r; } -- cgit v1.2.3 From 32cff42d0dc4fa5f474eff0980829537c520df5d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 17 Jun 2014 17:03:24 +0300 Subject: clk: ti: am43x: Fix boot with CONFIG_SOC_AM33XX disabled Define ti_clk_register_dpll_x2() and of_ti_am3_dpll_x2_setup() if AM43XX is defined. Fixes the below boot issue. [ 2.157258] gpmc_l3_clk not enabled [ 2.161194] gpmc_l3_clk not enabled [ 2.164896] Division by zero in kernel. [ 2.169055] CPU: 0 PID: 321 Comm: kworker/u2:2 Tainted: G W 3.16.0-rc1-00008-g4c0e520 #273 [ 2.178880] Workqueue: deferwq deferred_probe_work_func [ 2.184459] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 2.192752] [] (show_stack) from [] (dump_stack+0x80/0x9c) [ 2.200486] [] (dump_stack) from [] (Ldiv0+0x8/0x10) [ 2.207678] [] (Ldiv0) from [] (gpmc_calc_divider+0x24/0x40) [ 2.215490] [] (gpmc_calc_divider) from [] (gpmc_cs_set_timings+0x18/0x474) [ 2.224783] [] (gpmc_cs_set_timings) from [] (gpmc_nand_init+0x74/0x1a8) [ 2.233791] [] (gpmc_nand_init) from [] (gpmc_probe+0x52c/0x874) [ 2.242089] [] (gpmc_probe) from [] (platform_drv_probe+0x18/0x48) [ 2.250534] [] (platform_drv_probe) from [] (driver_probe_device+0x104/0x22c) [ 2.259988] [] (driver_probe_device) from [] (bus_for_each_drv+0x44/0x8c) [ 2.269087] [] (bus_for_each_drv) from [] (device_attach+0x74/0x8c) [ 2.277620] [] (device_attach) from [] (bus_probe_device+0x88/0xb0) [ 2.286074] [] (bus_probe_device) from [] (deferred_probe_work_func+0x60/0x90) [ 2.295611] [] (deferred_probe_work_func) from [] (process_one_work+0x1b4/0x4bc) [ 2.305288] [] (process_one_work) from [] (worker_thread+0x148/0x550) [ 2.313954] [] (worker_thread) from [] (kthread+0xc8/0xe4) [ 2.321628] [] (kthread) from [] (ret_from_fork+0x14/0x2c) Signed-off-by: Roger Quadros Reported-by: Tony Lindgren Signed-off-by: Tero Kristo --- drivers/clk/ti/dpll.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index abd956d5f838..79791e1bf282 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -161,7 +161,8 @@ cleanup: } #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ - defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) + defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \ + defined(CONFIG_SOC_AM43XX) /** * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock * @node: device node for this clock @@ -322,7 +323,7 @@ CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock", of_ti_omap4_dpll_x2_setup); #endif -#ifdef CONFIG_SOC_AM33XX +#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) static void __init of_ti_am3_dpll_x2_setup(struct device_node *node) { ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL); -- cgit v1.2.3 From 7d5fc85d961b807c799786afd175f5d964a2109f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 17 Jun 2014 11:04:32 +0300 Subject: clk: ti: set CLK_SET_RATE_NO_REPARENT for ti,mux-clock When setting the rate of a clock, by default the clock framework will change the parent of the clock to the most suitable one in __clk_mux_determine_rate() (most suitable by looking at the clock rate). This is a rather dangerous default, and causes problems on AM43x when using display and ethernet. There are multiple ways to select the clock muxes on AM43x, and some of those clock paths have the same source clocks for display and ethernet. When changing the clock rate for the display subsystem, the clock framework decides to change the display mux from the dedicated display PLL to a shared PLL which is used by the ethernet, and then changes the rate of the shared PLL, breaking the ethernet. As I don't think there ever is a case where we want the clock framework to automatically change the parent clock of a clock mux, this patch sets the CLK_SET_RATE_NO_REPARENT for all ti,mux-clocks. Signed-off-by: Tomi Valkeinen Reviewed-by: Paul Walmsley Tested-by: Felipe Balbi Signed-off-by: Tero Kristo --- drivers/clk/ti/mux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index 0197a478720c..e9d650e51287 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -160,7 +160,7 @@ static void of_mux_clk_setup(struct device_node *node) u8 clk_mux_flags = 0; u32 mask = 0; u32 shift = 0; - u32 flags = 0; + u32 flags = CLK_SET_RATE_NO_REPARENT; num_parents = of_clk_get_parent_count(node); if (num_parents < 2) { -- cgit v1.2.3 From 5cd8c48d95c10f729090c89757727e090719fd83 Mon Sep 17 00:00:00 2001 From: Zhuang Jin Can Date: Fri, 16 May 2014 05:57:57 +0800 Subject: usb: dwc3: gadget: check link trb after free_slot is increased In ISOC transfers, when free_slot points to the last TRB (i.e. Link TRB), and all queued requests meet Missed Interval Isoc error, busy_slot points to trb0. busy_slot->trb0 trb1 ... free_slot->trb31(Link TRB) After end transfer and receiving the XferNotReady event, trb_left is caculated as 1 which is wrong, and no TRB will be primed to the endpoint. The root cause is free_slot is not increased the same way as busy_slot. When busy_slot is increased by one, it checks if points to a link TRB after increasement, but free_slot checks it before increasement. free_slot should behave the same as busy_slot to make the trb_left caculation correct. Reviewed-by: Pratyush Anand Signed-off-by: Zhuang Jin Can Signed-off-by: Jiebing Li Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9d64dd02c57e..dab7927d1009 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -828,10 +828,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, length, last ? " last" : "", chain ? " chain" : ""); - /* Skip the LINK-TRB on ISOC */ - if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && - usb_endpoint_xfer_isoc(dep->endpoint.desc)) - dep->free_slot++; trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; @@ -843,6 +839,10 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, } dep->free_slot++; + /* Skip the LINK-TRB on ISOC */ + if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && + usb_endpoint_xfer_isoc(dep->endpoint.desc)) + dep->free_slot++; trb->size = DWC3_TRB_SIZE_LENGTH(length); trb->bpl = lower_32_bits(dma); -- cgit v1.2.3 From 4683ae86267f22dcd490953400c1d3fa12bcaccd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 21 May 2014 15:26:55 +0300 Subject: usb: gadget: f_rndis: fix an error code on allocation failure This should be return -ENOMEM. The current code returns successs. Fixes: de7a8d2d534f ('usb: gadget: f_rndis: OS descriptors support') Acked-by: Andrzej Pietrasiewicz Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index eed3ad878047..31274f70c4b9 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -687,7 +687,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), GFP_KERNEL); if (!f->os_desc_table) - return PTR_ERR(f->os_desc_table); + return -ENOMEM; f->os_desc_n = 1; f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; } -- cgit v1.2.3 From 6fb8cc82c096fd5ccf277678639193cae07125a0 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 2 Jun 2014 11:31:06 +0100 Subject: efi: Fix compiler warnings (unused, const, type) This patch fixes a few compiler warning in the efi code for unused variable, discarding const qualifier and wrong pointer type: drivers/firmware/efi/fdt.c|66 col 22| warning: unused variable ‘name’ [-Wunused-variable] drivers/firmware/efi/efi.c|368 col 3| warning: passing argument 3 of ‘of_get_flat_dt_prop’ from incompatible pointer type [enabled by default] drivers/firmware/efi/efi.c|368 col 8| warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default] Signed-off-by: Catalin Marinas Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi.c | 6 +++--- drivers/firmware/efi/fdt.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index cd36deb619fa..eff1a2f22f09 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -353,10 +353,10 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname, int depth, void *data) { struct param_info *info = data; - void *prop, *dest; - unsigned long len; + const void *prop; + void *dest; u64 val; - int i; + int i, len; if (depth != 1 || (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) diff --git a/drivers/firmware/efi/fdt.c b/drivers/firmware/efi/fdt.c index 5c6a8e8a9580..82d774161cc9 100644 --- a/drivers/firmware/efi/fdt.c +++ b/drivers/firmware/efi/fdt.c @@ -63,7 +63,7 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, */ prev = 0; for (;;) { - const char *type, *name; + const char *type; int len; node = fdt_next_node(fdt, prev, NULL); -- cgit v1.2.3 From e6dd42a917e62d916c6e513dbf87a4dec8cf3a1c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 28 May 2014 23:05:39 +0800 Subject: ahci: imx: manage only sata_ref_clk in imx_sata_enable[disable] Doing suspend/resume on imx6q and imx53 boards with no SATA disk attached will trigger the following warning. ------------[ cut here ]------------ WARNING: CPU: 0 PID: 661 at drivers/ata/libahci.c:224 ahci_enable_ahci+0x74/0x8) Modules linked in: CPU: 0 PID: 661 Comm: sh Tainted: G W 3.15.0-rc5-next-20140521-000027 Backtrace: [<80011c90>] (dump_backtrace) from [<80011e2c>] (show_stack+0x18/0x1c) r6:803a22f4 r5:00000000 r4:00000000 r3:00000000 [<80011e14>] (show_stack) from [<80661e60>] (dump_stack+0x88/0xa4) [<80661dd8>] (dump_stack) from [<80028fdc>] (warn_slowpath_common+0x70/0x94) r5:00000009 r4:00000000 [<80028f6c>] (warn_slowpath_common) from [<80029024>] (warn_slowpath_null+0x24/) r8:808f68c4 r7:00000000 r6:00000000 r5:00000000 r4:e0810004 [<80029000>] (warn_slowpath_null) from [<803a22f4>] (ahci_enable_ahci+0x74/0x80) [<803a2280>] (ahci_enable_ahci) from [<803a2324>] (ahci_reset_controller+0x24/0) r8:ddcd9410 r7:80351178 r6:ddcd9444 r5:dde8b850 r4:e0810000 r3:ddf35e90 [<803a2300>] (ahci_reset_controller) from [<803a2c68>] (ahci_platform_resume_ho) r7:80351178 r6:ddcd9444 r5:dde8b850 r4:ddcd9410 [<803a2c30>] (ahci_platform_resume_host) from [<803a38f0>] (imx_ahci_resume+0x2) r5:00000000 r4:ddcd9410 [<803a38c4>] (imx_ahci_resume) from [<803511ac>] (platform_pm_resume+0x34/0x54) .... The reason is that the SATA controller has no working clock at this point, and thus ahci_enable_ahci() fails to enable the controller. In case that there is no SATA disk attached, the imx_sata_disable() gets called in ahci_imx_error_handler(), and both sata_clk and sata_ref_clk will be disabled there. Because all the imx_sata_enable() calls afterward will return immediately due to imxpriv->no_device check, the SATA controller working clock sata_clk will never get any chance to be enabled again. This is a regression caused by commit 90870d79d4f2 (ahci-imx: Port to library-ised ahci_platform). Before the commit, only sata_ref_clk is managed by the driver in enable/disable function. But after the commit, all the clocks are enabled/disabled in a row by ahci platform helpers ahci_platform_enable[disable]_clks. Since ahb_clk is a bus clock which does not have gate at all, and i.MX low-power hardware module already manages sata_clk across suspend/resume cycle, the only clock that needs to be managed by software is sata_ref_clk. So instead of using ahci_platform_enable[disable]_clks to manage all the clocks in a row from imx_sata_enable[disable], we should manage only sata_ref_clk in there. Reported-by: Fabio Estevam Fixes: 90870d79d4f2 (ahci-imx: Port to library-ised ahci_platform) Signed-off-by: Shawn Guo Acked-by: Hans de Goede --- drivers/ata/ahci_imx.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 3a901520c62b..4384a7d72133 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -58,6 +58,8 @@ enum ahci_imx_type { struct imx_ahci_priv { struct platform_device *ahci_pdev; enum ahci_imx_type type; + struct clk *sata_clk; + struct clk *sata_ref_clk; struct clk *ahb_clk; struct regmap *gpr; bool no_device; @@ -224,7 +226,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv) return ret; } - ret = ahci_platform_enable_clks(hpriv); + ret = clk_prepare_enable(imxpriv->sata_ref_clk); if (ret < 0) goto disable_regulator; @@ -291,7 +293,7 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv) !IMX6Q_GPR13_SATA_MPLL_CLK_EN); } - ahci_platform_disable_clks(hpriv); + clk_disable_unprepare(imxpriv->sata_ref_clk); if (hpriv->target_pwr) regulator_disable(hpriv->target_pwr); @@ -385,6 +387,19 @@ static int imx_ahci_probe(struct platform_device *pdev) imxpriv->no_device = false; imxpriv->first_time = true; imxpriv->type = (enum ahci_imx_type)of_id->data; + + imxpriv->sata_clk = devm_clk_get(dev, "sata"); + if (IS_ERR(imxpriv->sata_clk)) { + dev_err(dev, "can't get sata clock.\n"); + return PTR_ERR(imxpriv->sata_clk); + } + + imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); + if (IS_ERR(imxpriv->sata_ref_clk)) { + dev_err(dev, "can't get sata_ref clock.\n"); + return PTR_ERR(imxpriv->sata_ref_clk); + } + imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); if (IS_ERR(imxpriv->ahb_clk)) { dev_err(dev, "can't get ahb clock.\n"); @@ -407,10 +422,14 @@ static int imx_ahci_probe(struct platform_device *pdev) hpriv->plat_data = imxpriv; - ret = imx_sata_enable(hpriv); + ret = clk_prepare_enable(imxpriv->sata_clk); if (ret) return ret; + ret = imx_sata_enable(hpriv); + if (ret) + goto disable_clk; + /* * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, * and IP vendor specific register IMX_TIMER1MS. @@ -435,16 +454,24 @@ static int imx_ahci_probe(struct platform_device *pdev) ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0, 0); if (ret) - imx_sata_disable(hpriv); + goto disable_sata; + + return 0; +disable_sata: + imx_sata_disable(hpriv); +disable_clk: + clk_disable_unprepare(imxpriv->sata_clk); return ret; } static void ahci_imx_host_stop(struct ata_host *host) { struct ahci_host_priv *hpriv = host->private_data; + struct imx_ahci_priv *imxpriv = hpriv->plat_data; imx_sata_disable(hpriv); + clk_disable_unprepare(imxpriv->sata_clk); } #ifdef CONFIG_PM_SLEEP -- cgit v1.2.3 From c5a1fbca6f35a85e9167b2cd9f7257eff0274f8b Mon Sep 17 00:00:00 2001 From: George Cherian Date: Thu, 22 May 2014 09:31:37 +0530 Subject: usb: dwc3: dwc3-omap: Fix the crash on module removal Following crash is seen on dwc3_omap removal Unable to handle kernel NULL pointer dereference at virtual address 00000018 pgd = ec098000 [00000018] *pgd=ad1f9831, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] SMP ARM Modules linked in: usb_f_ss_lb g_zero usb_f_acm u_serial usb_f_ecm u_ether libcomposite configfs snd_usb_audio snd_usbmidi_lib snd_rawmidi snd_hwdep snd_soc_omap snd_pcm_dmaengine snd_soc_core snd_compress snd_pcm snd_tim] CPU: 0 PID: 1296 Comm: rmmod Tainted: G W 3.15.0-rc4-02716-g95c4e18-dirty #10 task: ed05a080 ti: ec368000 task.ti: ec368000 PC is at release_resource+0x14/0x7c LR is at release_resource+0x10/0x7c pc : [] lr : [] psr: 60000013 sp : ec369ec0 ip : 60000013 fp : 00021008 r10: 00000000 r9 : ec368000 r8 : c000e7a4 r7 : 00000081 r6 : bf0062c0 r5 : ed7cd000 r4 : ed7d85c0 r3 : 00000000 r2 : 00000000 r1 : 00000011 r0 : c086d08c Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c5387d Table: ac098059 DAC: 00000015 Process rmmod (pid: 1296, stack limit = 0xec368248) Stack: (0xec369ec0 to 0xec36a000) 9ec0: 00000000 00000001 ed7cd000 c034de94 ed7cd010 ed7cd000 00000000 c034e194 9ee0: 00000000 bf0062cc ed7cd010 c03490b0 ed154cc0 ed4c2570 ed2b8410 ed156810 ed156810 bf006d24 c034db9c c034db84 c034c518 9f20: bf006d24 ed156810 bf006d24 c034cd2c bf006d24 bf006d68 00000800 c034c340 9f40: 00000000 c00a9e5c 00000020 00000000 bf006d68 00000800 ec369f4c 33637764 9f60: 616d6f5f 00000070 00000001 ec368000 ed05a080 c000e670 00000001 c0084010 9f80: 00021088 00000800 00021088 00000081 80000010 0000e6f4 00021088 00000800 9fa0: 00021088 c000e5e0 00021088 00000800 000210b8 00000800 e04f6d00 e04f6d00 9fc0: 00021088 00000800 00021088 00000081 00000001 00000000 be91de08 00021008 9fe0: 4d768880 be91dbb4 b6fc5984 4d76888c 80000010 000210b8 00000000 00000000 [] (release_resource) from [] (platform_device_del+0x6c/0x9c) [] (platform_device_del) from [] (platform_device_unregister+0xc/0x18) [] (platform_device_unregister) from [] (dwc3_omap_remove_core+0xc/0x14 [dwc3_omap]) [] (dwc3_omap_remove_core [dwc3_omap]) from [] (device_for_each_child+0x34/0x74) [] (device_for_each_child) from [] (dwc3_omap_remove+0x6c/0x78 [dwc3_omap]) [] (dwc3_omap_remove [dwc3_omap]) from [] (platform_drv_remove+0x18/0x1c) [] (platform_drv_remove) from [] (__device_release_driver+0x70/0xc8) [] (__device_release_driver) from [] (driver_detach+0xb4/0xb8) [] (driver_detach) from [] (bus_remove_driver+0x4c/0x90) [] (bus_remove_driver) from [] (SyS_delete_module+0x10c/0x198) [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x48) Code: e1a04000 e59f0068 eb14505e e5943010 (e5932018) ---[ end trace 7e2a8746ff4fc811 ]--- Segmentation fault [ balbi@ti.com : add CONFIG_OF dependency ] Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 1 + drivers/usb/dwc3/dwc3-omap.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 8eb996e4f058..261c3b428220 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -45,6 +45,7 @@ comment "Platform Glue Driver Support" config USB_DWC3_OMAP tristate "Texas Instruments OMAP5 and similar Platforms" depends on EXTCON && (ARCH_OMAP2PLUS || COMPILE_TEST) + depends on OF default USB_DWC3 help Some platforms from Texas Instruments like OMAP5, DRA7xxx and diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 4af4c3567656..737fdbe5e1a1 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -322,7 +322,7 @@ static int dwc3_omap_remove_core(struct device *dev, void *c) { struct platform_device *pdev = to_platform_device(dev); - platform_device_unregister(pdev); + of_device_unregister(pdev); return 0; } -- cgit v1.2.3 From 02dae36aa649a66c5c6181157ddd806e7b4913fc Mon Sep 17 00:00:00 2001 From: George Cherian Date: Thu, 22 May 2014 09:31:38 +0530 Subject: usb: dwc3: dwc3-omap: Disable/Enable only wrapper interrupts in prepare/complete The dwc3 wrapper driver should not be fiddling with the core interrupts. Disabling the core interrupts in prepare stops xhci from proper operation. So remove disable/enable of core interrupts from prepare/complete. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 737fdbe5e1a1..07a736acd0f2 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -599,7 +599,7 @@ static int dwc3_omap_prepare(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); - dwc3_omap_disable_irqs(omap); + dwc3_omap_write_irqmisc_set(omap, 0x00); return 0; } @@ -607,8 +607,19 @@ static int dwc3_omap_prepare(struct device *dev) static void dwc3_omap_complete(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); + u32 reg; - dwc3_omap_enable_irqs(omap); + reg = (USBOTGSS_IRQMISC_OEVT | + USBOTGSS_IRQMISC_DRVVBUS_RISE | + USBOTGSS_IRQMISC_CHRGVBUS_RISE | + USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | + USBOTGSS_IRQMISC_IDPULLUP_RISE | + USBOTGSS_IRQMISC_DRVVBUS_FALL | + USBOTGSS_IRQMISC_CHRGVBUS_FALL | + USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | + USBOTGSS_IRQMISC_IDPULLUP_FALL); + + dwc3_omap_write_irqmisc_set(omap, reg); } static int dwc3_omap_suspend(struct device *dev) -- cgit v1.2.3 From a9232076374334ca2bc2a448dfde96d38a54349a Mon Sep 17 00:00:00 2001 From: Jeff Westfahl Date: Thu, 29 May 2014 09:49:41 +0300 Subject: usb: gadget: u_ether: synchronize with transmit when stopping queue When disconnecting, it's possible that another thread has already made it into eth_start_xmit before we call netif_stop_queue. This can lead to a crash as eth_start_xmit tries to use resources that gether_disconnect is freeing. Use netif_tx_lock/unlock around netif_stop_queue to ensure no threads are executing during the remainder of gether_disconnect. Signed-off-by: Jeff Westfahl Tested-by: Jaeden Amero Signed-off-by: Felipe Balbi --- drivers/usb/gadget/u_ether.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 3d78a8844e43..97b027724ee7 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -1120,7 +1120,10 @@ void gether_disconnect(struct gether *link) DBG(dev, "%s\n", __func__); + netif_tx_lock(dev->net); netif_stop_queue(dev->net); + netif_tx_unlock(dev->net); + netif_carrier_off(dev->net); /* disable endpoints, forcing (synchronous) completion -- cgit v1.2.3 From 3fe15505296cb563362e2cf6d3aed73e123e0df0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 1 Jun 2014 20:31:46 -0700 Subject: usb: renesas: gadget: fixup: complete STATUS stage after receiving Current usbhs gadget driver didn't complete STATUS stage after receiving. It wasn't problem for us before, because some USB class doesn't use DATA OUT stage in control transfer. But, it is required on some device. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index d49f9c326035..4fd36530bfa3 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -681,6 +681,14 @@ usbhs_fifo_read_end: usbhs_pipe_number(pipe), pkt->length, pkt->actual, *is_done, pkt->zero); + /* + * Transmission end + */ + if (*is_done) { + if (usbhs_pipe_is_dcp(pipe)) + usbhs_dcp_control_transfer_done(pipe); + } + usbhs_fifo_read_busy: usbhsf_fifo_unselect(pipe, fifo); -- cgit v1.2.3 From 82363cf2eeafeea6ba88849f5e2febdc8a05943f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 10 Jun 2014 10:54:16 +0200 Subject: usb: musb: ux500: don't propagate the OF node There is a regression in the upcoming v3.16-rc1, that is caused by a problem that has been around for a while but now finally hangs the system. The bootcrawl looks like this: pinctrl-nomadik soc:pinctrl: pin GPIO256_AF28 already requested by a03e0000.usb_per5; cannot claim for musb-hdrc.0.auto pinctrl-nomadik soc:pinctrl: pin-256 (musb-hdrc.0.auto) status -22 pinctrl-nomadik soc:pinctrl: could not request pin 256 (GPIO256_AF28) from group usb_a_1 on device pinctrl-nomadik musb-hdrc musb-hdrc.0.auto: Error applying setting, reverse things back HS USB OTG: no transceiver configured musb-hdrc musb-hdrc.0.auto: musb_init_controller failed with status -517 platform musb-hdrc.0.auto: Driver musb-hdrc requests probe deferral (...) The ux500 MUSB driver propagates the OF node to the dynamically created musb-hdrc device, which is incorrect as it makes the OF core believe there are two devices spun from the very same DT node, which confuses other parts of the device core, notably the pin control subsystem, which will try to apply all the pin control settings also to the HDRC device as it gets instantiated. (The OMAP2430 for example, does not set the of_node member.) Cc: Cc: Arnd Bergmann Acked-by: Lee Jones Signed-off-by: Linus Walleij Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index c2e45e632723..f202e5088461 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -274,7 +274,6 @@ static int ux500_probe(struct platform_device *pdev) musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; - musb->dev.of_node = pdev->dev.of_node; glue->dev = &pdev->dev; glue->musb = musb; -- cgit v1.2.3 From f0688c8b81d2ea239c3fb0b848f623b579238d99 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 17 Jun 2014 17:47:41 +0200 Subject: usb: gadget: f_fs: fix NULL pointer dereference when there are no strings If the descriptors do not need any strings and user space sends empty set of strings, the ffs->stringtabs field remains NULL. Thus *ffs->stringtabs in functionfs_bind leads to a NULL pointer dereferenece. The bug was introduced by commit [fd7c9a007f: “use usb_string_ids_n()”]. While at it, remove double initialisation of lang local variable in that function. ffs->strings_count does not need to be checked in any way since in the above scenario it will remain zero and usb_string_ids_n() is a no-operation when colled with 0 argument. Cc: # v2.6.36+ Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 74202d67f911..8598c27c7d43 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1483,11 +1483,13 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev) ffs->ep0req->context = ffs; lang = ffs->stringtabs; - for (lang = ffs->stringtabs; *lang; ++lang) { - struct usb_string *str = (*lang)->strings; - int id = first_id; - for (; str->s; ++id, ++str) - str->id = id; + if (lang) { + for (; *lang; ++lang) { + struct usb_string *str = (*lang)->strings; + int id = first_id; + for (; str->s; ++id, ++str) + str->id = id; + } } ffs->gadget = cdev->gadget; -- cgit v1.2.3 From fe00b138295650fc46670b68342029b9fc391c62 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 18 Jun 2014 14:24:48 +0200 Subject: usb: gadget: OS descriptors configfs cleanup A number of variables serve a generic purpose of handling "compatible id" and "subcompatible id", but the names suggest they are for rndis only. Rename to reflect variables' purpose. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 2ddcd635ca2a..fadd6be26834 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1145,15 +1145,15 @@ static struct configfs_item_operations interf_item_ops = { .store_attribute = usb_os_desc_attr_store, }; -static ssize_t rndis_grp_compatible_id_show(struct usb_os_desc *desc, - char *page) +static ssize_t interf_grp_compatible_id_show(struct usb_os_desc *desc, + char *page) { memcpy(page, desc->ext_compat_id, 8); return 8; } -static ssize_t rndis_grp_compatible_id_store(struct usb_os_desc *desc, - const char *page, size_t len) +static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc, + const char *page, size_t len) { int l; @@ -1171,20 +1171,20 @@ static ssize_t rndis_grp_compatible_id_store(struct usb_os_desc *desc, return len; } -static struct usb_os_desc_attribute rndis_grp_attr_compatible_id = +static struct usb_os_desc_attribute interf_grp_attr_compatible_id = __CONFIGFS_ATTR(compatible_id, S_IRUGO | S_IWUSR, - rndis_grp_compatible_id_show, - rndis_grp_compatible_id_store); + interf_grp_compatible_id_show, + interf_grp_compatible_id_store); -static ssize_t rndis_grp_sub_compatible_id_show(struct usb_os_desc *desc, - char *page) +static ssize_t interf_grp_sub_compatible_id_show(struct usb_os_desc *desc, + char *page) { memcpy(page, desc->ext_compat_id + 8, 8); return 8; } -static ssize_t rndis_grp_sub_compatible_id_store(struct usb_os_desc *desc, - const char *page, size_t len) +static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc, + const char *page, size_t len) { int l; @@ -1202,14 +1202,14 @@ static ssize_t rndis_grp_sub_compatible_id_store(struct usb_os_desc *desc, return len; } -static struct usb_os_desc_attribute rndis_grp_attr_sub_compatible_id = +static struct usb_os_desc_attribute interf_grp_attr_sub_compatible_id = __CONFIGFS_ATTR(sub_compatible_id, S_IRUGO | S_IWUSR, - rndis_grp_sub_compatible_id_show, - rndis_grp_sub_compatible_id_store); + interf_grp_sub_compatible_id_show, + interf_grp_sub_compatible_id_store); static struct configfs_attribute *interf_grp_attrs[] = { - &rndis_grp_attr_compatible_id.attr, - &rndis_grp_attr_sub_compatible_id.attr, + &interf_grp_attr_compatible_id.attr, + &interf_grp_attr_sub_compatible_id.attr, NULL }; -- cgit v1.2.3 From 14574b546d87a282cc9ea0f43935cee6bfc97bf8 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 18 Jun 2014 14:24:49 +0200 Subject: usb: gadget: OS descriptors: provide interface directory names Function's interface directories need to be created when the function directory is created, but interface numbers are not known until the gadget is ready and bound to udc, so we cannot use numbers as part of interface directory names. Let the client decide what names to use. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 5 +++-- drivers/usb/gadget/configfs.h | 1 + drivers/usb/gadget/f_rndis.c | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index fadd6be26834..97142146eead 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1216,6 +1216,7 @@ static struct configfs_attribute *interf_grp_attrs[] = { int usb_os_desc_prepare_interf_dir(struct config_group *parent, int n_interf, struct usb_os_desc **desc, + char **names, struct module *owner) { struct config_group **f_default_groups, *os_desc_group, @@ -1257,8 +1258,8 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, d = desc[n_interf]; d->owner = owner; config_group_init_type_name(&d->group, "", interface_type); - config_item_set_name(&d->group.cg_item, "interface.%d", - n_interf); + config_item_set_name(&d->group.cg_item, "interface.%s", + names[n_interf]); interface_groups[n_interf] = &d->group; } diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index a14ac792c698..36c468c4f5e9 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h @@ -8,6 +8,7 @@ void unregister_gadget_item(struct config_item *item); int usb_os_desc_prepare_interf_dir(struct config_group *parent, int n_interf, struct usb_os_desc **desc, + char **names, struct module *owner); static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 31274f70c4b9..9c41e9515b8e 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -905,6 +905,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) { struct f_rndis_opts *opts; struct usb_os_desc *descs[1]; + char *names[1]; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) @@ -922,8 +923,9 @@ static struct usb_function_instance *rndis_alloc_inst(void) INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); descs[0] = &opts->rndis_os_desc; + names[0] = "rndis"; usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, - THIS_MODULE); + names, THIS_MODULE); config_group_init_type_name(&opts->func_inst.group, "", &rndis_func_type); -- cgit v1.2.3 From f0cae93f3f7e9a26c2d6bc182204c37dec3698eb Mon Sep 17 00:00:00 2001 From: Marcus Nutzinger Date: Thu, 5 Jun 2014 17:17:06 +0200 Subject: usb: gadget: gadgetfs: correct dev state This reverts commit 1826e9b1 (usb: gadget: gadgetfs: use after free in dev_release()) and places the call to put_dev() after setting the state. If this is not the final call to dev_release() and the state is not reset to STATE_DEV_DISABLED and hence all further open() calls to the gadgetfs ep0 device will fail with EBUSY. Signed-off-by: Marcus Nutzinger Reviewed-by: Christoph Muellner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index ee6c16416c30..2e4ce7704908 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1264,8 +1264,13 @@ dev_release (struct inode *inode, struct file *fd) kfree (dev->buf); dev->buf = NULL; - put_dev (dev); + /* other endpoints were all decoupled from this device */ + spin_lock_irq(&dev->lock); + dev->state = STATE_DEV_DISABLED; + spin_unlock_irq(&dev->lock); + + put_dev (dev); return 0; } -- cgit v1.2.3 From 5d881802c407d83c169c875dad88fe2bba066c33 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Mon, 26 May 2014 14:50:08 +0530 Subject: usb: musb: core: Handle Babble condition only in HOST mode BABBLE and RESET share the same interrupt. The interrupt is considered to be RESET if MUSB is in peripheral mode and as a BABBLE if MUSB is in HOST mode. Handle babble condition iff MUSB is in HOST mode. Fixes: ca88fc2ef0d7 (usb: musb: add a work_struct to recover from babble errors) Tested-by: Tony Lindgren Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 61da471b7aed..eff3c5cf84f4 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -849,7 +849,7 @@ b_host: } /* handle babble condition */ - if (int_usb & MUSB_INTR_BABBLE) + if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) schedule_work(&musb->recover_work); #if 0 -- cgit v1.2.3 From 27e249501ca06a3010519c306206cc402b61b5ab Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 20 Jun 2014 15:08:06 +0800 Subject: iommu/vt-d: fix bug in handling multiple RMRRs for the same PCI device Function dmar_iommu_notify_scope_dev() makes a wrong assumption that there's one RMRR for each PCI device at most, which causes DMA failure on some HP platforms. So enhance dmar_iommu_notify_scope_dev() to handle multiple RMRRs for the same PCI device. Fixbug: https://bugzilla.novell.com/show_bug.cgi?id=879482 Cc: # 3.15 Reported-by: Tom Mingarelli Tested-by: Linda Knippers Signed-off-by: Jiang Liu Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 6bb32773c3ac..51b6b77dc3e5 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3816,14 +3816,11 @@ int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info) ((void *)rmrr) + rmrr->header.length, rmrr->segment, rmrru->devices, rmrru->devices_cnt); - if (ret > 0) - break; - else if(ret < 0) + if(ret < 0) return ret; } else if (info->event == BUS_NOTIFY_DEL_DEVICE) { - if (dmar_remove_dev_scope(info, rmrr->segment, - rmrru->devices, rmrru->devices_cnt)) - break; + dmar_remove_dev_scope(info, rmrr->segment, + rmrru->devices, rmrru->devices_cnt); } } -- cgit v1.2.3 From d73a6d722a675dbba8f6b52c964a7076a24a12c1 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 20 Jun 2014 16:14:22 +0200 Subject: iommu/amd: Fix small race between invalidate_range_end/start Commit e79df31 introduced mmu_notifer_count to protect against parallel mmu_notifier_invalidate_range_start/end calls. The patch left a small race condition when invalidate_range_end() races with a new invalidate_range_start() the empty page-table may be reverted leading to stale TLB entries in the IOMMU and the device. Use a spin_lock instead of just an atomic variable to eliminate the race. Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu_v2.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index d4daa05efe60..499b4366a98d 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c @@ -45,7 +45,7 @@ struct pri_queue { struct pasid_state { struct list_head list; /* For global state-list */ atomic_t count; /* Reference count */ - atomic_t mmu_notifier_count; /* Counting nested mmu_notifier + unsigned mmu_notifier_count; /* Counting nested mmu_notifier calls */ struct task_struct *task; /* Task bound to this PASID */ struct mm_struct *mm; /* mm_struct for the faults */ @@ -53,7 +53,8 @@ struct pasid_state { struct pri_queue pri[PRI_QUEUE_SIZE]; /* PRI tag states */ struct device_state *device_state; /* Link to our device_state */ int pasid; /* PASID index */ - spinlock_t lock; /* Protect pri_queues */ + spinlock_t lock; /* Protect pri_queues and + mmu_notifer_count */ wait_queue_head_t wq; /* To wait for count == 0 */ }; @@ -431,15 +432,19 @@ static void mn_invalidate_range_start(struct mmu_notifier *mn, { struct pasid_state *pasid_state; struct device_state *dev_state; + unsigned long flags; pasid_state = mn_to_state(mn); dev_state = pasid_state->device_state; - if (atomic_add_return(1, &pasid_state->mmu_notifier_count) == 1) { + spin_lock_irqsave(&pasid_state->lock, flags); + if (pasid_state->mmu_notifier_count == 0) { amd_iommu_domain_set_gcr3(dev_state->domain, pasid_state->pasid, __pa(empty_page_table)); } + pasid_state->mmu_notifier_count += 1; + spin_unlock_irqrestore(&pasid_state->lock, flags); } static void mn_invalidate_range_end(struct mmu_notifier *mn, @@ -448,15 +453,19 @@ static void mn_invalidate_range_end(struct mmu_notifier *mn, { struct pasid_state *pasid_state; struct device_state *dev_state; + unsigned long flags; pasid_state = mn_to_state(mn); dev_state = pasid_state->device_state; - if (atomic_dec_and_test(&pasid_state->mmu_notifier_count)) { + spin_lock_irqsave(&pasid_state->lock, flags); + pasid_state->mmu_notifier_count -= 1; + if (pasid_state->mmu_notifier_count == 0) { amd_iommu_domain_set_gcr3(dev_state->domain, pasid_state->pasid, __pa(pasid_state->mm->pgd)); } + spin_unlock_irqrestore(&pasid_state->lock, flags); } static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm) @@ -650,7 +659,6 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid, goto out; atomic_set(&pasid_state->count, 1); - atomic_set(&pasid_state->mmu_notifier_count, 0); init_waitqueue_head(&pasid_state->wq); spin_lock_init(&pasid_state->lock); -- cgit v1.2.3 From b73842b75646da3810d6e1e161f223a288c64bd8 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 30 May 2014 22:18:18 +0200 Subject: irqchip: armada-370-xp: Mask all interrupts during initialization. Until now, the irq-armada-370-xp irqchip driver was not masking all interrupts at initialization. While in most cases this is not a problem because the bootloader has probably masked all interrupts, it becomes a problem when you use kexec: you're in kernel A, with many interrupts enabled, and then kexec into kernel B, without going through the bootloader. So during the boot process, if an interrupt occurs while the corresponding driver has not been loaded, you would get spurious interrupts. This commit fixes that by ensuring all interrupts are properly masked when the irqchip driver is initialized. Note that interrupt masking takes place at two level: at the global level (main_int_base) and at the per-CPU level (per_cpu_int_base). Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1401481098-23326-6-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index c887e6eebc41..574aba0eba4e 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -334,6 +334,15 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask, static void armada_xp_mpic_smp_cpu_init(void) { + u32 control; + int nr_irqs, i; + + control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); + nr_irqs = (control >> 2) & 0x3ff; + + for (i = 0; i < nr_irqs; i++) + writel(i, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); + /* Clear pending IPIs */ writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); @@ -474,7 +483,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, struct device_node *parent) { struct resource main_int_res, per_cpu_int_res; - int parent_irq; + int parent_irq, nr_irqs, i; u32 control; BUG_ON(of_address_to_resource(node, 0, &main_int_res)); @@ -496,9 +505,13 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, BUG_ON(!per_cpu_int_base); control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); + nr_irqs = (control >> 2) & 0x3ff; + + for (i = 0; i < nr_irqs; i++) + writel(i, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); armada_370_xp_mpic_domain = - irq_domain_add_linear(node, (control >> 2) & 0x3ff, + irq_domain_add_linear(node, nr_irqs, &armada_370_xp_mpic_irq_ops, NULL); BUG_ON(!armada_370_xp_mpic_domain); -- cgit v1.2.3 From 00ac20279174cf0a1f3d8e10654d2c5c4be5bdae Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 9 Jun 2014 11:05:02 -0700 Subject: irqchip: brcmstb-l2: Level-2 interrupts are edge sensitive The driver was configuring the interrupt handler for the Level-2 interrupts to be "level" triggered while they are in fact "edge" triggered. Fix this by using the correct handler. Reported-by: Brian Norris Signed-off-by: Florian Fainelli Link: https://lkml.kernel.org/r/1402337102-19428-1-git-send-email-f.fainelli@gmail.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-brcmstb-l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index 8ee2a36d5840..c15c840987d2 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -150,7 +150,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, /* Allocate a single Generic IRQ chip for this node */ ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, - np->full_name, handle_level_irq, clr, 0, 0); + np->full_name, handle_edge_irq, clr, 0, 0); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; -- cgit v1.2.3 From 361d79500244cc734588534d2756e2495f1549a6 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sat, 6 Dec 2014 05:54:00 +0000 Subject: iio:adc:ad799x: Fix reading and writing of event values, apply shift last two bits of ADC and limit values are zero and should not be reported (ad7993, ad7997); compare with read_raw() event values are 10 (ad7993, ad7997) or 12 bit max., check the range on write Signed-off-by: Peter Meerwald Cc: Stable@vger.kernel.org Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad799x.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 39b4cb48d738..6eba301ee03d 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -427,9 +427,12 @@ static int ad799x_write_event_value(struct iio_dev *indio_dev, int ret; struct ad799x_state *st = iio_priv(indio_dev); + if (val < 0 || val > RES_MASK(chan->scan_type.realbits)) + return -EINVAL; + mutex_lock(&indio_dev->mlock); ret = ad799x_i2c_write16(st, ad799x_threshold_reg(chan, dir, info), - val); + val << chan->scan_type.shift); mutex_unlock(&indio_dev->mlock); return ret; @@ -452,7 +455,8 @@ static int ad799x_read_event_value(struct iio_dev *indio_dev, mutex_unlock(&indio_dev->mlock); if (ret < 0) return ret; - *val = valin; + *val = (valin >> chan->scan_type.shift) & + RES_MASK(chan->scan_type.realbits); return IIO_VAL_INT; } -- cgit v1.2.3 From 045c243a511c8b688d36659cc3f781e84e9c2ddb Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 12 Jun 2014 14:34:11 -0500 Subject: spi: qup: Fix order of spi_register_master This patch moves the devm_spi_register_master below the initialization of the runtime_pm. If done in the wrong order, the spi_register_master fails if any probed slave devices issue SPI transactions. Signed-off-by: Andy Gross Acked-by: Ivan T. Ivanov Signed-off-by: Mark Brown --- drivers/spi/spi-qup.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index fc1de86d3c8a..e783e4ce2cdc 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -640,16 +640,19 @@ static int spi_qup_probe(struct platform_device *pdev) if (ret) goto error; - ret = devm_spi_register_master(dev, master); - if (ret) - goto error; - pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); + + ret = devm_spi_register_master(dev, master); + if (ret) + goto disable_pm; + return 0; +disable_pm: + pm_runtime_disable(&pdev->dev); error: clk_disable_unprepare(cclk); clk_disable_unprepare(iclk); -- cgit v1.2.3 From 318dbb02b50c8d4535ceb52f382e74ff7953aa42 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 20 Jun 2014 12:26:23 -0500 Subject: regulator: palmas: Fix SMPS enable/disable/is_enabled We use regmap regulator ops to enable/disable and check if regulator is enabled for various SMPS. However, these depend on valid enable_reg, enable_mask and enable_value in regulator descriptor. Currently we do not populate these for SMPS other than SMPS10, this results in spurious results as regmap assumes that the values are valid and ends up reading register 0x0 RTC:SECONDS_REG on Palmas variants that do have RTC! To fix this, we update proper parameters for the descriptor fields. Further, we want to ensure the behavior consistent with logic prior to commit dbabd624d4eec50b6, where, once you do a set_mode, enable/disable ensure the logic remains consistent and configures Palmas to the configuration that we set with set_mode (since the configuration register is common). To do this, we can rely on the regulator core's regulator_register behavior where the regulator descriptor pointer provided by the regulator driver is stored. (no reallocation and copy is done). This lets us update the enable_value post registration, to remain consistent with the mode we configure as part of set_mode. Fixes: dbabd624d4eec50b6 ("regulator: palmas: Reemove open coded functions with helper functions") Reported-by: Alexandre Courbot Signed-off-by: Nishanth Menon Tested-by: Alexandre Courbot Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 864ed02ce4b7..f5f522c499ba 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -323,6 +323,10 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) if (rail_enable) palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); + + /* Switch the enable value to ensure this is used for enable */ + pmic->desc[id].enable_val = pmic->current_reg_mode[id]; + return 0; } @@ -962,6 +966,14 @@ static int palmas_regulators_probe(struct platform_device *pdev) return ret; pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_mask = + PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + /* set_mode overrides this value */ + pmic->desc[id].enable_val = SMPS_CTRL_MODE_ON; } pmic->desc[id].type = REGULATOR_VOLTAGE; -- cgit v1.2.3 From b70e19c222a64018d308ebc80333575aff9f4e51 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Jun 2014 20:22:00 +0100 Subject: staging: iio/ad7291: fix error code in ad7291_probe() We should be returning a negative error code instead of success here. This would have been detected by GCC, except that the "ret" variable was initialized with a bogus value to disable GCC's uninitialized variable warnings. I've cleaned that up, as well. Signed-off-by: Dan Carpenter Signed-off-by: Jonathan Cameron Cc: Stable@vger.kernel.org --- drivers/staging/iio/adc/ad7291.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 357cef2a6f4c..7194bd138762 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -465,7 +465,7 @@ static int ad7291_probe(struct i2c_client *client, struct ad7291_platform_data *pdata = client->dev.platform_data; struct ad7291_chip_info *chip; struct iio_dev *indio_dev; - int ret = 0; + int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); if (!indio_dev) @@ -475,7 +475,7 @@ static int ad7291_probe(struct i2c_client *client, if (pdata && pdata->use_external_ref) { chip->reg = devm_regulator_get(&client->dev, "vref"); if (IS_ERR(chip->reg)) - return ret; + return PTR_ERR(chip->reg); ret = regulator_enable(chip->reg); if (ret) -- cgit v1.2.3 From a2c12493ed7e63a18cef33a71686d12ffcd6600e Mon Sep 17 00:00:00 2001 From: Adam Thomson Date: Thu, 6 Nov 2014 12:11:00 +0000 Subject: iio: of_iio_channel_get_by_name() returns non-null pointers for error legs Currently in the inkern.c code for IIO framework, the function of_iio_channel_get_by_name() will return a non-NULL pointer when it cannot find a channel using of_iio_channel_get() and when it tries to search for 'io-channel-ranges' property and fails. This is incorrect behaviour as the function which calls this expects a NULL pointer for failure. This patch rectifies the issue. Signed-off-by: Adam Thomson Signed-off-by: Jonathan Cameron Cc: Stable@vger.kernel.org --- drivers/iio/inkern.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index d833d55052ea..c7497009d60a 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -183,7 +183,7 @@ static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, else if (name && index >= 0) { pr_err("ERROR: could not get IIO channel %s:%s(%i)\n", np->full_name, name ? name : "", index); - return chan; + return NULL; } /* @@ -193,8 +193,9 @@ static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np, */ np = np->parent; if (np && !of_get_property(np, "io-channel-ranges", NULL)) - break; + return NULL; } + return chan; } @@ -317,6 +318,7 @@ struct iio_channel *iio_channel_get(struct device *dev, if (channel != NULL) return channel; } + return iio_channel_get_sys(name, channel_name); } EXPORT_SYMBOL_GPL(iio_channel_get); -- cgit v1.2.3 From 4f4366033945419b0c52118c29d3057d7c558765 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 19 Jun 2014 21:34:37 +0000 Subject: irqchip: spear_shirq: Fix interrupt offset The ras3 block on spear320 claims to have 3 interrupts. In fact it has one and 6 reserved interrupts. Account the 6 reserved to this block so it has 7 interrupts total. That matches the datasheet and the device tree entries. Broken since commit 80515a5a(ARM: SPEAr3xx: shirq: simplify and move the shared irq multiplexor to DT). Testing is overrated.... Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20140619212712.872379208@linutronix.de Fixes: 80515a5a2e3c ('ARM: SPEAr3xx: shirq: simplify and move the shared irq multiplexor to DT') Cc: # v3.8+ Acked-by: Viresh Kumar Signed-off-by: Jason Cooper --- drivers/irqchip/spear-shirq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c index 3fdda3a40269..6ce6bd3441bf 100644 --- a/drivers/irqchip/spear-shirq.c +++ b/drivers/irqchip/spear-shirq.c @@ -125,7 +125,7 @@ static struct spear_shirq spear320_shirq_ras2 = { }; static struct spear_shirq spear320_shirq_ras3 = { - .irq_nr = 3, + .irq_nr = 7, .irq_bit_off = 0, .invalid_irq = 1, .regs = { -- cgit v1.2.3 From 4a8573abe965115bc5b064401fd669b74e985258 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 12 Jun 2014 14:34:10 -0500 Subject: spi: qup: Remove chip select function This patch removes the chip select function. Chip select should instead be supported using GPIOs, defining the DT entry "cs-gpios", and letting the SPI core assert/deassert the chip select as it sees fit. The chip select control inside the controller is buggy. It is supposed to automatically assert the chip select based on the activity in the controller, but it is buggy and doesn't work at all. So instead we elect to use GPIOs. Signed-off-by: Andy Gross Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/qcom,spi-qup.txt | 6 ++++ drivers/spi/spi-qup.c | 33 ++++------------------ 2 files changed, 12 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt index b82a268f1bd4..bee6ff204baf 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt @@ -23,6 +23,12 @@ Optional properties: - spi-max-frequency: Specifies maximum SPI clock frequency, Units - Hz. Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt +- num-cs: total number of chipselects +- cs-gpios: should specify GPIOs used for chipselects. + The gpios will be referred to as reg = in the SPI child + nodes. If unspecified, a single SPI device without a chip + select can be used. + SPI slave nodes must be children of the SPI master node and can contain properties described in Documentation/devicetree/bindings/spi/spi-bus.txt diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index e783e4ce2cdc..c08da380cb23 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -424,31 +424,6 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) return 0; } -static void spi_qup_set_cs(struct spi_device *spi, bool enable) -{ - struct spi_qup *controller = spi_master_get_devdata(spi->master); - - u32 iocontol, mask; - - iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL); - - /* Disable auto CS toggle and use manual */ - iocontol &= ~SPI_IO_C_MX_CS_MODE; - iocontol |= SPI_IO_C_FORCE_CS; - - iocontol &= ~SPI_IO_C_CS_SELECT_MASK; - iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select); - - mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select; - - if (enable) - iocontol |= mask; - else - iocontol &= ~mask; - - writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL); -} - static int spi_qup_transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) @@ -571,12 +546,16 @@ static int spi_qup_probe(struct platform_device *pdev) return -ENOMEM; } + /* use num-cs unless not present or out of range */ + if (of_property_read_u16(dev->of_node, "num-cs", + &master->num_chipselect) || + (master->num_chipselect > SPI_NUM_CHIPSELECTS)) + master->num_chipselect = SPI_NUM_CHIPSELECTS; + master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; - master->num_chipselect = SPI_NUM_CHIPSELECTS; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->max_speed_hz = max_freq; - master->set_cs = spi_qup_set_cs; master->transfer_one = spi_qup_transfer_one; master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; -- cgit v1.2.3 From 636f4a31e3bb5ff8907d02a8862ee02f8a068084 Mon Sep 17 00:00:00 2001 From: Graham Williams Date: Wed, 18 Jun 2014 12:42:10 -0700 Subject: regulator: bcm590xx: fix vbus name The vbus regulator was not getting its name set. This results in the sysfs entry being empty. The lack of a bcm590xx_regs[] table entry also upsets Coverity runs. Add the table entry so the name gets set properly. Signed-off-by: Graham Williams Acked-by: Matt Porter Signed-off-by: Mark Brown --- drivers/regulator/bcm590xx-regulator.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 57544e254a78..58ece59367ae 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -119,6 +119,10 @@ static const unsigned int ldo_c_table[] = { 2900000, 3000000, 3300000, }; +static const unsigned int ldo_vbus[] = { + 5000000, +}; + /* DCDC group CSR: supported voltages in microvolts */ static const struct regulator_linear_range dcdc_csr_ranges[] = { REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), @@ -192,6 +196,7 @@ static struct bcm590xx_info bcm590xx_regs[] = { BCM590XX_REG_TABLE(gpldo4, ldo_a_table), BCM590XX_REG_TABLE(gpldo5, ldo_a_table), BCM590XX_REG_TABLE(gpldo6, ldo_a_table), + BCM590XX_REG_TABLE(vbus, ldo_vbus), }; struct bcm590xx_reg { -- cgit v1.2.3 From 2557e2d79d7de9505f5d64bdcbb96ca5c032bdcb Mon Sep 17 00:00:00 2001 From: Matwey V. Kornilov Date: Mon, 2 Jun 2014 20:17:29 +0400 Subject: drm/msm: Replace type of paddr to uint32_t. This patch helps to avoid the following build issue: drivers/gpu/drm/msm/msm_fbdev.c:108:2: error: passing argument 3 of 'msm_gem_get_iova_locked' from incompatible pointer type [-Werror] msm_gem_get_iova_locked(fbdev->bo, 0, &paddr); ^ In file included from drivers/gpu/drm/msm/msm_fbdev.c:18:0: drivers/gpu/drm/msm/msm_drv.h:153:5: note: expected 'uint32_t *' but argument is of type 'dma_addr_t *' int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, ^ Signed-off-by: Matwey V. Kornilov Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index a752ab83b810..5107fc4826bc 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -59,7 +59,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, struct drm_framebuffer *fb = NULL; struct fb_info *fbi = NULL; struct drm_mode_fb_cmd2 mode_cmd = {0}; - dma_addr_t paddr; + uint32_t paddr; int ret, size; sizes->surface_bpp = 32; -- cgit v1.2.3 From 370a4d8a79f166d2accc294c4db35e5cbe8c3a90 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Thu, 5 Jun 2014 18:30:58 +0100 Subject: drm/msm: storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Peter Griffin Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 0d2562fb681e..9a5d87db5c23 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -159,7 +159,7 @@ static int msm_unload(struct drm_device *dev) static int get_mdp_ver(struct platform_device *pdev) { #ifdef CONFIG_OF - const static struct of_device_id match_types[] = { { + static const struct of_device_id match_types[] = { { .compatible = "qcom,mdss_mdp", .data = (void *)5, }, { -- cgit v1.2.3 From b77f47e78982807286f6fdb4c39f9e798606dace Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Fri, 6 Jun 2014 10:03:32 -0400 Subject: drm/msm/hdmi: set hdp clock rate before prepare_enable The clock driver usually complains when a clock is being prepared before setting its rate. It is the case here for "core_clk" which needs to be set at 19.2 MHz before we attempt a prepare_enable(). Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi.c | 2 ++ drivers/gpu/drm/msm/hdmi/hdmi.h | 1 + drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 8 ++++++++ 3 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index ae750f6928c1..7f7aadef8a82 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -277,6 +277,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; + static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; config.phy_init = hdmi_phy_8x74_init; @@ -286,6 +287,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) config.pwr_reg_names = pwr_reg_names; config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); config.hpd_clk_names = hpd_clk_names; + config.hpd_freq = hpd_clk_freq; config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); config.pwr_clk_names = pwr_clk_names; config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 9fafee6a3e43..9d7723c6528a 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -87,6 +87,7 @@ struct hdmi_platform_config { /* clks that need to be on for hpd: */ const char **hpd_clk_names; + const long unsigned *hpd_freq; int hpd_clk_cnt; /* clks that need to be on for screen pwr (ie pixel clk): */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index e56a6196867c..28f7e3ec6c28 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -127,6 +127,14 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) } for (i = 0; i < config->hpd_clk_cnt; i++) { + if (config->hpd_freq && config->hpd_freq[i]) { + ret = clk_set_rate(hdmi->hpd_clks[i], + config->hpd_freq[i]); + if (ret) + dev_warn(dev->dev, "failed to set clk %s (%d)\n", + config->hpd_clk_names[i], ret); + } + ret = clk_prepare_enable(hdmi->hpd_clks[i]); if (ret) { dev_err(dev->dev, "failed to enable hpd clk: %s (%d)\n", -- cgit v1.2.3 From cf3198c2051a180d0cb469b275b2fb30a0533772 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sun, 15 Jun 2014 00:24:26 +0200 Subject: drm/msm: use PAGE_ALIGNED instead of IS_ALIGNED(PAGE_SIZE) use mm.h definition Cc: David Airlie Cc: Rob Clark Signed-off-by: Fabian Frederick Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 92b745986231..198ed848fec7 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -110,7 +110,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint32_t iova, VERB("unmap[%d]: %08x(%x)", i, iova, bytes); - BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE)); + BUG_ON(!PAGE_ALIGNED(bytes)); da += bytes; } -- cgit v1.2.3 From 87e956e9be0cdb832e90a4731b620286a8826842 Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Tue, 17 Jun 2014 10:32:37 -0400 Subject: drm/msm: fix IOMMU cleanup for -EPROBE_DEFER If probe fails after IOMMU is attached, we need to detach in order to clean up properly. Before this change, IOMMU faults would occur if the probe failed (-EPROBE_DEFER). Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 22 +++++++++++++++++----- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 1 + drivers/gpu/drm/msm/msm_gem.c | 6 ++++++ drivers/gpu/drm/msm/msm_iommu.c | 21 +++++++++++++++++++-- drivers/gpu/drm/msm/msm_mmu.h | 1 + 5 files changed, 44 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 42caf7fcb0b9..71510ee26e96 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -20,6 +20,10 @@ #include "msm_mmu.h" #include "mdp5_kms.h" +static const char *iommu_ports[] = { + "mdp_0", +}; + static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev); static int mdp5_hw_init(struct msm_kms *kms) @@ -104,6 +108,12 @@ static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file) static void mdp5_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + struct msm_mmu *mmu = mdp5_kms->mmu; + + if (mmu) { + mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); + mmu->funcs->destroy(mmu); + } kfree(mdp5_kms); } @@ -216,10 +226,6 @@ fail: return ret; } -static const char *iommu_ports[] = { - "mdp_0", -}; - static int get_clk(struct platform_device *pdev, struct clk **clkp, const char *name) { @@ -317,17 +323,23 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) mmu = msm_iommu_new(dev, config->iommu); if (IS_ERR(mmu)) { ret = PTR_ERR(mmu); + dev_err(dev->dev, "failed to init iommu: %d\n", ret); goto fail; } + ret = mmu->funcs->attach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); - if (ret) + if (ret) { + dev_err(dev->dev, "failed to attach iommu: %d\n", ret); + mmu->funcs->destroy(mmu); goto fail; + } } else { dev_info(dev->dev, "no iommu, fallback to phys " "contig buffers for scanout\n"); mmu = NULL; } + mdp5_kms->mmu = mmu; mdp5_kms->id = msm_register_mmu(dev, mmu); if (mdp5_kms->id < 0) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index c8b1a2522c25..6e981b692d1d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -33,6 +33,7 @@ struct mdp5_kms { /* mapper-id used to request GEM buffer mapped for scanout: */ int id; + struct msm_mmu *mmu; /* for tracking smp allocation amongst pipes: */ mdp5_smp_state_t smp_state; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index bb8026daebc9..690d7e7b6d1e 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -278,6 +278,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, uint32_t *iova) { struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct drm_device *dev = obj->dev; int ret = 0; if (!msm_obj->domain[id].iova) { @@ -285,6 +286,11 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, struct msm_mmu *mmu = priv->mmus[id]; struct page **pages = get_pages(obj); + if (!mmu) { + dev_err(dev->dev, "null MMU pointer\n"); + return -EINVAL; + } + if (IS_ERR(pages)) return PTR_ERR(pages); diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 198ed848fec7..4b2ad9181edf 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -28,7 +28,7 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, unsigned long iova, int flags, void *arg) { DBG("*** fault: iova=%08lx, flags=%d", iova, flags); - return 0; + return -ENOSYS; } static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) @@ -40,8 +40,10 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) for (i = 0; i < cnt; i++) { struct device *msm_iommu_get_ctx(const char *ctx_name); struct device *ctx = msm_iommu_get_ctx(names[i]); - if (IS_ERR_OR_NULL(ctx)) + if (IS_ERR_OR_NULL(ctx)) { + dev_warn(dev->dev, "couldn't get %s context", names[i]); continue; + } ret = iommu_attach_device(iommu->domain, ctx); if (ret) { dev_warn(dev->dev, "could not attach iommu to %s", names[i]); @@ -52,6 +54,20 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) return 0; } +static void msm_iommu_detach(struct msm_mmu *mmu, const char **names, int cnt) +{ + struct msm_iommu *iommu = to_msm_iommu(mmu); + int i; + + for (i = 0; i < cnt; i++) { + struct device *msm_iommu_get_ctx(const char *ctx_name); + struct device *ctx = msm_iommu_get_ctx(names[i]); + if (IS_ERR_OR_NULL(ctx)) + continue; + iommu_detach_device(iommu->domain, ctx); + } +} + static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, unsigned len, int prot) { @@ -127,6 +143,7 @@ static void msm_iommu_destroy(struct msm_mmu *mmu) static const struct msm_mmu_funcs funcs = { .attach = msm_iommu_attach, + .detach = msm_iommu_detach, .map = msm_iommu_map, .unmap = msm_iommu_unmap, .destroy = msm_iommu_destroy, diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 030324482b4a..21da6d154f71 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -22,6 +22,7 @@ struct msm_mmu_funcs { int (*attach)(struct msm_mmu *mmu, const char **names, int cnt); + void (*detach)(struct msm_mmu *mmu, const char **names, int cnt); int (*map)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, unsigned len, int prot); int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, -- cgit v1.2.3 From bfafe93a1cd466ef318b7e5f6c65f59aee147791 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 5 Jun 2014 20:31:47 +0300 Subject: drm/i915: cache hw power well enabled state Jesse noticed that the punit communication needed to query the VLV power well status can cause substantial delays. Since we can query the state frequently, for example during I2C transfers, maintain a cached version of the HW state to get rid of this delay. This fixes at least one reported regression where boot time increased by ~4 seconds due to frequent power well state queries on VLV during eDP EDID read. This regression has been introduced in commit bb4932c4f17b68f34645ffbcf845e4c29d17290b Author: Imre Deak Date: Mon Apr 14 20:24:33 2014 +0300 drm/i915: vlv: check port power domain instead of only D0 for eDP VDD on Reported-by: Jesse Barnes Signed-off-by: Imre Deak Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 6 +++--- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_pm.c | 37 +++++++++++++++--------------------- 4 files changed, 22 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 49414d30e8d4..a47fbf60b781 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -977,6 +977,8 @@ struct i915_power_well { bool always_on; /* power well enable/disable usage count */ int count; + /* cached hw enabled state */ + bool hw_enabled; unsigned long domains; unsigned long data; const struct i915_power_well_ops *ops; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index efd3cf50cb0f..9188fede99ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12411,8 +12411,8 @@ intel_display_capture_error_state(struct drm_device *dev) for_each_pipe(i) { error->pipe[i].power_domain_on = - intel_display_power_enabled_sw(dev_priv, - POWER_DOMAIN_PIPE(i)); + intel_display_power_enabled_unlocked(dev_priv, + POWER_DOMAIN_PIPE(i)); if (!error->pipe[i].power_domain_on) continue; @@ -12447,7 +12447,7 @@ intel_display_capture_error_state(struct drm_device *dev) enum transcoder cpu_transcoder = transcoders[i]; error->transcoder[i].power_domain_on = - intel_display_power_enabled_sw(dev_priv, + intel_display_power_enabled_unlocked(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder)); if (!error->transcoder[i].power_domain_on) continue; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bda0ae3d80cc..eaa27ee9e367 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *); void intel_power_domains_remove(struct drm_i915_private *); bool intel_display_power_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); -bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); void intel_display_power_get(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); void intel_display_power_put(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 54242e4f6f4c..9ad0c6afc487 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5603,8 +5603,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); } -bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; struct i915_power_well *power_well; @@ -5615,16 +5615,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, return false; power_domains = &dev_priv->power_domains; + is_enabled = true; + for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { if (power_well->always_on) continue; - if (!power_well->count) { + if (!power_well->hw_enabled) { is_enabled = false; break; } } + return is_enabled; } @@ -5632,30 +5635,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; - struct i915_power_well *power_well; - bool is_enabled; - int i; - - if (dev_priv->pm.suspended) - return false; + bool ret; power_domains = &dev_priv->power_domains; - is_enabled = true; - mutex_lock(&power_domains->lock); - for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { - if (power_well->always_on) - continue; - - if (!power_well->ops->is_enabled(dev_priv, power_well)) { - is_enabled = false; - break; - } - } + ret = intel_display_power_enabled_unlocked(dev_priv, domain); mutex_unlock(&power_domains->lock); - return is_enabled; + return ret; } /* @@ -5976,6 +5964,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, if (!power_well->count++) { DRM_DEBUG_KMS("enabling %s\n", power_well->name); power_well->ops->enable(dev_priv, power_well); + power_well->hw_enabled = true; } check_power_well_state(dev_priv, power_well); @@ -6005,6 +5994,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, if (!--power_well->count && i915.disable_power_well) { DRM_DEBUG_KMS("disabling %s\n", power_well->name); + power_well->hw_enabled = false; power_well->ops->disable(dev_priv, power_well); } @@ -6267,8 +6257,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv) int i; mutex_lock(&power_domains->lock); - for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) + for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { power_well->ops->sync_hw(dev_priv, power_well); + power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, + power_well); + } mutex_unlock(&power_domains->lock); } -- cgit v1.2.3 From 1cab4c68e339086cdaff7535848e878e8f261fca Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 20 May 2014 16:27:40 +0200 Subject: USB: option: add device ID for SpeedUp SU9800 usb 3g modem Reported by Alif Mubarak Ahmad: This device vendor and product id is 1c9e:9800 It is working as serial interface with generic usbserial driver. I thought it is more suitable to use usbserial option driver, which has better capability distinguishing between modem serial interface and micro sd storage interface. [ johan: style changes ] Signed-off-by: Oliver Neukum Tested-by: Alif Mubarak Ahmad Cc: Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 59c3108cc136..f4fd59c22158 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -352,6 +352,9 @@ static void option_instat_callback(struct urb *urb); /* Zoom */ #define ZOOM_PRODUCT_4597 0x9607 +/* SpeedUp SU9800 usb 3g modem */ +#define SPEEDUP_PRODUCT_SU9800 0x9800 + /* Haier products */ #define HAIER_VENDOR_ID 0x201e #define HAIER_PRODUCT_CE100 0x2009 @@ -1577,6 +1580,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, -- cgit v1.2.3 From aea1ae8760314e072bf1b773521e9de5d5dda10d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 5 Jun 2014 16:05:52 +0200 Subject: USB: ftdi_sio: fix null deref at port probe Fix NULL-pointer dereference when probing an interface with no endpoints. These devices have two bulk endpoints per interface, but this avoids crashing the kernel if a user forces a non-FTDI device to be probed. Note that the iterator variable was made unsigned in order to avoid a maybe-uninitialized compiler warning for ep_desc after the loop. Fixes: 895f28badce9 ("USB: ftdi_sio: fix hi-speed device packet size calculation") Reported-by: Mike Remski Tested-by: Mike Remski Cc: # 2.6.31 Signed-off-by: Johan Hovold --- drivers/usb/serial/ftdi_sio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index edf3b124583c..115662c16dcc 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1566,14 +1566,17 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) struct usb_device *udev = serial->dev; struct usb_interface *interface = serial->interface; - struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; + struct usb_endpoint_descriptor *ep_desc; unsigned num_endpoints; - int i; + unsigned i; num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); + if (!num_endpoints) + return; + /* NOTE: some customers have programmed FT232R/FT245R devices * with an endpoint size of 0 - not good. In this case, we * want to override the endpoint descriptor setting and use a -- cgit v1.2.3 From b0ebef36e93703e59003ad6a1a20227e47714417 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 6 Jun 2014 17:25:56 +0200 Subject: usb: option: add/modify Olivetti Olicard modems Adding a couple of Olivetti modems and blacklisting the net function on a couple which are already supported. Reported-by: Lars Melin Cc: Signed-off-by: Bjørn Mork Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f4fd59c22158..ac73f49cd9f0 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -375,8 +375,12 @@ static void option_instat_callback(struct urb *urb); /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c #define OLIVETTI_PRODUCT_OLICARD100 0xc000 +#define OLIVETTI_PRODUCT_OLICARD120 0xc001 +#define OLIVETTI_PRODUCT_OLICARD140 0xc002 #define OLIVETTI_PRODUCT_OLICARD145 0xc003 +#define OLIVETTI_PRODUCT_OLICARD155 0xc004 #define OLIVETTI_PRODUCT_OLICARD200 0xc005 +#define OLIVETTI_PRODUCT_OLICARD160 0xc00a #define OLIVETTI_PRODUCT_OLICARD500 0xc00b /* Celot products */ @@ -1615,15 +1619,21 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - - { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD140), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD155), + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), - .driver_info = (kernel_ulong_t)&net_intf6_blacklist - }, + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD160), + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist - }, + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, -- cgit v1.2.3 From 4bc8cad5e14cdd19e557e07888260a993933b94d Mon Sep 17 00:00:00 2001 From: Michael Welling Date: Wed, 18 Jun 2014 20:52:12 -0500 Subject: drivers:video:fbdev atmel_lcdfb.c power GPIO registration bug A list that was intended for storing power control GPIOs was never initialized correctly or filled. Without these lines of added code the kernel hangs when trying to access an uninitialized list when a power control GPIO is registered with the device tree. Signed-off-by: Michael Welling Acked-by: Nicolas Ferre Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/atmel_lcdfb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index e683b6ef9594..d36e830d6fc6 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -1057,6 +1057,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) goto put_display_node; } + INIT_LIST_HEAD(&pdata->pwr_gpios); ret = -ENOMEM; for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) { gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio", @@ -1082,6 +1083,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) dev_err(dev, "set direction output gpio %d failed\n", gpio); goto put_display_node; } + list_add(&og->list, &pdata->pwr_gpios); } if (is_gpio_power) -- cgit v1.2.3 From 56c4b63aaf4c2cd91966b2a5e69e5367bea60bbe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Jun 2014 15:47:05 +0300 Subject: drm/i915: default to having backlight if VBT not available Apparently there are Apple laptops with magic smoke for a VBIOS, which we fail to find and use. Default to having and setting up backlight in this case. This fixes a regression introduced by commit c675949ec58ca50d5a3ae3c757892f1560f6e896 Author: Jani Nikula Date: Wed Apr 9 11:31:37 2014 +0300 drm/i915: do not setup backlight if not available according to VBT Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=77831 Reported-and-tested-by: Matteo Cypriani Cc: stable@vger.kernel.org # 3.15+ Reviewed-by: Imre Deak Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_bios.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 1ee98f121a00..827498e081df 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -315,9 +315,6 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) const struct bdb_lfp_backlight_data *backlight_data; const struct bdb_lfp_backlight_data_entry *entry; - /* Err to enabling backlight if no backlight block. */ - dev_priv->vbt.backlight.present = true; - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); if (!backlight_data) return; @@ -1088,6 +1085,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC; + /* Default to having backlight */ + dev_priv->vbt.backlight.present = true; + /* LFP panel data */ dev_priv->vbt.lvds_dither = 1; dev_priv->vbt.lvds_vbt = 0; -- cgit v1.2.3 From 245f98f269714c08dc6d66d021d166cf36059bc4 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Fri, 13 Jun 2014 17:44:40 +0900 Subject: drm/exynos: hdmi: fix power order issue This patch resolves page fault issue of Mixer when disabled. The SFRs of VP and Mixer are updated by Vertical Sync of Timing generator which is a part of HDMI so the sequence to disable TV Subsystem should be as following: VP -> Mixer -> HDMI For this, this patch disables Mixer and VP (if used) prior to disabling HDMI. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_hdmi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index c104d0c9b385..aa259b0a873a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2090,6 +2090,11 @@ out: static void hdmi_dpms(struct exynos_drm_display *display, int mode) { + struct hdmi_context *hdata = display->ctx; + struct drm_encoder *encoder = hdata->encoder; + struct drm_crtc *crtc = encoder->crtc; + struct drm_crtc_helper_funcs *funcs = NULL; + DRM_DEBUG_KMS("mode %d\n", mode); switch (mode) { @@ -2099,6 +2104,20 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: + /* + * The SFRs of VP and Mixer are updated by Vertical Sync of + * Timing generator which is a part of HDMI so the sequence + * to disable TV Subsystem should be as following, + * VP -> Mixer -> HDMI + * + * Below codes will try to disable Mixer and VP(if used) + * prior to disabling HDMI. + */ + if (crtc) + funcs = crtc->helper_private; + if (funcs && funcs->dpms) + (*funcs->dpms)(crtc, mode); + hdmi_poweroff(display); break; default: -- cgit v1.2.3 From aaa51b13ffdc87ffbbde650bab9dee0a9c5c408f Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 10 Jun 2014 22:57:57 +0200 Subject: drm/exynos: dpi: Fix NULL pointer dereference with legacy bindings If there is no panel node in DT and instead display timings are provided directly in FIMD node, there is no panel object created and ctx->panel becomes NULL. However during Exynos DRM initialization drm_helper_hpd_irq_event() is called, which in turns calls exynos_dpi_detect(), which dereferences ctx->panel without a check, causing a NULL pointer derefrence. This patch fixes the issue by adding necessary NULL pointer check. Signed-off-by: Tomasz Figa Reviewed-by: Jingoo Han Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 482127f633c5..9e530f205ad2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool force) { struct exynos_dpi *ctx = connector_to_dpi(connector); - if (!ctx->panel->connector) + if (ctx->panel && !ctx->panel->connector) drm_panel_attach(ctx->panel, &ctx->connector); return connector_status_connected; -- cgit v1.2.3 From dcdffedaf277cd344c49650ee13e622d74af627c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 11 Jun 2014 09:36:23 +0300 Subject: drm/exynos: change zero to NULL for sparse We recently changed this function to return a pointer instead of an int so we need to change this zero to a NULL or Sparse complains: drivers/gpu/drm/exynos/exynos_drm_drv.h:346:47: warning: Using plain integer as NULL pointer Signed-off-by: Dan Carpenter Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 36535f398848..06cde4506278 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -343,7 +343,7 @@ struct exynos_drm_display * exynos_dpi_probe(struct device *dev); int exynos_dpi_remove(struct device *dev); #else static inline struct exynos_drm_display * -exynos_dpi_probe(struct device *dev) { return 0; } +exynos_dpi_probe(struct device *dev) { return NULL; } static inline int exynos_dpi_remove(struct device *dev) { return 0; } #endif -- cgit v1.2.3 From 0013fc9e550a0f9d2c4a19e553292680b6fdb283 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 17 Jun 2014 17:08:07 +0530 Subject: drm/exynos: Fix de-registration ordering 'exynos_drm_pdev' was not getting unregistered if platform_driver_register() failed. Fix the ordering to allow this. This also fixes the below warning by moving the #endif macro. While at it also fix the ordering in the exit function so that de-registration happens in opposite order of registration. drivers/gpu/drm/exynos/exynos_drm_drv.c:768:1: warning: label 'err_unregister_pd' defined but not used [-Wunused-label] Signed-off-by: Sachin Kamat Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index d91f27777537..ab7d182063c3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -765,24 +765,24 @@ static int exynos_drm_init(void) return 0; -err_unregister_pd: - platform_device_unregister(exynos_drm_pdev); - err_remove_vidi: #ifdef CONFIG_DRM_EXYNOS_VIDI exynos_drm_remove_vidi(); + +err_unregister_pd: #endif + platform_device_unregister(exynos_drm_pdev); return ret; } static void exynos_drm_exit(void) { + platform_driver_unregister(&exynos_drm_platform_driver); #ifdef CONFIG_DRM_EXYNOS_VIDI exynos_drm_remove_vidi(); #endif platform_device_unregister(exynos_drm_pdev); - platform_driver_unregister(&exynos_drm_platform_driver); } module_init(exynos_drm_init); -- cgit v1.2.3 From d9b68d89c2562814aaf67b890709f5aea4f7bf28 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 9 Jun 2014 16:10:59 +0200 Subject: drm/exynos: disable unused windows on apply The patch disables non-enabled HW windows on applying configuration, it will allow to clear windows enabled by bootloader. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index bb45ab2e7384..33161ad38201 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -741,6 +741,8 @@ static void fimd_apply(struct exynos_drm_manager *mgr) win_data = &ctx->win_data[i]; if (win_data->enabled) fimd_win_commit(mgr, i); + else + fimd_win_disable(mgr, i); } fimd_commit(mgr); -- cgit v1.2.3 From b4bfa3c7d0a464a468615e4c6e06b92387115a04 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 23 Jun 2014 11:02:21 +0530 Subject: drm/exynos: set power state variable after enabling clocks and power Power state variable holds the state of the mixer device. Power on and power off functions are toggling these variable at wrong place. State variable should be changed to true only after Runtime PM and clocks are enabled. Else it may result to a situation where mixer registers are accessed with device power enabled. Similar logic for poweroff sequence. Signed-off-by: Rahul Sharma Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 4c5aed7e54c8..c00abbe3cd13 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1061,7 +1061,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) mutex_unlock(&ctx->mixer_mutex); return; } - ctx->powered = true; + mutex_unlock(&ctx->mixer_mutex); pm_runtime_get_sync(ctx->dev); @@ -1072,6 +1072,10 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) clk_prepare_enable(res->sclk_mixer); } + mutex_lock(&ctx->mixer_mutex); + ctx->powered = true; + mutex_unlock(&ctx->mixer_mutex); + mixer_reg_write(res, MXR_INT_EN, ctx->int_en); mixer_win_reset(ctx); @@ -1084,14 +1088,20 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) struct mixer_resources *res = &ctx->mixer_res; mutex_lock(&ctx->mixer_mutex); - if (!ctx->powered) - goto out; + if (!ctx->powered) { + mutex_unlock(&ctx->mixer_mutex); + return; + } mutex_unlock(&ctx->mixer_mutex); mixer_window_suspend(mgr); ctx->int_en = mixer_reg_read(res, MXR_INT_EN); + mutex_lock(&ctx->mixer_mutex); + ctx->powered = false; + mutex_unlock(&ctx->mixer_mutex); + clk_disable_unprepare(res->mixer); if (ctx->vp_enabled) { clk_disable_unprepare(res->vp); @@ -1099,12 +1109,6 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) } pm_runtime_put_sync(ctx->dev); - - mutex_lock(&ctx->mixer_mutex); - ctx->powered = false; - -out: - mutex_unlock(&ctx->mixer_mutex); } static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) -- cgit v1.2.3 From 381be025ac1a6dc8efebdf146ced0d4a6007f77b Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 23 Jun 2014 11:02:22 +0530 Subject: drm/exynos: stop mixer before gating clocks during poweroff Mixer should be power gated only after it is gracefully stopped. The recommended sequence is to Stop the mixer and wait till it enters to IDLE state before gating the clocks and power to the mixer. Signed-off-by: Rahul Sharma Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 15 +++++++++++++++ drivers/gpu/drm/exynos/regs-mixer.h | 1 + 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index c00abbe3cd13..d35950121fc4 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -377,6 +377,20 @@ static void mixer_run(struct mixer_context *ctx) mixer_regs_dump(ctx); } +static void mixer_stop(struct mixer_context *ctx) +{ + struct mixer_resources *res = &ctx->mixer_res; + int timeout = 20; + + mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN); + + while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) && + --timeout) + usleep_range(10000, 12000); + + mixer_regs_dump(ctx); +} + static void vp_video_buffer(struct mixer_context *ctx, int win) { struct mixer_resources *res = &ctx->mixer_res; @@ -1094,6 +1108,7 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) } mutex_unlock(&ctx->mixer_mutex); + mixer_stop(ctx); mixer_window_suspend(mgr); ctx->int_en = mixer_reg_read(res, MXR_INT_EN); diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h index 4537026bc385..5f32e1a29411 100644 --- a/drivers/gpu/drm/exynos/regs-mixer.h +++ b/drivers/gpu/drm/exynos/regs-mixer.h @@ -78,6 +78,7 @@ #define MXR_STATUS_BIG_ENDIAN (1 << 3) #define MXR_STATUS_ENDIAN_MASK (1 << 3) #define MXR_STATUS_SYNC_ENABLE (1 << 2) +#define MXR_STATUS_REG_IDLE (1 << 1) #define MXR_STATUS_REG_RUN (1 << 0) /* bits for MXR_CFG */ -- cgit v1.2.3 From 5b01bd11b78b71ea1f5fc93e6e45ce6d71f5de1b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 23 Jun 2014 14:53:25 -0600 Subject: regulator: palmas: fix typo in enable_reg calculation When setting up .enable_reg for an SMPS regulator, presumably we should call PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, ...) rather than using LDO_BASE. This change makes the LCD panel and HDMI work again on the NVIDIA Dalmore board anyway. Fixes: 318dbb02b50c ("regulator: palmas: Fix SMPS enable/disable/is_enabled") Signed-off-by: Stephen Warren Acked-by: Nishanth Menon Tested-by: Alexandre Courbot Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index f5f522c499ba..327788892cc9 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -968,7 +968,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, palmas_regs_info[id].ctrl_addr); pmic->desc[id].enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; -- cgit v1.2.3 From 967ab6b177ee7111383585639e375d9f67638010 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 May 2014 14:16:30 +0100 Subject: drm/i915: Only mark the ctx as initialised after a SET_CONTEXT operation Fallout from commit 46470fc932ac8a0e8317a220b3f4ea4ed903338e Author: Mika Kuoppala Date: Wed May 21 19:01:06 2014 +0300 drm/i915: Add null state batch to active list undid the earlier fix of only marking the ctx as initialised after it is saved by the hardware during a SET_CONTEXT operation: commit ad1d219974a3d13412268525309c5892f6779ae9 Author: Ben Widawsky Date: Sat Dec 28 13:31:49 2013 -0800 drm/i915: set ctx->initialized only after RCS Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Damien Lespiau Cc: Mika Kuoppala Cc: Ben Widawsky Reviewed-by: Daniel Vetter Reviewed-by: Ben Widawsky [Jani: add reference to the earlier fix in the commit messsage.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_context.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 3ffe308d5893..a5ddf3bce9c3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -598,6 +598,7 @@ static int do_switch(struct intel_engine_cs *ring, struct intel_context *from = ring->last_context; struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); u32 hw_flags = 0; + bool uninitialized = false; int ret, i; if (from != NULL && ring == &dev_priv->ring[RCS]) { @@ -696,19 +697,20 @@ static int do_switch(struct intel_engine_cs *ring, i915_gem_context_unreference(from); } + uninitialized = !to->is_initialized && from == NULL; + to->is_initialized = true; + done: i915_gem_context_reference(to); ring->last_context = to; to->last_ring = ring; - if (ring->id == RCS && !to->is_initialized && from == NULL) { + if (uninitialized) { ret = i915_gem_render_state_init(ring); if (ret) DRM_ERROR("init render state: %d\n", ret); } - to->is_initialized = true; - return 0; unpin_out: -- cgit v1.2.3 From 5b5ffff0d25060ab0e21fa0f6cd16428e87bf1ea Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Jun 2014 09:56:24 +0100 Subject: drm/i915: Hold the table lock whilst walking the file's idr and counting the objects in debugfs Fixes an issue whereby we may race with the table updates (before the core takes the struct_mutex) and so risk dereferencing a stale pointer in the iterator for /debugfs/.../i915_gem_objects. For example, [ 1524.757545] BUG: unable to handle kernel paging request at f53af748 [ 1524.757572] IP: [] per_file_stats+0x12/0x100 [ 1524.757599] *pdpt = 0000000001b13001 *pde = 00000000379fb067 *pte = 80000000353af060 [ 1524.757621] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC [ 1524.757637] Modules linked in: ctr ccm arc4 ath9k ath9k_common ath9k_hw ath snd_hda_codec_conexant mac80211 snd_hda_codec_generic snd_hda_intel snd_hda_controller snd_hda_codec bnep snd_hwdep rfcomm snd_pcm gpio_ich dell_wmi sparse_keymap snd_seq_midi hid_multitouch uvcvideo snd_seq_midi_event dell_laptop snd_rawmidi dcdbas snd_seq videobuf2_vmalloc videobuf2_memops videobuf2_core usbhid videodev snd_seq_device coretemp snd_timer hid joydev kvm_intel cfg80211 ath3k kvm btusb bluetooth serio_raw snd microcode soundcore lpc_ich wmi mac_hid parport_pc ppdev lp parport psmouse ahci libahci [ 1524.757825] CPU: 3 PID: 1911 Comm: intel-gpu-overl Tainted: G W OE 3.15.0-rc3+ #96 [ 1524.757840] Hardware name: Dell Inc. Inspiron 1090/Inspiron 1090, BIOS A06 08/23/2011 [ 1524.757855] task: f52f36c0 ti: f4cbc000 task.ti: f4cbc000 [ 1524.757869] EIP: 0060:[] EFLAGS: 00210202 CPU: 3 [ 1524.757884] EIP is at per_file_stats+0x12/0x100 [ 1524.757896] EAX: 0000002d EBX: 00000000 ECX: f4cbdefc EDX: f53af700 [ 1524.757909] ESI: c1406970 EDI: f53af700 EBP: f4cbde6c ESP: f4cbde5c [ 1524.757922] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 1524.757934] CR0: 80050033 CR2: f53af748 CR3: 356af000 CR4: 000007f0 [ 1524.757945] Stack: [ 1524.757957] f4cbdefc 00000000 c1406970 f53af700 f4cbdea8 c12e5f15 f4cbdefc c1406970 [ 1524.757993] 0000ffff f4cbde90 0000002d f5dc5cd0 e4e80438 c1181d59 f4cbded8 f4d89900 [ 1524.758027] f5631b40 e5131074 c1903f37 f4cbdf28 c14068e6 f52648a0 c1927748 c1903f37 [ 1524.758062] Call Trace: [ 1524.758084] [] ? i915_gem_object_info+0x510/0x510 [ 1524.758106] [] idr_for_each+0xa5/0x100 [ 1524.758126] [] ? i915_gem_object_info+0x510/0x510 [ 1524.758148] [] ? seq_vprintf+0x29/0x50 [ 1524.758168] [] i915_gem_object_info+0x486/0x510 [ 1524.758189] [] seq_read+0xd6/0x380 [ 1524.758208] [] ? final_putname+0x1d/0x40 [ 1524.758227] [] ? seq_hlist_next_percpu+0x90/0x90 [ 1524.758246] [] vfs_read+0x82/0x150 [ 1524.758265] [] SyS_read+0x46/0x90 [ 1524.758285] [] sysenter_do_call+0x12/0x22 [ 1524.758298] Code: f5 8f 2a 00 83 c4 6c 31 c0 5b 5e 5f 5d c3 8d 74 26 00 8d bc 27 00 00 00 00 55 89 e5 57 56 53 83 ec 04 3e 8d 74 26 00 83 41 04 01 <8b> 42 48 01 41 08 8b 42 4c 89 d7 85 c0 75 07 8b 42 60 85 c0 74 [ 1524.758461] EIP: [] per_file_stats+0x12/0x100 SS:ESP 0068:f4cbde5c [ 1524.758485] CR2: 00000000f53af748 Reported-by: Sam Jansen Signed-off-by: Chris Wilson Cc: Sam Jansen Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 601caa88c092..b8c689202c40 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -446,7 +446,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data) memset(&stats, 0, sizeof(stats)); stats.file_priv = file->driver_priv; + spin_lock(&file->table_lock); idr_for_each(&file->object_idr, per_file_stats, &stats); + spin_unlock(&file->table_lock); /* * Although we have a valid reference on file->pid, that does * not guarantee that the task_struct who called get_pid() is -- cgit v1.2.3 From 5c0f4829e187f4d43f5ea5cd72cec343ddcdf594 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 23 Jun 2014 11:02:23 +0530 Subject: drm/exynos: allow multiple layer updates per vsync for mixer Allowing only one layer update per vsync can cause issues while there are update available for both layers. There is a good amount of possibility to loose updates if we allow single update per vsync. Signed-off-by: Rahul Sharma Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index d35950121fc4..6773b03fd921 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -511,13 +511,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) static void mixer_layer_update(struct mixer_context *ctx) { struct mixer_resources *res = &ctx->mixer_res; - u32 val; - - val = mixer_reg_read(res, MXR_CFG); - /* allow one update per vsync only */ - if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK)) - mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); + mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); } static void mixer_graph_buffer(struct mixer_context *ctx, int win) -- cgit v1.2.3 From d74ed93784ca3af005b0f5f1c44d972175bba4ad Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 23 Jun 2014 11:02:24 +0530 Subject: drm/exynos: soft reset mixer before reconfigure after power-on Mixer soft reset is a recommended step before reconfiguring the mixer after power on. Mixer looses the previous state of DMAs if soft reset. This is the recommendation from the hardware team. Signed-off-by: Rahul Sharma Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 6773b03fd921..6f1858187e28 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1085,6 +1085,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) ctx->powered = true; mutex_unlock(&ctx->mixer_mutex); + mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); + mixer_reg_write(res, MXR_INT_EN, ctx->int_en); mixer_win_reset(ctx); -- cgit v1.2.3 From 5d39b9ee8b16b57fdbc065b91ebdd4ac03dab568 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 23 Jun 2014 11:02:25 +0530 Subject: drm/exynos: enable vsync interrupt while waiting for vblank mixer_wait_for_vblank function expects that the upcoming vsync interrupt handler routine will clear the wait_vsync_event atomic variable. For this to happen, interrupts should be enabled and disabled properly. Signed-off-by: Rahul Sharma Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 6f1858187e28..7529946d0a74 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1019,6 +1019,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) } mutex_unlock(&mixer_ctx->mixer_mutex); + drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); + atomic_set(&mixer_ctx->wait_vsync_event, 1); /* @@ -1029,6 +1031,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) !atomic_read(&mixer_ctx->wait_vsync_event), HZ/20)) DRM_DEBUG_KMS("vblank wait timed out.\n"); + + drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe); } static void mixer_window_suspend(struct exynos_drm_manager *mgr) -- cgit v1.2.3 From 8922a908908ff947f1f211e07e2e97f1169ad3cb Mon Sep 17 00:00:00 2001 From: Ulrich Obergfell Date: Wed, 4 Jun 2014 13:34:57 +0200 Subject: scsi_error: fix invalid setting of host byte After scsi_try_to_abort_cmd returns, the eh_abort_handler may have already found that the command has completed in the device, causing the host_byte to be nonzero (e.g. it could be DID_ABORT). When this happens, ORing DID_TIME_OUT into the host byte will corrupt the result field and initiate an unwanted command retry. Fix this by using set_host_byte instead, following the model of commit 2082ebc45af9c9c648383b8cde0dc1948eadbf31. Cc: stable@vger.kernel.org Signed-off-by: Ulrich Obergfell [Fix all instances according to review comments. - Paolo] Signed-off-by: Paolo Bonzini Signed-off-by: Christoph Hellwig Reviewed-by: Ewan D. Milne Reviewed-by: Hannes Reinecke --- drivers/scsi/scsi_error.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index cbe38e5e7955..55ecf70fe3d9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -131,7 +131,7 @@ scmd_eh_abort_handler(struct work_struct *work) "aborting command %p\n", scmd)); rtn = scsi_try_to_abort_cmd(sdev->host->hostt, scmd); if (rtn == SUCCESS) { - scmd->result |= DID_TIME_OUT << 16; + set_host_byte(scmd, DID_TIME_OUT); if (scsi_host_eh_past_deadline(sdev->host)) { SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd, @@ -167,7 +167,7 @@ scmd_eh_abort_handler(struct work_struct *work) scmd_printk(KERN_WARNING, scmd, "scmd %p terminate " "aborted command\n", scmd)); - scmd->result |= DID_TIME_OUT << 16; + set_host_byte(scmd, DID_TIME_OUT); scsi_finish_command(scmd); } } @@ -291,7 +291,7 @@ enum blk_eh_timer_return scsi_times_out(struct request *req) if (scsi_abort_command(scmd) == SUCCESS) return BLK_EH_NOT_HANDLED; - scmd->result |= DID_TIME_OUT << 16; + set_host_byte(scmd, DID_TIME_OUT); if (unlikely(rtn == BLK_EH_NOT_HANDLED && !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) @@ -1777,7 +1777,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) break; case DID_ABORT: if (scmd->eh_eflags & SCSI_EH_ABORT_SCHEDULED) { - scmd->result |= DID_TIME_OUT << 16; + set_host_byte(scmd, DID_TIME_OUT); return SUCCESS; } case DID_NO_CONNECT: -- cgit v1.2.3 From a33c070bced8b283e22e8dbae35177a033b810bf Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 13 Jun 2014 14:01:45 +0200 Subject: scsi_error: set DID_TIME_OUT correctly Any callbacks in scsi_timeout_out() might return BLK_EH_RESET_TIMER, in which case we should leave the result alone and not set DID_TIME_OUT, as the command didn't actually timeout. Signed-off-by: Hannes Reinecke Signed-off-by: Christoph Hellwig Reviewed-by: Ewan D. Milne --- drivers/scsi/scsi_error.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 55ecf70fe3d9..7e957918f33f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -287,15 +287,15 @@ enum blk_eh_timer_return scsi_times_out(struct request *req) else if (host->hostt->eh_timed_out) rtn = host->hostt->eh_timed_out(scmd); - if (rtn == BLK_EH_NOT_HANDLED && !host->hostt->no_async_abort) - if (scsi_abort_command(scmd) == SUCCESS) + if (rtn == BLK_EH_NOT_HANDLED) { + if (!host->hostt->no_async_abort && + scsi_abort_command(scmd) == SUCCESS) return BLK_EH_NOT_HANDLED; - set_host_byte(scmd, DID_TIME_OUT); - - if (unlikely(rtn == BLK_EH_NOT_HANDLED && - !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) - rtn = BLK_EH_HANDLED; + set_host_byte(scmd, DID_TIME_OUT); + if (!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) + rtn = BLK_EH_HANDLED; + } return rtn; } -- cgit v1.2.3 From d2fa87c3af0df7ed10463afc588affdab954fa92 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 10:17:47 -0500 Subject: regulator: tps65218: Add the missing of_node assignment in probe Add the missing of_node assignment in probe. Fixes: 90e7d5262796 (regulator: tps65218: Add Regulator driver for TPS65218 PMIC) Signed-off-by: Keerthy Signed-off-by: Felipe Balbi Signed-off-by: Mark Brown Cc: # v3.15 --- drivers/regulator/tps65218-regulator.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 69b4b7750410..edbc46e56e41 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -240,6 +240,7 @@ static int tps65218_regulator_probe(struct platform_device *pdev) config.init_data = init_data; config.driver_data = tps; config.regmap = tps->regmap; + config.of_node = pdev->dev.of_node; rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config); if (IS_ERR(rdev)) { -- cgit v1.2.3 From 0eada6a1fc85a98ce69a199e46925abd6a7001c2 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 10:17:48 -0500 Subject: regulator: tps65218: Correct the the config register for LDO1 Correct the the config register for LDO1. Fixes: 90e7d5262796 (regulator: tps65218: Add Regulator driver for TPS65218 PMIC) Signed-off-by: Keerthy Signed-off-by: Felipe Balbi Signed-off-by: Mark Brown Cc: # v3.15 --- drivers/regulator/tps65218-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index edbc46e56e41..9effe48c605e 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -209,7 +209,7 @@ static const struct regulator_desc regulators[] = { 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, - TPS65218_REG_CONTROL_DCDC4, + TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, 2, 0), -- cgit v1.2.3 From 6fcfb0d682a8212d321a6131adc94daf0905992a Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 24 Jun 2014 17:14:40 +0300 Subject: xhci: Use correct SLOT ID when handling a reset device command Command completion events normally include command completion status, SLOT_ID, and a pointer to the original command. Reset device command completion SLOT_ID may be zero according to xhci specs 4.6.11. VIA controllers set the SLOT_ID to zero, triggering a WARN_ON in the command completion handler. Use the SLOT ID found from the original command instead. This patch should be applied to stable kernels since 3.13 that contain the commit 20e7acb13ff48fbc884d5918c3697c27de63922a "xhci: use completion event's slot id rather than dig it out of command" Cc: stable@vger.kernel.org # 3.13 Reported-by: Saran Neti Tested-by: Saran Neti Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d67ff71209f5..71657d39a578 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1433,8 +1433,11 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code); break; case TRB_RESET_DEV: - WARN_ON(slot_id != TRB_TO_SLOT_ID( - le32_to_cpu(cmd_trb->generic.field[3]))); + /* SLOT_ID field in reset device cmd completion event TRB is 0. + * Use the SLOT_ID from the command TRB instead (xhci 4.6.11) + */ + slot_id = TRB_TO_SLOT_ID( + le32_to_cpu(cmd_trb->generic.field[3])); xhci_handle_cmd_reset_dev(xhci, slot_id, event); break; case TRB_NEC_GET_FW: -- cgit v1.2.3 From 3213b151387df0b95f4eada104f68eb1c1409cb3 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 24 Jun 2014 17:14:41 +0300 Subject: xhci: correct burst count field for isoc transfers on 1.0 xhci hosts The transfer burst count (TBC) field in xhci 1.0 hosts should be set to the number of bursts needed to transfer all packets in a isoc TD. Supported values are 0-2 (1 to 3 bursts per service interval). Formula for TBC calculation is given in xhci spec section 4.11.2.3: TBC = roundup( Transfer Descriptor Packet Count / Max Burst Size +1 ) - 1 This patch should be applied to stable kernels since 3.0 that contain the commit 5cd43e33b9519143f06f507dd7cbee6b7a621885 "xhci 1.0: Set transfer burst count field." Cc: stable@vger.kernel.org # 3.0 Suggested-by: ShiChun Ma Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 71657d39a578..749fc68eb5c1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3537,7 +3537,7 @@ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci, return 0; max_burst = urb->ep->ss_ep_comp.bMaxBurst; - return roundup(total_packet_count, max_burst + 1) - 1; + return DIV_ROUND_UP(total_packet_count, max_burst + 1) - 1; } /* -- cgit v1.2.3 From ff8cbf250b448aac35589f6075082c3fcad8a8fe Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 24 Jun 2014 17:14:43 +0300 Subject: xhci: clear root port wake on bits if controller isn't wake-up capable When xHCI PCI host is suspended, if do_wakeup is false in xhci_pci_suspend, xhci_bus_suspend needs to clear all root port wake on bits. Otherwise some Intel platforms may get a spurious wakeup, even if PCI PME# is disabled. This patch should be back-ported to kernels as old as 2.6.37, that contains the commit 9777e3ce907d4cb5a513902a87ecd03b52499569 "USB: xHCI: bus power management implementation". Cc: stable@vger.kernel.org # 2.6.37 Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 2b998c60faf2..aa79e8749040 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -22,6 +22,7 @@ #include +#include #include #include "xhci.h" @@ -1139,7 +1140,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd) * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME * is enabled, so also enable remote wake here. */ - if (hcd->self.root_hub->do_remote_wakeup) { + if (hcd->self.root_hub->do_remote_wakeup + && device_may_wakeup(hcd->self.controller)) { + if (t1 & PORT_CONNECT) { t2 |= PORT_WKOC_E | PORT_WKDISC_E; t2 &= ~PORT_WKCONN_E; -- cgit v1.2.3 From d6236f6d1d885aa19d1cd7317346fe795227a3cc Mon Sep 17 00:00:00 2001 From: Wang, Yu Date: Tue, 24 Jun 2014 17:14:44 +0300 Subject: xhci: Fix runtime suspended xhci from blocking system suspend. The system suspend flow as following: 1, Freeze all user processes and kenrel threads. 2, Try to suspend all devices. 2.1, If pci device is in RPM suspended state, then pci driver will try to resume it to RPM active state in the prepare stage. 2.2, xhci_resume function calls usb_hcd_resume_root_hub to queue two workqueue items to resume usb2&usb3 roothub devices. 2.3, Call suspend callbacks of devices. 2.3.1, All suspend callbacks of all hcd's children, including roothub devices are called. 2.3.2, Finally, hcd_pci_suspend callback is called. Due to workqueue threads were already frozen in step 1, the workqueue items can't be scheduled, and the roothub devices can't be resumed in this flow. The HCD_FLAG_WAKEUP_PENDING flag which is set in usb_hcd_resume_root_hub won't be cleared. Finally, hcd_pci_suspend will return -EBUSY, and system suspend fails. The reason why this issue doesn't show up very often is due to that choose_wakeup will be called in step 2.3.1. In step 2.3.1, if udev->do_remote_wakeup is not equal to device_may_wakeup(&udev->dev), then udev will resume to RPM active for changing the wakeup settings. This has been a lucky hit which hides this issue. For some special xHCI controllers which have no USB2 port, then roothub will not match hub driver due to probe failed. Then its do_remote_wakeup will be set to zero, and we won't be as lucky. xhci driver doesn't need to resume roothub devices everytime like in the above case. It's only needed when there are pending event TRBs. This patch should be back-ported to kernels as old as 3.2, that contains the commit f69e3120df82391a0ee8118e0a156239a06b2afb "USB: XHCI: resume root hubs when the controller resumes" Cc: stable@vger.kernel.org # 3.2 Signed-off-by: Wang, Yu Acked-by: Alan Stern [use readl() instead of removed xhci_readl(), reword commit message -Mathias] Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2b8d9a24af09..7436d5f5e67a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -936,7 +936,7 @@ int xhci_suspend(struct xhci_hcd *xhci) */ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) { - u32 command, temp = 0; + u32 command, temp = 0, status; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; int retval = 0; @@ -1054,8 +1054,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) done: if (retval == 0) { - usb_hcd_resume_root_hub(hcd); - usb_hcd_resume_root_hub(xhci->shared_hcd); + /* Resume root hubs only when have pending events. */ + status = readl(&xhci->op_regs->status); + if (status & STS_EINT) { + usb_hcd_resume_root_hub(hcd); + usb_hcd_resume_root_hub(xhci->shared_hcd); + } } /* -- cgit v1.2.3 From 72cbaa3d2f563d7b48c9f8aef47ec9aa3a31adf2 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Tue, 24 Jun 2014 16:54:23 -0400 Subject: ahci: disable ncq feature for hisilicon sata NCQ feature is unsupported on hisilicon sata controller, so disable it. This version of IP is used by hip04 and hix5hd2 soc. tj: "|=" was replaced with "=" for no reason. Restored "|=". Signed-off-by: Kefeng Wang Sigend-off-by: Tejun Heo --- drivers/ata/ahci_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index ebe505c17763..b10d81ddb528 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -58,7 +58,7 @@ static int ahci_probe(struct platform_device *pdev) } if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) - hflags |= AHCI_HFLAG_NO_FBS; + hflags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, hflags, 0, 0); -- cgit v1.2.3 From f118ae5901172dacc4f272acf5eccfba06e8d221 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 23 Jun 2014 12:59:08 +0100 Subject: ata: ahci_imx: warn when disabling ahci link When the AHCI link is disabled, it can't be re-enabled except by resetting the entire SoC. Rather than doing this silently print some kernel messages to inform the user, along with how to avoid this. tj: Put a long printf format string on a single line. Signed-off-by: Russell King Signed-off-by: Tejun Heo --- drivers/ata/ahci_imx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 4384a7d72133..cac4360f272a 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -326,6 +326,9 @@ static void ahci_imx_error_handler(struct ata_port *ap) writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR); imx_sata_disable(hpriv); imxpriv->no_device = true; + + dev_info(ap->dev, "no device found, disabling link.\n"); + dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX ".hotplug=1 to enable hotplug\n"); } static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, -- cgit v1.2.3 From 1539fb9bd405ee32282ea0a38404f9e008ac5b7a Mon Sep 17 00:00:00 2001 From: Zhaowei Yuan Date: Wed, 18 Jun 2014 14:33:59 +0800 Subject: drm: fix NULL pointer access by wrong ioctl If user uses wrong ioctl command with _IOC_NONE and argument size greater than 0, it can cause NULL pointer access from memset of line 463. If _IOC_NONE, don't memset to 0 for kdata. Signed-off-by: Zhaowei Yuan Reviewed-by: David Herrmann Cc: Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 drivers/gpu/drm/drm_drv.c (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c old mode 100644 new mode 100755 index 03711d00aaae..8218078b6133 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -419,8 +419,9 @@ long drm_ioctl(struct file *filp, retcode = -EFAULT; goto err_i1; } - } else + } else if (cmd & IOC_OUT) { memset(kdata, 0, usize); + } if (ioctl->flags & DRM_UNLOCKED) retcode = func(dev, kdata, file_priv); -- cgit v1.2.3 From 8525a235c96a548873c6c5644f50df32b31f04c6 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Wed, 25 Jun 2014 12:20:39 +0530 Subject: drm/i915: vlv_prepare_pll is only needed in case of non DSI interfaces For MIPI, DSI PLL is configured separately in vlv_configure_dsi_pll during the DSI enable sequence Causing WARN dump otherwise in dpio_reads v2: Add IS_CHERRYVIEW check as suggested by Ville Signed-off-by: Shobhit Kumar Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9188fede99ef..5f285fba4e41 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4564,7 +4564,10 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->active) return; - vlv_prepare_pll(intel_crtc); + is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); + + if (!is_dsi && !IS_CHERRYVIEW(dev)) + vlv_prepare_pll(intel_crtc); /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -4598,8 +4601,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (encoder->pre_pll_enable) encoder->pre_pll_enable(encoder); - is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); - if (!is_dsi) { if (IS_CHERRYVIEW(dev)) chv_enable_pll(intel_crtc); -- cgit v1.2.3 From 5f2d25efa4c4567fa72b70de4e041252c72aa10e Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Fri, 6 Jun 2014 14:06:30 +0200 Subject: be2iscsi: add an missing goto in error path a jump to 'free_memory' is apparently missing Signed-off-by: Tomas Henzl Reviewed-by: Mike Christie Signed-off-by: Christoph Hellwig --- drivers/scsi/be2iscsi/be_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 554349029628..56467df3d6de 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4198,6 +4198,8 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) kfree(phba->ep_array); phba->ep_array = NULL; ret = -ENOMEM; + + goto free_memory; } for (i = 0; i < phba->params.cxns_per_ctrl; i++) { -- cgit v1.2.3 From beff65497ab12821c65739557c77d85bdd4ca618 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Fri, 6 Jun 2014 14:22:44 +0200 Subject: be2iscsi: remove potential junk pointer free commit 0e7c60c [SCSI] be2iscsi: fix memory leak in error path fixed an potential junk pointer free if mgmt_get_if_info() returned an error fix it on one more place Signed-off-by: Tomas Henzl Reviewed-by: Mike Christie Signed-off-by: Christoph Hellwig --- drivers/scsi/be2iscsi/be_mgmt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 6045aa78986a..07934b0b9ee1 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -1008,10 +1008,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba, BE2_IPV6 : BE2_IPV4 ; rc = mgmt_get_if_info(phba, ip_type, &if_info); - if (rc) { - kfree(if_info); + if (rc) return rc; - } if (boot_proto == ISCSI_BOOTPROTO_DHCP) { if (if_info->dhcp_state) { -- cgit v1.2.3 From f2c6f180c98e1a8bc84781f32894b595363d3dfb Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 17 Jun 2014 13:15:40 +0200 Subject: pm8001: Fix potential null pointer dereference and memory leak. The pm8001_get_phy_settings_info() function does not check the kzalloc() return value and does not free the allocated memory. Signed-off-by: Maurizio Lombardi Acked-by: Suresh Thiagarajan Acked-by: Jack Wang Signed-off-by: Christoph Hellwig --- drivers/scsi/pm8001/pm8001_init.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index c4f31b21feb8..e90c89f1d480 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -677,7 +677,7 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) * pm8001_get_phy_settings_info : Read phy setting values. * @pm8001_ha : our hba. */ -void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) +static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) { #ifdef PM8001_READ_VPD @@ -691,11 +691,15 @@ void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) payload.offset = 0; payload.length = 4096; payload.func_specific = kzalloc(4096, GFP_KERNEL); + if (!payload.func_specific) + return -ENOMEM; /* Read phy setting values from flash */ PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); wait_for_completion(&completion); pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific); + kfree(payload.func_specific); #endif + return 0; } #ifdef PM8001_USE_MSIX @@ -879,8 +883,11 @@ static int pm8001_pci_probe(struct pci_dev *pdev, pm8001_init_sas_add(pm8001_ha); /* phy setting support for motherboard controller */ if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 && - pdev->subsystem_vendor != 0) - pm8001_get_phy_settings_info(pm8001_ha); + pdev->subsystem_vendor != 0) { + rc = pm8001_get_phy_settings_info(pm8001_ha); + if (rc) + goto err_out_shost; + } pm8001_post_sas_ha_init(shost, chip); rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); if (rc) -- cgit v1.2.3 From 0353e085edb0f11e040cf91e71d831ec07943b20 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 23 Jun 2014 10:40:25 -0400 Subject: fc: ensure scan_work isn't active when freeing fc_rport debugfs caught this: WARNING: at lib/debugobjects.c:260 debug_print_object+0x83/0xa0() ODEBUG: free active (active state 0) object type: work_struct hint: fc_scsi_scan_rport+0x0/0xd0 [scsi_transport_fc] CPU: 1 PID: 184 Comm: kworker/1:1 Tainted: G W -------------- 3.10.0-123.el7.x86_64.debug #1 Hardware name: HP ProLiant DL120 G7, BIOS J01 07/01/2013 Workqueue: fc_wq_5 fc_rport_final_delete [scsi_transport_fc] Call Trace: [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x61/0x80 [] warn_slowpath_fmt+0x5c/0x80 [] debug_print_object+0x83/0xa0 [] ? fc_parse_wwn+0x100/0x100 [] debug_check_no_obj_freed+0x22b/0x270 [] ? fc_rport_dev_release+0x1e/0x30 [] kfree+0xd9/0x2d0 [] fc_rport_dev_release+0x1e/0x30 [] device_release+0x32/0xa0 [] kobject_release+0x7e/0x1b0 [] kobject_put+0x28/0x60 [] put_device+0x17/0x20 [] fc_rport_final_delete+0x165/0x210 [] process_one_work+0x220/0x710 [] ? process_one_work+0x1b4/0x710 [] worker_thread+0x11b/0x3a0 [] ? process_one_work+0x710/0x710 [] kthread+0xed/0x100 [] ? insert_kthread_work+0x80/0x80 [] ret_from_fork+0x7c/0xb0 [] ? insert_kthread_work+0x80/0x80 Seems to be because the scan_work work_struct might be active when the housing fc_rport struct gets freed. Ensure that we cancel it prior to freeing the rport Signed-off-by: Neil Horman Reviewed-by: Vasu Dev Reviewed-by: Hannes Reinecke Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi_transport_fc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f80908f74ca9..521f5838594b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -2549,6 +2549,7 @@ fc_rport_final_delete(struct work_struct *work) fc_flush_devloss(shost); if (!cancel_delayed_work(&rport->dev_loss_work)) fc_flush_devloss(shost); + cancel_work_sync(&rport->scan_work); spin_lock_irqsave(shost->host_lock, flags); rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; } -- cgit v1.2.3 From 9172b763a776bae644d140748a0352fc67277a4c Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Thu, 19 Jun 2014 15:05:00 +0200 Subject: bnx2fc: do not scan uninitialized lists in case of error. In case of of error, the bnx2fc_cmd_mgr_alloc() function will call the bnx2fc_cmd_mgr_free() to perform the cleanup. The problem is that in one case the latter may try to scan some not-yet initialized lists, resulting in a kernel panic. This patch prevents this from happening by freeing the lists before calling bnx2fc_cmd_mgr_free(). Signed-off-by: Maurizio Lombardi Acked-by: Eddie Wai Signed-off-by: Christoph Hellwig --- drivers/scsi/bnx2fc/bnx2fc_io.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 32a5e0a2a669..7bc47fc7c686 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -282,6 +282,8 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) arr_sz, GFP_KERNEL); if (!cmgr->free_list_lock) { printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); + kfree(cmgr->free_list); + cmgr->free_list = NULL; goto mem_err; } -- cgit v1.2.3 From d576a5e80cd07ea7049f8fd7b303c14df7b5d7d2 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 23 Jun 2014 10:41:02 -0400 Subject: bnx2fc: Improve stats update mechanism Recently had this warning reported: [ 290.489047] Call Trace: [ 290.489053] [] dump_stack+0x19/0x1b [ 290.489055] [] __might_sleep+0x179/0x230 [ 290.489057] [] mutex_lock_nested+0x55/0x520 [ 290.489061] [] ? bnx2fc_l2_rcv_thread+0xc5/0x4c0 [bnx2fc] [ 290.489065] [] fc_vport_id_lookup+0x3a/0xa0 [libfc] [ 290.489068] [] bnx2fc_l2_rcv_thread+0x22c/0x4c0 [bnx2fc] [ 290.489070] [] ? bnx2fc_vport_destroy+0x110/0x110 [bnx2fc] [ 290.489073] [] kthread+0xed/0x100 [ 290.489075] [] ? insert_kthread_work+0x80/0x80 [ 290.489077] [] ret_from_fork+0x7c/0xb0 [ 290.489078] [] ? insert_kthread_work+0x80/0x80 Its due to the fact that we call a potentially sleeping function from the bnx2fc rcv path with preemption disabled (via the get_cpu call embedded in the per-cpu variable stats lookup in bnx2fc_l2_rcv_thread. Easy enough fix, we can just move the stats collection later in the function where we are sure we won't preempt or sleep. This also allows us to not have to enable pre-emption when doing a per-cpu lookup, since we're certain not to get rescheduled. Signed-off-by: Neil Horman Acked-by: Eddie Wai Signed-off-by: Christoph Hellwig --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index f54843023466..785d0d71781e 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -516,23 +516,17 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) skb_pull(skb, sizeof(struct fcoe_hdr)); fr_len = skb->len - sizeof(struct fcoe_crc_eof); - stats = per_cpu_ptr(lport->stats, get_cpu()); - stats->RxFrames++; - stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; - fp = (struct fc_frame *)skb; fc_frame_init(fp); fr_dev(fp) = lport; fr_sof(fp) = hp->fcoe_sof; if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) { - put_cpu(); kfree_skb(skb); return; } fr_eof(fp) = crc_eof.fcoe_eof; fr_crc(fp) = crc_eof.fcoe_crc32; if (pskb_trim(skb, fr_len)) { - put_cpu(); kfree_skb(skb); return; } @@ -544,7 +538,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) port = lport_priv(vn_port); if (!ether_addr_equal(port->data_src_addr, dest_mac)) { BNX2FC_HBA_DBG(lport, "fpma mismatch\n"); - put_cpu(); kfree_skb(skb); return; } @@ -552,7 +545,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP) { /* Drop FCP data. We dont this in L2 path */ - put_cpu(); kfree_skb(skb); return; } @@ -562,7 +554,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) case ELS_LOGO: if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { /* drop non-FIP LOGO */ - put_cpu(); kfree_skb(skb); return; } @@ -572,22 +563,23 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) { /* Drop incoming ABTS */ - put_cpu(); kfree_skb(skb); return; } + stats = per_cpu_ptr(lport->stats, smp_processor_id()); + stats->RxFrames++; + stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; + if (le32_to_cpu(fr_crc(fp)) != ~crc32(~0, skb->data, fr_len)) { if (stats->InvalidCRCCount < 5) printk(KERN_WARNING PFX "dropping frame with " "CRC error\n"); stats->InvalidCRCCount++; - put_cpu(); kfree_skb(skb); return; } - put_cpu(); fc_exch_recv(lport, fp); } -- cgit v1.2.3 From 33a5fcee7f5d4920ff33997169e02cc34cbab6e6 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Tue, 24 Jun 2014 00:22:29 -0400 Subject: qla2xxx: Fix sparse warning in qla_target.c. Signed-off-by: Quinn Tran Signed-off-by: Saurav Kashyap Signed-off-by: Christoph Hellwig --- drivers/scsi/qla2xxx/qla_target.c | 17 +++++++++++------ drivers/scsi/qla2xxx/qla_target.h | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 4b188b0164e9..e632e14180cf 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1128,7 +1128,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, ctio->u.status1.flags = __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_TERMINATE); - ctio->u.status1.ox_id = entry->fcp_hdr_le.ox_id; + ctio->u.status1.ox_id = cpu_to_le16(entry->fcp_hdr_le.ox_id); qla2x00_start_iocbs(vha, vha->req); @@ -1262,6 +1262,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, { struct atio_from_isp *atio = &mcmd->orig_iocb.atio; struct ctio7_to_24xx *ctio; + uint16_t temp; ql_dbg(ql_dbg_tgt, ha, 0xe008, "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n", @@ -1292,7 +1293,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, ctio->u.status1.flags = (atio->u.isp24.attr << 9) | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS); - ctio->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); + temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); + ctio->u.status1.ox_id = cpu_to_le16(temp); ctio->u.status1.scsi_status = __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); ctio->u.status1.response_len = __constant_cpu_to_le16(8); @@ -1513,6 +1515,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, struct ctio7_to_24xx *pkt; struct qla_hw_data *ha = vha->hw; struct atio_from_isp *atio = &prm->cmd->atio; + uint16_t temp; pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr; prm->pkt = pkt; @@ -1541,13 +1544,13 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; pkt->exchange_addr = atio->u.isp24.exchange_addr; pkt->u.status0.flags |= (atio->u.isp24.attr << 9); - pkt->u.status0.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); + temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); + pkt->u.status0.ox_id = cpu_to_le16(temp); pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset); ql_dbg(ql_dbg_tgt, vha, 0xe00c, "qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n", - vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, - le16_to_cpu(pkt->u.status0.ox_id)); + vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, temp); return 0; } @@ -2619,6 +2622,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, struct qla_hw_data *ha = vha->hw; request_t *pkt; int ret = 0; + uint16_t temp; ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha); @@ -2655,7 +2659,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha, ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_TERMINATE); - ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); + temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); + ctio24->u.status1.ox_id = cpu_to_le16(temp); /* Most likely, it isn't needed */ ctio24->u.status1.residual = get_unaligned((uint32_t *) diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index e0a58fd13f66..d1d24fb0160a 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -443,7 +443,7 @@ struct ctio7_to_24xx { uint16_t reserved1; __le16 flags; uint32_t residual; - uint16_t ox_id; + __le16 ox_id; uint16_t scsi_status; uint32_t relative_offset; uint32_t reserved2; @@ -458,7 +458,7 @@ struct ctio7_to_24xx { uint16_t sense_length; uint16_t flags; uint32_t residual; - uint16_t ox_id; + __le16 ox_id; uint16_t scsi_status; uint16_t response_len; uint16_t reserved; -- cgit v1.2.3 From 9ee755974bea2f9880e517ec985dc9dede1b3a36 Mon Sep 17 00:00:00 2001 From: Brian King Date: Fri, 23 May 2014 10:52:10 -0500 Subject: ibmvscsi: Abort init sequence during error recovery If a CRQ reset is triggered for some reason while in the middle of performing VSCSI adapter initialization, we don't want to call the done function for the initialization MAD commands as this will only result in two threads attempting initialization at the same time, resulting in failures. Signed-off-by: Brian King Acked-by: Nathan Fontenot Cc: stable@vger.kernel.org Signed-off-by: Christoph Hellwig --- drivers/scsi/ibmvscsi/ibmvscsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 2ebfb2bb0f42..9caf9a979659 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -797,7 +797,8 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) evt->hostdata->dev); if (evt->cmnd_done) evt->cmnd_done(evt->cmnd); - } else if (evt->done) + } else if (evt->done && evt->crq.format != VIOSRP_MAD_FORMAT && + evt->iu.srp.login_req.opcode != SRP_LOGIN_REQ) evt->done(evt); free_event_struct(&evt->hostdata->pool, evt); spin_lock_irqsave(hostdata->host->host_lock, flags); -- cgit v1.2.3 From 7114aae02742d6b5c5a0d39a41deb61d415d3717 Mon Sep 17 00:00:00 2001 From: Brian King Date: Fri, 23 May 2014 10:52:11 -0500 Subject: ibmvscsi: Add memory barriers for send / receive Add a memory barrier prior to sending a new command to the VIOS to ensure the VIOS does not receive stale data in the command buffer. Also add a memory barrier when processing the CRQ for completed commands. Signed-off-by: Brian King Acked-by: Nathan Fontenot Cc: stable@vger.kernel.org Signed-off-by: Christoph Hellwig --- drivers/scsi/ibmvscsi/ibmvscsi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 9caf9a979659..7b23f21f22f1 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -185,6 +185,11 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) if (crq->valid & 0x80) { if (++queue->cur == queue->size) queue->cur = 0; + + /* Ensure the read of the valid bit occurs before reading any + * other bits of the CRQ entry + */ + rmb(); } else crq = NULL; spin_unlock_irqrestore(&queue->lock, flags); @@ -203,6 +208,11 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, { struct vio_dev *vdev = to_vio_dev(hostdata->dev); + /* + * Ensure the command buffer is flushed to memory before handing it + * over to the VIOS to prevent it from fetching any stale data. + */ + mb(); return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); } -- cgit v1.2.3 From cdda0e5acbb78f7b777049f8c27899e5c5bb368f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 4 Jun 2014 13:34:56 +0200 Subject: virtio-scsi: avoid cancelling uninitialized work items Calling the workqueue interface on uninitialized work items isn't a good idea even if they're zeroed. It's not failing catastrophically only through happy accidents. Signed-off-by: Paolo Bonzini Reviewed-by: Stefan Hajnoczi Cc: stable@vger.kernel.org Signed-off-by: Christoph Hellwig --- drivers/scsi/virtio_scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 89ee5929eb6d..bcad917fd89a 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -253,6 +253,8 @@ static void virtscsi_ctrl_done(struct virtqueue *vq) virtscsi_vq_done(vscsi, &vscsi->ctrl_vq, virtscsi_complete_free); }; +static void virtscsi_handle_event(struct work_struct *work); + static int virtscsi_kick_event(struct virtio_scsi *vscsi, struct virtio_scsi_event_node *event_node) { @@ -260,6 +262,7 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi, struct scatterlist sg; unsigned long flags; + INIT_WORK(&event_node->work, virtscsi_handle_event); sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event)); spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); @@ -377,7 +380,6 @@ static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf) { struct virtio_scsi_event_node *event_node = buf; - INIT_WORK(&event_node->work, virtscsi_handle_event); schedule_work(&event_node->work); } -- cgit v1.2.3 From 8faeb529b2dabb9df691d614dda18910a43d05c9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 4 Jun 2014 13:34:58 +0200 Subject: virtio-scsi: fix various bad behavior on aborted requests Even though the virtio-scsi spec guarantees that all requests related to the TMF will have been completed by the time the TMF itself completes, the request queue's callback might not have run yet. This causes requests to be completed more than once, and as a result triggers a variety of BUGs or oopses. Signed-off-by: Paolo Bonzini Reviewed-by: Venkatesh Srinivas Cc: stable@vger.kernel.org Signed-off-by: Christoph Hellwig --- drivers/scsi/virtio_scsi.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index bcad917fd89a..308256b5e4cb 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -237,6 +237,16 @@ static void virtscsi_req_done(struct virtqueue *vq) virtscsi_vq_done(vscsi, req_vq, virtscsi_complete_cmd); }; +static void virtscsi_poll_requests(struct virtio_scsi *vscsi) +{ + int i, num_vqs; + + num_vqs = vscsi->num_queues; + for (i = 0; i < num_vqs; i++) + virtscsi_vq_done(vscsi, &vscsi->req_vqs[i], + virtscsi_complete_cmd); +} + static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf) { struct virtio_scsi_cmd *cmd = buf; @@ -591,6 +601,18 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) ret = SUCCESS; + /* + * The spec guarantees that all requests related to the TMF have + * been completed, but the callback might not have run yet if + * we're using independent interrupts (e.g. MSI). Poll the + * virtqueues once. + * + * In the abort case, sc->scsi_done will do nothing, because + * the block layer must have detected a timeout and as a result + * REQ_ATOM_COMPLETE has been set. + */ + virtscsi_poll_requests(vscsi); + out: mempool_free(cmd, virtscsi_cmd_pool); return ret; -- cgit v1.2.3 From 54ed4ed8f9a5071a3bbae2e037376d8c02b9629b Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Wed, 25 Jun 2014 17:52:38 +0200 Subject: drbd: fix NULL pointer deref in blk_add_request_payload Discards don't have any payload. But the scsi layer still expects a bio_vec it can use internally, see sd_setup_discard_cmnd() and blk_add_request_payload(). Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_receiver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index b6c8aaf4931b..5b17ec88ea05 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1337,8 +1337,11 @@ int drbd_submit_peer_request(struct drbd_device *device, return 0; } + /* Discards don't have any payload. + * But the scsi layer still expects a bio_vec it can use internally, + * see sd_setup_discard_cmnd() and blk_add_request_payload(). */ if (peer_req->flags & EE_IS_TRIM) - nr_pages = 0; /* discards don't have any payload. */ + nr_pages = 1; /* In most cases, we will only need one bio. But in case the lower * level restrictions happen to be different at this offset on this -- cgit v1.2.3 From 5bb7889f440532f3dbbffdb6b3b0881a805abbce Mon Sep 17 00:00:00 2001 From: Levente Kurusa Date: Wed, 2 Apr 2014 12:00:37 +0200 Subject: TC: Handle device_register() errors. Make the TURBOchannel driver bail out if the call to device_register() failed. Signed-off-by: Levente Kurusa Acked-by: Maciej W. Rozycki Cc: LKML Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/6673/ Signed-off-by: Ralf Baechle --- drivers/tc/tc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index a8aaf6ac2ae2..946562389ca8 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c @@ -129,7 +129,10 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) tc_device_get_irq(tdev); - device_register(&tdev->dev); + if (device_register(&tdev->dev)) { + put_device(&tdev->dev); + goto out_err; + } list_add_tail(&tdev->node, &tbus->devices); out_err: @@ -148,7 +151,10 @@ static int __init tc_init(void) INIT_LIST_HEAD(&tc_bus.devices); dev_set_name(&tc_bus.dev, "tc"); - device_register(&tc_bus.dev); + if (device_register(&tc_bus.dev)) { + put_device(&tc_bus.dev); + return 0; + } if (tc_bus.info.slot_size) { unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000; -- cgit v1.2.3 From 2e48cecb55435e10c93c6aface1a1c7ef32f4e71 Mon Sep 17 00:00:00 2001 From: Guido Martínez Date: Tue, 17 Jun 2014 11:17:03 -0300 Subject: drm/i2c: tda998x: move drm_i2c_encoder_destroy call Currently tda998x_encoder_destroy() calls cec_write() and reg_clear(), as part of the release procedure. Such calls need to access the I2C bus and therefore, we need to call them before drm_i2c_encoder_destroy() which unregisters the I2C device. This commit moves the latter so it's done afterwards. Signed-off-by: Guido Martínez Signed-off-by: Ezequiel García Cc: #v3.9+ Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 48af5cac1902..b98c969aeffa 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1183,7 +1183,6 @@ static void tda998x_encoder_destroy(struct drm_encoder *encoder) { struct tda998x_priv *priv = to_tda998x_priv(encoder); - drm_i2c_encoder_destroy(encoder); /* disable all IRQs and free the IRQ handler */ cec_write(priv, REG_CEC_RXSHPDINTENA, 0); @@ -1193,6 +1192,7 @@ tda998x_encoder_destroy(struct drm_encoder *encoder) if (priv->cec) i2c_unregister_device(priv->cec); + drm_i2c_encoder_destroy(encoder); kfree(priv); } -- cgit v1.2.3 From 713456db179356c6b32a50ea1910fc509615c457 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 3 Mar 2014 14:09:36 +0000 Subject: drm/i2c: tda998x: faster polling for edid One of Jean-Francois patches changed the EDID polling to once every 10ms for 10 interations, whereas the original code did 1ms for 100 interations. This appears to cause boot-time detection to take noticably longer. Revert this change. Acked-by: Jean-Francois Moine Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index b98c969aeffa..3ff7d0713bfb 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1048,8 +1048,8 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) return i; } } else { - for (i = 10; i > 0; i--) { - msleep(10); + for (i = 100; i > 0; i--) { + msleep(1); ret = reg_read(priv, REG_INT_FLAGS_2); if (ret < 0) return ret; -- cgit v1.2.3 From 92fbdfcd7d6b9db6b0a738c5bd85a4a9d731629d Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 7 Feb 2014 19:52:33 +0000 Subject: drm/i2c: tda998x: add some basic mode validation The TDA998x can't handle modes with clocks above 150MHz, or resolutions larger than 8192x2048. Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 3ff7d0713bfb..5a738ad0c241 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -810,6 +810,12 @@ static int tda998x_encoder_mode_valid(struct drm_encoder *encoder, struct drm_display_mode *mode) { + if (mode->clock > 150000) + return MODE_CLOCK_HIGH; + if (mode->htotal >= BIT(13)) + return MODE_BAD_HVALUE; + if (mode->vtotal >= BIT(11)) + return MODE_BAD_VVALUE; return MODE_OK; } -- cgit v1.2.3 From 74c0554ac79ef5aecfeb087bc08771363b221c99 Mon Sep 17 00:00:00 2001 From: Emil Goode Date: Fri, 20 Jun 2014 23:50:37 +0200 Subject: video: vt8500lcdfb: Remove kfree call since devm_kzalloc() is used We use devm_kzalloc() to allocate memory for the struct vt8500lcd_info pointer fbi, so there is no need to free it in vt8500lcd_remove(). Signed-off-by: Emil Goode Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/vt8500lcdfb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c index a8f2b280f796..a1134c3f6c11 100644 --- a/drivers/video/fbdev/vt8500lcdfb.c +++ b/drivers/video/fbdev/vt8500lcdfb.c @@ -474,8 +474,6 @@ static int vt8500lcd_remove(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); - kfree(fbi); - return 0; } -- cgit v1.2.3 From 06f7d7931752ee1bd0903a38b1086c7ea5e10cdf Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 30 May 2014 15:56:34 +0530 Subject: video: omapdss: Fix potential null pointer dereference kmalloc can return null. Add a check to avoid potential null pointer dereference error when the pointer is accessed later. Signed-off-by: Sachin Kamat Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/omapdss-boot-init.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c index 99af9e88b2d8..2f0822ee3ff9 100644 --- a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c +++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c @@ -121,9 +121,11 @@ static void __init omapdss_add_to_list(struct device_node *node, bool root) { struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node), GFP_KERNEL); - n->node = node; - n->root = root; - list_add(&n->list, &dss_conv_list); + if (n) { + n->node = node; + n->root = root; + list_add(&n->list, &dss_conv_list); + } } static bool __init omapdss_list_contains(const struct device_node *node) -- cgit v1.2.3 From 1c93c725d61642511f02a3293bcd7e694d0397d2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Jun 2014 23:24:12 +0200 Subject: mfd: UCB1x00: Enable modular build The UCB1200 / UCB1300 driver uses the MCP_SA11X0 driver, which can be a loadable module, but this results in a link error when UCB1200 itself is built-in: drivers/built-in.o: In function `ucb1x00_io_set_dir': :(.text+0x4a364): undefined reference to `mcp_reg_write' drivers/built-in.o: In function `ucb1x00_io_write': :(.text+0x4a3dc): undefined reference to `mcp_reg_write' drivers/built-in.o: In function `ucb1x00_io_read': :(.text+0x4a400): undefined reference to `mcp_reg_read' drivers/built-in.o: In function `ucb1x00_adc_enable': :(.text+0x4a460): undefined reference to `mcp_enable' ... This can easily be resolved by making CONFIG_MCP_UCB1200 itself a tristate option, since that causes Kconfig to track the dependency correctly. Signed-off-by: Arnd Bergmann Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ee8204cc31e9..43706928ef86 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1248,7 +1248,7 @@ config MCP_SA11X0 # Chip drivers config MCP_UCB1200 - bool "Support for UCB1200 / UCB1300" + tristate "Support for UCB1200 / UCB1300" depends on MCP_SA11X0 select MCP -- cgit v1.2.3 From f41716dc52b4a8887070318a41745e2edb612906 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Jun 2014 23:24:14 +0200 Subject: mfd: STw481x: Allow modular build This driver depends on I2C, which may be a loadable module. While you'd probably want both to be built-in in practice, allowing a modular build avoids possible randconfig link errors. Signed-off-by: Arnd Bergmann Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 43706928ef86..e1f02c8290ab 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1225,7 +1225,7 @@ config MFD_WM8994 functionaltiy of the device other drivers must be enabled. config MFD_STW481X - bool "Support for ST Microelectronics STw481x" + tristate "Support for ST Microelectronics STw481x" depends on I2C && ARCH_NOMADIK select REGMAP_I2C select MFD_CORE -- cgit v1.2.3 From 9e8884872dd4e26ec18413fe1f817bf81d023713 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 Jun 2014 23:24:13 +0200 Subject: mfd: davinci: Voicecodec needs regmap_mmio Without REGMAP_MMIO, building that driver results in a link error: drivers/built-in.o: In function `davinci_vc_probe': :(.init.text+0x3c1c): undefined reference to `devm_regmap_init_mmio_clk' This adds a Kconfig 'select' statement as the usual way to ensure that REGMAP_MMIO is enabled. Signed-off-by: Arnd Bergmann Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e1f02c8290ab..6cc4b6acc22a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -760,6 +760,7 @@ config MFD_SYSCON config MFD_DAVINCI_VOICECODEC tristate select MFD_CORE + select REGMAP_MMIO config MFD_TI_AM335X_TSCADC tristate "TI ADC / Touch Screen chip support" -- cgit v1.2.3 From 7602e05df73f3c775d5ef808c0bc4af9711e4438 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 2 Jun 2014 19:27:58 +0300 Subject: mfd: ab8500: Fix dt irq mapping The AD8500 defines itself as interrupt-controller in DT, but it doesn't assign DT node to IRQ domain when creates it. As result, of_irq_xx() helpers don't work because they can't find necessary IRQ domain. Hence, fix it by assigning AD8500 core device DT node to IRQ domain when it's created. This patch fixes STE u8500 Snowball boot failure reported by Kevin Hilman https://lkml.org/lkml/2014/5/27/624 Reported-and-tested-by: Kevin Hilman Signed-off-by: Grygorii Strashko Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/ab8500-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index a8ee4a36a1d8..cf2e6a198c6b 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -591,7 +591,7 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np) num_irqs = AB8500_NR_IRQS; /* If ->irq_base is zero this will give a linear mapping */ - ab8500->domain = irq_domain_add_simple(NULL, + ab8500->domain = irq_domain_add_simple(ab8500->dev->of_node, num_irqs, 0, &ab8500_irq_ops, ab8500); -- cgit v1.2.3 From a67a6ed15513541579d38bcbd127e7be170710e5 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Thu, 19 Jun 2014 20:13:38 -0700 Subject: of: Check for phys_addr_t overflows in early_init_dt_add_memory_arch The common early_init_dt_add_memory_arch takes the base and size of a memory region as u64 types. The function never checks if the base and size can actually fit in a phys_addr_t which may be smaller than 64-bits. This may result in incorrect memory being passed to memblock_add if the memory falls outside the range of phys_addr_t. Add range checks for the base and size if phys_addr_t is smaller than u64. Reported-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Laura Abbott Acked-by: Nicolas Pitre Signed-off-by: Grant Likely --- drivers/of/fdt.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c4cddf0cd96d..b777d8f46bd5 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -880,6 +880,21 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) const u64 phys_offset = __pa(PAGE_OFFSET); base &= PAGE_MASK; size &= PAGE_MASK; + + if (sizeof(phys_addr_t) < sizeof(u64)) { + if (base > ULONG_MAX) { + pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", + base, base + size); + return; + } + + if (base + size > ULONG_MAX) { + pr_warning("Ignoring memory range 0x%lx - 0x%llx\n", + ULONG_MAX, base + size); + size = ULONG_MAX - base; + } + } + if (base + size < phys_offset) { pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", base, base + size); -- cgit v1.2.3 From 73413ffac3b713231dac466bca216f970042c5e5 Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Wed, 25 Jun 2014 12:22:56 +0800 Subject: bnx2x: Fix the MSI flags MSI-X should use PCI_MSIX_FLAGS not PCI_MSI_FLAGS. Signed-off-by: Yijing Wang Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 2887034523e0..6a8b1453a1b9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12937,7 +12937,7 @@ static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev, int cnic_cnt) * without the default SB. * For VFs there is no default SB, then we return (index+1). */ - pci_read_config_word(pdev, pdev->msix_cap + PCI_MSI_FLAGS, &control); + pci_read_config_word(pdev, pdev->msix_cap + PCI_MSIX_FLAGS, &control); index = control & PCI_MSIX_FLAGS_QSIZE; -- cgit v1.2.3 From ff4f58f0ca5dee33a80a72393dd195de9284702b Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 24 Jun 2014 00:24:25 -0500 Subject: staging: tidspbridge: fix an erroneous removal of parentheses Commit 4a9fdbb (staging: core: tiomap3430.c Fix line over 80 characters.) erroneously removed the parentheses around the function pointer leading to the following build error (when enabling the build of TI DSP/Bridge driver): drivers/staging/tidspbridge/core/tiomap3430.c: In function 'bridge_brd_monitor': drivers/staging/tidspbridge/core/tiomap3430.c:283:10: error: invalid type argument of unary '*' (have 'u32') make[3]: *** [drivers/staging/tidspbridge/core/tiomap3430.o] Error 1 Fix this build error properly. Fixes: 4a9fdbb (staging: core: tiomap3430.c Fix line over 80 characters.) Cc: Aybuke Ozdemir Cc: Peter P Waskiewicz Jr Cc: Omar Ramirez Luna Signed-off-by: Suman Anna Cc: stable # 3.15 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/core/tiomap3430.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 8945b4e3a2a6..cb50120ed7b5 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -280,8 +280,10 @@ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt) OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); /* Wait until the state has moved to ON */ - while (*pdata->dsp_prm_read(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST)& - OMAP_INTRANSITION_MASK); + while ((*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, + OMAP2_PM_PWSTST) & + OMAP_INTRANSITION_MASK) + ; /* Disable Automatic transition */ (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); -- cgit v1.2.3 From b06eef6eab8e4a241f88385527ac4d1844abc18d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 13 Jun 2014 04:05:16 +0000 Subject: iscsi-target: Convert chap_server_compute_md5 to use kstrtoul This patch converts chap_server_compute_md5() from simple_strtoul() to kstrtoul usage(). This addresses the case where a empty 'CHAP_I=' key value received during mutual authentication would be converted to a '0' by simple_strtoul(), instead of failing the login attempt. Reported-by: Tejas Vaykole Tested-by: Tejas Vaykole Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_auth.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index 19b842c3e0b3..9430eea7c0d6 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c @@ -174,7 +174,6 @@ static int chap_server_compute_md5( char *nr_out_ptr, unsigned int *nr_out_len) { - char *endptr; unsigned long id; unsigned char id_as_uchar; unsigned char digest[MD5_SIGNATURE_SIZE]; @@ -320,9 +319,14 @@ static int chap_server_compute_md5( } if (type == HEX) - id = simple_strtoul(&identifier[2], &endptr, 0); + ret = kstrtoul(&identifier[2], 0, &id); else - id = simple_strtoul(identifier, &endptr, 0); + ret = kstrtoul(identifier, 0, &id); + + if (ret < 0) { + pr_err("kstrtoul() failed for CHAP identifier: %d\n", ret); + goto out; + } if (id > 255) { pr_err("chap identifier: %lu greater than 255\n", id); goto out; -- cgit v1.2.3 From e4fae2318b5ddd7aec0e65871f1b455b796cf33d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 13 Jun 2014 04:28:31 +0000 Subject: iscsi-target; Enforce 1024 byte maximum for CHAP_C key value This patch adds a check in chap_server_compute_md5() to enforce a 1024 byte maximum for the CHAP_C key value following the requirement in RFC-3720 Section 11.1.4: "..., C and R are large-binary-values and their binary length (not the length of the character string that represents them in encoded form) MUST not exceed 1024 bytes." Reported-by: rahul.rane Tested-by: rahul.rane Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_auth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index 9430eea7c0d6..ab4915c0d933 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c @@ -355,6 +355,10 @@ static int chap_server_compute_md5( pr_err("Unable to convert incoming challenge\n"); goto out; } + if (challenge_len > 1024) { + pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n"); + goto out; + } /* * During mutual authentication, the CHAP_C generated by the * initiator must not match the original CHAP_C generated by -- cgit v1.2.3 From 83ff42fcce070801a3aa1cd6a3269d7426271a8d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Mon, 16 Jun 2014 20:25:54 +0000 Subject: target: Fix left-over se_lun->lun_sep pointer OOPs This patch fixes a left-over se_lun->lun_sep pointer OOPs when one of the /sys/kernel/config/target/$FABRIC/$WWPN/$TPGT/lun/$LUN/alua* attributes is accessed after the $DEVICE symlink has been removed. To address this bug, go ahead and clear se_lun->lun_sep memory in core_dev_unexport(), so that the existing checks for show/store ALUA attributes in target_core_fabric_configfs.c work as expected. Reported-by: Sebastian Herbszt Tested-by: Sebastian Herbszt Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 11d26fe65bfb..98da90167159 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -616,6 +616,7 @@ void core_dev_unexport( dev->export_count--; spin_unlock(&hba->device_lock); + lun->lun_sep = NULL; lun->lun_se_dev = NULL; } -- cgit v1.2.3 From 683497566d48f86e04d026de1ee658dd74fc1077 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Tue, 17 Jun 2014 21:54:38 +0000 Subject: iscsi-target: Explicily clear login response PDU in exception path This patch adds a explicit memset to the login response PDU exception path in iscsit_tx_login_rsp(). This addresses a regression bug introduced in commit baa4d64b where the initiator would end up not receiving the login response and associated status class + detail, before closing the login connection. Reported-by: Christophe Vu-Brugier Tested-by: Christophe Vu-Brugier Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 53e157cb8c54..fd90b28f1d94 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -1295,6 +1295,8 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta login->login_failed = 1; iscsit_collect_login_stats(conn, status_class, status_detail); + memset(&login->rsp[0], 0, ISCSI_HDR_LEN); + hdr = (struct iscsi_login_rsp *)&login->rsp[0]; hdr->opcode = ISCSI_OP_LOGIN_RSP; hdr->status_class = status_class; -- cgit v1.2.3 From b43f1886e4d3ea3f68665eaea96526ccdd53741d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Tue, 17 Jun 2014 22:23:03 +0000 Subject: tcm_loop: Fix memory leak in tcm_loop_submission_work error path This patch fixes a tcm_loop_cmd descriptor memory leak in the tcm_loop_submission_work() error path, and would result in warnings about leaked tcm_loop_cmd_cache objects at module unload time. Go ahead and invoke kmem_cache_free() to release tl_cmd back to tcm_loop_cmd_cache before calling sc->scsi_done(). Reported-by: Sebastian Herbszt Tested-by: Sebastian Herbszt Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 6d2f37578b29..8c64b8776a96 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -239,6 +239,7 @@ static void tcm_loop_submission_work(struct work_struct *work) return; out_done: + kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); sc->scsi_done(sc); return; } -- cgit v1.2.3 From 783ee43118dc773bc8b0342c5b230e017d5a04d0 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Mon, 9 Jun 2014 16:50:40 +0200 Subject: efi-pstore: Fix an overflow on 32-bit builds In generic_id the long int timestamp is multiplied by 100000 and needs an explicit cast to u64. Without that the id in the resulting pstore filename is wrong and userspace may have problems parsing it, but more importantly files in pstore can never be deleted and may fill the EFI flash (brick device?). This happens because when generic pstore code wants to delete a file, it passes the id to the EFI backend which reinterpretes it and a wrong variable name is attempted to be deleted. There's no error message but after remounting pstore, deleted files would reappear. Signed-off-by: Andrew Zaborowski Acked-by: David Rientjes Cc: Signed-off-by: Matt Fleming --- drivers/firmware/efi/efi-pstore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index 4b9dc836dcf9..e992abc5ef26 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -40,7 +40,7 @@ struct pstore_read_data { static inline u64 generic_id(unsigned long timestamp, unsigned int part, int count) { - return (timestamp * 100 + part) * 1000 + count; + return ((u64) timestamp * 100 + part) * 1000 + count; } static int efi_pstore_read_func(struct efivar_entry *entry, void *data) -- cgit v1.2.3 From e556756a6326d55dcbb476d471dcda36814fd696 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 9 Jun 2014 15:11:13 +0200 Subject: i2c: mux: pca954x: fix dependencies This driver causes the following randconfig build error: drivers/i2c/muxes/i2c-mux-pca954x.c: In function ‘pca954x_probe’: drivers/i2c/muxes/i2c-mux-pca954x.c:204:2: error: implicit declaration of function ‘devm_gpiod_get’ [-Werror=implicit-function-declaration] gpio = devm_gpiod_get(&client->dev, "reset"); ^ drivers/i2c/muxes/i2c-mux-pca954x.c:204:7: warning: assignment makes pointer from integer without a cast [enabled by default] gpio = devm_gpiod_get(&client->dev, "reset"); ^ drivers/i2c/muxes/i2c-mux-pca954x.c:206:3: error: implicit declaration of function ‘gpiod_direction_output’ [-Werror=implicit-function-declaration] gpiod_direction_output(gpio, 0); ^ cc1: some warnings being treated as errors make[3]: *** [drivers/i2c/muxes/i2c-mux-pca954x.o] Error 1 This is because it is getting compiled without gpiolib, so introduce an explicit dependency. Reported-by: Jim Davis Signed-off-by: Linus Walleij Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index f7f9865b8b89..f6d313e528de 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -40,6 +40,7 @@ config I2C_MUX_PCA9541 config I2C_MUX_PCA954x tristate "Philips PCA954x I2C Mux/switches" + depends on GPIOLIB help If you say yes here you get support for the Philips PCA954x I2C mux/switch devices. -- cgit v1.2.3 From 098aebc30292c10b31f6aa58bf4fe2c4b26001f6 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 24 Jun 2014 09:25:28 +0530 Subject: i2c: sun6i-p2wi: Remove duplicate inclusion of module.h module.h was included twice. Signed-off-by: Sachin Kamat Acked-by: Boris BREZILLON Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-sun6i-p2wi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c index 09de4fd12d57..4d75d4759709 100644 --- a/drivers/i2c/busses/i2c-sun6i-p2wi.c +++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c @@ -22,7 +22,6 @@ * */ #include -#include #include #include #include -- cgit v1.2.3 From 66e5482752386786c4346f4f4b214b0998639702 Mon Sep 17 00:00:00 2001 From: John Sung Date: Fri, 27 Jun 2014 16:22:08 +0800 Subject: HID: usbhid: quirk for PM1610 and PM1640 Touchscreen. These device needs to be added to the quirks list with HID_QUIRK_NOGET, otherwise they will reset upon receiving the get input report requests. Signed-off-by: John Sung Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 2 ++ drivers/hid/usbhid/hid-quirks.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6d00bb9366fa..1efeb12a38c7 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -715,6 +715,8 @@ #define USB_VENDOR_ID_PENMOUNT 0x14e1 #define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 +#define USB_DEVICE_ID_PENMOUNT_1610 0x1610 +#define USB_DEVICE_ID_PENMOUNT_1640 0x1640 #define USB_VENDOR_ID_PETALYNX 0x18b1 #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 59badc10a08c..fbaefc34ee95 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -76,6 +76,8 @@ static const struct hid_blacklist { { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, -- cgit v1.2.3 From 33c3b0d19184cb11bfe8cf8e552918650f81f767 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 24 Jun 2014 13:59:28 +0300 Subject: drm/i915: Wait for vblank after enabling the primary plane on BDW BDW signals the flip done interrupt immediately after the DSPSURF write when the plane is disabled. This is true even if we've already armed DSPCNTR to enable the plane at the next vblank. This causes major problems for our page flip code which relies on the flip done interrupts happening at vblank time. So what happens is that we enable the plane, and immediately allow userspace to submit a page flip. If the plane is still in the process of being enabled when the page flip is issued, the flip done gets signalled immediately. Our DSPSURFLIVE check catches this to prevent premature flip completion, but it also means that we don't get a flip done interrupt when the plane actually gets enabled, and so the page flip is never completed. Work around this by re-introducing blocking vblank waits on BDW whenever we enable the primary plane. I removed some of the vblank waits here: commit 6304cd91e7f05f8802ea6f91287cac09741d9c46 Author: Ville Syrjälä Date: Fri Apr 25 13:30:12 2014 +0300 drm/i915: Drop the excessive vblank waits from modeset codepaths To avoid these blocking vblank waits we should start using the vblank interrupt instead of the flip done interrupt to complete page flips. But that's material for another patch. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79354 Tested-by: Guo Jinxian Signed-off-by: Ville Syrjälä Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 9 +++++++++ drivers/gpu/drm/i915/intel_sprite.c | 8 ++++++++ 2 files changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5f285fba4e41..33725ed9215a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2087,6 +2087,7 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv, static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, enum plane plane, enum pipe pipe) { + struct drm_device *dev = dev_priv->dev; struct intel_crtc *intel_crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); int reg; @@ -2106,6 +2107,14 @@ static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); intel_flush_primary_plane(dev_priv, plane); + + /* + * BDW signals flip done immediately if the plane + * is disabled, even if the plane enable is already + * armed to occur at the next vblank :( + */ + if (IS_BROADWELL(dev)) + intel_wait_for_vblank(dev, intel_crtc->pipe); } /** diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 1b66ddcdfb33..9a17b4e92ef4 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -690,6 +690,14 @@ intel_post_enable_primary(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + /* + * BDW signals flip done immediately if the plane + * is disabled, even if the plane enable is already + * armed to occur at the next vblank :( + */ + if (IS_BROADWELL(dev)) + intel_wait_for_vblank(dev, intel_crtc->pipe); + /* * FIXME IPS should be fine as long as one plane is * enabled, but in practice it seems to have problems -- cgit v1.2.3 From 7adb5c876e9c0677078a1e1094c6eafd29c30b74 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 23 Jun 2014 15:34:22 -0300 Subject: usb: musb: Fix panic upon musb_am335x module removal At probe time, the musb_am335x driver register its childs by calling of_platform_populate(), which registers all childs in the devicetree hierarchy recursively. On the other side, the driver's remove() function uses of_device_unregister() to remove each child of musb_am335x's. However, when musb_dsps is loaded, its devices are attached to the musb_am335x device as musb_am335x childs. Hence, musb_am335x remove() will attempt to unregister the devices registered by musb_dsps, which produces a kernel panic. In other words, the childs in the "struct device" hierarchy are not the same as the childs in the "devicetree" hierarchy. Ideally, we should enforce the removal of the devices registered by musb_am335x *only*, instead of all its child devices. However, because of the recursive nature of of_platform_populate, this doesn't seem possible. Therefore, as the only solution at hand, this commit disables musb_am335x driver removal capability, preventing it from being ever removed. This was originally suggested by Sebastian Siewior: https://www.mail-archive.com/linux-omap@vger.kernel.org/msg104946.html And for reference, here's the panic upon module removal: musb-hdrc musb-hdrc.0.auto: remove, state 4 usb usb1: USB disconnect, device number 1 musb-hdrc musb-hdrc.0.auto: USB bus 1 deregistered Unable to handle kernel NULL pointer dereference at virtual address 0000008c pgd = de11c000 [0000008c] *pgd=9e174831, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] ARM Modules linked in: musb_am335x(-) musb_dsps musb_hdrc usbcore usb_common CPU: 0 PID: 623 Comm: modprobe Not tainted 3.15.0-rc4-00001-g24efd13 #69 task: de1b7500 ti: de122000 task.ti: de122000 PC is at am335x_shutdown+0x10/0x28 LR is at am335x_shutdown+0xc/0x28 pc : [] lr : [] psr: a0000013 sp : de123df8 ip : 00000004 fp : 00028f00 r10: 00000000 r9 : de122000 r8 : c000e6c4 r7 : de0e3c10 r6 : de0e3800 r5 : de624010 r4 : de1ec750 r3 : de0e3810 r2 : 00000000 r1 : 00000001 r0 : 00000000 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c5387d Table: 9e11c019 DAC: 00000015 Process modprobe (pid: 623, stack limit = 0xde122240) Stack: (0xde123df8 to 0xde124000) 3de0: de0e3810 bf054488 3e00: bf05444c de624010 60000013 bf043650 000012fc de624010 de0e3810 bf043a20 3e20: de0e3810 bf04b240 c0635b88 c02ca37c c02ca364 c02c8db0 de1b7500 de0e3844 3e40: de0e3810 c02c8e28 c0635b88 de02824c de0e3810 c02c884c de0e3800 de0e3810 3e60: de0e3818 c02c5b20 bf05417c de0e3800 de0e3800 c0635b88 de0f2410 c02ca838 3e80: bf05417c de0e3800 bf055438 c02ca8cc de0e3c10 bf054194 de0e3c10 c02ca37c 3ea0: c02ca364 c02c8db0 de1b7500 de0e3c44 de0e3c10 c02c8e28 c0635b88 de02824c 3ec0: de0e3c10 c02c884c de0e3c10 de0e3c10 de0e3c18 c02c5b20 de0e3c10 de0e3c10 3ee0: 00000000 bf059000 a0000013 c02c5bc0 00000000 bf05900c de0e3c10 c02c5c48 3f00: de0dd0c0 de1ec970 de0f2410 bf05929c de0f2444 bf05902c de0f2410 c02ca37c 3f20: c02ca364 c02c8db0 bf05929c de0f2410 bf05929c c02c94c8 bf05929c 00000000 3f40: 00000800 c02c8ab4 bf0592e0 c007fc40 c00dd820 6273756d 336d615f 00783533 3f60: c064a0ac de1b7500 de122000 de1b7500 c000e590 00000001 c000e6c4 c0060160 3f80: 00028e70 00028e70 00028ea4 00000081 60000010 00028e70 00028e70 00028ea4 3fa0: 00000081 c000e500 00028e70 00028e70 00028ea4 00000800 becb59f8 00027608 3fc0: 00028e70 00028e70 00028ea4 00000081 00000001 00000001 00000000 00028f00 3fe0: b6e6b6f0 becb59d4 000160e8 b6e6b6fc 60000010 00028ea4 00000000 00000000 [] (am335x_shutdown) from [] (dsps_musb_exit+0x3c/0x4c [musb_dsps]) [] (dsps_musb_exit [musb_dsps]) from [] (musb_shutdown+0x80/0x90 [musb_hdrc]) [] (musb_shutdown [musb_hdrc]) from [] (musb_remove+0x24/0x68 [musb_hdrc]) [] (musb_remove [musb_hdrc]) from [] (platform_drv_remove+0x18/0x1c) [] (platform_drv_remove) from [] (__device_release_driver+0x70/0xc8) [] (__device_release_driver) from [] (device_release_driver+0x20/0x2c) [] (device_release_driver) from [] (bus_remove_device+0xdc/0x10c) [] (bus_remove_device) from [] (device_del+0x104/0x198) [] (device_del) from [] (platform_device_del+0x14/0x9c) [] (platform_device_del) from [] (platform_device_unregister+0xc/0x20) [] (platform_device_unregister) from [] (dsps_remove+0x18/0x38 [musb_dsps]) [] (dsps_remove [musb_dsps]) from [] (platform_drv_remove+0x18/0x1c) [] (platform_drv_remove) from [] (__device_release_driver+0x70/0xc8) [] (__device_release_driver) from [] (device_release_driver+0x20/0x2c) [] (device_release_driver) from [] (bus_remove_device+0xdc/0x10c) [] (bus_remove_device) from [] (device_del+0x104/0x198) [] (device_del) from [] (device_unregister+0xc/0x20) [] (device_unregister) from [] (of_remove_populated_child+0xc/0x14 [musb_am335x]) [] (of_remove_populated_child [musb_am335x]) from [] (device_for_each_child+0x44/0x70) [] (device_for_each_child) from [] (am335x_child_remove+0x18/0x30 [musb_am335x]) [] (am335x_child_remove [musb_am335x]) from [] (platform_drv_remove+0x18/0x1c) [] (platform_drv_remove) from [] (__device_release_driver+0x70/0xc8) [] (__device_release_driver) from [] (driver_detach+0xb4/0xb8) [] (driver_detach) from [] (bus_remove_driver+0x4c/0xa0) [] (bus_remove_driver) from [] (SyS_delete_module+0x128/0x1cc) [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x48) Fixes: 97238b35d5bb ("usb: musb: dsps: use proper child nodes") Cc: # v3.12+ Acked-by: George Cherian Signed-off-by: Ezequiel Garcia Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_am335x.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_am335x.c b/drivers/usb/musb/musb_am335x.c index d2353781bd2d..1e58ed2361cc 100644 --- a/drivers/usb/musb/musb_am335x.c +++ b/drivers/usb/musb/musb_am335x.c @@ -19,21 +19,6 @@ err: return ret; } -static int of_remove_populated_child(struct device *dev, void *d) -{ - struct platform_device *pdev = to_platform_device(dev); - - of_device_unregister(pdev); - return 0; -} - -static int am335x_child_remove(struct platform_device *pdev) -{ - device_for_each_child(&pdev->dev, NULL, of_remove_populated_child); - pm_runtime_disable(&pdev->dev); - return 0; -} - static const struct of_device_id am335x_child_of_match[] = { { .compatible = "ti,am33xx-usb" }, { }, @@ -42,13 +27,17 @@ MODULE_DEVICE_TABLE(of, am335x_child_of_match); static struct platform_driver am335x_child_driver = { .probe = am335x_child_probe, - .remove = am335x_child_remove, .driver = { .name = "am335x-usb-childs", .of_match_table = am335x_child_of_match, }, }; -module_platform_driver(am335x_child_driver); +static int __init am335x_child_init(void) +{ + return platform_driver_register(&am335x_child_driver); +} +module_init(am335x_child_init); + MODULE_DESCRIPTION("AM33xx child devices"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 6ee96cc0004c084df22fc1d5d9e2cef2d38d8010 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Thu, 26 Jun 2014 13:07:48 +0200 Subject: usb: gadget: gr_udc: Fix check for invalid number of microframes The value 0x3 (not 0x11) in the field for additional transaction/microframe is reserved and should not be let through. Be clear in the error message about what value caused the error return. Reported-by: David Binderman Signed-off-by: Andreas Larsson Signed-off-by: Felipe Balbi --- drivers/usb/gadget/gr_udc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 99a37ed03e27..c7004ee89c90 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c @@ -1532,8 +1532,9 @@ static int gr_ep_enable(struct usb_ep *_ep, "%s mode: multiple trans./microframe not valid\n", (mode == 2 ? "Bulk" : "Control")); return -EINVAL; - } else if (nt == 0x11) { - dev_err(dev->dev, "Invalid value for trans./microframe\n"); + } else if (nt == 0x3) { + dev_err(dev->dev, + "Invalid value 0x3 for additional trans./microframe\n"); return -EINVAL; } else if ((nt + 1) * max > buffer_size) { dev_err(dev->dev, "Hw buffer size %d < max payload %d * %d\n", -- cgit v1.2.3 From c58d80f523ffc15ef4d062fc7aeb03793fe39701 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 20 Jun 2014 23:41:24 +0200 Subject: usb: musb: Ensure that cppi41 timer gets armed on premature DMA TX irq Some TI chips raise the DMA complete interrupt before the actual transfer has been completed. The code tries to busy wait for a few microseconds and if that fails it arms an hrtimer to recheck. So far so good, but that has the following issue: CPU 0 CPU1 start_next_transfer(RQ1); DMA interrupt if (premature_irq(RQ1)) if (!hrtimer_active(timer)) hrtimer_start(timer); hrtimer expires timer->state = CALLBACK_RUNNING; timer->fn() cppi41_recheck_tx_req() complete_request(RQ1); if (requests_pending()) start_next_transfer(RQ2); DMA interrupt if (premature_irq(RQ2)) if (!hrtimer_active(timer)) hrtimer_start(timer); timer->state = INACTIVE; The premature interrupt of request2 on CPU1 does not arm the timer and therefor the request completion never happens because it checks for !hrtimer_active(). hrtimer_active() evaluates: timer->state != HRTIMER_STATE_INACTIVE which of course evaluates to true in the above case as timer->state is CALLBACK_RUNNING. That's clearly documented: * A timer is active, when it is enqueued into the rbtree or the * callback function is running or it's in the state of being migrated * to another cpu. But that's not what the code wants to check. The code wants to check whether the timer is queued, i.e. whether its armed and waiting for expiry. We have a helper function for this: hrtimer_is_queued(). This evaluates: timer->state & HRTIMER_STATE_QUEUED So in the above case this evaluates to false and therefor forces the DMA interrupt on CPU1 to call hrtimer_start(). Use hrtimer_is_queued() instead of hrtimer_active() and evrything is good. Reported-by: Torben Hohn Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_cppi41.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 7b8bbf53127e..5341bb223b7c 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -318,7 +318,7 @@ static void cppi41_dma_callback(void *private_data) } list_add_tail(&cppi41_channel->tx_check, &controller->early_tx_list); - if (!hrtimer_active(&controller->early_tx)) { + if (!hrtimer_is_queued(&controller->early_tx)) { hrtimer_start_range_ns(&controller->early_tx, ktime_set(0, 140 * NSEC_PER_USEC), 40 * NSEC_PER_USEC, -- cgit v1.2.3 From 97c99b47ac58bacb7c09e1f47d5d184434f6b06a Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 20 Jun 2014 10:59:57 -0700 Subject: iscsi-target: Avoid rejecting incorrect ITT for Data-Out This patch changes iscsit_check_dataout_hdr() to dump the incoming Data-Out payload when the received ITT is not associated with a WRITE, instead of calling iscsit_reject_cmd() for the non WRITE ITT descriptor. This addresses a bug where an initiator sending an Data-Out for an ITT associated with a READ would end up generating a reject for the READ, eventually resulting in list corruption. Reported-by: Santosh Kulkarni Reported-by: Arshad Hussain Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 5663f4d19d02..1f4c794f5fcc 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1309,7 +1309,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, if (cmd->data_direction != DMA_TO_DEVICE) { pr_err("Command ITT: 0x%08x received DataOUT for a" " NON-WRITE command.\n", cmd->init_task_tag); - return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); + return iscsit_dump_data_payload(conn, payload_length, 1); } se_cmd = &cmd->se_cmd; iscsit_mod_dataout_timer(cmd); -- cgit v1.2.3 From 81a9c5e72bdf7109a65102ca61d8cbd722cf4021 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 23 Jun 2014 13:42:37 -0400 Subject: iscsi-target: fix iscsit_del_np deadlock on unload On uniprocessor preemptible kernel, target core deadlocks on unload. The following events happen: * iscsit_del_np is called * it calls send_sig(SIGINT, np->np_thread, 1); * the scheduler switches to the np_thread * the np_thread is woken up, it sees that kthread_should_stop() returns false, so it doesn't terminate * the np_thread clears signals with flush_signals(current); and goes back to sleep in iscsit_accept_np * the scheduler switches back to iscsit_del_np * iscsit_del_np calls kthread_stop(np->np_thread); * the np_thread is waiting in iscsit_accept_np and it doesn't respond to kthread_stop The deadlock could be resolved if the administrator sends SIGINT signal to the np_thread with killall -INT iscsi_np The reproducible deadlock was introduced in commit db6077fd0b7dd41dc6ff18329cec979379071f87, but the thread-stopping code was racy even before. This patch fixes the problem. Using kthread_should_stop to stop the np_thread is unreliable, so we test np_thread_state instead. If np_thread_state equals ISCSI_NP_THREAD_SHUTDOWN, the thread exits. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_login.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index fecb69535a15..5e71ac609418 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -1216,7 +1216,7 @@ old_sess_out: static int __iscsi_target_login_thread(struct iscsi_np *np) { u8 *buffer, zero_tsih = 0; - int ret = 0, rc, stop; + int ret = 0, rc; struct iscsi_conn *conn = NULL; struct iscsi_login *login; struct iscsi_portal_group *tpg = NULL; @@ -1230,6 +1230,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; complete(&np->np_restart_comp); + } else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) { + spin_unlock_bh(&np->np_thread_lock); + goto exit; } else { np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; } @@ -1422,10 +1425,8 @@ old_sess_out: } out: - stop = kthread_should_stop(); - /* Wait for another socket.. */ - if (!stop) - return 1; + return 1; + exit: iscsi_stop_login_thread_timer(np); spin_lock_bh(&np->np_thread_lock); @@ -1442,7 +1443,7 @@ int iscsi_target_login_thread(void *arg) allow_signal(SIGINT); - while (!kthread_should_stop()) { + while (1) { ret = __iscsi_target_login_thread(np); /* * We break and exit here unless another sock_accept() call -- cgit v1.2.3 From e8db5d6736a712a3e2280c0e31f4b301d85172d8 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Wed, 21 May 2014 16:33:27 +0800 Subject: thermal: hwmon: Make the check for critical temp valid consistent On 05/21/2014 04:22 PM, Aaron Lu wrote: > On 05/21/2014 01:57 PM, Kui Zhang wrote: >> Hello, >> >> I get following error when rmmod thermal. >> >> rmmod thermal >> Killed While dealing with this problem, I found another problem that also results in a kernel crash on thermal module removal: From: Aaron Lu Date: Wed, 21 May 2014 16:05:38 +0800 Subject: [PATCH] thermal: hwmon: Make the check for critical temp valid consistent We used the tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, temp) to decide if we need to create the temp_crit attribute file but we just check if tz->ops->get_crit_temp exists to decide if we need to remove that attribute file. Some ACPI thermal zone doesn't have a valid critical trip point and that would result in removing a non-existent device file on thermal module unload. Cc: All applicable Signed-off-by: Aaron Lu Signed-off-by: Zhang Rui --- drivers/thermal/thermal_hwmon.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index fdb07199d9c2..1967bee4f076 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -140,6 +140,12 @@ thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon, return NULL; } +static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz) +{ + unsigned long temp; + return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp); +} + int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) { struct thermal_hwmon_device *hwmon; @@ -189,21 +195,18 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) if (result) goto free_temp_mem; - if (tz->ops->get_crit_temp) { - unsigned long temperature; - if (!tz->ops->get_crit_temp(tz, &temperature)) { - snprintf(temp->temp_crit.name, - sizeof(temp->temp_crit.name), + if (thermal_zone_crit_temp_valid(tz)) { + snprintf(temp->temp_crit.name, + sizeof(temp->temp_crit.name), "temp%d_crit", hwmon->count); - temp->temp_crit.attr.attr.name = temp->temp_crit.name; - temp->temp_crit.attr.attr.mode = 0444; - temp->temp_crit.attr.show = temp_crit_show; - sysfs_attr_init(&temp->temp_crit.attr.attr); - result = device_create_file(hwmon->device, - &temp->temp_crit.attr); - if (result) - goto unregister_input; - } + temp->temp_crit.attr.attr.name = temp->temp_crit.name; + temp->temp_crit.attr.attr.mode = 0444; + temp->temp_crit.attr.show = temp_crit_show; + sysfs_attr_init(&temp->temp_crit.attr.attr); + result = device_create_file(hwmon->device, + &temp->temp_crit.attr); + if (result) + goto unregister_input; } mutex_lock(&thermal_hwmon_list_lock); @@ -250,7 +253,7 @@ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) } device_remove_file(hwmon->device, &temp->temp_input.attr); - if (tz->ops->get_crit_temp) + if (thermal_zone_crit_temp_valid(tz)) device_remove_file(hwmon->device, &temp->temp_crit.attr); mutex_lock(&thermal_hwmon_list_lock); -- cgit v1.2.3 From ca9521b770c988bb6bb8eea1241f7a487dab6ff1 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 18 Jun 2014 16:32:08 -0700 Subject: thermal: Add braces around suspect code It looks like this code is missing braces, otherwise the if statement shouldn't have been indented. Fix it. Signed-off-by: Stephen Boyd Signed-off-by: Zhang Rui --- drivers/thermal/of-thermal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 04b1be7fa018..a95ee2889b19 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -712,11 +712,12 @@ thermal_of_build_thermal_zone(struct device_node *np) } i = 0; - for_each_child_of_node(child, gchild) + for_each_child_of_node(child, gchild) { ret = thermal_of_populate_bind_params(gchild, &tz->tbps[i++], tz->trips, tz->ntrips); if (ret) goto free_tbps; + } finish: of_node_put(child); -- cgit v1.2.3 From dd354b84d47ec8ca53686bdb3cc1aecdeb75bef5 Mon Sep 17 00:00:00 2001 From: Punit Agrawal Date: Tue, 3 Jun 2014 10:59:58 +0100 Subject: thermal: Bind cooling devices with the correct arguments When binding cooling devices to thermal zones created from the device tree the minimum and maximum cooling states are in the wrong order leading to failure to bind. Fix the order of cooling states in the call to thermal_zone_bind_cooling_device to fix this. Cc:Zhang Rui Signed-off-by: Punit Agrawal Reviewed-by: Stephen Boyd Signed-off-by: Zhang Rui --- drivers/thermal/of-thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index a95ee2889b19..4b2b999b7611 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -156,8 +156,8 @@ static int of_thermal_bind(struct thermal_zone_device *thermal, ret = thermal_zone_bind_cooling_device(thermal, tbp->trip_id, cdev, - tbp->min, - tbp->max); + tbp->max, + tbp->min); if (ret) return ret; } -- cgit v1.2.3 From 93a88ef305ae928d9b1548d6c96734ae87843d02 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Chatradhi Date: Thu, 26 Jun 2014 18:20:14 +0530 Subject: hwmon: (ntc_thermistor) Correct information printed during probe Currently, dev_info() at the end of the probe says "type:%s ". But, prints pdev->name. This patch uses "pdev_id->name" which prints the thermistor type. Signed-off-by: Naveen Krishna Chatradhi Signed-off-by: Guenter Roeck --- drivers/hwmon/ntc_thermistor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index bdfbe9114889..ae66f42c4d6d 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -512,7 +512,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) } dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n", - pdev->name); + pdev_id->name); return 0; err_after_sysfs: -- cgit v1.2.3 From 84b4e042c4707bd1bf05094a51111403d680dc39 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 25 Jun 2014 08:24:29 -0700 Subject: drm/i915: only apply crt_present check on VLV Apparently we can't trust this field on other platforms and need to find some other way. This fixes a regression introduced in commit 27da3bdfcf7f5233cdfe4563f53edf1ecab7cea0 Author: Jesse Barnes Date: Fri Apr 4 16:12:07 2014 -0700 drm/i915: use VBT to determine whether to enumerate the VGA port Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Tested-by: Alan Stern Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 33725ed9215a..556c916dbf9d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11097,6 +11097,22 @@ const char *intel_output_name(int output) return names[output]; } +static bool intel_crt_present(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (IS_ULT(dev)) + return false; + + if (IS_CHERRYVIEW(dev)) + return false; + + if (IS_VALLEYVIEW(dev) && !dev_priv->vbt.int_crt_support) + return false; + + return true; +} + static void intel_setup_outputs(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -11105,7 +11121,7 @@ static void intel_setup_outputs(struct drm_device *dev) intel_lvds_init(dev); - if (!IS_ULT(dev) && !IS_CHERRYVIEW(dev) && dev_priv->vbt.int_crt_support) + if (intel_crt_present(dev)) intel_crt_init(dev); if (HAS_DDI(dev)) { -- cgit v1.2.3 From ceec634076b91bea57107541a46e92d765c69488 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jun 2014 11:34:48 +0200 Subject: HID: sensor-hub: fix potential memory leak hsdev is not freed in sensor_hub_probe when kasprintf inside the for loop fails. This is because hsdev is not set to platform_data yet (to be freed by the code in the err_no_mem label). So free the memory explicitly in the 'if' branch, as this is the only place where this is (and will) be needed. Reported-by: coverity Signed-off-by: Jiri Slaby Cc: srinivas pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/hid-sensor-hub.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 13ce4e3aebf4..e244e449cbba 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -636,6 +636,7 @@ static int sensor_hub_probe(struct hid_device *hdev, if (name == NULL) { hid_err(hdev, "Failed MFD device name\n"); ret = -ENOMEM; + kfree(hsdev); goto err_no_mem; } sd->hid_sensor_hub_client_devs[ -- cgit v1.2.3 From cec1cdea6f6d9fadf5f14fa80754d4a066ca76e0 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 23 Jun 2014 23:29:09 +0300 Subject: clk: samsung: fix several typos to fix boot on s3c2410 There's a several typos in a driver: 2410 instead of S3C2410 and wrong argument to ARRAY_SIZE(). They prevent s3c2410 from properly booting. Signed-off-by: Vasily Khoruzhick Reviewed-by: Heiko Stuebner Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-s3c2410.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index ba0716801db2..bd9a873da090 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -378,7 +378,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, if (!np) s3c2410_common_clk_register_fixed_ext(ctx, xti_f); - if (current_soc == 2410) { + if (current_soc == S3C2410) { if (_get_rate("xti") == 12 * MHZ) { s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl; s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl; @@ -432,7 +432,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, samsung_clk_register_fixed_factor(ctx, s3c2410_ffactor, ARRAY_SIZE(s3c2410_ffactor)); samsung_clk_register_alias(ctx, s3c2410_aliases, - ARRAY_SIZE(s3c2410_common_aliases)); + ARRAY_SIZE(s3c2410_aliases)); break; case S3C2440: samsung_clk_register_mux(ctx, s3c2440_muxes, -- cgit v1.2.3 From 34ece9e610682f34776136cba7b4600ea5d8fd94 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 23 Jun 2014 23:29:10 +0300 Subject: clk: samsung: add more aliases for s3c24xx Without these aliases clock lookup fails in s3c2410fb, s3cmci, s3c2410-nand, s3c24xx-i2s, and i2c-s3c2410 drivers. Signed-off-by: Vasily Khoruzhick Reviewed-by: Heiko Stuebner Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-s3c2410.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index bd9a873da090..140f4733c02e 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -152,6 +152,11 @@ struct samsung_clock_alias s3c2410_common_aliases[] __initdata = { ALIAS(HCLK, NULL, "hclk"), ALIAS(MPLL, NULL, "mpll"), ALIAS(FCLK, NULL, "fclk"), + ALIAS(PCLK, NULL, "watchdog"), + ALIAS(PCLK_SDI, NULL, "sdi"), + ALIAS(HCLK_NAND, NULL, "nand"), + ALIAS(PCLK_I2S, NULL, "iis"), + ALIAS(PCLK_I2C, NULL, "i2c"), }; /* S3C2410 specific clocks */ -- cgit v1.2.3 From a37c82a3b3c0910019abfd22a97be1fdf11ae3e5 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 24 Jun 2014 15:57:12 +0200 Subject: clk: samsung: exynos4: Remove SRC_MASK_ISP gates ISP special clocks have dedicated gating registers and so MUX SRC_MASK register should not be used. This patch fixes the problem of Exynos4x12-based boards freezing on system suspend, because those mux outputs need not to be masked while suspending. Signed-off-by: Tomasz Figa Cc: Mike Turquette --- drivers/clk/samsung/clk-exynos4.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 4f150c9dd38c..7f4a473a7ad7 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -925,21 +925,13 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { GATE(CLK_RTC, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0), GATE(CLK_KEYIF, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0), - GATE(CLK_SCLK_PWM_ISP, "sclk_pwm_isp", "div_pwm_isp", - E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_SPI0_ISP, "sclk_spi0_isp", "div_spi0_isp_pre", - E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_SPI1_ISP, "sclk_spi1_isp", "div_spi1_isp_pre", - E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "div_uart_isp", - E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT, 0), - GATE(CLK_PWM_ISP_SCLK, "pwm_isp_sclk", "sclk_pwm_isp", + GATE(CLK_PWM_ISP_SCLK, "pwm_isp_sclk", "div_pwm_isp", E4X12_GATE_IP_ISP, 0, 0, 0), - GATE(CLK_SPI0_ISP_SCLK, "spi0_isp_sclk", "sclk_spi0_isp", + GATE(CLK_SPI0_ISP_SCLK, "spi0_isp_sclk", "div_spi0_isp_pre", E4X12_GATE_IP_ISP, 1, 0, 0), - GATE(CLK_SPI1_ISP_SCLK, "spi1_isp_sclk", "sclk_spi1_isp", + GATE(CLK_SPI1_ISP_SCLK, "spi1_isp_sclk", "div_spi1_isp_pre", E4X12_GATE_IP_ISP, 2, 0, 0), - GATE(CLK_UART_ISP_SCLK, "uart_isp_sclk", "sclk_uart_isp", + GATE(CLK_UART_ISP_SCLK, "uart_isp_sclk", "div_uart_isp", E4X12_GATE_IP_ISP, 3, 0, 0), GATE(CLK_WDT, "watchdog", "aclk100", E4X12_GATE_IP_PERIR, 14, 0, 0), GATE(CLK_PCM0, "pcm0", "aclk100", E4X12_GATE_IP_MAUDIO, 2, -- cgit v1.2.3 From a92dda4bfad338b48c6190b1da70fe7f0eefc55d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 18 Jun 2014 10:52:23 +0100 Subject: clk: s3c64xx: Hookup SPI clocks correctly In the move to this clock driver the hookups for the SPI clocks were dropped, which causes my system Cragganmore (s3c6410 based) to be unable to locate any spibus clocks. This patch adds them back in. When taking the clock from the epll clock (SCLK) the rates on the SPI bus are incorrect, this needs further debugging but the hookup here should be correct and the problem should be else where. The USBCLK case has been dropped because this requires the USB PHY to be enabled. Signed-off-by: Charles Keepax Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-s3c64xx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index efa16ee592c8..8889ff1c10fc 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -418,8 +418,10 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = { ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"), ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"), ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"), - ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"), - ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"), + ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi_busclk0"), + ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi_busclk2"), + ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi_busclk0"), + ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi_busclk2"), ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"), ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"), ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"), -- cgit v1.2.3 From 0b1643b39ddae68f1b1b5ed848c8268a004a60a9 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Thu, 19 Jun 2014 11:17:16 +0530 Subject: clk/exynos5250: fix bit number for tv sysmmu clock Change bit from 2 to 9 for tv (mixer) sysmmu clock. Signed-off-by: Rahul Sharma Reviewed-by: Sachin Kamat Acked-by: Kukjin Kim Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 1fad4c5e3f5d..184f64293b26 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -661,7 +661,7 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0), GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0), GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub", - GATE_IP_DISP1, 2, 0, 0), + GATE_IP_DISP1, 9, 0, 0), GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 8, 0, 0), GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0), -- cgit v1.2.3 From 44ff0254b89079a8a95e652635e760d93196ac1f Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Thu, 5 Jun 2014 13:35:14 -0700 Subject: clk: exynos5420: Remove aclk66_peric from the clock tree description The "aclk66_peric" clock is a gate clock with a whole bunch of gates underneath it. This big gate isn't very useful to include in our clock tree. If any of the children need to be turned on then the big gate will need to be on anyway. ...and there are plenty of other "big gates" that aren't described in our clock tree, some of which shut off collections of clocks that have no relationship in the hierarchy so are hard to model. "aclk66_peric" is causing earlyprintk problems since it gets disabled as part of the boot process, so let's just remove it. Strangely (and for no good reason) this clock is exported as part of the common clock bindings. Remove it since there are no in-kernel device trees using it and no reason anyone out of tree should refer to it either. Signed-off-by: Doug Anderson Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 85 ++++++++++++++++++++++------------ include/dt-bindings/clock/exynos5420.h | 1 - 2 files changed, 55 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9d7d7eed03fd..61eccf0dd72f 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -890,8 +890,6 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = { GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen", GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0), - GATE(CLK_ACLK66_PERIC, "aclk66_peric", "mout_user_aclk66_peric", - GATE_BUS_TOP, 11, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk266_isp", "mout_user_aclk266_isp", GATE_BUS_TOP, 13, 0, 0), GATE(0, "aclk166", "mout_user_aclk166", @@ -994,34 +992,61 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = { SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), /* PERIC Block */ - GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_IP_PERIC, 0, 0, 0), - GATE(CLK_UART1, "uart1", "aclk66_peric", GATE_IP_PERIC, 1, 0, 0), - GATE(CLK_UART2, "uart2", "aclk66_peric", GATE_IP_PERIC, 2, 0, 0), - GATE(CLK_UART3, "uart3", "aclk66_peric", GATE_IP_PERIC, 3, 0, 0), - GATE(CLK_I2C0, "i2c0", "aclk66_peric", GATE_IP_PERIC, 6, 0, 0), - GATE(CLK_I2C1, "i2c1", "aclk66_peric", GATE_IP_PERIC, 7, 0, 0), - GATE(CLK_I2C2, "i2c2", "aclk66_peric", GATE_IP_PERIC, 8, 0, 0), - GATE(CLK_I2C3, "i2c3", "aclk66_peric", GATE_IP_PERIC, 9, 0, 0), - GATE(CLK_USI0, "usi0", "aclk66_peric", GATE_IP_PERIC, 10, 0, 0), - GATE(CLK_USI1, "usi1", "aclk66_peric", GATE_IP_PERIC, 11, 0, 0), - GATE(CLK_USI2, "usi2", "aclk66_peric", GATE_IP_PERIC, 12, 0, 0), - GATE(CLK_USI3, "usi3", "aclk66_peric", GATE_IP_PERIC, 13, 0, 0), - GATE(CLK_I2C_HDMI, "i2c_hdmi", "aclk66_peric", GATE_IP_PERIC, 14, 0, 0), - GATE(CLK_TSADC, "tsadc", "aclk66_peric", GATE_IP_PERIC, 15, 0, 0), - GATE(CLK_SPI0, "spi0", "aclk66_peric", GATE_IP_PERIC, 16, 0, 0), - GATE(CLK_SPI1, "spi1", "aclk66_peric", GATE_IP_PERIC, 17, 0, 0), - GATE(CLK_SPI2, "spi2", "aclk66_peric", GATE_IP_PERIC, 18, 0, 0), - GATE(CLK_I2S1, "i2s1", "aclk66_peric", GATE_IP_PERIC, 20, 0, 0), - GATE(CLK_I2S2, "i2s2", "aclk66_peric", GATE_IP_PERIC, 21, 0, 0), - GATE(CLK_PCM1, "pcm1", "aclk66_peric", GATE_IP_PERIC, 22, 0, 0), - GATE(CLK_PCM2, "pcm2", "aclk66_peric", GATE_IP_PERIC, 23, 0, 0), - GATE(CLK_PWM, "pwm", "aclk66_peric", GATE_IP_PERIC, 24, 0, 0), - GATE(CLK_SPDIF, "spdif", "aclk66_peric", GATE_IP_PERIC, 26, 0, 0), - GATE(CLK_USI4, "usi4", "aclk66_peric", GATE_IP_PERIC, 28, 0, 0), - GATE(CLK_USI5, "usi5", "aclk66_peric", GATE_IP_PERIC, 30, 0, 0), - GATE(CLK_USI6, "usi6", "aclk66_peric", GATE_IP_PERIC, 31, 0, 0), - - GATE(CLK_KEYIF, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0), + GATE(CLK_UART0, "uart0", "mout_user_aclk66_peric", + GATE_IP_PERIC, 0, 0, 0), + GATE(CLK_UART1, "uart1", "mout_user_aclk66_peric", + GATE_IP_PERIC, 1, 0, 0), + GATE(CLK_UART2, "uart2", "mout_user_aclk66_peric", + GATE_IP_PERIC, 2, 0, 0), + GATE(CLK_UART3, "uart3", "mout_user_aclk66_peric", + GATE_IP_PERIC, 3, 0, 0), + GATE(CLK_I2C0, "i2c0", "mout_user_aclk66_peric", + GATE_IP_PERIC, 6, 0, 0), + GATE(CLK_I2C1, "i2c1", "mout_user_aclk66_peric", + GATE_IP_PERIC, 7, 0, 0), + GATE(CLK_I2C2, "i2c2", "mout_user_aclk66_peric", + GATE_IP_PERIC, 8, 0, 0), + GATE(CLK_I2C3, "i2c3", "mout_user_aclk66_peric", + GATE_IP_PERIC, 9, 0, 0), + GATE(CLK_USI0, "usi0", "mout_user_aclk66_peric", + GATE_IP_PERIC, 10, 0, 0), + GATE(CLK_USI1, "usi1", "mout_user_aclk66_peric", + GATE_IP_PERIC, 11, 0, 0), + GATE(CLK_USI2, "usi2", "mout_user_aclk66_peric", + GATE_IP_PERIC, 12, 0, 0), + GATE(CLK_USI3, "usi3", "mout_user_aclk66_peric", + GATE_IP_PERIC, 13, 0, 0), + GATE(CLK_I2C_HDMI, "i2c_hdmi", "mout_user_aclk66_peric", + GATE_IP_PERIC, 14, 0, 0), + GATE(CLK_TSADC, "tsadc", "mout_user_aclk66_peric", + GATE_IP_PERIC, 15, 0, 0), + GATE(CLK_SPI0, "spi0", "mout_user_aclk66_peric", + GATE_IP_PERIC, 16, 0, 0), + GATE(CLK_SPI1, "spi1", "mout_user_aclk66_peric", + GATE_IP_PERIC, 17, 0, 0), + GATE(CLK_SPI2, "spi2", "mout_user_aclk66_peric", + GATE_IP_PERIC, 18, 0, 0), + GATE(CLK_I2S1, "i2s1", "mout_user_aclk66_peric", + GATE_IP_PERIC, 20, 0, 0), + GATE(CLK_I2S2, "i2s2", "mout_user_aclk66_peric", + GATE_IP_PERIC, 21, 0, 0), + GATE(CLK_PCM1, "pcm1", "mout_user_aclk66_peric", + GATE_IP_PERIC, 22, 0, 0), + GATE(CLK_PCM2, "pcm2", "mout_user_aclk66_peric", + GATE_IP_PERIC, 23, 0, 0), + GATE(CLK_PWM, "pwm", "mout_user_aclk66_peric", + GATE_IP_PERIC, 24, 0, 0), + GATE(CLK_SPDIF, "spdif", "mout_user_aclk66_peric", + GATE_IP_PERIC, 26, 0, 0), + GATE(CLK_USI4, "usi4", "mout_user_aclk66_peric", + GATE_IP_PERIC, 28, 0, 0), + GATE(CLK_USI5, "usi5", "mout_user_aclk66_peric", + GATE_IP_PERIC, 30, 0, 0), + GATE(CLK_USI6, "usi6", "mout_user_aclk66_peric", + GATE_IP_PERIC, 31, 0, 0), + + GATE(CLK_KEYIF, "keyif", "mout_user_aclk66_peric", + GATE_BUS_PERIC, 22, 0, 0), /* PERIS Block */ GATE(CLK_CHIPID, "chipid", "aclk66_psgen", diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h index 97dcb89d37d3..14e1c8f9640c 100644 --- a/include/dt-bindings/clock/exynos5420.h +++ b/include/dt-bindings/clock/exynos5420.h @@ -63,7 +63,6 @@ #define CLK_SCLK_MPHY_IXTAL24 161 /* gate clocks */ -#define CLK_ACLK66_PERIC 256 #define CLK_UART0 257 #define CLK_UART1 258 #define CLK_UART2 259 -- cgit v1.2.3 From 508ccea177ba35cbac382b9873c5cd77985bdf8d Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 30 Jun 2014 18:29:57 +0100 Subject: usb: phy: msm: Do not do runtime pm if the phy is not idle Use case is when the phy is configured in host mode and a usb device is attached to board before bootup. On bootup, with the existing code and runtime pm enabled, the driver would decrement the pm usage count without checking the current state of the phy. This pm usage count decrement would trigger the runtime pm which than would abort the usb enumeration which was in progress. In my case a usb stick gets detected and then immediatly the driver goes to low power mode which is not correct. log: [ 1.631412] msm_hsusb_host 12520000.usb: EHCI Host Controller [ 1.636556] msm_hsusb_host 12520000.usb: new USB bus registered, assigned bus number 1 [ 1.642563] msm_hsusb_host 12520000.usb: irq 220, io mem 0x12520000 [ 1.658197] msm_hsusb_host 12520000.usb: USB 2.0 started, EHCI 1.00 [ 1.659473] hub 1-0:1.0: USB hub found [ 1.663415] hub 1-0:1.0: 1 port detected ... [ 1.973352] usb 1-1: new high-speed USB device number 2 using msm_hsusb_host [ 2.107707] usb-storage 1-1:1.0: USB Mass Storage device detected [ 2.108993] scsi0 : usb-storage 1-1:1.0 [ 2.678341] msm_otg 12520000.phy: USB in low power mode [ 3.168977] usb 1-1: USB disconnect, device number 2 This issue was detected on IFC6410 board. This patch fixes the intial runtime pm trigger by checking the phy state and decrementing the pm use count only when the phy state is IDLE. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index ced34f39bdd4..c929370cdaa6 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1229,7 +1229,9 @@ static void msm_otg_sm_work(struct work_struct *w) motg->chg_state = USB_CHG_STATE_UNDEFINED; motg->chg_type = USB_INVALID_CHARGER; } - pm_runtime_put_sync(otg->phy->dev); + + if (otg->phy->state == OTG_STATE_B_IDLE) + pm_runtime_put_sync(otg->phy->dev); break; case OTG_STATE_B_PERIPHERAL: dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); -- cgit v1.2.3 From 8035691365b80428c58908215d4408559afe7cb3 Mon Sep 17 00:00:00 2001 From: Lothar Waßmann Date: Mon, 30 Jun 2014 13:17:27 +0200 Subject: usb: musb: dsps: fix the base address for accessing the mode register commit 943c13971c08 "usb: musb: dsps: implement ->set_mode()" should have made it possible to use the driver with boards that have the USBID pin unconnected. This doesn't actually work, since the driver uses the wrong base address to access the mode register. Furthermore it uses different base addresses in different places to access the same register (phy_utmi). Signed-off-by: Lothar Waßmann Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 51beb13c7e1a..09529f94e72d 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -494,10 +494,9 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) struct dsps_glue *glue = dev_get_drvdata(dev->parent); const struct dsps_musb_wrapper *wrp = glue->wrp; void __iomem *ctrl_base = musb->ctrl_base; - void __iomem *base = musb->mregs; u32 reg; - reg = dsps_readl(base, wrp->mode); + reg = dsps_readl(ctrl_base, wrp->mode); switch (mode) { case MUSB_HOST: @@ -510,7 +509,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) */ reg |= (1 << wrp->iddig_mux); - dsps_writel(base, wrp->mode, reg); + dsps_writel(ctrl_base, wrp->mode, reg); dsps_writel(ctrl_base, wrp->phy_utmi, 0x02); break; case MUSB_PERIPHERAL: @@ -523,10 +522,10 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) */ reg |= (1 << wrp->iddig_mux); - dsps_writel(base, wrp->mode, reg); + dsps_writel(ctrl_base, wrp->mode, reg); break; case MUSB_OTG: - dsps_writel(base, wrp->phy_utmi, 0x02); + dsps_writel(ctrl_base, wrp->phy_utmi, 0x02); break; default: dev_err(glue->dev, "unsupported mode %d\n", mode); -- cgit v1.2.3 From d0f9d64a0b8fb3399ca8dd0d54f4d305492c9217 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 20 Jun 2014 15:03:06 +0800 Subject: Thermal: imx: correct critical trip temperature setting On latest i.MX6 SOC with thermal calibration data of 0x5A100000, the critical trip temperature will be an invalid value and cause system auto shutdown as below log: thermal thermal_zone0: critical temperature reached(42 C),shutting down So, with universal formula for thermal sensor, only room temperature point is calibrated, which means the calibration data read from fuse only has valid data of bit [31:20], others are all 0, the critical trip point temperature can NOT depend on the hot point calibration data, here we set it to 20 C higher than default passive temperature. Signed-off-by: Anson Huang Acked-by: Shawn Guo Signed-off-by: Zhang Rui --- drivers/thermal/imx_thermal.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index a99c63152b8d..2c516f2eebed 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -306,7 +306,7 @@ static int imx_get_sensor_data(struct platform_device *pdev) { struct imx_thermal_data *data = platform_get_drvdata(pdev); struct regmap *map; - int t1, t2, n1, n2; + int t1, n1; int ret; u32 val; u64 temp64; @@ -333,14 +333,10 @@ static int imx_get_sensor_data(struct platform_device *pdev) /* * Sensor data layout: * [31:20] - sensor value @ 25C - * [19:8] - sensor value of hot - * [7:0] - hot temperature value * Use universal formula now and only need sensor value @ 25C * slope = 0.4297157 - (0.0015976 * 25C fuse) */ n1 = val >> 20; - n2 = (val & 0xfff00) >> 8; - t2 = val & 0xff; t1 = 25; /* t1 always 25C */ /* @@ -366,16 +362,16 @@ static int imx_get_sensor_data(struct platform_device *pdev) data->c2 = n1 * data->c1 + 1000 * t1; /* - * Set the default passive cooling trip point to 20 °C below the - * maximum die temperature. Can be changed from userspace. + * Set the default passive cooling trip point, + * can be changed from userspace. */ - data->temp_passive = 1000 * (t2 - 20); + data->temp_passive = IMX_TEMP_PASSIVE; /* - * The maximum die temperature is t2, let's give 5 °C cushion - * for noise and possible temperature rise between measurements. + * The maximum die temperature set to 20 C higher than + * IMX_TEMP_PASSIVE. */ - data->temp_critical = 1000 * (t2 - 5); + data->temp_critical = 1000 * 20 + data->temp_passive; return 0; } -- cgit v1.2.3 From fbe2ddcdcca9c15558533cb75e5161152338b548 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Mon, 2 Jun 2014 23:25:30 +0200 Subject: thermal: ti-soc-thermal: ti-bandgap.c: Cleaning up wrong address is checked Wrong address is checked after memory allocation. Signed-off-by: Rickard Strandqvist Signed-off-by: Zhang Rui --- drivers/thermal/ti-soc-thermal/ti-bandgap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c index a1271b55103a..634b6ce0e63a 100644 --- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c +++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c @@ -1155,7 +1155,7 @@ static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev) /* register shadow for context save and restore */ bgp->regval = devm_kzalloc(&pdev->dev, sizeof(*bgp->regval) * bgp->conf->sensor_count, GFP_KERNEL); - if (!bgp) { + if (!bgp->regval) { dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n"); return ERR_PTR(-ENOMEM); } -- cgit v1.2.3 From b14bf2d0c0358140041d1c1805a674376964d0e0 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 30 Jun 2014 11:04:21 -0400 Subject: usb-storage/SCSI: Add broken_fua blacklist flag Some buggy JMicron USB-ATA bridges don't know how to translate the FUA bit in READs or WRITEs. This patch adds an entry in unusual_devs.h and a blacklist flag to tell the sd driver not to use FUA. Signed-off-by: Alan Stern Reported-by: Michael Büsch Tested-by: Michael Büsch Acked-by: James Bottomley CC: Matthew Dharm CC: Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 5 ++++- drivers/usb/storage/scsiglue.c | 4 ++++ drivers/usb/storage/unusual_devs.h | 7 +++++++ include/linux/usb_usual.h | 4 +++- include/scsi/scsi_device.h | 1 + 5 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e9689d57ccb6..6825eda1114a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2441,7 +2441,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) } sdkp->DPOFUA = (data.device_specific & 0x10) != 0; - if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { + if (sdp->broken_fua) { + sd_first_printk(KERN_NOTICE, sdkp, "Disabling FUA\n"); + sdkp->DPOFUA = 0; + } else if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { sd_first_printk(KERN_NOTICE, sdkp, "Uses READ/WRITE(6), disabling FUA\n"); sdkp->DPOFUA = 0; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 9d38ddc8da49..866b5df36ed1 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -256,6 +256,10 @@ static int slave_configure(struct scsi_device *sdev) if (us->fflags & US_FL_WRITE_CACHE) sdev->wce_default_on = 1; + /* A few buggy USB-ATA bridges don't understand FUA */ + if (us->fflags & US_FL_BROKEN_FUA) + sdev->broken_fua = 1; + } else { /* Non-disk-type devices don't need to blacklist any pages diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 174a447868cd..80a5b366255f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1936,6 +1936,13 @@ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Michael Büsch */ +UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0114, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + /* Reported by Alexandre Oliva * JMicron responds to USN and several other SCSI ioctls with a * residue that causes subsequent I/O requests to fail. */ diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 1a64b26046ed..9b7de1b46437 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -70,7 +70,9 @@ US_FLAG(NEEDS_CAP16, 0x00400000) \ /* cannot handle READ_CAPACITY_10 */ \ US_FLAG(IGNORE_UAS, 0x00800000) \ - /* Device advertises UAS but it is broken */ + /* Device advertises UAS but it is broken */ \ + US_FLAG(BROKEN_FUA, 0x01000000) \ + /* Cannot handle FUA in WRITE or READ CDBs */ \ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 5853c913d2b0..27ab31017f09 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -173,6 +173,7 @@ struct scsi_device { unsigned is_visible:1; /* is the device visible in sysfs */ unsigned wce_default_on:1; /* Cache is ON by default */ unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ + unsigned broken_fua:1; /* Don't set FUA bit */ atomic_t disk_events_disable_depth; /* disable depth for disk events */ -- cgit v1.2.3 From 8ae587e5df6db3a950c2f417d48ce0a8d55b1792 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 30 Jun 2014 18:29:34 +0100 Subject: usb: Kconfig: make EHCI_MSM selectable for QCOM SOCs This patch makes the msm ehci driver available to use on QCOM SOCs, which have the same IP. Signed-off-by: Srinivas Kandagatla Acked-by: Felipe Balbi Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 61b7817bd66b..03314f861bee 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -176,7 +176,7 @@ config USB_EHCI_HCD_AT91 config USB_EHCI_MSM tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" - depends on ARCH_MSM + depends on ARCH_MSM || ARCH_QCOM select USB_EHCI_ROOT_HUB_TT ---help--- Enables support for the USB Host controller present on the -- cgit v1.2.3 From 13bbfb5c4eb4fc85bf977245f9b3624df0187184 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 26 May 2014 14:52:34 +0200 Subject: dma: cppi41: handle 0-length packets When a 0-length packet is received on the bus, desc->pd0 yields 1, which confuses the driver's users. This information is clearly wrong and not in accordance to the datasheet, but it's been observed on an AM335x board, very reproducible. Fix this by looking at bit 19 in PD2 of the completed packet. This bit will tell us if a zero-length packet was received on a queue. If it's set, ignore the value in PD0 and report a total length of 0 instead. Signed-off-by: Daniel Mack Signed-off-by: Vinod Koul --- drivers/dma/cppi41.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index d028f36ae655..8f8b0b608875 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -86,6 +86,9 @@ #define USBSS_IRQ_PD_COMP (1 << 2) +/* Packet Descriptor */ +#define PD2_ZERO_LENGTH (1 << 19) + struct cppi41_channel { struct dma_chan chan; struct dma_async_tx_descriptor txd; @@ -307,7 +310,7 @@ static irqreturn_t cppi41_irq(int irq, void *data) __iormb(); while (val) { - u32 desc; + u32 desc, len; q_num = __fls(val); val &= ~(1 << q_num); @@ -319,9 +322,13 @@ static irqreturn_t cppi41_irq(int irq, void *data) q_num, desc); continue; } - c->residue = pd_trans_len(c->desc->pd6) - - pd_trans_len(c->desc->pd0); + if (c->desc->pd2 & PD2_ZERO_LENGTH) + len = 0; + else + len = pd_trans_len(c->desc->pd0); + + c->residue = pd_trans_len(c->desc->pd6) - len; dma_cookie_complete(&c->txd); c->txd.callback(c->txd.callback_param); } -- cgit v1.2.3 From d1a792f3b4072bfac4150bb62aa34917b77fdb6d Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Wed, 25 Jun 2014 13:00:33 +0100 Subject: Update imx-sdma cyclic handling to report residue I received a report this morning from one of the Novena developers that the behaviour of the iMX6 ASoC codec driver (using imx-pcm-dma.c) was sub-optimal under high system load. While there are issues relating to system load remaining, upon reviewing the ASoC imx-pcm-dma.c driver, it was noticed that it not using the residue support, because SDMA doesn't support it. This has the effect that SDMA has to make multiple calls into the ASoC and ALSA code, one for each period. Since ALSA's snd_pcm_elapsed() does not need to be called multiple times and it is entirely sufficient to call it once to update ALSA with the current buffer position via the pointer method, we can do better here. We can also avoid stopping the DMA entirely, just like real cyclic DMA implementations behave. While this means that we replay some old samples, this is a nicer behaviour than having audio stop and restart. The changes to achieve this are relatively minor - imx-sdma.c can track where the DMA is to the nearest descriptor boundary - it does this already when deciding how many callbacks to issue. In doing this, buf_tail always points at the descriptor which will complete next. The residue is defined by the bytes remaining to the end of the buffer, when the buffer is viewed as a single block of memory [start...end]. So, when we start out, there's a full buffer worth of residue, and this counts down as we approach the end of the buffer, eventually becoming zero at the end, before returning to the full buffer worth when we wrap back to the start. Moving the walking of the descriptors into the interrupt handler means that we can update the BD_DONE flag at interrupt time, thus avoiding a delayed tasklet stopping the cyclic DMA. This means that the residue can be calculated from (total descriptors - buf_tail) * descriptor size. This is what the change below does. We update imx-pcm-dma.c to remove the NO_RESIDUE flag since we now provide the residue. Signed-off-by: Russell King Tested-by: Shawn Guo Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 22 ++++++++++++++++++---- sound/soc/fsl/imx-pcm-dma.c | 1 - 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 128714622bf5..14867e3ac8ff 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -255,6 +255,7 @@ struct sdma_channel { enum dma_slave_buswidth word_size; unsigned int buf_tail; unsigned int num_bd; + unsigned int period_len; struct sdma_buffer_descriptor *bd; dma_addr_t bd_phys; unsigned int pc_from_device, pc_to_device; @@ -592,6 +593,12 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event) } static void sdma_handle_channel_loop(struct sdma_channel *sdmac) +{ + if (sdmac->desc.callback) + sdmac->desc.callback(sdmac->desc.callback_param); +} + +static void sdma_update_channel_loop(struct sdma_channel *sdmac) { struct sdma_buffer_descriptor *bd; @@ -611,9 +618,6 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac) bd->mode.status |= BD_DONE; sdmac->buf_tail++; sdmac->buf_tail %= sdmac->num_bd; - - if (sdmac->desc.callback) - sdmac->desc.callback(sdmac->desc.callback_param); } } @@ -669,6 +673,9 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id) int channel = fls(stat) - 1; struct sdma_channel *sdmac = &sdma->channel[channel]; + if (sdmac->flags & IMX_DMA_SG_LOOP) + sdma_update_channel_loop(sdmac); + tasklet_schedule(&sdmac->tasklet); __clear_bit(channel, &stat); @@ -1129,6 +1136,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( sdmac->status = DMA_IN_PROGRESS; sdmac->buf_tail = 0; + sdmac->period_len = period_len; sdmac->flags |= IMX_DMA_SG_LOOP; sdmac->direction = direction; @@ -1225,9 +1233,15 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, struct dma_tx_state *txstate) { struct sdma_channel *sdmac = to_sdma_chan(chan); + u32 residue; + + if (sdmac->flags & IMX_DMA_SG_LOOP) + residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len; + else + residue = sdmac->chn_count - sdmac->chn_real_count; dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie, - sdmac->chn_count - sdmac->chn_real_count); + residue); return sdmac->status; } diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 0849b7b83f0a..0db94f492e97 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -59,7 +59,6 @@ int imx_pcm_dma_init(struct platform_device *pdev) { return devm_snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | SND_DMAENGINE_PCM_FLAG_COMPAT); } EXPORT_SYMBOL_GPL(imx_pcm_dma_init); -- cgit v1.2.3 From 5549d25f642a7e6cfb8744d0031a9da404f696d6 Mon Sep 17 00:00:00 2001 From: Deepak S Date: Sat, 28 Jun 2014 11:26:11 +0530 Subject: drm/i915: Drop early VLV WA to fix Voltage not getting dropped to Vmin Drop WA to fix Voltage not getting dropped to Vmin when Gfx is power gated for latest VLV revision. Workaround fixed in Latest VLV revision. Forcing Gfx clk up not needed, and Requesting the min freq should bring bring the voltage Vnn. v2: Drop WA for Latest VLV revision (Ville) Signed-off-by: Deepak S Reviewed-by: Ville Syrjälä [Jani: modified code comment, reformatted the commit message a bit.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9ad0c6afc487..c8bb7616e077 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3209,6 +3209,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val) */ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) { + struct drm_device *dev = dev_priv->dev; + + /* Latest VLV doesn't need to force the gfx clock */ + if (dev->pdev->revision >= 0xd) { + valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); + return; + } + /* * When we are idle. Drop to min voltage state. */ -- cgit v1.2.3 From 0b479c3db63303814c1d2f8e97497db6be1caaa4 Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Wed, 2 Jul 2014 14:53:42 +0800 Subject: fb: adv7393: add missing semicolon Commit f8bd493456c3da372ae81ed8f6b903f6207b9d98 by Jingoo Han introduced this problem. This makes bfin_adv7393fb.c failed to compile. Signed-off-by: Scott Jiang Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/bfin_adv7393fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c index a54f7f7d763b..8fe41caac38e 100644 --- a/drivers/video/fbdev/bfin_adv7393fb.c +++ b/drivers/video/fbdev/bfin_adv7393fb.c @@ -408,7 +408,7 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client, /* Workaround "PPI Does Not Start Properly In Specific Mode" */ if (ANOMALY_05000400) { ret = gpio_request_one(P_IDENT(P_PPI0_FS3), GPIOF_OUT_INIT_LOW, - "PPI0_FS3") + "PPI0_FS3"); if (ret) { dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n"); ret = -EBUSY; -- cgit v1.2.3 From 9368931db826d57b6b88b3145a00276626b48df0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 18 Jun 2014 11:46:35 -0400 Subject: drm/radeon: adjust default dispclk on DCE6 (v2) Set the default to 600Mhz if it's not set in the bios, and bump the default to 600Mhz if it's lower than that. This fixes display issues with certain 4k DP monitors when using 5.4 Ghz DP clocks. v2: fix typo. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_atombios.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 30844814c25a..173f378428a9 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1227,11 +1227,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) rdev->clock.default_dispclk = le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); if (rdev->clock.default_dispclk == 0) { - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) + rdev->clock.default_dispclk = 60000; /* 600 Mhz */ + else if (ASIC_IS_DCE5(rdev)) rdev->clock.default_dispclk = 54000; /* 540 Mhz */ else rdev->clock.default_dispclk = 60000; /* 600 Mhz */ } + /* set a reasonable default for DP */ + if (ASIC_IS_DCE6(rdev) && (rdev->clock.default_dispclk < 53900)) { + DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n", + rdev->clock.default_dispclk / 100); + rdev->clock.default_dispclk = 60000; + } rdev->clock.dp_extclk = le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); rdev->clock.current_dispclk = rdev->clock.default_dispclk; -- cgit v1.2.3 From 96682956572d79920e9da60d7300230329e10a7a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 18 Jun 2014 14:23:46 -0400 Subject: drm/radeon: only apply bapm changes for AC power on ARUBA Newer asics shouldn't need any manual adjustment. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 12c663e86ca1..e447e390d09a 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -73,8 +73,10 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev) rdev->pm.dpm.ac_power = true; else rdev->pm.dpm.ac_power = false; - if (rdev->asic->dpm.enable_bapm) - radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power); + if (rdev->family == CHIP_ARUBA) { + if (rdev->asic->dpm.enable_bapm) + radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power); + } mutex_unlock(&rdev->pm.mutex); } else if (rdev->pm.pm_method == PM_METHOD_PROFILE) { if (rdev->pm.profile == PM_PROFILE_AUTO) { -- cgit v1.2.3 From 09f95d5b8ca64a9ebb5e206ed936c1a70dc8e9c8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 17 Jun 2014 12:40:40 -0400 Subject: drm/radeon: enable bapm by default on KV/KB bapm allows the GPU and CPU to share TDP. This allows for additional performance out of the GPU and CPU when the headroom is available. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/kv_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 3f6e817d97ee..9ef8c38f2d66 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2726,7 +2726,7 @@ int kv_dpm_init(struct radeon_device *rdev) pi->caps_sclk_ds = true; pi->enable_auto_thermal_throttling = true; pi->disable_nb_ps3_in_battery = false; - pi->bapm_enable = false; + pi->bapm_enable = true; pi->voltage_drop_t = 0; pi->caps_sclk_throttle_low_notification = false; pi->caps_fps = false; /* true? */ -- cgit v1.2.3 From 0c78a44964db3d483b0c09a8236e0fe123aa9cfc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 17 Jun 2014 16:01:08 -0400 Subject: drm/radeon: enable bapm by default on desktop TN/RL boards bapm enabled the GPU and CPU to share TDP headroom. It was disabled by default since some laptops hung when it was enabled in conjunction with dpm. It seems to be stable on desktop boards and fixes hangs on boot with dpm enabled on certain boards, so enable it by default on desktop boards. bug: https://bugs.freedesktop.org/show_bug.cgi?id=72921 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/trinity_dpm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 2a2822c03329..20da6ff183df 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1874,7 +1874,15 @@ int trinity_dpm_init(struct radeon_device *rdev) for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) pi->at[i] = TRINITY_AT_DFLT; - pi->enable_bapm = false; + /* There are stability issues reported on latops with + * bapm installed when switching between AC and battery + * power. At the same time, some desktop boards hang + * if it's not enabled and dpm is enabled. + */ + if (rdev->flags & RADEON_IS_MOBILITY) + pi->enable_bapm = false; + else + pi->enable_bapm = true; pi->enable_nbps_policy = true; pi->enable_sclk_ds = true; pi->enable_gfx_power_gating = true; -- cgit v1.2.3 From a624f4290ab09e996b1040c3a349241f76742327 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 1 Jul 2014 11:23:03 -0400 Subject: drm/radeon: add a module parameter to control deep color support Some monitors seem to have problems with deep color enabled, even though they claim to support it. I'm not sure if the monitor need a quirk or if the driver is doing something the monitor doesn't like. At this point lets just disable deep color by default like we did for hdmi audio and work through the bugs so we can eventually enable it by default. bug: https://bugs.freedesktop.org/show_bug.cgi?id=80531 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_connectors.c | 3 +++ drivers/gpu/drm/radeon/radeon_drv.c | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4b0bbf88d5c0..a2e1ed8d4ed4 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -102,6 +102,7 @@ extern int radeon_runtime_pm; extern int radeon_hard_reset; extern int radeon_vm_size; extern int radeon_vm_block_size; +extern int radeon_deep_color; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 1b9177ed181f..44831197e82e 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -199,6 +199,9 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) } } + if ((radeon_deep_color == 0) && (bpc > 8)) + bpc = 8; + DRM_DEBUG("%s: Display bpc=%d, returned bpc=%d\n", connector->name, connector->display_info.bpc, bpc); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6e3017413386..cb1421369e3a 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -175,6 +175,7 @@ int radeon_runtime_pm = -1; int radeon_hard_reset = 0; int radeon_vm_size = 4096; int radeon_vm_block_size = 9; +int radeon_deep_color = 0; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -248,6 +249,9 @@ module_param_named(vm_size, radeon_vm_size, int, 0444); MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default 9)"); module_param_named(vm_block_size, radeon_vm_block_size, int, 0444); +MODULE_PARM_DESC(deep_color, "Deep Color support (1 = enable, 0 = disable (default))"); +module_param_named(deep_color, radeon_deep_color, int, 0444); + static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; -- cgit v1.2.3 From 4e5f97deda1b5a8aa5c1a81399d296fb4174875c Mon Sep 17 00:00:00 2001 From: Stefan Brüns Date: Sun, 29 Jun 2014 21:03:53 +0200 Subject: drm/radeon: Use only one line for whole DPCD debug output Signed-off-by: Stefan Brüns Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index c5b1f2da3954..35f4182c63b6 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -403,16 +403,18 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) { struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; u8 msg[DP_DPCD_SIZE]; - int ret, i; + int ret; + + char dpcd_hex_dump[DP_DPCD_SIZE * 3]; ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, DP_DPCD_SIZE); if (ret > 0) { memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); - DRM_DEBUG_KMS("DPCD: "); - for (i = 0; i < DP_DPCD_SIZE; i++) - DRM_DEBUG_KMS("%02x ", msg[i]); - DRM_DEBUG_KMS("\n"); + + hex_dump_to_buffer(dig_connector->dpcd, sizeof(dig_connector->dpcd), + 32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false); + DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump); radeon_dp_probe_oui(radeon_connector); -- cgit v1.2.3 From 88f39063ea9abb11f3321ab347821d3742ecf940 Mon Sep 17 00:00:00 2001 From: Stefan Brüns Date: Sun, 29 Jun 2014 21:02:20 +0200 Subject: drm/radeon: use RADEON_MAX_CRTCS, RADEON_MAX_AFMT_BLOCKS (v2) v2: agd5f: compile fix Signed-off-by: Stefan Brüns Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 4 ---- drivers/gpu/drm/radeon/radeon_mode.h | 8 ++++++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a2e1ed8d4ed4..29d9cc04c04e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -750,10 +750,6 @@ union radeon_irq_stat_regs { struct cik_irq_stat_regs cik; }; -#define RADEON_MAX_HPD_PINS 7 -#define RADEON_MAX_CRTCS 6 -#define RADEON_MAX_AFMT_BLOCKS 7 - struct radeon_irq { bool installed; spinlock_t lock; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ad0e4b8cc7e3..98a125d4e50b 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -46,6 +46,10 @@ struct radeon_device; #define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base) #define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base) +#define RADEON_MAX_HPD_PINS 7 +#define RADEON_MAX_CRTCS 6 +#define RADEON_MAX_AFMT_BLOCKS 7 + enum radeon_rmx_type { RMX_OFF, RMX_FULL, @@ -233,8 +237,8 @@ struct radeon_mode_info { struct card_info *atom_card_info; enum radeon_connector_table connector_table; bool mode_config_initialized; - struct radeon_crtc *crtcs[6]; - struct radeon_afmt *afmt[7]; + struct radeon_crtc *crtcs[RADEON_MAX_CRTCS]; + struct radeon_afmt *afmt[RADEON_MAX_AFMT_BLOCKS]; /* DVI-I properties */ struct drm_property *coherent_mode_property; /* DAC enable load detect */ -- cgit v1.2.3 From e07929810f0a19ddd756558290c7d72827cbfcd9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 1 Jul 2014 12:07:33 -0400 Subject: drm/radeon/dpm: fix typo in vddci setup for eg/btc We were using the vddc mask rather than the vddci mask. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=79071 Possibly also fixes: https://bugzilla.kernel.org/show_bug.cgi?id=68571 Noticed-by: Jonathan Howard Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/cypress_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 5a9a5f4d7888..47d31e915758 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c @@ -1551,7 +1551,7 @@ int cypress_populate_smc_voltage_tables(struct radeon_device *rdev, table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDCI] = 0; table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDCI] = - cpu_to_be32(eg_pi->vddc_voltage_table.mask_low); + cpu_to_be32(eg_pi->vddci_voltage_table.mask_low); } return 0; -- cgit v1.2.3 From b0880e87c1fd038b84498944f52e52c3e86ebe59 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 1 Jul 2014 12:11:31 -0400 Subject: drm/radeon/dpm: fix vddci setup typo on cayman We were using the vddc mask rather than the vddci mask. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=79071 May also fix: https://bugs.freedesktop.org/show_bug.cgi?id=69723 Noticed by: Dieter Nützel Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ni_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 004c931606c4..01fc4888e6fe 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -1315,7 +1315,7 @@ static void ni_populate_smc_voltage_tables(struct radeon_device *rdev, table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] = 0; table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] = - cpu_to_be32(eg_pi->vddc_voltage_table.mask_low); + cpu_to_be32(eg_pi->vddci_voltage_table.mask_low); } } -- cgit v1.2.3 From a2b6d3b33b6a255a271fb120cdc37c6757cdd2be Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 30 Jun 2014 18:12:34 +0900 Subject: drm/radeon: Track the status of a page flip more explicitly This prevents a panic: radeon_crtc_handle_page_flip() could run before radeon_flip_work_func(), triggering the BUG_ON() in drm_vblank_put(). Tested-by: Dieter Nützel Reviewed-by: Christian König Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_display.c | 19 ++++++++++++++----- drivers/gpu/drm/radeon/radeon_mode.h | 7 +++++++ 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8fc362aa6a1a..13896edcf0b6 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -285,7 +285,6 @@ static void radeon_unpin_work_func(struct work_struct *__work) void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; - struct radeon_flip_work *work; unsigned long flags; u32 update_pending; int vpos, hpos; @@ -295,8 +294,11 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id) return; spin_lock_irqsave(&rdev->ddev->event_lock, flags); - work = radeon_crtc->flip_work; - if (work == NULL) { + if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) { + DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != " + "RADEON_FLIP_SUBMITTED(%d)\n", + radeon_crtc->flip_status, + RADEON_FLIP_SUBMITTED); spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); return; } @@ -344,12 +346,17 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) spin_lock_irqsave(&rdev->ddev->event_lock, flags); work = radeon_crtc->flip_work; - if (work == NULL) { + if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) { + DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != " + "RADEON_FLIP_SUBMITTED(%d)\n", + radeon_crtc->flip_status, + RADEON_FLIP_SUBMITTED); spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); return; } /* Pageflip completed. Clean up. */ + radeon_crtc->flip_status = RADEON_FLIP_NONE; radeon_crtc->flip_work = NULL; /* wakeup userspace */ @@ -476,6 +483,7 @@ static void radeon_flip_work_func(struct work_struct *__work) /* do the flip (mmio) */ radeon_page_flip(rdev, radeon_crtc->crtc_id, base); + radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); up_read(&rdev->exclusive_lock); @@ -544,7 +552,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, /* We borrow the event spin lock for protecting flip_work */ spin_lock_irqsave(&crtc->dev->event_lock, flags); - if (radeon_crtc->flip_work) { + if (radeon_crtc->flip_status != RADEON_FLIP_NONE) { DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); spin_unlock_irqrestore(&crtc->dev->event_lock, flags); drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); @@ -552,6 +560,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, kfree(work); return -EBUSY; } + radeon_crtc->flip_status = RADEON_FLIP_PENDING; radeon_crtc->flip_work = work; /* update crtc fb */ diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 98a125d4e50b..0592ddb0904b 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -306,6 +306,12 @@ struct radeon_atom_ss { uint16_t amount; }; +enum radeon_flip_status { + RADEON_FLIP_NONE, + RADEON_FLIP_PENDING, + RADEON_FLIP_SUBMITTED +}; + struct radeon_crtc { struct drm_crtc base; int crtc_id; @@ -331,6 +337,7 @@ struct radeon_crtc { /* page flipping */ struct workqueue_struct *flip_queue; struct radeon_flip_work *flip_work; + enum radeon_flip_status flip_status; /* pll sharing */ struct radeon_atom_ss ss; bool ss_enabled; -- cgit v1.2.3 From 07b0f00964def8af9321cfd6c4a7e84f6362f728 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 26 Jun 2014 00:44:02 -0700 Subject: bnx2x: fix possible panic under memory stress While it is legal to kfree(NULL), it is not wise to use : put_page(virt_to_head_page(NULL)) BUG: unable to handle kernel paging request at ffffeba400000000 IP: [] virt_to_head_page+0x36/0x44 [bnx2x] Reported-by: Michel Lespinasse Signed-off-by: Eric Dumazet Cc: Ariel Elior Fixes: d46d132cc021 ("bnx2x: use netdev_alloc_frag()") Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 47c5814114e1..4b875da1c7ed 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -797,7 +797,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, return; } - bnx2x_frag_free(fp, new_data); + if (new_data) + bnx2x_frag_free(fp, new_data); drop: /* drop the packet and keep the buffer in the bin */ DP(NETIF_MSG_RX_STATUS, -- cgit v1.2.3 From 3b140a678834f55602e50e7d6a47663e230434a7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jun 2014 10:06:44 -0700 Subject: net: systemport: do not clear IFF_MULTICAST flag The SYSTEMPORT Ethernet MAC supports multicast just fine, it just lacks any sort of Unicast/Broadcast/Multicasting filtering at the Ethernet MAC level since that is handled by the front end Ethernet switch, but that is properly handled by bcm_sysport_set_rx_mode(). Some user-space applications might be relying on the presence of this flag to prevent using multicast sockets, this also prevents that interface from joining the IPv6 all-router mcast group. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 141160ef249a..f6bccd847ee6 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1589,12 +1589,6 @@ static int bcm_sysport_probe(struct platform_device *pdev) BUILD_BUG_ON(sizeof(struct bcm_tsb) != 8); dev->needed_headroom += sizeof(struct bcm_tsb); - /* We are interfaced to a switch which handles the multicast - * filtering for us, so we do not support programming any - * multicast hash table in this Ethernet MAC. - */ - dev->flags &= ~IFF_MULTICAST; - /* libphy will adjust the link state accordingly */ netif_carrier_off(dev); -- cgit v1.2.3 From 412bce83ac786197d0b2805c5bcded4d95cdeeb0 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jun 2014 10:06:45 -0700 Subject: net: systemport: fix UniMAC reset logic The UniMAC CMD_SW_RESET bit is not a self-clearing bit, so we need to assert it, wait a bit and clear it manually. As a result, umac_reset() is updated not to return any value. The previous version of the code simply wrote 0 to the CMD register, which would make the busy-waiting loop exit immediately, having zero effect. By writing 0 to the CMD register, we were clearing all bits in the CMD register, and not using the hardware reset default values which are set on purpose. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 33 ++++++++---------------------- 1 file changed, 9 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index f6bccd847ee6..d31f7d239064 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1254,28 +1254,17 @@ static inline void umac_enable_set(struct bcm_sysport_priv *priv, usleep_range(1000, 2000); } -static inline int umac_reset(struct bcm_sysport_priv *priv) +static inline void umac_reset(struct bcm_sysport_priv *priv) { - unsigned int timeout = 0; u32 reg; - int ret = 0; - - umac_writel(priv, 0, UMAC_CMD); - while (timeout++ < 1000) { - reg = umac_readl(priv, UMAC_CMD); - if (!(reg & CMD_SW_RESET)) - break; - - udelay(1); - } - - if (timeout == 1000) { - dev_err(&priv->pdev->dev, - "timeout waiting for MAC to come out of reset\n"); - ret = -ETIMEDOUT; - } - return ret; + reg = umac_readl(priv, UMAC_CMD); + reg |= CMD_SW_RESET; + umac_writel(priv, reg, UMAC_CMD); + udelay(10); + reg = umac_readl(priv, UMAC_CMD); + reg &= ~CMD_SW_RESET; + umac_writel(priv, reg, UMAC_CMD); } static void umac_set_hw_addr(struct bcm_sysport_priv *priv, @@ -1303,11 +1292,7 @@ static int bcm_sysport_open(struct net_device *dev) int ret; /* Reset UniMAC */ - ret = umac_reset(priv); - if (ret) { - netdev_err(dev, "UniMAC reset failed\n"); - return ret; - } + umac_reset(priv); /* Flush TX and RX FIFOs at TOPCTRL level */ topctrl_flush(priv); -- cgit v1.2.3 From 16f62d9bed0cdee5f9341b64cc7144869282122d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jun 2014 10:06:46 -0700 Subject: net: systemport: fix TX NAPI work done return value Although we do not limit the number of packets the TX completion function bcm_sysport_tx_reclaim() is allowed to reclaim, we were still using its return value as-is. This means that we could hit the WARN() in net/core/dev.c where work_done >= budget. Make sure we do exit the NAPI context when the TX ring is empty, and pretend there was no work to do. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index d31f7d239064..5776e503e4c5 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -654,13 +654,13 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget) work_done = bcm_sysport_tx_reclaim(ring->priv, ring); - if (work_done < budget) { + if (work_done == 0) { napi_complete(napi); /* re-enable TX interrupt */ intrl2_1_mask_clear(ring->priv, BIT(ring->index)); } - return work_done; + return 0; } static void bcm_sysport_tx_reclaim_all(struct bcm_sysport_priv *priv) -- cgit v1.2.3 From 0f50ce96b7c0488cffe64255694a2451b4347d09 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jun 2014 10:26:20 -0700 Subject: net: bcmgenet: disable clock before register_netdev As soon as register_netdev() is called, the network device notifiers are running which means that other parts of the kernel, or user-space programs can call the network device ndo_open() callback and use the interface. Disable the Ethernet device clock before we register the network device such that we do not create the following situation: CPU0 CPU1 register_netdev() bcmgenet_open() clk_prepare_enable() clk_disable_unprepare() and leave the hardware block gated off, while we think it should be gated on. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 5ba1cfbd60da..d17953cc5f49 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2535,14 +2535,14 @@ static int bcmgenet_probe(struct platform_device *pdev) netif_set_real_num_tx_queues(priv->dev, priv->hw_params->tx_queues + 1); netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); - err = register_netdev(dev); - if (err) - goto err_clk_disable; - /* Turn off the main clock, WOL clock is handled separately */ if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); + err = register_netdev(dev); + if (err) + goto err; + return err; err_clk_disable: -- cgit v1.2.3 From 219575eb6311ad090e26c675a6e217f5d48780a3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jun 2014 10:26:21 -0700 Subject: net: bcmgenet: start with carrier off We use the PHY library which will determine the link state for us, make sure we start with a carrier off until libphy has completed the link training. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index d17953cc5f49..e51e462bc8fd 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2535,6 +2535,9 @@ static int bcmgenet_probe(struct platform_device *pdev) netif_set_real_num_tx_queues(priv->dev, priv->hw_params->tx_queues + 1); netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); + /* libphy will determine the link state */ + netif_carrier_off(dev); + /* Turn off the main clock, WOL clock is handled separately */ if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); -- cgit v1.2.3 From b758858c5ceb1b30ae7d04dea6c74821bd7c7d69 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jun 2014 10:26:22 -0700 Subject: net: bcmgenet: do not set packet length for RX buffers Hardware will provide this information as soon as we will start processing incoming packets, so there is no need to set the RX buffer length during buffer allocation. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index e51e462bc8fd..16281ad2da12 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1408,13 +1408,6 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv) if (cb->skb) continue; - /* set the DMA descriptor length once and for all - * it will only change if we support dynamically sizing - * priv->rx_buf_len, but we do not - */ - dmadesc_set_length_status(priv, priv->rx_bd_assign_ptr, - priv->rx_buf_len << DMA_BUFLENGTH_SHIFT); - ret = bcmgenet_rx_refill(priv, cb); if (ret) break; -- cgit v1.2.3 From 4332ec1a99510943e50acbe03d6c023d5e327093 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 17 Jun 2014 17:03:24 +0300 Subject: clk: ti: am43x: Fix boot with CONFIG_SOC_AM33XX disabled Define ti_clk_register_dpll_x2() and of_ti_am3_dpll_x2_setup() if AM43XX is defined. Fixes the below boot issue. [ 2.157258] gpmc_l3_clk not enabled [ 2.161194] gpmc_l3_clk not enabled [ 2.164896] Division by zero in kernel. [ 2.169055] CPU: 0 PID: 321 Comm: kworker/u2:2 Tainted: G W 3.16.0-rc1-00008-g4c0e520 #273 [ 2.178880] Workqueue: deferwq deferred_probe_work_func [ 2.184459] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 2.192752] [] (show_stack) from [] (dump_stack+0x80/0x9c) [ 2.200486] [] (dump_stack) from [] (Ldiv0+0x8/0x10) [ 2.207678] [] (Ldiv0) from [] (gpmc_calc_divider+0x24/0x40) [ 2.215490] [] (gpmc_calc_divider) from [] (gpmc_cs_set_timings+0x18/0x474) [ 2.224783] [] (gpmc_cs_set_timings) from [] (gpmc_nand_init+0x74/0x1a8) [ 2.233791] [] (gpmc_nand_init) from [] (gpmc_probe+0x52c/0x874) [ 2.242089] [] (gpmc_probe) from [] (platform_drv_probe+0x18/0x48) [ 2.250534] [] (platform_drv_probe) from [] (driver_probe_device+0x104/0x22c) [ 2.259988] [] (driver_probe_device) from [] (bus_for_each_drv+0x44/0x8c) [ 2.269087] [] (bus_for_each_drv) from [] (device_attach+0x74/0x8c) [ 2.277620] [] (device_attach) from [] (bus_probe_device+0x88/0xb0) [ 2.286074] [] (bus_probe_device) from [] (deferred_probe_work_func+0x60/0x90) [ 2.295611] [] (deferred_probe_work_func) from [] (process_one_work+0x1b4/0x4bc) [ 2.305288] [] (process_one_work) from [] (worker_thread+0x148/0x550) [ 2.313954] [] (worker_thread) from [] (kthread+0xc8/0xe4) [ 2.321628] [] (kthread) from [] (ret_from_fork+0x14/0x2c) Signed-off-by: Roger Quadros Signed-off-by: Mike Turquette --- drivers/clk/ti/dpll.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index abd956d5f838..79791e1bf282 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -161,7 +161,8 @@ cleanup: } #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ - defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) + defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \ + defined(CONFIG_SOC_AM43XX) /** * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock * @node: device node for this clock @@ -322,7 +323,7 @@ CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock", of_ti_omap4_dpll_x2_setup); #endif -#ifdef CONFIG_SOC_AM33XX +#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) static void __init of_ti_am3_dpll_x2_setup(struct device_node *node) { ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL); -- cgit v1.2.3 From 2a96dfa49c83a2a7cbdb11382976aaa6b2636764 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 27 Jun 2014 14:21:10 +0200 Subject: clk: s2mps11: Fix double free corruption during driver unbind After unbinding the driver memory was corrupted by double free of clk_lookup structure. This lead to OOPS when re-binding the driver again. The driver allocated memory for 'clk_lookup' with devm_kzalloc. During driver removal this memory was freed twice: once by clkdev_drop() and second by devm code. Kernel panic log: [ 30.839284] Unable to handle kernel paging request at virtual address 5f343173 [ 30.846476] pgd = dee14000 [ 30.849165] [5f343173] *pgd=00000000 [ 30.852703] Internal error: Oops: 805 [#1] PREEMPT SMP ARM [ 30.858166] Modules linked in: [ 30.861208] CPU: 0 PID: 1 Comm: bash Not tainted 3.16.0-rc2-00239-g94bdf617b07e-dirty #40 [ 30.869364] task: df478000 ti: df480000 task.ti: df480000 [ 30.874752] PC is at clkdev_add+0x2c/0x38 [ 30.878738] LR is at clkdev_add+0x18/0x38 [ 30.882732] pc : [] lr : [] psr: 60000013 [ 30.882732] sp : df481e78 ip : 00000001 fp : c0700ed8 [ 30.894187] r10: 0000000c r9 : 00000000 r8 : c07b0e3c [ 30.899396] r7 : 00000002 r6 : df45f9d0 r5 : df421390 r4 : c0700d6c [ 30.905906] r3 : 5f343173 r2 : c0700d84 r1 : 60000013 r0 : c0700d6c [ 30.912417] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user [ 30.919534] Control: 10c53c7d Table: 5ee1406a DAC: 00000015 [ 30.925262] Process bash (pid: 1, stack limit = 0xdf480240) [ 30.930817] Stack: (0xdf481e78 to 0xdf482000) [ 30.935159] 1e60: 00001000 df6de610 [ 30.943321] 1e80: df7f4558 c0355650 c05ec6ec c0700eb0 df6de600 df7f4510 dec9d69c 00000014 [ 30.951480] 1ea0: 00167b48 df6de610 c0700e30 c0713518 00000000 c0700e30 dec9d69c 00000006 [ 30.959639] 1ec0: 00167b48 c02c1b7c c02c1b64 df6de610 c07aff48 c02c0420 c06fb150 c047cc20 [ 30.967798] 1ee0: df6de610 df6de610 c0700e30 df6de644 c06fb150 0000000c dec9d690 c02bef90 [ 30.975957] 1f00: dec9c6c0 dece4c00 df481f80 dece4c00 0000000c c02be73c 0000000c c016ca8c [ 30.984116] 1f20: c016ca48 00000000 00000000 c016c1f4 00000000 00000000 b6f18000 df481f80 [ 30.992276] 1f40: df7f66c0 0000000c df480000 df480000 b6f18000 c011094c df47839c 60000013 [ 31.000435] 1f60: 00000000 00000000 df7f66c0 df7f66c0 0000000c df480000 b6f18000 c0110dd4 [ 31.008594] 1f80: 00000000 00000000 0000000c b6ec05d8 0000000c b6f18000 00000004 c000f2a8 [ 31.016753] 1fa0: 00001000 c000f0e0 b6ec05d8 0000000c 00000001 b6f18000 0000000c 00000000 [ 31.024912] 1fc0: b6ec05d8 0000000c b6f18000 00000004 0000000c 00000001 00000000 00167b48 [ 31.033071] 1fe0: 00000000 bed83a80 b6e004f0 b6e5122c 60000010 00000001 ffffffff ffffffff [ 31.041248] [] (clkdev_add) from [] (s2mps11_clk_probe+0x2b4/0x3b4) [ 31.049223] [] (s2mps11_clk_probe) from [] (platform_drv_probe+0x18/0x48) [ 31.057728] [] (platform_drv_probe) from [] (driver_probe_device+0x13c/0x384) [ 31.066579] [] (driver_probe_device) from [] (bind_store+0x88/0xd8) [ 31.074564] [] (bind_store) from [] (drv_attr_store+0x20/0x2c) [ 31.082118] [] (drv_attr_store) from [] (sysfs_kf_write+0x44/0x48) [ 31.090016] [] (sysfs_kf_write) from [] (kernfs_fop_write+0xc0/0x17c) [ 31.098176] [] (kernfs_fop_write) from [] (vfs_write+0xa0/0x1c4) [ 31.105899] [] (vfs_write) from [] (SyS_write+0x40/0x8c) [ 31.112931] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x3c) [ 31.120481] Code: e2842018 e584501c e1a00004 e885000c (e5835000) [ 31.126596] ---[ end trace efad45bfa3a61b05 ]--- [ 31.131181] Kernel panic - not syncing: Fatal exception [ 31.136368] CPU1: stopping [ 31.139054] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G D 3.16.0-rc2-00239-g94bdf617b07e-dirty #40 [ 31.148697] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 31.156419] [] (show_stack) from [] (dump_stack+0x80/0xcc) [ 31.163622] [] (dump_stack) from [] (handle_IPI+0x130/0x15c) [ 31.170998] [] (handle_IPI) from [] (gic_handle_irq+0x60/0x68) [ 31.178549] [] (gic_handle_irq) from [] (__irq_svc+0x40/0x70) [ 31.186009] Exception stack(0xdf4bdf88 to 0xdf4bdfd0) [ 31.191046] df80: ffffffed 00000000 00000000 00000000 df4bc000 c06d042c [ 31.199207] dfa0: 00000000 ffffffed c06d03c0 00000000 c070c288 00000000 00000000 df4bdfd0 [ 31.207363] dfc0: c0010324 c0010328 60000013 ffffffff [ 31.212402] [] (__irq_svc) from [] (arch_cpu_idle+0x28/0x30) [ 31.219783] [] (arch_cpu_idle) from [] (cpu_startup_entry+0x2c4/0x3f0) [ 31.228027] [] (cpu_startup_entry) from [<400086c4>] (0x400086c4) [ 31.234968] ---[ end Kernel panic - not syncing: Fatal exception Fixes: 7cc560dea415 ("clk: s2mps11: Add support for s2mps11") Cc: Signed-off-by: Krzysztof Kozlowski Reviewed-by: Yadwinder Singh Brar Signed-off-by: Mike Turquette --- drivers/clk/clk-s2mps11.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 9b7b5859a420..3757e9e72d37 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -230,16 +230,13 @@ static int s2mps11_clk_probe(struct platform_device *pdev) goto err_reg; } - s2mps11_clk->lookup = devm_kzalloc(&pdev->dev, - sizeof(struct clk_lookup), GFP_KERNEL); + s2mps11_clk->lookup = clkdev_alloc(s2mps11_clk->clk, + s2mps11_name(s2mps11_clk), NULL); if (!s2mps11_clk->lookup) { ret = -ENOMEM; goto err_lup; } - s2mps11_clk->lookup->con_id = s2mps11_name(s2mps11_clk); - s2mps11_clk->lookup->clk = s2mps11_clk->clk; - clkdev_add(s2mps11_clk->lookup); } -- cgit v1.2.3 From e4adcff09ca39ecbcc4851d40d0f0a5458e7b77a Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 2 Jul 2014 12:16:31 +0800 Subject: usb: chipidea: udc: delete td from req's td list at ep_dequeue We need to delete un-finished td from current request's td list at ep_dequeue API, otherwise, this non-user td will be remained at td list before this request is freed. So if we do ep_queue-> ep_dequeue->ep_queue sequence, when the complete interrupt for the second ep_queue comes, we search td list for this request, the first td (added by the first ep_queue) will be handled, and its status is still active, so we will consider the this transfer still not be completed, but in fact, it has completed. It causes the peripheral side considers it never receives current data for this transfer. We met this problem when do "Error Recovery Test - Device Configured" test item for USBCV2 MSC test, the host has never received ACK for the IN token for CSW due to peripheral considers it does not get this CBW, the USBCV test log like belows: -------------------------------------------------------------------------- INFO Issuing BOT MSC Reset, reset should always succeed INFO Retrieving status on CBW endpoint INFO CBW endpoint status = 0x0 INFO Retrieving status on CSW endpoint INFO CSW endpoint status = 0x0 INFO Issuing required command (Test Unit Ready) to verify device has recovered INFO Issuing CBW (attempt #1): INFO |----- CBW LUN = 0x0 INFO |----- CBW Flags = 0x0 INFO |----- CBW Data Transfer Length = 0x0 INFO |----- CBW CDB Length = 0x6 INFO |----- CBW CDB-00 = 0x0 INFO |----- CBW CDB-01 = 0x0 INFO |----- CBW CDB-02 = 0x0 INFO |----- CBW CDB-03 = 0x0 INFO |----- CBW CDB-04 = 0x0 INFO |----- CBW CDB-05 = 0x0 INFO Issuing CSW : try 1 INFO CSW Bulk Request timed out! ERROR Failed CSW phase : should have been success or stall FAIL (5.3.4) The CSW status value must be 0x00, 0x01, or 0x02. ERROR BOTCommonMSCRequest failed: error=80004000 Cc: Andrzej Pietrasiewicz Cc: stable@vger.kernel.org Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/udc.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 69425b3cb6b7..9d2b673f90e3 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1321,6 +1321,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req); unsigned long flags; + struct td_node *node, *tmpnode; if (ep == NULL || req == NULL || hwreq->req.status != -EALREADY || hwep->ep.desc == NULL || list_empty(&hwreq->queue) || @@ -1331,6 +1332,12 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) hw_ep_flush(hwep->ci, hwep->num, hwep->dir); + list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) { + dma_pool_free(hwep->td_pool, node->ptr, node->dma); + list_del(&node->td); + kfree(node); + } + /* pop request */ list_del_init(&hwreq->queue); -- cgit v1.2.3 From c3dcac875e35c2e67ccaef10ef62ae5b1410d29c Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Sat, 28 Jun 2014 22:53:55 +0530 Subject: clk: sunxi: fix devm_ioremap_resource error detection code devm_ioremap_resource returns an ERR_PTR value, not NULL, on failure. A simplified version of the semantic match that finds this problem is as follows: // @@ expression e,e1; statement S; @@ *e = devm_ioremap_resource(...); if (!e1) S // Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Acked-by Boris BREZILLON Signed-off-by: Mike Turquette --- drivers/clk/sunxi/clk-sun6i-apb0-gates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index 44cd27c5c401..670f90d629d7 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c @@ -29,7 +29,7 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, r); - if (!reg) + if (IS_ERR(reg)) return PTR_ERR(reg); clk_parent = of_clk_get_parent_name(np, 0); -- cgit v1.2.3 From d9daa24720891a88bedb93928f57767da96e5c80 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 28 Jun 2014 01:23:35 +0200 Subject: net: fix circular dependency in of_mdio code Commit 86f6cf4127 (net: of_mdio: add of_mdiobus_link_phydev()) introduced a circular dependency between libphy and of_mdio. depmod: ERROR: /kernel/drivers/net/phy/libphy.ko in dependency cycle! depmod: ERROR: /kernel/drivers/of/of_mdio.ko in dependency cycle! The problem is that of_mdio.c references &mdio_bus_type and libphy now references of_mdiobus_link_phydev. Fix this by not exporting of_mdiobus_link_phydev() from of_mdio.ko. Make it a static function in mdio_bus.c instead. Signed-off-by: Daniel Mack Reported-by: Jeff Mahoney Fixes: 86f6cf4127 (net: of_mdio: add of_mdiobus_link_phydev()) Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ drivers/of/of_mdio.c | 34 ---------------------------------- include/linux/of_mdio.h | 8 -------- 3 files changed, 44 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 2e58aa54484c..4eaadcfcb0fe 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -187,6 +187,50 @@ struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np) return d ? to_mii_bus(d) : NULL; } EXPORT_SYMBOL(of_mdio_find_bus); + +/* Walk the list of subnodes of a mdio bus and look for a node that matches the + * phy's address with its 'reg' property. If found, set the of_node pointer for + * the phy. This allows auto-probed pyh devices to be supplied with information + * passed in via DT. + */ +static void of_mdiobus_link_phydev(struct mii_bus *mdio, + struct phy_device *phydev) +{ + struct device *dev = &phydev->dev; + struct device_node *child; + + if (dev->of_node || !mdio->dev.of_node) + return; + + for_each_available_child_of_node(mdio->dev.of_node, child) { + int addr; + int ret; + + ret = of_property_read_u32(child, "reg", &addr); + if (ret < 0) { + dev_err(dev, "%s has invalid PHY address\n", + child->full_name); + continue; + } + + /* A PHY must have a reg property in the range [0-31] */ + if (addr >= PHY_MAX_ADDR) { + dev_err(dev, "%s PHY address %i is too large\n", + child->full_name, addr); + continue; + } + + if (addr == phydev->addr) { + dev->of_node = child; + return; + } + } +} +#else /* !IS_ENABLED(CONFIG_OF_MDIO) */ +static inline void of_mdiobus_link_phydev(struct mii_bus *mdio, + struct phy_device *phydev) +{ +} #endif /** diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index a3bf2122a8d5..401b2453da45 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -182,40 +182,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) } EXPORT_SYMBOL(of_mdiobus_register); -/** - * of_mdiobus_link_phydev - Find a device node for a phy - * @mdio: pointer to mii_bus structure - * @phydev: phydev for which the of_node pointer should be set - * - * Walk the list of subnodes of a mdio bus and look for a node that matches the - * phy's address with its 'reg' property. If found, set the of_node pointer for - * the phy. This allows auto-probed pyh devices to be supplied with information - * passed in via DT. - */ -void of_mdiobus_link_phydev(struct mii_bus *mdio, - struct phy_device *phydev) -{ - struct device *dev = &phydev->dev; - struct device_node *child; - - if (dev->of_node || !mdio->dev.of_node) - return; - - for_each_available_child_of_node(mdio->dev.of_node, child) { - int addr; - - addr = of_mdio_parse_addr(&mdio->dev, child); - if (addr < 0) - continue; - - if (addr == phydev->addr) { - dev->of_node = child; - return; - } - } -} -EXPORT_SYMBOL(of_mdiobus_link_phydev); - /* Helper function for of_phy_find_device */ static int of_phy_match(struct device *dev, void *phy_np) { diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index a70c9493d55a..d449018d0726 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -25,9 +25,6 @@ struct phy_device *of_phy_attach(struct net_device *dev, extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); -extern void of_mdiobus_link_phydev(struct mii_bus *mdio, - struct phy_device *phydev); - #else /* CONFIG_OF */ static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) { @@ -63,11 +60,6 @@ static inline struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np) { return NULL; } - -static inline void of_mdiobus_link_phydev(struct mii_bus *mdio, - struct phy_device *phydev) -{ -} #endif /* CONFIG_OF */ #if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY) -- cgit v1.2.3 From b397207b7475afa9df2f94541f978100ff1ea47e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 2 Jul 2014 14:10:19 -0400 Subject: drm/radeon/cik: fix typo in EOP packet Volatile bit was in the wrong location. This bit is not used at the moment. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/cikd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index ae88660f34ea..0c6e1b55d968 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -1752,12 +1752,12 @@ #define EOP_TC_WB_ACTION_EN (1 << 15) /* L2 */ #define EOP_TCL1_ACTION_EN (1 << 16) #define EOP_TC_ACTION_EN (1 << 17) /* L2 */ +#define EOP_TCL2_VOLATILE (1 << 24) #define EOP_CACHE_POLICY(x) ((x) << 25) /* 0 - LRU * 1 - Stream * 2 - Bypass */ -#define EOP_TCL2_VOLATILE (1 << 27) #define DATA_SEL(x) ((x) << 29) /* 0 - discard * 1 - send low 32bit data -- cgit v1.2.3 From 7dae77f8809a81b0dc5195debae8fd78cbbcc550 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 2 Jul 2014 21:28:10 +0200 Subject: drm/radeon: page table BOs are kernel allocations Userspace shouldn't be able to access them. Signed-off-by: Christian König Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 899d9126cad6..eecff6bbd341 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -495,7 +495,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, mutex_unlock(&vm->mutex); r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, - RADEON_GPU_PAGE_SIZE, false, + RADEON_GPU_PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, NULL, &pt); if (r) return r; @@ -992,7 +992,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) return -ENOMEM; } - r = radeon_bo_create(rdev, pd_size, align, false, + r = radeon_bo_create(rdev, pd_size, align, true, RADEON_GEM_DOMAIN_VRAM, NULL, &vm->page_directory); if (r) -- cgit v1.2.3 From 186026874cdb57e91cdd080150162f0380348824 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 3 Jul 2014 07:54:26 +1000 Subject: drm: fix permissions on drm_drv.c 1539fb9bd405ee32282ea0a38404f9e008ac5b7a managed to somehow +x drm_drv.c undo it. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 drivers/gpu/drm/drm_drv.c (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c old mode 100755 new mode 100644 -- cgit v1.2.3 From c556bcddc78096caeb46dbe3ad0314dd951f1665 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 25 Jun 2014 14:44:19 -0700 Subject: clk: qcom: HDMI source sel is 3 not 2 The HDMI PLL input to the tv mux is supposed to be 3, not 2. Fix the code so that we can properly select the HDMI PLL. Fixes: 6d00b56fe "clk: qcom: Add support for MSM8960's multimedia clock controller (MMCC)" Reported-by: Rob Clark Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- drivers/clk/qcom/mmcc-msm8960.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 12f3c0b64fcd..4c449b3170f6 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -1209,7 +1209,7 @@ static struct clk_branch rot_clk = { static u8 mmcc_pxo_hdmi_map[] = { [P_PXO] = 0, - [P_HDMI_PLL] = 2, + [P_HDMI_PLL] = 3, }; static const char *mmcc_pxo_hdmi[] = { -- cgit v1.2.3 From 9bd359203210efeb5d8f0d81c155079f34b47449 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 2 Jul 2014 11:35:06 +1000 Subject: md: make sure GET_ARRAY_INFO ioctl reports correct "clean" status If an array has a bitmap, the when we set the "has bitmap" flag we incorrectly clear the "is clean" flag. "is clean" isn't really important when a bitmap is present, but it is best to get it right anyway. Reported-by: George Duffield Link: http://lkml.kernel.org/CAG__1a4MRV6gJL38XLAurtoSiD3rLBTmWpcS5HYvPpSfPR88UQ@mail.gmail.com Fixes: 36fa30636fb84b209210299684e1be66d9e58217 (v2.6.14) Signed-off-by: NeilBrown --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 34846856dbc6..817dbca6059e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5599,7 +5599,7 @@ static int get_array_info(struct mddev * mddev, void __user * arg) if (mddev->in_sync) info.state = (1<bitmap && mddev->bitmap_info.offset) - info.state = (1< Tested-by: Bill Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/53A518BB.60709@sbcglobal.net Signed-off-by: NeilBrown --- drivers/md/md.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 817dbca6059e..32fc19c540d4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7501,6 +7501,19 @@ void md_do_sync(struct md_thread *thread) rdev->recovery_offset < j) j = rdev->recovery_offset; rcu_read_unlock(); + + /* If there is a bitmap, we need to make sure all + * writes that started before we added a spare + * complete before we start doing a recovery. + * Otherwise the write might complete and (via + * bitmap_endwrite) set a bit in the bitmap after the + * recovery has checked that bit and skipped that + * region. + */ + if (mddev->bitmap) { + mddev->pers->quiesce(mddev, 1); + mddev->pers->quiesce(mddev, 0); + } } printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev)); -- cgit v1.2.3 From f46d53d0e9151ea9553361d2bf044ba555350e5f Mon Sep 17 00:00:00 2001 From: Maciej W. Rozycki Date: Sun, 29 Jun 2014 01:45:53 +0100 Subject: defxx: Remove an incorrectly inverted preprocessor conditional The RX handler of the driver has two paths switched between, depending on the size of the frame received, as determined by SKBUFF_RX_COPYBREAK. When a small frame is received, a new skb allocated has data space large enough to hold the incoming frame only, and data is copied there from the original skb whose buffer is returned to the DMA RX ring; in that case `rx_in_place' is 0. When a large frame is received, a new skb allocated has data space large enough to hold the largest frame possible, including the overhead for alignment, the receive status and padding, over 4.5kiB overall, and its buffer is placed on the DMA RX ring while the original buffer is passed up to the network stack avoiding the need to copy data; in that case `rx_in_place' is 1. However the latter scenario is only possible when dynamic buffers are used, as determined by DYNAMIC_BUFFERS, because otherwise the buffers used for the DMA RX ring are fixed at the time the interface is brought up. That leads to an observation that the preprocessor conditional around the `rx_in_place' check is inverted, the check only really matters when dynamic buffers are in use. It has gone unnoticed for many years since support for using dynamic buffers on the DMA RX ring was introduced in 2.1.40 -- because the only problem that results is in the case where `rx_in_place' is 1 frame data received is unnecessarily copied to the newly-allocated buffer, before the buffer placed on the the DMA receive RX and its contents ignored. Therefore the only symptom is some performance loss. Rather than flipping the condition though I decided to discard the conditional altogether -- in the case of static buffers `rx_in_place' is always 0 so GCC will optimise the C conditional away instead. Tested on a few DEFPA and DEFTA boards successfully using both small and large frames, both with DYNAMIC_BUFFERS defined and with the macro undefined. Signed-off-by: Maciej W. Rozycki Signed-off-by: David S. Miller --- drivers/net/fddi/defxx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index eb78203cd58e..052927be074b 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -3074,10 +3074,7 @@ static void dfx_rcv_queue_process( break; } else { -#ifndef DYNAMIC_BUFFERS - if (! rx_in_place) -#endif - { + if (!rx_in_place) { /* Receive buffer allocated, pass receive packet up */ skb_copy_to_linear_data(skb, -- cgit v1.2.3 From 1b037474d0c0b5ceb65bc809e3d8ac4497ee041b Mon Sep 17 00:00:00 2001 From: Maciej W. Rozycki Date: Sun, 29 Jun 2014 02:09:19 +0100 Subject: defxx: Fix !DYNAMIC_BUFFERS compilation warnings This fixes compilation warnings: drivers/net/fddi/defxx.c:294: warning: 'dfx_rcv_flush' declared inline after being called drivers/net/fddi/defxx.c:294: warning: previous declaration of 'dfx_rcv_flush' was here drivers/net/fddi/defxx.c:2854: warning: 'my_skb_align' defined but not used triggered when the driver is built with DYNAMIC_BUFFERS undefined. Code tested to work just fine with these changes and a few DEFPA and DEFTA boards. Signed-off-by: Maciej W. Rozycki Signed-off-by: David S. Miller --- drivers/net/fddi/defxx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index 052927be074b..2aa57270838f 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -291,7 +291,11 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type); static int dfx_rcv_init(DFX_board_t *bp, int get_buffers); static void dfx_rcv_queue_process(DFX_board_t *bp); +#ifdef DYNAMIC_BUFFERS static void dfx_rcv_flush(DFX_board_t *bp); +#else +static inline void dfx_rcv_flush(DFX_board_t *bp) {} +#endif static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb, struct net_device *dev); @@ -2849,7 +2853,7 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type) * Align an sk_buff to a boundary power of 2 * */ - +#ifdef DYNAMIC_BUFFERS static void my_skb_align(struct sk_buff *skb, int n) { unsigned long x = (unsigned long)skb->data; @@ -2859,7 +2863,7 @@ static void my_skb_align(struct sk_buff *skb, int n) skb_reserve(skb, v - x); } - +#endif /* * ================ @@ -3450,10 +3454,6 @@ static void dfx_rcv_flush( DFX_board_t *bp ) } } -#else -static inline void dfx_rcv_flush( DFX_board_t *bp ) -{ -} #endif /* DYNAMIC_BUFFERS */ /* -- cgit v1.2.3 From 35f6f45368632f21bd27559c44dbb1cab51d8947 Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Sun, 29 Jun 2014 11:54:55 +0300 Subject: net/mlx4_en: Don't use irq_affinity_notifier to track changes in IRQ affinity map IRQ affinity notifier can only have a single notifier - cpu_rmap notifier. Can't use it to track changes in IRQ affinity map. Detect IRQ affinity changes by comparing CPU to current IRQ affinity map during NAPI poll thread. CC: Thomas Gleixner CC: Ben Hutchings Fixes: 2eacc23 ("net/mlx4_core: Enforce irq affinity changes immediatly") Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cq.c | 2 - drivers/net/ethernet/mellanox/mlx4/en_cq.c | 4 ++ drivers/net/ethernet/mellanox/mlx4/en_rx.c | 16 +++++-- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 --- drivers/net/ethernet/mellanox/mlx4/eq.c | 69 ++++------------------------ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + include/linux/mlx4/device.h | 4 +- 7 files changed, 28 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c index 80f725228f5b..56022d647837 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/cq.c @@ -294,8 +294,6 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, init_completion(&cq->free); cq->irq = priv->eq_table.eq[cq->vector].irq; - cq->irq_affinity_change = false; - return 0; err_radix: diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c index 4b2130760eed..1213cc71348c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c @@ -128,6 +128,10 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, mlx4_warn(mdev, "Failed assigning an EQ to %s, falling back to legacy EQ's\n", name); } + + cq->irq_desc = + irq_to_desc(mlx4_eq_get_irq(mdev->dev, + cq->vector)); } } else { cq->vector = (cq->ring + 1 + priv->port) % diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index d2d415732d99..96724170308a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "mlx4_en.h" @@ -896,16 +897,25 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget) /* If we used up all the quota - we're probably not done yet... */ if (done == budget) { + int cpu_curr; + const struct cpumask *aff; + INC_PERF_COUNTER(priv->pstats.napi_quota); - if (unlikely(cq->mcq.irq_affinity_change)) { - cq->mcq.irq_affinity_change = false; + + cpu_curr = smp_processor_id(); + aff = irq_desc_get_irq_data(cq->irq_desc)->affinity; + + if (unlikely(!cpumask_test_cpu(cpu_curr, aff))) { + /* Current cpu is not according to smp_irq_affinity - + * probably affinity changed. need to stop this NAPI + * poll, and restart it on the right CPU + */ napi_complete(napi); mlx4_en_arm_cq(priv, cq); return 0; } } else { /* Done for now */ - cq->mcq.irq_affinity_change = false; napi_complete(napi); mlx4_en_arm_cq(priv, cq); } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 8be7483f8236..ac3dead3792c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -474,15 +474,9 @@ int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget) /* If we used up all the quota - we're probably not done yet... */ if (done < budget) { /* Done for now */ - cq->mcq.irq_affinity_change = false; napi_complete(napi); mlx4_en_arm_cq(priv, cq); return done; - } else if (unlikely(cq->mcq.irq_affinity_change)) { - cq->mcq.irq_affinity_change = false; - napi_complete(napi); - mlx4_en_arm_cq(priv, cq); - return 0; } return budget; } diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index d954ec1eac17..2a004b347e1d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -53,11 +53,6 @@ enum { MLX4_EQ_ENTRY_SIZE = 0x20 }; -struct mlx4_irq_notify { - void *arg; - struct irq_affinity_notify notify; -}; - #define MLX4_EQ_STATUS_OK ( 0 << 28) #define MLX4_EQ_STATUS_WRITE_FAIL (10 << 28) #define MLX4_EQ_OWNER_SW ( 0 << 24) @@ -1088,57 +1083,6 @@ static void mlx4_unmap_clr_int(struct mlx4_dev *dev) iounmap(priv->clr_base); } -static void mlx4_irq_notifier_notify(struct irq_affinity_notify *notify, - const cpumask_t *mask) -{ - struct mlx4_irq_notify *n = container_of(notify, - struct mlx4_irq_notify, - notify); - struct mlx4_priv *priv = (struct mlx4_priv *)n->arg; - struct radix_tree_iter iter; - void **slot; - - radix_tree_for_each_slot(slot, &priv->cq_table.tree, &iter, 0) { - struct mlx4_cq *cq = (struct mlx4_cq *)(*slot); - - if (cq->irq == notify->irq) - cq->irq_affinity_change = true; - } -} - -static void mlx4_release_irq_notifier(struct kref *ref) -{ - struct mlx4_irq_notify *n = container_of(ref, struct mlx4_irq_notify, - notify.kref); - kfree(n); -} - -static void mlx4_assign_irq_notifier(struct mlx4_priv *priv, - struct mlx4_dev *dev, int irq) -{ - struct mlx4_irq_notify *irq_notifier = NULL; - int err = 0; - - irq_notifier = kzalloc(sizeof(*irq_notifier), GFP_KERNEL); - if (!irq_notifier) { - mlx4_warn(dev, "Failed to allocate irq notifier. irq %d\n", - irq); - return; - } - - irq_notifier->notify.irq = irq; - irq_notifier->notify.notify = mlx4_irq_notifier_notify; - irq_notifier->notify.release = mlx4_release_irq_notifier; - irq_notifier->arg = priv; - err = irq_set_affinity_notifier(irq, &irq_notifier->notify); - if (err) { - kfree(irq_notifier); - irq_notifier = NULL; - mlx4_warn(dev, "Failed to set irq notifier. irq %d\n", irq); - } -} - - int mlx4_alloc_eq_table(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -1409,8 +1353,6 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char *name, struct cpu_rmap *rmap, continue; /*we dont want to break here*/ } - mlx4_assign_irq_notifier(priv, dev, - priv->eq_table.eq[vec].irq); eq_set_ci(&priv->eq_table.eq[vec], 1); } @@ -1427,6 +1369,14 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char *name, struct cpu_rmap *rmap, } EXPORT_SYMBOL(mlx4_assign_eq); +int mlx4_eq_get_irq(struct mlx4_dev *dev, int vec) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + + return priv->eq_table.eq[vec].irq; +} +EXPORT_SYMBOL(mlx4_eq_get_irq); + void mlx4_release_eq(struct mlx4_dev *dev, int vec) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -1438,9 +1388,6 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec) Belonging to a legacy EQ*/ mutex_lock(&priv->msix_ctl.pool_lock); if (priv->msix_ctl.pool_bm & 1ULL << i) { - irq_set_affinity_notifier( - priv->eq_table.eq[vec].irq, - NULL); free_irq(priv->eq_table.eq[vec].irq, &priv->eq_table.eq[vec]); priv->msix_ctl.pool_bm &= ~(1ULL << i); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 0e15295bedd6..624e1939e9ee 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -343,6 +343,7 @@ struct mlx4_en_cq { #define CQ_USER_PEND (MLX4_EN_CQ_STATE_POLL | MLX4_EN_CQ_STATE_POLL_YIELD) spinlock_t poll_lock; /* protects from LLS/napi conflicts */ #endif /* CONFIG_NET_RX_BUSY_POLL */ + struct irq_desc *irq_desc; }; struct mlx4_en_port_profile { diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index b12f4bbd064c..35b51e7af886 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -578,8 +578,6 @@ struct mlx4_cq { u32 cons_index; u16 irq; - bool irq_affinity_change; - __be32 *set_ci_db; __be32 *arm_db; int arm_sn; @@ -1167,6 +1165,8 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char *name, struct cpu_rmap *rmap, int *vector); void mlx4_release_eq(struct mlx4_dev *dev, int vec); +int mlx4_eq_get_irq(struct mlx4_dev *dev, int vec); + int mlx4_get_phys_port_id(struct mlx4_dev *dev); int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port); int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port); -- cgit v1.2.3 From bb273617a65b9ed75f8cf9417206cbfcfb41fc48 Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Sun, 29 Jun 2014 11:54:57 +0300 Subject: net/mlx4_en: IRQ affinity hint is not cleared on port down Need to remove affinity hint at mlx4_en_deactivate_cq() and not at mlx4_en_destroy_cq() - since affinity_mask might be free'd while still being used by procfs. Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_cq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c index 1213cc71348c..14c00048bbec 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c @@ -191,8 +191,6 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq) mlx4_en_unmap_buffer(&cq->wqres.buf); mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); if (priv->mdev->dev->caps.comp_pool && cq->vector) { - if (!cq->is_tx) - irq_set_affinity_hint(cq->mcq.irq, NULL); mlx4_release_eq(priv->mdev->dev, cq->vector); } cq->vector = 0; @@ -208,6 +206,7 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) if (!cq->is_tx) { napi_hash_del(&cq->napi); synchronize_rcu(); + irq_set_affinity_hint(cq->mcq.irq, NULL); } netif_napi_del(&cq->napi); -- cgit v1.2.3 From 0acf16768740776feffac506ce93b1c06c059ac6 Mon Sep 17 00:00:00 2001 From: Vince Bridgers Date: Sun, 29 Jun 2014 20:34:51 -0500 Subject: net: stmmac: add platform init/exit for Altera's ARM socfpga This patch adds platform init/exit functions and modifications to support suspend/resume for the Altera Cyclone 5 SOC Ethernet controller. The platform exit function puts the controller into reset using the socfpga reset controller driver. The platform init function sets up the Synopsys mac by first making sure the Ethernet controller is held in reset, programming the phy mode through external support logic, then deasserts reset through the socfpga reset manager driver. Signed-off-by: Vince Bridgers Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 69 ++++++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++ 2 files changed, 73 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index fd8a217556a1..ec632e666c56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include "stmmac.h" #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 @@ -34,6 +36,7 @@ struct socfpga_dwmac { u32 reg_shift; struct device *dev; struct regmap *sys_mgr_base_addr; + struct reset_control *stmmac_rst; }; static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) @@ -43,6 +46,13 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * u32 reg_offset, reg_shift; int ret; + dwmac->stmmac_rst = devm_reset_control_get(dev, + STMMAC_RESOURCE_NAME); + if (IS_ERR(dwmac->stmmac_rst)) { + dev_info(dev, "Could not get reset control!\n"); + return -EINVAL; + } + dwmac->interface = of_get_phy_mode(np); sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); @@ -125,6 +135,65 @@ static void *socfpga_dwmac_probe(struct platform_device *pdev) return dwmac; } +static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) +{ + struct socfpga_dwmac *dwmac = priv; + + /* On socfpga platform exit, assert and hold reset to the + * enet controller - the default state after a hard reset. + */ + if (dwmac->stmmac_rst) + reset_control_assert(dwmac->stmmac_rst); +} + +static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) +{ + struct socfpga_dwmac *dwmac = priv; + struct net_device *ndev = platform_get_drvdata(pdev); + struct stmmac_priv *stpriv = NULL; + int ret = 0; + + if (ndev) + stpriv = netdev_priv(ndev); + + /* Assert reset to the enet controller before changing the phy mode */ + if (dwmac->stmmac_rst) + reset_control_assert(dwmac->stmmac_rst); + + /* Setup the phy mode in the system manager registers according to + * devicetree configuration + */ + ret = socfpga_dwmac_setup(dwmac); + + /* Deassert reset for the phy configuration to be sampled by + * the enet controller, and operation to start in requested mode + */ + if (dwmac->stmmac_rst) + reset_control_deassert(dwmac->stmmac_rst); + + /* Before the enet controller is suspended, the phy is suspended. + * This causes the phy clock to be gated. The enet controller is + * resumed before the phy, so the clock is still gated "off" when + * the enet controller is resumed. This code makes sure the phy + * is "resumed" before reinitializing the enet controller since + * the enet controller depends on an active phy clock to complete + * a DMA reset. A DMA reset will "time out" if executed + * with no phy clock input on the Synopsys enet controller. + * Verified through Synopsys Case #8000711656. + * + * Note that the phy clock is also gated when the phy is isolated. + * Phy "suspend" and "isolate" controls are located in phy basic + * control register 0, and can be modified by the phy driver + * framework. + */ + if (stpriv && stpriv->phydev) + phy_resume(stpriv->phydev); + + return ret; +} + const struct stmmac_of_data socfpga_gmac_data = { .setup = socfpga_dwmac_probe, + .init = socfpga_dwmac_init, + .exit = socfpga_dwmac_exit, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 057a1208e594..18315f34938b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2878,6 +2878,10 @@ int stmmac_suspend(struct net_device *ndev) clk_disable_unprepare(priv->stmmac_clk); } spin_unlock_irqrestore(&priv->lock, flags); + + priv->oldlink = 0; + priv->speed = 0; + priv->oldduplex = -1; return 0; } -- cgit v1.2.3 From 43d24e48940d04f587818fadc5305b109f5cb8cf Mon Sep 17 00:00:00 2001 From: Vince Bridgers Date: Sun, 29 Jun 2014 20:34:52 -0500 Subject: net: stmmac: Correct duplicate if/then/else case found by cppcheck Cppcheck found a duplicate if/then/else case where a receive descriptor was being processed. This patch corrects that issue. cppcheck --force --enable=all --inline-suppr . ... Checking enh_desc.c... [enh_desc.c:148] -> [enh_desc.c:144]: (style) Found duplicate if expressions. ... Signed-off-by: Vince Bridgers Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 7e6628a91514..1e2bcf5f89e1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -145,7 +145,7 @@ static void enh_desc_get_ext_status(void *data, struct stmmac_extra_stats *x, x->rx_msg_type_delay_req++; else if (p->des4.erx.msg_type == RDES_EXT_DELAY_RESP) x->rx_msg_type_delay_resp++; - else if (p->des4.erx.msg_type == RDES_EXT_DELAY_REQ) + else if (p->des4.erx.msg_type == RDES_EXT_PDELAY_REQ) x->rx_msg_type_pdelay_req++; else if (p->des4.erx.msg_type == RDES_EXT_PDELAY_RESP) x->rx_msg_type_pdelay_resp++; -- cgit v1.2.3 From c8df8ce3ee5ff24993bba9033e7d13b16fa3809c Mon Sep 17 00:00:00 2001 From: Vince Bridgers Date: Sun, 29 Jun 2014 20:34:53 -0500 Subject: net: stmmac: Remove unneeded I/O read caught by cppcheck Cppcheck found a case where a local variable was being assigned a value, but not used. There seems to be no reason to read this register before assigning a new value, so addressing thie issue. cppcheck --force --enable=all --inline-suppr . shows ... Variable 'value' is reassigned a value before the old one has been used. Signed-off-by: Vince Bridgers Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index b3e148ef5683..9d3748361a1e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -320,11 +320,8 @@ static void dwmac1000_set_eee_timer(void __iomem *ioaddr, int ls, int tw) static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart) { - u32 value; - - value = readl(ioaddr + GMAC_AN_CTRL); /* auto negotiation enable and External Loopback enable */ - value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE; + u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE; if (restart) value |= GMAC_AN_CTRL_RAN; -- cgit v1.2.3 From 4e578080ed3262ed2c3985868539bc66218d25c0 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 2 Jul 2014 15:47:04 +0200 Subject: drm/vmwgfx: Fix incorrect write to read-only register v2: Commit "drm/vmwgfx: correct fb_fix_screeninfo.line_length", while fixing a vmwgfx fbdev bug, also writes the pitch to a supposedly read-only register: SVGA_REG_BYTES_PER_LINE, while it should be (and also in fact is) written to SVGA_REG_PITCHLOCK. This patch is Cc'd stable because of the unknown effects writing to this register might have, particularly on older device versions. v2: Updated log message. Cc: stable@vger.kernel.org Cc: Christopher Friedt Tested-by: Christopher Friedt Signed-off-by: Thomas Hellstrom Reviewed-by: Jakob Bornecrantz --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index a89ad938eacf..b031b48dbb3c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -179,7 +179,6 @@ static int vmw_fb_set_par(struct fb_info *info) vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, info->var.yoffset); vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); - vmw_write(vmw_priv, SVGA_REG_BYTES_PER_LINE, info->fix.line_length); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); } -- cgit v1.2.3 From 2e32baea46ce542c561a519414c840295b229c8f Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Wed, 2 Jul 2014 15:22:36 -0700 Subject: zram: revalidate disk after capacity change Alexander reported mkswap on /dev/zram0 is failed if other process is opening the block device file. Step is as follows, 0. Reset the unused zram device. 1. Use a program that opens /dev/zram0 with O_RDWR and sleeps until killed. 2. While that program sleeps, echo the correct value to /sys/block/zram0/disksize. 3. Verify (e.g. in /proc/partitions) that the disk size is applied correctly. It is. 4. While that program still sleeps, attempt to mkswap /dev/zram0. This fails: mkswap: error: swap area needs to be at least 40 KiB When I investigated, the size get by ioctl(fd, BLKGETSIZE64, xxx) on mkswap to get a size of blockdev was zero although zram0 has right size by 2. The reason is zram didn't revalidate disk after changing capacity so that size of blockdev's inode is not uptodate until all of file is close. This patch should fix the BUG. Signed-off-by: Minchan Kim Reported-by: Alexander E. Patrakov Tested-by: Alexander E. Patrakov Reviewed-by: Sergey Senozhatsky Cc: Nitin Gupta Acked-by: Jerome Marchand Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zram_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 48eccb350180..089e72cd37be 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -622,8 +622,10 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity) memset(&zram->stats, 0, sizeof(zram->stats)); zram->disksize = 0; - if (reset_capacity) + if (reset_capacity) { set_capacity(zram->disk, 0); + revalidate_disk(zram->disk); + } up_write(&zram->init_lock); } @@ -664,6 +666,7 @@ static ssize_t disksize_store(struct device *dev, zram->comp = comp; zram->disksize = disksize; set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); + revalidate_disk(zram->disk); up_write(&zram->init_lock); return len; -- cgit v1.2.3 From df86754b746e9a0ff6f863f690b1c01d408e3cdc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 2 Jul 2014 07:44:44 +0800 Subject: hwmon: (amc6821) Fix permissions for temp2_input temp2_input should not be writable, fix it. Reported-by: Guenter Roeck Signed-off-by: Axel Lin Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/amc6821.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index eea817296513..9f2be3dd28f3 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -704,7 +704,7 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, get_temp_alarm, NULL, IDX_TEMP1_MAX); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, get_temp_alarm, NULL, IDX_TEMP1_CRIT); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO | S_IWUSR, +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_temp, NULL, IDX_TEMP2_INPUT); static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, get_temp, set_temp, IDX_TEMP2_MIN); -- cgit v1.2.3 From 1035a9e3e9c76b64a860a774f5b867d28d34acc2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 2 Jul 2014 08:29:55 +0800 Subject: hwmon: (adm1029) Ensure the fan_div cache is updated in set_fan_div Writing to fanX_div does not clear the cache. As a result, reading from fanX_div may return the old value for up to two seconds after writing a new value. This patch ensures the fan_div cache is updated in set_fan_div(). Reported-by: Guenter Roeck Signed-off-by: Axel Lin Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/adm1029.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 78339e880bd6..2804571b269e 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -232,6 +232,9 @@ static ssize_t set_fan_div(struct device *dev, /* Update the value */ reg = (reg & 0x3F) | (val << 6); + /* Update the cache */ + data->fan_div[attr->index] = reg; + /* Write value */ i2c_smbus_write_byte_data(client, ADM1029_REG_FAN_DIV[attr->index], reg); -- cgit v1.2.3 From c024044d4da2c9c3b32933b4235df1e409293b84 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 3 Jul 2014 22:45:45 +0800 Subject: hwmon: (adm1021) Fix cache problem when writing temperature limits The module test script for the adm1021 driver exposes a cache problem when writing temperature limits. temp_min and temp_max are expected to be stored in milli-degrees C but are stored in degrees C. Reported-by: Guenter Roeck Signed-off-by: Axel Lin Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/adm1021.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 3eb4281689b5..d74241bb278c 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -185,7 +185,7 @@ static ssize_t set_temp_max(struct device *dev, struct adm1021_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; long temp; - int err; + int reg_val, err; err = kstrtol(buf, 10, &temp); if (err) @@ -193,10 +193,11 @@ static ssize_t set_temp_max(struct device *dev, temp /= 1000; mutex_lock(&data->update_lock); - data->temp_max[index] = clamp_val(temp, -128, 127); + reg_val = clamp_val(temp, -128, 127); + data->temp_max[index] = reg_val * 1000; if (!read_only) i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index), - data->temp_max[index]); + reg_val); mutex_unlock(&data->update_lock); return count; @@ -210,7 +211,7 @@ static ssize_t set_temp_min(struct device *dev, struct adm1021_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; long temp; - int err; + int reg_val, err; err = kstrtol(buf, 10, &temp); if (err) @@ -218,10 +219,11 @@ static ssize_t set_temp_min(struct device *dev, temp /= 1000; mutex_lock(&data->update_lock); - data->temp_min[index] = clamp_val(temp, -128, 127); + reg_val = clamp_val(temp, -128, 127); + data->temp_min[index] = reg_val * 1000; if (!read_only) i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index), - data->temp_min[index]); + reg_val); mutex_unlock(&data->update_lock); return count; -- cgit v1.2.3 From c149dcb5c60bfea8871f16dfcc0690255eeb825f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 4 Jul 2014 10:00:37 +0800 Subject: drm/i915: provide interface for audio driver to query cdclk For Haswell and Broadwell, if the display power well has been disabled, the display audio controller divider values EM4 M VALUE and EM5 N VALUE will have been lost. The CDCLK frequency is required for reprogramming them to generate 24MHz HD-A link BCLK. So provide a private interface for the audio driver to query CDCLK. This is a stopgap solution until a more generic interface between audio and display drivers has been implemented. Signed-off-by: Jani Nikula Reviewed-by: Damien Lespiau Signed-off-by: Mengdong Lin Cc: Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/intel_pm.c | 21 +++++++++++++++++++++ include/drm/i915_powerwell.h | 1 + 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6463f0201cf2..409d62676854 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6053,6 +6053,27 @@ int i915_release_power_well(void) } EXPORT_SYMBOL_GPL(i915_release_power_well); +/* + * Private interface for the audio driver to get CDCLK in kHz. + * + * Caller must request power well using i915_request_power_well() prior to + * making the call. + */ +int i915_get_cdclk_freq(void) +{ + struct drm_i915_private *dev_priv; + + if (!hsw_pwr) + return -ENODEV; + + dev_priv = container_of(hsw_pwr, struct drm_i915_private, + power_domains); + + return intel_ddi_get_cdclk_freq(dev_priv); +} +EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); + + #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ diff --git a/include/drm/i915_powerwell.h b/include/drm/i915_powerwell.h index 2baba9996094..baa6f11b1837 100644 --- a/include/drm/i915_powerwell.h +++ b/include/drm/i915_powerwell.h @@ -32,5 +32,6 @@ /* For use by hda_i915 driver */ extern int i915_request_power_well(void); extern int i915_release_power_well(void); +extern int i915_get_cdclk_freq(void); #endif /* _I915_POWERWELL_H_ */ -- cgit v1.2.3 From 89e6a13b88c8bf7ce1011a8a69113f22889f4585 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Sat, 5 Jul 2014 06:38:55 +0900 Subject: clocksource: exynos_mct: Fix ftrace In (93bfb76 clocksource: exynos_mct: register sched_clock callback) we supported using the MCT as a scheduler clock. We properly marked exynos4_read_sched_clock() as notrace. However, we then went and called another function that _wasn't_ notrace. That means if you do: cd /sys/kernel/debug/tracing/ echo function_graph > current_tracer You'll get a crash. Fix this (but still let other readers of the MCT be trace-enabled) by adding an extra function. It's important to keep other users of MCT traceable because the MCT is actually quite slow to access and we want exynos4_frc_read() to show up in ftrace profiles if it's the bottleneck. Signed-off-by: Doug Anderson Signed-off-by: Kukjin Kim --- drivers/clocksource/exynos_mct.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index f71d55f5e6e5..5ce99c07ce8c 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -162,7 +162,7 @@ static void exynos4_mct_frc_start(void) exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON); } -static cycle_t exynos4_frc_read(struct clocksource *cs) +static cycle_t notrace _exynos4_frc_read(void) { unsigned int lo, hi; u32 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U); @@ -176,6 +176,11 @@ static cycle_t exynos4_frc_read(struct clocksource *cs) return ((cycle_t)hi << 32) | lo; } +static cycle_t exynos4_frc_read(struct clocksource *cs) +{ + return _exynos4_frc_read(); +} + static void exynos4_frc_resume(struct clocksource *cs) { exynos4_mct_frc_start(); @@ -192,7 +197,7 @@ struct clocksource mct_frc = { static u64 notrace exynos4_read_sched_clock(void) { - return exynos4_frc_read(&mct_frc); + return _exynos4_frc_read(); } static void __init exynos4_clocksource_init(void) -- cgit v1.2.3 From 8bf13a4346996b5a53d5f0c64b0914693c818fc2 Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Sat, 5 Jul 2014 06:40:23 +0900 Subject: clocksource: exynos_mct: Register the timer for stable udelay This patch registers the exynos mct clocksource as the current timer as it has constant clock rate. This will generate correct udelay for the exynos platform and avoid using unnecessary calibrated jiffies. This change has been tested on exynos5420 based board and udelay is very close to expected. Without this patch udelay() on exynos5400 / exynos5800 is wildly inaccurate due to big.LITTLE not adjusting loops_per_jiffy correctly. Also without this patch udelay() on exynos5250 can be innacruate during transitions between frequencies < 800 MHz (you'll go 200 MHz -> 800 MHz -> 300 MHz and will run at 800 MHz for a time with the wrong loops_per_jiffy). [dianders: reworked and created version 3] Signed-off-by: Amit Daniel Kachhap Signed-off-by: Doug Anderson Signed-off-by: Kukjin Kim --- drivers/clocksource/exynos_mct.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 5ce99c07ce8c..ab51bf20a3ed 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -200,10 +200,21 @@ static u64 notrace exynos4_read_sched_clock(void) return _exynos4_frc_read(); } +static struct delay_timer exynos4_delay_timer; + +static cycles_t exynos4_read_current_timer(void) +{ + return _exynos4_frc_read(); +} + static void __init exynos4_clocksource_init(void) { exynos4_mct_frc_start(); + exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer; + exynos4_delay_timer.freq = clk_rate; + register_current_timer_delay(&exynos4_delay_timer); + if (clocksource_register_hz(&mct_frc, clk_rate)) panic("%s: can't register clocksource\n", mct_frc.name); -- cgit v1.2.3 From ef8290ac727b1718417a781412fb6c25e97b5389 Mon Sep 17 00:00:00 2001 From: Michael Welling Date: Tue, 10 Jun 2014 13:46:34 -0500 Subject: gpio: mcp23s08: Eliminates redundant checking. Unnecessary checking was added during the merge of the gpio branch. This patch removes the extra unnecessary checking. Signed-off-by: Michael Welling Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index fe7c0e211f9a..57adbc90fdad 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -900,8 +900,6 @@ static int mcp23s08_probe(struct spi_device *spi) if (spi_present_mask & (1 << addr)) chips++; } - if (!chips) - return -ENODEV; } else { type = spi_get_device_id(spi)->driver_data; pdata = dev_get_platdata(&spi->dev); @@ -940,10 +938,6 @@ static int mcp23s08_probe(struct spi_device *spi) if (!(spi_present_mask & (1 << addr))) continue; chips--; - if (chips < 0) { - dev_err(&spi->dev, "FATAL: invalid negative chip id\n"); - goto fail; - } data->mcp[addr] = &data->chip[chips]; status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, 0x40 | (addr << 1), type, base, -- cgit v1.2.3 From 1419d8151be990f115c38deac497ad84d26434dd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 11 Jun 2014 11:15:13 +0300 Subject: pinctrl: berlin: fix an error code in berlin_pinctrl_probe() We are returning success here because PTR_ERR(NULL) is zero. We should be returning -ENODEV. Fixes: 3de68d331c24 ('pinctrl: berlin: add the core pinctrl driver for Marvell Berlin SoCs') Signed-off-by: Dan Carpenter Acked-by: Sebastian Hesselbarth Signed-off-by: Linus Walleij --- drivers/pinctrl/berlin/berlin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c index edf5d2fd2b22..86db2235ab00 100644 --- a/drivers/pinctrl/berlin/berlin.c +++ b/drivers/pinctrl/berlin/berlin.c @@ -320,7 +320,7 @@ int berlin_pinctrl_probe(struct platform_device *pdev, regmap = dev_get_regmap(&pdev->dev, NULL); if (!regmap) - return PTR_ERR(regmap); + return -ENODEV; pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); if (!pctrl) -- cgit v1.2.3 From 6c3d8d4f05ec477f68615dc6120c46fec64a2268 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Mar 2014 07:44:00 +0000 Subject: iio: hid-sensor-press: Fix return values IIO_CHAN_INFO_SAMP_FREQ and IIO_CHAN_INFO_HYSTERESIS cases ignored the actual return values (which could be -EINVAL) and instead returned IIO_VAL_INT_PLUS_MICRO always. Return the actual value obtained from the functions. Both functions return IIO_VAL_INT_PLUS_MICRO upon success. Agreed with by Srinivas. Signed-off-by: Sachin Kamat Cc: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/hid-sensor-press.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c index 1cd190c73788..2c0d2a4fed8c 100644 --- a/drivers/iio/pressure/hid-sensor-press.c +++ b/drivers/iio/pressure/hid-sensor-press.c @@ -78,7 +78,6 @@ static int press_read_raw(struct iio_dev *indio_dev, struct press_state *press_state = iio_priv(indio_dev); int report_id = -1; u32 address; - int ret; int ret_type; s32 poll_value; @@ -128,14 +127,12 @@ static int press_read_raw(struct iio_dev *indio_dev, ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: - ret = hid_sensor_read_samp_freq_value( + ret_type = hid_sensor_read_samp_freq_value( &press_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; case IIO_CHAN_INFO_HYSTERESIS: - ret = hid_sensor_read_raw_hyst_value( + ret_type = hid_sensor_read_raw_hyst_value( &press_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; default: ret_type = -EINVAL; -- cgit v1.2.3 From 2f084c17562a3a20ee0cc11d3863ca5e8fd4e10b Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Mar 2014 07:44:00 +0000 Subject: iio: hid-sensor-accel-3d: Fix return values IIO_CHAN_INFO_SAMP_FREQ and IIO_CHAN_INFO_HYSTERESIS cases ignored the actual return values (which could be -EINVAL) and instead returned IIO_VAL_INT_PLUS_MICRO always. Return the actual value obtained from the functions. Both functions return IIO_VAL_INT_PLUS_MICRO upon success. Signed-off-by: Sachin Kamat Cc: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/hid-sensor-accel-3d.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 69abf9163df7..54e464e4bb72 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -110,7 +110,6 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev, struct accel_3d_state *accel_state = iio_priv(indio_dev); int report_id = -1; u32 address; - int ret; int ret_type; s32 poll_value; @@ -151,14 +150,12 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev, ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: - ret = hid_sensor_read_samp_freq_value( + ret_type = hid_sensor_read_samp_freq_value( &accel_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; case IIO_CHAN_INFO_HYSTERESIS: - ret = hid_sensor_read_raw_hyst_value( + ret_type = hid_sensor_read_raw_hyst_value( &accel_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; default: ret_type = -EINVAL; -- cgit v1.2.3 From 5f25b41f7ec242fce43d0f745369c0ba9d25cb72 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Mar 2014 07:44:00 +0000 Subject: iio: hid-sensor-magn-3d: Fix return values IIO_CHAN_INFO_SAMP_FREQ and IIO_CHAN_INFO_HYSTERESIS cases ignored the actual return values (which could be -EINVAL) and instead returned IIO_VAL_INT_PLUS_MICRO always. Return the actual value obtained from the functions. Both functions return IIO_VAL_INT_PLUS_MICRO upon success. Signed-off-by: Sachin Kamat Cc: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index 41cf29e2a371..b2b0937d5133 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -110,7 +110,6 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev, struct magn_3d_state *magn_state = iio_priv(indio_dev); int report_id = -1; u32 address; - int ret; int ret_type; s32 poll_value; @@ -153,14 +152,12 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev, ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: - ret = hid_sensor_read_samp_freq_value( + ret_type = hid_sensor_read_samp_freq_value( &magn_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; case IIO_CHAN_INFO_HYSTERESIS: - ret = hid_sensor_read_raw_hyst_value( + ret_type = hid_sensor_read_raw_hyst_value( &magn_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; default: ret_type = -EINVAL; -- cgit v1.2.3 From 5d24b0b37bd5229227d0271c58b15aeb52e9c966 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Mar 2014 07:44:00 +0000 Subject: iio: hid-sensor-als: Fix return values IIO_CHAN_INFO_SAMP_FREQ and IIO_CHAN_INFO_HYSTERESIS cases ignored the actual return values (which could be -EINVAL) and instead returned IIO_VAL_INT_PLUS_MICRO always. Return the actual value obtained from the functions. Both functions return IIO_VAL_INT_PLUS_MICRO upon success. Signed-off-by: Sachin Kamat Cc: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/light/hid-sensor-als.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index f34c94380b41..96e71e103ea7 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -79,7 +79,6 @@ static int als_read_raw(struct iio_dev *indio_dev, struct als_state *als_state = iio_priv(indio_dev); int report_id = -1; u32 address; - int ret; int ret_type; s32 poll_value; @@ -129,14 +128,12 @@ static int als_read_raw(struct iio_dev *indio_dev, ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: - ret = hid_sensor_read_samp_freq_value( + ret_type = hid_sensor_read_samp_freq_value( &als_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; case IIO_CHAN_INFO_HYSTERESIS: - ret = hid_sensor_read_raw_hyst_value( + ret_type = hid_sensor_read_raw_hyst_value( &als_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; default: ret_type = -EINVAL; -- cgit v1.2.3 From 27793803f2ea876799cc44e05bb28d34b34a3869 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Mar 2014 07:44:00 +0000 Subject: iio: hid-sensor-gyro-3d: Fix return values IIO_CHAN_INFO_SAMP_FREQ and IIO_CHAN_INFO_HYSTERESIS cases ignored the actual return values (which could be -EINVAL) and instead returned IIO_VAL_INT_PLUS_MICRO always. Return the actual value obtained from the functions. Both functions return IIO_VAL_INT_PLUS_MICRO upon success. Signed-off-by: Sachin Kamat Cc: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/hid-sensor-gyro-3d.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 40f4e4935d0d..fa034a3dad78 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -110,7 +110,6 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev, struct gyro_3d_state *gyro_state = iio_priv(indio_dev); int report_id = -1; u32 address; - int ret; int ret_type; s32 poll_value; @@ -151,14 +150,12 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev, ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: - ret = hid_sensor_read_samp_freq_value( + ret_type = hid_sensor_read_samp_freq_value( &gyro_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; case IIO_CHAN_INFO_HYSTERESIS: - ret = hid_sensor_read_raw_hyst_value( + ret_type = hid_sensor_read_raw_hyst_value( &gyro_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; default: ret_type = -EINVAL; -- cgit v1.2.3 From 4ff9f633c35e2d94eb92f92c48ae0d9172242889 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 7 Mar 2014 07:44:00 +0000 Subject: iio: hid-sensor-prox: Fix return values IIO_CHAN_INFO_SAMP_FREQ and IIO_CHAN_INFO_HYSTERESIS cases ignored the actual return values (which could be -EINVAL) and instead returned IIO_VAL_INT_PLUS_MICRO always. Return the actual value obtained from the functions. Both functions return IIO_VAL_INT_PLUS_MICRO upon success. Signed-off-by: Sachin Kamat Cc: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/light/hid-sensor-prox.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index d203ef4d892f..412bae86d6ae 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -74,7 +74,6 @@ static int prox_read_raw(struct iio_dev *indio_dev, struct prox_state *prox_state = iio_priv(indio_dev); int report_id = -1; u32 address; - int ret; int ret_type; s32 poll_value; @@ -125,14 +124,12 @@ static int prox_read_raw(struct iio_dev *indio_dev, ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: - ret = hid_sensor_read_samp_freq_value( + ret_type = hid_sensor_read_samp_freq_value( &prox_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; case IIO_CHAN_INFO_HYSTERESIS: - ret = hid_sensor_read_raw_hyst_value( + ret_type = hid_sensor_read_raw_hyst_value( &prox_state->common_attributes, val, val2); - ret_type = IIO_VAL_INT_PLUS_MICRO; break; default: ret_type = -EINVAL; -- cgit v1.2.3 From 6938ad40cb97a52d88a763008935340729a4acc7 Mon Sep 17 00:00:00 2001 From: Ted Juan Date: Fri, 20 Jun 2014 17:32:05 +0800 Subject: mtd: devices: elm: fix elm_context_save() and elm_context_restore() functions These two function's switch case lack the 'break' that make them always return error. Signed-off-by: Ted Juan Acked-by: Pekon Gupta Cc: # 3.12.x+ Signed-off-by: Brian Norris --- drivers/mtd/devices/elm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c index 7df86948e6d4..b4f61c7fc161 100644 --- a/drivers/mtd/devices/elm.c +++ b/drivers/mtd/devices/elm.c @@ -475,6 +475,7 @@ static int elm_context_save(struct elm_info *info) ELM_SYNDROME_FRAGMENT_1 + offset); regs->elm_syndrome_fragment_0[i] = elm_read_reg(info, ELM_SYNDROME_FRAGMENT_0 + offset); + break; default: return -EINVAL; } @@ -520,6 +521,7 @@ static int elm_context_restore(struct elm_info *info) regs->elm_syndrome_fragment_1[i]); elm_write_reg(info, ELM_SYNDROME_FRAGMENT_0 + offset, regs->elm_syndrome_fragment_0[i]); + break; default: return -EINVAL; } -- cgit v1.2.3 From e63f6e28dda6de3de2392ddca321e211fd860925 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Mon, 7 Jul 2014 01:13:46 +0200 Subject: Revert "ACPI / AC: Remove AC's proc directory." Revert commit ab0fd674d6ce (ACPI / AC: Remove AC's proc directory.), because some old tools (e.g. kpowersave from kde 3.5.10) are still using /proc/acpi/ac_adapter. Fixes: ab0fd674d6ce (ACPI / AC: Remove AC's proc directory.) Reported-and-tested-by: Sorin Manolache Signed-off-by: Lan Tianyu Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ac.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index c67f6f5ad611..36b0e61f9c09 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -30,6 +30,10 @@ #include #include #include +#ifdef CONFIG_ACPI_PROCFS_POWER +#include +#include +#endif #include #include #include @@ -52,6 +56,7 @@ MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI AC Adapter Driver"); MODULE_LICENSE("GPL"); + static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_remove(struct acpi_device *device); static void acpi_ac_notify(struct acpi_device *device, u32 event); @@ -67,6 +72,13 @@ static int acpi_ac_resume(struct device *dev); #endif static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); +#ifdef CONFIG_ACPI_PROCFS_POWER +extern struct proc_dir_entry *acpi_lock_ac_dir(void); +extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); +static int acpi_ac_open_fs(struct inode *inode, struct file *file); +#endif + + static int ac_sleep_before_get_state_ms; static struct acpi_driver acpi_ac_driver = { @@ -91,6 +103,16 @@ struct acpi_ac { #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) +#ifdef CONFIG_ACPI_PROCFS_POWER +static const struct file_operations acpi_ac_fops = { + .owner = THIS_MODULE, + .open = acpi_ac_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + /* -------------------------------------------------------------------------- AC Adapter Management -------------------------------------------------------------------------- */ @@ -143,6 +165,83 @@ static enum power_supply_property ac_props[] = { POWER_SUPPLY_PROP_ONLINE, }; +#ifdef CONFIG_ACPI_PROCFS_POWER +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +static struct proc_dir_entry *acpi_ac_dir; + +static int acpi_ac_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_ac *ac = seq->private; + + + if (!ac) + return 0; + + if (acpi_ac_get_state(ac)) { + seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); + return 0; + } + + seq_puts(seq, "state: "); + switch (ac->state) { + case ACPI_AC_STATUS_OFFLINE: + seq_puts(seq, "off-line\n"); + break; + case ACPI_AC_STATUS_ONLINE: + seq_puts(seq, "on-line\n"); + break; + default: + seq_puts(seq, "unknown\n"); + break; + } + + return 0; +} + +static int acpi_ac_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_ac_seq_show, PDE_DATA(inode)); +} + +static int acpi_ac_add_fs(struct acpi_ac *ac) +{ + struct proc_dir_entry *entry = NULL; + + printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded," + " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); + if (!acpi_device_dir(ac->device)) { + acpi_device_dir(ac->device) = + proc_mkdir(acpi_device_bid(ac->device), acpi_ac_dir); + if (!acpi_device_dir(ac->device)) + return -ENODEV; + } + + /* 'state' [R] */ + entry = proc_create_data(ACPI_AC_FILE_STATE, + S_IRUGO, acpi_device_dir(ac->device), + &acpi_ac_fops, ac); + if (!entry) + return -ENODEV; + return 0; +} + +static int acpi_ac_remove_fs(struct acpi_ac *ac) +{ + + if (acpi_device_dir(ac->device)) { + remove_proc_entry(ACPI_AC_FILE_STATE, + acpi_device_dir(ac->device)); + remove_proc_entry(acpi_device_bid(ac->device), acpi_ac_dir); + acpi_device_dir(ac->device) = NULL; + } + + return 0; +} +#endif + /* -------------------------------------------------------------------------- Driver Model -------------------------------------------------------------------------- */ @@ -243,6 +342,11 @@ static int acpi_ac_add(struct acpi_device *device) goto end; ac->charger.name = acpi_device_bid(device); +#ifdef CONFIG_ACPI_PROCFS_POWER + result = acpi_ac_add_fs(ac); + if (result) + goto end; +#endif ac->charger.type = POWER_SUPPLY_TYPE_MAINS; ac->charger.properties = ac_props; ac->charger.num_properties = ARRAY_SIZE(ac_props); @@ -258,8 +362,12 @@ static int acpi_ac_add(struct acpi_device *device) ac->battery_nb.notifier_call = acpi_ac_battery_notify; register_acpi_notifier(&ac->battery_nb); end: - if (result) + if (result) { +#ifdef CONFIG_ACPI_PROCFS_POWER + acpi_ac_remove_fs(ac); +#endif kfree(ac); + } dmi_check_system(ac_dmi_table); return result; @@ -303,6 +411,10 @@ static int acpi_ac_remove(struct acpi_device *device) power_supply_unregister(&ac->charger); unregister_acpi_notifier(&ac->battery_nb); +#ifdef CONFIG_ACPI_PROCFS_POWER + acpi_ac_remove_fs(ac); +#endif + kfree(ac); return 0; @@ -315,9 +427,20 @@ static int __init acpi_ac_init(void) if (acpi_disabled) return -ENODEV; +#ifdef CONFIG_ACPI_PROCFS_POWER + acpi_ac_dir = acpi_lock_ac_dir(); + if (!acpi_ac_dir) + return -ENODEV; +#endif + + result = acpi_bus_register_driver(&acpi_ac_driver); - if (result < 0) + if (result < 0) { +#ifdef CONFIG_ACPI_PROCFS_POWER + acpi_unlock_ac_dir(acpi_ac_dir); +#endif return -ENODEV; + } return 0; } @@ -325,6 +448,9 @@ static int __init acpi_ac_init(void) static void __exit acpi_ac_exit(void) { acpi_bus_unregister_driver(&acpi_ac_driver); +#ifdef CONFIG_ACPI_PROCFS_POWER + acpi_unlock_ac_dir(acpi_ac_dir); +#endif } module_init(acpi_ac_init); module_exit(acpi_ac_exit); -- cgit v1.2.3 From c16ed06024a6e699c332831dd50d8276744e3de8 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Fri, 20 Jun 2014 07:27:58 -0700 Subject: intel_pstate: Fix setting VID Commit 21855ff5 (intel_pstate: Set turbo VID for BayTrail) introduced setting the turbo VID which is required to prevent a machine check on some Baytrail SKUs under heavy graphics based workloads. The docmumentation update that brought the requirement to light also changed the bit mask used for enumerating P state and VID values from 0x7f to 0x3f. This change returns the mask value to 0x7f. Tested with the Intel NUC DN2820FYK, BIOS version FYBYT10H.86A.0034.2014.0513.1413 with v3.16-rc1 and v3.14.8 kernel versions. Fixes: 21855ff5 (intel_pstate: Set turbo VID for BayTrail) Link: https://bugzilla.kernel.org/show_bug.cgi?id=77951 Reported-and-tested-by: Rune Reterson Reported-and-tested-by: Eric Eickmeyer Cc: 3.13+ # 3.13+ Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 924bb2d42b1c..74376d615eca 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -357,21 +357,21 @@ static int byt_get_min_pstate(void) { u64 value; rdmsrl(BYT_RATIOS, value); - return (value >> 8) & 0x3F; + return (value >> 8) & 0x7F; } static int byt_get_max_pstate(void) { u64 value; rdmsrl(BYT_RATIOS, value); - return (value >> 16) & 0x3F; + return (value >> 16) & 0x7F; } static int byt_get_turbo_pstate(void) { u64 value; rdmsrl(BYT_TURBO_RATIOS, value); - return value & 0x3F; + return value & 0x7F; } static void byt_set_pstate(struct cpudata *cpudata, int pstate) @@ -405,8 +405,8 @@ static void byt_get_vid(struct cpudata *cpudata) rdmsrl(BYT_VIDS, value); - cpudata->vid.min = int_tofp((value >> 8) & 0x3f); - cpudata->vid.max = int_tofp((value >> 16) & 0x3f); + cpudata->vid.min = int_tofp((value >> 8) & 0x7f); + cpudata->vid.max = int_tofp((value >> 16) & 0x7f); cpudata->vid.ratio = div_fp( cpudata->vid.max - cpudata->vid.min, int_tofp(cpudata->pstate.max_pstate - -- cgit v1.2.3 From dd5fbf70f96dbfd7ee432096a1f979b2b3267856 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Fri, 20 Jun 2014 07:27:59 -0700 Subject: intel_pstate: don't touch turbo bit if turbo disabled or unavailable. If turbo is disabled in the BIOS bit 38 should be set in MSR_IA32_MISC_ENABLE register per section 14.3.2.1 of the SDM Vol 3 document 325384-050US Feb 2014. If this bit is set do *not* attempt to disable trubo via the MSR_IA32_PERF_CTL register. On some systems trying to disable turbo via MSR_IA32_PERF_CTL will cause subsequent writes to MSR_IA32_PERF_CTL not take affect, in fact reading MSR_IA32_PERF_CTL will not show the IDA/Turbo DISENGAGE bit(32) as set. A write of bit 32 to zero returns to normal operation. Also deal with the case where the processor does not support turbo and the BIOS does not report the fact in MSR_IA32_MISC_ENABLE but does report the max and turbo P states as the same value. Link: https://bugzilla.kernel.org/show_bug.cgi?id=64251 Cc: 3.13+ # 3.13+ Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 74376d615eca..127ead814619 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -128,6 +128,7 @@ static struct pstate_funcs pstate_funcs; struct perf_limits { int no_turbo; + int turbo_disabled; int max_perf_pct; int min_perf_pct; int32_t max_perf; @@ -287,7 +288,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, if (ret != 1) return -EINVAL; limits.no_turbo = clamp_t(int, input, 0 , 1); - + if (limits.turbo_disabled) { + pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); + limits.no_turbo = limits.turbo_disabled; + } return count; } @@ -381,7 +385,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) u32 vid; val = pstate << 8; - if (limits.no_turbo) + if (limits.no_turbo && !limits.turbo_disabled) val |= (u64)1 << 32; vid_fp = cpudata->vid.min + mul_fp( @@ -448,7 +452,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate) u64 val; val = pstate << 8; - if (limits.no_turbo) + if (limits.no_turbo && !limits.turbo_disabled) val |= (u64)1 << 32; wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); @@ -741,7 +745,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) limits.min_perf = int_tofp(1); limits.max_perf_pct = 100; limits.max_perf = int_tofp(1); - limits.no_turbo = 0; + limits.no_turbo = limits.turbo_disabled; return 0; } limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; @@ -784,6 +788,7 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) { struct cpudata *cpu; int rc; + u64 misc_en; rc = intel_pstate_init_cpu(policy->cpu); if (rc) @@ -791,8 +796,13 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) cpu = all_cpu_data[policy->cpu]; - if (!limits.no_turbo && - limits.min_perf_pct == 100 && limits.max_perf_pct == 100) + rdmsrl(MSR_IA32_MISC_ENABLE, misc_en); + if (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE || + cpu->pstate.max_pstate == cpu->pstate.turbo_pstate) { + limits.turbo_disabled = 1; + limits.no_turbo = 1; + } + if (limits.min_perf_pct == 100 && limits.max_perf_pct == 100) policy->policy = CPUFREQ_POLICY_PERFORMANCE; else policy->policy = CPUFREQ_POLICY_POWERSAVE; -- cgit v1.2.3 From 179e8471673ce0249cd4ecda796008f7757e5bad Mon Sep 17 00:00:00 2001 From: Vincent Minet Date: Sat, 5 Jul 2014 01:51:33 +0200 Subject: intel_pstate: Set CPU number before accessing MSRs Ensure that cpu->cpu is set before writing MSR_IA32_PERF_CTL during CPU initialization. Otherwise only cpu0 has its P-state set and all other cores are left with their values unchanged. In most cases, this is not too serious because the P-states will be set correctly when the timer function is run. But when the default governor is set to performance, the per-CPU current_pstate stays the same forever and no attempts are made to write the MSRs again. Signed-off-by: Vincent Minet Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 127ead814619..86631cb6f7de 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -700,9 +700,8 @@ static int intel_pstate_init_cpu(unsigned int cpunum) cpu = all_cpu_data[cpunum]; - intel_pstate_get_cpu_pstates(cpu); - cpu->cpu = cpunum; + intel_pstate_get_cpu_pstates(cpu); init_timer_deferrable(&cpu->timer); cpu->timer.function = intel_pstate_timer_func; -- cgit v1.2.3 From 2a58b4f88e3e51619916e9d090cbd1bb8d12b632 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 7 May 2014 13:38:00 +0100 Subject: iio:tcs3472: Check for buffer enabled and locking Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron --- drivers/iio/light/tcs3472.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index fe063a0a21cd..752569985d1d 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -52,6 +52,7 @@ struct tcs3472_data { struct i2c_client *client; + struct mutex lock; u8 enable; u8 control; u8 atime; @@ -116,10 +117,17 @@ static int tcs3472_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + mutex_lock(&data->lock); ret = tcs3472_req_data(data); - if (ret < 0) + if (ret < 0) { + mutex_unlock(&data->lock); return ret; + } ret = i2c_smbus_read_word_data(data->client, chan->address); + mutex_unlock(&data->lock); if (ret < 0) return ret; *val = ret; @@ -255,6 +263,7 @@ static int tcs3472_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; + mutex_init(&data->lock); indio_dev->dev.parent = &client->dev; indio_dev->info = &tcs3472_info; -- cgit v1.2.3 From b9326057a3d8447f5d2e74a7b521ccf21add2ec0 Mon Sep 17 00:00:00 2001 From: Andras Kovacs Date: Fri, 27 Jun 2014 14:50:11 +0200 Subject: USB: cp210x: add support for Corsair usb dongle Corsair USB Dongles are shipped with Corsair AXi series PSUs. These are cp210x serial usb devices, so make driver detect these. I have a program, that can get information from these PSUs. Tested with 2 different dongles shipped with Corsair AX860i and AX1200i units. Signed-off-by: Andras Kovacs Cc: Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 762e4a5f5ae9..330df5ce435b 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -153,6 +153,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ + { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ -- cgit v1.2.3 From 3d28bd840b2d3981cd28caf5fe1df38f1344dd60 Mon Sep 17 00:00:00 2001 From: Bernd Wachter Date: Wed, 2 Jul 2014 12:36:48 +0300 Subject: usb: option: Add ID for Telewell TW-LTE 4G v2 Add ID of the Telewell 4G v2 hardware to option driver to get legacy serial interface working Signed-off-by: Bernd Wachter Cc: Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ac73f49cd9f0..a9688940543d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1487,6 +1487,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, -- cgit v1.2.3 From 66b42b78bc1e816f92b662e8888c89195e4199e1 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:41:17 +0800 Subject: ACPI / EC: Avoid race condition related to advance_transaction() The advance_transaction() will be invoked from the IRQ context GPE handler and the task context ec_poll(). The handling of this function is locked so that the EC state machine are ensured to be advanced sequentially. But there is a problem. Before invoking advance_transaction(), EC_SC(R) is read. Then for advance_transaction(), there could be race condition around the lock from both contexts. The first one reading the register could fail this race and when it passes the stale register value to the state machine advancement code, the hardware condition is totally different from when the register is read. And the hardware accesses determined from the wrong hardware status can break the EC state machine. And there could be cases that the functionalities of the platform firmware are seriously affected. For example: 1. When 2 EC_DATA(W) writes compete the IBF=0, the 2nd EC_DATA(W) write may be invalid due to IBF=1 after the 1st EC_DATA(W) write. Then the hardware will either refuse to respond a next EC_SC(W) write of the next command or discard the current WR_EC command when it receives a EC_SC(W) write of the next command. 2. When 1 EC_SC(W) write and 1 EC_DATA(W) write compete the IBF=0, the EC_DATA(W) write may be invalid due to IBF=1 after the EC_SC(W) write. The next EC_DATA(R) could never be responded by the hardware. This is the root cause of the reported issue. Fix this issue by moving the EC_SC(R) access into the lock so that we can ensure that the state machine is advanced consistently. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams Reported-and-tested-by: Hans de Goede Reported-by: Barton Xu Tested-by: Steffen Weber Tested-by: Arthur Chen Signed-off-by: Lv Zheng Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ad11ba4a412d..762b4cc9d7b1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -168,12 +168,15 @@ static void start_transaction(struct acpi_ec *ec) acpi_ec_write_cmd(ec, ec->curr->command); } -static void advance_transaction(struct acpi_ec *ec, u8 status) +static void advance_transaction(struct acpi_ec *ec) { unsigned long flags; struct transaction *t; + u8 status; spin_lock_irqsave(&ec->lock, flags); + pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK"); + status = acpi_ec_read_status(ec); t = ec->curr; if (!t) goto unlock; @@ -236,7 +239,7 @@ static int ec_poll(struct acpi_ec *ec) msecs_to_jiffies(1))) return 0; } - advance_transaction(ec, acpi_ec_read_status(ec)); + advance_transaction(ec); } while (time_before(jiffies, delay)); pr_debug("controller reset, restart transaction\n"); spin_lock_irqsave(&ec->lock, flags); @@ -635,11 +638,8 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number, void *data) { struct acpi_ec *ec = data; - u8 status = acpi_ec_read_status(ec); - - pr_debug("~~~> interrupt, status:0x%02x\n", status); - advance_transaction(ec, status); + advance_transaction(ec); if (ec_transaction_done(ec) && (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { wake_up(&ec->wait); -- cgit v1.2.3 From f92fca0060fc4dc9227342d0072d75df98c1e5a5 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:41:35 +0800 Subject: ACPI / EC: Add asynchronous command byte write support Move the first command byte write into advance_transaction() so that all EC register accesses that can affect the command processing state machine can happen in this asynchronous state machine advancement function. The advance_transaction() function then can be a complete implementation of an asyncrhonous transaction for a single command so that: 1. The first command byte can be written in the interrupt context; 2. The command completion waiter can also be used to wait the first command byte's timeout; 3. In BURST mode, the follow-up command bytes can be written in the interrupt context directly, so that it doesn't need to return to the task context. Returning to the task context reduces the throughput of the BURST mode and in the worst cases where the system workload is very high, this leads to the hardware driven automatic BURST mode exit. In order not to increase memory consumption, convert 'done' into 'flags' to contain multiple indications: 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition, indicating the completion of the command transaction. 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first command byte. A new command can utilize this flag to compete for the right of accessing the underlying hardware. There is a follow-up bug fix that has utilized this new flag. The 2 flags are important because it also reflects a key concept of IO programs' design used in the system softwares. Normally an IO program running in the kernel should first be implemented in the asynchronous way. And the 2 flags are the most common way to implement its synchronous operations on top of the asynchronous operations: 1. POLL: This flag can be used to block until the asynchronous operations can happen. 2. COMPLETE: This flag can be used to block until the asynchronous operations have completed. By constructing code cleanly in this way, many difficult problems can be solved smoothly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams Reported-and-tested-by: Hans de Goede Reported-by: Barton Xu Tested-by: Steffen Weber Tested-by: Arthur Chen Signed-off-by: Lv Zheng Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 83 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 762b4cc9d7b1..f09386e9745f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -78,6 +78,9 @@ enum { EC_FLAGS_BLOCKED, /* Transactions are blocked */ }; +#define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ +#define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ + /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; module_param(ec_delay, uint, 0644); @@ -109,7 +112,7 @@ struct transaction { u8 ri; u8 wlen; u8 rlen; - bool done; + u8 flags; }; struct acpi_ec *boot_ec, *first_ec; @@ -150,63 +153,68 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) outb(data, ec->data_addr); } -static int ec_transaction_done(struct acpi_ec *ec) +static int ec_transaction_completed(struct acpi_ec *ec) { unsigned long flags; int ret = 0; spin_lock_irqsave(&ec->lock, flags); - if (!ec->curr || ec->curr->done) + if (!ec->curr || (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) ret = 1; spin_unlock_irqrestore(&ec->lock, flags); return ret; } -static void start_transaction(struct acpi_ec *ec) -{ - ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; - ec->curr->done = false; - acpi_ec_write_cmd(ec, ec->curr->command); -} - static void advance_transaction(struct acpi_ec *ec) { - unsigned long flags; struct transaction *t; u8 status; - spin_lock_irqsave(&ec->lock, flags); pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK"); status = acpi_ec_read_status(ec); t = ec->curr; if (!t) - goto unlock; - if (t->wlen > t->wi) { - if ((status & ACPI_EC_FLAG_IBF) == 0) - acpi_ec_write_data(ec, - t->wdata[t->wi++]); - else - goto err; - } else if (t->rlen > t->ri) { - if ((status & ACPI_EC_FLAG_OBF) == 1) { - t->rdata[t->ri++] = acpi_ec_read_data(ec); - if (t->rlen == t->ri) - t->done = true; + goto err; + if (t->flags & ACPI_EC_COMMAND_POLL) { + if (t->wlen > t->wi) { + if ((status & ACPI_EC_FLAG_IBF) == 0) + acpi_ec_write_data(ec, t->wdata[t->wi++]); + else + goto err; + } else if (t->rlen > t->ri) { + if ((status & ACPI_EC_FLAG_OBF) == 1) { + t->rdata[t->ri++] = acpi_ec_read_data(ec); + if (t->rlen == t->ri) + t->flags |= ACPI_EC_COMMAND_COMPLETE; + } else + goto err; + } else if (t->wlen == t->wi && + (status & ACPI_EC_FLAG_IBF) == 0) + t->flags |= ACPI_EC_COMMAND_COMPLETE; + return; + } else { + if ((status & ACPI_EC_FLAG_IBF) == 0) { + acpi_ec_write_cmd(ec, t->command); + t->flags |= ACPI_EC_COMMAND_POLL; } else goto err; - } else if (t->wlen == t->wi && - (status & ACPI_EC_FLAG_IBF) == 0) - t->done = true; - goto unlock; + return; + } err: /* * If SCI bit is set, then don't think it's a false IRQ * otherwise will take a not handled IRQ as a false one. */ - if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI)) - ++t->irq_count; + if (!(status & ACPI_EC_FLAG_SCI)) { + if (in_interrupt() && t) + ++t->irq_count; + } +} -unlock: - spin_unlock_irqrestore(&ec->lock, flags); +static void start_transaction(struct acpi_ec *ec) +{ + ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; + ec->curr->flags = 0; + advance_transaction(ec); } static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); @@ -231,15 +239,17 @@ static int ec_poll(struct acpi_ec *ec) /* don't sleep with disabled interrupts */ if (EC_FLAGS_MSI || irqs_disabled()) { udelay(ACPI_EC_MSI_UDELAY); - if (ec_transaction_done(ec)) + if (ec_transaction_completed(ec)) return 0; } else { if (wait_event_timeout(ec->wait, - ec_transaction_done(ec), + ec_transaction_completed(ec), msecs_to_jiffies(1))) return 0; } + spin_lock_irqsave(&ec->lock, flags); advance_transaction(ec); + spin_unlock_irqrestore(&ec->lock, flags); } while (time_before(jiffies, delay)); pr_debug("controller reset, restart transaction\n"); spin_lock_irqsave(&ec->lock, flags); @@ -637,10 +647,13 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number, void *data) { + unsigned long flags; struct acpi_ec *ec = data; + spin_lock_irqsave(&ec->lock, flags); advance_transaction(ec); - if (ec_transaction_done(ec) && + spin_unlock_irqrestore(&ec->lock, flags); + if (ec_transaction_completed(ec) && (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { wake_up(&ec->wait); ec_check_sci(ec, acpi_ec_read_status(ec)); -- cgit v1.2.3 From 9b80f0f73ae1583c22325ede341c74195847618c Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:41:48 +0800 Subject: ACPI / EC: Remove duplicated ec_wait_ibf0() waiter After we've added the first command byte write into advance_transaction(), the IBF=0 waiter is duplicated with the command completion waiter implemented in the ec_poll() because: If IBF=1 blocked the first command byte write invoked in the task context ec_poll(), it would be kicked off upon IBF=0 interrupt or timed out and retried again in the task context. Remove this seperate and duplicate IBF=0 waiter. By doing so we can reduce the overall number of times to access the EC_SC(R) status register. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams Reported-and-tested-by: Hans de Goede Reported-by: Barton Xu Tested-by: Steffen Weber Tested-by: Arthur Chen Signed-off-by: Lv Zheng Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f09386e9745f..d016ea31b8e9 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -281,23 +281,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, return ret; } -static int ec_check_ibf0(struct acpi_ec *ec) -{ - u8 status = acpi_ec_read_status(ec); - return (status & ACPI_EC_FLAG_IBF) == 0; -} - -static int ec_wait_ibf0(struct acpi_ec *ec) -{ - unsigned long delay = jiffies + msecs_to_jiffies(ec_delay); - /* interrupt wait manually if GPE mode is not active */ - while (time_before(jiffies, delay)) - if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), - msecs_to_jiffies(1))) - return 0; - return -ETIME; -} - static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) { int status; @@ -318,12 +301,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) goto unlock; } } - if (ec_wait_ibf0(ec)) { - pr_err("input buffer is not empty, " - "aborting transaction\n"); - status = -ETIME; - goto end; - } pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n", t->command, t->wdata ? t->wdata[0] : 0); /* disable GPE during transaction if storm is detected */ @@ -347,7 +324,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) set_bit(EC_FLAGS_GPE_STORM, &ec->flags); } pr_debug("transaction end\n"); -end: if (ec->global_lock) acpi_release_global_lock(glk); unlock: @@ -653,8 +629,7 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, spin_lock_irqsave(&ec->lock, flags); advance_transaction(ec); spin_unlock_irqrestore(&ec->lock, flags); - if (ec_transaction_completed(ec) && - (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { + if (ec_transaction_completed(ec)) { wake_up(&ec->wait); ec_check_sci(ec, acpi_ec_read_status(ec)); } -- cgit v1.2.3 From c0d653412fc8450370167a3268b78fc772ff9c87 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:42:07 +0800 Subject: ACPI / EC: Fix race condition in ec_transaction_completed() There is a race condition in ec_transaction_completed(). When ec_transaction_completed() is called in the GPE handler, it could return true because of (ec->curr == NULL). Then the wake_up() invocation could complete the next command unexpectedly since there is no lock between the 2 invocations. With the previous cleanup, the IBF=0 waiter race need not be handled any more. It's now safe to return a flag from advance_condition() to indicate the requirement of wakeup, the flag is returned from a locked context. The ec_transaction_completed() is now only invoked by the ec_poll() where the ec->curr is ensured to be different from NULL. After cleaning up, the EVT_SCI=1 check should be moved out of the wakeup condition so that an EVT_SCI raised with (ec->curr == NULL) can trigger a QR_SC command. Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891 Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931 Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911 Reported-and-tested-by: Gareth Williams Reported-and-tested-by: Hans de Goede Reported-by: Barton Xu Tested-by: Steffen Weber Tested-by: Arthur Chen Signed-off-by: Lv Zheng Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d016ea31b8e9..49d89909b4ed 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -158,16 +158,17 @@ static int ec_transaction_completed(struct acpi_ec *ec) unsigned long flags; int ret = 0; spin_lock_irqsave(&ec->lock, flags); - if (!ec->curr || (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) + if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) ret = 1; spin_unlock_irqrestore(&ec->lock, flags); return ret; } -static void advance_transaction(struct acpi_ec *ec) +static bool advance_transaction(struct acpi_ec *ec) { struct transaction *t; u8 status; + bool wakeup = false; pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK"); status = acpi_ec_read_status(ec); @@ -183,21 +184,25 @@ static void advance_transaction(struct acpi_ec *ec) } else if (t->rlen > t->ri) { if ((status & ACPI_EC_FLAG_OBF) == 1) { t->rdata[t->ri++] = acpi_ec_read_data(ec); - if (t->rlen == t->ri) + if (t->rlen == t->ri) { t->flags |= ACPI_EC_COMMAND_COMPLETE; + wakeup = true; + } } else goto err; } else if (t->wlen == t->wi && - (status & ACPI_EC_FLAG_IBF) == 0) + (status & ACPI_EC_FLAG_IBF) == 0) { t->flags |= ACPI_EC_COMMAND_COMPLETE; - return; + wakeup = true; + } + return wakeup; } else { if ((status & ACPI_EC_FLAG_IBF) == 0) { acpi_ec_write_cmd(ec, t->command); t->flags |= ACPI_EC_COMMAND_POLL; } else goto err; - return; + return wakeup; } err: /* @@ -208,13 +213,14 @@ err: if (in_interrupt() && t) ++t->irq_count; } + return wakeup; } static void start_transaction(struct acpi_ec *ec) { ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; ec->curr->flags = 0; - advance_transaction(ec); + (void)advance_transaction(ec); } static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); @@ -248,7 +254,7 @@ static int ec_poll(struct acpi_ec *ec) return 0; } spin_lock_irqsave(&ec->lock, flags); - advance_transaction(ec); + (void)advance_transaction(ec); spin_unlock_irqrestore(&ec->lock, flags); } while (time_before(jiffies, delay)); pr_debug("controller reset, restart transaction\n"); @@ -627,12 +633,10 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, struct acpi_ec *ec = data; spin_lock_irqsave(&ec->lock, flags); - advance_transaction(ec); - spin_unlock_irqrestore(&ec->lock, flags); - if (ec_transaction_completed(ec)) { + if (advance_transaction(ec)) wake_up(&ec->wait); - ec_check_sci(ec, acpi_ec_read_status(ec)); - } + spin_unlock_irqrestore(&ec->lock, flags); + ec_check_sci(ec, acpi_ec_read_status(ec)); return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; } -- cgit v1.2.3 From 4a3f6b5bf3f3293087a5f60ea3328715fe14b6de Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:42:19 +0800 Subject: ACPI / EC: Update revision due to recent changes The bug fixes and asynchronous improvements have been done to the EC driver by the previous commits. This patch increases the revision to 2.2 to indicate the behavior differences between the old and the new drivers. The copyright/authorship notices are also updated. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 49d89909b4ed..f8fb736e38df 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1,11 +1,14 @@ /* - * ec.c - ACPI Embedded Controller Driver (v2.1) + * ec.c - ACPI Embedded Controller Driver (v2.2) * - * Copyright (C) 2006-2008 Alexey Starikovskiy - * Copyright (C) 2006 Denis Sadykov - * Copyright (C) 2004 Luming Yu - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2001-2014 Intel Corporation + * Author: 2014 Lv Zheng + * 2006, 2007 Alexey Starikovskiy + * 2006 Denis Sadykov + * 2004 Luming Yu + * 2001, 2002 Andy Grover + * 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2008 Alexey Starikovskiy * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * -- cgit v1.2.3 From dd43de20f540179863d9d7c3188b6a6cfde9a731 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:42:42 +0800 Subject: ACPI / EC: Add detailed fields debugging support of EC_SC(R). Developers really don't need to translate EC_SC(R) in mind as long as the field details are decoded in the debugging message. Tested-by: Gareth Williams Tested-by: Steffen Weber Tested-by: Hans de Goede Tested-by: Arthur Chen Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f8fb736e38df..ff16132e5c52 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -55,6 +55,7 @@ /* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ +#define ACPI_EC_FLAG_CMD 0x08 /* Input buffer contains a command */ #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ @@ -133,26 +134,33 @@ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ static inline u8 acpi_ec_read_status(struct acpi_ec *ec) { u8 x = inb(ec->command_addr); - pr_debug("---> status = 0x%2.2x\n", x); + pr_debug("EC_SC(R) = 0x%2.2x " + "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", + x, + !!(x & ACPI_EC_FLAG_SCI), + !!(x & ACPI_EC_FLAG_BURST), + !!(x & ACPI_EC_FLAG_CMD), + !!(x & ACPI_EC_FLAG_IBF), + !!(x & ACPI_EC_FLAG_OBF)); return x; } static inline u8 acpi_ec_read_data(struct acpi_ec *ec) { u8 x = inb(ec->data_addr); - pr_debug("---> data = 0x%2.2x\n", x); + pr_debug("EC_DATA(R) = 0x%2.2x\n", x); return x; } static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) { - pr_debug("<--- command = 0x%2.2x\n", command); + pr_debug("EC_SC(W) = 0x%2.2x\n", command); outb(command, ec->command_addr); } static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) { - pr_debug("<--- data = 0x%2.2x\n", data); + pr_debug("EC_DATA(W) = 0x%2.2x\n", data); outb(data, ec->data_addr); } -- cgit v1.2.3 From ed4b197ddd4d7aa6623e7777ea326c67c3a6b8ed Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 3 Jul 2014 00:35:09 +0100 Subject: ACPI / EC: Free saved_ec on error exit path Smatch detected two memory leaks on saved_ec: drivers/acpi/ec.c:1070 acpi_ec_ecdt_probe() warn: possible memory leak of 'saved_ec' drivers/acpi/ec.c:1109 acpi_ec_ecdt_probe() warn: possible memory leak of 'saved_ec' Free saved_ec on these two error exit paths to stop the memory leak. Note that saved_ec maybe null, but kfree on null is allowed. Signed-off-by: Colin Ian King Acked-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ff16132e5c52..a66ab658abbc 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1069,8 +1069,10 @@ int __init acpi_ec_ecdt_probe(void) /* fall through */ } - if (EC_FLAGS_SKIP_DSDT_SCAN) + if (EC_FLAGS_SKIP_DSDT_SCAN) { + kfree(saved_ec); return -ENODEV; + } /* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */ @@ -1108,6 +1110,7 @@ install: } error: kfree(boot_ec); + kfree(saved_ec); boot_ec = NULL; return -ENODEV; } -- cgit v1.2.3 From 75646e758a0ecbed5024454507d5be5b9ea9dcbf Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Mon, 7 Jul 2014 15:47:12 +0800 Subject: ACPI / battery: Retry to get battery information if failed during probing Some machines (eg. Lenovo Z480) ECs are not stable during boot up and causes battery driver fails to be loaded due to failure of getting battery information from EC sometimes. After several retries, the operation will work. This patch is to retry to get battery information 5 times if the first try fails. Link: https://bugzilla.kernel.org/show_bug.cgi?id=75581 Reported-and-tested-by: naszar Cc: All applicable Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 0d7116f34b95..bc0b286ff2ba 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #ifdef CONFIG_ACPI_PROCFS_POWER @@ -1151,6 +1152,28 @@ static struct dmi_system_id bat_dmi_table[] = { {}, }; +/* + * Some machines'(E,G Lenovo Z480) ECs are not stable + * during boot up and this causes battery driver fails to be + * probed due to failure of getting battery information + * from EC sometimes. After several retries, the operation + * may work. So add retry code here and 20ms sleep between + * every retries. + */ +static int acpi_battery_update_retry(struct acpi_battery *battery) +{ + int retry, ret; + + for (retry = 5; retry; retry--) { + ret = acpi_battery_update(battery, false); + if (!ret) + break; + + msleep(20); + } + return ret; +} + static int acpi_battery_add(struct acpi_device *device) { int result = 0; @@ -1169,9 +1192,11 @@ static int acpi_battery_add(struct acpi_device *device) mutex_init(&battery->sysfs_lock); if (acpi_has_method(battery->device->handle, "_BIX")) set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); - result = acpi_battery_update(battery, false); + + result = acpi_battery_update_retry(battery); if (result) goto fail; + #ifdef CONFIG_ACPI_PROCFS_POWER result = acpi_battery_add_fs(device); #endif -- cgit v1.2.3 From 145e74a4e5022225adb84f4e5d4fff7938475c35 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 3 Jul 2014 13:44:23 -0700 Subject: hwmon: (adm1031) Fix writes to limit registers Upper limit for write operations to temperature limit registers was clamped to a fractional value. However, limit registers do not support fractional values. As a result, upper limits of 127.5 degrees C or higher resulted in a rounded limit of 128 degrees C. Since limit registers are signed, this was stored as -128 degrees C. Clamp limits to (-55, +127) degrees C to solve the problem. Value on writes to auto_temp[12]_min and auto_temp[12]_max were not clamped at all, but masked. As a result, out-of-range writes resulted in a more or less arbitrary limit. Clamp those attributes to (0, 127) degrees C for more predictable results. Cc: Axel Lin Cc: stable@vger.kernel.org Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/adm1031.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index a8a540ca8c34..51c1a5a165ab 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -365,6 +365,7 @@ set_auto_temp_min(struct device *dev, struct device_attribute *attr, if (ret) return ret; + val = clamp_val(val, 0, 127000); mutex_lock(&data->update_lock); data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), @@ -394,6 +395,7 @@ set_auto_temp_max(struct device *dev, struct device_attribute *attr, if (ret) return ret; + val = clamp_val(val, 0, 127000); mutex_lock(&data->update_lock); data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]); @@ -696,7 +698,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, if (ret) return ret; - val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875); + val = clamp_val(val, -55000, 127000); mutex_lock(&data->update_lock); data->temp_min[nr] = TEMP_TO_REG(val); adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr), @@ -717,7 +719,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, if (ret) return ret; - val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875); + val = clamp_val(val, -55000, 127000); mutex_lock(&data->update_lock); data->temp_max[nr] = TEMP_TO_REG(val); adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr), @@ -738,7 +740,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, if (ret) return ret; - val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875); + val = clamp_val(val, -55000, 127000); mutex_lock(&data->update_lock); data->temp_crit[nr] = TEMP_TO_REG(val); adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr), -- cgit v1.2.3 From 3179e8e684603645b573fdc46139473d5ee4b189 Mon Sep 17 00:00:00 2001 From: Wen-chien Jesse Sung Date: Wed, 2 Jul 2014 21:06:59 +0800 Subject: HID: use multi input quirk for 22b9:2968 This device generates ABS_Z and ABS_RX events instead of ABS_X and ABS_Y. Signed-off-by: Wen-chien Jesse Sung Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 1efeb12a38c7..48b66bbffc94 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -323,6 +323,7 @@ #define USB_VENDOR_ID_ETURBOTOUCH 0x22b9 #define USB_DEVICE_ID_ETURBOTOUCH 0x0006 +#define USB_DEVICE_ID_ETURBOTOUCH_2968 0x2968 #define USB_VENDOR_ID_EZKEY 0x0518 #define USB_DEVICE_ID_BTC_8193 0x0002 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index fbaefc34ee95..31e6727cd009 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -49,6 +49,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, -- cgit v1.2.3 From f6c2dd20108c35e30e2c1f3c6142d189451a626b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 6 Jul 2014 11:39:24 -0700 Subject: hwmon: (emc2103) Clamp limits instead of bailing out It is customary to clamp limits instead of bailing out with an error if a configured limit is out of the range supported by the driver. This simplifies limit configuration, since the user will not typically know chip and/or driver specific limits. Reviewed-by: Jean Delvare Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/emc2103.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index fd892dd48e4c..78002de46cb6 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -250,9 +250,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *da, if (result < 0) return result; - val = DIV_ROUND_CLOSEST(val, 1000); - if ((val < -63) || (val > 127)) - return -EINVAL; + val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127); mutex_lock(&data->update_lock); data->temp_min[nr] = val; @@ -274,9 +272,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *da, if (result < 0) return result; - val = DIV_ROUND_CLOSEST(val, 1000); - if ((val < -63) || (val > 127)) - return -EINVAL; + val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127); mutex_lock(&data->update_lock); data->temp_max[nr] = val; @@ -390,15 +386,14 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da, { struct emc2103_data *data = emc2103_update_device(dev); struct i2c_client *client = to_i2c_client(dev); - long rpm_target; + unsigned long rpm_target; - int result = kstrtol(buf, 10, &rpm_target); + int result = kstrtoul(buf, 10, &rpm_target); if (result < 0) return result; /* Datasheet states 16384 as maximum RPM target (table 3.2) */ - if ((rpm_target < 0) || (rpm_target > 16384)) - return -EINVAL; + rpm_target = clamp_val(rpm_target, 0, 16384); mutex_lock(&data->update_lock); -- cgit v1.2.3 From 7fe7381cbdadf16792e733789983690b3fa82880 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 7 Jul 2014 07:10:10 -0700 Subject: hwmon: (adc128d818) Drop write support on inX_input attributes Writes into input registers doesn't make sense, even more so since the writes actually ended up writing into the maximum limit registers. Drop it. Cc: stable@vger.kernel.org Reviewed-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/adc128d818.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adc128d818.c b/drivers/hwmon/adc128d818.c index 5ffd81f19d01..0625e50d7a6e 100644 --- a/drivers/hwmon/adc128d818.c +++ b/drivers/hwmon/adc128d818.c @@ -239,50 +239,50 @@ static ssize_t adc128_show_alarm(struct device *dev, return sprintf(buf, "%u\n", !!(alarms & mask)); } -static SENSOR_DEVICE_ATTR_2(in0_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 0, 0); +static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, + adc128_show_in, NULL, 0, 0); static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 0, 1); static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 0, 2); -static SENSOR_DEVICE_ATTR_2(in1_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 1, 0); +static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, + adc128_show_in, NULL, 1, 0); static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 1, 1); static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 1, 2); -static SENSOR_DEVICE_ATTR_2(in2_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 2, 0); +static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, + adc128_show_in, NULL, 2, 0); static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 2, 1); static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 2, 2); -static SENSOR_DEVICE_ATTR_2(in3_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 3, 0); +static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, + adc128_show_in, NULL, 3, 0); static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 3, 1); static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 3, 2); -static SENSOR_DEVICE_ATTR_2(in4_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 4, 0); +static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, + adc128_show_in, NULL, 4, 0); static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 4, 1); static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 4, 2); -static SENSOR_DEVICE_ATTR_2(in5_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 5, 0); +static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, + adc128_show_in, NULL, 5, 0); static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 5, 1); static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 5, 2); -static SENSOR_DEVICE_ATTR_2(in6_input, S_IWUSR | S_IRUGO, - adc128_show_in, adc128_set_in, 6, 0); +static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, + adc128_show_in, NULL, 6, 0); static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, adc128_show_in, adc128_set_in, 6, 1); static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, -- cgit v1.2.3 From 867f9d463b82462793ea4610e748be0b04b37fc7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 19 Jun 2014 11:19:16 +0100 Subject: ACPI / resources: only reject zero length resources based at address zero The recently merged change (in v3.14-rc6) to ACPI resource detection (below) causes all zero length ACPI resources to be elided from the table: commit b355cee88e3b1a193f0e9a81db810f6f83ad728b Author: Zhang Rui Date: Thu Feb 27 11:37:15 2014 +0800 ACPI / resources: ignore invalid ACPI device resources This change has caused a regression in (at least) serial port detection for a number of machines (see LP#1313981 [1]). These seem to represent their IO regions (presumably incorrectly) as a zero length region. Reverting the above commit restores these serial devices. Only elide zero length resources which lie at address 0. Fixes: b355cee88e3b (ACPI / resources: ignore invalid ACPI device resources) Signed-off-by: Andy Whitcroft Acked-by: Zhang Rui Cc: 3.14+ # 3.14+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 0bdacc5e26a3..2ba8f02ced36 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -77,7 +77,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) switch (ares->type) { case ACPI_RESOURCE_TYPE_MEMORY24: memory24 = &ares->data.memory24; - if (!memory24->address_length) + if (!memory24->minimum && !memory24->address_length) return false; acpi_dev_get_memresource(res, memory24->minimum, memory24->address_length, @@ -85,7 +85,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) break; case ACPI_RESOURCE_TYPE_MEMORY32: memory32 = &ares->data.memory32; - if (!memory32->address_length) + if (!memory32->minimum && !memory32->address_length) return false; acpi_dev_get_memresource(res, memory32->minimum, memory32->address_length, @@ -93,7 +93,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) break; case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: fixed_memory32 = &ares->data.fixed_memory32; - if (!fixed_memory32->address_length) + if (!fixed_memory32->address && !fixed_memory32->address_length) return false; acpi_dev_get_memresource(res, fixed_memory32->address, fixed_memory32->address_length, @@ -150,7 +150,7 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) switch (ares->type) { case ACPI_RESOURCE_TYPE_IO: io = &ares->data.io; - if (!io->address_length) + if (!io->minimum && !io->address_length) return false; acpi_dev_get_ioresource(res, io->minimum, io->address_length, @@ -158,7 +158,7 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) break; case ACPI_RESOURCE_TYPE_FIXED_IO: fixed_io = &ares->data.fixed_io; - if (!fixed_io->address_length) + if (!fixed_io->address && !fixed_io->address_length) return false; acpi_dev_get_ioresource(res, fixed_io->address, fixed_io->address_length, -- cgit v1.2.3 From 232de514379082e7ec431c66c9713a6ef23d5dcb Mon Sep 17 00:00:00 2001 From: Josef Gajdusek Date: Tue, 17 Jun 2014 23:15:49 +0200 Subject: ACPI / battery: fix wrong value of capacity_now reported when fully charged It seems that some batteries (noticed on DELL JYPJ136) assume capacity_now = design_capacity when fully charged. This causes reported capacity to suddenly jump to >full_charge_capacity (and that means capacity reported to userspace is >100% and incorrect) values after 99%. This patch detects capacity_now > full_charge_capacity, notifies userspace (unless it is the known bug where capacity_now == design_capacity) and trims the value to full_charge_capacity. Signed-off-by: Josef Gajdusek Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index bc0b286ff2ba..130f513e08c9 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -535,6 +535,20 @@ static int acpi_battery_get_state(struct acpi_battery *battery) " invalid.\n"); } + /* + * When fully charged, some batteries wrongly report + * capacity_now = design_capacity instead of = full_charge_capacity + */ + if (battery->capacity_now > battery->full_charge_capacity + && battery->full_charge_capacity != ACPI_BATTERY_VALUE_UNKNOWN) { + battery->capacity_now = battery->full_charge_capacity; + if (battery->capacity_now != battery->design_capacity) + printk_once(KERN_WARNING FW_BUG + "battery: reported current charge level (%d) " + "is higher than reported maximum charge level (%d).\n", + battery->capacity_now, battery->full_charge_capacity); + } + if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) && battery->capacity_now >= 0 && battery->capacity_now <= 100) battery->capacity_now = (battery->capacity_now * -- cgit v1.2.3 From 0b9f7d93ca6109048a4eb06332b666b6e29df4fe Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Mon, 7 Jul 2014 15:43:51 +0800 Subject: ACPI / i915: ignore firmware requests for backlight change Some Thinkpad laptops' firmware will initiate a backlight level change request through operation region on the events of AC plug/unplug, but since we are not using firmware's interface to do the backlight setting on these affected laptops, we do not want the firmware to use some arbitrary value from its ASL variable to set the backlight level on AC plug/unplug either. Link: https://bugzilla.kernel.org/show_bug.cgi?id=76491 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77091 Reported-and-tested-by: Igor Gnatenko Reported-and-tested-by: Anton Gubarkov Signed-off-by: Aaron Lu Acked-by: Jani Nikula Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 3 ++- drivers/gpu/drm/i915/intel_opregion.c | 9 +++++++++ include/acpi/video.h | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index fb9ffe9adc64..5bb1278e9324 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -241,13 +241,14 @@ static bool acpi_video_use_native_backlight(void) return use_native_backlight_dmi; } -static bool acpi_video_verify_backlight_support(void) +bool acpi_video_verify_backlight_support(void) { if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && backlight_device_registered(BACKLIGHT_RAW)) return false; return acpi_video_backlight_support(); } +EXPORT_SYMBOL_GPL(acpi_video_verify_backlight_support); /* backlight device sysfs support */ static int acpi_video_get_brightness(struct backlight_device *bd) diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 2e2c71fcc9ed..4f6b53998d79 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -403,6 +403,15 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); + /* + * If the acpi_video interface is not supposed to be used, don't + * bother processing backlight level change requests from firmware. + */ + if (!acpi_video_verify_backlight_support()) { + DRM_DEBUG_KMS("opregion backlight request ignored\n"); + return 0; + } + if (!(bclp & ASLE_BCLP_VALID)) return ASLC_BACKLIGHT_FAILED; diff --git a/include/acpi/video.h b/include/acpi/video.h index ea4c7bbded4d..843ef1adfbfa 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -22,6 +22,7 @@ extern void acpi_video_unregister(void); extern void acpi_video_unregister_backlight(void); extern int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid); +extern bool acpi_video_verify_backlight_support(void); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } @@ -31,6 +32,7 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type, { return -ENODEV; } +static inline bool acpi_video_verify_backlight_support(void) { return false; } #endif #endif -- cgit v1.2.3 From 08a56226d84706d402372d891550e130ef5df9f0 Mon Sep 17 00:00:00 2001 From: Edward Lin Date: Fri, 20 Jun 2014 16:13:42 +0800 Subject: ACPI / video: Add Dell Inspiron 5737 to the blacklist With win8 capabiltiy, the ACPI backlight control is broken. The system also loses backlight setting when resuming from S3. Add this model to the the ACPI video detect blacklist to make backlight functionality work. Although backlight functionality works via video.use_native_backlight=1, this approach may be safer. Signed-off-by: Edward Lin Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 33e3db548a29..c42feb2bacd0 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -166,6 +166,14 @@ static struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), }, }, + { + .callback = video_detect_force_vendor, + .ident = "Dell Inspiron 5737", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"), + }, + }, { }, }; -- cgit v1.2.3 From ab7027de5c01e4fba0e5ef946f0db27b2e3d799d Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Mon, 23 Jun 2014 22:30:46 +0200 Subject: ACPI / video: Add Acer TravelMate B113 to native backlight blacklist Fix backlight control for Acer TravelMate B113 Laptop by adding it to the video_dmi_table. A workaround before that was to use acpi_osi=Linux or acpi_backlight=vendor on boot but even then, only the function- keys worked. With this change there is no need for boot parameters and DE's controls work as well. Signed-off-by: Martin Kepplinger [rjw: Subject] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5bb1278e9324..071c1dfb93f3 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -563,6 +563,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-471G"), }, }, + { + .callback = video_set_use_native_backlight, + .ident = "Acer TravelMate B113", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"), + }, + }, { .callback = video_set_use_native_backlight, .ident = "HP ProBook 4340s", -- cgit v1.2.3 From 8844a00626c78c30e8cd757f2a048038f4983c53 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Tue, 1 Jul 2014 09:21:34 +0800 Subject: powerpc/ucc_geth: deal with a compile warning deal with a compile warning: comparison between 'enum qe_fltr_largest_external_tbl_lookup_key_size' and 'enum qe_fltr_tbl_lookup_key_size' the code: "if (ug_info->largestexternallookupkeysize == QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES)" is warned because different enum, so modify it. "enum qe_fltr_largest_external_tbl_lookup_key_size largestexternallookupkeysize; enum qe_fltr_tbl_lookup_key_size { QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES = 0x3f, /* LookupKey parsed by the Generate LookupKey CMD is truncated to 8 bytes */ QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES = 0x5f, /* LookupKey parsed by the Generate LookupKey CMD is truncated to 16 bytes */ }; /* QE FLTR extended filtering Largest External Table Lookup Key Size */ enum qe_fltr_largest_external_tbl_lookup_key_size { QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE = 0x0,/* not used */ QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES, /* 8 bytes */ QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES, /* 16 bytes */ };" Signed-off-by: Zhao Qiang Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/ucc_geth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index fab39e295441..36fc429298e3 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -2990,11 +2990,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (ug_info->rxExtendedFiltering) { size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; if (ug_info->largestexternallookupkeysize == - QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES) + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES) size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8; if (ug_info->largestexternallookupkeysize == - QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES) + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES) size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16; } -- cgit v1.2.3 From 26a9ebca982d52b96c921f7344b7c01b1e2d9672 Mon Sep 17 00:00:00 2001 From: David S. Miller Date: Mon, 7 Jul 2014 19:53:45 -0700 Subject: Revert "net: stmmac: add platform init/exit for Altera's ARM socfpga" This reverts commit 0acf16768740776feffac506ce93b1c06c059ac6. Breaks the build due to missing reference to phy_resume in the resulting dwmac-socfpga.o object. Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 69 ---------------------- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 -- 2 files changed, 73 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index ec632e666c56..fd8a217556a1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -20,9 +20,7 @@ #include #include #include -#include #include -#include "stmmac.h" #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 @@ -36,7 +34,6 @@ struct socfpga_dwmac { u32 reg_shift; struct device *dev; struct regmap *sys_mgr_base_addr; - struct reset_control *stmmac_rst; }; static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) @@ -46,13 +43,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * u32 reg_offset, reg_shift; int ret; - dwmac->stmmac_rst = devm_reset_control_get(dev, - STMMAC_RESOURCE_NAME); - if (IS_ERR(dwmac->stmmac_rst)) { - dev_info(dev, "Could not get reset control!\n"); - return -EINVAL; - } - dwmac->interface = of_get_phy_mode(np); sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); @@ -135,65 +125,6 @@ static void *socfpga_dwmac_probe(struct platform_device *pdev) return dwmac; } -static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) -{ - struct socfpga_dwmac *dwmac = priv; - - /* On socfpga platform exit, assert and hold reset to the - * enet controller - the default state after a hard reset. - */ - if (dwmac->stmmac_rst) - reset_control_assert(dwmac->stmmac_rst); -} - -static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) -{ - struct socfpga_dwmac *dwmac = priv; - struct net_device *ndev = platform_get_drvdata(pdev); - struct stmmac_priv *stpriv = NULL; - int ret = 0; - - if (ndev) - stpriv = netdev_priv(ndev); - - /* Assert reset to the enet controller before changing the phy mode */ - if (dwmac->stmmac_rst) - reset_control_assert(dwmac->stmmac_rst); - - /* Setup the phy mode in the system manager registers according to - * devicetree configuration - */ - ret = socfpga_dwmac_setup(dwmac); - - /* Deassert reset for the phy configuration to be sampled by - * the enet controller, and operation to start in requested mode - */ - if (dwmac->stmmac_rst) - reset_control_deassert(dwmac->stmmac_rst); - - /* Before the enet controller is suspended, the phy is suspended. - * This causes the phy clock to be gated. The enet controller is - * resumed before the phy, so the clock is still gated "off" when - * the enet controller is resumed. This code makes sure the phy - * is "resumed" before reinitializing the enet controller since - * the enet controller depends on an active phy clock to complete - * a DMA reset. A DMA reset will "time out" if executed - * with no phy clock input on the Synopsys enet controller. - * Verified through Synopsys Case #8000711656. - * - * Note that the phy clock is also gated when the phy is isolated. - * Phy "suspend" and "isolate" controls are located in phy basic - * control register 0, and can be modified by the phy driver - * framework. - */ - if (stpriv && stpriv->phydev) - phy_resume(stpriv->phydev); - - return ret; -} - const struct stmmac_of_data socfpga_gmac_data = { .setup = socfpga_dwmac_probe, - .init = socfpga_dwmac_init, - .exit = socfpga_dwmac_exit, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 18315f34938b..057a1208e594 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2878,10 +2878,6 @@ int stmmac_suspend(struct net_device *ndev) clk_disable_unprepare(priv->stmmac_clk); } spin_unlock_irqrestore(&priv->lock, flags); - - priv->oldlink = 0; - priv->speed = 0; - priv->oldduplex = -1; return 0; } -- cgit v1.2.3 From 797a816221655d7204c6a5536d1400c022b01939 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2014 14:26:37 +1000 Subject: drm/gk104/ram: bash mpll bit 31 on Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c index 1ad3ea503133..c5b46e302319 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c @@ -200,6 +200,7 @@ r1373f4_init(struct nve0_ramfuc *fuc) /* (re)program mempll, if required */ if (ram->mode == 2) { ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000); + ram_mask(fuc, 0x132000, 0x80000000, 0x80000000); ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); ram_mask(fuc, 0x132004, 0x103fffff, mcoef); ram_mask(fuc, 0x132000, 0x00000001, 0x00000001); -- cgit v1.2.3 From 3c4be80bce681740d31646b8aff06d82ef453566 Mon Sep 17 00:00:00 2001 From: Stéphane Marchesin Date: Fri, 27 Jun 2014 13:17:25 -0700 Subject: drm/nouveau/fb: Prevent inlining of ramfuc_reg When gcc 4.8 inlines this function, it eats up 16 bytes on the stack every time. Eventually we hit warnings because our stack grew too much: ramnve0.c:1383:1: error: the frame size of 1496 bytes is larger than 1024 bytes We fix this by preventing inlining for this function. Signed-off-by: Stéphane Marchesin Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h index 0f57fcfe0bbf..04e38492e74a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h @@ -26,7 +26,7 @@ ramfuc_reg2(u32 addr1, u32 addr2) }; } -static inline struct ramfuc_reg +static noinline struct ramfuc_reg ramfuc_reg(u32 addr) { return ramfuc_reg2(addr, addr); -- cgit v1.2.3 From 276e526cfb257add928a57b196ea3e5c22b703ef Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 30 Jun 2014 11:10:02 +1000 Subject: drm/nv50-/kms: pass a non-zero value for head to sor dpms methods There's Apple machines out there which (probably completely arbitrarily) restrict each output path to a particular head. This causes us to not be able to locate the output data needed to power on/off the DP output correctly. We fix this by passing in a head index we know is valid (as opposed to "head 0"). Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index afdf607df3e6..4c534b7b04da 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1741,7 +1741,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) } } - mthd = (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2; + mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3; + mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2; mthd |= nv_encoder->or; if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { -- cgit v1.2.3 From 028791bb7d662550c7435d38daeb1f0b88ed5b17 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 30 Jun 2014 13:04:14 +1000 Subject: drm/nouveau/kms: restore fbcon after display has been resumed Under some complicated circumstances (boot, suspend, resume, attach second display, suspend, resume, suspend, detach second display, resume, suspend, attach second display, resume), the fb_set_suspend() call can somehow result in a modeset being attempted before we're ready for it and things blow up in fun ways. Running display init first fixes the issue. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 17 +++++++++-------- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 13 +++---------- drivers/gpu/drm/nouveau/nouveau_fbcon.h | 1 - 3 files changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ddd83756b9a2..5425ffe3931d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev) ret = nouveau_do_resume(drm_dev); if (ret) return ret; - if (drm_dev->mode_config.num_crtc) - nouveau_fbcon_set_suspend(drm_dev, 0); - nouveau_fbcon_zfill_all(drm_dev); - if (drm_dev->mode_config.num_crtc) + if (drm_dev->mode_config.num_crtc) { nouveau_display_resume(drm_dev); + nouveau_fbcon_set_suspend(drm_dev, 0); + } + return 0; } @@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev) ret = nouveau_do_resume(drm_dev); if (ret) return ret; - if (drm_dev->mode_config.num_crtc) - nouveau_fbcon_set_suspend(drm_dev, 0); - nouveau_fbcon_zfill_all(drm_dev); - if (drm_dev->mode_config.num_crtc) + + if (drm_dev->mode_config.num_crtc) { nouveau_display_resume(drm_dev); + nouveau_fbcon_set_suspend(drm_dev, 0); + } + return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 64a42cfd3717..191665ee7f52 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) if (state == 1) nouveau_fbcon_save_disable_accel(dev); fb_set_suspend(drm->fbcon->helper.fbdev, state); - if (state == 0) + if (state == 0) { nouveau_fbcon_restore_accel(dev); + nouveau_fbcon_zfill(dev, drm->fbcon); + } console_unlock(); } } - -void -nouveau_fbcon_zfill_all(struct drm_device *dev) -{ - struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { - nouveau_fbcon_zfill(dev, drm->fbcon); - } -} diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index fdfc0c94fbcc..fcff797d2084 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info); int nouveau_fbcon_init(struct drm_device *dev); void nouveau_fbcon_fini(struct drm_device *dev); void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); -void nouveau_fbcon_zfill_all(struct drm_device *dev); void nouveau_fbcon_save_disable_accel(struct drm_device *dev); void nouveau_fbcon_restore_accel(struct drm_device *dev); -- cgit v1.2.3 From 0713b4510e62411071b748d786043cdaada56ce5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Jul 2014 10:54:52 +1000 Subject: drm/nouveau/dp: fix required link bandwidth calculations Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 6 +++--- drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | 6 +++--- drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c | 8 +++++--- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 26e962b7e702..2283c442a10d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -1516,11 +1516,11 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) } switch ((ctrl & 0x000f0000) >> 16) { - case 6: datarate = pclk * 30 / 8; break; - case 5: datarate = pclk * 24 / 8; break; + case 6: datarate = pclk * 30; break; + case 5: datarate = pclk * 24; break; case 2: default: - datarate = pclk * 18 / 8; + datarate = pclk * 18; break; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 48aa38a87e3f..fa30d8196f35 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -1159,11 +1159,11 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head) if (outp->info.type == DCB_OUTPUT_DP) { u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); switch ((sync & 0x000003c0) >> 6) { - case 6: pclk = pclk * 30 / 8; break; - case 5: pclk = pclk * 24 / 8; break; + case 6: pclk = pclk * 30; break; + case 5: pclk = pclk * 24; break; case 2: default: - pclk = pclk * 18 / 8; + pclk = pclk * 18; break; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c index 52c299c3d300..eb2d7789555d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c @@ -34,7 +34,7 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) struct nvkm_output_dp *outp = (void *)base; bool retrain = true; u8 link[2], stat[3]; - u32 rate; + u32 linkrate; int ret, i; /* check that the link is trained at a high enough rate */ @@ -44,8 +44,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) goto done; } - rate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET); - if (rate < ((datarate / 8) * 10)) { + linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET); + linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */ + datarate = (datarate + 9) / 10; /* -> decakilobits */ + if (linkrate < datarate) { DBG("link not trained at sufficient rate\n"); goto done; } -- cgit v1.2.3 From 7fac49337175f031d679f7ce0dab980ed6711237 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Jul 2014 08:53:50 +1000 Subject: drm/nouveau/dp: workaround broken display The display in fdo#76483 pulses the hotplug line for link retraining after we cut power to the main link on the source, even while it's in D3. fdo#76483 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index e1832778e8b6..7a1ebdfa9e1b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c @@ -87,6 +87,7 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) struct nvkm_output_dp *outpdp = (void *)outp; switch (data) { case NV94_DISP_SOR_DP_PWR_STATE_OFF: + nouveau_event_put(outpdp->irq); ((struct nvkm_output_dp_impl *)nv_oclass(outp)) ->lnk_pwr(outpdp, 0); atomic_set(&outpdp->lt.done, 0); -- cgit v1.2.3 From 0b4e8e7fd506d4ddb96f71230252d14066ce1597 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 Jul 2014 10:50:36 +1000 Subject: drm/nouveau/ram: fix test for gpio presence Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h index 04e38492e74a..2af9cfd2c60f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h @@ -107,7 +107,7 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec) #define ram_init(s,p) ramfuc_init(&(s)->base, (p)) #define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) -#define ram_have(s,r) ((s)->r_##r.addr != 0x000000) +#define ram_have(s,r) ((s)->r_##r.addr[0] != 0x000000) #define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) #define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) #define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) -- cgit v1.2.3 From 8dcb4b1526747d8431f9895e153dd478c9d16186 Mon Sep 17 00:00:00 2001 From: Bernd Wachter Date: Tue, 1 Jul 2014 22:01:09 +0300 Subject: net: qmi_wwan: Add ID for Telewell TW-LTE 4G v2 There's a new version of the Telewell 4G modem working with, but not recognized by this driver. Signed-off-by: Bernd Wachter Acked-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index cf62d7e8329f..c4638c67f6b9 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -741,6 +741,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, {QMI_FIXED_INTF(0x19d2, 0x1425, 2)}, {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */ + {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */ {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ -- cgit v1.2.3 From e326f2f13b209d56782609e833b87cb497e64b3b Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Wed, 2 Jul 2014 17:36:23 +0300 Subject: net/mlx4_en: Don't configure the HW vxlan parser when vxlan offloading isn't set The add_vxlan_port ndo driver code was wrongly testing whether HW vxlan offloads are supported by the device instead of checking if they are currently enabled. This causes the driver to configure the HW parser to conduct matching for vxlan packets but since no steering rules were set, vxlan packets are dropped on RX. Fix that by doing the right test, as done in the del_vxlan_port ndo handler. Fixes: 1b136de ('net/mlx4: Implement vxlan ndo calls') Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 7d4fb7bf2593..e94d96f0ef55 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2336,7 +2336,7 @@ static void mlx4_en_add_vxlan_port(struct net_device *dev, struct mlx4_en_priv *priv = netdev_priv(dev); __be16 current_port; - if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS)) + if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) return; if (sa_family == AF_INET6) -- cgit v1.2.3 From 39e0ee9964b1245b79ec89f6b89d8ec4ef672524 Mon Sep 17 00:00:00 2001 From: Suman Tripathi Date: Mon, 7 Jul 2014 22:33:04 +0530 Subject: libahci: export ahci_qc_issue() and ahci_start_fix_rx() The subsequent patch will make use of them. Signed-off-by: Loc Ho Signed-off-by: Suman Tripathi Signed-off-by: Tejun Heo --- drivers/ata/ahci.h | 2 ++ drivers/ata/libahci.c | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 05882e4445a6..5513296e5e2e 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -371,7 +371,9 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, int pmp, unsigned long deadline, int (*check_ready)(struct ata_link *link)); +unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); int ahci_stop_engine(struct ata_port *ap); +void ahci_start_fis_rx(struct ata_port *ap); void ahci_start_engine(struct ata_port *ap); int ahci_check_ready(struct ata_link *link); int ahci_kick_engine(struct ata_port *ap); diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 40ea583d3610..d72ce0470309 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -68,7 +68,6 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); -static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); @@ -620,7 +619,7 @@ int ahci_stop_engine(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ahci_stop_engine); -static void ahci_start_fis_rx(struct ata_port *ap) +void ahci_start_fis_rx(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); struct ahci_host_priv *hpriv = ap->host->private_data; @@ -646,6 +645,7 @@ static void ahci_start_fis_rx(struct ata_port *ap) /* flush */ readl(port_mmio + PORT_CMD); } +EXPORT_SYMBOL_GPL(ahci_start_fis_rx); static int ahci_stop_fis_rx(struct ata_port *ap) { @@ -1945,7 +1945,7 @@ irqreturn_t ahci_interrupt(int irq, void *dev_instance) } EXPORT_SYMBOL_GPL(ahci_interrupt); -static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) +unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *port_mmio = ahci_port_base(ap); @@ -1974,6 +1974,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) return 0; } +EXPORT_SYMBOL_GPL(ahci_qc_issue); static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) { -- cgit v1.2.3 From 2a0bdff6b958d1b2523d2754b6cd5e0ea4053016 Mon Sep 17 00:00:00 2001 From: Suman Tripathi Date: Mon, 7 Jul 2014 22:33:05 +0530 Subject: ahci_xgene: fix the dma state machine lockup for the IDENTIFY DEVICE PIO mode command. This patch fixes the dma state machine lockup due to the processing of IDENTIFY DEVICE PIO mode command. The X-Gene AHCI controller has an errata in which it cannot clear the BSY bit after the PIO setup FIS. The dma state machine enters CMFatalErrorUpdate state and locks up. This patch also removes the dma restart workaround from the read_id function as the read_id function is only called by libata layer for ATA_INTERNAL commands. But for some cases eg: PORT MULTIPLIER and udev, the framework will enumerate using SCSI commands and it will not call read_id function. Signed-off-by: Loc Ho Signed-off-by: Suman Tripathi Signed-off-by: Tejun Heo --- drivers/ata/ahci_xgene.c | 60 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 042a9bb45c86..ee3a3659bd9e 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -78,6 +78,7 @@ struct xgene_ahci_context { struct ahci_host_priv *hpriv; struct device *dev; + u8 last_cmd[MAX_AHCI_CHN_PERCTR]; /* tracking the last command issued*/ void __iomem *csr_core; /* Core CSR address of IP */ void __iomem *csr_diag; /* Diag CSR address of IP */ void __iomem *csr_axi; /* AXI CSR address of IP */ @@ -97,6 +98,50 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx) return 0; } +/** + * xgene_ahci_restart_engine - Restart the dma engine. + * @ap : ATA port of interest + * + * Restarts the dma engine inside the controller. + */ +static int xgene_ahci_restart_engine(struct ata_port *ap) +{ + struct ahci_host_priv *hpriv = ap->host->private_data; + + ahci_stop_engine(ap); + ahci_start_fis_rx(ap); + hpriv->start_engine(ap); + + return 0; +} + +/** + * xgene_ahci_qc_issue - Issue commands to the device + * @qc: Command to issue + * + * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot + * clear the BSY bit after receiving the PIO setup FIS. This results in the dma + * state machine goes into the CMFatalErrorUpdate state and locks up. By + * restarting the dma engine, it removes the controller out of lock up state. + */ +static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ahci_host_priv *hpriv = ap->host->private_data; + struct xgene_ahci_context *ctx = hpriv->plat_data; + int rc = 0; + + if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA)) + xgene_ahci_restart_engine(ap); + + rc = ahci_qc_issue(qc); + + /* Save the last command issued */ + ctx->last_cmd[ap->port_no] = qc->tf.command; + + return rc; +} + /** * xgene_ahci_read_id - Read ID data from the specified device * @dev: device @@ -104,14 +149,12 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx) * @id: data buffer * * This custom read ID function is required due to the fact that the HW - * does not support DEVSLP and the controller state machine may get stuck - * after processing the ID query command. + * does not support DEVSLP. */ static unsigned int xgene_ahci_read_id(struct ata_device *dev, struct ata_taskfile *tf, u16 *id) { u32 err_mask; - void __iomem *port_mmio = ahci_port_base(dev->link->ap); err_mask = ata_do_dev_read_id(dev, tf, id); if (err_mask) @@ -133,16 +176,6 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev, */ id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); - /* - * Due to HW errata, restart the port if no other command active. - * Otherwise the controller may get stuck. - */ - if (!readl(port_mmio + PORT_CMD_ISSUE)) { - writel(PORT_CMD_FIS_RX, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* Force a barrier */ - writel(PORT_CMD_FIS_RX | PORT_CMD_START, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* Force a barrier */ - } return 0; } @@ -300,6 +333,7 @@ static struct ata_port_operations xgene_ahci_ops = { .host_stop = xgene_ahci_host_stop, .hardreset = xgene_ahci_hardreset, .read_id = xgene_ahci_read_id, + .qc_issue = xgene_ahci_qc_issue, }; static const struct ata_port_info xgene_ahci_port_info = { -- cgit v1.2.3 From f50b407653f64e76d1c9abda61d0d85cde3ca9ca Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 2 Jul 2014 16:09:14 +0100 Subject: xen-netfront: don't nest queue locks in xennet_connect() The nesting of the per-queue rx_lock and tx_lock in xennet_connect() is confusing to both humans and lockdep. The locking is safe because this is the only place where the locks are nested in this way but lockdep still warns. Instead of adding the missing lockdep annotations, refactor the locking to avoid the confusing nesting. This is still safe, because the xenbus connection state changes are all serialized by the xenwatch thread. Signed-off-by: David Vrabel Reported-by: Sander Eikelenboom Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 2ccb4a02368b..6a37d62de40b 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -2046,13 +2046,15 @@ static int xennet_connect(struct net_device *dev) /* By now, the queue structures have been set up */ for (j = 0; j < num_queues; ++j) { queue = &np->queues[j]; - spin_lock_bh(&queue->rx_lock); - spin_lock_irq(&queue->tx_lock); /* Step 1: Discard all pending TX packet fragments. */ + spin_lock_irq(&queue->tx_lock); xennet_release_tx_bufs(queue); + spin_unlock_irq(&queue->tx_lock); /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */ + spin_lock_bh(&queue->rx_lock); + for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) { skb_frag_t *frag; const struct page *page; @@ -2076,6 +2078,8 @@ static int xennet_connect(struct net_device *dev) } queue->rx.req_prod_pvt = requeue_idx; + + spin_unlock_bh(&queue->rx_lock); } /* @@ -2087,13 +2091,17 @@ static int xennet_connect(struct net_device *dev) netif_carrier_on(np->netdev); for (j = 0; j < num_queues; ++j) { queue = &np->queues[j]; + notify_remote_via_irq(queue->tx_irq); if (queue->tx_irq != queue->rx_irq) notify_remote_via_irq(queue->rx_irq); - xennet_tx_buf_gc(queue); - xennet_alloc_rx_buffers(queue); + spin_lock_irq(&queue->tx_lock); + xennet_tx_buf_gc(queue); spin_unlock_irq(&queue->tx_lock); + + spin_lock_bh(&queue->rx_lock); + xennet_alloc_rx_buffers(queue); spin_unlock_bh(&queue->rx_lock); } -- cgit v1.2.3 From f9feb1e6a25f9e197f9e6e6cb04bf04d2cccff93 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 2 Jul 2014 16:09:15 +0100 Subject: xen-netfront: call netif_carrier_off() only once when disconnecting In xennet_disconnect_backend(), netif_carrier_off() was called once per queue when it needs to only be called once. The queue locking around the netif_carrier_off() call looked very odd. I think they were supposed to synchronize any NAPI instances with the expectation that no further NAPI instances would be scheduled because of the carrier being off (see the check in xennet_rx_interrupt()). But I can't easily tell if this works correctly. Instead, add a napi_synchronize() call after disabling the interrupts. This is obviously correct as with no Rx interrupts, no further NAPI instances will be scheduled. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 6a37d62de40b..055222bae6e4 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1439,16 +1439,11 @@ static void xennet_disconnect_backend(struct netfront_info *info) unsigned int i = 0; unsigned int num_queues = info->netdev->real_num_tx_queues; + netif_carrier_off(info->netdev); + for (i = 0; i < num_queues; ++i) { struct netfront_queue *queue = &info->queues[i]; - /* Stop old i/f to prevent errors whilst we rebuild the state. */ - spin_lock_bh(&queue->rx_lock); - spin_lock_irq(&queue->tx_lock); - netif_carrier_off(queue->info->netdev); - spin_unlock_irq(&queue->tx_lock); - spin_unlock_bh(&queue->rx_lock); - if (queue->tx_irq && (queue->tx_irq == queue->rx_irq)) unbind_from_irqhandler(queue->tx_irq, queue); if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) { @@ -1458,6 +1453,8 @@ static void xennet_disconnect_backend(struct netfront_info *info) queue->tx_evtchn = queue->rx_evtchn = 0; queue->tx_irq = queue->rx_irq = 0; + napi_synchronize(&queue->napi); + /* End access and free the pages */ xennet_end_access(queue->tx_ring_ref, queue->tx.sring); xennet_end_access(queue->rx_ring_ref, queue->rx.sring); -- cgit v1.2.3 From baa3c65298c089a9014b4e523a14ec2885cca1bc Mon Sep 17 00:00:00 2001 From: Jan Kardell Date: Thu, 6 Nov 2014 22:18:00 +0000 Subject: iio: ti_am335x_adc: Fix: Use same step id at FIFOs both ends Since AI lines could be selected at will (linux-3.11) the sending and receiving ends of the FIFO does not agree about what step is used for a line. It only works if the last lines are used, like 5,6,7, and fails if ie 2,4,6 is selected in DT. Signed-off-by: Jan Kardell Tested-by: Zubair Lutfullah Signed-off-by: Jonathan Cameron Cc: stable@vger.kernel.org --- drivers/iio/adc/ti_am335x_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index a4db3026bec6..d5dc4c6ce86c 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -374,7 +374,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, return -EAGAIN; } } - map_val = chan->channel + TOTAL_CHANNELS; + map_val = adc_dev->channel_step[chan->scan_index]; /* * We check the complete FIFO. We programmed just one entry but in case -- cgit v1.2.3 From 85b722d760f0de77c4bb371b77202784671f5a54 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sun, 6 Jul 2014 14:04:37 +0200 Subject: isdn: hisax: l3ni1.c: Fix for possible null pointer dereference There is otherwise a risk of a possible null pointer dereference. Was largely found by using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist --- drivers/isdn/hisax/l3ni1.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 0df6691d045c..8dc791bfaa6f 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -2059,13 +2059,17 @@ static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic) memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */ l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */ - if (ic->parm.ni1_io.timeout > 0) - if (!(pc = ni1_new_l3_process(st, -1))) - { free_invoke_id(st, id); + if (ic->parm.ni1_io.timeout > 0) { + pc = ni1_new_l3_process(st, -1); + if (!pc) { + free_invoke_id(st, id); return (-2); } - pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; /* remember id */ - pc->prot.ni1.proc = ic->parm.ni1_io.proc; /* and procedure */ + /* remember id */ + pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; + /* and procedure */ + pc->prot.ni1.proc = ic->parm.ni1_io.proc; + } if (!(skb = l3_alloc_skb(l))) { free_invoke_id(st, id); -- cgit v1.2.3 From 5a90af67c2126fe1d04ebccc1f8177e6ca70d3a9 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Tue, 8 Jul 2014 16:25:38 +0100 Subject: cpufreq: Makefile: fix compilation for davinci platform Since commtit 8a7b1227e303 (cpufreq: davinci: move cpufreq driver to drivers/cpufreq) this added dependancy only for CONFIG_ARCH_DAVINCI_DA850 where as davinci_cpufreq_init() call is used by all davinci platform. This patch fixes following build error: arch/arm/mach-davinci/built-in.o: In function `davinci_init_late': :(.init.text+0x928): undefined reference to `davinci_cpufreq_init' make: *** [vmlinux] Error 1 Fixes: 8a7b1227e303 (cpufreq: davinci: move cpufreq driver to drivers/cpufreq) Signed-off-by: Lad, Prabhakar Acked-by: Viresh Kumar Cc: 3.10+ # 3.10+ Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 738c8b7b17dc..db6d9a2fea4d 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o # LITTLE drivers, so that it is probed last. obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o -obj-$(CONFIG_ARCH_DAVINCI_DA850) += davinci-cpufreq.o +obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o -- cgit v1.2.3 From 0b0302449110ca5ca4350458ed57b971fcb78ec1 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Tue, 8 Jul 2014 14:49:28 +0800 Subject: r8152: wake up the device before dumping the hw counter The device should be waked up from runtime suspend before dumping the hw counter. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 25431965a625..a795ecf8d5b6 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -3204,8 +3204,13 @@ static void rtl8152_get_ethtool_stats(struct net_device *dev, struct r8152 *tp = netdev_priv(dev); struct tally_counter tally; + if (usb_autopm_get_interface(tp->intf) < 0) + return; + generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); + usb_autopm_put_interface(tp->intf); + data[0] = le64_to_cpu(tally.tx_packets); data[1] = le64_to_cpu(tally.rx_packets); data[2] = le64_to_cpu(tally.tx_errors); -- cgit v1.2.3 From fbc6daf19745b372c0d909e5d74ab02e42b70e51 Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Tue, 8 Jul 2014 11:28:12 +0300 Subject: net/mlx4_en: Ignore budget on TX napi polling It is recommended that TX work not count against the quota. The cost of TX packet liberation is a minute percentage of what it costs to process an RX frame. Furthermore, that SKB freeing makes memory available for other paths in the stack. Give the TX a larger budget and be more aggressive about cleaning up the Tx descriptors this budget could be changed using ethtool: $ ethtool -C eth1 tx-frames-irq Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 7 +++++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 1 + drivers/net/ethernet/mellanox/mlx4/en_tx.c | 28 ++++++++++++------------- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +++ 4 files changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index fa1a069e14e6..68d763d2d030 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -417,6 +417,8 @@ static int mlx4_en_get_coalesce(struct net_device *dev, coal->tx_coalesce_usecs = priv->tx_usecs; coal->tx_max_coalesced_frames = priv->tx_frames; + coal->tx_max_coalesced_frames_irq = priv->tx_work_limit; + coal->rx_coalesce_usecs = priv->rx_usecs; coal->rx_max_coalesced_frames = priv->rx_frames; @@ -426,6 +428,7 @@ static int mlx4_en_get_coalesce(struct net_device *dev, coal->rx_coalesce_usecs_high = priv->rx_usecs_high; coal->rate_sample_interval = priv->sample_interval; coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal; + return 0; } @@ -434,6 +437,9 @@ static int mlx4_en_set_coalesce(struct net_device *dev, { struct mlx4_en_priv *priv = netdev_priv(dev); + if (!coal->tx_max_coalesced_frames_irq) + return -EINVAL; + priv->rx_frames = (coal->rx_max_coalesced_frames == MLX4_EN_AUTO_CONF) ? MLX4_EN_RX_COAL_TARGET : @@ -457,6 +463,7 @@ static int mlx4_en_set_coalesce(struct net_device *dev, priv->rx_usecs_high = coal->rx_coalesce_usecs_high; priv->sample_interval = coal->rate_sample_interval; priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce; + priv->tx_work_limit = coal->tx_max_coalesced_frames_irq; return mlx4_en_moderation_update(priv); } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index e94d96f0ef55..7345c43b019e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2473,6 +2473,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, MLX4_WQE_CTRL_SOLICITED); priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up; priv->tx_ring_num = prof->tx_ring_num; + priv->tx_work_limit = MLX4_EN_DEFAULT_TX_WORK; priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS, GFP_KERNEL); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index ac3dead3792c..5045bab59633 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -351,9 +351,8 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring) return cnt; } -static int mlx4_en_process_tx_cq(struct net_device *dev, - struct mlx4_en_cq *cq, - int budget) +static bool mlx4_en_process_tx_cq(struct net_device *dev, + struct mlx4_en_cq *cq) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_cq *mcq = &cq->mcq; @@ -372,9 +371,10 @@ static int mlx4_en_process_tx_cq(struct net_device *dev, int factor = priv->cqe_factor; u64 timestamp = 0; int done = 0; + int budget = priv->tx_work_limit; if (!priv->port_up) - return 0; + return true; index = cons_index & size_mask; cqe = &buf[(index << factor) + factor]; @@ -447,7 +447,7 @@ static int mlx4_en_process_tx_cq(struct net_device *dev, netif_tx_wake_queue(ring->tx_queue); ring->wake_queue++; } - return done; + return done < budget; } void mlx4_en_tx_irq(struct mlx4_cq *mcq) @@ -467,18 +467,16 @@ int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget) struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi); struct net_device *dev = cq->dev; struct mlx4_en_priv *priv = netdev_priv(dev); - int done; + int clean_complete; - done = mlx4_en_process_tx_cq(dev, cq, budget); + clean_complete = mlx4_en_process_tx_cq(dev, cq); + if (!clean_complete) + return budget; - /* If we used up all the quota - we're probably not done yet... */ - if (done < budget) { - /* Done for now */ - napi_complete(napi); - mlx4_en_arm_cq(priv, cq); - return done; - } - return budget; + napi_complete(napi); + mlx4_en_arm_cq(priv, cq); + + return 0; } static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 624e1939e9ee..d72a5a894fc6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -126,6 +126,8 @@ enum { #define MAX_TX_RINGS (MLX4_EN_MAX_TX_RING_P_UP * \ MLX4_EN_NUM_UP) +#define MLX4_EN_DEFAULT_TX_WORK 256 + /* Target number of packets to coalesce with interrupt moderation */ #define MLX4_EN_RX_COAL_TARGET 44 #define MLX4_EN_RX_COAL_TIME 0x10 @@ -543,6 +545,7 @@ struct mlx4_en_priv { __be32 ctrl_flags; u32 flags; u8 num_tx_rings_p_up; + u32 tx_work_limit; u32 tx_ring_num; u32 rx_ring_num; u32 rx_skb_size; -- cgit v1.2.3 From 4d12bc63ab5e48c1d78fa13883cf6fefcea3afb1 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 8 Jul 2014 10:49:43 +0200 Subject: net: mvneta: fix operation in 10 Mbit/s mode As reported by Maggie Mae Roxas, the mvneta driver doesn't behave properly in 10 Mbit/s mode. This is due to a misconfiguration of the MVNETA_GMAC_AUTONEG_CONFIG register: bit MVNETA_GMAC_CONFIG_MII_SPEED must be set for a 100 Mbit/s speed, but cleared for a 10 Mbit/s speed, which the driver was not properly doing. This commit adjusts that by setting the MVNETA_GMAC_CONFIG_MII_SPEED bit only in 100 Mbit/s mode, and relying on the fact that all the speed related bits of this register are cleared at the beginning of the mvneta_adjust_link() function. This problem exists since c5aff18204da0 ("net: mvneta: driver for Marvell Armada 370/XP network unit") which is the commit that introduced the mvneta driver in the kernel. Cc: # v3.8+ Fixes: c5aff18204da0 ("net: mvneta: driver for Marvell Armada 370/XP network unit") Reported-by: Maggie Mae Roxas Cc: Maggie Mae Roxas Signed-off-by: Thomas Petazzoni Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 45beca17fa50..d49f08d22071 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -2529,7 +2529,7 @@ static void mvneta_adjust_link(struct net_device *ndev) if (phydev->speed == SPEED_1000) val |= MVNETA_GMAC_CONFIG_GMII_SPEED; - else + else if (phydev->speed == SPEED_100) val |= MVNETA_GMAC_CONFIG_MII_SPEED; mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); -- cgit v1.2.3 From 0a1985879437d14bda8c90d0dae3455c467d7642 Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Tue, 8 Jul 2014 19:44:07 -0400 Subject: net: mvneta: Fix big endian issue in mvneta_txq_desc_csum() This commit fixes the command value generated for CSUM calculation when running in big endian mode. The Ethernet protocol ID for IP was being unconditionally byte-swapped in the layer 3 protocol check (with swab16), which caused the mvneta driver to not function correctly in big endian mode. This patch byte-swaps the ID conditionally with htons. Cc: # v3.13+ Signed-off-by: Thomas Fitzsimmons Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index d49f08d22071..dadd9a5f6323 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1207,7 +1207,7 @@ static u32 mvneta_txq_desc_csum(int l3_offs, int l3_proto, command = l3_offs << MVNETA_TX_L3_OFF_SHIFT; command |= ip_hdr_len << MVNETA_TX_IP_HLEN_SHIFT; - if (l3_proto == swab16(ETH_P_IP)) + if (l3_proto == htons(ETH_P_IP)) command |= MVNETA_TXD_IP_CSUM; else command |= MVNETA_TX_L3_IP6; -- cgit v1.2.3 From 9c72cc6f00d24711ef585772396dd1ae180881a6 Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Thu, 3 Jul 2014 23:27:50 +0000 Subject: drm/i915: quirk asserts controllable backlight presence, overriding VBT commit c675949ec58ca50d5a3ae3c757892f1560f6e896 Author: Jani Nikula Date: Wed Apr 9 11:31:37 2014 +0300 drm/i915: do not setup backlight if not available according to VBT caused a regression on machines with a misconfigured VBT. Add a quirk to assert the presence of a controllable backlight. Use it to ignore the VBT backlight presence check during backlight setup. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Tested-by: James Duley Tested-by: Michael Mullin Reviewed-by: Jani Nikula Signed-off-by: Scot Doyle Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org # 3.15 only [danvet: Add cc: stable because the regressing commit is in 3.15.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 8 ++++++++ drivers/gpu/drm/i915/intel_panel.c | 8 ++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a47fbf60b781..374f964323ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -656,6 +656,7 @@ enum intel_sbi_destination { #define QUIRK_PIPEA_FORCE (1<<0) #define QUIRK_LVDS_SSC_DISABLE (1<<1) #define QUIRK_INVERT_BRIGHTNESS (1<<2) +#define QUIRK_BACKLIGHT_PRESENT (1<<3) struct intel_fbdev; struct intel_fbc_work; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 556c916dbf9d..949c765037ed 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11591,6 +11591,14 @@ static void quirk_invert_brightness(struct drm_device *dev) DRM_INFO("applying inverted panel brightness quirk\n"); } +/* Some VBT's incorrectly indicate no backlight is present */ +static void quirk_backlight_present(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT; + DRM_INFO("applying backlight present quirk\n"); +} + struct intel_quirk { int device; int subsystem_vendor; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 38a98570d10c..628cd8938274 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1118,8 +1118,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector) int ret; if (!dev_priv->vbt.backlight.present) { - DRM_DEBUG_KMS("native backlight control not available per VBT\n"); - return 0; + if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { + DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n"); + } else { + DRM_DEBUG_KMS("no backlight present per VBT\n"); + return 0; + } } /* set level and max in panel struct */ -- cgit v1.2.3 From 2e93a1aa9ca455aa3ad0294bcd6d66f38bf8b758 Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Thu, 3 Jul 2014 23:27:51 +0000 Subject: drm/i915: Acer C720 and C720P have controllable backlights The Acer C720 and C720P Chromebooks (with Celeron 2955U CPU) have a controllable backlight although their VBT reports otherwise. Apply quirk to ignore the backlight presence check during backlight setup. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Tested-by: James Duley Tested-by: Michael Mullin Signed-off-by: Scot Doyle CC: Jani Nikula Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org # 3.15 only [danvet: Add cc: stable because the regressing commit is in 3.15.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 949c765037ed..2ee81656f80a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11667,6 +11667,9 @@ static struct intel_quirk intel_quirks[] = { /* Acer Aspire 5336 */ { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness }, + + /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ + { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, }; static void intel_init_quirks(struct drm_device *dev) -- cgit v1.2.3 From d4967d8c6d4f52623f2be8eaff0b445dc5863c92 Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Thu, 3 Jul 2014 23:27:52 +0000 Subject: drm/i915: Toshiba CB35 has a controllable backlight The Toshiba CB35 Chromebook (with Celeron 2955U CPU) has a controllable backlight although its VBT reports otherwise. Apply quirk to ignore the backlight presence check during backlight setup. Patch tested by author on Toshiba CB35. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Signed-off-by: Scot Doyle CC: Jani Nikula Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org # 3.15 only [danvet: Add cc: stable because the regressing commit is in 3.15.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2ee81656f80a..e27e7804c0b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11670,6 +11670,9 @@ static struct intel_quirk intel_quirks[] = { /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, + + /* Toshiba CB35 Chromebook (Celeron 2955U) */ + { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, }; static void intel_init_quirks(struct drm_device *dev) -- cgit v1.2.3 From a799a9780eb5c874d9d7ca0bbee66401ca98c013 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Thu, 3 Jul 2014 16:35:40 +0530 Subject: drm/i915/vlv: DPI FIFO empty check is not needed While sending DPI SHUTDOWN command, we cannot wait for FIFO empty as pipes are not disabled at that time. In case of MIPI we disable port first and send SHUTDOWN command while pipe is still running and FIFOs will not be empty, causing spurious error log Signed-off-by: Shobhit Kumar Tested-by: Chris Wilson Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_cmd.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 3eeb21b9fddf..933c86305237 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c @@ -404,12 +404,6 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) else cmd |= DPI_LP_MODE; - /* DPI virtual channel?! */ - - mask = DPI_FIFO_EMPTY; - if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50)) - DRM_ERROR("Timeout waiting for DPI FIFO empty.\n"); - /* clear bit */ I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT); -- cgit v1.2.3 From aceb365ca9a51fb604313c08ed3061d6cc643237 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Thu, 3 Jul 2014 16:35:41 +0530 Subject: drm/i915/vlv: Update the DSI ULPS entry/exit sequence We should keep DEVICE_READY bit set in the ULPS enter sequence. In exit sequence also we should set DEVICE_READY, but thats causing blankout for me. Also exit sequence is simplified as per hw team recommendation. This should fix - [drm:intel_dsi_clear_device_ready] *ERROR* DSI LP not going Low Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80818 Signed-off-by: Shobhit Kumar Tested-by: Chris Wilson Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 02f99d768d49..3fd082933c87 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -117,17 +117,18 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(dev_priv); + I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); + usleep_range(2500, 3000); + val = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); usleep_range(1000, 1500); - I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); - usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); - usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); - usleep_range(2000, 2500); + + I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); + usleep_range(2500, 3000); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); - usleep_range(2000, 2500); + usleep_range(2500, 3000); } static void intel_dsi_enable(struct intel_encoder *encoder) @@ -271,23 +272,23 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) DRM_DEBUG_KMS("\n"); - I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER); usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER); usleep_range(2000, 2500); - val = I915_READ(MIPI_PORT_CTRL(pipe)); - I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); - usleep_range(1000, 1500); - if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT) == 0x00000), 30)) DRM_ERROR("DSI LP not going Low\n"); + val = I915_READ(MIPI_PORT_CTRL(pipe)); + I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); + usleep_range(1000, 1500); + I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); usleep_range(2000, 2500); -- cgit v1.2.3 From f1e1c2129b79cfdaf07bca37c5a10569fe021abe Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 5 Jun 2014 20:02:59 +0300 Subject: drm/i915: Don't clobber the GTT when it's within stolen memory On most gen2-4 platforms the GTT can be (or maybe always is?) inside the stolen memory region. If that's the case, reduce the size of the stolen memory appropriately to make make sure we don't clobber the GTT. v2: Deal with gen4 36 bit physical address Signed-off-by: Ville Syrjälä Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80151 Acked-by: Chris Wilson Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_stolen.c | 44 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ 2 files changed, 47 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 62ef55ba061c..7465ab0fd396 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -74,6 +74,50 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) if (base == 0) return 0; + /* make sure we don't clobber the GTT if it's within stolen memory */ + if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) { + struct { + u32 start, end; + } stolen[2] = { + { .start = base, .end = base + dev_priv->gtt.stolen_size, }, + { .start = base, .end = base + dev_priv->gtt.stolen_size, }, + }; + u64 gtt_start, gtt_end; + + gtt_start = I915_READ(PGTBL_CTL); + if (IS_GEN4(dev)) + gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) | + (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28; + else + gtt_start &= PGTBL_ADDRESS_LO_MASK; + gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4; + + if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end) + stolen[0].end = gtt_start; + if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end) + stolen[1].start = gtt_end; + + /* pick the larger of the two chunks */ + if (stolen[0].end - stolen[0].start > + stolen[1].end - stolen[1].start) { + base = stolen[0].start; + dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start; + } else { + base = stolen[1].start; + dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start; + } + + if (stolen[0].start != stolen[1].start || + stolen[0].end != stolen[1].end) { + DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n", + (unsigned long long) gtt_start, + (unsigned long long) gtt_end - 1); + DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n", + base, base + (u32) dev_priv->gtt.stolen_size - 1); + } + } + + /* Verify that nothing else uses this physical address. Stolen * memory should be reserved by the BIOS and hidden from the * kernel. So if the region is already marked as busy, something diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e691b30b2817..a5bab61bfc00 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -942,6 +942,9 @@ enum punit_power_well { /* * Instruction and interrupt control regs */ +#define PGTBL_CTL 0x02020 +#define PGTBL_ADDRESS_LO_MASK 0xfffff000 /* bits [31:12] */ +#define PGTBL_ADDRESS_HI_MASK 0x000000f0 /* bits [35:32] (gen4) */ #define PGTBL_ER 0x02024 #define RENDER_RING_BASE 0x02000 #define BSD_RING_BASE 0x04000 -- cgit v1.2.3 From 1bb9e632a0aeee1121e652ee4dc80e5e6f14bcd2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 8 Jul 2014 10:02:43 +0200 Subject: drm/i915: Only unbind vgacon, not other console drivers The console subsystem only provides a function to switch to a given console, but we want to actually only switach away from vgacon. Unconditionally switching to the dummy console resulted in switching away from fbcon in multi-gpu setups when other gpu drivers are loaded before i915. Then either the reinitialization of fbcon when i915 registers its fbdev emulation or the teardown of the fbcon driver killed the machine. So only switch to the dummy console when it's required. Kudos to Chris for the original idea, I've only refined it a bit to still unregister vgacon even when it's currently unused. This regression has been introduced in commit a4de05268e674e8ed31df6348269e22d6c6a1803 Author: Daniel Vetter Date: Thu Jun 5 16:20:46 2014 +0200 drm/i915: Kick out vga console Reported-and-tested-by: Ed Tomlinson Cc: Chris Wilson Cc: David Herrmann Reviewed-by: Chris Wilson Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6c656392d67d..d44344140627 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1464,12 +1464,13 @@ static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) #else static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) { - int ret; + int ret = 0; DRM_INFO("Replacing VGA console driver\n"); console_lock(); - ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); + if (con_is_bound(&vga_con)) + ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); if (ret == 0) { ret = do_unregister_con_driver(&vga_con); -- cgit v1.2.3 From 01527b3127997ef6370d5ad4fa25d96847fbf12a Mon Sep 17 00:00:00 2001 From: Clint Taylor Date: Mon, 7 Jul 2014 13:01:46 -0700 Subject: drm/i915/vlv: T12 eDP panel timing enforcement during reboot The panel power sequencer on vlv doesn't appear to accept changes to its T12 power down duration during warm reboots. This change forces a delay for warm reboots to the T12 panel timing as defined in the VBT table for the connected panel. Ver2: removed redundant pr_crit(), commented magic value for pp_div_reg Ver3: moved SYS_RESTART check earlier, new name for pp_div. Ver4: Minor issue changes Ver5: Move registration of reboot notifier to edp_connector_init, Added warning comment to handler about lack of PM notification. Signed-off-by: Clint Taylor Reviewed-by: Paulo Zanoni Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 42 ++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ 2 files changed, 44 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 52fda950fd2a..075170d1844f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -336,6 +338,37 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp) return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp)); } +/* Reboot notifier handler to shutdown panel power to guarantee T12 timing + This function only applicable when panel PM state is not to be tracked */ +static int edp_notify_handler(struct notifier_block *this, unsigned long code, + void *unused) +{ + struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp), + edp_notifier); + struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct drm_i915_private *dev_priv = dev->dev_private; + u32 pp_div; + u32 pp_ctrl_reg, pp_div_reg; + enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); + + if (!is_edp(intel_dp) || code != SYS_RESTART) + return 0; + + if (IS_VALLEYVIEW(dev)) { + pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe); + pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); + pp_div = I915_READ(pp_div_reg); + pp_div &= PP_REFERENCE_DIVIDER_MASK; + + /* 0x1F write to PP_DIV_REG sets max cycle delay */ + I915_WRITE(pp_div_reg, pp_div | 0x1F); + I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF); + msleep(intel_dp->panel_power_cycle_delay); + } + + return 0; +} + static bool edp_have_panel_power(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@ -3707,6 +3740,10 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); edp_panel_vdd_off_sync(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + if (intel_dp->edp_notifier.notifier_call) { + unregister_reboot_notifier(&intel_dp->edp_notifier); + intel_dp->edp_notifier.notifier_call = NULL; + } } kfree(intel_dig_port); } @@ -4184,6 +4221,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } mutex_unlock(&dev->mode_config.mutex); + if (IS_VALLEYVIEW(dev)) { + intel_dp->edp_notifier.notifier_call = edp_notify_handler; + register_reboot_notifier(&intel_dp->edp_notifier); + } + intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); intel_panel_setup_backlight(connector); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index eaa27ee9e367..f67340ed2c12 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -538,6 +538,8 @@ struct intel_dp { unsigned long last_power_on; unsigned long last_backlight_off; bool psr_setup_done; + struct notifier_block edp_notifier; + bool use_tps3; struct intel_connector *attached_connector; -- cgit v1.2.3 From c128c776e0f45d3edaf44ab3fecfa5d1f7067c07 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 9 Jul 2014 14:31:04 +0200 Subject: ACPI / PNP: add soc_button_array device ID to PNP IDs list The soc_button_array PNP driver was introduced in 3.15. But in commit eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device enumeration), when reworking the PNPACPI device enumeration, we missed the soc_button_array device ID. This results in a regression in 3.16-rc1 that soc_button_array pnp device fails to be enumerated. Fix the problem by adding soc_button_array device ID into the acpi_pnp scan handler's ID list. Fixes: eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device enumeration) Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_pnp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index 6703c1fd993a..4ddb0dca56f6 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c @@ -14,6 +14,8 @@ #include static const struct acpi_device_id acpi_pnp_device_ids[] = { + /* soc_button_array */ + {"PNP0C40"}, /* pata_isapnp */ {"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */ /* floppy */ -- cgit v1.2.3 From affb1aff300ddee54df307812b38f166e8a865ef Mon Sep 17 00:00:00 2001 From: K. Y. Srinivasan Date: Mon, 7 Jul 2014 16:34:24 -0700 Subject: Drivers: hv: vmbus: Fix a bug in the channel callback dispatch code Starting with Win8, we have implemented several optimizations to improve the scalability and performance of the VMBUS transport between the Host and the Guest. Some of the non-performance critical services cannot leverage these optimization since they only read and process one message at a time. Make adjustments to the callback dispatch code to account for the way non-performance critical drivers handle reading of the channel. Signed-off-by: K. Y. Srinivasan Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/hv/connection.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index e84f4526eb36..ae22e3c1fc4c 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -339,9 +339,13 @@ static void process_chn_event(u32 relid) */ do { - hv_begin_read(&channel->inbound); + if (read_state) + hv_begin_read(&channel->inbound); channel->onchannel_callback(arg); - bytes_to_read = hv_end_read(&channel->inbound); + if (read_state) + bytes_to_read = hv_end_read(&channel->inbound); + else + bytes_to_read = 0; } while (read_state && (bytes_to_read != 0)); } else { pr_err("no channel callback for relid - %u\n", relid); -- cgit v1.2.3 From 9bd2d0dfe4714dd5d7c09a93a5c9ea9e14ceb3fc Mon Sep 17 00:00:00 2001 From: K. Y. Srinivasan Date: Mon, 7 Jul 2014 16:34:25 -0700 Subject: Drivers: hv: util: Fix a bug in the KVP code Add code to poll the channel since we process only one message at a time and the host may not interrupt us. Also increase the receive buffer size since some KVP messages are close to 8K bytes in size. Signed-off-by: K. Y. Srinivasan Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.c | 17 ++++++++++++++--- drivers/hv/hv_util.c | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index ea852537307e..521c14625b3a 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -127,6 +127,17 @@ kvp_work_func(struct work_struct *dummy) kvp_respond_to_host(NULL, HV_E_FAIL); } +static void poll_channel(struct vmbus_channel *channel) +{ + if (channel->target_cpu != smp_processor_id()) + smp_call_function_single(channel->target_cpu, + hv_kvp_onchannelcallback, + channel, true); + else + hv_kvp_onchannelcallback(channel); +} + + static int kvp_handle_handshake(struct hv_kvp_msg *msg) { int ret = 1; @@ -155,7 +166,7 @@ static int kvp_handle_handshake(struct hv_kvp_msg *msg) kvp_register(dm_reg_value); kvp_transaction.active = false; if (kvp_transaction.kvp_context) - hv_kvp_onchannelcallback(kvp_transaction.kvp_context); + poll_channel(kvp_transaction.kvp_context); } return ret; } @@ -568,7 +579,7 @@ response_done: vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, VM_PKT_DATA_INBAND, 0); - + poll_channel(channel); } /* @@ -603,7 +614,7 @@ void hv_kvp_onchannelcallback(void *context) return; } - vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, + vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 4, &recvlen, &requestid); if (recvlen > 0) { diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index dd761806f0e8..3b9c9ef0deb8 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -319,7 +319,7 @@ static int util_probe(struct hv_device *dev, (struct hv_util_service *)dev_id->driver_data; int ret; - srv->recv_buffer = kmalloc(PAGE_SIZE * 2, GFP_KERNEL); + srv->recv_buffer = kmalloc(PAGE_SIZE * 4, GFP_KERNEL); if (!srv->recv_buffer) return -ENOMEM; if (srv->util_init) { -- cgit v1.2.3 From 5a7fbe7e9ea0b1b9d7ffdba64db1faa3a259164c Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Tue, 8 Jul 2014 14:42:23 +0200 Subject: USB: ftdi_sio: Add extra PID. This patch adds PID 0x0003 to the VID 0x128d (Testo). At least the Testo 435-4 uses this, likely other gear as well. Signed-off-by: Bert Vermeulen Cc: Johan Hovold Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 3 ++- drivers/usb/serial/ftdi_sio_ids.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 115662c16dcc..bf2e30a6824a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -720,7 +720,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, - { USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) }, + { USB_DEVICE(TESTO_VID, TESTO_1_PID) }, + { USB_DEVICE(TESTO_VID, TESTO_3_PID) }, { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 500474c48f4b..106cc16cc6ed 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -798,7 +798,8 @@ * Submitted by Colin Leroy */ #define TESTO_VID 0x128D -#define TESTO_USB_INTERFACE_PID 0x0001 +#define TESTO_1_PID 0x0001 +#define TESTO_3_PID 0x0003 /* * Mobility Electronics products. -- cgit v1.2.3 From b51ecea852b712618796d9eab8428a7d5f1f106f Mon Sep 17 00:00:00 2001 From: hayeswang Date: Wed, 9 Jul 2014 14:52:51 +0800 Subject: r8169: disable L23 For RTL8411, RTL8111G, RTL8402, RTL8105, and RTL8106, disable the feature of entering the L2/L3 link state of the PCIe. When the nic starts the process of entering the L2/L3 link state and the PCI reset occurs before the work is finished, the work would be queued and continue after the next the PCI reset occurs. This causes the device stays in L2/L3 link state, and the system couldn't find the device. Signed-off-by: Hayes Wang Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index be425ad5e824..06bdc31a828d 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -538,6 +538,7 @@ enum rtl_register_content { MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */ + Rdy_to_L23 = (1 << 1), /* L23 Enable */ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ /* Config4 register */ @@ -4897,6 +4898,21 @@ static void rtl_enable_clock_request(struct pci_dev *pdev) PCI_EXP_LNKCTL_CLKREQ_EN); } +static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable) +{ + void __iomem *ioaddr = tp->mmio_addr; + u8 data; + + data = RTL_R8(Config3); + + if (enable) + data |= Rdy_to_L23; + else + data &= ~Rdy_to_L23; + + RTL_W8(Config3, data); +} + #define R8168_CPCMD_QUIRK_MASK (\ EnableBist | \ Mac_dbgo_oe | \ @@ -5246,6 +5262,7 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) }; rtl_hw_start_8168f(tp); + rtl_pcie_state_l2l3_enable(tp, false); rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); @@ -5284,6 +5301,8 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC); + + rtl_pcie_state_l2l3_enable(tp, false); } static void rtl_hw_start_8168g_2(struct rtl8169_private *tp) @@ -5536,6 +5555,8 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); + + rtl_pcie_state_l2l3_enable(tp, false); } static void rtl_hw_start_8105e_2(struct rtl8169_private *tp) @@ -5571,6 +5592,8 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp) rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, ERIAR_EXGMAC); + + rtl_pcie_state_l2l3_enable(tp, false); } static void rtl_hw_start_8106(struct rtl8169_private *tp) @@ -5583,6 +5606,8 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp) RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); + + rtl_pcie_state_l2l3_enable(tp, false); } static void rtl_hw_start_8101(struct net_device *dev) -- cgit v1.2.3 From 6d827fbcc370ca259a2905309f64161ab7b10596 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 21 Jun 2014 08:08:08 -0700 Subject: i8k: Fix non-SMP operation Commit f36fdb9f0266 (i8k: Force SMM to run on CPU 0) adds support for multi-core CPUs to the driver. Unfortunately, that causes it to fail loading if compiled without SMP support, at least on 32 bit kernels. Kernel log shows "i8k: unable to get SMM Dell signature", and function i8k_smm is found to return -EINVAL. Testing revealed that the culprit is the missing return value check of set_cpus_allowed_ptr. Fixes: f36fdb9f0266 (i8k: Force SMM to run on CPU 0) Reported-by: Jim Bos Tested-by: Jim Bos Cc: stable@vger.kernel.org # 3.14+ Signed-off-by: Guenter Roeck Cc: Andreas Mohr Signed-off-by: Greg Kroah-Hartman --- drivers/char/i8k.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index d915707d2ba1..93dcad0c1cbe 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -138,7 +138,9 @@ static int i8k_smm(struct smm_regs *regs) if (!alloc_cpumask_var(&old_mask, GFP_KERNEL)) return -ENOMEM; cpumask_copy(old_mask, ¤t->cpus_allowed); - set_cpus_allowed_ptr(current, cpumask_of(0)); + rc = set_cpus_allowed_ptr(current, cpumask_of(0)); + if (rc) + goto out; if (smp_processor_id() != 0) { rc = -EBUSY; goto out; -- cgit v1.2.3 From a12f78c582b5a7a549fbee1a58d5778e651764ad Mon Sep 17 00:00:00 2001 From: Stefan Sørensen Date: Wed, 25 Jun 2014 14:40:16 +0200 Subject: dp83640: Always decode received status frames Currently status frames are only handled when packet timestamping is enabled, but status frames are also needed for pin event timestamping. Fix by moving packet timestamping check to after status frame decode. Signed-off-by: Stefan Sørensen Acked-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/phy/dp83640.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 6a999e6814a0..9408157a246c 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1323,15 +1323,15 @@ static bool dp83640_rxtstamp(struct phy_device *phydev, { struct dp83640_private *dp83640 = phydev->priv; - if (!dp83640->hwts_rx_en) - return false; - if (is_status_frame(skb, type)) { decode_status_frame(dp83640, skb); kfree_skb(skb); return true; } + if (!dp83640->hwts_rx_en) + return false; + SKB_PTP_TYPE(skb) = type; skb_queue_tail(&dp83640->rx_queue, skb); schedule_work(&dp83640->ts_work); -- cgit v1.2.3 From b4df480f68ae03b5dd4ab0db56536fbcec741705 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 10 Jul 2014 11:49:42 +0900 Subject: usbnet: smsc95xx: add reset_resume function with reset operation The smsc95xx needs to resume with reset operation. Otherwise it causes system hang by network error like below after resume. This case appears on odroid u3 board. [ 9.727600] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped [ 9.727648] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped [ 9.727689] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped [ 9.727728] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped [ 9.729486] PM: resume of devices complete after 2011.219 msecs [ 10.117609] Restarting tasks ... done. [ 11.725099] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped [ 13.480846] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped [ 13.481361] smsc95xx 1-2:1.0 eth0: kevent 2 may have been dropped ... Signed-off-by: Joonyoung Shim Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 424db65e4396..d07bf4cb893f 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1714,6 +1714,18 @@ static int smsc95xx_resume(struct usb_interface *intf) return ret; } +static int smsc95xx_reset_resume(struct usb_interface *intf) +{ + struct usbnet *dev = usb_get_intfdata(intf); + int ret; + + ret = smsc95xx_reset(dev); + if (ret < 0) + return ret; + + return smsc95xx_resume(intf); +} + static void smsc95xx_rx_csum_offload(struct sk_buff *skb) { skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2); @@ -2004,7 +2016,7 @@ static struct usb_driver smsc95xx_driver = { .probe = usbnet_probe, .suspend = smsc95xx_suspend, .resume = smsc95xx_resume, - .reset_resume = smsc95xx_resume, + .reset_resume = smsc95xx_reset_resume, .disconnect = usbnet_disconnect, .disable_hub_initiated_lpm = 1, .supports_autosuspend = 1, -- cgit v1.2.3 From 948264879b6894dc389a44b99fae4f0b72932619 Mon Sep 17 00:00:00 2001 From: Todd Fujinaka Date: Thu, 10 Jul 2014 01:47:15 -0700 Subject: igb: Workaround for i210 Errata 25: Slow System Clock On some devices, the internal PLL circuit occasionally provides the wrong clock frequency after power up. The probability of failure is less than one failure per 1000 power cycles. When the failure occurs, the internal clock frequency is around 1/20 of the correct frequency. Cc: stable Signed-off-by: Todd Fujinaka Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/igb/e1000_82575.c | 7 +++ drivers/net/ethernet/intel/igb/e1000_defines.h | 18 +++---- drivers/net/ethernet/intel/igb/e1000_hw.h | 3 ++ drivers/net/ethernet/intel/igb/e1000_i210.c | 66 ++++++++++++++++++++++++++ drivers/net/ethernet/intel/igb/e1000_i210.h | 12 +++++ drivers/net/ethernet/intel/igb/e1000_regs.h | 1 + drivers/net/ethernet/intel/igb/igb_main.c | 14 ++++++ 7 files changed, 113 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index a2db388cc31e..ee74f9536b31 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1481,6 +1481,13 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw) s32 ret_val; u16 i, rar_count = mac->rar_entry_count; + if ((hw->mac.type >= e1000_i210) && + !(igb_get_flash_presence_i210(hw))) { + ret_val = igb_pll_workaround_i210(hw); + if (ret_val) + return ret_val; + } + /* Initialize identification LED */ ret_val = igb_id_led_init(hw); if (ret_val) { diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index 2a8bb35c2df2..217f8138851b 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -46,14 +46,15 @@ #define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* SDP3 Data direction */ /* Physical Func Reset Done Indication */ -#define E1000_CTRL_EXT_PFRSTD 0x00004000 -#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 -#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 -#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000 -#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000 -#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 -#define E1000_CTRL_EXT_EIAME 0x01000000 -#define E1000_CTRL_EXT_IRCA 0x00000001 +#define E1000_CTRL_EXT_PFRSTD 0x00004000 +#define E1000_CTRL_EXT_SDLPE 0X00040000 /* SerDes Low Power Enable */ +#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 +#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 +#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000 +#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000 +#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 +#define E1000_CTRL_EXT_EIAME 0x01000000 +#define E1000_CTRL_EXT_IRCA 0x00000001 /* Interrupt delay cancellation */ /* Driver loaded bit for FW */ #define E1000_CTRL_EXT_DRV_LOAD 0x10000000 @@ -62,6 +63,7 @@ /* packet buffer parity error detection enabled */ /* descriptor FIFO parity error detection enable */ #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ +#define E1000_CTRL_EXT_PHYPDEN 0x00100000 #define E1000_I2CCMD_REG_ADDR_SHIFT 16 #define E1000_I2CCMD_PHY_ADDR_SHIFT 24 #define E1000_I2CCMD_OPCODE_READ 0x08000000 diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h index 89925e405849..ce55ea5d750c 100644 --- a/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/drivers/net/ethernet/intel/igb/e1000_hw.h @@ -567,4 +567,7 @@ struct net_device *igb_get_hw_dev(struct e1000_hw *hw); /* These functions must be implemented by drivers */ s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); + +void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); +void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); #endif /* _E1000_HW_H_ */ diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c index 337161f440dd..65d931669f81 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.c +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c @@ -834,3 +834,69 @@ s32 igb_init_nvm_params_i210(struct e1000_hw *hw) } return ret_val; } + +/** + * igb_pll_workaround_i210 + * @hw: pointer to the HW structure + * + * Works around an errata in the PLL circuit where it occasionally + * provides the wrong clock frequency after power up. + **/ +s32 igb_pll_workaround_i210(struct e1000_hw *hw) +{ + s32 ret_val; + u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val; + u16 nvm_word, phy_word, pci_word, tmp_nvm; + int i; + + /* Get and set needed register values */ + wuc = rd32(E1000_WUC); + mdicnfg = rd32(E1000_MDICNFG); + reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO; + wr32(E1000_MDICNFG, reg_val); + + /* Get data from NVM, or set default */ + ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD, + &nvm_word); + if (ret_val) + nvm_word = E1000_INVM_DEFAULT_AL; + tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL; + for (i = 0; i < E1000_MAX_PLL_TRIES; i++) { + /* check current state directly from internal PHY */ + igb_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE | + E1000_PHY_PLL_FREQ_REG), &phy_word); + if ((phy_word & E1000_PHY_PLL_UNCONF) + != E1000_PHY_PLL_UNCONF) { + ret_val = 0; + break; + } else { + ret_val = -E1000_ERR_PHY; + } + /* directly reset the internal PHY */ + ctrl = rd32(E1000_CTRL); + wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST); + + ctrl_ext = rd32(E1000_CTRL_EXT); + ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE); + wr32(E1000_CTRL_EXT, ctrl_ext); + + wr32(E1000_WUC, 0); + reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16); + wr32(E1000_EEARBC_I210, reg_val); + + igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); + pci_word |= E1000_PCI_PMCSR_D3; + igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); + usleep_range(1000, 2000); + pci_word &= ~E1000_PCI_PMCSR_D3; + igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word); + reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16); + wr32(E1000_EEARBC_I210, reg_val); + + /* restore WUC register */ + wr32(E1000_WUC, wuc); + } + /* restore MDICNFG setting */ + wr32(E1000_MDICNFG, mdicnfg); + return ret_val; +} diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h index 9f34976687ba..3442b6357d01 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.h +++ b/drivers/net/ethernet/intel/igb/e1000_i210.h @@ -33,6 +33,7 @@ s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data); s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data); s32 igb_init_nvm_params_i210(struct e1000_hw *hw); bool igb_get_flash_presence_i210(struct e1000_hw *hw); +s32 igb_pll_workaround_i210(struct e1000_hw *hw); #define E1000_STM_OPCODE 0xDB00 #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 @@ -78,4 +79,15 @@ enum E1000_INVM_STRUCTURE_TYPE { #define NVM_LED_1_CFG_DEFAULT_I211 0x0184 #define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C +/* PLL Defines */ +#define E1000_PCI_PMCSR 0x44 +#define E1000_PCI_PMCSR_D3 0x03 +#define E1000_MAX_PLL_TRIES 5 +#define E1000_PHY_PLL_UNCONF 0xFF +#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000 +#define E1000_PHY_PLL_FREQ_REG 0x000E +#define E1000_INVM_DEFAULT_AL 0x202F +#define E1000_INVM_AUTOLOAD 0x0A +#define E1000_INVM_PLL_WO_VAL 0x0010 + #endif diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h index 1cc4b1a7e597..f5ba4e4eafb9 100644 --- a/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/drivers/net/ethernet/intel/igb/e1000_regs.h @@ -66,6 +66,7 @@ #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ #define E1000_PBS 0x01008 /* Packet Buffer Size */ #define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */ #define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ #define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */ #define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index f145adbb55ac..57a96e00df8c 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -7215,6 +7215,20 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) } } +void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value) +{ + struct igb_adapter *adapter = hw->back; + + pci_read_config_word(adapter->pdev, reg, value); +} + +void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value) +{ + struct igb_adapter *adapter = hw->back; + + pci_write_config_word(adapter->pdev, reg, *value); +} + s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) { struct igb_adapter *adapter = hw->back; -- cgit v1.2.3 From 0378c9a855bfa395f595fbfb049707093e270f69 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Mon, 7 Jul 2014 11:52:41 +0300 Subject: crypto: caam - fix memleak in caam_jr module This patch fixes a memory leak that appears when caam_jr module is unloaded. Cc: # 3.13+ Signed-off-by: Cristian Stoica Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 1d80bd3636c5..b512a4ba7569 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -453,8 +453,8 @@ static int caam_jr_probe(struct platform_device *pdev) int error; jrdev = &pdev->dev; - jrpriv = kmalloc(sizeof(struct caam_drv_private_jr), - GFP_KERNEL); + jrpriv = devm_kmalloc(jrdev, sizeof(struct caam_drv_private_jr), + GFP_KERNEL); if (!jrpriv) return -ENOMEM; @@ -487,10 +487,8 @@ static int caam_jr_probe(struct platform_device *pdev) /* Now do the platform independent part */ error = caam_jr_init(jrdev); /* now turn on hardware */ - if (error) { - kfree(jrpriv); + if (error) return error; - } jrpriv->dev = jrdev; spin_lock(&driver_data.jr_alloc_lock); -- cgit v1.2.3 From 76252723e88681628a3dbb9c09c963e095476f73 Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Thu, 10 Jul 2014 03:29:39 -0700 Subject: igb: do a reset on SR-IOV re-init if device is down To properly re-initialize SR-IOV it is necessary to reset the device even if it is already down. Not doing this may result in Tx unit hangs. Cc: stable Signed-off-by: Stefan Assmann Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/igb/igb_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 57a96e00df8c..a9537ba7a5a0 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -7592,6 +7592,8 @@ static int igb_sriov_reinit(struct pci_dev *dev) if (netif_running(netdev)) igb_close(netdev); + else + igb_reset(adapter); igb_clear_interrupt_scheme(adapter); -- cgit v1.2.3 From acfe0ad74d2e1bfc81d1d7bf5e15b043985d3650 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sat, 14 Jun 2014 13:44:31 -0400 Subject: dm: allocate a special workqueue for deferred device removal The commit 2c140a246dc ("dm: allow remove to be deferred") introduced a deferred removal feature for the device mapper. When this feature is used (by passing a flag DM_DEFERRED_REMOVE to DM_DEV_REMOVE_CMD ioctl) and the user tries to remove a device that is currently in use, the device will be removed automatically in the future when the last user closes it. Device mapper used the system workqueue to perform deferred removals. However, some targets (dm-raid1, dm-mpath, dm-stripe) flush work items scheduled for the system workqueue from their destructor. If the destructor itself is called from the system workqueue during deferred removal, it introduces a possible deadlock - the workqueue tries to flush itself. Fix this possible deadlock by introducing a new workqueue for deferred removals. We allocate just one workqueue for all dm targets. The ability of dm targets to process IOs isn't dependent on deferred removal of unused targets, so a deadlock due to shared workqueue isn't possible. Also, cleanup local_init() to eliminate potential for returning success on failure. Signed-off-by: Mikulas Patocka Signed-off-by: Dan Carpenter Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org # 3.13+ --- drivers/md/dm.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 437d99045ef2..32b958dbc499 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -54,6 +54,8 @@ static void do_deferred_remove(struct work_struct *w); static DECLARE_WORK(deferred_remove_work, do_deferred_remove); +static struct workqueue_struct *deferred_remove_workqueue; + /* * For bio-based dm. * One of these is allocated per bio. @@ -276,16 +278,24 @@ static int __init local_init(void) if (r) goto out_free_rq_tio_cache; + deferred_remove_workqueue = alloc_workqueue("kdmremove", WQ_UNBOUND, 1); + if (!deferred_remove_workqueue) { + r = -ENOMEM; + goto out_uevent_exit; + } + _major = major; r = register_blkdev(_major, _name); if (r < 0) - goto out_uevent_exit; + goto out_free_workqueue; if (!_major) _major = r; return 0; +out_free_workqueue: + destroy_workqueue(deferred_remove_workqueue); out_uevent_exit: dm_uevent_exit(); out_free_rq_tio_cache: @@ -299,6 +309,7 @@ out_free_io_cache: static void local_exit(void) { flush_scheduled_work(); + destroy_workqueue(deferred_remove_workqueue); kmem_cache_destroy(_rq_tio_cache); kmem_cache_destroy(_io_cache); @@ -407,7 +418,7 @@ static void dm_blk_close(struct gendisk *disk, fmode_t mode) if (atomic_dec_and_test(&md->open_count) && (test_bit(DMF_DEFERRED_REMOVE, &md->flags))) - schedule_work(&deferred_remove_work); + queue_work(deferred_remove_workqueue, &deferred_remove_work); dm_put(md); -- cgit v1.2.3 From bf14299f1ce96c9d632533c4557303f8a74afc9e Mon Sep 17 00:00:00 2001 From: Jana Saout Date: Tue, 24 Jun 2014 14:27:04 -0400 Subject: dm crypt, dm zero: update author name following legal name change Signed-off-by: Jana Saout Signed-off-by: Mike Snitzer --- drivers/md/dm-crypt.c | 4 ++-- drivers/md/dm-zero.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 53b213226c01..4cba2d808afb 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Christophe Saout + * Copyright (C) 2003 Jana Saout * Copyright (C) 2004 Clemens Fruhwirth * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. * Copyright (C) 2013 Milan Broz @@ -1996,6 +1996,6 @@ static void __exit dm_crypt_exit(void) module_init(dm_crypt_init); module_exit(dm_crypt_exit); -MODULE_AUTHOR("Christophe Saout "); +MODULE_AUTHOR("Jana Saout "); MODULE_DESCRIPTION(DM_NAME " target for transparent encryption / decryption"); MODULE_LICENSE("GPL"); diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c index c99003e0d47a..b9a64bbce304 100644 --- a/drivers/md/dm-zero.c +++ b/drivers/md/dm-zero.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Christophe Saout + * Copyright (C) 2003 Jana Saout * * This file is released under the GPL. */ @@ -79,6 +79,6 @@ static void __exit dm_zero_exit(void) module_init(dm_zero_init) module_exit(dm_zero_exit) -MODULE_AUTHOR("Christophe Saout "); +MODULE_AUTHOR("Jana Saout "); MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 10f1d5d111e8aed46a0f1179faf9a3cf422f689e Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 27 Jun 2014 15:29:04 -0400 Subject: dm io: fix a race condition in the wake up code for sync_io There's a race condition between the atomic_dec_and_test(&io->count) in dec_count() and the waking of the sync_io() thread. If the thread is spuriously woken immediately after the decrement it may exit, making the on stack io struct invalid, yet the dec_count could still be using it. Fix this race by using a completion in sync_io() and dec_count(). Reported-by: Minfei Huang Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Acked-by: Mikulas Patocka Cc: stable@vger.kernel.org --- drivers/md/dm-io.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 3842ac738f98..db404a0f7e2c 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -32,7 +33,7 @@ struct dm_io_client { struct io { unsigned long error_bits; atomic_t count; - struct task_struct *sleeper; + struct completion *wait; struct dm_io_client *client; io_notify_fn callback; void *context; @@ -121,8 +122,8 @@ static void dec_count(struct io *io, unsigned int region, int error) invalidate_kernel_vmap_range(io->vma_invalidate_address, io->vma_invalidate_size); - if (io->sleeper) - wake_up_process(io->sleeper); + if (io->wait) + complete(io->wait); else { unsigned long r = io->error_bits; @@ -387,6 +388,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, */ volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1]; struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io)); + DECLARE_COMPLETION_ONSTACK(wait); if (num_regions > 1 && (rw & RW_MASK) != WRITE) { WARN_ON(1); @@ -395,7 +397,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, io->error_bits = 0; atomic_set(&io->count, 1); /* see dispatch_io() */ - io->sleeper = current; + io->wait = &wait; io->client = client; io->vma_invalidate_address = dp->vma_invalidate_address; @@ -403,15 +405,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, dispatch_io(rw, num_regions, where, dp, io, 1); - while (1) { - set_current_state(TASK_UNINTERRUPTIBLE); - - if (!atomic_read(&io->count)) - break; - - io_schedule(); - } - set_current_state(TASK_RUNNING); + wait_for_completion_io(&wait); if (error_bits) *error_bits = io->error_bits; @@ -434,7 +428,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, io = mempool_alloc(client->pool, GFP_NOIO); io->error_bits = 0; atomic_set(&io->count, 1); /* see dispatch_io() */ - io->sleeper = NULL; + io->wait = NULL; io->client = client; io->callback = fn; io->context = context; -- cgit v1.2.3 From 7a7a3b45fed9a144dbf766ee842a4c5d0632b81d Mon Sep 17 00:00:00 2001 From: Jun'ichi Nomura Date: Tue, 8 Jul 2014 00:55:14 +0000 Subject: dm mpath: fix IO hang due to logic bug in multipath_busy Commit e80991773 ("dm mpath: push back requests instead of queueing") modified multipath_busy() to return true if !pg_ready(). pg_ready() checks the current state of the multipath device and may return false even if a new IO is needed to change the state. Bart Van Assche reported that he had multipath IO lockup when he was performing cable pull tests. Analysis showed that the multipath device had a single path group with both paths active, but that the path group itself was not active. During the multipath device state transitions 'queue_io' got set but nothing could clear it. Clearing 'queue_io' only happens in __choose_pgpath(), but it won't be called if multipath_busy() returns true due to pg_ready() returning false when 'queue_io' is set. As such the !pg_ready() check in multipath_busy() is wrong because new IO will not be sent to multipath target and the multipath state change won't happen. That results in multipath IO lockup. The intent of multipath_busy() is to avoid unnecessary cycles of dequeue + request_fn + requeue if it is known that the multipath device will requeue. Such "busy" situations would be: - path group is being activated - there is no path and the multipath is setup to requeue if no path Fix multipath_busy() to return "busy" early only for these specific situations. Reported-by: Bart Van Assche Tested-by: Bart Van Assche Signed-off-by: Jun'ichi Nomura Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org # v3.15 --- drivers/md/dm-mpath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 3f6fd9d33ba3..f4167b013d99 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1611,8 +1611,9 @@ static int multipath_busy(struct dm_target *ti) spin_lock_irqsave(&m->lock, flags); - /* pg_init in progress, requeue until done */ - if (!pg_ready(m)) { + /* pg_init in progress or no paths available */ + if (m->pg_init_in_progress || + (!m->nr_valid_paths && m->queue_if_no_path)) { busy = 1; goto out; } -- cgit v1.2.3 From f6be5e64500abbba44e191e1ca0f3366c7d0291b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 3 Jul 2014 11:17:55 -0400 Subject: drm/radeon/dp: return -EIO for flags not zero case If there are error flags in the aux transaction return -EIO rather than -EBUSY. -EIO restarts the whole transaction while -EBUSY jus retries. Fixes problematic aux transfers. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=80684 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/atombios_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 35f4182c63b6..b1e11f8434e2 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -127,7 +127,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, /* flags not zero */ if (args.v1.ucReplyStatus == 2) { DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); - r = -EBUSY; + r = -EIO; goto done; } -- cgit v1.2.3 From 9b7d786b900baf7c0d1a7e211570aef1cb27590f Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 7 Jul 2014 11:16:29 +0200 Subject: drm/radeon: only print meaningful VM faults Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 6 ++++-- drivers/gpu/drm/radeon/evergreen.c | 6 ++++-- drivers/gpu/drm/radeon/si.c | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index dcd4518a9b08..0b2471107137 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -7676,14 +7676,16 @@ restart_ih: addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); + /* reset addr and status */ + WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); + if (addr == 0x0 && status == 0x0) + break; dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", addr); dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", status); cik_vm_decode_fault(rdev, status, addr, mc_client); - /* reset addr and status */ - WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); break; case 167: /* VCE */ DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e2f605224e8c..d5d4d3a86731 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -5066,14 +5066,16 @@ restart_ih: case 147: addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); + /* reset addr and status */ + WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); + if (addr == 0x0 && status == 0x0) + break; dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", addr); dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", status); cayman_vm_decode_fault(rdev, status, addr); - /* reset addr and status */ - WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); break; case 176: /* CP_INT in ring buffer */ case 177: /* CP_INT in IB1 */ diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 730cee2c34cf..eba0225259a4 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6376,14 +6376,16 @@ restart_ih: case 147: addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); + /* reset addr and status */ + WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); + if (addr == 0x0 && status == 0x0) + break; dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", addr); dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", status); si_vm_decode_fault(rdev, status, addr); - /* reset addr and status */ - WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); break; case 176: /* RINGID0 CP_INT */ radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); -- cgit v1.2.3 From 6abafb78f9881b4891baf74ab4e9f090ae45230e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 7 Jul 2014 17:59:37 -0400 Subject: drm/radeon: fix typo in golden register setup on evergreen Fixes hangs on driver load on some cards. bug: https://bugs.freedesktop.org/show_bug.cgi?id=76998 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/evergreen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d5d4d3a86731..f7ece0ff431b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -189,7 +189,7 @@ static const u32 evergreen_golden_registers[] = 0x8c1c, 0xffffffff, 0x00001010, 0x28350, 0xffffffff, 0x00000000, 0xa008, 0xffffffff, 0x00010000, - 0x5cc, 0xffffffff, 0x00000001, + 0x5c4, 0xffffffff, 0x00000001, 0x9508, 0xffffffff, 0x00000002, 0x913c, 0x0000000f, 0x0000000a }; @@ -476,7 +476,7 @@ static const u32 cedar_golden_registers[] = 0x8c1c, 0xffffffff, 0x00001010, 0x28350, 0xffffffff, 0x00000000, 0xa008, 0xffffffff, 0x00010000, - 0x5cc, 0xffffffff, 0x00000001, + 0x5c4, 0xffffffff, 0x00000001, 0x9508, 0xffffffff, 0x00000002 }; @@ -635,7 +635,7 @@ static const u32 juniper_mgcg_init[] = static const u32 supersumo_golden_registers[] = { 0x5eb4, 0xffffffff, 0x00000002, - 0x5cc, 0xffffffff, 0x00000001, + 0x5c4, 0xffffffff, 0x00000001, 0x7030, 0xffffffff, 0x00000011, 0x7c30, 0xffffffff, 0x00000011, 0x6104, 0x01000300, 0x00000000, @@ -719,7 +719,7 @@ static const u32 sumo_golden_registers[] = static const u32 wrestler_golden_registers[] = { 0x5eb4, 0xffffffff, 0x00000002, - 0x5cc, 0xffffffff, 0x00000001, + 0x5c4, 0xffffffff, 0x00000001, 0x7030, 0xffffffff, 0x00000011, 0x7c30, 0xffffffff, 0x00000011, 0x6104, 0x01000300, 0x00000000, -- cgit v1.2.3 From ed96377132e564d797c48a5490fd46bed01c4273 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 8 Jul 2014 18:25:25 -0400 Subject: drm/radeon: fix typo in ci_stop_dpm() Need to use the RREG32_SMC() accessor since the register is an smc indirect index. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ci_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 10dae4106c08..584090ac3eb9 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -1179,7 +1179,7 @@ static int ci_stop_dpm(struct radeon_device *rdev) tmp &= ~GLOBAL_PWRMGT_EN; WREG32_SMC(GENERAL_PWRMGT, tmp); - tmp = RREG32(SCLK_PWRMGT_CNTL); + tmp = RREG32_SMC(SCLK_PWRMGT_CNTL); tmp &= ~DYNAMIC_PM_EN; WREG32_SMC(SCLK_PWRMGT_CNTL, tmp); -- cgit v1.2.3 From 41959341ac7e33dd360c7a881d13566f9eca37b2 Mon Sep 17 00:00:00 2001 From: Alexandre Demers Date: Tue, 8 Jul 2014 22:27:36 -0400 Subject: drm/radeon/dpm: Reenabling SS on Cayman It reverts commit c745fe611ca42295c9d91d8e305d27983e9132ef now that Cayman is stable since VDDCI fix. Spread spectrum was not the culprit. This depends on b0880e87c1fd038b84498944f52e52c3e86ebe59 (drm/radeon/dpm: fix vddci setup typo on cayman). Signed-off-by: Alexandre Demers Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/rv770_dpm.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index da041a43d82e..3c76e1dcdf04 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -2329,12 +2329,6 @@ void rv770_get_engine_memory_ss(struct radeon_device *rdev) pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, ASIC_INTERNAL_MEMORY_SS, 0); - /* disable ss, causes hangs on some cayman boards */ - if (rdev->family == CHIP_CAYMAN) { - pi->sclk_ss = false; - pi->mclk_ss = false; - } - if (pi->sclk_ss || pi->mclk_ss) pi->dynamic_ss = true; else -- cgit v1.2.3 From c0fb262bf226a5c943e4309662353d5fb905310a Mon Sep 17 00:00:00 2001 From: Arun Kumar K Date: Fri, 11 Jul 2014 08:03:59 +0900 Subject: clk: exynos5420: Add IDs for clocks used in PD mfc Adds IDs for MUX clocks to be used by power domain for MFC for doing re-parenting while pd on/off. Signed-off-by: Arun Kumar K Signed-off-by: Shaik Ameer Basha Acked-by: Tomasz Figa Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos5420.c | 6 ++++-- include/dt-bindings/clock/exynos5420.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9d7d7eed03fd..f74f882f7f29 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -631,7 +631,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = { SRC_TOP4, 16, 1), MUX(0, "mout_user_aclk266", mout_user_aclk266_p, SRC_TOP4, 20, 1), MUX(0, "mout_user_aclk166", mout_user_aclk166_p, SRC_TOP4, 24, 1), - MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1), + MUX(CLK_MOUT_USER_ACLK333, "mout_user_aclk333", mout_user_aclk333_p, + SRC_TOP4, 28, 1), MUX(0, "mout_user_aclk400_disp1", mout_user_aclk400_disp1_p, SRC_TOP5, 0, 1), @@ -684,7 +685,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = { SRC_TOP11, 12, 1), MUX(0, "mout_sw_aclk266", mout_sw_aclk266_p, SRC_TOP11, 20, 1), MUX(0, "mout_sw_aclk166", mout_sw_aclk166_p, SRC_TOP11, 24, 1), - MUX(0, "mout_sw_aclk333", mout_sw_aclk333_p, SRC_TOP11, 28, 1), + MUX(CLK_MOUT_SW_ACLK333, "mout_sw_aclk333", mout_sw_aclk333_p, + SRC_TOP11, 28, 1), MUX(0, "mout_sw_aclk400_disp1", mout_sw_aclk400_disp1_p, SRC_TOP12, 4, 1), diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h index 97dcb89d37d3..3fc08ff24fa9 100644 --- a/include/dt-bindings/clock/exynos5420.h +++ b/include/dt-bindings/clock/exynos5420.h @@ -203,6 +203,8 @@ #define CLK_MOUT_G3D 641 #define CLK_MOUT_VPLL 642 #define CLK_MOUT_MAUDIO0 643 +#define CLK_MOUT_USER_ACLK333 644 +#define CLK_MOUT_SW_ACLK333 645 /* divider clocks */ #define CLK_DOUT_PIXEL 768 -- cgit v1.2.3 From c557d392fbf5badd693ea1946a4317c87a26a716 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 6 Jul 2014 11:29:52 -0400 Subject: serial: Test for no tx data on tx restart Commit 717f3bbab3c7628736ef738fdbf3d9a28578c26c, 'serial_core: Fix conditional start_tx on ring buffer not empty' exposes an incorrect assumption in several drivers' start_tx methods; the tx ring buffer can, in fact, be empty when restarting tx while performing flow control. Affected drivers: sunsab.c ip22zilog.c pmac_zilog.c sunzilog.c m32r_sio.c imx.c Other in-tree serial drivers either are not affected or already test for empty tx ring buffer before transmitting. Test for empty tx ring buffer in start_tx() method, after transmitting x_char (if applicable). Reported-by: Aaro Koskinen Cc: Seth Bollinger Cc: "David S. Miller" Cc: Sam Ravnborg Cc: Thomas Bogendoerfer Signed-off-by: Peter Hurley Cc: stable # 3.15 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 3 +++ drivers/tty/serial/ip22zilog.c | 2 ++ drivers/tty/serial/m32r_sio.c | 8 +++++--- drivers/tty/serial/pmac_zilog.c | 3 +++ drivers/tty/serial/sunsab.c | 3 +++ drivers/tty/serial/sunzilog.c | 2 ++ 6 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index e2f93874989b..56bd9aa56151 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -567,6 +567,9 @@ static void imx_start_tx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; + if (uart_circ_empty(&port.state->xmit)) + return; + if (USE_IRDA(sport)) { /* half duplex in IrDA mode; have to disable receive mode */ temp = readl(sport->port.membase + UCR4); diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 1efd4c36ba0c..99b7b8697861 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -603,6 +603,8 @@ static void ip22zilog_start_tx(struct uart_port *port) } else { struct circ_buf *xmit = &port->state->xmit; + if (uart_circ_empty(xmit)) + return; writeb(xmit->buf[xmit->tail], &channel->data); ZSDELAY(); ZS_WSYNC(channel); diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 68f2c53e0b54..5702828fb62e 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -266,9 +266,11 @@ static void m32r_sio_start_tx(struct uart_port *port) if (!(up->ier & UART_IER_THRI)) { up->ier |= UART_IER_THRI; serial_out(up, UART_IER, up->ier); - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; + if (!uart_circ_empty(xmit)) { + serial_out(up, UART_TX, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + up->port.icount.tx++; + } } while((serial_in(up, UART_LSR) & UART_EMPTY) != UART_EMPTY); #else diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 8193635103ee..f7ad5b903055 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -653,6 +653,8 @@ static void pmz_start_tx(struct uart_port *port) } else { struct circ_buf *xmit = &port->state->xmit; + if (uart_circ_empty(xmit)) + goto out; write_zsdata(uap, xmit->buf[xmit->tail]); zssync(uap); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); @@ -661,6 +663,7 @@ static void pmz_start_tx(struct uart_port *port) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); } + out: pmz_debug("pmz: start_tx() done.\n"); } diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 80a58eca785b..2f57df9a71d9 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -427,6 +427,9 @@ static void sunsab_start_tx(struct uart_port *port) struct circ_buf *xmit = &up->port.state->xmit; int i; + if (uart_circ_empty(xmit)) + return; + up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); writeb(up->interrupt_mask1, &up->regs->w.imr1); diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index a85db8b87156..02df3940b95e 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -703,6 +703,8 @@ static void sunzilog_start_tx(struct uart_port *port) } else { struct circ_buf *xmit = &port->state->xmit; + if (uart_circ_empty(xmit)) + return; writeb(xmit->buf[xmit->tail], &channel->data); ZSDELAY(); ZS_WSYNC(channel); -- cgit v1.2.3 From 99ecb001f52ef10ebf686d4e55b1cf64b1e56aa6 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 6 Jul 2014 11:29:53 -0400 Subject: serial: arc_uart: Use uart_circ_empty() for open-coded comparison Replace open-coded test for empty tx ring buffer with equivalent helper function, uart_circ_empty(). No functional change. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/arc_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index c9f5c9dcc15c..008c223eaf26 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -177,7 +177,7 @@ static void arc_serial_tx_chars(struct arc_uart_port *uart) uart->port.icount.tx++; uart->port.x_char = 0; sent = 1; - } else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */ + } else if (!uart_circ_empty(xmit)) { ch = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); uart->port.icount.tx++; -- cgit v1.2.3 From 19eeb2f9e750f47c805f66e3b0e889b12557d80f Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Thu, 10 Jul 2014 18:43:01 -0400 Subject: farsync: fix invalid memory accesses in fst_add_one() and fst_init_card() There are several issues in fst_add_one() and fst_init_card(): - invalid pointer dereference at card->ports[card->nports - 1] if register_hdlc_device() fails for the first port in fst_init_card(); - fst_card_array overflow at fst_card_array[no_of_cards_added] because there is no checks for array overflow; - use after free because pointer to deallocated card is left in fst_card_array if something fails after fst_card_array[no_of_cards_added] = card; - several leaks on failure paths in fst_add_one(). The patch fixes all the issues and makes code more readable. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: David S. Miller --- drivers/net/wan/farsync.c | 112 ++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 93ace042d0aa..1f041271f7fe 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2363,7 +2363,7 @@ static char *type_strings[] = { "FarSync TE1" }; -static void +static int fst_init_card(struct fst_card_info *card) { int i; @@ -2374,24 +2374,21 @@ fst_init_card(struct fst_card_info *card) * we'll have to revise it in some way then. */ for (i = 0; i < card->nports; i++) { - err = register_hdlc_device(card->ports[i].dev); - if (err < 0) { - int j; + err = register_hdlc_device(card->ports[i].dev); + if (err < 0) { pr_err("Cannot register HDLC device for port %d (errno %d)\n", - i, -err); - for (j = i; j < card->nports; j++) { - free_netdev(card->ports[j].dev); - card->ports[j].dev = NULL; - } - card->nports = i; - break; - } + i, -err); + while (i--) + unregister_hdlc_device(card->ports[i].dev); + return err; + } } pr_info("%s-%s: %s IRQ%d, %d ports\n", port_to_dev(&card->ports[0])->name, port_to_dev(&card->ports[card->nports - 1])->name, type_strings[card->type], card->irq, card->nports); + return 0; } static const struct net_device_ops fst_ops = { @@ -2447,15 +2444,12 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* Try to enable the device */ if ((err = pci_enable_device(pdev)) != 0) { pr_err("Failed to enable card. Err %d\n", -err); - kfree(card); - return err; + goto enable_fail; } if ((err = pci_request_regions(pdev, "FarSync")) !=0) { pr_err("Failed to allocate regions. Err %d\n", -err); - pci_disable_device(pdev); - kfree(card); - return err; + goto regions_fail; } /* Get virtual addresses of memory regions */ @@ -2464,30 +2458,21 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) card->phys_ctlmem = pci_resource_start(pdev, 3); if ((card->mem = ioremap(card->phys_mem, FST_MEMSIZE)) == NULL) { pr_err("Physical memory remap failed\n"); - pci_release_regions(pdev); - pci_disable_device(pdev); - kfree(card); - return -ENODEV; + err = -ENODEV; + goto ioremap_physmem_fail; } if ((card->ctlmem = ioremap(card->phys_ctlmem, 0x10)) == NULL) { pr_err("Control memory remap failed\n"); - pci_release_regions(pdev); - pci_disable_device(pdev); - iounmap(card->mem); - kfree(card); - return -ENODEV; + err = -ENODEV; + goto ioremap_ctlmem_fail; } dbg(DBG_PCI, "kernel mem %p, ctlmem %p\n", card->mem, card->ctlmem); /* Register the interrupt handler */ if (request_irq(pdev->irq, fst_intr, IRQF_SHARED, FST_DEV_NAME, card)) { pr_err("Unable to register interrupt %d\n", card->irq); - pci_release_regions(pdev); - pci_disable_device(pdev); - iounmap(card->ctlmem); - iounmap(card->mem); - kfree(card); - return -ENODEV; + err = -ENODEV; + goto irq_fail; } /* Record info we need */ @@ -2513,13 +2498,8 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) while (i--) free_netdev(card->ports[i].dev); pr_err("FarSync: out of memory\n"); - free_irq(card->irq, card); - pci_release_regions(pdev); - pci_disable_device(pdev); - iounmap(card->ctlmem); - iounmap(card->mem); - kfree(card); - return -ENODEV; + err = -ENOMEM; + goto hdlcdev_fail; } card->ports[i].dev = dev; card->ports[i].card = card; @@ -2565,9 +2545,16 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, card); /* Remainder of card setup */ + if (no_of_cards_added >= FST_MAX_CARDS) { + pr_err("FarSync: too many cards\n"); + err = -ENOMEM; + goto card_array_fail; + } fst_card_array[no_of_cards_added] = card; card->card_no = no_of_cards_added++; /* Record instance and bump it */ - fst_init_card(card); + err = fst_init_card(card); + if (err) + goto init_card_fail; if (card->family == FST_FAMILY_TXU) { /* * Allocate a dma buffer for transmit and receives @@ -2577,29 +2564,46 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) &card->rx_dma_handle_card); if (card->rx_dma_handle_host == NULL) { pr_err("Could not allocate rx dma buffer\n"); - fst_disable_intr(card); - pci_release_regions(pdev); - pci_disable_device(pdev); - iounmap(card->ctlmem); - iounmap(card->mem); - kfree(card); - return -ENOMEM; + err = -ENOMEM; + goto rx_dma_fail; } card->tx_dma_handle_host = pci_alloc_consistent(card->device, FST_MAX_MTU, &card->tx_dma_handle_card); if (card->tx_dma_handle_host == NULL) { pr_err("Could not allocate tx dma buffer\n"); - fst_disable_intr(card); - pci_release_regions(pdev); - pci_disable_device(pdev); - iounmap(card->ctlmem); - iounmap(card->mem); - kfree(card); - return -ENOMEM; + err = -ENOMEM; + goto tx_dma_fail; } } return 0; /* Success */ + +tx_dma_fail: + pci_free_consistent(card->device, FST_MAX_MTU, + card->rx_dma_handle_host, + card->rx_dma_handle_card); +rx_dma_fail: + fst_disable_intr(card); + for (i = 0 ; i < card->nports ; i++) + unregister_hdlc_device(card->ports[i].dev); +init_card_fail: + fst_card_array[card->card_no] = NULL; +card_array_fail: + for (i = 0 ; i < card->nports ; i++) + free_netdev(card->ports[i].dev); +hdlcdev_fail: + free_irq(card->irq, card); +irq_fail: + iounmap(card->ctlmem); +ioremap_ctlmem_fail: + iounmap(card->mem); +ioremap_physmem_fail: + pci_release_regions(pdev); +regions_fail: + pci_disable_device(pdev); +enable_fail: + kfree(card); + return err; } /* -- cgit v1.2.3 From 4cad9f3b61c7268fa89ab8096e23202300399b5d Mon Sep 17 00:00:00 2001 From: Suresh Reddy Date: Fri, 11 Jul 2014 14:03:01 +0530 Subject: be2net: set EQ DB clear-intr bit in be_open() On BE3, if the clear-interrupt bit of the EQ doorbell is not set the first time it is armed, ocassionally we have observed that the EQ doesn't raise anymore interrupts even if it is in armed state. This patch fixes this by setting the clear-interrupt bit when EQs are armed for the first time in be_open(). Signed-off-by: Suresh Reddy Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 34a26e42f19d..1e187fb760f8 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2902,7 +2902,7 @@ static int be_open(struct net_device *netdev) for_all_evt_queues(adapter, eqo, i) { napi_enable(&eqo->napi); be_enable_busy_poll(eqo); - be_eq_notify(adapter, eqo->q.id, true, false, 0); + be_eq_notify(adapter, eqo->q.id, true, true, 0); } adapter->flags |= BE_FLAGS_NAPI_ENABLED; -- cgit v1.2.3 From a91d45f1a343188793d6f2bdf1a72c64015a8255 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Fri, 11 Jul 2014 16:48:27 +0800 Subject: r8152: fix r8152_csum_workaround function The transport offset of the IPv4 packet should be fixed and wouldn't be out of the hw limitation, so the r8152_csum_workaround() should be used for IPv6 packets. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index a795ecf8d5b6..7bad2d316637 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1359,7 +1359,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, struct sk_buff_head seg_list; struct sk_buff *segs, *nskb; - features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO); + features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6); segs = skb_gso_segment(skb, features); if (IS_ERR(segs) || !segs) goto drop; -- cgit v1.2.3 From 8bec751bd63847b4044aab8b215db52aa6abde61 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Thu, 10 Jul 2014 22:36:46 -0400 Subject: serial: imx: Fix build breakage Fix breakage introduced by commit c557d392fbf5badd693ea1946a4317c87a26a716, 'serial: Test for no tx data on tx restart'. Reported-by: Stephen Rothwell Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 56bd9aa56151..044e86d528ae 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -567,7 +567,7 @@ static void imx_start_tx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; - if (uart_circ_empty(&port.state->xmit)) + if (uart_circ_empty(&port->state->xmit)) return; if (USE_IRDA(sport)) { -- cgit v1.2.3 From d8279a40e50ad55539780aa617a32a53d7f0953e Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Thu, 10 Jul 2014 14:00:34 +0200 Subject: USB: serial: ftdi_sio: Add Infineon Triboard This adds support for Infineon TriBoard TC1798 [1]. Only interface 1 is used as serial line (see [2], Figure 8-6). [1] http://www.infineon.com/cms/de/product/microcontroller/development-tools-software-and-kits/tricore-tm-development-tools-software-and-kits/starterkits-and-evaluation-boards/starter-kit-tc1798/channel.html?channel=db3a304333b8a7ca0133cfa3d73e4268 [2] http://www.infineon.com/dgdl/TriBoardManual-TC1798-V10.pdf?folderId=db3a304412b407950112b409ae7c0343&fileId=db3a304333b8a7ca0133cfae99fe426a Signed-off-by: Michal Sojka Cc: Johan Hovold Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bf2e30a6824a..8a3813be1b28 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -945,6 +945,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, + /* Infineon Devices */ + { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 106cc16cc6ed..c4777bc6aee0 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -583,6 +583,12 @@ #define RATOC_VENDOR_ID 0x0584 #define RATOC_PRODUCT_ID_USB60F 0xb020 +/* + * Infineon Technologies + */ +#define INFINEON_VID 0x058b +#define INFINEON_TRIBOARD_PID 0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */ + /* * Acton Research Corp. */ -- cgit v1.2.3 From 9820ccba4b1e9c0cdacf254a7be8616357086ebc Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 10 Jul 2014 11:54:59 +0530 Subject: phy: sun4i: depend on RESET_CONTROLLER The driver depend on the reset framework in a mandatory way. Make sure reset_control_get is defined by adding this dependency in Kconfig Signed-off-by: Maxime Ripard Reported-by: Arnd Bergmann Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 16a2f067c242..1d8099a56a91 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -112,6 +112,7 @@ config PHY_EXYNOS5250_SATA config PHY_SUN4I_USB tristate "Allwinner sunxi SoC USB PHY driver" depends on ARCH_SUNXI && HAS_IOMEM && OF + depends on RESET_CONTROLLER select GENERIC_PHY help Enable this to support the transceiver that is part of Allwinner -- cgit v1.2.3 From 3df9fcd59fd829da046ca63518ad8e51482a39e0 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Thu, 10 Jul 2014 11:55:00 +0530 Subject: phy: omap-usb2: fix devm_ioremap_resource error detection code devm_ioremap_resource returns an ERR_PTR value, not NULL, on failure. A simplified version of the semantic match that finds this problem is as follows: // @@ expression e,e1; statement S; @@ *e = devm_ioremap_resource(...); if (!e1) S // Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/phy-omap-usb2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 7007c11fe07d..2063d542b4e4 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -233,8 +233,8 @@ static int omap_usb2_probe(struct platform_device *pdev) if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); phy->phy_base = devm_ioremap_resource(&pdev->dev, res); - if (!phy->phy_base) - return -ENOMEM; + if (IS_ERR(phy->phy_base)) + return PTR_ERR(phy->phy_base); phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; } -- cgit v1.2.3 From bf5baf954a8249ad565862faa98accb19f3ab957 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Thu, 10 Jul 2014 11:55:01 +0530 Subject: drivers: phy: phy-samsung-usb2.c: Add missing MODULE_DEVICE_TABLE Allow phy-exynos-usb2 to be autoloaded based on devicetree information. Tested on Odroid X2 with its USB subsystem build as modules. Signed-off-by: Sjoerd Simons Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/phy-samsung-usb2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c index 8a8c6bc8709a..1e69a32c221d 100644 --- a/drivers/phy/phy-samsung-usb2.c +++ b/drivers/phy/phy-samsung-usb2.c @@ -107,6 +107,7 @@ static const struct of_device_id samsung_usb2_phy_of_match[] = { #endif { }, }; +MODULE_DEVICE_TABLE(of, samsung_usb2_phy_of_match); static int samsung_usb2_phy_probe(struct platform_device *pdev) { -- cgit v1.2.3 From e73b49f1c4e75c44d62585cc3e5b9c7894b61c32 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Jul 2014 11:55:02 +0530 Subject: phy: core: Fix error path in phy_create() Prevent resources from being freed twice in case device_add() call fails within phy_create(). Also use ida_simple_remove() instead of ida_remove() as we had used ida_simple_get() to allocate the ida. Cc: 3.13+ # 3.13+ Signed-off-by: Roger Quadros Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/phy-core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index c64a2f3b2d62..49c446530101 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -614,8 +614,9 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops, return phy; put_dev: - put_device(&phy->dev); - ida_remove(&phy_ida, phy->id); + put_device(&phy->dev); /* calls phy_release() which frees resources */ + return ERR_PTR(ret); + free_phy: kfree(phy); return ERR_PTR(ret); @@ -799,7 +800,7 @@ static void phy_release(struct device *dev) phy = to_phy(dev); dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); - ida_remove(&phy_ida, phy->id); + ida_simple_remove(&phy_ida, phy->id); kfree(phy); } -- cgit v1.2.3 From eb82a3d846fab00c4b9ad6bbe5ade4fa5febc0af Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Jul 2014 11:55:03 +0530 Subject: phy: omap-usb2: Balance pm_runtime_enable() on probe failure and remove If probe fails then we need to call pm_runtime_disable() to balance out the previous pm_runtime_enable() call. Else it will cause unbalanced pm_runtime_enable() call in the succeding probe call. This anomaly was observed when the call to devm_phy_create() failed with -EPROBE_DEFER. Balance out the pm_runtime_enable() call in .remove() as well. Signed-off-by: Roger Quadros Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/phy-omap-usb2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 2063d542b4e4..34b396146c8a 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -262,7 +262,6 @@ static int omap_usb2_probe(struct platform_device *pdev) otg->phy = &phy->phy; platform_set_drvdata(pdev, phy); - pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, &ops, NULL); if (IS_ERR(generic_phy)) @@ -270,10 +269,13 @@ static int omap_usb2_probe(struct platform_device *pdev) phy_set_drvdata(generic_phy, phy); + pm_runtime_enable(phy->dev); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) + if (IS_ERR(phy_provider)) { + pm_runtime_disable(phy->dev); return PTR_ERR(phy_provider); + } phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); if (IS_ERR(phy->wkupclk)) { @@ -317,6 +319,7 @@ static int omap_usb2_remove(struct platform_device *pdev) if (!IS_ERR(phy->optclk)) clk_unprepare(phy->optclk); usb_remove_phy(&phy->phy); + pm_runtime_disable(phy->dev); return 0; } -- cgit v1.2.3 From 15ebb05248d025534773c9ef64915bd888f04e4b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 19 Jun 2014 21:52:23 +0000 Subject: clk: spear3xx: Use proper control register offset The control register is at offset 0x10, not 0x0. This is wreckaged since commit 5df33a62c (SPEAr: Switch to common clock framework). Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Acked-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear3xx_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index c2d204315546..125eba86c844 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -211,7 +211,7 @@ static inline void spear310_clk_init(void) { } /* array of all spear 320 clock lookups */ #ifdef CONFIG_MACH_SPEAR320 -#define SPEAR320_CONTROL_REG (soc_config_base + 0x0000) +#define SPEAR320_CONTROL_REG (soc_config_base + 0x0010) #define SPEAR320_EXT_CTRL_REG (soc_config_base + 0x0018) #define SPEAR320_UARTX_PCLK_MASK 0x1 -- cgit v1.2.3 From 449437778bd09b73a5e51554f7219706da08917f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 19 Jun 2014 21:52:24 +0000 Subject: clk: spear3xx: Set proper clock parent of uart1/2 The uarts only work when the parent is ras_ahb_clk. The stale 3.5 based ST tree does this in the board file. Add it to the clk init function. Not pretty, but the mess there is amazing anyway. Signed-off-by: Thomas Gleixner Acked-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear3xx_clock.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 125eba86c844..bb5f387774e2 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -245,7 +245,8 @@ static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk", "ras_syn0_gclk", }; static const char *uartx_parents[] = { "ras_syn1_gclk", "ras_apb_clk", }; -static void __init spear320_clk_init(void __iomem *soc_config_base) +static void __init spear320_clk_init(void __iomem *soc_config_base, + struct clk *ras_apb_clk) { struct clk *clk; @@ -342,6 +343,8 @@ static void __init spear320_clk_init(void __iomem *soc_config_base) SPEAR320_CONTROL_REG, UART1_PCLK_SHIFT, UART1_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a3000000.serial"); + /* Enforce ras_apb_clk */ + clk_set_parent(clk, ras_apb_clk); clk = clk_register_mux(NULL, "uart2_clk", uartx_parents, ARRAY_SIZE(uartx_parents), @@ -349,6 +352,8 @@ static void __init spear320_clk_init(void __iomem *soc_config_base) SPEAR320_EXT_CTRL_REG, SPEAR320_UART2_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a4000000.serial"); + /* Enforce ras_apb_clk */ + clk_set_parent(clk, ras_apb_clk); clk = clk_register_mux(NULL, "uart3_clk", uartx_parents, ARRAY_SIZE(uartx_parents), @@ -379,12 +384,12 @@ static void __init spear320_clk_init(void __iomem *soc_config_base) clk_register_clkdev(clk, NULL, "60100000.serial"); } #else -static inline void spear320_clk_init(void __iomem *soc_config_base) { } +static inline void spear320_clk_init(void __iomem *sb, struct clk *rc) { } #endif void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_base) { - struct clk *clk, *clk1; + struct clk *clk, *clk1, *ras_apb_clk; clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); @@ -613,6 +618,7 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_ clk = clk_register_gate(NULL, "ras_apb_clk", "apb_clk", 0, RAS_CLK_ENB, RAS_APB_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_apb_clk", NULL); + ras_apb_clk = clk; clk = clk_register_gate(NULL, "ras_32k_clk", "osc_32k_clk", 0, RAS_CLK_ENB, RAS_32K_CLK_ENB, 0, &_lock); @@ -659,5 +665,5 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_ else if (of_machine_is_compatible("st,spear310")) spear310_clk_init(); else if (of_machine_is_compatible("st,spear320")) - spear320_clk_init(soc_config_base); + spear320_clk_init(soc_config_base, ras_apb_clk); } -- cgit v1.2.3 From 655fc39bf40331e13503bed85c9ed0278bc35575 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 9 Jul 2014 21:04:00 +0200 Subject: firewire: IEEE 1394 (FireWire) support should depend on HAS_DMA Commit b3d681a4fc108f9653bbb44e4f4e72db2b8a5734 ("firewire: Use COMPILE_TEST for build testing") added COMPILE_TEST as an alternative dependency for the purpose of build testing the firewire core. However, this bypasses all other implicit dependencies assumed by PCI, like HAS_DMA. If NO_DMA=y: drivers/built-in.o: In function `fw_iso_buffer_destroy': (.text+0x36a096): undefined reference to `dma_unmap_page' drivers/built-in.o: In function `fw_iso_buffer_map_dma': (.text+0x36a164): undefined reference to `dma_map_page' drivers/built-in.o: In function `fw_iso_buffer_map_dma': (.text+0x36a172): undefined reference to `dma_mapping_error' drivers/built-in.o: In function `sbp2_send_management_orb': sbp2.c:(.text+0x36c6b4): undefined reference to `dma_map_single' sbp2.c:(.text+0x36c6c8): undefined reference to `dma_mapping_error' sbp2.c:(.text+0x36c772): undefined reference to `dma_map_single' sbp2.c:(.text+0x36c786): undefined reference to `dma_mapping_error' sbp2.c:(.text+0x36c854): undefined reference to `dma_unmap_single' sbp2.c:(.text+0x36c872): undefined reference to `dma_unmap_single' drivers/built-in.o: In function `sbp2_map_scatterlist': sbp2.c:(.text+0x36ccbc): undefined reference to `scsi_dma_map' sbp2.c:(.text+0x36cd36): undefined reference to `dma_map_single' sbp2.c:(.text+0x36cd4e): undefined reference to `dma_mapping_error' sbp2.c:(.text+0x36cd84): undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `sbp2_unmap_scatterlist': sbp2.c:(.text+0x36cda6): undefined reference to `scsi_dma_unmap' sbp2.c:(.text+0x36cdc6): undefined reference to `dma_unmap_single' drivers/built-in.o: In function `complete_command_orb': sbp2.c:(.text+0x36d6ac): undefined reference to `dma_unmap_single' drivers/built-in.o: In function `sbp2_scsi_queuecommand': sbp2.c:(.text+0x36d8e0): undefined reference to `dma_map_single' sbp2.c:(.text+0x36d8f6): undefined reference to `dma_mapping_error' Add an explicit dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Reviewed-by: Jean Delvare Signed-off-by: Stefan Richter --- drivers/firewire/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 4199849e3758..145974f9662b 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -1,4 +1,5 @@ menu "IEEE 1394 (FireWire) support" + depends on HAS_DMA depends on PCI || COMPILE_TEST # firewire-core does not depend on PCI but is # not useful without PCI controller driver -- cgit v1.2.3 From 54c39e9ba3a93e3848ad8f9d082c39010cfc5e73 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 2 Jul 2014 15:16:32 +0200 Subject: mtd: nand: reduce the warning noise when the ECC is too weak In commit 67a9ad9b8a6f ("mtd: nand: Warn the user if the selected ECC strength is too weak"), a check was added to inform the user when the ECC used for a NAND device is weaker than the recommended ECC advertised by the NAND chip. However, the warning uses WARN_ON(), which has two undesirable side-effects: - It just prints to the kernel log the fact that there is a warning in this file, at this line, but it doesn't explain anything about the warning itself. - It dumps a stack trace which is very noisy, for something that the user is most likely not able to fix. If a certain ECC used by the kernel is weaker than the advertised one, it's most likely to make sure the kernel uses an ECC that is compatible with the one used by the bootloader, and changing the bootloader may not necessarily be easy. Therefore, normal users would not be able to do anything to fix this very noisy warning, and will have to suffer from it at every kernel boot. At least every time I see this stack trace in my kernel boot log, I wonder what new thing is broken, just to realize that it's once again this NAND ECC warning. Therefore, this commit turns: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at /home/thomas/projets/linux-2.6/drivers/mtd/nand/nand_base.c:4051 nand_scan_tail+0x538/0x780() Modules linked in: CPU: 0 PID: 1 Comm: swapper Not tainted 3.16.0-rc3-dirty #4 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (warn_slowpath_common+0x6c/0x8c) [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [] (warn_slowpath_null) from [] (nand_scan_tail+0x538/0x780) [] (nand_scan_tail) from [] (orion_nand_probe+0x224/0x2e4) [] (orion_nand_probe) from [] (platform_drv_probe+0x18/0x4c) [] (platform_drv_probe) from [] (really_probe+0x80/0x218) [] (really_probe) from [] (__driver_attach+0x98/0x9c) [] (__driver_attach) from [] (bus_for_each_dev+0x64/0x94) [] (bus_for_each_dev) from [] (bus_add_driver+0x144/0x1ec) [] (bus_add_driver) from [] (driver_register+0x78/0xf8) [] (driver_register) from [] (platform_driver_probe+0x20/0xb8) [] (platform_driver_probe) from [] (do_one_initcall+0x80/0x1d8) [] (do_one_initcall) from [] (kernel_init_freeable+0xf4/0x1b4) [] (kernel_init_freeable) from [] (kernel_init+0x8/0xec) [] (kernel_init) from [] (ret_from_fork+0x14/0x24) ---[ end trace 62f87d875aceccb4 ]--- Into the much shorter, and much more useful: nand: WARNING: MT29F2G08ABAEAWP: the ECC used on your system is too weak compared to the one required by the NAND chip Signed-off-by: Thomas Petazzoni Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 41167e9e991e..4f3e80c68a26 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4047,8 +4047,10 @@ int nand_scan_tail(struct mtd_info *mtd) ecc->layout->oobavail += ecc->layout->oobfree[i].length; mtd->oobavail = ecc->layout->oobavail; - /* ECC sanity check: warn noisily if it's too weak */ - WARN_ON(!nand_ecc_strength_good(mtd)); + /* ECC sanity check: warn if it's too weak */ + if (!nand_ecc_strength_good(mtd)) + pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n", + mtd->name); /* * Set the number of read / write steps for one page depending on ECC -- cgit v1.2.3 From 812c5fa82bae9f377f49000d7636c19a8b61735c Mon Sep 17 00:00:00 2001 From: Andrea Adami Date: Mon, 2 Jun 2014 23:38:35 +0200 Subject: mtd: cfi_cmdset_0001.c: add support for Sharp LH28F640BF NOR This family of chips was long ago supported by the pre-cfi driver. CFI code tested on several Zaurus SL-5500 (Collie) 2x16 on 32 bit bus. Function is_LH28F640BF() mimics is_m29ew() from cmdset_0002.c Buffer write fixes as seen in 2007 patch c/o Anti Sullin artecdesign.ee> http://comments.gmane.org/gmane.linux.ports.arm.kernel/36733 [Brian: this patch is semi-urgent, because the following patch switches to using CFI detection for a chip which (until now) is unsupported by the CFI driver 9218310 ARM: 8084/1: sa1100: collie: revert back to cfi_probe ] Signed-off-by: Andrea Adami Signed-off-by: Brian Norris --- drivers/mtd/chips/cfi_cmdset_0001.c | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e4ec355704a6..a7543ba3e190 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -52,6 +52,11 @@ /* Atmel chips */ #define AT49BV640D 0x02de #define AT49BV640DT 0x02db +/* Sharp chips */ +#define LH28F640BFHE_PTTL90 0x00b0 +#define LH28F640BFHE_PBTL90 0x00b1 +#define LH28F640BFHE_PTTL70A 0x00b2 +#define LH28F640BFHE_PBTL70A 0x00b3 static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -258,6 +263,36 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd) (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; }; +static int is_LH28F640BF(struct cfi_private *cfi) +{ + /* Sharp LH28F640BF Family */ + if (cfi->mfr == CFI_MFR_SHARP && ( + cfi->id == LH28F640BFHE_PTTL90 || cfi->id == LH28F640BFHE_PBTL90 || + cfi->id == LH28F640BFHE_PTTL70A || cfi->id == LH28F640BFHE_PBTL70A)) + return 1; + return 0; +} + +static void fixup_LH28F640BF(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + struct cfi_pri_intelext *extp = cfi->cmdset_priv; + + /* Reset the Partition Configuration Register on LH28F640BF + * to a single partition (PCR = 0x000): PCR is embedded into A0-A15. */ + if (is_LH28F640BF(cfi)) { + printk(KERN_INFO "Reset Partition Config. Register: 1 Partition of 4 planes\n"); + map_write(map, CMD(0x60), 0); + map_write(map, CMD(0x04), 0); + + /* We have set one single partition thus + * Simultaneous Operations are not allowed */ + printk(KERN_INFO "cfi_cmdset_0001: Simultaneous Operations disabled\n"); + extp->FeatureSupport &= ~512; + } +} + static void fixup_use_point(struct mtd_info *mtd) { struct map_info *map = mtd->priv; @@ -309,6 +344,8 @@ static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct }, { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb }, { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock }, + { CFI_MFR_SHARP, CFI_ID_ANY, fixup_unlock_powerup_lock }, + { CFI_MFR_SHARP, CFI_ID_ANY, fixup_LH28F640BF }, { 0, 0, NULL } }; @@ -1649,6 +1686,12 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, initial_adr = adr; cmd_adr = adr & ~(wbufsize-1); + /* Sharp LH28F640BF chips need the first address for the + * Page Buffer Program command. See Table 5 of + * LH28F320BF, LH28F640BF, LH28F128BF Series (Appendix FUM00701) */ + if (is_LH28F640BF(cfi)) + cmd_adr = adr; + /* Let's determine this according to the interleave only once */ write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9); -- cgit v1.2.3 From 5a680fad352525c3461ed1f7e3269d31a9128a07 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 11 Jul 2014 16:55:15 -0700 Subject: net: bcmgenet: fix RGMII_MODE_EN bit RGMII_MODE_EN bit was defined to 0, while it is actually 6. It was not much of a problem on older designs where this was a no-op, and the RGMII data-path would always be enabled, but newer GENET controllers need to explicitely enable their RGMII data-pad using this bit. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 0f117105fed1..e23c993b1362 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -331,9 +331,9 @@ struct bcmgenet_mib_counters { #define EXT_ENERGY_DET_MASK (1 << 12) #define EXT_RGMII_OOB_CTRL 0x0C -#define RGMII_MODE_EN (1 << 0) #define RGMII_LINK (1 << 4) #define OOB_DISABLE (1 << 5) +#define RGMII_MODE_EN (1 << 6) #define ID_MODE_DIS (1 << 16) #define EXT_GPHY_CTRL 0x1C -- cgit v1.2.3 From a8a3e41c67d24eb12f9ab9680cbb85e24fcd9711 Mon Sep 17 00:00:00 2001 From: Christoph Schulz Date: Sun, 13 Jul 2014 00:53:15 +0200 Subject: net: pppoe: use correct channel MTU when using Multilink PPP The PPP channel MTU is used with Multilink PPP when ppp_mp_explode() (see ppp_generic module) tries to determine how big a fragment might be. According to RFC 1661, the MTU excludes the 2-byte PPP protocol field, see the corresponding comment and code in ppp_mp_explode(): /* * hdrlen includes the 2-byte PPP protocol field, but the * MTU counts only the payload excluding the protocol field. * (RFC1661 Section 2) */ mtu = pch->chan->mtu - (hdrlen - 2); However, the pppoe module *does* include the PPP protocol field in the channel MTU, which is wrong as it causes the PPP payload to be 1-2 bytes too big under certain circumstances (one byte if PPP protocol compression is used, two otherwise), causing the generated Ethernet packets to be dropped. So the pppoe module has to subtract two bytes from the channel MTU. This error only manifests itself when using Multilink PPP, as otherwise the channel MTU is not used anywhere. In the following, I will describe how to reproduce this bug. We configure two pppd instances for multilink PPP over two PPPoE links, say eth2 and eth3, with a MTU of 1492 bytes for each link and a MRRU of 2976 bytes. (This MRRU is computed by adding the two link MTUs and subtracting the MP header twice, which is 4 bytes long.) The necessary pppd statements on both sides are "multilink mtu 1492 mru 1492 mrru 2976". On the client side, we additionally need "plugin rp-pppoe.so eth2" and "plugin rp-pppoe.so eth3", respectively; on the server side, we additionally need to start two pppoe-server instances to be able to establish two PPPoE sessions, one over eth2 and one over eth3. We set the MTU of the PPP network interface to the MRRU (2976) on both sides of the connection in order to make use of the higher bandwidth. (If we didn't do that, IP fragmentation would kick in, which we want to avoid.) Now we send a ICMPv4 echo request with a payload of 2948 bytes from client to server over the PPP link. This results in the following network packet: 2948 (echo payload) + 8 (ICMPv4 header) + 20 (IPv4 header) --------------------- 2976 (PPP payload) These 2976 bytes do not exceed the MTU of the PPP network interface, so the IP packet is not fragmented. Now the multilink PPP code in ppp_mp_explode() prepends one protocol byte (0x21 for IPv4), making the packet one byte bigger than the negotiated MRRU. So this packet would have to be divided in three fragments. But this does not happen as each link MTU is assumed to be two bytes larger. So this packet is diveded into two fragments only, one of size 1489 and one of size 1488. Now we have for that bigger fragment: 1489 (PPP payload) + 4 (MP header) + 2 (PPP protocol field for the MP payload (0x3d)) + 6 (PPPoE header) -------------------------- 1501 (Ethernet payload) This packet exceeds the link MTU and is discarded. If one configures the link MTU on the client side to 1501, one can see the discarded Ethernet frames with tcpdump running on the client. A ping -s 2948 -c 1 192.168.15.254 leads to the smaller fragment that is correctly received on the server side: (tcpdump -vvvne -i eth3 pppoes and ppp proto 0x3d) 52:54:00:ad:87:fd > 52:54:00:79:5c:d0, ethertype PPPoE S (0x8864), length 1514: PPPoE [ses 0x3] MLPPP (0x003d), length 1494: seq 0x000, Flags [end], length 1492 and to the bigger fragment that is not received on the server side: (tcpdump -vvvne -i eth2 pppoes and ppp proto 0x3d) 52:54:00:70:9e:89 > 52:54:00:5d:6f:b0, ethertype PPPoE S (0x8864), length 1515: PPPoE [ses 0x5] MLPPP (0x003d), length 1495: seq 0x000, Flags [begin], length 1493 With the patch below, we correctly obtain three fragments: 52:54:00:ad:87:fd > 52:54:00:79:5c:d0, ethertype PPPoE S (0x8864), length 1514: PPPoE [ses 0x1] MLPPP (0x003d), length 1494: seq 0x000, Flags [begin], length 1492 52:54:00:70:9e:89 > 52:54:00:5d:6f:b0, ethertype PPPoE S (0x8864), length 1514: PPPoE [ses 0x1] MLPPP (0x003d), length 1494: seq 0x000, Flags [none], length 1492 52:54:00:ad:87:fd > 52:54:00:79:5c:d0, ethertype PPPoE S (0x8864), length 27: PPPoE [ses 0x1] MLPPP (0x003d), length 7: seq 0x000, Flags [end], length 5 And the ICMPv4 echo request is successfully received at the server side: IP (tos 0x0, ttl 64, id 21925, offset 0, flags [DF], proto ICMP (1), length 2976) 192.168.222.2 > 192.168.15.254: ICMP echo request, id 30530, seq 0, length 2956 The bug was introduced in commit c9aa6895371b2a257401f59d3393c9f7ac5a8698 ("[PPPOE]: Advertise PPPoE MTU") from the very beginning. This patch applies to 3.10 upwards but the fix can be applied (with minor modifications) to kernels as old as 2.6.32. Signed-off-by: Christoph Schulz Signed-off-by: David S. Miller --- drivers/net/ppp/pppoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index 2ea7efd11857..6c9c16d76935 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -675,7 +675,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.hdrlen = (sizeof(struct pppoe_hdr) + dev->hard_header_len); - po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr); + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; po->chan.private = sk; po->chan.ops = &pppoe_chan_ops; -- cgit v1.2.3 From 548d28bd0eac840d122b691279ce9f4ce6ecbfb6 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Sun, 13 Jul 2014 09:47:47 +0200 Subject: bonding: fix ad_select module param check Obvious copy/paste error when I converted the ad_select to the new option API. "lacp_rate" there should be "ad_select" so we can get the proper value. CC: Jay Vosburgh CC: Veaceslav Falico CC: Andy Gospodarek CC: David S. Miller Fixes: 9e5f5eebe765 ("bonding: convert ad_select to use the new option API") Reported-by: Karim Scheik Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3a451b6cd3d5..701f86cd5993 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4068,7 +4068,7 @@ static int bond_check_params(struct bond_params *params) } if (ad_select) { - bond_opt_initstr(&newval, lacp_rate); + bond_opt_initstr(&newval, ad_select); valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_SELECT), &newval); if (!valptr) { -- cgit v1.2.3 From 32b333fe99069d090a12cc106fd5ae1002fe642f Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 14 Jul 2014 11:42:44 +0800 Subject: mlx4: mark napi id for gro_skb Napi id was not marked for gro_skb, this will lead rx busy loop won't work correctly since they stack never try to call low latency receive method because of a zero socket napi id. Fix this by marking napi id for gro_skb. The transaction rate of 1 byte netperf tcp_rr gets about 50% increased (from 20531.68 to 30610.88). Cc: Amir Vadai Signed-off-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 96724170308a..5535862f27cc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -783,6 +783,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud PKT_HASH_TYPE_L3); skb_record_rx_queue(gro_skb, cq->ring); + skb_mark_napi_id(gro_skb, &cq->napi); if (ring->hwtstamp_rx_filter == HWTSTAMP_FILTER_ALL) { timestamp = mlx4_en_get_cqe_ts(cqe); -- cgit v1.2.3 From 3916a3192793fd3c11f69d623ef0cdbdbf9ea10a Mon Sep 17 00:00:00 2001 From: Christoph Schulz Date: Mon, 14 Jul 2014 08:01:10 +0200 Subject: net: ppp: don't call sk_chk_filter twice Commit 568f194e8bd16c353ad50f9ab95d98b20578a39d ("net: ppp: use sk_unattached_filter api") causes sk_chk_filter() to be called twice when setting a PPP pass or active filter. This applies to both the generic PPP subsystem implemented by drivers/net/ppp/ppp_generic.c and the ISDN PPP subsystem implemented by drivers/isdn/i4l/isdn_ppp.c. The first call is from within get_filter(). The second one is through the call chain ppp_ioctl() or isdn_ppp_ioctl() --> sk_unattached_filter_create() --> __sk_prepare_filter() --> sk_chk_filter() The first call from within get_filter() should be deleted as get_filter() is called just before calling sk_unattached_filter_create() later on, which eventually calls sk_chk_filter() anyway. For 3.15.x, this proposed change is a bugfix rather than a pure optimization as in that branch, sk_chk_filter() may replace filter codes by other codes which are not recognized when executing sk_chk_filter() a second time. So with 3.15.x, if sk_chk_filter() is called twice, the second invocation may yield EINVAL (this depends on the filter codes found in the filter to be set, but because the replacement is done for frequently used codes, this is almost always the case). The net effect is that setting pass and/or active PPP filters does not work anymore, since sk_unattached_filter_create() always returns EINVAL due to the second call to sk_chk_filter(), regardless whether the filter was originally sane or not. Signed-off-by: Christoph Schulz Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_ppp.c | 8 +------- drivers/net/ppp/ppp_generic.c | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 61ac63237446..a333b7f798d1 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -442,7 +442,7 @@ static int get_filter(void __user *arg, struct sock_filter **p) { struct sock_fprog uprog; struct sock_filter *code = NULL; - int len, err; + int len; if (copy_from_user(&uprog, arg, sizeof(uprog))) return -EFAULT; @@ -458,12 +458,6 @@ static int get_filter(void __user *arg, struct sock_filter **p) if (IS_ERR(code)) return PTR_ERR(code); - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); - return err; - } - *p = code; return uprog.len; } diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 91d6c1272fcf..e2f20f807de8 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -539,7 +539,7 @@ static int get_filter(void __user *arg, struct sock_filter **p) { struct sock_fprog uprog; struct sock_filter *code = NULL; - int len, err; + int len; if (copy_from_user(&uprog, arg, sizeof(uprog))) return -EFAULT; @@ -554,12 +554,6 @@ static int get_filter(void __user *arg, struct sock_filter **p) if (IS_ERR(code)) return PTR_ERR(code); - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); - return err; - } - *p = code; return uprog.len; } -- cgit v1.2.3 From 5c763edfe4879ffc3a87fef64f743d4b5497aabb Mon Sep 17 00:00:00 2001 From: Olivier Sobrie Date: Mon, 14 Jul 2014 12:08:49 +0200 Subject: hso: remove unused workqueue The workqueue "retry_unthrottle_workqueue" is not scheduled anywhere in the code. So, remove it. Signed-off-by: Olivier Sobrie Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index a3a05869309d..9ca2b418a3ee 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -261,7 +261,6 @@ struct hso_serial { u16 curr_rx_urb_offset; u8 rx_urb_filled[MAX_RX_URBS]; struct tasklet_struct unthrottle_tasklet; - struct work_struct retry_unthrottle_workqueue; }; struct hso_device { @@ -1252,14 +1251,6 @@ static void hso_unthrottle(struct tty_struct *tty) tasklet_hi_schedule(&serial->unthrottle_tasklet); } -static void hso_unthrottle_workfunc(struct work_struct *work) -{ - struct hso_serial *serial = - container_of(work, struct hso_serial, - retry_unthrottle_workqueue); - hso_unthrottle_tasklet(serial); -} - /* open the requested serial port */ static int hso_serial_open(struct tty_struct *tty, struct file *filp) { @@ -1295,8 +1286,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) tasklet_init(&serial->unthrottle_tasklet, (void (*)(unsigned long))hso_unthrottle_tasklet, (unsigned long)serial); - INIT_WORK(&serial->retry_unthrottle_workqueue, - hso_unthrottle_workfunc); result = hso_start_serial_device(serial->parent, GFP_KERNEL); if (result) { hso_stop_serial_device(serial->parent); @@ -1345,7 +1334,6 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) if (!usb_gone) hso_stop_serial_device(serial->parent); tasklet_kill(&serial->unthrottle_tasklet); - cancel_work_sync(&serial->retry_unthrottle_workqueue); } if (!usb_gone) -- cgit v1.2.3 From 8f9818af4eaef1150282e18355aaea425474a411 Mon Sep 17 00:00:00 2001 From: Olivier Sobrie Date: Mon, 14 Jul 2014 12:08:50 +0200 Subject: hso: fix deadlock when receiving bursts of data When the module sends bursts of data, sometimes a deadlock happens in the hso driver when the tty buffer doesn't get the chance to be flushed quickly enough. Remove the endless while loop in function put_rxbuf_data() which is called by the urb completion handler. If there isn't enough room in the tty buffer, discards all the data received in the URB. Cc: David Miller Cc: David Laight Cc: One Thousand Gnomes Cc: Dan Williams Cc: Jan Dumon Signed-off-by: Olivier Sobrie Acked-by: Alan Cox Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9ca2b418a3ee..a4272ed62da8 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -258,7 +258,6 @@ struct hso_serial { * so as not to drop characters on the floor. */ int curr_rx_urb_idx; - u16 curr_rx_urb_offset; u8 rx_urb_filled[MAX_RX_URBS]; struct tasklet_struct unthrottle_tasklet; }; @@ -2001,8 +2000,7 @@ static void ctrl_callback(struct urb *urb) static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) { struct tty_struct *tty; - int write_length_remaining = 0; - int curr_write_len; + int count; /* Sanity check */ if (urb == NULL || serial == NULL) { @@ -2012,29 +2010,28 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) tty = tty_port_tty_get(&serial->port); + if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { + tty_kref_put(tty); + return -1; + } + /* Push data to tty */ - write_length_remaining = urb->actual_length - - serial->curr_rx_urb_offset; D1("data to push to tty"); - while (write_length_remaining) { - if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { - tty_kref_put(tty); - return -1; - } - curr_write_len = tty_insert_flip_string(&serial->port, - urb->transfer_buffer + serial->curr_rx_urb_offset, - write_length_remaining); - serial->curr_rx_urb_offset += curr_write_len; - write_length_remaining -= curr_write_len; + count = tty_buffer_request_room(&serial->port, urb->actual_length); + if (count >= urb->actual_length) { + tty_insert_flip_string(&serial->port, urb->transfer_buffer, + urb->actual_length); tty_flip_buffer_push(&serial->port); + } else { + dev_warn(&serial->parent->usb->dev, + "dropping data, %d bytes lost\n", urb->actual_length); } + tty_kref_put(tty); - if (write_length_remaining == 0) { - serial->curr_rx_urb_offset = 0; - serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; - } - return write_length_remaining; + serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; + + return 0; } @@ -2205,7 +2202,6 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) } } serial->curr_rx_urb_idx = 0; - serial->curr_rx_urb_offset = 0; if (serial->tx_urb) usb_kill_urb(serial->tx_urb); -- cgit v1.2.3