From 379f10910c962e3be187317ee3b8e981ba6d3b03 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Fri, 4 Nov 2016 09:09:21 +0530 Subject: [PATCH 001/359] ARM: EXYNOS: Remove smp_init_cpus hook from platsmp.c We can safely remove exynos_smp_init_cpus() hook from mach-exynos/platsmp.c, as all SMP platforms in mach-exynos can rely on DT for CPU core description instead of determining number of cores from the SCU. Signed-off-by: Pankaj Dubey Reviewed-by: Alim Akhtar Tested-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/platsmp.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 98ffe1e62ad5..a5d68411a037 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -385,36 +385,6 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) return pen_release != -1 ? ret : 0; } -/* - * Initialise the CPU possible map early - this describes the CPUs - * which may be present or become present in the system. - */ - -static void __init exynos_smp_init_cpus(void) -{ - void __iomem *scu_base = scu_base_addr(); - unsigned int i, ncores; - - if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) - ncores = scu_base ? scu_get_core_count(scu_base) : 1; - else - /* - * CPU Nodes are passed thru DT and set_cpu_possible - * is set by "arm_dt_init_cpu_maps". - */ - return; - - /* sanity check */ - if (ncores > nr_cpu_ids) { - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", - ncores, nr_cpu_ids); - ncores = nr_cpu_ids; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) { int i; @@ -479,7 +449,6 @@ static void exynos_cpu_die(unsigned int cpu) #endif /* CONFIG_HOTPLUG_CPU */ const struct smp_operations exynos_smp_ops __initconst = { - .smp_init_cpus = exynos_smp_init_cpus, .smp_prepare_cpus = exynos_smp_prepare_cpus, .smp_secondary_init = exynos_secondary_init, .smp_boot_secondary = exynos_boot_secondary, From 9d56d6cb4e937ead2c6a45d11b8441ea512c6b80 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 4 Nov 2016 10:45:53 +0100 Subject: [PATCH 002/359] ARM: S3C24XX: Add DMA slave maps for remaining s3c24xx SoCs This patch adds DMA slave map tables for the remaining s3c24xx SoC types so the whole platform can be switched to the new API. A few devices for which there was no DMA support with current code are omitted from the tables. Signed-off-by: Sylwester Nawrocki Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c24xx/common.c | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index f6c3f151d0d4..b59f4f4f256f 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -345,10 +345,40 @@ static struct s3c24xx_dma_channel s3c2410_dma_channels[DMACH_MAX] = { [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), }, }; +static const struct dma_slave_map s3c2410_dma_slave_map[] = { + { "s3c2410-sdi", "rx-tx", (void *)DMACH_SDI }, + { "s3c2410-spi.0", "rx", (void *)DMACH_SPI0_RX }, + { "s3c2410-spi.0", "tx", (void *)DMACH_SPI0_TX }, + { "s3c2410-spi.1", "rx", (void *)DMACH_SPI1_RX }, + { "s3c2410-spi.1", "tx", (void *)DMACH_SPI1_TX }, + /* + * The DMA request source[1] (DMACH_UARTx_SRC2) are + * not used in the UART driver. + */ + { "s3c2410-uart.0", "rx", (void *)DMACH_UART0 }, + { "s3c2410-uart.0", "tx", (void *)DMACH_UART0 }, + { "s3c2410-uart.1", "rx", (void *)DMACH_UART1 }, + { "s3c2410-uart.1", "tx", (void *)DMACH_UART1 }, + { "s3c2410-uart.2", "rx", (void *)DMACH_UART2 }, + { "s3c2410-uart.2", "tx", (void *)DMACH_UART2 }, + { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN }, + { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT }, + { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 }, + { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 }, + { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 }, + { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 }, + { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 }, + { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 }, + { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 }, + { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 } +}; + static struct s3c24xx_dma_platdata s3c2410_dma_platdata = { .num_phy_channels = 4, .channels = s3c2410_dma_channels, .num_channels = DMACH_MAX, + .slave_map = s3c2410_dma_slave_map, + .slavecnt = ARRAY_SIZE(s3c2410_dma_slave_map), }; struct platform_device s3c2410_device_dma = { @@ -388,10 +418,36 @@ static struct s3c24xx_dma_channel s3c2412_dma_channels[DMACH_MAX] = { [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, 16 }, }; +static const struct dma_slave_map s3c2412_dma_slave_map[] = { + { "s3c2412-sdi", "rx-tx", (void *)DMACH_SDI }, + { "s3c2412-spi.0", "rx", (void *)DMACH_SPI0_RX }, + { "s3c2412-spi.0", "tx", (void *)DMACH_SPI0_TX }, + { "s3c2412-spi.1", "rx", (void *)DMACH_SPI1_RX }, + { "s3c2412-spi.1", "tx", (void *)DMACH_SPI1_TX }, + { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 }, + { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 }, + { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 }, + { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 }, + { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 }, + { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 }, + { "s3c2412-iis", "rx", (void *)DMACH_I2S_IN }, + { "s3c2412-iis", "tx", (void *)DMACH_I2S_OUT }, + { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 }, + { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 }, + { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 }, + { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 }, + { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 }, + { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 }, + { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 }, + { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 } +}; + static struct s3c24xx_dma_platdata s3c2412_dma_platdata = { .num_phy_channels = 4, .channels = s3c2412_dma_channels, .num_channels = DMACH_MAX, + .slave_map = s3c2412_dma_slave_map, + .slavecnt = ARRAY_SIZE(s3c2412_dma_slave_map), }; struct platform_device s3c2412_device_dma = { @@ -534,10 +590,30 @@ static struct s3c24xx_dma_channel s3c2443_dma_channels[DMACH_MAX] = { [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, 29 }, }; +static const struct dma_slave_map s3c2443_dma_slave_map[] = { + { "s3c2440-sdi", "rx-tx", (void *)DMACH_SDI }, + { "s3c2443-spi.0", "rx", (void *)DMACH_SPI0_RX }, + { "s3c2443-spi.0", "tx", (void *)DMACH_SPI0_TX }, + { "s3c2443-spi.1", "rx", (void *)DMACH_SPI1_RX }, + { "s3c2443-spi.1", "tx", (void *)DMACH_SPI1_TX }, + { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 }, + { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 }, + { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 }, + { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 }, + { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 }, + { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 }, + { "s3c2440-uart.3", "rx", (void *)DMACH_UART3 }, + { "s3c2440-uart.3", "tx", (void *)DMACH_UART3 }, + { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN }, + { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT }, +}; + static struct s3c24xx_dma_platdata s3c2443_dma_platdata = { .num_phy_channels = 6, .channels = s3c2443_dma_channels, .num_channels = DMACH_MAX, + .slave_map = s3c2443_dma_slave_map, + .slavecnt = ARRAY_SIZE(s3c2443_dma_slave_map), }; struct platform_device s3c2443_device_dma = { From 14944934f8ace3cb7c02edfbdfb664577de53365 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 21 Nov 2016 11:26:27 -0600 Subject: [PATCH 003/359] ARM: OMAP2+: Remove legacy gpio code OMAP2+ GPOs are initialized now using device tree, so legacy gpio initialization code can be removed. Signed-off-by: Grygorii Strashko Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/gpio.c | 160 ------------------- arch/arm/mach-omap2/omap_hwmod_common_data.h | 4 - 3 files changed, 1 insertion(+), 165 deletions(-) delete mode 100644 arch/arm/mach-omap2/gpio.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 9b1ef53c16d0..1ff04f1a6d96 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -7,7 +7,7 @@ ccflags-y := -I$(srctree)/$(src)/include \ # Common support obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \ - common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ + common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ omap_device.o omap-headsmp.o sram.o drm.o hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c deleted file mode 100644 index 7a577145b68b..000000000000 --- a/arch/arm/mach-omap2/gpio.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * OMAP2+ specific gpio initialization - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * Author: - * Charulatha V - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - -#include "soc.h" -#include "omap_hwmod.h" -#include "omap_device.h" -#include "omap-pm.h" - -#include "powerdomain.h" - -static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) -{ - struct platform_device *pdev; - struct omap_gpio_platform_data *pdata; - struct omap_gpio_dev_attr *dev_attr; - char *name = "omap_gpio"; - int id; - struct powerdomain *pwrdm; - - /* - * extract the device id from name field available in the - * hwmod database and use the same for constructing ids for - * gpio devices. - * CAUTION: Make sure the name in the hwmod database does - * not change. If changed, make corresponding change here - * or make use of static variable mechanism to handle this. - */ - sscanf(oh->name, "gpio%d", &id); - - pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); - if (!pdata) { - pr_err("gpio%d: Memory allocation failed\n", id); - return -ENOMEM; - } - - dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr; - pdata->bank_width = dev_attr->bank_width; - pdata->dbck_flag = dev_attr->dbck_flag; - pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; - pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); - if (!pdata->regs) { - pr_err("gpio%d: Memory allocation failed\n", id); - kfree(pdata); - return -ENOMEM; - } - - switch (oh->class->rev) { - case 0: - if (id == 1) - /* non-wakeup GPIO pins for OMAP2 Bank1 */ - pdata->non_wakeup_gpios = 0xe203ffc0; - else if (id == 2) - /* non-wakeup GPIO pins for OMAP2 Bank2 */ - pdata->non_wakeup_gpios = 0x08700040; - /* fall through */ - - case 1: - pdata->regs->revision = OMAP24XX_GPIO_REVISION; - pdata->regs->direction = OMAP24XX_GPIO_OE; - pdata->regs->datain = OMAP24XX_GPIO_DATAIN; - pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT; - pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT; - pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT; - pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1; - pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; - pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1; - pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2; - pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; - pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; - pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; - pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; - pdata->regs->ctrl = OMAP24XX_GPIO_CTRL; - pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN; - pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0; - pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1; - pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT; - pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT; - break; - case 2: - pdata->regs->revision = OMAP4_GPIO_REVISION; - pdata->regs->direction = OMAP4_GPIO_OE; - pdata->regs->datain = OMAP4_GPIO_DATAIN; - pdata->regs->dataout = OMAP4_GPIO_DATAOUT; - pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT; - pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT; - pdata->regs->irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0; - pdata->regs->irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1; - pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0; - pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1; - pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0; - pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1; - pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; - pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; - pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; - pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; - pdata->regs->ctrl = OMAP4_GPIO_CTRL; - pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0; - pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0; - pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1; - pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT; - pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT; - break; - default: - WARN(1, "Invalid gpio bank_type\n"); - kfree(pdata->regs); - kfree(pdata); - return -EINVAL; - } - - pwrdm = omap_hwmod_get_pwrdm(oh); - pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); - - pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata)); - kfree(pdata); - - if (IS_ERR(pdev)) { - WARN(1, "Can't build omap_device for %s:%s.\n", - name, oh->name); - return PTR_ERR(pdev); - } - - return 0; -} - -/* - * gpio_init needs to be done before - * machine_init functions access gpio APIs. - * Hence gpio_init is a omap_postcore_initcall. - */ -static int __init omap2_gpio_init(void) -{ - /* If dtb is there, the devices will be created dynamically */ - if (of_have_populated_dt()) - return -ENODEV; - - return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL); -} -omap_postcore_initcall(omap2_gpio_init); diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h index cdfbb44ceb0c..f22e9cb39f4a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h @@ -121,10 +121,6 @@ extern struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[]; extern struct omap_hwmod_irq_info omap2_dispc_irqs[]; extern struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[]; extern struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[]; -extern struct omap_hwmod_irq_info omap2_gpio1_irqs[]; -extern struct omap_hwmod_irq_info omap2_gpio2_irqs[]; -extern struct omap_hwmod_irq_info omap2_gpio3_irqs[]; -extern struct omap_hwmod_irq_info omap2_gpio4_irqs[]; extern struct omap_hwmod_irq_info omap2_dma_system_irqs[]; extern struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[]; extern struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[]; From 47af2c676ae1e84140225d261a00bdf88f1f9f7e Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Mon, 28 Nov 2016 16:22:44 -0500 Subject: [PATCH 004/359] iio: 104-quad-8: Fix index control configuration The LS7266R1 requires bits 5 & 6 to be high in order to select the Index Control Register. This patch fixes a typo that incorrectly selects the Input/Output Control Register where the Index Control Register was desired. Fixes: 28e5d3bb0325 ("iio: 104-quad-8: Add IIO support for the ACCES 104-QUAD-8") Signed-off-by: William Breathitt Gray Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/counter/104-quad-8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c index 2d2ee353dde7..c0a69d7e9ce7 100644 --- a/drivers/iio/counter/104-quad-8.c +++ b/drivers/iio/counter/104-quad-8.c @@ -362,7 +362,7 @@ static int quad8_set_synchronous_mode(struct iio_dev *indio_dev, priv->synchronous_mode[chan->channel] = synchronous_mode; /* Load Index Control configuration to Index Control Register */ - outb(0x40 | idr_cfg, base_offset); + outb(0x60 | idr_cfg, base_offset); return 0; } @@ -444,7 +444,7 @@ static int quad8_set_index_polarity(struct iio_dev *indio_dev, priv->index_polarity[chan->channel] = index_polarity; /* Load Index Control configuration to Index Control Register */ - outb(0x40 | idr_cfg, base_offset); + outb(0x60 | idr_cfg, base_offset); return 0; } From 7e1c4058e741c781b262b15a2e86a40602aaa6b6 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Mon, 28 Nov 2016 16:55:34 -0500 Subject: [PATCH 005/359] iio: 104-quad-8: Fix off-by-one errors when addressing IOR The Input/Output Control register (IOR) is offset by 1 from the respective channel data register. This patch fixes off-by-one errors when attempting to write to a channel IOR where the base address was not properly offset. Fixes: 28e5d3bb0325 ("iio: 104-quad-8: Add IIO support for the ACCES 104-QUAD-8") Signed-off-by: William Breathitt Gray Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/counter/104-quad-8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c index c0a69d7e9ce7..07b6d20c0756 100644 --- a/drivers/iio/counter/104-quad-8.c +++ b/drivers/iio/counter/104-quad-8.c @@ -153,7 +153,7 @@ static int quad8_write_raw(struct iio_dev *indio_dev, ior_cfg = val | priv->preset_enable[chan->channel] << 1; /* Load I/O control configuration */ - outb(0x40 | ior_cfg, base_offset); + outb(0x40 | ior_cfg, base_offset + 1); return 0; case IIO_CHAN_INFO_SCALE: @@ -241,7 +241,7 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev, size_t len) { struct quad8_iio *const priv = iio_priv(indio_dev); - const int base_offset = priv->base + 2 * chan->channel; + const int base_offset = priv->base + 2 * chan->channel + 1; bool preset_enable; int ret; unsigned int ior_cfg; From e91c3dfcd3ff88218c972cb24f932c4d434bbb09 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Tue, 29 Nov 2016 10:51:48 -0500 Subject: [PATCH 006/359] iio: 104-quad-8: Fix active level mismatch for the preset enable option The set_to_preset_on_index sysfs attribute provides a boolean configuration option to enable a preset operation on the respective channel's counter when Index occurs. However, the corresponding configuration bit on the Input/Output Control register must be set low to enable the preset operation. This patch inverts the internal driver boolean logic exposed via the set_to_preset_on_index attribute in order to correctly configure the device which expects an active low bit. Fixes: 28e5d3bb0325 ("iio: 104-quad-8: Add IIO support for the ACCES 104-QUAD-8") Signed-off-by: William Breathitt Gray Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/counter/104-quad-8.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c index 07b6d20c0756..a5913e97945e 100644 --- a/drivers/iio/counter/104-quad-8.c +++ b/drivers/iio/counter/104-quad-8.c @@ -233,7 +233,7 @@ static ssize_t quad8_read_set_to_preset_on_index(struct iio_dev *indio_dev, const struct quad8_iio *const priv = iio_priv(indio_dev); return snprintf(buf, PAGE_SIZE, "%u\n", - priv->preset_enable[chan->channel]); + !priv->preset_enable[chan->channel]); } static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev, @@ -250,6 +250,9 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev, if (ret) return ret; + /* Preset enable is active low in Input/Output Control register */ + preset_enable = !preset_enable; + priv->preset_enable[chan->channel] = preset_enable; ior_cfg = priv->ab_enable[chan->channel] | From da6b21e97e39d42f90ab490ce7b54a0fe2c3fe35 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 18 Nov 2016 13:15:12 +0200 Subject: [PATCH 007/359] ARM: Drop fixed 200 Hz timer requirement from Samsung platforms All Samsung platforms, including the Exynos, are selecting HZ_FIXED with 200 Hz. Unfortunately in case of multiplatform image this affects also other platforms when Exynos is enabled. This looks like an very old legacy code, dating back to initial upstreaming of S3C24xx. Probably it was required for s3c24xx timer driver, which was removed in commit ad38bdd15d5b ("ARM: SAMSUNG: Remove unused plat-samsung/time.c"). Since then, this fixed 200 Hz spread everywhere, including out-of-tree Samsung kernels (SoC vendor's and Tizen's). I believe this choice was rather an effect of coincidence instead of conscious choice. On S3C24xx, the PWM counter is only 16 bit wide, and with the typical 12MHz input clock that overflows every 5.5ms. This works with HZ=200 or higher but not with HZ=100 which needs a 10ms interval between ticks. On Later chips (S3C64xx, S5P and EXYNOS), the counter is 32 bits and does not have this problem. The new samsung_pwm_timer driver solves the problem by scaling the input clock by a factor of 50 on S3C24xx, which makes it less accurate but allows HZ=100 as well as CONFIG_NO_HZ with fewer wakeups. Few perf mem and sched tests on Odroid XU3 board (Exynos5422, 4x Cortex A7, 4x Cortex A15) show no regressions when switching from 200 Hz to other values. Reported-by: Lee Jones [Dropping of 200_HZ from S3C/S5P was suggested by Arnd] Reported-by: Arnd Bergmann Cc: Kukjin Kim Signed-off-by: Krzysztof Kozlowski [Tested on Exynos5800] Tested-by: Javier Martinez Canillas Acked-by: Kukjin Kim [Tested on S3C2440] Tested-by: Sylwester Nawrocki Acked-by: Lee Jones --- arch/arm/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b5d529fdffab..ced2e08a9d08 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1496,8 +1496,7 @@ source kernel/Kconfig.preempt config HZ_FIXED int - default 200 if ARCH_EBSA110 || ARCH_S3C24XX || \ - ARCH_S5PV210 || ARCH_EXYNOS4 + default 200 if ARCH_EBSA110 default 128 if SOC_AT91RM9200 default 0 From 8ebcb400af619ee0ddeb39c06fc35511b20cc697 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 1 Dec 2016 10:07:26 +0100 Subject: [PATCH 008/359] arm64: dts: h3ulcb: Provide sd0_uhs node Provide separaate sd0 and sd0_uhs nodes rather than duplicate sd0 nodes. Cc: Vladimir Barinov Cc: Sergei Shtylyov Fixes: 93373c309a70 ("arm64: dts: h3ulcb: rename SDHI0 pins") Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts index 6ffb0517421a..dbea2c3d8f0c 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts @@ -169,7 +169,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0 { + sdhi0_pins_uhs: sd0_uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>; From c8b1b3dd89ea7b3f77a73e59c4c4495e16338e15 Mon Sep 17 00:00:00 2001 From: Brendan McGrath Date: Sat, 10 Dec 2016 21:20:42 +1100 Subject: [PATCH 009/359] HID: asus: Fix keyboard support The previous submission which added Touchpad support broke the Keyboard support of this driver. This patch: 1. fixes the Keyboard support (by assigning drvdata->input); 2. renames NOTEBOOK_QUIRKS to KEYBOARD_QUIRKS; 3. adds the NO_INIT_REPORT quirk to the KEYBOARD_QUIRKS; and 4. sets the input->name to 'Asus Keyboard' for the keyboard Signed-off-by: Brendan McGrath Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index d40ed9fdf68d..70b12f89a193 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -64,7 +64,8 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_SKIP_INPUT_MAPPING BIT(2) #define QUIRK_IS_MULTITOUCH BIT(3) -#define NOTEBOOK_QUIRKS QUIRK_FIX_NOTEBOOK_REPORT +#define KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ + QUIRK_NO_INIT_REPORTS) #define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \ QUIRK_SKIP_INPUT_MAPPING | \ QUIRK_IS_MULTITOUCH) @@ -170,11 +171,11 @@ static int asus_raw_event(struct hid_device *hdev, static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) { + struct input_dev *input = hi->input; struct asus_drvdata *drvdata = hid_get_drvdata(hdev); if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { int ret; - struct input_dev *input = hi->input; input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); @@ -191,10 +192,10 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) hid_err(hdev, "Asus input mt init slots failed: %d\n", ret); return ret; } - - drvdata->input = input; } + drvdata->input = input; + return 0; } @@ -286,7 +287,11 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_stop_hw; } - drvdata->input->name = "Asus TouchPad"; + if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { + drvdata->input->name = "Asus TouchPad"; + } else { + drvdata->input->name = "Asus Keyboard"; + } if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { ret = asus_start_multitouch(hdev); @@ -315,7 +320,7 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, static const struct hid_device_id asus_devices[] = { { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), NOTEBOOK_QUIRKS}, + USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), KEYBOARD_QUIRKS}, { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_TOUCHPAD), TOUCHPAD_QUIRKS }, { } From 6c206e4d99f2ed2a5a59875858e3beecc69b6474 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 16 Dec 2016 14:28:40 +0100 Subject: [PATCH 010/359] x86, swiotlb: Simplify pci_swiotlb_detect_override() At the end of the function, the local variable use_swiotlb has always the same value as the global variable swiotlb. Hence drop the local variable completely. Signed-off-by: Geert Uytterhoeven Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/kernel/pci-swiotlb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index b47edb8f5256..36049af2715e 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c @@ -68,12 +68,10 @@ static struct dma_map_ops swiotlb_dma_ops = { */ int __init pci_swiotlb_detect_override(void) { - int use_swiotlb = swiotlb | swiotlb_force; - if (swiotlb_force) swiotlb = 1; - return use_swiotlb; + return swiotlb; } IOMMU_INIT_FINISH(pci_swiotlb_detect_override, pci_xen_swiotlb_detect, From ae7871be189cb41184f1e05742b4a99e2c59774d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 16 Dec 2016 14:28:41 +0100 Subject: [PATCH 011/359] swiotlb: Convert swiotlb_force from int to enum Convert the flag swiotlb_force from an int to an enum, to prepare for the advent of more possible values. Suggested-by: Konrad Rzeszutek Wilk Signed-off-by: Geert Uytterhoeven Signed-off-by: Konrad Rzeszutek Wilk --- arch/arm64/mm/dma-mapping.c | 3 ++- arch/arm64/mm/init.c | 3 ++- arch/x86/kernel/pci-swiotlb.c | 2 +- arch/x86/xen/pci-swiotlb-xen.c | 2 +- drivers/xen/swiotlb-xen.c | 4 ++-- include/linux/swiotlb.h | 7 ++++++- include/trace/events/swiotlb.h | 16 +++++++++------- lib/swiotlb.c | 8 ++++---- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 3f74d0d98de6..02265a589ef5 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -524,7 +524,8 @@ EXPORT_SYMBOL(dummy_dma_ops); static int __init arm64_dma_init(void) { - if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) + if (swiotlb_force == SWIOTLB_FORCE || + max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) swiotlb = 1; return atomic_pool_init(); diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 212c4d1e2f26..716d1226ba69 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -401,7 +401,8 @@ static void __init free_unused_memmap(void) */ void __init mem_init(void) { - if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) + if (swiotlb_force == SWIOTLB_FORCE || + max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) swiotlb_init(1); set_max_mapnr(pfn_to_page(max_pfn) - mem_map); diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 36049af2715e..410efb2c7b80 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c @@ -68,7 +68,7 @@ static struct dma_map_ops swiotlb_dma_ops = { */ int __init pci_swiotlb_detect_override(void) { - if (swiotlb_force) + if (swiotlb_force == SWIOTLB_FORCE) swiotlb = 1; return swiotlb; diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index a9fafb5c8738..a0b36a9d5df1 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c @@ -48,7 +48,7 @@ int __init pci_xen_swiotlb_detect(void) * activate this IOMMU. If running as PV privileged, activate it * irregardless. */ - if ((xen_initial_domain() || swiotlb || swiotlb_force)) + if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE) xen_swiotlb = 1; /* If we are running under Xen, we MUST disable the native SWIOTLB. diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 478fb91e3df2..aba12009422e 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -392,7 +392,7 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, if (dma_capable(dev, dev_addr, size) && !range_straddles_page_boundary(phys, size) && !xen_arch_need_swiotlb(dev, phys, dev_addr) && - !swiotlb_force) { + (swiotlb_force != SWIOTLB_FORCE)) { /* we are not interested in the dma_addr returned by * xen_dma_map_page, only in the potential cache flushes executed * by the function. */ @@ -552,7 +552,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, phys_addr_t paddr = sg_phys(sg); dma_addr_t dev_addr = xen_phys_to_bus(paddr); - if (swiotlb_force || + if (swiotlb_force == SWIOTLB_FORCE || xen_arch_need_swiotlb(hwdev, paddr, dev_addr) || !dma_capable(hwdev, dev_addr, sg->length) || range_straddles_page_boundary(paddr, sg->length)) { diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 183f37c8a5e1..71d104e4c849 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -9,7 +9,12 @@ struct device; struct page; struct scatterlist; -extern int swiotlb_force; +enum swiotlb_force { + SWIOTLB_NORMAL, /* Default - depending on HW DMA mask etc. */ + SWIOTLB_FORCE, /* swiotlb=force */ +}; + +extern enum swiotlb_force swiotlb_force; /* * Maximum allowable number of contiguous slabs to map, diff --git a/include/trace/events/swiotlb.h b/include/trace/events/swiotlb.h index 7ea4c5e7c448..5e2e30a7efce 100644 --- a/include/trace/events/swiotlb.h +++ b/include/trace/events/swiotlb.h @@ -11,16 +11,16 @@ TRACE_EVENT(swiotlb_bounced, TP_PROTO(struct device *dev, dma_addr_t dev_addr, size_t size, - int swiotlb_force), + enum swiotlb_force swiotlb_force), TP_ARGS(dev, dev_addr, size, swiotlb_force), TP_STRUCT__entry( - __string( dev_name, dev_name(dev) ) - __field( u64, dma_mask ) - __field( dma_addr_t, dev_addr ) - __field( size_t, size ) - __field( int, swiotlb_force ) + __string( dev_name, dev_name(dev) ) + __field( u64, dma_mask ) + __field( dma_addr_t, dev_addr ) + __field( size_t, size ) + __field( enum swiotlb_force, swiotlb_force ) ), TP_fast_assign( @@ -37,7 +37,9 @@ TRACE_EVENT(swiotlb_bounced, __entry->dma_mask, (unsigned long long)__entry->dev_addr, __entry->size, - __entry->swiotlb_force ? "swiotlb_force" : "" ) + __print_symbolic(__entry->swiotlb_force, + { SWIOTLB_NORMAL, "NORMAL" }, + { SWIOTLB_FORCE, "FORCE" })) ); #endif /* _TRACE_SWIOTLB_H */ diff --git a/lib/swiotlb.c b/lib/swiotlb.c index cb1b54ee8527..a32dce6d5101 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -53,7 +53,7 @@ */ #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) -int swiotlb_force; +enum swiotlb_force swiotlb_force; /* * Used to do a quick range check in swiotlb_tbl_unmap_single and @@ -107,7 +107,7 @@ setup_io_tlb_npages(char *str) if (*str == ',') ++str; if (!strcmp(str, "force")) - swiotlb_force = 1; + swiotlb_force = SWIOTLB_FORCE; return 0; } @@ -763,7 +763,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, * we can safely return the device addr and not worry about bounce * buffering it. */ - if (dma_capable(dev, dev_addr, size) && !swiotlb_force) + if (dma_capable(dev, dev_addr, size) && swiotlb_force != SWIOTLB_FORCE) return dev_addr; trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); @@ -904,7 +904,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, phys_addr_t paddr = sg_phys(sg); dma_addr_t dev_addr = phys_to_dma(hwdev, paddr); - if (swiotlb_force || + if (swiotlb_force == SWIOTLB_FORCE || !dma_capable(hwdev, dev_addr, sg->length)) { phys_addr_t map = map_single(hwdev, sg_phys(sg), sg->length, dir, attrs); From fff5d99225107f5f13fe4a9805adc2a1c4b5fb00 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 16 Dec 2016 14:28:42 +0100 Subject: [PATCH 012/359] swiotlb: Add swiotlb=noforce debug option On architectures like arm64, swiotlb is tied intimately to the core architecture DMA support. In addition, ZONE_DMA cannot be disabled. To aid debugging and catch devices not supporting DMA to memory outside the 32-bit address space, add a kernel command line option "swiotlb=noforce", which disables the use of bounce buffers. If specified, trying to map memory that cannot be used with DMA will fail, and a rate-limited warning will be printed. Note that io_tlb_nslabs is set to 1, which is the minimal supported value. Signed-off-by: Geert Uytterhoeven Signed-off-by: Konrad Rzeszutek Wilk --- .../admin-guide/kernel-parameters.txt | 3 ++- include/linux/swiotlb.h | 1 + include/trace/events/swiotlb.h | 3 ++- lib/swiotlb.c | 18 ++++++++++++++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index be2d6d0a03a4..7d5f4f4cecfa 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3807,10 +3807,11 @@ it if 0 is given (See Documentation/cgroup-v1/memory.txt) swiotlb= [ARM,IA-64,PPC,MIPS,X86] - Format: { | force } + Format: { | force | noforce } -- Number of I/O TLB slabs force -- force using of bounce buffers even if they wouldn't be automatically used by the kernel + noforce -- Never use bounce buffers (for debugging) switches= [HW,M68k] diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 71d104e4c849..d9c84a9cde3d 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -12,6 +12,7 @@ struct scatterlist; enum swiotlb_force { SWIOTLB_NORMAL, /* Default - depending on HW DMA mask etc. */ SWIOTLB_FORCE, /* swiotlb=force */ + SWIOTLB_NO_FORCE, /* swiotlb=noforce */ }; extern enum swiotlb_force swiotlb_force; diff --git a/include/trace/events/swiotlb.h b/include/trace/events/swiotlb.h index 5e2e30a7efce..288c0c54a2b4 100644 --- a/include/trace/events/swiotlb.h +++ b/include/trace/events/swiotlb.h @@ -39,7 +39,8 @@ TRACE_EVENT(swiotlb_bounced, __entry->size, __print_symbolic(__entry->swiotlb_force, { SWIOTLB_NORMAL, "NORMAL" }, - { SWIOTLB_FORCE, "FORCE" })) + { SWIOTLB_FORCE, "FORCE" }, + { SWIOTLB_NO_FORCE, "NO_FORCE" })) ); #endif /* _TRACE_SWIOTLB_H */ diff --git a/lib/swiotlb.c b/lib/swiotlb.c index a32dce6d5101..9def738af4f4 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -106,8 +106,12 @@ setup_io_tlb_npages(char *str) } if (*str == ',') ++str; - if (!strcmp(str, "force")) + if (!strcmp(str, "force")) { swiotlb_force = SWIOTLB_FORCE; + } else if (!strcmp(str, "noforce")) { + swiotlb_force = SWIOTLB_NO_FORCE; + io_tlb_nslabs = 1; + } return 0; } @@ -543,8 +547,15 @@ static phys_addr_t map_single(struct device *hwdev, phys_addr_t phys, size_t size, enum dma_data_direction dir, unsigned long attrs) { - dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); + dma_addr_t start_dma_addr; + if (swiotlb_force == SWIOTLB_NO_FORCE) { + dev_warn_ratelimited(hwdev, "Cannot do DMA to address %pa\n", + &phys); + return SWIOTLB_MAP_ERROR; + } + + start_dma_addr = phys_to_dma(hwdev, io_tlb_start); return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, dir, attrs); } @@ -721,6 +732,9 @@ static void swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir, int do_panic) { + if (swiotlb_force == SWIOTLB_NO_FORCE) + return; + /* * Ran out of IOMMU space for this operation. This is very bad. * Unfortunately the drivers cannot handle this operation properly. From 2b6579d4a71afb19c6583470783371b992944f67 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Thu, 8 Dec 2016 19:09:50 -0800 Subject: [PATCH 013/359] HID: sony: Fix error handling bug when touchpad registration fails The error handling code in sony_input_configured in general uses goto based cleanup. Recently we migrated code from sony_probe to here, but we didn't update the existing touchpad registration code, which was already here to use the goto. Signed-off-by: Roderick Colenbrander Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 7687c0875395..f68c921af55e 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2548,7 +2548,7 @@ static int sony_input_configured(struct hid_device *hdev, hid_err(sc->hdev, "Unable to initialize multi-touch slots: %d\n", ret); - return ret; + goto err_stop; } sony_init_output_report(sc, dualshock4_send_output_report); From c70d5f70ccbbdf56bb86adb42127db90d0c90976 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Thu, 8 Dec 2016 19:09:51 -0800 Subject: [PATCH 014/359] HID: sony: Use DS4 MAC address as unique identifier on USB The DS4 MAC address is reported as a unique identified when using Bluetooth. For USB there is no unique identifier reported yet, so use the MAC address. Signed-off-by: Roderick Colenbrander Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index f68c921af55e..c6982a29a56d 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2390,6 +2390,12 @@ static int sony_check_add(struct sony_sc *sc) } memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); + + snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq), + "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + sc->mac_address[5], sc->mac_address[4], + sc->mac_address[3], sc->mac_address[2], + sc->mac_address[1], sc->mac_address[0]); } else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || (sc->quirks & NAVIGATION_CONTROLLER_USB)) { buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL); From 405182c2459fe2de4a3994ef39e866993e0e61d1 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Thu, 8 Dec 2016 19:09:52 -0800 Subject: [PATCH 015/359] HID: sony: Ignore DS4 dongle reports when no device is connected When the DS4 dongle is connected, it always generates HID reports even when no DS4 is paired to it. This patch adds logic to ignore HID reports from the dongle if there is no DS4 currently attached. Signed-off-by: Roderick Colenbrander Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index c6982a29a56d..f405b07d0381 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1099,8 +1099,11 @@ struct sony_sc { u8 led_delay_on[MAX_LEDS]; u8 led_delay_off[MAX_LEDS]; u8 led_count; + bool ds4_dongle_connected; }; +static void sony_set_leds(struct sony_sc *sc); + static inline void sony_schedule_work(struct sony_sc *sc) { if (!sc->defer_initialization) @@ -1430,6 +1433,31 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, return -EILSEQ; } } + + /* + * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates + * if a DS4 is actually connected (indicated by '0'). + * For non-dongle, this bit is always 0 (connected). + */ + if (sc->hdev->vendor == USB_VENDOR_ID_SONY && + sc->hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) { + bool connected = (rd[31] & 0x04) ? false : true; + + if (!sc->ds4_dongle_connected && connected) { + hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n"); + sony_set_leds(sc); + sc->ds4_dongle_connected = true; + } else if (sc->ds4_dongle_connected && !connected) { + hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n"); + sc->ds4_dongle_connected = false; + /* Return 0, so hidraw can get the report. */ + return 0; + } else if (!sc->ds4_dongle_connected) { + /* Return 0, so hidraw can get the report. */ + return 0; + } + } + dualshock4_parse_report(sc, rd, size); } From 8f2b468aadc81ca0fc78e41696b648e30d91ba5c Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 20 Dec 2016 07:27:59 +0100 Subject: [PATCH 016/359] s390/vtime: correct system time accounting There is a slight misaccounting of system time in vtime_account_user. This function is called once per HZ tick in interrupt context. The irq_enter function already accounted the system time up to the point of the irq_enter call. The system time from irq_enter until vtime_account_user/do_account_vtime is reached is irq time but it is accounted to the previous context. Just drop the hardirq offset from arch/s390/kernel/vtime.c. Reported-by: Frederic Weisbecker Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/vtime.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 6b246aadf311..1b5c5ee9fc1b 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -94,7 +94,7 @@ static void update_mt_scaling(void) * Update process times based on virtual cpu times stored by entry.S * to the lowcore fields user_timer, system_timer & steal_clock. */ -static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) +static int do_account_vtime(struct task_struct *tsk) { u64 timer, clock, user, system, steal; u64 user_scaled, system_scaled; @@ -138,7 +138,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) } account_user_time(tsk, user); tsk->utimescaled += user_scaled; - account_system_time(tsk, hardirq_offset, system); + account_system_time(tsk, 0, system); tsk->stimescaled += system_scaled; steal = S390_lowcore.steal_timer; @@ -152,7 +152,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) void vtime_task_switch(struct task_struct *prev) { - do_account_vtime(prev, 0); + do_account_vtime(prev); prev->thread.user_timer = S390_lowcore.user_timer; prev->thread.system_timer = S390_lowcore.system_timer; S390_lowcore.user_timer = current->thread.user_timer; @@ -166,7 +166,7 @@ void vtime_task_switch(struct task_struct *prev) */ void vtime_account_user(struct task_struct *tsk) { - if (do_account_vtime(tsk, HARDIRQ_OFFSET)) + if (do_account_vtime(tsk)) virt_timer_expire(); } From cabab3f9f5ca077535080b3252e6168935b914af Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 20 Dec 2016 12:58:10 +0100 Subject: [PATCH 017/359] s390/kbuild: enable modversions for symbols exported from asm s390 version of commit 334bb7738764 ("x86/kbuild: enable modversions for symbols exported from asm") so we get also rid of all these warnings: WARNING: EXPORT symbol "_mcount" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "memcpy" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "memmove" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "memset" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "save_fpu_regs" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "sie64a" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "sie_exit" [vmlinux] version generation failed, symbol will not be versioned. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/asm-prototypes.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 arch/s390/include/asm/asm-prototypes.h diff --git a/arch/s390/include/asm/asm-prototypes.h b/arch/s390/include/asm/asm-prototypes.h new file mode 100644 index 000000000000..2c3413b0ca52 --- /dev/null +++ b/arch/s390/include/asm/asm-prototypes.h @@ -0,0 +1,8 @@ +#ifndef _ASM_S390_PROTOTYPES_H + +#include +#include +#include +#include + +#endif /* _ASM_S390_PROTOTYPES_H */ From b508fc354f6d168ec18673d99d3bce9d6c1d9475 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 21 Dec 2016 11:20:45 +0100 Subject: [PATCH 018/359] nvme: update maintainers information Switch the new, shared nvme git repository, which is co-maintained by everyone involved with NVMe. Also add the nvme_ioctl.h UAPI header to the files list. Signed-off-by: Christoph Hellwig --- MAINTAINERS | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f6eb97b35e0f..9b279928461d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8852,17 +8852,22 @@ F: drivers/video/fbdev/nvidia/ NVM EXPRESS DRIVER M: Keith Busch M: Jens Axboe +M: Christoph Hellwig +M: Sagi Grimberg L: linux-nvme@lists.infradead.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git -W: https://kernel.googlesource.com/pub/scm/linux/kernel/git/axboe/linux-block/ +T: git://git.infradead.org/nvme.git +W: http://git.infradead.org/nvme.git S: Supported F: drivers/nvme/host/ F: include/linux/nvme.h +F: include/uapi/linux/nvme_ioctl.h NVM EXPRESS TARGET DRIVER M: Christoph Hellwig M: Sagi Grimberg L: linux-nvme@lists.infradead.org +T: git://git.infradead.org/nvme.git +W: http://git.infradead.org/nvme.git S: Supported F: drivers/nvme/target/ From e6282aef7b89a11d26e731060c4409b7aac278bf Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 19 Dec 2016 11:37:50 -0500 Subject: [PATCH 019/359] nvme: simplify stripe quirk Some OEMs believe they own the Identify Controller vendor specific region and will repurpose it with their own values. While not common, we can't rely on the PCI VID:DID to tell use how to decode the field we reserved for this as the stripe size so we need to do something else for the list of devices using this quirk. The field was supposed to allow flexibility on the device's back-end striping, but it turned out that never materialized; the chunk is always the same as MDTS in the products subscribing to this quirk, so this patch removes the stripe_size field and sets the chunk to the max hw transfer size for the devices using this quirk. Signed-off-by: Keith Busch Signed-off-by: Christoph Hellwig --- drivers/nvme/host/core.c | 17 ++--------------- drivers/nvme/host/nvme.h | 1 - 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index b40cfb076f02..2fc86dc7a8df 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1193,8 +1193,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); } - if (ctrl->stripe_size) - blk_queue_chunk_sectors(q, ctrl->stripe_size >> 9); + if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) + blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); blk_queue_virt_boundary(q, ctrl->page_size - 1); if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) vwc = true; @@ -1250,19 +1250,6 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) ctrl->max_hw_sectors = min_not_zero(ctrl->max_hw_sectors, max_hw_sectors); - if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && id->vs[3]) { - unsigned int max_hw_sectors; - - ctrl->stripe_size = 1 << (id->vs[3] + page_shift); - max_hw_sectors = ctrl->stripe_size >> (page_shift - 9); - if (ctrl->max_hw_sectors) { - ctrl->max_hw_sectors = min(max_hw_sectors, - ctrl->max_hw_sectors); - } else { - ctrl->max_hw_sectors = max_hw_sectors; - } - } - nvme_set_queue_limits(ctrl, ctrl->admin_q); ctrl->sgls = le32_to_cpu(id->sgls); ctrl->kas = le16_to_cpu(id->kas); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index bd5321441d12..6377e14586dc 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -135,7 +135,6 @@ struct nvme_ctrl { u32 page_size; u32 max_hw_sectors; - u32 stripe_size; u16 oncs; u16 vid; atomic_t abort_limit; From 9fa196e7fc7a0f12329d5346164abb27f026991c Mon Sep 17 00:00:00 2001 From: Max Gurtovoy Date: Mon, 19 Dec 2016 16:18:24 +0200 Subject: [PATCH 020/359] nvme/pci: Fix whitespace problem Convert to tabs and remove unneeded whitespaces. Signed-off-by: Max Gurtovoy Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 2fd7dc2e8fc4..7d6c87028568 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -50,7 +50,7 @@ #define NVME_AQ_DEPTH 256 #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) - + /* * We handle AEN commands ourselves and don't even let the * block layer know about them. @@ -1909,10 +1909,10 @@ static int nvme_dev_map(struct nvme_dev *dev) if (!dev->bar) goto release; - return 0; + return 0; release: - pci_release_mem_regions(pdev); - return -ENODEV; + pci_release_mem_regions(pdev); + return -ENODEV; } static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) From ff13b39ecf726715a96fcd3c23e50eb792ef6516 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 9 Dec 2016 12:08:58 -0500 Subject: [PATCH 021/359] nvme/pci: Delete misleading queue-wrap comment It is not theoretically possible for this driver to wrap twice while processing completions. The driver allocates only 'queue_depth - 1' tags, so there can never be more than that to reap when processing a completion queue. Removing this misleading comment makes it a little less likely people with broken controllers will blame the driver for their spurious interrupts. Signed-off-by: Keith Busch Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 7d6c87028568..151ce59f4ffb 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -712,15 +712,8 @@ static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag) req = blk_mq_tag_to_rq(*nvmeq->tags, cqe.command_id); nvme_req(req)->result = cqe.result; blk_mq_complete_request(req, le16_to_cpu(cqe.status) >> 1); - } - /* If the controller ignores the cq head doorbell and continuously - * writes to the queue, it is theoretically possible to wrap around - * the queue twice and mistakenly return IRQ_NONE. Linux only - * requires that 0.1% of your interrupts are handled, so this isn't - * a big problem. - */ if (head == nvmeq->cq_head && phase == nvmeq->cq_phase) return; From 2c473a9d02fbe881506d5d43bc7edb776f2f46f5 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 6 Dec 2016 10:14:35 -0800 Subject: [PATCH 022/359] nvme/scsi: Remove START STOP emulation Now that the broken power state control is gone, it appears to serve no purpose. Just delete it. NVME devices don't have a concept of started vs stopped anyway. Signed-off-by: Andy Lutomirski Reviewed-by: Keith Busch Signed-off-by: Christoph Hellwig --- drivers/nvme/host/scsi.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/nvme/host/scsi.c b/drivers/nvme/host/scsi.c index b71e95044b43..a5c09e703bd8 100644 --- a/drivers/nvme/host/scsi.c +++ b/drivers/nvme/host/scsi.c @@ -2160,30 +2160,6 @@ static int nvme_trans_synchronize_cache(struct nvme_ns *ns, return nvme_trans_status_code(hdr, nvme_sc); } -static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr, - u8 *cmd) -{ - u8 immed, no_flush; - - immed = cmd[1] & 0x01; - no_flush = cmd[4] & 0x04; - - if (immed != 0) { - return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, - ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, - SCSI_ASCQ_CAUSE_NOT_REPORTABLE); - } else { - if (no_flush == 0) { - /* Issue NVME FLUSH command prior to START STOP UNIT */ - int res = nvme_trans_synchronize_cache(ns, hdr); - if (res) - return res; - } - - return 0; - } -} - static int nvme_trans_format_unit(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *cmd) { @@ -2439,9 +2415,6 @@ static int nvme_scsi_translate(struct nvme_ns *ns, struct sg_io_hdr *hdr) case SECURITY_PROTOCOL_OUT: retcode = nvme_trans_security_protocol(ns, hdr, cmd); break; - case START_STOP: - retcode = nvme_trans_start_stop(ns, hdr, cmd); - break; case SYNCHRONIZE_CACHE: retcode = nvme_trans_synchronize_cache(ns, hdr); break; From c703489885218900579279cec4b4ab8e7fce383b Mon Sep 17 00:00:00 2001 From: James Smart Date: Tue, 20 Dec 2016 11:06:08 -0800 Subject: [PATCH 023/359] nvme/fc: correct some printk information Dan Carpenters's tool caught a pointer reference - should have been just ptr, not &ptr. Don't bother. Remove the pointer value in the printf. Its irrelevant. Signed-off-by: James Smart Reported-by: Dan Carpenter Signed-off-by: Christoph Hellwig --- drivers/nvme/host/fc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 771e2e761872..827c2b57e5bb 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2401,8 +2401,8 @@ __nvme_fc_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, WARN_ON_ONCE(!changed); dev_info(ctrl->ctrl.device, - "NVME-FC{%d}: new ctrl: NQN \"%s\" (%p)\n", - ctrl->cnum, ctrl->ctrl.opts->subsysnqn, &ctrl); + "NVME-FC{%d}: new ctrl: NQN \"%s\"\n", + ctrl->cnum, ctrl->ctrl.opts->subsysnqn); kref_get(&ctrl->ctrl.kref); From 17a1ec08ce7074f05795e5c32a3e5bc9a797bbf8 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Thu, 15 Dec 2016 14:20:48 +0100 Subject: [PATCH 024/359] nvme/fc: simplify error handling of nvme_fc_create_hw_io_queues Simplify the error handling of nvme_fc_create_hw_io_queues(), this saves us one variable and one level of indentation. Signed-off-by: Johannes Thumshirn Reviwed-by: James Smart Signed-off-by: Christoph Hellwig --- drivers/nvme/host/fc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 827c2b57e5bb..aa0bc60810a7 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -1491,19 +1491,20 @@ static int nvme_fc_create_hw_io_queues(struct nvme_fc_ctrl *ctrl, u16 qsize) { struct nvme_fc_queue *queue = &ctrl->queues[1]; - int i, j, ret; + int i, ret; for (i = 1; i < ctrl->queue_count; i++, queue++) { ret = __nvme_fc_create_hw_queue(ctrl, queue, i, qsize); - if (ret) { - for (j = i-1; j >= 0; j--) - __nvme_fc_delete_hw_queue(ctrl, - &ctrl->queues[j], j); - return ret; - } + if (ret) + goto delete_queues; } return 0; + +delete_queues: + for (; i >= 0; i--) + __nvme_fc_delete_hw_queue(ctrl, &ctrl->queues[i], i); + return ret; } static int From 6c73f949300f17851f53fa80c9d1611ccd6909d3 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 9 Dec 2016 12:59:46 -0700 Subject: [PATCH 025/359] nvmet: fix KATO offset in Set Features The Set Features implementation for Keep Alive Timer was using the wrong structure when retrieving the KATO value; it was treating the Set Features command as a Property Set command. The NVMe spec defines the Keep Alive Timer feature as having one input in CDW11 (4 bytes at offset 44 in the command) whereas the code was reading 8 bytes at offset 48. Since the Linux NVMe over Fabrics host never sets this feature, this code has presumably never been tested. Signed-off-by: Daniel Verkamp Signed-off-by: Christoph Hellwig --- drivers/nvme/target/admin-cmd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index ec1ad2aa0a4c..95ae52390478 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -382,7 +382,6 @@ static void nvmet_execute_set_features(struct nvmet_req *req) { struct nvmet_subsys *subsys = req->sq->ctrl->subsys; u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10[0]); - u64 val; u32 val32; u16 status = 0; @@ -392,8 +391,7 @@ static void nvmet_execute_set_features(struct nvmet_req *req) (subsys->max_qid - 1) | ((subsys->max_qid - 1) << 16)); break; case NVME_FEAT_KATO: - val = le64_to_cpu(req->cmd->prop_set.value); - val32 = val & 0xffff; + val32 = le32_to_cpu(req->cmd->common.cdw10[1]); req->sq->ctrl->kato = DIV_ROUND_UP(val32, 1000); nvmet_set_result(req, req->sq->ctrl->kato); break; From 7c3a23b85cac5f3caa531f369c1e3a5f1a8b555f Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 9 Dec 2016 14:59:47 +0000 Subject: [PATCH 026/359] nvmet/fcloop: remove some logically dead code performing redundant ret checks The check to see if ret is non-zero and return this rather than count is redundant in two occassions. It is redundant because prior to this check, the return code ret is already checked for a non-zero error return value and we return from the function at that point. Signed-off-by: Colin Ian King Reviewed-off-by: James Smart Signed-off-by: Christoph Hellwig --- drivers/nvme/target/fcloop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index bcb8ebeb01c5..4e8e6a22bce1 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -845,7 +845,7 @@ fcloop_create_remote_port(struct device *dev, struct device_attribute *attr, rport->lport = nport->lport; nport->rport = rport; - return ret ? ret : count; + return count; } @@ -952,7 +952,7 @@ fcloop_create_target_port(struct device *dev, struct device_attribute *attr, tport->lport = nport->lport; nport->tport = tport; - return ret ? ret : count; + return count; } From b428018a065b62191b9f8a3f553ebf4423017a78 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Mon, 19 Dec 2016 12:48:41 -0800 Subject: [PATCH 027/359] KVM: nVMX: fix instruction skipping during emulated vm-entry kvm_skip_emulated_instruction() should not be called after emulating a VM-entry failure during or after loading guest state (nested_vmx_entry_failure()). Otherwise the L1 hypervisor is resumed some number of bytes past vmcs->host_rip. Fixes: eb2775621701e6ee3ea2a474437d04e93ccdcb2f Signed-off-by: David Matlack Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 24db5fb6f575..ba20b00a450f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -10473,12 +10473,12 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) !nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4)) { nested_vmx_entry_failure(vcpu, vmcs12, EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); - goto out; + return 1; } if (vmcs12->vmcs_link_pointer != -1ull) { nested_vmx_entry_failure(vcpu, vmcs12, EXIT_REASON_INVALID_STATE, ENTRY_FAIL_VMCS_LINK_PTR); - goto out; + return 1; } /* @@ -10498,7 +10498,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) ia32e != !!(vmcs12->guest_ia32_efer & EFER_LME))) { nested_vmx_entry_failure(vcpu, vmcs12, EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); - goto out; + return 1; } } @@ -10516,7 +10516,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) ia32e != !!(vmcs12->host_ia32_efer & EFER_LME)) { nested_vmx_entry_failure(vcpu, vmcs12, EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); - goto out; + return 1; } } From e2a33c34ddff22ee208d80abdd12b88a98d6cb60 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Thu, 15 Dec 2016 12:00:27 -0500 Subject: [PATCH 028/359] clk: renesas: mstp: Support 8-bit registers for r7s72100 The RZ/A1 is different than the other Renesas SOCs because the MSTP registers are 8-bit instead of 32-bit and if you try writing values as 32-bit nothing happens...meaning this driver never worked for r7s72100. Fixes: b6face404f38 ("ARM: shmobile: r7s72100: add essential clock nodes to dtsi") Signed-off-by: Chris Brandt Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Acked-by: Kuninori Morimoto Signed-off-by: Stephen Boyd --- drivers/clk/renesas/clk-mstp.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 9375777776d9..b533f99550e1 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -37,12 +37,14 @@ * @smstpcr: module stop control register * @mstpsr: module stop status register (optional) * @lock: protects writes to SMSTPCR + * @width_8bit: registers are 8-bit, not 32-bit */ struct mstp_clock_group { struct clk_onecell_data data; void __iomem *smstpcr; void __iomem *mstpsr; spinlock_t lock; + bool width_8bit; }; /** @@ -59,6 +61,18 @@ struct mstp_clock { #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) +static inline u32 cpg_mstp_read(struct mstp_clock_group *group, + u32 __iomem *reg) +{ + return group->width_8bit ? readb(reg) : clk_readl(reg); +} + +static inline void cpg_mstp_write(struct mstp_clock_group *group, u32 val, + u32 __iomem *reg) +{ + group->width_8bit ? writeb(val, reg) : clk_writel(val, reg); +} + static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) { struct mstp_clock *clock = to_mstp_clock(hw); @@ -70,12 +84,12 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) spin_lock_irqsave(&group->lock, flags); - value = clk_readl(group->smstpcr); + value = cpg_mstp_read(group, group->smstpcr); if (enable) value &= ~bitmask; else value |= bitmask; - clk_writel(value, group->smstpcr); + cpg_mstp_write(group, value, group->smstpcr); spin_unlock_irqrestore(&group->lock, flags); @@ -83,7 +97,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) return 0; for (i = 1000; i > 0; --i) { - if (!(clk_readl(group->mstpsr) & bitmask)) + if (!(cpg_mstp_read(group, group->mstpsr) & bitmask)) break; cpu_relax(); } @@ -114,9 +128,9 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) u32 value; if (group->mstpsr) - value = clk_readl(group->mstpsr); + value = cpg_mstp_read(group, group->mstpsr); else - value = clk_readl(group->smstpcr); + value = cpg_mstp_read(group, group->smstpcr); return !(value & BIT(clock->bit_index)); } @@ -188,6 +202,9 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) return; } + if (of_device_is_compatible(np, "renesas,r7s72100-mstp-clocks")) + group->width_8bit = true; + for (i = 0; i < MSTP_MAX_CLOCKS; ++i) clks[i] = ERR_PTR(-ENOENT); From 3868f132cce6abab089fd6b12d6a7333712ade83 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Wed, 14 Dec 2016 15:22:28 +0100 Subject: [PATCH 029/359] clk: stm32f4: Use CLK_OF_DECLARE_DRIVER initialization method Clock and reset controller use same compatible strings (same IP). Since commit 989eafd0b609 ("clk: core: Avoid double initialization of clocks") the OF core flags clock controllers registered with the CLK_OF_DECLARE() macro as OF_POPULATED, so platform devices with the same compatible string will not be registered. Signed-off-by: Gabriel Fernandez Signed-off-by: Stephen Boyd --- drivers/clk/clk-stm32f4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 5eb05dbf59b8..fc585f370549 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -768,5 +768,5 @@ static void __init stm32f4_rcc_init(struct device_node *np) kfree(clks); iounmap(base); } -CLK_OF_DECLARE(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); -CLK_OF_DECLARE(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); +CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); +CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); From 7ecec8503af37de6be4f96b53828d640a968705f Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 12 Dec 2016 14:35:13 +0000 Subject: [PATCH 030/359] xen/setup: Don't relocate p2m over existing one When relocating the p2m, take special care not to relocate it so that is overlaps with the current location of the p2m/initrd. This is needed since the full extent of the current location is not marked as a reserved region in the e820. This was seen to happen to a dom0 with a large initial p2m and a small reserved region in the middle of the initial p2m. Signed-off-by: Ross Lagerwall Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- arch/x86/xen/setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 8c394e30e5fe..f3f7b41116f7 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -713,10 +713,9 @@ static void __init xen_reserve_xen_mfnlist(void) size = PFN_PHYS(xen_start_info->nr_p2m_frames); } - if (!xen_is_e820_reserved(start, size)) { - memblock_reserve(start, size); + memblock_reserve(start, size); + if (!xen_is_e820_reserved(start, size)) return; - } #ifdef CONFIG_X86_32 /* @@ -727,6 +726,7 @@ static void __init xen_reserve_xen_mfnlist(void) BUG(); #else xen_relocate_p2m(); + memblock_free(start, size); #endif } From 2f60b28831c7e63759b59113898e6fe4dc90dd43 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Tue, 20 Dec 2016 22:02:20 +0800 Subject: [PATCH 031/359] xen/evtchn: use rb_entry() To make the code clearer, use rb_entry() instead of container_of() to deal with rbtree. Signed-off-by: Geliang Tang Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/xen/evtchn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index e8c7f09d01be..6890897a6f30 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -125,7 +125,7 @@ static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn) while (*new) { struct user_evtchn *this; - this = container_of(*new, struct user_evtchn, node); + this = rb_entry(*new, struct user_evtchn, node); parent = *new; if (this->port < evtchn->port) @@ -157,7 +157,7 @@ static struct user_evtchn *find_evtchn(struct per_user_data *u, unsigned port) while (node) { struct user_evtchn *evtchn; - evtchn = container_of(node, struct user_evtchn, node); + evtchn = rb_entry(node, struct user_evtchn, node); if (evtchn->port < port) node = node->rb_left; From 64d656a162d7ba49d6d1863e41407b0f95e19258 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 22 Dec 2016 19:20:45 +0100 Subject: [PATCH 032/359] block: add back plugging in __blkdev_direct_IO This allows sending larger than 1 MB requests to devices that support large I/O sizes. Signed-off-by: Christoph Hellwig Reported-by: Laurence Oberman Signed-off-by: Jens Axboe --- fs/block_dev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/block_dev.c b/fs/block_dev.c index 7c4507224ed6..206a92aab52e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -328,6 +328,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) struct file *file = iocb->ki_filp; struct inode *inode = bdev_file_inode(file); struct block_device *bdev = I_BDEV(inode); + struct blk_plug plug; struct blkdev_dio *dio; struct bio *bio; bool is_read = (iov_iter_rw(iter) == READ); @@ -353,6 +354,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) dio->multi_bio = false; dio->should_dirty = is_read && (iter->type == ITER_IOVEC); + blk_start_plug(&plug); for (;;) { bio->bi_bdev = bdev; bio->bi_iter.bi_sector = pos >> 9; @@ -394,6 +396,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) submit_bio(bio); bio = bio_alloc(GFP_KERNEL, nr_pages); } + blk_finish_plug(&plug); if (!dio->is_sync) return -EIOCBQUEUED; From 72c5296f9d64d8f5f27c2133e5f108a45a353d71 Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Tue, 20 Dec 2016 14:38:14 -0700 Subject: [PATCH 033/359] genhd: remove dead and duplicated scsi code blk_scsi_cmd_filter use was deprecated by 4beab5c6 and the SCSI macros are duplicated in blkdev.h, both likely reintroduced by a bad merge from 540eed56. Signed-off-by: Jon Derrick Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe --- include/linux/genhd.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/linux/genhd.h b/include/linux/genhd.h index e0341af6950e..76f39754e7b0 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -146,15 +146,6 @@ enum { DISK_EVENT_EJECT_REQUEST = 1 << 1, /* eject requested */ }; -#define BLK_SCSI_MAX_CMDS (256) -#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) - -struct blk_scsi_cmd_filter { - unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; - unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; - struct kobject kobj; -}; - struct disk_part_tbl { struct rcu_head rcu_head; int len; From 639b08810d6ad74ded2c5f6e233c4fcb9d147168 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 22 Dec 2016 08:19:46 +0100 Subject: [PATCH 034/359] xen: xenbus driver must not accept invalid transaction ids When accessing Xenstore in a transaction the user is specifying a transaction id which he normally obtained from Xenstore when starting the transaction. Xenstore is validating a transaction id against all known transaction ids of the connection the request came in. As all requests of a domain not being the one where Xenstore lives share one connection, validation of transaction ids of different users of Xenstore in that domain should be done by the kernel of that domain being the multiplexer between the Xenstore users in that domain and Xenstore. In order to prohibit one Xenstore user "hijacking" a transaction from another user the xenbus driver has to verify a given transaction id against all known transaction ids of the user before forwarding it to Xenstore. Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_dev_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 6c0ead4be784..a06828124b70 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -316,7 +316,7 @@ static int xenbus_write_transaction(unsigned msg_type, rc = -ENOMEM; goto out; } - } else if (msg_type == XS_TRANSACTION_END) { + } else if (u->u.msg.tx_id != 0) { list_for_each_entry(trans, &u->transactions, list) if (trans->handle.id == u->u.msg.tx_id) break; From 9a6161fe73bdd3ae4a1e18421b0b20cb7141f680 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 22 Dec 2016 08:19:47 +0100 Subject: [PATCH 035/359] xen: return xenstore command failures via response instead of rc When the xenbus driver does some special handling for a Xenstore command any error condition related to the command should be returned via an error response instead of letting the related write operation fail. Otherwise the user land handler might take wrong decisions assuming the connection to Xenstore is broken. While at it try to return the same error values xenstored would return for those cases. Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_dev_frontend.c | 47 ++++++++++++++---------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index a06828124b70..79130b310247 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -302,6 +302,29 @@ static void watch_fired(struct xenbus_watch *watch, mutex_unlock(&adap->dev_data->reply_mutex); } +static int xenbus_command_reply(struct xenbus_file_priv *u, + unsigned int msg_type, const char *reply) +{ + struct { + struct xsd_sockmsg hdr; + const char body[16]; + } msg; + int rc; + + msg.hdr = u->u.msg; + msg.hdr.type = msg_type; + msg.hdr.len = strlen(reply) + 1; + if (msg.hdr.len > sizeof(msg.body)) + return -E2BIG; + + mutex_lock(&u->reply_mutex); + rc = queue_reply(&u->read_buffers, &msg, sizeof(msg.hdr) + msg.hdr.len); + wake_up(&u->read_waitq); + mutex_unlock(&u->reply_mutex); + + return rc; +} + static int xenbus_write_transaction(unsigned msg_type, struct xenbus_file_priv *u) { @@ -321,7 +344,7 @@ static int xenbus_write_transaction(unsigned msg_type, if (trans->handle.id == u->u.msg.tx_id) break; if (&trans->list == &u->transactions) - return -ESRCH; + return xenbus_command_reply(u, XS_ERROR, "ENOENT"); } reply = xenbus_dev_request_and_reply(&u->u.msg); @@ -372,12 +395,12 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u) path = u->u.buffer + sizeof(u->u.msg); token = memchr(path, 0, u->u.msg.len); if (token == NULL) { - rc = -EILSEQ; + rc = xenbus_command_reply(u, XS_ERROR, "EINVAL"); goto out; } token++; if (memchr(token, 0, u->u.msg.len - (token - path)) == NULL) { - rc = -EILSEQ; + rc = xenbus_command_reply(u, XS_ERROR, "EINVAL"); goto out; } @@ -411,23 +434,7 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u) } /* Success. Synthesize a reply to say all is OK. */ - { - struct { - struct xsd_sockmsg hdr; - char body[3]; - } __packed reply = { - { - .type = msg_type, - .len = sizeof(reply.body) - }, - "OK" - }; - - mutex_lock(&u->reply_mutex); - rc = queue_reply(&u->read_buffers, &reply, sizeof(reply)); - wake_up(&u->read_waitq); - mutex_unlock(&u->reply_mutex); - } + rc = xenbus_command_reply(u, msg_type, "OK"); out: return rc; From 61033e089cde41464f820c8c381ce170d89470f0 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 22 Dec 2016 08:19:48 +0100 Subject: [PATCH 036/359] xen: remove stale xs_input_avail() from header In drivers/xen/xenbus/xenbus_comms.h there is a stale declaration of xs_input_avail(). Remove it. Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_comms.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h index e74f9c1fbd80..867a2e425208 100644 --- a/drivers/xen/xenbus/xenbus_comms.h +++ b/drivers/xen/xenbus/xenbus_comms.h @@ -42,7 +42,6 @@ int xb_write(const void *data, unsigned len); int xb_read(void *data, unsigned len); int xb_data_to_read(void); int xb_wait_for_data_to_read(void); -int xs_input_avail(void); extern struct xenstore_domain_interface *xen_store_interface; extern int xen_store_evtchn; extern enum xenstore_init xen_store_domain_type; From e3ba730702af370563f66cb610b71aa0ca67955e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 22 Dec 2016 10:15:20 +0100 Subject: [PATCH 037/359] fsnotify: Remove fsnotify_duplicate_mark() There are only two calls sites of fsnotify_duplicate_mark(). Those are in kernel/audit_tree.c and both are bogus. Vfsmount pointer is unused for audit tree, inode pointer and group gets set in fsnotify_add_mark_locked() later anyway, mask and free_mark are already set in alloc_chunk(). In fact, calling fsnotify_duplicate_mark() is actively harmful because following fsnotify_add_mark_locked() will leak group reference by overwriting the group pointer. So just remove the two calls to fsnotify_duplicate_mark() and the function. Signed-off-by: Jan Kara [PM: line wrapping to fit in 80 chars] Signed-off-by: Paul Moore --- fs/notify/mark.c | 12 ------------ include/linux/fsnotify_backend.h | 2 -- kernel/audit_tree.c | 8 ++++---- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index d3fea0bd89e2..6043306e8e21 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -510,18 +510,6 @@ void fsnotify_detach_group_marks(struct fsnotify_group *group) } } -void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) -{ - assert_spin_locked(&old->lock); - new->inode = old->inode; - new->mnt = old->mnt; - if (old->group) - fsnotify_get_group(old->group); - new->group = old->group; - new->mask = old->mask; - new->free_mark = old->free_mark; -} - /* * Nothing fancy, just initialize lists and locks and counters. */ diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 7268ed076be8..ce77caa2bb10 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -324,8 +324,6 @@ extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(str extern struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, struct inode *inode); /* find (and take a reference) to a mark associated with group and vfsmount */ extern struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt); -/* copy the values from old into new */ -extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old); /* set the ignored_mask of a mark */ extern void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask); /* set the mask of a mark (might pin the object into memory */ diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 055f11b0a50f..b4b58400531f 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -258,8 +258,8 @@ static void untag_chunk(struct node *p) if (!new) goto Fallback; - fsnotify_duplicate_mark(&new->mark, entry); - if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, NULL, 1)) { + if (fsnotify_add_mark(&new->mark, + entry->group, entry->inode, NULL, 1)) { fsnotify_put_mark(&new->mark); goto Fallback; } @@ -395,8 +395,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) return -ENOENT; } - fsnotify_duplicate_mark(chunk_entry, old_entry); - if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, NULL, 1)) { + if (fsnotify_add_mark(chunk_entry, + old_entry->group, old_entry->inode, NULL, 1)) { spin_unlock(&old_entry->lock); fsnotify_put_mark(chunk_entry); fsnotify_put_mark(old_entry); From 6ef4e07ecd2db21025c446327ecf34414366498b Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Sat, 24 Dec 2016 10:00:42 +0100 Subject: [PATCH 038/359] KVM: x86: reset MMU on KVM_SET_VCPU_EVENTS Otherwise, mismatch between the smm bit in hflags and the MMU role can cause a NULL pointer dereference. Cc: stable@vger.kernel.org Signed-off-by: Xiao Guangrong Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 445c51b6cf6d..0b387d61c103 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3070,6 +3070,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, memset(&events->reserved, 0, sizeof(events->reserved)); } +static void kvm_set_hflags(struct kvm_vcpu *vcpu, unsigned emul_flags); + static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events) { @@ -3106,10 +3108,13 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, vcpu->arch.apic->sipi_vector = events->sipi_vector; if (events->flags & KVM_VCPUEVENT_VALID_SMM) { + u32 hflags = vcpu->arch.hflags; if (events->smi.smm) - vcpu->arch.hflags |= HF_SMM_MASK; + hflags |= HF_SMM_MASK; else - vcpu->arch.hflags &= ~HF_SMM_MASK; + hflags &= ~HF_SMM_MASK; + kvm_set_hflags(vcpu, hflags); + vcpu->arch.smi_pending = events->smi.pending; if (events->smi.smm_inside_nmi) vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK; From b8395cc7a454efc616e335c22af22d8513abdafc Mon Sep 17 00:00:00 2001 From: Min He Date: Mon, 5 Dec 2016 10:53:25 +0800 Subject: [PATCH 039/359] drm/i915/gvt: fix an error in opregion handling It should be vgpu_opregion(vgpu)->va, not vgpu_opregion(vgpu). Signed-off-by: Min He Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/opregion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c index d2a0fbc896c3..81cd921770c6 100644 --- a/drivers/gpu/drm/i915/gvt/opregion.c +++ b/drivers/gpu/drm/i915/gvt/opregion.c @@ -65,7 +65,7 @@ static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map) int i, ret; for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++) { - mfn = intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu) + mfn = intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu)->va + i * PAGE_SIZE); if (mfn == INTEL_GVT_INVALID_ADDR) { gvt_err("fail to get MFN from VA\n"); From d650ac06023796ade7cb5ec4d5650c67dc494ed0 Mon Sep 17 00:00:00 2001 From: Ping Gao Date: Thu, 8 Dec 2016 10:14:48 +0800 Subject: [PATCH 040/359] drm/i915/gvt: reset the GGTT entry when vGPU created The GGTT space is partitioned between vGPUs, it could be reused by next vGPU after previous one is release, the stale entries need point to scratch page when vGPU created. v2: Reset logic move to vGPU create. v3: Correct the commit msg. v4: Move the reset function to vGPU init gtt function, as result it's no need explicitly in vGPU reset logic as vGPU init gtt called during reset. Signed-off-by: Ping Gao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 55 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/gtt.h | 4 +++ 2 files changed, 59 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 7eaaf1c9ed2b..6c5fdf5b2ce2 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1998,6 +1998,8 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) INIT_LIST_HEAD(>t->oos_page_list_head); INIT_LIST_HEAD(>t->post_shadow_list_head); + intel_vgpu_reset_ggtt(vgpu); + ggtt_mm = intel_vgpu_create_mm(vgpu, INTEL_GVT_MM_GGTT, NULL, 1, 0); if (IS_ERR(ggtt_mm)) { @@ -2206,6 +2208,7 @@ int intel_vgpu_g2v_destroy_ppgtt_mm(struct intel_vgpu *vgpu, int intel_gvt_init_gtt(struct intel_gvt *gvt) { int ret; + void *page_addr; gvt_dbg_core("init gtt\n"); @@ -2218,6 +2221,23 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) return -ENODEV; } + gvt->gtt.scratch_ggtt_page = + alloc_page(GFP_KERNEL | GFP_ATOMIC | __GFP_ZERO); + if (!gvt->gtt.scratch_ggtt_page) { + gvt_err("fail to allocate scratch ggtt page\n"); + return -ENOMEM; + } + + page_addr = page_address(gvt->gtt.scratch_ggtt_page); + + gvt->gtt.scratch_ggtt_mfn = + intel_gvt_hypervisor_virt_to_mfn(page_addr); + if (gvt->gtt.scratch_ggtt_mfn == INTEL_GVT_INVALID_ADDR) { + gvt_err("fail to translate scratch ggtt page\n"); + __free_page(gvt->gtt.scratch_ggtt_page); + return -EFAULT; + } + if (enable_out_of_sync) { ret = setup_spt_oos(gvt); if (ret) { @@ -2239,6 +2259,41 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) */ void intel_gvt_clean_gtt(struct intel_gvt *gvt) { + __free_page(gvt->gtt.scratch_ggtt_page); + if (enable_out_of_sync) clean_spt_oos(gvt); } + +/** + * intel_vgpu_reset_ggtt - reset the GGTT entry + * @vgpu: a vGPU + * + * This function is called at the vGPU create stage + * to reset all the GGTT entries. + * + */ +void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) +{ + struct intel_gvt *gvt = vgpu->gvt; + struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; + u32 index; + u32 offset; + u32 num_entries; + struct intel_gvt_gtt_entry e; + + memset(&e, 0, sizeof(struct intel_gvt_gtt_entry)); + e.type = GTT_TYPE_GGTT_PTE; + ops->set_pfn(&e, gvt->gtt.scratch_ggtt_mfn); + e.val64 |= _PAGE_PRESENT; + + index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT; + num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT; + for (offset = 0; offset < num_entries; offset++) + ops->set_entry(NULL, &e, index + offset, false, 0, vgpu); + + index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT; + num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT; + for (offset = 0; offset < num_entries; offset++) + ops->set_entry(NULL, &e, index + offset, false, 0, vgpu); +} diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index d250013bc37b..b315ab3593ec 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h @@ -81,6 +81,9 @@ struct intel_gvt_gtt { struct list_head oos_page_use_list_head; struct list_head oos_page_free_list_head; struct list_head mm_lru_list_head; + + struct page *scratch_ggtt_page; + unsigned long scratch_ggtt_mfn; }; enum { @@ -202,6 +205,7 @@ struct intel_vgpu_gtt { extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu); +void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu); extern int intel_gvt_init_gtt(struct intel_gvt *gvt); extern void intel_gvt_clean_gtt(struct intel_gvt *gvt); From bfeca3e5716a16b95a1fb7104e477ca3bd5ed59e Mon Sep 17 00:00:00 2001 From: Jike Song Date: Fri, 16 Dec 2016 10:51:04 +0800 Subject: [PATCH 041/359] drm/i915/gvt/kvmgt: dereference the pointer within lock Though there is no issue exposed yet, it's possible that another thread releases the entry while our trying to deref it out of the lock. Fit it by moving the dereference within lock. Signed-off-by: Jike Song Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/kvmgt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 4dd6722a7339..4ba196796846 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -114,12 +114,15 @@ static struct gvt_dma *__gvt_cache_find(struct intel_vgpu *vgpu, gfn_t gfn) static kvm_pfn_t gvt_cache_find(struct intel_vgpu *vgpu, gfn_t gfn) { struct gvt_dma *entry; + kvm_pfn_t pfn; mutex_lock(&vgpu->vdev.cache_lock); - entry = __gvt_cache_find(vgpu, gfn); - mutex_unlock(&vgpu->vdev.cache_lock); - return entry == NULL ? 0 : entry->pfn; + entry = __gvt_cache_find(vgpu, gfn); + pfn = (entry == NULL) ? 0 : entry->pfn; + + mutex_unlock(&vgpu->vdev.cache_lock); + return pfn; } static void gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, kvm_pfn_t pfn) From faaaa53bdc6750c438887d44f99b60ad97ec74b4 Mon Sep 17 00:00:00 2001 From: Jike Song Date: Fri, 16 Dec 2016 10:51:05 +0800 Subject: [PATCH 042/359] drm/i915/gvt/kvmgt: check returned slot for gfn gfn_to_memslot() may return NULL if the gfn is mmio or invalid. A malicious user might input a bad gfn to panic the host if we don't check it. Signed-off-by: Jike Song Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/kvmgt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 4ba196796846..8b3b071a535e 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1137,6 +1137,10 @@ static int kvmgt_write_protect_add(unsigned long handle, u64 gfn) idx = srcu_read_lock(&kvm->srcu); slot = gfn_to_memslot(kvm, gfn); + if (!slot) { + srcu_read_unlock(&kvm->srcu, idx); + return -EINVAL; + } spin_lock(&kvm->mmu_lock); @@ -1167,6 +1171,10 @@ static int kvmgt_write_protect_remove(unsigned long handle, u64 gfn) idx = srcu_read_lock(&kvm->srcu); slot = gfn_to_memslot(kvm, gfn); + if (!slot) { + srcu_read_unlock(&kvm->srcu, idx); + return -EINVAL; + } spin_lock(&kvm->mmu_lock); From 364fb6b789ffce44c1b5429086c47b0df6c36aff Mon Sep 17 00:00:00 2001 From: Jike Song Date: Fri, 16 Dec 2016 10:51:06 +0800 Subject: [PATCH 043/359] drm/i915/gvt/kvmgt: prevent double-release of vgpu The release action might be triggered from either user's closing mdev or the detaching event of kvm and vfio_group, so this patch introduces an atomic to prevent double-release. Signed-off-by: Jike Song Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gvt.h | 1 + drivers/gpu/drm/i915/gvt/kvmgt.c | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index ad0e9364ee70..0af17016f33f 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -175,6 +175,7 @@ struct intel_vgpu { struct notifier_block group_notifier; struct kvm *kvm; struct work_struct release_work; + atomic_t released; } vdev; #endif }; diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 8b3b071a535e..efb01435f13f 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -500,7 +500,16 @@ static int intel_vgpu_open(struct mdev_device *mdev) goto undo_iommu; } - return kvmgt_guest_init(mdev); + ret = kvmgt_guest_init(mdev); + if (ret) + goto undo_group; + + atomic_set(&vgpu->vdev.released, 0); + return ret; + +undo_group: + vfio_unregister_notifier(&mdev->dev, VFIO_GROUP_NOTIFY, + &vgpu->vdev.group_notifier); undo_iommu: vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, @@ -512,17 +521,26 @@ static int intel_vgpu_open(struct mdev_device *mdev) static void __intel_vgpu_release(struct intel_vgpu *vgpu) { struct kvmgt_guest_info *info; + int ret; if (!handle_valid(vgpu->handle)) return; - vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY, + if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1)) + return; + + ret = vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY, &vgpu->vdev.iommu_notifier); - vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY, + WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret); + + ret = vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY, &vgpu->vdev.group_notifier); + WARN(ret, "vfio_unregister_notifier for group failed: %d\n", ret); info = (struct kvmgt_guest_info *)vgpu->handle; kvmgt_guest_exit(info); + + vgpu->vdev.kvm = NULL; vgpu->handle = 0; } From 8ff842fd9eab69f8cf99fdd21ce25a5a0411473e Mon Sep 17 00:00:00 2001 From: Jike Song Date: Fri, 16 Dec 2016 10:51:07 +0800 Subject: [PATCH 044/359] drm/i915/gvt/kvmgt: trival: code cleanup Don't introduce local variables unless necessary. Signed-off-by: Jike Song Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/kvmgt.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index efb01435f13f..934963970288 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -555,6 +555,7 @@ static void intel_vgpu_release_work(struct work_struct *work) { struct intel_vgpu *vgpu = container_of(work, struct intel_vgpu, vdev.release_work); + __intel_vgpu_release(vgpu); } @@ -1340,18 +1341,14 @@ static int kvmgt_guest_init(struct mdev_device *mdev) static bool kvmgt_guest_exit(struct kvmgt_guest_info *info) { - struct intel_vgpu *vgpu; - if (!info) { gvt_err("kvmgt_guest_info invalid\n"); return false; } - vgpu = info->vgpu; - kvm_page_track_unregister_notifier(info->kvm, &info->track_node); kvmgt_protect_table_destroy(info); - gvt_cache_destroy(vgpu); + gvt_cache_destroy(info->vgpu); vfree(info); return true; From 34700631bd465de3e555e5964f36a0919c466aa8 Mon Sep 17 00:00:00 2001 From: Min He Date: Wed, 21 Dec 2016 14:54:48 +0800 Subject: [PATCH 045/359] drm/i915/gvt: fix an issue in emulating cfg space PCI_COMMAND There's an issue in current cfg space emulation for PCI_COMMAND (offset 0x4): when guest changes some bits other than PCI_COMMAND_MEMORY, this write operation will not be written to virutal cfg space successfully. This patch is to fix the wrong behavior above. Signed-off-by: Min He Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cfg_space.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index db516382a4d4..959c7f0144b4 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -123,6 +123,7 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu, u8 changed = old ^ new; int ret; + memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes); if (!(changed & PCI_COMMAND_MEMORY)) return 0; @@ -142,7 +143,6 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu, return ret; } - memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes); return 0; } From 4e0203ba11e735694600d7c704d7d56f069f9eb6 Mon Sep 17 00:00:00 2001 From: Pei Zhang Date: Fri, 23 Dec 2016 23:55:08 +0800 Subject: [PATCH 046/359] drm/i915/gvt: fix typo in cfg_space range check PCI basic config space's size is 256 bytes. When check if access crosses space range, should use "> 256". Signed-off-by: Pei Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cfg_space.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index 959c7f0144b4..711c31c8d8b4 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -240,7 +240,7 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, if (WARN_ON(bytes > 4)) return -EINVAL; - if (WARN_ON(offset + bytes >= INTEL_GVT_MAX_CFG_SPACE_SZ)) + if (WARN_ON(offset + bytes > INTEL_GVT_MAX_CFG_SPACE_SZ)) return -EINVAL; /* First check if it's PCI_COMMAND */ From 709f94ff018a4403d0bb32643254058d5d9cfa24 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Fri, 16 Dec 2016 14:43:56 +0000 Subject: [PATCH 047/359] ACPI: Drop misplaced acpi_dma_deconfigure() call from acpi_bind_one() The acpi_bind_one() error return path can be hit either on physical node allocation failure or if the device being configured is already associated with an ACPI node and its ACPI companion does not match the one acpi_bind_one() is setting it up with. In both cases the error return path is executed before DMA is configured for a device therefore there is no need to call acpi_dma_deconfigure() on the function error return path. Furthermore, if acpi_bind_one() does configure DMA for a device (ie it successfully executes acpi_dma_configure()) acpi_bind_one() always completes execution successfully hence there is no need to add an exit path to deconfigure the DMA set-up (ie by calling acpi_dma_deconfigure()). Remove the misplaced acpi_dma_deconfigure() in acpi_bind_one() to reinstate its correct error return path behaviour. Fixes: d760a1baf20e (ACPI: Implement acpi_dma_configure) Signed-off-by: Lorenzo Pieralisi Signed-off-by: Rafael J. Wysocki --- drivers/acpi/glue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index f8d65647ea79..eb709e7c9ffd 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -250,7 +250,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) return 0; err: - acpi_dma_deconfigure(dev); ACPI_COMPANION_SET(dev, NULL); put_device(dev); put_device(&acpi_dev->dev); From 9c4aa1eecb48cfac18ed5e3aca9d9ae58fbafc11 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 16 Dec 2016 12:07:57 +0800 Subject: [PATCH 048/359] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding Sometimes, the users may require a quirk to be provided from ACPI subsystem core to prevent a GPE from flooding. Normally, if a GPE cannot be dispatched, ACPICA core automatically prevents the GPE from firing. But there are cases the GPE is dispatched by _Lxx/_Exx provided via AML table, and OSPM is lacking of the knowledge to get _Lxx/_Exx correctly executed to handle the GPE, thus the GPE flooding may still occur. The existing quirk mechanism can be enabled/disabled using the following commands to prevent such kind of GPE flooding during runtime: # echo mask > /sys/firmware/acpi/interrupts/gpe00 # echo unmask > /sys/firmware/acpi/interrupts/gpe00 To avoid GPE flooding during boot, we need a boot stage mechanism. This patch provides such a boot stage quirk mechanism to stop this kind of GPE flooding. This patch doesn't fix any feature gap but since the new feature gaps could be found in the future endlessly, and can disappear if the feature gaps are filled, providing a boot parameter rather than a DMI table should suffice. Link: https://bugzilla.kernel.org/show_bug.cgi?id=53071 Link: https://bugzilla.kernel.org/show_bug.cgi?id=117481 Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/887793 Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- .../admin-guide/kernel-parameters.txt | 10 ++++ drivers/acpi/internal.h | 1 + drivers/acpi/scan.c | 1 + drivers/acpi/sysfs.c | 56 +++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 21e2d8863705..d1eec5ed1134 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -106,6 +106,16 @@ use by PCI Format: ,... + acpi_mask_gpe= [HW,ACPI] + Due to the existence of _Lxx/_Exx, some GPEs triggered + by unsupported hardware/firmware features can result in + GPE floodings that cannot be automatically disabled by + the GPE dispatcher. + This facility can be used to prevent such uncontrolled + GPE floodings. + Format: + Support masking of GPEs numbered from 0x00 to 0x7f. + acpi_no_auto_serialize [HW,ACPI] Disable auto-serialization of AML methods AML control methods that contain the opcodes to create diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 1b41a2739dac..0c452265c111 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -37,6 +37,7 @@ void acpi_amba_init(void); static inline void acpi_amba_init(void) {} #endif int acpi_sysfs_init(void); +void acpi_gpe_apply_masked_gpes(void); void acpi_container_init(void); void acpi_memory_hotplug_init(void); #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 45dec874ea55..192691880d55 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2074,6 +2074,7 @@ int __init acpi_scan_init(void) } } + acpi_gpe_apply_masked_gpes(); acpi_update_all_gpes(); acpi_ec_ecdt_start(); diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 703c26e7022c..cf05ae973381 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -708,6 +708,62 @@ static ssize_t counter_set(struct kobject *kobj, return result ? result : size; } +/* + * A Quirk Mechanism for GPE Flooding Prevention: + * + * Quirks may be needed to prevent GPE flooding on a specific GPE. The + * flooding typically cannot be detected and automatically prevented by + * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in + * the AML tables. This normally indicates a feature gap in Linux, thus + * instead of providing endless quirk tables, we provide a boot parameter + * for those who want this quirk. For example, if the users want to prevent + * the GPE flooding for GPE 00, they need to specify the following boot + * parameter: + * acpi_mask_gpe=0x00 + * The masking status can be modified by the following runtime controlling + * interface: + * echo unmask > /sys/firmware/acpi/interrupts/gpe00 + */ + +/* + * Currently, the GPE flooding prevention only supports to mask the GPEs + * numbered from 00 to 7f. + */ +#define ACPI_MASKABLE_GPE_MAX 0x80 + +static u64 __initdata acpi_masked_gpes; + +static int __init acpi_gpe_set_masked_gpes(char *val) +{ + u8 gpe; + + if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX) + return -EINVAL; + acpi_masked_gpes |= ((u64)1< Date: Thu, 22 Dec 2016 13:17:07 +0300 Subject: [PATCH 049/359] ACPI / watchdog: Print out error number when device creation fails If the platform device creation fails for whichever reason the driver prints out something like: [ 0.978837] ACPI: watchdog: Failed to create platform device However, that is quite confusing and does not include any information why it failed. To make it more understandable, reword it like: [ 0.978837] ACPI: watchdog: Device creation failed: -16 Which tells that we failed to create the watchdog device because some of the resources were already reserved (-EBUSY). Signed-off-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_watchdog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 13caebd679f5..8c4e0a18460a 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -114,7 +114,7 @@ void __init acpi_watchdog_init(void) pdev = platform_device_register_simple("wdat_wdt", PLATFORM_DEVID_NONE, resources, nresources); if (IS_ERR(pdev)) - pr_err("Failed to create platform device\n"); + pr_err("Device creation failed: %ld\n", PTR_ERR(pdev)); kfree(resources); From 366430b5c2f61a75d45b9fc00886ffff12f395ab Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 24 Dec 2016 00:29:56 +0100 Subject: [PATCH 050/359] cpufreq: intel_pstate: Do not expose PID parameters in passive mode If intel_pstate works in the passive mode in which it acts as a regular cpufreq driver and collaborates with generic cpufreq governors, the PID parameters are not used, so do not expose them via debugfs in that case. Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7cd0177ddeaf..0d01cb2dc6d2 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -964,10 +964,6 @@ static void __init intel_pstate_debug_expose_params(void) struct dentry *debugfs_parent; int i = 0; - if (hwp_active || - pstate_funcs.get_target_pstate == get_target_pstate_use_cpu_load) - return; - debugfs_parent = debugfs_create_dir("pstate_snb", NULL); if (IS_ERR_OR_NULL(debugfs_parent)) return; @@ -2433,7 +2429,10 @@ static int __init intel_pstate_init(void) if (rc) goto out; - intel_pstate_debug_expose_params(); + if (intel_pstate_driver == &intel_pstate && !hwp_active && + pstate_funcs.get_target_pstate != get_target_pstate_use_cpu_load) + intel_pstate_debug_expose_params(); + intel_pstate_sysfs_expose_params(); if (hwp_active) From 3d37d41a148c32389ed360e10a9f8a7cd37ce166 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:33 -0300 Subject: [PATCH 051/359] ARM: dts: omap2: Add an empty chosen node to top level DTSI Commit d1f3156fc8c7 ("ARM: dts: omap2: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: d1f3156fc8c7 ("ARM: dts: omap2: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap2.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index 4f793a025a72..f1d6de8b3c19 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -17,6 +17,7 @@ / { interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>; + chosen { }; aliases { serial0 = &uart1; From 23ab4c6183ac0679d80888b5c4cc1d528fcc21c2 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:34 -0300 Subject: [PATCH 052/359] ARM: dts: omap3: Add an empty chosen node to top level DTSI Commit 008a2ebcd677 ("ARM: dts: omap3: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: 008a2ebcd677 ("ARM: dts: omap3: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index ecf5eb584c75..a3ff4933dbc1 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -17,6 +17,7 @@ / { interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>; + chosen { }; aliases { i2c0 = &i2c1; From 6c565d1a63ce241a0100f5d327c48dde87b4df76 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:35 -0300 Subject: [PATCH 053/359] ARM: dts: omap4: Add an empty chosen node to top level DTSI Commit da6269e7e3dd ("ARM: dts: omap4: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: da6269e7e3dd ("ARM: dts: omap4: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap4.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 8087456b5fbe..578c53f08309 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -15,6 +15,7 @@ / { interrupt-parent = <&wakeupgen>; #address-cells = <1>; #size-cells = <1>; + chosen { }; aliases { i2c0 = &i2c1; From c9faa84cb9c34852ad70cb175457ae21fc06f39b Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:36 -0300 Subject: [PATCH 054/359] ARM: dts: omap5: Add an empty chosen node to top level DTSI Commit 76a8548ea987 ("ARM: dts: omap5: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: 76a8548ea987 ("ARM: dts: omap5: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap5.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 968c67a49dbd..7cd92babc41a 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -17,6 +17,7 @@ / { compatible = "ti,omap5"; interrupt-parent = <&wakeupgen>; + chosen { }; aliases { i2c0 = &i2c1; From 1d8d6d3f2f7d553c479f24ab93767974a8c2dfad Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:37 -0300 Subject: [PATCH 055/359] ARM: dts: am33xx: Add an empty chosen node to top level DTSI Commit f8bf01611c99 ("ARM: dts: am33xx: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: f8bf01611c99 ("ARM: dts: am33xx: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am33xx.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 64c8aa9057a3..18d72a245e88 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -16,6 +16,7 @@ / { interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>; + chosen { }; aliases { i2c0 = &i2c0; From ce95077d0cdfcc8e40dea10a1680249831ccec77 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:38 -0300 Subject: [PATCH 056/359] ARM: dts: am4372: Add an empty chosen node to top level DTSI Commit 75813028bbd7 ("ARM: dts: am4372: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: 75813028bbd7 ("ARM: dts: am4372: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am4372.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index ac55f93fc91e..2df9e6050c2f 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -16,6 +16,7 @@ / { interrupt-parent = <&wakeupgen>; #address-cells = <1>; #size-cells = <1>; + chosen { }; memory@0 { device_type = "memory"; From 9536fd30d41ae4f30d04762676e5f5f602e16aa8 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:39 -0300 Subject: [PATCH 057/359] ARM: dts: dm814x: Add an empty chosen node to top level DTSI Commit 76155b378c59 ("ARM: dts: dm814x: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: 76155b378c59 ("ARM: dts: dm814x: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dm814x.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi index 1facc5f12cef..81b8cecb5820 100644 --- a/arch/arm/boot/dts/dm814x.dtsi +++ b/arch/arm/boot/dts/dm814x.dtsi @@ -12,6 +12,7 @@ / { interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>; + chosen { }; aliases { i2c0 = &i2c1; From 6ed80b3a232e61da6d0189bbbe2b2b9afaefe3b3 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:40 -0300 Subject: [PATCH 058/359] ARM: dts: dm816x: Add an empty chosen node to top level DTSI Commit 06bfb9c19957 ("ARM: dts: dm816x: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: 06bfb9c19957 ("ARM: dts: dm816x: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dm816x.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index 61dd2f6b02bc..6db652ae9bd5 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi @@ -12,6 +12,7 @@ / { interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>; + chosen { }; aliases { i2c0 = &i2c1; From 7f6c857b12911ed56b2056f9d5491e16b5fc95ea Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 19 Dec 2016 11:44:41 -0300 Subject: [PATCH 059/359] ARM: dts: dra7: Add an empty chosen node to top level DTSI Commit 55871eb6e2cc ("ARM: dts: dra7: Remove skeleton.dtsi usage") removed the skeleton.dtsi usage since we want to get rid of it. But this can cause issues when booting a kernel with a boot-loader that doesn't create a chosen node if this isn't present in the DTB since the decompressor relies on a pre-existing chosen node to be available to insert the command line and merge other ATAGS info. Fixes: 55871eb6e2cc ("ARM: dts: dra7: Remove skeleton.dtsi usage") Reported-by: Pali Rohar Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index addb7530cfbe..1faf24acd521 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -18,6 +18,7 @@ / { compatible = "ti,dra7xx"; interrupt-parent = <&crossbar_mpu>; + chosen { }; aliases { i2c0 = &i2c1; From 7245f67f86e847769f41dacad26bb8f5b5d74bf4 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 3 Dec 2016 04:57:23 -0600 Subject: [PATCH 060/359] ARM: dts: omap3: Add DTS for Logic PD SOM-LV 37xx Dev Kit Fixes: ("ab8dd3aed011 ARM: DTS: Add minimal Support for Logic PD DM3730 SOM-LV") This adds the dts file into the Makefile. This should have been included in the original patch. V2: Update patch description - same source code V1: Original patch Reviewed-by: Javier Martinez Canillas Signed-off-by: Adam Ford Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index cccdbcb557b6..7327250f0bb6 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -501,6 +501,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \ am3517-evm.dtb \ am3517_mt_ventoux.dtb \ logicpd-torpedo-37xx-devkit.dtb \ + logicpd-som-lv-37xx-devkit.dtb \ omap3430-sdp.dtb \ omap3-beagle.dtb \ omap3-beagle-xm.dtb \ From f86a2c875fd146d9b82c8fdd86d31084507bcf4c Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 5 Dec 2016 09:27:44 +0530 Subject: [PATCH 061/359] ARM: omap2+: am437x: rollback to use omap3_gptimer_timer_init() The commit 55ee7017ee31 ("arm: omap2: board-generic: use omap4_local_timer_init for AM437x") unintentionally changes the clocksource devices for AM437x from OMAP GP Timer to SyncTimer32K. Unfortunately, the SyncTimer32K is starving from frequency deviation as mentioned in commit 5b5c01359152 ("ARM: OMAP2+: AM43x: Use gptimer as clocksource") and, as reported by Franklin [1], even its monotonic nature is under question (most probably there is a HW issue, but it's still under investigation). Taking into account above facts It's reasonable to rollback to the use of omap3_gptimer_timer_init(). [1] http://www.spinics.net/lists/linux-omap/msg127425.html Fixes: 55ee7017ee31 ("arm: omap2: board-generic: use omap4_local_timer_init for AM437x") Reported-by: Cooper Jr., Franklin Signed-off-by: Grygorii Strashko Signed-off-by: Lokesh Vutla Signed-off-by: Keerthy Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-generic.c | 2 +- arch/arm/mach-omap2/timer.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 36d9943205ca..dc9e34e670a2 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -304,7 +304,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") .init_late = am43xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .init_time = omap4_local_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = am43_boards_compat, .restart = omap44xx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 56128da23c3a..07dd692c4737 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -510,18 +510,19 @@ void __init omap3_secure_sync32k_timer_init(void) } #endif /* CONFIG_ARCH_OMAP3 */ -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \ + defined(CONFIG_SOC_AM43XX) void __init omap3_gptimer_timer_init(void) { __omap_sync32k_timer_init(2, "timer_sys_ck", NULL, 1, "timer_sys_ck", "ti,timer-alwon", true); - - clocksource_probe(); + if (of_have_populated_dt()) + clocksource_probe(); } #endif #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ - defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX) + defined(CONFIG_SOC_DRA7XX) static void __init omap4_sync32k_timer_init(void) { __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon", From 5066d5296ff2db20625e5f46e7338872c90c649f Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Thu, 8 Dec 2016 09:40:30 +0530 Subject: [PATCH 062/359] ARM: omap2+: fixing wrong strcat for Non-NULL terminated string Issue caught with static analysis tool: "Dangerous usage of 'name' (strncpy doesn't always 0-terminate it)" Use strlcpy _includes_ the NUL terminator, and strlcat() which ensures that it won't overflow the buffer. Reported-by: Maninder Singh Signed-off-by: Vaneet Narang CC: Russell King Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 759e1d45ba25..e8b988714a09 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -741,14 +741,14 @@ static int _init_main_clk(struct omap_hwmod *oh) int ret = 0; char name[MOD_CLK_MAX_NAME_LEN]; struct clk *clk; + static const char modck[] = "_mod_ck"; - /* +7 magic comes from '_mod_ck' suffix */ - if (strlen(oh->name) + 7 > MOD_CLK_MAX_NAME_LEN) + if (strlen(oh->name) >= MOD_CLK_MAX_NAME_LEN - strlen(modck)) pr_warn("%s: warning: cropping name for %s\n", __func__, oh->name); - strncpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - 7); - strcat(name, "_mod_ck"); + strlcpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - strlen(modck)); + strlcat(name, modck, MOD_CLK_MAX_NAME_LEN); clk = clk_get(NULL, name); if (!IS_ERR(clk)) { From 30aa2e48962c6e4cd5258840f55f2f413b0bdbb4 Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Fri, 9 Dec 2016 15:28:30 +0900 Subject: [PATCH 063/359] ARM: dts: am335x: Fix the interrupt name of TPS65217 Use 'interrupt-names' for getting the charger interrupt number. Fixes: 1934e89a769b ("ARM: dts: am335x: Add the charger interrupt") Signed-off-by: Milo Kim Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-bone-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index dc561d505bbe..14b62690c464 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -320,7 +320,7 @@ &tps { charger { interrupts = , ; - interrupts-names = "AC", "USB"; + interrupt-names = "AC", "USB"; status = "okay"; }; From be53e38f0df21c3d45cdf4cede37ee73554cdbb8 Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Fri, 9 Dec 2016 15:28:31 +0900 Subject: [PATCH 064/359] dt-bindings: mfd: Remove TPS65217 interrupts Interrupt numbers are from the datasheet, so no need to keep them in the ABI. Use the number in the DT file. Signed-off-by: Milo Kim Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-bone-common.dtsi | 8 +++---- include/dt-bindings/mfd/tps65217.h | 26 ----------------------- 2 files changed, 3 insertions(+), 31 deletions(-) delete mode 100644 include/dt-bindings/mfd/tps65217.h diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 14b62690c464..3e32dd18fd25 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -6,8 +6,6 @@ * published by the Free Software Foundation. */ -#include - / { cpus { cpu@0 { @@ -319,13 +317,13 @@ &tps { ti,pmic-shutdown-controller; charger { - interrupts = , ; - interrupt-names = "AC", "USB"; + interrupts = <0>, <1>; + interrupt-names = "USB", "AC"; status = "okay"; }; pwrbutton { - interrupts = ; + interrupts = <2>; status = "okay"; }; diff --git a/include/dt-bindings/mfd/tps65217.h b/include/dt-bindings/mfd/tps65217.h deleted file mode 100644 index cafb9e60cf12..000000000000 --- a/include/dt-bindings/mfd/tps65217.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This header provides macros for TI TPS65217 DT bindings. - * - * Copyright (C) 2016 Texas Instruments - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#ifndef __DT_BINDINGS_TPS65217_H__ -#define __DT_BINDINGS_TPS65217_H__ - -#define TPS65217_IRQ_USB 0 -#define TPS65217_IRQ_AC 1 -#define TPS65217_IRQ_PB 2 - -#endif From 81d7358d7038dd1001547950087e5b0641732f3f Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Fri, 9 Dec 2016 15:28:32 +0900 Subject: [PATCH 065/359] dt-bindings: power/supply: Update TPS65217 properties Add interrupt specifiers for USB and AC charger input. Interrupt numbers are from the datasheet. Fix wrong property for compatible string. Signed-off-by: Milo Kim Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- .../devicetree/bindings/power/supply/tps65217_charger.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt b/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt index 98d131acee95..a11072c5a866 100644 --- a/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt +++ b/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt @@ -2,11 +2,16 @@ TPS65217 Charger Required Properties: -compatible: "ti,tps65217-charger" +-interrupts: TPS65217 interrupt numbers for the AC and USB charger input change. + Should be <0> for the USB charger and <1> for the AC adapter. +-interrupt-names: Should be "USB" and "AC" This node is a subnode of the tps65217 PMIC. Example: tps65217-charger { - compatible = "ti,tps65090-charger"; + compatible = "ti,tps65217-charger"; + interrupts = <0>, <1>; + interrupt-names = "USB", "AC"; }; From 820381572fc015baa4f5744f5d4583ec0c0f1b82 Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Fri, 9 Dec 2016 15:28:33 +0900 Subject: [PATCH 066/359] dt-bindings: input: Specify the interrupt number of TPS65217 power button Specify the power button interrupt number which is from the datasheet. Signed-off-by: Milo Kim Acked-by: Rob Herring Signed-off-by: Tony Lindgren --- .../devicetree/bindings/input/tps65218-pwrbutton.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt index 3e5b9793341f..8682ab6d4a50 100644 --- a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt +++ b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt @@ -8,8 +8,9 @@ This driver provides a simple power button event via an Interrupt. Required properties: - compatible: should be "ti,tps65217-pwrbutton" or "ti,tps65218-pwrbutton" -Required properties for TPS65218: +Required properties: - interrupts: should be one of the following + - <2>: For controllers compatible with tps65217 - <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218 Examples: @@ -17,6 +18,7 @@ Examples: &tps { tps65217-pwrbutton { compatible = "ti,tps65217-pwrbutton"; + interrupts = <2>; }; }; From 10d27dfaf6b6ce3bd7598b1e20e58446c5697a50 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 12 Dec 2016 11:58:04 +0200 Subject: [PATCH 067/359] ARM: dts: am57xx-idk: Support VBUS detection on USB2 port VBUS detection is available on the board via the palmas PMIC. Use extcon-palmas driver instead of extcon-gpio-usb driver. Signed-off-by: Roger Quadros Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am571x-idk.dts | 10 +++++----- arch/arm/boot/dts/am572x-idk.dts | 10 +++++----- arch/arm/boot/dts/am57xx-idk-common.dtsi | 7 +++++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts index d6e43e5184c1..ad68d1eb3bc3 100644 --- a/arch/arm/boot/dts/am571x-idk.dts +++ b/arch/arm/boot/dts/am571x-idk.dts @@ -62,11 +62,6 @@ mmc0-led { linux,default-trigger = "mmc0"; }; }; - - extcon_usb2: extcon_usb2 { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>; - }; }; &mmc1 { @@ -79,3 +74,8 @@ &mmc1 { &omap_dwc3_2 { extcon = <&extcon_usb2>; }; + +&extcon_usb2 { + id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>; + vbus-gpio = <&gpio7 22 GPIO_ACTIVE_HIGH>; +}; diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts index 27d9149cedba..4ed40be761b2 100644 --- a/arch/arm/boot/dts/am572x-idk.dts +++ b/arch/arm/boot/dts/am572x-idk.dts @@ -23,11 +23,6 @@ memory@0 { reg = <0x0 0x80000000 0x0 0x80000000>; }; - extcon_usb2: extcon_usb2 { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>; - }; - status-leds { compatible = "gpio-leds"; cpu0-led { @@ -76,6 +71,11 @@ &omap_dwc3_2 { extcon = <&extcon_usb2>; }; +&extcon_usb2 { + id-gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>; + vbus-gpio = <&gpio3 26 GPIO_ACTIVE_HIGH>; +}; + &mmc1 { status = "okay"; vmmc-supply = <&v3_3d>; diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi index 555ae21f2b9a..14bdb24e67ce 100644 --- a/arch/arm/boot/dts/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi @@ -303,6 +303,13 @@ tps659038_gpio: tps659038_gpio { gpio-controller; #gpio-cells = <2>; }; + + extcon_usb2: tps659038_usb { + compatible = "ti,palmas-usb-vid"; + ti,enable-vbus-detection; + ti,enable-id-detection; + /* ID & VBUS GPIOs provided in board dts */ + }; }; }; From 5acd016c88937be3667ba4e6b60f0f74455b5e80 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 12 Dec 2016 11:58:05 +0200 Subject: [PATCH 068/359] ARM: dts: am57xx-idk: Put USB2 port in peripheral mode USB2 port can be operated in dual-role mode but till we have dual-role support in dwc3 driver let's limit this port to peripheral mode. If we don't do so it defaults to host mode. USB1 port is meant for host only operation and we don't want both ports in host only mode. Signed-off-by: Roger Quadros Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am57xx-idk-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi index 14bdb24e67ce..814a720d5c3d 100644 --- a/arch/arm/boot/dts/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi @@ -376,7 +376,7 @@ &usb1 { }; &usb2 { - dr_mode = "otg"; + dr_mode = "peripheral"; }; &mmc2 { From 1a177cf72b3a6226f01652df8292d07edf67e7af Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Wed, 14 Dec 2016 14:27:03 +0530 Subject: [PATCH 069/359] ARM: dts: dra72-evm-tps65917: Add voltage supplies to usb_phy, mmc, dss Commit 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917") added a separate dtsi for dra72-evm-tps65917 moving all the voltage supplies to this file. But it missed adding voltage supplies to usb_phy, mmc, dss and deleted from dra72-evm-common.dtsi. Adding the voltage supply phandles to these nodes in dra72-evm-tps65917.dtsi Fixes: 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917") Reported-by: Carlos Hernandez Signed-off-by: Roger Quadros Signed-off-by: Lokesh Vutla Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra72-evm-tps65917.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi index ee6dac44edf1..e6df676886c0 100644 --- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi +++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi @@ -132,3 +132,19 @@ tps65917_power_button { ti,palmas-long-press-seconds = <6>; }; }; + +&usb2_phy1 { + phy-supply = <&ldo4_reg>; +}; + +&usb2_phy2 { + phy-supply = <&ldo4_reg>; +}; + +&dss { + vdda_video-supply = <&ldo5_reg>; +}; + +&mmc1 { + vmmc_aux-supply = <&ldo1_reg>; +}; From 4cf48f1d7520a4d325af58eded4d8090e1b40be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 14 Dec 2016 22:29:44 +0100 Subject: [PATCH 070/359] ARM: dts: n900: Mark eMMC slot with no-sdio and no-sd flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to initialize eMMC slot as SDIO or SD cause failure in n900 port of qemu. eMMC itself is not detected and is not working. Real Nokia N900 harware does not have this problem. As eMMC is really not SDIO or SD based such change is harmless and will fix support for qemu. Signed-off-by: Pali Rohár Acked-by: Pavel Machek Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-n900.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 87ca50b53002..4d448f145ed1 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -734,6 +734,8 @@ &mmc2 { vmmc_aux-supply = <&vsim>; bus-width = <8>; non-removable; + no-sdio; + no-sd; }; &mmc3 { From 9a6b6f75d9daa892ae8f6e5ed6ae0ab49b9586cb Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 3 Dec 2016 21:46:02 +0100 Subject: [PATCH 071/359] ARM: OMAP2+: PRM: Delete an error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. Link: http://events.linuxfoundation.org/sites/events/files/slides/LCJ16-Refactor_Strings-WSang_0.pdf Signed-off-by: Markus Elfring Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/prm_common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 5b2f5138d938..2b138b65129a 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -295,10 +295,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) GFP_KERNEL); if (!prcm_irq_chips || !prcm_irq_setup->saved_mask || - !prcm_irq_setup->priority_mask) { - pr_err("PRCM: kzalloc failed\n"); + !prcm_irq_setup->priority_mask) goto err; - } memset(mask, 0, sizeof(mask)); From fe4f6c801c03bc13113d0dc32f02d4ea8ed89ffd Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 27 Dec 2016 19:46:27 -0500 Subject: [PATCH 072/359] fscrypt: fix the test_dummy_encryption mount option Commit f1c131b45410a: "crypto: xts - Convert to skcipher" now fails the setkey operation if the AES key is the same as the tweak key. Previously this check was only done if FIPS mode is enabled. Now this check is also done if weak key checking was requested. This is reasonable, but since we were using the dummy key which was a constant series of 0x42 bytes, it now caused dummy encrpyption test mode to fail. Fix this by using 0x42... and 0x24... for the two keys, so they are different. Fixes: f1c131b45410a202eb45cc55980a7a9e4e4b4f40 Cc: stable@vger.kernel.org Signed-off-by: Theodore Ts'o --- fs/crypto/keyinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index 6eeea1dcba41..95cd4c3b06c3 100644 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -248,7 +248,8 @@ int fscrypt_get_crypt_info(struct inode *inode) goto out; if (fscrypt_dummy_context_enabled(inode)) { - memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE); + memset(raw_key, 0x42, keysize/2); + memset(raw_key+keysize/2, 0x24, keysize - (keysize/2)); goto got_key; } From 5701659004d68085182d2fd4199c79172165fa65 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 27 Dec 2016 18:23:06 -0800 Subject: [PATCH 073/359] net: stmmac: Fix race between stmmac_drv_probe and stmmac_open There is currently a small window during which the network device registered by stmmac can be made visible, yet all resources, including and clock and MDIO bus have not had a chance to be set up, this can lead to the following error to occur: [ 473.919358] stmmaceth 0000:01:00.0 (unnamed net_device) (uninitialized): stmmac_dvr_probe: warning: cannot get CSR clock [ 473.919382] stmmaceth 0000:01:00.0: no reset control found [ 473.919412] stmmac - user ID: 0x10, Synopsys ID: 0x42 [ 473.919429] stmmaceth 0000:01:00.0: DMA HW capability register supported [ 473.919436] stmmaceth 0000:01:00.0: RX Checksum Offload Engine supported [ 473.919443] stmmaceth 0000:01:00.0: TX Checksum insertion supported [ 473.919451] stmmaceth 0000:01:00.0 (unnamed net_device) (uninitialized): Enable RX Mitigation via HW Watchdog Timer [ 473.921395] libphy: PHY stmmac-1:00 not found [ 473.921417] stmmaceth 0000:01:00.0 eth0: Could not attach to PHY [ 473.921427] stmmaceth 0000:01:00.0 eth0: stmmac_open: Cannot attach to PHY (error: -19) [ 473.959710] libphy: stmmac: probed [ 473.959724] stmmaceth 0000:01:00.0 eth0: PHY ID 01410cc2 at 0 IRQ POLL (stmmac-1:00) active [ 473.959728] stmmaceth 0000:01:00.0 eth0: PHY ID 01410cc2 at 1 IRQ POLL (stmmac-1:01) [ 473.959731] stmmaceth 0000:01:00.0 eth0: PHY ID 01410cc2 at 2 IRQ POLL (stmmac-1:02) [ 473.959734] stmmaceth 0000:01:00.0 eth0: PHY ID 01410cc2 at 3 IRQ POLL (stmmac-1:03) Fix this by making sure that register_netdev() is the last thing being done, which guarantees that the clock and the MDIO bus are available. Fixes: 4bfcbd7abce2 ("stmmac: Move the mdio_register/_unregister in probe/remove") Reported-by: Kweh, Hock Leong Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index bb40382e205d..5910ea51f8f6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3339,13 +3339,6 @@ int stmmac_dvr_probe(struct device *device, spin_lock_init(&priv->lock); - ret = register_netdev(ndev); - if (ret) { - netdev_err(priv->dev, "%s: ERROR %i registering the device\n", - __func__, ret); - goto error_netdev_register; - } - /* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be * changed at run-time and it is fixed. Viceversa the driver'll try to @@ -3372,11 +3365,14 @@ int stmmac_dvr_probe(struct device *device, } } - return 0; + ret = register_netdev(ndev); + if (ret) + netdev_err(priv->dev, "%s: ERROR %i registering the device\n", + __func__, ret); + + return ret; error_mdio_register: - unregister_netdev(ndev); -error_netdev_register: netif_napi_del(&priv->napi); error_hw_init: clk_disable_unprepare(priv->pclk); From f6c5c1f96d976e1fb9d71fb824629c450ee0a122 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 27 Dec 2016 14:28:51 -0800 Subject: [PATCH 074/359] platform/x86: fix surface3_button build errors Fix build errors when I2C=m and SURFACE_3_BUTTON=y. The driver uses i2c interfaces so it should depend on I2C. drivers/built-in.o: In function `surface3_driver_init': surface3_button.c:(.init.text+0x75cb0): undefined reference to `i2c_register_driver' drivers/built-in.o: In function `surface3_driver_exit': surface3_button.c:(.exit.text+0x31a8): undefined reference to `i2c_del_driver' Fixes: 1a64b719d3ae (platform/x86: Introduce button support for the Surface 3) Signed-off-by: Randy Dunlap Reported-by: kbuild test robot Cc: Benjamin Tissoires Cc: platform-driver-x86@vger.kernel.org Cc: Darren Hart Signed-off-by: Andy Shevchenko --- drivers/platform/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 5fe8be089b8b..59aa8e302bc3 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1034,7 +1034,7 @@ config SURFACE_PRO3_BUTTON config SURFACE_3_BUTTON tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet" - depends on ACPI && KEYBOARD_GPIO + depends on ACPI && KEYBOARD_GPIO && I2C ---help--- This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet. From a608a9d52fa4168efd478d684039ed545a69dbcd Mon Sep 17 00:00:00 2001 From: Micha? K?pie? Date: Fri, 23 Dec 2016 10:00:08 +0100 Subject: [PATCH 075/359] platform/x86: fujitsu-laptop: use brightness_set_blocking for LED-setting callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All LED-setting functions in fujitsu-laptop are currently assigned to the brightness_set callback, which is incorrect because they can sleep (due to their use of call_fext_func(), which in turn issues ACPI calls) and the documentation (in include/linux/leds.h) clearly states they must not. Assign them to brightness_set_blocking instead and change them to match the expected function prototype. This change makes it possible to use Fujitsu-specific LEDs with "heavy" triggers, like disk-activity or phy0rx. Fixes: 3a407086090b ("fujitsu-laptop: Add BL power, LED control and radio state information") Fixes: 4f62568c1fcf ("fujitsu-laptop: Support radio LED") Fixes: d6b88f64b0d4 ("fujitsu-laptop: Add support for eco LED") Signed-off-by: Michał Kępień Acked-by: Jonathan Woithe Signed-off-by: Andy Shevchenko --- drivers/platform/x86/fujitsu-laptop.c | 42 +++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 61f39abf5dc8..82d67715ce76 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -177,43 +177,43 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); #if IS_ENABLED(CONFIG_LEDS_CLASS) static enum led_brightness logolamp_get(struct led_classdev *cdev); -static void logolamp_set(struct led_classdev *cdev, +static int logolamp_set(struct led_classdev *cdev, enum led_brightness brightness); static struct led_classdev logolamp_led = { .name = "fujitsu::logolamp", .brightness_get = logolamp_get, - .brightness_set = logolamp_set + .brightness_set_blocking = logolamp_set }; static enum led_brightness kblamps_get(struct led_classdev *cdev); -static void kblamps_set(struct led_classdev *cdev, +static int kblamps_set(struct led_classdev *cdev, enum led_brightness brightness); static struct led_classdev kblamps_led = { .name = "fujitsu::kblamps", .brightness_get = kblamps_get, - .brightness_set = kblamps_set + .brightness_set_blocking = kblamps_set }; static enum led_brightness radio_led_get(struct led_classdev *cdev); -static void radio_led_set(struct led_classdev *cdev, +static int radio_led_set(struct led_classdev *cdev, enum led_brightness brightness); static struct led_classdev radio_led = { .name = "fujitsu::radio_led", .brightness_get = radio_led_get, - .brightness_set = radio_led_set + .brightness_set_blocking = radio_led_set }; static enum led_brightness eco_led_get(struct led_classdev *cdev); -static void eco_led_set(struct led_classdev *cdev, +static int eco_led_set(struct led_classdev *cdev, enum led_brightness brightness); static struct led_classdev eco_led = { .name = "fujitsu::eco_led", .brightness_get = eco_led_get, - .brightness_set = eco_led_set + .brightness_set_blocking = eco_led_set }; #endif @@ -267,48 +267,48 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) #if IS_ENABLED(CONFIG_LEDS_CLASS) /* LED class callbacks */ -static void logolamp_set(struct led_classdev *cdev, +static int logolamp_set(struct led_classdev *cdev, enum led_brightness brightness) { if (brightness >= LED_FULL) { call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); - call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON); + return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON); } else if (brightness >= LED_HALF) { call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); - call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF); + return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF); } else { - call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF); + return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF); } } -static void kblamps_set(struct led_classdev *cdev, +static int kblamps_set(struct led_classdev *cdev, enum led_brightness brightness) { if (brightness >= LED_FULL) - call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON); + return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON); else - call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF); + return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF); } -static void radio_led_set(struct led_classdev *cdev, +static int radio_led_set(struct led_classdev *cdev, enum led_brightness brightness) { if (brightness >= LED_FULL) - call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON); + return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON); else - call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0); + return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0); } -static void eco_led_set(struct led_classdev *cdev, +static int eco_led_set(struct led_classdev *cdev, enum led_brightness brightness) { int curr; curr = call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0); if (brightness >= LED_FULL) - call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr | ECO_LED_ON); + return call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr | ECO_LED_ON); else - call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr & ~ECO_LED_ON); + return call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr & ~ECO_LED_ON); } static enum led_brightness logolamp_get(struct led_classdev *cdev) From 0df0f207aab4f42e5c96a807adf9a6845b69e984 Mon Sep 17 00:00:00 2001 From: Paul Blakey Date: Wed, 28 Dec 2016 14:54:47 +0200 Subject: [PATCH 076/359] net/sched: cls_flower: Fix missing addr_type in classify Since we now use a non zero mask on addr_type, we are matching on its value (IPV4/IPV6). So before this fix, matching on enc_src_ip/enc_dst_ip failed in SW/classify path since its value was zero. This patch sets the proper value of addr_type for encapsulated packets. Fixes: 970bfcd09791 ('net/sched: cls_flower: Use mask for addr_type') Signed-off-by: Paul Blakey Reviewed-by: Hadar Hen Zion Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- net/sched/cls_flower.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 333f8e268431..970db7a41684 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -153,10 +153,14 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, switch (ip_tunnel_info_af(info)) { case AF_INET: + skb_key.enc_control.addr_type = + FLOW_DISSECTOR_KEY_IPV4_ADDRS; skb_key.enc_ipv4.src = key->u.ipv4.src; skb_key.enc_ipv4.dst = key->u.ipv4.dst; break; case AF_INET6: + skb_key.enc_control.addr_type = + FLOW_DISSECTOR_KEY_IPV6_ADDRS; skb_key.enc_ipv6.src = key->u.ipv6.src; skb_key.enc_ipv6.dst = key->u.ipv6.dst; break; From 9da34cd34e85aacc55af8774b81b1f23e86014f9 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Wed, 28 Dec 2016 14:58:31 +0200 Subject: [PATCH 077/359] net/mlx5: Disable RoCE on the e-switch management port under switchdev mode Under the switchdev/offloads mode, packets that don't match any e-switch steering rule are sent towards the e-switch management port. We use a NIC HW steering rule set per vport (uplink and VFs) to make them be received into the host OS through the respective vport representor netdevice. Currnetly such missed RoCE packets will not get to this NIC steering rule, and hence VF RoCE will not work over the slow path of the offloads mode. This is b/c these packets will be matched by a steering rule added by the firmware that serves RoCE traffic set on the PF NIC vport which is also the e-switch management port under SRIOV. Disabling RoCE on the e-switch management vport when we are in the offloads mode, will signal to the firmware to remove their RoCE rule, and then the missed RoCE packets will be matched by the representor NIC steering rule as any other missed packets. To achieve that, we disable RoCE on the PF vport. We do that by removing (hot-unplugging) the IB device instance associated with the PF. This is also required by our current model where the PF serves as the uplink representor and hence only SW switching (TC, bridge, OVS) applications and slow path vport mlx5e net-device should be running over that vport. Fixes: c930a3ad7453 ('net/mlx5e: Add devlink based SRIOV mode changes') Signed-off-by: Or Gerlitz Reviewed-by: Hadar Hen Zion Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 466e161010f7..03293ed1cc22 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -695,6 +695,12 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int nvports) if (err) goto err_reps; } + + /* disable PF RoCE so missed packets don't go through RoCE steering */ + mlx5_dev_list_lock(); + mlx5_remove_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB); + mlx5_dev_list_unlock(); + return 0; err_reps: @@ -718,6 +724,11 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw) { int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs; + /* enable back PF RoCE */ + mlx5_dev_list_lock(); + mlx5_add_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB); + mlx5_dev_list_unlock(); + mlx5_eswitch_disable_sriov(esw); err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY); if (err) { From 883371c453b937f9eb581fb4915210865982736f Mon Sep 17 00:00:00 2001 From: Noa Osherovich Date: Wed, 28 Dec 2016 14:58:32 +0200 Subject: [PATCH 078/359] net/mlx5: Check FW limitations on log_max_qp before setting it When setting HCA capabilities, set log_max_qp to be the minimum between the selected profile's value and the HCA limitation. Fixes: 938fe83c8dcb ('net/mlx5_core: New device capabilities...') Signed-off-by: Noa Osherovich Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 54e5a786f191..23c12f1aaa39 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -503,6 +503,13 @@ static int handle_hca_cap(struct mlx5_core_dev *dev) MLX5_SET(cmd_hca_cap, set_hca_cap, pkey_table_size, to_fw_pkey_sz(dev, 128)); + /* Check log_max_qp from HCA caps to set in current profile */ + if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < profile[prof_sel].log_max_qp) { + mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n", + profile[prof_sel].log_max_qp, + MLX5_CAP_GEN_MAX(dev, log_max_qp)); + profile[prof_sel].log_max_qp = MLX5_CAP_GEN_MAX(dev, log_max_qp); + } if (prof->mask & MLX5_PROF_MASK_QP_SIZE) MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_qp, prof->log_max_qp); From 689a248df83b6032edc57e86267b4e5cc8d7174e Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Wed, 28 Dec 2016 14:58:33 +0200 Subject: [PATCH 079/359] net/mlx5: Cancel recovery work in remove flow If there is pending delayed work for health recovery it must be canceled if the device is being unloaded. Fixes: 05ac2c0b7438 ("net/mlx5: Fix race between PCI error handlers and health work") Signed-off-by: Daniel Jurgens Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 23c12f1aaa39..0b49739eadd3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1196,6 +1196,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, { int err = 0; + mlx5_drain_health_wq(dev); + mutex_lock(&dev->intf_state_mutex); if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", @@ -1358,10 +1360,9 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev, mlx5_enter_error_state(dev); mlx5_unload_one(dev, priv, false); - /* In case of kernel call save the pci state and drain health wq */ + /* In case of kernel call save the pci state */ if (state) { pci_save_state(pdev); - mlx5_drain_health_wq(dev); mlx5_pci_disable_device(dev); } From d151d73dcc99de87c63bdefebcc4cb69de1cdc40 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Wed, 28 Dec 2016 14:58:34 +0200 Subject: [PATCH 080/359] net/mlx5: Avoid shadowing numa_node Avoid using a local variable named numa_node to avoid shadowing a public one. Fixes: db058a186f98 ('net/mlx5_core: Set irq affinity hints') Signed-off-by: Eli Cohen Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 0b49739eadd3..6547f22e6b9b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -582,7 +582,6 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) struct mlx5_priv *priv = &mdev->priv; struct msix_entry *msix = priv->msix_arr; int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector; - int numa_node = priv->numa_node; int err; if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { @@ -590,7 +589,7 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) return -ENOMEM; } - cpumask_set_cpu(cpumask_local_spread(i, numa_node), + cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), priv->irq_info[i].mask); err = irq_set_affinity_hint(irq, priv->irq_info[i].mask); From 077b1e8069b9b74477b01d28f6b83774dc19a142 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 28 Dec 2016 14:58:35 +0200 Subject: [PATCH 081/359] net/mlx5: Mask destination mac value in ethtool steering rules We need to mask the destination mac value with the destination mac mask when adding steering rule via ethtool. Fixes: 1174fce8d1410 ('net/mlx5e: Support l3/l4 flow type specs in ethtool flow steering') Signed-off-by: Maor Gottlieb Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c index 3691451c728c..d088effd7160 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c @@ -247,6 +247,7 @@ static int set_flow_attrs(u32 *match_c, u32 *match_v, } if (fs->flow_type & FLOW_MAC_EXT && !is_zero_ether_addr(fs->m_ext.h_dest)) { + mask_spec(fs->m_ext.h_dest, fs->h_ext.h_dest, ETH_ALEN); ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, dmac_47_16), fs->m_ext.h_dest); From 9b8c514291a83e53c073b473bdca6267f17a02c2 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Wed, 28 Dec 2016 14:58:36 +0200 Subject: [PATCH 082/359] net/mlx5: Release FTE lock in error flow Release the FTE lock when adding rule to the FTE has failed. Fixes: 0fd758d6112f ('net/mlx5: Don't unlock fte while still using it') Signed-off-by: Maor Gottlieb Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index a263d8904a4c..0ac7a2fc916c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1263,6 +1263,7 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg, nested_lock_ref_node(&fte->node, FS_MUTEX_CHILD); handle = add_rule_fte(fte, fg, dest, dest_num, false); if (IS_ERR(handle)) { + unlock_ref_node(&fte->node); kfree(fte); goto unlock_fg; } From ccce1700263d8b5b219359d04180492a726cea16 Mon Sep 17 00:00:00 2001 From: Mohamad Haj Yahia Date: Wed, 28 Dec 2016 14:58:37 +0200 Subject: [PATCH 083/359] net/mlx5: Prevent setting multicast macs for VFs Need to check that VF mac address entered by the admin user is either zero or unicast mac. Multicast mac addresses are prohibited. Fixes: 77256579c6b4 ('net/mlx5: E-Switch, Introduce Vport administration functions') Signed-off-by: Mohamad Haj Yahia Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index d6807c3cc461..f14d9c9ba773 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1860,7 +1860,7 @@ int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, if (!ESW_ALLOWED(esw)) return -EPERM; - if (!LEGAL_VPORT(esw, vport)) + if (!LEGAL_VPORT(esw, vport) || is_multicast_ether_addr(mac)) return -EINVAL; mutex_lock(&esw->state_lock); From 465db5dab86d6688fa5132edd1237102f4a20e84 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Wed, 28 Dec 2016 14:58:38 +0200 Subject: [PATCH 084/359] Revert "net/mlx5e: Expose PCIe statistics to ethtool" This reverts commit 9c7262399ba12825f3ca4b00a76d8d5e77c720f5. PCIe counters were introduced in a new firmware version, as a result users with old firmware encountered a syndrome every 200ms due to update stats work. This feature will be re-introduced later with appropriate capabilities infrastructure. Fixes: 9c7262399ba1 ("net/mlx5e: Expose PCIe statistics to ethtool") Signed-off-by: Gal Pressman Reported-by: Jesper Dangaard Brouer Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlx5/core/en_ethtool.c | 17 ---------- .../net/ethernet/mellanox/mlx5/core/en_main.c | 24 -------------- .../ethernet/mellanox/mlx5/core/en_stats.h | 32 +------------------ 3 files changed, 1 insertion(+), 72 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 352462af8d51..33a399a8b5d5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -171,7 +171,6 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset) return NUM_SW_COUNTERS + MLX5E_NUM_Q_CNTRS(priv) + NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS + - NUM_PCIE_COUNTERS + MLX5E_NUM_RQ_STATS(priv) + MLX5E_NUM_SQ_STATS(priv) + MLX5E_NUM_PFC_COUNTERS(priv) + @@ -219,14 +218,6 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data) strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_2819_stats_desc[i].format); - for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++) - strcpy(data + (idx++) * ETH_GSTRING_LEN, - pcie_perf_stats_desc[i].format); - - for (i = 0; i < NUM_PCIE_TAS_COUNTERS; i++) - strcpy(data + (idx++) * ETH_GSTRING_LEN, - pcie_tas_stats_desc[i].format); - for (prio = 0; prio < NUM_PPORT_PRIO; prio++) { for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++) sprintf(data + (idx++) * ETH_GSTRING_LEN, @@ -339,14 +330,6 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev, data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters, pport_2819_stats_desc, i); - for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++) - data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters, - pcie_perf_stats_desc, i); - - for (i = 0; i < NUM_PCIE_TAS_COUNTERS; i++) - data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_tas_counters, - pcie_tas_stats_desc, i); - for (prio = 0; prio < NUM_PPORT_PRIO; prio++) { for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++) data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio], diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index cbfa38fc72c0..be5ef036401d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -291,36 +291,12 @@ static void mlx5e_update_q_counter(struct mlx5e_priv *priv) &qcnt->rx_out_of_buffer); } -static void mlx5e_update_pcie_counters(struct mlx5e_priv *priv) -{ - struct mlx5e_pcie_stats *pcie_stats = &priv->stats.pcie; - struct mlx5_core_dev *mdev = priv->mdev; - int sz = MLX5_ST_SZ_BYTES(mpcnt_reg); - void *out; - u32 *in; - - in = mlx5_vzalloc(sz); - if (!in) - return; - - out = pcie_stats->pcie_perf_counters; - MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP); - mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0); - - out = pcie_stats->pcie_tas_counters; - MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP); - mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0); - - kvfree(in); -} - void mlx5e_update_stats(struct mlx5e_priv *priv) { mlx5e_update_q_counter(priv); mlx5e_update_vport_counters(priv); mlx5e_update_pport_counters(priv); mlx5e_update_sw_counters(priv); - mlx5e_update_pcie_counters(priv); } void mlx5e_update_stats_work(struct work_struct *work) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index f202f872f57f..ba5db1dd23a9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h @@ -39,7 +39,7 @@ #define MLX5E_READ_CTR32_CPU(ptr, dsc, i) \ (*(u32 *)((char *)ptr + dsc[i].offset)) #define MLX5E_READ_CTR32_BE(ptr, dsc, i) \ - be32_to_cpu(*(__be32 *)((char *)ptr + dsc[i].offset)) + be64_to_cpu(*(__be32 *)((char *)ptr + dsc[i].offset)) #define MLX5E_DECLARE_STAT(type, fld) #fld, offsetof(type, fld) #define MLX5E_DECLARE_RX_STAT(type, fld) "rx%d_"#fld, offsetof(type, fld) @@ -276,32 +276,6 @@ static const struct counter_desc pport_per_prio_pfc_stats_desc[] = { { "rx_%s_pause_transition", PPORT_PER_PRIO_OFF(rx_pause_transition) }, }; -#define PCIE_PERF_OFF(c) \ - MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c) -#define PCIE_PERF_GET(pcie_stats, c) \ - MLX5_GET(mpcnt_reg, pcie_stats->pcie_perf_counters, \ - counter_set.pcie_perf_cntrs_grp_data_layout.c) -#define PCIE_TAS_OFF(c) \ - MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_tas_cntrs_grp_data_layout.c) -#define PCIE_TAS_GET(pcie_stats, c) \ - MLX5_GET(mpcnt_reg, pcie_stats->pcie_tas_counters, \ - counter_set.pcie_tas_cntrs_grp_data_layout.c) - -struct mlx5e_pcie_stats { - __be64 pcie_perf_counters[MLX5_ST_SZ_QW(mpcnt_reg)]; - __be64 pcie_tas_counters[MLX5_ST_SZ_QW(mpcnt_reg)]; -}; - -static const struct counter_desc pcie_perf_stats_desc[] = { - { "rx_pci_signal_integrity", PCIE_PERF_OFF(rx_errors) }, - { "tx_pci_signal_integrity", PCIE_PERF_OFF(tx_errors) }, -}; - -static const struct counter_desc pcie_tas_stats_desc[] = { - { "tx_pci_transport_nonfatal_msg", PCIE_TAS_OFF(non_fatal_err_msg_sent) }, - { "tx_pci_transport_fatal_msg", PCIE_TAS_OFF(fatal_err_msg_sent) }, -}; - struct mlx5e_rq_stats { u64 packets; u64 bytes; @@ -386,8 +360,6 @@ static const struct counter_desc sq_stats_desc[] = { #define NUM_PPORT_802_3_COUNTERS ARRAY_SIZE(pport_802_3_stats_desc) #define NUM_PPORT_2863_COUNTERS ARRAY_SIZE(pport_2863_stats_desc) #define NUM_PPORT_2819_COUNTERS ARRAY_SIZE(pport_2819_stats_desc) -#define NUM_PCIE_PERF_COUNTERS ARRAY_SIZE(pcie_perf_stats_desc) -#define NUM_PCIE_TAS_COUNTERS ARRAY_SIZE(pcie_tas_stats_desc) #define NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS \ ARRAY_SIZE(pport_per_prio_traffic_stats_desc) #define NUM_PPORT_PER_PRIO_PFC_COUNTERS \ @@ -397,7 +369,6 @@ static const struct counter_desc sq_stats_desc[] = { NUM_PPORT_2819_COUNTERS + \ NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS * \ NUM_PPORT_PRIO) -#define NUM_PCIE_COUNTERS (NUM_PCIE_PERF_COUNTERS + NUM_PCIE_TAS_COUNTERS) #define NUM_RQ_STATS ARRAY_SIZE(rq_stats_desc) #define NUM_SQ_STATS ARRAY_SIZE(sq_stats_desc) @@ -406,7 +377,6 @@ struct mlx5e_stats { struct mlx5e_qcounter_stats qcnt; struct mlx5e_vport_stats vport; struct mlx5e_pport_stats pport; - struct mlx5e_pcie_stats pcie; struct rtnl_link_stats64 vf_vport; }; From 1efbd205b3cc5882a8c386c58a57134044e9d5ba Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Wed, 28 Dec 2016 14:58:39 +0200 Subject: [PATCH 085/359] Revert "net/mlx5: Add MPCNT register infrastructure" This reverts commit 7f503169cabd70c1f13b9279c50eca7dfb9a7d51. Fixes: 7f503169cabd ("net/mlx5: Add MPCNT register infrastructure") Signed-off-by: Gal Pressman Reported-by: Jesper Dangaard Brouer Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- include/linux/mlx5/device.h | 5 -- include/linux/mlx5/driver.h | 1 - include/linux/mlx5/mlx5_ifc.h | 93 ----------------------------------- 3 files changed, 99 deletions(-) diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index 9f489365b3d3..52b437431c6a 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -1071,11 +1071,6 @@ enum { MLX5_INFINIBAND_PORT_COUNTERS_GROUP = 0x20, }; -enum { - MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP = 0x0, - MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP = 0x2, -}; - static inline u16 mlx5_to_sw_pkey_sz(int pkey_sz) { if (pkey_sz > MLX5_MAX_LOG_PKEY_TABLE) diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 0ae55361e674..735b36335f29 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -123,7 +123,6 @@ enum { MLX5_REG_HOST_ENDIANNESS = 0x7004, MLX5_REG_MCIA = 0x9014, MLX5_REG_MLCR = 0x902b, - MLX5_REG_MPCNT = 0x9051, }; enum mlx5_dcbx_oper_mode { diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 57bec544e20a..a852e9db6f0d 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -1757,80 +1757,6 @@ struct mlx5_ifc_eth_802_3_cntrs_grp_data_layout_bits { u8 reserved_at_4c0[0x300]; }; -struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits { - u8 life_time_counter_high[0x20]; - - u8 life_time_counter_low[0x20]; - - u8 rx_errors[0x20]; - - u8 tx_errors[0x20]; - - u8 l0_to_recovery_eieos[0x20]; - - u8 l0_to_recovery_ts[0x20]; - - u8 l0_to_recovery_framing[0x20]; - - u8 l0_to_recovery_retrain[0x20]; - - u8 crc_error_dllp[0x20]; - - u8 crc_error_tlp[0x20]; - - u8 reserved_at_140[0x680]; -}; - -struct mlx5_ifc_pcie_tas_cntrs_grp_data_layout_bits { - u8 life_time_counter_high[0x20]; - - u8 life_time_counter_low[0x20]; - - u8 time_to_boot_image_start[0x20]; - - u8 time_to_link_image[0x20]; - - u8 calibration_time[0x20]; - - u8 time_to_first_perst[0x20]; - - u8 time_to_detect_state[0x20]; - - u8 time_to_l0[0x20]; - - u8 time_to_crs_en[0x20]; - - u8 time_to_plastic_image_start[0x20]; - - u8 time_to_iron_image_start[0x20]; - - u8 perst_handler[0x20]; - - u8 times_in_l1[0x20]; - - u8 times_in_l23[0x20]; - - u8 dl_down[0x20]; - - u8 config_cycle1usec[0x20]; - - u8 config_cycle2to7usec[0x20]; - - u8 config_cycle_8to15usec[0x20]; - - u8 config_cycle_16_to_63usec[0x20]; - - u8 config_cycle_64usec[0x20]; - - u8 correctable_err_msg_sent[0x20]; - - u8 non_fatal_err_msg_sent[0x20]; - - u8 fatal_err_msg_sent[0x20]; - - u8 reserved_at_2e0[0x4e0]; -}; - struct mlx5_ifc_cmd_inter_comp_event_bits { u8 command_completion_vector[0x20]; @@ -2995,12 +2921,6 @@ union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits { u8 reserved_at_0[0x7c0]; }; -union mlx5_ifc_pcie_cntrs_grp_data_layout_auto_bits { - struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits pcie_perf_cntrs_grp_data_layout; - struct mlx5_ifc_pcie_tas_cntrs_grp_data_layout_bits pcie_tas_cntrs_grp_data_layout; - u8 reserved_at_0[0x7c0]; -}; - union mlx5_ifc_event_auto_bits { struct mlx5_ifc_comp_event_bits comp_event; struct mlx5_ifc_dct_events_bits dct_events; @@ -7320,18 +7240,6 @@ struct mlx5_ifc_ppcnt_reg_bits { union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits counter_set; }; -struct mlx5_ifc_mpcnt_reg_bits { - u8 reserved_at_0[0x8]; - u8 pcie_index[0x8]; - u8 reserved_at_10[0xa]; - u8 grp[0x6]; - - u8 clr[0x1]; - u8 reserved_at_21[0x1f]; - - union mlx5_ifc_pcie_cntrs_grp_data_layout_auto_bits counter_set; -}; - struct mlx5_ifc_ppad_reg_bits { u8 reserved_at_0[0x3]; u8 single_mac[0x1]; @@ -7937,7 +7845,6 @@ union mlx5_ifc_ports_control_registers_document_bits { struct mlx5_ifc_pmtu_reg_bits pmtu_reg; struct mlx5_ifc_ppad_reg_bits ppad_reg; struct mlx5_ifc_ppcnt_reg_bits ppcnt_reg; - struct mlx5_ifc_mpcnt_reg_bits mpcnt_reg; struct mlx5_ifc_pplm_reg_bits pplm_reg; struct mlx5_ifc_pplr_reg_bits pplr_reg; struct mlx5_ifc_ppsc_reg_bits ppsc_reg; From 4525a45bfad55a00ef218c5fbe5d98a3d8170bf5 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Wed, 28 Dec 2016 14:58:40 +0200 Subject: [PATCH 086/359] net/mlx5e: Check ets capability before initializing ets settings During the initial setup, the ets command is sent to firmware without checking if the HCA supports ets. This causes the invalid command error. Add the ets capiblity check before sending firmware command to initialize ets settings. Fixes: e207b7e99176 ("net/mlx5e: ConnectX-4 firmware support for DCBX") Signed-off-by: Huy Nguyen Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index 7f6c225666c1..f0b460f47f29 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -723,6 +723,9 @@ static void mlx5e_ets_init(struct mlx5e_priv *priv) int i; struct ieee_ets ets; + if (!MLX5_CAP_GEN(priv->mdev, ets)) + return; + memset(&ets, 0, sizeof(ets)); ets.ets_cap = mlx5_max_tc(priv->mdev) + 1; for (i = 0; i < ets.ets_cap; i++) { From 610e89e05c3f28a7394935aa6b91f99548c4fd3c Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Wed, 28 Dec 2016 14:58:41 +0200 Subject: [PATCH 087/359] net/mlx5e: Don't sync netdev state when not registered Skip setting netdev vxlan ports and netdev rx_mode on driver load when netdev is not yet registered. Synchronizing with netdev state is needed only on reset flow where the netdev remains registered for the whole reset period. This also fixes an access before initialization of net_device.addr_list_lock - which for some reason initialized on register_netdev - where we queued set_rx_mode work on driver load before netdev registration. Fixes: 26e59d8077a3 ("net/mlx5e: Implement mlx5e interface attach/detach callbacks") Signed-off-by: Saeed Mahameed Reported-by: Sebastian Ott Reviewed-by: Mohamad Haj Yahia Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx5/core/en_main.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index be5ef036401d..cf270f6c90e8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3781,14 +3781,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) mlx5_lag_add(mdev, netdev); - if (mlx5e_vxlan_allowed(mdev)) { - rtnl_lock(); - udp_tunnel_get_rx_info(netdev); - rtnl_unlock(); - } - mlx5e_enable_async_events(priv); - queue_work(priv->wq, &priv->set_rx_mode_work); if (MLX5_CAP_GEN(mdev, vport_group_manager)) { mlx5_query_nic_vport_mac_address(mdev, 0, rep.hw_id); @@ -3798,6 +3791,18 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) rep.netdev = netdev; mlx5_eswitch_register_vport_rep(esw, 0, &rep); } + + if (netdev->reg_state != NETREG_REGISTERED) + return; + + /* Device already registered: sync netdev system state */ + if (mlx5e_vxlan_allowed(mdev)) { + rtnl_lock(); + udp_tunnel_get_rx_info(netdev); + rtnl_unlock(); + } + + queue_work(priv->wq, &priv->set_rx_mode_work); } static void mlx5e_nic_disable(struct mlx5e_priv *priv) From 37f304d10030bb425c19099e7b955d9c3ec4cba3 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Wed, 28 Dec 2016 14:58:42 +0200 Subject: [PATCH 088/359] net/mlx5e: Disable netdev after close Disable netdev should come after it was closed, although no harm of doing it before -hence the MLX5E_STATE_DESTROYING bit- but it is more natural this way. Fixes: 26e59d8077a3 ("net/mlx5e: Implement mlx5e interface attach/detach callbacks") Signed-off-by: Saeed Mahameed Reviewed-by: Mohamad Haj Yahia Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index cf270f6c90e8..1236b27b1493 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3947,10 +3947,6 @@ void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev) const struct mlx5e_profile *profile = priv->profile; set_bit(MLX5E_STATE_DESTROYING, &priv->state); - if (profile->disable) - profile->disable(priv); - - flush_workqueue(priv->wq); rtnl_lock(); if (netif_running(netdev)) @@ -3958,6 +3954,10 @@ void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev) netif_device_detach(netdev); rtnl_unlock(); + if (profile->disable) + profile->disable(priv); + flush_workqueue(priv->wq); + mlx5e_destroy_q_counter(priv); profile->cleanup_rx(priv); mlx5e_close_drop_rq(priv); From 9dd0f896d2cc5815d859e945db90915071cd44b3 Mon Sep 17 00:00:00 2001 From: Augusto Mecking Caringi Date: Wed, 28 Dec 2016 16:02:05 +0000 Subject: [PATCH 089/359] net: atm: Fix warnings in net/atm/lec.c when !CONFIG_PROC_FS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the following warnings when CONFIG_PROC_FS is not set: linux/net/atm/lec.c: In function ‘lane_module_cleanup’: linux/net/atm/lec.c:1062:27: error: ‘atm_proc_root’ undeclared (first use in this function) remove_proc_entry("lec", atm_proc_root); ^ linux/net/atm/lec.c:1062:27: note: each undeclared identifier is reported only once for each function it appears in Signed-off-by: Augusto Mecking Caringi Signed-off-by: David S. Miller --- net/atm/lec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/atm/lec.c b/net/atm/lec.c index 019557d0a11d..09cfe87f0a44 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -1059,7 +1059,9 @@ static void __exit lane_module_cleanup(void) { int i; +#ifdef CONFIG_PROC_FS remove_proc_entry("lec", atm_proc_root); +#endif deregister_atm_ioctl(&lane_ioctl_ops); From 60133867f1f111aaf3a8c00375b8026142a9a591 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 28 Dec 2016 16:44:23 +0000 Subject: [PATCH 090/359] net: wan: slic_ds26522: fix spelling mistake: "configurated" -> "configured" trivial fix to spelling mistake in pr_info message Signed-off-by: Colin Ian King Signed-off-by: David S. Miller --- drivers/net/wan/slic_ds26522.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wan/slic_ds26522.c b/drivers/net/wan/slic_ds26522.c index b776a0ab106c..9d9b4e0def2a 100644 --- a/drivers/net/wan/slic_ds26522.c +++ b/drivers/net/wan/slic_ds26522.c @@ -218,7 +218,7 @@ static int slic_ds26522_probe(struct spi_device *spi) ret = slic_ds26522_init_configure(spi); if (ret == 0) - pr_info("DS26522 cs%d configurated\n", spi->chip_select); + pr_info("DS26522 cs%d configured\n", spi->chip_select); return ret; } From e9112936f240856c925321fd2bd91adc7c00399c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 21 Dec 2016 16:03:42 -0600 Subject: [PATCH 091/359] arm64: dts: msm8996: Add required memory carveouts This patch adds required memory carveouts so that the kernel does not access memory that is in use or has been reserved for use by other remote processors. Signed-off-by: Andy Gross Signed-off-by: Stephen Boyd --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 9d1d7ad9b075..29ed6b61c737 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -64,6 +64,16 @@ smem_mem: smem-mem@86000000 { reg = <0x0 0x86000000 0x0 0x200000>; no-map; }; + + memory@85800000 { + reg = <0x0 0x85800000 0x0 0x800000>; + no-map; + }; + + memory@86200000 { + reg = <0x0 0x86200000 0x0 0x2600000>; + no-map; + }; }; cpus { From ae774e2c68d19da7a8e982889a5a1684cac93c78 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 11:44:35 +0100 Subject: [PATCH 092/359] drm/doc: link style-guide to doc-guide Our style guide should only be the delta compared to the overall one. Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483008275-29383-1-git-send-email-daniel.vetter@ffwll.ch --- Documentation/gpu/introduction.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst index 1903595b5310..6960e31f71e1 100644 --- a/Documentation/gpu/introduction.rst +++ b/Documentation/gpu/introduction.rst @@ -49,3 +49,5 @@ section name should be all upper-case or not, and whether it should end in a colon or not. Go with the file-local style. Other common section names are "Notes" with information for dangerous or tricky corner cases, and "FIXME" where the interface could be cleaned up. + +Also read the :ref:`guidelines for the kernel documentation at large `. From e4c5e13aa45c23692e4acf56f0b3533f328199b2 Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Wed, 28 Dec 2016 23:23:46 +0800 Subject: [PATCH 093/359] ipv6: Should use consistent conditional judgement for ip6 fragment between __ip6_append_data and ip6_finish_output There is an inconsistent conditional judgement between __ip6_append_data and ip6_finish_output functions, the variable length in __ip6_append_data just include the length of application's payload and udp6 header, don't include the length of ipv6 header, but in ip6_finish_output use (skb->len > ip6_skb_dst_mtu(skb)) as judgement, and skb->len include the length of ipv6 header. That causes some particular application's udp6 payloads whose length are between (MTU - IPv6 Header) and MTU were fragmented by ip6_fragment even though the rst->dev support UFO feature. Add the length of ipv6 header to length in __ip6_append_data to keep consistent conditional judgement as ip6_finish_output for ip6 fragment. Signed-off-by: Zheng Li Signed-off-by: David S. Miller --- net/ipv6/ip6_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 70d0de404197..38122d04fadc 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1373,7 +1373,7 @@ static int __ip6_append_data(struct sock *sk, */ cork->length += length; - if (((length > mtu) || + if ((((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) && (sk->sk_protocol == IPPROTO_UDP) && (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && From b2eb09af7370fedc6b9d9f05762f01625438467a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 28 Dec 2016 15:44:41 -0800 Subject: [PATCH 094/359] net: stmmac: Fix error path after register_netdev move Commit 5701659004d6 ("net: stmmac: Fix race between stmmac_drv_probe and stmmac_open") re-ordered how the MDIO bus registration and the network device are registered, but missed to unwind the MDIO bus registration in case we fail to register the network device. Fixes: 5701659004d6 ("net: stmmac: Fix race between stmmac_drv_probe and stmmac_open") Signed-off-by: Florian Fainelli Acked-by: Kweh, Hock Leong Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 5910ea51f8f6..39eb7a65bb9f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3366,12 +3366,19 @@ int stmmac_dvr_probe(struct device *device, } ret = register_netdev(ndev); - if (ret) + if (ret) { netdev_err(priv->dev, "%s: ERROR %i registering the device\n", __func__, ret); + goto error_netdev_register; + } return ret; +error_netdev_register: + if (priv->hw->pcs != STMMAC_PCS_RGMII && + priv->hw->pcs != STMMAC_PCS_TBI && + priv->hw->pcs != STMMAC_PCS_RTBI) + stmmac_mdio_unregister(ndev); error_mdio_register: netif_napi_del(&priv->napi); error_hw_init: From 4775cc1f2d5abca894ac32774eefc22c45347d1c Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 28 Dec 2016 17:52:15 +0100 Subject: [PATCH 095/359] rtnl: stats - add missing netlink message size checks We miss to check if the netlink message is actually big enough to contain a struct if_stats_msg. Add a check to prevent userland from sending us short messages that would make us access memory beyond the end of the message. Fixes: 10c9ead9f3c6 ("rtnetlink: add new RTM_GETSTATS message to dump...") Signed-off-by: Mathias Krause Cc: Roopa Prabhu Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 18b5aae99bec..75e3ea7bda08 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3898,6 +3898,9 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh) u32 filter_mask; int err; + if (nlmsg_len(nlh) < sizeof(*ifsm)) + return -EINVAL; + ifsm = nlmsg_data(nlh); if (ifsm->ifindex > 0) dev = __dev_get_by_index(net, ifsm->ifindex); @@ -3947,6 +3950,9 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) cb->seq = net->dev_base_seq; + if (nlmsg_len(cb->nlh) < sizeof(*ifsm)) + return -EINVAL; + ifsm = nlmsg_data(cb->nlh); filter_mask = ifsm->filter_mask; if (!filter_mask) From f0c16ba8933ed217c2688b277410b2a37ba81591 Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Thu, 29 Dec 2016 16:45:04 +0800 Subject: [PATCH 096/359] net: fix incorrect original ingress device index in PKTINFO When we send a packet for our own local address on a non-loopback interface (e.g. eth0), due to the change had been introduced from commit 0b922b7a829c ("net: original ingress device index in PKTINFO"), the original ingress device index would be set as the loopback interface. However, the packet should be considered as if it is being arrived via the sending interface (eth0), otherwise it would break the expectation of the userspace application (e.g. the DHCPRELEASE message from dhcp_release binary would be ignored by the dnsmasq daemon, since it come from lo which is not the interface dnsmasq bind to) Fixes: 0b922b7a829c ("net: original ingress device index in PKTINFO") Acked-by: David Ahern Signed-off-by: Wei Zhang Signed-off-by: David S. Miller --- net/ipv4/ip_sockglue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 57e1405e8282..53ae0c6315ad 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -1225,8 +1225,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) * which has interface index (iif) as the first member of the * underlying inet{6}_skb_parm struct. This code then overlays * PKTINFO_SKB_CB and in_pktinfo also has iif as the first - * element so the iif is picked up from the prior IPCB + * element so the iif is picked up from the prior IPCB. If iif + * is the loopback interface, then return the sending interface + * (e.g., process binds socket to eth0 for Tx which is + * redirected to loopback in the rtable/dst). */ + if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX) + pktinfo->ipi_ifindex = inet_iif(skb); + pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb); } else { pktinfo->ipi_ifindex = 0; From 3b01fe7f91c8e4f9afc4fae3c5af72c14958d2d8 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 29 Dec 2016 18:37:09 +0200 Subject: [PATCH 097/359] net/mlx4_core: Use-after-free causes a resource leak in flow-steering detach mlx4_QP_FLOW_STEERING_DETACH_wrapper first removes the steering rule (which results in freeing the rule structure), and then references a field in this struct (the qp number) when releasing the busy-status on the rule's qp. Since this memory was freed, it could reallocated and changed. Therefore, the qp number in the struct may be incorrect, so that we are releasing the incorrect qp. This leaves the rule's qp in the busy state (and could possibly release an incorrect qp as well). Fix this by saving the qp number in a local variable, for use after removing the steering rule. Fixes: 2c473ae7e582 ("net/mlx4_core: Disallow releasing VF QPs which have steering rules") Signed-off-by: Jack Morgenstein Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index c548beaaf910..4b3e139e9c82 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -4473,6 +4473,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, struct res_qp *rqp; struct res_fs_rule *rrule; u64 mirr_reg_id; + int qpn; if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) @@ -4489,10 +4490,11 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, } mirr_reg_id = rrule->mirr_rule_id; kfree(rrule->mirr_mbox); + qpn = rrule->qpn; /* Release the rule form busy state before removal */ put_res(dev, slave, vhcr->in_param, RES_FS_RULE); - err = get_res(dev, slave, rrule->qpn, RES_QP, &rqp); + err = get_res(dev, slave, qpn, RES_QP, &rqp); if (err) return err; @@ -4517,7 +4519,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, if (!err) atomic_dec(&rqp->ref_count); out: - put_res(dev, slave, rrule->qpn, RES_QP); + put_res(dev, slave, qpn, RES_QP); return err; } From 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Thu, 29 Dec 2016 18:37:10 +0200 Subject: [PATCH 098/359] net/mlx4_en: Fix bad WQE issue Single send WQE in RX buffer should be stamped with software ownership in order to prevent the flow of QP in error in FW once UPDATE_QP is called. Fixes: 9f519f68cfff ('mlx4_en: Not using Shared Receive Queues') Signed-off-by: Eugenia Emantayev Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 3c37e216bbf3..eac527e25ec9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -445,8 +445,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn; ring->stride = stride; - if (ring->stride <= TXBB_SIZE) + if (ring->stride <= TXBB_SIZE) { + /* Stamp first unused send wqe */ + __be32 *ptr = (__be32 *)ring->buf; + __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT); + *ptr = stamp; + /* Move pointer to start of rx section */ ring->buf += TXBB_SIZE; + } ring->log_stride = ffs(ring->stride) - 1; ring->buf_size = ring->size * ring->stride; From c1d5f8ff80ea84768f5fae1ca9d1abfbb5e6bbaa Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Thu, 29 Dec 2016 18:37:11 +0200 Subject: [PATCH 099/359] net/mlx4: Remove BUG_ON from ICM allocation routine This patch removes BUG_ON() macro from mlx4_alloc_icm_coherent() by checking DMA address alignment in advance and performing proper folding in case of error. Fixes: 5b0bf5e25efe ("mlx4_core: Support ICM tables in coherent memory") Reported-by: Ozgur Karatas Signed-off-by: Leon Romanovsky Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/icm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c index 2a9dd460a95f..e1f9e7cebf8f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c @@ -118,8 +118,13 @@ static int mlx4_alloc_icm_coherent(struct device *dev, struct scatterlist *mem, if (!buf) return -ENOMEM; + if (offset_in_page(buf)) { + dma_free_coherent(dev, PAGE_SIZE << order, + buf, sg_dma_address(mem)); + return -ENOMEM; + } + sg_set_buf(mem, buf, PAGE_SIZE << order); - BUG_ON(mem->offset); sg_dma_len(mem) = PAGE_SIZE << order; return 0; } From 61b6034c6cfdcb265bb453505c3d688e7567727a Mon Sep 17 00:00:00 2001 From: Slava Shwartsman Date: Thu, 29 Dec 2016 18:37:12 +0200 Subject: [PATCH 100/359] net/mlx4_en: Fix type mismatch for 32-bit systems is_power_of_2 expects unsigned long and we pass u64 max_val_cycles, this will be truncated on 32 bit systems, and the result is not what we were expecting. div_u64 expects u32 as a second argument and we pass max_val_cycles_rounded which is u64 hence it will always be truncated. Fix was tested on both 64 and 32 bit systems and got same results for max_val_cycles and max_val_cycles_rounded. Fixes: 4850cf458157 ("net/mlx4_en: Resolve dividing by zero in 32-bit system") Signed-off-by: Slava Shwartsman Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 015198c14fa8..504461a464c5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -245,13 +245,9 @@ static u32 freq_to_shift(u16 freq) { u32 freq_khz = freq * 1000; u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC; - u64 tmp_rounded = - roundup_pow_of_two(max_val_cycles) > max_val_cycles ? - roundup_pow_of_two(max_val_cycles) - 1 : UINT_MAX; - u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ? - max_val_cycles : tmp_rounded; + u64 max_val_cycles_rounded = 1ULL << fls64(max_val_cycles - 1); /* calculate max possible multiplier in order to fit in 64bit */ - u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded); + u64 max_mul = div64_u64(ULLONG_MAX, max_val_cycles_rounded); /* This comes from the reverse of clocksource_khz2mult */ return ilog2(div_u64(max_mul * freq_khz, 1000000)); From 10b1c04e92229ebeb38ccd0dcf2b6d3ec73c0575 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 29 Dec 2016 18:37:13 +0200 Subject: [PATCH 101/359] net/mlx4_core: Fix raw qp flow steering rules under SRIOV Demoting simple flow steering rule priority (for DPDK) was achieved by wrapping FW commands MLX4_QP_FLOW_STEERING_ATTACH/DETACH for the PF as well, and forcing the priority to MLX4_DOMAIN_NIC in the wrapper function for the PF and all VFs. In function mlx4_ib_create_flow(), this change caused the main rule creation for the PF to be wrapped, while it left the associated tunnel steering rule creation unwrapped for the PF. This mismatch caused rule deletion failures in mlx4_ib_destroy_flow() for the PF when the detach wrapper function did not find the associated tunnel-steering rule (since creation of that rule for the PF did not go through the wrapper function). Fix this by setting MLX4_QP_FLOW_STEERING_ATTACH/DETACH to be "native" (so that the PF invocation does not go through the wrapper), and perform the required priority demotion for the PF in the mlx4_ib_create_flow() code path. Fixes: 48564135cba8 ("net/mlx4_core: Demote simple multicast and broadcast flow steering rules") Signed-off-by: Jack Morgenstein Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- drivers/infiniband/hw/mlx4/main.c | 14 ++++++++++-- drivers/net/ethernet/mellanox/mlx4/main.c | 18 +++++++++++++++ .../ethernet/mellanox/mlx4/resource_tracker.c | 22 +------------------ include/linux/mlx4/device.h | 2 ++ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index c8413fc120e6..7031a8dd4d14 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1682,9 +1682,19 @@ static int __mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_att size += ret; } + if (mlx4_is_master(mdev->dev) && flow_type == MLX4_FS_REGULAR && + flow_attr->num_of_specs == 1) { + struct _rule_hw *rule_header = (struct _rule_hw *)(ctrl + 1); + enum ib_flow_spec_type header_spec = + ((union ib_flow_spec *)(flow_attr + 1))->type; + + if (header_spec == IB_FLOW_SPEC_ETH) + mlx4_handle_eth_header_mcast_prio(ctrl, rule_header); + } + ret = mlx4_cmd_imm(mdev->dev, mailbox->dma, reg_id, size >> 2, 0, MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, - MLX4_CMD_WRAPPED); + MLX4_CMD_NATIVE); if (ret == -ENOMEM) pr_err("mcg table is full. Fail to register network rule.\n"); else if (ret == -ENXIO) @@ -1701,7 +1711,7 @@ static int __mlx4_ib_destroy_flow(struct mlx4_dev *dev, u64 reg_id) int err; err = mlx4_cmd(dev, reg_id, 0, 0, MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, - MLX4_CMD_WRAPPED); + MLX4_CMD_NATIVE); if (err) pr_err("Fail to detach network rule. registration id = 0x%llx\n", reg_id); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 5e7840a7a33b..bffa6f345f2f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -782,6 +783,23 @@ int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) } EXPORT_SYMBOL(mlx4_is_slave_active); +void mlx4_handle_eth_header_mcast_prio(struct mlx4_net_trans_rule_hw_ctrl *ctrl, + struct _rule_hw *eth_header) +{ + if (is_multicast_ether_addr(eth_header->eth.dst_mac) || + is_broadcast_ether_addr(eth_header->eth.dst_mac)) { + struct mlx4_net_trans_rule_hw_eth *eth = + (struct mlx4_net_trans_rule_hw_eth *)eth_header; + struct _rule_hw *next_rule = (struct _rule_hw *)(eth + 1); + bool last_rule = next_rule->size == 0 && next_rule->id == 0 && + next_rule->rsvd == 0; + + if (last_rule) + ctrl->prio = cpu_to_be16(MLX4_DOMAIN_NIC); + } +} +EXPORT_SYMBOL(mlx4_handle_eth_header_mcast_prio); + static void slave_adjust_steering_mode(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, struct mlx4_init_hca_param *hca_param) diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 4b3e139e9c82..56185a0b827d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -4164,22 +4164,6 @@ static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, return 0; } -static void handle_eth_header_mcast_prio(struct mlx4_net_trans_rule_hw_ctrl *ctrl, - struct _rule_hw *eth_header) -{ - if (is_multicast_ether_addr(eth_header->eth.dst_mac) || - is_broadcast_ether_addr(eth_header->eth.dst_mac)) { - struct mlx4_net_trans_rule_hw_eth *eth = - (struct mlx4_net_trans_rule_hw_eth *)eth_header; - struct _rule_hw *next_rule = (struct _rule_hw *)(eth + 1); - bool last_rule = next_rule->size == 0 && next_rule->id == 0 && - next_rule->rsvd == 0; - - if (last_rule) - ctrl->prio = cpu_to_be16(MLX4_DOMAIN_NIC); - } -} - /* * In case of missing eth header, append eth header with a MAC address * assigned to the VF. @@ -4363,10 +4347,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); if (header_id == MLX4_NET_TRANS_RULE_ID_ETH) - handle_eth_header_mcast_prio(ctrl, rule_header); - - if (slave == dev->caps.function) - goto execute; + mlx4_handle_eth_header_mcast_prio(ctrl, rule_header); switch (header_id) { case MLX4_NET_TRANS_RULE_ID_ETH: @@ -4394,7 +4375,6 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, goto err_put_qp; } -execute: err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, vhcr->in_modifier, 0, MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 93bdb3485192..6533c16e27ad 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -1384,6 +1384,8 @@ int set_phv_bit(struct mlx4_dev *dev, u8 port, int new_val); int get_phv_bit(struct mlx4_dev *dev, u8 port, int *phv); int mlx4_get_is_vlan_offload_disabled(struct mlx4_dev *dev, u8 port, bool *vlan_offload_disabled); +void mlx4_handle_eth_header_mcast_prio(struct mlx4_net_trans_rule_hw_ctrl *ctrl, + struct _rule_hw *eth_header); int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx); int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx); int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); From 2983f296f2327bc517e3b29344fce82271160197 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Thu, 8 Dec 2016 17:31:14 +0530 Subject: [PATCH 102/359] pinctrl/amd: Set the level based on ACPI tables In the function amd_gpio_irq_set_type, read the values from the ACPI table to set the level and drop the settings passed by the client. Cc: # 4.8.x+ Reviewed-by: Pankaj Sen Reviewed-by: Nitesh Kumar Agrawal Reviewed-by: Shah, Nehal-bakulchandra Signed-off-by: Shyam-sundar S-k Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index aea310a91821..c9a146948192 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -382,26 +382,21 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type) { int ret = 0; u32 pin_reg; - unsigned long flags; - bool level_trig; - u32 active_level; + unsigned long flags, irq_flags; struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct amd_gpio *gpio_dev = gpiochip_get_data(gc); spin_lock_irqsave(&gpio_dev->lock, flags); pin_reg = readl(gpio_dev->base + (d->hwirq)*4); - /* - * When level_trig is set EDGE and active_level is set HIGH in BIOS - * default settings, ignore incoming settings from client and use - * BIOS settings to configure GPIO register. + /* Ignore the settings coming from the client and + * read the values from the ACPI tables + * while setting the trigger type */ - level_trig = !(pin_reg & (LEVEL_TRIGGER << LEVEL_TRIG_OFF)); - active_level = pin_reg & (ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); - if(level_trig && - ((active_level >> ACTIVE_LEVEL_OFF) == ACTIVE_HIGH)) - type = IRQ_TYPE_EDGE_FALLING; + irq_flags = irq_get_trigger_type(d->irq); + if (irq_flags != IRQ_TYPE_NONE) + type = irq_flags; switch (type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_RISING: From f24d311f92b516a8aadef5056424ccabb4068e7b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 6 Dec 2016 15:08:16 +0100 Subject: [PATCH 103/359] pinctrl: meson: fix gpio request disabling other modes The pinctrl_gpio_request is called with the "full" gpio number, already containing the base, then meson_pmx_request_gpio is then called with the final pin number. Remove the base addition when calling meson_pmx_disable_other_groups. Fixes: 6ac730951104 ("pinctrl: add driver for Amlogic Meson SoCs") CC: Beniamino Galvani Signed-off-by: Neil Armstrong Acked-by: Kevin Hilman Acked-by: Beniamino Galvani Signed-off-by: Linus Walleij --- drivers/pinctrl/meson/pinctrl-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index a579126832af..620c231a2889 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -212,7 +212,7 @@ static int meson_pmx_request_gpio(struct pinctrl_dev *pcdev, { struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); - meson_pmx_disable_other_groups(pc, range->pin_base + offset, -1); + meson_pmx_disable_other_groups(pc, offset, -1); return 0; } From 41744213602a206f24adcb4a2b7551db3c700e72 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 26 Dec 2016 12:46:01 +0100 Subject: [PATCH 104/359] parisc: Mark cr16 clocksource unstable on SMP systems The cr16 interval timer of each CPU is not syncronized to other cr16 timers in other CPUs in a SMP system. So, delay the registration of the cr16 clocksource until all CPUs have been detected and then - if we are on a SMP machine - mark the cr16 clocksource as unstable and lower it's rating before registering it at the clocksource framework. This patch fixes the stalled CPU warnings which we have seen since introduction of the cr16 clocksource. Signed-off-by: Helge Deller Cc: # v4.8+ --- arch/parisc/kernel/time.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index da0d9cb63403..1e22f981cd81 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -235,9 +235,26 @@ void __init time_init(void) cr16_hz = 100 * PAGE0->mem_10msec; /* Hz */ - /* register at clocksource framework */ - clocksource_register_hz(&clocksource_cr16, cr16_hz); - /* register as sched_clock source */ sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz); } + +static int __init init_cr16_clocksource(void) +{ + /* + * The cr16 interval timers are not syncronized across CPUs, so mark + * them unstable and lower rating on SMP systems. + */ + if (num_online_cpus() > 1) { + clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; + clocksource_cr16.rating = 0; + } + + /* register at clocksource framework */ + clocksource_register_hz(&clocksource_cr16, + 100 * PAGE0->mem_10msec); + + return 0; +} + +device_initcall(init_cr16_clocksource); From 1fe0a7e0bc52024a445945c9e7691551aba97390 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 27 Dec 2016 18:03:50 +0100 Subject: [PATCH 105/359] parisc: Drop TIF_RESTORE_SIGMASK and switch to generic code Commit 7e7814180b33 ("signal: consolidate {TS,TLF}_RESTORE_SIGMASK code") introduced code with which the "restore sigmask" flag lives in task_struct instead of ti->flags. Let's use this optimization on parisc too. Signed-off-by: Helge Deller --- arch/parisc/include/asm/thread_info.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 7581330ea35b..88fe0aad4390 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h @@ -49,7 +49,6 @@ struct thread_info { #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_32BIT 4 /* 32 bit binary */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */ -#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ #define TIF_SINGLESTEP 9 /* single stepping? */ From 2344ef3c86a7fe41f97bf66c7936001b6132860b Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 30 Dec 2016 00:07:38 +0300 Subject: [PATCH 106/359] sh_eth: fix branch prediction in sh_eth_interrupt() IIUC, likely()/unlikely() should apply to the whole *if* statement's expression, not a part of it -- fix such expression in sh_eth_interrupt() accordingly... Fixes: 283e38db65e7 ("sh_eth: Fix serialisation of interrupt disable with interrupt & NAPI handlers") Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index f341c1bc7001..0af7fc279c85 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1656,7 +1656,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) else goto out; - if (!likely(mdp->irq_enabled)) { + if (unlikely(!mdp->irq_enabled)) { sh_eth_write(ndev, 0, EESIPR); goto out; } From f5a0aab84b74de68523599817569c057c7ac1622 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 29 Dec 2016 15:29:03 -0800 Subject: [PATCH 107/359] net: ipv4: dst for local input routes should use l3mdev if relevant IPv4 output routes already use l3mdev device instead of loopback for dst's if it is applicable. Change local input routes to do the same. This fixes icmp responses for unreachable UDP ports which are directed to the wrong table after commit 9d1a6c4ea43e4 because local_input routes use the loopback device. Moving from ingress device to loopback loses the L3 domain causing responses based on the dst to get to lost. Fixes: 9d1a6c4ea43e4 ("net: icmp_route_lookup should use rt dev to determine L3 domain") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- net/ipv4/route.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a82a11747b3f..0fcac8e7a2b2 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1914,7 +1914,8 @@ out: return err; } } - rth = rt_dst_alloc(net->loopback_dev, flags | RTCF_LOCAL, res.type, + rth = rt_dst_alloc(l3mdev_master_dev_rcu(dev) ? : net->loopback_dev, + flags | RTCF_LOCAL, res.type, IN_DEV_CONF_GET(in_dev, NOPOLICY), false, do_cache); if (!rth) goto e_nobufs; From 3d387d923c18afbacef8f14ccaa2ace2a297df74 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 28 Dec 2016 17:42:09 +0100 Subject: [PATCH 108/359] drm/printer: add debug printer Useful for dumping lots of data into dmesg, e.g. drm_mm. v2: Fixup export_symbol line, I misplaced a hunk (Chris). Cc: Rob Clark Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1482943330-11592-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_print.c | 6 ++++++ include/drm/drm_print.h | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index ad3caaa1f48b..02a107d50706 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -40,6 +40,12 @@ void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf) } EXPORT_SYMBOL(__drm_printfn_info); +void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf) +{ + pr_debug("%s %pV", p->prefix, vaf); +} +EXPORT_SYMBOL(__drm_printfn_debug); + /** * drm_printf - print to a &drm_printer stream * @p: the &drm_printer diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 1adf84aea622..e9d0ba20089c 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -60,19 +60,20 @@ /** * struct drm_printer - drm output "stream" - * @printfn: actual output fxn - * @arg: output fxn specific data * * Do not use struct members directly. Use drm_printer_seq_file(), * drm_printer_info(), etc to initialize. And drm_printf() for output. */ struct drm_printer { + /* private: */ void (*printfn)(struct drm_printer *p, struct va_format *vaf); void *arg; + const char *prefix; }; void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); +void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf); void drm_printf(struct drm_printer *p, const char *f, ...); @@ -109,4 +110,19 @@ static inline struct drm_printer drm_info_printer(struct device *dev) return p; } +/** + * drm_debug_printer - construct a &drm_printer that outputs to pr_debug() + * @prefix: debug output prefix + * + * RETURNS: + * The &drm_printer object + */ +static inline struct drm_printer drm_debug_printer(const char *prefix) +{ + struct drm_printer p = { + .printfn = __drm_printfn_debug, + .prefix = prefix + }; + return p; +} #endif /* DRM_PRINT_H_ */ From 01d1f7a99e457952aa51849ed7c1cc4ced7bca4b Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Thu, 8 Dec 2016 15:22:58 +0100 Subject: [PATCH 109/359] iio: bmi160: Fix time needed to sleep after command execution Datasheet specifies typical and maximum execution times for which CMD register is occupied after previous command execution. We took these values as minimum and maximum time for usleep_range() call before making a new command execution. To be sure, that the CMD register is no longer occupied we need to wait *at least* the maximum time specified by datasheet. Signed-off-by: Marcin Niestroj Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/imu/bmi160/bmi160_core.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index 5355507f8fa1..c9e319bff58b 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -66,10 +66,8 @@ #define BMI160_REG_DUMMY 0x7F -#define BMI160_ACCEL_PMU_MIN_USLEEP 3200 -#define BMI160_ACCEL_PMU_MAX_USLEEP 3800 -#define BMI160_GYRO_PMU_MIN_USLEEP 55000 -#define BMI160_GYRO_PMU_MAX_USLEEP 80000 +#define BMI160_ACCEL_PMU_MIN_USLEEP 3800 +#define BMI160_GYRO_PMU_MIN_USLEEP 80000 #define BMI160_SOFTRESET_USLEEP 1000 #define BMI160_CHANNEL(_type, _axis, _index) { \ @@ -151,20 +149,9 @@ static struct bmi160_regs bmi160_regs[] = { }, }; -struct bmi160_pmu_time { - unsigned long min; - unsigned long max; -}; - -static struct bmi160_pmu_time bmi160_pmu_time[] = { - [BMI160_ACCEL] = { - .min = BMI160_ACCEL_PMU_MIN_USLEEP, - .max = BMI160_ACCEL_PMU_MAX_USLEEP - }, - [BMI160_GYRO] = { - .min = BMI160_GYRO_PMU_MIN_USLEEP, - .max = BMI160_GYRO_PMU_MIN_USLEEP, - }, +static unsigned long bmi160_pmu_time[] = { + [BMI160_ACCEL] = BMI160_ACCEL_PMU_MIN_USLEEP, + [BMI160_GYRO] = BMI160_GYRO_PMU_MIN_USLEEP, }; struct bmi160_scale { @@ -289,7 +276,7 @@ int bmi160_set_mode(struct bmi160_data *data, enum bmi160_sensor_type t, if (ret < 0) return ret; - usleep_range(bmi160_pmu_time[t].min, bmi160_pmu_time[t].max); + usleep_range(bmi160_pmu_time[t], bmi160_pmu_time[t] + 1000); return 0; } From b5c3714fe8789745521d8351d75049b9c6a0d26b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 12:09:24 +0100 Subject: [PATCH 110/359] drm/mm: Convert to drm_printer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Including all drivers. I thought about keeping small compat functions to avoid having to change all drivers. But I really like the drm_printer idea, so figured spreading it more widely is a good thing. v2: Review from Chris: - Natural argument order and better name for drm_mm_print. - show_mm() macro in the selftest. Cc: Rob Clark Cc: Russell King Cc: Alex Deucher Cc: Christian König Cc: Lucas Stach Cc: Tomi Valkeinen Cc: Thierry Reding Cc: Jyri Sarha Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483009764-8281-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 3 +- drivers/gpu/drm/armada/armada_debugfs.c | 6 +- drivers/gpu/drm/drm_mm.c | 67 ++++---------------- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 10 +-- drivers/gpu/drm/msm/msm_debugfs.c | 6 +- drivers/gpu/drm/omapdrm/omap_debugfs.c | 6 +- drivers/gpu/drm/qxl/qxl_ttm.c | 6 +- drivers/gpu/drm/radeon/radeon_ttm.c | 6 +- drivers/gpu/drm/selftests/test-drm_mm.c | 12 ++-- drivers/gpu/drm/tegra/drm.c | 5 +- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 +- drivers/gpu/drm/ttm/ttm_bo_manager.c | 3 +- include/drm/drm_mm.h | 9 +-- 15 files changed, 62 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index 00f46b0e076d..c6c125d31161 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -235,9 +235,10 @@ static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man, const char *prefix) { struct amdgpu_gtt_mgr *mgr = man->priv; + struct drm_printer p = drm_debug_printer(prefix); spin_lock(&mgr->lock); - drm_mm_debug_table(&mgr->mm, prefix); + drm_mm_print(&mgr->mm, &p); spin_unlock(&mgr->lock); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index bc70f80260d8..88e77045bdd6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1482,18 +1482,18 @@ static int amdgpu_mm_dump_table(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = dev->dev_private; struct drm_mm *mm = (struct drm_mm *)adev->mman.bdev.man[ttm_pl].priv; - int ret; struct ttm_bo_global *glob = adev->mman.bdev.glob; + struct drm_printer p = drm_seq_file_printer(m); spin_lock(&glob->lru_lock); - ret = drm_mm_dump_table(m, mm); + drm_mm_print(mm, &p); spin_unlock(&glob->lru_lock); if (ttm_pl == TTM_PL_VRAM) seq_printf(m, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n", adev->mman.bdev.man[ttm_pl].size, (u64)atomic64_read(&adev->vram_usage) >> 20, (u64)atomic64_read(&adev->vram_vis_usage) >> 20); - return ret; + return 0; } static int ttm_pl_vram = TTM_PL_VRAM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index d710226a0fff..ac9007986c11 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -207,9 +207,10 @@ static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, const char *prefix) { struct amdgpu_vram_mgr *mgr = man->priv; + struct drm_printer p = drm_debug_printer(prefix); spin_lock(&mgr->lock); - drm_mm_debug_table(&mgr->mm, prefix); + drm_mm_print(&mgr->mm, &p); spin_unlock(&mgr->lock); } diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c index 90222e60d2d6..0c7b915be082 100644 --- a/drivers/gpu/drm/armada/armada_debugfs.c +++ b/drivers/gpu/drm/armada/armada_debugfs.c @@ -19,13 +19,13 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct armada_private *priv = dev->dev_private; - int ret; + struct drm_printer p = drm_seq_file_printer(m); mutex_lock(&priv->linear_lock); - ret = drm_mm_dump_table(m, &priv->linear); + drm_mm_dump_table(&p, &priv->linear); mutex_unlock(&priv->linear_lock); - return ret; + return 0; } static int armada_debugfs_reg_show(struct seq_file *m, void *data) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 1a5b4eba2386..e54aa3fa538f 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -832,8 +832,7 @@ void drm_mm_takedown(struct drm_mm *mm) } EXPORT_SYMBOL(drm_mm_takedown); -static u64 drm_mm_debug_hole(const struct drm_mm_node *entry, - const char *prefix) +static u64 drm_mm_dump_hole(struct drm_printer *p, const struct drm_mm_node *entry) { u64 hole_start, hole_end, hole_size; @@ -841,49 +840,7 @@ static u64 drm_mm_debug_hole(const struct drm_mm_node *entry, hole_start = drm_mm_hole_node_start(entry); hole_end = drm_mm_hole_node_end(entry); hole_size = hole_end - hole_start; - pr_debug("%s %#llx-%#llx: %llu: free\n", prefix, hole_start, - hole_end, hole_size); - return hole_size; - } - - return 0; -} - -/** - * drm_mm_debug_table - dump allocator state to dmesg - * @mm: drm_mm allocator to dump - * @prefix: prefix to use for dumping to dmesg - */ -void drm_mm_debug_table(const struct drm_mm *mm, const char *prefix) -{ - const struct drm_mm_node *entry; - u64 total_used = 0, total_free = 0, total = 0; - - total_free += drm_mm_debug_hole(&mm->head_node, prefix); - - drm_mm_for_each_node(entry, mm) { - pr_debug("%s %#llx-%#llx: %llu: used\n", prefix, entry->start, - entry->start + entry->size, entry->size); - total_used += entry->size; - total_free += drm_mm_debug_hole(entry, prefix); - } - total = total_free + total_used; - - pr_debug("%s total: %llu, used %llu free %llu\n", prefix, total, - total_used, total_free); -} -EXPORT_SYMBOL(drm_mm_debug_table); - -#if defined(CONFIG_DEBUG_FS) -static u64 drm_mm_dump_hole(struct seq_file *m, const struct drm_mm_node *entry) -{ - u64 hole_start, hole_end, hole_size; - - if (entry->hole_follows) { - hole_start = drm_mm_hole_node_start(entry); - hole_end = drm_mm_hole_node_end(entry); - hole_size = hole_end - hole_start; - seq_printf(m, "%#018llx-%#018llx: %llu: free\n", hole_start, + drm_printf(p, "%#018llx-%#018llx: %llu: free\n", hole_start, hole_end, hole_size); return hole_size; } @@ -892,28 +849,26 @@ static u64 drm_mm_dump_hole(struct seq_file *m, const struct drm_mm_node *entry) } /** - * drm_mm_dump_table - dump allocator state to a seq_file - * @m: seq_file to dump to - * @mm: drm_mm allocator to dump + * drm_mm_print - print allocator state + * @mm: drm_mm allocator to print + * @p: DRM printer to use */ -int drm_mm_dump_table(struct seq_file *m, const struct drm_mm *mm) +void drm_mm_print(const struct drm_mm *mm, struct drm_printer *p) { const struct drm_mm_node *entry; u64 total_used = 0, total_free = 0, total = 0; - total_free += drm_mm_dump_hole(m, &mm->head_node); + total_free += drm_mm_dump_hole(p, &mm->head_node); drm_mm_for_each_node(entry, mm) { - seq_printf(m, "%#018llx-%#018llx: %llu: used\n", entry->start, + drm_printf(p, "%#018llx-%#018llx: %llu: used\n", entry->start, entry->start + entry->size, entry->size); total_used += entry->size; - total_free += drm_mm_dump_hole(m, entry); + total_free += drm_mm_dump_hole(p, entry); } total = total_free + total_used; - seq_printf(m, "total: %llu, used %llu free %llu\n", total, + drm_printf(p, "total: %llu, used %llu free %llu\n", total, total_used, total_free); - return 0; } -EXPORT_SYMBOL(drm_mm_dump_table); -#endif +EXPORT_SYMBOL(drm_mm_print); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 30d70ed143f7..b92c24e07cea 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -147,21 +147,23 @@ static int etnaviv_gem_show(struct drm_device *dev, struct seq_file *m) static int etnaviv_mm_show(struct drm_device *dev, struct seq_file *m) { - int ret; + struct drm_printer p = drm_seq_file_printer(m); read_lock(&dev->vma_offset_manager->vm_lock); - ret = drm_mm_dump_table(m, &dev->vma_offset_manager->vm_addr_space_mm); + drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); read_unlock(&dev->vma_offset_manager->vm_lock); - return ret; + return 0; } static int etnaviv_mmu_show(struct etnaviv_gpu *gpu, struct seq_file *m) { + struct drm_printer p = drm_seq_file_printer(m); + seq_printf(m, "Active Objects (%s):\n", dev_name(gpu->dev)); mutex_lock(&gpu->mmu->lock); - drm_mm_dump_table(m, &gpu->mmu->mm); + drm_mm_print(&gpu->mmu->mm, &p); mutex_unlock(&gpu->mmu->lock); return 0; diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index c1b40f5adb60..387f0616e115 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -52,7 +52,11 @@ static int msm_gem_show(struct drm_device *dev, struct seq_file *m) static int msm_mm_show(struct drm_device *dev, struct seq_file *m) { - return drm_mm_dump_table(m, &dev->vma_offset_manager->vm_addr_space_mm); + struct drm_printer p = drm_seq_file_printer(m); + + drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); + + return 0; } static int msm_fb_show(struct drm_device *dev, struct seq_file *m) diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c index 479bf24050f8..bf65862daf62 100644 --- a/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c @@ -50,7 +50,11 @@ static int mm_show(struct seq_file *m, void *arg) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - return drm_mm_dump_table(m, &dev->vma_offset_manager->vm_addr_space_mm); + struct drm_printer p = drm_seq_file_printer(m); + + drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); + + return 0; } #ifdef CONFIG_DRM_FBDEV_EMULATION diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 11761330a6b8..1b096c5252ad 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -463,13 +463,13 @@ static int qxl_mm_dump_table(struct seq_file *m, void *data) struct drm_mm *mm = (struct drm_mm *)node->info_ent->data; struct drm_device *dev = node->minor->dev; struct qxl_device *rdev = dev->dev_private; - int ret; struct ttm_bo_global *glob = rdev->mman.bdev.glob; + struct drm_printer p = drm_seq_file_printer(m); spin_lock(&glob->lru_lock); - ret = drm_mm_dump_table(m, mm); + drm_mm_print(mm, &p); spin_unlock(&glob->lru_lock); - return ret; + return 0; } #endif diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0cf03ccbf0a7..1888144d0fed 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -1033,13 +1033,13 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; struct drm_mm *mm = (struct drm_mm *)rdev->mman.bdev.man[ttm_pl].priv; - int ret; struct ttm_bo_global *glob = rdev->mman.bdev.glob; + struct drm_printer p = drm_seq_file_printer(m); spin_lock(&glob->lru_lock); - ret = drm_mm_dump_table(m, mm); + drm_mm_print(mm, &p); spin_unlock(&glob->lru_lock); - return ret; + return 0; } static int ttm_pl_vram = TTM_PL_VRAM; diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 2ce92f4dcfc7..6d2a5cd211f3 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c @@ -194,6 +194,10 @@ static bool assert_node(struct drm_mm_node *node, struct drm_mm *mm, return ok; } +#define show_mm(mm) do { \ + struct drm_printer __p = drm_debug_printer(__func__); \ + drm_mm_print((mm), &__p); } while (0) + static int igt_init(void *ignored) { const unsigned int size = 4096; @@ -250,7 +254,7 @@ static int igt_init(void *ignored) out: if (ret) - drm_mm_debug_table(&mm, __func__); + show_mm(&mm); drm_mm_takedown(&mm); return ret; } @@ -286,7 +290,7 @@ static int igt_debug(void *ignored) return ret; } - drm_mm_debug_table(&mm, __func__); + show_mm(&mm); return 0; } @@ -2031,7 +2035,7 @@ static int igt_color_evict(void *ignored) ret = 0; out: if (ret) - drm_mm_debug_table(&mm, __func__); + show_mm(&mm); drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); drm_mm_takedown(&mm); @@ -2130,7 +2134,7 @@ static int igt_color_evict_range(void *ignored) ret = 0; out: if (ret) - drm_mm_debug_table(&mm, __func__); + show_mm(&mm); drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); drm_mm_takedown(&mm); diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index e289dbc6ad82..4d966cddcc71 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -891,8 +891,11 @@ static int tegra_debugfs_iova(struct seq_file *s, void *data) struct drm_info_node *node = (struct drm_info_node *)s->private; struct drm_device *drm = node->minor->dev; struct tegra_drm *tegra = drm->dev_private; + struct drm_printer p = drm_seq_file_printer(s); - return drm_mm_dump_table(s, &tegra->mm); + drm_mm_print(&tegra->mm, &p); + + return 0; } static struct drm_info_list tegra_debugfs_list[] = { diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index bd0a3bd07167..ec15585c7a27 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -507,7 +507,9 @@ static int tilcdc_mm_show(struct seq_file *m, void *arg) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - return drm_mm_dump_table(m, &dev->vma_offset_manager->vm_addr_space_mm); + struct drm_printer p = drm_seq_file_printer(m); + drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); + return 0; } static struct drm_info_list tilcdc_debugfs_list[] = { diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c index aea6a01500e1..988c48d1cf3e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_manager.c +++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c @@ -141,9 +141,10 @@ static void ttm_bo_man_debug(struct ttm_mem_type_manager *man, const char *prefix) { struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; + struct drm_printer p = drm_debug_printer(prefix); spin_lock(&rman->lock); - drm_mm_debug_table(&rman->mm, prefix); + drm_mm_print(&rman->mm, &p); spin_unlock(&rman->lock); } diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 92ec5759caae..1383ac2328b8 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -42,12 +42,10 @@ #include #include #include -#ifdef CONFIG_DEBUG_FS -#include -#endif #ifdef CONFIG_DRM_DEBUG_MM #include #endif +#include #ifdef CONFIG_DRM_DEBUG_MM #define DRM_MM_BUG_ON(expr) BUG_ON(expr) @@ -462,9 +460,6 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan, struct drm_mm_node *node); struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan); -void drm_mm_debug_table(const struct drm_mm *mm, const char *prefix); -#ifdef CONFIG_DEBUG_FS -int drm_mm_dump_table(struct seq_file *m, const struct drm_mm *mm); -#endif +void drm_mm_print(const struct drm_mm *mm, struct drm_printer *p); #endif From 6d1b81d8e25d81b4ed4363fa3e7d70aa563b7112 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 29 Dec 2016 20:41:28 +0800 Subject: [PATCH 111/359] drm: add crtc helper drm_crtc_from_index() It adds a crtc helper drm_crtc_from_index() to find the registered CRTC with a given index, just like drm_plane_from_index(). Signed-off-by: Shawn Guo Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483015290-16660-2-git-send-email-shawnguo@kernel.org --- drivers/gpu/drm/drm_crtc.c | 20 ++++++++++++++++++++ include/drm/drm_crtc.h | 1 + 2 files changed, 21 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 080c8d361f1f..75e0beeb3793 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -46,6 +46,26 @@ #include "drm_crtc_internal.h" #include "drm_internal.h" +/** + * drm_crtc_from_index - find the registered CRTC at an index + * @dev: DRM device + * @idx: index of registered CRTC to find for + * + * Given a CRTC index, return the registered CRTC from DRM device's + * list of CRTCs with matching index. + */ +struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx) +{ + struct drm_crtc *crtc; + + drm_for_each_crtc(crtc, dev) + if (idx == crtc->index) + return crtc; + + return NULL; +} +EXPORT_SYMBOL(drm_crtc_from_index); + /** * drm_crtc_force_disable - Forcibly turn off a CRTC * @crtc: CRTC to turn off diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 6920dee3a2d1..89daa77c37fc 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -822,6 +822,7 @@ int drm_crtc_force_disable(struct drm_crtc *crtc); int drm_crtc_force_disable_all(struct drm_device *dev); int drm_mode_set_config_internal(struct drm_mode_set *set); +struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx); /* Helpers */ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, From ac620ba3d09bc96eca203658ad2e145adf911ac3 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 29 Dec 2016 20:41:29 +0800 Subject: [PATCH 112/359] drm: zte: use crtc helper drm_crtc_from_index() Function zx_find_crtc() does the exactly same thing as what crtc helper drm_crtc_from_index() provides. Use the helper to save some code. Signed-off-by: Shawn Guo Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483015290-16660-3-git-send-email-shawnguo@kernel.org --- drivers/gpu/drm/zte/zx_vou.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c index 73fe15c17c32..a86e3a5852a2 100644 --- a/drivers/gpu/drm/zte/zx_vou.c +++ b/drivers/gpu/drm/zte/zx_vou.c @@ -355,17 +355,6 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou, return 0; } -static inline struct drm_crtc *zx_find_crtc(struct drm_device *drm, int pipe) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) - if (crtc->index == pipe) - return crtc; - - return NULL; -} - int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe) { struct drm_crtc *crtc; @@ -373,7 +362,7 @@ int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe) struct zx_vou_hw *vou; u32 int_frame_mask; - crtc = zx_find_crtc(drm, pipe); + crtc = drm_crtc_from_index(drm, pipe); if (!crtc) return 0; @@ -393,7 +382,7 @@ void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe) struct zx_crtc *zcrtc; struct zx_vou_hw *vou; - crtc = zx_find_crtc(drm, pipe); + crtc = drm_crtc_from_index(drm, pipe); if (!crtc) return; From 48df6336d770a5a1fcc83bef9f1d541600983b5f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 29 Dec 2016 20:41:30 +0800 Subject: [PATCH 113/359] drm: rockchip: use crtc helper drm_crtc_from_index() Function rockchip_crtc_from_pipe() does the exactly same thing as what crtc helper drm_crtc_from_index() provides. Use the helper to save some code. Signed-off-by: Shawn Guo Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483015290-16660-4-git-send-email-shawnguo@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 2390c8577617..c30d649cb147 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -99,24 +99,11 @@ void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc) priv->crtc_funcs[pipe] = NULL; } -static struct drm_crtc *rockchip_crtc_from_pipe(struct drm_device *drm, - int pipe) -{ - struct drm_crtc *crtc; - int i = 0; - - list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) - if (i++ == pipe) - return crtc; - - return NULL; -} - static int rockchip_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct rockchip_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc = rockchip_crtc_from_pipe(dev, pipe); + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); if (crtc && priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->enable_vblank) @@ -129,7 +116,7 @@ static void rockchip_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct rockchip_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc = rockchip_crtc_from_pipe(dev, pipe); + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); if (crtc && priv->crtc_funcs[pipe] && priv->crtc_funcs[pipe]->enable_vblank) From e82dfa00da407eee80acbd6297003eb5ce913fcc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 29 Dec 2016 13:37:29 +0000 Subject: [PATCH 114/359] drm: Reduce verbosity level for drm_core_init() debug message Currently at the end of drm_core_init() we print [ 0.735185] [drm] Initialized which does not provide any user information and is only a breadcrumb for developers, so reduce it from info to debug. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161229133729.32673-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 4a7b3e98d586..bf3df4e4fdce 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -924,7 +924,7 @@ static int __init drm_core_init(void) if (ret < 0) goto error; - DRM_INFO("Initialized\n"); + DRM_DEBUG("Initialized\n"); return 0; error: From 75f6dfe3e652e1adef8cc1b073c89f3e22103a8f Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Wed, 28 Dec 2016 12:32:11 -0200 Subject: [PATCH 115/359] drm: Deduplicate driver initialization message Several DRM drivers print the same initialization message right after drm_dev_register, so move that to common code. The exception is i915, which uses its own register handle, so let it keep its own message. Notice that this was tested only with Exynos, but looks simple enough for the other drivers. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161228143216.26821-2-krisman@collabora.co.uk --- drivers/gpu/drm/armada/armada_drv.c | 6 ------ drivers/gpu/drm/drm_drv.c | 7 +++++++ drivers/gpu/drm/drm_pci.c | 4 ---- drivers/gpu/drm/drm_platform.c | 4 ---- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 4 ---- drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 4 ---- drivers/gpu/drm/tegra/drm.c | 4 ---- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 4 ---- 8 files changed, 7 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 07086b427c22..63f42d001f33 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -203,12 +203,6 @@ static int armada_drm_bind(struct device *dev) armada_drm_debugfs_init(priv->drm.primary); #endif - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - armada_drm_driver.name, armada_drm_driver.major, - armada_drm_driver.minor, armada_drm_driver.patchlevel, - armada_drm_driver.date, dev_name(dev), - priv->drm.primary->index); - return 0; err_poll: diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index bf3df4e4fdce..9d2b4b630601 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -728,6 +728,7 @@ static void remove_compat_control_link(struct drm_device *dev) */ int drm_dev_register(struct drm_device *dev, unsigned long flags) { + struct drm_driver *driver = dev->driver; int ret; mutex_lock(&drm_global_mutex); @@ -758,6 +759,12 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) drm_modeset_register_all(dev); ret = 0; + + DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + driver->name, driver->major, driver->minor, + driver->patchlevel, driver->date, dev_name(dev->dev), + dev->primary->index); + goto out_unlock; err_minors: diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 3ceea9cb9d3e..dc358f860aea 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -257,10 +257,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if (ret) goto err_agp; - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, pci_name(pdev), dev->primary->index); - /* No locking needed since shadow-attach is single-threaded since it may * only be called from the per-driver module init hook. */ if (drm_core_check_feature(dev, DRIVER_LEGACY)) diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 026269851ce9..7af3005a030c 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -57,10 +57,6 @@ static int drm_get_platform_dev(struct platform_device *platdev, if (ret) goto err_free; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - return 0; err_free: diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 0b35da73c2b0..9a31711d5158 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -415,10 +415,6 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) if (ret < 0) goto unref; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, - driver->major, driver->minor, driver->patchlevel, - driver->date, drm->primary->index); - return 0; unref: diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index fa228b7b022c..7df0e8535e41 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -217,10 +217,6 @@ static int kirin_drm_bind(struct device *dev) if (ret) goto err_kms_cleanup; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, drm_dev->primary->index); - return 0; err_kms_cleanup: diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 4d966cddcc71..2817f43f3344 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -995,10 +995,6 @@ static int host1x_drm_probe(struct host1x_device *dev) if (err < 0) goto unref; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, - driver->major, driver->minor, driver->patchlevel, - driver->date, drm->primary->index); - return 0; unref: diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c index 3b97d50fd392..43e1d5916c6c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c @@ -83,10 +83,6 @@ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev) if (ret) goto err_free; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, - driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - return 0; err_free: From 8caead148a45764bf4adb33220271d0266b85fe5 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Wed, 28 Dec 2016 12:32:13 -0200 Subject: [PATCH 116/359] drm: Drop unused forward declaration of drm_version Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161228143216.26821-4-krisman@collabora.co.uk --- drivers/gpu/drm/drm_ioctl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index d180673c1323..5c80e720aeca 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -95,9 +95,6 @@ * broken. */ -static int drm_version(struct drm_device *dev, void *data, - struct drm_file *file_priv); - /* * Get the bus id. * From 5bbf92d3eb01cb5adcf613e2532dc918172c598f Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Wed, 28 Dec 2016 12:32:14 -0200 Subject: [PATCH 117/359] drm: Export drm_ioctl_permit to kernel-doc drm_ioctl_permit is exported but missed a kernel-doc style documentation. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161228143216.26821-5-krisman@collabora.co.uk --- drivers/gpu/drm/drm_ioctl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 5c80e720aeca..a7c61c23685a 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -478,15 +478,17 @@ static int drm_version(struct drm_device *dev, void *data, return err; } -/* +/** * drm_ioctl_permit - Check ioctl permissions against caller * * @flags: ioctl permission flags. * @file_priv: Pointer to struct drm_file identifying the caller. * * Checks whether the caller is allowed to run an ioctl with the - * indicated permissions. If so, returns zero. Otherwise returns an - * error code suitable for ioctl return. + * indicated permissions. + * + * Returns: + * Zero if allowed, -EACCES otherwise. */ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) { From b834ff86a61c236282e68890c17316f6928eebad Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Fri, 30 Dec 2016 12:50:49 +0100 Subject: [PATCH 118/359] drm: Update TTM initialization documentation ttm_global_reference was renamed to drm_global_reference. This updates the documentation to reflect that. While we are there, document the drm_global_reference API and update the initialization interface documentation. Signed-off-by: Gabriel Krisman Bertazi [danvet: Keep the warning, ttm docs are still massively inadequate.] Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161228143216.26821-7-krisman@collabora.co.uk --- Documentation/gpu/drm-mm.rst | 27 +++++++++++++++++---------- drivers/gpu/drm/drm_global.c | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index cb5daffcd6be..0285b68f6201 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -34,25 +34,26 @@ TTM initialization ------------------ **Warning** - This section is outdated. -Drivers wishing to support TTM must fill out a drm_bo_driver -structure. The structure contains several fields with function pointers -for initializing the TTM, allocating and freeing memory, waiting for -command completion and fence synchronization, and memory migration. See -the radeon_ttm.c file for an example of usage. +Drivers wishing to support TTM must pass a filled :c:type:`ttm_bo_driver +` structure to ttm_bo_device_init, together with an +initialized global reference to the memory manager. The ttm_bo_driver +structure contains several fields with function pointers for +initializing the TTM, allocating and freeing memory, waiting for command +completion and fence synchronization, and memory migration. -The ttm_global_reference structure is made up of several fields: +The :c:type:`struct drm_global_reference ` is made +up of several fields: .. code-block:: c - struct ttm_global_reference { + struct drm_global_reference { enum ttm_global_types global_type; size_t size; void *object; - int (*init) (struct ttm_global_reference *); - void (*release) (struct ttm_global_reference *); + int (*init) (struct drm_global_reference *); + void (*release) (struct drm_global_reference *); }; @@ -76,6 +77,12 @@ ttm_bo_global_release(), respectively. Also, like the previous object, ttm_global_item_ref() is used to create an initial reference count for the TTM, which will call your initialization function. +See the radeon_ttm.c file for an example of usage. + +.. kernel-doc:: drivers/gpu/drm/drm_global.c + :export: + + The Graphics Execution Manager (GEM) ==================================== diff --git a/drivers/gpu/drm/drm_global.c b/drivers/gpu/drm/drm_global.c index b404287abb97..b2dc21e33ae0 100644 --- a/drivers/gpu/drm/drm_global.c +++ b/drivers/gpu/drm/drm_global.c @@ -63,6 +63,18 @@ void drm_global_release(void) } } +/** + * drm_global_item_ref - Initialize and acquire reference to memory + * object + * @ref: Object for initialization + * + * This initializes a memory object, allocating memory and calling the + * .init() hook. Further calls will increase the reference count for + * that item. + * + * Returns: + * Zero on success, non-zero otherwise. + */ int drm_global_item_ref(struct drm_global_reference *ref) { int ret = 0; @@ -97,6 +109,17 @@ int drm_global_item_ref(struct drm_global_reference *ref) } EXPORT_SYMBOL(drm_global_item_ref); +/** + * drm_global_item_unref - Drop reference to memory + * object + * @ref: Object being removed + * + * Drop a reference to the memory object and eventually call the + * release() hook. The allocated object should be dropped in the + * release() hook or before calling this function + * + */ + void drm_global_item_unref(struct drm_global_reference *ref) { struct drm_global_item *item = &glob[ref->global_type]; From a8182863438232dce79f76cc511d752a219ff33a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:21 +0100 Subject: [PATCH 119/359] drm/docs: Small cleanup in drm-uapi.rst - Remove the outdated hunk about driver documentation which somehow got misplaced here in the split-up. - Collect all the testing&validation stuff together and give the CRC section a heading for prettier output. Cc: Tomeu Vizoso Cc: Jani Nikula Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-1-git-send-email-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-uapi.rst | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index de3ac9f90f8f..fcc228ef5bc4 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -156,8 +156,12 @@ other hand, a driver requires shared state between clients which is visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes. + +Testing and validation +====================== + Validating changes with IGT -=========================== +--------------------------- There's a collection of tests that aims to cover the whole functionality of DRM drivers and that can be used to check that changes to DRM drivers or the @@ -193,6 +197,12 @@ run-tests.sh is a wrapper around piglit that will execute the tests matching the -t options. A report in HTML format will be available in ./results/html/index.html. Results can be compared with piglit. +Display CRC Support +------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c + :doc: CRC ABI + VBlank event handling ===================== @@ -209,16 +219,3 @@ DRM_IOCTL_MODESET_CTL mode setting, since on many devices the vertical blank counter is reset to 0 at some point during modeset. Modern drivers should not call this any more since with kernel mode setting it is a no-op. - -This second part of the GPU Driver Developer's Guide documents driver -code, implementation details and also all the driver-specific userspace -interfaces. Especially since all hardware-acceleration interfaces to -userspace are driver specific for efficiency and other reasons these -interfaces can be rather substantial. Hence every driver has its own -chapter. - -Testing and validation -====================== - -.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c - :doc: CRC ABI From 05fc03217e08b90bff1ff22792d5f86dd32f15a6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:23 +0100 Subject: [PATCH 120/359] drm/mm: Some doc polish Added some boilerplate for the structs, documented members where they are relevant and plenty of markup for hyperlinks all over. And a few small wording polish. Note that the intro needs some more love after the DRM_MM_INSERT_* patch from Chris has landed. v2: Spelling fixes (Chris). v3: Use &struct foo instead of &foo structure (Chris). Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-3-git-send-email-daniel.vetter@ffwll.ch --- Documentation/gpu/drm-mm.rst | 2 +- drivers/gpu/drm/drm_mm.c | 41 ++++++++++-------- include/drm/drm_mm.h | 84 ++++++++++++++++++++++++++++-------- 3 files changed, 89 insertions(+), 38 deletions(-) diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 0285b68f6201..d3c6d77246cd 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -449,7 +449,7 @@ LRU Scan/Eviction Support ------------------------- .. kernel-doc:: drivers/gpu/drm/drm_mm.c - :doc: lru scan roaster + :doc: lru scan roster DRM MM Range Allocator Function References ------------------------------------------ diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index e54aa3fa538f..229b3f525dee 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -59,8 +59,8 @@ * * The main data struct is &drm_mm, allocations are tracked in &drm_mm_node. * Drivers are free to embed either of them into their own suitable - * datastructures. drm_mm itself will not do any allocations of its own, so if - * drivers choose not to embed nodes they need to still allocate them + * datastructures. drm_mm itself will not do any memory allocations of its own, + * so if drivers choose not to embed nodes they need to still allocate them * themselves. * * The range allocator also supports reservation of preallocated blocks. This is @@ -78,7 +78,7 @@ * steep cliff not a real concern. Removing a node again is O(1). * * drm_mm supports a few features: Alignment and range restrictions can be - * supplied. Further more every &drm_mm_node has a color value (which is just an + * supplied. Furthermore every &drm_mm_node has a color value (which is just an * opaque unsigned long) which in conjunction with a driver callback can be used * to implement sophisticated placement restrictions. The i915 DRM driver uses * this to implement guard pages between incompatible caching domains in the @@ -296,11 +296,11 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, * @mm: drm_mm allocator to insert @node into * @node: drm_mm_node to insert * - * This functions inserts an already set-up drm_mm_node into the allocator, - * meaning that start, size and color must be set by the caller. This is useful - * to initialize the allocator with preallocated objects which must be set-up - * before the range allocator can be set-up, e.g. when taking over a firmware - * framebuffer. + * This functions inserts an already set-up &drm_mm_node into the allocator, + * meaning that start, size and color must be set by the caller. All other + * fields must be cleared to 0. This is useful to initialize the allocator with + * preallocated objects which must be set-up before the range allocator can be + * set-up, e.g. when taking over a firmware framebuffer. * * Returns: * 0 on success, -ENOSPC if there's no hole where @node is. @@ -375,7 +375,7 @@ EXPORT_SYMBOL(drm_mm_reserve_node); * @sflags: flags to fine-tune the allocation search * @aflags: flags to fine-tune the allocation behavior * - * The preallocated node must be cleared to 0. + * The preallocated @node must be cleared to 0. * * Returns: * 0 on success, -ENOSPC if there's no suitable hole. @@ -537,7 +537,7 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) EXPORT_SYMBOL(drm_mm_replace_node); /** - * DOC: lru scan roaster + * DOC: lru scan roster * * Very often GPUs need to have continuous allocations for a given object. When * evicting objects to make space for a new one it is therefore not most @@ -549,9 +549,11 @@ EXPORT_SYMBOL(drm_mm_replace_node); * The DRM range allocator supports this use-case through the scanning * interfaces. First a scan operation needs to be initialized with * drm_mm_scan_init() or drm_mm_scan_init_with_range(). The driver adds - * objects to the roster (probably by walking an LRU list, but this can be - * freely implemented) (using drm_mm_scan_add_block()) until a suitable hole - * is found or there are no further evictable objects. + * objects to the roster, probably by walking an LRU list, but this can be + * freely implemented. Eviction candiates are added using + * drm_mm_scan_add_block() until a suitable hole is found or there are no + * further evictable objects. Eviction roster metadata is tracked in struct + * &drm_mm_scan. * * The driver must walk through all objects again in exactly the reverse * order to restore the allocator state. Note that while the allocator is used @@ -559,7 +561,7 @@ EXPORT_SYMBOL(drm_mm_replace_node); * * Finally the driver evicts all objects selected (drm_mm_scan_remove_block() * reported true) in the scan, and any overlapping nodes after color adjustment - * (drm_mm_scan_evict_color()). Adding and removing an object is O(1), and + * (drm_mm_scan_color_evict()). Adding and removing an object is O(1), and * since freeing a node is also O(1) the overall complexity is * O(scanned_objects). So like the free stack which needs to be walked before a * scan operation even begins this is linear in the number of objects. It @@ -705,14 +707,15 @@ EXPORT_SYMBOL(drm_mm_scan_add_block); * @scan: the active drm_mm scanner * @node: drm_mm_node to remove * - * Nodes _must_ be removed in exactly the reverse order from the scan list as - * they have been added (e.g. using list_add as they are added and then - * list_for_each over that eviction list to remove), otherwise the internal + * Nodes **must** be removed in exactly the reverse order from the scan list as + * they have been added (e.g. using list_add() as they are added and then + * list_for_each() over that eviction list to remove), otherwise the internal * state of the memory manager will be corrupted. * * When the scan list is empty, the selected memory nodes can be freed. An - * immediately following drm_mm_search_free with !DRM_MM_SEARCH_BEST will then - * return the just freed block (because its at the top of the free_stack list). + * immediately following drm_mm_insert_node_in_range_generic() or one of the + * simpler versions of that function with !DRM_MM_SEARCH_BEST will then return + * the just freed block (because its at the top of the free_stack list). * * Returns: * True if this block should be evicted, false otherwise. Will always diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 1383ac2328b8..3bddca8fd2b5 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -67,16 +67,29 @@ enum drm_mm_allocator_flags { #define DRM_MM_BOTTOMUP DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT #define DRM_MM_TOPDOWN DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP +/** + * struct drm_mm_node - allocated block in the DRM allocator + * + * This represents an allocated block in a &drm_mm allocator. Except for + * pre-reserved nodes inserted using drm_mm_reserve_node() the structure is + * entirely opaque and should only be accessed through the provided funcions. + * Since allocation of these nodes is entirely handled by the driver they can be + * embedded. + */ struct drm_mm_node { + /** @color: Opaque driver-private tag. */ + unsigned long color; + /** @start: Start address of the allocated block. */ + u64 start; + /** @size: Size of the allocated block. */ + u64 size; + /* private: */ struct list_head node_list; struct list_head hole_stack; struct rb_node rb; unsigned hole_follows : 1; unsigned allocated : 1; bool scanned_block : 1; - unsigned long color; - u64 start; - u64 size; u64 __subtree_last; struct drm_mm *mm; #ifdef CONFIG_DRM_DEBUG_MM @@ -84,7 +97,29 @@ struct drm_mm_node { #endif }; +/** + * struct drm_mm - DRM allocator + * + * DRM range allocator with a few special functions and features geared towards + * managing GPU memory. Except for the @color_adjust callback the structure is + * entirely opaque and should only be accessed through the provided functions + * and macros. This structure can be embedded into larger driver structures. + */ struct drm_mm { + /** + * @color_adjust: + * + * Optional driver callback to further apply restrictions on a hole. The + * node argument points at the node containing the hole from which the + * block would be allocated (see drm_mm_hole_follows() and friends). The + * other arguments are the size of the block to be allocated. The driver + * can adjust the start and end as needed to e.g. insert guard pages. + */ + void (*color_adjust)(const struct drm_mm_node *node, + unsigned long color, + u64 *start, u64 *end); + + /* private: */ /* List of all memory nodes that immediately precede a free hole. */ struct list_head hole_stack; /* head_node.node_list is the list of all memory nodes, ordered @@ -93,14 +128,20 @@ struct drm_mm { /* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */ struct rb_root interval_tree; - void (*color_adjust)(const struct drm_mm_node *node, - unsigned long color, - u64 *start, u64 *end); - unsigned long scan_active; }; +/** + * struct drm_mm_scan - DRM allocator eviction roaster data + * + * This structure tracks data needed for the eviction roaster set up using + * drm_mm_scan_init(), and used with drm_mm_scan_add_block() and + * drm_mm_scan_remove_block(). The structure is entirely opaque and should only + * be accessed through the provided functions and macros. It is meant to be + * allocated temporarily by the driver on the stack. + */ struct drm_mm_scan { + /* private: */ struct drm_mm *mm; u64 size; @@ -159,7 +200,8 @@ static inline bool drm_mm_initialized(const struct drm_mm *mm) * * Holes are embedded into the drm_mm using the tail of a drm_mm_node. * If you wish to know whether a hole follows this particular node, - * query this function. + * query this function. See also drm_mm_hole_node_start() and + * drm_mm_hole_node_end(). * * Returns: * True if a hole follows the @node. @@ -228,23 +270,23 @@ static inline u64 drm_mm_hole_node_end(const struct drm_mm_node *hole_node) /** * drm_mm_for_each_node - iterator to walk over all allocated nodes - * @entry: drm_mm_node structure to assign to in each iteration step - * @mm: drm_mm allocator to walk + * @entry: &struct drm_mm_node to assign to in each iteration step + * @mm: &drm_mm allocator to walk * * This iterator walks over all nodes in the range allocator. It is implemented - * with list_for_each, so not save against removal of elements. + * with list_for_each(), so not save against removal of elements. */ #define drm_mm_for_each_node(entry, mm) \ list_for_each_entry(entry, drm_mm_nodes(mm), node_list) /** * drm_mm_for_each_node_safe - iterator to walk over all allocated nodes - * @entry: drm_mm_node structure to assign to in each iteration step - * @next: drm_mm_node structure to store the next step - * @mm: drm_mm allocator to walk + * @entry: &struct drm_mm_node to assign to in each iteration step + * @next: &struct drm_mm_node to store the next step + * @mm: &drm_mm allocator to walk * * This iterator walks over all nodes in the range allocator. It is implemented - * with list_for_each_safe, so save against removal of elements. + * with list_for_each_safe(), so save against removal of elements. */ #define drm_mm_for_each_node_safe(entry, next, mm) \ list_for_each_entry_safe(entry, next, drm_mm_nodes(mm), node_list) @@ -259,13 +301,13 @@ static inline u64 drm_mm_hole_node_end(const struct drm_mm_node *hole_node) /** * drm_mm_for_each_hole - iterator to walk over all holes - * @entry: drm_mm_node used internally to track progress - * @mm: drm_mm allocator to walk + * @entry: &drm_mm_node used internally to track progress + * @mm: &drm_mm allocator to walk * @hole_start: ulong variable to assign the hole start to on each iteration * @hole_end: ulong variable to assign the hole end to on each iteration * * This iterator walks over all holes in the range allocator. It is implemented - * with list_for_each, so not save against removal of elements. @entry is used + * with list_for_each(), so not save against removal of elements. @entry is used * internally and will not reflect a real drm_mm_node for the very first hole. * Hence users of this iterator may not access it. * @@ -334,6 +376,9 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, * @sflags: flags to fine-tune the allocation search * @aflags: flags to fine-tune the allocation behavior * + * This is a simplified version of drm_mm_insert_node_in_range_generic() with no + * range restrictions applied. + * * The preallocated node must be cleared to 0. * * Returns: @@ -434,6 +479,9 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan, * @color: opaque tag value to use for the allocation * @flags: flags to specify how the allocation will be performed afterwards * + * This is a simplified version of drm_mm_scan_init_with_range() with no range + * restrictions applied. + * * This simply sets up the scanning routines with the parameters for the desired * hole. * From f641d3b536e559dd2bae9245ec2e7d86cdf623fd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:24 +0100 Subject: [PATCH 121/359] dma-buf: use preferred struct reference in kernel-doc sed -e 's/\( \* .*\)struct &\([_a-z]*\)/\1\&struct \2/' -i Originally I wasnt a friend of this style because I thought a line-break between the "&struct" and "foo" part would break it. But a quick test shows that " * &struct \n * foo\n" works pefectly well with current kernel-doc. So time to mass-apply these changes! Cc: Sumit Semwal Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-4-git-send-email-daniel.vetter@ffwll.ch --- drivers/dma-buf/dma-buf.c | 6 +++--- include/linux/dma-buf.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 91aff74ed092..ab814aff0a5b 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -128,7 +128,7 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) * DOC: fence polling * * To support cross-device and cross-driver synchronization of buffer access - * implicit fences (represented internally in the kernel with struct &fence) can + * implicit fences (represented internally in the kernel with &struct fence) can * be attached to a &dma_buf. The glue for that and a few related things are * provided in the &reservation_object structure. * @@ -373,7 +373,7 @@ static inline int is_dma_buf_file(struct file *file) * Additionally, provide a name string for exporter; useful in debugging. * * @exp_info: [in] holds all the export related information provided - * by the exporter. see struct &dma_buf_export_info + * by the exporter. see &struct dma_buf_export_info * for further details. * * Returns, on success, a newly created dma_buf object, which wraps the @@ -517,7 +517,7 @@ EXPORT_SYMBOL_GPL(dma_buf_get); * * If, as a result of this call, the refcount becomes 0, the 'release' file * operation related to this fd is called. It calls the release operation of - * struct &dma_buf_ops in turn, and frees the memory allocated for dmabuf when + * &struct dma_buf_ops in turn, and frees the memory allocated for dmabuf when * exported. */ void dma_buf_put(struct dma_buf *dmabuf) diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 57828154e440..4d61fc55278b 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -278,7 +278,7 @@ struct dma_buf_ops { * Shared dma buffers are reference counted using dma_buf_put() and * get_dma_buf(). * - * Device DMA access is handled by the separate struct &dma_buf_attachment. + * Device DMA access is handled by the separate &struct dma_buf_attachment. */ struct dma_buf { size_t size; @@ -355,7 +355,7 @@ struct dma_buf_export_info { * DEFINE_DMA_BUF_EXPORT_INFO - helper macro for exporters * @name: export-info name * - * DEFINE_DMA_BUF_EXPORT_INFO macro defines the struct &dma_buf_export_info, + * DEFINE_DMA_BUF_EXPORT_INFO macro defines the &struct dma_buf_export_info, * zeroes it out and pre-populates exp_name in it. */ #define DEFINE_DMA_BUF_EXPORT_INFO(name) \ From e9b4d7b56f293ed4de9ff7d16759d33492f83180 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:25 +0100 Subject: [PATCH 122/359] dma-buf: Use recommended structure member reference I just learned that &struct_name.member_name works and looks pretty even. It doesn't (yet) link to the member directly though, which would be really good for big structures or vfunc tables (where the per-member kerneldoc tends to be long). Cc: Sumit Semwal Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-5-git-send-email-daniel.vetter@ffwll.ch --- drivers/dma-buf/dma-buf.c | 5 ++--- include/linux/dma-buf.h | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index ab814aff0a5b..718f832a5c71 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -516,9 +516,8 @@ EXPORT_SYMBOL_GPL(dma_buf_get); * Uses file's refcounting done implicitly by fput(). * * If, as a result of this call, the refcount becomes 0, the 'release' file - * operation related to this fd is called. It calls the release operation of - * &struct dma_buf_ops in turn, and frees the memory allocated for dmabuf when - * exported. + * operation related to this fd is called. It calls &dma_buf_ops.release vfunc + * in turn, and frees the memory allocated for dmabuf when exported. */ void dma_buf_put(struct dma_buf *dmabuf) { diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 4d61fc55278b..bfb3704fc6fc 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -66,8 +66,8 @@ struct dma_buf_ops { * is not the case, and the allocation cannot be moved, it should also * fail the attach operation. * - * Any exporter-private housekeeping data can be stored in the priv - * pointer of &dma_buf_attachment structure. + * Any exporter-private housekeeping data can be stored in the + * &dma_buf_attachment.priv pointer. * * This callback is optional. * @@ -106,7 +106,7 @@ struct dma_buf_ops { * * Note that any specific buffer attributes required for this function * should get added to device_dma_parameters accessible via - * device->dma_params from the &dma_buf_attachment. The @attach callback + * &device.dma_params from the &dma_buf_attachment. The @attach callback * should also check these constraints. * * If this is being called for the first time, the exporter can now From ea0dd85a75f15174cc2bf75f805e378391995931 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:26 +0100 Subject: [PATCH 123/359] drm/doc: use preferred struct reference in kernel-doc sed -e 's/\( \* .*\)struct &\([_a-z]*\)/\1\&struct \2/' -i Originally I wasnt a friend of this style because I thought a line-break between the "&struct" and "foo" part would break it. But a quick test shows that " * &struct \n * foo\n" works pefectly well with current kernel-doc. So time to mass-apply these changes! Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-6-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic.c | 6 +++--- drivers/gpu/drm/drm_atomic_helper.c | 8 ++++---- drivers/gpu/drm/drm_auth.c | 8 ++++---- drivers/gpu/drm/drm_bridge.c | 4 ++-- drivers/gpu/drm/drm_color_mgmt.c | 4 ++-- drivers/gpu/drm/drm_connector.c | 2 +- drivers/gpu/drm/drm_crtc_helper.c | 14 +++++++------- drivers/gpu/drm/drm_drv.c | 10 +++++----- drivers/gpu/drm/drm_dumb_buffers.c | 2 +- drivers/gpu/drm/drm_encoder.c | 4 ++-- drivers/gpu/drm/drm_fb_cma_helper.c | 2 +- drivers/gpu/drm/drm_framebuffer.c | 6 +++--- drivers/gpu/drm/drm_irq.c | 2 +- drivers/gpu/drm/drm_plane.c | 2 +- drivers/gpu/drm/drm_plane_helper.c | 2 +- drivers/gpu/drm/drm_probe_helper.c | 2 +- drivers/gpu/drm/drm_property.c | 2 +- drivers/gpu/drm/drm_simple_kms_helper.c | 2 +- include/drm/drm_atomic.h | 2 +- include/drm/drm_auth.h | 2 +- include/drm/drm_bridge.h | 8 ++++---- include/drm/drm_connector.h | 10 +++++----- include/drm/drm_crtc.h | 8 ++++---- include/drm/drm_fb_helper.h | 2 +- include/drm/drm_framebuffer.h | 6 +++--- include/drm/drm_irq.h | 4 ++-- include/drm/drm_mode_config.h | 10 +++++----- include/drm/drm_modeset_helper_vtables.h | 2 +- include/drm/drm_plane.h | 4 ++-- include/drm/drm_print.h | 4 ++-- include/drm/drm_simple_kms_helper.h | 8 ++++---- 31 files changed, 76 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index b1b54011a92c..681d5f97639d 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1882,7 +1882,7 @@ EXPORT_SYMBOL(drm_atomic_clean_old_fb); * As a contrast, with implicit fencing the kernel keeps track of any * ongoing rendering, and automatically ensures that the atomic update waits * for any pending rendering to complete. For shared buffers represented with - * a struct &dma_buf this is tracked in &reservation_object structures. + * a &struct dma_buf this is tracked in &reservation_object structures. * Implicit syncing is how Linux traditionally worked (e.g. DRI2/3 on X.org), * whereas explicit fencing is what Android wants. * @@ -1898,7 +1898,7 @@ EXPORT_SYMBOL(drm_atomic_clean_old_fb); * it will only check if the Sync File is a valid one. * * On the driver side the fence is stored on the @fence parameter of - * struct &drm_plane_state. Drivers which also support implicit fencing + * &struct drm_plane_state. Drivers which also support implicit fencing * should set the implicit fence using drm_atomic_set_fence_for_plane(), * to make sure there's consistent behaviour between drivers in precedence * of implicit vs. explicit fencing. @@ -1917,7 +1917,7 @@ EXPORT_SYMBOL(drm_atomic_clean_old_fb); * DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1. * * Note that out-fences don't have a special interface to drivers and are - * internally represented by a struct &drm_pending_vblank_event in struct + * internally represented by a &struct drm_pending_vblank_event in struct * &drm_crtc_state, which is also used by the nonblocking atomic commit * helpers and for the DRM event handling for existing userspace. */ diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 799c1564a4f8..8eab8944c736 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -56,9 +56,9 @@ * implement these functions themselves but must use the provided helpers. * * The atomic helper uses the same function table structures as all other - * modesetting helpers. See the documentation for struct &drm_crtc_helper_funcs, - * struct &drm_encoder_helper_funcs and struct &drm_connector_helper_funcs. It - * also shares the struct &drm_plane_helper_funcs function table with the plane + * modesetting helpers. See the documentation for &struct drm_crtc_helper_funcs, + * struct &drm_encoder_helper_funcs and &struct drm_connector_helper_funcs. It + * also shares the &struct drm_plane_helper_funcs function table with the plane * helpers. */ static void @@ -1369,7 +1369,7 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock) * actually committing the hardware state, and for nonblocking commits this call * must be placed in the async worker. See also drm_atomic_helper_swap_state() * and it's stall parameter, for when a driver's commit hooks look at the - * ->state pointers of struct &drm_crtc, &drm_plane or &drm_connector directly. + * ->state pointers of &struct drm_crtc, &drm_plane or &drm_connector directly. * * Completion of the hardware commit step must be signalled using * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 6b143514a566..860cfe124c2a 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -35,8 +35,8 @@ /** * DOC: master and authentication * - * struct &drm_master is used to track groups of clients with open - * primary/legacy device nodes. For every struct &drm_file which has had at + * &struct drm_master is used to track groups of clients with open + * primary/legacy device nodes. For every &struct drm_file which has had at * least once successfully became the device master (either through the * SET_MASTER IOCTL, or implicitly through opening the primary device node when * no one else is the current master that time) there exists one &drm_master. @@ -294,7 +294,7 @@ EXPORT_SYMBOL(drm_is_current_master); /** * drm_master_get - reference a master pointer - * @master: struct &drm_master + * @master: &struct drm_master * * Increments the reference count of @master and returns a pointer to @master. */ @@ -322,7 +322,7 @@ static void drm_master_destroy(struct kref *kref) /** * drm_master_put - unreference and clear a master pointer - * @master: pointer to a pointer of struct &drm_master + * @master: pointer to a pointer of &struct drm_master * * This decrements the &drm_master behind @master and sets it to NULL. */ diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index cd10095e8d00..ae5e57ad718c 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -33,7 +33,7 @@ /** * DOC: overview * - * struct &drm_bridge represents a device that hangs on to an encoder. These are + * &struct drm_bridge represents a device that hangs on to an encoder. These are * handy when a regular &drm_encoder entity isn't enough to represent the entire * encoder chain. * @@ -55,7 +55,7 @@ * just provide additional hooks to get the desired output at the end of the * encoder chain. * - * Bridges can also be chained up using the next pointer in struct &drm_bridge. + * Bridges can also be chained up using the next pointer in &struct drm_bridge. * * Both legacy CRTC helpers and the new atomic modeset helpers support bridges. */ diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 6543ebde501a..789b4c65cd69 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -36,7 +36,7 @@ * "DEGAMMA_LUT”: * Blob property to set the degamma lookup table (LUT) mapping pixel data * from the framebuffer before it is given to the transformation matrix. - * The data is interpreted as an array of struct &drm_color_lut elements. + * The data is interpreted as an array of &struct drm_color_lut elements. * Hardware might choose not to use the full precision of the LUT elements * nor use all the elements of the LUT (for example the hardware might * choose to interpolate between LUT[0] and LUT[4]). @@ -65,7 +65,7 @@ * “GAMMA_LUT”: * Blob property to set the gamma lookup table (LUT) mapping pixel data * after the transformation matrix to data sent to the connector. The - * data is interpreted as an array of struct &drm_color_lut elements. + * data is interpreted as an array of &struct drm_color_lut elements. * Hardware might choose not to use the full precision of the LUT elements * nor use all the elements of the LUT (for example the hardware might * choose to interpolate between LUT[0] and LUT[4]). diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 3115db2ae6b1..799edd0d308e 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -49,7 +49,7 @@ * Connectors must be attached to an encoder to be used. For devices that map * connectors to encoders 1:1, the connector should be attached at * initialization time with a call to drm_mode_connector_attach_encoder(). The - * driver must also set the struct &drm_connector encoder field to point to the + * driver must also set the &struct drm_connector encoder field to point to the * attached encoder. * * For connectors which are not fixed (like built-in panels) the driver needs to diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 923a17c05e01..1e281dd42e4b 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -71,7 +71,7 @@ * * These legacy modeset helpers use the same function table structures as * all other modesetting helpers. See the documentation for struct - * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct + * &drm_crtc_helper_funcs, &struct drm_encoder_helper_funcs and struct * &drm_connector_helper_funcs. */ @@ -478,10 +478,10 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) * @set: mode set configuration * * The drm_crtc_helper_set_config() helper function implements the set_config - * callback of struct &drm_crtc_funcs for drivers using the legacy CRTC helpers. + * callback of &struct drm_crtc_funcs for drivers using the legacy CRTC helpers. * * It first tries to locate the best encoder for each connector by calling the - * connector ->best_encoder() (struct &drm_connector_helper_funcs) helper + * connector ->best_encoder() (&struct drm_connector_helper_funcs) helper * operation. * * After locating the appropriate encoders, the helper function will call the @@ -493,7 +493,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) * * If the adjusted mode is identical to the current mode but changes to the * frame buffer need to be applied, the drm_crtc_helper_set_config() function - * will call the CRTC ->mode_set_base() (struct &drm_crtc_helper_funcs) helper + * will call the CRTC ->mode_set_base() (&struct drm_crtc_helper_funcs) helper * operation. * * If the adjusted mode differs from the current mode, or if the @@ -501,7 +501,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) * performs a full mode set sequence by calling the ->prepare(), ->mode_set() * and ->commit() CRTC and encoder helper operations, in that order. * Alternatively it can also use the dpms and disable helper operations. For - * details see struct &drm_crtc_helper_funcs and struct + * details see &struct drm_crtc_helper_funcs and struct * &drm_encoder_helper_funcs. * * This function is deprecated. New drivers must implement atomic modeset @@ -852,12 +852,12 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) * @mode: DPMS mode * * The drm_helper_connector_dpms() helper function implements the ->dpms() - * callback of struct &drm_connector_funcs for drivers using the legacy CRTC helpers. + * callback of &struct drm_connector_funcs for drivers using the legacy CRTC helpers. * * This is the main helper function provided by the CRTC helper framework for * implementing the DPMS connector attribute. It computes the new desired DPMS * state for all encoders and CRTCs in the output mesh and calls the ->dpms() - * callbacks provided by the driver in struct &drm_crtc_helper_funcs and struct + * callbacks provided by the driver in &struct drm_crtc_helper_funcs and struct * &drm_encoder_helper_funcs appropriately. * * This function is deprecated. New drivers must implement atomic modeset diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 9d2b4b630601..135c746dc9c7 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -298,7 +298,7 @@ void drm_minor_release(struct drm_minor *minor) /** * DOC: driver instance overview * - * A device instance for a drm driver is represented by struct &drm_device. This + * A device instance for a drm driver is represented by &struct drm_device. This * is allocated with drm_dev_alloc(), usually from bus-specific ->probe() * callbacks implemented by the driver. The driver then needs to initialize all * the various subsystems for the drm device like memory management, vblank @@ -323,7 +323,7 @@ void drm_minor_release(struct drm_minor *minor) * historical baggage. Hence use the reference counting provided by * drm_dev_ref() and drm_dev_unref() only carefully. * - * It is recommended that drivers embed struct &drm_device into their own device + * It is recommended that drivers embed &struct drm_device into their own device * structure, which is supported through drm_dev_init(). */ @@ -461,8 +461,8 @@ static void drm_fs_inode_free(struct inode *inode) * Note that for purely virtual devices @parent can be NULL. * * Drivers that do not want to allocate their own device struct - * embedding struct &drm_device can call drm_dev_alloc() instead. For drivers - * that do embed struct &drm_device it must be placed first in the overall + * embedding &struct drm_device can call drm_dev_alloc() instead. For drivers + * that do embed &struct drm_device it must be placed first in the overall * structure, and the overall structure must be allocated using kmalloc(): The * drm core's release function unconditionally calls kfree() on the @dev pointer * when the final reference is released. @@ -568,7 +568,7 @@ EXPORT_SYMBOL(drm_dev_init); * * Note that for purely virtual devices @parent can be NULL. * - * Drivers that wish to subclass or embed struct &drm_device into their + * Drivers that wish to subclass or embed &struct drm_device into their * own struct should look at using drm_dev_init() instead. * * RETURNS: diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c index 8ac5a1c1d811..e5c61cda4ae3 100644 --- a/drivers/gpu/drm/drm_dumb_buffers.c +++ b/drivers/gpu/drm/drm_dumb_buffers.c @@ -43,7 +43,7 @@ * KMS frame buffers. * * To support dumb objects drivers must implement the dumb_create, - * dumb_destroy and dumb_map_offset operations from struct &drm_driver. See + * dumb_destroy and dumb_map_offset operations from &struct drm_driver. See * there for further details. * * Note that dumb objects may not be used for gpu acceleration, as has been diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 5f0598e4bf6f..487cfe3989e8 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -30,8 +30,8 @@ * DOC: overview * * Encoders represent the connecting element between the CRTC (as the overall - * pixel pipeline, represented by struct &drm_crtc) and the connectors (as the - * generic sink entity, represented by struct &drm_connector). An encoder takes + * pixel pipeline, represented by &struct drm_crtc) and the connectors (as the + * generic sink entity, represented by &struct drm_connector). An encoder takes * pixel data from a CRTC and converts it to a format suitable for any attached * connector. Encoders are objects exposed to userspace, originally to allow * userspace to infer cloning and connector/CRTC restrictions. Unfortunately diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 591f30ebc42a..96f3965b8028 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -273,7 +273,7 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); * @plane: Which plane * @state: Plane state attach fence to * - * This should be put into prepare_fb hook of struct &drm_plane_helper_funcs . + * This should be put into prepare_fb hook of &struct drm_plane_helper_funcs . * * This function checks if the plane FB has an dma-buf attached, extracts * the exclusive fence and attaches it to plane state for the atomic helper diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 94ddab41f24f..588ccc3a2218 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -39,13 +39,13 @@ * Frame buffers rely on the underlying memory manager for allocating backing * storage. When creating a frame buffer applications pass a memory handle * (or a list of memory handles for multi-planar formats) through the - * struct &drm_mode_fb_cmd2 argument. For drivers using GEM as their userspace + * &struct drm_mode_fb_cmd2 argument. For drivers using GEM as their userspace * buffer management interface this would be a GEM handle. Drivers are however * free to use their own backing storage object handles, e.g. vmwgfx directly * exposes special TTM handles to userspace and so expects TTM handles in the * create ioctl and not GEM handles. * - * Framebuffers are tracked with struct &drm_framebuffer. They are published + * Framebuffers are tracked with &struct drm_framebuffer. They are published * using drm_framebuffer_init() - after calling that function userspace can use * and access the framebuffer object. The helper function * drm_helper_mode_fill_fb_struct() can be used to pre-fill the required @@ -55,7 +55,7 @@ * drivers can grab additional references with drm_framebuffer_reference() and * drop them again with drm_framebuffer_unreference(). For driver-private * framebuffers for which the last reference is never dropped (e.g. for the - * fbdev framebuffer when the struct struct &drm_framebuffer is embedded into + * fbdev framebuffer when the struct &struct drm_framebuffer is embedded into * the fbdev helper struct) drivers can manually clean up a framebuffer at * module unload time with drm_framebuffer_unregister_private(). But doing this * is not recommended, and it's better to have a normal free-standing struct diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index feb091310ffe..88c69e71102e 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -982,7 +982,7 @@ static void send_vblank_event(struct drm_device *dev, * period. This helper function implements exactly the required vblank arming * behaviour. * - * NOTE: Drivers using this to send out the event in struct &drm_crtc_state + * NOTE: Drivers using this to send out the event in &struct drm_crtc_state * as part of an atomic commit must ensure that the next vblank happens at * exactly the same time as the atomic commit is committed to the hardware. This * function itself does **not** protect again the next vblank interrupt racing diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 8ad20af88ed7..7b7275f0c2df 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -37,7 +37,7 @@ * rotation or Z-position. All these properties are stored in &drm_plane_state. * * To create a plane, a KMS drivers allocates and zeroes an instances of - * struct &drm_plane (possibly as part of a larger structure) and registers it + * &struct drm_plane (possibly as part of a larger structure) and registers it * with a call to drm_universal_plane_init(). * * Cursor and overlay planes are optional. All drivers should provide one diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 8b042a193613..35d43607a47d 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -60,7 +60,7 @@ * Again drivers are strongly urged to switch to the new interfaces. * * The plane helpers share the function table structures with other helpers, - * specifically also the atomic helpers. See struct &drm_plane_helper_funcs for + * specifically also the atomic helpers. See &struct drm_plane_helper_funcs for * the details. */ diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 7cff91e7497f..97a32898ef50 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -55,7 +55,7 @@ * handling code to avoid probing unrelated outputs. * * The probe helpers share the function table structures with other display - * helper libraries. See struct &drm_connector_helper_funcs for the details. + * helper libraries. See &struct drm_connector_helper_funcs for the details. */ static bool drm_kms_helper_poll = true; diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c index 24be69d29964..0d0e5dc0ee23 100644 --- a/drivers/gpu/drm/drm_property.c +++ b/drivers/gpu/drm/drm_property.c @@ -34,7 +34,7 @@ * even the only way to transport metadata about the desired new modeset * configuration from userspace to the kernel. Properties have a well-defined * value range, which is enforced by the drm core. See the documentation of the - * flags member of struct &drm_property for an overview of the different + * flags member of &struct drm_property for an overview of the different * property types and ranges. * * Properties don't store the current value directly, but need to be diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 3cc42f5dfba1..35c5d99296b9 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -23,7 +23,7 @@ * * drm_simple_display_pipe_init() initializes a simple display pipeline * which has only one full-screen scanout buffer feeding one output. The - * pipeline is represented by struct &drm_simple_display_pipe and binds + * pipeline is represented by &struct drm_simple_display_pipe and binds * together &drm_plane, &drm_crtc and &drm_encoder structures into one fixed * entity. Some flexibility for code reuse is provided through a separately * allocated &drm_connector object and supporting optional &drm_bridge diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index b0ebe0fafc41..fd2d971bca32 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -398,7 +398,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); * drm_atomic_crtc_needs_modeset - compute combined modeset need * @state: &drm_crtc_state for the CRTC * - * To give drivers flexibility struct &drm_crtc_state has 3 booleans to track + * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track * whether the state CRTC changed enough to need a full modeset cycle: * connectors_changed, mode_changed and active_changed. This helper simply * combines these three to compute the overall need for a modeset for @state. diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h index 155588eb8ccf..eecbc2f43f55 100644 --- a/include/drm/drm_auth.h +++ b/include/drm/drm_auth.h @@ -48,7 +48,7 @@ struct drm_master { */ char *unique; /** - * @unique_len: Length of unique field. Protected by struct &drm_device + * @unique_len: Length of unique field. Protected by &struct drm_device * master_mutex. */ int unique_len; diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 435be20029f7..d3ca16f4da8f 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -98,7 +98,7 @@ struct drm_bridge_funcs { * preceding element is a bridge this means it's called before that * bridge's ->disable() function. If the preceding element is a * &drm_encoder it's called right before the encoder's ->disable(), - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * ->prepare() or ->dpms() hook from &struct drm_encoder_helper_funcs. * * The bridge can assume that the display pipe (i.e. clocks and timing * signals) feeding it is still running when this callback is called. @@ -115,7 +115,7 @@ struct drm_bridge_funcs { * preceding element is a bridge this means it's called after that * bridge's ->post_disable() function. If the preceding element is a * &drm_encoder it's called right after the encoder's ->disable(), - * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * ->prepare() or ->dpms() hook from &struct drm_encoder_helper_funcs. * * The bridge must assume that the display pipe (i.e. clocks and timing * singals) feeding it is no longer running when this callback is @@ -144,7 +144,7 @@ struct drm_bridge_funcs { * preceding element is a bridge this means it's called before that * bridge's ->pre_enable() function. If the preceding element is a * &drm_encoder it's called right before the encoder's ->enable(), - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * ->commit() or ->dpms() hook from &struct drm_encoder_helper_funcs. * * The display pipe (i.e. clocks and timing signals) feeding this bridge * will not yet be running when this callback is called. The bridge must @@ -163,7 +163,7 @@ struct drm_bridge_funcs { * preceding element is a bridge this means it's called after that * bridge's ->enable() function. If the preceding element is a * &drm_encoder it's called right after the encoder's ->enable(), - * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. + * ->commit() or ->dpms() hook from &struct drm_encoder_helper_funcs. * * The bridge can assume that the display pipe (i.e. clocks and timing * signals) feeding it is running when this callback is called. This diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 6e352a0b5c81..acb4241bff7d 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -94,7 +94,7 @@ enum subpixel_order { * * Describes a given display (e.g. CRT or flat panel) and its limitations. For * fixed display sinks like built-in panels there's not much difference between - * this and struct &drm_connector. But for sinks with a real cable this + * this and &struct drm_connector. But for sinks with a real cable this * structure is meant to describe all the things at the other end of the cable. * * For sinks which provide an EDID this can be filled out by calling @@ -422,7 +422,7 @@ struct drm_connector_funcs { * &drm_mode_config_funcs) will be cleaned up by calling the * @atomic_destroy_state hook in this structure. * - * Atomic drivers which don't subclass struct &drm_connector_state should use + * Atomic drivers which don't subclass &struct drm_connector_state should use * drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the * state structure to extend it with driver-private state should use * __drm_atomic_helper_connector_duplicate_state() to make sure shared state is @@ -525,7 +525,7 @@ struct drm_connector_funcs { /** * @atomic_print_state: * - * If driver subclasses struct &drm_connector_state, it should implement + * If driver subclasses &struct drm_connector_state, it should implement * this optional hook for printing additional driver specific state. * * Do not call this directly, use drm_atomic_connector_print_state() @@ -904,8 +904,8 @@ void drm_connector_list_iter_put(struct drm_connector_list_iter *iter); /** * drm_for_each_connector_iter - connector_list iterator macro - * @connector: struct &drm_connector pointer used as cursor - * @iter: struct &drm_connector_list_iter + * @connector: &struct drm_connector pointer used as cursor + * @iter: &struct drm_connector_list_iter * * Note that @connector is only valid within the list body, if you want to use * @connector after calling drm_connector_list_iter_put() then you need to grab diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 89daa77c37fc..e9bc21950439 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -315,7 +315,7 @@ struct drm_crtc_funcs { * * This is the main legacy entry point to change the modeset state on a * CRTC. All the details of the desired configuration are passed in a - * struct &drm_mode_set - see there for details. + * &struct drm_mode_set - see there for details. * * Drivers implementing atomic modeset should use * drm_atomic_helper_set_config() to implement this hook. @@ -346,7 +346,7 @@ struct drm_crtc_funcs { * shared dma-buf. * * An application can request to be notified when the page flip has - * completed. The drm core will supply a struct &drm_event in the event + * completed. The drm core will supply a &struct drm_event in the event * parameter in this case. This can be handled by the * drm_crtc_send_vblank_event() function, which the driver should call on * the provided event upon completion of the flip. Note that if @@ -431,7 +431,7 @@ struct drm_crtc_funcs { * &drm_mode_config_funcs) will be cleaned up by calling the * @atomic_destroy_state hook in this structure. * - * Atomic drivers which don't subclass struct &drm_crtc should use + * Atomic drivers which don't subclass &struct drm_crtc should use * drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the * state structure to extend it with driver-private state should use * __drm_atomic_helper_crtc_duplicate_state() to make sure shared state is @@ -583,7 +583,7 @@ struct drm_crtc_funcs { /** * @atomic_print_state: * - * If driver subclasses struct &drm_crtc_state, it should implement + * If driver subclasses &struct drm_crtc_state, it should implement * this optional hook for printing additional driver specific state. * * Do not call this directly, use drm_atomic_crtc_print_state() diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 975deedd593e..53687c5664b8 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -181,7 +181,7 @@ struct drm_fb_helper_connector { * * This is the main structure used by the fbdev helpers. Drivers supporting * fbdev emulation should embedded this into their overall driver structure. - * Drivers must also fill out a struct &drm_fb_helper_funcs with a few + * Drivers must also fill out a &struct drm_fb_helper_funcs with a few * operations. */ struct drm_fb_helper { diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index f0dde1d02be4..046c35e54099 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h @@ -51,7 +51,7 @@ struct drm_framebuffer_funcs { * @create_handle: * * Create a buffer handle in the driver-specific buffer manager (either - * GEM or TTM) valid for the passed-in struct &drm_file. This is used by + * GEM or TTM) valid for the passed-in &struct drm_file. This is used by * the core to implement the GETFB IOCTL, which returns (for * sufficiently priviledged user) also a native buffer handle. This can * be used for seamless transitions between modesetting clients by @@ -149,7 +149,7 @@ struct drm_framebuffer { * * This should not be used to specifiy x/y pixel offsets into the buffer * data (even for linear buffers). Specifying an x/y pixel offset is - * instead done through the source rectangle in struct &drm_plane_state. + * instead done through the source rectangle in &struct drm_plane_state. */ unsigned int offsets[4]; /** @@ -187,7 +187,7 @@ struct drm_framebuffer { */ int hot_y; /** - * @filp_head: Placed on struct &drm_file fbs list_head, protected by + * @filp_head: Placed on &struct drm_file fbs list_head, protected by * fbs_lock in the same structure. */ struct list_head filp_head; diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 293d08caab60..18cfd11307e1 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -51,8 +51,8 @@ struct drm_pending_vblank_event { * * Note that for historical reasons - the vblank handling code is still shared * with legacy/non-kms drivers - this is a free-standing structure not directly - * connected to struct &drm_crtc. But all public interface functions are taking - * a struct &drm_crtc to hide this implementation detail. + * connected to &struct drm_crtc. But all public interface functions are taking + * a &struct drm_crtc to hide this implementation detail. */ struct drm_vblank_crtc { /** diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 5b735549bd51..17942c0f32a8 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -47,7 +47,7 @@ struct drm_mode_config_funcs { * * Create a new framebuffer object. The core does basic checks on the * requested metadata, but most of that is left to the driver. See - * struct &drm_mode_fb_cmd2 for details. + * &struct drm_mode_fb_cmd2 for details. * * If the parameters are deemed valid and the backing storage objects in * the underlying memory manager all exist, then the driver allocates @@ -135,7 +135,7 @@ struct drm_mode_config_funcs { * error conditions which don't have to be checked at the * ->atomic_check() stage? * - * See the documentation for struct &drm_atomic_state for how exactly + * See the documentation for &struct drm_atomic_state for how exactly * an atomic modeset update is described. * * Drivers using the atomic helpers can implement this hook using @@ -171,7 +171,7 @@ struct drm_mode_config_funcs { * calling this function, and that nothing has been changed in the * interim. * - * See the documentation for struct &drm_atomic_state for how exactly + * See the documentation for &struct drm_atomic_state for how exactly * an atomic modeset update is described. * * Drivers using the atomic helpers can implement this hook using @@ -198,7 +198,7 @@ struct drm_mode_config_funcs { * completed. These events are per-CRTC and can be distinguished by the * CRTC index supplied in &drm_event to userspace. * - * The drm core will supply a struct &drm_event in the event + * The drm core will supply a &struct drm_event in the event * member of each CRTC's &drm_crtc_state structure. See the * documentation for &drm_crtc_state for more details about the precise * semantics of this event. @@ -381,7 +381,7 @@ struct drm_mode_config { /** * @connector_list: List of connector objects. Protected by * @connector_list_lock. Only use drm_for_each_connector_iter() and - * struct &drm_connector_list_iter to walk this list. + * &struct drm_connector_list_iter to walk this list. */ struct list_head connector_list; int num_encoder; diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 625c7475c5df..46f5b349f059 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -726,7 +726,7 @@ struct drm_connector_helper_funcs { * fixed panel can also manually add specific modes using * drm_mode_probed_add(). Drivers which manually add modes should also * make sure that the @display_info, @width_mm and @height_mm fields of the - * struct &drm_connector are filled in. + * &struct drm_connector are filled in. * * Virtual drivers that just want some standard VESA mode with a given * resolution can call drm_add_modes_noedid(), and mark the preferred diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index db3bbdeb36d5..e049bc52fb07 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -253,7 +253,7 @@ struct drm_plane_funcs { * &drm_mode_config_funcs) will be cleaned up by calling the * @atomic_destroy_state hook in this structure. * - * Atomic drivers which don't subclass struct &drm_plane_state should use + * Atomic drivers which don't subclass &struct drm_plane_state should use * drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the * state structure to extend it with driver-private state should use * __drm_atomic_helper_plane_duplicate_state() to make sure shared state is @@ -381,7 +381,7 @@ struct drm_plane_funcs { /** * @atomic_print_state: * - * If driver subclasses struct &drm_plane_state, it should implement + * If driver subclasses &struct drm_plane_state, it should implement * this optional hook for printing additional driver specific state. * * Do not call this directly, use drm_atomic_plane_print_state() diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index e9d0ba20089c..7d98763c0444 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -80,7 +80,7 @@ void drm_printf(struct drm_printer *p, const char *f, ...); /** * drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file - * @f: the struct &seq_file to output to + * @f: the &struct seq_file to output to * * RETURNS: * The &drm_printer object @@ -96,7 +96,7 @@ static inline struct drm_printer drm_seq_file_printer(struct seq_file *f) /** * drm_info_printer - construct a &drm_printer that outputs to dev_printk() - * @dev: the struct &device pointer + * @dev: the &struct device pointer * * RETURNS: * The &drm_printer object diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index 2bbc610ec3a2..fe8c4ba905ac 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -73,9 +73,9 @@ struct drm_simple_display_pipe_funcs { /** * @prepare_fb: * - * Optional, called by struct &drm_plane_helper_funcs ->prepare_fb . + * Optional, called by &struct drm_plane_helper_funcs ->prepare_fb . * Please read the documentation for the ->prepare_fb hook in - * struct &drm_plane_helper_funcs for more details. + * &struct drm_plane_helper_funcs for more details. */ int (*prepare_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state); @@ -83,9 +83,9 @@ struct drm_simple_display_pipe_funcs { /** * @cleanup_fb: * - * Optional, called by struct &drm_plane_helper_funcs ->cleanup_fb . + * Optional, called by &struct drm_plane_helper_funcs ->cleanup_fb . * Please read the documentation for the ->cleanup_fb hook in - * struct &drm_plane_helper_funcs for more details. + * &struct drm_plane_helper_funcs for more details. */ void (*cleanup_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state); From 347e89034a3b70123d0481712883c03cc704eb68 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:27 +0100 Subject: [PATCH 124/359] drm: Nuke connector_list locking assert I've forgotten to remove this when revamping the connector_list locking. Cc: seanpaul@chromium.org Reviewed-by: David Herrmann Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-7-git-send-email-daniel.vetter@ffwll.ch --- include/drm/drm_connector.h | 6 +----- include/drm/drm_crtc.h | 14 -------------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index acb4241bff7d..d489cc003b7e 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -875,11 +875,7 @@ void drm_mode_put_tile_group(struct drm_device *dev, * deprecated. Use drm_for_each_connector_iter() instead. */ #define drm_for_each_connector(connector, dev) \ - for (assert_drm_connector_list_read_locked(&(dev)->mode_config), \ - connector = list_first_entry(&(dev)->mode_config.connector_list, \ - struct drm_connector, head); \ - &connector->head != (&(dev)->mode_config.connector_list); \ - connector = list_next_entry(connector, head)) + list_for_each_entry(connector, &(dev)->mode_config.connector_list, head) /** * struct drm_connector_list_iter - connector_list iterator diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e9bc21950439..17c9f52d6ecb 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -836,18 +836,4 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, #define drm_for_each_crtc(crtc, dev) \ list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head) -static inline void -assert_drm_connector_list_read_locked(struct drm_mode_config *mode_config) -{ - /* - * The connector hotadd/remove code currently grabs both locks when - * updating lists. Hence readers need only hold either of them to be - * safe and the check amounts to - * - * WARN_ON(not_holding(A) && not_holding(B)). - */ - WARN_ON(!mutex_is_locked(&mode_config->mutex) && - !drm_modeset_is_locked(&mode_config->connection_mutex)); -} - #endif /* __DRM_CRTC_H__ */ From f5a8d8774bbb81c64073c1e29ce29cfa3d044f83 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:28 +0100 Subject: [PATCH 125/359] drm/doc: Update styleguide The new cool is &struct foo (kernel-doc now copes with linebreaks), and structure members should be referenced using &foo.bar. Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-8-git-send-email-daniel.vetter@ffwll.ch --- Documentation/gpu/introduction.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst index 6960e31f71e1..eb284eb748ba 100644 --- a/Documentation/gpu/introduction.rst +++ b/Documentation/gpu/introduction.rst @@ -23,13 +23,12 @@ For consistency this documentation uses American English. Abbreviations are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so on. To aid in reading, documentations make full use of the markup characters kerneldoc provides: @parameter for function parameters, -@member for structure members, &structure to reference structures and -function() for functions. These all get automatically hyperlinked if -kerneldoc for the referenced objects exists. When referencing entries in -function vtables please use ->vfunc(). Note that kerneldoc does not -support referencing struct members directly, so please add a reference -to the vtable struct somewhere in the same paragraph or at least -section. +@member for structure members (within the same structure), &struct structure to +reference structures and function() for functions. These all get automatically +hyperlinked if kerneldoc for the referenced objects exists. When referencing +entries in function vtables (and structure members in general) please use +&vtable_name.vfunc. Unfortunately this does not yet yield a direct link to the +member, only the structure. Except in special situations (to separate locked from unlocked variants) locking requirements for functions aren't documented in the kerneldoc. From 5edbfc474c928dcfb37adc6c9f8ef708323c856d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:29 +0100 Subject: [PATCH 126/359] drm/rect: Fix formatting of example code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drive-by polish. Cc: Ville Syrjälä Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-9-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_rect.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c index e6057d8cdcd5..bc5575960ebc 100644 --- a/drivers/gpu/drm/drm_rect.c +++ b/drivers/gpu/drm/drm_rect.c @@ -371,10 +371,10 @@ EXPORT_SYMBOL(drm_rect_rotate); * to the vertical axis of the original untransformed * coordinate space, so that you never have to flip * them when doing a rotatation and its inverse. - * That is, if you do: + * That is, if you do :: * - * drm_rotate(&r, width, height, rotation); - * drm_rotate_inv(&r, width, height, rotation); + * drm_rotate(&r, width, height, rotation); + * drm_rotate_inv(&r, width, height, rotation); * * you will always get back the original rectangle. */ From 824387b2f6a1a177bf518a61ebbf861ae058f45d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:30 +0100 Subject: [PATCH 127/359] drm/atomic-helpers: Remove outdated comment We forgot to clean this up when adding connector refcounting. Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-10-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic_helper.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 8eab8944c736..5e5224460042 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3286,11 +3286,6 @@ EXPORT_SYMBOL(drm_atomic_helper_duplicate_state); void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) { - /* - * This is currently a placeholder so that drivers that subclass the - * state will automatically do the right thing if code is ever added - * to this function. - */ if (state->crtc) drm_connector_unreference(state->connector); } From 1259feddd0f83649d5c48d730c140b4f7f3fa288 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 30 Dec 2016 13:14:18 +0900 Subject: [PATCH 128/359] pinctrl: samsung: Fix the width of PINCFG_TYPE_DRV bitfields for Exynos5433 This patch fixes the wrong width of PINCFG_TYPE_DRV bitfields for Exynos5433 because PINCFG_TYPE_DRV of Exynos5433 has 4bit fields in the *_DRV registers. Usually, other Exynos have 2bit field for PINCFG_TYPE_DRV. Fixes: 3c5ecc9ed353 ("pinctrl: exynos: Add support for Exynos5433") Cc: stable@vger.kernel.org Cc: Tomasz Figa Cc: Krzysztof Kozlowski Cc: Sylwester Nawrocki Cc: Linus Walleij Cc: Kukjin Kim Cc: Javier Martinez Canillas Signed-off-by: Chanwoo Choi Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-exynos.c | 91 +++++++++++++----------- drivers/pinctrl/samsung/pinctrl-exynos.h | 31 ++++++++ 2 files changed, 82 insertions(+), 40 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 12f7d1eb65bc..07409fde02b2 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -56,6 +56,17 @@ static const struct samsung_pin_bank_type bank_type_alive = { .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, }; +/* Exynos5433 has the 4bit widths for PINCFG_TYPE_DRV bitfields. */ +static const struct samsung_pin_bank_type exynos5433_bank_type_off = { + .fld_width = { 4, 1, 2, 4, 2, 2, }, + .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, }, +}; + +static const struct samsung_pin_bank_type exynos5433_bank_type_alive = { + .fld_width = { 4, 1, 2, 4, }, + .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, +}; + static void exynos_irq_mask(struct irq_data *irqd) { struct irq_chip *chip = irq_data_get_irq_chip(irqd); @@ -1335,82 +1346,82 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { /* pin banks of exynos5433 pin-controller - ALIVE */ static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = { - EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), - EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), - EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), - EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), - EXYNOS_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1), - EXYNOS_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1), - EXYNOS_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1), - EXYNOS_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1), - EXYNOS_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1), + EXYNOS5433_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), + EXYNOS5433_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), + EXYNOS5433_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), + EXYNOS5433_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), + EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1), + EXYNOS5433_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1), + EXYNOS5433_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1), + EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1), + EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1), }; /* pin banks of exynos5433 pin-controller - AUD */ static const struct samsung_pin_bank_data exynos5433_pin_banks1[] = { - EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), - EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), + EXYNOS5433_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), + EXYNOS5433_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), }; /* pin banks of exynos5433 pin-controller - CPIF */ static const struct samsung_pin_bank_data exynos5433_pin_banks2[] = { - EXYNOS_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00), + EXYNOS5433_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00), }; /* pin banks of exynos5433 pin-controller - eSE */ static const struct samsung_pin_bank_data exynos5433_pin_banks3[] = { - EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00), + EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00), }; /* pin banks of exynos5433 pin-controller - FINGER */ static const struct samsung_pin_bank_data exynos5433_pin_banks4[] = { - EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00), + EXYNOS5433_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00), }; /* pin banks of exynos5433 pin-controller - FSYS */ static const struct samsung_pin_bank_data exynos5433_pin_banks5[] = { - EXYNOS_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00), - EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04), - EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08), - EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c), - EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10), - EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14), + EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00), + EXYNOS5433_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04), + EXYNOS5433_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08), + EXYNOS5433_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c), + EXYNOS5433_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10), + EXYNOS5433_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14), }; /* pin banks of exynos5433 pin-controller - IMEM */ static const struct samsung_pin_bank_data exynos5433_pin_banks6[] = { - EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00), + EXYNOS5433_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00), }; /* pin banks of exynos5433 pin-controller - NFC */ static const struct samsung_pin_bank_data exynos5433_pin_banks7[] = { - EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00), + EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00), }; /* pin banks of exynos5433 pin-controller - PERIC */ static const struct samsung_pin_bank_data exynos5433_pin_banks8[] = { - EXYNOS_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00), - EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04), - EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08), - EXYNOS_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c), - EXYNOS_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10), - EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14), - EXYNOS_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18), - EXYNOS_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c), - EXYNOS_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20), - EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24), - EXYNOS_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28), - EXYNOS_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c), - EXYNOS_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30), - EXYNOS_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34), - EXYNOS_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38), - EXYNOS_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c), - EXYNOS_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40), + EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00), + EXYNOS5433_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04), + EXYNOS5433_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08), + EXYNOS5433_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c), + EXYNOS5433_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10), + EXYNOS5433_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14), + EXYNOS5433_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18), + EXYNOS5433_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c), + EXYNOS5433_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20), + EXYNOS5433_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24), + EXYNOS5433_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28), + EXYNOS5433_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c), + EXYNOS5433_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30), + EXYNOS5433_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34), + EXYNOS5433_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38), + EXYNOS5433_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c), + EXYNOS5433_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40), }; /* pin banks of exynos5433 pin-controller - TOUCH */ static const struct samsung_pin_bank_data exynos5433_pin_banks9[] = { - EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), + EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), }; /* diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h index 5821525a2c84..a473092fb8d2 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.h +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h @@ -90,6 +90,37 @@ .pctl_res_idx = pctl_idx, \ } \ +#define EXYNOS5433_PIN_BANK_EINTG(pins, reg, id, offs) \ + { \ + .type = &exynos5433_bank_type_off, \ + .pctl_offset = reg, \ + .nr_pins = pins, \ + .eint_type = EINT_TYPE_GPIO, \ + .eint_offset = offs, \ + .name = id \ + } + +#define EXYNOS5433_PIN_BANK_EINTW(pins, reg, id, offs) \ + { \ + .type = &exynos5433_bank_type_alive, \ + .pctl_offset = reg, \ + .nr_pins = pins, \ + .eint_type = EINT_TYPE_WKUP, \ + .eint_offset = offs, \ + .name = id \ + } + +#define EXYNOS5433_PIN_BANK_EINTW_EXT(pins, reg, id, offs, pctl_idx) \ + { \ + .type = &exynos5433_bank_type_alive, \ + .pctl_offset = reg, \ + .nr_pins = pins, \ + .eint_type = EINT_TYPE_WKUP, \ + .eint_offset = offs, \ + .name = id, \ + .pctl_res_idx = pctl_idx, \ + } \ + /** * struct exynos_weint_data: irq specific data for all the wakeup interrupts * generated by the external wakeup interrupt controller. From 6098909cf2d0f9dda63aed3b6651d91f7ce6a473 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 Dec 2016 14:16:39 +0000 Subject: [PATCH 129/359] drm: Avoid NULL dereference of drm_device.dev For a virtual device, drm_device.dev is NULL, so becareful not to dereference it unconditionally in core code such as drm_dev_register(). Fixes: 75f6dfe3e652 ("drm: Deduplicate driver initialization message") Signed-off-by: Chris Wilson Cc: Gabriel Krisman Bertazi Cc: Daniel Vetter Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161230141639.10487-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 135c746dc9c7..1b11ab628da7 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -762,7 +762,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", driver->name, driver->major, driver->minor, - driver->patchlevel, driver->date, dev_name(dev->dev), + driver->patchlevel, driver->date, + dev->dev ? dev_name(dev->dev) : "virtual device", dev->primary->index); goto out_unlock; From a766347b15c01507db9bf01f9b7021be5a776691 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 11 Dec 2016 22:14:32 +0100 Subject: [PATCH 130/359] firmware: arm_scpi: fix reading sensor values on pre-1.0 SCPI firmwares The pre-1.0 SCPI firmwares are using single __le32 as sensor value, while the SCPI v1.0 protocol uses two __le32 as sensor values(64bit) split into 32bit upper and 32bit lower value. Using an "struct sensor_value" to read the sensor value on a pre-1.0 SCPI firmware gives garbage in the "hi_val" field. This patch fixes the issue by reading only the lower 32-bit value for all pre-1.0 SCPI versions. Suggested-by: Sudeep Holla Signed-off-by: Martin Blumenstingl [sudeep.holla@arm.com: updated the commit log to reflect the implementation] Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 70e13230d8db..9ad0b1934be9 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -721,11 +721,17 @@ static int scpi_sensor_get_value(u16 sensor, u64 *val) ret = scpi_send_message(CMD_SENSOR_VALUE, &id, sizeof(id), &buf, sizeof(buf)); - if (!ret) + if (ret) + return ret; + + if (scpi_info->is_legacy) + /* only 32-bits supported, hi_val can be junk */ + *val = le32_to_cpu(buf.lo_val); + else *val = (u64)le32_to_cpu(buf.hi_val) << 32 | le32_to_cpu(buf.lo_val); - return ret; + return 0; } static int scpi_device_get_power_state(u16 dev_id) From 368400e242dc04963ca5ff0b70654f1470344a0a Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Sat, 10 Dec 2016 21:13:51 +0100 Subject: [PATCH 131/359] ARM: dts: vexpress: Support GICC_DIR operations The GICv2 CPU interface registers span across 8K, not 4K as indicated in the DT. Only the GICC_DIR register is located after the initial 4K boundary, leaving a functional system but without support for separately EOI'ing and deactivating interrupts. After this change the system supports split priority drop and interrupt deactivation. Acked-by: Marc Zyngier Signed-off-by: Christoffer Dall [sudeep.holla@arm.com: included same fix for tc1 platform too] Signed-off-by: Sudeep Holla --- arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts | 2 +- arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index 102838fcc588..15f4fd3f4695 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -81,7 +81,7 @@ gic: interrupt-controller@2c001000 { #address-cells = <0>; interrupt-controller; reg = <0 0x2c001000 0 0x1000>, - <0 0x2c002000 0 0x1000>, + <0 0x2c002000 0 0x2000>, <0 0x2c004000 0 0x2000>, <0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 45d08cc37b01..bd107c5a0226 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts @@ -131,7 +131,7 @@ gic: interrupt-controller@2c001000 { #address-cells = <0>; interrupt-controller; reg = <0 0x2c001000 0 0x1000>, - <0 0x2c002000 0 0x1000>, + <0 0x2c002000 0 0x2000>, <0 0x2c004000 0 0x2000>, <0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; From 08c1a4ef7cccd5632526be923c5b6eaca59d8b01 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 30 Dec 2016 08:13:30 -0700 Subject: [PATCH 132/359] vfio-mdev: Fix mtty sample driver building This sample driver was originally under Documentation/ and was moved to samples, but build support was never adjusted for the new location. Signed-off-by: Alex Williamson Reviewed-by: Eric Auger Tested-by: Eric Auger Reviewed-by: Kirti Wankhede --- samples/Kconfig | 7 +++++++ samples/Makefile | 3 ++- samples/vfio-mdev/Makefile | 14 +------------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/samples/Kconfig b/samples/Kconfig index a6d2a43bbf2e..b124f62ed6cb 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -105,4 +105,11 @@ config SAMPLE_BLACKFIN_GPTIMERS help Build samples of blackfin gptimers sample module. +config SAMPLE_VFIO_MDEV_MTTY + tristate "Build VFIO mtty example mediated device sample code -- loadable modules only" + depends on VFIO_MDEV_DEVICE && m + help + Build a virtual tty sample driver for use as a VFIO + mediated device + endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index e17d66d77f09..86a137e451d9 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -2,4 +2,5 @@ obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \ - configfs/ connector/ v4l/ trace_printk/ blackfin/ + configfs/ connector/ v4l/ trace_printk/ blackfin/ \ + vfio-mdev/ diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile index a932edbe38eb..cbbd868a50a8 100644 --- a/samples/vfio-mdev/Makefile +++ b/samples/vfio-mdev/Makefile @@ -1,13 +1 @@ -# -# Makefile for mtty.c file -# -KERNEL_DIR:=/lib/modules/$(shell uname -r)/build - -obj-m:=mtty.o - -modules clean modules_install: - $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) $@ - -default: modules - -module: modules +obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o From 6c38c055cc4c0a5da31873d173b2de3085f43f33 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 30 Dec 2016 08:13:31 -0700 Subject: [PATCH 133/359] vfio/type1: Restore mapping performance with mdev support As part of the mdev support, type1 now gets a task reference per vfio_dma and uses that to get an mm reference for the task while working on accounting. That's correct, but it's not fast. For some paths, like vfio_pin_pages_remote(), we know we're only called from user context, so we can restore the lighter weight calls. In other cases, we're effectively already testing whether we're in the stored task context elsewhere, extend this vfio_lock_acct() as well. Signed-off-by: Alex Williamson Reviewed by: Kirti Wankhede --- drivers/vfio/vfio_iommu_type1.c | 98 +++++++++++++++++---------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index f3726ba12aa6..9266271a787a 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -268,28 +268,38 @@ static void vfio_lock_acct(struct task_struct *task, long npage) { struct vwork *vwork; struct mm_struct *mm; + bool is_current; if (!npage) return; - mm = get_task_mm(task); + is_current = (task->mm == current->mm); + + mm = is_current ? task->mm : get_task_mm(task); if (!mm) - return; /* process exited or nothing to do */ + return; /* process exited */ if (down_write_trylock(&mm->mmap_sem)) { mm->locked_vm += npage; up_write(&mm->mmap_sem); - mmput(mm); + if (!is_current) + mmput(mm); return; } + if (is_current) { + mm = get_task_mm(task); + if (!mm) + return; + } + /* * Couldn't get mmap_sem lock, so must setup to update * mm->locked_vm later. If locked_vm were atomic, we * wouldn't need this silliness */ vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL); - if (!vwork) { + if (WARN_ON(!vwork)) { mmput(mm); return; } @@ -393,77 +403,71 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr, long npage, unsigned long *pfn_base) { - unsigned long limit; - bool lock_cap = ns_capable(task_active_pid_ns(dma->task)->user_ns, - CAP_IPC_LOCK); - struct mm_struct *mm; - long ret, i = 0, lock_acct = 0; + unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + bool lock_cap = capable(CAP_IPC_LOCK); + long ret, pinned = 0, lock_acct = 0; bool rsvd; dma_addr_t iova = vaddr - dma->vaddr + dma->iova; - mm = get_task_mm(dma->task); - if (!mm) + /* This code path is only user initiated */ + if (!current->mm) return -ENODEV; - ret = vaddr_get_pfn(mm, vaddr, dma->prot, pfn_base); + ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, pfn_base); if (ret) - goto pin_pg_remote_exit; + return ret; + pinned++; rsvd = is_invalid_reserved_pfn(*pfn_base); - limit = task_rlimit(dma->task, RLIMIT_MEMLOCK) >> PAGE_SHIFT; /* * Reserved pages aren't counted against the user, externally pinned * pages are already counted against the user. */ if (!rsvd && !vfio_find_vpfn(dma, iova)) { - if (!lock_cap && mm->locked_vm + 1 > limit) { + if (!lock_cap && current->mm->locked_vm + 1 > limit) { put_pfn(*pfn_base, dma->prot); pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__, limit << PAGE_SHIFT); - ret = -ENOMEM; - goto pin_pg_remote_exit; + return -ENOMEM; } lock_acct++; } - i++; - if (likely(!disable_hugepages)) { - /* Lock all the consecutive pages from pfn_base */ - for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; i < npage; - i++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) { - unsigned long pfn = 0; + if (unlikely(disable_hugepages)) + goto out; - ret = vaddr_get_pfn(mm, vaddr, dma->prot, &pfn); - if (ret) - break; + /* Lock all the consecutive pages from pfn_base */ + for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; pinned < npage; + pinned++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) { + unsigned long pfn = 0; - if (pfn != *pfn_base + i || - rsvd != is_invalid_reserved_pfn(pfn)) { + ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, &pfn); + if (ret) + break; + + if (pfn != *pfn_base + pinned || + rsvd != is_invalid_reserved_pfn(pfn)) { + put_pfn(pfn, dma->prot); + break; + } + + if (!rsvd && !vfio_find_vpfn(dma, iova)) { + if (!lock_cap && + current->mm->locked_vm + lock_acct + 1 > limit) { put_pfn(pfn, dma->prot); + pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", + __func__, limit << PAGE_SHIFT); break; } - - if (!rsvd && !vfio_find_vpfn(dma, iova)) { - if (!lock_cap && - mm->locked_vm + lock_acct + 1 > limit) { - put_pfn(pfn, dma->prot); - pr_warn("%s: RLIMIT_MEMLOCK (%ld) " - "exceeded\n", __func__, - limit << PAGE_SHIFT); - break; - } - lock_acct++; - } + lock_acct++; } } - vfio_lock_acct(dma->task, lock_acct); - ret = i; +out: + vfio_lock_acct(current, lock_acct); -pin_pg_remote_exit: - mmput(mm); - return ret; + return pinned; } static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova, @@ -473,10 +477,10 @@ static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova, long unlocked = 0, locked = 0; long i; - for (i = 0; i < npage; i++) { + for (i = 0; i < npage; i++, iova += PAGE_SIZE) { if (put_pfn(pfn++, dma->prot)) { unlocked++; - if (vfio_find_vpfn(dma, iova + (i << PAGE_SHIFT))) + if (vfio_find_vpfn(dma, iova)) locked++; } } From 49550787a90b5bfa44d8dc424d11824dbe21473d Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 30 Dec 2016 08:13:33 -0700 Subject: [PATCH 134/359] vfio-mdev: Fix remove race Using the mtty mdev sample driver we can generate a remove race by starting one shell that continuously creates mtty devices and several other shells all attempting to remove devices, in my case four remove shells. The fault occurs in mdev_remove_sysfs_files() where the passed type arg is NULL, which suggests we've received a struct device in mdev_device_remove() but it's in some sort of teardown state. The solution here is to make use of the accidentally unused list_head on the mdev_device such that the mdev core keeps a list of all the mdev devices. This allows us to validate that we have a valid mdev before we start removal, remove it from the list to prevent others from working on it, and if the vendor driver refuses to remove, we can re-add it to the list. Cc: Kirti Wankhede Signed-off-by: Alex Williamson --- drivers/vfio/mdev/mdev_core.c | 36 +++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index be1ee89ee917..6bb4d4c469ab 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -27,6 +27,9 @@ static LIST_HEAD(parent_list); static DEFINE_MUTEX(parent_list_lock); static struct class_compat *mdev_bus_compat_class; +static LIST_HEAD(mdev_list); +static DEFINE_MUTEX(mdev_list_lock); + static int _find_mdev_device(struct device *dev, void *data) { struct mdev_device *mdev; @@ -316,6 +319,11 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) dev_dbg(&mdev->dev, "MDEV: created\n"); mutex_unlock(&parent->lock); + + mutex_lock(&mdev_list_lock); + list_add(&mdev->next, &mdev_list); + mutex_unlock(&mdev_list_lock); + return ret; create_failed: @@ -329,12 +337,30 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) int mdev_device_remove(struct device *dev, bool force_remove) { - struct mdev_device *mdev; + struct mdev_device *mdev, *tmp; struct parent_device *parent; struct mdev_type *type; int ret; + bool found = false; mdev = to_mdev_device(dev); + + mutex_lock(&mdev_list_lock); + list_for_each_entry(tmp, &mdev_list, next) { + if (tmp == mdev) { + found = true; + break; + } + } + + if (found) + list_del(&mdev->next); + + mutex_unlock(&mdev_list_lock); + + if (!found) + return -ENODEV; + type = to_mdev_type(mdev->type_kobj); parent = mdev->parent; mutex_lock(&parent->lock); @@ -342,6 +368,11 @@ int mdev_device_remove(struct device *dev, bool force_remove) ret = mdev_device_remove_ops(mdev, force_remove); if (ret) { mutex_unlock(&parent->lock); + + mutex_lock(&mdev_list_lock); + list_add(&mdev->next, &mdev_list); + mutex_unlock(&mdev_list_lock); + return ret; } @@ -349,7 +380,8 @@ int mdev_device_remove(struct device *dev, bool force_remove) device_unregister(dev); mutex_unlock(&parent->lock); mdev_put_parent(parent); - return ret; + + return 0; } static int __init mdev_init(void) From 42930553a7c11f06351bc08b889808d0f6020f08 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 30 Dec 2016 08:13:38 -0700 Subject: [PATCH 135/359] vfio-mdev: de-polute the namespace, rename parent_device & parent_ops Add an mdev_ prefix so we're not poluting the namespace so much. Cc: Zhenyu Wang Cc: Zhi Wang Cc: Jike Song Signed-off-by: Alex Williamson Reviewed by: Kirti Wankhede --- Documentation/vfio-mediated-device.txt | 24 +++++++++++----------- drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +- drivers/vfio/mdev/mdev_core.c | 28 +++++++++++++------------- drivers/vfio/mdev/mdev_private.h | 6 +++--- drivers/vfio/mdev/mdev_sysfs.c | 8 ++++---- drivers/vfio/mdev/vfio_mdev.c | 12 +++++------ include/linux/mdev.h | 16 +++++++-------- samples/vfio-mdev/mtty.c | 2 +- 8 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Documentation/vfio-mediated-device.txt b/Documentation/vfio-mediated-device.txt index b38afec35edc..cfee106a3679 100644 --- a/Documentation/vfio-mediated-device.txt +++ b/Documentation/vfio-mediated-device.txt @@ -127,22 +127,22 @@ the VFIO when devices are unbound from the driver. Physical Device Driver Interface -------------------------------- -The physical device driver interface provides the parent_ops[3] structure to -define the APIs to manage work in the mediated core driver that is related to -the physical device. +The physical device driver interface provides the mdev_parent_ops[3] structure +to define the APIs to manage work in the mediated core driver that is related +to the physical device. -The structures in the parent_ops structure are as follows: +The structures in the mdev_parent_ops structure are as follows: * dev_attr_groups: attributes of the parent device * mdev_attr_groups: attributes of the mediated device * supported_config: attributes to define supported configurations -The functions in the parent_ops structure are as follows: +The functions in the mdev_parent_ops structure are as follows: * create: allocate basic resources in a driver for a mediated device * remove: free resources in a driver when a mediated device is destroyed -The callbacks in the parent_ops structure are as follows: +The callbacks in the mdev_parent_ops structure are as follows: * open: open callback of mediated device * close: close callback of mediated device @@ -151,14 +151,14 @@ The callbacks in the parent_ops structure are as follows: * write: write emulation callback * mmap: mmap emulation callback -A driver should use the parent_ops structure in the function call to register -itself with the mdev core driver: +A driver should use the mdev_parent_ops structure in the function call to +register itself with the mdev core driver: extern int mdev_register_device(struct device *dev, - const struct parent_ops *ops); + const struct mdev_parent_ops *ops); -However, the parent_ops structure is not required in the function call that a -driver should use to unregister itself with the mdev core driver: +However, the mdev_parent_ops structure is not required in the function call +that a driver should use to unregister itself with the mdev core driver: extern void mdev_unregister_device(struct device *dev); @@ -394,5 +394,5 @@ References [1] See Documentation/vfio.txt for more information on VFIO. [2] struct mdev_driver in include/linux/mdev.h -[3] struct parent_ops in include/linux/mdev.h +[3] struct mdev_parent_ops in include/linux/mdev.h [4] struct vfio_iommu_driver_ops in include/linux/vfio.h diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 4dd6722a7339..081ada238107 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1089,7 +1089,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd, return 0; } -static const struct parent_ops intel_vgpu_ops = { +static const struct mdev_parent_ops intel_vgpu_ops = { .supported_type_groups = intel_vgpu_type_groups, .create = intel_vgpu_create, .remove = intel_vgpu_remove, diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 6bb4d4c469ab..bf3b3b0b3d2b 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -45,7 +45,7 @@ static int _find_mdev_device(struct device *dev, void *data) return 0; } -static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid) +static bool mdev_device_exist(struct mdev_parent *parent, uuid_le uuid) { struct device *dev; @@ -59,9 +59,9 @@ static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid) } /* Should be called holding parent_list_lock */ -static struct parent_device *__find_parent_device(struct device *dev) +static struct mdev_parent *__find_parent_device(struct device *dev) { - struct parent_device *parent; + struct mdev_parent *parent; list_for_each_entry(parent, &parent_list, next) { if (parent->dev == dev) @@ -72,8 +72,8 @@ static struct parent_device *__find_parent_device(struct device *dev) static void mdev_release_parent(struct kref *kref) { - struct parent_device *parent = container_of(kref, struct parent_device, - ref); + struct mdev_parent *parent = container_of(kref, struct mdev_parent, + ref); struct device *dev = parent->dev; kfree(parent); @@ -81,7 +81,7 @@ static void mdev_release_parent(struct kref *kref) } static -inline struct parent_device *mdev_get_parent(struct parent_device *parent) +inline struct mdev_parent *mdev_get_parent(struct mdev_parent *parent) { if (parent) kref_get(&parent->ref); @@ -89,7 +89,7 @@ inline struct parent_device *mdev_get_parent(struct parent_device *parent) return parent; } -static inline void mdev_put_parent(struct parent_device *parent) +static inline void mdev_put_parent(struct mdev_parent *parent) { if (parent) kref_put(&parent->ref, mdev_release_parent); @@ -98,7 +98,7 @@ static inline void mdev_put_parent(struct parent_device *parent) static int mdev_device_create_ops(struct kobject *kobj, struct mdev_device *mdev) { - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; int ret; ret = parent->ops->create(kobj, mdev); @@ -125,7 +125,7 @@ static int mdev_device_create_ops(struct kobject *kobj, */ static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove) { - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; int ret; /* @@ -156,10 +156,10 @@ static int mdev_device_remove_cb(struct device *dev, void *data) * Add device to list of registered parent devices. * Returns a negative value on error, otherwise 0. */ -int mdev_register_device(struct device *dev, const struct parent_ops *ops) +int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops) { int ret; - struct parent_device *parent; + struct mdev_parent *parent; /* check for mandatory ops */ if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups) @@ -232,7 +232,7 @@ EXPORT_SYMBOL(mdev_register_device); void mdev_unregister_device(struct device *dev) { - struct parent_device *parent; + struct mdev_parent *parent; bool force_remove = true; mutex_lock(&parent_list_lock); @@ -269,7 +269,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) { int ret; struct mdev_device *mdev; - struct parent_device *parent; + struct mdev_parent *parent; struct mdev_type *type = to_mdev_type(kobj); parent = mdev_get_parent(type->parent); @@ -338,7 +338,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) int mdev_device_remove(struct device *dev, bool force_remove) { struct mdev_device *mdev, *tmp; - struct parent_device *parent; + struct mdev_parent *parent; struct mdev_type *type; int ret; bool found = false; diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h index d35097cbf3d7..0b72c2d9ee40 100644 --- a/drivers/vfio/mdev/mdev_private.h +++ b/drivers/vfio/mdev/mdev_private.h @@ -19,7 +19,7 @@ void mdev_bus_unregister(void); struct mdev_type { struct kobject kobj; struct kobject *devices_kobj; - struct parent_device *parent; + struct mdev_parent *parent; struct list_head next; struct attribute_group *group; }; @@ -29,8 +29,8 @@ struct mdev_type { #define to_mdev_type(_kobj) \ container_of(_kobj, struct mdev_type, kobj) -int parent_create_sysfs_files(struct parent_device *parent); -void parent_remove_sysfs_files(struct parent_device *parent); +int parent_create_sysfs_files(struct mdev_parent *parent); +void parent_remove_sysfs_files(struct mdev_parent *parent); int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type); void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type); diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c index 1a53deb2ee10..802df210929b 100644 --- a/drivers/vfio/mdev/mdev_sysfs.c +++ b/drivers/vfio/mdev/mdev_sysfs.c @@ -92,7 +92,7 @@ static struct kobj_type mdev_type_ktype = { .release = mdev_type_release, }; -struct mdev_type *add_mdev_supported_type(struct parent_device *parent, +struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent, struct attribute_group *group) { struct mdev_type *type; @@ -158,7 +158,7 @@ static void remove_mdev_supported_type(struct mdev_type *type) kobject_put(&type->kobj); } -static int add_mdev_supported_type_groups(struct parent_device *parent) +static int add_mdev_supported_type_groups(struct mdev_parent *parent) { int i; @@ -183,7 +183,7 @@ static int add_mdev_supported_type_groups(struct parent_device *parent) } /* mdev sysfs functions */ -void parent_remove_sysfs_files(struct parent_device *parent) +void parent_remove_sysfs_files(struct mdev_parent *parent) { struct mdev_type *type, *tmp; @@ -196,7 +196,7 @@ void parent_remove_sysfs_files(struct parent_device *parent) kset_unregister(parent->mdev_types_kset); } -int parent_create_sysfs_files(struct parent_device *parent) +int parent_create_sysfs_files(struct mdev_parent *parent) { int ret; diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index ffc36758cb84..fa848a701b8b 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -27,7 +27,7 @@ static int vfio_mdev_open(void *device_data) { struct mdev_device *mdev = device_data; - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; int ret; if (unlikely(!parent->ops->open)) @@ -46,7 +46,7 @@ static int vfio_mdev_open(void *device_data) static void vfio_mdev_release(void *device_data) { struct mdev_device *mdev = device_data; - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; if (likely(parent->ops->release)) parent->ops->release(mdev); @@ -58,7 +58,7 @@ static long vfio_mdev_unlocked_ioctl(void *device_data, unsigned int cmd, unsigned long arg) { struct mdev_device *mdev = device_data; - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; if (unlikely(!parent->ops->ioctl)) return -EINVAL; @@ -70,7 +70,7 @@ static ssize_t vfio_mdev_read(void *device_data, char __user *buf, size_t count, loff_t *ppos) { struct mdev_device *mdev = device_data; - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; if (unlikely(!parent->ops->read)) return -EINVAL; @@ -82,7 +82,7 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf, size_t count, loff_t *ppos) { struct mdev_device *mdev = device_data; - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; if (unlikely(!parent->ops->write)) return -EINVAL; @@ -93,7 +93,7 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf, static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma) { struct mdev_device *mdev = device_data; - struct parent_device *parent = mdev->parent; + struct mdev_parent *parent = mdev->parent; if (unlikely(!parent->ops->mmap)) return -EINVAL; diff --git a/include/linux/mdev.h b/include/linux/mdev.h index ec819e9a115a..853bb78e5866 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -14,9 +14,9 @@ #define MDEV_H /* Parent device */ -struct parent_device { - struct device *dev; - const struct parent_ops *ops; +struct mdev_parent { + struct device *dev; + const struct mdev_parent_ops *ops; /* internal */ struct kref ref; @@ -29,7 +29,7 @@ struct parent_device { /* Mediated device */ struct mdev_device { struct device dev; - struct parent_device *parent; + struct mdev_parent *parent; uuid_le uuid; void *driver_data; @@ -40,7 +40,7 @@ struct mdev_device { }; /** - * struct parent_ops - Structure to be registered for each parent device to + * struct mdev_parent_ops - Structure to be registered for each parent device to * register the device to mdev module. * * @owner: The module owner. @@ -86,10 +86,10 @@ struct mdev_device { * @mdev: mediated device structure * @vma: vma structure * Parent device that support mediated device should be registered with mdev - * module with parent_ops structure. + * module with mdev_parent_ops structure. **/ -struct parent_ops { +struct mdev_parent_ops { struct module *owner; const struct attribute_group **dev_attr_groups; const struct attribute_group **mdev_attr_groups; @@ -159,7 +159,7 @@ extern struct bus_type mdev_bus_type; #define dev_is_mdev(d) ((d)->bus == &mdev_bus_type) extern int mdev_register_device(struct device *dev, - const struct parent_ops *ops); + const struct mdev_parent_ops *ops); extern void mdev_unregister_device(struct device *dev); extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner); diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 6b633a4ea333..1a74f0e488da 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -1402,7 +1402,7 @@ struct attribute_group *mdev_type_groups[] = { NULL, }; -struct parent_ops mdev_fops = { +struct mdev_parent_ops mdev_fops = { .owner = THIS_MODULE, .dev_attr_groups = mtty_dev_groups, .mdev_attr_groups = mdev_dev_groups, From 9372e6feaafb65d88f667ffb5b7b425f8568344f Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 30 Dec 2016 08:13:41 -0700 Subject: [PATCH 136/359] vfio-mdev: Make mdev_parent private Rather than hoping for good behavior by marking some elements internal, enforce it by making the entire structure private and creating an accessor function for the one useful external field. Cc: Zhenyu Wang Cc: Zhi Wang Cc: Jike Song Signed-off-by: Alex Williamson Reviewed by: Kirti Wankhede --- Documentation/vfio-mediated-device.txt | 3 +++ drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +- drivers/vfio/mdev/mdev_core.c | 6 ++++++ drivers/vfio/mdev/mdev_private.h | 10 ++++++++++ include/linux/mdev.h | 15 ++------------- samples/vfio-mdev/mtty.c | 2 +- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Documentation/vfio-mediated-device.txt b/Documentation/vfio-mediated-device.txt index cfee106a3679..d226c7a5ba8b 100644 --- a/Documentation/vfio-mediated-device.txt +++ b/Documentation/vfio-mediated-device.txt @@ -223,6 +223,9 @@ Directories and files under the sysfs for Each Physical Device sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name); + (or using mdev_parent_dev(mdev) to arrive at the parent device outside + of the core mdev code) + * device_api This attribute should show which device API is being created, for example, diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 081ada238107..38500329aa92 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -396,7 +396,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev) struct device *pdev; void *gvt; - pdev = mdev->parent->dev; + pdev = mdev_parent_dev(mdev); gvt = kdev_to_i915(pdev)->gvt; type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index bf3b3b0b3d2b..30d05304241e 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -30,6 +30,12 @@ static struct class_compat *mdev_bus_compat_class; static LIST_HEAD(mdev_list); static DEFINE_MUTEX(mdev_list_lock); +struct device *mdev_parent_dev(struct mdev_device *mdev) +{ + return mdev->parent->dev; +} +EXPORT_SYMBOL(mdev_parent_dev); + static int _find_mdev_device(struct device *dev, void *data) { struct mdev_device *mdev; diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h index 0b72c2d9ee40..b05dd22fc9a6 100644 --- a/drivers/vfio/mdev/mdev_private.h +++ b/drivers/vfio/mdev/mdev_private.h @@ -16,6 +16,16 @@ int mdev_bus_register(void); void mdev_bus_unregister(void); +struct mdev_parent { + struct device *dev; + const struct mdev_parent_ops *ops; + struct kref ref; + struct mutex lock; + struct list_head next; + struct kset *mdev_types_kset; + struct list_head type_list; +}; + struct mdev_type { struct kobject kobj; struct kobject *devices_kobj; diff --git a/include/linux/mdev.h b/include/linux/mdev.h index 853bb78e5866..f586222b6c25 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -13,19 +13,6 @@ #ifndef MDEV_H #define MDEV_H -/* Parent device */ -struct mdev_parent { - struct device *dev; - const struct mdev_parent_ops *ops; - - /* internal */ - struct kref ref; - struct mutex lock; - struct list_head next; - struct kset *mdev_types_kset; - struct list_head type_list; -}; - /* Mediated device */ struct mdev_device { struct device dev; @@ -165,4 +152,6 @@ extern void mdev_unregister_device(struct device *dev); extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner); extern void mdev_unregister_driver(struct mdev_driver *drv); +extern struct device *mdev_parent_dev(struct mdev_device *mdev); + #endif /* MDEV_H */ diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 1a74f0e488da..5e13efc62bad 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -734,7 +734,7 @@ int mtty_create(struct kobject *kobj, struct mdev_device *mdev) for (i = 0; i < 2; i++) { snprintf(name, MTTY_STRING_LEN, "%s-%d", - dev_driver_string(mdev->parent->dev), i + 1); + dev_driver_string(mdev_parent_dev(mdev)), i + 1); if (!strcmp(kobj->name, name)) { nr_ports = i + 1; break; From 99e3123e3d72616a829dad6d25aa005ef1ef9b13 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 30 Dec 2016 08:13:44 -0700 Subject: [PATCH 137/359] vfio-mdev: Make mdev_device private and abstract interfaces Abstract access to mdev_device so that we can define which interfaces are public rather than relying on comments in the structure. Cc: Zhenyu Wang Cc: Zhi Wang Signed-off-by: Alex Williamson Reviewed-by: Jike Song Reviewed by: Kirti Wankhede --- drivers/gpu/drm/i915/gvt/kvmgt.c | 18 +++++++++--------- drivers/vfio/mdev/mdev_core.c | 30 ++++++++++++++++++++++++++++++ drivers/vfio/mdev/mdev_private.h | 13 +++++++++++++ include/linux/mdev.h | 31 ++++++------------------------- samples/vfio-mdev/mtty.c | 24 +++++++++++++----------- 5 files changed, 71 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 38500329aa92..f8021a01df63 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -166,7 +166,7 @@ static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu, static void gvt_cache_remove(struct intel_vgpu *vgpu, gfn_t gfn) { - struct device *dev = &vgpu->vdev.mdev->dev; + struct device *dev = mdev_dev(vgpu->vdev.mdev); struct gvt_dma *this; unsigned long g1; int rc; @@ -195,7 +195,7 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu) { struct gvt_dma *dma; struct rb_node *node = NULL; - struct device *dev = &vgpu->vdev.mdev->dev; + struct device *dev = mdev_dev(vgpu->vdev.mdev); unsigned long gfn; mutex_lock(&vgpu->vdev.cache_lock); @@ -418,7 +418,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev) mdev_set_drvdata(mdev, vgpu); gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n", - dev_name(&mdev->dev)); + dev_name(mdev_dev(mdev))); return 0; } @@ -482,7 +482,7 @@ static int intel_vgpu_open(struct mdev_device *mdev) vgpu->vdev.group_notifier.notifier_call = intel_vgpu_group_notifier; events = VFIO_IOMMU_NOTIFY_DMA_UNMAP; - ret = vfio_register_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, &events, + ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &events, &vgpu->vdev.iommu_notifier); if (ret != 0) { gvt_err("vfio_register_notifier for iommu failed: %d\n", ret); @@ -490,7 +490,7 @@ static int intel_vgpu_open(struct mdev_device *mdev) } events = VFIO_GROUP_NOTIFY_SET_KVM; - ret = vfio_register_notifier(&mdev->dev, VFIO_GROUP_NOTIFY, &events, + ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY, &events, &vgpu->vdev.group_notifier); if (ret != 0) { gvt_err("vfio_register_notifier for group failed: %d\n", ret); @@ -500,7 +500,7 @@ static int intel_vgpu_open(struct mdev_device *mdev) return kvmgt_guest_init(mdev); undo_iommu: - vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, + vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &vgpu->vdev.iommu_notifier); out: return ret; @@ -513,9 +513,9 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) if (!handle_valid(vgpu->handle)) return; - vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY, + vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY, &vgpu->vdev.iommu_notifier); - vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY, + vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_GROUP_NOTIFY, &vgpu->vdev.group_notifier); info = (struct kvmgt_guest_info *)vgpu->handle; @@ -1372,7 +1372,7 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn) return pfn; pfn = INTEL_GVT_INVALID_ADDR; - dev = &info->vgpu->vdev.mdev->dev; + dev = mdev_dev(info->vgpu->vdev.mdev); rc = vfio_pin_pages(dev, &gfn, 1, IOMMU_READ | IOMMU_WRITE, &pfn); if (rc != 1) { gvt_err("vfio_pin_pages failed for gfn 0x%lx: %d\n", gfn, rc); diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index 30d05304241e..36d75c367d22 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -36,6 +36,36 @@ struct device *mdev_parent_dev(struct mdev_device *mdev) } EXPORT_SYMBOL(mdev_parent_dev); +void *mdev_get_drvdata(struct mdev_device *mdev) +{ + return mdev->driver_data; +} +EXPORT_SYMBOL(mdev_get_drvdata); + +void mdev_set_drvdata(struct mdev_device *mdev, void *data) +{ + mdev->driver_data = data; +} +EXPORT_SYMBOL(mdev_set_drvdata); + +struct device *mdev_dev(struct mdev_device *mdev) +{ + return &mdev->dev; +} +EXPORT_SYMBOL(mdev_dev); + +struct mdev_device *mdev_from_dev(struct device *dev) +{ + return dev_is_mdev(dev) ? to_mdev_device(dev) : NULL; +} +EXPORT_SYMBOL(mdev_from_dev); + +uuid_le mdev_uuid(struct mdev_device *mdev) +{ + return mdev->uuid; +} +EXPORT_SYMBOL(mdev_uuid); + static int _find_mdev_device(struct device *dev, void *data) { struct mdev_device *mdev; diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h index b05dd22fc9a6..a9cefd70a705 100644 --- a/drivers/vfio/mdev/mdev_private.h +++ b/drivers/vfio/mdev/mdev_private.h @@ -26,6 +26,19 @@ struct mdev_parent { struct list_head type_list; }; +struct mdev_device { + struct device dev; + struct mdev_parent *parent; + uuid_le uuid; + void *driver_data; + struct kref ref; + struct list_head next; + struct kobject *type_kobj; +}; + +#define to_mdev_device(dev) container_of(dev, struct mdev_device, dev) +#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type) + struct mdev_type { struct kobject kobj; struct kobject *devices_kobj; diff --git a/include/linux/mdev.h b/include/linux/mdev.h index f586222b6c25..3ee44b8d2bb3 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -13,18 +13,7 @@ #ifndef MDEV_H #define MDEV_H -/* Mediated device */ -struct mdev_device { - struct device dev; - struct mdev_parent *parent; - uuid_le uuid; - void *driver_data; - - /* internal */ - struct kref ref; - struct list_head next; - struct kobject *type_kobj; -}; +struct mdev_device; /** * struct mdev_parent_ops - Structure to be registered for each parent device to @@ -75,7 +64,6 @@ struct mdev_device { * Parent device that support mediated device should be registered with mdev * module with mdev_parent_ops structure. **/ - struct mdev_parent_ops { struct module *owner; const struct attribute_group **dev_attr_groups; @@ -129,22 +117,13 @@ struct mdev_driver { }; #define to_mdev_driver(drv) container_of(drv, struct mdev_driver, driver) -#define to_mdev_device(dev) container_of(dev, struct mdev_device, dev) -static inline void *mdev_get_drvdata(struct mdev_device *mdev) -{ - return mdev->driver_data; -} - -static inline void mdev_set_drvdata(struct mdev_device *mdev, void *data) -{ - mdev->driver_data = data; -} +extern void *mdev_get_drvdata(struct mdev_device *mdev); +extern void mdev_set_drvdata(struct mdev_device *mdev, void *data); +extern uuid_le mdev_uuid(struct mdev_device *mdev); extern struct bus_type mdev_bus_type; -#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type) - extern int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops); extern void mdev_unregister_device(struct device *dev); @@ -153,5 +132,7 @@ extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner); extern void mdev_unregister_driver(struct mdev_driver *drv); extern struct device *mdev_parent_dev(struct mdev_device *mdev); +extern struct device *mdev_dev(struct mdev_device *mdev); +extern struct mdev_device *mdev_from_dev(struct device *dev); #endif /* MDEV_H */ diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 5e13efc62bad..919c10d5b12e 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -164,7 +164,7 @@ static struct mdev_state *find_mdev_state_by_uuid(uuid_le uuid) struct mdev_state *mds; list_for_each_entry(mds, &mdev_devices_list, next) { - if (uuid_le_cmp(mds->mdev->uuid, uuid) == 0) + if (uuid_le_cmp(mdev_uuid(mds->mdev), uuid) == 0) return mds; } @@ -341,7 +341,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, pr_err("Serial port %d: Fifo level trigger\n", index); #endif - mtty_trigger_interrupt(mdev_state->mdev->uuid); + mtty_trigger_interrupt( + mdev_uuid(mdev_state->mdev)); } } else { #if defined(DEBUG_INTR) @@ -355,7 +356,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, */ if (mdev_state->s[index].uart_reg[UART_IER] & UART_IER_RLSI) - mtty_trigger_interrupt(mdev_state->mdev->uuid); + mtty_trigger_interrupt( + mdev_uuid(mdev_state->mdev)); } mutex_unlock(&mdev_state->rxtx_lock); break; @@ -374,7 +376,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, pr_err("Serial port %d: IER_THRI write\n", index); #endif - mtty_trigger_interrupt(mdev_state->mdev->uuid); + mtty_trigger_interrupt( + mdev_uuid(mdev_state->mdev)); } mutex_unlock(&mdev_state->rxtx_lock); @@ -445,7 +448,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, #if defined(DEBUG_INTR) pr_err("Serial port %d: MCR_OUT2 write\n", index); #endif - mtty_trigger_interrupt(mdev_state->mdev->uuid); + mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev)); } if ((mdev_state->s[index].uart_reg[UART_IER] & UART_IER_MSI) && @@ -453,7 +456,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, #if defined(DEBUG_INTR) pr_err("Serial port %d: MCR RTS/DTR write\n", index); #endif - mtty_trigger_interrupt(mdev_state->mdev->uuid); + mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev)); } break; @@ -504,7 +507,8 @@ static void handle_bar_read(unsigned int index, struct mdev_state *mdev_state, #endif if (mdev_state->s[index].uart_reg[UART_IER] & UART_IER_THRI) - mtty_trigger_interrupt(mdev_state->mdev->uuid); + mtty_trigger_interrupt( + mdev_uuid(mdev_state->mdev)); } mutex_unlock(&mdev_state->rxtx_lock); @@ -1298,10 +1302,8 @@ static ssize_t sample_mdev_dev_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct mdev_device *mdev = to_mdev_device(dev); - - if (mdev) - return sprintf(buf, "This is MDEV %s\n", dev_name(&mdev->dev)); + if (mdev_from_dev(dev)) + return sprintf(buf, "This is MDEV %s\n", dev_name(dev)); return sprintf(buf, "\n"); } From 45e869714489431625c569d21fc952428d761476 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 30 Dec 2016 08:13:47 -0700 Subject: [PATCH 138/359] vfio-pci: use 32-bit comparisons for register address for gcc-4.5 Using ancient compilers (gcc-4.5 or older) on ARM, we get a link failure with the vfio-pci driver: ERROR: "__aeabi_lcmp" [drivers/vfio/pci/vfio-pci.ko] undefined! The reason is that the compiler tries to do a comparison of a 64-bit range. This changes it to convert to a 32-bit number explicitly first, as newer compilers do for themselves. Signed-off-by: Arnd Bergmann Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci_rdwr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c index 5ffd1d9ad4bd..357243d76f10 100644 --- a/drivers/vfio/pci/vfio_pci_rdwr.c +++ b/drivers/vfio/pci/vfio_pci_rdwr.c @@ -193,7 +193,10 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf, if (!vdev->has_vga) return -EINVAL; - switch (pos) { + if (pos > 0xbfffful) + return -EINVAL; + + switch ((u32)pos) { case 0xa0000 ... 0xbffff: count = min(count, (size_t)(0xc0000 - pos)); iomem = ioremap_nocache(0xa0000, 0xbffff - 0xa0000 + 1); From 1dff32d7df7ff5d80194ebce7ab5755b32564e13 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 13 Dec 2016 14:24:53 +0000 Subject: [PATCH 139/359] arm64: dts: vexpress: Support GICC_DIR operations The GICv2 CPU interface registers span across 8K, not 4K as indicated in the DT. Only the GICC_DIR register is located after the initial 4K boundary, leaving a functional system but without support for separately EOI'ing and deactivating interrupts. After this change the system supports split priority drop and interrupt deactivation. This patch is based on similar one from Christoffer Dall: commit 368400e242dc ("ARM: dts: vexpress: Support GICC_DIR operations") Signed-off-by: Sudeep Holla --- arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts index a852e28a40e1..a83ed2c6bbf7 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts +++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts @@ -81,7 +81,7 @@ gic: interrupt-controller@2c001000 { #address-cells = <0>; interrupt-controller; reg = <0x0 0x2c001000 0 0x1000>, - <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c002000 0 0x2000>, <0x0 0x2c004000 0 0x2000>, <0x0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; From 433e404f07bee649e46b7f3cd951bc05b0150b3a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 Dec 2016 14:55:10 +0000 Subject: [PATCH 140/359] drm/armada: s/drm_mm_dump_table/drm_mm_print/ Missed rename during v2 of b5c3714fe878 ("drm/mm: Convert to drm_printer") Reported-by: kbuild test robot Fixes: b5c3714fe878 ("drm/mm: Convert to drm_printer") Signed-off-by: Chris Wilson Cc: Daniel Vetter Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161230145510.12951-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/armada/armada_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c index 0c7b915be082..a8020cf9da2e 100644 --- a/drivers/gpu/drm/armada/armada_debugfs.c +++ b/drivers/gpu/drm/armada/armada_debugfs.c @@ -22,7 +22,7 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data) struct drm_printer p = drm_seq_file_printer(m); mutex_lock(&priv->linear_lock); - drm_mm_dump_table(&p, &priv->linear); + drm_mm_print(&priv->linear, &p); mutex_unlock(&priv->linear_lock); return 0; From b1448ea9cd95868e3e91313b643818d18917b382 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Dec 2016 13:30:24 +0100 Subject: [PATCH 141/359] iio: adc: TI_AM335X_ADC should depend on HAS_DMA If NO_DMA=y: ERROR: "bad_dma_ops" [drivers/iio/adc/ti_am335x_adc.ko] undefined! Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Fixes: f438b9da (" drivers: iio: ti_am335x_adc: add dma support") Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 38bc319904c4..9c8b558ba19e 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -561,7 +561,7 @@ config TI_ADS8688 config TI_AM335X_ADC tristate "TI's AM335X ADC driver" - depends on MFD_TI_AM335X_TSCADC + depends on MFD_TI_AM335X_TSCADC && HAS_DMA select IIO_BUFFER select IIO_KFIFO_BUF help From 7357f89954b6d005df6ab8929759e78d7d9a80f9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 30 Dec 2016 17:38:52 +0100 Subject: [PATCH 142/359] drm/armada: Fix compile fail I reported the include issue for tracepoints a while ago, but nothing seems to have happened. Now it bit us, since the drm_mm_print conversion was broken for armada. Fix it, so I can re-enable armada in the drm-misc build configs. v2: Rebase just the compile fix on top of Chris' build fix. Cc: Russell King Cc: Chris Wilson Acked: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483115932-19584-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/armada/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile index a18f156c8b66..64c0b4546fb2 100644 --- a/drivers/gpu/drm/armada/Makefile +++ b/drivers/gpu/drm/armada/Makefile @@ -4,3 +4,5 @@ armada-y += armada_510.o armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o obj-$(CONFIG_DRM_ARMADA) := armada.o + +CFLAGS_armada_trace.o := -I$(src) From b112481bb327c0fc7c65767b71b87a033688a892 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:31 +0100 Subject: [PATCH 143/359] drm/cma-helper: simplify setup for drivers with ->dirty callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we store the fb funcs pointer, we can remove a bit of boilerplate. Also remove the _fbdev_ in the example code, since the fb_funcs->dirty callback has nothing to do with fbdev. It's a KMS feature, only used by the fbdev deferred_io support to implement flushing/upload. Cc: Noralf Trønnes Cc: Laurent Pinchart Reviewed-by: Laurent Pinchart [danvet: Move the misplaced kerneldoc change from a later patch to this one here.] Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-11-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fb_cma_helper.c | 60 ++++++++++------------------- include/drm/drm_fb_cma_helper.h | 5 +-- 2 files changed, 22 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 96f3965b8028..ea2f8466be00 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -39,6 +39,7 @@ struct drm_fb_cma { struct drm_fbdev_cma { struct drm_fb_helper fb_helper; struct drm_fb_cma *fb; + const struct drm_framebuffer_funcs *fb_funcs; }; /** @@ -58,39 +59,29 @@ struct drm_fbdev_cma { * * Example fbdev deferred io code:: * - * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb, - * struct drm_file *file_priv, - * unsigned flags, unsigned color, - * struct drm_clip_rect *clips, - * unsigned num_clips) + * static int driver_fb_dirty(struct drm_framebuffer *fb, + * struct drm_file *file_priv, + * unsigned flags, unsigned color, + * struct drm_clip_rect *clips, + * unsigned num_clips) * { * struct drm_gem_cma_object *cma = drm_fb_cma_get_gem_obj(fb, 0); * ... push changes ... * return 0; * } * - * static struct drm_framebuffer_funcs driver_fbdev_fb_funcs = { + * static struct drm_framebuffer_funcs driver_fb_funcs = { * .destroy = drm_fb_cma_destroy, * .create_handle = drm_fb_cma_create_handle, - * .dirty = driver_fbdev_fb_dirty, + * .dirty = driver_fb_dirty, * }; * - * static int driver_fbdev_create(struct drm_fb_helper *helper, - * struct drm_fb_helper_surface_size *sizes) - * { - * return drm_fbdev_cma_create_with_funcs(helper, sizes, - * &driver_fbdev_fb_funcs); - * } + * Initialize:: * - * static const struct drm_fb_helper_funcs driver_fb_helper_funcs = { - * .fb_probe = driver_fbdev_create, - * }; - * - * Initialize: * fbdev = drm_fbdev_cma_init_with_funcs(dev, 16, * dev->mode_config.num_crtc, * dev->mode_config.num_connector, - * &driver_fb_helper_funcs); + * &driver_fb_funcs); * */ @@ -408,13 +399,9 @@ static void drm_fbdev_cma_defio_fini(struct fb_info *fbi) kfree(fbi->fbops); } -/* - * For use in a (struct drm_fb_helper_funcs *)->fb_probe callback function that - * needs custom struct drm_framebuffer_funcs, like dirty() for deferred_io use. - */ -int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes, - const struct drm_framebuffer_funcs *funcs) +static int +drm_fbdev_cma_create(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper); struct drm_mode_fb_cmd2 mode_cmd = { 0 }; @@ -450,7 +437,8 @@ int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, goto err_gem_free_object; } - fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1, funcs); + fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1, + fbdev_cma->fb_funcs); if (IS_ERR(fbdev_cma->fb)) { dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); ret = PTR_ERR(fbdev_cma->fb); @@ -476,7 +464,7 @@ int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, fbi->screen_size = size; fbi->fix.smem_len = size; - if (funcs->dirty) { + if (fbdev_cma->fb_funcs->dirty) { ret = drm_fbdev_cma_defio_init(fbi, obj); if (ret) goto err_cma_destroy; @@ -493,13 +481,6 @@ int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, drm_gem_object_unreference_unlocked(&obj->base); return ret; } -EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); - -static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - return drm_fbdev_cma_create_with_funcs(helper, sizes, &drm_fb_cma_funcs); -} static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = { .fb_probe = drm_fbdev_cma_create, @@ -511,13 +492,13 @@ static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = { * @preferred_bpp: Preferred bits per pixel for the device * @num_crtc: Number of CRTCs * @max_conn_count: Maximum number of connectors - * @funcs: fb helper functions, in particular fb_probe() + * @funcs: fb helper functions, in particular a custom dirty() callback * * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR. */ struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev, unsigned int preferred_bpp, unsigned int num_crtc, - unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs) + unsigned int max_conn_count, const struct drm_framebuffer_funcs *funcs) { struct drm_fbdev_cma *fbdev_cma; struct drm_fb_helper *helper; @@ -528,10 +509,11 @@ struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev, dev_err(dev->dev, "Failed to allocate drm fbdev.\n"); return ERR_PTR(-ENOMEM); } + fbdev_cma->fb_funcs = funcs; helper = &fbdev_cma->fb_helper; - drm_fb_helper_prepare(dev, helper, funcs); + drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs); ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); if (ret < 0) { @@ -577,7 +559,7 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, unsigned int max_conn_count) { return drm_fbdev_cma_init_with_funcs(dev, preferred_bpp, num_crtc, - max_conn_count, &drm_fb_cma_helper_funcs); + max_conn_count, &drm_fb_cma_funcs); } EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h index 3b00f6480b83..9f4e34ea99fd 100644 --- a/include/drm/drm_fb_cma_helper.h +++ b/include/drm/drm_fb_cma_helper.h @@ -17,7 +17,7 @@ struct drm_plane_state; struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev, unsigned int preferred_bpp, unsigned int num_crtc, - unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs); + unsigned int max_conn_count, const struct drm_framebuffer_funcs *funcs); struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, unsigned int preferred_bpp, unsigned int num_crtc, unsigned int max_conn_count); @@ -26,9 +26,6 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma); void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state); -int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes, - const struct drm_framebuffer_funcs *funcs); void drm_fb_cma_destroy(struct drm_framebuffer *fb); int drm_fb_cma_create_handle(struct drm_framebuffer *fb, From 421242aab39ebf45c34eb668b267f3861c8bcab2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 29 Dec 2016 21:48:34 +0100 Subject: [PATCH 144/359] drm/cma-helpers: Use recommened kerneldoc for struct member refs I just learned that &struct_name.member_name works and looks pretty even. It doesn't (yet) link to the member directly though, which would be really good for big structures or vfunc tables (where the per-member kerneldoc tends to be long). Also some minor drive-by polish where it makes sense, I read a lot of docs ... v2: Review from Laurent: - Move misplaced doc change to the right patch. - Remove "DRM driver's", it's redundant. - Spotted 3 more places where where we could add prose reference with a real one. Cc: Laurent Pinchart Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-14-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fb_cma_helper.c | 26 +++++++++++++------------- drivers/gpu/drm/drm_gem_cma_helper.c | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index ea2f8466be00..20a4011f790d 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -48,14 +48,14 @@ struct drm_fbdev_cma { * Provides helper functions for creating a cma (contiguous memory allocator) * backed framebuffer. * - * drm_fb_cma_create() is used in the &drm_mode_config_funcs ->fb_create + * drm_fb_cma_create() is used in the &drm_mode_config_funcs.fb_create * callback function to create a cma backed framebuffer. * * An fbdev framebuffer backed by cma is also available by calling * drm_fbdev_cma_init(). drm_fbdev_cma_fini() tears it down. - * If the &drm_framebuffer_funcs ->dirty callback is set, fb_deferred_io - * will be set up automatically. dirty() is called by - * drm_fb_helper_deferred_io() in process context (struct delayed_work). + * If the &drm_framebuffer_funcs.dirty callback is set, fb_deferred_io will be + * set up automatically. &drm_framebuffer_funcs.dirty is called by + * drm_fb_helper_deferred_io() in process context (&struct delayed_work). * * Example fbdev deferred io code:: * @@ -155,16 +155,16 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, /** * drm_fb_cma_create_with_funcs() - helper function for the - * &drm_mode_config_funcs ->fb_create - * callback function + * &drm_mode_config_funcs.fb_create + * callback * @dev: DRM device * @file_priv: drm file for the ioctl call * @mode_cmd: metadata from the userspace fb creation request * @funcs: vtable to be used for the new framebuffer object * * This can be used to set &drm_framebuffer_funcs for drivers that need the - * dirty() callback. Use drm_fb_cma_create() if you don't need to change - * &drm_framebuffer_funcs. + * &drm_framebuffer_funcs.dirty callback. Use drm_fb_cma_create() if you don't + * need to change &drm_framebuffer_funcs. */ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd, @@ -221,14 +221,14 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev, EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs); /** - * drm_fb_cma_create() - &drm_mode_config_funcs ->fb_create callback function + * drm_fb_cma_create() - &drm_mode_config_funcs.fb_create callback function * @dev: DRM device * @file_priv: drm file for the ioctl call * @mode_cmd: metadata from the userspace fb creation request * * If your hardware has special alignment or pitch requirements these should be * checked before calling this function. Use drm_fb_cma_create_with_funcs() if - * you need to set &drm_framebuffer_funcs ->dirty. + * you need to set &drm_framebuffer_funcs.dirty. */ struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) @@ -264,7 +264,7 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); * @plane: Which plane * @state: Plane state attach fence to * - * This should be put into prepare_fb hook of &struct drm_plane_helper_funcs . + * This should be set as the &struct drm_plane_helper_funcs.prepare_fb hook. * * This function checks if the plane FB has an dma-buf attached, extracts * the exclusive fence and attaches it to plane state for the atomic helper @@ -588,7 +588,7 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_fini); * drm_fbdev_cma_restore_mode() - Restores initial framebuffer mode * @fbdev_cma: The drm_fbdev_cma struct, may be NULL * - * This function is usually called from the DRM drivers lastclose callback. + * This function is usually called from the &drm_driver.lastclose callback. */ void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma) { @@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_restore_mode); * drm_fbdev_cma_hotplug_event() - Poll for hotpulug events * @fbdev_cma: The drm_fbdev_cma struct, may be NULL * - * This function is usually called from the DRM drivers output_poll_changed + * This function is usually called from the &drm_mode_config.output_poll_changed * callback. */ void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma) diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 1d6c335584ec..e0806a2ad11c 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -176,8 +176,8 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, * * This function frees the backing memory of the CMA GEM object, cleans up the * GEM object state and frees the memory used to store the object itself. - * Drivers using the CMA helpers should set this as their DRM driver's - * ->gem_free_object() callback. + * Drivers using the CMA helpers should set this as their + * &drm_driver.gem_free_object callback. */ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) { @@ -207,7 +207,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_free_object); * This aligns the pitch and size arguments to the minimum required. This is * an internal helper that can be wrapped by a driver to account for hardware * with more specific alignment requirements. It should not be used directly - * as the ->dumb_create() callback in a DRM driver. + * as their &drm_driver.dumb_create callback. * * Returns: * 0 on success or a negative error code on failure. @@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create_internal); * This function computes the pitch of the dumb buffer and rounds it up to an * integer number of bytes per pixel. Drivers for hardware that doesn't have * any additional restrictions on the pitch can directly use this function as - * their ->dumb_create() callback. + * their &drm_driver.dumb_create callback. * * For hardware with additional restrictions, drivers can adjust the fields * set up by userspace and pass the IOCTL data along to the @@ -274,7 +274,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create); * * This function look up an object by its handle and returns the fake mmap * offset associated with it. Drivers using the CMA helpers should set this - * as their DRM driver's ->dumb_map_offset() callback. + * as their &drm_driver.dumb_map_offset callback. * * Returns: * 0 on success or a negative error code on failure. @@ -391,7 +391,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_describe); * * This function exports a scatter/gather table suitable for PRIME usage by * calling the standard DMA mapping API. Drivers using the CMA helpers should - * set this as their DRM driver's ->gem_prime_get_sg_table() callback. + * set this as their &drm_driver.gem_prime_get_sg_table callback. * * Returns: * A pointer to the scatter/gather table of pinned pages or NULL on failure. @@ -429,8 +429,8 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table); * This function imports a scatter/gather table exported via DMA-BUF by * another driver. Imported buffers must be physically contiguous in memory * (i.e. the scatter/gather table must contain a single entry). Drivers that - * use the CMA helpers should set this as their DRM driver's - * ->gem_prime_import_sg_table() callback. + * use the CMA helpers should set this as their + * &drm_driver.gem_prime_import_sg_table callback. * * Returns: * A pointer to a newly created GEM object or an ERR_PTR-encoded negative @@ -467,7 +467,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table); * * This function maps a buffer imported via DRM PRIME into a userspace * process's address space. Drivers that use the CMA helpers should set this - * as their DRM driver's ->gem_prime_mmap() callback. + * as their &drm_driver.gem_prime_mmap callback. * * Returns: * 0 on success or a negative error code on failure. @@ -496,7 +496,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); * virtual address space. Since the CMA buffers are already mapped into the * kernel virtual address space this simply returns the cached virtual * address. Drivers using the CMA helpers should set this as their DRM - * driver's ->gem_prime_vmap() callback. + * driver's &drm_driver.gem_prime_vmap callback. * * Returns: * The kernel virtual address of the CMA GEM object's backing store. @@ -518,7 +518,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap); * This function removes a buffer exported via DRM PRIME from the kernel's * virtual address space. This is a no-op because CMA buffers cannot be * unmapped from kernel space. Drivers using the CMA helpers should set this - * as their DRM driver's ->gem_prime_vunmap() callback. + * as their &drm_driver.gem_prime_vunmap callback. */ void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr) { From 1a38de880992764d4bd5bccbd306b87d860e377d Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 30 Dec 2016 13:37:20 +0530 Subject: [PATCH 145/359] ARM: dts: am572x-idk: Add gpios property to control PCIE_RESETn Add 'gpios' property to pcie1 dt node and populate it with GPIO3_23 in order to drive PCIE_RESETn high. This gets PCIe cards to be detected in AM572X IDK board. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am572x-idk.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts index 4ed40be761b2..8350b4b34b08 100644 --- a/arch/arm/boot/dts/am572x-idk.dts +++ b/arch/arm/boot/dts/am572x-idk.dts @@ -87,3 +87,7 @@ &mmc1 { &sn65hvs882 { load-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; }; + +&pcie1 { + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; From b4e8a0eb718749455601fa7b283febc42cca8957 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 29 Dec 2016 02:16:36 +0900 Subject: [PATCH 146/359] iio: max44000: correct value in illuminance_integration_time_available According to the datasheet, the shortest available integration time for ALS ADC conversion is 1.5625ms but illuminance_integration_time_available sysfs file shows wrong value. Cc: Crestez Dan Leonard Cc: Jonathan Cameron Cc: Hartmut Knaack Cc: Lars-Peter Clausen Cc: Peter Meerwald-Stadler Signed-off-by: Akinobu Mita Fixes: d5d8f49b6 ("max44000: Expose ambient sensor scaling") Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/max44000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c index a144ca3461fc..81bd8e8da4a6 100644 --- a/drivers/iio/light/max44000.c +++ b/drivers/iio/light/max44000.c @@ -113,7 +113,7 @@ static const char max44000_int_time_avail_str[] = "0.100 " "0.025 " "0.00625 " - "0.001625"; + "0.0015625"; /* Available scales (internal to ulux) with pretty manual alignment: */ static const int max44000_scale_avail_ulux_array[] = { From 42d97eb0ade31e1bc537d086842f5d6e766d9d51 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 19 Dec 2016 14:20:13 -0800 Subject: [PATCH 147/359] fscrypt: fix renaming and linking special files Attempting to link a device node, named pipe, or socket file into an encrypted directory through rename(2) or link(2) always failed with EPERM. This happened because fscrypt_has_permitted_context() saw that the file was unencrypted and forbid creating the link. This behavior was unexpected because such files are never encrypted; only regular files, directories, and symlinks can be encrypted. To fix this, make fscrypt_has_permitted_context() always return true on special files. This will be covered by a test in my encryption xfstests patchset. Fixes: 9bd8212f981e ("ext4 crypto: add encryption policy and password salt support") Signed-off-by: Eric Biggers Reviewed-by: Richard Weinberger Cc: stable@vger.kernel.org Signed-off-by: Theodore Ts'o --- fs/crypto/policy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 6ed7c2eebeec..d6cd7ea4851d 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -179,6 +179,11 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) BUG_ON(1); } + /* No restrictions on file types which are never encrypted */ + if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) && + !S_ISLNK(child->i_mode)) + return 1; + /* no restrictions if the parent directory is not encrypted */ if (!parent->i_sb->s_cop->is_encrypted(parent)) return 1; From 65c8aea07de11b6507efa175edb44bd8b4488218 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 16 Nov 2016 22:15:28 +0100 Subject: [PATCH 148/359] iio: common: st_sensors: fix channel data parsing Using realbits as i2c/spi read len, when that value is not byte aligned (e.g 12 bits), lead to skip msb part of out data registers. Fix this taking into account scan_type.shift in addition to scan_type.realbits as read length: read_len = DIV_ROUND_UP(realbits + shift, 8) This fix has been tested on 8, 12, 16, 24 bit sensors Fixes: e7385de5291e ("iio:st_sensors: align on storagebits boundaries") Signed-off-by: Lorenzo Bianconi Tested-by: Linus Walleij Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/common/st_sensors/st_sensors_buffer.c | 4 +++- drivers/iio/common/st_sensors/st_sensors_core.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index fe7775bb3740..df4045203a07 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -30,7 +30,9 @@ static int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) for_each_set_bit(i, indio_dev->active_scan_mask, num_data_channels) { const struct iio_chan_spec *channel = &indio_dev->channels[i]; - unsigned int bytes_to_read = channel->scan_type.realbits >> 3; + unsigned int bytes_to_read = + DIV_ROUND_UP(channel->scan_type.realbits + + channel->scan_type.shift, 8); unsigned int storage_bytes = channel->scan_type.storagebits >> 3; diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 975a1f19f747..d5cf7f31eaf9 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -483,8 +483,10 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev, int err; u8 *outdata; struct st_sensor_data *sdata = iio_priv(indio_dev); - unsigned int byte_for_channel = ch->scan_type.realbits >> 3; + unsigned int byte_for_channel; + byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits + + ch->scan_type.shift, 8); outdata = kmalloc(byte_for_channel, GFP_KERNEL); if (!outdata) return -ENOMEM; From 65e4345c8ef8811bbb4860fe5f2df10646b7f2e1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 30 Dec 2016 23:54:18 +0100 Subject: [PATCH 149/359] iio: accel: st_accel: fix LIS3LV02 reading and scaling The LIS3LV02 has a special bit that need to be set to get the read values left aligned. Before this patch we get gibberish like this: iio_generic_buffer -a -c10 -n lis3lv02dl_accel (...) 0.000000 -0.010042 -0.642688 19155832931907 0.000000 -0.010042 -0.642688 19155858751073 Which is because we read a raw value for 1g as 64 which is the nominal 1024 for 1g shifted 4 bits to the left by being right-aligned rather than left aligned. Since all other sensors are left aligned, add some code to set the special DAS (data alignment setting) bit to 1 so that the right value is now read like this: iio_generic_buffer -a -c10 -n lis3lv02dl_accel (...) 0.000000 -0.147095 -10.120135 24761614364956 -0.029419 -0.176514 -10.120135 24761631624540 The scaling was weird as well: we have a gain of 1000 for 1g and 3000 for 6g. I don't even remember how I came up with the old values but they are wrong. Fixes: 3acddf74f807 ("iio: st-sensors: add support for lis3lv02d accelerometer") Cc: Lorenzo Bianconi Cc: Giuseppe Barba Cc: Denis Ciocca Signed-off-by: Linus Walleij Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_core.c | 12 ++++++++++-- drivers/iio/common/st_sensors/st_sensors_core.c | 9 +++++++++ include/linux/iio/common/st_sensors.h | 12 ++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index f6b6d42385e1..784670e2736b 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -353,12 +353,12 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { [0] = { .num = ST_ACCEL_FS_AVL_2G, .value = 0x00, - .gain = IIO_G_TO_M_S_2(1024), + .gain = IIO_G_TO_M_S_2(1000), }, [1] = { .num = ST_ACCEL_FS_AVL_6G, .value = 0x01, - .gain = IIO_G_TO_M_S_2(340), + .gain = IIO_G_TO_M_S_2(3000), }, }, }, @@ -366,6 +366,14 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .addr = 0x21, .mask = 0x40, }, + /* + * Data Alignment Setting - needs to be set to get + * left-justified data like all other sensors. + */ + .das = { + .addr = 0x21, + .mask = 0x01, + }, .drdy_irq = { .addr = 0x21, .mask_int1 = 0x04, diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index d5cf7f31eaf9..79c8c7cd70d5 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -401,6 +401,15 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, return err; } + /* set DAS */ + if (sdata->sensor_settings->das.addr) { + err = st_sensors_write_data_with_mask(indio_dev, + sdata->sensor_settings->das.addr, + sdata->sensor_settings->das.mask, 1); + if (err < 0) + return err; + } + if (sdata->int_pin_open_drain) { dev_info(&indio_dev->dev, "set interrupt line to open drain mode\n"); diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 228bd44efa4c..497f2b3a5a62 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -115,6 +115,16 @@ struct st_sensor_bdu { u8 mask; }; +/** + * struct st_sensor_das - ST sensor device data alignment selection + * @addr: address of the register. + * @mask: mask to write the das flag for left alignment. + */ +struct st_sensor_das { + u8 addr; + u8 mask; +}; + /** * struct st_sensor_data_ready_irq - ST sensor device data-ready interrupt * @addr: address of the register. @@ -185,6 +195,7 @@ struct st_sensor_transfer_function { * @enable_axis: Enable one or more axis of the sensor. * @fs: Full scale register and full scale list available. * @bdu: Block data update register. + * @das: Data Alignment Selection register. * @drdy_irq: Data ready register of the sensor. * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read. * @bootime: samples to discard when sensor passing from power-down to power-up. @@ -200,6 +211,7 @@ struct st_sensor_settings { struct st_sensor_axis enable_axis; struct st_sensor_fullscale fs; struct st_sensor_bdu bdu; + struct st_sensor_das das; struct st_sensor_data_ready_irq drdy_irq; bool multi_read_bit; unsigned int bootime; From aa439248ab71bcd2d26a01708dead4dd56616499 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 30 Dec 2016 15:56:14 +0100 Subject: [PATCH 150/359] cpufreq: intel_pstate: Use locking in intel_pstate_resume() Theoretically, intel_pstate_resume() may be executed in parallel with intel_pstate_set_policy(), if the latter is invoked via cpufreq_update_policy() as a result of a notification, so use intel_pstate_limits_lock in there too to avoid race conditions. Signed-off-by: Rafael J. Wysocki Acked-by: Srinivas Pandruvada --- drivers/cpufreq/intel_pstate.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 0d01cb2dc6d2..dc457abb7dab 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -914,12 +914,20 @@ static int intel_pstate_hwp_save_state(struct cpufreq_policy *policy) static int intel_pstate_resume(struct cpufreq_policy *policy) { + int ret; + if (!hwp_active) return 0; + mutex_lock(&intel_pstate_limits_lock); + all_cpu_data[policy->cpu]->epp_policy = 0; - return intel_pstate_hwp_set_policy(policy); + ret = intel_pstate_hwp_set_policy(policy); + + mutex_unlock(&intel_pstate_limits_lock); + + return ret; } static void intel_pstate_hwp_set_online_cpus(void) From cad30467963267509d5b0d7d3c9bd1af3b91e720 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 30 Dec 2016 15:57:11 +0100 Subject: [PATCH 151/359] cpufreq: intel_pstate: Use locking in intel_cpufreq_verify_policy() Race conditions are possible if intel_cpufreq_verify_policy() is executed in parallel with global limits updates from sysfs, so the invocation of intel_pstate_update_perf_limits() in it should be carried out under intel_pstate_limits_lock. Make that happen. Signed-off-by: Rafael J. Wysocki Acked-by: Srinivas Pandruvada --- drivers/cpufreq/intel_pstate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index dc457abb7dab..f8e514d7fbc4 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -2103,8 +2103,12 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy) if (per_cpu_limits) perf_limits = cpu->perf_limits; + mutex_lock(&intel_pstate_limits_lock); + intel_pstate_update_perf_limits(policy, perf_limits); + mutex_unlock(&intel_pstate_limits_lock); + return 0; } From 111b8b3fe4fae35d4a85e9f524b077f5c4951e65 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 30 Dec 2016 15:58:21 +0100 Subject: [PATCH 152/359] cpufreq: intel_pstate: Always keep all limits settings in sync Make intel_pstate update per-logical-CPU limits when the global settings are changed to ensure that they are always in sync and users will not see confusing values in per-logical-CPU sysfs attributes. This also fixes the problem that setting the "no_turbo" global attribute to 1 in the "passive" mode (ie. when intel_pstate acts as a regular cpufreq driver) when scaling_governor is set to "performance" has no effect. Signed-off-by: Rafael J. Wysocki Acked-by: Srinivas Pandruvada --- drivers/cpufreq/intel_pstate.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index f8e514d7fbc4..e261438cd690 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -803,13 +803,13 @@ static struct freq_attr *hwp_cpufreq_attrs[] = { NULL, }; -static void intel_pstate_hwp_set(const struct cpumask *cpumask) +static void intel_pstate_hwp_set(struct cpufreq_policy *policy) { int min, hw_min, max, hw_max, cpu, range, adj_range; struct perf_limits *perf_limits = limits; u64 value, cap; - for_each_cpu(cpu, cpumask) { + for_each_cpu(cpu, policy->cpus) { int max_perf_pct, min_perf_pct; struct cpudata *cpu_data = all_cpu_data[cpu]; s16 epp; @@ -895,7 +895,7 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask) static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy) { if (hwp_active) - intel_pstate_hwp_set(policy->cpus); + intel_pstate_hwp_set(policy); return 0; } @@ -930,11 +930,12 @@ static int intel_pstate_resume(struct cpufreq_policy *policy) return ret; } -static void intel_pstate_hwp_set_online_cpus(void) +static void intel_pstate_update_policies(void) { - get_online_cpus(); - intel_pstate_hwp_set(cpu_online_mask); - put_online_cpus(); + int cpu; + + for_each_possible_cpu(cpu) + cpufreq_update_policy(cpu); } /************************** debugfs begin ************************/ @@ -1055,11 +1056,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, limits->no_turbo = clamp_t(int, input, 0, 1); - if (hwp_active) - intel_pstate_hwp_set_online_cpus(); - mutex_unlock(&intel_pstate_limits_lock); + intel_pstate_update_policies(); + return count; } @@ -1084,11 +1084,10 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, limits->max_perf_pct); limits->max_perf = div_ext_fp(limits->max_perf_pct, 100); - if (hwp_active) - intel_pstate_hwp_set_online_cpus(); - mutex_unlock(&intel_pstate_limits_lock); + intel_pstate_update_policies(); + return count; } @@ -1113,11 +1112,10 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, limits->min_perf_pct); limits->min_perf = div_ext_fp(limits->min_perf_pct, 100); - if (hwp_active) - intel_pstate_hwp_set_online_cpus(); - mutex_unlock(&intel_pstate_limits_lock); + intel_pstate_update_policies(); + return count; } From ab51e6ba0059f92036a08e41ba5cc70e77ce02df Mon Sep 17 00:00:00 2001 From: Augusto Mecking Caringi Date: Fri, 30 Dec 2016 11:34:08 +0000 Subject: [PATCH 153/359] PM / domains: Fix 'may be used uninitialized' build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the following gcc warning: drivers/base/power/domain.c: In function ‘genpd_runtime_resume’: drivers/base/power/domain.c:642:14: warning: ‘time_start’ may be used uninitialized in this function [-Wmaybe-uninitialized] elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start) The same problem (in another function in this same file) was fixed in commit d33d5a6c88fc (avoid spurious "may be used uninitialized" warning) Signed-off-by: Augusto Mecking Caringi Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index a5e1262b964b..2997026b4dfb 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -626,6 +626,7 @@ static int genpd_runtime_resume(struct device *dev) out: /* Measure resume latency. */ + time_start = 0; if (timed && runtime_pm) time_start = ktime_get(); From e1a3a60a2ebe991605acb14cd58e39c0545e174e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 30 Dec 2016 17:42:32 -0600 Subject: [PATCH 154/359] net: socket: don't set sk_uid to garbage value in ->setattr() ->setattr() was recently implemented for socket files to sync the socket inode's uid to the new 'sk_uid' member of struct sock. It does this by copying over the ia_uid member of struct iattr. However, ia_uid is actually only valid when ATTR_UID is set in ia_valid, indicating that the uid is being changed, e.g. by chown. Other metadata operations such as chmod or utimes leave ia_uid uninitialized. Therefore, sk_uid could be set to a "garbage" value from the stack. Fix this by only copying the uid over when ATTR_UID is set. Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.") Signed-off-by: Eric Biggers Tested-by: Lorenzo Colitti Acked-by: Lorenzo Colitti Signed-off-by: David S. Miller --- net/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/socket.c b/net/socket.c index 8487bf136e5c..a8c2307590b8 100644 --- a/net/socket.c +++ b/net/socket.c @@ -537,7 +537,7 @@ int sockfs_setattr(struct dentry *dentry, struct iattr *iattr) { int err = simple_setattr(dentry, iattr); - if (!err) { + if (!err && (iattr->ia_valid & ATTR_UID)) { struct socket *sock = SOCKET_I(d_inode(dentry)); sock->sk->sk_uid = iattr->ia_uid; From 086cc1c31a0ec075dac02425367c871bb65bc2c9 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Wed, 14 Dec 2016 21:27:57 +0900 Subject: [PATCH 155/359] openrisc: Add _text symbol to fix ksym build error The build robot reports: .tmp_kallsyms1.o: In function `kallsyms_relative_base': >> (.rodata+0x8a18): undefined reference to `_text' This is when using 'make alldefconfig'. Adding this _text symbol to mark the start of the kernel as in other architecture fixes this. Signed-off-by: Stafford Horne Acked-by: Jonas Bonn --- arch/openrisc/kernel/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/openrisc/kernel/vmlinux.lds.S b/arch/openrisc/kernel/vmlinux.lds.S index ef31fc24344e..552544616b9d 100644 --- a/arch/openrisc/kernel/vmlinux.lds.S +++ b/arch/openrisc/kernel/vmlinux.lds.S @@ -44,6 +44,8 @@ SECTIONS /* Read-only sections, merged into text segment: */ . = LOAD_BASE ; + _text = .; + /* _s_kernel_ro must be page aligned */ . = ALIGN(PAGE_SIZE); _s_kernel_ro = .; From 4200462d88f47f3759bdf4705f87e207b0f5b2e4 Mon Sep 17 00:00:00 2001 From: Reiter Wolfgang Date: Sat, 31 Dec 2016 21:11:57 +0100 Subject: [PATCH 156/359] drop_monitor: add missing call to genlmsg_end Update nlmsg_len field with genlmsg_end to enable userspace processing using nlmsg_next helper. Also adds error handling. Signed-off-by: Reiter Wolfgang Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/core/drop_monitor.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 8e0c0635ee97..f465bad2ef2c 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -75,6 +75,7 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) struct nlattr *nla; struct sk_buff *skb; unsigned long flags; + void *msg_header; al = sizeof(struct net_dm_alert_msg); al += dm_hit_limit * sizeof(struct net_dm_drop_point); @@ -82,17 +83,31 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) skb = genlmsg_new(al, GFP_KERNEL); - if (skb) { - genlmsg_put(skb, 0, 0, &net_drop_monitor_family, - 0, NET_DM_CMD_ALERT); - nla = nla_reserve(skb, NLA_UNSPEC, - sizeof(struct net_dm_alert_msg)); - msg = nla_data(nla); - memset(msg, 0, al); - } else { - mod_timer(&data->send_timer, jiffies + HZ / 10); - } + if (!skb) + goto err; + msg_header = genlmsg_put(skb, 0, 0, &net_drop_monitor_family, + 0, NET_DM_CMD_ALERT); + if (!msg_header) { + nlmsg_free(skb); + skb = NULL; + goto err; + } + nla = nla_reserve(skb, NLA_UNSPEC, + sizeof(struct net_dm_alert_msg)); + if (!nla) { + nlmsg_free(skb); + skb = NULL; + goto err; + } + msg = nla_data(nla); + memset(msg, 0, al); + genlmsg_end(skb, msg_header); + goto out; + +err: + mod_timer(&data->send_timer, jiffies + HZ / 10); +out: spin_lock_irqsave(&data->lock, flags); swap(data->skb, skb); spin_unlock_irqrestore(&data->lock, flags); From 97b84fd6d91766ea57dcc350d78f42639e011c30 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 30 Dec 2016 19:48:19 +0100 Subject: [PATCH 157/359] l2tp: consider '::' as wildcard address in l2tp_ip6 socket lookup An L2TP socket bound to the unspecified address should match with any address. If not, it can't receive any packet and __l2tp_ip6_bind_lookup() can't prevent another socket from binding on the same device/tunnel ID. While there, rename the 'addr' variable to 'sk_laddr' (local addr), to make following patch clearer. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller --- net/l2tp/l2tp_ip6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index f092ac441fdd..3135b9d55df5 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -64,7 +64,7 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net, struct sock *sk; sk_for_each_bound(sk, &l2tp_ip6_bind_table) { - const struct in6_addr *addr = inet6_rcv_saddr(sk); + const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk); struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk); if (l2tp == NULL) @@ -72,7 +72,7 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net, if ((l2tp->conn_id == tunnel_id) && net_eq(sock_net(sk), net) && - (!addr || ipv6_addr_equal(addr, laddr)) && + (!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) && (!sk->sk_bound_dev_if || !dif || sk->sk_bound_dev_if == dif)) goto found; From a9b2dff80be979432484afaf7f8d8e73f9e8838a Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 30 Dec 2016 19:48:20 +0100 Subject: [PATCH 158/359] l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups For connected sockets, __l2tp_ip{,6}_bind_lookup() needs to check the remote IP when looking for a matching socket. Otherwise a connected socket can receive traffic not originating from its peer. Drop l2tp_ip_bind_lookup() and l2tp_ip6_bind_lookup() instead of updating their prototype, as these functions aren't used. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller --- net/l2tp/l2tp_ip.c | 19 ++++++------------- net/l2tp/l2tp_ip6.c | 20 ++++++-------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 8938b6ba57a0..3d73278b86ca 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -47,7 +47,8 @@ static inline struct l2tp_ip_sock *l2tp_ip_sk(const struct sock *sk) return (struct l2tp_ip_sock *)sk; } -static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id) +static struct sock *__l2tp_ip_bind_lookup(const struct net *net, __be32 laddr, + __be32 raddr, int dif, u32 tunnel_id) { struct sock *sk; @@ -61,6 +62,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif if ((l2tp->conn_id == tunnel_id) && net_eq(sock_net(sk), net) && !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && + (!inet->inet_daddr || !raddr || inet->inet_daddr == raddr) && (!sk->sk_bound_dev_if || !dif || sk->sk_bound_dev_if == dif)) goto found; @@ -71,15 +73,6 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif return sk; } -static inline struct sock *l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id) -{ - struct sock *sk = __l2tp_ip_bind_lookup(net, laddr, dif, tunnel_id); - if (sk) - sock_hold(sk); - - return sk; -} - /* When processing receive frames, there are two cases to * consider. Data frames consist of a non-zero session-id and an * optional cookie. Control frames consist of a regular L2TP header @@ -183,8 +176,8 @@ static int l2tp_ip_recv(struct sk_buff *skb) struct iphdr *iph = (struct iphdr *) skb_network_header(skb); read_lock_bh(&l2tp_ip_lock); - sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb), - tunnel_id); + sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr, + inet_iif(skb), tunnel_id); if (!sk) { read_unlock_bh(&l2tp_ip_lock); goto discard; @@ -280,7 +273,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) inet->inet_saddr = 0; /* Use device */ write_lock_bh(&l2tp_ip_lock); - if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr, + if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr, 0, sk->sk_bound_dev_if, addr->l2tp_conn_id)) { write_unlock_bh(&l2tp_ip_lock); ret = -EADDRINUSE; diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 3135b9d55df5..331ccf5a7bad 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -59,12 +59,14 @@ static inline struct l2tp_ip6_sock *l2tp_ip6_sk(const struct sock *sk) static struct sock *__l2tp_ip6_bind_lookup(struct net *net, struct in6_addr *laddr, + const struct in6_addr *raddr, int dif, u32 tunnel_id) { struct sock *sk; sk_for_each_bound(sk, &l2tp_ip6_bind_table) { const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk); + const struct in6_addr *sk_raddr = &sk->sk_v6_daddr; struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk); if (l2tp == NULL) @@ -73,6 +75,7 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net, if ((l2tp->conn_id == tunnel_id) && net_eq(sock_net(sk), net) && (!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) && + (!raddr || ipv6_addr_any(sk_raddr) || ipv6_addr_equal(sk_raddr, raddr)) && (!sk->sk_bound_dev_if || !dif || sk->sk_bound_dev_if == dif)) goto found; @@ -83,17 +86,6 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net, return sk; } -static inline struct sock *l2tp_ip6_bind_lookup(struct net *net, - struct in6_addr *laddr, - int dif, u32 tunnel_id) -{ - struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id); - if (sk) - sock_hold(sk); - - return sk; -} - /* When processing receive frames, there are two cases to * consider. Data frames consist of a non-zero session-id and an * optional cookie. Control frames consist of a regular L2TP header @@ -197,8 +189,8 @@ static int l2tp_ip6_recv(struct sk_buff *skb) struct ipv6hdr *iph = ipv6_hdr(skb); read_lock_bh(&l2tp_ip6_lock); - sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb), - tunnel_id); + sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr, + inet6_iif(skb), tunnel_id); if (!sk) { read_unlock_bh(&l2tp_ip6_lock); goto discard; @@ -330,7 +322,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) rcu_read_unlock(); write_lock_bh(&l2tp_ip6_lock); - if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if, + if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, NULL, bound_dev_if, addr->l2tp_conn_id)) { write_unlock_bh(&l2tp_ip6_lock); err = -EADDRINUSE; From af92305e567b7f4c9cf48b9e46c1f48ec9ffb1fb Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 17 Nov 2016 03:30:51 +0200 Subject: [PATCH 159/359] ARM: dts: imx31: fix AVIC base address On i.MX31 AVIC interrupt controller base address is at 0x68000000. The problem was shadowed by the AVIC driver, which takes the correct base address from a SoC specific header file. Fixes: d2a37b3d91f4 ("ARM i.MX31: Add devicetree support") Signed-off-by: Vladimir Zapolskiy Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx31.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi index 685916e3d8a1..85cd8be22f71 100644 --- a/arch/arm/boot/dts/imx31.dtsi +++ b/arch/arm/boot/dts/imx31.dtsi @@ -31,11 +31,11 @@ cpu { }; }; - avic: avic-interrupt-controller@60000000 { + avic: interrupt-controller@68000000 { compatible = "fsl,imx31-avic", "fsl,avic"; interrupt-controller; #interrupt-cells = <1>; - reg = <0x60000000 0x100000>; + reg = <0x68000000 0x100000>; }; soc { From db9e188674ec53fe7bf7d9322ffb0256974c8ec7 Mon Sep 17 00:00:00 2001 From: Gary Bisson Date: Fri, 25 Nov 2016 00:42:47 +0100 Subject: [PATCH 160/359] ARM: dts: imx6qdl-nitrogen6x: remove duplicate iomux entry The NANDF_CS2 pad is also part of the wlan-vmmcgrp iomux group. Removing is from the usdhc2grp group avoids the following error: imx6q-pinctrl 20e0000.iomuxc: pin MX6Q_PAD_NANDF_CS2 already requested by regulators:regulator@4; cannot claim for 2194000.usdhc imx6q-pinctrl 20e0000.iomuxc: pin-187 (2194000.usdhc) status -22 imx6q-pinctrl 20e0000.iomuxc: could not request pin 187 (MX6Q_PAD_NANDF_CS2) from group usdhc2grp on device 20e0000.iomuxc Signed-off-by: Gary Bisson Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi index e476d01959ea..26d060484728 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi @@ -533,7 +533,6 @@ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17071 MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071 MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071 MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071 - MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0 >; }; From 4c51de4570d6881e2a4a7f56d55385336de0bd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 27 Nov 2016 20:54:44 +0100 Subject: [PATCH 161/359] ARM: dts: vf610-zii-dev-rev-b: Add missing newline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while reviewing Marvell dsa bindings usage. Fixes: f283745b3caf ("arm: vf610: zii devel b: Add support for switch interrupts") Cc: Andrew Lunn Cc: David S. Miller Signed-off-by: Andreas Färber Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts index 7ea617e47fe4..958b4c42d320 100644 --- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts +++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts @@ -153,7 +153,8 @@ switch0phy0: switch0phy0@0 { switch0phy1: switch1phy0@1 { reg = <1>; interrupt-parent = <&switch0>; - interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; }; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + }; switch0phy2: switch1phy0@2 { reg = <2>; interrupt-parent = <&switch0>; From d7da1ccfa2c26d54230ee6aae28902dd10b325a7 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Fri, 2 Dec 2016 15:05:38 +0000 Subject: [PATCH 162/359] ARM: i.MX: remove map_io callback There is no need to define map_io only for debug_ll_io_init() since it is already called in devicemaps_init() if map_io is NULL. Apart from that, for NOMMU build debug_ll_io_init() is a nop which leads to following error: CC arch/arm/mach-imx/mach-imx1.o arch/arm/mach-imx/mach-imx1.c:40:13: error: 'debug_ll_io_init' undeclared here (not in a function) .map_io = debug_ll_io_init, ^ make[1]: *** [arch/arm/mach-imx/mach-imx1.o] Error 1 Cc: Alexander Shiyan Cc: Sascha Hauer Cc: Fabio Estevam Signed-off-by: Vladimir Murzin Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx1.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/mach-imx1.c b/arch/arm/mach-imx/mach-imx1.c index de5ab8d88549..3a8406e45b65 100644 --- a/arch/arm/mach-imx/mach-imx1.c +++ b/arch/arm/mach-imx/mach-imx1.c @@ -37,7 +37,6 @@ static const char * const imx1_dt_board_compat[] __initconst = { }; DT_MACHINE_START(IMX1_DT, "Freescale i.MX1 (Device Tree Support)") - .map_io = debug_ll_io_init, .init_early = imx1_init_early, .init_irq = imx1_init_irq, .dt_compat = imx1_dt_board_compat, From 4541d31e2ab547fa0eea8ce22d3593d0f4cce1fd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 2 Jan 2017 09:17:26 +0100 Subject: [PATCH 163/359] drm/bridge: Use recommened kerneldoc for struct member refs I just learned that &struct_name.member_name works and looks pretty even. It doesn't (yet) link to the member directly though, which would be really good for big structures or vfunc tables (where the per-member kerneldoc tends to be long). Also some minor drive-by polish where it makes sense, I read a lot of docs ... Cc: Archit Taneja Cc: Jani Nikula Cc: Chris Wilson Reviewed-by: Archit Taneja [danvet: Remove spurious hunk that Archit spotted.] Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483044517-5770-13-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_bridge.c | 27 +++++++++++------------ include/drm/drm_bridge.h | 42 ++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index ae5e57ad718c..86a7637ba344 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -55,7 +55,7 @@ * just provide additional hooks to get the desired output at the end of the * encoder chain. * - * Bridges can also be chained up using the next pointer in &struct drm_bridge. + * Bridges can also be chained up using the &drm_bridge.next pointer. * * Both legacy CRTC helpers and the new atomic modeset helpers support bridges. */ @@ -179,7 +179,7 @@ void drm_bridge_detach(struct drm_bridge *bridge) * @mode: desired mode to be set for the bridge * @adjusted_mode: updated mode that works for this bridge * - * Calls ->mode_fixup() &drm_bridge_funcs op for all the bridges in the + * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the * encoder chain, starting from the first bridge to the last. * * Note: the bridge passed should be the one closest to the encoder @@ -206,11 +206,10 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge, EXPORT_SYMBOL(drm_bridge_mode_fixup); /** - * drm_bridge_disable - calls ->disable() &drm_bridge_funcs op for all - * bridges in the encoder chain. + * drm_bridge_disable - disables all bridges in the encoder chain * @bridge: bridge control structure * - * Calls ->disable() &drm_bridge_funcs op for all the bridges in the encoder + * Calls &drm_bridge_funcs.disable op for all the bridges in the encoder * chain, starting from the last bridge to the first. These are called before * calling the encoder's prepare op. * @@ -229,11 +228,10 @@ void drm_bridge_disable(struct drm_bridge *bridge) EXPORT_SYMBOL(drm_bridge_disable); /** - * drm_bridge_post_disable - calls ->post_disable() &drm_bridge_funcs op for - * all bridges in the encoder chain. + * drm_bridge_post_disable - cleans up after disabling all bridges in the encoder chain * @bridge: bridge control structure * - * Calls ->post_disable() &drm_bridge_funcs op for all the bridges in the + * Calls &drm_bridge_funcs.post_disable op for all the bridges in the * encoder chain, starting from the first bridge to the last. These are called * after completing the encoder's prepare op. * @@ -258,7 +256,7 @@ EXPORT_SYMBOL(drm_bridge_post_disable); * @mode: desired mode to be set for the bridge * @adjusted_mode: updated mode that works for this bridge * - * Calls ->mode_set() &drm_bridge_funcs op for all the bridges in the + * Calls &drm_bridge_funcs.mode_set op for all the bridges in the * encoder chain, starting from the first bridge to the last. * * Note: the bridge passed should be the one closest to the encoder @@ -278,11 +276,11 @@ void drm_bridge_mode_set(struct drm_bridge *bridge, EXPORT_SYMBOL(drm_bridge_mode_set); /** - * drm_bridge_pre_enable - calls ->pre_enable() &drm_bridge_funcs op for all - * bridges in the encoder chain. + * drm_bridge_pre_enable - prepares for enabling all + * bridges in the encoder chain * @bridge: bridge control structure * - * Calls ->pre_enable() &drm_bridge_funcs op for all the bridges in the encoder + * Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder * chain, starting from the last bridge to the first. These are called * before calling the encoder's commit op. * @@ -301,11 +299,10 @@ void drm_bridge_pre_enable(struct drm_bridge *bridge) EXPORT_SYMBOL(drm_bridge_pre_enable); /** - * drm_bridge_enable - calls ->enable() &drm_bridge_funcs op for all bridges - * in the encoder chain. + * drm_bridge_enable - enables all bridges in the encoder chain * @bridge: bridge control structure * - * Calls ->enable() &drm_bridge_funcs op for all the bridges in the encoder + * Calls &drm_bridge_funcs.enable op for all the bridges in the encoder * chain, starting from the first bridge to the last. These are called * after completing the encoder's commit op. * diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index d3ca16f4da8f..fdd82fcbf168 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -96,9 +96,10 @@ struct drm_bridge_funcs { * This callback should disable the bridge. It is called right before * the preceding element in the display pipe is disabled. If the * preceding element is a bridge this means it's called before that - * bridge's ->disable() function. If the preceding element is a - * &drm_encoder it's called right before the encoder's ->disable(), - * ->prepare() or ->dpms() hook from &struct drm_encoder_helper_funcs. + * bridge's @disable vfunc. If the preceding element is a &drm_encoder + * it's called right before the &drm_encoder_helper_funcs.disable, + * &drm_encoder_helper_funcs.prepare or &drm_encoder_helper_funcs.dpms + * hook. * * The bridge can assume that the display pipe (i.e. clocks and timing * signals) feeding it is still running when this callback is called. @@ -110,12 +111,13 @@ struct drm_bridge_funcs { /** * @post_disable: * - * This callback should disable the bridge. It is called right after - * the preceding element in the display pipe is disabled. If the - * preceding element is a bridge this means it's called after that - * bridge's ->post_disable() function. If the preceding element is a - * &drm_encoder it's called right after the encoder's ->disable(), - * ->prepare() or ->dpms() hook from &struct drm_encoder_helper_funcs. + * This callback should disable the bridge. It is called right after the + * preceding element in the display pipe is disabled. If the preceding + * element is a bridge this means it's called after that bridge's + * @post_disable function. If the preceding element is a &drm_encoder + * it's called right after the encoder's + * &drm_encoder_helper_funcs.disable, &drm_encoder_helper_funcs.prepare + * or &drm_encoder_helper_funcs.dpms hook. * * The bridge must assume that the display pipe (i.e. clocks and timing * singals) feeding it is no longer running when this callback is @@ -129,9 +131,11 @@ struct drm_bridge_funcs { * @mode_set: * * This callback should set the given mode on the bridge. It is called - * after the ->mode_set() callback for the preceding element in the - * display pipeline has been called already. The display pipe (i.e. - * clocks and timing signals) is off when this function is called. + * after the @mode_set callback for the preceding element in the display + * pipeline has been called already. If the bridge is the first element + * then this would be &drm_encoder_helper_funcs.mode_set. The display + * pipe (i.e. clocks and timing signals) is off when this function is + * called. */ void (*mode_set)(struct drm_bridge *bridge, struct drm_display_mode *mode, @@ -142,9 +146,10 @@ struct drm_bridge_funcs { * This callback should enable the bridge. It is called right before * the preceding element in the display pipe is enabled. If the * preceding element is a bridge this means it's called before that - * bridge's ->pre_enable() function. If the preceding element is a - * &drm_encoder it's called right before the encoder's ->enable(), - * ->commit() or ->dpms() hook from &struct drm_encoder_helper_funcs. + * bridge's @pre_enable function. If the preceding element is a + * &drm_encoder it's called right before the encoder's + * &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or + * &drm_encoder_helper_funcs.dpms hook. * * The display pipe (i.e. clocks and timing signals) feeding this bridge * will not yet be running when this callback is called. The bridge must @@ -161,9 +166,10 @@ struct drm_bridge_funcs { * This callback should enable the bridge. It is called right after * the preceding element in the display pipe is enabled. If the * preceding element is a bridge this means it's called after that - * bridge's ->enable() function. If the preceding element is a - * &drm_encoder it's called right after the encoder's ->enable(), - * ->commit() or ->dpms() hook from &struct drm_encoder_helper_funcs. + * bridge's @enable function. If the preceding element is a + * &drm_encoder it's called right after the encoder's + * &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or + * &drm_encoder_helper_funcs.dpms hook. * * The bridge can assume that the display pipe (i.e. clocks and timing * signals) feeding it is running when this callback is called. This From f3419735279564d40467ebe4147d8a41cef00685 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 20 Nov 2016 21:26:02 +0000 Subject: [PATCH 164/359] usb: dwc2: Do not set host parameter in peripheral mode Since commit "usb: dwc2: Improve handling of host and device hwparams" the host mode specific hardware parameter aren't initialized in peripheral mode from the register settings anymore. So we better do not set them in this case which avoids the following warnings on bcm2835: 256 invalid for host_nperio_tx_fifo_size. Check HW configuration. 512 invalid for host_perio_tx_fifo_size. Check HW configuration. Fixes: 55e1040e424b ("usb: dwc2: Improve handling of host and device hwparams") Acked-by: John Youn Signed-off-by: Stefan Wahren Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/params.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index a786256535b6..fd5f7f83843d 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -1132,6 +1132,12 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg, false, "host-dma", true, false, dma_capable); + dwc2_set_param_host_rx_fifo_size(hsotg, + params->host_rx_fifo_size); + dwc2_set_param_host_nperio_tx_fifo_size(hsotg, + params->host_nperio_tx_fifo_size); + dwc2_set_param_host_perio_tx_fifo_size(hsotg, + params->host_perio_tx_fifo_size); } dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable); dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable); @@ -1140,12 +1146,6 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg, params->host_support_fs_ls_low_power); dwc2_set_param_enable_dynamic_fifo(hsotg, params->enable_dynamic_fifo); - dwc2_set_param_host_rx_fifo_size(hsotg, - params->host_rx_fifo_size); - dwc2_set_param_host_nperio_tx_fifo_size(hsotg, - params->host_nperio_tx_fifo_size); - dwc2_set_param_host_perio_tx_fifo_size(hsotg, - params->host_perio_tx_fifo_size); dwc2_set_param_max_transfer_size(hsotg, params->max_transfer_size); dwc2_set_param_max_packet_count(hsotg, From de02238d6a7982a71682fe8da2996993a5a5eee7 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 20 Nov 2016 21:26:03 +0000 Subject: [PATCH 165/359] usb: dwc2: fix dwc2_get_device_property for u8 and u16 According to the Devicetree ePAPR [1] the datatypes u8 and u16 are not defined. So using device_property_read_u16() would result in a partial read of a 32-bit big-endian integer which is not intended. So we better read the complete 32-bit value. This fixes a regression on bcm2835 where the values for g-rx-fifo-size and g-np-tx-fifo-size always read as zero: Invalid value 0 for param g-rx-fifo-size Invalid value 0 for param g-np-tx-fifo-size [1] - http://elinux.org/images/c/cf/Power_ePAPR_APPROVED_v1.1.pdf Fixes: 05ee799f202 ("usb: dwc2: Move gadget settings into core_params") Acked-by: John Youn Signed-off-by: Stefan Wahren Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/params.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index fd5f7f83843d..2c7b6243734c 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -247,8 +247,6 @@ MODULE_DEVICE_TABLE(of, dwc2_of_match_table); static void dwc2_get_device_property(struct dwc2_hsotg *hsotg, char *property, u8 size, u64 *value) { - u8 val8; - u16 val16; u32 val32; switch (size) { @@ -256,17 +254,7 @@ static void dwc2_get_device_property(struct dwc2_hsotg *hsotg, *value = device_property_read_bool(hsotg->dev, property); break; case 1: - if (device_property_read_u8(hsotg->dev, property, &val8)) - return; - - *value = val8; - break; case 2: - if (device_property_read_u16(hsotg->dev, property, &val16)) - return; - - *value = val16; - break; case 4: if (device_property_read_u32(hsotg->dev, property, &val32)) return; From 6118d0647b10eaca06b278dee2022602d8f2f07a Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 20 Nov 2016 21:26:04 +0000 Subject: [PATCH 166/359] usb: dwc2: fix default value for DMA support The current defaults for DMA results on a non-DMA platform in a unnecessary error message: Invalid value 0 for param gadget-dma So fix this by using dma_capable as default value. Fixes: 9962b62f1be ("usb: dwc2: Deprecate g-use-dma binding") Acked-by: John Youn Signed-off-by: Stefan Wahren Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 2c7b6243734c..30b954e148ed 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -1088,7 +1088,7 @@ static void dwc2_set_gadget_dma(struct dwc2_hsotg *hsotg) /* Buffer DMA */ dwc2_set_param_bool(hsotg, &p->g_dma, false, "gadget-dma", - true, false, + dma_capable, false, dma_capable); /* DMA Descriptor */ @@ -1118,7 +1118,7 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg, dwc2_set_param_bool(hsotg, &p->host_dma, false, "host-dma", - true, false, + dma_capable, false, dma_capable); dwc2_set_param_host_rx_fifo_size(hsotg, params->host_rx_fifo_size); From efc95b2ca42424de222119a3a260624f3a050f8e Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 20 Nov 2016 21:26:05 +0000 Subject: [PATCH 167/359] usb: dwc2: gadget: fix default value for gadget-dma-desc The current default for gadget DMA descriptor results on bcm2835 in a unnecessary error message: Invalid value 1 for param gadget-dma-desc So fix this by using hw->dma_desc_enable as default value. Fixes: dec4b55677e ("usb: dwc2: gadget: Add descriptor DMA parameter") Acked-by: John Youn Signed-off-by: Stefan Wahren Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/params.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 30b954e148ed..11fe68a4627b 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -1094,7 +1094,7 @@ static void dwc2_set_gadget_dma(struct dwc2_hsotg *hsotg) /* DMA Descriptor */ dwc2_set_param_bool(hsotg, &p->g_dma_desc, false, "gadget-dma-desc", - p->g_dma, false, + !!hw->dma_desc_enable, false, !!hw->dma_desc_enable); } From 7931ec86c1b738e4e90e58c6d95e5f720d45ee56 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 20 Dec 2016 13:57:32 +0200 Subject: [PATCH 168/359] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() For now this is just a cleanup patch, no functional changes. We will be using the new function to fix a bug introduced long ago by commit 0416e494ce7d ("usb: dwc3: ep0: correct cache sync issue in case of ep0_bounced") and further worsened by commit c0bd5456a470 ("usb: dwc3: ep0: handle non maxpacket aligned transfers > 512") Cc: Reported-by: Janusz Dziedzic Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 4878d187c7d4..06febd07ec4e 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -39,18 +39,13 @@ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep); static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, struct dwc3_ep *dep, struct dwc3_request *req); -static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type, bool chain) +static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum, + dma_addr_t buf_dma, u32 len, u32 type, bool chain) { - struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; struct dwc3_ep *dep; - int ret; - dep = dwc->eps[epnum]; - if (dep->flags & DWC3_EP_BUSY) - return 0; trb = &dwc->ep0_trb[dep->trb_enqueue]; @@ -71,15 +66,26 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb->ctrl |= (DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_LST); - if (chain) + trace_dwc3_prepare_trb(dep, trb); +} + +static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, + u32 len, u32 type, bool chain) +{ + struct dwc3_gadget_ep_cmd_params params; + struct dwc3_ep *dep; + int ret; + + dep = dwc->eps[epnum]; + if (dep->flags & DWC3_EP_BUSY) return 0; + dwc3_ep0_prepare_one_trb(dwc, epnum, buf_dma, len, type, chain); + memset(¶ms, 0, sizeof(params)); params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); - trace_dwc3_prepare_trb(dep, trb); - ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) return ret; From 19ec31230eb3084431bc2e565fd085f79f564274 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 20 Dec 2016 14:08:48 +0200 Subject: [PATCH 169/359] usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb() Let's call dwc3_ep0_prepare_one_trb() explicitly because there are occasions where we will need more than one TRB to handle an EP0 transfer. A follow-up patch will fix one bug related to multiple-TRB Data Phases when it comes to mapping/unmapping requests for DMA. Cc: Reported-by: Janusz Dziedzic Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 06febd07ec4e..9bb1f8526f3e 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -69,8 +69,7 @@ static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum, trace_dwc3_prepare_trb(dep, trb); } -static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type, bool chain) +static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_ep *dep; @@ -80,8 +79,6 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, if (dep->flags & DWC3_EP_BUSY) return 0; - dwc3_ep0_prepare_one_trb(dwc, epnum, buf_dma, len, type, chain); - memset(¶ms, 0, sizeof(params)); params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); @@ -286,8 +283,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) complete(&dwc->ep0_in_setup); - ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, + dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8, DWC3_TRBCTL_CONTROL_SETUP, false); + ret = dwc3_ep0_start_trans(dwc, 0); WARN_ON(ret < 0); } @@ -918,9 +916,9 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, dwc->ep0_next_event = DWC3_EP0_COMPLETE; - ret = dwc3_ep0_start_trans(dwc, epnum, - dwc->ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA, false); + dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ctrl_req_addr, + 0, DWC3_TRBCTL_CONTROL_DATA, false); + ret = dwc3_ep0_start_trans(dwc, epnum); WARN_ON(ret < 0); } } @@ -999,9 +997,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, req->direction = !!dep->number; if (req->request.length == 0) { - ret = dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc->ctrl_req_addr, 0, DWC3_TRBCTL_CONTROL_DATA, false); + ret = dwc3_ep0_start_trans(dwc, dep->number); } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && (dep->number == 0)) { u32 transfer_size = 0; @@ -1017,7 +1016,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, if (req->request.length > DWC3_EP0_BOUNCE_SIZE) { transfer_size = ALIGN(req->request.length - maxpacket, maxpacket); - ret = dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma, transfer_size, DWC3_TRBCTL_CONTROL_DATA, @@ -1029,18 +1028,20 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, dwc->ep0_bounced = true; - ret = dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc->ep0_bounce_addr, transfer_size, DWC3_TRBCTL_CONTROL_DATA, false); + ret = dwc3_ep0_start_trans(dwc, dep->number); } else { ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request, dep->number); if (ret) return; - ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma, + dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma, req->request.length, DWC3_TRBCTL_CONTROL_DATA, false); + ret = dwc3_ep0_start_trans(dwc, dep->number); } WARN_ON(ret < 0); @@ -1054,8 +1055,9 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 : DWC3_TRBCTL_CONTROL_STATUS2; - return dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc->ctrl_req_addr, 0, type, false); + return dwc3_ep0_start_trans(dwc, dep->number); } static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) From d62145929992f331fdde924d5963ab49588ccc7d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 20 Dec 2016 14:14:40 +0200 Subject: [PATCH 170/359] usb: dwc3: gadget: always unmap EP0 requests commit 0416e494ce7d ("usb: dwc3: ep0: correct cache sync issue in case of ep0_bounced") introduced a bug where we would leak DMA resources which would cause us to starve the system of them resulting in failing DMA transfers. Fix the bug by making sure that we always unmap EP0 requests since those are *always* mapped. Fixes: 0416e494ce7d ("usb: dwc3: ep0: correct cache sync issue in case of ep0_bounced") Cc: Tested-by: Tomasz Medrek Reported-by: Janusz Dziedzic Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index efddaf5d11d1..0286e3141864 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -180,11 +180,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, if (req->request.status == -EINPROGRESS) req->request.status = status; - if (dwc->ep0_bounced && dep->number == 0) + if (dwc->ep0_bounced && dep->number <= 1) dwc->ep0_bounced = false; - else - usb_gadget_unmap_request_by_dev(dwc->sysdev, - &req->request, req->direction); + + usb_gadget_unmap_request_by_dev(dwc->sysdev, + &req->request, req->direction); trace_dwc3_gadget_giveback(req); From e71d363d9c611c99fb78f53bfee99616e7fe352c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 23 Dec 2016 14:40:40 +0200 Subject: [PATCH 171/359] usb: dwc3: core: avoid Overflow events Now that we're handling so many transfers at a time and for some dwc3 revisions LPM events *must* be enabled, we can fall into a situation where too many events fire and we start receiving Overflow events. Let's do what XHCI does and allocate a full page for the Event Ring, this will avoid any future issues. Cc: # v4.9 Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index de5a8570be04..7bf8016e1182 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -45,9 +45,7 @@ #define DWC3_XHCI_RESOURCES_NUM 2 #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ -#define DWC3_EVENT_SIZE 4 /* bytes */ -#define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */ -#define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM) +#define DWC3_EVENT_BUFFERS_SIZE 4096 #define DWC3_EVENT_TYPE_MASK 0xfe #define DWC3_EVENT_TYPE_DEV 0 From 51c1685d956221576e165dd88a20063b169bae5a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 27 Dec 2016 13:13:42 +0200 Subject: [PATCH 172/359] usb: dwc3: pci: Fix dr_mode misspelling usb_get_dr_mode() expects the device-property to be spelled "dr_mode" not "dr-mode". Spelling it properly fixes the following warning showing up in dmesg: [ 8704.500545] dwc3 dwc3.2.auto: Configuration mismatch. dr_mode forced to gadget Signed-off-by: Hans de Goede --- drivers/usb/dwc3/dwc3-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 2b73339f286b..409d2eb848b5 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -115,7 +115,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) int ret; struct property_entry properties[] = { - PROPERTY_ENTRY_STRING("dr-mode", "peripheral"), + PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), { } }; From 7e4da3fcf7c9fe042f2f7cb7bf23861a899b4a8f Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Tue, 20 Dec 2016 19:52:16 +0100 Subject: [PATCH 173/359] usb: gadget: composite: Test get_alt() presence instead of set_alt() By convention (according to doc) if function does not provide get_alt() callback composite framework should assume that it has only altsetting 0 and should respond with error if host tries to set other one. After commit dd4dff8b035f ("USB: composite: Fix bug: should test set_alt function pointer before use it") we started checking set_alt() callback instead of get_alt(). This check is useless as we check if set_alt() is set inside usb_add_function() and fail if it's NULL. Let's fix this check and move comment about why we check the get method instead of set a little bit closer to prevent future false fixes. Fixes: dd4dff8b035f ("USB: composite: Fix bug: should test set_alt function pointer before use it") Cc: stable Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 41ab61f9b6e0..002822d98fda 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1694,9 +1694,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) value = min(w_length, (u16) 1); break; - /* function drivers must handle get/set altsetting; if there's - * no get() method, we know only altsetting zero works. - */ + /* function drivers must handle get/set altsetting */ case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) goto unknown; @@ -1705,7 +1703,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) f = cdev->config->interface[intf]; if (!f) break; - if (w_value && !f->set_alt) + + /* + * If there's no get_alt() method, we know only altsetting zero + * works. There is no need to check if set_alt() is not NULL + * as we check this in usb_add_function(). + */ + if (w_value && !f->get_alt) break; value = f->set_alt(f, w_index, w_value); if (value == USB_GADGET_DELAYED_STATUS) { From 96a420d2d37cc019d0fbb95c9f0e965fa1080e1f Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Thu, 15 Dec 2016 12:47:41 +0000 Subject: [PATCH 174/359] usb: gadget: f_fs: Document eventfd effect on descriptor format. When FUNCTIONFS_EVENTFD flag is set, __ffs_data_got_descs reads a 32bits, little-endian value right after the fixed structure header, and passes it to eventfd_ctx_fdget. Document this. Also, rephrase a comment to be affirmative about the role of string descriptor at index 0. Ref: USB 2.0 spec paragraph "9.6.7 String", and also checked to still be current in USB 3.0 spec paragraph "9.6.9 String". Signed-off-by: Vincent Pelletier Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_fs.c | 4 ++-- include/uapi/linux/usb/functionfs.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index aab3fc1dbb94..818f4997c1ac 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -2091,8 +2091,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, case FFS_STRING: /* - * Strings are indexed from 1 (0 is magic ;) reserved - * for languages list or some such) + * Strings are indexed from 1 (0 is reserved + * for languages list) */ if (*valuep > helper->ffs->strings_count) helper->ffs->strings_count = *valuep; diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index acc63697a0cc..b2a31a55a612 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h @@ -93,6 +93,7 @@ struct usb_ext_prop_desc { * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 | * | 4 | length | LE32 | length of the whole data chunk | * | 8 | flags | LE32 | combination of functionfs_flags | + * | | eventfd | LE32 | eventfd file descriptor | * | | fs_count | LE32 | number of full-speed descriptors | * | | hs_count | LE32 | number of high-speed descriptors | * | | ss_count | LE32 | number of super-speed descriptors | From 354bc45bf329494ef6051f3229ef50b9e2a7ea2a Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Thu, 15 Dec 2016 12:47:42 +0000 Subject: [PATCH 175/359] usb: gadget: f_fs: Fix ExtCompat descriptor validation Reserved1 is documented as expected to be set to 0, but this test fails when it it set to 0. Reverse the condition. Signed-off-by: Vincent Pelletier Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 818f4997c1ac..e4e4376de3ee 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -2252,7 +2252,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, if (len < sizeof(*d) || d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->Reserved1) return -EINVAL; for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i) if (d->Reserved2[i]) From bcdbeb844773333d2d1c08004f3b3e25921040e5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 14 Dec 2016 14:55:56 -0500 Subject: [PATCH 176/359] USB: dummy-hcd: fix bug in stop_activity (handle ep0) The stop_activity() routine in dummy-hcd is supposed to unlink all active requests for every endpoint, among other things. But it doesn't handle ep0. As a result, fuzz testing can generate a WARNING like the following: WARNING: CPU: 0 PID: 4410 at drivers/usb/gadget/udc/dummy_hcd.c:672 dummy_free_request+0x153/0x170 Modules linked in: CPU: 0 PID: 4410 Comm: syz-executor Not tainted 4.9.0-rc7+ #32 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffff88006a64ed10 ffffffff81f96b8a ffffffff41b58ab3 1ffff1000d4c9d35 ffffed000d4c9d2d ffff880065f8ac00 0000000041b58ab3 ffffffff8598b510 ffffffff81f968f8 0000000041b58ab3 ffffffff859410e0 ffffffff813f0590 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [] dump_stack+0x292/0x398 lib/dump_stack.c:51 [] __warn+0x19f/0x1e0 kernel/panic.c:550 [] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585 [] dummy_free_request+0x153/0x170 drivers/usb/gadget/udc/dummy_hcd.c:672 [] usb_ep_free_request+0xc0/0x420 drivers/usb/gadget/udc/core.c:195 [] gadgetfs_unbind+0x131/0x190 drivers/usb/gadget/legacy/inode.c:1612 [] usb_gadget_remove_driver+0x10f/0x2b0 drivers/usb/gadget/udc/core.c:1228 [] usb_gadget_unregister_driver+0x154/0x240 drivers/usb/gadget/udc/core.c:1357 This patch fixes the problem by iterating over all the endpoints in the driver's ep array instead of iterating over the gadget's ep_list, which explicitly leaves out ep0. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 02b14e91ae6c..c60abe3a68f9 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -330,7 +330,7 @@ static void nuke(struct dummy *dum, struct dummy_ep *ep) /* caller must hold lock */ static void stop_activity(struct dummy *dum) { - struct dummy_ep *ep; + int i; /* prevent any more requests */ dum->address = 0; @@ -338,8 +338,8 @@ static void stop_activity(struct dummy *dum) /* The timer is left running so that outstanding URBs can fail */ /* nuke any pending requests first, so driver i/o is quiesced */ - list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list) - nuke(dum, ep); + for (i = 0; i < DUMMY_ENDPOINTS; ++i) + nuke(dum, &dum->ep[i]); /* driver now does any non-usb quiescing necessary */ } From 0994b0a257557e18ee8f0b7c5f0f73fe2b54eec1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 6 Dec 2016 08:36:29 +0100 Subject: [PATCH 177/359] usb: gadgetfs: restrict upper bound on device configuration size Andrey Konovalov reported that we were not properly checking the upper limit before of a device configuration size before calling memdup_user(), which could cause some problems. So set the upper limit to PAGE_SIZE * 4, which should be good enough for all devices. Reported-by: Andrey Konovalov Cc: stable Signed-off-by: Greg Kroah-Hartman Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index e8f4102d19df..48f1409b438a 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1762,7 +1762,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) } spin_unlock_irq(&dev->lock); - if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) + if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) || + (len > PAGE_SIZE * 4)) return -EINVAL; /* we might need to change message format someday */ From d7fd41c6dbcc547578a8a56cc52d6f2d36e505bc Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Thu, 8 Dec 2016 10:57:34 +0100 Subject: [PATCH 178/359] usb: dwc3: skip interrupt when ep disabled In case EP disabled pass only EPCPLT command to be handled. In other case we could hit Bug like below. BUG: unable to handle kernel NULL pointer dereference at 0000000000000003 IP: [] dwc3_thread_interrupt+0x11c8/0x1790 while dep->endpoint.desc is NULL. Signed-off-by: Janusz Dziedzic Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0286e3141864..725b13ad220d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2232,9 +2232,14 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dep = dwc->eps[epnum]; - if (!(dep->flags & DWC3_EP_ENABLED) && - !(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) - return; + if (!(dep->flags & DWC3_EP_ENABLED)) { + if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) + return; + + /* Handle only EPCMDCMPLT when EP disabled */ + if (event->endpoint_event != DWC3_DEPEVT_EPCMDCMPLT) + return; + } if (epnum == 0 || epnum == 1) { dwc3_ep0_interrupt(dwc, event); From b3ce3ce02d146841af012d08506b4071db8ffde3 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 8 Dec 2016 19:55:22 +0800 Subject: [PATCH 179/359] usb: gadget: f_fs: Fix possibe deadlock When system try to close /dev/usb-ffs/adb/ep0 on one core, at the same time another core try to attach new UDC, which will cause deadlock as below scenario. Thus we should release ffs lock before issuing unregister_gadget_item(). [ 52.642225] c1 ====================================================== [ 52.642228] c1 [ INFO: possible circular locking dependency detected ] [ 52.642236] c1 4.4.6+ #1 Tainted: G W O [ 52.642241] c1 ------------------------------------------------------- [ 52.642245] c1 usb ffs open/2808 is trying to acquire lock: [ 52.642270] c0 (udc_lock){+.+.+.}, at: [] usb_gadget_unregister_driver+0x3c/0xc8 [ 52.642272] c1 but task is already holding lock: [ 52.642283] c0 (ffs_lock){+.+.+.}, at: [] ffs_data_clear+0x30/0x140 [ 52.642285] c1 which lock already depends on the new lock. [ 52.642287] c1 the existing dependency chain (in reverse order) is: [ 52.642295] c0 -> #1 (ffs_lock){+.+.+.}: [ 52.642307] c0 [] __lock_acquire+0x20f0/0x2238 [ 52.642314] c0 [] lock_acquire+0xe4/0x298 [ 52.642322] c0 [] mutex_lock_nested+0x7c/0x3cc [ 52.642328] c0 [] ffs_func_bind+0x504/0x6e8 [ 52.642334] c0 [] usb_add_function+0x84/0x184 [ 52.642340] c0 [] configfs_composite_bind+0x264/0x39c [ 52.642346] c0 [] udc_bind_to_driver+0x58/0x11c [ 52.642352] c0 [] usb_udc_attach_driver+0x90/0xc8 [ 52.642358] c0 [] gadget_dev_desc_UDC_store+0xd4/0x128 [ 52.642369] c0 [] configfs_write_file+0xd0/0x13c [ 52.642376] c0 [] vfs_write+0xb8/0x214 [ 52.642381] c0 [] SyS_write+0x54/0xb0 [ 52.642388] c0 [] el0_svc_naked+0x24/0x28 [ 52.642395] c0 -> #0 (udc_lock){+.+.+.}: [ 52.642401] c0 [] print_circular_bug+0x84/0x2e4 [ 52.642407] c0 [] __lock_acquire+0x2138/0x2238 [ 52.642412] c0 [] lock_acquire+0xe4/0x298 [ 52.642420] c0 [] mutex_lock_nested+0x7c/0x3cc [ 52.642427] c0 [] usb_gadget_unregister_driver+0x3c/0xc8 [ 52.642432] c0 [] unregister_gadget_item+0x28/0x44 [ 52.642439] c0 [] ffs_data_clear+0x138/0x140 [ 52.642444] c0 [] ffs_data_reset+0x20/0x6c [ 52.642450] c0 [] ffs_data_closed+0xac/0x12c [ 52.642454] c0 [] ffs_ep0_release+0x20/0x2c [ 52.642460] c0 [] __fput+0xb0/0x1f4 [ 52.642466] c0 [] ____fput+0x20/0x2c [ 52.642473] c0 [] task_work_run+0xb4/0xe8 [ 52.642482] c0 [] do_exit+0x360/0xb9c [ 52.642487] c0 [] do_group_exit+0x4c/0xb0 [ 52.642494] c0 [] get_signal+0x380/0x89c [ 52.642501] c0 [] do_signal+0x154/0x518 [ 52.642507] c0 [] do_notify_resume+0x70/0x78 [ 52.642512] c0 [] work_pending+0x1c/0x20 [ 52.642514] c1 other info that might help us debug this: [ 52.642517] c1 Possible unsafe locking scenario: [ 52.642518] c1 CPU0 CPU1 [ 52.642520] c1 ---- ---- [ 52.642525] c0 lock(ffs_lock); [ 52.642529] c0 lock(udc_lock); [ 52.642533] c0 lock(ffs_lock); [ 52.642537] c0 lock(udc_lock); [ 52.642539] c1 *** DEADLOCK *** [ 52.642543] c1 1 lock held by usb ffs open/2808: [ 52.642555] c0 #0: (ffs_lock){+.+.+.}, at: [] ffs_data_clear+0x30/0x140 [ 52.642557] c1 stack backtrace: [ 52.642563] c1 CPU: 1 PID: 2808 Comm: usb ffs open Tainted: G [ 52.642565] c1 Hardware name: Spreadtrum SP9860g Board (DT) [ 52.642568] c1 Call trace: [ 52.642573] c1 [] dump_backtrace+0x0/0x170 [ 52.642577] c1 [] show_stack+0x20/0x28 [ 52.642583] c1 [] dump_stack+0xa8/0xe0 [ 52.642587] c1 [] print_circular_bug+0x1fc/0x2e4 [ 52.642591] c1 [] __lock_acquire+0x2138/0x2238 [ 52.642595] c1 [] lock_acquire+0xe4/0x298 [ 52.642599] c1 [] mutex_lock_nested+0x7c/0x3cc [ 52.642604] c1 [] usb_gadget_unregister_driver+0x3c/0xc8 [ 52.642608] c1 [] unregister_gadget_item+0x28/0x44 [ 52.642613] c1 [] ffs_data_clear+0x138/0x140 [ 52.642618] c1 [] ffs_data_reset+0x20/0x6c [ 52.642621] c1 [] ffs_data_closed+0xac/0x12c [ 52.642625] c1 [] ffs_ep0_release+0x20/0x2c [ 52.642629] c1 [] __fput+0xb0/0x1f4 [ 52.642633] c1 [] ____fput+0x20/0x2c [ 52.642636] c1 [] task_work_run+0xb4/0xe8 [ 52.642640] c1 [] do_exit+0x360/0xb9c [ 52.642644] c1 [] do_group_exit+0x4c/0xb0 [ 52.642647] c1 [] get_signal+0x380/0x89c [ 52.642651] c1 [] do_signal+0x154/0x518 [ 52.642656] c1 [] do_notify_resume+0x70/0x78 [ 52.642659] c1 [] work_pending+0x1c/0x20 Acked-by: Michal Nazarewicz Signed-off-by: Baolin Wang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_fs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index e4e4376de3ee..5e746adc8a2d 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3666,6 +3666,7 @@ static void ffs_closed(struct ffs_data *ffs) { struct ffs_dev *ffs_obj; struct f_fs_opts *opts; + struct config_item *ci; ENTER(); ffs_dev_lock(); @@ -3689,8 +3690,11 @@ static void ffs_closed(struct ffs_data *ffs) || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount)) goto done; - unregister_gadget_item(ffs_obj->opts-> - func_inst.group.cg_item.ci_parent->ci_parent); + ci = opts->func_inst.group.cg_item.ci_parent->ci_parent; + ffs_dev_unlock(); + + unregister_gadget_item(ci); + return; done: ffs_dev_unlock(); } From faab50984fe6636e616c7cc3d30308ba391d36fd Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 9 Dec 2016 15:17:46 -0500 Subject: [PATCH 180/359] USB: gadgetfs: fix unbounded memory allocation bug Andrey Konovalov reports that fuzz testing with syzkaller causes a KASAN warning in gadgetfs: BUG: KASAN: slab-out-of-bounds in dev_config+0x86f/0x1190 at addr ffff88003c47e160 Write of size 65537 by task syz-executor0/6356 CPU: 3 PID: 6356 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #19 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffff88003c107ad8 ffffffff81f96aba ffffffff3dc11ef0 1ffff10007820eee ffffed0007820ee6 ffff88003dc11f00 0000000041b58ab3 ffffffff8598b4c8 ffffffff81f96828 ffffffff813fb4a0 ffff88003b6eadc0 ffff88003c107738 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [] dump_stack+0x292/0x398 lib/dump_stack.c:51 [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159 [< inline >] print_address_description mm/kasan/report.c:197 [] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286 [] kasan_report+0x35/0x40 mm/kasan/report.c:306 [< inline >] check_memory_region_inline mm/kasan/kasan.c:308 [] check_memory_region+0x139/0x190 mm/kasan/kasan.c:315 [] kasan_check_write+0x14/0x20 mm/kasan/kasan.c:326 [< inline >] copy_from_user arch/x86/include/asm/uaccess.h:689 [< inline >] ep0_write drivers/usb/gadget/legacy/inode.c:1135 [] dev_config+0x86f/0x1190 drivers/usb/gadget/legacy/inode.c:1759 [] __vfs_write+0x5d5/0x760 fs/read_write.c:510 [] vfs_write+0x170/0x4e0 fs/read_write.c:560 [< inline >] SYSC_write fs/read_write.c:607 [] SyS_write+0xfb/0x230 fs/read_write.c:599 [] entry_SYSCALL_64_fastpath+0x1f/0xc2 Indeed, there is a comment saying that the value of len is restricted to a 16-bit integer, but the code doesn't actually do this. This patch fixes the warning. It replaces the comment with a computation that forces the amount of data copied from the user in ep0_write() to be no larger than the wLength size for the control transfer, which is a 16-bit quantity. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 48f1409b438a..01ed3bc0c3c8 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1126,7 +1126,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* data and/or status stage for control request */ } else if (dev->state == STATE_DEV_SETUP) { - /* IN DATA+STATUS caller makes len <= wLength */ + len = min_t(size_t, len, dev->setup_wLength); if (dev->setup_in) { retval = setup_req (dev->gadget->ep0, dev->req, len); if (retval == 0) { From add333a81a16abbd4f106266a2553677a165725f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 9 Dec 2016 15:18:43 -0500 Subject: [PATCH 181/359] USB: gadgetfs: fix use-after-free bug Andrey Konovalov reports that fuzz testing with syzkaller causes a KASAN use-after-free bug report in gadgetfs: BUG: KASAN: use-after-free in gadgetfs_setup+0x208a/0x20e0 at addr ffff88003dfe5bf2 Read of size 2 by task syz-executor0/22994 CPU: 3 PID: 22994 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #16 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffff88006df06a18 ffffffff81f96aba ffffffffe0528500 1ffff1000dbe0cd6 ffffed000dbe0cce ffff88006df068f0 0000000041b58ab3 ffffffff8598b4c8 ffffffff81f96828 1ffff1000dbe0ccd ffff88006df06708 ffff88006df06748 Call Trace: [ 201.343209] [< inline >] __dump_stack lib/dump_stack.c:15 [ 201.343209] [] dump_stack+0x292/0x398 lib/dump_stack.c:51 [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159 [< inline >] print_address_description mm/kasan/report.c:197 [] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286 [< inline >] kasan_report mm/kasan/report.c:306 [] __asan_report_load_n_noabort+0x3a/0x40 mm/kasan/report.c:337 [< inline >] config_buf drivers/usb/gadget/legacy/inode.c:1298 [] gadgetfs_setup+0x208a/0x20e0 drivers/usb/gadget/legacy/inode.c:1368 [] dummy_timer+0x11f0/0x36d0 drivers/usb/gadget/udc/dummy_hcd.c:1858 [] call_timer_fn+0x241/0x800 kernel/time/timer.c:1308 [< inline >] expire_timers kernel/time/timer.c:1348 [] __run_timers+0xa06/0xec0 kernel/time/timer.c:1641 [] run_timer_softirq+0x21/0x80 kernel/time/timer.c:1654 [] __do_softirq+0x2fb/0xb63 kernel/softirq.c:284 The cause of the bug is subtle. The dev_config() routine gets called twice by the fuzzer. The first time, the user data contains both a full-speed configuration descriptor and a high-speed config descriptor, causing dev->hs_config to be set. But it also contains an invalid device descriptor, so the buffer containing the descriptors is deallocated and dev_config() returns an error. The second time dev_config() is called, the user data contains only a full-speed config descriptor. But dev->hs_config still has the stale pointer remaining from the first call, causing the routine to think that there is a valid high-speed config. Later on, when the driver dereferences the stale pointer to copy that descriptor, we get a use-after-free access. The fix is simple: Clear dev->hs_config if the passed-in data does not contain a high-speed config descriptor. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 01ed3bc0c3c8..f1ca33942607 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1800,6 +1800,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) goto fail; kbuf += total; length -= total; + } else { + dev->hs_config = NULL; } /* could support multiple configs, using another encoding! */ From 1c069b057dcf64fada952eaa868d35f02bb0cfc2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 9 Dec 2016 15:24:24 -0500 Subject: [PATCH 182/359] USB: gadgetfs: fix checks of wTotalLength in config descriptors Andrey Konovalov's fuzz testing of gadgetfs showed that we should improve the driver's checks for valid configuration descriptors passed in by the user. In particular, the driver needs to verify that the wTotalLength value in the descriptor is not too short (smaller than USB_DT_CONFIG_SIZE). And the check for whether wTotalLength is too large has to be changed, because the driver assumes there is always enough room remaining in the buffer to hold a device descriptor (at least USB_DT_DEVICE_SIZE bytes). This patch adds the additional check and fixes the existing check. It may do a little more than strictly necessary, but one extra check won't hurt. Signed-off-by: Alan Stern CC: Andrey Konovalov CC: Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index f1ca33942607..08e5ecc05079 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1734,10 +1734,12 @@ static struct usb_gadget_driver gadgetfs_driver = { * such as configuration notifications. */ -static int is_valid_config (struct usb_config_descriptor *config) +static int is_valid_config(struct usb_config_descriptor *config, + unsigned int total) { return config->bDescriptorType == USB_DT_CONFIG && config->bLength == USB_DT_CONFIG_SIZE + && total >= USB_DT_CONFIG_SIZE && config->bConfigurationValue != 0 && (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0 && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0; @@ -1787,7 +1789,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* full or low speed config */ dev->config = (void *) kbuf; total = le16_to_cpu(dev->config->wTotalLength); - if (!is_valid_config (dev->config) || total >= length) + if (!is_valid_config(dev->config, total) || + total > length - USB_DT_DEVICE_SIZE) goto fail; kbuf += total; length -= total; @@ -1796,7 +1799,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (kbuf [1] == USB_DT_CONFIG) { dev->hs_config = (void *) kbuf; total = le16_to_cpu(dev->hs_config->wTotalLength); - if (!is_valid_config (dev->hs_config) || total >= length) + if (!is_valid_config(dev->hs_config, total) || + total > length - USB_DT_DEVICE_SIZE) goto fail; kbuf += total; length -= total; From 890e6c236dcda6d45c5f0bdd23665636376f6831 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 9 Dec 2016 15:25:15 -0500 Subject: [PATCH 183/359] USB: gadgetfs: remove unnecessary assignment The dev_config() routine in gadgetfs has a check that dev->dev->bNumConfigurations is equal to 1, and then contains a redundant line of code setting the value to 1. This patch removes the unnecessary assignment. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 08e5ecc05079..6bde4396927c 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1818,7 +1818,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) || dev->dev->bDescriptorType != USB_DT_DEVICE || dev->dev->bNumConfigurations != 1) goto fail; - dev->dev->bNumConfigurations = 1; dev->dev->bcdUSB = cpu_to_le16 (0x0200); /* triggers gadgetfs_bind(); then we can enumerate. */ From 12a7f17fac5b370bec87259e4c718faf563ce900 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 12 Dec 2016 13:37:52 -0600 Subject: [PATCH 184/359] usb: dwc3: omap: fix race of pm runtime with irq handler in probe Now races can happen between interrupt handler execution and PM runtime in error handling code path in probe and in dwc3_omap_remove() which will lead to system crash: in probe: ... err1: pm_runtime_put_sync(dev); ^^ PM runtime can race with IRQ handler when deferred probing happening due to extcon pm_runtime_disable(dev); return ret; in dwc3_omap_remove: ... dwc3_omap_disable_irqs(omap); ^^ IRQs are disabled in HW, but handler may still run of_platform_depopulate(omap->dev); pm_runtime_put_sync(&pdev->dev); ^^ PM runtime can race with IRQ handler pm_runtime_disable(&pdev->dev); return 0; So, OMAP DWC3 IRQ need to be disabled before calling pm_runtime_put() in probe and in dwc3_omap_remove(). Acked-by: Tony Lindgren Signed-off-by: Grygorii Strashko Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 29e80cc9b634..eb1b9cb3f9d1 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -510,7 +511,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) /* check the DMA Status */ reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); - + irq_set_status_flags(omap->irq, IRQ_NOAUTOEN); ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt, dwc3_omap_interrupt_thread, IRQF_SHARED, "dwc3-omap", omap); @@ -531,7 +532,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) } dwc3_omap_enable_irqs(omap); - + enable_irq(omap->irq); return 0; err2: @@ -552,6 +553,7 @@ static int dwc3_omap_remove(struct platform_device *pdev) extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); dwc3_omap_disable_irqs(omap); + disable_irq(omap->irq); of_platform_depopulate(omap->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); From 0eae2fde164caaa013a3f7341fd3e7e36e8e2865 Mon Sep 17 00:00:00 2001 From: John Youn Date: Mon, 28 Nov 2016 16:30:58 -0800 Subject: [PATCH 185/359] usb: dwc3: pci: Add "linux,sysdev_is_parent" property Calling platform_device_add_properties() replaces existing properties so the "linux,sysdev_is_parent" property doesn't get set. Add this property to each platform. Fixes: d64ff406e51e ("usb: dwc3: use bus->sysdev for DMA configuration") Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 409d2eb848b5..b01156343513 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -73,16 +73,6 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) { struct platform_device *dwc3 = dwc->dwc3; struct pci_dev *pdev = dwc->pci; - int ret; - - struct property_entry sysdev_property[] = { - PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), - { }, - }; - - ret = platform_device_add_properties(dwc3, sysdev_property); - if (ret) - return ret; if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { @@ -105,6 +95,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"), PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), { }, }; @@ -116,6 +107,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) struct property_entry properties[] = { PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), { } }; @@ -167,6 +159,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), { }, }; From 86e881e7d769f40bd5ed08677e503bc15d89dec6 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 1 Dec 2016 10:02:11 +0100 Subject: [PATCH 186/359] usb: dwc2: fix flags for DMA descriptor allocation in dwc2_hsotg_ep_enable dwc2_hsotg_ep_enable can be called from interrupt context, so all allocations should be done with GFP_ATOMIC flags. This fixes following issue on ARM architecture: [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x74/0x94) [] (dump_stack) from [] (__warn+0xd4/0x100) [] (__warn) from [] (warn_slowpath_null+0x20/0x28) [] (warn_slowpath_null) from [] (smp_call_function_many+0xcc/0x2a4) [] (smp_call_function_many) from [] (on_each_cpu_mask+0x38/0xa8) [] (on_each_cpu_mask) from [] (start_isolate_page_range+0x134/0x1b8) [] (start_isolate_page_range) from [] (alloc_contig_range+0xac/0x2f8) [] (alloc_contig_range) from [] (cma_alloc+0xe0/0x1a8) [] (cma_alloc) from [] (__alloc_from_contiguous+0x38/0xe0) [] (__alloc_from_contiguous) from [] (cma_allocator_alloc+0x30/0x38) [] (cma_allocator_alloc) from [] (__dma_alloc+0x1c0/0x2c8) [] (__dma_alloc) from [] (arm_dma_alloc+0x3c/0x48) [] (arm_dma_alloc) from [] (dwc2_hsotg_ep_enable+0xec/0x46c) [] (dwc2_hsotg_ep_enable) from [] (usb_ep_enable+0x2c/0x3c) [] (usb_ep_enable) from [] (ecm_set_alt+0xa8/0x154) [] (ecm_set_alt) from [] (composite_setup+0xd74/0x1540) [] (composite_setup) from [] (dwc2_hsotg_complete_setup+0xb8/0x370) [] (dwc2_hsotg_complete_setup) from [] (usb_gadget_giveback_request+0xc/0x10) [] (usb_gadget_giveback_request) from [] (dwc2_hsotg_complete_request+0x78/0x128) [] (dwc2_hsotg_complete_request) from [] (dwc2_hsotg_epint+0x69c/0x81c) [] (dwc2_hsotg_epint) from [] (dwc2_hsotg_irq+0xfc/0x748) [] (dwc2_hsotg_irq) from [] (__handle_irq_event_percpu+0x58/0x140) [] (__handle_irq_event_percpu) from [] (handle_irq_event_percpu+0x1c/0x58) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x38/0x5c) [] (handle_irq_event) from [] (handle_fasteoi_irq+0xc4/0x19c) [] (handle_fasteoi_irq) from [] (generic_handle_irq+0x18/0x28) [] (generic_handle_irq) from [] (__handle_domain_irq+0x6c/0xe4) [] (__handle_domain_irq) from [] (gic_handle_irq+0x50/0x9c) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0xa8) Fixes: 5f54c54b0ba83 ("usb: dwc2: gadget: Add DDMA chain pointers to dwc2_hsotg_ep structure") Acked-by: John Youn Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index b95930f20d90..c55db4aa54d6 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3753,7 +3753,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, hs_ep->desc_list = dma_alloc_coherent(hsotg->dev, MAX_DMA_DESC_NUM_GENERIC * sizeof(struct dwc2_dma_desc), - &hs_ep->desc_list_dma, GFP_KERNEL); + &hs_ep->desc_list_dma, GFP_ATOMIC); if (!hs_ep->desc_list) { ret = -ENOMEM; goto error2; From 8f8983a5683623b62b339d159573f95a1fce44f3 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 1 Apr 2016 17:13:12 +0300 Subject: [PATCH 187/359] usb: dwc3: pci: add Intel Gemini Lake PCI ID Intel Gemini Lake SoC has the same DWC3 than Broxton. Add the new ID to the supported Devices. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index b01156343513..cce0a220b6b0 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -38,6 +38,7 @@ #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa #define PCI_DEVICE_ID_INTEL_APL 0x5aaa #define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 +#define PCI_DEVICE_ID_INTEL_GLK 0x31aa #define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511" #define PCI_INTEL_BXT_FUNC_PMU_PWR 4 @@ -267,6 +268,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, { } /* Terminating Entry */ }; From 7b01738112608ce47083178ae2b9ebadf02d32cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20H=C3=A4dicke?= Date: Thu, 29 Dec 2016 23:02:11 +0100 Subject: [PATCH 188/359] usb: gadget: udc: core: fix return code of usb_gadget_probe_driver() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression which was introduced by commit f1bddbb, by reverting a small fragment of commit 855ed04. If the following conditions were met, usb_gadget_probe_driver() returned 0, although the call was unsuccessful: 1. A particular UDC was specified by thge gadget driver (using member "udc_name" of struct usb_gadget_driver). 2. The UDC with this name is available. 3. Another gadget driver is already bound to this gadget. 4. The gadget driver has the "match_existing_only" flag set. In this case, the return code variable "ret" is set to 0, the return code of a strcmp() call (to check for the second condition). This also fixes an oops which could occur in the following scenario: 1. Two usb gadget instances were configured using configfs. 2. The first gadget configuration was bound to a UDC (using the configfs attribute "UDC"). 3. It was tried to bind the second gadget configuration to the same UDC in the same way. This operation was then wrongly reported as being successful. 4. The second gadget configuration's "UDC" attribute is cleared, to unbind the (not really bound) second gadget configuration from the UDC. ] __list_del_entry+0x29/0xc0 PGD 41b4c5067 PUD 41a598067 PMD 0 Oops: 0000 [#1] SMP Modules linked in: cdc_acm usb_f_fs usb_f_serial usb_f_acm u_serial libcomposite configfs dummy_hcd bnep intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm snd_hda_codec_hdmi irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd snd_hda_codec_realtek snd_hda_codec_generic serio_raw uvcvideo videobuf2_vmalloc btusb snd_usb_audio snd_hda_intel videobuf2_memops btrtl snd_hda_codec snd_hda_core snd_usbmidi_lib btbcm videobuf2_v4l2 btintel snd_hwdep videobuf2_core snd_seq_midi bluetooth snd_seq_midi_event videodev xpad efi_pstore snd_pcm_oss rfkill joydev media crc16 ff_memless snd_mixer_oss snd_rawmidi nls_ascii snd_pcm snd_seq snd_seq_device nls_cp437 mei_me snd_timer vfat sg udc_core lpc_ich fat efivars mfd_core mei snd soundcore battery nuvoton_cir rc_core evdev intel_smartconnect ie31200_edac edac_core shpchp tpm_tis tpm_tis_core tpm parport_pc ppdev lp parport efivarfs autofs4 btrfs xor raid6_pq hid_logitech_hidpp hid_logitech_dj hid_generic usbhid hid uas usb_storage sr_mod cdrom sd_mod ahci libahci nouveau i915 crc32c_intel i2c_algo_bit psmouse ttm xhci_pci libata scsi_mod ehci_pci drm_kms_helper xhci_hcd ehci_hcd r8169 mii usbcore drm nvme nvme_core fjes button [last unloaded: net2280] CPU: 5 PID: 829 Comm: bash Not tainted 4.9.0-rc7 #1 Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./Z77 Extreme3, BIOS P1.50 07/11/2013 task: ffff880419ce4040 task.stack: ffffc90002ed4000 RIP: 0010:[] [] __list_del_entry+0x29/0xc0 RSP: 0018:ffffc90002ed7d68 EFLAGS: 00010207 RAX: 0000000000000000 RBX: ffff88041787ec30 RCX: dead000000000200 RDX: 0000000000000000 RSI: ffff880417482002 RDI: ffff88041787ec30 RBP: ffffc90002ed7d68 R08: 0000000000000000 R09: 0000000000000010 R10: 0000000000000000 R11: ffff880419ce4040 R12: ffff88041787eb68 R13: ffff88041787eaa8 R14: ffff88041560a2c0 R15: 0000000000000001 FS: 00007fe4e49b8700(0000) GS:ffff88042f340000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000041b4c4000 CR4: 00000000001406e0 Stack: ffffc90002ed7d80 ffffffff94f5e68d ffffffffc0ae5ef0 ffffc90002ed7da0 ffffffffc0ae22aa ffff88041787e800 ffff88041787e800 ffffc90002ed7dc0 ffffffffc0d7a727 ffffffff952273fa ffff88041aba5760 ffffc90002ed7df8 Call Trace: [] list_del+0xd/0x30 [] usb_gadget_unregister_driver+0xaa/0xc0 [udc_core] [] unregister_gadget+0x27/0x60 [libcomposite] [] ? mutex_lock+0x1a/0x30 [] gadget_dev_desc_UDC_store+0x88/0xe0 [libcomposite] [] configfs_write_file+0xa0/0x100 [configfs] [] __vfs_write+0x37/0x160 [] ? __fd_install+0x30/0xd0 [] ? _raw_spin_unlock+0xe/0x10 [] vfs_write+0xb8/0x1b0 [] SyS_write+0x58/0xc0 [] ? __close_fd+0x94/0xc0 [] entry_SYSCALL_64_fastpath+0x1e/0xad Code: 66 90 55 48 8b 07 48 b9 00 01 00 00 00 00 ad de 48 8b 57 08 48 89 e5 48 39 c8 74 29 48 b9 00 02 00 00 00 00 ad de 48 39 ca 74 3a <4c> 8b 02 4c 39 c7 75 52 4c 8b 40 08 4c 39 c7 75 66 48 89 50 08 RIP [] __list_del_entry+0x29/0xc0 RSP CR2: 0000000000000000 ---[ end trace 99fc090ab3ff6cbc ]--- Fixes: f1bddbb ("usb: gadget: Fix binding to UDC via configfs interface") Signed-off-by: Felix Hädicke Tested-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 9483489080f6..0402177f93cd 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1317,7 +1317,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) if (!ret) break; } - if (!ret && !udc->driver) + if (ret) + ret = -ENODEV; + else if (udc->driver) + ret = -EBUSY; + else goto found; } else { list_for_each_entry(udc, &udc_list, list) { From 5d45b011c14a791ef23555a59ff7a3e6d213530f Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 7 Dec 2016 16:22:15 +0100 Subject: [PATCH 189/359] ARM: davinci: da850: fix infinite loop in clk_set_rate() The aemif clock is added twice to the lookup table in da850.c. This breaks the children list of pll0_sysclk3 as we're using the same list links in struct clk. When calling clk_set_rate(), we get stuck in propagate_rate(). Create a separate clock for nand, inheriting the rate of the aemif clock and retrieve it in the davinci_nand module. Cc: # 4.9.x Signed-off-by: Bartosz Golaszewski Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/da850.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index e770c97ea45c..e9d019cc8f46 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -367,6 +367,16 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +/* + * In order to avoid adding the aemif_clk to the clock lookup table twice (and + * screwing up the linked list in the process) create a separate clock for + * nand inheriting the rate from aemif_clk. + */ +static struct clk aemif_nand_clk = { + .name = "nand", + .parent = &aemif_clk, +}; + static struct clk usb11_clk = { .name = "usb11", .parent = &pll0_sysclk4, @@ -537,7 +547,15 @@ static struct clk_lookup da850_clks[] = { CLK("da830-mmc.0", NULL, &mmcsd0_clk), CLK("da830-mmc.1", NULL, &mmcsd1_clk), CLK("ti-aemif", NULL, &aemif_clk), - CLK(NULL, "aemif", &aemif_clk), + /* + * The only user of this clock is davinci_nand and it get's it through + * con_id. The nand node itself is created from within the aemif + * driver to guarantee that it's probed after the aemif timing + * parameters are configured. of_dev_auxdata is not accessible from + * the aemif driver and can't be passed to of_platform_populate(). For + * that reason we're leaving the dev_id here as NULL. + */ + CLK(NULL, "aemif", &aemif_nand_clk), CLK("ohci-da8xx", "usb11", &usb11_clk), CLK("musb-da8xx", "usb20", &usb20_clk), CLK("spi_davinci.0", NULL, &spi0_clk), From ef37427ac5677331145ab27a17e6f5f1b43f0c11 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 7 Dec 2016 16:22:16 +0100 Subject: [PATCH 190/359] ARM: davinci: da850: don't add emac clock to lookup table twice Similarly to the aemif clock - this screws up the linked list of clock children. Create a separate clock for mdio inheriting the rate from emac_clk. Cc: # 3.12.x- Signed-off-by: Bartosz Golaszewski [nsekhar@ti.com: add a comment over mdio_clk to explaing its existence + commit headline updates] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/da850.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index e9d019cc8f46..1d873d15b545 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -319,6 +319,16 @@ static struct clk emac_clk = { .gpsc = 1, }; +/* + * In order to avoid adding the emac_clk to the clock lookup table twice (and + * screwing up the linked list in the process) create a separate clock for + * mdio inheriting the rate from emac_clk. + */ +static struct clk mdio_clk = { + .name = "mdio", + .parent = &emac_clk, +}; + static struct clk mcasp_clk = { .name = "mcasp", .parent = &async3_clk, @@ -539,7 +549,7 @@ static struct clk_lookup da850_clks[] = { CLK(NULL, "arm", &arm_clk), CLK(NULL, "rmii", &rmii_clk), CLK("davinci_emac.1", NULL, &emac_clk), - CLK("davinci_mdio.0", "fck", &emac_clk), + CLK("davinci_mdio.0", "fck", &mdio_clk), CLK("davinci-mcasp.0", NULL, &mcasp_clk), CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk), CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk), From 427157631648c980e8bba4d73a21508b9e1a47ec Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 18 Dec 2016 10:19:28 +0100 Subject: [PATCH 191/359] USB: serial: f81534: detect errors from f81534_logic_to_phy_port() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With gcc 4.1.2: drivers/usb/serial/f81534.c: In function ‘f81534_port_probe’: drivers/usb/serial/f81534.c:1250: warning: comparison is always false due to limited range of data type f81534_logic_to_phy_port() may return a negative error value, which is ignored by assigning it to u8 f81534_port_private.phy_num. Use an intermediate variable of type int to fix this. While at it, forward the actual error code instead of converting it to -ENODEV, and drop the useless check for F81534_NUM_PORT, as the callee always returns a valid port number in case of success. Fixes: 0c9bd6004d258d46 ("USB: serial: add Fintek F81532/534 driver") Signed-off-by: Geert Uytterhoeven Signed-off-by: Johan Hovold --- drivers/usb/serial/f81534.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 8282a6a18fee..22f23a429a95 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -1237,6 +1237,7 @@ static int f81534_attach(struct usb_serial *serial) static int f81534_port_probe(struct usb_serial_port *port) { struct f81534_port_private *port_priv; + int ret; port_priv = devm_kzalloc(&port->dev, sizeof(*port_priv), GFP_KERNEL); if (!port_priv) @@ -1246,10 +1247,11 @@ static int f81534_port_probe(struct usb_serial_port *port) mutex_init(&port_priv->mcr_mutex); /* Assign logic-to-phy mapping */ - port_priv->phy_num = f81534_logic_to_phy_port(port->serial, port); - if (port_priv->phy_num < 0 || port_priv->phy_num >= F81534_NUM_PORT) - return -ENODEV; + ret = f81534_logic_to_phy_port(port->serial, port); + if (ret < 0) + return ret; + port_priv->phy_num = ret; usb_set_serial_port_data(port, port_priv); dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__, port->port_number, port_priv->phy_num); From 35f432a03e41d3bf08c51ede917f94e2288fbe8c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 2 Jan 2017 11:19:29 +0100 Subject: [PATCH 192/359] mac80211: initialize fast-xmit 'info' later In ieee80211_xmit_fast(), 'info' is initialized to point to the skb that's passed in, but that skb may later be replaced by a clone (if it was shared), leading to an invalid pointer. This can lead to use-after-free and also later crashes since the real SKB's info->hw_queue doesn't get initialized properly. Fix this by assigning info only later, when it's needed, after the skb replacement (may have) happened. Cc: stable@vger.kernel.org Reported-by: Ben Greear Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2c21b7039136..0d8b716e509e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3287,7 +3287,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); int hw_headroom = sdata->local->hw.extra_tx_headroom; struct ethhdr eth; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_info *info; struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; struct ieee80211_tx_data tx; ieee80211_tx_result r; @@ -3351,6 +3351,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); + info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); info->band = fast_tx->band; info->control.vif = &sdata->vif; From 48cd30b49527f04078ef7de217cc188157f76ba6 Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Fri, 9 Dec 2016 17:59:32 +0100 Subject: [PATCH 193/359] ARM: davinci: Make __clk_{enable,disable} functions public In some cases, there is a need to enable a clock as part of clock enable callback of a different clock. For example, USB 2.0 PHY clock enable requires USB 2.0 clock to be enabled. In this case, it is safe to instead call __clk_enable() since the clock framework lock is already taken. Calling clk_enable() causes recursive locking error. A similar case arises in the clock disable path. To enable such usage, make __clk_{enable,disable} functions publicly available outside of clock.c. Also, call them davinci_clk_{enable|disable} now to be consistent with how other davinci-specific clock functions are named. Note that these functions are not exported to drivers. They are meant for usage in platform specific clock management code. Signed-off-by: Alexandre Bailon Suggested-by: David Lechner Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/clock.c | 12 ++++++------ arch/arm/mach-davinci/clock.h | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index df42c93a93d6..f5dce9b4e617 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -31,10 +31,10 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clockfw_lock); -static void __clk_enable(struct clk *clk) +void davinci_clk_enable(struct clk *clk) { if (clk->parent) - __clk_enable(clk->parent); + davinci_clk_enable(clk->parent); if (clk->usecount++ == 0) { if (clk->flags & CLK_PSC) davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, @@ -44,7 +44,7 @@ static void __clk_enable(struct clk *clk) } } -static void __clk_disable(struct clk *clk) +void davinci_clk_disable(struct clk *clk) { if (WARN_ON(clk->usecount == 0)) return; @@ -56,7 +56,7 @@ static void __clk_disable(struct clk *clk) clk->clk_disable(clk); } if (clk->parent) - __clk_disable(clk->parent); + davinci_clk_disable(clk->parent); } int davinci_clk_reset(struct clk *clk, bool reset) @@ -103,7 +103,7 @@ int clk_enable(struct clk *clk) return -EINVAL; spin_lock_irqsave(&clockfw_lock, flags); - __clk_enable(clk); + davinci_clk_enable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); return 0; @@ -118,7 +118,7 @@ void clk_disable(struct clk *clk) return; spin_lock_irqsave(&clockfw_lock, flags); - __clk_disable(clk); + davinci_clk_disable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); } EXPORT_SYMBOL(clk_disable); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index e2a5437a1aee..fa2b83752e03 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -132,6 +132,8 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); int davinci_set_refclk_rate(unsigned long rate); int davinci_simple_set_rate(struct clk *clk, unsigned long rate); int davinci_clk_reset(struct clk *clk, bool reset); +void davinci_clk_enable(struct clk *clk); +void davinci_clk_disable(struct clk *clk); extern struct platform_device davinci_wdt_device; extern void davinci_watchdog_reset(struct platform_device *); From d1df1e01af1d7c91e48204b9eb8b9f20cdb90700 Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Fri, 9 Dec 2016 17:59:33 +0100 Subject: [PATCH 194/359] ARM: davinci: da8xx: Fix sleeping function called from invalid context Everytime the usb20 phy is enabled, there is a "sleeping function called from invalid context" BUG. In addition, there is a recursive locking happening because of the recurse call to clk_enable(). clk_enable() from arch/arm/mach-davinci/clock.c uses spin_lock_irqsave() before to invoke the callback usb20_phy_clk_enable(). usb20_phy_clk_enable() uses clk_get() and clk_enable_prepapre() which may sleep. Replace clk_prepare_enable() by davinci_clk_enable(). Signed-off-by: Alexandre Bailon Suggested-by: David Lechner [nsekhar@ti.com: minor commit description adjustment] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/usb-da8xx.c | 34 ++++++++++++++----------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c index c6feecf7ae24..9a6af0bd5dc3 100644 --- a/arch/arm/mach-davinci/usb-da8xx.c +++ b/arch/arm/mach-davinci/usb-da8xx.c @@ -22,6 +22,8 @@ #define DA8XX_USB0_BASE 0x01e00000 #define DA8XX_USB1_BASE 0x01e25000 +static struct clk *usb20_clk; + static struct platform_device da8xx_usb_phy = { .name = "da8xx-usb-phy", .id = -1, @@ -158,26 +160,13 @@ int __init da8xx_register_usb_refclkin(int rate) static void usb20_phy_clk_enable(struct clk *clk) { - struct clk *usb20_clk; - int err; u32 val; u32 timeout = 500000; /* 500 msec */ val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); - usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20"); - if (IS_ERR(usb20_clk)) { - pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk)); - return; - } - /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */ - err = clk_prepare_enable(usb20_clk); - if (err) { - pr_err("failed to enable usb20 clk: %d\n", err); - clk_put(usb20_clk); - return; - } + davinci_clk_enable(usb20_clk); /* * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1 @@ -197,8 +186,7 @@ static void usb20_phy_clk_enable(struct clk *clk) pr_err("Timeout waiting for USB 2.0 PHY clock good\n"); done: - clk_disable_unprepare(usb20_clk); - clk_put(usb20_clk); + davinci_clk_disable(usb20_clk); } static void usb20_phy_clk_disable(struct clk *clk) @@ -285,11 +273,19 @@ static struct clk_lookup usb20_phy_clk_lookup = int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin) { struct clk *parent; - int ret = 0; + int ret; + + usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20"); + ret = PTR_ERR_OR_ZERO(usb20_clk); + if (ret) + return ret; parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux"); - if (IS_ERR(parent)) - return PTR_ERR(parent); + ret = PTR_ERR_OR_ZERO(parent); + if (ret) { + clk_put(usb20_clk); + return ret; + } usb20_phy_clk.parent = parent; ret = clk_register(&usb20_phy_clk); From f83f90cf7ba68deb09406ea9da80852a64c4db29 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Fri, 23 Dec 2016 12:50:13 +0000 Subject: [PATCH 195/359] HID: usbhid: Add quirk for the Futaba TOSD-5711BB VFD The Futaba TOSD-5711BB VFD crashes when the initial HID report is requested, register the display in hid-ids and tell hid-quirks to not do the init. Signed-off-by: Alex Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ec277b96eaa1..62b03d53ecd1 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -365,6 +365,9 @@ #define USB_VENDOR_ID_FLATFROG 0x25b5 #define USB_DEVICE_ID_MULTITOUCH_3200 0x0002 +#define USB_VENDOR_ID_FUTABA 0x0547 +#define USB_DEVICE_ID_LED_DISPLAY 0x7000 + #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index b3e01c82af05..6fd49788fbe6 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -88,6 +88,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, From 8aa2cc7e747881d1fd52db28261b201d4e3e5565 Mon Sep 17 00:00:00 2001 From: Marcel Hasler Date: Tue, 20 Dec 2016 22:08:13 +0100 Subject: [PATCH 196/359] HID: usbhid: Add quirk for Mayflash/Dragonrise DolphinBar. The DolphinBar by Mayflash (identified as Dragonrise) needs HID_QUIRK_MULTI_INPUT to split it up into four input devices. Without this quirk the adapter is falsely recognized as a tablet. See also bug 115841 (https://bugzilla.kernel.org/show_bug.cgi?id=115841). Signed-off-by: Marcel Hasler Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 62b03d53ecd1..54bd22dc1411 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -319,6 +319,7 @@ #define USB_VENDOR_ID_DRAGONRISE 0x0079 #define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 #define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801 +#define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843 #define USB_VENDOR_ID_DWAV 0x0eef diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 6fd49788fbe6..e9d6cc7cdfc5 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -83,6 +83,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, From 143fca77cce906d35f7a60ccef648e888df589f2 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 27 Dec 2016 08:57:59 -0800 Subject: [PATCH 197/359] HID: sensor-hub: Move the memset to sensor_hub_get_feature() While applying patch d443a0aa3a29: "HID: hid-sensor-hub: clear memory to avoid random data", there was some issues in applying correct version of the patch. This resulted in the breakage of sensor functions as all request like power-up will be reset by the memset() in the function sensor_hub_set_feature(). The reset of caller buffer should be in the function sensor_hub_get_feature(), not in the sensor_hub_set_feature(). Fixes: d443a0aa3a29 ("HID: hid-sensor-hub: clear memory to avoid random data") Cc: Stable # 4.9+ Signed-off-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/hid-sensor-hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 5c925228847c..4ef73374a8f9 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -212,7 +212,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, __s32 value; int ret = 0; - memset(buffer, 0, buffer_size); mutex_lock(&data->mutex); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); if (!report || (field_index >= report->maxfield)) { @@ -256,6 +255,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, int buffer_index = 0; int i; + memset(buffer, 0, buffer_size); + mutex_lock(&data->mutex); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); if (!report || (field_index >= report->maxfield) || From 23c4cfbdab494568600ae6073a2bf02be4b10f4e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 28 Dec 2016 13:06:26 +0200 Subject: [PATCH 198/359] drm/edid: constify edid quirk list No reason not to be const. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1482923186-22430-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/drm_edid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 67d6a73731d8..4ff04aa84dd0 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -91,7 +91,7 @@ struct detailed_mode_closure { #define LEVEL_GTF2 2 #define LEVEL_CVT 3 -static struct edid_quirk { +static const struct edid_quirk { char vendor[4]; int product_id; u32 quirks; @@ -1478,7 +1478,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); * * Returns true if @vendor is in @edid, false otherwise */ -static bool edid_vendor(struct edid *edid, char *vendor) +static bool edid_vendor(struct edid *edid, const char *vendor) { char edid_vendor[3]; @@ -1498,7 +1498,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) */ static u32 edid_get_quirks(struct edid *edid) { - struct edid_quirk *quirk; + const struct edid_quirk *quirk; int i; for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) { From 6c006a9d94bfb5cbcc5150e8fd7f45d3f92f3ee8 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Sun, 25 Dec 2016 19:01:03 +0530 Subject: [PATCH 199/359] clean_bdev_aliases: Prevent cleaning blocks that are not in block range The first block to be cleaned may start at a non-zero page offset. In such a scenario clean_bdev_aliases() will end up cleaning blocks that do not fall in the range of blocks to be cleaned. This commit fixes the issue by skipping blocks that do not fall in valid block range. Signed-off-by: Chandan Rajendra Reviewed-by: Jan Kara Reviewed-by: Eryu Guan Signed-off-by: Jens Axboe --- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/buffer.c b/fs/buffer.c index d21771fcf7d3..0e87401cf335 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1660,7 +1660,7 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len) head = page_buffers(page); bh = head; do { - if (!buffer_mapped(bh)) + if (!buffer_mapped(bh) || (bh->b_blocknr < block)) goto next; if (bh->b_blocknr >= block + len) break; From f2e0a0b292682dd94274d6793d76656b41526147 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 2 Jan 2017 09:46:15 -0700 Subject: [PATCH 200/359] block: Make wbt_wait() definition consistent with declaration Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism") Signed-off-by: Bart Van Assche Signed-off-by: Jens Axboe --- block/blk-wbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index 6e82769f4042..fd28c2806406 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -595,7 +595,7 @@ static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio) * in an irq held spinlock, if it holds one when calling this function. * If we do sleep, we'll release and re-grab it. */ -unsigned int wbt_wait(struct rq_wb *rwb, struct bio *bio, spinlock_t *lock) +enum wbt_flags wbt_wait(struct rq_wb *rwb, struct bio *bio, spinlock_t *lock) { unsigned int ret = 0; From 542b9f0759ed74ca0f1a9f3ff090c95ea73eba91 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 29 Dec 2016 04:06:11 -0800 Subject: [PATCH 201/359] ARM: dts: qcom: apq8064: Add missing scm clock As per the device tree binding the apq8064 scm node requires the core clock to be specified, so add this. Signed-off-by: Bjorn Andersson Signed-off-by: Andy Gross --- arch/arm/boot/dts/qcom-apq8064.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 268bd470c865..407a4610f4a7 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -303,6 +304,9 @@ dsps_smsm: dsps@4 { firmware { scm { compatible = "qcom,scm-apq8064"; + + clocks = <&rpmcc RPM_DAYTONA_FABRIC_CLK>; + clock-names = "core"; }; }; From 9eca53508a157c6b6fdb6e06796902cf8a920d29 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 2 Jan 2017 09:48:47 -0700 Subject: [PATCH 202/359] block: Avoid that sparse complains about context imbalance in __wbt_wait() This patch does not change any functionality. Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism") Signed-off-by: Bart Van Assche Signed-off-by: Jens Axboe --- block/blk-wbt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index fd28c2806406..f0a9c07b4c7a 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -544,6 +544,8 @@ static inline bool may_queue(struct rq_wb *rwb, struct rq_wait *rqw, * the timer to kick off queuing again. */ static void __wbt_wait(struct rq_wb *rwb, unsigned long rw, spinlock_t *lock) + __releases(lock) + __acquires(lock) { struct rq_wait *rqw = get_rq_wait(rwb, current_is_kswapd()); DEFINE_WAIT(wait); @@ -558,13 +560,12 @@ static void __wbt_wait(struct rq_wb *rwb, unsigned long rw, spinlock_t *lock) if (may_queue(rwb, rqw, &wait, rw)) break; - if (lock) + if (lock) { spin_unlock_irq(lock); - - io_schedule(); - - if (lock) + io_schedule(); spin_lock_irq(lock); + } else + io_schedule(); } while (1); finish_wait(&rqw->wait, &wait); From b4a9eb4cd5966c8aad3d007d206a2cbda97d6928 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 2 Jan 2017 17:43:15 +0100 Subject: [PATCH 203/359] parisc: Add line-break when printing segfault info Add a leading line break else printed line gets too long. Signed-off-by: Helge Deller Cc: # v4.9 --- arch/parisc/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 8ff9253930af..1a0b4f63f0e9 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -234,7 +234,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long code, tsk->comm, code, address); print_vma_addr(KERN_CONT " in ", regs->iaoq[0]); - pr_cont(" trap #%lu: %s%c", code, trap_name(code), + pr_cont("\ntrap #%lu: %s%c", code, trap_name(code), vma ? ',':'\n'); if (vma) From d0af683407a26a4437d8fa6e283ea201f2ae8146 Mon Sep 17 00:00:00 2001 From: Ian Kumlien Date: Mon, 2 Jan 2017 09:18:35 +0100 Subject: [PATCH 204/359] flow_dissector: Update pptp handling to avoid null pointer deref. __skb_flow_dissect can be called with a skb or a data packet, either can be NULL. All calls seems to have been moved to __skb_header_pointer except the pptp handling which is still calling skb_header_pointer. skb_header_pointer will use skb->data and thus: [ 109.556866] BUG: unable to handle kernel NULL pointer dereference at 0000000000000080 [ 109.557102] IP: [] __skb_flow_dissect+0xa88/0xce0 [ 109.557263] PGD 0 [ 109.557338] [ 109.557484] Oops: 0000 [#1] SMP [ 109.557562] Modules linked in: chaoskey [ 109.557783] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.9.0 #79 [ 109.557867] Hardware name: Supermicro A1SRM-LN7F/LN5F/A1SRM-LN7F-2758, BIOS 1.0c 11/04/2015 [ 109.557957] task: ffff94085c27bc00 task.stack: ffffb745c0068000 [ 109.558041] RIP: 0010:[] [] __skb_flow_dissect+0xa88/0xce0 [ 109.558203] RSP: 0018:ffff94087fc83d40 EFLAGS: 00010206 [ 109.558286] RAX: 0000000000000130 RBX: ffffffff8975bf80 RCX: ffff94084fab6800 [ 109.558373] RDX: 0000000000000010 RSI: 000000000000000c RDI: 0000000000000000 [ 109.558460] RBP: 0000000000000b88 R08: 0000000000000000 R09: 0000000000000022 [ 109.558547] R10: 0000000000000008 R11: ffff94087fc83e04 R12: 0000000000000000 [ 109.558763] R13: ffff94084fab6800 R14: ffff94087fc83e04 R15: 000000000000002f [ 109.558979] FS: 0000000000000000(0000) GS:ffff94087fc80000(0000) knlGS:0000000000000000 [ 109.559326] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 109.559539] CR2: 0000000000000080 CR3: 0000000281809000 CR4: 00000000001026e0 [ 109.559753] Stack: [ 109.559957] 000000000000000c ffff94084fab6822 0000000000000001 ffff94085c2b5fc0 [ 109.560578] 0000000000000001 0000000000002000 0000000000000000 0000000000000000 [ 109.561200] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 109.561820] Call Trace: [ 109.562027] [ 109.562108] [] ? eth_get_headlen+0x7a/0xf0 [ 109.562522] [] ? igb_poll+0x96a/0xe80 [ 109.562737] [] ? net_rx_action+0x20b/0x350 [ 109.562953] [] ? __do_softirq+0xe8/0x280 [ 109.563169] [] ? irq_exit+0xaa/0xb0 [ 109.563382] [] ? do_IRQ+0x4b/0xc0 [ 109.563597] [] ? common_interrupt+0x7f/0x7f [ 109.563810] [ 109.563890] [] ? cpuidle_enter_state+0x130/0x2c0 [ 109.564304] [] ? cpuidle_enter_state+0x120/0x2c0 [ 109.564520] [] ? cpu_startup_entry+0x19f/0x1f0 [ 109.564737] [] ? start_secondary+0x12a/0x140 [ 109.564950] Code: 83 e2 20 a8 80 0f 84 60 01 00 00 c7 04 24 08 00 00 00 66 85 d2 0f 84 be fe ff ff e9 69 fe ff ff 8b 34 24 89 f2 83 c2 04 66 85 c0 <41> 8b 84 24 80 00 00 00 0f 49 d6 41 8d 31 01 d6 41 2b 84 24 84 [ 109.569959] RIP [] __skb_flow_dissect+0xa88/0xce0 [ 109.570245] RSP [ 109.570453] CR2: 0000000000000080 Fixes: ab10dccb1160 ("rps: Inspect PPTP encapsulated by GRE to get flow hash") Signed-off-by: Ian Kumlien Signed-off-by: David S. Miller --- net/core/flow_dissector.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index d6447dc10371..fe4e1531976c 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -468,8 +468,9 @@ bool __skb_flow_dissect(const struct sk_buff *skb, if (hdr->flags & GRE_ACK) offset += sizeof(((struct pptp_gre_header *)0)->ack); - ppp_hdr = skb_header_pointer(skb, nhoff + offset, - sizeof(_ppp_hdr), _ppp_hdr); + ppp_hdr = __skb_header_pointer(skb, nhoff + offset, + sizeof(_ppp_hdr), + data, hlen, _ppp_hdr); if (!ppp_hdr) goto out_bad; From 7ababb782690e03b78657e27bd051e20163af2d6 Mon Sep 17 00:00:00 2001 From: Michal Tesar Date: Mon, 2 Jan 2017 14:38:36 +0100 Subject: [PATCH 205/359] igmp: Make igmp group member RFC 3376 compliant 5.2. Action on Reception of a Query When a system receives a Query, it does not respond immediately. Instead, it delays its response by a random amount of time, bounded by the Max Resp Time value derived from the Max Resp Code in the received Query message. A system may receive a variety of Queries on different interfaces and of different kinds (e.g., General Queries, Group-Specific Queries, and Group-and-Source-Specific Queries), each of which may require its own delayed response. Before scheduling a response to a Query, the system must first consider previously scheduled pending responses and in many cases schedule a combined response. Therefore, the system must be able to maintain the following state: o A timer per interface for scheduling responses to General Queries. o A per-group and interface timer for scheduling responses to Group- Specific and Group-and-Source-Specific Queries. o A per-group and interface list of sources to be reported in the response to a Group-and-Source-Specific Query. When a new Query with the Router-Alert option arrives on an interface, provided the system has state to report, a delay for a response is randomly selected in the range (0, [Max Resp Time]) where Max Resp Time is derived from Max Resp Code in the received Query message. The following rules are then used to determine if a Report needs to be scheduled and the type of Report to schedule. The rules are considered in order and only the first matching rule is applied. 1. If there is a pending response to a previous General Query scheduled sooner than the selected delay, no additional response needs to be scheduled. 2. If the received Query is a General Query, the interface timer is used to schedule a response to the General Query after the selected delay. Any previously pending response to a General Query is canceled. --8<-- Currently the timer is rearmed with new random expiration time for every incoming query regardless of possibly already pending report. Which is not aligned with the above RFE. It also might happen that higher rate of incoming queries can postpone the report after the expiration time of the first query causing group membership loss. Now the per interface general query timer is rearmed only when there is no pending report already scheduled on that interface or the newly selected expiration time is before the already pending scheduled report. Signed-off-by: Michal Tesar Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 68d622133f53..5b15459955f8 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -219,9 +219,14 @@ static void igmp_start_timer(struct ip_mc_list *im, int max_delay) static void igmp_gq_start_timer(struct in_device *in_dev) { int tv = prandom_u32() % in_dev->mr_maxdelay; + unsigned long exp = jiffies + tv + 2; + + if (in_dev->mr_gq_running && + time_after_eq(exp, (in_dev->mr_gq_timer).expires)) + return; in_dev->mr_gq_running = 1; - if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2)) + if (!mod_timer(&in_dev->mr_gq_timer, exp)) in_dev_hold(in_dev); } From e9572fdd13e299cfba03abbfd2786c84ac055249 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 2 Jan 2017 17:53:39 +0100 Subject: [PATCH 206/359] hwmon: (lm90) fix temp1_max_alarm attribute Since commit commit eb1c8f4325d5 ("hwmon: (lm90) Convert to use new hwmon registration API") the temp1_max_alarm and temp1_crit_alarm attributes are mapped to the same alarm bit. Fix the typo. Fixes: eb1c8f4325d5 ("hwmon: (lm90) Convert to use new hwmon registration API") Signed-off-by: Micehael Walle Signed-off-by: Guenter Roeck --- drivers/hwmon/lm90.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 322ed9272811..841f2428e84a 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -1036,7 +1036,7 @@ static const u8 lm90_temp_emerg_index[3] = { }; static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 }; -static const u8 lm90_max_alarm_bits[3] = { 0, 4, 12 }; +static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 }; static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 }; static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 }; static const u8 lm90_fault_bits[3] = { 0, 2, 10 }; From 4e5da369df64628358e25ffedcf80ac43af3793d Mon Sep 17 00:00:00 2001 From: Alexander Alemayhu Date: Mon, 2 Jan 2017 18:52:24 +0100 Subject: [PATCH 207/359] Documentation/networking: fix typo in mpls-sysctl s/utliziation/utilization Signed-off-by: Alexander Alemayhu Signed-off-by: David S. Miller --- Documentation/networking/mpls-sysctl.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/networking/mpls-sysctl.txt b/Documentation/networking/mpls-sysctl.txt index 9ed15f86c17c..15d8d16934fd 100644 --- a/Documentation/networking/mpls-sysctl.txt +++ b/Documentation/networking/mpls-sysctl.txt @@ -5,8 +5,8 @@ platform_labels - INTEGER possible to configure forwarding for label values equal to or greater than the number of platform labels. - A dense utliziation of the entries in the platform label table - is possible and expected aas the platform labels are locally + A dense utilization of the entries in the platform label table + is possible and expected as the platform labels are locally allocated. If the number of platform label table entries is set to 0 no From c2a6bbaf0c5f90463a7011a295bbdb7e33c80b51 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 30 Dec 2016 02:27:31 +0100 Subject: [PATCH 208/359] ACPI / scan: Prefer devices without _HID/_CID for _ADR matching The way acpi_find_child_device() works currently is that, if there are two (or more) devices with the same _ADR value in the same namespace scope (which is not specifically allowed by the spec and the OS behavior in that case is not defined), the first one of them found to be present (with the help of _STA) will be returned. This covers the majority of cases, but is not sufficient if some of the devices in question have a _HID (or _CID) returning some valid ACPI/PNP device IDs (which is disallowed by the spec) and the ASL writers' expectation appears to be that the OS will match devices without a valid ACPI/PNP device ID against a given bus address first. To cover this special case as well, modify find_child_checks() to prefer devices without ACPI/PNP device IDs over devices that have them. Suggested-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki Tested-by: Hans de Goede --- drivers/acpi/glue.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index eb709e7c9ffd..fb19e1cdb641 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -98,7 +98,15 @@ static int find_child_checks(struct acpi_device *adev, bool check_children) if (check_children && list_empty(&adev->children)) return -ENODEV; - return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; + /* + * If the device has a _HID (or _CID) returning a valid ACPI/PNP + * device ID, it is better to make it look less attractive here, so that + * the other device with the same _ADR value (that may not have a valid + * device ID) can be matched going forward. [This means a second spec + * violation in a row, so whatever we do here is best effort anyway.] + */ + return sta_present && list_empty(&adev->pnp.ids) ? + FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; } struct acpi_device *acpi_find_child_device(struct acpi_device *parent, From 6e092c8c04632dde947208f95537ec6eaaa89d8a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 19 Dec 2016 21:36:39 +0100 Subject: [PATCH 209/359] PM / docs: Drop confusing kernel-doc references from infrastructure.rst The references to drivers/base/power/main.c and drivers/acpi/scan.c from Documentation/driver-api/infrastructure.rst are confusing. They both cause descriptions of functions that are not relevant to device drivers at all to be generated and none of them is sufficient to cover the API in a meaningful way. Drop them for now. Signed-off-by: Rafael J. Wysocki Acked-by: Jonathan Corbet --- Documentation/driver-api/infrastructure.rst | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Documentation/driver-api/infrastructure.rst b/Documentation/driver-api/infrastructure.rst index 0bb0b5fc9512..6d9ff316b608 100644 --- a/Documentation/driver-api/infrastructure.rst +++ b/Documentation/driver-api/infrastructure.rst @@ -55,21 +55,6 @@ Device Drivers DMA Management .. kernel-doc:: drivers/base/dma-mapping.c :export: -Device Drivers Power Management -------------------------------- - -.. kernel-doc:: drivers/base/power/main.c - :export: - -Device Drivers ACPI Support ---------------------------- - -.. kernel-doc:: drivers/acpi/scan.c - :export: - -.. kernel-doc:: drivers/acpi/scan.c - :internal: - Device drivers PnP support -------------------------- From 9932ef3ca7f481af59d85cec6023fc7ff1588f04 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 28 Dec 2016 20:52:34 +0900 Subject: [PATCH 210/359] MAINTAINERS: Add myself as reviewer for DEVFREQ subsystem support Add myself to the DEVFREQ entry as reviewer, I've been helping reviewing and tesing the devfreq support patches for the couple of years. Also, I'm going to contribute the improvement for devfreq subsystem. It would be easier for me for review if I'm cc'ed for patches. Signed-off-by: Chanwoo Choi Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index ad9b965e5e44..8fb6156c4656 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3745,6 +3745,7 @@ F: include/linux/devcoredump.h DEVICE FREQUENCY (DEVFREQ) M: MyungJoo Ham M: Kyungmin Park +R: Chanwoo Choi L: linux-pm@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git S: Maintained From 73613b16cb5c5d5a659fc8832eff99eead3f9afb Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 28 Dec 2016 20:52:35 +0900 Subject: [PATCH 211/359] PM / devfreq: Fix the bug of devfreq_add_device when governor is NULL This patch fixes the bug of devfreq_add_device(). The devfreq device must have the default governor. If find_devfreq_governor() returns error, devfreq_add_device() fail to add the devfreq instance. Fixes: 1b5c1be2c88e (PM / devfreq: map devfreq drivers to governor using name) Signed-off-by: Chanwoo Choi Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/devfreq.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index a324801d6a66..47206a21bb90 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -593,11 +593,16 @@ struct devfreq *devfreq_add_device(struct device *dev, list_add(&devfreq->node, &devfreq_list); governor = find_devfreq_governor(devfreq->governor_name); - if (!IS_ERR(governor)) - devfreq->governor = governor; - if (devfreq->governor) - err = devfreq->governor->event_handler(devfreq, - DEVFREQ_GOV_START, NULL); + if (IS_ERR(governor)) { + dev_err(dev, "%s: Unable to find governor for the device\n", + __func__); + err = PTR_ERR(governor); + goto err_init; + } + + devfreq->governor = governor; + err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START, + NULL); if (err) { dev_err(dev, "%s: Unable to start governor for the device\n", __func__); From 32dd7731699765f21dbe6df9020e613d4ed73fc3 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 28 Dec 2016 20:52:36 +0900 Subject: [PATCH 212/359] PM / devfreq: exynos-bus: Fix the wrong return value This patch fixes the wrong return value. If devfreq driver requires the wrong and non-available governor, it is fail. So, this patch returns the error insead of -EPROBE_DEFER. Fixes: 403e0689d2a9 (PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor) Signed-off-by: Chanwoo Choi Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/exynos-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c index a8ed7792ece2..9af86f46fbec 100644 --- a/drivers/devfreq/exynos-bus.c +++ b/drivers/devfreq/exynos-bus.c @@ -497,7 +497,7 @@ static int exynos_bus_probe(struct platform_device *pdev) if (IS_ERR(bus->devfreq)) { dev_err(dev, "failed to add devfreq dev with passive governor\n"); - ret = -EPROBE_DEFER; + ret = PTR_ERR(bus->devfreq); goto err; } From 116dad7d4339d0965169df8a864fc829f684794d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 30 Dec 2016 08:09:03 -0200 Subject: [PATCH 213/359] ARM: dts: imx6: Disable "weim" node in the dtsi files Commit 1be81ea5860744520 ("ARM: dts: imx6: Add imx-weim parameters to dtsi's") causes the following probe error when the weim node is not present on the board dts (such as imx6q-sabresd): imx-weim 21b8000.weim: Invalid 'ranges' configuration imx-weim: probe of 21b8000.weim failed with error -22 There is no need to always enable the "weim" node on mx6. Do the same as in the other i.MX dtsi files where "weim" is disabled and only gets enabled on a per dts basis. All the imx6 weim dts users explicitily provide 'status = "okay"', so this change has no impact on current imx6 weim users. If a board does not use the weim driver it will not describe its 'ranges' property, so simply disable the 'weim' node in the imx6 dtsi files to avoid such probe error message. Fixes: 1be81ea5860744520 ("ARM: dts: imx6: Add imx-weim parameters to dtsi's") Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 1 + arch/arm/boot/dts/imx6sl.dtsi | 1 + arch/arm/boot/dts/imx6sx.dtsi | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 53e6e63cbb02..89b834f3fa17 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1100,6 +1100,7 @@ weim: weim@021b8000 { interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_EIM_SLOW>; fsl,weim-cs-gpr = <&gpr>; + status = "disabled"; }; ocotp: ocotp@021bc000 { diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 4fd6de29f07d..19cbd879c448 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -900,6 +900,7 @@ weim: weim@021b8000 { reg = <0x021b8000 0x4000>; interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>; fsl,weim-cs-gpr = <&gpr>; + status = "disabled"; }; ocotp: ocotp@021bc000 { diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 076a30f9bcae..10f333016197 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -977,6 +977,7 @@ weim: weim@021b8000 { interrupts = ; clocks = <&clks IMX6SX_CLK_EIM_SLOW>; fsl,weim-cs-gpr = <&gpr>; + status = "disabled"; }; ocotp: ocotp@021bc000 { From 8581f1b5ee0837e55197f036406bc99746ac94b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 20 Dec 2016 18:51:17 +0200 Subject: [PATCH 214/359] drm/i915: Force VDD off on the new power seqeuencer before starting to use it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently some VLV BIOSen like to leave the VDD force bit enabled even for power seqeuncers that aren't properly hooked up to any port. That will result in a imbalance in the AUX power domain refcount when we stat to use said power sequencer as edp_panel_vdd_on() will not grab the power domain reference if it sees that the VDD is already on. To fix this let's make sure we turn off the VDD force bit when we initialize the power sequencer registers. That is, unless it's being done from the init path since there we are actually initializing the registers for the current power sequencer and we don't want to turn VDD off needlessly as that would require waiting for the power cycle delay before we turn it back on. This fixes the following kind of warnings: WARNING: CPU: 0 PID: 123 at ../drivers/gpu/drm/i915/intel_runtime_pm.c:1455 intel_display_power_put+0x13a/0x170 [i915]() WARN_ON(!power_domains->domain_use_count[domain]) ... v2: Fix typos in comment (David) Cc: stable@vger.kernel.org Cc: Matwey V. Kornilov Tested-by: Matwey V. Kornilov Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98695 Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/20161220165117.24801-1-ville.syrjala@linux.intel.com Reviewed-by: David Weinehall (cherry picked from commit 5d5ab2d26f32bdaa5872b938658e0bf8d341bc4c) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dp.c | 41 +++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d9bc19be855e..0b8e8eb85c19 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -355,7 +355,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, struct intel_dp *intel_dp); static void intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, - struct intel_dp *intel_dp); + struct intel_dp *intel_dp, + bool force_disable_vdd); static void intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp); @@ -516,7 +517,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) /* init power sequencer on this pipe and port */ intel_dp_init_panel_power_sequencer(dev, intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true); /* * Even vdd force doesn't work until we've made @@ -553,7 +554,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp) * Only the HW needs to be reprogrammed, the SW state is fixed and * has been setup during connector init. */ - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); return 0; } @@ -636,7 +637,7 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) port_name(port), pipe_name(intel_dp->pps_pipe)); intel_dp_init_panel_power_sequencer(dev, intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); } void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) @@ -2912,7 +2913,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) /* init power sequencer on this pipe and port */ intel_dp_init_panel_power_sequencer(dev, intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true); } static void vlv_pre_enable_dp(struct intel_encoder *encoder, @@ -5055,7 +5056,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, static void intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, - struct intel_dp *intel_dp) + struct intel_dp *intel_dp, + bool force_disable_vdd) { struct drm_i915_private *dev_priv = to_i915(dev); u32 pp_on, pp_off, pp_div, port_sel = 0; @@ -5068,6 +5070,31 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, intel_pps_get_registers(dev_priv, intel_dp, ®s); + /* + * On some VLV machines the BIOS can leave the VDD + * enabled even on power seqeuencers which aren't + * hooked up to any port. This would mess up the + * power domain tracking the first time we pick + * one of these power sequencers for use since + * edp_panel_vdd_on() would notice that the VDD was + * already on and therefore wouldn't grab the power + * domain reference. Disable VDD first to avoid this. + * This also avoids spuriously turning the VDD on as + * soon as the new power seqeuencer gets initialized. + */ + if (force_disable_vdd) { + u32 pp = ironlake_get_pp_control(intel_dp); + + WARN(pp & PANEL_POWER_ON, "Panel power already on\n"); + + if (pp & EDP_FORCE_VDD) + DRM_DEBUG_KMS("VDD already on, disabling first\n"); + + pp &= ~EDP_FORCE_VDD; + + I915_WRITE(regs.pp_ctrl, pp); + } + pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | (seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT); pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) | @@ -5122,7 +5149,7 @@ static void intel_dp_pps_init(struct drm_device *dev, vlv_initial_power_sequencer_setup(intel_dp); } else { intel_dp_init_panel_power_sequencer(dev, intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); } } From 00b2b7288299a8c73c0c37b531a075ba5c849e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 20 Dec 2016 17:39:02 +0200 Subject: [PATCH 215/359] drm/i915: Move the min_pixclk[] handling to the end of readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to determine the pixel rate of the pipe can't be done until we know the clock, which means it can't be done until the encoder .get_config() hooks have been called. So let's move the min_pixclk[] stuff to the end of intel_modeset_readout_hw_state() when we actually have gathered all the required infromation. Cc: Maarten Lankhorst Cc: Mika Kahola Cc: Ander Conselvan de Oliveira Fixes: 565602d7501a ("drm/i915: Do not acquire crtc state to check clock during modeset, v4.") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/20161220153902.15621-1-ville.syrjala@linux.intel.com Reviewed-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst (cherry picked from commit aca1ebf491518910df156f3dab6a66306bb52e28) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6daad8613760..3dc8724df400 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -16791,7 +16791,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) for_each_intel_crtc(dev, crtc) { struct intel_crtc_state *crtc_state = crtc->config; - int pixclk = 0; __drm_atomic_helper_crtc_destroy_state(&crtc_state->base); memset(crtc_state, 0, sizeof(*crtc_state)); @@ -16803,23 +16802,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) crtc->base.enabled = crtc_state->base.enable; crtc->active = crtc_state->base.active; - if (crtc_state->base.active) { + if (crtc_state->base.active) dev_priv->active_crtcs |= 1 << crtc->pipe; - if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - pixclk = ilk_pipe_pixel_rate(crtc_state); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - pixclk = crtc_state->base.adjusted_mode.crtc_clock; - else - WARN_ON(dev_priv->display.modeset_calc_cdclk); - - /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ - if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) - pixclk = DIV_ROUND_UP(pixclk * 100, 95); - } - - dev_priv->min_pixclk[crtc->pipe] = pixclk; - readout_plane_state(crtc); DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n", @@ -16892,6 +16877,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) } for_each_intel_crtc(dev, crtc) { + int pixclk = 0; + crtc->base.hwmode = crtc->config->base.adjusted_mode; memset(&crtc->base.mode, 0, sizeof(crtc->base.mode)); @@ -16919,10 +16906,23 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) */ crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED; + if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) + pixclk = ilk_pipe_pixel_rate(crtc->config); + else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + pixclk = crtc->config->base.adjusted_mode.crtc_clock; + else + WARN_ON(dev_priv->display.modeset_calc_cdclk); + + /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ + if (IS_BROADWELL(dev_priv) && crtc->config->ips_enabled) + pixclk = DIV_ROUND_UP(pixclk * 100, 95); + drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode); update_scanline_offset(crtc); } + dev_priv->min_pixclk[crtc->pipe] = pixclk; + intel_pipe_config_sanity_check(dev_priv, crtc->config); } } From a6d3e7d35d088b2aabad1688b740e17bfdf566c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 21 Dec 2016 16:45:47 +0200 Subject: [PATCH 216/359] drm/i915: Initialize overlay->last_flip properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize overlay->last_flip properly instead of leaving it zeroed. Cc: stable@vger.kernel.org Cc: Chris Wilson Fixes: 0d9bdd886f29 ("drm/i915: Convert intel_overlay to request tracking") Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/20161221144547.27319-1-ville.syrjala@linux.intel.com (cherry picked from commit 330afdb1df0f3fb48583105493a8f4f8d9e3af36) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_overlay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index fd0e4dac7cc1..ef7dfea40242 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1430,6 +1430,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) overlay->contrast = 75; overlay->saturation = 146; + init_request_active(&overlay->last_flip, NULL); + regs = intel_overlay_map_regs(overlay); if (!regs) goto out_unpin_bo; From b72eb5ffa6d8601d9ba72619d75fb5b27723743a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 7 Dec 2016 17:56:47 +0000 Subject: [PATCH 217/359] drm/i915: Fix oopses in the overlay code due to i915_gem_active stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i915_gem_active stuff doesn't like a NULL ->retire hook, but the overlay code can set it to NULL. That obviously ends up oopsing. Fix it by introducing a new helper to assign the retirement callback that will switch out the NULL function pointer with i915_gem_retire_noop. Cc: stable@vger.kernel.org Cc: Chris Wilson Cc: Joonas Lahtinen Fixes: 0d9bdd886f29 ("drm/i915: Convert intel_overlay to request tracking") Signed-off-by: Ville Syrjälä Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/20161207175647.10018-1-chris@chris-wilson.co.uk (cherry picked from commit ecd9caa0522db5a6b03ac8858c42067ef9d8323b) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_request.h | 19 +++++++++++++++++++ drivers/gpu/drm/i915/intel_overlay.c | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index e2b077df2da0..d229f47d1028 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h @@ -413,6 +413,25 @@ i915_gem_active_set(struct i915_gem_active *active, rcu_assign_pointer(active->request, request); } +/** + * i915_gem_active_set_retire_fn - updates the retirement callback + * @active - the active tracker + * @fn - the routine called when the request is retired + * @mutex - struct_mutex used to guard retirements + * + * i915_gem_active_set_retire_fn() updates the function pointer that + * is called when the final request associated with the @active tracker + * is retired. + */ +static inline void +i915_gem_active_set_retire_fn(struct i915_gem_active *active, + i915_gem_retire_fn fn, + struct mutex *mutex) +{ + lockdep_assert_held(mutex); + active->retire = fn ?: i915_gem_retire_noop; +} + static inline struct drm_i915_gem_request * __i915_gem_active_peek(const struct i915_gem_active *active) { diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index ef7dfea40242..57ef9c88843c 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -216,7 +216,8 @@ static void intel_overlay_submit_request(struct intel_overlay *overlay, { GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip, &overlay->i915->drm.struct_mutex)); - overlay->last_flip.retire = retire; + i915_gem_active_set_retire_fn(&overlay->last_flip, retire, + &overlay->i915->drm.struct_mutex); i915_gem_active_set(&overlay->last_flip, req); i915_add_request(req); } From 9169757ae67bc927750ae907624e65cc15b4fe5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 7 Dec 2016 19:28:03 +0200 Subject: [PATCH 218/359] drm/i915: Fix oops in overlay due to frontbuffer tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vma will be NULL if the overlay was previously off, so dereferencing it will oops. Check for NULL before doing that. Cc: stable@vger.kernel.org Cc: Chris Wilson Cc: Joonas Lahtinen Fixes: 9b3b7841b86d ("drm/i915/overlay: Use VMA as the primary tracker for images") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1481131693-27993-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson (cherry picked from commit 4a15cdbbc55463e55a7cdcf33f84ccc742ca9c29) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_overlay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 57ef9c88843c..e589e17876dc 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -840,8 +840,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret) goto out_unpin; - i915_gem_track_fb(overlay->vma->obj, new_bo, - INTEL_FRONTBUFFER_OVERLAY(pipe)); + i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL, + vma->obj, INTEL_FRONTBUFFER_OVERLAY(pipe)); overlay->old_vma = overlay->vma; overlay->vma = vma; From c3f923b5545306570eff00d11ca051bd67699a23 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Dec 2016 14:57:57 +0000 Subject: [PATCH 219/359] drm/i915: Don't clflush before release phys object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we teardown the backing storage for the phys object, we copy from the coherent contiguous block back to the shmemfs object, clflushing as we go. Trying to clflush the invalid sg beforehand just oops and would be redundant (due to it already being coherent, and clflushed afterwards). Reported-by: Ville Syrjälä Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/20161223145804.6605-3-chris@chris-wilson.co.uk (cherry picked from commit e5facdf9644f4490520e0489a0252e8feaba3744) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4a31b7a891ec..30a1322c8677 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -244,14 +244,16 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) static void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, - struct sg_table *pages) + struct sg_table *pages, + bool needs_clflush) { GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED); if (obj->mm.madv == I915_MADV_DONTNEED) obj->mm.dirty = false; - if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 && + if (needs_clflush && + (obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 && !cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) drm_clflush_sg(pages); @@ -263,7 +265,7 @@ static void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, struct sg_table *pages) { - __i915_gem_object_release_shmem(obj, pages); + __i915_gem_object_release_shmem(obj, pages, false); if (obj->mm.dirty) { struct address_space *mapping = obj->base.filp->f_mapping; @@ -2231,7 +2233,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj, struct sgt_iter sgt_iter; struct page *page; - __i915_gem_object_release_shmem(obj, pages); + __i915_gem_object_release_shmem(obj, pages, true); i915_gem_gtt_finish_pages(obj, pages); From 64d1461ce0c3b8ecc1c6b61f4ad1c1d10ce971a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Dec 2016 14:57:58 +0000 Subject: [PATCH 220/359] drm/i915: Silence allocation failure during sg_trim() As trimming the sg table is merely an optimisation that gracefully fails if we cannot allocate a new table, we do not need to report the failure either. Fixes: 0c40ce130e38 ("drm/i915: Trim the object sg table") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/20161223145804.6605-4-chris@chris-wilson.co.uk (cherry picked from commit 8bfc478fa455b4908f745df368355b415460c60e) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 30a1322c8677..5d146f9f4aad 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2324,7 +2324,7 @@ static void i915_sg_trim(struct sg_table *orig_st) if (orig_st->nents == orig_st->orig_nents) return; - if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL)) + if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN)) return; new_sg = new_st.sgl; From 2471eb5fb6e1433e28426ece235e3730348019ec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Dec 2016 14:58:04 +0000 Subject: [PATCH 221/359] drm/i915: Prevent timeline updates whilst performing reset As the fence may be signaled concurrently from an interrupt on another device, it is possible for the list of requests on the timeline to be modified as we walk it. Take both (the context's timeline and the global timeline) locks to prevent such modifications. Fixes: 80b204bce8f2 ("drm/i915: Enable multiple timelines") Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Mika Kuoppala Cc: Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/20161223145804.6605-10-chris@chris-wilson.co.uk (cherry picked from commit 00c25e3f40083a6d5f1111955baccd287ee49258) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5d146f9f4aad..1e505d30b71e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2730,6 +2730,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) struct drm_i915_gem_request *request; struct i915_gem_context *incomplete_ctx; struct intel_timeline *timeline; + unsigned long flags; bool ring_hung; if (engine->irq_seqno_barrier) @@ -2765,13 +2766,20 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) if (i915_gem_context_is_default(incomplete_ctx)) return; + timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine); + + spin_lock_irqsave(&engine->timeline->lock, flags); + spin_lock(&timeline->lock); + list_for_each_entry_continue(request, &engine->timeline->requests, link) if (request->ctx == incomplete_ctx) reset_request(request); - timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine); list_for_each_entry(request, &timeline->requests, link) reset_request(request); + + spin_unlock(&timeline->lock); + spin_unlock_irqrestore(&engine->timeline->lock, flags); } void i915_gem_reset(struct drm_i915_private *dev_priv) From e2eb31d72156c58b717396383496a7c93aa01b75 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 3 Jan 2017 11:58:32 +0900 Subject: [PATCH 222/359] ALSA: fireworks: fix asymmetric API call at unit removal ALSA fireworks driver has a bug not to call an API to destroy 'cmp_connection' structure for input direction. Currently this causes no issues because it just destroys 'mutex' structure, while it's better to fix it for future work. Fix: d23c2cc4485d ("ALSA: fireworks/bebob/dice/oxfw: allow stream destructor after releasing runtime") Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/fireworks/fireworks_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index ee47924aef0d..827161bc269c 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -117,7 +117,7 @@ destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) conn = &efw->in_conn; amdtp_stream_destroy(stream); - cmp_connection_destroy(&efw->out_conn); + cmp_connection_destroy(conn); } static int From 6a2a2f45560a9cb7bc49820883b042e44f83726c Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 3 Jan 2017 11:58:33 +0900 Subject: [PATCH 223/359] ALSA: firewire-tascam: Fix to handle error from initialization of stream data This module has a bug not to return error code in a case that data structure for transmitted packets fails to be initialized. This commit fixes the bug. Fixes: 35efa5c489de ("ALSA: firewire-tascam: add streaming functionality") Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/tascam/tascam-stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c index 4ad3bd7fd445..f1657a4e0621 100644 --- a/sound/firewire/tascam/tascam-stream.c +++ b/sound/firewire/tascam/tascam-stream.c @@ -343,7 +343,7 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm) if (err < 0) amdtp_stream_destroy(&tscm->rx_stream); - return 0; + return err; } /* At bus reset, streaming is stopped and some registers are clear. */ From 6b7e95d1336b9eb0d4c6db190ce756480496bd13 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 3 Jan 2017 11:58:34 +0900 Subject: [PATCH 224/359] ALSA: firewire-lib: change structure member with proper type The 'amdtp_stream' structure is initialized by a call of 'amdtp_stream_init()'. Although a parameter of this function is for bit flags of packet attributes, its type is enumerator. This commit changes the type so that it's proper for a bit flags. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/amdtp-stream.c | 2 +- sound/firewire/amdtp-stream.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 00060c4a9deb..8ce93cdc4b0d 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -69,7 +69,7 @@ static void pcm_period_tasklet(unsigned long data); * @protocol_size: the size to allocate newly for protocol */ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, - enum amdtp_stream_direction dir, enum cip_flags flags, + enum amdtp_stream_direction dir, int flags, unsigned int fmt, amdtp_stream_process_data_blocks_t process_data_blocks, unsigned int protocol_size) diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index c1bc7fad056e..7be21429cd12 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -93,7 +93,7 @@ typedef unsigned int (*amdtp_stream_process_data_blocks_t)( unsigned int *syt); struct amdtp_stream { struct fw_unit *unit; - enum cip_flags flags; + int flags; enum amdtp_stream_direction direction; struct mutex mutex; @@ -137,7 +137,7 @@ struct amdtp_stream { }; int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, - enum amdtp_stream_direction dir, enum cip_flags flags, + enum amdtp_stream_direction dir, int flags, unsigned int fmt, amdtp_stream_process_data_blocks_t process_data_blocks, unsigned int protocol_size); From 9418ee15f718939aa7e650fd586d73765eb21f20 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 3 Jan 2017 14:32:09 +0200 Subject: [PATCH 225/359] usb: dwc3: gadget: Fix full speed mode DCFG.DEVSPD == 0x3 is not valid and we need to set DCFG.DEVSPD to 0x1 for full speed mode. Same goes for DSTS.CONNECTSPD. Old databooks had 0x3 for full speed in 48MHz mode for USB1.1 transceivers which was never supported. Newer databooks don't mention 0x3 at all. Cc: John Youn Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 6 ++---- drivers/usb/dwc3/gadget.c | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 7bf8016e1182..14b760209680 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -309,9 +309,8 @@ #define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */ #define DWC3_DCFG_SUPERSPEED (4 << 0) #define DWC3_DCFG_HIGHSPEED (0 << 0) -#define DWC3_DCFG_FULLSPEED2 (1 << 0) +#define DWC3_DCFG_FULLSPEED (1 << 0) #define DWC3_DCFG_LOWSPEED (2 << 0) -#define DWC3_DCFG_FULLSPEED1 (3 << 0) #define DWC3_DCFG_NUMP_SHIFT 17 #define DWC3_DCFG_NUMP(n) (((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f) @@ -403,9 +402,8 @@ #define DWC3_DSTS_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */ #define DWC3_DSTS_SUPERSPEED (4 << 0) #define DWC3_DSTS_HIGHSPEED (0 << 0) -#define DWC3_DSTS_FULLSPEED2 (1 << 0) +#define DWC3_DSTS_FULLSPEED (1 << 0) #define DWC3_DSTS_LOWSPEED (2 << 0) -#define DWC3_DSTS_FULLSPEED1 (3 << 0) /* Device Generic Command Register */ #define DWC3_DGCMD_SET_LMP 0x01 diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 725b13ad220d..204c754cc647 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1720,7 +1720,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) reg |= DWC3_DCFG_LOWSPEED; break; case USB_SPEED_FULL: - reg |= DWC3_DCFG_FULLSPEED1; + reg |= DWC3_DCFG_FULLSPEED; break; case USB_SPEED_HIGH: reg |= DWC3_DCFG_HIGHSPEED; @@ -2536,8 +2536,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) dwc->gadget.ep0->maxpacket = 64; dwc->gadget.speed = USB_SPEED_HIGH; break; - case DWC3_DSTS_FULLSPEED2: - case DWC3_DSTS_FULLSPEED1: + case DWC3_DSTS_FULLSPEED: dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); dwc->gadget.ep0->maxpacket = 64; dwc->gadget.speed = USB_SPEED_FULL; From 43aef5c2ca90535b3227e97e71604291875444ed Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 2 Jan 2017 17:28:39 -0600 Subject: [PATCH 226/359] usb: gadget: Fix copy/pasted error message This fixes an error message that was probably copied and pasted. The same message is used for both the in and out endpoints, so it makes it impossible to know which one actually failed because both cases say "IN". Make the out endpoint error message say "OUT". Signed-off-by: David Lechner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 3151d2a0fe59..5f8139b8e601 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -593,7 +593,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } status = usb_ep_enable(hidg->out_ep); if (status < 0) { - ERROR(cdev, "Enable IN endpoint FAILED!\n"); + ERROR(cdev, "Enable OUT endpoint FAILED!\n"); goto fail; } hidg->out_ep->driver_data = hidg; From f9751a60f17eb09e1d1bd036daaddc3ea3a8bed6 Mon Sep 17 00:00:00 2001 From: Shyam Saini Date: Sat, 24 Dec 2016 14:22:46 +0530 Subject: [PATCH 227/359] xen: events: Replace BUG() with BUG_ON() Replace BUG() with BUG_ON() using coccinelle Signed-off-by: Shyam Saini Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/xen/events/events_fifo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c index 7ef27c6ed72f..71224abdd9f9 100644 --- a/drivers/xen/events/events_fifo.c +++ b/drivers/xen/events/events_fifo.c @@ -369,8 +369,7 @@ static void evtchn_fifo_resume(void) } ret = init_control_block(cpu, control_block); - if (ret < 0) - BUG(); + BUG_ON(ret < 0); } /* From 8f87e626b059f1b82b017f53c5ee91fbc4486e36 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 2 Jan 2017 12:56:02 +0100 Subject: [PATCH 228/359] net: stmmac: dwmac-oxnas: fix of-node leak Use the syscon lookup-by-phandle helper so that the reference taken by of_parse_phandle() is released when done with the node. Fixes: 5ed7414062e7 ("net: stmmac: Add OXNAS Glue Driver") Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c index c35597586121..fcc237e0aae1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c @@ -109,16 +109,9 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; - struct device_node *sysctrl; struct oxnas_dwmac *dwmac; int ret; - sysctrl = of_parse_phandle(pdev->dev.of_node, "oxsemi,sys-ctrl", 0); - if (!sysctrl) { - dev_err(&pdev->dev, "failed to get sys-ctrl node\n"); - return -EINVAL; - } - ret = stmmac_get_platform_resources(pdev, &stmmac_res); if (ret) return ret; @@ -134,7 +127,8 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) dwmac->dev = &pdev->dev; plat_dat->bsp_priv = dwmac; - dwmac->regmap = syscon_node_to_regmap(sysctrl); + dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "oxsemi,sys-ctrl"); if (IS_ERR(dwmac->regmap)) { dev_err(&pdev->dev, "failed to have sysctrl regmap\n"); return PTR_ERR(dwmac->regmap); From 6b4c212b95ce6a586473a772fb2d28ab22a38f0e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 2 Jan 2017 12:56:03 +0100 Subject: [PATCH 229/359] net: stmmac: dwmac-oxnas: fix fixed-link-phydev leaks Make sure to deregister and free any fixed-link phy registered during probe on probe errors and on driver unbind by calling the new glue helper function. For driver unbind, use the generic stmmac-platform remove implementation and add an exit callback to disable the clock. Fixes: 5ed7414062e7 ("net: stmmac: Add OXNAS Glue Driver") Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c index fcc237e0aae1..3efd110613df 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c @@ -105,6 +105,13 @@ static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac) return 0; } +static void oxnas_dwmac_exit(struct platform_device *pdev, void *priv) +{ + struct oxnas_dwmac *dwmac = priv; + + clk_disable_unprepare(dwmac->clk); +} + static int oxnas_dwmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; @@ -121,40 +128,44 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) return PTR_ERR(plat_dat); dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); - if (!dwmac) - return -ENOMEM; + if (!dwmac) { + ret = -ENOMEM; + goto err_remove_config_dt; + } dwmac->dev = &pdev->dev; plat_dat->bsp_priv = dwmac; + plat_dat->exit = oxnas_dwmac_exit; dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "oxsemi,sys-ctrl"); if (IS_ERR(dwmac->regmap)) { dev_err(&pdev->dev, "failed to have sysctrl regmap\n"); - return PTR_ERR(dwmac->regmap); + ret = PTR_ERR(dwmac->regmap); + goto err_remove_config_dt; } dwmac->clk = devm_clk_get(&pdev->dev, "gmac"); - if (IS_ERR(dwmac->clk)) - return PTR_ERR(dwmac->clk); + if (IS_ERR(dwmac->clk)) { + ret = PTR_ERR(dwmac->clk); + goto err_remove_config_dt; + } ret = oxnas_dwmac_init(dwmac); if (ret) - return ret; + goto err_remove_config_dt; ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) - clk_disable_unprepare(dwmac->clk); + goto err_dwmac_exit; - return ret; -} -static int oxnas_dwmac_remove(struct platform_device *pdev) -{ - struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev); - int ret = stmmac_dvr_remove(&pdev->dev); + return 0; - clk_disable_unprepare(dwmac->clk); +err_dwmac_exit: + oxnas_dwmac_exit(pdev, plat_dat->bsp_priv); +err_remove_config_dt: + stmmac_remove_config_dt(pdev, plat_dat); return ret; } @@ -197,7 +208,7 @@ MODULE_DEVICE_TABLE(of, oxnas_dwmac_match); static struct platform_driver oxnas_dwmac_driver = { .probe = oxnas_dwmac_probe, - .remove = oxnas_dwmac_remove, + .remove = stmmac_pltfr_remove, .driver = { .name = "oxnas-dwmac", .pm = &oxnas_dwmac_pm_ops, From a8de4d719dfc12bc22192d7daef7c7ae6cfb8b80 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 2 Jan 2017 12:56:04 +0100 Subject: [PATCH 230/359] net: stmmac: dwmac-oxnas: use generic pm implementation Now that we have an exit callback in place, add init as well and get rid of the custom PM callbacks in favour of the generic ones. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 38 +++---------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c index 3efd110613df..3dc7d279f805 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c @@ -60,8 +60,9 @@ struct oxnas_dwmac { struct regmap *regmap; }; -static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac) +static int oxnas_dwmac_init(struct platform_device *pdev, void *priv) { + struct oxnas_dwmac *dwmac = priv; unsigned int value; int ret; @@ -135,6 +136,7 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) dwmac->dev = &pdev->dev; plat_dat->bsp_priv = dwmac; + plat_dat->init = oxnas_dwmac_init; plat_dat->exit = oxnas_dwmac_exit; dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, @@ -151,7 +153,7 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) goto err_remove_config_dt; } - ret = oxnas_dwmac_init(dwmac); + ret = oxnas_dwmac_init(pdev, plat_dat->bsp_priv); if (ret) goto err_remove_config_dt; @@ -170,36 +172,6 @@ static int oxnas_dwmac_probe(struct platform_device *pdev) return ret; } -#ifdef CONFIG_PM_SLEEP -static int oxnas_dwmac_suspend(struct device *dev) -{ - struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(dev); - int ret; - - ret = stmmac_suspend(dev); - clk_disable_unprepare(dwmac->clk); - - return ret; -} - -static int oxnas_dwmac_resume(struct device *dev) -{ - struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(dev); - int ret; - - ret = oxnas_dwmac_init(dwmac); - if (ret) - return ret; - - ret = stmmac_resume(dev); - - return ret; -} -#endif /* CONFIG_PM_SLEEP */ - -static SIMPLE_DEV_PM_OPS(oxnas_dwmac_pm_ops, - oxnas_dwmac_suspend, oxnas_dwmac_resume); - static const struct of_device_id oxnas_dwmac_match[] = { { .compatible = "oxsemi,ox820-dwmac" }, { } @@ -211,7 +183,7 @@ static struct platform_driver oxnas_dwmac_driver = { .remove = stmmac_pltfr_remove, .driver = { .name = "oxnas-dwmac", - .pm = &oxnas_dwmac_pm_ops, + .pm = &stmmac_pltfr_pm_ops, .of_match_table = oxnas_dwmac_match, }, }; From 515028fe29d84a15f77d071a13b2d34eb3d137af Mon Sep 17 00:00:00 2001 From: Bartosz Folta Date: Mon, 2 Jan 2017 12:41:50 +0000 Subject: [PATCH 231/359] net: macb: Updated resource allocation function calls to new version of API. Changed function calls of resource allocation to new API. Changed way of setting DMA mask. Removed unnecessary sanity check. This patch is sent in regard to recently applied patch Commit 83a77e9ec4150ee4acc635638f7dedd9da523a26 net: macb: Added PCI wrapper for Platform Driver. Signed-off-by: Bartosz Folta Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb_pci.c | 27 +++++++++---------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_pci.c b/drivers/net/ethernet/cadence/macb_pci.c index 92be2cd8f817..9906fda76087 100644 --- a/drivers/net/ethernet/cadence/macb_pci.c +++ b/drivers/net/ethernet/cadence/macb_pci.c @@ -1,5 +1,5 @@ /** - * macb_pci.c - Cadence GEM PCI wrapper. + * Cadence GEM PCI wrapper. * * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com * @@ -45,32 +45,27 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct macb_platform_data plat_data; struct resource res[2]; - /* sanity check */ - if (!id) - return -EINVAL; - /* enable pci device */ - err = pci_enable_device(pdev); + err = pcim_enable_device(pdev); if (err < 0) { - dev_err(&pdev->dev, "Enabling PCI device has failed: 0x%04X", - err); - return -EACCES; + dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err); + return err; } pci_set_master(pdev); /* set up resources */ memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); - res[0].start = pdev->resource[0].start; - res[0].end = pdev->resource[0].end; + res[0].start = pci_resource_start(pdev, 0); + res[0].end = pci_resource_end(pdev, 0); res[0].name = PCI_DRIVER_NAME; res[0].flags = IORESOURCE_MEM; - res[1].start = pdev->irq; + res[1].start = pci_irq_vector(pdev, 0); res[1].name = PCI_DRIVER_NAME; res[1].flags = IORESOURCE_IRQ; - dev_info(&pdev->dev, "EMAC physical base addr = 0x%p\n", - (void *)(uintptr_t)pci_resource_start(pdev, 0)); + dev_info(&pdev->dev, "EMAC physical base addr: %pa\n", + &res[0].start); /* set up macb platform data */ memset(&plat_data, 0, sizeof(plat_data)); @@ -100,7 +95,7 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id) plat_info.num_res = ARRAY_SIZE(res); plat_info.data = &plat_data; plat_info.size_data = sizeof(plat_data); - plat_info.dma_mask = DMA_BIT_MASK(32); + plat_info.dma_mask = pdev->dma_mask; /* register platform device */ plat_dev = platform_device_register_full(&plat_info); @@ -120,7 +115,6 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id) clk_unregister(plat_data.pclk); err_pclk_register: - pci_disable_device(pdev); return err; } @@ -130,7 +124,6 @@ static void macb_remove(struct pci_dev *pdev) struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev); platform_device_unregister(plat_dev); - pci_disable_device(pdev); clk_unregister(plat_data->pclk); clk_unregister(plat_data->hclk); } From 5350d54f6cd12eaff623e890744c79b700bd3f17 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 2 Jan 2017 13:32:54 -0800 Subject: [PATCH 232/359] ipv4: Do not allow MAIN to be alias for new LOCAL w/ custom rules In the case of custom rules being present we need to handle the case of the LOCAL table being intialized after the new rule has been added. To address that I am adding a new check so that we can make certain we don't use an alias of MAIN for LOCAL when allocating a new table. Fixes: 0ddcf43d5d4a ("ipv4: FIB Local/MAIN table collapse") Reported-by: Oliver Brunel Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3ff8938893ec..eae0332b0e8c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -85,7 +85,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id) if (tb) return tb; - if (id == RT_TABLE_LOCAL) + if (id == RT_TABLE_LOCAL && !net->ipv4.fib_has_custom_rules) alias = fib_new_table(net, RT_TABLE_MAIN); tb = fib_trie_table(id, alias); From 096de2f83ebc8e0404c5b7e847a4abd27b9739da Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Tue, 3 Jan 2017 16:26:04 +0100 Subject: [PATCH 233/359] benet: stricter vxlan offloading check in be_features_check When VXLAN offloading is enabled, be_features_check() tries to check if an encapsulated packet is indeed a VXLAN packet. The check is not strict enough, and considers any UDP-encapsulated ethernet frame with a 8-byte tunnel header as being VXLAN. Unfortunately, both GENEVE and VXLAN-GPE have a 8-byte header, so they get through this check. Force the UDP destination port to be the one that has been offloaded to hardware. Without this, GENEVE-encapsulated packets can end up having an incorrect checksum when both a GENEVE and a VXLAN (offloaded) tunnel are configured. This is similar to commit a547224dceed ("mlx4e: Do not attempt to offload VXLAN ports that are unrecognized"). Signed-off-by: Sabrina Dubroca Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 7e1633bf5a22..225e9a4877d7 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -5155,7 +5155,9 @@ static netdev_features_t be_features_check(struct sk_buff *skb, skb->inner_protocol_type != ENCAP_TYPE_ETHER || skb->inner_protocol != htons(ETH_P_TEB) || skb_inner_mac_header(skb) - skb_transport_header(skb) != - sizeof(struct udphdr) + sizeof(struct vxlanhdr)) + sizeof(struct udphdr) + sizeof(struct vxlanhdr) || + !adapter->vxlan_port || + udp_hdr(skb)->dest != adapter->vxlan_port) return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); return features; From 3b48ab2248e61408910e792fe84d6ec466084c1a Mon Sep 17 00:00:00 2001 From: Reiter Wolfgang Date: Tue, 3 Jan 2017 01:39:10 +0100 Subject: [PATCH 234/359] drop_monitor: consider inserted data in genlmsg_end Final nlmsg_len field update must reflect inserted net_dm_drop_point data. This patch depends on previous patch: "drop_monitor: add missing call to genlmsg_end" Signed-off-by: Reiter Wolfgang Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/core/drop_monitor.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index f465bad2ef2c..fb55327dcfea 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -102,7 +102,6 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) } msg = nla_data(nla); memset(msg, 0, al); - genlmsg_end(skb, msg_header); goto out; err: @@ -112,6 +111,13 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) swap(data->skb, skb); spin_unlock_irqrestore(&data->lock, flags); + if (skb) { + struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data; + struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlh); + + genlmsg_end(skb, genlmsg_data(gnlh)); + } + return skb; } From e7c9a3d9e432200fd4c17855c2c23ac784d6e833 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 14 Dec 2016 17:13:24 -0800 Subject: [PATCH 235/359] staging: octeon: Call SET_NETDEV_DEV() The Octeon driver calls into PHYLIB which now checks for net_device->dev.parent, so make sure we do set it before calling into any MDIO/PHYLIB related function. Fixes: ec988ad78ed6 ("phy: Don't increment MDIO bus refcount unless it's a different owner") Reported-by: Aaro Koskinen Cc: stable # 4.9+ Signed-off-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 8130dfe89745..4971aa54756a 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -770,6 +770,7 @@ static int cvm_oct_probe(struct platform_device *pdev) /* Initialize the device private structure. */ struct octeon_ethernet *priv = netdev_priv(dev); + SET_NETDEV_DEV(dev, &pdev->dev); dev->netdev_ops = &cvm_oct_pow_netdev_ops; priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED; priv->port = CVMX_PIP_NUM_INPUT_PORTS; @@ -816,6 +817,7 @@ static int cvm_oct_probe(struct platform_device *pdev) } /* Initialize the device private structure. */ + SET_NETDEV_DEV(dev, &pdev->dev); priv = netdev_priv(dev); priv->netdev = dev; priv->of_node = cvm_oct_node_for_port(pip, interface, From ee8665e28e8d90ce69d4abe5a469c14a8707ae0e Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 3 Jan 2017 18:28:43 +0200 Subject: [PATCH 236/359] xhci: free xhci virtual devices with leaf nodes first the tt_info provided by a HS hub might be in use to by a child device Make sure we free the devices in the correct order. This is needed in special cases such as when xhci controller is reset when resuming from hibernate, and all virt_devices are freed. Also free the virt_devices starting from max slot_id as children more commonly have higher slot_id than parent. CC: Reported-by: Guenter Roeck Tested-by: Guenter Roeck Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 38 +++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 321de2e0161b..1dfd1c223cf2 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -979,6 +979,40 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) xhci->devs[slot_id] = NULL; } +/* + * Free a virt_device structure. + * If the virt_device added a tt_info (a hub) and has children pointing to + * that tt_info, then free the child first. Recursive. + * We can't rely on udev at this point to find child-parent relationships. + */ +void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_id) +{ + struct xhci_virt_device *vdev; + struct list_head *tt_list_head; + struct xhci_tt_bw_info *tt_info, *next; + int i; + + vdev = xhci->devs[slot_id]; + if (!vdev) + return; + + tt_list_head = &(xhci->rh_bw[vdev->real_port - 1].tts); + list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { + /* is this a hub device that added a tt_info to the tts list */ + if (tt_info->slot_id == slot_id) { + /* are any devices using this tt_info? */ + for (i = 1; i < HCS_MAX_SLOTS(xhci->hcs_params1); i++) { + vdev = xhci->devs[i]; + if (vdev && (vdev->tt_info == tt_info)) + xhci_free_virt_devices_depth_first( + xhci, i); + } + } + } + /* we are now at a leaf device */ + xhci_free_virt_device(xhci, slot_id); +} + int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags) { @@ -1828,8 +1862,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } } - for (i = 1; i < MAX_HC_SLOTS; ++i) - xhci_free_virt_device(xhci, i); + for (i = HCS_MAX_SLOTS(xhci->hcs_params1); i > 0; i--) + xhci_free_virt_devices_depth_first(xhci, i); dma_pool_destroy(xhci->segment_pool); xhci->segment_pool = NULL; From 90797aee5d6902b49a453c97d83c326408aeb5a8 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 3 Jan 2017 18:28:44 +0200 Subject: [PATCH 237/359] usb: xhci: fix return value of xhci_setup_device() xhci_setup_device() should return failure with correct error number when xhci host has died, removed or halted. During usb device enumeration, if usb host is not accessible (died, removed or halted), the hc_driver->address_device() should return a corresponding error code to usb core. But current xhci driver just returns success. This misleads usb core to continue the enumeration by reading the device descriptor, which will result in failure, and users will get a misleading message like "device descriptor read/8, error -110". Cc: # v4.3+ Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1cd56417cbec..0c8deb9ed42d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3787,8 +3787,10 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, mutex_lock(&xhci->mutex); - if (xhci->xhc_state) /* dying, removing or halted */ + if (xhci->xhc_state) { /* dying, removing or halted */ + ret = -ESHUTDOWN; goto out; + } if (!udev->slot_id) { xhci_dbg_trace(xhci, trace_xhci_dbg_address, From 28bedb5ae463b9f7e5195cbc93f1795e374bdef8 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Tue, 3 Jan 2017 18:28:45 +0200 Subject: [PATCH 238/359] usb: return error code when platform_get_irq fails In function xhci_mtk_probe(), variable ret takes the return value. Its value should be negative on failures. However, when the call to function platform_get_irq() fails, it does not set the error code, and 0 will be returned. 0 indicates no error. As a result, the callers of function xhci_mtk_probe() will not be able to detect the error. This patch fixes the bug by assigning the return value of platform_get_irq() to variable ret if it fails. CC: Signed-off-by: Pan Bian Reviewed-by: Matthias Brugger Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 1094ebd2838f..bac961cd24ad 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -579,8 +579,10 @@ static int xhci_mtk_probe(struct platform_device *pdev) goto disable_ldos; irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (irq < 0) { + ret = irq; goto disable_clk; + } /* Initialize dma_mask and coherent_dma_mask to 32-bits */ ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); From 2b985467371a58ae44d76c7ba12b0951fee6ed98 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 3 Jan 2017 18:28:46 +0200 Subject: [PATCH 239/359] usb: xhci: fix possible wild pointer handle_cmd_completion() frees a command structure which might be still referenced by xhci->current_cmd. This might cause problem when xhci->current_cmd is accessed after that. A real-life case could be like this. The host takes a very long time to respond to a command, and the command timer is fired at the same time when the command completion event arrives. The command completion handler frees xhci->current_cmd before the timer function can grab xhci->lock. Afterward, timer function grabs the lock and go ahead with checking and setting members of xhci->current_cmd. Cc: # v3.16+ Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bdf6b13d9b67..acc37311c938 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1267,14 +1267,18 @@ void xhci_handle_command_timeout(unsigned long data) bool second_timeout = false; xhci = (struct xhci_hcd *) data; - /* mark this command to be cancelled */ spin_lock_irqsave(&xhci->lock, flags); - if (xhci->current_cmd) { - if (xhci->current_cmd->status == COMP_CMD_ABORT) - second_timeout = true; - xhci->current_cmd->status = COMP_CMD_ABORT; + + if (!xhci->current_cmd) { + spin_unlock_irqrestore(&xhci->lock, flags); + return; } + /* mark this command to be cancelled */ + if (xhci->current_cmd->status == COMP_CMD_ABORT) + second_timeout = true; + xhci->current_cmd->status = COMP_CMD_ABORT; + /* Make sure command ring is running before aborting it */ hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && @@ -1422,6 +1426,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, xhci->current_cmd = list_entry(cmd->cmd_list.next, struct xhci_command, cmd_list); mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); + } else if (xhci->current_cmd == cmd) { + xhci->current_cmd = NULL; } event_handled: From 2a7cfdf37b7c08ac29df4c62ea5ccb01474b6597 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Tue, 3 Jan 2017 18:28:47 +0200 Subject: [PATCH 240/359] usb: host: xhci: Fix possible wild pointer when handling abort command When current command was supposed to be aborted, host will free the command in handle_cmd_completion() function. But it might be still referenced by xhci->current_cmd, which need to set NULL. Cc: Signed-off-by: Baolin Wang Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index acc37311c938..bc8be6f6669e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1363,8 +1363,11 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, */ if (cmd_comp_code == COMP_CMD_ABORT) { xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; - if (cmd->status == COMP_CMD_ABORT) + if (cmd->status == COMP_CMD_ABORT) { + if (xhci->current_cmd == cmd) + xhci->current_cmd = NULL; goto event_handled; + } } cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3])); From a5a1b9514154437aa1ed35c291191f82fd3e941a Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 3 Jan 2017 18:28:48 +0200 Subject: [PATCH 241/359] xhci: Handle command completion and timeout race If we get a command completion event at the same time as the command timeout work starts on another cpu we might end up aborting the wrong command. If the command completion takes the xhci lock before the timeout work, it will handle the command, pick the next command, mark it as current_cmd, and re-queue the timeout work. When the timeout work finally gets the lock It will start aborting the wrong command. This case can be resolved by checking if the timeout work is pending inside the timeout function itself. A new timeout work can only be pending if the command completed and a new command was queued. If there are no more commands pending then command completion will set the current_cmd to NULL, which is already handled in the timeout work. Cc: Reported-by: Baolin Wang Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bc8be6f6669e..935193c6bf23 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1269,7 +1269,11 @@ void xhci_handle_command_timeout(unsigned long data) spin_lock_irqsave(&xhci->lock, flags); - if (!xhci->current_cmd) { + /* + * If timeout work is pending, or current_cmd is NULL, it means we + * raced with command completion. Command is handled so just return. + */ + if (!xhci->current_cmd || timer_pending(&xhci->cmd_timer)) { spin_unlock_irqrestore(&xhci->lock, flags); return; } From 4dea70778c0f48b4385c7720c363ec8d37a401b4 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 3 Jan 2017 18:28:49 +0200 Subject: [PATCH 242/359] usb: xhci: hold lock over xhci_abort_cmd_ring() In command timer function, xhci_handle_command_timeout(), xhci->lock is unlocked before call into xhci_abort_cmd_ring(). This might cause race between the timer function and the event handler. The xhci_abort_cmd_ring() function sets the CMD_RING_ABORT bit in the command register and polling it until the setting takes effect. A stop command ring event might be handled between writing the abort bit and polling for it. The event handler will restart the command ring, which causes the failure of polling, and we ever believed that we failed to stop it. As a bonus, this also fixes some issues of calling functions without locking in xhci_handle_command_timeout(). Cc: # 3.7+ Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 935193c6bf23..2f453e442ac7 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1287,29 +1287,34 @@ void xhci_handle_command_timeout(unsigned long data) hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && (hw_ring_state & CMD_RING_RUNNING)) { - spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg(xhci, "Command timeout\n"); ret = xhci_abort_cmd_ring(xhci); if (unlikely(ret == -ESHUTDOWN)) { xhci_err(xhci, "Abort command ring failed\n"); xhci_cleanup_command_queue(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); xhci_dbg(xhci, "xHCI host controller is dead.\n"); + + return; } - return; + + goto time_out_completed; } /* command ring failed to restart, or host removed. Bail out */ if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) { - spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg(xhci, "command timed out twice, ring start fail?\n"); xhci_cleanup_command_queue(xhci); - return; + + goto time_out_completed; } /* command timeout on stopped ring, ring can't be aborted */ xhci_dbg(xhci, "Command timeout on stopped ring\n"); xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd); + +time_out_completed: spin_unlock_irqrestore(&xhci->lock, flags); return; } From cb4d5ce588c5ff68e0fdd30370a0e6bc2c0a736b Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 3 Jan 2017 18:28:50 +0200 Subject: [PATCH 243/359] xhci: Use delayed_work instead of timer for command timeout This is preparation to fix abort operation race (See "xhci: Fix race related to abort operation"). To make timeout sleepable, use delayed_work instead of timer. [change a newly added pending timer fix to pending work -Mathias] Signed-off-by: OGAWA Hirofumi Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 7 +++---- drivers/usb/host/xhci-ring.c | 26 ++++++++++++++++---------- drivers/usb/host/xhci.h | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1dfd1c223cf2..57c038c5afa5 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1829,7 +1829,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) int size; int i, j, num_ports; - del_timer_sync(&xhci->cmd_timer); + cancel_delayed_work_sync(&xhci->cmd_timer); /* Free the Event Ring Segment Table and the actual Event Ring */ size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); @@ -2376,9 +2376,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) INIT_LIST_HEAD(&xhci->cmd_list); - /* init command timeout timer */ - setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout, - (unsigned long)xhci); + /* init command timeout work */ + INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout); page_size = readl(&xhci->op_regs->page_size); xhci_dbg_trace(xhci, trace_xhci_dbg_init, diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2f453e442ac7..fdff6a4cf206 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -279,6 +279,11 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci) readl(&xhci->dba->doorbell[0]); } +static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci, unsigned long delay) +{ + return mod_delayed_work(system_wq, &xhci->cmd_timer, delay); +} + static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) { u64 temp_64; @@ -295,7 +300,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) * but the completion event in never sent. Use the cmd timeout timer to * handle those cases. Use twice the time to cover the bit polling retry */ - mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT)); + xhci_mod_cmd_timer(xhci, 2 * XHCI_CMD_DEFAULT_TIMEOUT); xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); @@ -320,7 +325,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) xhci_err(xhci, "Stopped the command ring failed, " "maybe the host is dead\n"); - del_timer(&xhci->cmd_timer); + cancel_delayed_work(&xhci->cmd_timer); xhci->xhc_state |= XHCI_STATE_DYING; xhci_halt(xhci); return -ESHUTDOWN; @@ -1251,21 +1256,22 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && !(xhci->xhc_state & XHCI_STATE_DYING)) { xhci->current_cmd = cur_cmd; - mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); + xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); xhci_ring_cmd_db(xhci); } return; } -void xhci_handle_command_timeout(unsigned long data) +void xhci_handle_command_timeout(struct work_struct *work) { struct xhci_hcd *xhci; int ret; unsigned long flags; u64 hw_ring_state; bool second_timeout = false; - xhci = (struct xhci_hcd *) data; + + xhci = container_of(to_delayed_work(work), struct xhci_hcd, cmd_timer); spin_lock_irqsave(&xhci->lock, flags); @@ -1273,7 +1279,7 @@ void xhci_handle_command_timeout(unsigned long data) * If timeout work is pending, or current_cmd is NULL, it means we * raced with command completion. Command is handled so just return. */ - if (!xhci->current_cmd || timer_pending(&xhci->cmd_timer)) { + if (!xhci->current_cmd || delayed_work_pending(&xhci->cmd_timer)) { spin_unlock_irqrestore(&xhci->lock, flags); return; } @@ -1346,7 +1352,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); - del_timer(&xhci->cmd_timer); + cancel_delayed_work(&xhci->cmd_timer); trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event); @@ -1437,7 +1443,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, if (cmd->cmd_list.next != &xhci->cmd_list) { xhci->current_cmd = list_entry(cmd->cmd_list.next, struct xhci_command, cmd_list); - mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); + xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); } else if (xhci->current_cmd == cmd) { xhci->current_cmd = NULL; } @@ -3808,9 +3814,9 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, /* if there are no other commands queued we start the timeout timer */ if (xhci->cmd_list.next == &cmd->cmd_list && - !timer_pending(&xhci->cmd_timer)) { + !delayed_work_pending(&xhci->cmd_timer)) { xhci->current_cmd = cmd; - mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); + xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); } queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8ccc11a974b8..b54c486df956 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1568,7 +1568,7 @@ struct xhci_hcd { #define CMD_RING_STATE_STOPPED (1 << 2) struct list_head cmd_list; unsigned int cmd_ring_reserved_trbs; - struct timer_list cmd_timer; + struct delayed_work cmd_timer; struct xhci_command *current_cmd; struct xhci_ring *event_ring; struct xhci_erst erst; @@ -1934,7 +1934,7 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state); void xhci_stop_endpoint_command_watchdog(unsigned long arg); -void xhci_handle_command_timeout(unsigned long data); +void xhci_handle_command_timeout(struct work_struct *work); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); From 1c111b6c3844a142e03bcfc2fa17bfbdea08e9dc Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 3 Jan 2017 18:28:51 +0200 Subject: [PATCH 244/359] xhci: Fix race related to abort operation Current abort operation has race. xhci_handle_command_timeout() xhci_abort_cmd_ring() xhci_write_64(CMD_RING_ABORT) xhci_handshake(5s) do { check CMD_RING_RUNNING udelay(1) ... COMP_CMD_ABORT event COMP_CMD_STOP event xhci_handle_stopped_cmd_ring() restart cmd_ring CMD_RING_RUNNING become 1 again } while () return -ETIMEDOUT xhci_write_64(CMD_RING_ABORT) /* can abort random command */ To do abort operation correctly, we have to wait both of COMP_CMD_STOP event and negation of CMD_RING_RUNNING. But like above, while timeout handler is waiting negation of CMD_RING_RUNNING, event handler can restart cmd_ring. So timeout handler never be notice negation of CMD_RING_RUNNING, and retry of CMD_RING_ABORT can abort random command (BTW, I guess retry of CMD_RING_ABORT was workaround of this race). To fix this race, this moves xhci_handle_stopped_cmd_ring() to xhci_abort_cmd_ring(). And timeout handler waits COMP_CMD_STOP event. At this point, timeout handler is owner of cmd_ring, and safely restart cmd_ring by using xhci_handle_stopped_cmd_ring(). [FWIW, as bonus, this way would be easily extend to add CMD_RING_PAUSE operation] [locks edited as patch is rebased on other locking fixes -Mathias] Signed-off-by: OGAWA Hirofumi Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 1 + drivers/usb/host/xhci-ring.c | 168 ++++++++++++++++++----------------- drivers/usb/host/xhci.h | 1 + 3 files changed, 90 insertions(+), 80 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 57c038c5afa5..8414ed2a02de 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2378,6 +2378,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) /* init command timeout work */ INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout); + init_completion(&xhci->cmd_ring_stop_completion); page_size = readl(&xhci->op_regs->page_size); xhci_dbg_trace(xhci, trace_xhci_dbg_init, diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fdff6a4cf206..7a14e9ad664d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -284,23 +284,71 @@ static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci, unsigned long delay) return mod_delayed_work(system_wq, &xhci->cmd_timer, delay); } -static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) +static struct xhci_command *xhci_next_queued_cmd(struct xhci_hcd *xhci) +{ + return list_first_entry_or_null(&xhci->cmd_list, struct xhci_command, + cmd_list); +} + +/* + * Turn all commands on command ring with status set to "aborted" to no-op trbs. + * If there are other commands waiting then restart the ring and kick the timer. + * This must be called with command ring stopped and xhci->lock held. + */ +static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, + struct xhci_command *cur_cmd) +{ + struct xhci_command *i_cmd; + u32 cycle_state; + + /* Turn all aborted commands in list to no-ops, then restart */ + list_for_each_entry(i_cmd, &xhci->cmd_list, cmd_list) { + + if (i_cmd->status != COMP_CMD_ABORT) + continue; + + i_cmd->status = COMP_CMD_STOP; + + xhci_dbg(xhci, "Turn aborted command %p to no-op\n", + i_cmd->command_trb); + /* get cycle state from the original cmd trb */ + cycle_state = le32_to_cpu( + i_cmd->command_trb->generic.field[3]) & TRB_CYCLE; + /* modify the command trb to no-op command */ + i_cmd->command_trb->generic.field[0] = 0; + i_cmd->command_trb->generic.field[1] = 0; + i_cmd->command_trb->generic.field[2] = 0; + i_cmd->command_trb->generic.field[3] = cpu_to_le32( + TRB_TYPE(TRB_CMD_NOOP) | cycle_state); + + /* + * caller waiting for completion is called when command + * completion event is received for these no-op commands + */ + } + + xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; + + /* ring command ring doorbell to restart the command ring */ + if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && + !(xhci->xhc_state & XHCI_STATE_DYING)) { + xhci->current_cmd = cur_cmd; + xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); + xhci_ring_cmd_db(xhci); + } +} + +/* Must be called with xhci->lock held, releases and aquires lock back */ +static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) { u64 temp_64; int ret; xhci_dbg(xhci, "Abort command ring\n"); - temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); - xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; + reinit_completion(&xhci->cmd_ring_stop_completion); - /* - * Writing the CMD_RING_ABORT bit should cause a cmd completion event, - * however on some host hw the CMD_RING_RUNNING bit is correctly cleared - * but the completion event in never sent. Use the cmd timeout timer to - * handle those cases. Use twice the time to cover the bit polling retry - */ - xhci_mod_cmd_timer(xhci, 2 * XHCI_CMD_DEFAULT_TIMEOUT); + temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); @@ -320,17 +368,30 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) udelay(1000); ret = xhci_handshake(&xhci->op_regs->cmd_ring, CMD_RING_RUNNING, 0, 3 * 1000 * 1000); - if (ret == 0) - return 0; - - xhci_err(xhci, "Stopped the command ring failed, " - "maybe the host is dead\n"); - cancel_delayed_work(&xhci->cmd_timer); - xhci->xhc_state |= XHCI_STATE_DYING; - xhci_halt(xhci); - return -ESHUTDOWN; + if (ret < 0) { + xhci_err(xhci, "Stopped the command ring failed, " + "maybe the host is dead\n"); + xhci->xhc_state |= XHCI_STATE_DYING; + xhci_halt(xhci); + return -ESHUTDOWN; + } + } + /* + * Writing the CMD_RING_ABORT bit should cause a cmd completion event, + * however on some host hw the CMD_RING_RUNNING bit is correctly cleared + * but the completion event in never sent. Wait 2 secs (arbitrary + * number) to handle those cases after negation of CMD_RING_RUNNING. + */ + spin_unlock_irqrestore(&xhci->lock, flags); + ret = wait_for_completion_timeout(&xhci->cmd_ring_stop_completion, + msecs_to_jiffies(2000)); + spin_lock_irqsave(&xhci->lock, flags); + if (!ret) { + xhci_dbg(xhci, "No stop event for abort, ring start fail?\n"); + xhci_cleanup_command_queue(xhci); + } else { + xhci_handle_stopped_cmd_ring(xhci, xhci_next_queued_cmd(xhci)); } - return 0; } @@ -1212,64 +1273,12 @@ void xhci_cleanup_command_queue(struct xhci_hcd *xhci) xhci_complete_del_and_free_cmd(cur_cmd, COMP_CMD_ABORT); } -/* - * Turn all commands on command ring with status set to "aborted" to no-op trbs. - * If there are other commands waiting then restart the ring and kick the timer. - * This must be called with command ring stopped and xhci->lock held. - */ -static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, - struct xhci_command *cur_cmd) -{ - struct xhci_command *i_cmd, *tmp_cmd; - u32 cycle_state; - - /* Turn all aborted commands in list to no-ops, then restart */ - list_for_each_entry_safe(i_cmd, tmp_cmd, &xhci->cmd_list, - cmd_list) { - - if (i_cmd->status != COMP_CMD_ABORT) - continue; - - i_cmd->status = COMP_CMD_STOP; - - xhci_dbg(xhci, "Turn aborted command %p to no-op\n", - i_cmd->command_trb); - /* get cycle state from the original cmd trb */ - cycle_state = le32_to_cpu( - i_cmd->command_trb->generic.field[3]) & TRB_CYCLE; - /* modify the command trb to no-op command */ - i_cmd->command_trb->generic.field[0] = 0; - i_cmd->command_trb->generic.field[1] = 0; - i_cmd->command_trb->generic.field[2] = 0; - i_cmd->command_trb->generic.field[3] = cpu_to_le32( - TRB_TYPE(TRB_CMD_NOOP) | cycle_state); - - /* - * caller waiting for completion is called when command - * completion event is received for these no-op commands - */ - } - - xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; - - /* ring command ring doorbell to restart the command ring */ - if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && - !(xhci->xhc_state & XHCI_STATE_DYING)) { - xhci->current_cmd = cur_cmd; - xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); - xhci_ring_cmd_db(xhci); - } - return; -} - - void xhci_handle_command_timeout(struct work_struct *work) { struct xhci_hcd *xhci; int ret; unsigned long flags; u64 hw_ring_state; - bool second_timeout = false; xhci = container_of(to_delayed_work(work), struct xhci_hcd, cmd_timer); @@ -1283,18 +1292,17 @@ void xhci_handle_command_timeout(struct work_struct *work) spin_unlock_irqrestore(&xhci->lock, flags); return; } - /* mark this command to be cancelled */ - if (xhci->current_cmd->status == COMP_CMD_ABORT) - second_timeout = true; xhci->current_cmd->status = COMP_CMD_ABORT; /* Make sure command ring is running before aborting it */ hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && (hw_ring_state & CMD_RING_RUNNING)) { + /* Prevent new doorbell, and start command abort */ + xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; xhci_dbg(xhci, "Command timeout\n"); - ret = xhci_abort_cmd_ring(xhci); + ret = xhci_abort_cmd_ring(xhci, flags); if (unlikely(ret == -ESHUTDOWN)) { xhci_err(xhci, "Abort command ring failed\n"); xhci_cleanup_command_queue(xhci); @@ -1308,9 +1316,9 @@ void xhci_handle_command_timeout(struct work_struct *work) goto time_out_completed; } - /* command ring failed to restart, or host removed. Bail out */ - if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) { - xhci_dbg(xhci, "command timed out twice, ring start fail?\n"); + /* host removed. Bail out */ + if (xhci->xhc_state & XHCI_STATE_REMOVING) { + xhci_dbg(xhci, "host removed, ring start fail?\n"); xhci_cleanup_command_queue(xhci); goto time_out_completed; @@ -1360,7 +1368,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, /* If CMD ring stopped we own the trbs between enqueue and dequeue */ if (cmd_comp_code == COMP_CMD_STOP) { - xhci_handle_stopped_cmd_ring(xhci, cmd); + complete_all(&xhci->cmd_ring_stop_completion); return; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index b54c486df956..2d7b6374b58d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1569,6 +1569,7 @@ struct xhci_hcd { struct list_head cmd_list; unsigned int cmd_ring_reserved_trbs; struct delayed_work cmd_timer; + struct completion cmd_ring_stop_completion; struct xhci_command *current_cmd; struct xhci_ring *event_ring; struct xhci_erst erst; From 6c97cfc1a097b1e0786c836e92b7a72b4d031e25 Mon Sep 17 00:00:00 2001 From: Wan Ahmad Zainie Date: Tue, 3 Jan 2017 18:28:52 +0200 Subject: [PATCH 245/359] usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Apollo Lake Intel Apollo Lake also requires XHCI_PME_STUCK_QUIRK. Adding its PCI ID to quirk. Cc: Signed-off-by: Wan Ahmad Zainie Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index e96ae80d107e..954abfd5014d 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -165,7 +165,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) { + pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI)) { xhci->quirks |= XHCI_PME_STUCK_QUIRK; } if (pdev->vendor == PCI_VENDOR_ID_INTEL && From 29fc1aa454d0603493b47a8e2410ae6e9ab20258 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 3 Jan 2017 18:28:53 +0200 Subject: [PATCH 246/359] usb: host: xhci: handle COMP_STOP from SETUP phase too Stop Endpoint command can come at any point and we have no control of that. We should make sure to handle COMP_STOP on SETUP phase as well, otherwise urb->actual_length might be set to negative values in some occasions such as below: urb->length = 4; build_control_transfer_td_for(urb, ep); stop_endpoint(ep); COMP_STOP: [...] urb->actual_length = urb->length - trb->length; trb->length is 8 for SETUP stage (8 control request bytes), so actual_length would be set to -4 in this case. While doing that, also make sure to use TRB_TYPE field of the actual TRB instead of matching pointers to figure out in which stage of the control transfer we got our completion event. Cc: Signed-off-by: Felipe Balbi Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7a14e9ad664d..25f522b09dd9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1971,8 +1971,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, struct xhci_ep_ctx *ep_ctx; u32 trb_comp_code; u32 remaining, requested; - bool on_data_stage; + u32 trb_type; + trb_type = TRB_FIELD_TO_TYPE(le32_to_cpu(ep_trb->generic.field[3])); slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); xdev = xhci->devs[slot_id]; ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; @@ -1982,14 +1983,11 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, requested = td->urb->transfer_buffer_length; remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); - /* not setup (dequeue), or status stage means we are at data stage */ - on_data_stage = (ep_trb != ep_ring->dequeue && ep_trb != td->last_trb); - switch (trb_comp_code) { case COMP_SUCCESS: - if (ep_trb != td->last_trb) { + if (trb_type != TRB_STATUS) { xhci_warn(xhci, "WARN: Success on ctrl %s TRB without IOC set?\n", - on_data_stage ? "data" : "setup"); + (trb_type == TRB_DATA) ? "data" : "setup"); *status = -ESHUTDOWN; break; } @@ -1999,15 +1997,25 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, *status = 0; break; case COMP_STOP_SHORT: - if (on_data_stage) + if (trb_type == TRB_DATA || trb_type == TRB_NORMAL) td->urb->actual_length = remaining; else xhci_warn(xhci, "WARN: Stopped Short Packet on ctrl setup or status TRB\n"); goto finish_td; case COMP_STOP: - if (on_data_stage) + switch (trb_type) { + case TRB_SETUP: + td->urb->actual_length = 0; + goto finish_td; + case TRB_DATA: + case TRB_NORMAL: td->urb->actual_length = requested - remaining; - goto finish_td; + goto finish_td; + default: + xhci_warn(xhci, "WARN: unexpected TRB Type %d\n", + trb_type); + goto finish_td; + } case COMP_STOP_INVAL: goto finish_td; default: @@ -2019,7 +2027,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, /* else fall through */ case COMP_STALL: /* Did we transfer part of the data (middle) phase? */ - if (on_data_stage) + if (trb_type == TRB_DATA || trb_type == TRB_NORMAL) td->urb->actual_length = requested - remaining; else if (!td->urb_length_set) td->urb->actual_length = 0; @@ -2027,14 +2035,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, } /* stopped at setup stage, no data transferred */ - if (ep_trb == ep_ring->dequeue) + if (trb_type == TRB_SETUP) goto finish_td; /* * if on data stage then update the actual_length of the URB and flag it * as set, so it won't be overwritten in the event for the last TRB. */ - if (on_data_stage) { + if (trb_type == TRB_DATA || + trb_type == TRB_NORMAL) { td->urb_length_set = true; td->urb->actual_length = requested - remaining; xhci_dbg(xhci, "Waiting for status stage event\n"); From 1cf3df8a9ca73e736404e308b099459948c1e902 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 7 Nov 2016 14:35:50 -0800 Subject: [PATCH 247/359] ARM64: dts: meson-gxl: fix GPIO include Signed-off-by: Kevin Hilman --- arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index 9f89b99c4806..3af54dce3f63 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -43,7 +43,7 @@ #include "meson-gx.dtsi" #include -#include +#include / { compatible = "amlogic,meson-gxl"; From fafdbdf767891081de5f1063c984a94a59bac3c4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 1 Dec 2016 10:05:58 +0100 Subject: [PATCH 248/359] ARM64: dts: meson-gx: Add Graphic Controller nodes Add Video Processing Unit and CVBS Output nodes, and enable CVBS on selected boards. Reviewed-by: Laurent Pinchart Signed-off-by: Neil Armstrong Signed-off-by: Kevin Hilman --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 16 ++++++++++++++++ .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 16 ++++++++++++++++ arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 16 ++++++++++++++++ arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 4 ++++ .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts | 16 ++++++++++++++++ arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 4 ++++ .../boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 16 ++++++++++++++++ arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 4 ++++ 8 files changed, 92 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index fc033c0d2a0f..eada0b58ba1c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -356,5 +356,21 @@ sd_emmc_c: mmc@74000 { status = "disabled"; }; }; + + vpu: vpu@d0100000 { + compatible = "amlogic,meson-gx-vpu"; + reg = <0x0 0xd0100000 0x0 0x100000>, + <0x0 0xc883c000 0x0 0x1000>, + <0x0 0xc8838000 0x0 0x1000>; + reg-names = "vpu", "hhi", "dmc"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + + /* CVBS VDAC output port */ + cvbs_vdac_port: port@0 { + reg = <0>; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts index 969682092e0f..4cbd626a9e88 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts @@ -142,6 +142,16 @@ sdio_pwrseq: sdio-pwrseq { clocks = <&wifi32k>; clock-names = "ext_clock"; }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; }; &uart_AO { @@ -229,3 +239,9 @@ &pwm_ef { clocks = <&clkc CLKID_FCLK_DIV4>; clock-names = "clkin0"; }; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi index 203be28978d5..4a96e0f6f926 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi @@ -125,6 +125,16 @@ sdio_pwrseq: sdio-pwrseq { clocks = <&wifi32k>; clock-names = "ext_clock"; }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; }; /* This UART is brought out to the DB9 connector */ @@ -234,3 +244,9 @@ &pwm_ef { clocks = <&clkc CLKID_FCLK_DIV4>; clock-names = "clkin0"; }; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 51edd5b5c460..596240c38a9c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -506,3 +506,7 @@ &sd_emmc_c { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; + +&vpu { + compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts index e99101ae9664..cea4a3eded9b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts @@ -117,6 +117,16 @@ sdio_pwrseq: sdio-pwrseq { clocks = <&wifi32k>; clock-names = "ext_clock"; }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; }; &uart_AO { @@ -203,3 +213,9 @@ &pwm_ef { clocks = <&clkc CLKID_FCLK_DIV4>; clock-names = "clkin0"; }; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index 3af54dce3f63..69216246275d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -299,3 +299,7 @@ &sd_emmc_c { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; + +&vpu { + compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts index f859d75db8bd..5a337d339df1 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts @@ -90,6 +90,16 @@ emmc_pwrseq: emmc-pwrseq { compatible = "mmc-pwrseq-emmc"; reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; }; + + cvbs-connector { + compatible = "composite-video-connector"; + + port { + cvbs_connector_in: endpoint { + remote-endpoint = <&cvbs_vdac_out>; + }; + }; + }; }; /* This UART is brought out to the DB9 connector */ @@ -167,3 +177,9 @@ external_phy: ethernet-phy@0 { max-speed = <1000>; }; }; + +&cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi index c1974bbbddea..eb2f0c3e5e53 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi @@ -112,3 +112,7 @@ cpu7: cpu@103 { }; }; }; + +&vpu { + compatible = "amlogic,meson-gxm-vpu", "amlogic,meson-gx-vpu"; +}; From fcdaf1a2a7a042a290f4c7de28bcdebd5de18445 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Dec 2016 16:56:23 -0800 Subject: [PATCH 249/359] ARM64: defconfig: enable DRM_MESON as module Signed-off-by: Kevin Hilman --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 869dded0f09f..33b744d54739 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -331,6 +331,7 @@ CONFIG_DRM_VC4=m CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_I2C_ADV7511=m CONFIG_DRM_HISI_KIRIN=m +CONFIG_DRM_MESON=m CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_BACKLIGHT_GENERIC=m From 4309cfe334af9c3565d39e1ce3f9c62183cc67e4 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 3 Jan 2017 12:32:47 +0000 Subject: [PATCH 250/359] drivers: psci: annotate timer on stack to silence odebug messages When DEBUG_OBJECTS config is enabled, we get the below odebug warnings: ODEBUG: object is on stack, but not annotated WARNING: CPU: 3 PID: 1304 at kernel/lib/debugobjects.c:300 __debug_object_init+0x1f0/0x458 CPU: 3 PID: 1304 Comm: psci_suspend_te Tainted: G W 4.9.0-06564-gf80f3f199260 #284 task: ffffe9e1b55a1600 task.stack: ffffe9e1b51c0000 PC is at __debug_object_init+0x1f0/0x458 LR is at __debug_object_init+0x1ec/0x458 Call trace: __debug_object_init+0x1f0/0x458 debug_object_activate+0x150/0x260 mod_timer+0xb4/0x4c0 suspend_test_thread+0x1cc/0x3c0 kthread+0x110/0x140 ret_from_fork+0x10/0x40 This patch annotates the timer on the stack using setup_timer_on_stack function to remove the above warnings. Cc: Kevin Brodsky Cc: Mark Rutland Cc: Lorenzo Pieralisi Signed-off-by: Sudeep Holla Signed-off-by: Lorenzo Pieralisi --- drivers/firmware/psci_checker.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c index 44bdb78f837b..29d58feaf675 100644 --- a/drivers/firmware/psci_checker.c +++ b/drivers/firmware/psci_checker.c @@ -270,8 +270,7 @@ static int suspend_test_thread(void *arg) struct cpuidle_device *dev; struct cpuidle_driver *drv; /* No need for an actual callback, we just want to wake up the CPU. */ - struct timer_list wakeup_timer = - TIMER_INITIALIZER(dummy_callback, 0, 0); + struct timer_list wakeup_timer; /* Wait for the main thread to give the start signal. */ wait_for_completion(&suspend_threads_started); @@ -287,6 +286,7 @@ static int suspend_test_thread(void *arg) pr_info("CPU %d entering suspend cycles, states 1 through %d\n", cpu, drv->state_count - 1); + setup_timer_on_stack(&wakeup_timer, dummy_callback, 0); for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) { int index; /* From 32d53d1baf874caabe66ba565699ed5853fa2b6f Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 3 Jan 2017 12:32:48 +0000 Subject: [PATCH 251/359] MAINTAINERS: extend PSCI entry to cover the newly add PSCI checker code This patch extends the file entry for PSCI so that the newly added PSCI checker module code is also covered. Cc: Mark Rutland Cc: Lorenzo Pieralisi Signed-off-by: Sudeep Holla Signed-off-by: Lorenzo Pieralisi --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index cfff2c9e3d94..c7397bdef186 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9842,7 +9842,7 @@ M: Mark Rutland M: Lorenzo Pieralisi L: linux-arm-kernel@lists.infradead.org S: Maintained -F: drivers/firmware/psci.c +F: drivers/firmware/psci*.c F: include/linux/psci.h F: include/uapi/linux/psci.h From 0b47a6bd1150f4846b1d61925a4cc5a96593a541 Mon Sep 17 00:00:00 2001 From: Jiandi An Date: Tue, 27 Dec 2016 18:47:32 -0600 Subject: [PATCH 252/359] Xen: ARM: Zero reserved fields of xatp before making hypervisor call Ensure all reserved fields of xatp are zero before making hypervisor call to XEN in xen_map_device_mmio(). xenmem_add_to_physmap_one() in XEN fails the mapping request if extra.res reserved field in xatp is not zero for XENMAPSPACE_dev_mmio request. Signed-off-by: Jiandi An Reviewed-by: Stefano Stabellini --- drivers/xen/arm-device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c index 778acf80aacb..85dd20e05726 100644 --- a/drivers/xen/arm-device.c +++ b/drivers/xen/arm-device.c @@ -58,9 +58,13 @@ static int xen_map_device_mmio(const struct resource *resources, xen_pfn_t *gpfns; xen_ulong_t *idxs; int *errs; - struct xen_add_to_physmap_range xatp; for (i = 0; i < count; i++) { + struct xen_add_to_physmap_range xatp = { + .domid = DOMID_SELF, + .space = XENMAPSPACE_dev_mmio + }; + r = &resources[i]; nr = DIV_ROUND_UP(resource_size(r), XEN_PAGE_SIZE); if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0)) @@ -87,9 +91,7 @@ static int xen_map_device_mmio(const struct resource *resources, idxs[j] = XEN_PFN_DOWN(r->start) + j; } - xatp.domid = DOMID_SELF; xatp.size = nr; - xatp.space = XENMAPSPACE_dev_mmio; set_xen_guest_handle(xatp.gpfns, gpfns); set_xen_guest_handle(xatp.idxs, idxs); From 9988f4d577f42f43b7612d755477585f35424af7 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 16 Dec 2016 12:59:31 -0800 Subject: [PATCH 253/359] latent_entropy: fix ARM build error on earlier gcc This fixes build errors seen on gcc-4.9.3 or gcc-5.3.1 for an ARM: arm-soc/init/initramfs.c: In function 'error': arm-soc/init/initramfs.c:50:1: error: unrecognizable insn: } ^ (insn 26 25 27 5 (set (reg:SI 111 [ local_entropy.243 ]) (rotatert:SI (reg:SI 116 [ local_entropy.243 ]) (const_int -30 [0xffffffffffffffe2]))) -1 (nil)) Patch from PaX Team Reported-by: Arnd Bergmann Reported-by: Brad Spengler Cc: stable@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/latent_entropy_plugin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c index 12541126575b..8ff203ad4809 100644 --- a/scripts/gcc-plugins/latent_entropy_plugin.c +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -328,9 +328,9 @@ static enum tree_code get_op(tree *rhs) op = LROTATE_EXPR; /* * This code limits the value of random_const to - * the size of a wide int for the rotation + * the size of a long for the rotation */ - random_const &= HOST_BITS_PER_WIDE_INT - 1; + random_const %= TYPE_PRECISION(long_unsigned_type_node); break; } From 81d873a87114b05dbb74d1fbf0c4322ba4bfdee4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 16 Dec 2016 11:36:06 -0800 Subject: [PATCH 254/359] gcc-plugins: update gcc-common.h for gcc-7 This updates gcc-common.h from Emese Revfy for gcc 7. This fixes issues seen by Kugan and Arnd. Build tested with gcc 5.4 and 7 snapshot. Cc: stable@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/gcc-common.h | 85 ++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 950fd2e64bb7..12262c0cc691 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -39,6 +39,9 @@ #include "hash-map.h" #endif +#if BUILDING_GCC_VERSION >= 7000 +#include "memmodel.h" +#endif #include "emit-rtl.h" #include "debug.h" #include "target.h" @@ -91,6 +94,9 @@ #include "tree-ssa-alias.h" #include "tree-ssa.h" #include "stringpool.h" +#if BUILDING_GCC_VERSION >= 7000 +#include "tree-vrp.h" +#endif #include "tree-ssanames.h" #include "print-tree.h" #include "tree-eh.h" @@ -287,6 +293,22 @@ static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct c return NULL; } +static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable) +{ + cgraph_node_ptr alias; + + if (callback(node, data)) + return true; + + for (alias = node->same_body; alias; alias = alias->next) { + if (include_overwritable || cgraph_function_body_availability(alias) > AVAIL_OVERWRITABLE) + if (cgraph_for_node_and_aliases(alias, callback, data, include_overwritable)) + return true; + } + + return false; +} + #define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \ for ((node) = cgraph_first_function_with_gimple_body(); (node); \ (node) = cgraph_next_function_with_gimple_body(node)) @@ -399,6 +421,7 @@ typedef union gimple_statement_d gassign; typedef union gimple_statement_d gcall; typedef union gimple_statement_d gcond; typedef union gimple_statement_d gdebug; +typedef union gimple_statement_d ggoto; typedef union gimple_statement_d gphi; typedef union gimple_statement_d greturn; @@ -452,6 +475,16 @@ static inline const gdebug *as_a_const_gdebug(const_gimple stmt) return stmt; } +static inline ggoto *as_a_ggoto(gimple stmt) +{ + return stmt; +} + +static inline const ggoto *as_a_const_ggoto(const_gimple stmt) +{ + return stmt; +} + static inline gphi *as_a_gphi(gimple stmt) { return stmt; @@ -496,6 +529,14 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt) typedef struct rtx_def rtx_insn; +static inline const char *get_decl_section_name(const_tree decl) +{ + if (DECL_SECTION_NAME(decl) == NULL_TREE) + return NULL; + + return TREE_STRING_POINTER(DECL_SECTION_NAME(decl)); +} + static inline void set_decl_section_name(tree node, const char *value) { if (value) @@ -511,6 +552,7 @@ typedef struct gimple_statement_base gassign; typedef struct gimple_statement_call gcall; typedef struct gimple_statement_base gcond; typedef struct gimple_statement_base gdebug; +typedef struct gimple_statement_base ggoto; typedef struct gimple_statement_phi gphi; typedef struct gimple_statement_base greturn; @@ -564,6 +606,16 @@ static inline const gdebug *as_a_const_gdebug(const_gimple stmt) return stmt; } +static inline ggoto *as_a_ggoto(gimple stmt) +{ + return stmt; +} + +static inline const ggoto *as_a_const_ggoto(const_gimple stmt) +{ + return stmt; +} + static inline gphi *as_a_gphi(gimple stmt) { return as_a(stmt); @@ -611,6 +663,11 @@ inline bool is_a_helper::test(const_gimple gs) #define INSN_DELETED_P(insn) (insn)->deleted() +static inline const char *get_decl_section_name(const_tree decl) +{ + return DECL_SECTION_NAME(decl); +} + /* symtab/cgraph related */ #define debug_cgraph_node(node) (node)->debug() #define cgraph_get_node(decl) cgraph_node::get(decl) @@ -619,6 +676,7 @@ inline bool is_a_helper::test(const_gimple gs) #define cgraph_n_nodes symtab->cgraph_count #define cgraph_max_uid symtab->cgraph_max_uid #define varpool_get_node(decl) varpool_node::get(decl) +#define dump_varpool_node(file, node) (node)->dump(file) #define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ (caller)->create_edge((callee), (call_stmt), (count), (freq)) @@ -674,6 +732,11 @@ static inline cgraph_node_ptr cgraph_alias_target(cgraph_node_ptr node) return node->get_alias_target(); } +static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable) +{ + return node->call_for_symbol_thunks_and_aliases(callback, data, include_overwritable); +} + static inline struct cgraph_node_hook_list *cgraph_add_function_insertion_hook(cgraph_node_hook hook, void *data) { return symtab->add_cgraph_insertion_hook(hook, data); @@ -729,6 +792,13 @@ static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree l return gimple_build_assign(lhs, subcode, op1, op2 PASS_MEM_STAT); } +template <> +template <> +inline bool is_a_helper::test(const_gimple gs) +{ + return gs->code == GIMPLE_GOTO; +} + template <> template <> inline bool is_a_helper::test(const_gimple gs) @@ -766,6 +836,16 @@ static inline const gcall *as_a_const_gcall(const_gimple stmt) return as_a(stmt); } +static inline ggoto *as_a_ggoto(gimple stmt) +{ + return as_a(stmt); +} + +static inline const ggoto *as_a_const_ggoto(const_gimple stmt) +{ + return as_a(stmt); +} + static inline gphi *as_a_gphi(gimple stmt) { return as_a(stmt); @@ -828,4 +908,9 @@ static inline void debug_gimple_stmt(const_gimple s) #define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s)) #endif +#if BUILDING_GCC_VERSION >= 7000 +#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \ + get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep) +#endif + #endif From be29d20f3f5db1f0b4e49a4f6eeedf840e2bf9b1 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 14 Dec 2016 14:40:05 +0100 Subject: [PATCH 255/359] audit: Fix sleep in atomic Audit tree code was happily adding new notification marks while holding spinlocks. Since fsnotify_add_mark() acquires group->mark_mutex this can lead to sleeping while holding a spinlock, deadlocks due to lock inversion, and probably other fun. Fix the problem by acquiring group->mark_mutex earlier. CC: Paul Moore Signed-off-by: Jan Kara Signed-off-by: Paul Moore --- kernel/audit_tree.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index b4b58400531f..862969014cf6 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -231,9 +231,11 @@ static void untag_chunk(struct node *p) if (size) new = alloc_chunk(size); + mutex_lock(&entry->group->mark_mutex); spin_lock(&entry->lock); if (chunk->dead || !entry->inode) { spin_unlock(&entry->lock); + mutex_unlock(&entry->group->mark_mutex); if (new) free_chunk(new); goto out; @@ -251,6 +253,7 @@ static void untag_chunk(struct node *p) list_del_rcu(&chunk->hash); spin_unlock(&hash_lock); spin_unlock(&entry->lock); + mutex_unlock(&entry->group->mark_mutex); fsnotify_destroy_mark(entry, audit_tree_group); goto out; } @@ -258,8 +261,8 @@ static void untag_chunk(struct node *p) if (!new) goto Fallback; - if (fsnotify_add_mark(&new->mark, - entry->group, entry->inode, NULL, 1)) { + if (fsnotify_add_mark_locked(&new->mark, entry->group, entry->inode, + NULL, 1)) { fsnotify_put_mark(&new->mark); goto Fallback; } @@ -293,6 +296,7 @@ static void untag_chunk(struct node *p) owner->root = new; spin_unlock(&hash_lock); spin_unlock(&entry->lock); + mutex_unlock(&entry->group->mark_mutex); fsnotify_destroy_mark(entry, audit_tree_group); fsnotify_put_mark(&new->mark); /* drop initial reference */ goto out; @@ -309,6 +313,7 @@ static void untag_chunk(struct node *p) put_tree(owner); spin_unlock(&hash_lock); spin_unlock(&entry->lock); + mutex_unlock(&entry->group->mark_mutex); out: fsnotify_put_mark(entry); spin_lock(&hash_lock); @@ -386,18 +391,21 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) chunk_entry = &chunk->mark; + mutex_lock(&old_entry->group->mark_mutex); spin_lock(&old_entry->lock); if (!old_entry->inode) { /* old_entry is being shot, lets just lie */ spin_unlock(&old_entry->lock); + mutex_unlock(&old_entry->group->mark_mutex); fsnotify_put_mark(old_entry); free_chunk(chunk); return -ENOENT; } - if (fsnotify_add_mark(chunk_entry, - old_entry->group, old_entry->inode, NULL, 1)) { + if (fsnotify_add_mark_locked(chunk_entry, old_entry->group, + old_entry->inode, NULL, 1)) { spin_unlock(&old_entry->lock); + mutex_unlock(&old_entry->group->mark_mutex); fsnotify_put_mark(chunk_entry); fsnotify_put_mark(old_entry); return -ENOSPC; @@ -413,6 +421,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) chunk->dead = 1; spin_unlock(&chunk_entry->lock); spin_unlock(&old_entry->lock); + mutex_unlock(&old_entry->group->mark_mutex); fsnotify_destroy_mark(chunk_entry, audit_tree_group); @@ -445,6 +454,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) spin_unlock(&hash_lock); spin_unlock(&chunk_entry->lock); spin_unlock(&old_entry->lock); + mutex_unlock(&old_entry->group->mark_mutex); fsnotify_destroy_mark(old_entry, audit_tree_group); fsnotify_put_mark(chunk_entry); /* drop initial reference */ fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ From 7158339d4c1ede786c48fa5c062fa68df366ba94 Mon Sep 17 00:00:00 2001 From: Jeff Moyer Date: Tue, 3 Jan 2017 17:51:33 -0500 Subject: [PATCH 256/359] block: fix up io_poll documentation /sys/block//queue/io_poll is a boolean. Fix the docs. Signed-off-by: Jeff Moyer Signed-off-by: Jens Axboe --- Documentation/block/queue-sysfs.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index 51642159aedb..c0a3bb5a6e4e 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt @@ -54,9 +54,9 @@ This is the hardware sector size of the device, in bytes. io_poll (RW) ------------ -When read, this file shows the total number of block IO polls and how -many returned success. Writing '0' to this file will disable polling -for this device. Writing any non-zero value will enable this feature. +When read, this file shows whether polling is enabled (1) or disabled +(0). Writing '0' to this file will disable polling for this device. +Writing any non-zero value will enable this feature. io_poll_delay (RW) ------------------ From 926d93a33e59b2729afdbad357233c17184de9d2 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 3 Jan 2017 09:37:55 -0800 Subject: [PATCH 257/359] net: vrf: Add missing Rx counters The move from rx-handler to L3 receive handler inadvertantly dropped the rx counters. Restore them. Fixes: 74b20582ac38 ("net: l3mdev: Add hook in ip and ipv6") Reported-by: Dinesh Dutt Signed-off-by: David Ahern Signed-off-by: David S. Miller --- drivers/net/vrf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 7532646c3b7b..23dfb0eac098 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -967,6 +967,7 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev, */ need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr); if (!ipv6_ndisc_frame(skb) && !need_strict) { + vrf_rx_stats(vrf_dev, skb->len); skb->dev = vrf_dev; skb->skb_iif = vrf_dev->ifindex; @@ -1011,6 +1012,8 @@ static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev, goto out; } + vrf_rx_stats(vrf_dev, skb->len); + skb_push(skb, skb->mac_len); dev_queue_xmit_nit(skb, vrf_dev); skb_pull(skb, skb->mac_len); From 7a21272b088894070391a94fdd1c67014020fa1d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 3 Jan 2017 18:39:32 -0800 Subject: [PATCH 258/359] xfs: fix double-cleanup when CUI recovery fails Dan Carpenter reported a double-free of rcur if _defer_finish fails while we're recovering CUI items. Fix the error recovery to prevent this. Reported-by: Dan Carpenter Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_refcount_item.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index fe86a668a57e..6e4c7446c3d4 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -526,13 +526,14 @@ xfs_cui_recover( xfs_refcount_finish_one_cleanup(tp, rcur, error); error = xfs_defer_finish(&tp, &dfops, NULL); if (error) - goto abort_error; + goto abort_defer; set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); error = xfs_trans_commit(tp); return error; abort_error: xfs_refcount_finish_one_cleanup(tp, rcur, error); +abort_defer: xfs_defer_cancel(&dfops); xfs_trans_cancel(tp); return error; From 20e73b000bcded44a91b79429d8fa743247602ad Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 3 Jan 2017 18:39:33 -0800 Subject: [PATCH 259/359] xfs: use the actual AG length when reserving blocks We need to use the actual AG length when making per-AG reservations, since we could otherwise end up reserving more blocks out of the last AG than there are actual blocks. Complained-about-by: Brian Foster Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_ag_resv.c | 3 +++ fs/xfs/libxfs/xfs_refcount_btree.c | 9 ++++++--- fs/xfs/libxfs/xfs_refcount_btree.h | 3 ++- fs/xfs/libxfs/xfs_rmap_btree.c | 14 +++++++------- fs/xfs/libxfs/xfs_rmap_btree.h | 3 ++- fs/xfs/xfs_fsops.c | 14 ++++++++++++++ 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index e5ebc3770460..d346d42c54d1 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -256,6 +256,9 @@ xfs_ag_resv_init( goto out; } + ASSERT(xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved + + xfs_perag_resv(pag, XFS_AG_RESV_AGFL)->ar_reserved <= + pag->pagf_freeblks + pag->pagf_flcount); out: return error; } diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 6fb2215f8ff7..50add5272807 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -409,13 +409,14 @@ xfs_refcountbt_calc_size( */ xfs_extlen_t xfs_refcountbt_max_size( - struct xfs_mount *mp) + struct xfs_mount *mp, + xfs_agblock_t agblocks) { /* Bail out if we're uninitialized, which can happen in mkfs. */ if (mp->m_refc_mxr[0] == 0) return 0; - return xfs_refcountbt_calc_size(mp, mp->m_sb.sb_agblocks); + return xfs_refcountbt_calc_size(mp, agblocks); } /* @@ -430,22 +431,24 @@ xfs_refcountbt_calc_reserves( { struct xfs_buf *agbp; struct xfs_agf *agf; + xfs_agblock_t agblocks; xfs_extlen_t tree_len; int error; if (!xfs_sb_version_hasreflink(&mp->m_sb)) return 0; - *ask += xfs_refcountbt_max_size(mp); error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); if (error) return error; agf = XFS_BUF_TO_AGF(agbp); + agblocks = be32_to_cpu(agf->agf_length); tree_len = be32_to_cpu(agf->agf_refcount_blocks); xfs_buf_relse(agbp); + *ask += xfs_refcountbt_max_size(mp, agblocks); *used += tree_len; return error; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index 3be7768bd51a..9db008b955b7 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -66,7 +66,8 @@ extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp); extern xfs_extlen_t xfs_refcountbt_calc_size(struct xfs_mount *mp, unsigned long long len); -extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp); +extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp, + xfs_agblock_t agblocks); extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index de25771764ba..74e5a54bc428 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -550,13 +550,14 @@ xfs_rmapbt_calc_size( */ xfs_extlen_t xfs_rmapbt_max_size( - struct xfs_mount *mp) + struct xfs_mount *mp, + xfs_agblock_t agblocks) { /* Bail out if we're uninitialized, which can happen in mkfs. */ if (mp->m_rmap_mxr[0] == 0) return 0; - return xfs_rmapbt_calc_size(mp, mp->m_sb.sb_agblocks); + return xfs_rmapbt_calc_size(mp, agblocks); } /* @@ -571,25 +572,24 @@ xfs_rmapbt_calc_reserves( { struct xfs_buf *agbp; struct xfs_agf *agf; - xfs_extlen_t pool_len; + xfs_agblock_t agblocks; xfs_extlen_t tree_len; int error; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; - /* Reserve 1% of the AG or enough for 1 block per record. */ - pool_len = max(mp->m_sb.sb_agblocks / 100, xfs_rmapbt_max_size(mp)); - *ask += pool_len; - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); if (error) return error; agf = XFS_BUF_TO_AGF(agbp); + agblocks = be32_to_cpu(agf->agf_length); tree_len = be32_to_cpu(agf->agf_rmap_blocks); xfs_buf_relse(agbp); + /* Reserve 1% of the AG or enough for 1 block per record. */ + *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks)); *used += tree_len; return error; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 2a9ac472fb15..19c08e933049 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -60,7 +60,8 @@ extern void xfs_rmapbt_compute_maxlevels(struct xfs_mount *mp); extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp, unsigned long long len); -extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp); +extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, + xfs_agblock_t agblocks); extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 93d12fa2670d..242e8091296d 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -631,6 +631,20 @@ xfs_growfs_data_private( xfs_set_low_space_thresholds(mp); mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); + /* + * If we expanded the last AG, free the per-AG reservation + * so we can reinitialize it with the new size. + */ + if (new) { + struct xfs_perag *pag; + + pag = xfs_perag_get(mp, agno); + error = xfs_ag_resv_free(pag); + xfs_perag_put(pag); + if (error) + goto out; + } + /* Reserve AG metadata blocks. */ error = xfs_fs_reserve_ag_blocks(mp); if (error && error != -ENOSPC) From a1b7a4dea6166cf46be895bce4aac67ea5160fe8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 3 Jan 2017 18:39:33 -0800 Subject: [PATCH 260/359] xfs: fix crash and data corruption due to removal of busy COW extents There is a race window between write_cache_pages calling clear_page_dirty_for_io and XFS calling set_page_writeback, in which the mapping for an inode is tagged neither as dirty, nor as writeback. If the COW shrinker hits in exactly that window we'll remove the delayed COW extents and writepages trying to write it back, which in release kernels will manifest as corruption of the bmap btree, and in debug kernels will trip the ASSERT about now calling xfs_bmapi_write with the COWFORK flag for holes. A complex customer load manages to hit this window fairly reliably, probably by always having COW writeback in flight while the cow shrinker runs. This patch adds another check for having the I_DIRTY_PAGES flag set, which is still set during this race window. While this fixes the problem I'm still not overly happy about the way the COW shrinker works as it still seems a bit fragile. Signed-off-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index ff4d6311c7f4..70ca4f608321 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1597,7 +1597,8 @@ xfs_inode_free_cowblocks( * If the mapping is dirty or under writeback we cannot touch the * CoW fork. Leave it alone if we're in the midst of a directio. */ - if (mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY) || + if ((VFS_I(ip)->i_state & I_DIRTY_PAGES) || + mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY) || mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_WRITEBACK) || atomic_read(&VFS_I(ip)->i_dio_count)) return 0; From 721a0edfbe1f302b93274ce75e0d62843ca63e0d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 3 Jan 2017 18:39:34 -0800 Subject: [PATCH 261/359] xfs: update MAINTAINERS I am taking over as XFS maintainer from Dave Chinner[1], so update contact information and git tree pointers. [1] http://lkml.iu.edu/hypermail/linux/kernel/1612.1/04390.html Signed-off-by: Darrick J. Wong --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index cfff2c9e3d94..793a016d9e4d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13527,11 +13527,11 @@ F: arch/x86/xen/*swiotlb* F: drivers/xen/*swiotlb* XFS FILESYSTEM -M: Dave Chinner +M: Darrick J. Wong M: linux-xfs@vger.kernel.org L: linux-xfs@vger.kernel.org W: http://xfs.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git +T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git S: Supported F: Documentation/filesystems/xfs.txt F: fs/xfs/ From ff97f2399edac1e0fb3fa7851d5fbcbdf04717cf Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Tue, 3 Jan 2017 20:34:17 -0800 Subject: [PATCH 262/359] xfs: fix max_retries _show and _store functions max_retries _show and _store functions should test against cfg->max_retries, not cfg->retry_timeout Signed-off-by: Carlos Maiolino Reviewed-by: Eric Sandeen Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index 276d3023d60f..de6195e38910 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -396,7 +396,7 @@ max_retries_show( int retries; struct xfs_error_cfg *cfg = to_error_cfg(kobject); - if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER) + if (cfg->max_retries == XFS_ERR_RETRY_FOREVER) retries = -1; else retries = cfg->max_retries; @@ -422,7 +422,7 @@ max_retries_store( return -EINVAL; if (val == -1) - cfg->retry_timeout = XFS_ERR_RETRY_FOREVER; + cfg->max_retries = XFS_ERR_RETRY_FOREVER; else cfg->max_retries = val; return count; From a5ad0fd8524e5144512a5c25eda5a5d6fd55fda8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 1 Jan 2017 16:20:53 -0800 Subject: [PATCH 263/359] drm: nouveau: fix build when LEDS_CLASS=m Fix build errors in nouveau driver when CONFIG_LEDS_CLASS=m and CONFIG_DRM_NOUVEAU=y. If LEDS_CLASS is enabled, DRM_NOUVEAU is restricted to the same kconfig value as LEDS_CLASS. drivers/built-in.o: In function `nouveau_do_suspend': nouveau_drm.c:(.text+0x2030b1): undefined reference to `nouveau_led_suspend' drivers/built-in.o: In function `nouveau_do_resume': nouveau_drm.c:(.text+0x2034ca): undefined reference to `nouveau_led_resume' drivers/built-in.o: In function `nouveau_drm_unload': nouveau_drm.c:(.text+0x203a15): undefined reference to `nouveau_led_fini' drivers/built-in.o: In function `nouveau_drm_load': nouveau_drm.c:(.text+0x204423): undefined reference to `nouveau_led_init' BTW, this line in Kbuild: nouveau-$(CONFIG_LEDS_CLASS) += nouveau_led.o does nothing when CONFIG_LEDS_CLASS=m and CONFIG_DRM_NOUVEAU=y. Signed-off-by: Randy Dunlap Reported-by: kbuild test robot Cc: Martin Peres Cc: Ben Skeggs Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/029a1ec5-48ac-a3ce-3106-430e0f2584bb@infradead.org --- drivers/gpu/drm/nouveau/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 2922a82cba8e..0c78c30db56c 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -1,6 +1,7 @@ config DRM_NOUVEAU tristate "Nouveau (NVIDIA) cards" depends on DRM && PCI + depends on LEDS_CLASS || LEDS_CLASS=n select FW_LOADER select DRM_KMS_HELPER select DRM_TTM From 569265002782503d40fb32a45a950f2ac42af353 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Mon, 2 Jan 2017 12:20:08 -0200 Subject: [PATCH 264/359] drm: Document deprecated load/unload hook v2: - Replace discouraged with deprecated - Link to new initialization/teardown functions Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170102142008.22174-3-krisman@collabora.co.uk --- include/drm/drm_drv.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index c4fc49583dc0..9c2d9f0bb043 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -64,12 +64,47 @@ struct drm_mode_create_dumb; * structure for GEM drivers. */ struct drm_driver { + + /** + * @load: + * + * Backward-compatible driver callback to complete + * initialization steps after the driver is registered. For + * this reason, may suffer from race conditions and its use is + * deprecated for new drivers. It is therefore only supported + * for existing drivers not yet converted to the new scheme. + * See drm_dev_init() and drm_dev_register() for proper and + * race-free way to set up a &struct drm_device. + * + * Returns: + * + * Zero on success, non-zero value on failure. + */ int (*load) (struct drm_device *, unsigned long flags); int (*firstopen) (struct drm_device *); int (*open) (struct drm_device *, struct drm_file *); void (*preclose) (struct drm_device *, struct drm_file *file_priv); void (*postclose) (struct drm_device *, struct drm_file *); void (*lastclose) (struct drm_device *); + + /** + * @unload: + * + * Reverse the effects of the driver load callback. Ideally, + * the clean up performed by the driver should happen in the + * reverse order of the initialization. Similarly to the load + * hook, this handler is deprecated and its usage should be + * dropped in favor of an open-coded teardown function at the + * driver layer. See drm_dev_unregister() and drm_dev_unref() + * for the proper way to remove a &struct drm_device. + * + * The unload() hook is called right after unregistering + * the device. + * + * Returns: + * + * The return value is ignored. + */ int (*unload) (struct drm_device *); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); int (*dma_quiescent) (struct drm_device *); From 4b0ea93f250afc6c1128e201b0a8a115ae613e47 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 3 Jan 2017 17:00:27 +0530 Subject: [PATCH 265/359] gpu: drm: mgag200: mgag200_main:- Handle error from pci_iomap Here, pci_iomap can fail, handle this case and return -ENOMEM. Signed-off-by: Arvind Yadav Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483443027-13444-1-git-send-email-arvind.yadav.cs@gmail.com --- drivers/gpu/drm/mgag200/mgag200_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 95d628b9457e..da8ba6c154e3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -145,6 +145,8 @@ static int mga_vram_init(struct mga_device *mdev) } mem = pci_iomap(mdev->dev->pdev, 0, 0); + if (!mem) + return -ENOMEM; mdev->mc.vram_size = mga_probe_vram(mdev, mem); From 3dca01114dcecb1cf324534cd8d75fd1306a516b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:40 +0100 Subject: [PATCH 266/359] USB: serial: cyberjack: fix NULL-deref at open Fix NULL-pointer dereference when clearing halt at open should the device lack a bulk-out endpoint. Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... PC is at cyberjack_open+0x40/0x9c [cyberjack] Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/cyberjack.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 5f17a3b9916d..80260b08398b 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -50,6 +50,7 @@ #define CYBERJACK_PRODUCT_ID 0x0100 /* Function prototypes */ +static int cyberjack_attach(struct usb_serial *serial); static int cyberjack_port_probe(struct usb_serial_port *port); static int cyberjack_port_remove(struct usb_serial_port *port); static int cyberjack_open(struct tty_struct *tty, @@ -77,6 +78,7 @@ static struct usb_serial_driver cyberjack_device = { .description = "Reiner SCT Cyberjack USB card reader", .id_table = id_table, .num_ports = 1, + .attach = cyberjack_attach, .port_probe = cyberjack_port_probe, .port_remove = cyberjack_port_remove, .open = cyberjack_open, @@ -100,6 +102,14 @@ struct cyberjack_private { short wrsent; /* Data already sent */ }; +static int cyberjack_attach(struct usb_serial *serial) +{ + if (serial->num_bulk_out < serial->num_ports) + return -ENODEV; + + return 0; +} + static int cyberjack_port_probe(struct usb_serial_port *port) { struct cyberjack_private *priv; From c4ac4496e835b78a45dfbf74f6173932217e4116 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:41 +0100 Subject: [PATCH 267/359] USB: serial: garmin_gps: fix memory leak on failed URB submit Make sure to free the URB transfer buffer in case submission fails (e.g. due to a disconnect). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/garmin_gps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 97cabf803c2f..b2f2e87aed94 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1043,6 +1043,7 @@ static int garmin_write_bulk(struct usb_serial_port *port, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); count = status; + kfree(buffer); } /* we are done with this urb, so let the host driver From 0dd408425eb21ddf26a692b3c8044c9e7d1a7948 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:42 +0100 Subject: [PATCH 268/359] USB: serial: io_edgeport: fix NULL-deref at open Fix NULL-pointer dereference when initialising URBs at open should a non-EPIC device lack a bulk-in or interrupt-in endpoint. Unable to handle kernel NULL pointer dereference at virtual address 00000028 ... PC is at edge_open+0x24c/0x3e8 [io_edgeport] Note that the EPIC-device probe path has the required sanity checks so this makes those checks partially redundant. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/io_edgeport.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dcc0c58aaad5..d50e5773483f 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2751,6 +2751,11 @@ static int edge_startup(struct usb_serial *serial) EDGE_COMPATIBILITY_MASK1, EDGE_COMPATIBILITY_MASK2 }; + if (serial->num_bulk_in < 1 || serial->num_interrupt_in < 1) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + dev = serial->dev; /* create our private serial structure */ From a323fefc6f5079844dc62ffeb54f491d0242ca35 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:43 +0100 Subject: [PATCH 269/359] USB: serial: io_ti: fix NULL-deref at open Fix NULL-pointer dereference when clearing halt at open should a malicious device lack the expected endpoints when in download mode. Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... [] (edge_open [io_ti]) from [] (serial_port_activate+0x68/0x98 [usbserial]) [] (serial_port_activate [usbserial]) from [] (tty_port_open+0x9c/0xe8) [] (tty_port_open) from [] (serial_open+0x48/0x6c [usbserial]) [] (serial_open [usbserial]) from [] (tty_open+0xcc/0x5cc) Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/io_ti.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index c339163698eb..bf8a4f432f4b 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2546,6 +2546,13 @@ static int edge_startup(struct usb_serial *serial) int status; u16 product_id; + /* Make sure we have the required endpoints when in download mode. */ + if (serial->interface->cur_altsetting->desc.bNumEndpoints > 1) { + if (serial->num_bulk_in < serial->num_ports || + serial->num_bulk_out < serial->num_ports) + return -ENODEV; + } + /* create our private serial structure */ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); if (!edge_serial) From 4f9785cc99feeb3673993b471f646b4dbaec2cc1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:44 +0100 Subject: [PATCH 270/359] USB: serial: io_ti: fix another NULL-deref at open In case a device is left in "boot-mode" we must not register any port devices in order to avoid a NULL-pointer dereference on open due to missing endpoints. This could be used by a malicious device to trigger an OOPS: Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... [] (edge_open [io_ti]) from [] (serial_port_activate+0x68/0x98 [usbserial]) [] (serial_port_activate [usbserial]) from [] (tty_port_open+0x9c/0xe8) [] (tty_port_open) from [] (serial_open+0x48/0x6c [usbserial]) [] (serial_open [usbserial]) from [] (tty_open+0xcc/0x5cc) Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/io_ti.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index bf8a4f432f4b..3b1cfba0ec84 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1508,7 +1508,7 @@ static int do_boot_mode(struct edgeport_serial *serial, dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__); serial->product_info.TiMode = TI_MODE_BOOT; - return 0; + return 1; } static int ti_do_config(struct edgeport_port *port, int feature, int on) @@ -2560,14 +2560,18 @@ static int edge_startup(struct usb_serial *serial) mutex_init(&edge_serial->es_lock); edge_serial->serial = serial; + INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work); usb_set_serial_data(serial, edge_serial); status = download_fw(edge_serial); - if (status) { + if (status < 0) { kfree(edge_serial); return status; } + if (status > 0) + return 1; /* bind but do not register any ports */ + product_id = le16_to_cpu( edge_serial->serial->dev->descriptor.idProduct); @@ -2579,7 +2583,6 @@ static int edge_startup(struct usb_serial *serial) } } - INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work); edge_heartbeat_schedule(edge_serial); return 0; From 2330d0a853da260d8a9834a70df448032b9ff623 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:45 +0100 Subject: [PATCH 271/359] USB: serial: io_ti: fix I/O after disconnect Cancel the heartbeat work on driver unbind in order to avoid I/O after disconnect in case the port is held open. Note that the cancel in release() is still needed to stop the heartbeat after late probe errors. Fixes: 26c78daade0f ("USB: io_ti: Add heartbeat to keep idle EP/416 ports from disconnecting") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/io_ti.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 3b1cfba0ec84..4b0b978fb356 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2590,6 +2590,9 @@ static int edge_startup(struct usb_serial *serial) static void edge_disconnect(struct usb_serial *serial) { + struct edgeport_serial *edge_serial = usb_get_serial_data(serial); + + cancel_delayed_work_sync(&edge_serial->heartbeat_work); } static void edge_release(struct usb_serial *serial) From e35d6d7c4e6532a89732cf4bace0e910ee684c88 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:46 +0100 Subject: [PATCH 272/359] USB: serial: io_ti: bind to interface after fw download Bind to the interface, but do not register any ports, after having downloaded the firmware. The device will still disconnect and re-enumerate, but this way we avoid an error messages from being logged as part of the process: io_ti: probe of 1-1.3:1.0 failed with error -5 Signed-off-by: Johan Hovold --- drivers/usb/serial/io_ti.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 4b0b978fb356..9a0db2965fbb 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1499,8 +1499,7 @@ static int do_boot_mode(struct edgeport_serial *serial, dev_dbg(dev, "%s - Download successful -- Device rebooting...\n", __func__); - /* return an error on purpose */ - return -ENODEV; + return 1; } stayinbootmode: From 90507d54f712d81b74815ef3a4bbb555cd9fab2f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:47 +0100 Subject: [PATCH 273/359] USB: serial: iuu_phoenix: fix NULL-deref at open Fix NULL-pointer dereference at open should the device lack a bulk-in or bulk-out endpoint: Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... PC is at iuu_open+0x78/0x59c [iuu_phoenix] Fixes: 07c3b1a10016 ("USB: remove broken usb-serial num_endpoints check") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/iuu_phoenix.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 344b4eea4bd5..d57fb5199218 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -68,6 +68,16 @@ struct iuu_private { u32 clk; }; +static int iuu_attach(struct usb_serial *serial) +{ + unsigned char num_ports = serial->num_ports; + + if (serial->num_bulk_in < num_ports || serial->num_bulk_out < num_ports) + return -ENODEV; + + return 0; +} + static int iuu_port_probe(struct usb_serial_port *port) { struct iuu_private *priv; @@ -1196,6 +1206,7 @@ static struct usb_serial_driver iuu_device = { .tiocmset = iuu_tiocmset, .set_termios = iuu_set_termios, .init_termios = iuu_init_termios, + .attach = iuu_attach, .port_probe = iuu_port_probe, .port_remove = iuu_port_remove, }; From 5d9b0f859babe96175cd33d7162a9463a875ffde Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:48 +0100 Subject: [PATCH 274/359] USB: serial: keyspan_pda: verify endpoints at probe Check for the expected endpoints in attach() and fail loudly if not present. Note that failing to do this appears to be benign since da280e348866 ("USB: keyspan_pda: clean up write-urb busy handling") which prevents a NULL-pointer dereference in write() by never marking a non-existent write-urb as free. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable # < v3.3 Signed-off-by: Johan Hovold --- drivers/usb/serial/keyspan_pda.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index e49ad0c63ad8..83523fcf6fb9 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -699,6 +699,19 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); #endif +static int keyspan_pda_attach(struct usb_serial *serial) +{ + unsigned char num_ports = serial->num_ports; + + if (serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + + return 0; +} + static int keyspan_pda_port_probe(struct usb_serial_port *port) { @@ -776,6 +789,7 @@ static struct usb_serial_driver keyspan_pda_device = { .break_ctl = keyspan_pda_break_ctl, .tiocmget = keyspan_pda_tiocmget, .tiocmset = keyspan_pda_tiocmset, + .attach = keyspan_pda_attach, .port_probe = keyspan_pda_port_probe, .port_remove = keyspan_pda_port_remove, }; From 21ce57840243c7b70fbc1ebd3dceeb70bb6e9e09 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:49 +0100 Subject: [PATCH 275/359] USB: serial: kobil_sct: fix NULL-deref in write Fix NULL-pointer dereference in write() should the device lack the expected interrupt-out endpoint: Unable to handle kernel NULL pointer dereference at virtual address 00000054 ... PC is at kobil_write+0x144/0x2a0 [kobil_sct] Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/kobil_sct.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 2363654cafc9..813035f51fe7 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -51,6 +51,7 @@ /* Function prototypes */ +static int kobil_attach(struct usb_serial *serial); static int kobil_port_probe(struct usb_serial_port *probe); static int kobil_port_remove(struct usb_serial_port *probe); static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); @@ -86,6 +87,7 @@ static struct usb_serial_driver kobil_device = { .description = "KOBIL USB smart card terminal", .id_table = id_table, .num_ports = 1, + .attach = kobil_attach, .port_probe = kobil_port_probe, .port_remove = kobil_port_remove, .ioctl = kobil_ioctl, @@ -113,6 +115,16 @@ struct kobil_private { }; +static int kobil_attach(struct usb_serial *serial) +{ + if (serial->num_interrupt_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing interrupt-out endpoint\n"); + return -ENODEV; + } + + return 0; +} + static int kobil_port_probe(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; From b05aebc25fdc5aeeac3ee29f0dc9f58dd07c13cc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:50 +0100 Subject: [PATCH 276/359] USB: serial: mos7720: fix NULL-deref at open Fix NULL-pointer dereference at port open if a device lacks the expected bulk in and out endpoints. Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... [] (mos7720_open [mos7720]) from [] (serial_port_activate+0x68/0x98 [usbserial]) [] (serial_port_activate [usbserial]) from [] (tty_port_open+0x9c/0xe8) [] (tty_port_open) from [] (serial_open+0x48/0x6c [usbserial]) [] (serial_open [usbserial]) from [] (tty_open+0xcc/0x5cc) Fixes: 0f64478cbc7a ("USB: add USB serial mos7720 driver") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7720.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index d52caa03679c..3220d0bc767b 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1917,6 +1917,11 @@ static int mos7720_startup(struct usb_serial *serial) u16 product; int ret_val; + if (serial->num_bulk_in < 2 || serial->num_bulk_out < 2) { + dev_err(&serial->interface->dev, "missing bulk endpoints\n"); + return -ENODEV; + } + product = le16_to_cpu(serial->dev->descriptor.idProduct); dev = serial->dev; From 91a1ff4d53c5184d383d0baeeaeab6f9736f2ff3 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:51 +0100 Subject: [PATCH 277/359] USB: serial: mos7720: fix use-after-free on probe errors The interrupt URB was submitted on probe but never stopped on probe errors. This can lead to use-after-free issues in the completion handler when accessing the freed usb-serial struct: Unable to handle kernel paging request at virtual address 6b6b6be7 ... [] (mos7715_interrupt_callback [mos7720]) from [] (__usb_hcd_giveback_urb+0x80/0x140) [] (__usb_hcd_giveback_urb) from [] (usb_hcd_giveback_urb+0x50/0x138) [] (usb_hcd_giveback_urb) from [] (musb_giveback+0xc8/0x1cc) Fixes: b69578df7e98 ("USB: usbserial: mos7720: add support for parallel port on moschip 7715") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7720.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 3220d0bc767b..9170ae856b34 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1962,8 +1962,10 @@ static int mos7720_startup(struct usb_serial *serial) #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT if (product == MOSCHIP_DEVICE_ID_7715) { ret_val = mos7715_parport_init(serial); - if (ret_val < 0) + if (ret_val < 0) { + usb_kill_urb(serial->port[0]->interrupt_in_urb); return ret_val; + } } #endif /* LSR For Port 1 */ @@ -1975,6 +1977,8 @@ static int mos7720_startup(struct usb_serial *serial) static void mos7720_release(struct usb_serial *serial) { + usb_kill_urb(serial->port[0]->interrupt_in_urb); + #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT /* close the parallel port */ From 75dd211e773afcbc264677b0749d1cf7d937ab2d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:52 +0100 Subject: [PATCH 278/359] USB: serial: mos7720: fix parport use-after-free on probe errors Do not submit the interrupt URB until after the parport has been successfully registered to avoid another use-after-free in the completion handler when accessing the freed parport private data in case of a racing completion. Fixes: b69578df7e98 ("USB: usbserial: mos7720: add support for parallel port on moschip 7715") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7720.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 9170ae856b34..e494821ae528 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1952,22 +1952,20 @@ static int mos7720_startup(struct usb_serial *serial) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); - /* start the interrupt urb */ - ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); - if (ret_val) - dev_err(&dev->dev, - "%s - Error %d submitting control urb\n", - __func__, ret_val); - #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT if (product == MOSCHIP_DEVICE_ID_7715) { ret_val = mos7715_parport_init(serial); - if (ret_val < 0) { - usb_kill_urb(serial->port[0]->interrupt_in_urb); + if (ret_val < 0) return ret_val; - } } #endif + /* start the interrupt urb */ + ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); + if (ret_val) { + dev_err(&dev->dev, "failed to submit interrupt urb: %d\n", + ret_val); + } + /* LSR For Port 1 */ read_mos_reg(serial, 0, MOS7720_LSR, &data); dev_dbg(&dev->dev, "LSR:%x\n", data); From fde1faf872ed86d88e245191bc15a8e57368cd1c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:53 +0100 Subject: [PATCH 279/359] USB: serial: mos7720: fix parallel probe A static usb-serial-driver structure that is used to initialise the interrupt URB was modified during probe depending on the currently probed device type, something which could break a parallel probe of a device of a different type. Fix this up by overriding the default completion callback for MCS7715 devices in attach() instead. We may want to use two usb-serial driver instances for the two types later. Fixes: fb088e335d78 ("USB: serial: add support for serial port on the moschip 7715") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7720.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e494821ae528..d6c4441db5f8 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -65,8 +65,6 @@ struct moschip_port { struct urb *write_urb_pool[NUM_URBS]; }; -static struct usb_serial_driver moschip7720_2port_driver; - #define USB_VENDOR_ID_MOSCHIP 0x9710 #define MOSCHIP_DEVICE_ID_7720 0x7720 #define MOSCHIP_DEVICE_ID_7715 0x7715 @@ -970,25 +968,6 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) tty_port_tty_wakeup(&mos7720_port->port->port); } -/* - * mos77xx_probe - * this function installs the appropriate read interrupt endpoint callback - * depending on whether the device is a 7720 or 7715, thus avoiding costly - * run-time checks in the high-frequency callback routine itself. - */ -static int mos77xx_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - if (id->idProduct == MOSCHIP_DEVICE_ID_7715) - moschip7720_2port_driver.read_int_callback = - mos7715_interrupt_callback; - else - moschip7720_2port_driver.read_int_callback = - mos7720_interrupt_callback; - - return 0; -} - static int mos77xx_calc_num_ports(struct usb_serial *serial) { u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); @@ -1946,6 +1925,12 @@ static int mos7720_startup(struct usb_serial *serial) tmp->interrupt_in_endpointAddress; serial->port[1]->interrupt_in_urb = NULL; serial->port[1]->interrupt_in_buffer = NULL; + + if (serial->port[0]->interrupt_in_urb) { + struct urb *urb = serial->port[0]->interrupt_in_urb; + + urb->complete = mos7715_interrupt_callback; + } } /* setting configuration feature to one */ @@ -2060,7 +2045,6 @@ static struct usb_serial_driver moschip7720_2port_driver = { .close = mos7720_close, .throttle = mos7720_throttle, .unthrottle = mos7720_unthrottle, - .probe = mos77xx_probe, .attach = mos7720_startup, .release = mos7720_release, .port_probe = mos7720_port_probe, @@ -2074,7 +2058,7 @@ static struct usb_serial_driver moschip7720_2port_driver = { .chars_in_buffer = mos7720_chars_in_buffer, .break_ctl = mos7720_break, .read_bulk_callback = mos7720_bulk_in_callback, - .read_int_callback = NULL /* dynamically assigned in probe() */ + .read_int_callback = mos7720_interrupt_callback, }; static struct usb_serial_driver * const serial_drivers[] = { From 9da049bcedf43e20e8cb77ee00a1239497ed9fa2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:54 +0100 Subject: [PATCH 280/359] USB: serial: mos7720: remove obsolete port initialisation Since commit b69578df7e98 ("USB: usbserial: mos7720: add support for parallel port on moschip 7715"), the interrupt urb is no longer submitted at first port open and the endpoint-address initialisation at port-probe is no longer used. Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7720.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index d6c4441db5f8..91bc170b408a 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -2011,11 +2011,6 @@ static int mos7720_port_probe(struct usb_serial_port *port) if (!mos7720_port) return -ENOMEM; - /* Initialize all port interrupt end point to port 0 int endpoint. - * Our device has only one interrupt endpoint common to all ports. - */ - port->interrupt_in_endpointAddress = - port->serial->port[0]->interrupt_in_endpointAddress; mos7720_port->port = port; usb_set_serial_port_data(port, mos7720_port); From 5c75633ef751dd4cd8f443dc35152c1ae563162e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:55 +0100 Subject: [PATCH 281/359] USB: serial: mos7840: fix NULL-deref at open Fix NULL-pointer dereference in open() should the device lack the expected endpoints: Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... PC is at mos7840_open+0x88/0x8dc [mos7840] Note that we continue to treat the interrupt-in endpoint as optional for now. Fixes: 3f5429746d91 ("USB: Moschip 7840 USB-Serial Driver") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7840.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 9a220b8e810f..bb933c6321e5 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -2113,6 +2113,17 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) return mos7840_num_ports; } +static int mos7840_attach(struct usb_serial *serial) +{ + if (serial->num_bulk_in < serial->num_ports || + serial->num_bulk_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + + return 0; +} + static int mos7840_port_probe(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; @@ -2388,6 +2399,7 @@ static struct usb_serial_driver moschip7840_4port_device = { .tiocmset = mos7840_tiocmset, .tiocmiwait = usb_serial_generic_tiocmiwait, .get_icount = usb_serial_generic_get_icount, + .attach = mos7840_attach, .port_probe = mos7840_port_probe, .port_remove = mos7840_port_remove, .read_bulk_callback = mos7840_bulk_in_callback, From fc43e651bf39ef174a86fde4c4593f796b1474c1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:56 +0100 Subject: [PATCH 282/359] USB: serial: mos7840: remove unused write URB Remove code to manage a write URB that was never allocated. Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7840.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index bb933c6321e5..c03cd511669a 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -214,7 +214,6 @@ MODULE_DEVICE_TABLE(usb, id_table); struct moschip_port { int port_num; /*Actual port number in the device(1,2,etc) */ - struct urb *write_urb; /* write URB for this port */ struct urb *read_urb; /* read URB for this port */ __u8 shadowLCR; /* last LCR value received */ __u8 shadowMCR; /* last MCR value received */ @@ -1186,7 +1185,6 @@ static void mos7840_close(struct usb_serial_port *port) } } - usb_kill_urb(mos7840_port->write_urb); usb_kill_urb(mos7840_port->read_urb); mos7840_port->read_urb_busy = false; @@ -1199,12 +1197,6 @@ static void mos7840_close(struct usb_serial_port *port) } } - if (mos7840_port->write_urb) { - /* if this urb had a transfer buffer already (old tx) free it */ - kfree(mos7840_port->write_urb->transfer_buffer); - usb_free_urb(mos7840_port->write_urb); - } - Data = 0x0; mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); From 472d7e55d559aa1cbf58c73b14fcfc4651b1a9f5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:57 +0100 Subject: [PATCH 283/359] USB: serial: mos7840: fix misleading interrupt-URB comment The interrupt URB is killed at final port close since commit 0de9a7024e7a ("USB: overhaul of mos7840 driver"). Fixes: 0de9a7024e7a ("USB: overhaul of mos7840 driver") Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7840.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index c03cd511669a..ea27fb23967a 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1036,9 +1036,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) serial, serial->port[0]->interrupt_in_urb->interval); - /* start interrupt read for mos7840 * - * will continue as long as mos7840 is connected */ - + /* start interrupt read for mos7840 */ response = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); From a5bc01949e3b19d8a23b5eabc6fc71bb50dc820e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:58 +0100 Subject: [PATCH 284/359] USB: serial: omninet: fix NULL-derefs at open and disconnect Fix NULL-pointer dereferences at open() and disconnect() should the device lack the expected bulk-out endpoints: Unable to handle kernel NULL pointer dereference at virtual address 000000b4 ... [c0170ff0>] (__lock_acquire) from [] (lock_acquire+0x108/0x264) [] (lock_acquire) from [] (_raw_spin_lock_irqsave+0x58/0x6c) [] (_raw_spin_lock_irqsave) from [] (tty_port_tty_set+0x28/0xa4) [] (tty_port_tty_set) from [] (omninet_open+0x30/0x40 [omninet]) [] (omninet_open [omninet]) from [] (serial_port_activate+0x68/0x98 [usbserial]) Unable to handle kernel NULL pointer dereference at virtual address 00000234 ... [] (omninet_disconnect [omninet]) from [] (usb_serial_disconnect+0xe4/0x100 [usbserial]) Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/omninet.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index f6c6900bccf0..a180b17d2432 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -38,6 +38,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static int omninet_write_room(struct tty_struct *tty); static void omninet_disconnect(struct usb_serial *serial); +static int omninet_attach(struct usb_serial *serial); static int omninet_port_probe(struct usb_serial_port *port); static int omninet_port_remove(struct usb_serial_port *port); @@ -56,6 +57,7 @@ static struct usb_serial_driver zyxel_omninet_device = { .description = "ZyXEL - omni.net lcd plus usb", .id_table = id_table, .num_ports = 1, + .attach = omninet_attach, .port_probe = omninet_port_probe, .port_remove = omninet_port_remove, .open = omninet_open, @@ -104,6 +106,17 @@ struct omninet_data { __u8 od_outseq; /* Sequence number for bulk_out URBs */ }; +static int omninet_attach(struct usb_serial *serial) +{ + /* The second bulk-out endpoint is used for writing. */ + if (serial->num_bulk_out < 2) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + + return 0; +} + static int omninet_port_probe(struct usb_serial_port *port) { struct omninet_data *od; From 5afeef2366db14587b65558bbfd5a067542e07fb Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:39:59 +0100 Subject: [PATCH 285/359] USB: serial: oti6858: fix NULL-deref at open Fix NULL-pointer dereference in open() should the device lack the expected endpoints: Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... PC is at oti6858_open+0x30/0x1d0 [oti6858] Note that a missing interrupt-in endpoint would have caused open() to fail. Fixes: 49cdee0ed0fc ("USB: oti6858 usb-serial driver (in Nokia CA-42 cable)") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/oti6858.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index a4b88bc038b6..b8bf52bf7a94 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -134,6 +134,7 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty); static int oti6858_tiocmget(struct tty_struct *tty); static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); +static int oti6858_attach(struct usb_serial *serial); static int oti6858_port_probe(struct usb_serial_port *port); static int oti6858_port_remove(struct usb_serial_port *port); @@ -158,6 +159,7 @@ static struct usb_serial_driver oti6858_device = { .write_bulk_callback = oti6858_write_bulk_callback, .write_room = oti6858_write_room, .chars_in_buffer = oti6858_chars_in_buffer, + .attach = oti6858_attach, .port_probe = oti6858_port_probe, .port_remove = oti6858_port_remove, }; @@ -324,6 +326,20 @@ static void send_data(struct work_struct *work) usb_serial_port_softint(port); } +static int oti6858_attach(struct usb_serial *serial) +{ + unsigned char num_ports = serial->num_ports; + + if (serial->num_bulk_in < num_ports || + serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + + return 0; +} + static int oti6858_port_probe(struct usb_serial_port *port) { struct oti6858_private *priv; From 76ab439ed1b68778e9059c79ecc5d14de76c89a8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:40:00 +0100 Subject: [PATCH 286/359] USB: serial: pl2303: fix NULL-deref at open Fix NULL-pointer dereference in open() should a type-0 or type-1 device lack the expected endpoints: Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... PC is at pl2303_open+0x38/0xec [pl2303] Note that a missing interrupt-in endpoint would have caused open() to fail. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/pl2303.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ae682e4eeaef..46fca6b75846 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -220,9 +220,17 @@ static int pl2303_probe(struct usb_serial *serial, static int pl2303_startup(struct usb_serial *serial) { struct pl2303_serial_private *spriv; + unsigned char num_ports = serial->num_ports; enum pl2303_type type = TYPE_01; unsigned char *buf; + if (serial->num_bulk_in < num_ports || + serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) return -ENOMEM; From f09d1886a41e9063b43da493ef0e845ac8afd2fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:40:01 +0100 Subject: [PATCH 287/359] USB: serial: quatech2: fix sleep-while-atomic in close The write URB was being killed using the synchronous interface while holding a spin lock in close(). Simply drop the lock and busy-flag update, something which would have been taken care of by the completion handler if the URB was in flight. Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/quatech2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 659cb8606bd9..5709cc93b083 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -408,16 +408,12 @@ static void qt2_close(struct usb_serial_port *port) { struct usb_serial *serial; struct qt2_port_private *port_priv; - unsigned long flags; int i; serial = port->serial; port_priv = usb_get_serial_port_data(port); - spin_lock_irqsave(&port_priv->urb_lock, flags); usb_kill_urb(port_priv->write_urb); - port_priv->urb_in_use = false; - spin_unlock_irqrestore(&port_priv->urb_lock, flags); /* flush the port transmit buffer */ i = usb_control_msg(serial->dev, From cc0909248258f679c4bb4cd315565d40abaf6bc6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:40:02 +0100 Subject: [PATCH 288/359] USB: serial: spcp8x5: fix NULL-deref at open Fix NULL-pointer dereference in open() should the device lack the expected endpoints: Unable to handle kernel NULL pointer dereference at virtual address 00000030 ... PC is at spcp8x5_open+0x30/0xd0 [spcp8x5] Fixes: 619a6f1d1423 ("USB: add usb-serial spcp8x5 driver") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/spcp8x5.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index ef0dbf0703c5..475e6c31b266 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -154,6 +154,19 @@ static int spcp8x5_probe(struct usb_serial *serial, return 0; } +static int spcp8x5_attach(struct usb_serial *serial) +{ + unsigned char num_ports = serial->num_ports; + + if (serial->num_bulk_in < num_ports || + serial->num_bulk_out < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + + return 0; +} + static int spcp8x5_port_probe(struct usb_serial_port *port) { const struct usb_device_id *id = usb_get_serial_data(port->serial); @@ -477,6 +490,7 @@ static struct usb_serial_driver spcp8x5_device = { .tiocmget = spcp8x5_tiocmget, .tiocmset = spcp8x5_tiocmset, .probe = spcp8x5_probe, + .attach = spcp8x5_attach, .port_probe = spcp8x5_port_probe, .port_remove = spcp8x5_port_remove, }; From ef079936d3cd09e63612834fe2698eeada0d8e3f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 3 Jan 2017 16:40:03 +0100 Subject: [PATCH 289/359] USB: serial: ti_usb_3410_5052: fix NULL-deref at open Fix NULL-pointer dereference in open() should a malicious device lack the expected endpoints: Unable to handle kernel NULL pointer dereference at virtual address 00000030 .. [] (ti_open [ti_usb_3410_5052]) from [] (serial_port_activate+0x68/0x98 [usbserial]) Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/ti_usb_3410_5052.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 8db9d071d940..64b85b8dedf3 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -579,6 +579,13 @@ static int ti_startup(struct usb_serial *serial) goto free_tdev; } + if (serial->num_bulk_in < serial->num_ports || + serial->num_bulk_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + status = -ENODEV; + goto free_tdev; + } + return 0; free_tdev: From 24835e442f289813aa568d142a755672a740503c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 21 Dec 2016 11:23:30 +0100 Subject: [PATCH 290/359] drm: reference count event->completion When writing the generic nonblocking commit code I assumed that through clever lifetime management I can assure that the completion (stored in drm_crtc_commit) only gets freed after it is completed. And that worked. I also wanted to make nonblocking helpers resilient against driver bugs, by having timeouts everywhere. And that worked too. Unfortunately taking boths things together results in oopses :( Well, at least sometimes: What seems to happen is that the drm event hangs around forever stuck in limbo land. The nonblocking helpers eventually time out, move on and release it. Now the bug I tested all this against is drivers that just entirely fail to deliver the vblank events like they should, and in those cases the event is simply leaked. But what seems to happen, at least sometimes, on i915 is that the event is set up correctly, but somohow the vblank fails to fire in time. Which means the event isn't leaked, it's still there waiting for eventually a vblank to fire. That tends to happen when re-enabling the pipe, and then the trap springs and the kernel oopses. The correct fix here is simply to refcount the crtc commit to make sure that the event sticks around even for drivers which only sometimes fail to deliver vblanks for some arbitrary reasons. Since crtc commits are already refcounted that's easy to do. References: https://bugs.freedesktop.org/show_bug.cgi?id=96781 Cc: Jim Rees Cc: Chris Wilson Cc: Maarten Lankhorst Cc: Jani Nikula Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161221102331.31033-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic_helper.c | 11 +++++++++++ drivers/gpu/drm/drm_fops.c | 2 +- include/drm/drmP.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 5e5224460042..9460f3a4c1c2 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1355,6 +1355,15 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock) return ret < 0 ? ret : 0; } +void release_crtc_commit(struct completion *completion) +{ + struct drm_crtc_commit *commit = container_of(completion, + typeof(*commit), + flip_done); + + drm_crtc_commit_put(commit); +} + /** * drm_atomic_helper_setup_commit - setup possibly nonblocking commit * @state: new modeset state to be committed @@ -1447,6 +1456,8 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, } crtc_state->event->base.completion = &commit->flip_done; + crtc_state->event->base.completion_release = release_crtc_commit; + drm_crtc_commit_get(commit); } return 0; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 48e106557c92..e22645375e60 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -689,8 +689,8 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) assert_spin_locked(&dev->event_lock); if (e->completion) { - /* ->completion might disappear as soon as it signalled. */ complete_all(e->completion); + e->completion_release(e->completion); e->completion = NULL; } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 8671ddd256fc..ffa8b6d6d367 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -360,6 +360,7 @@ struct drm_ioctl_desc { /* Event queued up for userspace to read */ struct drm_pending_event { struct completion *completion; + void (*completion_release)(struct completion *completion); struct drm_event *event; struct dma_fence *fence; struct list_head link; From 85bcf96caba8b4a7c0805555638629ba3c67ea0c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 6 Dec 2016 16:20:36 +0100 Subject: [PATCH 291/359] ALSA: hda - Fix up GPIO for ASUS ROG Ranger ASUS ROG Ranger VIII with ALC1150 codec requires the extra GPIO pin to up for the front panel. Just use the existing fixup for setting up the GPIO pins. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=189411 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9448daff9d8b..d43f396450f2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2230,6 +2230,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), + SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), From 04f6152d9fbad5bb78bccd05e798fa2d66c571e9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 4 Jan 2017 12:58:44 +0100 Subject: [PATCH 292/359] MAINTAINERS: add myself as maintainer of fbdev I would like to help with fbdev maintenance. I can dedicate some time for reviewing and handling patches but won't have time for much more. The subsystem will remain in maintenance mode (no new drivers will be added to it). Cc: Tomi Valkeinen Cc: Daniel Vetter Signed-off-by: Bartlomiej Zolnierkiewicz --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index cfff2c9e3d94..2775b14f861a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5080,9 +5080,11 @@ F: drivers/net/wan/dlci.c F: drivers/net/wan/sdla.c FRAMEBUFFER LAYER +M: Bartlomiej Zolnierkiewicz L: linux-fbdev@vger.kernel.org +T: git git://github.com/bzolnier/linux.git Q: http://patchwork.kernel.org/project/linux-fbdev/list/ -S: Orphan +S: Maintained F: Documentation/fb/ F: drivers/video/ F: include/video/ From 4dcd19bfabaee8f9f4bcf203afba09b98ccbaf76 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 13 Dec 2016 13:50:52 +0530 Subject: [PATCH 293/359] video: fbdev: cobalt_lcdfb: Handle return NULL error from devm_ioremap Here, If devm_ioremap will fail. It will return NULL. Kernel can run into a NULL-pointer dereference. This error check will avoid NULL pointer dereference. Signed-off-by: Arvind Yadav Acked-by: Yoichi Yuasa Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/cobalt_lcdfb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index 2d3b691f3fc4..038ac6934fe9 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -308,6 +308,11 @@ static int cobalt_lcdfb_probe(struct platform_device *dev) info->screen_size = resource_size(res); info->screen_base = devm_ioremap(&dev->dev, res->start, info->screen_size); + if (!info->screen_base) { + framebuffer_release(info); + return -ENOMEM; + } + info->fbops = &cobalt_lcd_fbops; info->fix = cobalt_lcdfb_fix; info->fix.smem_start = res->start; From aec0e86172a79eb5e44aff1055bb953fe4d47c59 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Mon, 5 Dec 2016 20:09:07 +0800 Subject: [PATCH 294/359] iommu/vt-d: Flush old iommu caches for kdump when the device gets context mapped We met the DMAR fault both on hpsa P420i and P421 SmartArray controllers under kdump, it can be steadily reproduced on several different machines, the dmesg log is like: HP HPSA Driver (v 3.4.16-0) hpsa 0000:02:00.0: using doorbell to reset controller hpsa 0000:02:00.0: board ready after hard reset. hpsa 0000:02:00.0: Waiting for controller to respond to no-op DMAR: Setting identity map for device 0000:02:00.0 [0xe8000 - 0xe8fff] DMAR: Setting identity map for device 0000:02:00.0 [0xf4000 - 0xf4fff] DMAR: Setting identity map for device 0000:02:00.0 [0xbdf6e000 - 0xbdf6efff] DMAR: Setting identity map for device 0000:02:00.0 [0xbdf6f000 - 0xbdf7efff] DMAR: Setting identity map for device 0000:02:00.0 [0xbdf7f000 - 0xbdf82fff] DMAR: Setting identity map for device 0000:02:00.0 [0xbdf83000 - 0xbdf84fff] DMAR: DRHD: handling fault status reg 2 DMAR: [DMA Read] Request device [02:00.0] fault addr fffff000 [fault reason 06] PTE Read access is not set hpsa 0000:02:00.0: controller message 03:00 timed out hpsa 0000:02:00.0: no-op failed; re-trying After some debugging, we found that the fault addr is from DMA initiated at the driver probe stage after reset(not in-flight DMA), and the corresponding pte entry value is correct, the fault is likely due to the old iommu caches of the in-flight DMA before it. Thus we need to flush the old cache after context mapping is setup for the device, where the device is supposed to finish reset at its driver probe stage and no in-flight DMA exists hereafter. I'm not sure if the hardware is responsible for invalidating all the related caches allocated in the iommu hardware before, but seems not the case for hpsa, actually many device drivers have problems in properly resetting the hardware. Anyway flushing (again) by software in kdump kernel when the device gets context mapped which is a quite infrequent operation does little harm. With this patch, the problematic machine can survive the kdump tests. CC: Myron Stowe CC: Joseph Szczypek CC: Don Brace CC: Baoquan He CC: Dave Young Fixes: 091d42e43d21 ("iommu/vt-d: Copy translation tables from old kernel") Fixes: dbcd861f252d ("iommu/vt-d: Do not re-use domain-ids from the old kernel") Fixes: cf484d0e6939 ("iommu/vt-d: Mark copied context entries") Signed-off-by: Xunlei Pang Tested-by: Don Brace Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c66c273dfd8a..8862dc1e88eb 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2037,6 +2037,25 @@ static int domain_context_mapping_one(struct dmar_domain *domain, if (context_present(context)) goto out_unlock; + /* + * For kdump cases, old valid entries may be cached due to the + * in-flight DMA and copied pgtable, but there is no unmapping + * behaviour for them, thus we need an explicit cache flush for + * the newly-mapped device. For kdump, at this point, the device + * is supposed to finish reset at its driver probe stage, so no + * in-flight DMA will exist, and we don't need to worry anymore + * hereafter. + */ + if (context_copied(context)) { + u16 did_old = context_domain_id(context); + + if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) + iommu->flush.flush_context(iommu, did_old, + (((u16)bus) << 8) | devfn, + DMA_CCMD_MASK_NOBIT, + DMA_CCMD_DEVICE_INVL); + } + pgd = domain->pgd; context_clear_entry(context); From 65ca7f5f7d1cdde6c25172fe6107cd16902f826f Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Tue, 6 Dec 2016 10:14:23 -0800 Subject: [PATCH 295/359] iommu/vt-d: Fix pasid table size encoding Different encodings are used to represent supported PASID bits and number of PASID table entries. The current code assigns ecap_pss directly to extended context table entry PTS which is wrong and could result in writing non-zero bits to the reserved fields. IOMMU fault reason 11 will be reported when reserved bits are nonzero. This patch converts ecap_pss to extend context entry pts encoding based on VT-d spec. Chapter 9.4 as follows: - number of PASID bits = ecap_pss + 1 - number of PASID table entries = 2^(pts + 5) Software assigned limit of pasid_max value is also respected to match the allocation limitation of PASID table. cc: Mika Kuoppala cc: Ashok Raj Signed-off-by: Jacob Pan Tested-by: Mika Kuoppala Fixes: 2f26e0a9c9860 ('iommu/vt-d: Add basic SVM PASID support') Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 8862dc1e88eb..8a185250ae5a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -5204,6 +5204,25 @@ static void intel_iommu_remove_device(struct device *dev) } #ifdef CONFIG_INTEL_IOMMU_SVM +#define MAX_NR_PASID_BITS (20) +static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu) +{ + /* + * Convert ecap_pss to extend context entry pts encoding, also + * respect the soft pasid_max value set by the iommu. + * - number of PASID bits = ecap_pss + 1 + * - number of PASID table entries = 2^(pts + 5) + * Therefore, pts = ecap_pss - 4 + * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15 + */ + if (ecap_pss(iommu->ecap) < 5) + return 0; + + /* pasid_max is encoded as actual number of entries not the bits */ + return find_first_bit((unsigned long *)&iommu->pasid_max, + MAX_NR_PASID_BITS) - 5; +} + int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev) { struct device_domain_info *info; @@ -5236,7 +5255,9 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd if (!(ctx_lo & CONTEXT_PASIDE)) { context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table); - context[1].lo = (u64)virt_to_phys(iommu->pasid_table) | ecap_pss(iommu->ecap); + context[1].lo = (u64)virt_to_phys(iommu->pasid_table) | + intel_iommu_get_pts(iommu); + wmb(); /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both * extended to permit requests-with-PASID if the PASIDE bit From 432abf68a79332282329286d190e21fe3ac02a31 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 12 Dec 2016 07:28:26 -0500 Subject: [PATCH 296/359] iommu/amd: Fix the left value check of cmd buffer The generic command buffer entry is 128 bits (16 bytes), so the offset of tail and head pointer should be 16 bytes aligned and increased with 0x10 per command. When cmd buf is full, head = (tail + 0x10) % CMD_BUFFER_SIZE. So when left space of cmd buf should be able to store only two command, we should be issued one COMPLETE_WAIT additionally to wait all older commands completed. Then the left space should be increased after IOMMU fetching from cmd buf. So left check value should be left <= 0x20 (two commands). Signed-off-by: Huang Rui Fixes: ac0ea6e92b222 ('x86/amd-iommu: Improve handling of full command buffer') Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 019e02707cd5..3ef0f42984f2 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1023,7 +1023,7 @@ static int __iommu_queue_command_sync(struct amd_iommu *iommu, next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE; left = (head - next_tail) % CMD_BUFFER_SIZE; - if (left <= 2) { + if (left <= 0x20) { struct iommu_cmd sync_cmd; int ret; From d293dbaa540b5800817cc10832d764b17cc211b5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 24 Nov 2016 14:27:26 +0300 Subject: [PATCH 297/359] vfio-mdev: fix some error codes in the sample code This is just sample code. We forget to set the error codes in a couple places. Signed-off-by: Dan Carpenter Reported-by: Alexey Khoroshilov Signed-off-by: Alex Williamson --- samples/vfio-mdev/mtty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 919c10d5b12e..1fc57a5093a7 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -1449,6 +1449,7 @@ static int __init mtty_dev_init(void) if (IS_ERR(mtty_dev.vd_class)) { pr_err("Error: failed to register mtty_dev class\n"); + ret = PTR_ERR(mtty_dev.vd_class); goto failed1; } @@ -1460,7 +1461,8 @@ static int __init mtty_dev_init(void) if (ret) goto failed2; - if (mdev_register_device(&mtty_dev.dev, &mdev_fops) != 0) + ret = mdev_register_device(&mtty_dev.dev, &mdev_fops); + if (ret) goto failed3; mutex_init(&mdev_list_lock); From e19f32da5ded958238eac1bbe001192acef191a2 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 3 Jan 2017 17:26:46 +0530 Subject: [PATCH 298/359] vfio-pci: Handle error from pci_iomap Here, pci_iomap can fail, handle this case release selected pci regions and return -ENOMEM. Signed-off-by: Arvind Yadav Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index dcd7c2a99618..324c52e3a1a4 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -1142,6 +1142,10 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma) return ret; vdev->barmap[index] = pci_iomap(pdev, index, 0); + if (!vdev->barmap[index]) { + pci_release_selected_regions(pdev, 1 << index); + return -ENOMEM; + } } vma->vm_private_data = vdev; From 76fede2fa79d0d02f6874f023a39b8bd5f52e297 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 4 Jan 2017 12:34:00 +0100 Subject: [PATCH 299/359] drm/atomic: Fix outdated comment. Commit 0853695c3ba4 ("drm: Add reference counting to drm_atomic_state") adds reference counting to atomic state, but didn't update the comments in drm_atomic_(nonblocking_)commit. Clarify lifetime a bit more. Fixes: 0853695c3ba4 ("drm: Add reference counting to drm_atomic_state") Cc: # v4.10-rc1+ Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/7acd1c78-ea86-7776-d98d-c846186e4b88@linux.intel.com --- drivers/gpu/drm/drm_atomic.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 681d5f97639d..672f1de84d6c 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1599,10 +1599,8 @@ EXPORT_SYMBOL(drm_atomic_check_only); * more locks but encountered a deadlock. The caller must then do the usual w/w * backoff dance and restart. All other errors are fatal. * - * Also note that on successful execution ownership of @state is transferred - * from the caller of this function to the function itself. The caller must not - * free or in any other way access @state. If the function fails then the caller - * must clean up @state itself. + * This function will take its own reference on @state. + * Callers should always release their reference with drm_atomic_state_put(). * * Returns: * 0 on success, negative error code on failure. @@ -1630,10 +1628,8 @@ EXPORT_SYMBOL(drm_atomic_commit); * more locks but encountered a deadlock. The caller must then do the usual w/w * backoff dance and restart. All other errors are fatal. * - * Also note that on successful execution ownership of @state is transferred - * from the caller of this function to the function itself. The caller must not - * free or in any other way access @state. If the function fails then the caller - * must clean up @state itself. + * This function will take its own reference on @state. + * Callers should always release their reference with drm_atomic_state_put(). * * Returns: * 0 on success, negative error code on failure. From 6ef4fb387d50fa8f3bffdffc868b57e981cdd709 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 3 Jan 2017 14:27:26 +0000 Subject: [PATCH 300/359] arm64: mm: fix show_pte KERN_CONT fallout Recent changes made KERN_CONT mandatory for continued lines. In the absence of KERN_CONT, a newline may be implicit inserted by the core printk code. In show_pte, we (erroneously) use printk without KERN_CONT for continued prints, resulting in output being split across a number of lines, and not matching the intended output, e.g. [ff000000000000] *pgd=00000009f511b003 , *pud=00000009f4a80003 , *pmd=0000000000000000 Fix this by using pr_cont() for all the continuations. Acked-by: Will Deacon Signed-off-by: Mark Rutland Signed-off-by: Catalin Marinas --- arch/arm64/mm/fault.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index a78a5c401806..156169c6981b 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -88,21 +88,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr) break; pud = pud_offset(pgd, addr); - printk(", *pud=%016llx", pud_val(*pud)); + pr_cont(", *pud=%016llx", pud_val(*pud)); if (pud_none(*pud) || pud_bad(*pud)) break; pmd = pmd_offset(pud, addr); - printk(", *pmd=%016llx", pmd_val(*pmd)); + pr_cont(", *pmd=%016llx", pmd_val(*pmd)); if (pmd_none(*pmd) || pmd_bad(*pmd)) break; pte = pte_offset_map(pmd, addr); - printk(", *pte=%016llx", pte_val(*pte)); + pr_cont(", *pte=%016llx", pte_val(*pte)); pte_unmap(pte); } while(0); - printk("\n"); + pr_cont("\n"); } #ifdef CONFIG_ARM64_HW_AFDBM From 9d84fb27fa135c99c9fe3de33628774a336a70a8 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 3 Jan 2017 18:27:01 +0000 Subject: [PATCH 301/359] arm64: restore get_current() optimisation Commit c02433dd6de32f04 ("arm64: split thread_info from task stack") inverted the relationship between get_current() and current_thread_info(), with sp_el0 now holding the current task_struct rather than the current thead_info. The new implementation of get_current() prevents the compiler from being able to optimize repeated calls to either, resulting in a noticeable penalty in some microbenchmarks. This patch restores the previous optimisation by implementing get_current() in the same way as our old current_thread_info(), using a non-volatile asm statement. Acked-by: Will Deacon Signed-off-by: Mark Rutland Reported-by: Davidlohr Bueso Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/current.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h index f2bcbe2d9889..86c404171305 100644 --- a/arch/arm64/include/asm/current.h +++ b/arch/arm64/include/asm/current.h @@ -9,9 +9,17 @@ struct task_struct; +/* + * We don't use read_sysreg() as we want the compiler to cache the value where + * possible. + */ static __always_inline struct task_struct *get_current(void) { - return (struct task_struct *)read_sysreg(sp_el0); + unsigned long sp_el0; + + asm ("mrs %0, sp_el0" : "=r" (sp_el0)); + + return (struct task_struct *)sp_el0; } #define current get_current() From 5026c9cb0744a9cd40242743ca91a5d712f468c6 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Wed, 14 Dec 2016 17:56:51 +0200 Subject: [PATCH 302/359] mei: bus: fix mei_cldev_enable KDoc Adjust function name in KDoc. Fixes: d49dc5e76fc9 (mei: bus: use mei_cldev_ prefix for the API functions) Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 0037153c80a6..2d9c5dd06e42 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -450,7 +450,7 @@ bool mei_cldev_enabled(struct mei_cl_device *cldev) EXPORT_SYMBOL_GPL(mei_cldev_enabled); /** - * mei_cldev_enable_device - enable me client device + * mei_cldev_enable - enable me client device * create connection with me client * * @cldev: me client device From e09ee853c92011860a4bd2fbdf6126f60fc16bd3 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Wed, 14 Dec 2016 17:56:52 +0200 Subject: [PATCH 303/359] mei: move write cb to completion on credentials failures The credentials handling was pushed to the write handlers but error handling wasn't done properly. Move write callbacks to completion queue to destroy them and to notify a blocked writer about the failure Fixes: 136698e535cd1 (mei: push credentials inside the irq write handler) Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 391936c1aa04..b0395601c6ae 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1541,7 +1541,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, rets = first_chunk ? mei_cl_tx_flow_ctrl_creds(cl) : 1; if (rets < 0) - return rets; + goto err; if (rets == 0) { cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); @@ -1575,11 +1575,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, cb->buf.size, cb->buf_idx); rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx); - if (rets) { - cl->status = rets; - list_move_tail(&cb->list, &cmpl_list->list); - return rets; - } + if (rets) + goto err; cl->status = 0; cl->writing_state = MEI_WRITING; @@ -1587,14 +1584,21 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, cb->completed = mei_hdr.msg_complete == 1; if (first_chunk) { - if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) - return -EIO; + if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) { + rets = -EIO; + goto err; + } } if (mei_hdr.msg_complete) list_move_tail(&cb->list, &dev->write_waiting_list.list); return 0; + +err: + cl->status = rets; + list_move_tail(&cb->list, &cmpl_list->list); + return rets; } /** From 01d0d2c42a14cee8f619d3e9d571ce3469f5ef51 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Wed, 4 Jan 2017 16:18:09 +0000 Subject: [PATCH 304/359] nvmem: qfprom: Allow single byte accesses for read/write The nvmem core driver supports to read and write single byte. So, allow qfprom to support this feature. This change helps in extracting a required value based on bit-offset and number of bits for the required value in the nvmem cell. Signed-off-by: Vivek Gautam Cc: Srinivas Kandagatla Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/qfprom.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c index b5305f08b184..2bdb6c389328 100644 --- a/drivers/nvmem/qfprom.c +++ b/drivers/nvmem/qfprom.c @@ -21,11 +21,11 @@ static int qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes) { void __iomem *base = context; - u32 *val = _val; - int i = 0, words = bytes / 4; + u8 *val = _val; + int i = 0, words = bytes; while (words--) - *val++ = readl(base + reg + (i++ * 4)); + *val++ = readb(base + reg + i++); return 0; } @@ -34,11 +34,11 @@ static int qfprom_reg_write(void *context, unsigned int reg, void *_val, size_t bytes) { void __iomem *base = context; - u32 *val = _val; - int i = 0, words = bytes / 4; + u8 *val = _val; + int i = 0, words = bytes; while (words--) - writel(*val++, base + reg + (i++ * 4)); + writeb(*val++, base + reg + i++); return 0; } @@ -53,7 +53,7 @@ static int qfprom_remove(struct platform_device *pdev) static struct nvmem_config econfig = { .name = "qfprom", .owner = THIS_MODULE, - .stride = 4, + .stride = 1, .word_size = 1, .reg_read = qfprom_reg_read, .reg_write = qfprom_reg_write, From 14ba972842f9e84e6d3264bc0302101b8a792288 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Wed, 4 Jan 2017 16:18:10 +0000 Subject: [PATCH 305/359] nvmem: imx-ocotp: Fix wrong register size All i.MX6 SoCs have an OCOTP Controller with 4kbit fuses. The i.MX6SL is an exception and has only 2kbit fuses. In the TRM for the i.MX6DQ (IMX6QDRM - Rev 2, 06/2014) the fuses size is described in chapter 46.1.1 with: "32-bit word restricted program and read to 4Kbits of eFuse OTP(512x8)." In the TRM for the i.MX6SL (IMX6SLRM - Rev 2, 06/2015) the fuses size is described in chapter 34.1.1 with: "32-bit word restricted program and read to 2 kbit of eFuse OTP(128x8)." Since the Freescale Linux kernel OCOTP driver works with a fuses size of 2 kbit for the i.MX6SL, it looks like the TRM is wrong and the formula to calculate the correct fuses size has to be 256x8. Signed-off-by: Daniel Schultz Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/imx-ocotp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c index ac27b9bac3b9..8e7b120696fa 100644 --- a/drivers/nvmem/imx-ocotp.c +++ b/drivers/nvmem/imx-ocotp.c @@ -71,7 +71,7 @@ static struct nvmem_config imx_ocotp_nvmem_config = { static const struct of_device_id imx_ocotp_dt_ids[] = { { .compatible = "fsl,imx6q-ocotp", (void *)128 }, - { .compatible = "fsl,imx6sl-ocotp", (void *)32 }, + { .compatible = "fsl,imx6sl-ocotp", (void *)64 }, { .compatible = "fsl,imx6sx-ocotp", (void *)128 }, { }, }; From b577fafc4366eb82334518c552912652328c74fa Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 4 Jan 2017 16:18:11 +0000 Subject: [PATCH 306/359] nvmem: fix nvmem_cell_read() return type doc nvmem_cell_read() returns void *, not char *. This is a cleanup that got left out of commit a6c50912508d ("nvmem: Declare nvmem_cell_read() consistently"). Signed-off-by: Brian Norris Fixes: a6c50912508d ("nvmem: Declare nvmem_cell_read() consistently") Signed-off-by: Srinivas Kandagatla Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 965911d9b36a..398ea7f54826 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -981,8 +981,8 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, * @cell: nvmem cell to be read. * @len: pointer to length of cell which will be populated on successful read. * - * Return: ERR_PTR() on error or a valid pointer to a char * buffer on success. - * The buffer should be freed by the consumer with a kfree(). + * Return: ERR_PTR() on error or a valid pointer to a buffer on success. The + * buffer should be freed by the consumer with a kfree(). */ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) { From 63dfb0dac9055145db85ce764355aef2f563739a Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 3 Jan 2017 17:22:20 +0800 Subject: [PATCH 307/359] net: usb: asix_devices: add .reset_resume for USB PM The USB core may call reset_resume when it fails to resume asix device. And USB core can recovery this abnormal resume at low level driver, the same .resume at asix driver can work too. Add .reset_resume can avoid disconnecting after backing from system resume, and NFS can still be mounted after this commit. Signed-off-by: Peter Chen Signed-off-by: David S. Miller --- drivers/net/usb/asix_devices.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 6c646e228833..6e98ede997d3 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -1367,6 +1367,7 @@ static struct usb_driver asix_driver = { .probe = usbnet_probe, .suspend = asix_suspend, .resume = asix_resume, + .reset_resume = asix_resume, .disconnect = usbnet_disconnect, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, From a9a8cdb368d99bb655b5cdabea560446db0527cc Mon Sep 17 00:00:00 2001 From: Varun Prakash Date: Tue, 3 Jan 2017 21:25:48 +0530 Subject: [PATCH 308/359] libcxgb: fix error check for ip6_route_output() ip6_route_output() never returns NULL so check dst->error instead of !dst. Signed-off-by: Varun Prakash Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c index 0f0de5b63622..d04a6c163445 100644 --- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c +++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c @@ -133,17 +133,15 @@ cxgb_find_route6(struct cxgb4_lld_info *lldi, if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL) fl6.flowi6_oif = sin6_scope_id; dst = ip6_route_output(&init_net, NULL, &fl6); - if (!dst) - goto out; - if (!cxgb_our_interface(lldi, get_real_dev, - ip6_dst_idev(dst)->dev) && - !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK)) { + if (dst->error || + (!cxgb_our_interface(lldi, get_real_dev, + ip6_dst_idev(dst)->dev) && + !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK))) { dst_release(dst); - dst = NULL; + return NULL; } } -out: return dst; } EXPORT_SYMBOL(cxgb_find_route6); From cd7aeb1f9706b665ad8659df8ff036e7bc0097f4 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 3 Jan 2017 13:57:00 -0500 Subject: [PATCH 309/359] LiquidIO VF: s/select/imply/ for PTP_1588_CLOCK Fix a minor fallout from the merge of the timers and the networking trees. The following error may result if the PTP_1588_CLOCK prerequisites are not available: drivers/built-in.o: In function `ptp_clock_unregister': (.text+0x40e0a5): undefined reference to `pps_unregister_source' drivers/built-in.o: In function `ptp_clock_unregister': (.text+0x40e0cc): undefined reference to `posix_clock_unregister' drivers/built-in.o: In function `ptp_clock_event': (.text+0x40e249): undefined reference to `pps_event' drivers/built-in.o: In function `ptp_clock_register': (.text+0x40e5e1): undefined reference to `pps_register_source' drivers/built-in.o: In function `ptp_clock_register': (.text+0x40e62c): undefined reference to `posix_clock_register' drivers/built-in.o: In function `ptp_clock_register': (.text+0x40e68d): undefined reference to `pps_unregister_source' Signed-off-by: Nicolas Pitre Acked-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/net/ethernet/cavium/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig index bbc8bd16cb97..dcbce6cac63e 100644 --- a/drivers/net/ethernet/cavium/Kconfig +++ b/drivers/net/ethernet/cavium/Kconfig @@ -77,7 +77,7 @@ config OCTEON_MGMT_ETHERNET config LIQUIDIO_VF tristate "Cavium LiquidIO VF support" depends on 64BIT && PCI_MSI - select PTP_1588_CLOCK + imply PTP_1588_CLOCK ---help--- This driver supports Cavium LiquidIO Intelligent Server Adapter based on CN23XX chips. From bb7da333d0a9f3bddc08f84187b7579a3f68fd24 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 3 Jan 2017 16:34:48 -0800 Subject: [PATCH 310/359] net: systemport: Utilize skb_put_padto() Since we need to pad our packets, utilize skb_put_padto() which increases skb->len by how much we need to pad, allowing us to eliminate the test on skb->len right below. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 25d1eb4933d0..e67908b5edfe 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1028,13 +1028,12 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb, * (including FCS and tag) because the length verification is done after * the Broadcom tag is stripped off the ingress packet. */ - if (skb_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN)) { + if (skb_put_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN)) { ret = NETDEV_TX_OK; goto out; } - skb_len = skb->len < ETH_ZLEN + ENET_BRCM_TAG_LEN ? - ETH_ZLEN + ENET_BRCM_TAG_LEN : skb->len; + skb_len = skb->len; mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE); if (dma_mapping_error(kdev, mapping)) { From 38e5a85562a6cd911fc26d951d576551a688574c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 3 Jan 2017 16:34:49 -0800 Subject: [PATCH 311/359] net: systemport: Pad packet before inserting TSB Inserting the TSB means adding an extra 8 bytes in front the of packet that is going to be used as metadata information by the TDMA engine, but stripped off, so it does not really help with the packet padding. For some odd packet sizes that fall below the 60 bytes payload (e.g: ARP) we can end-up padding them after the TSB insertion, thus making them 64 bytes, but with the TDMA stripping off the first 8 bytes, they could still be smaller than 64 bytes which is required to ingress the switch. Fix this by swapping the padding and TSB insertion, guaranteeing that the packets have the right sizes. Fixes: 80105befdb4b ("net: systemport: add Broadcom SYSTEMPORT Ethernet MAC driver") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index e67908b5edfe..7e8cf213fd81 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1012,15 +1012,6 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb, goto out; } - /* Insert TSB and checksum infos */ - if (priv->tsb_en) { - skb = bcm_sysport_insert_tsb(skb, dev); - if (!skb) { - ret = NETDEV_TX_OK; - goto out; - } - } - /* The Ethernet switch we are interfaced with needs packets to be at * least 64 bytes (including FCS) otherwise they will be discarded when * they enter the switch port logic. When Broadcom tags are enabled, we @@ -1033,6 +1024,15 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb, goto out; } + /* Insert TSB and checksum infos */ + if (priv->tsb_en) { + skb = bcm_sysport_insert_tsb(skb, dev); + if (!skb) { + ret = NETDEV_TX_OK; + goto out; + } + } + skb_len = skb->len; mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE); From 3fe61f0940d9c7892462c893602fdccfe8b24e8c Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 4 Jan 2017 13:21:29 +0200 Subject: [PATCH 312/359] dpaa_eth: cleanup after init_phy() failure Signed-off-by: Madalin Bucur Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 624ba9058dc4..77517aa3e8d9 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -2291,7 +2291,8 @@ static int dpaa_open(struct net_device *net_dev) net_dev->phydev = mac_dev->init_phy(net_dev, priv->mac_dev); if (!net_dev->phydev) { netif_err(priv, ifup, net_dev, "init_phy() failed\n"); - return -ENODEV; + err = -ENODEV; + goto phy_init_failed; } for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) { @@ -2314,6 +2315,7 @@ static int dpaa_open(struct net_device *net_dev) for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) fman_port_disable(mac_dev->port[i]); +phy_init_failed: dpaa_eth_napi_disable(priv); return err; From 0fbb0f24dde8759925fc56e9dbc6a5b2cbba99c4 Mon Sep 17 00:00:00 2001 From: Roy Pledge Date: Wed, 4 Jan 2017 13:21:30 +0200 Subject: [PATCH 313/359] dpaa_eth: Initialize CGR structure before init The QBMan CGR options needs to be zeroed before calling the init function Signed-off-by: Roy Pledge Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 77517aa3e8d9..c9b7ad65e563 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -733,6 +733,7 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv) priv->cgr_data.cgr.cb = dpaa_eth_cgscn; /* Enable Congestion State Change Notifications and CS taildrop */ + memset(&initcgr, 0, sizeof(initcgr)); initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES); initcgr.cgr.cscn_en = QM_CGR_EN; @@ -2422,6 +2423,7 @@ static int dpaa_ingress_cgr_init(struct dpaa_priv *priv) } /* Enable CS TD, but disable Congestion State Change Notifications. */ + memset(&initcgr, 0, sizeof(initcgr)); initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES); initcgr.cgr.cscn_en = QM_CGR_EN; cs_th = DPAA_INGRESS_CS_THRESHOLD; From 4fdda95893de776a8efdf661bbf0e338f2f13dcb Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Wed, 4 Jan 2017 15:10:56 +0000 Subject: [PATCH 314/359] sfc: don't report RX hash keys to ethtool when RSS wasn't enabled If we failed to set up RSS on EF10 (e.g. because firmware declared RX_RSS_LIMITED), ethtool --show-nfc $dev rx-flow-hash ... should report no fields, rather than confusingly reporting what fields we _would_ be hashing on if RSS was working. Fixes: dcb4123cbec0 ("sfc: disable RSS when unsupported") Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef10.c | 3 ++- drivers/net/ethernet/sfc/ethtool.c | 2 ++ drivers/net/ethernet/sfc/net_driver.h | 2 ++ drivers/net/ethernet/sfc/siena.c | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index de2947ccc5ad..5eb0e684fd76 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1323,7 +1323,8 @@ static int efx_ef10_init_nic(struct efx_nic *efx) } /* don't fail init if RSS setup doesn't work */ - efx->type->rx_push_rss_config(efx, false, efx->rx_indir_table); + rc = efx->type->rx_push_rss_config(efx, false, efx->rx_indir_table); + efx->rss_active = (rc == 0); return 0; } diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 87bdc56b4e3a..18ebaea44e82 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -975,6 +975,8 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev, case ETHTOOL_GRXFH: { info->data = 0; + if (!efx->rss_active) /* No RSS */ + return 0; switch (info->flow_type) { case UDP_V4_FLOW: if (efx->rx_hash_udp_4tuple) diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 1a635ced62d0..1c62c1a00fca 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -860,6 +860,7 @@ struct vfdi_status; * @rx_hash_key: Toeplitz hash key for RSS * @rx_indir_table: Indirection table for RSS * @rx_scatter: Scatter mode enabled for receives + * @rss_active: RSS enabled on hardware * @rx_hash_udp_4tuple: UDP 4-tuple hashing enabled * @int_error_count: Number of internal errors seen recently * @int_error_expire: Time at which error count will be expired @@ -998,6 +999,7 @@ struct efx_nic { u8 rx_hash_key[40]; u32 rx_indir_table[128]; bool rx_scatter; + bool rss_active; bool rx_hash_udp_4tuple; unsigned int_error_count; diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index a3901bc96586..4e54e5dc9fcb 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -403,6 +403,7 @@ static int siena_init_nic(struct efx_nic *efx) efx_writeo(efx, &temp, FR_AZ_RX_CFG); siena_rx_push_rss_config(efx, false, efx->rx_indir_table); + efx->rss_active = true; /* Enable event logging */ rc = efx_mcdi_log_ctrl(efx, true, false, 0); From c6ef7fd40eddad38a8825cbd6bb2ce8bdbba88f5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 4 Jan 2017 15:08:15 -0500 Subject: [PATCH 315/359] vfio-mdev: fix non-standard ioctl return val causing i386 build fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What appears to be a copy and paste error from the line above gets the ioctl a ssize_t return value instead of the traditional "int". The associated sample code used "long" which meant it would compile for x86-64 but not i386, with the latter failing as follows: CC [M] samples/vfio-mdev/mtty.o samples/vfio-mdev/mtty.c:1418:20: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .ioctl = mtty_ioctl, ^ samples/vfio-mdev/mtty.c:1418:20: note: (near initialization for ‘mdev_fops.ioctl’) cc1: some warnings being treated as errors Since in this case, vfio is working with struct file_operations; as such: long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); ...and so here we just standardize on long vs. the normal int that user space typically sees and documents as per "man ioctl" and similar. Fixes: 9d1a546c53b4 ("docs: Sample driver to demonstrate how to use Mediated device framework.") Cc: Kirti Wankhede Cc: Neo Jia Cc: kvm@vger.kernel.org Signed-off-by: Paul Gortmaker Signed-off-by: Alex Williamson --- include/linux/mdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mdev.h b/include/linux/mdev.h index 3ee44b8d2bb3..b6e048e1045f 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -78,7 +78,7 @@ struct mdev_parent_ops { size_t count, loff_t *ppos); ssize_t (*write)(struct mdev_device *mdev, const char __user *buf, size_t count, loff_t *ppos); - ssize_t (*ioctl)(struct mdev_device *mdev, unsigned int cmd, + long (*ioctl)(struct mdev_device *mdev, unsigned int cmd, unsigned long arg); int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma); }; From c7efff9284dfde95a11aaa811c9d8ec8167f0f6e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Jan 2017 21:38:16 +0100 Subject: [PATCH 316/359] ALSA: hda - Apply asus-mode8 fixup to ASUS X71SL Although the old quirk table showed ASUS X71SL with ALC663 codec being compatible with asus-mode3 fixup, the bugzilla reporter explained that asus-model8 fits better for the dual headphone controls. So be it. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=191781 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d43f396450f2..7d660ee1d5e8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6984,6 +6984,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51), SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51), + SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), From 71eae1ca77fd6be218d8a952d97bba827e56516d Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 4 Jan 2017 23:10:23 +0300 Subject: [PATCH 317/359] sh_eth: enable RX descriptor word 0 shift on SH7734 The RX descriptor word 0 on SH7734 has the RFS[9:0] field in bits 16-25 (bits 0-15 usually used for that are occupied by the packet checksum). Thus we need to set the 'shift_rd0' field in the SH7734 SoC data... Fixes: f0e81fecd4f8 ("net: sh_eth: Add support SH7734") Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 0af7fc279c85..00fafabab1d0 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -819,6 +819,7 @@ static struct sh_eth_cpu_data sh7734_data = { .tsu = 1, .hw_crc = 1, .select_mii = 1, + .shift_rd0 = 1, }; /* SH7763 */ From e11b6293a8fcd3f29376808910f49bd82f72b69a Mon Sep 17 00:00:00 2001 From: Hoan Tran Date: Thu, 15 Dec 2016 14:55:00 -0800 Subject: [PATCH 318/359] cpufreq: dt: Add support for APM X-Gene 2 Add the compatible string for supporting the generic device tree cpufreq-dt driver on APM's X-Gene 2 SoC. Signed-off-by: Hoan Tran Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index bc97b6a4b1cf..7fcaf26e8f81 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -26,6 +26,8 @@ static const struct of_device_id machines[] __initconst = { { .compatible = "allwinner,sun8i-a83t", }, { .compatible = "allwinner,sun8i-h3", }, + { .compatible = "apm,xgene-shadowcat", }, + { .compatible = "arm,integrator-ap", }, { .compatible = "arm,integrator-cp", }, From 1d0f953086f090a022f2c0e1448300c15372db46 Mon Sep 17 00:00:00 2001 From: Ioan-Adrian Ratiu Date: Thu, 5 Jan 2017 00:37:46 +0200 Subject: [PATCH 319/359] ALSA: usb-audio: Fix irq/process data synchronization Commit 16200948d83 ("ALSA: usb-audio: Fix race at stopping the stream") was incomplete causing another more severe kernel panic, so it got reverted. This fixes both the original problem and its fallout kernel race/crash. The original fix is to move the endpoint member NULL clearing logic inside wait_clear_urbs() so the irq triggering the urb completion doesn't call retire_capture/playback_urb() after the NULL clearing and generate a panic. However this creates a new race between snd_usb_endpoint_start()'s call to wait_clear_urbs() and the irq urb completion handler which again calls retire_capture/playback_urb() leading to a new NULL dereference. We keep the EP deactivation code in snd_usb_endpoint_start() because removing it will break the EP reference counting (see [1] [2] for info), however we don't need the "can_sleep" mechanism anymore because a new function was introduced (snd_usb_endpoint_sync_pending_stop()) which synchronizes pending stops and gets called inside the pcm prepare callback. It also makes sense to remove can_sleep because it was also removed from deactivate_urbs() signature in [3] so we benefit from more simplification. [1] commit 015618b90 ("ALSA: snd-usb: Fix URB cancellation at stream start") [2] commit e9ba389c5 ("ALSA: usb-audio: Fix scheduling-while-atomic bug in PCM capture stream") [3] commit ccc1696d5 ("ALSA: usb-audio: simplify endpoint deactivation code") Fixes: f8114f8583bb ("Revert "ALSA: usb-audio: Fix race at stopping the stream"") Signed-off-by: Ioan-Adrian Ratiu Signed-off-by: Takashi Iwai --- sound/usb/endpoint.c | 17 +++++++---------- sound/usb/endpoint.h | 2 +- sound/usb/pcm.c | 10 +++++----- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 15d1d5c63c3c..2f0ea70a998c 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -534,6 +534,11 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) alive, ep->ep_num); clear_bit(EP_FLAG_STOPPING, &ep->flags); + ep->data_subs = NULL; + ep->sync_slave = NULL; + ep->retire_data_urb = NULL; + ep->prepare_data_urb = NULL; + return 0; } @@ -912,9 +917,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, /** * snd_usb_endpoint_start: start an snd_usb_endpoint * - * @ep: the endpoint to start - * @can_sleep: flag indicating whether the operation is executed in - * non-atomic context + * @ep: the endpoint to start * * A call to this function will increment the use count of the endpoint. * In case it is not already running, the URBs for this endpoint will be @@ -924,7 +927,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, * * Returns an error if the URB submission failed, 0 in all other cases. */ -int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) +int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) { int err; unsigned int i; @@ -938,8 +941,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) /* just to be sure */ deactivate_urbs(ep, false); - if (can_sleep) - wait_clear_urbs(ep); ep->active_mask = 0; ep->unlink_mask = 0; @@ -1020,10 +1021,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep) if (--ep->use_count == 0) { deactivate_urbs(ep, false); - ep->data_subs = NULL; - ep->sync_slave = NULL; - ep->retire_data_urb = NULL; - ep->prepare_data_urb = NULL; set_bit(EP_FLAG_STOPPING, &ep->flags); } } diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 6428392d8f62..584f295d7c77 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -18,7 +18,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, struct audioformat *fmt, struct snd_usb_endpoint *sync_ep); -int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep); +int snd_usb_endpoint_start(struct snd_usb_endpoint *ep); void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep); void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 34c6d4f2c0b6..9aa5b1855481 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -218,7 +218,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, } } -static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) +static int start_endpoints(struct snd_usb_substream *subs) { int err; @@ -231,7 +231,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) dev_dbg(&subs->dev->dev, "Starting data EP @%p\n", ep); ep->data_subs = subs; - err = snd_usb_endpoint_start(ep, can_sleep); + err = snd_usb_endpoint_start(ep); if (err < 0) { clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags); return err; @@ -260,7 +260,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) dev_dbg(&subs->dev->dev, "Starting sync EP @%p\n", ep); ep->sync_slave = subs->data_endpoint; - err = snd_usb_endpoint_start(ep, can_sleep); + err = snd_usb_endpoint_start(ep); if (err < 0) { clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); return err; @@ -850,7 +850,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) /* for playback, submit the URBs now; otherwise, the first hwptr_done * updates for all URBs would happen at the same time when starting */ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) - ret = start_endpoints(subs, true); + ret = start_endpoints(subs); unlock: snd_usb_unlock_shutdown(subs->stream->chip); @@ -1666,7 +1666,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream switch (cmd) { case SNDRV_PCM_TRIGGER_START: - err = start_endpoints(subs, false); + err = start_endpoints(subs); if (err < 0) return err; From 13a6c8328e6056932dc680e447d4c5e8ad9add17 Mon Sep 17 00:00:00 2001 From: Ioan-Adrian Ratiu Date: Thu, 5 Jan 2017 00:37:47 +0200 Subject: [PATCH 320/359] ALSA: usb-audio: test EP_FLAG_RUNNING at urb completion Testing EP_FLAG_RUNNING in snd_complete_urb() before running the completion logic allows us to save a few cpu cycles by returning early, skipping the pending urb in case the stream was stopped; the stop logic handles the urb and sets the completion callbacks to NULL. Signed-off-by: Ioan-Adrian Ratiu Signed-off-by: Takashi Iwai --- sound/usb/endpoint.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 2f0ea70a998c..c90607ebe155 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -384,6 +384,9 @@ static void snd_complete_urb(struct urb *urb) if (unlikely(atomic_read(&ep->chip->shutdown))) goto exit_clear; + if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) + goto exit_clear; + if (usb_pipeout(ep->pipe)) { retire_outbound_urb(ep, ctx); /* can be stopped during retire callback */ From e4f34cf6d59160818dcdcf41f4116cc88093ece3 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Thu, 5 Jan 2017 09:41:31 +0900 Subject: [PATCH 321/359] Revert "ALSA: firewire-lib: change structure member with proper type" This reverts commit 6b7e95d1336b9eb0d4c6db190ce756480496bd13. This commit is based on a concern about value of the given parameter. It's expected to be ORed value with some enumeration-constants, thus often it can not be one of the enumeration-constants. I understood that this is out of specification and causes implementation-dependent issues. In C language specification, enumerated type can be interpreted as an integer type, in which all of enumeration-constants in corresponding enumerator-list can be stored. Implementations can select one of char, signed int and unsigned int as its type, and this selection is implementation-dependent. In GCC, a signed integer is selected when at least one of enumeration-constants has negative value, else an unsigned integer is selected. This behaviour can be switched by -fshort-enums to short type. Anyway, the type can be decided after scanning all of enumeration-constants. Totally, there's no rules to constrain the value of enumerated type to be one of enumeration-constants. In short, in enumerated type, decision of actual type for the type is the most important and enumeration-constants are just used for the decision, thus it's permitted to have an integer value in a range of enumeration-constants. In our case, actual type for the type is currently deterministic to be either char or unsigned int. Under GCC, it's unsigned int. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/amdtp-stream.c | 2 +- sound/firewire/amdtp-stream.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 8ce93cdc4b0d..00060c4a9deb 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -69,7 +69,7 @@ static void pcm_period_tasklet(unsigned long data); * @protocol_size: the size to allocate newly for protocol */ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, - enum amdtp_stream_direction dir, int flags, + enum amdtp_stream_direction dir, enum cip_flags flags, unsigned int fmt, amdtp_stream_process_data_blocks_t process_data_blocks, unsigned int protocol_size) diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index 7be21429cd12..c1bc7fad056e 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -93,7 +93,7 @@ typedef unsigned int (*amdtp_stream_process_data_blocks_t)( unsigned int *syt); struct amdtp_stream { struct fw_unit *unit; - int flags; + enum cip_flags flags; enum amdtp_stream_direction direction; struct mutex mutex; @@ -137,7 +137,7 @@ struct amdtp_stream { }; int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, - enum amdtp_stream_direction dir, int flags, + enum amdtp_stream_direction dir, enum cip_flags flags, unsigned int fmt, amdtp_stream_process_data_blocks_t process_data_blocks, unsigned int protocol_size); From b3ba3f6fab873a8d757fbcd9f83c3f69e369cddf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 21 Dec 2016 14:03:35 +0100 Subject: [PATCH 322/359] drm: Add kernel-doc for drm_crtc_commit_get/put I was lazy, rectify that! Also align with drm_atomic_state_get/put for ocd. v2: Git add helps. Acked-by: Alex Deucher Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161221130335.5321-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic.c | 9 ++------- include/drm/drm_atomic.h | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 672f1de84d6c..6414bcf7f41b 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -35,19 +35,14 @@ #include "drm_crtc_internal.h" -static void crtc_commit_free(struct kref *kref) +void __drm_crtc_commit_free(struct kref *kref) { struct drm_crtc_commit *commit = container_of(kref, struct drm_crtc_commit, ref); kfree(commit); } - -void drm_crtc_commit_put(struct drm_crtc_commit *commit) -{ - kref_put(&commit->ref, crtc_commit_free); -} -EXPORT_SYMBOL(drm_crtc_commit_put); +EXPORT_SYMBOL(__drm_crtc_commit_free); /** * drm_atomic_state_default_release - diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index fd2d971bca32..f96220ed4004 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -189,12 +189,31 @@ struct drm_atomic_state { struct work_struct commit_work; }; -void drm_crtc_commit_put(struct drm_crtc_commit *commit); +void __drm_crtc_commit_free(struct kref *kref); + +/** + * drm_crtc_commit_get - acquire a reference to the CRTC commit + * @commit: CRTC commit + * + * Increases the reference of @commit. + */ static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) { kref_get(&commit->ref); } +/** + * drm_crtc_commit_put - release a reference to the CRTC commmit + * @commit: CRTC commit + * + * This releases a reference to @commit which is freed after removing the + * final reference. No locking required and callable from any context. + */ +static inline void drm_crtc_commit_put(struct drm_crtc_commit *commit) +{ + kref_put(&commit->ref, __drm_crtc_commit_free); +} + struct drm_atomic_state * __must_check drm_atomic_state_alloc(struct drm_device *dev); void drm_atomic_state_clear(struct drm_atomic_state *state); From 00bd61757821e46e78300635450a657e250b6146 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 5 Jan 2017 08:59:17 +0100 Subject: [PATCH 323/359] Revert "drm: nouveau: fix build when LEDS_CLASS=m" This reverts commit a5ad0fd8524e5144512a5c25eda5a5d6fd55fda8. It results in kconfing complaining about recursive depencies: drivers/usb/Kconfig:39:error: recursive dependency detected! For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/input/mouse/Kconfig:187: symbol MOUSE_APPLETOUCH depends on INPUT For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/input/Kconfig:8: symbol INPUT is selected by VT For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/tty/Kconfig:12: symbol VT is selected by FB_STI For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/video/fbdev/Kconfig:678: symbol FB_STI depends on FB For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/video/fbdev/Kconfig:5: symbol FB is selected by DRM_KMS_FB_HELPER For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/gpu/drm/Kconfig:72: symbol DRM_KMS_FB_HELPER is selected by DRM_KMS_CMA_HELPER For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/gpu/drm/Kconfig:128: symbol DRM_KMS_CMA_HELPER is selected by DRM_HDLCD For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/gpu/drm/arm/Kconfig:6: symbol DRM_HDLCD depends on COMMON_CLK For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/clk/Kconfig:9: symbol COMMON_CLK is selected by X86_INTEL_QUARK For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" arch/x86/Kconfig:554: symbol X86_INTEL_QUARK depends on X86_PLATFORM_DEVICES For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/platform/x86/Kconfig:5: symbol X86_PLATFORM_DEVICES is selected by DRM_NOUVEAU For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/gpu/drm/nouveau/Kconfig:1: symbol DRM_NOUVEAU depends on LEDS_CLASS For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/leds/Kconfig:16: symbol LEDS_CLASS is selected by ATH9K_HTC For a resolution refer to Documentation/kbuild/kconfig-language.txt subsection "Kconfig recursive dependency limitations" drivers/net/wireless/ath/ath9k/Kconfig:158: symbol ATH9K_HTC depends on USB warning: (DRM_NOUVEAU && DRM_I915 && DRM_GMA500) selects ACPI_VIDEO which has unmet direct dependencies (ACPI && X86 && +BACKLIGHT_CLASS_DEVICE && INPUT) And there's apparently a better patch available already. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/nouveau/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 0c78c30db56c..2922a82cba8e 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -1,7 +1,6 @@ config DRM_NOUVEAU tristate "Nouveau (NVIDIA) cards" depends on DRM && PCI - depends on LEDS_CLASS || LEDS_CLASS=n select FW_LOADER select DRM_KMS_HELPER select DRM_TTM From 88017bd06e74c82dd0b953e3766ec0d1e3c8d63c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 4 Jan 2017 13:44:56 -0200 Subject: [PATCH 324/359] drm/imx: imx-tve: Remove unused variable 'ret' is never used in tve_enable/tve_disable(), so just remove it. Signed-off-by: Fabio Estevam Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483544696-32707-1-git-send-email-fabio.estevam@nxp.com --- drivers/gpu/drm/imx/imx-tve.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 3b602ee33c44..8f8aa4a63122 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -150,13 +150,11 @@ __releases(&tve->lock) static void tve_enable(struct imx_tve *tve) { - int ret; - if (!tve->enabled) { tve->enabled = true; clk_prepare_enable(tve->clk); - ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, - TVE_EN, TVE_EN); + regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, + TVE_EN, TVE_EN); } /* clear interrupt status register */ @@ -174,12 +172,9 @@ static void tve_enable(struct imx_tve *tve) static void tve_disable(struct imx_tve *tve) { - int ret; - if (tve->enabled) { tve->enabled = false; - ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, - TVE_EN, 0); + regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, TVE_EN, 0); clk_disable_unprepare(tve->clk); } } From 1aa81be3af121636824e40eec737706e62c9da0c Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 2 Jan 2017 13:59:09 +0100 Subject: [PATCH 325/359] drm: Move locking into drm_debugfs_crtc_crc_add There's no reason any more for callers of this function to take the lock themselves, so just move the lock to the function to avoid confusion and bugs when more callers are contributed. Signed-off-by: Tomeu Vizoso Reviewed-by: Emil Velikov Reviewed-by: Robert Foss Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170102125912.22305-2-tomeu.vizoso@collabora.com --- drivers/gpu/drm/drm_debugfs_crc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 00e771fb7df2..68b171af237b 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -325,16 +325,19 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, struct drm_crtc_crc_entry *entry; int head, tail; - assert_spin_locked(&crc->lock); + spin_lock(&crc->lock); /* Caller may not have noticed yet that userspace has stopped reading */ - if (!crc->opened) + if (!crc->opened) { + spin_unlock(&crc->lock); return -EINVAL; + } head = crc->head; tail = crc->tail; if (CIRC_SPACE(head, tail, DRM_CRC_ENTRIES_NR) < 1) { + spin_unlock(&crc->lock); DRM_ERROR("Overflow of CRC buffer, userspace reads too slow.\n"); return -ENOBUFS; } @@ -347,6 +350,8 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, head = (head + 1) & (DRM_CRC_ENTRIES_NR - 1); crc->head = head; + spin_unlock(&crc->lock); + return 0; } EXPORT_SYMBOL_GPL(drm_crtc_add_crc_entry); From e8fa5671183c80342d520ad81d14fa79a9d4a680 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 2 Jan 2017 13:59:10 +0100 Subject: [PATCH 326/359] drm: crc: Wait for a frame before returning from open() Don't return from the open() call on the crc/data file until the HW has produced a first frame, as there's great variability in when the HW is able to do that and userspace shouldn't have to guess when this specific HW is ready to start giving frame CRCs. Signed-off-by: Tomeu Vizoso Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170102125912.22305-3-tomeu.vizoso@collabora.com --- drivers/gpu/drm/drm_debugfs_crc.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 68b171af237b..8b0eeeed4d78 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -125,6 +125,12 @@ static const struct file_operations drm_crtc_crc_control_fops = { .write = crc_control_write }; +static int crtc_crc_data_count(struct drm_crtc_crc *crc) +{ + assert_spin_locked(&crc->lock); + return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); +} + static int crtc_crc_open(struct inode *inode, struct file *filep) { struct drm_crtc *crtc = inode->i_private; @@ -160,8 +166,19 @@ static int crtc_crc_open(struct inode *inode, struct file *filep) crc->entries = entries; crc->values_cnt = values_cnt; crc->opened = true; + + /* + * Only return once we got a first frame, so userspace doesn't have to + * guess when this particular piece of HW will be ready to start + * generating CRCs. + */ + ret = wait_event_interruptible_lock_irq(crc->wq, + crtc_crc_data_count(crc), + crc->lock); spin_unlock_irq(&crc->lock); + WARN_ON(ret); + return 0; err_disable: @@ -189,12 +206,6 @@ static int crtc_crc_release(struct inode *inode, struct file *filep) return 0; } -static int crtc_crc_data_count(struct drm_crtc_crc *crc) -{ - assert_spin_locked(&crc->lock); - return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); -} - /* * 1 frame field of 10 chars plus a number of CRC fields of 10 chars each, space * separated, with a newline at the end and null-terminated. From c7858bf16c0b2cc62f475f31e6df28c3a68da1d6 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 3 Jan 2017 13:49:42 +0100 Subject: [PATCH 327/359] asm-prototypes: Clear any CPP defines before declaring the functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The asm-prototypes.h file is used to provide dummy function declarations for genksyms, when processing asm files with EXPORT_SYMBOL. Make sure that any architecture defines get out of our way. x86 currently has an issue with memcpy on 64bit with CONFIG_KMEMCHECK=y and with memset/__memset on 32bit: $ cat init/test.c #include $ make -s init/test.o In file included from ./arch/x86/include/asm/string.h:4:0, from ./include/linux/string.h:18, from ./include/linux/bitmap.h:8, from ./include/linux/cpumask.h:11, from ./arch/x86/include/asm/cpumask.h:4, from ./arch/x86/include/asm/msr.h:10, from ./arch/x86/include/asm/processor.h:20, from ./arch/x86/include/asm/cpufeature.h:4, from ./arch/x86/include/asm/thread_info.h:52, from ./include/linux/thread_info.h:25, from ./arch/x86/include/asm/preempt.h:6, from ./include/linux/preempt.h:59, from ./include/linux/spinlock.h:50, from ./include/linux/seqlock.h:35, from ./include/linux/time.h:5, from ./include/uapi/linux/timex.h:56, from ./include/linux/timex.h:56, from ./include/linux/sched.h:19, from ./include/linux/uaccess.h:4, from ./arch/x86/include/asm/asm-prototypes.h:2, from init/test.c:1: ./arch/x86/include/asm/string_64.h:52:47: error: expected declaration specifiers or ‘...’ before ‘(’ token #define memcpy(dst, src, len) __inline_memcpy((dst), (src), (len)) ./include/asm-generic/asm-prototypes.h:6:14: note: in expansion of macro ‘memcpy’ extern void *memcpy(void *, const void *, __kernel_size_t); ^ ... During real build, this manifests itself by genksyms segfaulting. Fixes: 334bb7738764 ("x86/kbuild: enable modversions for symbols exported from asm") Reported-and-tested-by: Borislav Petkov Cc: Adam Borowski Signed-off-by: Michal Marek --- include/asm-generic/asm-prototypes.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/asm-generic/asm-prototypes.h b/include/asm-generic/asm-prototypes.h index df13637e4017..939869c772b1 100644 --- a/include/asm-generic/asm-prototypes.h +++ b/include/asm-generic/asm-prototypes.h @@ -1,7 +1,13 @@ #include +#undef __memset extern void *__memset(void *, int, __kernel_size_t); +#undef __memcpy extern void *__memcpy(void *, const void *, __kernel_size_t); +#undef __memmove extern void *__memmove(void *, const void *, __kernel_size_t); +#undef memset extern void *memset(void *, int, __kernel_size_t); +#undef memcpy extern void *memcpy(void *, const void *, __kernel_size_t); +#undef memmove extern void *memmove(void *, const void *, __kernel_size_t); From 4c881451d3017033597ea186cf79ae41a73e1ef8 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 3 Jan 2017 17:43:00 +0000 Subject: [PATCH 328/359] KVM: MIPS: Don't clobber CP0_Status.UX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 64-bit kernels, MIPS KVM will clear CP0_Status.UX to prevent the guest (running in user mode) from accessing the 64-bit memory segments. However the previous value of CP0_Status.UX is never restored when exiting from the guest. If the user process uses 64-bit addressing (the n64 ABI) this can result in address error exceptions from the kernel if it needs to deliver a signal before returning to user mode, as the kernel will need to write a sigframe to high user addresses on the user stack which are disallowed by CP0_Status.UX=0. This is fixed by explicitly setting SX and UX again when exiting from the guest, and explicitly clearing those bits when returning to the guest. Having the SX and UX bits set when handling guest exits (rather than only when exiting to userland) will be helpful when we support VZ, since we shouldn't need to directly read or write guest memory, so it will be valid for cache management IPIs to access host user addresses. Signed-off-by: James Hogan Cc: Paolo Bonzini Cc: "Radim Krčmář" Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Cc: # 4.8.x- Signed-off-by: Radim Krčmář --- arch/mips/kvm/entry.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c index 6a02b3a3fa65..e92fb190e2d6 100644 --- a/arch/mips/kvm/entry.c +++ b/arch/mips/kvm/entry.c @@ -521,6 +521,9 @@ void *kvm_mips_build_exit(void *addr) uasm_i_and(&p, V0, V0, AT); uasm_i_lui(&p, AT, ST0_CU0 >> 16); uasm_i_or(&p, V0, V0, AT); +#ifdef CONFIG_64BIT + uasm_i_ori(&p, V0, V0, ST0_SX | ST0_UX); +#endif uasm_i_mtc0(&p, V0, C0_STATUS); uasm_i_ehb(&p); @@ -643,7 +646,7 @@ static void *kvm_mips_build_ret_to_guest(void *addr) /* Setup status register for running guest in UM */ uasm_i_ori(&p, V1, V1, ST0_EXL | KSU_USER | ST0_IE); - UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX)); + UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX | ST0_SX | ST0_UX)); uasm_i_and(&p, V1, V1, AT); uasm_i_mtc0(&p, V1, C0_STATUS); uasm_i_ehb(&p); From 32eb12a6c11034867401d56b012e3c15d5f8141e Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 3 Jan 2017 17:43:01 +0000 Subject: [PATCH 329/359] KVM: MIPS: Flush KVM entry code from icache globally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flush the KVM entry code from the icache on all CPUs, not just the one that built the entry code. Signed-off-by: James Hogan Cc: Paolo Bonzini Cc: "Radim Krčmář" Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Cc: # 3.16.x- Signed-off-by: Radim Krčmář --- arch/mips/kvm/mips.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 06a60b19acfb..29ec9ab3fd55 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -360,8 +360,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) dump_handler("kvm_exit", gebase + 0x2000, vcpu->arch.vcpu_run); /* Invalidate the icache for these ranges */ - local_flush_icache_range((unsigned long)gebase, - (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); + flush_icache_range((unsigned long)gebase, + (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); /* * Allocate comm page for guest kernel, a TLB will be reserved for From 69130ea1e6b9167d2459e2bab521196d0a0c0e68 Mon Sep 17 00:00:00 2001 From: Jan Dakinevich Date: Fri, 23 Dec 2016 01:13:53 +0300 Subject: [PATCH 330/359] KVM: VMX: remove duplicated declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declaration of VMX_VPID_EXTENT_SUPPORTED_MASK occures twice in the code. Probably, it was happened after unsuccessful merge. Signed-off-by: Jan Dakinevich Signed-off-by: Radim Krčmář --- arch/x86/kvm/vmx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ba20b00a450f..a236decb81e4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -132,12 +132,6 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO); #define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5 -#define VMX_VPID_EXTENT_SUPPORTED_MASK \ - (VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT | \ - VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | \ - VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT | \ - VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT) - /* * Hyper-V requires all of these, so mark them as supported even though * they are just treated the same as all-context. From 696c7f8e0373026e8bfb29b2d9ff2d0a92059d4d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 5 Jan 2017 02:13:31 +0100 Subject: [PATCH 331/359] ACPI / DMAR: Avoid passing NULL to acpi_put_table() Linus reported that commit 174cc7187e6f "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel" added a new warning on his desktop system: ACPI Warning: Table ffffffff9fe6c0a0, Validation count is zero before decrement which turns out to come from the acpi_put_table() in detect_intel_iommu(). This happens if the DMAR table is not present in which case NULL is passed to acpi_put_table() which doesn't check against that and attempts to handle it regardless. For this reason, check the pointer passed to acpi_put_table() before invoking it. Reported-by: Linus Torvalds Tested-by: Paul E. McKenney Fixes: 6b11d1d67713 ("ACPI / osl: Remove acpi_get_table_with_size()/early_acpi_os_unmap_memory() users") Signed-off-by: Rafael J. Wysocki --- drivers/iommu/dmar.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index a88576d50740..8ccbd7023194 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -903,8 +903,10 @@ int __init detect_intel_iommu(void) x86_init.iommu.iommu_init = intel_iommu_init; #endif - acpi_put_table(dmar_tbl); - dmar_tbl = NULL; + if (dmar_tbl) { + acpi_put_table(dmar_tbl); + dmar_tbl = NULL; + } up_write(&dmar_global_lock); return ret ? 1 : -ENODEV; From ae30ab4cd711a147cafaf5674c333c5a84fe53fb Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 5 Jan 2017 20:29:35 +1000 Subject: [PATCH 332/359] kbuild: initramfs fix dependency checking for compressed target When using initramfs compression, the data file compression suffix gets quotes pulled in from Kconfig, e.g., initramfs_data.cpio".gz" which make does not match a target and causes rebuild. Fix this by filtering out quotes from the Kconfig string. Fixes: 35e669e1a254 ("initramfs: select builtin initram compression algorithm on KConfig instead of Makefile") Reviewed-by: Francisco Blas Izquierdo Riera (klondike) Signed-off-by: Nicholas Piggin Signed-off-by: Linus Torvalds --- usr/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/Makefile b/usr/Makefile index 17a513268325..746c3fd0b933 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -5,7 +5,7 @@ klibcdirs:; PHONY += klibcdirs -suffix_y = $(CONFIG_INITRAMFS_COMPRESSION) +suffix_y = $(subst $\",,$(CONFIG_INITRAMFS_COMPRESSION)) AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/initramfs_data.cpio$(suffix_y)" # Generate builtin.o based on initramfs_data.o From 9e3596b0c6539e28546ff7c72a06576627068353 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 5 Jan 2017 20:29:36 +1000 Subject: [PATCH 333/359] kbuild: initramfs cleanup, set target from Kconfig Rather than keep a list of all possible compression types in the Makefile, set the target explicitly from Kconfig. Reviewed-by: Francisco Blas Izquierdo Riera (klondike) Signed-off-by: Nicholas Piggin Signed-off-by: Linus Torvalds --- usr/Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/usr/Makefile b/usr/Makefile index 746c3fd0b933..0b87e71c00fc 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -6,7 +6,9 @@ klibcdirs:; PHONY += klibcdirs suffix_y = $(subst $\",,$(CONFIG_INITRAMFS_COMPRESSION)) -AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/initramfs_data.cpio$(suffix_y)" +datafile_y = initramfs_data.cpio$(suffix_y) +AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/$(datafile_y)" + # Generate builtin.o based on initramfs_data.o obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o @@ -14,7 +16,7 @@ obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o # initramfs_data.o contains the compressed initramfs_data.cpio image. # The image is included using .incbin, a dependency which is not # tracked automatically. -$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE +$(obj)/initramfs_data.o: $(obj)/$(datafile_y) FORCE ##### # Generate the initramfs cpio archive @@ -38,10 +40,8 @@ endif quiet_cmd_initfs = GEN $@ cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) -targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 \ - initramfs_data.cpio.lzma initramfs_data.cpio.xz \ - initramfs_data.cpio.lzo initramfs_data.cpio.lz4 \ - initramfs_data.cpio +targets := $(datafile_y) + # do not try to update files included in initramfs $(deps_initramfs): ; @@ -51,6 +51,6 @@ $(deps_initramfs): klibcdirs # 2) There are changes in which files are included (added or deleted) # 3) If gen_init_cpio are newer than initramfs_data.cpio # 4) arguments to gen_initramfs.sh changes -$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs +$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d $(call if_changed,initfs) From 6def85a396ce7796bd9f4561c6ae8138833f7a52 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 3 Jan 2017 18:13:46 -0600 Subject: [PATCH 334/359] usb: musb: core: add clear_ep_rxintr() to musb_platform_ops During dma teardown for dequque urb, if musb load is high, musb might generate bogus rx ep interrupt even when the rx fifo is flushed. In such case any of the follow log messages could happen. musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0 musb_host_rx 1936: RX3 dma busy, csr 2020 As mentioned in the current inline comment, clearing ep interrupt in the teardown path avoids the bogus interrupt. Clearing ep interrupt is platform dependent, so this patch adds a platform callback to allow glue driver to clear the ep interrupt. This bug seems to be existing since the initial driver for musb support, but I only validated the fix back to v4.1, so only cc stable for v4.1+. cc: stable@vger.kernel.org # 4.1+ Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.h | 7 +++++++ drivers/usb/musb/musb_host.c | 10 ++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index a611e2f67bdc..ade902ea1221 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -216,6 +216,7 @@ struct musb_platform_ops { void (*pre_root_reset_end)(struct musb *musb); void (*post_root_reset_end)(struct musb *musb); int (*phy_callback)(enum musb_vbus_id_status status); + void (*clear_ep_rxintr)(struct musb *musb, int epnum); }; /* @@ -626,6 +627,12 @@ static inline void musb_platform_post_root_reset_end(struct musb *musb) musb->ops->post_root_reset_end(musb); } +static inline void musb_platform_clear_ep_rxintr(struct musb *musb, int epnum) +{ + if (musb->ops->clear_ep_rxintr) + musb->ops->clear_ep_rxintr(musb, epnum); +} + /* * gets the "dr_mode" property from DT and converts it into musb_mode * if the property is not found or not recognized returns MUSB_OTG diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index f6cdbad00dac..ac3a4952abb4 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2374,12 +2374,11 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) int is_in = usb_pipein(urb->pipe); int status = 0; u16 csr; + struct dma_channel *dma = NULL; musb_ep_select(regs, hw_end); if (is_dma_capable()) { - struct dma_channel *dma; - dma = is_in ? ep->rx_channel : ep->tx_channel; if (dma) { status = ep->musb->dma_controller->channel_abort(dma); @@ -2395,10 +2394,9 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) /* giveback saves bulk toggle */ csr = musb_h_flush_rxfifo(ep, 0); - /* REVISIT we still get an irq; should likely clear the - * endpoint's irq status here to avoid bogus irqs. - * clearing that status is platform-specific... - */ + /* clear the endpoint's irq status here to avoid bogus irqs */ + if (is_dma_capable() && dma) + musb_platform_clear_ep_rxintr(musb, ep->epnum); } else if (ep->epnum) { musb_h_tx_flush_fifo(ep); csr = musb_readw(epio, MUSB_TXCSR); From c48400baa02155a5ddad63e8554602e48782278c Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 3 Jan 2017 18:13:47 -0600 Subject: [PATCH 335/359] usb: musb: dsps: implement clear_ep_rxintr() callback During dma teardown for dequque urb, if musb load is high, musb might generate bogus rx ep interrupt even when the rx fifo is flushed. In such case any of the follow log messages could happen. musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0 musb_host_rx 1936: RX3 dma busy, csr 2020 As mentioned in the current inline comment, clearing ep interrupt in the teardown path avoids the bogus interrupt, so implement clear_ep_rxintr() callback. This bug seems to be existing since the initial driver for musb support, but I only validated the fix back to v4.1, so only cc stable for v4.1+. cc: stable@vger.kernel.org # 4.1+ Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_dsps.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index feae1561b9ab..9f125e179acd 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -267,6 +267,17 @@ static void otg_timer(unsigned long _musb) pm_runtime_put_autosuspend(dev); } +void dsps_musb_clear_ep_rxintr(struct musb *musb, int epnum) +{ + u32 epintr; + struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); + const struct dsps_musb_wrapper *wrp = glue->wrp; + + /* musb->lock might already been held */ + epintr = (1 << epnum) << wrp->rxep_shift; + musb_writel(musb->ctrl_base, wrp->epintr_status, epintr); +} + static irqreturn_t dsps_interrupt(int irq, void *hci) { struct musb *musb = hci; @@ -622,6 +633,7 @@ static struct musb_platform_ops dsps_ops = { .set_mode = dsps_musb_set_mode, .recover = dsps_musb_recover, + .clear_ep_rxintr = dsps_musb_clear_ep_rxintr, }; static u64 musb_dmamask = DMA_BIT_MASK(32); From 8c300fe282fa254ea730c92cb0983e2642dc1fff Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 3 Jan 2017 18:13:48 -0600 Subject: [PATCH 336/359] usb: musb: Fix trying to free already-free IRQ 4 When unloading omap2430, we can get the following splat: WARNING: CPU: 1 PID: 295 at kernel/irq/manage.c:1478 __free_irq+0xa8/0x2c8 Trying to free already-free IRQ 4 ... [] (free_irq) from [] (musbhs_dma_controller_destroy+0x28/0xb0 [musb_hdrc]) [] (musbhs_dma_controller_destroy [musb_hdrc]) from [] (musb_remove+0xf0/0x12c [musb_hdrc]) [] (musb_remove [musb_hdrc]) from [] (platform_drv_remove+0x24/0x3c) ... This is because the irq number in use is 260 nowadays, and the dma controller is using u8 instead of int. Fixes: 6995eb68aab7 ("USB: musb: enable low level DMA operation for Blackfin") Signed-off-by: Tony Lindgren [b-liu@ti.com: added Fixes tag] Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musbhsdma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index f7b13fd25257..a3dcbd55e436 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h @@ -157,5 +157,5 @@ struct musb_dma_controller { void __iomem *base; u8 channel_count; u8 used_channels; - u8 irq; + int irq; }; From c8bd2ac3b4c6c84c4a7cdceaed626247db698ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lefaure?= Date: Tue, 3 Jan 2017 18:13:49 -0600 Subject: [PATCH 337/359] usb: musb: fix compilation warning on unused function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function musb_run_resume_work is called only when CONFIG_PM is enabled. So this function should not be defined when CONFIG_PM is disabled. Otherwise the compiler issues a warning: drivers/usb/musb/musb_core.c:2057:12: error: ‘musb_run_resume_work’ defined but not used [-Werror=unused-function] static int musb_run_resume_work(struct musb *musb) ^~~~~~~~~~~~~~~~~~~~ Signed-off-by: Jérémy Lefaure Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 9e226468a13e..fca288bbc800 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2050,6 +2050,7 @@ struct musb_pending_work { struct list_head node; }; +#ifdef CONFIG_PM /* * Called from musb_runtime_resume(), musb_resume(), and * musb_queue_resume_work(). Callers must take musb->lock. @@ -2077,6 +2078,7 @@ static int musb_run_resume_work(struct musb *musb) return error; } +#endif /* * Called to run work if device is active or else queue the work to happen From 5563bb5743cb09bde0d0f4660a5e5b19c26903bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lefaure?= Date: Tue, 3 Jan 2017 18:13:52 -0600 Subject: [PATCH 338/359] usb: musb: blackfin: add bfin_fifo_offset in bfin_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function bfin_fifo_offset is defined but not used: drivers/usb/musb/blackfin.c:36:12: warning: ‘bfin_fifo_offset’ defined but not used [-Wunused-function] static u32 bfin_fifo_offset(u8 epnum) ^~~~~~~~~~~~~~~~ Adding bfin_fifo_offset to bfin_ops fixes this warning and allows musb core to call this function instead of default_fifo_offset. Fixes: cc92f6818f6e ("usb: musb: Populate new IO functions for blackfin") Signed-off-by: Jérémy Lefaure Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/blackfin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 310238c6b5cd..896798071817 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -469,6 +469,7 @@ static const struct musb_platform_ops bfin_ops = { .init = bfin_musb_init, .exit = bfin_musb_exit, + .fifo_offset = bfin_fifo_offset, .readb = bfin_readb, .writeb = bfin_writeb, .readw = bfin_readw, From 3bc02bce908c7250781376052248f5cd60a4e3d4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Dec 2016 15:37:30 +0100 Subject: [PATCH 339/359] usb: hub: Move hub_port_disable() to fix warning if PM is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CONFIG_PM=n: drivers/usb/core/hub.c:107: warning: ‘hub_usb3_port_prepare_disable’ declared inline after being called drivers/usb/core/hub.c:107: warning: previous declaration of ‘hub_usb3_port_prepare_disable’ was here To fix this, move hub_port_disable() after hub_usb3_port_prepare_disable(), and adjust forward declarations. Fixes: 37be66767e3cae4f ("usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices") Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 59 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1fa5c0f29c64..a56c75e09786 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -103,8 +103,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); -static void hub_usb3_port_prepare_disable(struct usb_hub *hub, - struct usb_port *port_dev); +static int hub_port_disable(struct usb_hub *hub, int port1, int set_state); static inline char *portspeed(struct usb_hub *hub, int portstatus) { @@ -902,34 +901,6 @@ static int hub_set_port_link_state(struct usb_hub *hub, int port1, USB_PORT_FEAT_LINK_STATE); } -/* - * USB-3 does not have a similar link state as USB-2 that will avoid negotiating - * a connection with a plugged-in cable but will signal the host when the cable - * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices - */ -static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) -{ - struct usb_port *port_dev = hub->ports[port1 - 1]; - struct usb_device *hdev = hub->hdev; - int ret = 0; - - if (!hub->error) { - if (hub_is_superspeed(hub->hdev)) { - hub_usb3_port_prepare_disable(hub, port_dev); - ret = hub_set_port_link_state(hub, port_dev->portnum, - USB_SS_PORT_LS_U3); - } else { - ret = usb_clear_port_feature(hdev, port1, - USB_PORT_FEAT_ENABLE); - } - } - if (port_dev->child && set_state) - usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED); - if (ret && ret != -ENODEV) - dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret); - return ret; -} - /* * Disable a port and mark a logical connect-change event, so that some * time later hub_wq will disconnect() any existing usb_device on the port @@ -4162,6 +4133,34 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, #endif /* CONFIG_PM */ +/* + * USB-3 does not have a similar link state as USB-2 that will avoid negotiating + * a connection with a plugged-in cable but will signal the host when the cable + * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices + */ +static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) +{ + struct usb_port *port_dev = hub->ports[port1 - 1]; + struct usb_device *hdev = hub->hdev; + int ret = 0; + + if (!hub->error) { + if (hub_is_superspeed(hub->hdev)) { + hub_usb3_port_prepare_disable(hub, port_dev); + ret = hub_set_port_link_state(hub, port_dev->portnum, + USB_SS_PORT_LS_U3); + } else { + ret = usb_clear_port_feature(hdev, port1, + USB_PORT_FEAT_ENABLE); + } + } + if (port_dev->child && set_state) + usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED); + if (ret && ret != -ENODEV) + dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret); + return ret; +} + /* USB 2.0 spec, 7.1.7.3 / fig 7-29: * From 674aea07e38200ea6f31ff6d5f200f0cf6cdb325 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 2 Jan 2017 15:26:17 +0100 Subject: [PATCH 340/359] usb: storage: unusual_uas: Add JMicron JMS56x to unusual device This device gives the following error on detection. xhci_hcd 0000:00:11.0: ERROR Transfer event for disabled endpoint or incorrect stream ring The same error is not seen when it is added to unusual_device list with US_FL_NO_REPORT_OPCODES passed. Signed-off-by: George Cherian Signed-off-by: Oliver Neukum CC: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index af3c7eecff91..16cc18369111 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -2109,6 +2109,13 @@ UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_BROKEN_FUA ), +/* Reported-by George Cherian */ +UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999, + "JMicron", + "JMS56x", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + /* * Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) * and Mac USB Dock USB-SCSI */ From 421463b80b40e919dc57483f967ebd41674a81ff Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 5 Jan 2017 09:36:26 -0800 Subject: [PATCH 341/359] hyper-v: Add myself as additional MAINTAINER Update the Hyper-V MAINTAINERS to include myself. Signed-off-by: Stephen Hemminger Acked-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index cfff2c9e3d94..fd394aece553 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5961,6 +5961,7 @@ F: drivers/media/platform/sti/hva Hyper-V CORE AND DRIVERS M: "K. Y. Srinivasan" M: Haiyang Zhang +M: Stephen Hemminger L: devel@linuxdriverproject.org S: Maintained F: arch/x86/include/asm/mshyperv.h From 8f12dc24490bde0d604b8bdfca05ea4b06a624a7 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Thu, 22 Dec 2016 08:43:55 +0100 Subject: [PATCH 342/359] usb: ohci-at91: use descriptor-based gpio APIs correctly The gpiod_get* function family does not want the -gpio suffix. Use devm_gpiod_get_index_optional instead of devm_gpiod_get_optional. The descriptor based APIs handle active high/low automatically. The vbus-gpios are output, request enable while getting the gpio. Don't try to get any vbus-gpios for ports outside num-ports. WTF? Big sigh. Fixes: 054d4b7b577d ("usb: ohci-at91: Use descriptor-based gpio APIs") Signed-off-by: Peter Rosin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index be9e63836881..414e3c376dbb 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -43,7 +43,6 @@ struct at91_usbh_data { struct gpio_desc *overcurrent_pin[AT91_MAX_USBH_PORTS]; u8 ports; /* number of ports on root hub */ u8 overcurrent_supported; - u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS]; u8 overcurrent_status[AT91_MAX_USBH_PORTS]; u8 overcurrent_changed[AT91_MAX_USBH_PORTS]; }; @@ -266,8 +265,7 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int if (!valid_port(port)) return; - gpiod_set_value(pdata->vbus_pin[port], - pdata->vbus_pin_active_low[port] ^ enable); + gpiod_set_value(pdata->vbus_pin[port], enable); } static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) @@ -275,8 +273,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) if (!valid_port(port)) return -EINVAL; - return gpiod_get_value(pdata->vbus_pin[port]) ^ - pdata->vbus_pin_active_low[port]; + return gpiod_get_value(pdata->vbus_pin[port]); } /* @@ -533,18 +530,17 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) pdata->ports = ports; at91_for_each_port(i) { - pdata->vbus_pin[i] = devm_gpiod_get_optional(&pdev->dev, - "atmel,vbus-gpio", - GPIOD_IN); + if (i >= pdata->ports) + break; + + pdata->vbus_pin[i] = + devm_gpiod_get_index_optional(&pdev->dev, "atmel,vbus", + i, GPIOD_OUT_HIGH); if (IS_ERR(pdata->vbus_pin[i])) { err = PTR_ERR(pdata->vbus_pin[i]); dev_err(&pdev->dev, "unable to claim gpio \"vbus\": %d\n", err); continue; } - - pdata->vbus_pin_active_low[i] = gpiod_get_value(pdata->vbus_pin[i]); - - ohci_at91_usb_set_power(pdata, i, 1); } at91_for_each_port(i) { @@ -552,8 +548,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) break; pdata->overcurrent_pin[i] = - devm_gpiod_get_optional(&pdev->dev, - "atmel,oc-gpio", GPIOD_IN); + devm_gpiod_get_index_optional(&pdev->dev, "atmel,oc", + i, GPIOD_IN); if (IS_ERR(pdata->overcurrent_pin[i])) { err = PTR_ERR(pdata->overcurrent_pin[i]); dev_err(&pdev->dev, "unable to claim gpio \"overcurrent\": %d\n", err); From 0a8fd1346254974c3a852338508e4a4cddbb35f1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 19 Dec 2016 12:03:41 -0500 Subject: [PATCH 343/359] USB: fix problems with duplicate endpoint addresses When checking a new device's descriptors, the USB core does not check for duplicate endpoint addresses. This can cause a problem when the sysfs files for those endpoints are created; trying to create multiple files with the same name will provoke a WARNING: WARNING: CPU: 2 PID: 865 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x8a/0xa0 sysfs: cannot create duplicate filename '/devices/platform/dummy_hcd.0/usb2/2-1/2-1:64.0/ep_05' Kernel panic - not syncing: panic_on_warn set ... CPU: 2 PID: 865 Comm: kworker/2:1 Not tainted 4.9.0-rc7+ #34 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Workqueue: usb_hub_wq hub_event ffff88006bee64c8 ffffffff81f96b8a ffffffff00000001 1ffff1000d7dcc2c ffffed000d7dcc24 0000000000000001 0000000041b58ab3 ffffffff8598b510 ffffffff81f968f8 ffffffff850fee20 ffffffff85cff020 dffffc0000000000 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [] dump_stack+0x292/0x398 lib/dump_stack.c:51 [] panic+0x1cb/0x3a9 kernel/panic.c:179 [] __warn+0x1c4/0x1e0 kernel/panic.c:542 [] warn_slowpath_fmt+0xc5/0x110 kernel/panic.c:565 [] sysfs_warn_dup+0x8a/0xa0 fs/sysfs/dir.c:30 [] sysfs_create_dir_ns+0x178/0x1d0 fs/sysfs/dir.c:59 [< inline >] create_dir lib/kobject.c:71 [] kobject_add_internal+0x227/0xa60 lib/kobject.c:229 [< inline >] kobject_add_varg lib/kobject.c:366 [] kobject_add+0x139/0x220 lib/kobject.c:411 [] device_add+0x353/0x1660 drivers/base/core.c:1088 [] device_register+0x1d/0x20 drivers/base/core.c:1206 [] usb_create_ep_devs+0x163/0x260 drivers/usb/core/endpoint.c:195 [] create_intf_ep_devs+0x13b/0x200 drivers/usb/core/message.c:1030 [] usb_set_configuration+0x1083/0x18d0 drivers/usb/core/message.c:1937 [] generic_probe+0x6e/0xe0 drivers/usb/core/generic.c:172 [] usb_probe_device+0xaa/0xe0 drivers/usb/core/driver.c:263 This patch prevents the problem by checking for duplicate endpoint addresses during enumeration and skipping any duplicates. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov Tested-by: Andrey Konovalov CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 0aa9e7d697a5..25dbd8c7aec7 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -239,6 +239,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, if (ifp->desc.bNumEndpoints >= num_ep) goto skip_to_next_endpoint_or_interface_descriptor; + /* Check for duplicate endpoint addresses */ + for (i = 0; i < ifp->desc.bNumEndpoints; ++i) { + if (ifp->endpoint[i].desc.bEndpointAddress == + d->bEndpointAddress) { + dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", + cfgno, inum, asnum, d->bEndpointAddress); + goto skip_to_next_endpoint_or_interface_descriptor; + } + } + endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; ++ifp->desc.bNumEndpoints; From 82f42e4cc164ed486c9e2b1b74e65b176830d947 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Wed, 4 Jan 2017 10:12:55 +0100 Subject: [PATCH 344/359] fbmem: add a default get_fb_unmapped_area function Allow generic frame-buffer to provide a default get_fb_unmapped_area function if specific devices need it. Usually this function is defined in architecture directories but define it here may limit code duplication especially for all ARM platforms without MMU. version 5: - set get_unmapped_area field if FB_PROVIDE_GET_FB_UNMAPPED_AREA is defined version 4: - introdude a configuration flag to be independent of architecture Signed-off-by: Benjamin Gaignard Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483521177-21794-2-git-send-email-benjamin.gaignard@linaro.org --- drivers/video/fbdev/Kconfig | 8 ++++++++ drivers/video/fbdev/core/fbmem.c | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 5d3b0db5ce0a..922e4eaed9c5 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -138,6 +138,14 @@ config FB_SYS_IMAGEBLIT blitting. This is used by drivers that don't provide their own (accelerated) version and the framebuffer is in system RAM. +config FB_PROVIDE_GET_FB_UNMAPPED_AREA + bool + depends on FB + default n + ---help--- + Allow generic frame-buffer to provide get_fb_unmapped_area + function. + menuconfig FB_FOREIGN_ENDIAN bool "Framebuffer foreign endianness support" depends on FB diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 76c1ad96fb37..069fe7960df1 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1492,6 +1492,21 @@ __releases(&info->lock) return 0; } +#ifdef CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA +unsigned long get_fb_unmapped_area(struct file *filp, + unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags) +{ + struct fb_info * const info = filp->private_data; + unsigned long fb_size = PAGE_ALIGN(info->fix.smem_len); + + if (pgoff > fb_size || len > fb_size - pgoff) + return -EINVAL; + + return (unsigned long)info->screen_base + pgoff; +} +#endif + static const struct file_operations fb_fops = { .owner = THIS_MODULE, .read = fb_read, @@ -1503,7 +1518,8 @@ static const struct file_operations fb_fops = { .mmap = fb_mmap, .open = fb_open, .release = fb_release, -#ifdef HAVE_ARCH_FB_UNMAPPED_AREA +#if defined(HAVE_ARCH_FB_UNMAPPED_AREA) || \ + defined(CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA) .get_unmapped_area = get_fb_unmapped_area, #endif #ifdef CONFIG_FB_DEFERRED_IO From 99c48e1e38f0aeaa107ad67c8d91f6c9d9d567a9 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Wed, 4 Jan 2017 10:12:56 +0100 Subject: [PATCH 345/359] drm: compile drm_vm.c only when needed drm_vm.c functions are only need for DRM_LEGACY and DRM_NOUVEAU. Use a new DRM_VM to define when drm_vm.c in needed. stub drm_legacy_vma_flush() to avoid compilation issues version 4: - a "config DRM_VM" in Kconfig Signed-off-by: Benjamin Gaignard [danvet: Fix conflict.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/Kconfig | 5 +++++ drivers/gpu/drm/Makefile | 3 ++- drivers/gpu/drm/drm_legacy.h | 7 +++++++ drivers/gpu/drm/nouveau/Kconfig | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 29146fa83001..d56b85c03b7b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -136,6 +136,10 @@ config DRM_KMS_CMA_HELPER help Choose this if you need the KMS CMA helper functions +config DRM_VM + bool + depends on DRM + source "drivers/gpu/drm/i2c/Kconfig" source "drivers/gpu/drm/arm/Kconfig" @@ -264,6 +268,7 @@ source "drivers/gpu/drm/meson/Kconfig" menuconfig DRM_LEGACY bool "Enable legacy drivers (DANGEROUS)" depends on DRM + select DRM_VM help Enable legacy DRI1 drivers. Those drivers expose unsafe and dangerous APIs to user-space, which can be used to circumvent access diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index d00c389f24bf..92de3991fa56 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -5,7 +5,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_context.o drm_dma.o \ drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ - drm_lock.o drm_memory.o drm_drv.o drm_vm.o \ + drm_lock.o drm_memory.o drm_drv.o \ drm_scatter.o drm_pci.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ @@ -19,6 +19,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_dumb_buffers.o drm_mode_config.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o +drm-$(CONFIG_DRM_VM) += drm_vm.o drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o drm-$(CONFIG_PCI) += ati_pcigart.o diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index c6f422e879dd..e4bb5ad747c8 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -74,7 +74,14 @@ int drm_legacy_freebufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_mapbufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_dma_ioctl(struct drm_device *d, void *v, struct drm_file *f); +#ifdef CONFIG_DRM_VM void drm_legacy_vma_flush(struct drm_device *d); +#else +static inline void drm_legacy_vma_flush(struct drm_device *d) +{ + /* do nothing */ +} +#endif /* * AGP Support diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 2922a82cba8e..0f2f0afc8f67 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -16,6 +16,7 @@ config DRM_NOUVEAU select INPUT if ACPI && X86 select THERMAL if ACPI && X86 select ACPI_VIDEO if ACPI && X86 + select DRM_VM help Choose this option for open-source NVIDIA support. From 62a0d98a188cc4ebd8ea54b37d274ec20465e464 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Wed, 4 Jan 2017 10:12:57 +0100 Subject: [PATCH 346/359] drm: allow to use mmuless SoC Some SoC without MMU have display driver where a drm/kms driver could be implemented. Before doing such kind of thing drm/kms must allow to use mmuless devices. This patch propose to remove MMU configuration flag and add a cma helper function to help implementing mmuless display driver version 4: - add documentation about drm_gem_cma_get_unmapped_area() - stub it MMU case Signed-off-by: Benjamin Gaignard [danvet: Use recommended struct member references in kernel-doc.] Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483521177-21794-4-git-send-email-benjamin.gaignard@linaro.org --- Documentation/gpu/drm-mm.rst | 11 +++++ drivers/gpu/drm/Kconfig | 4 +- drivers/gpu/drm/drm_gem_cma_helper.c | 71 ++++++++++++++++++++++++++++ include/drm/drm_gem_cma_helper.h | 17 +++++++ 4 files changed, 101 insertions(+), 2 deletions(-) diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index d3c6d77246cd..1ea94fc86caa 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -310,6 +310,17 @@ created. Drivers that want to map the GEM object upfront instead of handling page faults can implement their own mmap file operation handler. +For platforms without MMU the GEM core provides a helper method +:c:func:`drm_gem_cma_get_unmapped_area`. The mmap() routines will call +this to get a proposed address for the mapping. + +To use :c:func:`drm_gem_cma_get_unmapped_area`, drivers must fill the +struct :c:type:`struct file_operations ` get_unmapped_area +field with a pointer on :c:func:`drm_gem_cma_get_unmapped_area`. + +More detailed information about get_unmapped_area can be found in +Documentation/nommu-mmap.txt + Memory Coherency ---------------- diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index d56b85c03b7b..505ca1d262ee 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -6,7 +6,7 @@ # menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" - depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU && HAS_DMA + depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA select HDMI select FB_CMDLINE select I2C @@ -113,7 +113,7 @@ config DRM_LOAD_EDID_FIRMWARE config DRM_TTM tristate - depends on DRM + depends on DRM && MMU help GPU memory management subsystem for devices with multiple GPU memory types. Will be enabled automatically if a device driver diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index e0806a2ad11c..5cf38a474845 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -358,6 +358,77 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) } EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); +#ifndef CONFIG_MMU +/** + * drm_gem_cma_get_unmapped_area - propose address for mapping in noMMU cases + * @filp: file object + * @addr: memory address + * @len: buffer size + * @pgoff: page offset + * @flags: memory flags + * + * This function is used in noMMU platforms to propose address mapping + * for a given buffer. + * It's intended to be used as a direct handler for the struct + * &file_operations.get_unmapped_area operation. + * + * Returns: + * mapping address on success or a negative error code on failure. + */ +unsigned long drm_gem_cma_get_unmapped_area(struct file *filp, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags) +{ + struct drm_gem_cma_object *cma_obj; + struct drm_gem_object *obj = NULL; + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_vma_offset_node *node; + + if (drm_device_is_unplugged(dev)) + return -ENODEV; + + drm_vma_offset_lock_lookup(dev->vma_offset_manager); + node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager, + pgoff, + len >> PAGE_SHIFT); + if (likely(node)) { + obj = container_of(node, struct drm_gem_object, vma_node); + /* + * When the object is being freed, after it hits 0-refcnt it + * proceeds to tear down the object. In the process it will + * attempt to remove the VMA offset and so acquire this + * mgr->vm_lock. Therefore if we find an object with a 0-refcnt + * that matches our range, we know it is in the process of being + * destroyed and will be freed as soon as we release the lock - + * so we have to check for the 0-refcnted object and treat it as + * invalid. + */ + if (!kref_get_unless_zero(&obj->refcount)) + obj = NULL; + } + + drm_vma_offset_unlock_lookup(dev->vma_offset_manager); + + if (!obj) + return -EINVAL; + + if (!drm_vma_node_is_allowed(node, priv)) { + drm_gem_object_unreference_unlocked(obj); + return -EACCES; + } + + cma_obj = to_drm_gem_cma_obj(obj); + + drm_gem_object_unreference_unlocked(obj); + + return cma_obj->vaddr ? (unsigned long)cma_obj->vaddr : -EINVAL; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_get_unmapped_area); +#endif + #ifdef CONFIG_DEBUG_FS /** * drm_gem_cma_describe - describe a CMA GEM object for debugfs diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index acd6af8a8e67..2abcd5190cc1 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -53,6 +53,23 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, extern const struct vm_operations_struct drm_gem_cma_vm_ops; +#ifndef CONFIG_MMU +unsigned long drm_gem_cma_get_unmapped_area(struct file *filp, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags); +#else +static inline unsigned long drm_gem_cma_get_unmapped_area(struct file *filp, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags) +{ + return -EINVAL; +} +#endif + #ifdef CONFIG_DEBUG_FS void drm_gem_cma_describe(struct drm_gem_cma_object *obj, struct seq_file *m); #endif From 9f547425fd9fbcb42b177ec7eec46bd4d7d4ae45 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Fri, 6 Jan 2017 10:15:03 +0100 Subject: [PATCH 347/359] drm: crc: Call wake_up_interruptible() each time there is a new CRC entry Each time new data has being added in CRC list inform reader by calling wake_up_interruptible(). This should avoid to do it in all drivers. Signed-off-by: Benjamin Gaignard Cc: Tomeu Vizoso Cc: Daniel Vetter Reviewed-by: Tomeu Vizoso Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483694104-25627-1-git-send-email-benjamin.gaignard@linaro.org --- drivers/gpu/drm/drm_debugfs_crc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 8b0eeeed4d78..96891c4a6e23 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -363,6 +363,8 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, spin_unlock(&crc->lock); + wake_up_interruptible(&crc->wq); + return 0; } EXPORT_SYMBOL_GPL(drm_crtc_add_crc_entry); From 7453c549f5f6485c0d79cad7844870dcc7d1b34d Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 20 Dec 2016 10:02:02 -0500 Subject: [PATCH 348/359] swiotlb: Export swiotlb_max_segment to users So they can figure out what is the optimal number of pages that can be contingously stitched together without fear of bounce buffer. We also expose an mechanism for sub-users of SWIOTLB API, such as Xen-SWIOTLB to set the max segment value. And lastly if swiotlb=force is set (which mandates we bounce buffer everything) we set max_segment so at least we can bounce buffer one 4K page instead of a giant 512KB one for which we may not have space. Signed-off-by: Konrad Rzeszutek Wilk Reported-and-Tested-by: Juergen Gross --- drivers/gpu/drm/i915/i915_gem.c | 11 +---------- drivers/xen/swiotlb-xen.c | 4 ++++ include/linux/swiotlb.h | 3 +++ lib/swiotlb.c | 26 ++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d0dcaf35b429..115fa399608c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2290,15 +2290,6 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, mutex_unlock(&obj->mm.lock); } -static unsigned int swiotlb_max_size(void) -{ -#if IS_ENABLED(CONFIG_SWIOTLB) - return rounddown(swiotlb_nr_tbl() << IO_TLB_SHIFT, PAGE_SIZE); -#else - return 0; -#endif -} - static void i915_sg_trim(struct sg_table *orig_st) { struct sg_table new_st; @@ -2345,7 +2336,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); - max_segment = swiotlb_max_size(); + max_segment = swiotlb_max_segment(); if (!max_segment) max_segment = rounddown(UINT_MAX, PAGE_SIZE); diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index aba12009422e..f905d6eeb048 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -275,6 +275,10 @@ int __ref xen_swiotlb_init(int verbose, bool early) rc = 0; } else rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs); + + if (!rc) + swiotlb_set_max_segment(PAGE_SIZE); + return rc; error: if (repeat--) { diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index d9c84a9cde3d..4ee479f2f355 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -114,11 +114,14 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask); #ifdef CONFIG_SWIOTLB extern void __init swiotlb_free(void); +unsigned int swiotlb_max_segment(void); #else static inline void swiotlb_free(void) { } +static inline unsigned int swiotlb_max_segment(void) { return 0; } #endif extern void swiotlb_print_info(void); extern int is_swiotlb_buffer(phys_addr_t paddr); +extern void swiotlb_set_max_segment(unsigned int); #endif /* __LINUX_SWIOTLB_H */ diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 9def738af4f4..975b8fc4f1e1 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -82,6 +82,12 @@ static phys_addr_t io_tlb_overflow_buffer; static unsigned int *io_tlb_list; static unsigned int io_tlb_index; +/* + * Max segment that we can provide which (if pages are contingous) will + * not be bounced (unless SWIOTLB_FORCE is set). + */ +unsigned int max_segment; + /* * We need to save away the original address corresponding to a mapped entry * for the sync operations. @@ -124,6 +130,20 @@ unsigned long swiotlb_nr_tbl(void) } EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); +unsigned int swiotlb_max_segment(void) +{ + return max_segment; +} +EXPORT_SYMBOL_GPL(swiotlb_max_segment); + +void swiotlb_set_max_segment(unsigned int val) +{ + if (swiotlb_force == SWIOTLB_FORCE) + max_segment = 1; + else + max_segment = rounddown(val, PAGE_SIZE); +} + /* default to 64MB */ #define IO_TLB_DEFAULT_SIZE (64UL<<20) unsigned long swiotlb_size_or_default(void) @@ -205,6 +225,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) if (verbose) swiotlb_print_info(); + swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT); return 0; } @@ -283,6 +304,7 @@ swiotlb_late_init_with_default_size(size_t default_size) rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs); if (rc) free_pages((unsigned long)vstart, order); + return rc; } @@ -337,6 +359,8 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) late_alloc = 1; + swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT); + return 0; cleanup4: @@ -351,6 +375,7 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) io_tlb_end = 0; io_tlb_start = 0; io_tlb_nslabs = 0; + max_segment = 0; return -ENOMEM; } @@ -379,6 +404,7 @@ void __init swiotlb_free(void) PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); } io_tlb_nslabs = 0; + max_segment = 0; } int is_swiotlb_buffer(phys_addr_t paddr) From 01d0f715869161dc70e2bf66fcdf6533a6a782cd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 6 Jan 2017 08:20:03 +0100 Subject: [PATCH 349/359] MAINTAINERS: add greybus subsystem mailing list The Greybus driver subsystem has a mailing list, so list it in the MAINTAINERS file so that people know to send patches there as well. Signed-off-by: Greg Kroah-Hartman Acked-by: Johan Hovold Reviewed-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index cfff2c9e3d94..f6cb07684cea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5504,6 +5504,7 @@ M: Alex Elder M: Greg Kroah-Hartman S: Maintained F: drivers/staging/greybus/ +L: greybus-dev@lists.linaro.org GREYBUS AUDIO PROTOCOLS DRIVERS M: Vaibhav Agarwal From b0b9b3df27d100a975b4e8818f35382b64a5e35c Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sat, 7 Jan 2017 15:37:31 -0800 Subject: [PATCH 350/359] mm: stop leaking PageTables 4.10-rc loadtest (even on x86, and even without THPCache) fails with "fork: Cannot allocate memory" or some such; and /proc/meminfo shows PageTables growing. Commit 953c66c2b22a ("mm: THP page cache support for ppc64") that got merged in rc1 removed the freeing of an unused preallocated pagetable after do_fault_around() has called map_pages(). This is usually a good optimization, so that the followup doesn't have to reallocate one; but it's not sufficient to shift the freeing into alloc_set_pte(), since there are failure cases (most commonly VM_FAULT_RETRY) which never reach finish_fault(). Check and free it at the outer level in do_fault(), then we don't need to worry in alloc_set_pte(), and can restore that to how it was (I cannot find any reason to pte_free() under lock as it was doing). And fix a separate pagetable leak, or crash, introduced by the same change, that could only show up on some ppc64: why does do_set_pmd()'s failure case attempt to withdraw a pagetable when it never deposited one, at the same time overwriting (so leaking) the vmf->prealloc_pte? Residue of an earlier implementation, perhaps? Delete it. Fixes: 953c66c2b22a ("mm: THP page cache support for ppc64") Cc: Aneesh Kumar K.V Cc: Kirill A. Shutemov Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Michael Neuling Cc: Paul Mackerras Cc: Balbir Singh Cc: Andrew Morton Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds --- mm/memory.c | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 7d23b5050248..9f2c15cdb32c 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3008,13 +3008,6 @@ static int do_set_pmd(struct vm_fault *vmf, struct page *page) ret = 0; count_vm_event(THP_FILE_MAPPED); out: - /* - * If we are going to fallback to pte mapping, do a - * withdraw with pmd lock held. - */ - if (arch_needs_pgtable_deposit() && ret == VM_FAULT_FALLBACK) - vmf->prealloc_pte = pgtable_trans_huge_withdraw(vma->vm_mm, - vmf->pmd); spin_unlock(vmf->ptl); return ret; } @@ -3055,20 +3048,18 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, ret = do_set_pmd(vmf, page); if (ret != VM_FAULT_FALLBACK) - goto fault_handled; + return ret; } if (!vmf->pte) { ret = pte_alloc_one_map(vmf); if (ret) - goto fault_handled; + return ret; } /* Re-check under ptl */ - if (unlikely(!pte_none(*vmf->pte))) { - ret = VM_FAULT_NOPAGE; - goto fault_handled; - } + if (unlikely(!pte_none(*vmf->pte))) + return VM_FAULT_NOPAGE; flush_icache_page(vma, page); entry = mk_pte(page, vma->vm_page_prot); @@ -3088,15 +3079,8 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, /* no need to invalidate: a not-present page won't be cached */ update_mmu_cache(vma, vmf->address, vmf->pte); - ret = 0; -fault_handled: - /* preallocated pagetable is unused: free it */ - if (vmf->prealloc_pte) { - pte_free(vmf->vma->vm_mm, vmf->prealloc_pte); - vmf->prealloc_pte = 0; - } - return ret; + return 0; } @@ -3360,15 +3344,24 @@ static int do_shared_fault(struct vm_fault *vmf) static int do_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; + int ret; /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */ if (!vma->vm_ops->fault) - return VM_FAULT_SIGBUS; - if (!(vmf->flags & FAULT_FLAG_WRITE)) - return do_read_fault(vmf); - if (!(vma->vm_flags & VM_SHARED)) - return do_cow_fault(vmf); - return do_shared_fault(vmf); + ret = VM_FAULT_SIGBUS; + else if (!(vmf->flags & FAULT_FLAG_WRITE)) + ret = do_read_fault(vmf); + else if (!(vma->vm_flags & VM_SHARED)) + ret = do_cow_fault(vmf); + else + ret = do_shared_fault(vmf); + + /* preallocated pagetable is unused: free it */ + if (vmf->prealloc_pte) { + pte_free(vma->vm_mm, vmf->prealloc_pte); + vmf->prealloc_pte = 0; + } + return ret; } static int numa_migrate_prep(struct page *page, struct vm_area_struct *vma, From ea07b862ac8ef9b8c8358517d2e39f847dda6659 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 6 Jan 2017 19:21:43 -0500 Subject: [PATCH 351/359] mm: workingset: fix use-after-free in shadow node shrinker Several people report seeing warnings about inconsistent radix tree nodes followed by crashes in the workingset code, which all looked like use-after-free access from the shadow node shrinker. Dave Jones managed to reproduce the issue with a debug patch applied, which confirmed that the radix tree shrinking indeed frees shadow nodes while they are still linked to the shadow LRU: WARNING: CPU: 2 PID: 53 at lib/radix-tree.c:643 delete_node+0x1e4/0x200 CPU: 2 PID: 53 Comm: kswapd0 Not tainted 4.10.0-rc2-think+ #3 Call Trace: delete_node+0x1e4/0x200 __radix_tree_delete_node+0xd/0x10 shadow_lru_isolate+0xe6/0x220 __list_lru_walk_one.isra.4+0x9b/0x190 list_lru_walk_one+0x23/0x30 scan_shadow_nodes+0x2e/0x40 shrink_slab.part.44+0x23d/0x5d0 shrink_node+0x22c/0x330 kswapd+0x392/0x8f0 This is the WARN_ON_ONCE(!list_empty(&node->private_list)) placed in the inlined radix_tree_shrink(). The problem is with 14b468791fa9 ("mm: workingset: move shadow entry tracking to radix tree exceptional tracking"), which passes an update callback into the radix tree to link and unlink shadow leaf nodes when tree entries change, but forgot to pass the callback when reclaiming a shadow node. While the reclaimed shadow node itself is unlinked by the shrinker, its deletion from the tree can cause the left-most leaf node in the tree to be shrunk. If that happens to be a shadow node as well, we don't unlink it from the LRU as we should. Consider this tree, where the s are shadow entries: root->rnode | [0 n] | | [s ] [sssss] Now the shadow node shrinker reclaims the rightmost leaf node through the shadow node LRU: root->rnode | [0 ] | [s ] Because the parent of the deleted node is the first level below the root and has only one child in the left-most slot, the intermediate level is shrunk and the node containing the single shadow is put in its place: root->rnode | [s ] The shrinker again sees a single left-most slot in a first level node and thus decides to store the shadow in root->rnode directly and free the node - which is a leaf node on the shadow node LRU. root->rnode | s Without the update callback, the freed node remains on the shadow LRU, where it causes later shrinker runs to crash. Pass the node updater callback into __radix_tree_delete_node() in case the deletion causes the left-most branch in the tree to collapse too. Also add warnings when linked nodes are freed right away, rather than wait for the use-after-free when the list is scanned much later. Fixes: 14b468791fa9 ("mm: workingset: move shadow entry tracking to radix tree exceptional tracking") Reported-by: Dave Chinner Reported-by: Hugh Dickins Reported-by: Andrea Arcangeli Reported-and-tested-by: Dave Jones Signed-off-by: Johannes Weiner Cc: Christoph Hellwig Cc: Chris Leech Cc: Lee Duncan Cc: Jan Kara Cc: Kirill A. Shutemov Cc: Matthew Wilcox Cc: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/radix-tree.h | 4 +++- lib/radix-tree.c | 11 +++++++++-- mm/workingset.c | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 5dea8f6440e4..52bda854593b 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -306,7 +306,9 @@ void radix_tree_iter_replace(struct radix_tree_root *, void radix_tree_replace_slot(struct radix_tree_root *root, void **slot, void *item); void __radix_tree_delete_node(struct radix_tree_root *root, - struct radix_tree_node *node); + struct radix_tree_node *node, + radix_tree_update_node_t update_node, + void *private); void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *); void *radix_tree_delete(struct radix_tree_root *, unsigned long); void radix_tree_clear_tags(struct radix_tree_root *root, diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 6f382e07de77..0b92d605fb69 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -640,6 +640,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root, update_node(node, private); } + WARN_ON_ONCE(!list_empty(&node->private_list)); radix_tree_node_free(node); } } @@ -666,6 +667,7 @@ static void delete_node(struct radix_tree_root *root, root->rnode = NULL; } + WARN_ON_ONCE(!list_empty(&node->private_list)); radix_tree_node_free(node); node = parent; @@ -767,6 +769,7 @@ static void radix_tree_free_nodes(struct radix_tree_node *node) struct radix_tree_node *old = child; offset = child->offset + 1; child = child->parent; + WARN_ON_ONCE(!list_empty(&node->private_list)); radix_tree_node_free(old); if (old == entry_to_node(node)) return; @@ -1824,15 +1827,19 @@ EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot); * __radix_tree_delete_node - try to free node after clearing a slot * @root: radix tree root * @node: node containing @index + * @update_node: callback for changing leaf nodes + * @private: private data to pass to @update_node * * After clearing the slot at @index in @node from radix tree * rooted at @root, call this function to attempt freeing the * node and shrinking the tree. */ void __radix_tree_delete_node(struct radix_tree_root *root, - struct radix_tree_node *node) + struct radix_tree_node *node, + radix_tree_update_node_t update_node, + void *private) { - delete_node(root, node, NULL, NULL); + delete_node(root, node, update_node, private); } /** diff --git a/mm/workingset.c b/mm/workingset.c index 241fa5d6b3b2..abb58ffa3c64 100644 --- a/mm/workingset.c +++ b/mm/workingset.c @@ -473,7 +473,8 @@ static enum lru_status shadow_lru_isolate(struct list_head *item, if (WARN_ON_ONCE(node->exceptional)) goto out_invalid; inc_node_state(page_pgdat(virt_to_page(node)), WORKINGSET_NODERECLAIM); - __radix_tree_delete_node(&mapping->page_tree, node); + __radix_tree_delete_node(&mapping->page_tree, node, + workingset_update_node, mapping); out_invalid: spin_unlock(&mapping->tree_lock); From a121103c922847ba5010819a3f250f1f7fc84ab8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 8 Jan 2017 14:18:17 -0800 Subject: [PATCH 352/359] Linux 4.10-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5470d599384a..5f1a84735ff6 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 10 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Roaring Lionus # *DOCUMENTATION* From a09759e82f2d60823027e9d3391bbea40f919604 Mon Sep 17 00:00:00 2001 From: Vincent Abriou Date: Fri, 6 Jan 2017 17:44:43 +0100 Subject: [PATCH 353/359] drm: remove useless parameters from drm_pick_cmdline_mode function drm_pick_cmdline_mode width and height parameters are useless. Just remove them. Cc: Daniel Vetter Cc: Jani Nikula Signed-off-by: Vincent Abriou Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483721084-20278-2-git-send-email-vincent.abriou@st.com --- drivers/gpu/drm/drm_fb_helper.c | 7 +++---- drivers/gpu/drm/i915/intel_fbdev.c | 2 +- include/drm/drm_fb_helper.h | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 730342cbe899..0ab6aaacb7d6 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1752,8 +1752,7 @@ static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) return fb_connector->connector->cmdline_mode.specified; } -struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, - int width, int height) +struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn) { struct drm_cmdline_mode *cmdline_mode; struct drm_display_mode *mode; @@ -1871,7 +1870,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, if (!enabled[i]) continue; fb_helper_conn = fb_helper->connector_info[i]; - modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height); + modes[i] = drm_pick_cmdline_mode(fb_helper_conn); if (!modes[i]) { can_clone = false; break; @@ -1993,7 +1992,7 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper, fb_helper_conn->connector->base.id); /* got for command line mode first */ - modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height); + modes[i] = drm_pick_cmdline_mode(fb_helper_conn); if (!modes[i]) { DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n", fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id : 0); diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 570c07d59d1a..a46b19d9de0e 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -447,7 +447,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, connector->name); /* go for command line mode first */ - modes[i] = drm_pick_cmdline_mode(fb_conn, width, height); + modes[i] = drm_pick_cmdline_mode(fb_conn); /* try for preferred next */ if (!modes[i]) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 53687c5664b8..e62e1cf22678 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -295,8 +295,7 @@ struct drm_display_mode * drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height); struct drm_display_mode * -drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, - int width, int height); +drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn); int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, From 931c670d209b64a6033c1a2857ff309eee88f9c8 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 7 Jan 2017 16:52:11 +0800 Subject: [PATCH 354/359] drm: add more document for drm_crtc_from_index() Add a bit more document for function drm_crtc_from_index() to cross link it with drm_crtc_from_index(), and explain that the function is useful in vblank code. While at it, add cross link comment for drm_plane_from_index() as well. Signed-off-by: Shawn Guo Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483779131-19935-1-git-send-email-shawnguo@kernel.org --- drivers/gpu/drm/drm_crtc.c | 5 ++++- drivers/gpu/drm/drm_plane.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 75e0beeb3793..bd3c8b243447 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -52,7 +52,10 @@ * @idx: index of registered CRTC to find for * * Given a CRTC index, return the registered CRTC from DRM device's - * list of CRTCs with matching index. + * list of CRTCs with matching index. This is the inverse of drm_crtc_index(). + * It's useful in the vblank callbacks (like &drm_driver.enable_vblank or + * &drm_driver.disable_vblank), since that still deals with indices instead + * of pointers to &struct drm_crtc." */ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx) { diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 7b7275f0c2df..eed66be18329 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -254,7 +254,7 @@ EXPORT_SYMBOL(drm_plane_cleanup); * @idx: index of registered plane to find for * * Given a plane index, return the registered plane from DRM device's - * list of planes with matching index. + * list of planes with matching index. This is the inverse of drm_plane_index(). */ struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx) From 11b3c20bdd15d17382068be569740de1dccb173d Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Fri, 6 Jan 2017 15:57:31 -0200 Subject: [PATCH 355/359] drm: Change the return type of the unload hook to void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The integer returned by the unload hook is ignored by the drm core, so let's make it void. This patch was created using the following Coccinelle semantic script (except for the declaration and comment in drm_drv.h): Compile-tested only. // @ get_name @ struct drm_driver drv; identifier fn; @@ drv.unload = fn; @ replace_type @ identifier get_name.fn; @@ - int + void fn (...) { ... } @ remove_return_param @ identifier get_name.fn; @@ void fn (...) { <... if (...) return - ... ; ...> } @ drop_final_return @ identifier get_name.fn; @@ void fn (...) { ... - return 0; } // Suggested-by: Daniel Vetter Signed-off-by: Gabriel Krisman Bertazi Acked-by: Christian König . Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20170106175731.29196-1-krisman@collabora.co.uk --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 ++--- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_main.c | 3 +-- drivers/gpu/drm/bochs/bochs_drv.c | 3 +-- drivers/gpu/drm/cirrus/cirrus_drv.h | 2 +- drivers/gpu/drm/cirrus/cirrus_main.c | 5 ++--- drivers/gpu/drm/exynos/exynos_drm_drv.c | 4 +--- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 4 +--- drivers/gpu/drm/gma500/psb_drv.c | 3 +-- drivers/gpu/drm/mga/mga_dma.c | 4 +--- drivers/gpu/drm/mga/mga_drv.h | 2 +- drivers/gpu/drm/mgag200/mgag200_drv.h | 2 +- drivers/gpu/drm/mgag200/mgag200_main.c | 5 ++--- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +-- drivers/gpu/drm/omapdrm/omap_drv.c | 4 +--- drivers/gpu/drm/qxl/qxl_drv.h | 2 +- drivers/gpu/drm/qxl/qxl_kms.c | 5 ++--- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/radeon_kms.c | 5 ++--- drivers/gpu/drm/savage/savage_bci.c | 4 +--- drivers/gpu/drm/savage/savage_drv.h | 2 +- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 4 +--- drivers/gpu/drm/sis/sis_drv.c | 4 +--- drivers/gpu/drm/tegra/drm.c | 6 ++---- drivers/gpu/drm/udl/udl_drv.h | 2 +- drivers/gpu/drm/udl/udl_main.c | 3 +-- drivers/gpu/drm/via/via_drv.h | 2 +- drivers/gpu/drm/via/via_map.c | 4 +--- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 +- drivers/gpu/drm/virtio/virtgpu_kms.c | 3 +-- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 +--- include/drm/drm_drv.h | 5 +---- 33 files changed, 39 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 54ac8a845e9f..7077ed65d403 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1711,7 +1711,7 @@ extern const struct drm_ioctl_desc amdgpu_ioctls_kms[]; extern const int amdgpu_max_kms_ioctl; int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags); -int amdgpu_driver_unload_kms(struct drm_device *dev); +void amdgpu_driver_unload_kms(struct drm_device *dev); void amdgpu_driver_lastclose_kms(struct drm_device *dev); int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv); void amdgpu_driver_postclose_kms(struct drm_device *dev, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 9af87eaf8ee3..8aef25828888 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -50,12 +50,12 @@ static inline bool amdgpu_has_atpx(void) { return false; } * This is the main unload function for KMS (all asics). * Returns 0 on success. */ -int amdgpu_driver_unload_kms(struct drm_device *dev) +void amdgpu_driver_unload_kms(struct drm_device *dev) { struct amdgpu_device *adev = dev->dev_private; if (adev == NULL) - return 0; + return; if (adev->rmmio == NULL) goto done_free; @@ -74,7 +74,6 @@ int amdgpu_driver_unload_kms(struct drm_device *dev) done_free: kfree(adev); dev->dev_private = NULL; - return 0; } /** diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 6f3b6f50cf52..1051181d8c0d 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -122,7 +122,7 @@ struct ast_private { }; int ast_driver_load(struct drm_device *dev, unsigned long flags); -int ast_driver_unload(struct drm_device *dev); +void ast_driver_unload(struct drm_device *dev); struct ast_gem_object; diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index d85af0ff2653..5b59888426cf 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -476,7 +476,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) return ret; } -int ast_driver_unload(struct drm_device *dev) +void ast_driver_unload(struct drm_device *dev) { struct ast_private *ast = dev->dev_private; @@ -489,7 +489,6 @@ int ast_driver_unload(struct drm_device *dev) pci_iounmap(dev->pdev, ast->ioregs); pci_iounmap(dev->pdev, ast->regs); kfree(ast); - return 0; } int ast_gem_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 15a293e65b31..8a12b3f6fc66 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -19,7 +19,7 @@ MODULE_PARM_DESC(fbdev, "register fbdev device"); /* ---------------------------------------------------------------------- */ /* drm interface */ -static int bochs_unload(struct drm_device *dev) +static void bochs_unload(struct drm_device *dev) { struct bochs_device *bochs = dev->dev_private; @@ -29,7 +29,6 @@ static int bochs_unload(struct drm_device *dev) bochs_hw_fini(dev); kfree(bochs); dev->dev_private = NULL; - return 0; } static int bochs_load(struct drm_device *dev, unsigned long flags) diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h index b59aeef4635a..8690352d96f7 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.h +++ b/drivers/gpu/drm/cirrus/cirrus_drv.h @@ -231,7 +231,7 @@ irqreturn_t cirrus_driver_irq_handler(int irq, void *arg); /* cirrus_kms.c */ int cirrus_driver_load(struct drm_device *dev, unsigned long flags); -int cirrus_driver_unload(struct drm_device *dev); +void cirrus_driver_unload(struct drm_device *dev); extern struct drm_ioctl_desc cirrus_ioctls[]; extern int cirrus_max_ioctl; diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index 52d901fa8687..e7fc95f63dca 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c @@ -208,18 +208,17 @@ int cirrus_driver_load(struct drm_device *dev, unsigned long flags) return r; } -int cirrus_driver_unload(struct drm_device *dev) +void cirrus_driver_unload(struct drm_device *dev) { struct cirrus_device *cdev = dev->dev_private; if (cdev == NULL) - return 0; + return; cirrus_modeset_fini(cdev); cirrus_mm_fini(cdev); cirrus_device_fini(cdev); kfree(cdev); dev->dev_private = NULL; - return 0; } int cirrus_gem_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 739180ac3da5..3ec053542e93 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -186,7 +186,7 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) return ret; } -static int exynos_drm_unload(struct drm_device *dev) +static void exynos_drm_unload(struct drm_device *dev) { exynos_drm_device_subdrv_remove(dev); @@ -200,8 +200,6 @@ static int exynos_drm_unload(struct drm_device *dev) kfree(dev->dev_private); dev->dev_private = NULL; - - return 0; } static int commit_is_pending(struct exynos_drm_private *priv, u32 crtcs) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 9a31711d5158..48705248f894 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -116,7 +116,7 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) return ret; } -static int fsl_dcu_unload(struct drm_device *dev) +static void fsl_dcu_unload(struct drm_device *dev) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; @@ -131,8 +131,6 @@ static int fsl_dcu_unload(struct drm_device *dev) drm_irq_uninstall(dev); dev->dev_private = NULL; - - return 0; } static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg) diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index ff37ea585664..0dc7ba2fdc22 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -159,7 +159,7 @@ static int psb_do_init(struct drm_device *dev) return 0; } -static int psb_driver_unload(struct drm_device *dev) +static void psb_driver_unload(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; @@ -220,7 +220,6 @@ static int psb_driver_unload(struct drm_device *dev) dev->dev_private = NULL; } gma_power_uninit(dev); - return 0; } static int psb_driver_load(struct drm_device *dev, unsigned long flags) diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 1f2f9ca25901..a1d8dd15b131 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c @@ -1127,12 +1127,10 @@ int mga_dma_buffers(struct drm_device *dev, void *data, /** * Called just before the module is unloaded. */ -int mga_driver_unload(struct drm_device *dev) +void mga_driver_unload(struct drm_device *dev) { kfree(dev->dev_private); dev->dev_private = NULL; - - return 0; } /** diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index bb312339e0b0..d5ce829b3199 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h @@ -166,7 +166,7 @@ extern int mga_dma_reset(struct drm_device *dev, void *data, extern int mga_dma_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int mga_driver_load(struct drm_device *dev, unsigned long flags); -extern int mga_driver_unload(struct drm_device *dev); +extern void mga_driver_unload(struct drm_device *dev); extern void mga_driver_lastclose(struct drm_device *dev); extern int mga_driver_dma_quiescent(struct drm_device *dev); diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 87e0934773de..0d6e998d63e6 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -258,7 +258,7 @@ int mgag200_framebuffer_init(struct drm_device *dev, int mgag200_driver_load(struct drm_device *dev, unsigned long flags); -int mgag200_driver_unload(struct drm_device *dev); +void mgag200_driver_unload(struct drm_device *dev); int mgag200_gem_create(struct drm_device *dev, u32 size, bool iskernel, struct drm_gem_object **obj); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index da8ba6c154e3..dce8a3eb5a10 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -264,18 +264,17 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) return r; } -int mgag200_driver_unload(struct drm_device *dev) +void mgag200_driver_unload(struct drm_device *dev) { struct mga_device *mdev = dev->dev_private; if (mdev == NULL) - return 0; + return; mgag200_modeset_fini(mdev); mgag200_fbdev_fini(mdev); drm_mode_config_cleanup(dev); mgag200_mm_fini(mdev); dev->dev_private = NULL; - return 0; } int mgag200_gem_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 59348fc41c77..dd7b52ab505a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -502,7 +502,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) return ret; } -static int +static void nouveau_drm_unload(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); @@ -531,7 +531,6 @@ nouveau_drm_unload(struct drm_device *dev) if (drm->hdmi_device) pci_dev_put(drm->hdmi_device); nouveau_cli_destroy(&drm->client); - return 0; } void diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index fdc83cbcde61..4fd2e1799a88 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -694,7 +694,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags) return 0; } -static int dev_unload(struct drm_device *dev) +static void dev_unload(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; @@ -717,8 +717,6 @@ static int dev_unload(struct drm_device *dev) dev->dev_private = NULL; dev_set_drvdata(dev->dev, NULL); - - return 0; } static int dev_open(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index f15ddd0eb85b..883d8639c04e 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -337,7 +337,7 @@ extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl; int qxl_driver_load(struct drm_device *dev, unsigned long flags); -int qxl_driver_unload(struct drm_device *dev); +void qxl_driver_unload(struct drm_device *dev); int qxl_modeset_init(struct qxl_device *qdev); void qxl_modeset_fini(struct qxl_device *qdev); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index af685f1d91f8..b2491407b616 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -285,12 +285,12 @@ static void qxl_device_fini(struct qxl_device *qdev) qxl_debugfs_remove_files(qdev); } -int qxl_driver_unload(struct drm_device *dev) +void qxl_driver_unload(struct drm_device *dev) { struct qxl_device *qdev = dev->dev_private; if (qdev == NULL) - return 0; + return; drm_vblank_cleanup(dev); @@ -299,7 +299,6 @@ int qxl_driver_unload(struct drm_device *dev) kfree(qdev); dev->dev_private = NULL; - return 0; } int qxl_driver_load(struct drm_device *dev, unsigned long flags) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 00ea0002b539..af3bbe82fd48 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -102,7 +102,7 @@ #define KMS_DRIVER_MINOR 48 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); -int radeon_driver_unload_kms(struct drm_device *dev); +void radeon_driver_unload_kms(struct drm_device *dev); void radeon_driver_lastclose_kms(struct drm_device *dev); int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv); void radeon_driver_postclose_kms(struct drm_device *dev, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 4388ddeec8d2..116cf0d23595 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -53,12 +53,12 @@ static inline bool radeon_has_atpx(void) { return false; } * the rest of the device (CP, writeback, etc.). * Returns 0 on success. */ -int radeon_driver_unload_kms(struct drm_device *dev) +void radeon_driver_unload_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; if (rdev == NULL) - return 0; + return; if (rdev->rmmio == NULL) goto done_free; @@ -78,7 +78,6 @@ int radeon_driver_unload_kms(struct drm_device *dev) done_free: kfree(rdev); dev->dev_private = NULL; - return 0; } /** diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index d47dff95fe52..2a5b8466d806 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c @@ -655,13 +655,11 @@ void savage_driver_lastclose(struct drm_device *dev) } } -int savage_driver_unload(struct drm_device *dev) +void savage_driver_unload(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; kfree(dev_priv); - - return 0; } static int savage_do_init_bci(struct drm_device * dev, drm_savage_init_t * init) diff --git a/drivers/gpu/drm/savage/savage_drv.h b/drivers/gpu/drm/savage/savage_drv.h index 37b699571ad0..44a1009b6ecb 100644 --- a/drivers/gpu/drm/savage/savage_drv.h +++ b/drivers/gpu/drm/savage/savage_drv.h @@ -210,7 +210,7 @@ extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, extern int savage_driver_load(struct drm_device *dev, unsigned long chipset); extern int savage_driver_firstopen(struct drm_device *dev); extern void savage_driver_lastclose(struct drm_device *dev); -extern int savage_driver_unload(struct drm_device *dev); +extern void savage_driver_unload(struct drm_device *dev); extern void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index 38dd55f4af81..33cec3d42389 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -104,7 +104,7 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev, * DRM operations */ -static int shmob_drm_unload(struct drm_device *dev) +static void shmob_drm_unload(struct drm_device *dev) { drm_kms_helper_poll_fini(dev); drm_mode_config_cleanup(dev); @@ -112,8 +112,6 @@ static int shmob_drm_unload(struct drm_device *dev) drm_irq_uninstall(dev); dev->dev_private = NULL; - - return 0; } static int shmob_drm_load(struct drm_device *dev, unsigned long flags) diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index a836451920f0..7f05da13ea5e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -54,15 +54,13 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) return 0; } -static int sis_driver_unload(struct drm_device *dev) +static void sis_driver_unload(struct drm_device *dev) { drm_sis_private_t *dev_priv = dev->dev_private; idr_destroy(&dev_priv->object_idr); kfree(dev_priv); - - return 0; } static const struct file_operations sis_driver_fops = { diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 2817f43f3344..0f4eacb0af4f 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -214,7 +214,7 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) return err; } -static int tegra_drm_unload(struct drm_device *drm) +static void tegra_drm_unload(struct drm_device *drm) { struct host1x_device *device = to_host1x_device(drm->dev); struct tegra_drm *tegra = drm->dev_private; @@ -227,7 +227,7 @@ static int tegra_drm_unload(struct drm_device *drm) err = host1x_device_exit(device); if (err < 0) - return err; + return; if (tegra->domain) { iommu_domain_free(tegra->domain); @@ -235,8 +235,6 @@ static int tegra_drm_unload(struct drm_device *drm) } kfree(tegra); - - return 0; } static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp) diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index f338a576efc8..6c4286e57362 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -100,7 +100,7 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len); void udl_urb_completion(struct urb *urb); int udl_driver_load(struct drm_device *dev, unsigned long flags); -int udl_driver_unload(struct drm_device *dev); +void udl_driver_unload(struct drm_device *dev); int udl_fbdev_init(struct drm_device *dev); void udl_fbdev_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 873f010d9616..a9d93b871a15 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -367,7 +367,7 @@ int udl_drop_usb(struct drm_device *dev) return 0; } -int udl_driver_unload(struct drm_device *dev) +void udl_driver_unload(struct drm_device *dev) { struct udl_device *udl = dev->dev_private; @@ -379,5 +379,4 @@ int udl_driver_unload(struct drm_device *dev) udl_fbdev_cleanup(dev); udl_modeset_cleanup(dev); kfree(udl); - return 0; } diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index 286a785fab4f..9873942ca8f4 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -134,7 +134,7 @@ extern int via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file extern int via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int via_driver_load(struct drm_device *dev, unsigned long chipset); -extern int via_driver_unload(struct drm_device *dev); +extern void via_driver_unload(struct drm_device *dev); extern int via_init_context(struct drm_device *dev, int context); extern int via_final_context(struct drm_device *dev, int context); diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 0b3522dba6e8..2ad865870372 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c @@ -116,13 +116,11 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) return 0; } -int via_driver_unload(struct drm_device *dev) +void via_driver_unload(struct drm_device *dev) { drm_via_private_t *dev_priv = dev->dev_private; idr_destroy(&dev_priv->object_idr); kfree(dev_priv); - - return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 025f2e3d483f..2f766735c16d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -215,7 +215,7 @@ extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; /* virtio_kms.c */ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags); -int virtio_gpu_driver_unload(struct drm_device *dev); +void virtio_gpu_driver_unload(struct drm_device *dev); int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 1235519853f4..fae75394b5d0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -246,7 +246,7 @@ static void virtio_gpu_cleanup_cap_cache(struct virtio_gpu_device *vgdev) } } -int virtio_gpu_driver_unload(struct drm_device *dev) +void virtio_gpu_driver_unload(struct drm_device *dev) { struct virtio_gpu_device *vgdev = dev->dev_private; @@ -262,7 +262,6 @@ int virtio_gpu_driver_unload(struct drm_device *dev) virtio_gpu_cleanup_cap_cache(vgdev); kfree(vgdev->capsets); kfree(vgdev); - return 0; } int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 18061a4bc2f2..be35385bb26c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -951,7 +951,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) return ret; } -static int vmw_driver_unload(struct drm_device *dev) +static void vmw_driver_unload(struct drm_device *dev) { struct vmw_private *dev_priv = vmw_priv(dev); enum vmw_res_type i; @@ -998,8 +998,6 @@ static int vmw_driver_unload(struct drm_device *dev) idr_destroy(&dev_priv->res_idr[i]); kfree(dev_priv); - - return 0; } static void vmw_postclose(struct drm_device *dev, diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 9c2d9f0bb043..34ece393c639 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -101,11 +101,8 @@ struct drm_driver { * The unload() hook is called right after unregistering * the device. * - * Returns: - * - * The return value is ignored. */ - int (*unload) (struct drm_device *); + void (*unload) (struct drm_device *); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); int (*dma_quiescent) (struct drm_device *); int (*context_dtor) (struct drm_device *dev, int context); From 011cda589938e56eb93685dee8ead0bb0506f9e2 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Sat, 7 Jan 2017 12:39:11 +0100 Subject: [PATCH 356/359] drm: fix compilations issues introduced by "drm: allow to use mmuless SoC" Removing MMU configuration flag from DRM make few automatic build failed when they answer yes to all flags. Add asm/vga.h file on Blackfin architecture to not broke compilation. Signed-off-by: Benjamin Gaignard Fixes: 62a0d98a188c ("drm: allow to use mmuless SoC") Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1483789151-6603-1-git-send-email-benjamin.gaignard@linaro.org --- arch/blackfin/include/asm/vga.h | 1 + drivers/gpu/drm/Kconfig | 4 ++-- drivers/gpu/drm/ast/Kconfig | 2 +- drivers/gpu/drm/bochs/Kconfig | 2 +- drivers/gpu/drm/cirrus/Kconfig | 2 +- drivers/gpu/drm/gma500/Kconfig | 2 +- drivers/gpu/drm/hisilicon/hibmc/Kconfig | 2 +- drivers/gpu/drm/mgag200/Kconfig | 2 +- drivers/gpu/drm/nouveau/Kconfig | 2 +- drivers/gpu/drm/qxl/Kconfig | 2 +- drivers/gpu/drm/virtio/Kconfig | 2 +- drivers/gpu/drm/vmwgfx/Kconfig | 2 +- 12 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 arch/blackfin/include/asm/vga.h diff --git a/arch/blackfin/include/asm/vga.h b/arch/blackfin/include/asm/vga.h new file mode 100644 index 000000000000..89d82fd8fcf1 --- /dev/null +++ b/arch/blackfin/include/asm/vga.h @@ -0,0 +1 @@ +#include diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 505ca1d262ee..6f3f9e68c218 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -146,7 +146,7 @@ source "drivers/gpu/drm/arm/Kconfig" config DRM_RADEON tristate "ATI Radeon" - depends on DRM && PCI + depends on DRM && PCI && MMU select FW_LOADER select DRM_KMS_HELPER select DRM_TTM @@ -166,7 +166,7 @@ source "drivers/gpu/drm/radeon/Kconfig" config DRM_AMDGPU tristate "AMD GPU" - depends on DRM && PCI + depends on DRM && PCI && MMU select FW_LOADER select DRM_KMS_HELPER select DRM_TTM diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index 15f6ce7acb2a..9647e1f07088 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig @@ -1,6 +1,6 @@ config DRM_AST tristate "AST server chips" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_TTM select DRM_KMS_HELPER select DRM_TTM diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig index f739763f47ce..bd2718015cdb 100644 --- a/drivers/gpu/drm/bochs/Kconfig +++ b/drivers/gpu/drm/bochs/Kconfig @@ -1,6 +1,6 @@ config DRM_BOCHS tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_TTM help diff --git a/drivers/gpu/drm/cirrus/Kconfig b/drivers/gpu/drm/cirrus/Kconfig index 04b3c161dfae..ca3809851377 100644 --- a/drivers/gpu/drm/cirrus/Kconfig +++ b/drivers/gpu/drm/cirrus/Kconfig @@ -1,6 +1,6 @@ config DRM_CIRRUS_QEMU tristate "Cirrus driver for QEMU emulated device" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_TTM help diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig index 8906d67494fc..df11582f1efc 100644 --- a/drivers/gpu/drm/gma500/Kconfig +++ b/drivers/gpu/drm/gma500/Kconfig @@ -1,6 +1,6 @@ config DRM_GMA500 tristate "Intel GMA5/600 KMS Framebuffer" - depends on DRM && PCI && X86 + depends on DRM && PCI && X86 && MMU select DRM_KMS_HELPER select DRM_TTM # GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915 diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig index 380622a0da35..c7129dc3bdfc 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig @@ -1,6 +1,6 @@ config DRM_HISI_HIBMC tristate "DRM Support for Hisilicon Hibmc" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_TTM diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index 520e5e668d6c..db58578719d2 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -1,6 +1,6 @@ config DRM_MGAG200 tristate "Kernel modesetting driver for MGA G200 server engines" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_TTM help diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 0f2f0afc8f67..c02a13406a81 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -1,6 +1,6 @@ config DRM_NOUVEAU tristate "Nouveau (NVIDIA) cards" - depends on DRM && PCI + depends on DRM && PCI && MMU select FW_LOADER select DRM_KMS_HELPER select DRM_TTM diff --git a/drivers/gpu/drm/qxl/Kconfig b/drivers/gpu/drm/qxl/Kconfig index da45b11b66b8..378da5918e6c 100644 --- a/drivers/gpu/drm/qxl/Kconfig +++ b/drivers/gpu/drm/qxl/Kconfig @@ -1,6 +1,6 @@ config DRM_QXL tristate "QXL virtual GPU" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_TTM select CRC32 diff --git a/drivers/gpu/drm/virtio/Kconfig b/drivers/gpu/drm/virtio/Kconfig index 81d1807ac228..0c384d9a2b75 100644 --- a/drivers/gpu/drm/virtio/Kconfig +++ b/drivers/gpu/drm/virtio/Kconfig @@ -1,6 +1,6 @@ config DRM_VIRTIO_GPU tristate "Virtio GPU driver" - depends on DRM && VIRTIO + depends on DRM && VIRTIO && MMU select DRM_KMS_HELPER select DRM_TTM help diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index fb7b82aad763..8c308dac99c5 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -1,6 +1,6 @@ config DRM_VMWGFX tristate "DRM driver for VMware Virtual GPU" - depends on DRM && PCI && X86 + depends on DRM && PCI && X86 && MMU select FB_DEFERRED_IO select FB_CFB_FILLRECT select FB_CFB_COPYAREA From 83dd1376fd92f33bdeca9e83d479534a4e7f870b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Jan 2017 14:12:20 +0000 Subject: [PATCH 357/359] dma-fence: Clear fence->status during dma_fence_init() As the fence->status is an optional field that may be set before dma_fence_signal() is called to convey that the fence completed with an error, we have to ensure that it is always set to zero on initialisation so that the typical use (i.e. unset) always flags a successful completion. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Reviewed-by: Daniel Vetter Reviewed-by: Sumit Semwal Signed-off-by: Sumit Semwal Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-1-chris@chris-wilson.co.uk --- drivers/dma-buf/dma-fence.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 0212af7997d9..cb6eef308cd9 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -541,6 +541,7 @@ dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops, fence->context = context; fence->seqno = seqno; fence->flags = 0UL; + fence->status = 0; trace_dma_fence_init(fence); } From d6c99f4bf093a58d3ab47caaec74b81f18bc4e3f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Jan 2017 14:12:21 +0000 Subject: [PATCH 358/359] dma-fence: Wrap querying the fence->status The fence->status is an optional field that is only valid once the fence has been signaled. (Driver may fill the fence->status with an error code prior to calling dma_fence_signal().) Given the restriction upon its validity, wrap querying of the fence->status into a helper dma_fence_get_status(). Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Reviewed-by: Sumit Semwal Signed-off-by: Sumit Semwal Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-2-chris@chris-wilson.co.uk --- drivers/dma-buf/dma-fence.c | 25 +++++++++++++++++++++++++ drivers/dma-buf/sync_debug.c | 17 ++++++++--------- drivers/dma-buf/sync_file.c | 6 ++---- include/linux/dma-fence.h | 24 ++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index cb6eef308cd9..5e66dfece03c 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -281,6 +281,31 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb, } EXPORT_SYMBOL(dma_fence_add_callback); +/** + * dma_fence_get_status - returns the status upon completion + * @fence: [in] the dma_fence to query + * + * This wraps dma_fence_get_status_locked() to return the error status + * condition on a signaled fence. See dma_fence_get_status_locked() for more + * details. + * + * Returns 0 if the fence has not yet been signaled, 1 if the fence has + * been signaled without an error condition, or a negative error code + * if the fence has been completed in err. + */ +int dma_fence_get_status(struct dma_fence *fence) +{ + unsigned long flags; + int status; + + spin_lock_irqsave(fence->lock, flags); + status = dma_fence_get_status_locked(fence); + spin_unlock_irqrestore(fence->lock, flags); + + return status; +} +EXPORT_SYMBOL(dma_fence_get_status); + /** * dma_fence_remove_callback - remove a callback from the signaling list * @fence: [in] the fence to wait on diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c index 48b20e34fb6d..c769dc653b34 100644 --- a/drivers/dma-buf/sync_debug.c +++ b/drivers/dma-buf/sync_debug.c @@ -62,30 +62,29 @@ void sync_file_debug_remove(struct sync_file *sync_file) static const char *sync_status_str(int status) { - if (status == 0) - return "signaled"; + if (status < 0) + return "error"; if (status > 0) - return "active"; + return "signaled"; - return "error"; + return "active"; } static void sync_print_fence(struct seq_file *s, struct dma_fence *fence, bool show) { - int status = 1; struct sync_timeline *parent = dma_fence_parent(fence); + int status; - if (dma_fence_is_signaled_locked(fence)) - status = fence->status; + status = dma_fence_get_status_locked(fence); seq_printf(s, " %s%sfence %s", show ? parent->name : "", show ? "_" : "", sync_status_str(status)); - if (status <= 0) { + if (status) { struct timespec64 ts64 = ktime_to_timespec64(fence->timestamp); @@ -136,7 +135,7 @@ static void sync_print_sync_file(struct seq_file *s, int i; seq_printf(s, "[%p] %s: %s\n", sync_file, sync_file->name, - sync_status_str(!dma_fence_is_signaled(sync_file->fence))); + sync_status_str(dma_fence_get_status(sync_file->fence))); if (dma_fence_is_array(sync_file->fence)) { struct dma_fence_array *array = to_dma_fence_array(sync_file->fence); diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 07cb9b908f30..2321035f6204 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -373,10 +373,8 @@ static void sync_fill_fence_info(struct dma_fence *fence, sizeof(info->obj_name)); strlcpy(info->driver_name, fence->ops->get_driver_name(fence), sizeof(info->driver_name)); - if (dma_fence_is_signaled(fence)) - info->status = fence->status >= 0 ? 1 : fence->status; - else - info->status = 0; + + info->status = dma_fence_get_status(fence); info->timestamp_ns = ktime_to_ns(fence->timestamp); } diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index d51a7d23c358..19f7af905182 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -378,6 +378,30 @@ static inline struct dma_fence *dma_fence_later(struct dma_fence *f1, return dma_fence_is_signaled(f2) ? NULL : f2; } +/** + * dma_fence_get_status_locked - returns the status upon completion + * @fence: [in] the dma_fence to query + * + * Drivers can supply an optional error status condition before they signal + * the fence (to indicate whether the fence was completed due to an error + * rather than success). The value of the status condition is only valid + * if the fence has been signaled, dma_fence_get_status_locked() first checks + * the signal state before reporting the error status. + * + * Returns 0 if the fence has not yet been signaled, 1 if the fence has + * been signaled without an error condition, or a negative error code + * if the fence has been completed in err. + */ +static inline int dma_fence_get_status_locked(struct dma_fence *fence) +{ + if (dma_fence_is_signaled_locked(fence)) + return fence->status < 0 ? fence->status : 1; + else + return 0; +} + +int dma_fence_get_status(struct dma_fence *fence); + signed long dma_fence_wait_timeout(struct dma_fence *, bool intr, signed long timeout); signed long dma_fence_wait_any_timeout(struct dma_fence **fences, From a009e975da5c7d42a7f5eaadc54946eb5f76c9af Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Jan 2017 14:12:22 +0000 Subject: [PATCH 359/359] dma-fence: Introduce drm_fence_set_error() helper The dma_fence.error field (formerly known as dma_fence.status) is an optional field that may be set by drivers before calling dma_fence_signal(). The field can be used to indicate that the fence was completed in err rather than with success, and is visible to other consumers of the fence and to userspace via sync_file. This patch renames the field from status to error so that its meaning is hopefully more clear (and distinct from dma_fence_get_status() which is a composite between the error state and signal state) and adds a helper that validates the preconditions of when it is suitable to adjust the error field. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Reviewed-by: Sumit Semwal Signed-off-by: Sumit Semwal Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-3-chris@chris-wilson.co.uk --- drivers/dma-buf/dma-fence.c | 2 +- include/linux/dma-fence.h | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 5e66dfece03c..a1bfc098ea10 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -566,7 +566,7 @@ dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops, fence->context = context; fence->seqno = seqno; fence->flags = 0UL; - fence->status = 0; + fence->error = 0; trace_dma_fence_init(fence); } diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index 19f7af905182..6048fa404e57 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -47,7 +47,7 @@ struct dma_fence_cb; * can be compared to decide which fence would be signaled later. * @flags: A mask of DMA_FENCE_FLAG_* defined below * @timestamp: Timestamp when the fence was signaled. - * @status: Optional, only valid if < 0, must be set before calling + * @error: Optional, only valid if < 0, must be set before calling * dma_fence_signal, indicates that the fence has completed with an error. * * the flags member must be manipulated and read using the appropriate @@ -79,7 +79,7 @@ struct dma_fence { unsigned seqno; unsigned long flags; ktime_t timestamp; - int status; + int error; }; enum dma_fence_flag_bits { @@ -133,7 +133,7 @@ struct dma_fence_cb { * or some failure occurred that made it impossible to enable * signaling. True indicates successful enabling. * - * fence->status may be set in enable_signaling, but only when false is + * fence->error may be set in enable_signaling, but only when false is * returned. * * Calling dma_fence_signal before enable_signaling is called allows @@ -145,7 +145,7 @@ struct dma_fence_cb { * the second time will be a noop since it was already signaled. * * Notes on signaled: - * May set fence->status if returning true. + * May set fence->error if returning true. * * Notes on wait: * Must not be NULL, set to dma_fence_default_wait for default implementation. @@ -395,13 +395,33 @@ static inline struct dma_fence *dma_fence_later(struct dma_fence *f1, static inline int dma_fence_get_status_locked(struct dma_fence *fence) { if (dma_fence_is_signaled_locked(fence)) - return fence->status < 0 ? fence->status : 1; + return fence->error ?: 1; else return 0; } int dma_fence_get_status(struct dma_fence *fence); +/** + * dma_fence_set_error - flag an error condition on the fence + * @fence: [in] the dma_fence + * @error: [in] the error to store + * + * Drivers can supply an optional error status condition before they signal + * the fence, to indicate that the fence was completed due to an error + * rather than success. This must be set before signaling (so that the value + * is visible before any waiters on the signal callback are woken). This + * helper exists to help catching erroneous setting of #dma_fence.error. + */ +static inline void dma_fence_set_error(struct dma_fence *fence, + int error) +{ + BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)); + BUG_ON(error >= 0 || error < -MAX_ERRNO); + + fence->error = error; +} + signed long dma_fence_wait_timeout(struct dma_fence *, bool intr, signed long timeout); signed long dma_fence_wait_any_timeout(struct dma_fence **fences,