diff options
436 files changed, 3845 insertions, 2463 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-hsi b/Documentation/ABI/testing/sysfs-bus-hsi new file mode 100644 index 00000000000..1b1b282a99e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-hsi @@ -0,0 +1,19 @@ +What:		/sys/bus/hsi +Date:		April 2012 +KernelVersion:	3.4 +Contact:	Carlos Chinea <carlos.chinea@nokia.com> +Description: +		High Speed Synchronous Serial Interface (HSI) is a +		serial interface mainly used for connecting application +		engines (APE) with cellular modem engines (CMT) in cellular +		handsets. +		The bus will be populated with devices (hsi_clients) representing +		the protocols available in the system. Bus drivers implement +		those protocols. + +What:		/sys/bus/hsi/devices/.../modalias +Date:		April 2012 +KernelVersion:	3.4 +Contact:	Carlos Chinea <carlos.chinea@nokia.com> +Description:	Stores the same MODALIAS value emitted by uevent +		Format: hsi:<hsi_client device name> diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml index 3fd3ce5df27..5274c24d11e 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml @@ -1,6 +1,6 @@      <refentry id="V4L2-PIX-FMT-NV12M">        <refmeta> -	<refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle> +	<refentrytitle>V4L2_PIX_FMT_NV12M ('NM12')</refentrytitle>  	&manvol;        </refmeta>        <refnamediv> diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index 9957863daf1..60308f1eefd 100644 --- a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml @@ -1,6 +1,6 @@      <refentry id="V4L2-PIX-FMT-YUV420M">        <refmeta> -	<refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle> +	<refentrytitle>V4L2_PIX_FMT_YUV420M ('YM12')</refentrytitle>  	&manvol;        </refmeta>        <refnamediv> diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt index ec715cd78fb..6ec291ea1c7 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt @@ -9,7 +9,7 @@ architectures).  II. How does it work? -There are four per-task flags used for that, PF_NOFREEZE, PF_FROZEN, TIF_FREEZE +There are three per-task flags used for that, PF_NOFREEZE, PF_FROZEN  and PF_FREEZER_SKIP (the last one is auxiliary).  The tasks that have  PF_NOFREEZE unset (all user space processes and some kernel threads) are  regarded as 'freezable' and treated in a special way before the system enters a @@ -17,30 +17,31 @@ suspend state as well as before a hibernation image is created (in what follows  we only consider hibernation, but the description also applies to suspend).  Namely, as the first step of the hibernation procedure the function -freeze_processes() (defined in kernel/power/process.c) is called.  It executes -try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and -either wakes them up, if they are kernel threads, or sends fake signals to them, -if they are user space processes.  A task that has TIF_FREEZE set, should react -to it by calling the function called __refrigerator() (defined in -kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state -to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. -Then, we say that the task is 'frozen' and therefore the set of functions -handling this mechanism is referred to as 'the freezer' (these functions are -defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). -User space processes are generally frozen before kernel threads. +freeze_processes() (defined in kernel/power/process.c) is called.  A system-wide +variable system_freezing_cnt (as opposed to a per-task flag) is used to indicate +whether the system is to undergo a freezing operation. And freeze_processes() +sets this variable.  After this, it executes try_to_freeze_tasks() that sends a +fake signal to all user space processes, and wakes up all the kernel threads. +All freezable tasks must react to that by calling try_to_freeze(), which +results in a call to __refrigerator() (defined in kernel/freezer.c), which sets +the task's PF_FROZEN flag, changes its state to TASK_UNINTERRUPTIBLE and makes +it loop until PF_FROZEN is cleared for it. Then, we say that the task is +'frozen' and therefore the set of functions handling this mechanism is referred +to as 'the freezer' (these functions are defined in kernel/power/process.c, +kernel/freezer.c & include/linux/freezer.h). User space processes are generally +frozen before kernel threads.  __refrigerator() must not be called directly.  Instead, use the  try_to_freeze() function (defined in include/linux/freezer.h), that checks -the task's TIF_FREEZE flag and makes the task enter __refrigerator() if the -flag is set. +if the task is to be frozen and makes the task enter __refrigerator().  For user space processes try_to_freeze() is called automatically from the  signal-handling code, but the freezable kernel threads need to call it  explicitly in suitable places or use the wait_event_freezable() or  wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) -that combine interruptible sleep with checking if TIF_FREEZE is set and calling -try_to_freeze().  The main loop of a freezable kernel thread may look like the -following one: +that combine interruptible sleep with checking if the task is to be frozen and +calling try_to_freeze().  The main loop of a freezable kernel thread may look +like the following one:  	set_freezable();  	do { @@ -53,7 +54,7 @@ following one:  (from drivers/usb/core/hub.c::hub_thread()).  If a freezable kernel thread fails to call try_to_freeze() after the freezer has -set TIF_FREEZE for it, the freezing of tasks will fail and the entire +initiated a freezing operation, the freezing of tasks will fail and the entire  hibernation operation will be cancelled.  For this reason, freezable kernel  threads must call try_to_freeze() somewhere or use one of the  wait_event_freezable() and wait_event_freezable_timeout() macros. diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt index 78771709142..d389acd31e1 100644 --- a/Documentation/security/keys.txt +++ b/Documentation/security/keys.txt @@ -123,7 +123,7 @@ KEY SERVICE OVERVIEW  The key service provides a number of features besides keys: - (*) The key service defines two special key types: + (*) The key service defines three special key types:       (+) "keyring" @@ -137,6 +137,18 @@ The key service provides a number of features besides keys:  	 blobs of data. These can be created, updated and read by userspace,  	 and aren't intended for use by kernel services. +     (+) "logon" + +	 Like a "user" key, a "logon" key has a payload that is an arbitrary +	 blob of data. It is intended as a place to store secrets which are +	 accessible to the kernel but not to userspace programs. + +	 The description can be arbitrary, but must be prefixed with a non-zero +	 length string that describes the key "subclass". The subclass is +	 separated from the rest of the description by a ':'. "logon" keys can +	 be created and updated from userspace, but the payload is only +	 readable from kernel space. +   (*) Each process subscribes to three keyrings: a thread-specific keyring, a       process-specific keyring, and a session-specific keyring. diff --git a/MAINTAINERS b/MAINTAINERS index 1a2f8f5823e..bb76fc42fc4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3592,6 +3592,7 @@ S:	Supported  F:	drivers/net/wireless/iwlegacy/  INTEL WIRELESS WIFI LINK (iwlwifi) +M:	Johannes Berg <johannes.berg@intel.com>  M:	Wey-Yi Guy <wey-yi.w.guy@intel.com>  M:	Intel Linux Wireless <ilw@linux.intel.com>  L:	linux-wireless@vger.kernel.org @@ -7578,8 +7579,8 @@ F:	Documentation/filesystems/xfs.txt  F:	fs/xfs/  XILINX AXI ETHERNET DRIVER -M:	Ariane Keller <ariane.keller@tik.ee.ethz.ch> -M:	Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch> +M:	Anirudha Sarangi <anirudh@xilinx.com> +M:	John Linn <John.Linn@xilinx.com>  S:	Maintained  F:	drivers/net/ethernet/xilinx/xilinx_axienet* @@ -1,7 +1,7 @@  VERSION = 3  PATCHLEVEL = 4  SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc5  NAME = Saber-toothed Squirrel  # *DOCUMENTATION* diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts index 15ded0deaa7..45bc4bb04e5 100644 --- a/arch/arm/boot/dts/msm8660-surf.dts +++ b/arch/arm/boot/dts/msm8660-surf.dts @@ -10,7 +10,7 @@  	intc: interrupt-controller@02080000 {  		compatible = "qcom,msm-8660-qgic";  		interrupt-controller; -		#interrupt-cells = <1>; +		#interrupt-cells = <3>;  		reg = < 0x02080000 0x1000 >,  		      < 0x02081000 0x1000 >;  	}; @@ -19,6 +19,6 @@  		compatible = "qcom,msm-hsuart", "qcom,msm-uart";  		reg = <0x19c40000 0x1000>,  		      <0x19c00000 0x1000>; -		interrupts = <195>; +		interrupts = <0 195 0x0>;  	};  }; diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index b5ac644e12a..6b31cb60daa 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -112,6 +112,7 @@ CONFIG_WATCHDOG=y  CONFIG_IMX2_WDT=y  CONFIG_MFD_MC13XXX=y  CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y  CONFIG_REGULATOR_MC13783=y  CONFIG_REGULATOR_MC13892=y  CONFIG_FB=y diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index 42da9183acc..082175c54e7 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -14,6 +14,8 @@ CONFIG_MODULE_FORCE_UNLOAD=y  # CONFIG_BLK_DEV_BSG is not set  CONFIG_BLK_DEV_INTEGRITY=y  CONFIG_ARCH_S3C24XX=y +# CONFIG_CPU_S3C2410 is not set +CONFIG_CPU_S3C2440=y  CONFIG_S3C_ADC=y  CONFIG_S3C24XX_PWM=y  CONFIG_MACH_MINI2440=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 889d73ac1ae..7e84f453e8a 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -8,8 +8,6 @@ CONFIG_MODULE_UNLOAD=y  # CONFIG_LBDAF is not set  # CONFIG_BLK_DEV_BSG is not set  CONFIG_ARCH_U8500=y -CONFIG_UX500_SOC_DB5500=y -CONFIG_UX500_SOC_DB8500=y  CONFIG_MACH_HREFV60=y  CONFIG_MACH_SNOWBALL=y  CONFIG_MACH_U5500=y @@ -39,7 +37,6 @@ CONFIG_CAIF=y  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"  CONFIG_BLK_DEV_RAM=y  CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_MISC_DEVICES=y  CONFIG_AB8500_PWM=y  CONFIG_SENSORS_BH1780=y  CONFIG_NETDEVICES=y @@ -65,16 +62,18 @@ CONFIG_SERIAL_AMBA_PL011=y  CONFIG_SERIAL_AMBA_PL011_CONSOLE=y  CONFIG_HW_RANDOM=y  CONFIG_HW_RANDOM_NOMADIK=y -CONFIG_I2C=y -CONFIG_I2C_NOMADIK=y  CONFIG_SPI=y  CONFIG_SPI_PL022=y  CONFIG_GPIO_STMPE=y  CONFIG_GPIO_TC3589X=y +CONFIG_POWER_SUPPLY=y +CONFIG_AB8500_BM=y +CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y  CONFIG_MFD_STMPE=y  CONFIG_MFD_TC3589X=y  CONFIG_AB5500_CORE=y  CONFIG_AB8500_CORE=y +CONFIG_REGULATOR=y  CONFIG_REGULATOR_AB8500=y  # CONFIG_HID_SUPPORT is not set  CONFIG_USB_GADGET=y diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 5b150afb995..fef42b21cec 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -118,14 +118,10 @@ static int twd_cpufreq_transition(struct notifier_block *nb,  	 * The twd clock events must be reprogrammed to account for the new  	 * frequency.  The timer is local to a cpu, so cross-call to the  	 * changing cpu. -	 * -	 * Only wait for it to finish, if the cpu is active to avoid -	 * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during -	 * booting of that cpu.  	 */  	if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)  		smp_call_function_single(freqs->cpu, twd_update_frequency, -					 NULL, cpu_active(freqs->cpu)); +			NULL, 1);  	return NOTIFY_OK;  } diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 99ce5c955e3..05774e5b1cb 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -1173,7 +1173,6 @@ void __init at91_add_device_serial(void)  		printk(KERN_INFO "AT91: No default serial console defined.\n");  }  #else -void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}  void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}  void __init at91_set_serial_console(unsigned portnr) {}  void __init at91_add_device_serial(void) {} diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index dd7f782b0b9..104ca40d8d1 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -23,6 +23,7 @@  #include <linux/interrupt.h>  #include <linux/irq.h>  #include <linux/clockchips.h> +#include <linux/export.h>  #include <asm/mach/time.h> @@ -176,6 +177,7 @@ static struct clock_event_device clkevt = {  };  void __iomem *at91_st_base; +EXPORT_SYMBOL_GPL(at91_st_base);  void __init at91rm9200_ioremap_st(u32 addr)  { diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index 11cbaa8946f..b2e4fe21f34 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -117,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = {  };  #define EK_FLASH_BASE	AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE	SZ_2M +#define EK_FLASH_SIZE	SZ_8M  static struct physmap_flash_data ek_flash_data = {  	.width		= 2, diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index c3f99446286..065fed34242 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -85,8 +85,6 @@ static struct resource dm9000_resource[] = {  		.flags	= IORESOURCE_MEM  	},  	[2] = { -		.start	= AT91_PIN_PC11, -		.end	= AT91_PIN_PC11,  		.flags	= IORESOURCE_IRQ  			| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,  	} @@ -130,6 +128,8 @@ static struct sam9_smc_config __initdata dm9000_smc_config = {  static void __init ek_add_device_dm9000(void)  { +	struct resource *r = &dm9000_resource[2]; +  	/* Configure chip-select 2 (DM9000) */  	sam9_smc_configure(0, 2, &dm9000_smc_config); @@ -139,6 +139,7 @@ static void __init ek_add_device_dm9000(void)  	/* Configure Interrupt pin as input, no pull-up */  	at91_set_gpio_input(AT91_PIN_PC11, 0); +	r->start = r->end = gpio_to_irq(AT91_PIN_PC11);  	platform_device_register(&dm9000_device);  }  #else diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index a0f4d7424cd..6b692824c98 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -35,6 +35,7 @@  #include "generic.h"  void __iomem *at91_pmc_base; +EXPORT_SYMBOL_GPL(at91_pmc_base);  /*   * There's a lot more which can be done with clocks, including cpufreq diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 36604782a78..ea2c57a86ca 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base;  #define at91_pmc_write(field, value) \  	__raw_writel(value, at91_pmc_base + field)  #else -.extern at91_aic_base +.extern at91_pmc_base  #endif  #define	AT91_PMC_SCER		0x00			/* System Clock Enable Register */ diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 97cc04dc807..f44a2e7272e 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -54,6 +54,7 @@ void __init at91_init_interrupts(unsigned int *priority)  }  void __iomem *at91_ramc_base[2]; +EXPORT_SYMBOL_GPL(at91_ramc_base);  void __init at91_ioremap_ramc(int id, u32 addr, u32 size)  { @@ -292,6 +293,7 @@ void __init at91_ioremap_rstc(u32 base_addr)  }  void __iomem *at91_matrix_base; +EXPORT_SYMBOL_GPL(at91_matrix_base);  void __init at91_ioremap_matrix(u32 base_addr)  { diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c index 22e4e0a28ad..adbfb199458 100644 --- a/arch/arm/mach-bcmring/core.c +++ b/arch/arm/mach-bcmring/core.c @@ -52,8 +52,8 @@  #include <mach/csp/chipcHw_inline.h>  #include <mach/csp/tmrHw_reg.h> -static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); -static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); +static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL); +static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL);  static struct clk pll1_clk = {  	.name = "PLL1", diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c index df54c2a9222..6efd1e5919f 100644 --- a/arch/arm/mach-exynos/clock-exynos4.c +++ b/arch/arm/mach-exynos/clock-exynos4.c @@ -497,25 +497,25 @@ static struct clk exynos4_init_clocks_off[] = {  		.ctrlbit	= (1 << 3),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.0", +		.devname	= "exynos4-sdhci.0",  		.parent		= &exynos4_clk_aclk_133.clk,  		.enable		= exynos4_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 5),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.1", +		.devname	= "exynos4-sdhci.1",  		.parent		= &exynos4_clk_aclk_133.clk,  		.enable		= exynos4_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 6),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.2", +		.devname	= "exynos4-sdhci.2",  		.parent		= &exynos4_clk_aclk_133.clk,  		.enable		= exynos4_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 7),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.3", +		.devname	= "exynos4-sdhci.3",  		.parent		= &exynos4_clk_aclk_133.clk,  		.enable		= exynos4_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 8), @@ -1202,7 +1202,7 @@ static struct clksrc_clk exynos4_clk_sclk_uart3 = {  static struct clksrc_clk exynos4_clk_sclk_mmc0 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.0", +		.devname	= "exynos4-sdhci.0",  		.parent		= &exynos4_clk_dout_mmc0.clk,  		.enable		= exynos4_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 0), @@ -1213,7 +1213,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc0 = {  static struct clksrc_clk exynos4_clk_sclk_mmc1 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.1", +		.devname	= "exynos4-sdhci.1",  		.parent		= &exynos4_clk_dout_mmc1.clk,  		.enable		= exynos4_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 4), @@ -1224,7 +1224,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc1 = {  static struct clksrc_clk exynos4_clk_sclk_mmc2 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.2", +		.devname	= "exynos4-sdhci.2",  		.parent		= &exynos4_clk_dout_mmc2.clk,  		.enable		= exynos4_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 8), @@ -1235,7 +1235,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc2 = {  static struct clksrc_clk exynos4_clk_sclk_mmc3 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.3", +		.devname	= "exynos4-sdhci.3",  		.parent		= &exynos4_clk_dout_mmc3.clk,  		.enable		= exynos4_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 12), @@ -1340,10 +1340,10 @@ static struct clk_lookup exynos4_clk_lookup[] = {  	CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk),  	CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk),  	CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk), -	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), -	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), -	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), -	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), +	CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), +	CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), +	CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), +	CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk),  	CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0),  	CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),  	CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1), diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index d013982d0f8..5cd7a8b8868 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -455,25 +455,25 @@ static struct clk exynos5_init_clocks_off[] = {  		.ctrlbit	= (1 << 20),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.0", +		.devname	= "exynos4-sdhci.0",  		.parent		= &exynos5_clk_aclk_200.clk,  		.enable		= exynos5_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 12),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.1", +		.devname	= "exynos4-sdhci.1",  		.parent		= &exynos5_clk_aclk_200.clk,  		.enable		= exynos5_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 13),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.2", +		.devname	= "exynos4-sdhci.2",  		.parent		= &exynos5_clk_aclk_200.clk,  		.enable		= exynos5_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 14),  	}, {  		.name		= "hsmmc", -		.devname	= "s3c-sdhci.3", +		.devname	= "exynos4-sdhci.3",  		.parent		= &exynos5_clk_aclk_200.clk,  		.enable		= exynos5_clk_ip_fsys_ctrl,  		.ctrlbit	= (1 << 15), @@ -813,7 +813,7 @@ static struct clksrc_clk exynos5_clk_sclk_uart3 = {  static struct clksrc_clk exynos5_clk_sclk_mmc0 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.0", +		.devname	= "exynos4-sdhci.0",  		.parent		= &exynos5_clk_dout_mmc0.clk,  		.enable		= exynos5_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 0), @@ -824,7 +824,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc0 = {  static struct clksrc_clk exynos5_clk_sclk_mmc1 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.1", +		.devname	= "exynos4-sdhci.1",  		.parent		= &exynos5_clk_dout_mmc1.clk,  		.enable		= exynos5_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 4), @@ -835,7 +835,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc1 = {  static struct clksrc_clk exynos5_clk_sclk_mmc2 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.2", +		.devname	= "exynos4-sdhci.2",  		.parent		= &exynos5_clk_dout_mmc2.clk,  		.enable		= exynos5_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 8), @@ -846,7 +846,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc2 = {  static struct clksrc_clk exynos5_clk_sclk_mmc3 = {  	.clk	= {  		.name		= "sclk_mmc", -		.devname	= "s3c-sdhci.3", +		.devname	= "exynos4-sdhci.3",  		.parent		= &exynos5_clk_dout_mmc3.clk,  		.enable		= exynos5_clksrc_mask_fsys_ctrl,  		.ctrlbit	= (1 << 12), @@ -990,10 +990,10 @@ static struct clk_lookup exynos5_clk_lookup[] = {  	CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),  	CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),  	CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk), -	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), -	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), -	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), -	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), +	CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), +	CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), +	CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), +	CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),  	CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),  	CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),  	CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1), diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 8614aab47cc..5ccd6e80a60 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -326,6 +326,11 @@ static void __init exynos4_map_io(void)  	s3c_fimc_setname(2, "exynos4-fimc");  	s3c_fimc_setname(3, "exynos4-fimc"); +	s3c_sdhci_setname(0, "exynos4-sdhci"); +	s3c_sdhci_setname(1, "exynos4-sdhci"); +	s3c_sdhci_setname(2, "exynos4-sdhci"); +	s3c_sdhci_setname(3, "exynos4-sdhci"); +  	/* The I2C bus controllers are directly compatible with s3c2440 */  	s3c_i2c0_setname("s3c2440-i2c");  	s3c_i2c1_setname("s3c2440-i2c"); @@ -344,6 +349,11 @@ static void __init exynos5_map_io(void)  	s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC;  	s3c_device_i2c0.resource[1].end   = EXYNOS5_IRQ_IIC; +	s3c_sdhci_setname(0, "exynos4-sdhci"); +	s3c_sdhci_setname(1, "exynos4-sdhci"); +	s3c_sdhci_setname(2, "exynos4-sdhci"); +	s3c_sdhci_setname(3, "exynos4-sdhci"); +  	/* The I2C bus controllers are directly compatible with s3c2440 */  	s3c_i2c0_setname("s3c2440-i2c");  	s3c_i2c1_setname("s3c2440-i2c"); @@ -537,7 +547,9 @@ void __init exynos5_init_irq(void)  {  	int irq; -	gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); +#ifdef CONFIG_OF +	of_irq_init(exynos4_dt_irq_match); +#endif  	for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) {  		combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), diff --git a/arch/arm/mach-exynos/dev-dwmci.c b/arch/arm/mach-exynos/dev-dwmci.c index b025db4bf60..79035018fb7 100644 --- a/arch/arm/mach-exynos/dev-dwmci.c +++ b/arch/arm/mach-exynos/dev-dwmci.c @@ -16,6 +16,7 @@  #include <linux/dma-mapping.h>  #include <linux/platform_device.h>  #include <linux/interrupt.h> +#include <linux/ioport.h>  #include <linux/mmc/dw_mmc.h>  #include <plat/devs.h> @@ -33,16 +34,8 @@ static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)  }  static struct resource exynos4_dwmci_resource[] = { -	[0] = { -		.start	= EXYNOS4_PA_DWMCI, -		.end	= EXYNOS4_PA_DWMCI + SZ_4K - 1, -		.flags	= IORESOURCE_MEM, -	}, -	[1] = { -		.start	= IRQ_DWMCI, -		.end	= IRQ_DWMCI, -		.flags	= IORESOURCE_IRQ, -	} +	[0] = DEFINE_RES_MEM(EXYNOS4_PA_DWMCI, SZ_4K), +	[1] = DEFINE_RES_IRQ(EXYNOS4_IRQ_DWMCI),  };  static struct dw_mci_board exynos4_dwci_pdata = { diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index b4f1f902ce6..ed90aef404c 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -112,6 +112,7 @@ static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {  	.host_caps		= (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |  				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |  				MMC_CAP_ERASE), +	.host_caps2		= MMC_CAP2_BROKEN_VOLTAGE,  	.cd_type		= S3C_SDHCI_CD_PERMANENT,  	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,  }; diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index 7ebf79c2ab3..cb2b027f09a 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -747,6 +747,7 @@ static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {  	.max_width		= 8,  	.host_caps		= (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |  				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +	.host_caps2		= MMC_CAP2_BROKEN_VOLTAGE,  	.cd_type		= S3C_SDHCI_CD_PERMANENT,  	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,  }; diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c index 861ceb8232d..ed38d03c61f 100644 --- a/arch/arm/mach-imx/imx27-dt.c +++ b/arch/arm/mach-imx/imx27-dt.c @@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {  static int __init imx27_avic_add_irq_domain(struct device_node *np,  				struct device_node *interrupt_parent)  { -	irq_domain_add_simple(np, 0); +	irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL);  	return 0;  } @@ -44,7 +44,9 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np,  {  	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; -	irq_domain_add_simple(np, gpio_irq_base); +	gpio_irq_base -= 32; +	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, +				NULL);  	return 0;  } diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index 05250aed61f..e10f3914fcf 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -35,7 +35,7 @@ static void imx5_idle(void)  	}  	clk_enable(gpc_dvfs_clk);  	mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); -	if (tzic_enable_wake() != 0) +	if (!tzic_enable_wake())  		cpu_do_idle();  	clk_disable(gpc_dvfs_clk);  } diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 962e7116975..fb3496a52ef 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -17,6 +17,7 @@  #include <linux/irqdomain.h>  #include <linux/of.h>  #include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/memblock.h> @@ -49,10 +50,22 @@ static void __init msm8x60_map_io(void)  	msm_map_msm8x60_io();  } +#ifdef CONFIG_OF +static struct of_device_id msm_dt_gic_match[] __initdata = { +	{ .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, +	{} +}; +#endif +  static void __init msm8x60_init_irq(void)  { -	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, -		 (void *)MSM_QGIC_CPU_BASE); +	if (!of_have_populated_dt()) +		gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, +			 (void *)MSM_QGIC_CPU_BASE); +#ifdef CONFIG_OF +	else +		of_irq_init(msm_dt_gic_match); +#endif  	/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */  	writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); @@ -73,16 +86,8 @@ static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = {  	{}  }; -static struct of_device_id msm_dt_gic_match[] __initdata = { -	{ .compatible = "qcom,msm-8660-qgic", }, -	{} -}; -  static void __init msm8x60_dt_init(void)  { -	irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS, -				GIC_SPI_START); -  	if (of_machine_is_compatible("qcom,msm8660-surf")) {  		printk(KERN_INFO "Init surf UART registers\n");  		msm8x60_init_uart12dm(); diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 087dba0df47..e9cc52d4cb2 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -27,6 +27,7 @@  #include <linux/io.h>  #include <linux/spinlock.h> +#include <mach/hardware.h>  #include <plat/mux.h> diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 6e90665a7c4..fb202af01d0 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -47,9 +47,9 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev,  	int n = (pdev->id - 1) << 1;  	u32 l; -	l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); +	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);  	l |= source << n; -	__raw_writel(l, MOD_CONF_CTRL_1); +	omap_writel(l, MOD_CONF_CTRL_1);  	return 0;  } diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index a39fc4bbd2b..130ab00c09a 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -20,6 +20,7 @@  #include <linux/usb/otg.h>  #include <linux/spi/spi.h>  #include <linux/i2c/twl.h> +#include <linux/mfd/twl6040.h>  #include <linux/gpio_keys.h>  #include <linux/regulator/machine.h>  #include <linux/regulator/fixed.h> @@ -560,7 +561,7 @@ static struct regulator_init_data sdp4430_vusim = {  	},  }; -static struct twl4030_codec_data twl6040_codec = { +static struct twl6040_codec_data twl6040_codec = {  	/* single-step ramp for headset and handsfree */  	.hs_left_step	= 0x0f,  	.hs_right_step	= 0x0f, @@ -568,7 +569,7 @@ static struct twl4030_codec_data twl6040_codec = {  	.hf_right_step	= 0x1d,  }; -static struct twl4030_vibra_data twl6040_vibra = { +static struct twl6040_vibra_data twl6040_vibra = {  	.vibldrv_res = 8,  	.vibrdrv_res = 3,  	.viblmotor_res = 10, @@ -577,16 +578,14 @@ static struct twl4030_vibra_data twl6040_vibra = {  	.vddvibr_uV = 0,	/* fixed volt supply - VBAT */  }; -static struct twl4030_audio_data twl6040_audio = { +static struct twl6040_platform_data twl6040_data = {  	.codec		= &twl6040_codec,  	.vibra		= &twl6040_vibra,  	.audpwron_gpio	= 127, -	.naudint_irq	= OMAP44XX_IRQ_SYS_2N,  	.irq_base	= TWL6040_CODEC_IRQ_BASE,  };  static struct twl4030_platform_data sdp4430_twldata = { -	.audio		= &twl6040_audio,  	/* Regulators */  	.vusim		= &sdp4430_vusim,  	.vaux1		= &sdp4430_vaux1, @@ -617,7 +616,8 @@ static int __init omap4_i2c_init(void)  			TWL_COMMON_REGULATOR_VCXIO |  			TWL_COMMON_REGULATOR_VUSB |  			TWL_COMMON_REGULATOR_CLK32KG); -	omap4_pmic_init("twl6030", &sdp4430_twldata); +	omap4_pmic_init("twl6030", &sdp4430_twldata, +			&twl6040_data, OMAP44XX_IRQ_SYS_2N);  	omap_register_i2c_bus(2, 400, NULL, 0);  	omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,  				ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 74e1687b517..098d183a008 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = {  static void __init omap4_i2c_init(void)  { -	omap4_pmic_init("twl6030", &sdp4430_twldata); +	omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0);  }  static void __init omap4_init(void) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index d8c0e89f012..1b782ba5343 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -25,6 +25,7 @@  #include <linux/gpio.h>  #include <linux/usb/otg.h>  #include <linux/i2c/twl.h> +#include <linux/mfd/twl6040.h>  #include <linux/regulator/machine.h>  #include <linux/regulator/fixed.h>  #include <linux/wl12xx.h> @@ -284,7 +285,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)  	return 0;  } -static struct twl4030_codec_data twl6040_codec = { +static struct twl6040_codec_data twl6040_codec = {  	/* single-step ramp for headset and handsfree */  	.hs_left_step	= 0x0f,  	.hs_right_step	= 0x0f, @@ -292,17 +293,14 @@ static struct twl4030_codec_data twl6040_codec = {  	.hf_right_step	= 0x1d,  }; -static struct twl4030_audio_data twl6040_audio = { +static struct twl6040_platform_data twl6040_data = {  	.codec		= &twl6040_codec,  	.audpwron_gpio	= 127, -	.naudint_irq	= OMAP44XX_IRQ_SYS_2N,  	.irq_base	= TWL6040_CODEC_IRQ_BASE,  };  /* Panda board uses the common PMIC configuration */ -static struct twl4030_platform_data omap4_panda_twldata = { -	.audio		= &twl6040_audio, -}; +static struct twl4030_platform_data omap4_panda_twldata;  /*   * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM @@ -326,7 +324,8 @@ static int __init omap4_panda_i2c_init(void)  			TWL_COMMON_REGULATOR_VCXIO |  			TWL_COMMON_REGULATOR_VUSB |  			TWL_COMMON_REGULATOR_CLK32KG); -	omap4_pmic_init("twl6030", &omap4_panda_twldata); +	omap4_pmic_init("twl6030", &omap4_panda_twldata, +			&twl6040_data, OMAP44XX_IRQ_SYS_2N);  	omap_register_i2c_bus(2, 400, NULL, 0);  	/*  	 * Bus 3 is attached to the DVI port where devices like the pico DLP diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 2c27fdb61e6..7144ae651d3 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1422,6 +1422,9 @@ static int _ocp_softreset(struct omap_hwmod *oh)  		goto dis_opt_clks;  	_write_sysconfig(v, oh); +	if (oh->class->sysc->srst_udelay) +		udelay(oh->class->sysc->srst_udelay); +  	if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)  		omap_test_timeout((omap_hwmod_read(oh,  						    oh->class->sysc->syss_offs) @@ -1903,10 +1906,20 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)   */  int omap_hwmod_softreset(struct omap_hwmod *oh)  { -	if (!oh) +	u32 v; +	int ret; + +	if (!oh || !(oh->_sysc_cache))  		return -EINVAL; -	return _ocp_softreset(oh); +	v = oh->_sysc_cache; +	ret = _set_softreset(oh, &v); +	if (ret) +		goto error; +	_write_sysconfig(v, oh); + +error: +	return ret;  }  /** diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a5409ce3f32..a6bde34e443 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1000,7 +1000,6 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {  			.flags	= OMAP_FIREWALL_L4,  		}  	}, -	.flags		= OCPIF_SWSUP_IDLE,  	.user		= OCP_USER_MPU | OCP_USER_SDMA,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index c4f56cb60d7..04a3885f447 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1049,7 +1049,6 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {  	.slave		= &omap2430_dss_venc_hwmod,  	.clk		= "dss_ick",  	.addr		= omap2_dss_venc_addrs, -	.flags		= OCPIF_SWSUP_IDLE,  	.user		= OCP_USER_MPU | OCP_USER_SDMA,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 34b9766d1d2..db86ce90c69 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1676,7 +1676,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {  			.flags	= OMAP_FIREWALL_L4,  		}  	}, -	.flags		= OCPIF_SWSUP_IDLE,  	.user		= OCP_USER_MPU | OCP_USER_SDMA,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index cc9bd106a85..6abc75753e4 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2594,6 +2594,15 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {  static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {  	.rev_offs	= 0x0000,  	.sysc_offs	= 0x0010, +	/* +	 * ISS needs 100 OCP clk cycles delay after a softreset before +	 * accessing sysconfig again. +	 * The lowest frequency at the moment for L3 bus is 100 MHz, so +	 * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). +	 * +	 * TODO: Indicate errata when available. +	 */ +	.srst_udelay	= 2,  	.sysc_flags	= (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |  			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),  	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 0cdd359a128..9fc2f44188c 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -108,8 +108,14 @@ static void omap_uart_set_noidle(struct platform_device *pdev)  static void omap_uart_set_smartidle(struct platform_device *pdev)  {  	struct omap_device *od = to_omap_device(pdev); +	u8 idlemode; -	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); +	if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) +		idlemode = HWMOD_IDLEMODE_SMART_WKUP; +	else +		idlemode = HWMOD_IDLEMODE_SMART; + +	omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);  }  #else @@ -120,124 +126,8 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {}  #endif /* CONFIG_PM */  #ifdef CONFIG_OMAP_MUX -static struct omap_device_pad default_uart1_pads[] __initdata = { -	{ -		.name	= "uart1_cts.uart1_cts", -		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart1_rts.uart1_rts", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart1_tx.uart1_tx", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart1_rx.uart1_rx", -		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, -		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -		.idle	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -	}, -}; - -static struct omap_device_pad default_uart2_pads[] __initdata = { -	{ -		.name	= "uart2_cts.uart2_cts", -		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart2_rts.uart2_rts", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart2_tx.uart2_tx", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart2_rx.uart2_rx", -		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, -		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -		.idle	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -	}, -}; - -static struct omap_device_pad default_uart3_pads[] __initdata = { -	{ -		.name	= "uart3_cts_rctx.uart3_cts_rctx", -		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart3_rts_sd.uart3_rts_sd", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart3_tx_irtx.uart3_tx_irtx", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart3_rx_irrx.uart3_rx_irrx", -		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, -		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0, -		.idle	= OMAP_PIN_INPUT | OMAP_MUX_MODE0, -	}, -}; - -static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { -	{ -		.name   = "gpmc_wait2.uart4_tx", -		.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "gpmc_wait3.uart4_rx", -		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, -		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE2, -		.idle	= OMAP_PIN_INPUT | OMAP_MUX_MODE2, -	}, -}; - -static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { -	{ -		.name	= "uart4_tx.uart4_tx", -		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, -	}, -	{ -		.name	= "uart4_rx.uart4_rx", -		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, -		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0, -		.idle	= OMAP_PIN_INPUT | OMAP_MUX_MODE0, -	}, -}; -  static void omap_serial_fill_default_pads(struct omap_board_data *bdata)  { -	switch (bdata->id) { -	case 0: -		bdata->pads = default_uart1_pads; -		bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); -		break; -	case 1: -		bdata->pads = default_uart2_pads; -		bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); -		break; -	case 2: -		bdata->pads = default_uart3_pads; -		bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); -		break; -	case 3: -		if (cpu_is_omap44xx()) { -			bdata->pads = default_omap4_uart4_pads; -			bdata->pads_cnt = -				ARRAY_SIZE(default_omap4_uart4_pads); -		} else if (cpu_is_omap3630()) { -			bdata->pads = default_omap36xx_uart4_pads; -			bdata->pads_cnt = -				ARRAY_SIZE(default_omap36xx_uart4_pads); -		} -		break; -	default: -		break; -	}  }  #else  static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 4b57757bf9d..7a7b89304c4 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -37,6 +37,16 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = {  	.flags		= I2C_CLIENT_WAKE,  }; +static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { +	{ +		.addr		= 0x48, +		.flags		= I2C_CLIENT_WAKE, +	}, +	{ +		I2C_BOARD_INFO("twl6040", 0x4b), +	}, +}; +  void __init omap_pmic_init(int bus, u32 clkrate,  			   const char *pmic_type, int pmic_irq,  			   struct twl4030_platform_data *pmic_data) @@ -49,14 +59,31 @@ void __init omap_pmic_init(int bus, u32 clkrate,  	omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);  } +void __init omap4_pmic_init(const char *pmic_type, +		    struct twl4030_platform_data *pmic_data, +		    struct twl6040_platform_data *twl6040_data, int twl6040_irq) +{ +	/* PMIC part*/ +	strncpy(omap4_i2c1_board_info[0].type, pmic_type, +		sizeof(omap4_i2c1_board_info[0].type)); +	omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N; +	omap4_i2c1_board_info[0].platform_data = pmic_data; + +	/* TWL6040 audio IC part */ +	omap4_i2c1_board_info[1].irq = twl6040_irq; +	omap4_i2c1_board_info[1].platform_data = twl6040_data; + +	omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2); + +} +  void __init omap_pmic_late_init(void)  {  	/* Init the OMAP TWL parameters (if PMIC has been registerd) */ -	if (!pmic_i2c_board_info.irq) -		return; - -	omap3_twl_init(); -	omap4_twl_init(); +	if (pmic_i2c_board_info.irq) +		omap3_twl_init(); +	if (omap4_i2c1_board_info[0].irq) +		omap4_twl_init();  }  #if defined(CONFIG_ARCH_OMAP3) diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h index 275dde8cb27..09627483a57 100644 --- a/arch/arm/mach-omap2/twl-common.h +++ b/arch/arm/mach-omap2/twl-common.h @@ -29,6 +29,7 @@  struct twl4030_platform_data; +struct twl6040_platform_data;  void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,  		    struct twl4030_platform_data *pmic_data); @@ -46,12 +47,9 @@ static inline void omap3_pmic_init(const char *pmic_type,  	omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);  } -static inline void omap4_pmic_init(const char *pmic_type, -				   struct twl4030_platform_data *pmic_data) -{ -	/* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */ -	omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data); -} +void omap4_pmic_init(const char *pmic_type, +		    struct twl4030_platform_data *pmic_data, +		    struct twl6040_platform_data *audio_data, int twl6040_irq);  void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,  			   u32 pdata_flags, u32 regulators_flags); diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h index c54cef25895..cbf51ae8185 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h @@ -17,6 +17,7 @@   *   * bit     23 - Input/Output (PXA2xx specific)   * bit     24 - Wakeup Enable(PXA2xx specific) + * bit     25 - Keep Output  (PXA2xx specific)   */  #define MFP_DIR_IN		(0x0 << 23) @@ -25,6 +26,12 @@  #define MFP_DIR(x)		(((x) >> 23) & 0x1)  #define MFP_LPM_CAN_WAKEUP	(0x1 << 24) + +/* + * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to + * retain their last output level (low or high). + * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input. + */  #define MFP_LPM_KEEP_OUTPUT	(0x1 << 25)  #define WAKEUP_ON_EDGE_RISE	(MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE) diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index b0a84288778..ef0426a159d 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -33,6 +33,8 @@  #define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))  #define GPLR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5))  #define GPDR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c) +#define GPSR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18) +#define GPCR(x)		__REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24)  #define PWER_WE35	(1 << 24) @@ -348,6 +350,7 @@ static inline void pxa27x_mfp_init(void) {}  #ifdef CONFIG_PM  static unsigned long saved_gafr[2][4];  static unsigned long saved_gpdr[4]; +static unsigned long saved_gplr[4];  static unsigned long saved_pgsr[4];  static int pxa2xx_mfp_suspend(void) @@ -366,14 +369,26 @@ static int pxa2xx_mfp_suspend(void)  	}  	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { -  		saved_gafr[0][i] = GAFR_L(i);  		saved_gafr[1][i] = GAFR_U(i);  		saved_gpdr[i] = GPDR(i * 32); +		saved_gplr[i] = GPLR(i * 32);  		saved_pgsr[i] = PGSR(i); -		GPDR(i * 32) = gpdr_lpm[i]; +		GPSR(i * 32) = PGSR(i); +		GPCR(i * 32) = ~PGSR(i); +	} + +	/* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */ +	for (i = 0; i < pxa_last_gpio; i++) { +		if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) || +		    ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && +		     (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i)))) +			GPDR(i) |= GPIO_bit(i); +		else +			GPDR(i) &= ~GPIO_bit(i);  	} +  	return 0;  } @@ -384,6 +399,8 @@ static void pxa2xx_mfp_resume(void)  	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {  		GAFR_L(i) = saved_gafr[0][i];  		GAFR_U(i) = saved_gafr[1][i]; +		GPSR(i * 32) = saved_gplr[i]; +		GPCR(i * 32) = ~saved_gplr[i];  		GPDR(i * 32) = saved_gpdr[i];  		PGSR(i) = saved_pgsr[i];  	} diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 6bce78edce7..4726c246dcd 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -421,8 +421,11 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)  	pxa_register_device(&pxa27x_device_i2c_power, info);  } +static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { +	.gpio_set_wake = gpio_set_wake, +}; +  static struct platform_device *devices[] __initdata = { -	&pxa_device_gpio,  	&pxa27x_device_udc,  	&pxa_device_pmu,  	&pxa_device_i2s, @@ -458,6 +461,7 @@ static int __init pxa27x_init(void)  		register_syscore_ops(&pxa2xx_mfp_syscore_ops);  		register_syscore_ops(&pxa2xx_clock_syscore_ops); +		pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info);  		ret = platform_add_devices(devices, ARRAY_SIZE(devices));  	} diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index 0f3a327ebca..b34287ab5af 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -111,10 +111,6 @@ config S3C24XX_SETUP_TS  	help  	  Compile in platform device definition for Samsung TouchScreen. -# cpu-specific sections - -if CPU_S3C2410 -  config S3C2410_DMA  	bool  	depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442) @@ -127,6 +123,10 @@ config S3C2410_PM  	help  	  Power Management code common to S3C2410 and better +# cpu-specific sections + +if CPU_S3C2410 +  config S3C24XX_SIMTEC_NOR  	bool  	help diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index a8933de3d62..32395664e87 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -25,6 +25,7 @@  #include <linux/gpio_keys.h>  #include <linux/input.h>  #include <linux/gpio.h> +#include <linux/mmc/host.h>  #include <linux/interrupt.h>  #include <asm/hardware/vic.h> @@ -765,6 +766,7 @@ static void __init goni_pmic_init(void)  /* MoviNAND */  static struct s3c_sdhci_platdata goni_hsmmc0_data __initdata = {  	.max_width		= 4, +	.host_caps2		= MMC_CAP2_BROKEN_VOLTAGE,  	.cd_type		= S3C_SDHCI_CD_PERMANENT,  }; diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 7c524b4e415..16be4c56abe 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -306,7 +306,7 @@ void sa11x0_register_irda(struct irda_platform_data *irda)  }  static struct resource sa1100_rtc_resources[] = { -	DEFINE_RES_MEM(0x90010000, 0x9001003f), +	DEFINE_RES_MEM(0x90010000, 0x40),  	DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),  	DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),  }; diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 1621ad07d28..33339745d43 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1667,8 +1667,10 @@ void __init u300_init_irq(void)  	for (i = 0; i < U300_VIC_IRQS_END; i++)  		set_bit(i, (unsigned long *) &mask[0]); -	vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); -	vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]); +	vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START, +		 mask[0], mask[0]); +	vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START, +		 mask[1], mask[1]);  } diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c index a38f80238ea..cb04bd6ab3e 100644 --- a/arch/arm/mach-u300/i2c.c +++ b/arch/arm/mach-u300/i2c.c @@ -146,9 +146,6 @@ static struct ab3100_platform_data ab3100_plf_data = {  				.min_uV = 1800000,  				.max_uV = 1800000,  				.valid_modes_mask = REGULATOR_MODE_NORMAL, -				.valid_ops_mask = -				REGULATOR_CHANGE_VOLTAGE | -				REGULATOR_CHANGE_STATUS,  				.always_on = 1,  				.boot_on = 1,  			}, @@ -160,9 +157,6 @@ static struct ab3100_platform_data ab3100_plf_data = {  				.min_uV = 2500000,  				.max_uV = 2500000,  				.valid_modes_mask = REGULATOR_MODE_NORMAL, -				.valid_ops_mask = -				REGULATOR_CHANGE_VOLTAGE | -				REGULATOR_CHANGE_STATUS,  				.always_on = 1,  				.boot_on = 1,  			}, @@ -230,8 +224,7 @@ static struct ab3100_platform_data ab3100_plf_data = {  				.max_uV = 1800000,  				.valid_modes_mask = REGULATOR_MODE_NORMAL,  				.valid_ops_mask = -				REGULATOR_CHANGE_VOLTAGE | -				REGULATOR_CHANGE_STATUS, +				REGULATOR_CHANGE_VOLTAGE,  				.always_on = 1,  				.boot_on = 1,  			}, diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h index ee78a26707e..ec09c1e07b1 100644 --- a/arch/arm/mach-u300/include/mach/irqs.h +++ b/arch/arm/mach-u300/include/mach/irqs.h @@ -12,101 +12,101 @@  #ifndef __MACH_IRQS_H  #define __MACH_IRQS_H -#define IRQ_U300_INTCON0_START		0 -#define IRQ_U300_INTCON1_START		32 +#define IRQ_U300_INTCON0_START		1 +#define IRQ_U300_INTCON1_START		33  /* These are on INTCON0 - 30 lines */ -#define IRQ_U300_IRQ0_EXT		0 -#define IRQ_U300_IRQ1_EXT		1 -#define IRQ_U300_DMA			2 -#define IRQ_U300_VIDEO_ENC_0		3 -#define IRQ_U300_VIDEO_ENC_1		4 -#define IRQ_U300_AAIF_RX		5 -#define IRQ_U300_AAIF_TX		6 -#define IRQ_U300_AAIF_VGPIO		7 -#define IRQ_U300_AAIF_WAKEUP		8 -#define IRQ_U300_PCM_I2S0_FRAME		9 -#define IRQ_U300_PCM_I2S0_FIFO		10 -#define IRQ_U300_PCM_I2S1_FRAME		11 -#define IRQ_U300_PCM_I2S1_FIFO		12 -#define IRQ_U300_XGAM_GAMCON		13 -#define IRQ_U300_XGAM_CDI		14 -#define IRQ_U300_XGAM_CDICON		15 +#define IRQ_U300_IRQ0_EXT		1 +#define IRQ_U300_IRQ1_EXT		2 +#define IRQ_U300_DMA			3 +#define IRQ_U300_VIDEO_ENC_0		4 +#define IRQ_U300_VIDEO_ENC_1		5 +#define IRQ_U300_AAIF_RX		6 +#define IRQ_U300_AAIF_TX		7 +#define IRQ_U300_AAIF_VGPIO		8 +#define IRQ_U300_AAIF_WAKEUP		9 +#define IRQ_U300_PCM_I2S0_FRAME		10 +#define IRQ_U300_PCM_I2S0_FIFO		11 +#define IRQ_U300_PCM_I2S1_FRAME		12 +#define IRQ_U300_PCM_I2S1_FIFO		13 +#define IRQ_U300_XGAM_GAMCON		14 +#define IRQ_U300_XGAM_CDI		15 +#define IRQ_U300_XGAM_CDICON		16  #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)  /* MMIACC not used on the DB3210 or DB3350 chips */ -#define IRQ_U300_XGAM_MMIACC		16 +#define IRQ_U300_XGAM_MMIACC		17  #endif -#define IRQ_U300_XGAM_PDI		17 -#define IRQ_U300_XGAM_PDICON		18 -#define IRQ_U300_XGAM_GAMEACC		19 -#define IRQ_U300_XGAM_MCIDCT		20 -#define IRQ_U300_APEX			21 -#define IRQ_U300_UART0			22 -#define IRQ_U300_SPI			23 -#define IRQ_U300_TIMER_APP_OS		24 -#define IRQ_U300_TIMER_APP_DD		25 -#define IRQ_U300_TIMER_APP_GP1		26 -#define IRQ_U300_TIMER_APP_GP2		27 -#define IRQ_U300_TIMER_OS		28 -#define IRQ_U300_TIMER_MS		29 -#define IRQ_U300_KEYPAD_KEYBF		30 -#define IRQ_U300_KEYPAD_KEYBR		31 +#define IRQ_U300_XGAM_PDI		18 +#define IRQ_U300_XGAM_PDICON		19 +#define IRQ_U300_XGAM_GAMEACC		20 +#define IRQ_U300_XGAM_MCIDCT		21 +#define IRQ_U300_APEX			22 +#define IRQ_U300_UART0			23 +#define IRQ_U300_SPI			24 +#define IRQ_U300_TIMER_APP_OS		25 +#define IRQ_U300_TIMER_APP_DD		26 +#define IRQ_U300_TIMER_APP_GP1		27 +#define IRQ_U300_TIMER_APP_GP2		28 +#define IRQ_U300_TIMER_OS		29 +#define IRQ_U300_TIMER_MS		30 +#define IRQ_U300_KEYPAD_KEYBF		31 +#define IRQ_U300_KEYPAD_KEYBR		32  /* These are on INTCON1 - 32 lines */ -#define IRQ_U300_GPIO_PORT0		32 -#define IRQ_U300_GPIO_PORT1		33 -#define IRQ_U300_GPIO_PORT2		34 +#define IRQ_U300_GPIO_PORT0		33 +#define IRQ_U300_GPIO_PORT1		34 +#define IRQ_U300_GPIO_PORT2		35  #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \      defined(CONFIG_MACH_U300_BS335)  /* These are for DB3150, DB3200 and DB3350 */ -#define IRQ_U300_WDOG			35 -#define IRQ_U300_EVHIST			36 -#define IRQ_U300_MSPRO			37 -#define IRQ_U300_MMCSD_MCIINTR0		38 -#define IRQ_U300_MMCSD_MCIINTR1		39 -#define IRQ_U300_I2C0			40 -#define IRQ_U300_I2C1			41 -#define IRQ_U300_RTC			42 -#define IRQ_U300_NFIF			43 -#define IRQ_U300_NFIF2			44 +#define IRQ_U300_WDOG			36 +#define IRQ_U300_EVHIST			37 +#define IRQ_U300_MSPRO			38 +#define IRQ_U300_MMCSD_MCIINTR0		39 +#define IRQ_U300_MMCSD_MCIINTR1		40 +#define IRQ_U300_I2C0			41 +#define IRQ_U300_I2C1			42 +#define IRQ_U300_RTC			43 +#define IRQ_U300_NFIF			44 +#define IRQ_U300_NFIF2			45  #endif  /* DB3150 and DB3200 have only 45 IRQs */  #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) -#define U300_VIC_IRQS_END		45 +#define U300_VIC_IRQS_END		46  #endif  /* The DB3350-specific interrupt lines */  #ifdef CONFIG_MACH_U300_BS335 -#define IRQ_U300_ISP_F0			45 -#define IRQ_U300_ISP_F1			46 -#define IRQ_U300_ISP_F2			47 -#define IRQ_U300_ISP_F3			48 -#define IRQ_U300_ISP_F4			49 -#define IRQ_U300_GPIO_PORT3		50 -#define IRQ_U300_SYSCON_PLL_LOCK	51 -#define IRQ_U300_UART1			52 -#define IRQ_U300_GPIO_PORT4		53 -#define IRQ_U300_GPIO_PORT5		54 -#define IRQ_U300_GPIO_PORT6		55 -#define U300_VIC_IRQS_END		56 +#define IRQ_U300_ISP_F0			46 +#define IRQ_U300_ISP_F1			47 +#define IRQ_U300_ISP_F2			48 +#define IRQ_U300_ISP_F3			49 +#define IRQ_U300_ISP_F4			50 +#define IRQ_U300_GPIO_PORT3		51 +#define IRQ_U300_SYSCON_PLL_LOCK	52 +#define IRQ_U300_UART1			53 +#define IRQ_U300_GPIO_PORT4		54 +#define IRQ_U300_GPIO_PORT5		55 +#define IRQ_U300_GPIO_PORT6		56 +#define U300_VIC_IRQS_END		57  #endif  /* The DB3210-specific interrupt lines */  #ifdef CONFIG_MACH_U300_BS365 -#define IRQ_U300_GPIO_PORT3		35 -#define IRQ_U300_GPIO_PORT4		36 -#define IRQ_U300_WDOG			37 -#define IRQ_U300_EVHIST			38 -#define IRQ_U300_MSPRO			39 -#define IRQ_U300_MMCSD_MCIINTR0		40 -#define IRQ_U300_MMCSD_MCIINTR1		41 -#define IRQ_U300_I2C0			42 -#define IRQ_U300_I2C1			43 -#define IRQ_U300_RTC			44 -#define IRQ_U300_NFIF			45 -#define IRQ_U300_NFIF2			46 -#define IRQ_U300_SYSCON_PLL_LOCK	47 -#define U300_VIC_IRQS_END		48 +#define IRQ_U300_GPIO_PORT3		36 +#define IRQ_U300_GPIO_PORT4		37 +#define IRQ_U300_WDOG			38 +#define IRQ_U300_EVHIST			39 +#define IRQ_U300_MSPRO			40 +#define IRQ_U300_MMCSD_MCIINTR0		41 +#define IRQ_U300_MMCSD_MCIINTR1		42 +#define IRQ_U300_I2C0			43 +#define IRQ_U300_I2C1			44 +#define IRQ_U300_RTC			45 +#define IRQ_U300_NFIF			46 +#define IRQ_U300_NFIF2			47 +#define IRQ_U300_SYSCON_PLL_LOCK	48 +#define U300_VIC_IRQS_END		49  #endif  /* Maximum 8*7 GPIO lines */ @@ -117,6 +117,6 @@  #define IRQ_U300_GPIO_END		(U300_VIC_IRQS_END)  #endif -#define NR_IRQS				(IRQ_U300_GPIO_END) +#define NR_IRQS				(IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START)  #endif diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 880d02ec89d..ef7099eea0f 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -17,6 +17,7 @@ config UX500_SOC_DB5500  config UX500_SOC_DB8500  	bool  	select MFD_DB8500_PRCMU +	select REGULATOR  	select REGULATOR_DB8500_PRCMU  	select CPU_FREQ_TABLE if CPU_FREQ diff --git a/arch/arm/mach-ux500/mbox-db5500.c b/arch/arm/mach-ux500/mbox-db5500.c index 2b2d51caf9d..0127490218c 100644 --- a/arch/arm/mach-ux500/mbox-db5500.c +++ b/arch/arm/mach-ux500/mbox-db5500.c @@ -168,7 +168,7 @@ static ssize_t mbox_read_fifo(struct device *dev,  	return sprintf(buf, "0x%X\n", mbox_value);  } -static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo); +static DEVICE_ATTR(fifo, S_IWUSR | S_IRUGO, mbox_read_fifo, mbox_write_fifo);  static int mbox_show(struct seq_file *s, void *data)  { diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index d2058ef8345..eff5842f623 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -99,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  	 */  	write_pen_release(cpu_logical_map(cpu)); -	gic_raise_softirq(cpumask_of(cpu), 1); +	smp_send_reschedule(cpu);  	timeout = jiffies + (1 * HZ);  	while (time_before(jiffies, timeout)) { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 8070145ccb9..3f26db4ee8e 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -305,6 +305,7 @@ struct omap_hwmod_sysc_fields {   * @rev_offs: IP block revision register offset (from module base addr)   * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)   * @syss_offs: OCP_SYSSTATUS register offset (from module base addr) + * @srst_udelay: Delay needed after doing a softreset in usecs   * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}   * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported   * @clockact: the default value of the module CLOCKACTIVITY bits @@ -330,9 +331,10 @@ struct omap_hwmod_class_sysconfig {  	u16 sysc_offs;  	u16 syss_offs;  	u16 sysc_flags; +	struct omap_hwmod_sysc_fields *sysc_fields; +	u8 srst_udelay;  	u8 idlemodes;  	u8 clockact; -	struct omap_hwmod_sysc_fields *sysc_fields;  };  /** diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index eec98afa0f8..f9a8c5341ee 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -348,7 +348,6 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,  			sdrc_actim_ctrl_b_1, sdrc_mr_1);  } -#ifdef CONFIG_PM  void omap3_sram_restore_context(void)  {  	omap_sram_ceil = omap_sram_base + omap_sram_size; @@ -358,17 +357,18 @@ void omap3_sram_restore_context(void)  			       omap3_sram_configure_core_dpll_sz);  	omap_push_sram_idle();  } -#endif /* CONFIG_PM */ - -#endif /* CONFIG_ARCH_OMAP3 */  static inline int omap34xx_sram_init(void)  { -#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)  	omap3_sram_restore_context(); -#endif  	return 0;  } +#else +static inline int omap34xx_sram_init(void) +{ +	return 0; +} +#endif /* CONFIG_ARCH_OMAP3 */  static inline int am33xx_sram_init(void)  { diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index 317e246ffc5..e834c5ef437 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -18,6 +18,8 @@  #ifndef __PLAT_S3C_SDHCI_H  #define __PLAT_S3C_SDHCI_H __FILE__ +#include <plat/devs.h> +  struct platform_device;  struct mmc_host;  struct mmc_card; @@ -356,4 +358,30 @@ static inline void exynos4_default_sdhci3(void) { }  #endif /* CONFIG_EXYNOS4_SETUP_SDHCI */ +static inline void s3c_sdhci_setname(int id, char *name) +{ +	switch (id) { +#ifdef CONFIG_S3C_DEV_HSMMC +	case 0: +		s3c_device_hsmmc0.name = name; +		break; +#endif +#ifdef CONFIG_S3C_DEV_HSMMC1 +	case 1: +		s3c_device_hsmmc1.name = name; +		break; +#endif +#ifdef CONFIG_S3C_DEV_HSMMC2 +	case 2: +		s3c_device_hsmmc2.name = name; +		break; +#endif +#ifdef CONFIG_S3C_DEV_HSMMC3 +	case 3: +		s3c_device_hsmmc3.name = name; +		break; +#endif +	} +} +  #endif /* __PLAT_S3C_SDHCI_H */ diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index 1633a6f306c..85038f54354 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -38,7 +38,7 @@ static struct platform_device rtc_device = {  	.name = "rtc-bfin",  	.id   = -1,  }; -#endif +#endif	/* CONFIG_RTC_DRV_BFIN */  #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)  #ifdef CONFIG_SERIAL_BFIN_UART0 @@ -100,7 +100,7 @@ static struct platform_device bfin_uart0_device = {  		.platform_data = &bfin_uart0_peripherals, /* Passed to driver */  	},  }; -#endif +#endif	/* CONFIG_SERIAL_BFIN_UART0 */  #ifdef CONFIG_SERIAL_BFIN_UART1  static struct resource bfin_uart1_resources[] = {  	{ @@ -148,7 +148,7 @@ static struct platform_device bfin_uart1_device = {  		.platform_data = &bfin_uart1_peripherals, /* Passed to driver */  	},  }; -#endif +#endif	/* CONFIG_SERIAL_BFIN_UART1 */  #ifdef CONFIG_SERIAL_BFIN_UART2  static struct resource bfin_uart2_resources[] = {  	{ @@ -196,8 +196,8 @@ static struct platform_device bfin_uart2_device = {  		.platform_data = &bfin_uart2_peripherals, /* Passed to driver */  	},  }; -#endif -#endif +#endif	/* CONFIG_SERIAL_BFIN_UART2 */ +#endif	/* CONFIG_SERIAL_BFIN */  #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)  #ifdef CONFIG_BFIN_SIR0 @@ -224,7 +224,7 @@ static struct platform_device bfin_sir0_device = {  	.num_resources = ARRAY_SIZE(bfin_sir0_resources),  	.resource = bfin_sir0_resources,  }; -#endif +#endif	/* CONFIG_BFIN_SIR0 */  #ifdef CONFIG_BFIN_SIR1  static struct resource bfin_sir1_resources[] = {  	{ @@ -249,7 +249,7 @@ static struct platform_device bfin_sir1_device = {  	.num_resources = ARRAY_SIZE(bfin_sir1_resources),  	.resource = bfin_sir1_resources,  }; -#endif +#endif	/* CONFIG_BFIN_SIR1 */  #ifdef CONFIG_BFIN_SIR2  static struct resource bfin_sir2_resources[] = {  	{ @@ -274,8 +274,8 @@ static struct platform_device bfin_sir2_device = {  	.num_resources = ARRAY_SIZE(bfin_sir2_resources),  	.resource = bfin_sir2_resources,  }; -#endif -#endif +#endif	/* CONFIG_BFIN_SIR2 */ +#endif	/* CONFIG_BFIN_SIR */  #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)  #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART @@ -311,7 +311,7 @@ static struct platform_device bfin_sport0_uart_device = {  		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */  	},  }; -#endif +#endif	/* CONFIG_SERIAL_BFIN_SPORT0_UART */  #ifdef CONFIG_SERIAL_BFIN_SPORT1_UART  static struct resource bfin_sport1_uart_resources[] = {  	{ @@ -345,7 +345,7 @@ static struct platform_device bfin_sport1_uart_device = {  		.platform_data = &bfin_sport1_peripherals, /* Passed to driver */  	},  }; -#endif +#endif	/* CONFIG_SERIAL_BFIN_SPORT1_UART */  #ifdef CONFIG_SERIAL_BFIN_SPORT2_UART  static struct resource bfin_sport2_uart_resources[] = {  	{ @@ -379,7 +379,7 @@ static struct platform_device bfin_sport2_uart_device = {  		.platform_data = &bfin_sport2_peripherals, /* Passed to driver */  	},  }; -#endif +#endif	/* CONFIG_SERIAL_BFIN_SPORT2_UART */  #ifdef CONFIG_SERIAL_BFIN_SPORT3_UART  static struct resource bfin_sport3_uart_resources[] = {  	{ @@ -413,8 +413,8 @@ static struct platform_device bfin_sport3_uart_device = {  		.platform_data = &bfin_sport3_peripherals, /* Passed to driver */  	},  }; -#endif -#endif +#endif	/* CONFIG_SERIAL_BFIN_SPORT3_UART */ +#endif	/* CONFIG_SERIAL_BFIN_SPORT */  #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)  static unsigned short bfin_can_peripherals[] = { @@ -452,7 +452,7 @@ static struct platform_device bfin_can_device = {  		.platform_data = &bfin_can_peripherals, /* Passed to driver */  	},  }; -#endif +#endif	/* CONFIG_CAN_BFIN */  /*   *  USB-LAN EzExtender board @@ -488,7 +488,7 @@ static struct platform_device smc91x_device = {  		.platform_data	= &smc91x_info,  	},  }; -#endif +#endif	/* CONFIG_SMC91X */  #if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)  /* all SPI peripherals info goes here */ @@ -518,7 +518,8 @@ static struct flash_platform_data bfin_spi_flash_data = {  static struct bfin5xx_spi_chip spi_flash_chip_info = {  	.enable_dma = 0,         /* use dma transfer with this chip*/  }; -#endif +#endif	/* CONFIG_MTD_M25P80 */ +#endif	/* CONFIG_SPI_BFIN5XX */  #if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)  #include <linux/spi/ad7879.h> @@ -535,7 +536,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {  	.gpio_export		= 1,	/* Export GPIO to gpiolib */  	.gpio_base		= -1,	/* Dynamic allocation */  }; -#endif +#endif	/* CONFIG_TOUCHSCREEN_AD7879 */  #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)  #include <asm/bfin-lq035q1.h> @@ -564,7 +565,7 @@ static struct platform_device bfin_lq035q1_device = {  		.platform_data = &bfin_lq035q1_data,  	},  }; -#endif +#endif	/* CONFIG_FB_BFIN_LQ035Q1 */  static struct spi_board_info bf538_spi_board_info[] __initdata = {  #if defined(CONFIG_MTD_M25P80) \ @@ -579,7 +580,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = {  		.controller_data = &spi_flash_chip_info,  		.mode = SPI_MODE_3,  	}, -#endif +#endif	/* CONFIG_MTD_M25P80 */  #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)  	{  		.modalias = "ad7879", @@ -590,7 +591,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = {  		.chip_select = 1,  		.mode = SPI_CPHA | SPI_CPOL,  	}, -#endif +#endif	/* CONFIG_TOUCHSCREEN_AD7879_SPI */  #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)  	{  		.modalias = "bfin-lq035q1-spi", @@ -599,7 +600,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = {  		.chip_select = 2,  		.mode = SPI_CPHA | SPI_CPOL,  	}, -#endif +#endif	/* CONFIG_FB_BFIN_LQ035Q1 */  #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)  	{  		.modalias = "spidev", @@ -607,7 +608,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = {  		.bus_num = 0,  		.chip_select = 1,  	}, -#endif +#endif	/* CONFIG_SPI_SPIDEV */  };  /* SPI (0) */ @@ -716,8 +717,6 @@ static struct platform_device bf538_spi_master2 = {  		},  }; -#endif  /* spi master and devices */ -  #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)  static struct resource bfin_twi0_resource[] = {  	[0] = { @@ -759,8 +758,8 @@ static struct platform_device i2c_bfin_twi1_device = {  	.num_resources = ARRAY_SIZE(bfin_twi1_resource),  	.resource = bfin_twi1_resource,  }; -#endif -#endif +#endif	/* CONFIG_BF542 */ +#endif	/* CONFIG_I2C_BLACKFIN_TWI */  #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)  #include <linux/gpio_keys.h> diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c index 37302218ca4..0f2367cc549 100644 --- a/arch/hexagon/kernel/dma.c +++ b/arch/hexagon/kernel/dma.c @@ -22,6 +22,7 @@  #include <linux/bootmem.h>  #include <linux/genalloc.h>  #include <asm/dma-mapping.h> +#include <linux/module.h>  struct dma_map_ops *dma_ops;  EXPORT_SYMBOL(dma_ops); diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index 18c4f0b0f4b..ff02821bfb7 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -1,7 +1,7 @@  /*   * Process creation support for Hexagon   * - * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 and @@ -88,7 +88,7 @@ void (*idle_sleep)(void) = default_idle;  void cpu_idle(void)  {  	while (1) { -		tick_nohz_stop_sched_tick(1); +		tick_nohz_idle_enter();  		local_irq_disable();  		while (!need_resched()) {  			idle_sleep(); @@ -97,7 +97,7 @@ void cpu_idle(void)  			local_irq_disable();  		}  		local_irq_enable(); -		tick_nohz_restart_sched_tick(); +		tick_nohz_idle_exit();  		schedule();  	}  } diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 32342de1a79..96c3b2c4dba 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c @@ -28,6 +28,7 @@  #include <linux/ptrace.h>  #include <linux/regset.h>  #include <linux/user.h> +#include <linux/elf.h>  #include <asm/user.h> diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c index 9b44a9e2d05..1298141874a 100644 --- a/arch/hexagon/kernel/smp.c +++ b/arch/hexagon/kernel/smp.c @@ -1,7 +1,7 @@  /*   * SMP support for Hexagon   * - * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License version 2 and @@ -28,6 +28,7 @@  #include <linux/sched.h>  #include <linux/smp.h>  #include <linux/spinlock.h> +#include <linux/cpu.h>  #include <asm/time.h>    /*  timer_interrupt  */  #include <asm/hexagon_vm.h> @@ -177,7 +178,12 @@ void __cpuinit start_secondary(void)  	printk(KERN_INFO "%s cpu %d\n", __func__, current_thread_info()->cpu); +	notify_cpu_starting(cpu); + +	ipi_call_lock();  	set_cpu_online(cpu, true); +	ipi_call_unlock(); +  	local_irq_enable();  	cpu_idle(); diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c index 6bee15c9c11..5d9b33b6793 100644 --- a/arch/hexagon/kernel/time.c +++ b/arch/hexagon/kernel/time.c @@ -28,6 +28,7 @@  #include <linux/of.h>  #include <linux/of_address.h>  #include <linux/of_irq.h> +#include <linux/module.h>  #include <asm/timer-regs.h>  #include <asm/hexagon_vm.h> diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c index f212a453b52..5d39f42f708 100644 --- a/arch/hexagon/kernel/vdso.c +++ b/arch/hexagon/kernel/vdso.c @@ -21,6 +21,7 @@  #include <linux/err.h>  #include <linux/mm.h>  #include <linux/vmalloc.h> +#include <linux/binfmts.h>  #include <asm/vdso.h> diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 9d0fd7d5bb8..f00ba025375 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -604,12 +604,6 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)  	spin_unlock(&(x)->ctx_lock);  } -static inline unsigned int -pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) -{ -	return do_munmap(mm, addr, len); -} -  static inline unsigned long   pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)  { @@ -1458,8 +1452,9 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)   * a PROTECT_CTX() section.   */  static int -pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size) +pfm_remove_smpl_mapping(void *vaddr, unsigned long size)  { +	struct task_struct *task = current;  	int r;  	/* sanity checks */ @@ -1473,13 +1468,8 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz  	/*  	 * does the actual unmapping  	 */ -	down_write(&task->mm->mmap_sem); +	r = vm_munmap((unsigned long)vaddr, size); -	DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size)); - -	r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0); - -	up_write(&task->mm->mmap_sem);  	if (r !=0) {  		printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);  	} @@ -1945,7 +1935,7 @@ pfm_flush(struct file *filp, fl_owner_t id)  	 * because some VM function reenables interrupts.  	 *  	 */ -	if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size); +	if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size);  	return 0;  } diff --git a/arch/m68k/configs/m5275evb_defconfig b/arch/m68k/configs/m5275evb_defconfig index 33c32aeca12..a1230e82bb1 100644 --- a/arch/m68k/configs/m5275evb_defconfig +++ b/arch/m68k/configs/m5275evb_defconfig @@ -49,7 +49,6 @@ CONFIG_BLK_DEV_RAM=y  CONFIG_NETDEVICES=y  CONFIG_NET_ETHERNET=y  CONFIG_FEC=y -CONFIG_FEC2=y  # CONFIG_NETDEV_1000 is not set  # CONFIG_NETDEV_10000 is not set  CONFIG_PPP=y diff --git a/arch/m68k/platform/527x/config.c b/arch/m68k/platform/527x/config.c index 7ed848c3b84..f91a53294c3 100644 --- a/arch/m68k/platform/527x/config.c +++ b/arch/m68k/platform/527x/config.c @@ -74,9 +74,7 @@ static void __init m527x_fec_init(void)  	writew(par | 0xf00, MCF_IPSBAR + 0x100082);  	v = readb(MCF_IPSBAR + 0x100078);  	writeb(v | 0xc0, MCF_IPSBAR + 0x100078); -#endif -#ifdef CONFIG_FEC2  	/* Set multi-function pins to ethernet mode for fec1 */  	par = readw(MCF_IPSBAR + 0x100082);  	writew(par | 0xa0, MCF_IPSBAR + 0x100082); diff --git a/arch/m68k/platform/68EZ328/Makefile b/arch/m68k/platform/68EZ328/Makefile index ee97735a242..b44d799b111 100644 --- a/arch/m68k/platform/68EZ328/Makefile +++ b/arch/m68k/platform/68EZ328/Makefile @@ -3,9 +3,3 @@  #  obj-y := config.o - -extra-y := bootlogo.rh - -$(obj)/bootlogo.rh: $(src)/bootlogo.h -	perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \ -		> $(obj)/bootlogo.rh diff --git a/arch/m68k/platform/68VZ328/Makefile b/arch/m68k/platform/68VZ328/Makefile index 447ffa0fd7c..a49d75e6548 100644 --- a/arch/m68k/platform/68VZ328/Makefile +++ b/arch/m68k/platform/68VZ328/Makefile @@ -3,14 +3,9 @@  #  obj-y		:= config.o -logo-$(UCDIMM)	:= bootlogo.rh -logo-$(DRAGEN2)	:= screen.h -extra-y		:= $(logo-y) - -$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h -	perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh +extra-$(DRAGEN2):= screen.h  $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl  	perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h -clean-files := $(obj)/screen.h $(obj)/bootlogo.rh +clean-files := $(obj)/screen.h diff --git a/arch/m68k/platform/68EZ328/bootlogo.h b/arch/m68k/platform/68VZ328/bootlogo.h index e842bdae583..b38e2b25514 100644 --- a/arch/m68k/platform/68EZ328/bootlogo.h +++ b/arch/m68k/platform/68VZ328/bootlogo.h @@ -1,6 +1,6 @@  #define splash_width 640  #define splash_height 480 -static unsigned char splash_bits[] = { +unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = {    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c index fa50c48292f..7af97362b95 100644 --- a/arch/m68k/platform/coldfire/device.c +++ b/arch/m68k/platform/coldfire/device.c @@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = {  static struct platform_device mcf_fec1 = {  	.name			= "fec", -	.id			= 0, +	.id			= 1,  	.num_resources		= ARRAY_SIZE(mcf_fec1_resources),  	.resource		= mcf_fec1_resources,  }; diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi new file mode 100644 index 00000000000..1cf0b77b1ef --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi @@ -0,0 +1,43 @@ +/* + * PQ3 MPIC Message (Group B) device tree stub [ controller @ offset 0x42400 ] + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer. + *     * Redistributions in binary form must reproduce the above copyright + *       notice, this list of conditions and the following disclaimer in the + *       documentation and/or other materials provided with the distribution. + *     * Neither the name of Freescale Semiconductor nor the + *       names of its contributors may be used to endorse or promote products + *       derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +message@42400 { +	compatible = "fsl,mpic-v3.1-msgr"; +	reg = <0x42400 0x200>; +	interrupts = < +		0xb4 2 0 0 +		0xb5 2 0 0 +		0xb6 2 0 0 +		0xb7 2 0 0>; +}; diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi index fdedf7b1fe0..71c30eb1005 100644 --- a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi +++ b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi @@ -53,6 +53,16 @@ timer@41100 {  		      3 0 3 0>;  }; +message@41400 { +	compatible = "fsl,mpic-v3.1-msgr"; +	reg = <0x41400 0x200>; +	interrupts = < +		0xb0 2 0 0 +		0xb1 2 0 0 +		0xb2 2 0 0 +		0xb3 2 0 0>; +}; +  msi@41600 {  	compatible = "fsl,mpic-msi";  	reg = <0x41600 0x80>; diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e648af92ced..0e40843a1c6 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -18,10 +18,6 @@  #include <linux/atomic.h> -/* Define a way to iterate across irqs. */ -#define for_each_irq(i) \ -	for ((i) = 0; (i) < NR_IRQS; ++(i)) -  extern atomic_t ppc_n_lost_interrupts;  /* This number is used when no interrupt has been assigned */ diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index c65b9294376..c9f698a994b 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h @@ -275,9 +275,6 @@ struct mpic  	unsigned int		isu_mask;  	/* Number of sources */  	unsigned int		num_sources; -	/* default senses array */ -	unsigned char		*senses; -	unsigned int		senses_count;  	/* vector numbers used for internal sources (ipi/timers) */  	unsigned int		ipi_vecs[4]; @@ -415,21 +412,6 @@ extern struct mpic *mpic_alloc(struct device_node *node,  extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,  			    phys_addr_t phys_addr); -/* Set default sense codes - * - * @mpic:	controller - * @senses:	array of sense codes - * @count:	size of above array - * - * Optionally provide an array (indexed on hardware interrupt numbers - * for this MPIC) of default sense codes for the chip. Those are linux - * sense codes IRQ_TYPE_* - * - * The driver gets ownership of the pointer, don't dispose of it or - * anything like that. __init only. - */ -extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count); -  /* Initialize the controller. After this has been called, none of the above   * should be called again for this mpic diff --git a/arch/powerpc/include/asm/mpic_msgr.h b/arch/powerpc/include/asm/mpic_msgr.h index 3ec37dc9003..326d33ca55c 100644 --- a/arch/powerpc/include/asm/mpic_msgr.h +++ b/arch/powerpc/include/asm/mpic_msgr.h @@ -13,6 +13,7 @@  #include <linux/types.h>  #include <linux/spinlock.h> +#include <asm/smp.h>  struct mpic_msgr {  	u32 __iomem *base; diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index b86faa9107d..8a97aa7289d 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -15,11 +15,6 @@  #ifndef __ASM_POWERPC_REG_BOOKE_H__  #define __ASM_POWERPC_REG_BOOKE_H__ -#ifdef CONFIG_BOOKE_WDT -extern u32 booke_wdt_enabled; -extern u32 booke_wdt_period; -#endif /* CONFIG_BOOKE_WDT */ -  /* Machine State Register (MSR) Fields */  #define MSR_GS		(1<<28) /* Guest state */  #define MSR_UCLE	(1<<26)	/* User-mode cache lock enable */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5ec1b2354ca..43eb74fcedd 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -330,14 +330,10 @@ void migrate_irqs(void)  	alloc_cpumask_var(&mask, GFP_KERNEL); -	for_each_irq(irq) { +	for_each_irq_desc(irq, desc) {  		struct irq_data *data;  		struct irq_chip *chip; -		desc = irq_to_desc(irq); -		if (!desc) -			continue; -  		data = irq_desc_get_irq_data(desc);  		if (irqd_is_per_cpu(data))  			continue; diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index c957b1202bd..5df77779440 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -23,14 +23,11 @@  void machine_kexec_mask_interrupts(void) {  	unsigned int i; +	struct irq_desc *desc; -	for_each_irq(i) { -		struct irq_desc *desc = irq_to_desc(i); +	for_each_irq_desc(i, desc) {  		struct irq_chip *chip; -		if (!desc) -			continue; -  		chip = irq_desc_get_chip(desc);  		if (!chip)  			continue; diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 9825f29d1fa..ec8a53fa9e8 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -150,6 +150,9 @@ notrace void __init machine_init(u64 dt_ptr)  }  #ifdef CONFIG_BOOKE_WDT +extern u32 booke_wdt_enabled; +extern u32 booke_wdt_period; +  /* Checks wdt=x and wdt_period=xx command-line option */  notrace int __init early_parse_wdt(char *p)  { diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 9fef5302adc..67dac22b436 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -21,6 +21,12 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = {  	{ .compatible = "fsl,qe", },  	{ .compatible = "fsl,cpm2", },  	{ .compatible = "fsl,srio", }, +	/* So that the DMA channel nodes can be probed individually: */ +	{ .compatible = "fsl,eloplus-dma", }, +	/* For the PMC driver */ +	{ .compatible = "fsl,mpc8548-guts", }, +	/* Probably unnecessary? */ +	{ .compatible = "gpio-leds", },  	{},  }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 9a6f04406e0..d208ebccb91 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -399,12 +399,6 @@ static int __init board_fixups(void)  machine_arch_initcall(mpc8568_mds, board_fixups);  machine_arch_initcall(mpc8569_mds, board_fixups); -static struct of_device_id mpc85xx_ids[] = { -	{ .compatible = "fsl,mpc8548-guts", }, -	{ .compatible = "gpio-leds", }, -	{}, -}; -  static int __init mpc85xx_publish_devices(void)  {  	if (machine_is(mpc8568_mds)) @@ -412,10 +406,7 @@ static int __init mpc85xx_publish_devices(void)  	if (machine_is(mpc8569_mds))  		simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); -	mpc85xx_common_publish_devices(); -	of_platform_bus_probe(NULL, mpc85xx_ids, NULL); - -	return 0; +	return mpc85xx_common_publish_devices();  }  machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index e74b7cde9ae..f700c81a132 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -460,18 +460,7 @@ static void __init p1022_ds_setup_arch(void)  	pr_info("Freescale P1022 DS reference board\n");  } -static struct of_device_id __initdata p1022_ds_ids[] = { -	/* So that the DMA channel nodes can be probed individually: */ -	{ .compatible = "fsl,eloplus-dma", }, -	{}, -}; - -static int __init p1022_ds_publish_devices(void) -{ -	mpc85xx_common_publish_devices(); -	return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); -} -machine_device_initcall(p1022_ds, p1022_ds_publish_devices); +machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices);  machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index d09f3e8e686..85825b5401e 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)  		pr_devel("axon_msi: woff %x roff %x msi %x\n",  			  write_offset, msic->read_offset, msi); -		if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { +		if (msi < nr_irqs && irq_get_chip_data(msi) == msic) {  			generic_handle_irq(msi);  			msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);  		} else { @@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)  	if (rc)  		return rc; -	/* We rely on being able to stash a virq in a u16 */ -	BUILD_BUG_ON(NR_IRQS > 65536); -  	list_for_each_entry(entry, &dev->msi_list, list) {  		virq = irq_create_direct_mapping(msic->irq_domain);  		if (virq == NO_IRQ) { @@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device)  	}  	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); -	msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); +	/* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ +	msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic);  	if (!msic->irq_domain) {  		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",  		       dn->full_name); diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index f9a48af335c..8c6dc42ecf6 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c @@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void)  {  	int	i; -	for (i = 1; i < NR_IRQS; i++) +	for (i = 1; i < nr_irqs; i++)  		beat_destruct_irq_plug(i);  } diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 996c5ff7824..03685a329d7 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -366,11 +366,20 @@ static void kw_i2c_timeout(unsigned long data)  	unsigned long flags;  	spin_lock_irqsave(&host->lock, flags); + +	/* +	 * If the timer is pending, that means we raced with the +	 * irq, in which case we just return +	 */ +	if (timer_pending(&host->timeout_timer)) +		goto skip; +  	kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));  	if (host->state != state_idle) {  		host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;  		add_timer(&host->timeout_timer);  	} + skip:  	spin_unlock_irqrestore(&host->lock, flags);  } diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 66ad93de1d5..c4e630576ff 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -57,9 +57,9 @@ static int max_real_irqs;  static DEFINE_RAW_SPINLOCK(pmac_pic_lock); -#define NR_MASK_WORDS	((NR_IRQS + 31) / 32) -static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +/* The max irq number this driver deals with is 128; see max_irqs */ +static DECLARE_BITMAP(ppc_lost_interrupts, 128); +static DECLARE_BITMAP(ppc_cached_irq_mask, 128);  static int pmac_irq_cascade = -1;  static struct irq_domain *pmac_pic_host; diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index aadbe4f6d53..178a5f300bc 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -30,9 +30,9 @@ config PPC_SPLPAR  	  two or more partitions.  config EEH -	bool "PCI Extended Error Handling (EEH)" if EXPERT +	bool  	depends on PPC_PSERIES && PCI -	default y if !EXPERT +	default y  config PSERIES_MSI         bool diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 309d38ef732..a75e37dc41a 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -1076,7 +1076,7 @@ static void eeh_add_device_late(struct pci_dev *dev)  	pr_debug("EEH: Adding device %s\n", pci_name(dev));  	dn = pci_device_to_OF_node(dev); -	edev = pci_dev_to_eeh_dev(dev); +	edev = of_node_to_eeh_dev(dn);  	if (edev->pdev == dev) {  		pr_debug("EEH: Already referenced !\n");  		return; diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index d3be961e2ae..10386b676d8 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -51,8 +51,7 @@  static intctl_cpm2_t __iomem *cpm2_intctl;  static struct irq_domain *cpm2_pic_host; -#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */  static const u_char irq_to_siureg[] = {  	1, 1, 1, 1, 1, 1, 1, 1, diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c index d5f5416be31..b724622c3a0 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/sysdev/mpc8xx_pic.c @@ -18,69 +18,45 @@  extern int cpm_get_irq(struct pt_regs *regs);  static struct irq_domain *mpc8xx_pic_host; -#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long mpc8xx_cached_irq_mask;  static sysconf8xx_t __iomem *siu_reg; -int cpm_get_irq(struct pt_regs *regs); +static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) +{ +	return 0x80000000 >> irqd_to_hwirq(d); +}  static void mpc8xx_unmask_irq(struct irq_data *d)  { -	int	bit, word; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	word = irq_nr >> 5; - -	ppc_cached_irq_mask[word] |= (1 << (31-bit)); -	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); +	mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); +	out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);  }  static void mpc8xx_mask_irq(struct irq_data *d)  { -	int	bit, word; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	word = irq_nr >> 5; - -	ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); -	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); +	mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); +	out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);  }  static void mpc8xx_ack(struct irq_data *d)  { -	int	bit; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); +	out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d));  }  static void mpc8xx_end_irq(struct irq_data *d)  { -	int bit, word; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	word = irq_nr >> 5; - -	ppc_cached_irq_mask[word] |= (1 << (31-bit)); -	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); +	mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); +	out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);  }  static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)  { -	if (flow_type & IRQ_TYPE_EDGE_FALLING) { -		irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); +	/* only external IRQ senses are programmable */ +	if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) {  		unsigned int siel = in_be32(&siu_reg->sc_siel); - -		/* only external IRQ senses are programmable */ -		if ((hw & 1) == 0) { -			siel |= (0x80000000 >> hw); -			out_be32(&siu_reg->sc_siel, siel); -			__irq_set_handler_locked(d->irq, handle_edge_irq); -		} +		siel |= mpc8xx_irqd_to_bit(d); +		out_be32(&siu_reg->sc_siel, siel); +		__irq_set_handler_locked(d->irq, handle_edge_irq);  	}  	return 0;  } @@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,  		IRQ_TYPE_EDGE_FALLING,  	}; +	if (intspec[0] > 0x1f) +		return 0; +  	*out_hwirq = intspec[0];  	if (intsize > 1 && intspec[1] < 4)  		*out_flags = map_pic_senses[intspec[1]]; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9ac71ebd2c4..395af134774 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq)  }  /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src)  { -	unsigned int src = virq_to_hw(irq); -  	return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);  }  /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src)  { -	unsigned int src = virq_to_hw(irq); -  	return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);  } @@ -876,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)  	if (src >= mpic->num_sources)  		return -EINVAL; +	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); + +	/* We don't support "none" type */  	if (flow_type == IRQ_TYPE_NONE) -		if (mpic->senses && src < mpic->senses_count) -			flow_type = mpic->senses[src]; -	if (flow_type == IRQ_TYPE_NONE) -		flow_type = IRQ_TYPE_LEVEL_LOW; +		flow_type = IRQ_TYPE_DEFAULT; + +	/* Default: read HW settings */ +	if (flow_type == IRQ_TYPE_DEFAULT) { +		switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) | +			       MPIC_INFO(VECPRI_SENSE_MASK))) { +			case MPIC_INFO(VECPRI_SENSE_EDGE) | +			     MPIC_INFO(VECPRI_POLARITY_POSITIVE): +				flow_type = IRQ_TYPE_EDGE_RISING; +				break; +			case MPIC_INFO(VECPRI_SENSE_EDGE) | +			     MPIC_INFO(VECPRI_POLARITY_NEGATIVE): +				flow_type = IRQ_TYPE_EDGE_FALLING; +				break; +			case MPIC_INFO(VECPRI_SENSE_LEVEL) | +			     MPIC_INFO(VECPRI_POLARITY_POSITIVE): +				flow_type = IRQ_TYPE_LEVEL_HIGH; +				break; +			case MPIC_INFO(VECPRI_SENSE_LEVEL) | +			     MPIC_INFO(VECPRI_POLARITY_NEGATIVE): +				flow_type = IRQ_TYPE_LEVEL_LOW; +				break; +		} +	} +	/* Apply to irq desc */  	irqd_set_trigger_type(d, flow_type); +	/* Apply to HW */  	if (mpic_is_ht_interrupt(mpic, src))  		vecpri = MPIC_VECPRI_POLARITY_POSITIVE |  			MPIC_VECPRI_SENSE_EDGE;  	else  		vecpri = mpic_type_to_vecpri(mpic, flow_type); -	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));  	vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |  			MPIC_INFO(VECPRI_SENSE_MASK));  	vnew |= vecpri; @@ -1026,7 +1046,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,  	irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);  	/* Set default irq type */ -	irq_set_irq_type(virq, IRQ_TYPE_NONE); +	irq_set_irq_type(virq, IRQ_TYPE_DEFAULT);  	/* If the MPIC was reset, then all vectors have already been  	 * initialized.  Otherwise, a per source lazy initialization @@ -1417,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,  		mpic->num_sources = isu_first + mpic->isu_size;  } -void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count) -{ -	mpic->senses = senses; -	mpic->senses_count = count; -} -  void __init mpic_init(struct mpic *mpic)  {  	int i, cpu; @@ -1555,12 +1569,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)  		return;  	raw_spin_lock_irqsave(&mpic_lock, flags); -	if (mpic_is_ipi(mpic, irq)) { +	if (mpic_is_ipi(mpic, src)) {  		reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &  			~MPIC_VECPRI_PRIORITY_MASK;  		mpic_ipi_write(src - mpic->ipi_vecs[0],  			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); -	} else if (mpic_is_tm(mpic, irq)) { +	} else if (mpic_is_tm(mpic, src)) {  		reg = mpic_tm_read(src - mpic->timer_vecs[0]) &  			~MPIC_VECPRI_PRIORITY_MASK;  		mpic_tm_write(src - mpic->timer_vecs[0], diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 6e7fa386e76..483d8fa72e8 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -27,6 +27,7 @@  static struct mpic_msgr **mpic_msgrs;  static unsigned int mpic_msgr_count; +static DEFINE_RAW_SPINLOCK(msgrs_lock);  static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value)  { @@ -56,12 +57,11 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num)  	if (reg_num >= mpic_msgr_count)  		return ERR_PTR(-ENODEV); -	raw_spin_lock_irqsave(&msgr->lock, flags); -	if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) { -		msgr = mpic_msgrs[reg_num]; +	raw_spin_lock_irqsave(&msgrs_lock, flags); +	msgr = mpic_msgrs[reg_num]; +	if (msgr->in_use == MSGR_FREE)  		msgr->in_use = MSGR_INUSE; -	} -	raw_spin_unlock_irqrestore(&msgr->lock, flags); +	raw_spin_unlock_irqrestore(&msgrs_lock, flags);  	return msgr;  } @@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev)  		reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i;  		msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE; -		msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET; +		msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET);  		msgr->in_use = MSGR_FREE;  		msgr->num = i;  		raw_spin_lock_init(&msgr->lock); diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c index 49a3ece1c6b..702256a1ca1 100644 --- a/arch/powerpc/sysdev/scom.c +++ b/arch/powerpc/sysdev/scom.c @@ -22,6 +22,7 @@  #include <linux/debugfs.h>  #include <linux/slab.h>  #include <linux/export.h> +#include <asm/debug.h>  #include <asm/prom.h>  #include <asm/scom.h> diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index ea5e204e345..cd1d18db92c 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void)  {  	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();  	unsigned int irq, virq; +	struct irq_desc *desc;  	/* If we used to be the default server, move to the new "boot_cpuid" */  	if (hw_cpu == xics_default_server) @@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void)  	/* Allow IPIs again... */  	icp_ops->set_priority(DEFAULT_PRIORITY); -	for_each_irq(virq) { -		struct irq_desc *desc; +	for_each_irq_desc(virq, desc) {  		struct irq_chip *chip;  		long server;  		unsigned long flags; @@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void)  		/* We can't set affinity on ISA interrupts */  		if (virq < NUM_ISA_INTERRUPTS)  			continue; -		desc = irq_to_desc(virq);  		/* We only need to migrate enabled IRQS */ -		if (!desc || !desc->action) +		if (!desc->action)  			continue;  		if (desc->irq_data.domain != xics_host)  			continue; diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h index 37f2f4a5523..f4c1c20bcdf 100644 --- a/arch/sh/include/asm/atomic.h +++ b/arch/sh/include/asm/atomic.h @@ -11,7 +11,7 @@  #include <linux/types.h>  #include <asm/cmpxchg.h> -#define ATOMIC_INIT(i)	( (atomic_t) { (i) } ) +#define ATOMIC_INIT(i)	{ (i) }  #define atomic_read(v)		(*(volatile int *)&(v)->counter)  #define atomic_set(v,i)		((v)->counter = (i)) diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 324eef93c90..e99b104d967 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -86,7 +86,7 @@ static noinline int vmalloc_fault(unsigned long address)  	pte_t *pte_k;  	/* Make sure we are in vmalloc/module/P3 area: */ -	if (!(address >= VMALLOC_START && address < P3_ADDR_MAX)) +	if (!(address >= P3SEG && address < P3_ADDR_MAX))  		return -1;  	/* diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 1210fde1874..160cac9c403 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -23,6 +23,7 @@  #include <linux/pm.h>  #include <linux/delay.h>  #include <linux/gfp.h> +#include <linux/cpu.h>  #include <asm/cacheflush.h>  #include <asm/tlbflush.h> @@ -78,6 +79,8 @@ void __cpuinit leon_callin(void)  	local_flush_tlb_all();  	leon_configure_cache_smp(); +	notify_cpu_starting(cpuid); +  	/* Get our local ticker going. */  	smp_setup_percpu_timer(); diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 232df994953..3ee51f189a5 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -566,15 +566,10 @@ out:  SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len)  { -	long ret; -  	if (invalid_64bit_range(addr, len))  		return -EINVAL; -	down_write(¤t->mm->mmap_sem); -	ret = do_munmap(current->mm, addr, len); -	up_write(¤t->mm->mmap_sem); -	return ret; +	return vm_munmap(addr, len);  }  extern unsigned long do_mremap(unsigned long addr, diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h index 5d5a635530b..32e6cbe8dff 100644 --- a/arch/tile/include/asm/pci.h +++ b/arch/tile/include/asm/pci.h @@ -47,8 +47,8 @@ struct pci_controller {   */  #define PCI_DMA_BUS_IS_PHYS     1 -int __devinit tile_pci_init(void); -int __devinit pcibios_init(void); +int __init tile_pci_init(void); +int __init pcibios_init(void);  static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index a1bb59eecc1..b56d12bf590 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -141,7 +141,7 @@ static int __devinit tile_init_irqs(int controller_id,   *   * Returns the number of controllers discovered.   */ -int __devinit tile_pci_init(void) +int __init tile_pci_init(void)  {  	int i; @@ -287,7 +287,7 @@ static void __devinit fixup_read_and_payload_sizes(void)   * The controllers have been set up by the time we get here, by a call to   * tile_pci_init.   */ -int __devinit pcibios_init(void) +int __init pcibios_init(void)  {  	int i; diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c index 9efbc1391b3..89529c9f060 100644 --- a/arch/tile/kernel/single_step.c +++ b/arch/tile/kernel/single_step.c @@ -346,12 +346,10 @@ void single_step_once(struct pt_regs *regs)  		}  		/* allocate a cache line of writable, executable memory */ -		down_write(¤t->mm->mmap_sem); -		buffer = (void __user *) do_mmap(NULL, 0, 64, +		buffer = (void __user *) vm_mmap(NULL, 0, 64,  					  PROT_EXEC | PROT_READ | PROT_WRITE,  					  MAP_PRIVATE | MAP_ANONYMOUS,  					  0); -		up_write(¤t->mm->mmap_sem);  		if (IS_ERR((void __force *)buffer)) {  			kfree(state); diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index a0559930a18..c85e3ac99bb 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -33,6 +33,9 @@  	__HEAD  ENTRY(startup_32)  #ifdef CONFIG_EFI_STUB +	jmp	preferred_addr + +	.balign	0x10  	/*  	 * We don't need the return address, so set up the stack so  	 * efi_main() can find its arugments. @@ -41,12 +44,17 @@ ENTRY(startup_32)  	call	efi_main  	cmpl	$0, %eax -	je	preferred_addr  	movl	%eax, %esi -	call	1f +	jne	2f  1: +	/* EFI init failed, so hang. */ +	hlt +	jmp	1b +2: +	call	3f +3:  	popl	%eax -	subl	$1b, %eax +	subl	$3b, %eax  	subl	BP_pref_address(%esi), %eax  	add	BP_code32_start(%esi), %eax  	leal	preferred_addr(%eax), %eax diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 558d76ce23b..87e03a13d8e 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -200,18 +200,28 @@ ENTRY(startup_64)  	 * entire text+data+bss and hopefully all of memory.  	 */  #ifdef CONFIG_EFI_STUB -	pushq	%rsi +	/* +	 * The entry point for the PE/COFF executable is 0x210, so only +	 * legacy boot loaders will execute this jmp. +	 */ +	jmp	preferred_addr + +	.org 0x210  	mov	%rcx, %rdi  	mov	%rdx, %rsi  	call	efi_main -	popq	%rsi -	cmpq	$0,%rax -	je	preferred_addr  	movq	%rax,%rsi -	call	1f +	cmpq	$0,%rax +	jne	2f  1: +	/* EFI init failed, so hang. */ +	hlt +	jmp	1b +2: +	call	3f +3:  	popq	%rax -	subq	$1b, %rax +	subq	$3b, %rax  	subq	BP_pref_address(%rsi), %rax  	add	BP_code32_start(%esi), %eax  	leaq	preferred_addr(%rax), %rax diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index ed549767a23..24443a33208 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -205,8 +205,13 @@ int main(int argc, char ** argv)  	put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);  #ifdef CONFIG_X86_32 -	/* Address of entry point */ -	put_unaligned_le32(i, &buf[pe_header + 0x28]); +	/* +	 * Address of entry point. +	 * +	 * The EFI stub entry point is +16 bytes from the start of +	 * the .text section. +	 */ +	put_unaligned_le32(i + 16, &buf[pe_header + 0x28]);  	/* .text size */  	put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]); @@ -217,9 +222,11 @@ int main(int argc, char ** argv)  	/*  	 * Address of entry point. startup_32 is at the beginning and  	 * the 64-bit entry point (startup_64) is always 512 bytes -	 * after. +	 * after. The EFI stub entry point is 16 bytes after that, as +	 * the first instruction allows legacy loaders to jump over +	 * the EFI stub initialisation  	 */ -	put_unaligned_le32(i + 512, &buf[pe_header + 0x28]); +	put_unaligned_le32(i + 528, &buf[pe_header + 0x28]);  	/* .text size */  	put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]); diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index d511d951a05..4824fb45560 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end)  	end = PAGE_ALIGN(end);  	if (end <= start)  		return; -	down_write(¤t->mm->mmap_sem); -	do_brk(start, end - start); -	up_write(¤t->mm->mmap_sem); +	vm_brk(start, end - start);  }  #ifdef CORE_DUMP @@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)  		pos = 32;  		map_size = ex.a_text+ex.a_data; -		down_write(¤t->mm->mmap_sem); -		error = do_brk(text_addr & PAGE_MASK, map_size); -		up_write(¤t->mm->mmap_sem); +		error = vm_brk(text_addr & PAGE_MASK, map_size);  		if (error != (text_addr & PAGE_MASK)) {  			send_sig(SIGKILL, current, 0); @@ -373,9 +369,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)  		if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {  			loff_t pos = fd_offset; -			down_write(¤t->mm->mmap_sem); -			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); -			up_write(¤t->mm->mmap_sem); +			vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);  			bprm->file->f_op->read(bprm->file,  					(char __user *)N_TXTADDR(ex),  					ex.a_text+ex.a_data, &pos); @@ -385,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)  			goto beyond_if;  		} -		down_write(¤t->mm->mmap_sem); -		error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, +		error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,  				PROT_READ | PROT_EXEC,  				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |  				MAP_EXECUTABLE | MAP_32BIT,  				fd_offset); -		up_write(¤t->mm->mmap_sem);  		if (error != N_TXTADDR(ex)) {  			send_sig(SIGKILL, current, 0);  			return error;  		} -		down_write(¤t->mm->mmap_sem); -		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, +		error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,  				PROT_READ | PROT_WRITE | PROT_EXEC,  				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |  				MAP_EXECUTABLE | MAP_32BIT,  				fd_offset + ex.a_text); -		up_write(¤t->mm->mmap_sem);  		if (error != N_DATADDR(ex)) {  			send_sig(SIGKILL, current, 0);  			return error; @@ -476,9 +466,7 @@ static int load_aout_library(struct file *file)  			error_time = jiffies;  		}  #endif -		down_write(¤t->mm->mmap_sem); -		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); -		up_write(¤t->mm->mmap_sem); +		vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);  		file->f_op->read(file, (char __user *)start_addr,  			ex.a_text + ex.a_data, &pos); @@ -490,12 +478,10 @@ static int load_aout_library(struct file *file)  		goto out;  	}  	/* Now use mmap to map the library into memory. */ -	down_write(¤t->mm->mmap_sem); -	error = do_mmap(file, start_addr, ex.a_text + ex.a_data, +	error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,  			PROT_READ | PROT_WRITE | PROT_EXEC,  			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,  			N_TXTOFF(ex)); -	up_write(¤t->mm->mmap_sem);  	retval = error;  	if (error != start_addr)  		goto out; @@ -503,9 +489,7 @@ static int load_aout_library(struct file *file)  	len = PAGE_ALIGN(ex.a_text + ex.a_data);  	bss = ex.a_text + ex.a_data + ex.a_bss;  	if (bss > len) { -		down_write(¤t->mm->mmap_sem); -		error = do_brk(start_addr + len, bss - len); -		up_write(¤t->mm->mmap_sem); +		error = vm_brk(start_addr + len, bss - len);  		retval = error;  		if (error != start_addr + len)  			goto out; diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h index 3427b7798db..7ef7c3020e5 100644 --- a/arch/x86/include/asm/posix_types.h +++ b/arch/x86/include/asm/posix_types.h @@ -7,9 +7,9 @@  #else  # ifdef __i386__  #  include "posix_types_32.h" -# elif defined(__LP64__) -#  include "posix_types_64.h" -# else +# elif defined(__ILP32__)  #  include "posix_types_x32.h" +# else +#  include "posix_types_64.h"  # endif  #endif diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h index 4a085383af2..5ca71c065ee 100644 --- a/arch/x86/include/asm/sigcontext.h +++ b/arch/x86/include/asm/sigcontext.h @@ -257,7 +257,7 @@ struct sigcontext {  	__u64 oldmask;  	__u64 cr2;  	struct _fpstate __user *fpstate;	/* zero when no FPU context */ -#ifndef __LP64__ +#ifdef __ILP32__  	__u32 __fpstate_pad;  #endif  	__u64 reserved1[8]; diff --git a/arch/x86/include/asm/siginfo.h b/arch/x86/include/asm/siginfo.h index fc1aa553564..34c47b3341c 100644 --- a/arch/x86/include/asm/siginfo.h +++ b/arch/x86/include/asm/siginfo.h @@ -2,7 +2,13 @@  #define _ASM_X86_SIGINFO_H  #ifdef __x86_64__ -# define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int)) +# ifdef __ILP32__ /* x32 */ +typedef long long __kernel_si_clock_t __attribute__((aligned(4))); +#  define __ARCH_SI_CLOCK_T		__kernel_si_clock_t +#  define __ARCH_SI_ATTRIBUTES		__attribute__((aligned(8))) +# else /* x86-64 */ +#  define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int)) +# endif  #endif  #include <asm-generic/siginfo.h> diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h index 37cdc9d99bb..4437001d8e3 100644 --- a/arch/x86/include/asm/unistd.h +++ b/arch/x86/include/asm/unistd.h @@ -63,10 +63,10 @@  #else  # ifdef __i386__  #  include <asm/unistd_32.h> -# elif defined(__LP64__) -#  include <asm/unistd_64.h> -# else +# elif defined(__ILP32__)  #  include <asm/unistd_x32.h> +# else +#  include <asm/unistd_64.h>  # endif  #endif diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index baaca8defec..764b66a4cf8 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -195,6 +195,5 @@ extern struct x86_msi_ops x86_msi;  extern void x86_init_noop(void);  extern void x86_init_uint_noop(unsigned int unused); -extern void x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node);  #endif diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 103b6ab368d..146a49c763a 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -24,6 +24,10 @@ unsigned long acpi_realmode_flags;  static char temp_stack[4096];  #endif +asmlinkage void acpi_enter_s3(void) +{ +	acpi_enter_sleep_state(3, wake_sleep_flags); +}  /**   * acpi_suspend_lowlevel - save kernel state   * diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index 416d4be13fe..d68677a2a01 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h @@ -3,12 +3,16 @@   */  #include <asm/trampoline.h> +#include <linux/linkage.h>  extern unsigned long saved_video_mode;  extern long saved_magic;  extern int wakeup_pmode_return; +extern u8 wake_sleep_flags; +extern asmlinkage void acpi_enter_s3(void); +  extern unsigned long acpi_copy_wakeup_routine(unsigned long);  extern void wakeup_long64(void); diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S index 13ab720573e..72610839f03 100644 --- a/arch/x86/kernel/acpi/wakeup_32.S +++ b/arch/x86/kernel/acpi/wakeup_32.S @@ -74,9 +74,7 @@ restore_registers:  ENTRY(do_suspend_lowlevel)  	call	save_processor_state  	call	save_registers -	pushl	$3 -	call	acpi_enter_sleep_state -	addl	$4, %esp +	call	acpi_enter_s3  #	In case of S3 failure, we'll emerge here.  Jump  # 	to ret_point to recover diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 8ea5164cbd0..014d1d28c39 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -71,9 +71,7 @@ ENTRY(do_suspend_lowlevel)  	movq	%rsi, saved_rsi  	addq	$8, %rsp -	movl	$3, %edi -	xorl	%eax, %eax -	call	acpi_enter_sleep_state +	call	acpi_enter_s3  	/* in case something went wrong, restore the machine status and go on */  	jmp	resume_point diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 11544d8f1e9..edc24480469 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1637,9 +1637,11 @@ static int __init apic_verify(void)  	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;  	/* The BIOS may have set up the APIC at some other address */ -	rdmsr(MSR_IA32_APICBASE, l, h); -	if (l & MSR_IA32_APICBASE_ENABLE) -		mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; +	if (boot_cpu_data.x86 >= 6) { +		rdmsr(MSR_IA32_APICBASE, l, h); +		if (l & MSR_IA32_APICBASE_ENABLE) +			mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; +	}  	pr_info("Found and enabled local APIC!\n");  	return 0; @@ -1657,13 +1659,15 @@ int __init apic_force_enable(unsigned long addr)  	 * MSR. This can only be done in software for Intel P6 or later  	 * and AMD K7 (Model > 1) or later.  	 */ -	rdmsr(MSR_IA32_APICBASE, l, h); -	if (!(l & MSR_IA32_APICBASE_ENABLE)) { -		pr_info("Local APIC disabled by BIOS -- reenabling.\n"); -		l &= ~MSR_IA32_APICBASE_BASE; -		l |= MSR_IA32_APICBASE_ENABLE | addr; -		wrmsr(MSR_IA32_APICBASE, l, h); -		enabled_via_apicbase = 1; +	if (boot_cpu_data.x86 >= 6) { +		rdmsr(MSR_IA32_APICBASE, l, h); +		if (!(l & MSR_IA32_APICBASE_ENABLE)) { +			pr_info("Local APIC disabled by BIOS -- reenabling.\n"); +			l &= ~MSR_IA32_APICBASE_BASE; +			l |= MSR_IA32_APICBASE_ENABLE | addr; +			wrmsr(MSR_IA32_APICBASE, l, h); +			enabled_via_apicbase = 1; +		}  	}  	return apic_verify();  } @@ -2209,10 +2213,12 @@ static void lapic_resume(void)  		 * FIXME! This will be wrong if we ever support suspend on  		 * SMP! We'll need to do this as part of the CPU restore!  		 */ -		rdmsr(MSR_IA32_APICBASE, l, h); -		l &= ~MSR_IA32_APICBASE_BASE; -		l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; -		wrmsr(MSR_IA32_APICBASE, l, h); +		if (boot_cpu_data.x86 >= 6) { +			rdmsr(MSR_IA32_APICBASE, l, h); +			l &= ~MSR_IA32_APICBASE_BASE; +			l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; +			wrmsr(MSR_IA32_APICBASE, l, h); +		}  	}  	maxlvt = lapic_get_maxlvt(); diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 899803e0321..23e75422e01 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -207,8 +207,11 @@ static void __init map_csrs(void)  static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)  { -	c->phys_proc_id = node; -	per_cpu(cpu_llc_id, smp_processor_id()) = node; + +	if (c->phys_proc_id != node) { +		c->phys_proc_id = node; +		per_cpu(cpu_llc_id, smp_processor_id()) = node; +	}  }  static int __init numachip_system_init(void) diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 8a778db45e3..991e315f422 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -24,6 +24,12 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)  {  	if (x2apic_phys)  		return x2apic_enabled(); +	else if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) && +		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) && +		x2apic_enabled()) { +		printk(KERN_DEBUG "System requires x2apic physical mode\n"); +		return 1; +	}  	else  		return 0;  } diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 0a44b90602b..1c67ca100e4 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -26,7 +26,8 @@   *	contact AMD for precise details and a CPU swap.   *   *	See	http://www.multimania.com/poulot/k6bug.html - *		http://www.amd.com/K6/k6docs/revgd.html + *	and	section 2.6.2 of "AMD-K6 Processor Revision Guide - Model 6" + *		(Publication # 21266  Issue Date: August 1998)   *   *	The following test is erm.. interesting. AMD neglected to up   *	the chip setting when fixing the bug but they also tweaked some @@ -94,7 +95,6 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)  				"system stability may be impaired when more than 32 MB are used.\n");  		else  			printk(KERN_CONT "probably OK (after B9730xxxx).\n"); -		printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n");  	}  	/* K6 with old style WHCR */ @@ -353,10 +353,11 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)  		node = per_cpu(cpu_llc_id, cpu);  	/* -	 * If core numbers are inconsistent, it's likely a multi-fabric platform, -	 * so invoke platform-specific handler +	 * On multi-fabric platform (e.g. Numascale NumaChip) a +	 * platform-specific handler needs to be called to fixup some +	 * IDs of the CPU.  	 */ -	if (c->phys_proc_id != node) +	if (x86_cpuinit.fixup_cpu_id)  		x86_cpuinit.fixup_cpu_id(c, node);  	if (!node_online(node)) { diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 67e258362a3..cf79302198a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1163,15 +1163,6 @@ static void dbg_restore_debug_regs(void)  #endif /* ! CONFIG_KGDB */  /* - * Prints an error where the NUMA and configured core-number mismatch and the - * platform didn't override this to fix it up - */ -void __cpuinit x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node) -{ -	pr_err("NUMA core number %d differs from configured core number %d\n", node, c->phys_proc_id); -} - -/*   * cpu_init() initializes state that is per-CPU. Some data is already   * initialized (naturally) in the bootstrap process, such as the GDT   * and IDT. We reload them nevertheless, this function acts as a diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 73d08ed98a6..b8f3653dddb 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -433,14 +433,14 @@ int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot,  	/*  check if @slot is already used or the index is already disabled */  	ret = amd_get_l3_disable_slot(nb, slot);  	if (ret >= 0) -		return -EINVAL; +		return -EEXIST;  	if (index > nb->l3_cache.indices)  		return -EINVAL;  	/* check whether the other slot has disabled the same index already */  	if (index == amd_get_l3_disable_slot(nb, !slot)) -		return -EINVAL; +		return -EEXIST;  	amd_l3_disable_index(nb, cpu, slot, index); @@ -468,8 +468,8 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,  	err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val);  	if (err) {  		if (err == -EEXIST) -			printk(KERN_WARNING "L3 disable slot %d in use!\n", -					    slot); +			pr_warning("L3 slot %d in use/index already disabled!\n", +				   slot);  		return err;  	}  	return count; diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 7734bcbb5a3..2d6e6498c17 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -235,6 +235,7 @@ int init_fpu(struct task_struct *tsk)  	if (tsk_used_math(tsk)) {  		if (HAVE_HWFP && tsk == current)  			unlazy_fpu(tsk); +		tsk->thread.fpu.last_cpu = ~0;  		return 0;  	} diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 73465aab28f..8a2ce8fd41c 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -82,11 +82,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)  {  	struct cpuinfo_x86 *c = &cpu_data(cpu); -	if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { -		pr_warning("CPU%d: family %d not supported\n", cpu, c->x86); -		return -1; -	} -  	csig->rev = c->microcode;  	pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); @@ -380,6 +375,13 @@ static struct microcode_ops microcode_amd_ops = {  struct microcode_ops * __init init_amd_microcode(void)  { +	struct cpuinfo_x86 *c = &cpu_data(0); + +	if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { +		pr_warning("AMD CPU family 0x%x not supported\n", c->x86); +		return NULL; +	} +  	patch = (void *)get_zeroed_page(GFP_KERNEL);  	if (!patch)  		return NULL; diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 87a0f868830..c9bda6d6035 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -419,10 +419,8 @@ static int mc_device_add(struct device *dev, struct subsys_interface *sif)  	if (err)  		return err; -	if (microcode_init_cpu(cpu) == UCODE_ERROR) { -		sysfs_remove_group(&dev->kobj, &mc_attr_group); +	if (microcode_init_cpu(cpu) == UCODE_ERROR)  		return -EINVAL; -	}  	return err;  } @@ -528,11 +526,11 @@ static int __init microcode_init(void)  		microcode_ops = init_intel_microcode();  	else if (c->x86_vendor == X86_VENDOR_AMD)  		microcode_ops = init_amd_microcode(); - -	if (!microcode_ops) { +	else  		pr_err("no support for this CPU vendor\n"); + +	if (!microcode_ops)  		return -ENODEV; -	}  	microcode_pdev = platform_device_register_simple("microcode", -1,  							 NULL, 0); diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index e9f265fd79a..9cf71d0b2d3 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -93,7 +93,6 @@ struct x86_init_ops x86_init __initdata = {  struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {  	.early_percpu_clock_init	= x86_init_noop,  	.setup_percpu_clockev		= setup_secondary_APIC_clock, -	.fixup_cpu_id			= x86_default_fixup_cpu_id,  };  static void default_nmi_init(void) { }; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4044ce0bf7c..91a5e989abc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,  		if (npages && !old.rmap) {  			unsigned long userspace_addr; -			down_write(¤t->mm->mmap_sem); -			userspace_addr = do_mmap(NULL, 0, +			userspace_addr = vm_mmap(NULL, 0,  						 npages * PAGE_SIZE,  						 PROT_READ | PROT_WRITE,  						 map_flags,  						 0); -			up_write(¤t->mm->mmap_sem);  			if (IS_ERR((void *)userspace_addr))  				return PTR_ERR((void *)userspace_addr); @@ -6366,10 +6364,8 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,  	if (!user_alloc && !old.user_alloc && old.rmap && !npages) {  		int ret; -		down_write(¤t->mm->mmap_sem); -		ret = do_munmap(current->mm, old.userspace_addr, +		ret = vm_munmap(old.userspace_addr,  				old.npages * PAGE_SIZE); -		up_write(¤t->mm->mmap_sem);  		if (ret < 0)  			printk(KERN_WARNING  			       "kvm_vm_ioctl_set_memory_region: " diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index e0a37233c0a..e31bcd8f2ee 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -805,7 +805,7 @@ void intel_scu_devices_create(void)  		} else  			i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);  	} -	intel_scu_notifier_post(SCU_AVAILABLE, 0L); +	intel_scu_notifier_post(SCU_AVAILABLE, NULL);  }  EXPORT_SYMBOL_GPL(intel_scu_devices_create); @@ -814,7 +814,7 @@ void intel_scu_devices_destroy(void)  {  	int i; -	intel_scu_notifier_post(SCU_DOWN, 0L); +	intel_scu_notifier_post(SCU_DOWN, NULL);  	for (i = 0; i < ipc_next_dev; i++)  		platform_device_del(ipc_devs[i]); diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 4f51bebac02..a8f8844b8d3 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -261,7 +261,8 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,  static bool __init xen_check_mwait(void)  { -#ifdef CONFIG_ACPI +#if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ +	!defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)  	struct xen_platform_op op = {  		.cmd			= XENPF_set_processor_pminfo,  		.u.set_pminfo.id	= -1, @@ -349,7 +350,6 @@ static void __init xen_init_cpuid_mask(void)  	/* Xen will set CR4.OSXSAVE if supported and not disabled by force */  	if ((cx & xsave_mask) != xsave_mask)  		cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ -  	if (xen_check_mwait())  		cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32));  } diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 5fac6919b95..0503c0c493a 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -178,6 +178,7 @@ static void __init xen_fill_possible_map(void)  static void __init xen_filter_cpu_maps(void)  {  	int i, rc; +	unsigned int subtract = 0;  	if (!xen_initial_domain())  		return; @@ -192,8 +193,22 @@ static void __init xen_filter_cpu_maps(void)  		} else {  			set_cpu_possible(i, false);  			set_cpu_present(i, false); +			subtract++;  		}  	} +#ifdef CONFIG_HOTPLUG_CPU +	/* This is akin to using 'nr_cpus' on the Linux command line. +	 * Which is OK as when we use 'dom0_max_vcpus=X' we can only +	 * have up to X, while nr_cpu_ids is greater than X. This +	 * normally is not a problem, except when CPU hotplugging +	 * is involved and then there might be more than X CPUs +	 * in the guest - which will not work as there is no +	 * hypercall to expand the max number of VCPUs an already +	 * running guest has. So cap it up to X. */ +	if (subtract) +		nr_cpu_ids = nr_cpu_ids - subtract; +#endif +  }  static void __init xen_smp_prepare_boot_cpu(void) diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 79d7362ad6d..3e45aa00071 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -96,7 +96,7 @@ ENTRY(xen_restore_fl_direct)  	/* check for unmasked and pending */  	cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending -	jz 1f +	jnz 1f  2:	call check_events  1:  ENDPATCH(xen_restore_fl_direct) diff --git a/arch/xtensa/include/asm/hardirq.h b/arch/xtensa/include/asm/hardirq.h index 26664cef8f1..91695a13549 100644 --- a/arch/xtensa/include/asm/hardirq.h +++ b/arch/xtensa/include/asm/hardirq.h @@ -11,9 +11,6 @@  #ifndef _XTENSA_HARDIRQ_H  #define _XTENSA_HARDIRQ_H -void ack_bad_irq(unsigned int irq); -#define ack_bad_irq ack_bad_irq -  #include <asm-generic/hardirq.h>  #endif	/* _XTENSA_HARDIRQ_H */ diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index d04cd3a625f..4beb43c087d 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -14,6 +14,7 @@  #ifdef __KERNEL__  #include <asm/byteorder.h>  #include <asm/page.h> +#include <linux/bug.h>  #include <linux/kernel.h>  #include <linux/types.h> diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index b69b000349f..d78869a00b1 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -496,6 +496,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)  	signr = get_signal_to_deliver(&info, &ka, regs, NULL);  	if (signr > 0) { +		int ret;  		/* Are we from a system call? */ diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index 107f6f7be5e..dd30f40af9f 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len)  	index = sctx->count[0] & 0x7f;  	/* Update number of bytes */ -	if (!(sctx->count[0] += len)) +	if ((sctx->count[0] += len) < len)  		sctx->count[1]++;          part_len = 128 - index; diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index ab513a972c9..a716fede4f2 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -74,7 +74,8 @@ acpi_status acpi_reset(void)  	/* Check if the reset register is supported */ -	if (!reset_reg->address) { +	if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || +	    !reset_reg->address) {  		return_ACPI_STATUS(AE_NOT_EXIST);  	} diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index c1d61243593..a6c77e8b37b 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -23,7 +23,8 @@ void acpi_reboot(void)  	/* Is the reset register supported? The spec says we should be  	 * checking the bit width and bit offset, but Windows ignores  	 * these fields */ -	/* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */ +	if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) +		return;  	reset_value = acpi_gbl_FADT.reset_value; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 1d661b5c328..eb6fd233764 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -28,23 +28,33 @@  #include "internal.h"  #include "sleep.h" +u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS;  static unsigned int gts, bfs; -module_param(gts, uint, 0644); -module_param(bfs, uint, 0644); -MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); -MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); - -static u8 wake_sleep_flags(void) +static int set_param_wake_flag(const char *val, struct kernel_param *kp)  { -	u8 flags = ACPI_NO_OPTIONAL_METHODS; +	int ret = param_set_int(val, kp); -	if (gts) -		flags |= ACPI_EXECUTE_GTS; -	if (bfs) -		flags |= ACPI_EXECUTE_BFS; +	if (ret) +		return ret; -	return flags; +	if (kp->arg == (const char *)>s) { +		if (gts) +			wake_sleep_flags |= ACPI_EXECUTE_GTS; +		else +			wake_sleep_flags &= ~ACPI_EXECUTE_GTS; +	} +	if (kp->arg == (const char *)&bfs) { +		if (bfs) +			wake_sleep_flags |= ACPI_EXECUTE_BFS; +		else +			wake_sleep_flags &= ~ACPI_EXECUTE_BFS; +	} +	return ret;  } +module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); +module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); +MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); +MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);  static u8 sleep_states[ACPI_S_STATE_COUNT]; @@ -263,7 +273,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)  {  	acpi_status status = AE_OK;  	u32 acpi_state = acpi_target_sleep_state; -	u8 flags = wake_sleep_flags();  	int error;  	ACPI_FLUSH_CPU_CACHE(); @@ -271,7 +280,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)  	switch (acpi_state) {  	case ACPI_STATE_S1:  		barrier(); -		status = acpi_enter_sleep_state(acpi_state, flags); +		status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags);  		break;  	case ACPI_STATE_S3: @@ -286,7 +295,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)  	acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);  	/* Reprogram control registers and execute _BFS */ -	acpi_leave_sleep_state_prep(acpi_state, flags); +	acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags);  	/* ACPI 3.0 specs (P62) says that it's the responsibility  	 * of the OSPM to clear the status bit [ implying that the @@ -550,30 +559,27 @@ static int acpi_hibernation_begin(void)  static int acpi_hibernation_enter(void)  { -	u8 flags = wake_sleep_flags();  	acpi_status status = AE_OK;  	ACPI_FLUSH_CPU_CACHE();  	/* This shouldn't return.  If it returns, we have a problem */ -	status = acpi_enter_sleep_state(ACPI_STATE_S4, flags); +	status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags);  	/* Reprogram control registers and execute _BFS */ -	acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); +	acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);  	return ACPI_SUCCESS(status) ? 0 : -EFAULT;  }  static void acpi_hibernation_leave(void)  { -	u8 flags = wake_sleep_flags(); -  	/*  	 * If ACPI is not enabled by the BIOS and the boot kernel, we need to  	 * enable it here.  	 */  	acpi_enable();  	/* Reprogram control registers and execute _BFS */ -	acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); +	acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags);  	/* Check the hardware signature */  	if (facs && s4_hardware_signature != facs->hardware_signature) {  		printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " @@ -828,12 +834,10 @@ static void acpi_power_off_prepare(void)  static void acpi_power_off(void)  { -	u8 flags = wake_sleep_flags(); -  	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */  	printk(KERN_DEBUG "%s called\n", __func__);  	local_irq_disable(); -	acpi_enter_sleep_state(ACPI_STATE_S5, flags); +	acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags);  }  /* diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index cdcf75c0954..3e2a6002aae 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -404,16 +404,19 @@ int bcma_sprom_get(struct bcma_bus *bus)  		return -EOPNOTSUPP;  	if (!bcma_sprom_ext_available(bus)) { +		bool sprom_onchip; +  		/*  		 * External SPROM takes precedence so check  		 * on-chip OTP only when no external SPROM  		 * is present.  		 */ -		if (bcma_sprom_onchip_available(bus)) { +		sprom_onchip = bcma_sprom_onchip_available(bus); +		if (sprom_onchip) {  			/* determine offset */  			offset = bcma_sprom_onchip_offset(bus);  		} -		if (!offset) { +		if (!offset || !sprom_onchip) {  			/*  			 * Maybe there is no SPROM on the device?  			 * Now we ask the arch code if there is some sprom diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 89860f34a7e..4f66171c668 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info  				    "discard-secure", "%d",  				    blkif->vbd.discard_secure);  		if (err) { -			dev_warn(dev-dev, "writing discard-secure (%d)", err); +			dev_warn(&dev->dev, "writing discard-secure (%d)", err);  			return;  		}  	} diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 0053d7ebb5c..8f3f74ce8c7 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -18,6 +18,7 @@  #include <linux/interrupt.h>  #include <linux/spinlock.h>  #include <linux/gfp.h> +#include <linux/module.h>  #include <crypto/ctr.h>  #include <crypto/des.h> diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc641c79652..921039e56f8 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -124,6 +124,9 @@ struct talitos_private {  	void __iomem *reg;  	int irq[2]; +	/* SEC global registers lock  */ +	spinlock_t reg_lock ____cacheline_aligned; +  	/* SEC version geometry (from device tree node) */  	unsigned int num_channels;  	unsigned int chfifo_len; @@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data)			\  {									\  	struct device *dev = (struct device *)data;			\  	struct talitos_private *priv = dev_get_drvdata(dev);		\ +	unsigned long flags;						\  									\  	if (ch_done_mask & 1)						\  		flush_channel(dev, 0, 0, 0);				\ @@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data)			\  out:									\  	/* At this point, all completed channels have been processed */	\  	/* Unmask done interrupts for channels completed later on. */	\ +	spin_lock_irqsave(&priv->reg_lock, flags);			\  	setbits32(priv->reg + TALITOS_IMR, ch_done_mask);		\  	setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);	\ +	spin_unlock_irqrestore(&priv->reg_lock, flags);			\  }  DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)  DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) @@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data)	       \  	struct device *dev = data;					       \  	struct talitos_private *priv = dev_get_drvdata(dev);		       \  	u32 isr, isr_lo;						       \ +	unsigned long flags;						       \  									       \ +	spin_lock_irqsave(&priv->reg_lock, flags);			       \  	isr = in_be32(priv->reg + TALITOS_ISR);				       \  	isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);			       \  	/* Acknowledge interrupt */					       \  	out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \  	out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);			       \  									       \ -	if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo))    \ -		talitos_error(dev, isr, isr_lo);			       \ -	else								       \ +	if (unlikely(isr & ch_err_mask || isr_lo)) {			       \ +		spin_unlock_irqrestore(&priv->reg_lock, flags);		       \ +		talitos_error(dev, isr & ch_err_mask, isr_lo);		       \ +	}								       \ +	else {								       \  		if (likely(isr & ch_done_mask)) {			       \  			/* mask further done interrupts. */		       \  			clrbits32(priv->reg + TALITOS_IMR, ch_done_mask);      \  			/* done_task will unmask done interrupts at exit */    \  			tasklet_schedule(&priv->done_task[tlet]);	       \  		}							       \ +		spin_unlock_irqrestore(&priv->reg_lock, flags);		       \ +	}								       \  									       \  	return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED :  \  								IRQ_NONE;      \ @@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev)  	priv->ofdev = ofdev; +	spin_lock_init(&priv->reg_lock); +  	err = talitos_probe_irq(ofdev);  	if (err)  		goto err_out; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index cf9da362d64..ef378b5b17e 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -91,11 +91,10 @@ config DW_DMAC  config AT_HDMAC  	tristate "Atmel AHB DMA support" -	depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 +	depends on ARCH_AT91  	select DMA_ENGINE  	help -	  Support the Atmel AHB DMA controller.  This can be integrated in -	  chips such as the Atmel AT91SAM9RL. +	  Support the Atmel AHB DMA controller.  config FSL_DMA  	tristate "Freescale Elo and Elo Plus DMA support" diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index c301a8ec31a..3d704abd791 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -1429,6 +1429,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,  			 * signal  			 */  			release_phy_channel(plchan); +			plchan->phychan_hold = 0;  		}  		/* Dequeue jobs and free LLIs */  		if (plchan->at) { diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 7aa58d20489..445fdf81169 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -221,10 +221,6 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)  	vdbg_dump_regs(atchan); -	/* clear any pending interrupt */ -	while (dma_readl(atdma, EBCISR)) -		cpu_relax(); -  	channel_writel(atchan, SADDR, 0);  	channel_writel(atchan, DADDR, 0);  	channel_writel(atchan, CTRLA, 0); diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index a45b5d2a598..bb787d8e152 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -571,11 +571,14 @@ static void imxdma_tasklet(unsigned long data)  	if (desc->desc.callback)  		desc->desc.callback(desc->desc.callback_param); -	dma_cookie_complete(&desc->desc); - -	/* If we are dealing with a cyclic descriptor keep it on ld_active */ +	/* If we are dealing with a cyclic descriptor keep it on ld_active +	 * and dont mark the descripor as complete. +	 * Only in non-cyclic cases it would be marked as complete +	 */  	if (imxdma_chan_is_doing_cyclic(imxdmac))  		goto out; +	else +		dma_cookie_complete(&desc->desc);  	/* Free 2D slot if it was an interleaved transfer */  	if (imxdmac->enabled_2d) { diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index c81ef7e10e0..655d4ce6ed0 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c @@ -201,10 +201,6 @@ static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)  static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)  { -	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(tx->chan); - -	mxs_dma_enable_chan(mxs_chan); -  	return dma_cookie_assign(tx);  } @@ -558,9 +554,9 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,  static void mxs_dma_issue_pending(struct dma_chan *chan)  { -	/* -	 * Nothing to do. We only have a single descriptor. -	 */ +	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); + +	mxs_dma_enable_chan(mxs_chan);  }  static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 282caf118be..2ee6e23930a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2225,12 +2225,9 @@ static inline void free_desc_list(struct list_head *list)  {  	struct dma_pl330_dmac *pdmac;  	struct dma_pl330_desc *desc; -	struct dma_pl330_chan *pch; +	struct dma_pl330_chan *pch = NULL;  	unsigned long flags; -	if (list_empty(list)) -		return; -  	/* Finish off the work list */  	list_for_each_entry(desc, list, node) {  		dma_async_tx_callback callback; @@ -2247,6 +2244,10 @@ static inline void free_desc_list(struct list_head *list)  		desc->pchan = NULL;  	} +	/* pch will be unset if list was empty */ +	if (!pch) +		return; +  	pdmac = pch->dmac;  	spin_lock_irqsave(&pdmac->pool_lock, flags); @@ -2257,12 +2258,9 @@ static inline void free_desc_list(struct list_head *list)  static inline void handle_cyclic_desc_list(struct list_head *list)  {  	struct dma_pl330_desc *desc; -	struct dma_pl330_chan *pch; +	struct dma_pl330_chan *pch = NULL;  	unsigned long flags; -	if (list_empty(list)) -		return; -  	list_for_each_entry(desc, list, node) {  		dma_async_tx_callback callback; @@ -2274,6 +2272,10 @@ static inline void handle_cyclic_desc_list(struct list_head *list)  			callback(desc->txd.callback_param);  	} +	/* pch will be unset if list was empty */ +	if (!pch) +		return; +  	spin_lock_irqsave(&pch->lock, flags);  	list_splice_tail_init(list, &pch->work_list);  	spin_unlock_irqrestore(&pch->lock, flags); @@ -2926,8 +2928,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)  	INIT_LIST_HEAD(&pd->channels);  	/* Initialize channel parameters */ -	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri, -			(u8)pi->pcfg.num_chan); +	if (pdat) +		num_chan = max_t(int, pdat->nr_valid_peri, pi->pcfg.num_chan); +	else +		num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan); +  	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);  	for (i = 0; i < num_chan; i++) { diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index bdd41d4bfa8..2ed1ac3513f 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -18,6 +18,7 @@  #include <linux/pm_runtime.h>  #include <linux/err.h>  #include <linux/amba/bus.h> +#include <linux/regulator/consumer.h>  #include <plat/ste_dma40.h> @@ -69,6 +70,22 @@ enum d40_command {  };  /* + * enum d40_events - The different Event Enables for the event lines. + * + * @D40_DEACTIVATE_EVENTLINE: De-activate Event line, stopping the logical chan. + * @D40_ACTIVATE_EVENTLINE: Activate the Event line, to start a logical chan. + * @D40_SUSPEND_REQ_EVENTLINE: Requesting for suspending a event line. + * @D40_ROUND_EVENTLINE: Status check for event line. + */ + +enum d40_events { +	D40_DEACTIVATE_EVENTLINE	= 0, +	D40_ACTIVATE_EVENTLINE		= 1, +	D40_SUSPEND_REQ_EVENTLINE	= 2, +	D40_ROUND_EVENTLINE		= 3 +}; + +/*   * These are the registers that has to be saved and later restored   * when the DMA hw is powered off.   * TODO: Add save/restore of D40_DREG_GCC on dma40 v3 or later, if that works. @@ -870,8 +887,8 @@ static void d40_save_restore_registers(struct d40_base *base, bool save)  }  #endif -static int d40_channel_execute_command(struct d40_chan *d40c, -				       enum d40_command command) +static int __d40_execute_command_phy(struct d40_chan *d40c, +				     enum d40_command command)  {  	u32 status;  	int i; @@ -880,6 +897,12 @@ static int d40_channel_execute_command(struct d40_chan *d40c,  	unsigned long flags;  	u32 wmask; +	if (command == D40_DMA_STOP) { +		ret = __d40_execute_command_phy(d40c, D40_DMA_SUSPEND_REQ); +		if (ret) +			return ret; +	} +  	spin_lock_irqsave(&d40c->base->execmd_lock, flags);  	if (d40c->phy_chan->num % 2 == 0) @@ -973,67 +996,109 @@ static void d40_term_all(struct d40_chan *d40c)  		}  	d40c->pending_tx = 0; -	d40c->busy = false;  } -static void __d40_config_set_event(struct d40_chan *d40c, bool enable, -				   u32 event, int reg) +static void __d40_config_set_event(struct d40_chan *d40c, +				   enum d40_events event_type, u32 event, +				   int reg)  {  	void __iomem *addr = chan_base(d40c) + reg;  	int tries; +	u32 status; + +	switch (event_type) { + +	case D40_DEACTIVATE_EVENTLINE: -	if (!enable) {  		writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event))  		       | ~D40_EVENTLINE_MASK(event), addr); -		return; -	} +		break; + +	case D40_SUSPEND_REQ_EVENTLINE: +		status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> +			  D40_EVENTLINE_POS(event); + +		if (status == D40_DEACTIVATE_EVENTLINE || +		    status == D40_SUSPEND_REQ_EVENTLINE) +			break; +		writel((D40_SUSPEND_REQ_EVENTLINE << D40_EVENTLINE_POS(event)) +		       | ~D40_EVENTLINE_MASK(event), addr); + +		for (tries = 0 ; tries < D40_SUSPEND_MAX_IT; tries++) { + +			status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> +				  D40_EVENTLINE_POS(event); + +			cpu_relax(); +			/* +			 * Reduce the number of bus accesses while +			 * waiting for the DMA to suspend. +			 */ +			udelay(3); + +			if (status == D40_DEACTIVATE_EVENTLINE) +				break; +		} + +		if (tries == D40_SUSPEND_MAX_IT) { +			chan_err(d40c, +				"unable to stop the event_line chl %d (log: %d)" +				"status %x\n", d40c->phy_chan->num, +				 d40c->log_num, status); +		} +		break; + +	case D40_ACTIVATE_EVENTLINE:  	/*  	 * The hardware sometimes doesn't register the enable when src and dst  	 * event lines are active on the same logical channel.  Retry to ensure  	 * it does.  Usually only one retry is sufficient.  	 */ -	tries = 100; -	while (--tries) { -		writel((D40_ACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) -		       | ~D40_EVENTLINE_MASK(event), addr); +		tries = 100; +		while (--tries) { +			writel((D40_ACTIVATE_EVENTLINE << +				D40_EVENTLINE_POS(event)) | +				~D40_EVENTLINE_MASK(event), addr); -		if (readl(addr) & D40_EVENTLINE_MASK(event)) -			break; -	} +			if (readl(addr) & D40_EVENTLINE_MASK(event)) +				break; +		} -	if (tries != 99) -		dev_dbg(chan2dev(d40c), -			"[%s] workaround enable S%cLNK (%d tries)\n", -			__func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', -			100 - tries); +		if (tries != 99) +			dev_dbg(chan2dev(d40c), +				"[%s] workaround enable S%cLNK (%d tries)\n", +				__func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', +				100 - tries); -	WARN_ON(!tries); -} +		WARN_ON(!tries); +		break; -static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) -{ -	unsigned long flags; +	case D40_ROUND_EVENTLINE: +		BUG(); +		break; -	spin_lock_irqsave(&d40c->phy_chan->lock, flags); +	} +} +static void d40_config_set_event(struct d40_chan *d40c, +				 enum d40_events event_type) +{  	/* Enable event line connected to device (or memcpy) */  	if ((d40c->dma_cfg.dir ==  STEDMA40_PERIPH_TO_MEM) ||  	    (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) {  		u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); -		__d40_config_set_event(d40c, do_enable, event, +		__d40_config_set_event(d40c, event_type, event,  				       D40_CHAN_REG_SSLNK);  	}  	if (d40c->dma_cfg.dir !=  STEDMA40_PERIPH_TO_MEM) {  		u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); -		__d40_config_set_event(d40c, do_enable, event, +		__d40_config_set_event(d40c, event_type, event,  				       D40_CHAN_REG_SDLNK);  	} - -	spin_unlock_irqrestore(&d40c->phy_chan->lock, flags);  }  static u32 d40_chan_has_events(struct d40_chan *d40c) @@ -1047,6 +1112,64 @@ static u32 d40_chan_has_events(struct d40_chan *d40c)  	return val;  } +static int +__d40_execute_command_log(struct d40_chan *d40c, enum d40_command command) +{ +	unsigned long flags; +	int ret = 0; +	u32 active_status; +	void __iomem *active_reg; + +	if (d40c->phy_chan->num % 2 == 0) +		active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; +	else +		active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + +	spin_lock_irqsave(&d40c->phy_chan->lock, flags); + +	switch (command) { +	case D40_DMA_STOP: +	case D40_DMA_SUSPEND_REQ: + +		active_status = (readl(active_reg) & +				 D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> +				 D40_CHAN_POS(d40c->phy_chan->num); + +		if (active_status == D40_DMA_RUN) +			d40_config_set_event(d40c, D40_SUSPEND_REQ_EVENTLINE); +		else +			d40_config_set_event(d40c, D40_DEACTIVATE_EVENTLINE); + +		if (!d40_chan_has_events(d40c) && (command == D40_DMA_STOP)) +			ret = __d40_execute_command_phy(d40c, command); + +		break; + +	case D40_DMA_RUN: + +		d40_config_set_event(d40c, D40_ACTIVATE_EVENTLINE); +		ret = __d40_execute_command_phy(d40c, command); +		break; + +	case D40_DMA_SUSPENDED: +		BUG(); +		break; +	} + +	spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); +	return ret; +} + +static int d40_channel_execute_command(struct d40_chan *d40c, +				       enum d40_command command) +{ +	if (chan_is_logical(d40c)) +		return __d40_execute_command_log(d40c, command); +	else +		return __d40_execute_command_phy(d40c, command); +} +  static u32 d40_get_prmo(struct d40_chan *d40c)  {  	static const unsigned int phy_map[] = { @@ -1149,15 +1272,7 @@ static int d40_pause(struct d40_chan *d40c)  	spin_lock_irqsave(&d40c->lock, flags);  	res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); -	if (res == 0) { -		if (chan_is_logical(d40c)) { -			d40_config_set_event(d40c, false); -			/* Resume the other logical channels if any */ -			if (d40_chan_has_events(d40c)) -				res = d40_channel_execute_command(d40c, -								  D40_DMA_RUN); -		} -	} +  	pm_runtime_mark_last_busy(d40c->base->dev);  	pm_runtime_put_autosuspend(d40c->base->dev);  	spin_unlock_irqrestore(&d40c->lock, flags); @@ -1174,45 +1289,17 @@ static int d40_resume(struct d40_chan *d40c)  	spin_lock_irqsave(&d40c->lock, flags);  	pm_runtime_get_sync(d40c->base->dev); -	if (d40c->base->rev == 0) -		if (chan_is_logical(d40c)) { -			res = d40_channel_execute_command(d40c, -							  D40_DMA_SUSPEND_REQ); -			goto no_suspend; -		}  	/* If bytes left to transfer or linked tx resume job */ -	if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { - -		if (chan_is_logical(d40c)) -			d40_config_set_event(d40c, true); - +	if (d40_residue(d40c) || d40_tx_is_linked(d40c))  		res = d40_channel_execute_command(d40c, D40_DMA_RUN); -	} -no_suspend:  	pm_runtime_mark_last_busy(d40c->base->dev);  	pm_runtime_put_autosuspend(d40c->base->dev);  	spin_unlock_irqrestore(&d40c->lock, flags);  	return res;  } -static int d40_terminate_all(struct d40_chan *chan) -{ -	unsigned long flags; -	int ret = 0; - -	ret = d40_pause(chan); -	if (!ret && chan_is_physical(chan)) -		ret = d40_channel_execute_command(chan, D40_DMA_STOP); - -	spin_lock_irqsave(&chan->lock, flags); -	d40_term_all(chan); -	spin_unlock_irqrestore(&chan->lock, flags); - -	return ret; -} -  static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)  {  	struct d40_chan *d40c = container_of(tx->chan, @@ -1232,20 +1319,6 @@ static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)  static int d40_start(struct d40_chan *d40c)  { -	if (d40c->base->rev == 0) { -		int err; - -		if (chan_is_logical(d40c)) { -			err = d40_channel_execute_command(d40c, -							  D40_DMA_SUSPEND_REQ); -			if (err) -				return err; -		} -	} - -	if (chan_is_logical(d40c)) -		d40_config_set_event(d40c, true); -  	return d40_channel_execute_command(d40c, D40_DMA_RUN);  } @@ -1258,10 +1331,10 @@ static struct d40_desc *d40_queue_start(struct d40_chan *d40c)  	d40d = d40_first_queued(d40c);  	if (d40d != NULL) { -		if (!d40c->busy) +		if (!d40c->busy) {  			d40c->busy = true; - -		pm_runtime_get_sync(d40c->base->dev); +			pm_runtime_get_sync(d40c->base->dev); +		}  		/* Remove from queue */  		d40_desc_remove(d40d); @@ -1388,8 +1461,8 @@ static void dma_tasklet(unsigned long data)  	return; - err: -	/* Rescue manoeuvre if receiving double interrupts */ +err: +	/* Rescue manouver if receiving double interrupts */  	if (d40c->pending_tx > 0)  		d40c->pending_tx--;  	spin_unlock_irqrestore(&d40c->lock, flags); @@ -1770,7 +1843,6 @@ static int d40_config_memcpy(struct d40_chan *d40c)  	return 0;  } -  static int d40_free_dma(struct d40_chan *d40c)  { @@ -1806,43 +1878,18 @@ static int d40_free_dma(struct d40_chan *d40c)  	}  	pm_runtime_get_sync(d40c->base->dev); -	res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); +	res = d40_channel_execute_command(d40c, D40_DMA_STOP);  	if (res) { -		chan_err(d40c, "suspend failed\n"); +		chan_err(d40c, "stop failed\n");  		goto out;  	} -	if (chan_is_logical(d40c)) { -		/* Release logical channel, deactivate the event line */ +	d40_alloc_mask_free(phy, is_src, chan_is_logical(d40c) ? event : 0); -		d40_config_set_event(d40c, false); +	if (chan_is_logical(d40c))  		d40c->base->lookup_log_chans[d40c->log_num] = NULL; - -		/* -		 * Check if there are more logical allocation -		 * on this phy channel. -		 */ -		if (!d40_alloc_mask_free(phy, is_src, event)) { -			/* Resume the other logical channels if any */ -			if (d40_chan_has_events(d40c)) { -				res = d40_channel_execute_command(d40c, -								  D40_DMA_RUN); -				if (res) -					chan_err(d40c, -						"Executing RUN command\n"); -			} -			goto out; -		} -	} else { -		(void) d40_alloc_mask_free(phy, is_src, 0); -	} - -	/* Release physical channel */ -	res = d40_channel_execute_command(d40c, D40_DMA_STOP); -	if (res) { -		chan_err(d40c, "Failed to stop channel\n"); -		goto out; -	} +	else +		d40c->base->lookup_phy_chans[phy->num] = NULL;  	if (d40c->busy) {  		pm_runtime_mark_last_busy(d40c->base->dev); @@ -1852,7 +1899,6 @@ static int d40_free_dma(struct d40_chan *d40c)  	d40c->busy = false;  	d40c->phy_chan = NULL;  	d40c->configured = false; -	d40c->base->lookup_phy_chans[phy->num] = NULL;  out:  	pm_runtime_mark_last_busy(d40c->base->dev); @@ -2070,7 +2116,7 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,  	if (sg_next(&sg_src[sg_len - 1]) == sg_src)  		desc->cyclic = true; -	if (direction != DMA_NONE) { +	if (direction != DMA_TRANS_NONE) {  		dma_addr_t dev_addr = d40_get_dev_addr(chan, direction);  		if (direction == DMA_DEV_TO_MEM) @@ -2371,6 +2417,31 @@ static void d40_issue_pending(struct dma_chan *chan)  	spin_unlock_irqrestore(&d40c->lock, flags);  } +static void d40_terminate_all(struct dma_chan *chan) +{ +	unsigned long flags; +	struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); +	int ret; + +	spin_lock_irqsave(&d40c->lock, flags); + +	pm_runtime_get_sync(d40c->base->dev); +	ret = d40_channel_execute_command(d40c, D40_DMA_STOP); +	if (ret) +		chan_err(d40c, "Failed to stop channel\n"); + +	d40_term_all(d40c); +	pm_runtime_mark_last_busy(d40c->base->dev); +	pm_runtime_put_autosuspend(d40c->base->dev); +	if (d40c->busy) { +		pm_runtime_mark_last_busy(d40c->base->dev); +		pm_runtime_put_autosuspend(d40c->base->dev); +	} +	d40c->busy = false; + +	spin_unlock_irqrestore(&d40c->lock, flags); +} +  static int  dma40_config_to_halfchannel(struct d40_chan *d40c,  			    struct stedma40_half_channel_info *info, @@ -2551,7 +2622,8 @@ static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,  	switch (cmd) {  	case DMA_TERMINATE_ALL: -		return d40_terminate_all(d40c); +		d40_terminate_all(chan); +		return 0;  	case DMA_PAUSE:  		return d40_pause(d40c);  	case DMA_RESUME: @@ -2908,6 +2980,12 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)  	dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n",  		 rev, res->start); +	if (rev < 2) { +		d40_err(&pdev->dev, "hardware revision: %d is not supported", +			rev); +		goto failure; +	} +  	plat_data = pdev->dev.platform_data;  	/* Count the number of logical channels in use */ @@ -2998,6 +3076,7 @@ failure:  	if (base) {  		kfree(base->lcla_pool.alloc_map); +		kfree(base->reg_val_backup_chan);  		kfree(base->lookup_log_chans);  		kfree(base->lookup_phy_chans);  		kfree(base->phy_res); diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h index 8d3d490968a..51e8e5396e9 100644 --- a/drivers/dma/ste_dma40_ll.h +++ b/drivers/dma/ste_dma40_ll.h @@ -62,8 +62,6 @@  #define D40_SREG_ELEM_LOG_LIDX_MASK	(0xFF << D40_SREG_ELEM_LOG_LIDX_POS)  /* Link register */ -#define D40_DEACTIVATE_EVENTLINE	0x0 -#define D40_ACTIVATE_EVENTLINE		0x1  #define D40_EVENTLINE_POS(i)		(2 * i)  #define D40_EVENTLINE_MASK(i)		(0x3 << D40_EVENTLINE_POS(i)) diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index d25599f2a3f..891e4674d29 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -191,6 +191,176 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)  	}  } +static bool +validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len) +{ +	struct efi_generic_dev_path *node; +	int offset = 0; + +	node = (struct efi_generic_dev_path *)buffer; + +	while (offset < len) { +		offset += node->length; + +		if (offset > len) +			return false; + +		if ((node->type == EFI_DEV_END_PATH || +		     node->type == EFI_DEV_END_PATH2) && +		    node->sub_type == EFI_DEV_END_ENTIRE) +			return true; + +		node = (struct efi_generic_dev_path *)(buffer + offset); +	} + +	/* +	 * If we're here then either node->length pointed past the end +	 * of the buffer or we reached the end of the buffer without +	 * finding a device path end node. +	 */ +	return false; +} + +static bool +validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len) +{ +	/* An array of 16-bit integers */ +	if ((len % 2) != 0) +		return false; + +	return true; +} + +static bool +validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) +{ +	u16 filepathlength; +	int i, desclength = 0; + +	/* Either "Boot" or "Driver" followed by four digits of hex */ +	for (i = match; i < match+4; i++) { +		if (hex_to_bin(var->VariableName[i] & 0xff) < 0) +			return true; +	} + +	/* A valid entry must be at least 6 bytes */ +	if (len < 6) +		return false; + +	filepathlength = buffer[4] | buffer[5] << 8; + +	/* +	 * There's no stored length for the description, so it has to be +	 * found by hand +	 */ +	desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len) + 2; + +	/* Each boot entry must have a descriptor */ +	if (!desclength) +		return false; + +	/* +	 * If the sum of the length of the description, the claimed filepath +	 * length and the original header are greater than the length of the +	 * variable, it's malformed +	 */ +	if ((desclength + filepathlength + 6) > len) +		return false; + +	/* +	 * And, finally, check the filepath +	 */ +	return validate_device_path(var, match, buffer + desclength + 6, +				    filepathlength); +} + +static bool +validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len) +{ +	/* A single 16-bit integer */ +	if (len != 2) +		return false; + +	return true; +} + +static bool +validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len) +{ +	int i; + +	for (i = 0; i < len; i++) { +		if (buffer[i] > 127) +			return false; + +		if (buffer[i] == 0) +			return true; +	} + +	return false; +} + +struct variable_validate { +	char *name; +	bool (*validate)(struct efi_variable *var, int match, u8 *data, +			 int len); +}; + +static const struct variable_validate variable_validate[] = { +	{ "BootNext", validate_uint16 }, +	{ "BootOrder", validate_boot_order }, +	{ "DriverOrder", validate_boot_order }, +	{ "Boot*", validate_load_option }, +	{ "Driver*", validate_load_option }, +	{ "ConIn", validate_device_path }, +	{ "ConInDev", validate_device_path }, +	{ "ConOut", validate_device_path }, +	{ "ConOutDev", validate_device_path }, +	{ "ErrOut", validate_device_path }, +	{ "ErrOutDev", validate_device_path }, +	{ "Timeout", validate_uint16 }, +	{ "Lang", validate_ascii_string }, +	{ "PlatformLang", validate_ascii_string }, +	{ "", NULL }, +}; + +static bool +validate_var(struct efi_variable *var, u8 *data, int len) +{ +	int i; +	u16 *unicode_name = var->VariableName; + +	for (i = 0; variable_validate[i].validate != NULL; i++) { +		const char *name = variable_validate[i].name; +		int match; + +		for (match = 0; ; match++) { +			char c = name[match]; +			u16 u = unicode_name[match]; + +			/* All special variables are plain ascii */ +			if (u > 127) +				return true; + +			/* Wildcard in the matching name means we've matched */ +			if (c == '*') +				return variable_validate[i].validate(var, +							     match, data, len); + +			/* Case sensitive match */ +			if (c != u) +				break; + +			/* Reached the end of the string while matching */ +			if (!c) +				return variable_validate[i].validate(var, +							     match, data, len); +		} +	} + +	return true; +} +  static efi_status_t  get_var_data_locked(struct efivars *efivars, struct efi_variable *var)  { @@ -324,6 +494,12 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)  		return -EINVAL;  	} +	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || +	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) { +		printk(KERN_ERR "efivars: Malformed variable content\n"); +		return -EINVAL; +	} +  	spin_lock(&efivars->lock);  	status = efivars->ops->set_variable(new_var->VariableName,  					    &new_var->VendorGuid, @@ -626,6 +802,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,  	if (!capable(CAP_SYS_ADMIN))  		return -EACCES; +	if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || +	    validate_var(new_var, new_var->Data, new_var->DataSize) == false) { +		printk(KERN_ERR "efivars: Malformed variable content\n"); +		return -EINVAL; +	} +  	spin_lock(&efivars->lock);  	/* diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 5689ce62fd8..fc3ace3fd4c 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -64,6 +64,7 @@ struct pxa_gpio_chip {  	unsigned long	irq_mask;  	unsigned long	irq_edge_rise;  	unsigned long	irq_edge_fall; +	int (*set_wake)(unsigned int gpio, unsigned int on);  #ifdef CONFIG_PM  	unsigned long	saved_gplr; @@ -269,7 +270,8 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)  				(value ? GPSR_OFFSET : GPCR_OFFSET));  } -static int __devinit pxa_init_gpio_chip(int gpio_end) +static int __devinit pxa_init_gpio_chip(int gpio_end, +					int (*set_wake)(unsigned int, unsigned int))  {  	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;  	struct pxa_gpio_chip *chips; @@ -285,6 +287,7 @@ static int __devinit pxa_init_gpio_chip(int gpio_end)  		sprintf(chips[i].label, "gpio-%d", i);  		chips[i].regbase = gpio_reg_base + BANK_OFF(i); +		chips[i].set_wake = set_wake;  		c->base  = gpio;  		c->label = chips[i].label; @@ -412,6 +415,17 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)  	writel_relaxed(gfer, c->regbase + GFER_OFFSET);  } +static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) +{ +	int gpio = pxa_irq_to_gpio(d->irq); +	struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); + +	if (c->set_wake) +		return c->set_wake(gpio, on); +	else +		return 0; +} +  static void pxa_unmask_muxed_gpio(struct irq_data *d)  {  	int gpio = pxa_irq_to_gpio(d->irq); @@ -427,6 +441,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {  	.irq_mask	= pxa_mask_muxed_gpio,  	.irq_unmask	= pxa_unmask_muxed_gpio,  	.irq_set_type	= pxa_gpio_irq_type, +	.irq_set_wake	= pxa_gpio_set_wake,  };  static int pxa_gpio_nums(void) @@ -471,6 +486,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)  	struct pxa_gpio_chip *c;  	struct resource *res;  	struct clk *clk; +	struct pxa_gpio_platform_data *info;  	int gpio, irq, ret;  	int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; @@ -516,7 +532,8 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)  	}  	/* Initialize GPIO chips */ -	pxa_init_gpio_chip(pxa_last_gpio); +	info = dev_get_platdata(&pdev->dev); +	pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);  	/* clear all GPIO edge detects */  	for_each_gpio_chip(gpio, c) { diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 30372f7b2d4..348b367debe 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data,   * \param arg pointer to a drm_buf_map structure.   * \return zero on success or a negative number on failure.   * - * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls do_mmap() with + * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls vm_mmap() with   * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls   * drm_mmap_dma().   */ @@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data,  				retcode = -EINVAL;  				goto done;  			} -			down_write(¤t->mm->mmap_sem); -			virtual = do_mmap(file_priv->filp, 0, map->size, +			virtual = vm_mmap(file_priv->filp, 0, map->size,  					  PROT_READ | PROT_WRITE,  					  MAP_SHARED,  					  token); -			up_write(¤t->mm->mmap_sem);  		} else { -			down_write(¤t->mm->mmap_sem); -			virtual = do_mmap(file_priv->filp, 0, dma->byte_count, +			virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,  					  PROT_READ | PROT_WRITE,  					  MAP_SHARED, 0); -			up_write(¤t->mm->mmap_sem);  		}  		if (virtual > -1024UL) {  			/* Real error */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 26d51979116..1dffa8359f8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -149,22 +149,12 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj,  	unsigned long pfn;  	if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { -		unsigned long usize = buf->size; -  		if (!buf->pages)  			return -EINTR; -		while (usize > 0) { -			pfn = page_to_pfn(buf->pages[page_offset++]); -			vm_insert_mixed(vma, f_vaddr, pfn); -			f_vaddr += PAGE_SIZE; -			usize -= PAGE_SIZE; -		} - -		return 0; -	} - -	pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; +		pfn = page_to_pfn(buf->pages[page_offset++]); +	} else +		pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;  	return vm_insert_mixed(vma, f_vaddr, pfn);  } @@ -524,6 +514,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,  		if (!buffer->pages)  			return -EINVAL; +		vma->vm_flags |= VM_MIXEDMAP; +  		do {  			ret = vm_insert_page(vma, uaddr, buffer->pages[i++]);  			if (ret) { @@ -581,10 +573,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,  	obj->filp->f_op = &exynos_drm_gem_fops;  	obj->filp->private_data = obj; -	down_write(¤t->mm->mmap_sem); -	addr = do_mmap(obj->filp, 0, args->size, +	addr = vm_mmap(obj->filp, 0, args->size,  			PROT_READ | PROT_WRITE, MAP_SHARED, 0); -	up_write(¤t->mm->mmap_sem);  	drm_gem_object_unreference_unlocked(obj); @@ -712,7 +702,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv,  int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  {  	struct drm_gem_object *obj = vma->vm_private_data; -	struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);  	struct drm_device *dev = obj->dev;  	unsigned long f_vaddr;  	pgoff_t page_offset; @@ -724,21 +713,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  	mutex_lock(&dev->struct_mutex); -	/* -	 * allocate all pages as desired size if user wants to allocate -	 * physically non-continuous memory. -	 */ -	if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { -		ret = exynos_drm_gem_get_pages(obj); -		if (ret < 0) -			goto err; -	} -  	ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset);  	if (ret < 0)  		DRM_ERROR("failed to map pages.\n"); -err:  	mutex_unlock(&dev->struct_mutex);  	return convert_to_vm_err_msg(ret); diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 2c8a60c3b98..f920fb5e42b 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)  	if (buf_priv->currently_mapped == I810_BUF_MAPPED)  		return -EINVAL; +	/* This is all entirely broken */  	down_write(¤t->mm->mmap_sem);  	old_fops = file_priv->filp->f_op;  	file_priv->filp->f_op = &i810_buffer_fops; @@ -157,11 +158,8 @@ static int i810_unmap_buffer(struct drm_buf *buf)  	if (buf_priv->currently_mapped != I810_BUF_MAPPED)  		return -EINVAL; -	down_write(¤t->mm->mmap_sem); -	retcode = do_munmap(current->mm, -			    (unsigned long)buf_priv->virtual, +	retcode = vm_munmap((unsigned long)buf_priv->virtual,  			    (size_t) buf->total); -	up_write(¤t->mm->mmap_sem);  	buf_priv->currently_mapped = I810_BUF_UNMAPPED;  	buf_priv->virtual = NULL; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0e3c6acde95..0d1e4b7b4b9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,  	if (obj == NULL)  		return -ENOENT; -	down_write(¤t->mm->mmap_sem); -	addr = do_mmap(obj->filp, 0, args->size, +	addr = vm_mmap(obj->filp, 0, args->size,  		       PROT_READ | PROT_WRITE, MAP_SHARED,  		       args->offset); -	up_write(¤t->mm->mmap_sem);  	drm_gem_object_unreference_unlocked(obj);  	if (IS_ERR((void *)addr))  		return addr; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f51a696486c..de431942ded 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1133,6 +1133,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,  			return -EINVAL;  		} +		if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { +			DRM_DEBUG("execbuf with %u cliprects\n", +				  args->num_cliprects); +			return -EINVAL; +		}  		cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),  				    GFP_KERNEL);  		if (cliprects == NULL) { @@ -1404,7 +1409,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,  	struct drm_i915_gem_exec_object2 *exec2_list = NULL;  	int ret; -	if (args->buffer_count < 1) { +	if (args->buffer_count < 1 || +	    args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {  		DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);  		return -EINVAL;  	} diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b4bb1ef77dd..9d24d65f0c3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -568,6 +568,7 @@  #define   CM0_MASK_SHIFT          16  #define   CM0_IZ_OPT_DISABLE      (1<<6)  #define   CM0_ZR_OPT_DISABLE      (1<<5) +#define	  CM0_STC_EVICT_DISABLE_LRA_SNB	(1<<5)  #define   CM0_DEPTH_EVICT_DISABLE (1<<4)  #define   CM0_COLOR_EVICT_DISABLE (1<<3)  #define   CM0_DEPTH_WRITE_DISABLE (1<<1) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4d3d736a4f5..90b9793fd5d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -430,8 +430,8 @@ intel_crt_detect(struct drm_connector *connector, bool force)  {  	struct drm_device *dev = connector->dev;  	struct intel_crt *crt = intel_attached_crt(connector); -	struct drm_crtc *crtc;  	enum drm_connector_status status; +	struct intel_load_detect_pipe tmp;  	if (I915_HAS_HOTPLUG(dev)) {  		if (intel_crt_detect_hotplug(connector)) { @@ -450,23 +450,16 @@ intel_crt_detect(struct drm_connector *connector, bool force)  		return connector->status;  	/* for pre-945g platforms use load detect */ -	crtc = crt->base.base.crtc; -	if (crtc && crtc->enabled) { -		status = intel_crt_load_detect(crt); -	} else { -		struct intel_load_detect_pipe tmp; - -		if (intel_get_load_detect_pipe(&crt->base, connector, NULL, -					       &tmp)) { -			if (intel_crt_detect_ddc(connector)) -				status = connector_status_connected; -			else -				status = intel_crt_load_detect(crt); -			intel_release_load_detect_pipe(&crt->base, connector, -						       &tmp); -		} else -			status = connector_status_unknown; -	} +	if (intel_get_load_detect_pipe(&crt->base, connector, NULL, +				       &tmp)) { +		if (intel_crt_detect_ddc(connector)) +			status = connector_status_connected; +		else +			status = intel_crt_load_detect(crt); +		intel_release_load_detect_pipe(&crt->base, connector, +					       &tmp); +	} else +		status = connector_status_unknown;  	return status;  } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f75806e5bff..80fce51e2f4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -401,6 +401,14 @@ static int init_render_ring(struct intel_ring_buffer *ring)  	if (INTEL_INFO(dev)->gen >= 6) {  		I915_WRITE(INSTPM,  			   INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); + +		/* From the Sandybridge PRM, volume 1 part 3, page 24: +		 * "If this bit is set, STCunit will have LRA as replacement +		 *  policy. [...] This bit must be reset.  LRA replacement +		 *  policy is not supported." +		 */ +		I915_WRITE(CACHE_MODE_0, +			   CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT);  	}  	return ret; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e36b171c1e7..232d77d07d8 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -731,6 +731,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,  	uint16_t width, height;  	uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;  	uint16_t h_sync_offset, v_sync_offset; +	int mode_clock;  	width = mode->crtc_hdisplay;  	height = mode->crtc_vdisplay; @@ -745,7 +746,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,  	h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;  	v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; -	dtd->part1.clock = mode->clock / 10; +	mode_clock = mode->clock; +	mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; +	mode_clock /= 10; +	dtd->part1.clock = mode_clock; +  	dtd->part1.h_active = width & 0xff;  	dtd->part1.h_blank = h_blank_len & 0xff;  	dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | @@ -996,7 +1001,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);  	u32 sdvox;  	struct intel_sdvo_in_out_map in_out; -	struct intel_sdvo_dtd input_dtd; +	struct intel_sdvo_dtd input_dtd, output_dtd;  	int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);  	int rate; @@ -1021,20 +1026,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  					  intel_sdvo->attached_output))  		return; -	/* We have tried to get input timing in mode_fixup, and filled into -	 * adjusted_mode. -	 */ -	if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { -		input_dtd = intel_sdvo->input_dtd; -	} else { -		/* Set the output timing to the screen */ -		if (!intel_sdvo_set_target_output(intel_sdvo, -						  intel_sdvo->attached_output)) -			return; - -		intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); -		(void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); -	} +	/* lvds has a special fixed output timing. */ +	if (intel_sdvo->is_lvds) +		intel_sdvo_get_dtd_from_mode(&output_dtd, +					     intel_sdvo->sdvo_lvds_fixed_mode); +	else +		intel_sdvo_get_dtd_from_mode(&output_dtd, mode); +	(void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd);  	/* Set the input timing to the screen. Assume always input 0. */  	if (!intel_sdvo_set_target_input(intel_sdvo)) @@ -1052,6 +1050,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	    !intel_sdvo_set_tv_format(intel_sdvo))  		return; +	/* We have tried to get input timing in mode_fixup, and filled into +	 * adjusted_mode. +	 */ +	intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);  	(void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);  	switch (pixel_multiplier) { diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b5ff1f7b6f7..af1054f8202 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -575,6 +575,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,  		if (rdev->family < CHIP_RV770)  			pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; +		/* use frac fb div on APUs */ +		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) +			pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;  	} else {  		pll->flags |= RADEON_PLL_LEGACY; @@ -955,8 +958,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode  		break;  	} -	if (radeon_encoder->active_device & -	    (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { +	if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || +	    (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {  		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  		struct drm_connector *connector =  			radeon_get_connector_for_encoder(encoder); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8086c96e0b0..0a1d4bd65ed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)  		radeon_legacy_init_crtc(dev, radeon_crtc);  } -static const char *encoder_names[36] = { +static const char *encoder_names[37] = {  	"NONE",  	"INTERNAL_LVDS",  	"INTERNAL_TMDS1", @@ -570,6 +570,7 @@ static const char *encoder_names[36] = {  	"INTERNAL_UNIPHY2",  	"NUTMEG",  	"TRAVIS", +	"INTERNAL_VCE"  };  static const char *connector_names[15] = { diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a3d03325299..ffddcba32af 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -34,7 +34,7 @@ config HID  config HID_BATTERY_STRENGTH  	bool  	depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY -	default y +	default n  config HIDRAW  	bool "/dev/hidraw raw HID device support" diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c index de47039c708..9f85f827607 100644 --- a/drivers/hid/hid-tivo.c +++ b/drivers/hid/hid-tivo.c @@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,  static const struct hid_device_id tivo_devices[] = {  	/* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ -	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },  	{ }  }; diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c index 88a050df238..3ad91f6447d 100644 --- a/drivers/hsi/clients/hsi_char.c +++ b/drivers/hsi/clients/hsi_char.c @@ -123,7 +123,7 @@ struct hsc_client_data {  static unsigned int hsc_major;  /* Maximum buffer size that hsi_char will accept from userspace */  static unsigned int max_data_size = 0x1000; -module_param(max_data_size, uint, S_IRUSR | S_IWUSR); +module_param(max_data_size, uint, 0);  MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)");  static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg, diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c index 4e2d79b7933..2d58f939d27 100644 --- a/drivers/hsi/hsi.c +++ b/drivers/hsi/hsi.c @@ -21,26 +21,13 @@   */  #include <linux/hsi/hsi.h>  #include <linux/compiler.h> -#include <linux/rwsem.h>  #include <linux/list.h> -#include <linux/spinlock.h>  #include <linux/kobject.h>  #include <linux/slab.h>  #include <linux/string.h> +#include <linux/notifier.h>  #include "hsi_core.h" -static struct device_type hsi_ctrl = { -	.name	= "hsi_controller", -}; - -static struct device_type hsi_cl = { -	.name	= "hsi_client", -}; - -static struct device_type hsi_port = { -	.name	= "hsi_port", -}; -  static ssize_t modalias_show(struct device *dev,  			struct device_attribute *a __maybe_unused, char *buf)  { @@ -54,8 +41,7 @@ static struct device_attribute hsi_bus_dev_attrs[] = {  static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)  { -	if (dev->type == &hsi_cl) -		add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); +	add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));  	return 0;  } @@ -80,12 +66,10 @@ static void hsi_client_release(struct device *dev)  static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)  {  	struct hsi_client *cl; -	unsigned long flags;  	cl = kzalloc(sizeof(*cl), GFP_KERNEL);  	if (!cl)  		return; -	cl->device.type = &hsi_cl;  	cl->tx_cfg = info->tx_cfg;  	cl->rx_cfg = info->rx_cfg;  	cl->device.bus = &hsi_bus_type; @@ -93,14 +77,11 @@ static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)  	cl->device.release = hsi_client_release;  	dev_set_name(&cl->device, info->name);  	cl->device.platform_data = info->platform_data; -	spin_lock_irqsave(&port->clock, flags); -	list_add_tail(&cl->link, &port->clients); -	spin_unlock_irqrestore(&port->clock, flags);  	if (info->archdata)  		cl->device.archdata = *info->archdata;  	if (device_register(&cl->device) < 0) {  		pr_err("hsi: failed to register client: %s\n", info->name); -		kfree(cl); +		put_device(&cl->device);  	}  } @@ -120,13 +101,6 @@ static void hsi_scan_board_info(struct hsi_controller *hsi)  static int hsi_remove_client(struct device *dev, void *data __maybe_unused)  { -	struct hsi_client *cl = to_hsi_client(dev); -	struct hsi_port *port = to_hsi_port(dev->parent); -	unsigned long flags; - -	spin_lock_irqsave(&port->clock, flags); -	list_del(&cl->link); -	spin_unlock_irqrestore(&port->clock, flags);  	device_unregister(dev);  	return 0; @@ -140,12 +114,17 @@ static int hsi_remove_port(struct device *dev, void *data __maybe_unused)  	return 0;  } -static void hsi_controller_release(struct device *dev __maybe_unused) +static void hsi_controller_release(struct device *dev)  { +	struct hsi_controller *hsi = to_hsi_controller(dev); + +	kfree(hsi->port); +	kfree(hsi);  } -static void hsi_port_release(struct device *dev __maybe_unused) +static void hsi_port_release(struct device *dev)  { +	kfree(to_hsi_port(dev));  }  /** @@ -170,20 +149,12 @@ int hsi_register_controller(struct hsi_controller *hsi)  	unsigned int i;  	int err; -	hsi->device.type = &hsi_ctrl; -	hsi->device.bus = &hsi_bus_type; -	hsi->device.release = hsi_controller_release; -	err = device_register(&hsi->device); +	err = device_add(&hsi->device);  	if (err < 0)  		return err;  	for (i = 0; i < hsi->num_ports; i++) { -		hsi->port[i].device.parent = &hsi->device; -		hsi->port[i].device.bus = &hsi_bus_type; -		hsi->port[i].device.release = hsi_port_release; -		hsi->port[i].device.type = &hsi_port; -		INIT_LIST_HEAD(&hsi->port[i].clients); -		spin_lock_init(&hsi->port[i].clock); -		err = device_register(&hsi->port[i].device); +		hsi->port[i]->device.parent = &hsi->device; +		err = device_add(&hsi->port[i]->device);  		if (err < 0)  			goto out;  	} @@ -192,7 +163,9 @@ int hsi_register_controller(struct hsi_controller *hsi)  	return 0;  out: -	hsi_unregister_controller(hsi); +	while (i-- > 0) +		device_del(&hsi->port[i]->device); +	device_del(&hsi->device);  	return err;  } @@ -223,6 +196,29 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)  }  /** + * hsi_put_controller - Free an HSI controller + * + * @hsi: Pointer to the HSI controller to freed + * + * HSI controller drivers should only use this function if they need + * to free their allocated hsi_controller structures before a successful + * call to hsi_register_controller. Other use is not allowed. + */ +void hsi_put_controller(struct hsi_controller *hsi) +{ +	unsigned int i; + +	if (!hsi) +		return; + +	for (i = 0; i < hsi->num_ports; i++) +		if (hsi->port && hsi->port[i]) +			put_device(&hsi->port[i]->device); +	put_device(&hsi->device); +} +EXPORT_SYMBOL_GPL(hsi_put_controller); + +/**   * hsi_alloc_controller - Allocate an HSI controller and its ports   * @n_ports: Number of ports on the HSI controller   * @flags: Kernel allocation flags @@ -232,55 +228,52 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)  struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags)  {  	struct hsi_controller	*hsi; -	struct hsi_port		*port; +	struct hsi_port		**port;  	unsigned int		i;  	if (!n_ports)  		return NULL; -	port = kzalloc(sizeof(*port)*n_ports, flags); -	if (!port) -		return NULL;  	hsi = kzalloc(sizeof(*hsi), flags);  	if (!hsi) -		goto out; -	for (i = 0; i < n_ports; i++) { -		dev_set_name(&port[i].device, "port%d", i); -		port[i].num = i; -		port[i].async = hsi_dummy_msg; -		port[i].setup = hsi_dummy_cl; -		port[i].flush = hsi_dummy_cl; -		port[i].start_tx = hsi_dummy_cl; -		port[i].stop_tx = hsi_dummy_cl; -		port[i].release = hsi_dummy_cl; -		mutex_init(&port[i].lock); +		return NULL; +	port = kzalloc(sizeof(*port)*n_ports, flags); +	if (!port) { +		kfree(hsi); +		return NULL;  	}  	hsi->num_ports = n_ports;  	hsi->port = port; +	hsi->device.release = hsi_controller_release; +	device_initialize(&hsi->device); + +	for (i = 0; i < n_ports; i++) { +		port[i] = kzalloc(sizeof(**port), flags); +		if (port[i] == NULL) +			goto out; +		port[i]->num = i; +		port[i]->async = hsi_dummy_msg; +		port[i]->setup = hsi_dummy_cl; +		port[i]->flush = hsi_dummy_cl; +		port[i]->start_tx = hsi_dummy_cl; +		port[i]->stop_tx = hsi_dummy_cl; +		port[i]->release = hsi_dummy_cl; +		mutex_init(&port[i]->lock); +		ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); +		dev_set_name(&port[i]->device, "port%d", i); +		hsi->port[i]->device.release = hsi_port_release; +		device_initialize(&hsi->port[i]->device); +	}  	return hsi;  out: -	kfree(port); +	hsi_put_controller(hsi);  	return NULL;  }  EXPORT_SYMBOL_GPL(hsi_alloc_controller);  /** - * hsi_free_controller - Free an HSI controller - * @hsi: Pointer to HSI controller - */ -void hsi_free_controller(struct hsi_controller *hsi) -{ -	if (!hsi) -		return; - -	kfree(hsi->port); -	kfree(hsi); -} -EXPORT_SYMBOL_GPL(hsi_free_controller); - -/**   * hsi_free_msg - Free an HSI message   * @msg: Pointer to the HSI message   * @@ -414,37 +407,67 @@ void hsi_release_port(struct hsi_client *cl)  }  EXPORT_SYMBOL_GPL(hsi_release_port); -static int hsi_start_rx(struct hsi_client *cl, void *data __maybe_unused) +static int hsi_event_notifier_call(struct notifier_block *nb, +				unsigned long event, void *data __maybe_unused)  { -	if (cl->hsi_start_rx) -		(*cl->hsi_start_rx)(cl); +	struct hsi_client *cl = container_of(nb, struct hsi_client, nb); + +	(*cl->ehandler)(cl, event);  	return 0;  } -static int hsi_stop_rx(struct hsi_client *cl, void *data __maybe_unused) +/** + * hsi_register_port_event - Register a client to receive port events + * @cl: HSI client that wants to receive port events + * @cb: Event handler callback + * + * Clients should register a callback to be able to receive + * events from the ports. Registration should happen after + * claiming the port. + * The handler can be called in interrupt context. + * + * Returns -errno on error, or 0 on success. + */ +int hsi_register_port_event(struct hsi_client *cl, +			void (*handler)(struct hsi_client *, unsigned long))  { -	if (cl->hsi_stop_rx) -		(*cl->hsi_stop_rx)(cl); +	struct hsi_port *port = hsi_get_port(cl); -	return 0; +	if (!handler || cl->ehandler) +		return -EINVAL; +	if (!hsi_port_claimed(cl)) +		return -EACCES; +	cl->ehandler = handler; +	cl->nb.notifier_call = hsi_event_notifier_call; + +	return atomic_notifier_chain_register(&port->n_head, &cl->nb);  } +EXPORT_SYMBOL_GPL(hsi_register_port_event); -static int hsi_port_for_each_client(struct hsi_port *port, void *data, -				int (*fn)(struct hsi_client *cl, void *data)) +/** + * hsi_unregister_port_event - Stop receiving port events for a client + * @cl: HSI client that wants to stop receiving port events + * + * Clients should call this function before releasing their associated + * port. + * + * Returns -errno on error, or 0 on success. + */ +int hsi_unregister_port_event(struct hsi_client *cl)  { -	struct hsi_client *cl; +	struct hsi_port *port = hsi_get_port(cl); +	int err; -	spin_lock(&port->clock); -	list_for_each_entry(cl, &port->clients, link) { -		spin_unlock(&port->clock); -		(*fn)(cl, data); -		spin_lock(&port->clock); -	} -	spin_unlock(&port->clock); +	WARN_ON(!hsi_port_claimed(cl)); -	return 0; +	err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); +	if (!err) +		cl->ehandler = NULL; + +	return err;  } +EXPORT_SYMBOL_GPL(hsi_unregister_port_event);  /**   * hsi_event -Notifies clients about port events @@ -458,22 +481,12 @@ static int hsi_port_for_each_client(struct hsi_port *port, void *data,   * Events:   * HSI_EVENT_START_RX - Incoming wake line high   * HSI_EVENT_STOP_RX - Incoming wake line down + * + * Returns -errno on error, or 0 on success.   */ -void hsi_event(struct hsi_port *port, unsigned int event) +int hsi_event(struct hsi_port *port, unsigned long event)  { -	int (*fn)(struct hsi_client *cl, void *data); - -	switch (event) { -	case HSI_EVENT_START_RX: -		fn = hsi_start_rx; -		break; -	case HSI_EVENT_STOP_RX: -		fn = hsi_stop_rx; -		break; -	default: -		return; -	} -	hsi_port_for_each_client(port, NULL, fn); +	return atomic_notifier_call_chain(&port->n_head, event, NULL);  }  EXPORT_SYMBOL_GPL(hsi_event); diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index ce43642ef03..f85ce70d967 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -47,7 +47,7 @@ struct ad7314_data {  	u16 rx ____cacheline_aligned;  }; -static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) +static int ad7314_spi_read(struct ad7314_data *chip)  {  	int ret; @@ -57,9 +57,7 @@ static int ad7314_spi_read(struct ad7314_data *chip, s16 *data)  		return ret;  	} -	*data = be16_to_cpu(chip->rx); - -	return ret; +	return be16_to_cpu(chip->rx);  }  static ssize_t ad7314_show_temperature(struct device *dev, @@ -70,12 +68,12 @@ static ssize_t ad7314_show_temperature(struct device *dev,  	s16 data;  	int ret; -	ret = ad7314_spi_read(chip, &data); +	ret = ad7314_spi_read(chip);  	if (ret < 0)  		return ret;  	switch (spi_get_device_id(chip->spi_dev)->driver_data) {  	case ad7314: -		data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; +		data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET;  		data = (data << 6) >> 6;  		return sprintf(buf, "%d\n", 250 * data); @@ -86,7 +84,7 @@ static ssize_t ad7314_show_temperature(struct device *dev,  		 * with a sign bit - which is a 14 bit 2's complement  		 * register.  1lsb - 31.25 milli degrees centigrade  		 */ -		data &= ADT7301_TEMP_MASK; +		data = ret & ADT7301_TEMP_MASK;  		data = (data << 2) >> 2;  		return sprintf(buf, "%d\n", diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index 7765e4f74ec..1958f03efd7 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -59,14 +59,11 @@ struct ads1015_data {  	struct ads1015_channel_data channel_data[ADS1015_CHANNELS];  }; -static int ads1015_read_value(struct i2c_client *client, unsigned int channel, -			      int *value) +static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)  {  	u16 config; -	s16 conversion;  	struct ads1015_data *data = i2c_get_clientdata(client);  	unsigned int pga = data->channel_data[channel].pga; -	int fullscale;  	unsigned int data_rate = data->channel_data[channel].data_rate;  	unsigned int conversion_time_ms;  	int res; @@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,  	if (res < 0)  		goto err_unlock;  	config = res; -	fullscale = fullscale_table[pga];  	conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);  	/* setup and start single conversion */ @@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,  	}  	res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); -	if (res < 0) -		goto err_unlock; -	conversion = res; - -	mutex_unlock(&data->update_lock); - -	*value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); - -	return 0;  err_unlock:  	mutex_unlock(&data->update_lock);  	return res;  } +static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, +			     s16 reg) +{ +	struct ads1015_data *data = i2c_get_clientdata(client); +	unsigned int pga = data->channel_data[channel].pga; +	int fullscale = fullscale_table[pga]; + +	return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +} +  /* sysfs callback function */  static ssize_t show_in(struct device *dev, struct device_attribute *da,  	char *buf)  {  	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);  	struct i2c_client *client = to_i2c_client(dev); -	int in;  	int res; +	int index = attr->index; -	res = ads1015_read_value(client, attr->index, &in); +	res = ads1015_read_adc(client, index); +	if (res < 0) +		return res; -	return (res < 0) ? res : sprintf(buf, "%d\n", in); +	return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));  }  static const struct sensor_device_attribute ads1015_in[] = { diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index b7494af1e4a..e8e18cab1fb 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -122,6 +122,41 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)  	return true;  } +/* + * Newer BKDG versions have an updated recommendation on how to properly + * initialize the running average range (was: 0xE, now: 0x9). This avoids + * counter saturations resulting in bogus power readings. + * We correct this value ourselves to cope with older BIOSes. + */ +static DEFINE_PCI_DEVICE_TABLE(affected_device) = { +	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, +	{ 0 } +}; + +static void __devinit tweak_runavg_range(struct pci_dev *pdev) +{ +	u32 val; + +	/* +	 * let this quirk apply only to the current version of the +	 * northbridge, since future versions may change the behavior +	 */ +	if (!pci_match_id(affected_device, pdev)) +		return; + +	pci_bus_read_config_dword(pdev->bus, +		PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), +		REG_TDP_RUNNING_AVERAGE, &val); +	if ((val & 0xf) != 0xe) +		return; + +	val &= ~0xf; +	val |=  0x9; +	pci_bus_write_config_dword(pdev->bus, +		PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), +		REG_TDP_RUNNING_AVERAGE, val); +} +  static void __devinit fam15h_power_init_data(struct pci_dev *f4,  					     struct fam15h_power_data *data)  { @@ -155,6 +190,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,  	struct device *dev;  	int err; +	/* +	 * though we ignore every other northbridge, we still have to +	 * do the tweaking on _each_ node in MCM processors as the counters +	 * are working hand-in-hand +	 */ +	tweak_runavg_range(pdev); +  	if (!fam15h_power_is_internal_node0(pdev)) {  		err = -ENODEV;  		goto exit; diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 426bb7617ec..b0d0bc8a6fb 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1854,6 +1854,8 @@ static bool generate_unmatched_resp(struct ib_mad_private *recv,  		response->mad.mad.mad_hdr.method = IB_MGMT_METHOD_GET_RESP;  		response->mad.mad.mad_hdr.status =  			cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB); +		if (recv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) +			response->mad.mad.mad_hdr.status |= IB_SMP_DIRECTION;  		return true;  	} else { @@ -1869,6 +1871,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,  	struct ib_mad_list_head *mad_list;  	struct ib_mad_agent_private *mad_agent;  	int port_num; +	int ret = IB_MAD_RESULT_SUCCESS;  	mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;  	qp_info = mad_list->mad_queue->qp_info; @@ -1952,8 +1955,6 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,  local:  	/* Give driver "right of first refusal" on incoming MAD */  	if (port_priv->device->process_mad) { -		int ret; -  		ret = port_priv->device->process_mad(port_priv->device, 0,  						     port_priv->port_num,  						     wc, &recv->grh, @@ -1981,7 +1982,8 @@ local:  		 * or via recv_handler in ib_mad_complete_recv()  		 */  		recv = NULL; -	} else if (generate_unmatched_resp(recv, response)) { +	} else if ((ret & IB_MAD_RESULT_SUCCESS) && +		   generate_unmatched_resp(recv, response)) {  		agent_send_response(&response->mad.mad, &recv->grh, wc,  				    port_priv->device, port_num, qp_info->qp->qp_num);  	} diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 669673e8143..b948b6dd5d5 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -247,7 +247,7 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,  		err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port,  				   NULL, NULL, in_mad, out_mad);  		if (err) -			return err; +			goto out;  		/* Checking LinkSpeedActive for FDR-10 */  		if (out_mad->data[15] & 0x1) diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 2d787796bf5..7faf4a7fcaa 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA  config INPUT_TWL6040_VIBRA  	tristate "Support for TWL6040 Vibrator" -	depends on TWL4030_CORE -	select TWL6040_CORE +	depends on TWL6040_CORE  	select INPUT_FF_MEMLESS  	help  	  This option enables support for TWL6040 Vibrator Driver. diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 45874fed523..14e94f56cb7 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -28,7 +28,7 @@  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/workqueue.h> -#include <linux/i2c/twl.h> +#include <linux/input.h>  #include <linux/mfd/twl6040.h>  #include <linux/slab.h>  #include <linux/delay.h> @@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);  static int __devinit twl6040_vibra_probe(struct platform_device *pdev)  { -	struct twl4030_vibra_data *pdata = pdev->dev.platform_data; +	struct twl6040_vibra_data *pdata = pdev->dev.platform_data;  	struct vibra_info *info;  	int ret; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 8081a0a5d60..a4b14a41cbf 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -274,7 +274,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)  	static unsigned char param = 0xc8;  	struct synaptics_data *priv = psmouse->private; -	if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) +	if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || +	      SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))  		return 0;  	if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c index 800243b6037..64ad702a2ec 100644 --- a/drivers/leds/leds-atmel-pwm.c +++ b/drivers/leds/leds-atmel-pwm.c @@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)   * NOTE:  we reuse the platform_data structure of GPIO leds,   * but repurpose its "gpio" number as a PWM channel number.   */ -static int __init pwmled_probe(struct platform_device *pdev) +static int __devinit pwmled_probe(struct platform_device *pdev)  {  	const struct gpio_led_platform_data	*pdata;  	struct pwmled				*leds; diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index b0ba52459ed..68965e66324 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)  	int ret;  	unsigned redundancy = 0;  	struct raid_dev *dev; -	struct md_rdev *rdev, *freshest; +	struct md_rdev *rdev, *tmp, *freshest;  	struct mddev *mddev = &rs->md;  	switch (rs->raid_type->level) { @@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)  	}  	freshest = NULL; -	rdev_for_each(rdev, mddev) { +	rdev_for_each_safe(rdev, tmp, mddev) {  		if (!rdev->meta_bdev)  			continue; diff --git a/drivers/md/md.c b/drivers/md/md.c index b572e1e386c..477eb2e180c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev)  		 * any transients in the value of "sync_action".  		 */  		set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); -		clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);  		/* Clear some bits that don't mean anything, but  		 * might be left set  		 */  		clear_bit(MD_RECOVERY_INTR, &mddev->recovery);  		clear_bit(MD_RECOVERY_DONE, &mddev->recovery); -		if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) +		if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || +		    test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))  			goto unlock;  		/* no recovery is running.  		 * remove any failed drives, then @@ -8140,7 +8140,8 @@ static int md_notify_reboot(struct notifier_block *this,  	for_each_mddev(mddev, tmp) {  		if (mddev_trylock(mddev)) { -			__md_stop_writes(mddev); +			if (mddev->pers) +				__md_stop_writes(mddev);  			mddev->safemode = 2;  			mddev_unlock(mddev);  		} diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 7f98984e4fa..eab2ea42420 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -54,6 +54,7 @@ struct xc5000_priv {  	struct list_head hybrid_tuner_instance_list;  	u32 if_khz; +	u32 xtal_khz;  	u32 freq_hz;  	u32 bandwidth;  	u8  video_standard; @@ -214,9 +215,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = {  	.size = 12401,  }; -static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { -	.name = "dvb-fe-xc5000c-41.024.5-31875.fw", -	.size = 16503, +static const struct xc5000_fw_cfg xc5000c_41_024_5 = { +	.name = "dvb-fe-xc5000c-41.024.5.fw", +	.size = 16497,  };  static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) @@ -226,7 +227,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)  	case XC5000A:  		return &xc5000a_1_6_114;  	case XC5000C: -		return &xc5000c_41_024_5_31875; +		return &xc5000c_41_024_5;  	}  } @@ -572,6 +573,31 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)  	return found;  } +static int xc_set_xtal(struct dvb_frontend *fe) +{ +	struct xc5000_priv *priv = fe->tuner_priv; +	int ret = XC_RESULT_SUCCESS; + +	switch (priv->chip_id) { +	default: +	case XC5000A: +		/* 32.000 MHz xtal is default */ +		break; +	case XC5000C: +		switch (priv->xtal_khz) { +		default: +		case 32000: +			/* 32.000 MHz xtal is default */ +			break; +		case 31875: +			/* 31.875 MHz xtal configuration */ +			ret = xc_write_reg(priv, 0x000f, 0x8081); +			break; +		} +		break; +	} +	return ret; +}  static int xc5000_fwupload(struct dvb_frontend *fe)  { @@ -603,6 +629,8 @@ static int xc5000_fwupload(struct dvb_frontend *fe)  	} else {  		printk(KERN_INFO "xc5000: firmware uploading...\n");  		ret = xc_load_i2c_sequence(fe,  fw->data); +		if (XC_RESULT_SUCCESS == ret) +			ret = xc_set_xtal(fe);  		printk(KERN_INFO "xc5000: firmware upload complete...\n");  	} @@ -1164,6 +1192,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,  		priv->if_khz = cfg->if_khz;  	} +	if (priv->xtal_khz == 0) +		priv->xtal_khz = cfg->xtal_khz; +  	if (priv->radio_input == 0)  		priv->radio_input = cfg->radio_input; diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index 3396f8e02b4..39a73bf0140 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/drivers/media/common/tuners/xc5000.h @@ -34,6 +34,7 @@ struct xc5000_config {  	u8   i2c_address;  	u32  if_khz;  	u8   radio_input; +	u32  xtal_khz;  	int chip_id;  }; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 39696c6a4ed..0f64d718265 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1446,6 +1446,28 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)  				__func__);  			return -EINVAL;  		} +		/* +		 * Get a delivery system that is compatible with DVBv3 +		 * NOTE: in order for this to work with softwares like Kaffeine that +		 *	uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to +		 *	DVB-S, drivers that support both should put the SYS_DVBS entry +		 *	before the SYS_DVBS2, otherwise it won't switch back to DVB-S. +		 *	The real fix is that userspace applications should not use DVBv3 +		 *	and not trust on calling FE_SET_FRONTEND to switch the delivery +		 *	system. +		 */ +		ncaps = 0; +		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { +			if (fe->ops.delsys[ncaps] == desired_system) { +				delsys = desired_system; +				break; +			} +			ncaps++; +		} +		if (delsys == SYS_UNDEFINED) { +			dprintk("%s() Couldn't find a delivery system that matches %d\n", +				__func__, desired_system); +		}  	} else {  		/*  		 * This is a DVBv5 call. So, it likely knows the supported @@ -1494,9 +1516,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)  				__func__);  			return -EINVAL;  		} -		c->delivery_system = delsys;  	} +	c->delivery_system = delsys; +  	/*  	 * The DVBv3 or DVBv5 call is requesting a different system. So,  	 * emulation is needed. diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 36d11756492..a414b1f2b6a 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -1520,8 +1520,10 @@ static int scu_command(struct drxk_state *state,  	dprintk(1, "\n");  	if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || -	    ((resultLen > 0) && (result == NULL))) -		goto error; +	    ((resultLen > 0) && (result == NULL))) { +		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); +		return status; +	}  	mutex_lock(&state->mutex); diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index b09c5fae489..af526586fa2 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1046,6 +1046,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)  		goto exit_unregister_led;  	} +	data->dev->driver_type = RC_DRIVER_IR_RAW;  	data->dev->driver_name = WBCIR_NAME;  	data->dev->input_name = WBCIR_NAME;  	data->dev->input_phys = "wbcir/cir0"; diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f2479c5c0eb..ce1e7ba940f 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -492,7 +492,7 @@ config VIDEO_VS6624  config VIDEO_MT9M032  	tristate "MT9M032 camera sensor support" -	depends on I2C && VIDEO_V4L2 +	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API  	select VIDEO_APTINA_PLL  	---help---  	  This driver supports MT9M032 camera sensors from Aptina, monochrome diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c index 7636672c354..645973c5feb 100644 --- a/drivers/media/video/mt9m032.c +++ b/drivers/media/video/mt9m032.c @@ -392,10 +392,11 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,  	}  	/* Scaling is not supported, the format is thus fixed. */ -	ret = mt9m032_get_pad_format(subdev, fh, fmt); +	fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); +	ret = 0;  done: -	mutex_lock(&sensor->lock); +	mutex_unlock(&sensor->lock);  	return ret;  } diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 29f463cc09c..11e44386fa9 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -268,10 +268,17 @@ config TWL6030_PWM  	  This is used to control charging LED brightness.  config TWL6040_CORE -	bool -	depends on TWL4030_CORE && GENERIC_HARDIRQS +	bool "Support for TWL6040 audio codec" +	depends on I2C=y && GENERIC_HARDIRQS  	select MFD_CORE +	select REGMAP_I2C  	default n +	help +	  Say yes here if you want support for Texas Instruments TWL6040 audio +	  codec. +	  This driver provides common support for accessing the device, +	  additional drivers must be enabled in order to use the +	  functionality of the device (audio, vibra).  config MFD_STMPE  	bool "Support STMicroelectronics STMPE" diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 1895cf9fab8..1582c3d9525 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip,  static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)  { -	return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO; +	struct asic3 *asic = container_of(chip, struct asic3, gpio); + +	return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;  }  static __init int asic3_gpio_probe(struct platform_device *pdev, diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 95a2e546a48..c8aae6640e6 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -25,7 +25,6 @@  #include <linux/clk.h>  #include <linux/dma-mapping.h>  #include <linux/spinlock.h> -#include <linux/gpio.h>  #include <plat/usb.h>  #include <linux/pm_runtime.h> @@ -502,19 +501,6 @@ static void omap_usbhs_init(struct device *dev)  	pm_runtime_get_sync(dev);  	spin_lock_irqsave(&omap->lock, flags); -	if (pdata->ehci_data->phy_reset) { -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -			gpio_request_one(pdata->ehci_data->reset_gpio_port[0], -					 GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -			gpio_request_one(pdata->ehci_data->reset_gpio_port[1], -					 GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - -		/* Hold the PHY in RESET for enough time till DIR is high */ -		udelay(10); -	} -  	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);  	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -593,39 +579,10 @@ static void omap_usbhs_init(struct device *dev)  			usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);  	} -	if (pdata->ehci_data->phy_reset) { -		/* Hold the PHY in RESET for enough time till -		 * PHY is settled and ready -		 */ -		udelay(10); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -			gpio_set_value -				(pdata->ehci_data->reset_gpio_port[0], 1); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -			gpio_set_value -				(pdata->ehci_data->reset_gpio_port[1], 1); -	} -  	spin_unlock_irqrestore(&omap->lock, flags);  	pm_runtime_put_sync(dev);  } -static void omap_usbhs_deinit(struct device *dev) -{ -	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev); -	struct usbhs_omap_platform_data	*pdata = &omap->platdata; - -	if (pdata->ehci_data->phy_reset) { -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -			gpio_free(pdata->ehci_data->reset_gpio_port[0]); - -		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -			gpio_free(pdata->ehci_data->reset_gpio_port[1]); -	} -} -  /**   * usbhs_omap_probe - initialize TI-based HCDs @@ -860,7 +817,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)  {  	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); -	omap_usbhs_deinit(&pdev->dev);  	iounmap(omap->tll_base);  	iounmap(omap->uhh_base);  	clk_put(omap->init_60m_fclk); diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index 99ef944c621..44afae0a69c 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = {  	{.name = "rc5t583-key",      }  }; -int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_write(rc5t583->regmap, reg, val); -} - -int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	unsigned int ival; -	int ret; -	ret = regmap_read(rc5t583->regmap, reg, &ival); -	if (!ret) -		*val = (uint8_t)ival; -	return ret; -} - -int rc5t583_set_bits(struct device *dev, unsigned int reg, -			unsigned int bit_mask) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); -} - -int rc5t583_clear_bits(struct device *dev, unsigned int reg, -			unsigned int bit_mask) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); -} - -int rc5t583_update(struct device *dev, unsigned int reg, -		unsigned int val, unsigned int mask) -{ -	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); -	return regmap_update_bits(rc5t583->regmap, reg, mask, val); -} -  static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,  	int id, int ext_pwr, int slots)  { @@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id,  			ds_id, ext_pwr_req);  	return 0;  } +EXPORT_SYMBOL(rc5t583_ext_power_req_config);  static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,  	struct rc5t583_platform_data *pdata) diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b2d8e512d3c..2d6bedadca0 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -30,7 +30,9 @@  #include <linux/platform_device.h>  #include <linux/gpio.h>  #include <linux/delay.h> -#include <linux/i2c/twl.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/err.h>  #include <linux/mfd/core.h>  #include <linux/mfd/twl6040.h> @@ -39,7 +41,7 @@  int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)  {  	int ret; -	u8 val = 0; +	unsigned int val;  	mutex_lock(&twl6040->io_mutex);  	/* Vibra control registers from cache */ @@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)  		     reg == TWL6040_REG_VIBCTLR)) {  		val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];  	} else { -		ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); +		ret = regmap_read(twl6040->regmap, reg, &val);  		if (ret < 0) {  			mutex_unlock(&twl6040->io_mutex);  			return ret; @@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)  	int ret;  	mutex_lock(&twl6040->io_mutex); -	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +	ret = regmap_write(twl6040->regmap, reg, val);  	/* Cache the vibra control registers */  	if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)  		twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; @@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write);  int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)  {  	int ret; -	u8 val;  	mutex_lock(&twl6040->io_mutex); -	ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); -	if (ret) -		goto out; - -	val |= mask; -	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); -out: +	ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);  	mutex_unlock(&twl6040->io_mutex);  	return ret;  } @@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits);  int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)  {  	int ret; -	u8 val;  	mutex_lock(&twl6040->io_mutex); -	ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); -	if (ret) -		goto out; - -	val &= ~mask; -	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); -out: +	ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);  	mutex_unlock(&twl6040->io_mutex);  	return ret;  } @@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = {  	},  }; -static int __devinit twl6040_probe(struct platform_device *pdev) +static bool twl6040_readable_reg(struct device *dev, unsigned int reg)  { -	struct twl4030_audio_data *pdata = pdev->dev.platform_data; +	/* Register 0 is not readable */ +	if (!reg) +		return false; +	return true; +} + +static struct regmap_config twl6040_regmap_config = { +	.reg_bits = 8, +	.val_bits = 8, +	.max_register = TWL6040_REG_STATUS, /* 0x2e */ + +	.readable_reg = twl6040_readable_reg, +}; + +static int __devinit twl6040_probe(struct i2c_client *client, +				     const struct i2c_device_id *id) +{ +	struct twl6040_platform_data *pdata = client->dev.platform_data;  	struct twl6040 *twl6040;  	struct mfd_cell *cell = NULL;  	int ret, children = 0;  	if (!pdata) { -		dev_err(&pdev->dev, "Platform data is missing\n"); +		dev_err(&client->dev, "Platform data is missing\n");  		return -EINVAL;  	}  	/* In order to operate correctly we need valid interrupt config */ -	if (!pdata->naudint_irq || !pdata->irq_base) { -		dev_err(&pdev->dev, "Invalid IRQ configuration\n"); +	if (!client->irq || !pdata->irq_base) { +		dev_err(&client->dev, "Invalid IRQ configuration\n");  		return -EINVAL;  	} -	twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); -	if (!twl6040) -		return -ENOMEM; +	twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), +			       GFP_KERNEL); +	if (!twl6040) { +		ret = -ENOMEM; +		goto err; +	} + +	twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); +	if (IS_ERR(twl6040->regmap)) { +		ret = PTR_ERR(twl6040->regmap); +		goto err; +	} -	platform_set_drvdata(pdev, twl6040); +	i2c_set_clientdata(client, twl6040); -	twl6040->dev = &pdev->dev; -	twl6040->irq = pdata->naudint_irq; +	twl6040->dev = &client->dev; +	twl6040->irq = client->irq;  	twl6040->irq_base = pdata->irq_base;  	mutex_init(&twl6040->mutex); @@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)  	}  	if (children) { -		ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, +		ret = mfd_add_devices(&client->dev, -1, twl6040->cells,  				      children, NULL, 0);  		if (ret)  			goto mfd_err;  	} else { -		dev_err(&pdev->dev, "No platform data found for children\n"); +		dev_err(&client->dev, "No platform data found for children\n");  		ret = -ENODEV;  		goto mfd_err;  	} @@ -608,14 +622,15 @@ gpio2_err:  	if (gpio_is_valid(twl6040->audpwron))  		gpio_free(twl6040->audpwron);  gpio1_err: -	platform_set_drvdata(pdev, NULL); -	kfree(twl6040); +	i2c_set_clientdata(client, NULL); +	regmap_exit(twl6040->regmap); +err:  	return ret;  } -static int __devexit twl6040_remove(struct platform_device *pdev) +static int __devexit twl6040_remove(struct i2c_client *client)  { -	struct twl6040 *twl6040 = platform_get_drvdata(pdev); +	struct twl6040 *twl6040 = i2c_get_clientdata(client);  	if (twl6040->power_count)  		twl6040_power(twl6040, 0); @@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev)  	free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);  	twl6040_irq_exit(twl6040); -	mfd_remove_devices(&pdev->dev); -	platform_set_drvdata(pdev, NULL); -	kfree(twl6040); +	mfd_remove_devices(&client->dev); +	i2c_set_clientdata(client, NULL); +	regmap_exit(twl6040->regmap);  	return 0;  } -static struct platform_driver twl6040_driver = { +static const struct i2c_device_id twl6040_i2c_id[] = { +	{ "twl6040", 0, }, +	{ }, +}; +MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); + +static struct i2c_driver twl6040_driver = { +	.driver = { +		.name = "twl6040", +		.owner = THIS_MODULE, +	},  	.probe		= twl6040_probe,  	.remove		= __devexit_p(twl6040_remove), -	.driver		= { -		.owner	= THIS_MODULE, -		.name	= "twl6040", -	}, +	.id_table	= twl6040_i2c_id,  }; -module_platform_driver(twl6040_driver); +module_i2c_driver(twl6040_driver);  MODULE_DESCRIPTION("TWL6040 MFD");  MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index b1809650b7a..dabec556ebb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,  {  	struct mmc_blk_data *md = mq->data;  	struct mmc_card *card = md->queue.card; -	unsigned int from, nr, arg; +	unsigned int from, nr, arg, trim_arg, erase_arg;  	int err = 0, type = MMC_BLK_SECDISCARD;  	if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { @@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,  		goto out;  	} +	from = blk_rq_pos(req); +	nr = blk_rq_sectors(req); +  	/* The sanitize operation is supported at v4.5 only */  	if (mmc_can_sanitize(card)) { -		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -				EXT_CSD_SANITIZE_START, 1, 0); -		goto out; +		erase_arg = MMC_ERASE_ARG; +		trim_arg = MMC_TRIM_ARG; +	} else { +		erase_arg = MMC_SECURE_ERASE_ARG; +		trim_arg = MMC_SECURE_TRIM1_ARG;  	} -	from = blk_rq_pos(req); -	nr = blk_rq_sectors(req); - -	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) -		arg = MMC_SECURE_TRIM1_ARG; -	else -		arg = MMC_SECURE_ERASE_ARG; +	if (mmc_erase_group_aligned(card, from, nr)) +		arg = erase_arg; +	else if (mmc_can_trim(card)) +		arg = trim_arg; +	else { +		err = -EINVAL; +		goto out; +	}  retry:  	if (card->quirks & MMC_QUIRK_INAND_CMD38) {  		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -904,25 +910,41 @@ retry:  				 INAND_CMD38_ARG_SECERASE,  				 0);  		if (err) -			goto out; +			goto out_retry;  	} +  	err = mmc_erase(card, from, nr, arg); -	if (!err && arg == MMC_SECURE_TRIM1_ARG) { +	if (err == -EIO) +		goto out_retry; +	if (err) +		goto out; + +	if (arg == MMC_SECURE_TRIM1_ARG) {  		if (card->quirks & MMC_QUIRK_INAND_CMD38) {  			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,  					 INAND_CMD38_ARG_EXT_CSD,  					 INAND_CMD38_ARG_SECTRIM2,  					 0);  			if (err) -				goto out; +				goto out_retry;  		} +  		err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); +		if (err == -EIO) +			goto out_retry; +		if (err) +			goto out;  	} -out: -	if (err == -EIO && !mmc_blk_reset(md, card->host, type)) + +	if (mmc_can_sanitize(card)) +		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, +				 EXT_CSD_SANITIZE_START, 1, 0); +out_retry: +	if (err && !mmc_blk_reset(md, card->host, type))  		goto retry;  	if (!err)  		mmc_blk_reset_success(md, type); +out:  	spin_lock_irq(&md->lock);  	__blk_end_request(req, err, blk_rq_bytes(req));  	spin_unlock_irq(&md->lock); @@ -1802,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card)  }  #ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) +static int mmc_blk_suspend(struct mmc_card *card)  {  	struct mmc_blk_data *part_md;  	struct mmc_blk_data *md = mmc_get_drvdata(card); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 2517547b436..996f8e36e23 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,  	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);  	q->limits.max_discard_sectors = max_discard; -	if (card->erased_byte == 0) +	if (card->erased_byte == 0 && !mmc_can_discard(card))  		q->limits.discard_zeroes_data = 1;  	q->limits.discard_granularity = card->pref_erase << 9;  	/* granularity must not be greater than max. discard */ diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 3f606068d55..c60cee92a2b 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev)  	return 0;  } -static int mmc_bus_suspend(struct device *dev, pm_message_t state) +static int mmc_bus_suspend(struct device *dev)  {  	struct mmc_driver *drv = to_mmc_driver(dev->driver);  	struct mmc_card *card = mmc_dev_to_card(dev);  	int ret = 0;  	if (dev->driver && drv->suspend) -		ret = drv->suspend(card, state); +		ret = drv->suspend(card);  	return ret;  } @@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev)  	return pm_runtime_suspend(dev);  } +#endif /* !CONFIG_PM_RUNTIME */ +  static const struct dev_pm_ops mmc_bus_pm_ops = { -	.runtime_suspend	= mmc_runtime_suspend, -	.runtime_resume		= mmc_runtime_resume, -	.runtime_idle		= mmc_runtime_idle, +	SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, +			mmc_runtime_idle) +	SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)  }; -#define MMC_PM_OPS_PTR	(&mmc_bus_pm_ops) - -#else /* !CONFIG_PM_RUNTIME */ - -#define MMC_PM_OPS_PTR	NULL - -#endif /* !CONFIG_PM_RUNTIME */ -  static struct bus_type mmc_bus_type = {  	.name		= "mmc",  	.dev_attrs	= mmc_dev_attrs, @@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = {  	.uevent		= mmc_bus_uevent,  	.probe		= mmc_bus_probe,  	.remove		= mmc_bus_remove, -	.suspend	= mmc_bus_suspend, -	.resume		= mmc_bus_resume, -	.pm		= MMC_PM_OPS_PTR, +	.pm		= &mmc_bus_pm_ops,  };  int mmc_register_bus(void) diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index 29de31e260d..2c14be73254 100644 --- a/drivers/mmc/core/cd-gpio.c +++ b/drivers/mmc/core/cd-gpio.c @@ -12,6 +12,7 @@  #include <linux/gpio.h>  #include <linux/interrupt.h>  #include <linux/jiffies.h> +#include <linux/mmc/cd-gpio.h>  #include <linux/mmc/host.h>  #include <linux/module.h>  #include <linux/slab.h> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7474c47b9c0..ba821fe70bc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1409,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,  {  	unsigned int erase_timeout; -	if (card->ext_csd.erase_group_def & 1) { +	if (arg == MMC_DISCARD_ARG || +	    (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { +		erase_timeout = card->ext_csd.trim_timeout; +	} else if (card->ext_csd.erase_group_def & 1) {  		/* High Capacity Erase Group Size uses HC timeouts */  		if (arg == MMC_TRIM_ARG)  			erase_timeout = card->ext_csd.trim_timeout; @@ -1681,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card)  {  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)  		return 1; -	if (mmc_can_discard(card)) -		return 1;  	return 0;  }  EXPORT_SYMBOL(mmc_can_trim); @@ -1701,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);  int mmc_can_sanitize(struct mmc_card *card)  { +	if (!mmc_can_trim(card) && !mmc_can_erase(card)) +		return 0;  	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)  		return 1;  	return 0; @@ -2235,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)  			mmc_card_is_removable(host))  		return err; +	mmc_claim_host(host);  	if (card && mmc_card_mmc(card) &&  			(card->ext_csd.cache_size > 0)) {  		enable = !!enable; @@ -2252,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)  				card->ext_csd.cache_ctrl = enable;  		}  	} +	mmc_release_host(host);  	return err;  } @@ -2269,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)  	cancel_delayed_work(&host->detect);  	mmc_flush_scheduled_work(); -	if (mmc_try_claim_host(host)) { -		err = mmc_cache_ctrl(host, 0); -		mmc_release_host(host); -	} else { -		err = -EBUSY; -	} +	err = mmc_cache_ctrl(host, 0);  	if (err)  		goto out;  	mmc_bus_get(host);  	if (host->bus_ops && !host->bus_dead) { -		/* -		 * A long response time is not acceptable for device drivers -		 * when doing suspend. Prevent mmc_claim_host in the suspend -		 * sequence, to potentially wait "forever" by trying to -		 * pre-claim the host. -		 */ -		if (mmc_try_claim_host(host)) { -			if (host->bus_ops->suspend) { -				err = host->bus_ops->suspend(host); -			} -			mmc_release_host(host); +		if (host->bus_ops->suspend) +			err = host->bus_ops->suspend(host); -			if (err == -ENOSYS || !host->bus_ops->resume) { -				/* -				 * We simply "remove" the card in this case. -				 * It will be redetected on resume.  (Calling -				 * bus_ops->remove() with a claimed host can -				 * deadlock.) -				 */ -				if (host->bus_ops->remove) -					host->bus_ops->remove(host); -				mmc_claim_host(host); -				mmc_detach_bus(host); -				mmc_power_off(host); -				mmc_release_host(host); -				host->pm_flags = 0; -				err = 0; -			} -		} else { -			err = -EBUSY; +		if (err == -ENOSYS || !host->bus_ops->resume) { +			/* +			 * We simply "remove" the card in this case. +			 * It will be redetected on resume.  (Calling +			 * bus_ops->remove() with a claimed host can +			 * deadlock.) +			 */ +			if (host->bus_ops->remove) +				host->bus_ops->remove(host); +			mmc_claim_host(host); +			mmc_detach_bus(host); +			mmc_power_off(host); +			mmc_release_host(host); +			host->pm_flags = 0; +			err = 0;  		}  	}  	mmc_bus_put(host); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bf3c9b456aa..ab3fc461710 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)  		return -ENODEV;  	sg_len = dw_mci_pre_dma_transfer(host, data, 0); -	if (sg_len < 0) +	if (sg_len < 0) { +		host->dma_ops->stop(host);  		return sg_len; +	}  	host->using_dma = 1; @@ -1879,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host)  	if (!host->dma_ops)  		goto no_dma; -	if (host->dma_ops->init) { +	if (host->dma_ops->init && host->dma_ops->start && +	    host->dma_ops->stop && host->dma_ops->cleanup) {  		if (host->dma_ops->init(host)) {  			dev_err(&host->dev, "%s: Unable to initialize "  				"DMA Controller.\n", __func__); diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index b0f2ef98818..e3f5af96ab8 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -363,6 +363,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)  		goto out;  	dmaengine_submit(desc); +	dma_async_issue_pending(host->dmach);  	return;  out: @@ -403,6 +404,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)  		goto out;  	dmaengine_submit(desc); +	dma_async_issue_pending(host->dmach);  	return;  out: @@ -531,6 +533,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)  		goto out;  	dmaengine_submit(desc); +	dma_async_issue_pending(host->dmach);  	return;  out:  	dev_warn(mmc_dev(host->mmc), diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5c2b1c10af9..56d4499d438 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,  	 * the pbias cell programming support is still missing when  	 * booting with Device tree  	 */ -	if (of_have_populated_dt() && !vdd) +	if (dev->of_node && !vdd)  		return 0;  	if (mmc_slot(host).before_set_reg) @@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  			 * can't be allowed when booting with device  			 * tree.  			 */ -			(!of_have_populated_dt())) { +			!host->dev->of_node) {  				/*  				 * The mmc_select_voltage fn of the core does  				 * not seem to set the power_mode to @@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = {  		.data = &omap4_reg_offset,  	},  	{}, -} +};  MODULE_DEVICE_TABLE(of, omap_mmc_of_match);  static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 6193a0d7bde..8abdaf6697a 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)  	clk_prepare_enable(clk);  	pltfm_host->clk = clk; -	if (!is_imx25_esdhc(imx_data)) -		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; +	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;  	if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))  		/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9aa77f3f04a..ccefdebeff1 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)  	u32 present, irqs;  	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || -	    !mmc_card_is_removable(host->mmc)) +	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))  		return;  	present = sdhci_readl(host, SDHCI_PRESENT_STATE) & diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 75b1dde1635..9ec51cec2e1 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -266,6 +266,7 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this,  	desc->callback		= dma_irq_callback;  	desc->callback_param	= this;  	dmaengine_submit(desc); +	dma_async_issue_pending(get_dma_chan(this));  	/* Wait for the interrupt from the DMA block. */  	err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 25197b698dd..b8b4c7ba884 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev)  	BUGLVL(D_NORMAL) printk(VERSION);  	BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); -	BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", +	BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",  	       dev->dev_addr[0], dev->mem_start, dev->irq);  	if (dev->mem_start <= 0 || dev->irq <= 0) { -		BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " +		BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "  		       "must specify the shmem and irq!\n");  		return -ENODEV;  	}  	if (dev->dev_addr[0] == 0) { -		BUGMSG(D_NORMAL, "You need to specify your card's station " +		BUGLVL(D_NORMAL) printk("You need to specify your card's station "  		       "ID!\n");  		return -ENODEV;  	} @@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev)  	 * will be taken.  	 */  	if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { -		BUGMSG(D_NORMAL, "Card memory already allocated\n"); +		BUGLVL(D_NORMAL) printk("Card memory already allocated\n");  		return -ENODEV;  	}  	return arcrimi_found(dev); diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 9a66e2a910a..9c1c8cd5223 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work)  		size_t fifo_occupancy = 0;  		/* Wakeup timeout */ -		dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", +		dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n",  			__func__);  		/* Check FIFO to check if modem has sent something. */  		WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,  					&fifo_occupancy)); -		dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", +		dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",  				__func__, (unsigned) fifo_occupancy);  		/* Check if we misssed the interrupt. */ @@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev)  static void cfhsi_shutdown(struct cfhsi *cfhsi)  { -	u8 *tx_buf, *rx_buf; +	u8 *tx_buf, *rx_buf, *flip_buf;  	/* Stop TXing */  	netif_tx_stop_all_queues(cfhsi->ndev); @@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)  	/* Store bufferes: will be freed later. */  	tx_buf = cfhsi->tx_buf;  	rx_buf = cfhsi->rx_buf; - +	flip_buf = cfhsi->rx_flip_buf;  	/* Flush transmit queues. */  	cfhsi_abort_tx(cfhsi); @@ -1247,6 +1247,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)  	/* Free buffers. */  	kfree(tx_buf);  	kfree(rx_buf); +	kfree(flip_buf);  }  int cfhsi_remove(struct platform_device *pdev) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 5234586dff1..629c4ba5d49 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -875,6 +875,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)  					    PCAN_USBPRO_INFO_FW,  					    &fi, sizeof(fi));  		if (err) { +			kfree(usb_if);  			dev_err(dev->netdev->dev.parent,  				"unable to read %s firmware info (err %d)\n",  				pcan_usb_pro.name, err); @@ -885,6 +886,7 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)  					    PCAN_USBPRO_INFO_BL,  					    &bi, sizeof(bi));  		if (err) { +			kfree(usb_if);  			dev_err(dev->netdev->dev.parent,  				"unable to read %s bootloader info (err %d)\n",  				pcan_usb_pro.name, err); diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index d5c6d92f1ee..442d91a2747 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev)  	return 0;  } -static void dummy_dev_free(struct net_device *dev) +static void dummy_dev_uninit(struct net_device *dev)  {  	free_percpu(dev->dstats); -	free_netdev(dev);  }  static const struct net_device_ops dummy_netdev_ops = {  	.ndo_init		= dummy_dev_init, +	.ndo_uninit		= dummy_dev_uninit,  	.ndo_start_xmit		= dummy_xmit,  	.ndo_validate_addr	= eth_validate_addr,  	.ndo_set_rx_mode	= set_multicast_list, @@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev)  	/* Initialize the device structure. */  	dev->netdev_ops = &dummy_netdev_ops; -	dev->destructor = dummy_dev_free; +	dev->destructor = free_netdev;  	/* Fill in device structure with ethernet-generic values. */  	dev->tx_queue_len = 0; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 40ac4143654..c926857e820 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)  					"pcie phy link down %x\n", status);  			if (netif_running(adapter->netdev)) {	/* reset MAC */  				iowrite32(0, adapter->hw.hw_addr + REG_IMR); -				schedule_work(&adapter->pcie_dma_to_rst_task); +				schedule_work(&adapter->reset_dev_task);  				return IRQ_HANDLED;  			}  		} @@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)  					"pcie DMA r/w error (status = 0x%x)\n",  					status);  			iowrite32(0, adapter->hw.hw_addr + REG_IMR); -			schedule_work(&adapter->pcie_dma_to_rst_task); +			schedule_work(&adapter->reset_dev_task);  			return IRQ_HANDLED;  		} @@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)  	atl1_clean_rx_ring(adapter);  } -static void atl1_tx_timeout_task(struct work_struct *work) +static void atl1_reset_dev_task(struct work_struct *work)  {  	struct atl1_adapter *adapter = -		container_of(work, struct atl1_adapter, tx_timeout_task); +		container_of(work, struct atl1_adapter, reset_dev_task);  	struct net_device *netdev = adapter->netdev;  	netif_device_detach(netdev); @@ -3038,12 +3038,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,  		    (unsigned long)adapter);  	adapter->phy_timer_pending = false; -	INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); +	INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);  	INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); -	INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); -  	err = register_netdev(netdev);  	if (err)  		goto err_common; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h index 109d6da8be9..e04bf4d71e4 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.h +++ b/drivers/net/ethernet/atheros/atlx/atl1.h @@ -758,9 +758,8 @@ struct atl1_adapter {  	u16 link_speed;  	u16 link_duplex;  	spinlock_t lock; -	struct work_struct tx_timeout_task; +	struct work_struct reset_dev_task;  	struct work_struct link_chg_task; -	struct work_struct pcie_dma_to_rst_task;  	struct timer_list phy_config_timer;  	bool phy_timer_pending; diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c index 3cd8837236d..c9e9dc57986 100644 --- a/drivers/net/ethernet/atheros/atlx/atlx.c +++ b/drivers/net/ethernet/atheros/atlx/atlx.c @@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev)  {  	struct atlx_adapter *adapter = netdev_priv(netdev);  	/* Do the reset outside of interrupt context */ -	schedule_work(&adapter->tx_timeout_task); +	schedule_work(&adapter->reset_dev_task);  }  /* diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index ad95324dc04..64392ec410a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -942,6 +942,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,  	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :  		DCBX_E3B0_MAX_NUM_COS_PORT0; +	if (pri >= max_num_of_cos) { +		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " +		   "parameter Illegal strict priority\n"); +	    return -EINVAL; +	} +  	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {  		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "  				   "parameter There can't be two COS's with " @@ -949,12 +955,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,  		return -EINVAL;  	} -	if (pri > max_num_of_cos) { -		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " -		   "parameter Illegal strict priority\n"); -	    return -EINVAL; -	} -  	sp_pri_to_cos[pri] = cos_entry;  	return 0; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 64c76443a7a..b461c24945e 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1310,10 +1310,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)  		if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)  			oem_reg |= HV_OEM_BITS_LPLU; - -		/* Set Restart auto-neg to activate the bits */ -		if (!hw->phy.ops.check_reset_block(hw)) -			oem_reg |= HV_OEM_BITS_RESTART_AN;  	} else {  		if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |  			       E1000_PHY_CTRL_NOND0A_GBE_DISABLE)) @@ -1324,6 +1320,11 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)  			oem_reg |= HV_OEM_BITS_LPLU;  	} +	/* Set Restart auto-neg to activate the bits */ +	if ((d0_state || (hw->mac.type != e1000_pchlan)) && +	    !hw->phy.ops.check_reset_block(hw)) +		oem_reg |= HV_OEM_BITS_RESTART_AN; +  	ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);  release: @@ -3682,7 +3683,11 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)  	if (hw->mac.type >= e1000_pchlan) {  		e1000_oem_bits_config_ich8lan(hw, false); -		e1000_phy_hw_reset_ich8lan(hw); + +		/* Reset PHY to activate OEM bits on 82577/8 */ +		if (hw->mac.type == e1000_pchlan) +			e1000e_phy_hw_reset_generic(hw); +  		ret_val = hw->phy.ops.acquire(hw);  		if (ret_val)  			return; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index 027d7a75be3..ed1b47dc083 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -622,6 +622,16 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx,  		if (adapter->hw.mac.type == ixgbe_mac_82599EB)  			set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); +#ifdef IXGBE_FCOE +		if (adapter->netdev->features & NETIF_F_FCOE_MTU) { +			struct ixgbe_ring_feature *f; +			f = &adapter->ring_feature[RING_F_FCOE]; +			if ((rxr_idx >= f->mask) && +			    (rxr_idx < f->mask + f->indices)) +				set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); +		} + +#endif /* IXGBE_FCOE */  		/* apply Rx specific ring traits */  		ring->count = adapter->rx_ring_count;  		ring->queue_index = rxr_idx; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 3e26b1f9ac7..a7f3cd872ca 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3154,14 +3154,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)  			set_ring_rsc_enabled(rx_ring);  		else  			clear_ring_rsc_enabled(rx_ring); -#ifdef IXGBE_FCOE -		if (netdev->features & NETIF_F_FCOE_MTU) { -			struct ixgbe_ring_feature *f; -			f = &adapter->ring_feature[RING_F_FCOE]; -			if ((i >= f->mask) && (i < f->mask + f->indices)) -				set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); -		} -#endif /* IXGBE_FCOE */  	}  } @@ -4836,7 +4828,9 @@ static int ixgbe_resume(struct pci_dev *pdev)  	pci_wake_from_d3(pdev, false); +	rtnl_lock();  	err = ixgbe_init_interrupt_scheme(adapter); +	rtnl_unlock();  	if (err) {  		e_dev_err("Cannot initialize interrupts for device\n");  		return err; @@ -4893,6 +4887,16 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)  	if (wufc) {  		ixgbe_set_rx_mode(netdev); +		/* +		 * enable the optics for both mult-speed fiber and +		 * 82599 SFP+ fiber as we can WoL. +		 */ +		if (hw->mac.ops.enable_tx_laser && +		    (hw->phy.multispeed_fiber || +		    (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber && +		     hw->mac.type == ixgbe_mac_82599EB))) +			hw->mac.ops.enable_tx_laser(hw); +  		/* turn on all-multi mode if wake on multicast is enabled */  		if (wufc & IXGBE_WUFC_MC) {  			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index c722aa607d0..f8dda009d3c 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -889,16 +889,17 @@ static int ks8851_net_stop(struct net_device *dev)  	netif_stop_queue(dev);  	mutex_lock(&ks->lock); +	/* turn off the IRQs and ack any outstanding */ +	ks8851_wrreg16(ks, KS_IER, 0x0000); +	ks8851_wrreg16(ks, KS_ISR, 0xffff); +	mutex_unlock(&ks->lock);  	/* stop any outstanding work */  	flush_work(&ks->irq_work);  	flush_work(&ks->tx_work);  	flush_work(&ks->rxctrl_work); -	/* turn off the IRQs and ack any outstanding */ -	ks8851_wrreg16(ks, KS_IER, 0x0000); -	ks8851_wrreg16(ks, KS_ISR, 0xffff); - +	mutex_lock(&ks->lock);  	/* shutdown RX process */  	ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -907,6 +908,7 @@ static int ks8851_net_stop(struct net_device *dev)  	/* set powermode to soft power down to save power */  	ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); +	mutex_unlock(&ks->lock);  	/* ensure any queued tx buffers are dumped */  	while (!skb_queue_empty(&ks->txq)) { @@ -918,7 +920,6 @@ static int ks8851_net_stop(struct net_device *dev)  		dev_kfree_skb(txb);  	} -	mutex_unlock(&ks->lock);  	return 0;  } @@ -1418,6 +1419,7 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	struct net_device *ndev;  	struct ks8851_net *ks;  	int ret; +	unsigned cider;  	ndev = alloc_etherdev(sizeof(struct ks8851_net));  	if (!ndev) @@ -1484,8 +1486,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	ks8851_soft_reset(ks, GRR_GSR);  	/* simple check for a valid chip being connected to the bus */ - -	if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { +	cider = ks8851_rdreg16(ks, KS_CIDER); +	if ((cider & ~CIDER_REV_MASK) != CIDER_ID) {  		dev_err(&spi->dev, "failed to read device ID\n");  		ret = -ENODEV;  		goto err_id; @@ -1516,15 +1518,14 @@ static int __devinit ks8851_probe(struct spi_device *spi)  	}  	netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n", -		    CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), -		    ndev->dev_addr, ndev->irq, +		    CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq,  		    ks->rc_ccr & CCR_EEPROM ? "has" : "no");  	return 0;  err_netdev: -	free_irq(ndev->irq, ndev); +	free_irq(ndev->irq, ks);  err_id:  err_irq: diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index b8104d9f408..5ffde23ac8f 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -40,7 +40,7 @@  #define	DRV_NAME	"ks8851_mll"  static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES			32 +#define MAX_RECV_FRAMES			255  #define MAX_BUF_SIZE			2048  #define TX_BUF_SIZE			2000  #define RX_BUF_SIZE			2000 diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index ef723b185d8..eaf9ff0262a 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)  		memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);  	} -	memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); +	memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);  	interrupt = hw_block_intr(hw); diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index abc79076f86..b3287c0fe27 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -958,6 +958,11 @@ static inline void cp_start_hw (struct cp_private *cp)  	cpw8(Cmd, RxOn | TxOn);  } +static void cp_enable_irq(struct cp_private *cp) +{ +	cpw16_f(IntrMask, cp_intr_mask); +} +  static void cp_init_hw (struct cp_private *cp)  {  	struct net_device *dev = cp->dev; @@ -997,8 +1002,6 @@ static void cp_init_hw (struct cp_private *cp)  	cpw16(MultiIntr, 0); -	cpw16_f(IntrMask, cp_intr_mask); -  	cpw8_f(Cfg9346, Cfg9346_Lock);  } @@ -1130,6 +1133,8 @@ static int cp_open (struct net_device *dev)  	if (rc)  		goto err_out_hw; +	cp_enable_irq(cp); +  	netif_carrier_off(dev);  	mii_check_media(&cp->mii_if, netif_msg_link(cp), true);  	netif_start_queue(dev); @@ -2031,6 +2036,7 @@ static int cp_resume (struct pci_dev *pdev)  	/* FIXME: sh*t may happen if the Rx ring buffer is depleted */  	cp_init_rings_index (cp);  	cp_init_hw (cp); +	cp_enable_irq(cp);  	netif_start_queue (dev);  	spin_lock_irqsave (&cp->lock, flags); diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 4a697102707..cd3defb11ff 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1166,10 +1166,8 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)  /* Quickly dumps bad packets */  static void -smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)  { -	unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; -  	if (likely(pktwords >= 4)) {  		unsigned int timeout = 500;  		unsigned int val; @@ -1233,7 +1231,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)  			continue;  		} -		skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); +		skb = netdev_alloc_skb(dev, pktwords << 2);  		if (unlikely(!skb)) {  			SMSC_WARN(pdata, rx_err,  				  "Unable to allocate skb for rx packet"); @@ -1243,14 +1241,12 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)  			break;  		} -		skb->data = skb->head; -		skb_reset_tail_pointer(skb); +		pdata->ops->rx_readfifo(pdata, +				 (unsigned int *)skb->data, pktwords);  		/* Align IP on 16B boundary */  		skb_reserve(skb, NET_IP_ALIGN);  		skb_put(skb, pktlength - 4); -		pdata->ops->rx_readfifo(pdata, -				 (unsigned int *)skb->head, pktwords);  		skb->protocol = eth_type_trans(skb, dev);  		skb_checksum_none_assert(skb);  		netif_receive_skb(skb); @@ -1565,7 +1561,7 @@ static int smsc911x_open(struct net_device *dev)  	smsc911x_reg_write(pdata, FIFO_INT, temp);  	/* set RX Data offset to 2 bytes for alignment */ -	smsc911x_reg_write(pdata, RX_CFG, (2 << 8)); +	smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));  	/* enable NAPI polling before enabling RX interrupts */  	napi_enable(&pdata->napi); @@ -2382,7 +2378,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)  	SET_NETDEV_DEV(dev, &pdev->dev);  	pdata = netdev_priv(dev); -  	dev->irq = irq_res->start;  	irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;  	pdata->ioaddr = ioremap_nocache(res->start, res_size); @@ -2446,7 +2441,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)  	if (retval) {  		SMSC_WARN(pdata, probe,  			  "Unable to claim requested irq: %d", dev->irq); -		goto out_free_irq; +		goto out_disable_resources;  	}  	retval = register_netdev(dev); diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 2757c7d6e63..e4e47088e26 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -181,6 +181,11 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)  		__davinci_mdio_reset(data);  		return -EAGAIN;  	} + +	reg = __raw_readl(®s->user[0].access); +	if ((reg & USERACCESS_GO) == 0) +		return 0; +  	dev_err(data->dev, "timed out waiting for user access\n");  	return -ETIMEDOUT;  } diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h index cc83af083fd..44b8d2bad8c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -2,9 +2,7 @@   * Definitions for Xilinx Axi Ethernet device driver.   *   * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   */  #ifndef XILINX_AXIENET_H diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 2fcbeba6814..9c365e192a3 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -4,9 +4,9 @@   * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi   * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>   * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu> + * Copyright (c) 2010 - 2011 PetaLogix + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   *   * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6   * and Spartan6. diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index d70b6e79f6c..e90e1f46121 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -2,9 +2,9 @@   * MDIO bus driver for the Xilinx Axi Ethernet device   *   * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 Xilinx, Inc. All rights reserved. - * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch> - * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch> + * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu> + * Copyright (c) 2010 - 2011 PetaLogix + * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.   */  #include <linux/of_address.h> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index dd294783b5c..2d59138db7f 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -44,6 +44,7 @@ struct net_device_context {  	/* point back to our device context */  	struct hv_device *device_ctx;  	struct delayed_work dwork; +	struct work_struct work;  }; @@ -51,30 +52,22 @@ static int ring_size = 128;  module_param(ring_size, int, S_IRUGO);  MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); -struct set_multicast_work { -	struct work_struct work; -	struct net_device *net; -}; -  static void do_set_multicast(struct work_struct *w)  { -	struct set_multicast_work *swk = -		container_of(w, struct set_multicast_work, work); -	struct net_device *net = swk->net; - -	struct net_device_context *ndevctx = netdev_priv(net); +	struct net_device_context *ndevctx = +		container_of(w, struct net_device_context, work);  	struct netvsc_device *nvdev;  	struct rndis_device *rdev;  	nvdev = hv_get_drvdata(ndevctx->device_ctx); -	if (nvdev == NULL) -		goto out; +	if (nvdev == NULL || nvdev->ndev == NULL) +		return;  	rdev = nvdev->extension;  	if (rdev == NULL) -		goto out; +		return; -	if (net->flags & IFF_PROMISC) +	if (nvdev->ndev->flags & IFF_PROMISC)  		rndis_filter_set_packet_filter(rdev,  			NDIS_PACKET_TYPE_PROMISCUOUS);  	else @@ -82,21 +75,13 @@ static void do_set_multicast(struct work_struct *w)  			NDIS_PACKET_TYPE_BROADCAST |  			NDIS_PACKET_TYPE_ALL_MULTICAST |  			NDIS_PACKET_TYPE_DIRECTED); - -out: -	kfree(w);  }  static void netvsc_set_multicast_list(struct net_device *net)  { -	struct set_multicast_work *swk = -		kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); -	if (swk == NULL) -		return; +	struct net_device_context *net_device_ctx = netdev_priv(net); -	swk->net = net; -	INIT_WORK(&swk->work, do_set_multicast); -	schedule_work(&swk->work); +	schedule_work(&net_device_ctx->work);  }  static int netvsc_open(struct net_device *net) @@ -125,6 +110,8 @@ static int netvsc_close(struct net_device *net)  	netif_tx_disable(net); +	/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ +	cancel_work_sync(&net_device_ctx->work);  	ret = rndis_filter_close(device_obj);  	if (ret != 0)  		netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -335,6 +322,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)  	nvdev->start_remove = true;  	cancel_delayed_work_sync(&ndevctx->dwork); +	cancel_work_sync(&ndevctx->work);  	netif_tx_disable(ndev);  	rndis_filter_device_remove(hdev); @@ -403,6 +391,7 @@ static int netvsc_probe(struct hv_device *dev,  	net_device_ctx->device_ctx = dev;  	hv_set_drvdata(dev, net);  	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); +	INIT_WORK(&net_device_ctx->work, do_set_multicast);  	net->netdev_ops = &device_ops; @@ -456,6 +445,7 @@ static int netvsc_remove(struct hv_device *dev)  	ndev_ctx = netdev_priv(net);  	cancel_delayed_work_sync(&ndev_ctx->dwork); +	cancel_work_sync(&ndev_ctx->work);  	/* Stop outbound asap */  	netif_tx_disable(net); diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index f08c85acf76..5ac46f5226f 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");  #define IP1001_PHASE_SEL_MASK		3	/* IP1001 RX/TXPHASE_SEL */  #define IP1001_APS_ON			11	/* IP1001 APS Mode  bit */  #define IP101A_G_APS_ON			2	/* IP101A/G APS Mode bit */ +#define IP101A_G_IRQ_CONF_STATUS	0x11	/* Conf Info IRQ & Status Reg */  static int ip175c_config_init(struct phy_device *phydev)  { @@ -185,6 +186,15 @@ static int ip175c_config_aneg(struct phy_device *phydev)  	return 0;  } +static int ip101a_g_ack_interrupt(struct phy_device *phydev) +{ +	int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); +	if (err < 0) +		return err; + +	return 0; +} +  static struct phy_driver ip175c_driver = {  	.phy_id		= 0x02430d80,  	.name		= "ICPlus IP175C", @@ -204,7 +214,6 @@ static struct phy_driver ip1001_driver = {  	.phy_id_mask	= 0x0ffffff0,  	.features	= PHY_GBIT_FEATURES | SUPPORTED_Pause |  			  SUPPORTED_Asym_Pause, -	.flags		= PHY_HAS_INTERRUPT,  	.config_init	= &ip1001_config_init,  	.config_aneg	= &genphy_config_aneg,  	.read_status	= &genphy_read_status, @@ -220,6 +229,7 @@ static struct phy_driver ip101a_g_driver = {  	.features	= PHY_BASIC_FEATURES | SUPPORTED_Pause |  			  SUPPORTED_Asym_Pause,  	.flags		= PHY_HAS_INTERRUPT, +	.ack_interrupt	= ip101a_g_ack_interrupt,  	.config_init	= &ip101a_g_config_init,  	.config_aneg	= &genphy_config_aneg,  	.read_status	= &genphy_read_status, diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 33f8c51968b..21d7151fb0a 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -235,7 +235,7 @@ struct ppp_net {  /* Prototypes. */  static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,  			struct file *file, unsigned int cmd, unsigned long arg); -static int ppp_xmit_process(struct ppp *ppp); +static void ppp_xmit_process(struct ppp *ppp);  static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);  static void ppp_push(struct ppp *ppp);  static void ppp_channel_push(struct channel *pch); @@ -969,8 +969,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)  	put_unaligned_be16(proto, pp);  	skb_queue_tail(&ppp->file.xq, skb); -	if (!ppp_xmit_process(ppp)) -		netif_stop_queue(dev); +	ppp_xmit_process(ppp);  	return NETDEV_TX_OK;   outf: @@ -1048,11 +1047,10 @@ static void ppp_setup(struct net_device *dev)   * Called to do any work queued up on the transmit side   * that can now be done.   */ -static int +static void  ppp_xmit_process(struct ppp *ppp)  {  	struct sk_buff *skb; -	int ret = 0;  	ppp_xmit_lock(ppp);  	if (!ppp->closing) { @@ -1062,13 +1060,12 @@ ppp_xmit_process(struct ppp *ppp)  			ppp_send_frame(ppp, skb);  		/* If there's no work left to do, tell the core net  		   code that we can accept some more. */ -		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) { +		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))  			netif_wake_queue(ppp->dev); -			ret = 1; -		} +		else +			netif_stop_queue(ppp->dev);  	}  	ppp_xmit_unlock(ppp); -	return ret;  }  static inline struct sk_buff * diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 552d24bf862..d316503b35d 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -365,6 +365,27 @@ static const struct driver_info	qmi_wwan_force_int4 = {  	.data		= BIT(4), /* interface whitelist bitmap */  }; +/* Sierra Wireless provide equally useless interface descriptors + * Devices in QMI mode can be switched between two different + * configurations: + *   a) USB interface #8 is QMI/wwan + *   b) USB interfaces #8, #19 and #20 are QMI/wwan + * + * Both configurations provide a number of other interfaces (serial++), + * some of which have the same endpoint configuration as we expect, so + * a whitelist or blacklist is necessary. + * + * FIXME: The below whitelist should include BIT(20).  It does not + * because I cannot get it to work... + */ +static const struct driver_info	qmi_wwan_sierra = { +	.description	= "Sierra Wireless wwan/QMI device", +	.flags		= FLAG_WWAN, +	.bind		= qmi_wwan_bind_gobi, +	.unbind		= qmi_wwan_unbind_shared, +	.manage_power	= qmi_wwan_manage_power, +	.data		= BIT(8) | BIT(19), /* interface whitelist bitmap */ +};  #define HUAWEI_VENDOR_ID	0x12D1  #define QMI_GOBI_DEVICE(vend, prod) \ @@ -445,6 +466,15 @@ static const struct usb_device_id products[] = {  		.bInterfaceProtocol = 0xff,  		.driver_info        = (unsigned long)&qmi_wwan_force_int4,  	}, +	{	/* Sierra Wireless MC77xx in QMI mode */ +		.match_flags	    = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, +		.idVendor           = 0x1199, +		.idProduct          = 0x68a2, +		.bInterfaceClass    = 0xff, +		.bInterfaceSubClass = 0xff, +		.bInterfaceProtocol = 0xff, +		.driver_info        = (unsigned long)&qmi_wwan_sierra, +	},  	{QMI_GOBI_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */  	{QMI_GOBI_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */  	{QMI_GOBI_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */ diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 187d01ccb97..a2349483cd2 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1051,6 +1051,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->net->ethtool_ops = &smsc75xx_ethtool_ops;  	dev->net->flags |= IFF_MULTICAST;  	dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; +	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;  	return 0;  } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4de2760c593..af8acc85f4b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -626,16 +626,15 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)  	/* This can happen with OOM and indirect buffers. */  	if (unlikely(capacity < 0)) {  		if (likely(capacity == -ENOMEM)) { -			if (net_ratelimit()) { +			if (net_ratelimit())  				dev_warn(&dev->dev,  					 "TX queue failure: out of memory\n"); -			} else { +		} else {  			dev->stats.tx_fifo_errors++;  			if (net_ratelimit())  				dev_warn(&dev->dev,  					 "Unexpected TX queue failure: %d\n",  					 capacity); -			}  		}  		dev->stats.tx_dropped++;  		kfree_skb(skb); diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index ebb9f24eefb..1a623183cbe 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2483,6 +2483,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)  		pr_err("Control memory remap failed\n");  		pci_release_regions(pdev);  		pci_disable_device(pdev); +		iounmap(card->mem);  		kfree(card);  		return -ENODEV;  	} diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 8faa129da5a..8c50d9d19d7 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -19,6 +19,7 @@  #include <linux/nl80211.h>  #include <linux/platform_device.h>  #include <linux/etherdevice.h> +#include <linux/export.h>  #include <ar231x_platform.h>  #include "ath5k.h"  #include "debug.h" @@ -119,7 +120,7 @@ static int ath_ahb_probe(struct platform_device *pdev)  	if (res == NULL) {  		dev_err(&pdev->dev, "no IRQ resource found\n");  		ret = -ENXIO; -		goto err_out; +		goto err_iounmap;  	}  	irq = res->start; @@ -128,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev)  	if (hw == NULL) {  		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");  		ret = -ENOMEM; -		goto err_out; +		goto err_iounmap;  	}  	ah = hw->priv; @@ -185,6 +186,8 @@ static int ath_ahb_probe(struct platform_device *pdev)   err_free_hw:  	ieee80211_free_hw(hw);  	platform_set_drvdata(pdev, NULL); + err_iounmap: +        iounmap(mem);   err_out:  	return ret;  } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2504ab00558..798ea57252b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1548,6 +1548,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  	struct ath_hw *ah = sc->sc_ah;  	struct ath_common *common = ath9k_hw_common(ah);  	struct ieee80211_conf *conf = &hw->conf; +	bool reset_channel = false;  	ath9k_ps_wakeup(sc);  	mutex_lock(&sc->mutex); @@ -1556,6 +1557,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  		sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);  		if (sc->ps_idle)  			ath_cancel_work(sc); +		else +			/* +			 * The chip needs a reset to properly wake up from +			 * full sleep +			 */ +			reset_channel = ah->chip_fullsleep;  	}  	/* @@ -1584,7 +1591,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)  		}  	} -	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { +	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {  		struct ieee80211_channel *curchan = hw->conf.channel;  		int pos = curchan->hw_value;  		int old_pos = -1; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 834e6bc45e8..23eaa1b26eb 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1820,6 +1820,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,  	struct ath_frame_info *fi = get_frame_info(skb);  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;  	struct ath_buf *bf; +	int fragno;  	u16 seqno;  	bf = ath_tx_get_buffer(sc); @@ -1831,9 +1832,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,  	ATH_TXBUF_RESET(bf);  	if (tid) { +		fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;  		seqno = tid->seq_next;  		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); -		INCR(tid->seq_next, IEEE80211_SEQ_MAX); + +		if (fragno) +			hdr->seq_ctrl |= cpu_to_le16(fragno); + +		if (!ieee80211_has_morefrags(hdr->frame_control)) +			INCR(tid->seq_next, IEEE80211_SEQ_MAX); +  		bf->bf_state.seqno = seqno;  	} diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 231ddf4a674..7083db75b00 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -7614,6 +7614,7 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,  {  	int len_mpdu;  	struct ieee80211_rx_status rx_status; +	struct ieee80211_hdr *hdr;  	memset(&rx_status, 0, sizeof(rx_status));  	prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -7623,6 +7624,13 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,  	skb_pull(p, D11_PHY_HDR_LEN);  	__skb_trim(p, len_mpdu); +	/* unmute transmit */ +	if (wlc->hw->suspended_fifos) { +		hdr = (struct ieee80211_hdr *)p->data; +		if (ieee80211_is_beacon(hdr->frame_control)) +			brcms_b_mute(wlc->hw, false); +	} +  	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));  	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);  } diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 3fa1ecebadf..2fa879b015b 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -103,7 +103,7 @@ static const u32 cipher_suites[] = {   * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1   * in the firmware spec   */ -static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)  {  	int ret = -ENOTSUPP; @@ -1411,7 +1411,12 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,  		goto done;  	} -	lbs_set_authtype(priv, sme); +	ret = lbs_set_authtype(priv, sme); +	if (ret == -ENOTSUPP) { +		wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); +		goto done; +	} +  	lbs_set_radio(priv, preamble, 1);  	/* Do the actual association */ diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 445ff21772e..2f218f9a3fd 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -48,15 +48,15 @@  #define PCIE_HOST_INT_STATUS_MASK			0xC3C  #define PCIE_SCRATCH_2_REG				0xC40  #define PCIE_SCRATCH_3_REG				0xC44 -#define PCIE_SCRATCH_4_REG				0xCC0 -#define PCIE_SCRATCH_5_REG				0xCC4 -#define PCIE_SCRATCH_6_REG				0xCC8 -#define PCIE_SCRATCH_7_REG				0xCCC -#define PCIE_SCRATCH_8_REG				0xCD0 -#define PCIE_SCRATCH_9_REG				0xCD4 -#define PCIE_SCRATCH_10_REG				0xCD8 -#define PCIE_SCRATCH_11_REG				0xCDC -#define PCIE_SCRATCH_12_REG				0xCE0 +#define PCIE_SCRATCH_4_REG				0xCD0 +#define PCIE_SCRATCH_5_REG				0xCD4 +#define PCIE_SCRATCH_6_REG				0xCD8 +#define PCIE_SCRATCH_7_REG				0xCDC +#define PCIE_SCRATCH_8_REG				0xCE0 +#define PCIE_SCRATCH_9_REG				0xCE4 +#define PCIE_SCRATCH_10_REG				0xCE8 +#define PCIE_SCRATCH_11_REG				0xCEC +#define PCIE_SCRATCH_12_REG				0xCF0  #define CPU_INTR_DNLD_RDY				BIT(0)  #define CPU_INTR_DOOR_BELL				BIT(1) diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 083a49fee56..165274c064b 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o  obj-$(CONFIG_PARISC) += setup-bus.o  obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o  obj-$(CONFIG_PPC) += setup-bus.o +obj-$(CONFIG_FRV) += setup-bus.o  obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o  obj-$(CONFIG_X86_VISWS) += setup-irq.o  obj-$(CONFIG_MN10300) += setup-bus.o diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index ec3b8cc188a..df6296c5f47 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -908,10 +908,6 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)  	const struct pinctrl_ops *ops = pctldev->desc->pctlops;  	unsigned selector = 0; -	/* No grouping */ -	if (!ops) -		return 0; -  	mutex_lock(&pinctrl_mutex);  	seq_puts(s, "registered pin groups:\n"); @@ -1225,6 +1221,19 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)  #endif +static int pinctrl_check_ops(struct pinctrl_dev *pctldev) +{ +	const struct pinctrl_ops *ops = pctldev->desc->pctlops; + +	if (!ops || +	    !ops->list_groups || +	    !ops->get_group_name || +	    !ops->get_group_pins) +		return -EINVAL; + +	return 0; +} +  /**   * pinctrl_register() - register a pin controller device   * @pctldesc: descriptor for this pin controller @@ -1256,6 +1265,14 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,  	INIT_LIST_HEAD(&pctldev->gpio_ranges);  	pctldev->dev = dev; +	/* check core ops for sanity */ +	ret = pinctrl_check_ops(pctldev); +	if (ret) { +		pr_err("%s pinctrl ops lacks necessary functions\n", +			pctldesc->name); +		goto out_err; +	} +  	/* If we're implementing pinmuxing, check the ops for sanity */  	if (pctldesc->pmxops) {  		ret = pinmux_check_ops(pctldev); diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index bc8384c6f3e..639db4d0aa7 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -50,7 +50,7 @@   */  #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.24" +#define DRV_VER "0.5.26"  /*   * According to the Atom N270 datasheet, @@ -83,8 +83,8 @@ static int kernelmode;  #endif  static unsigned int interval = 10; -static unsigned int fanon = 63000; -static unsigned int fanoff = 58000; +static unsigned int fanon = 60000; +static unsigned int fanoff = 53000;  static unsigned int verbose;  static unsigned int fanstate = ACERHDF_FAN_AUTO;  static char force_bios[16]; @@ -150,6 +150,8 @@ static const struct bios_settings_t bios_tbl[] = {  	{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },  	{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },  	{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, +	/* LT1005u */ +	{"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} },  	/* Acer 1410 */  	{"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, @@ -161,6 +163,7 @@ static const struct bios_settings_t bios_tbl[] = {  	{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, +	{"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },  	/* Acer 1810xx */  	{"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1810T",  "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, @@ -183,29 +186,44 @@ static const struct bios_settings_t bios_tbl[] = {  	{"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1810T",  "v1.3310", 0x55, 0x58, {0x9e, 0x00} },  	{"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, +	{"Acer", "Aspire 1810T",  "v1.3314", 0x55, 0x58, {0x9e, 0x00} },  	/* Acer 531 */ +	{"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} },  	{"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, +	{"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, +	/* Acer 751 */ +	{"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} }, +	/* Acer 1825 */ +	{"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, +	{"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, +	/* Acer TravelMate 7730 */ +	{"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} },  	/* Gateway */ -	{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, -	{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, -	{"Gateway", "LT31",   "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, -	{"Gateway", "LT31",   "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, -	{"Gateway", "LT31",   "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "AOA110", "v0.3103",  0x55, 0x58, {0x21, 0x00} }, +	{"Gateway", "AOA150", "v0.3103",  0x55, 0x58, {0x20, 0x00} }, +	{"Gateway", "LT31",   "v1.3103",  0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "LT31",   "v1.3201",  0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "LT31",   "v1.3302",  0x55, 0x58, {0x9e, 0x00} }, +	{"Gateway", "LT31",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00} },  	/* Packard Bell */ -	{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, -	{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, -	{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, -	{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, -	{"Packard Bell", "DOTMU",  "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMU",  "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMA",  "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, -	{"Packard Bell", "DOTMA",  "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOA150",  "v0.3104",  0x55, 0x58, {0x21, 0x00} }, +	{"Packard Bell", "DOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00} }, +	{"Packard Bell", "AOA110",  "v0.3105",  0x55, 0x58, {0x21, 0x00} }, +	{"Packard Bell", "AOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00} }, +	{"Packard Bell", "ENBFT",   "V1.3118",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "ENBFT",   "V1.3127",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v1.3303",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3120",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3108",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3113",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3115",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3117",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v0.3119",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMU",   "v1.3204",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMA",   "v1.3201",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMA",   "v1.3302",  0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTMA",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, +	{"Packard Bell", "DOTVR46", "v1.3308",  0x55, 0x58, {0x9e, 0x00} },  	/* pewpew-terminator */  	{"", "", "", 0, 0, {0, 0} }  }; @@ -701,15 +719,20 @@ MODULE_LICENSE("GPL");  MODULE_AUTHOR("Peter Feuerer");  MODULE_DESCRIPTION("Aspire One temperature and fan driver");  MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:");  MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:");  MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:");  MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); +MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:");  MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");  MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); +MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:");  MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); +MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:");  module_init(acerhdf_init);  module_exit(acerhdf_exit); diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index a05fc9c955d..e6c08ee8d46 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -212,6 +212,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {  		},  		.driver_data = &quirk_dell_vostro_v130,  	}, +	{ }  };  static struct calling_interface_buffer *buffer; diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index f7ba316e0ed..0ffdb3cde2b 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1565,7 +1565,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)  		ips->poll_turbo_status = true;  	if (!ips_get_i915_syms(ips)) { -		dev_err(&dev->dev, "failed to get i915 symbols, graphics turbo disabled\n"); +		dev_info(&dev->dev, "failed to get i915 symbols, graphics turbo disabled until i915 loads\n");  		ips->gpu_turbo_enabled = false;  	} else {  		dev_dbg(&dev->dev, "graphics turbo enabled\n"); diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index cd188ab72f7..c293d0cdb10 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -902,6 +902,7 @@ read_rtc:  		}  		ds1307->nvram->attr.name = "nvram";  		ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; +		sysfs_bin_attr_init(ds1307->nvram);  		ds1307->nvram->read = ds1307_nvram_read,  		ds1307->nvram->write = ds1307_nvram_write,  		ds1307->nvram->size = chip->nvram_size; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3ed748355b9..00c024039c9 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -74,7 +74,7 @@ config SPI_ATMEL  	  This selects a driver for the Atmel SPI Controller, present on  	  many AT32 (AVR32) and AT91 (ARM) chips. -config SPI_BFIN +config SPI_BFIN5XX  	tristate "SPI controller driver for ADI Blackfin5xx"  	depends on BLACKFIN  	help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index a1d48e0ba3d..9d75d2198ff 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o  obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o  obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o  obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o -obj-$(CONFIG_SPI_BFIN)			+= spi-bfin5xx.o +obj-$(CONFIG_SPI_BFIN5XX)		+= spi-bfin5xx.o  obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o  obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o  obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index f01b2648452..7491971139a 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -1,7 +1,7 @@  /*   * Broadcom BCM63xx SPI controller support   * - * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> + * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>   * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>   *   * This program is free software; you can redistribute it and/or @@ -30,6 +30,8 @@  #include <linux/spi/spi.h>  #include <linux/completion.h>  #include <linux/err.h> +#include <linux/workqueue.h> +#include <linux/pm_runtime.h>  #include <bcm63xx_dev_spi.h> @@ -37,8 +39,6 @@  #define DRV_VER		"0.1.2"  struct bcm63xx_spi { -	spinlock_t		lock; -	int			stopping;  	struct completion	done;  	void __iomem		*regs; @@ -96,17 +96,12 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {  	{   391000, SPI_CLK_0_391MHZ }  }; -static int bcm63xx_spi_setup_transfer(struct spi_device *spi, -				      struct spi_transfer *t) +static int bcm63xx_spi_check_transfer(struct spi_device *spi, +					struct spi_transfer *t)  { -	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);  	u8 bits_per_word; -	u8 clk_cfg, reg; -	u32 hz; -	int i;  	bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; -	hz = (t) ? t->speed_hz : spi->max_speed_hz;  	if (bits_per_word != 8) {  		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",  			__func__, bits_per_word); @@ -119,6 +114,19 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,  		return -EINVAL;  	} +	return 0; +} + +static void bcm63xx_spi_setup_transfer(struct spi_device *spi, +				      struct spi_transfer *t) +{ +	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); +	u32 hz; +	u8 clk_cfg, reg; +	int i; + +	hz = (t) ? t->speed_hz : spi->max_speed_hz; +  	/* Find the closest clock configuration */  	for (i = 0; i < SPI_CLK_MASK; i++) {  		if (hz <= bcm63xx_spi_freq_table[i][0]) { @@ -139,8 +147,6 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,  	bcm_spi_writeb(bs, reg, SPI_CLK_CFG);  	dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",  		clk_cfg, hz); - -	return 0;  }  /* the spi->mode bits understood by this driver: */ @@ -153,9 +159,6 @@ static int bcm63xx_spi_setup(struct spi_device *spi)  	bs = spi_master_get_devdata(spi->master); -	if (bs->stopping) -		return -ESHUTDOWN; -  	if (!spi->bits_per_word)  		spi->bits_per_word = 8; @@ -165,7 +168,7 @@ static int bcm63xx_spi_setup(struct spi_device *spi)  		return -EINVAL;  	} -	ret = bcm63xx_spi_setup_transfer(spi, NULL); +	ret = bcm63xx_spi_check_transfer(spi, NULL);  	if (ret < 0) {  		dev_err(&spi->dev, "setup: unsupported mode bits %x\n",  			spi->mode & ~MODEBITS); @@ -190,28 +193,29 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)  	bs->remaining_bytes -= size;  } -static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) +static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, +					struct spi_transfer *t)  {  	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);  	u16 msg_ctl;  	u16 cmd; +	/* Disable the CMD_DONE interrupt */ +	bcm_spi_writeb(bs, 0, SPI_INT_MASK); +  	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",  		t->tx_buf, t->rx_buf, t->len);  	/* Transmitter is inhibited */  	bs->tx_ptr = t->tx_buf;  	bs->rx_ptr = t->rx_buf; -	init_completion(&bs->done);  	if (t->tx_buf) {  		bs->remaining_bytes = t->len;  		bcm63xx_spi_fill_tx_fifo(bs);  	} -	/* Enable the command done interrupt which -	 * we use to determine completion of a command */ -	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); +	init_completion(&bs->done);  	/* Fill in the Message control register */  	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); @@ -230,33 +234,76 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  	cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);  	cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);  	bcm_spi_writew(bs, cmd, SPI_CMD); -	wait_for_completion(&bs->done); -	/* Disable the CMD_DONE interrupt */ -	bcm_spi_writeb(bs, 0, SPI_INT_MASK); +	/* Enable the CMD_DONE interrupt */ +	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);  	return t->len - bs->remaining_bytes;  } -static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) +static int bcm63xx_spi_prepare_transfer(struct spi_master *master)  { -	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); -	struct spi_transfer *t; -	int ret = 0; +	struct bcm63xx_spi *bs = spi_master_get_devdata(master); -	if (unlikely(list_empty(&m->transfers))) -		return -EINVAL; +	pm_runtime_get_sync(&bs->pdev->dev); -	if (bs->stopping) -		return -ESHUTDOWN; +	return 0; +} + +static int bcm63xx_spi_unprepare_transfer(struct spi_master *master) +{ +	struct bcm63xx_spi *bs = spi_master_get_devdata(master); + +	pm_runtime_put(&bs->pdev->dev); + +	return 0; +} + +static int bcm63xx_spi_transfer_one(struct spi_master *master, +					struct spi_message *m) +{ +	struct bcm63xx_spi *bs = spi_master_get_devdata(master); +	struct spi_transfer *t; +	struct spi_device *spi = m->spi; +	int status = 0; +	unsigned int timeout = 0;  	list_for_each_entry(t, &m->transfers, transfer_list) { -		ret += bcm63xx_txrx_bufs(spi, t); -	} +		unsigned int len = t->len; +		u8 rx_tail; -	m->complete(m->context); +		status = bcm63xx_spi_check_transfer(spi, t); +		if (status < 0) +			goto exit; -	return ret; +		/* configure adapter for a new transfer */ +		bcm63xx_spi_setup_transfer(spi, t); + +		while (len) { +			/* send the data */ +			len -= bcm63xx_txrx_bufs(spi, t); + +			timeout = wait_for_completion_timeout(&bs->done, HZ); +			if (!timeout) { +				status = -ETIMEDOUT; +				goto exit; +			} + +			/* read out all data */ +			rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + +			/* Read out all the data */ +			if (rx_tail) +				memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); +		} + +		m->actual_length += t->len; +	} +exit: +	m->status = status; +	spi_finalize_current_message(master); + +	return 0;  }  /* This driver supports single master mode only. Hence @@ -267,39 +314,15 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)  	struct spi_master *master = (struct spi_master *)dev_id;  	struct bcm63xx_spi *bs = spi_master_get_devdata(master);  	u8 intr; -	u16 cmd;  	/* Read interupts and clear them immediately */  	intr = bcm_spi_readb(bs, SPI_INT_STATUS);  	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);  	bcm_spi_writeb(bs, 0, SPI_INT_MASK); -	/* A tansfer completed */ -	if (intr & SPI_INTR_CMD_DONE) { -		u8 rx_tail; - -		rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); - -		/* Read out all the data */ -		if (rx_tail) -			memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); - -		/* See if there is more data to send */ -		if (bs->remaining_bytes > 0) { -			bcm63xx_spi_fill_tx_fifo(bs); - -			/* Start the transfer */ -			bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT, -				       SPI_MSG_CTL); -			cmd = bcm_spi_readw(bs, SPI_CMD); -			cmd |= SPI_CMD_START_IMMEDIATE; -			cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); -			bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); -			bcm_spi_writew(bs, cmd, SPI_CMD); -		} else { -			complete(&bs->done); -		} -	} +	/* A transfer completed */ +	if (intr & SPI_INTR_CMD_DONE) +		complete(&bs->done);  	return IRQ_HANDLED;  } @@ -345,7 +368,6 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)  	}  	bs = spi_master_get_devdata(master); -	init_completion(&bs->done);  	platform_set_drvdata(pdev, master);  	bs->pdev = pdev; @@ -379,12 +401,13 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)  	master->bus_num = pdata->bus_num;  	master->num_chipselect = pdata->num_chipselect;  	master->setup = bcm63xx_spi_setup; -	master->transfer = bcm63xx_transfer; +	master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; +	master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; +	master->transfer_one_message = bcm63xx_spi_transfer_one; +	master->mode_bits = MODEBITS;  	bs->speed_hz = pdata->speed_hz; -	bs->stopping = 0;  	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));  	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); -	spin_lock_init(&bs->lock);  	/* Initialize hardware */  	clk_enable(bs->clk); @@ -418,18 +441,16 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)  	struct spi_master *master = platform_get_drvdata(pdev);  	struct bcm63xx_spi *bs = spi_master_get_devdata(master); +	spi_unregister_master(master); +  	/* reset spi block */  	bcm_spi_writeb(bs, 0, SPI_INT_MASK); -	spin_lock(&bs->lock); -	bs->stopping = 1;  	/* HW shutdown */  	clk_disable(bs->clk);  	clk_put(bs->clk); -	spin_unlock(&bs->lock);  	platform_set_drvdata(pdev, 0); -	spi_unregister_master(master);  	return 0;  } diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index 248a2cc671a..1fe51198a62 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -252,19 +252,15 @@ static void  bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)  {  	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; -	unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15);  	bfin_sport_spi_disable(drv_data);  	dev_dbg(drv_data->dev, "restoring spi ctl state\n");  	bfin_write(&drv_data->regs->tcr1, chip->ctl_reg); -	bfin_write(&drv_data->regs->tcr2, bits);  	bfin_write(&drv_data->regs->tclkdiv, chip->baud); -	bfin_write(&drv_data->regs->tfsdiv, bits);  	SSYNC();  	bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS)); -	bfin_write(&drv_data->regs->rcr2, bits);  	SSYNC();  	bfin_sport_spi_cs_active(chip); @@ -420,11 +416,15 @@ bfin_sport_spi_pump_transfers(unsigned long data)  	drv_data->cs_change = transfer->cs_change;  	/* Bits per word setup */ -	bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; -	if (bits_per_word == 8) -		drv_data->ops = &bfin_sport_transfer_ops_u8; -	else +	bits_per_word = transfer->bits_per_word ? : +		message->spi->bits_per_word ? : 8; +	if (bits_per_word % 16 == 0)  		drv_data->ops = &bfin_sport_transfer_ops_u16; +	else +		drv_data->ops = &bfin_sport_transfer_ops_u8; +	bfin_write(&drv_data->regs->tcr2, bits_per_word - 1); +	bfin_write(&drv_data->regs->tfsdiv, bits_per_word - 1); +	bfin_write(&drv_data->regs->rcr2, bits_per_word - 1);  	drv_data->state = RUNNING_STATE; @@ -598,11 +598,12 @@ bfin_sport_spi_setup(struct spi_device *spi)  			}  			chip->cs_chg_udelay = chip_info->cs_chg_udelay;  			chip->idle_tx_val = chip_info->idle_tx_val; -			spi->bits_per_word = chip_info->bits_per_word;  		}  	} -	if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { +	if (spi->bits_per_word % 8) { +		dev_err(&spi->dev, "%d bits_per_word is not supported\n", +				spi->bits_per_word);  		ret = -EINVAL;  		goto error;  	} diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index 3b83ff8b1e2..9bb4d4af854 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -396,7 +396,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  		/* last read */  		if (drv_data->rx) {  			dev_dbg(&drv_data->pdev->dev, "last read\n"); -			if (n_bytes % 2) { +			if (!(n_bytes % 2)) {  				u16 *buf = (u16 *)drv_data->rx;  				for (loop = 0; loop < n_bytes / 2; loop++)  					*buf++ = bfin_read(&drv_data->regs->rdbr); @@ -424,7 +424,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  	if (drv_data->rx && drv_data->tx) {  		/* duplex */  		dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); -		if (n_bytes % 2) { +		if (!(n_bytes % 2)) {  			u16 *buf = (u16 *)drv_data->rx;  			u16 *buf2 = (u16 *)drv_data->tx;  			for (loop = 0; loop < n_bytes / 2; loop++) { @@ -442,7 +442,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  	} else if (drv_data->rx) {  		/* read */  		dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); -		if (n_bytes % 2) { +		if (!(n_bytes % 2)) {  			u16 *buf = (u16 *)drv_data->rx;  			for (loop = 0; loop < n_bytes / 2; loop++) {  				*buf++ = bfin_read(&drv_data->regs->rdbr); @@ -458,7 +458,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)  	} else if (drv_data->tx) {  		/* write */  		dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); -		if (n_bytes % 2) { +		if (!(n_bytes % 2)) {  			u16 *buf = (u16 *)drv_data->tx;  			for (loop = 0; loop < n_bytes / 2; loop++) {  				bfin_read(&drv_data->regs->rdbr); @@ -587,6 +587,7 @@ static void bfin_spi_pump_transfers(unsigned long data)  	if (message->state == DONE_STATE) {  		dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n");  		message->status = 0; +		bfin_spi_flush(drv_data);  		bfin_spi_giveback(drv_data);  		return;  	} @@ -870,8 +871,10 @@ static void bfin_spi_pump_transfers(unsigned long data)  		message->actual_length += drv_data->len_in_bytes;  		/* Move to next transfer of this msg */  		message->state = bfin_spi_next_transfer(drv_data); -		if (drv_data->cs_change) +		if (drv_data->cs_change && message->state != DONE_STATE) { +			bfin_spi_flush(drv_data);  			bfin_spi_cs_deactive(drv_data, chip); +		}  	}  	/* Schedule next transfer tasklet */ @@ -1026,7 +1029,6 @@ static int bfin_spi_setup(struct spi_device *spi)  		chip->cs_chg_udelay = chip_info->cs_chg_udelay;  		chip->idle_tx_val = chip_info->idle_tx_val;  		chip->pio_interrupt = chip_info->pio_interrupt; -		spi->bits_per_word = chip_info->bits_per_word;  	} else {  		/* force a default base state */  		chip->ctl_reg &= bfin_ctl_reg; diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 6db2887852d..e8055073e84 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -545,13 +545,12 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi)   * in case of failure.   */  static struct dma_async_tx_descriptor * -ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir) +ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir)  {  	struct spi_transfer *t = espi->current_msg->state;  	struct dma_async_tx_descriptor *txd;  	enum dma_slave_buswidth buswidth;  	struct dma_slave_config conf; -	enum dma_transfer_direction slave_dirn;  	struct scatterlist *sg;  	struct sg_table *sgt;  	struct dma_chan *chan; @@ -567,14 +566,13 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)  	memset(&conf, 0, sizeof(conf));  	conf.direction = dir; -	if (dir == DMA_FROM_DEVICE) { +	if (dir == DMA_DEV_TO_MEM) {  		chan = espi->dma_rx;  		buf = t->rx_buf;  		sgt = &espi->rx_sgt;  		conf.src_addr = espi->sspdr_phys;  		conf.src_addr_width = buswidth; -		slave_dirn = DMA_DEV_TO_MEM;  	} else {  		chan = espi->dma_tx;  		buf = t->tx_buf; @@ -582,7 +580,6 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)  		conf.dst_addr = espi->sspdr_phys;  		conf.dst_addr_width = buswidth; -		slave_dirn = DMA_MEM_TO_DEV;  	}  	ret = dmaengine_slave_config(chan, &conf); @@ -633,8 +630,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)  	if (!nents)  		return ERR_PTR(-ENOMEM); -	txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, -					slave_dirn, DMA_CTRL_ACK); +	txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, DMA_CTRL_ACK);  	if (!txd) {  		dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir);  		return ERR_PTR(-ENOMEM); @@ -651,12 +647,12 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir)   * unmapped.   */  static void ep93xx_spi_dma_finish(struct ep93xx_spi *espi, -				  enum dma_data_direction dir) +				  enum dma_transfer_direction dir)  {  	struct dma_chan *chan;  	struct sg_table *sgt; -	if (dir == DMA_FROM_DEVICE) { +	if (dir == DMA_DEV_TO_MEM) {  		chan = espi->dma_rx;  		sgt = &espi->rx_sgt;  	} else { @@ -677,16 +673,16 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi)  	struct spi_message *msg = espi->current_msg;  	struct dma_async_tx_descriptor *rxd, *txd; -	rxd = ep93xx_spi_dma_prepare(espi, DMA_FROM_DEVICE); +	rxd = ep93xx_spi_dma_prepare(espi, DMA_DEV_TO_MEM);  	if (IS_ERR(rxd)) {  		dev_err(&espi->pdev->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd));  		msg->status = PTR_ERR(rxd);  		return;  	} -	txd = ep93xx_spi_dma_prepare(espi, DMA_TO_DEVICE); +	txd = ep93xx_spi_dma_prepare(espi, DMA_MEM_TO_DEV);  	if (IS_ERR(txd)) { -		ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); +		ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM);  		dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(rxd));  		msg->status = PTR_ERR(txd);  		return; @@ -705,8 +701,8 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi)  	wait_for_completion(&espi->wait); -	ep93xx_spi_dma_finish(espi, DMA_TO_DEVICE); -	ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); +	ep93xx_spi_dma_finish(espi, DMA_MEM_TO_DEV); +	ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM);  }  /** diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 09c925aaf32..400ae2121a2 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1667,9 +1667,15 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct  	/* cpsdvsr = 254 & scr = 255 */  	min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); -	if (!((freq <= max_tclk) && (freq >= min_tclk))) { +	if (freq > max_tclk) +		dev_warn(&pl022->adev->dev, +			"Max speed that can be programmed is %d Hz, you requested %d\n", +			max_tclk, freq); + +	if (freq < min_tclk) {  		dev_err(&pl022->adev->dev, -			"controller data is incorrect: out of range frequency"); +			"Requested frequency: %d Hz is less than minimum possible %d Hz\n", +			freq, min_tclk);  		return -EINVAL;  	} @@ -1681,26 +1687,37 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct  		while (scr <= SCR_MAX) {  			tmp = spi_rate(rate, cpsdvsr, scr); -			if (tmp > freq) +			if (tmp > freq) { +				/* we need lower freq */  				scr++; +				continue; +			} +  			/* -			 * If found exact value, update and break. -			 * If found more closer value, update and continue. +			 * If found exact value, mark found and break. +			 * If found more closer value, update and break.  			 */ -			else if ((tmp == freq) || (tmp > best_freq)) { +			if (tmp > best_freq) {  				best_freq = tmp;  				best_cpsdvsr = cpsdvsr;  				best_scr = scr;  				if (tmp == freq) -					break; +					found = 1;  			} -			scr++; +			/* +			 * increased scr will give lower rates, which are not +			 * required +			 */ +			break;  		}  		cpsdvsr += 2;  		scr = SCR_MIN;  	} +	WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n", +			freq); +  	clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF);  	clk_freq->scr = (u8) (best_scr & 0xFF);  	dev_dbg(&pl022->adev->dev, @@ -1823,9 +1840,12 @@ static int pl022_setup(struct spi_device *spi)  	} else  		chip->cs_control = chip_info->cs_control; -	if (bits <= 3) { -		/* PL022 doesn't support less than 4-bits */ +	/* Check bits per word with vendor specific range */ +	if ((bits <= 3) || (bits > pl022->vendor->max_bpw)) {  		status = -ENOTSUPP; +		dev_err(&spi->dev, "illegal data size for this controller!\n"); +		dev_err(&spi->dev, "This controller can only handle 4 <= n <= %d bit words\n", +				pl022->vendor->max_bpw);  		goto err_config_params;  	} else if (bits <= 8) {  		dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); @@ -1838,20 +1858,10 @@ static int pl022_setup(struct spi_device *spi)  		chip->read = READING_U16;  		chip->write = WRITING_U16;  	} else { -		if (pl022->vendor->max_bpw >= 32) { -			dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); -			chip->n_bytes = 4; -			chip->read = READING_U32; -			chip->write = WRITING_U32; -		} else { -			dev_err(&spi->dev, -				"illegal data size for this controller!\n"); -			dev_err(&spi->dev, -				"a standard pl022 can only handle " -				"1 <= n <= 16 bit words\n"); -			status = -ENOTSUPP; -			goto err_config_params; -		} +		dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); +		chip->n_bytes = 4; +		chip->read = READING_U32; +		chip->write = WRITING_U32;  	}  	/* Now Initialize all register settings required for this chip */ diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 400df8cbee5..d91751f9ffe 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -36,6 +36,7 @@  #include <linux/prefetch.h>  #include <linux/ratelimit.h>  #include <linux/smp.h> +#include <linux/interrupt.h>  #include <net/dst.h>  #ifdef CONFIG_XFRM  #include <linux/xfrm.h> diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 56d74dc2fbd..91a97b3e45c 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -32,6 +32,7 @@  #include <linux/ip.h>  #include <linux/ratelimit.h>  #include <linux/string.h> +#include <linux/interrupt.h>  #include <net/dst.h>  #ifdef CONFIG_XFRM  #include <linux/xfrm.h> diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 9112cd88215..60cba8194de 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -31,6 +31,7 @@  #include <linux/etherdevice.h>  #include <linux/phy.h>  #include <linux/slab.h> +#include <linux/interrupt.h>  #include <net/dst.h> diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 2b45d3d1800..04cd57f2a6d 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -383,8 +383,6 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f)  		pd->tx_pool = &f->link;  		pd->tx_pool_count++;  		f = 0; -	} else { -		kfree(f);  	}  	spin_unlock_bh(&pd->tx_frame_lock);  	if (f) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 7862513cc29..9cf29fcea11 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -79,10 +79,6 @@  #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)  #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) -#define OMAP343X_CTRL_REGADDR(reg) \ -	OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) - -  /* Forward Declarations: */  static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt);  static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, @@ -418,19 +414,27 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,  		/* Assert RST1 i.e only the RST only for DSP megacell */  		if (!status) { +			/* +			 * XXX: ioremapping  MUST be removed once ctrl +			 * function is made available. +			 */ +			void __iomem *ctrl = ioremap(OMAP343X_CTRL_BASE, SZ_4K); +			if (!ctrl) +				return -ENOMEM; +  			(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,  					OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD,  					OMAP2_RM_RSTCTRL);  			/* Mask address with 1K for compatibility */  			__raw_writel(dsp_addr & OMAP3_IVA2_BOOTADDR_MASK, -					OMAP343X_CTRL_REGADDR( -					OMAP343X_CONTROL_IVA2_BOOTADDR)); +					ctrl + OMAP343X_CONTROL_IVA2_BOOTADDR);  			/*  			 * Set bootmode to self loop if dsp_debug flag is true  			 */  			__raw_writel((dsp_debug) ? OMAP3_IVA2_BOOTMOD_IDLE : 0, -					OMAP343X_CTRL_REGADDR( -					OMAP343X_CONTROL_IVA2_BOOTMOD)); +					ctrl + OMAP343X_CONTROL_IVA2_BOOTMOD); + +			iounmap(ctrl);  		}  	}  	if (!status) { diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c index 70055c8111e..870f934f4f3 100644 --- a/drivers/staging/tidspbridge/core/wdt.c +++ b/drivers/staging/tidspbridge/core/wdt.c @@ -53,7 +53,10 @@ int dsp_wdt_init(void)  	int ret = 0;  	dsp_wdt.sm_wdt = NULL; -	dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE); +	dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K); +	if (!dsp_wdt.reg_base) +		return -ENOMEM; +  	tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);  	dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); @@ -99,6 +102,9 @@ void dsp_wdt_exit(void)  	dsp_wdt.fclk = NULL;  	dsp_wdt.iclk = NULL;  	dsp_wdt.sm_wdt = NULL; + +	if (dsp_wdt.reg_base) +		iounmap(dsp_wdt.reg_base);  	dsp_wdt.reg_base = NULL;  } diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 3ed2c8f656a..7048e01f081 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -2,7 +2,7 @@ config ZCACHE  	bool "Dynamic compression of swap pages and clean pagecache pages"  	# X86 dependency is because zsmalloc uses non-portable pte/tlb  	# functions -	depends on (CLEANCACHE || FRONTSWAP) && CRYPTO && X86 +	depends on (CLEANCACHE || FRONTSWAP) && CRYPTO=y && X86  	select ZSMALLOC  	select CRYPTO_LZO  	default n diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 24145c30c9b..6cc4358f68c 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1073,8 +1073,10 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,  		    (new_serial.close_delay != port->close_delay) ||  		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||  		    ((new_serial.flags & ~ASYNC_USR_MASK) != -		     (port->flags & ~ASYNC_USR_MASK))) +		     (port->flags & ~ASYNC_USR_MASK))) { +			tty_unlock();  			return -EPERM; +		}  		port->flags = ((port->flags & ~ASYNC_USR_MASK) |  			       (new_serial.flags & ASYNC_USR_MASK));  		state->custom_divisor = new_serial.custom_divisor; diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index e6c3dbd781d..836fe273123 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)  		port->x_char = 0;  		return IRQ_HANDLED;  	} -	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { -		clps711xuart_stop_tx(port); -		return IRQ_HANDLED; -	} + +	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) +		goto disable_tx_irq;  	count = port->fifosize >> 1;  	do { @@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)  	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)  		uart_write_wakeup(port); -	if (uart_circ_empty(xmit)) -		clps711xuart_stop_tx(port); +	if (uart_circ_empty(xmit)) { +	disable_tx_irq: +		disable_irq_nosync(TX_IRQ(port)); +		tx_enabled(port) = 0; +	}  	return IRQ_HANDLED;  } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index bbbec4a74cf..c2816f49480 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1447,9 +1447,11 @@ static int pch_uart_verify_port(struct uart_port *port,  			__func__);  		return -EOPNOTSUPP;  #endif -		priv->use_dma = 1;  		priv->use_dma_flag = 1;  		dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); +		if (!priv->use_dma) +			pch_request_dma(port); +		priv->use_dma = 1;  	}  	return 0; diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 08ebe901bb5..654755a990d 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)  	tty = NULL;  	if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {  		if (!ZS_IS_OPEN(uap_a)) { -			pmz_debug("ChanA interrupt while open !\n"); +			pmz_debug("ChanA interrupt while not open !\n");  			goto skip_a;  		}  		write_zsreg(uap_a, R0, RES_H_IUS); @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)  	spin_lock(&uap_b->port.lock);  	tty = NULL;  	if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { -		if (!ZS_IS_OPEN(uap_a)) { -			pmz_debug("ChanB interrupt while open !\n"); +		if (!ZS_IS_OPEN(uap_b)) { +			pmz_debug("ChanB interrupt while not open !\n");  			goto skip_b;  		}  		write_zsreg(uap_b, R0, RES_H_IUS); diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c6f6560d436..0bb2b3248da 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -157,8 +157,9 @@ static void wdm_out_callback(struct urb *urb)  	spin_lock(&desc->iuspin);  	desc->werr = urb->status;  	spin_unlock(&desc->iuspin); -	clear_bit(WDM_IN_USE, &desc->flags);  	kfree(desc->outbuf); +	desc->outbuf = NULL; +	clear_bit(WDM_IN_USE, &desc->flags);  	wake_up(&desc->wait);  } @@ -338,7 +339,7 @@ static ssize_t wdm_write  	if (we < 0)  		return -EIO; -	desc->outbuf = buf = kmalloc(count, GFP_KERNEL); +	buf = kmalloc(count, GFP_KERNEL);  	if (!buf) {  		rv = -ENOMEM;  		goto outnl; @@ -406,10 +407,12 @@ static ssize_t wdm_write  	req->wIndex = desc->inum;  	req->wLength = cpu_to_le16(count);  	set_bit(WDM_IN_USE, &desc->flags); +	desc->outbuf = buf;  	rv = usb_submit_urb(desc->command, GFP_KERNEL);  	if (rv < 0) {  		kfree(buf); +		desc->outbuf = NULL;  		clear_bit(WDM_IN_USE, &desc->flags);  		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);  	} else { diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 622b4a48e73..57ed9e400c0 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -493,6 +493,15 @@ static int hcd_pci_suspend_noirq(struct device *dev)  	pci_save_state(pci_dev); +	/* +	 * Some systems crash if an EHCI controller is in D3 during +	 * a sleep transition.  We have to leave such controllers in D0. +	 */ +	if (hcd->broken_pci_sleep) { +		dev_dbg(dev, "Staying in PCI D0\n"); +		return retval; +	} +  	/* If the root hub is dead rather than suspended, disallow remote  	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as  	 * dying, so we only need to check the primary roothub. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a2aa9d652c6..ec6c97dadbe 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)  {  	struct usb_device	*udev = *pdev;  	int			i; -	struct usb_hcd		*hcd = bus_to_hcd(udev->bus);  	/* mark the device as inactive, so any further urb submissions for  	 * this device (and any of its children) will fail immediately. @@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)  	 * so that the hardware is now fully quiesced.  	 */  	dev_dbg (&udev->dev, "unregistering device\n"); -	mutex_lock(hcd->bandwidth_mutex);  	usb_disable_device(udev, 0); -	mutex_unlock(hcd->bandwidth_mutex);  	usb_hcd_synchronize_unlinks(udev);  	usb_remove_ep_devs(&udev->ep0); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index aed3e07942d..ca717da3be9 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1136,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,   * Deallocates hcd/hardware state for the endpoints (nuking all or most   * pending urbs) and usbcore state for the interfaces, so that usbcore   * must usb_set_configuration() before any interfaces could be used. - * - * Must be called with hcd->bandwidth_mutex held.   */  void usb_disable_device(struct usb_device *dev, int skip_ep0)  { @@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  			usb_disable_endpoint(dev, i + USB_DIR_IN, false);  		}  		/* Remove endpoints from the host controller internal state */ +		mutex_lock(hcd->bandwidth_mutex);  		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); +		mutex_unlock(hcd->bandwidth_mutex);  		/* Second pass: remove endpoint pointers */  	}  	for (i = skip_ep0; i < 16; ++i) { @@ -1750,7 +1750,6 @@ free_interfaces:  	/* if it's already configured, clear out old state first.  	 * getting rid of old interfaces means unbinding their drivers.  	 */ -	mutex_lock(hcd->bandwidth_mutex);  	if (dev->state != USB_STATE_ADDRESS)  		usb_disable_device(dev, 1);	/* Skip ep0 */ @@ -1763,6 +1762,7 @@ free_interfaces:  	 * host controller will not allow submissions to dropped endpoints.  If  	 * this call fails, the device state is unchanged.  	 */ +	mutex_lock(hcd->bandwidth_mutex);  	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);  	if (ret < 0) {  		mutex_unlock(hcd->bandwidth_mutex); diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7bd815a507e..99b58d84553 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)  	for (i = 0; i < dwc->num_event_buffers; i++) {  		evt = dwc->ev_buffs[i]; -		if (evt) { +		if (evt)  			dwc3_free_one_event_buffer(dwc, evt); -			dwc->ev_buffs[i] = NULL; -		}  	} + +	kfree(dwc->ev_buffs);  }  /** diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 25910e251c0..3584a169886 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,  			dwc->test_mode_nr = wIndex >> 8;  			dwc->test_mode = true; +			break; +		default: +			return -EINVAL;  		}  		break; @@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,  	length = trb->size & DWC3_TRB_SIZE_MASK;  	if (dwc->ep0_bounced) { +		unsigned transfer_size = ur->length; +		unsigned maxp = ep0->endpoint.maxpacket; + +		transfer_size += (maxp - (transfer_size % maxp));  		transferred = min_t(u32, ur->length, -				ep0->endpoint.maxpacket - length); +				transfer_size - length);  		memcpy(ur->buf, dwc->ep0_bounce, transferred);  		dwc->ep0_bounced = false;  	} else {  		transferred = ur->length - length; -		ur->actual += transferred;  	} +	ur->actual += transferred; +  	if ((epnum & 1) && ur->actual < ur->length) {  		/* for some reason we did not get everything out */ diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 0c935d7c65b..9d7bcd91007 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)  			mod_timer(&udc->vbus_timer,  				  jiffies + VBUS_POLL_TIMEOUT);  		} else { -			if (request_irq(udc->board.vbus_pin, at91_vbus_irq, -					0, driver_name, udc)) { +			if (request_irq(gpio_to_irq(udc->board.vbus_pin), +					at91_vbus_irq, 0, driver_name, udc)) {  				DBG("request vbus irq %d failed\n",  				    udc->board.vbus_pin);  				retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)  	return 0;  fail4:  	if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) -		free_irq(udc->board.vbus_pin, udc); +		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);  fail3:  	if (gpio_is_valid(udc->board.vbus_pin))  		gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)  	device_init_wakeup(&pdev->dev, 0);  	remove_debug_file(udc);  	if (gpio_is_valid(udc->board.vbus_pin)) { -		free_irq(udc->board.vbus_pin, udc); +		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);  		gpio_free(udc->board.vbus_pin);  	}  	free_irq(udc->udp_irq, udc); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a6dfd216416..170cbe89d9f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -927,7 +927,6 @@ static int dummy_udc_stop(struct usb_gadget *g,  	dum->driver = NULL; -	dummy_pullup(&dum->gadget, 0);  	return 0;  } diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1cbba70836b..f52cb1ae45d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)  	if (code == FUNCTIONFS_INTERFACE_REVMAP) {  		struct ffs_function *func = ffs->func;  		ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; -	} else if (gadget->ops->ioctl) { +	} else if (gadget && gadget->ops->ioctl) {  		ret = gadget->ops->ioctl(gadget, code, value);  	} else {  		ret = -ENOTTY; @@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)  		ffs->ep0req = NULL;  		ffs->gadget = NULL;  		ffs_data_put(ffs); +		clear_bit(FFS_FL_BOUND, &ffs->flags);  	}  } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index a371e966425..cb8c162cae5 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2189,7 +2189,7 @@ unknown_cmnd:  		common->data_size_from_cmnd = 0;  		sprintf(unknown, "Unknown x%02x", common->cmnd[0]);  		reply = check_command(common, common->cmnd_size, -				      DATA_DIR_UNKNOWN, 0xff, 0, unknown); +				      DATA_DIR_UNKNOWN, ~0, 0, unknown);  		if (reply == 0) {  			common->curlun->sense_data = SS_INVALID_COMMAND;  			reply = -EINVAL; diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 7b1cf18df5e..52343654f5d 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)  			if (buf) {  				memcpy(req->buf, buf, n);  				req->complete = rndis_response_complete; +				req->context = rndis;  				rndis_free_response(rndis->config, buf);  				value = n;  			} diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 4fac5692774..a896d73f7a9 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_dev *fsg)  		fsg->data_size_from_cmnd = 0;  		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);  		if ((reply = check_command(fsg, fsg->cmnd_size, -				DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { +				DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {  			fsg->curlun->sense_data = SS_INVALID_COMMAND;  			reply = -EINVAL;  		} diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 5f94e79cd6b..55abfb6bd61 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)  		: (1 << (ep_index(ep)));  	/* check if the pipe is empty */ -	if (!(list_empty(&ep->queue))) { +	if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {  		/* Add td to the end */  		struct fsl_req *lastreq;  		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)  		return -ENOMEM;  	} -	/* Update ep0 state */ -	if ((ep_index(ep) == 0)) -		udc->ep0_state = DATA_STATE_XMIT; -  	/* irq handler advances the queue */  	if (req != NULL)  		list_add_tail(&req->queue, &ep->queue); @@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)  		udc->ep0_dir = USB_DIR_OUT;  	ep = &udc->eps[0]; -	udc->ep0_state = WAIT_FOR_OUT_STATUS; +	if (udc->ep0_state != DATA_STATE_XMIT) +		udc->ep0_state = WAIT_FOR_OUT_STATUS;  	req->ep = ep;  	req->req.length = 0; @@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,  	list_add_tail(&req->queue, &ep->queue);  	udc->ep0_state = DATA_STATE_XMIT; +	if (ep0_prime_status(udc, EP_DIR_OUT)) +		ep0stall(udc); +  	return;  stall:  	ep0stall(udc); @@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,  		spin_lock(&udc->lock);  		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)  				?  DATA_STATE_XMIT : DATA_STATE_RECV; +		/* +		 * If the data stage is IN, send status prime immediately. +		 * See 2.0 Spec chapter 8.5.3.3 for detail. +		 */ +		if (udc->ep0_state == DATA_STATE_XMIT) +			if (ep0_prime_status(udc, EP_DIR_OUT)) +				ep0stall(udc); +  	} else {  		/* No data phase, IN status from gadget */  		udc->ep0_dir = USB_DIR_IN; @@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,  	switch (udc->ep0_state) {  	case DATA_STATE_XMIT: -		/* receive status phase */ -		if (ep0_prime_status(udc, EP_DIR_OUT)) -			ep0stall(udc); +		/* already primed at setup_received_irq */ +		udc->ep0_state = WAIT_FOR_OUT_STATUS;  		break;  	case DATA_STATE_RECV:  		/* send status phase */ diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 331cd6729d3..a85eaf40b94 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {  static struct ffs_data *gfs_ffs_data;  static unsigned long gfs_registered; -static int  gfs_init(void) +static int __init gfs_init(void)  {  	ENTER(); @@ -169,7 +169,7 @@ static int  gfs_init(void)  }  module_init(gfs_init); -static void  gfs_exit(void) +static void __exit gfs_exit(void)  {  	ENTER(); diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 69295ba9d99..105b206cd84 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)  	/* currently we allocate TX FIFOs for all possible endpoints,  	 * and assume that they are all the same size. */ -	for (ep = 0; ep <= 15; ep++) { +	for (ep = 1; ep <= 15; ep++) {  		val = addr;  		val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;  		addr += size; @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,  	/* write size / packets */  	writel(epsize, hsotg->regs + epsize_reg); -	if (using_dma(hsotg)) { +	if (using_dma(hsotg) && !continuing) {  		unsigned int dma_reg;  		/* write DMA address to control register, buffer already @@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,  	reg |= mpsval;  	writel(reg, regs + S3C_DIEPCTL(ep)); -	reg = readl(regs + S3C_DOEPCTL(ep)); -	reg &= ~S3C_DxEPCTL_MPS_MASK; -	reg |= mpsval; -	writel(reg, regs + S3C_DOEPCTL(ep)); +	if (ep) { +		reg = readl(regs + S3C_DOEPCTL(ep)); +		reg &= ~S3C_DxEPCTL_MPS_MASK; +		reg |= mpsval; +		writel(reg, regs + S3C_DOEPCTL(ep)); +	}  	return; @@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,  		    ints & S3C_DIEPMSK_TxFIFOEmpty) {  			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",  				__func__, idx); -			s3c_hsotg_trytx(hsotg, hs_ep); +			if (!using_dma(hsotg)) +				s3c_hsotg_trytx(hsotg, hs_ep);  		}  	}  } diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 56da49f31d6..e5e44f8cde9 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -263,9 +263,9 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)  	if (udc_is_newstyle(udc)) {  		udc->driver->disconnect(udc->gadget); +		usb_gadget_disconnect(udc->gadget);  		udc->driver->unbind(udc->gadget);  		usb_gadget_udc_stop(udc->gadget, udc->driver); -		usb_gadget_disconnect(udc->gadget);  	} else {  		usb_gadget_stop(udc->gadget, udc->driver);  	} @@ -411,9 +411,13 @@ static ssize_t usb_udc_softconn_store(struct device *dev,  	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);  	if (sysfs_streq(buf, "connect")) { +		if (udc_is_newstyle(udc)) +			usb_gadget_udc_start(udc->gadget, udc->driver);  		usb_gadget_connect(udc->gadget);  	} else if (sysfs_streq(buf, "disconnect")) {  		usb_gadget_disconnect(udc->gadget); +		if (udc_is_newstyle(udc)) +			usb_gadget_udc_stop(udc->gadget, udc->driver);  	} else {  		dev_err(dev, "unsupported command '%s'\n", buf);  		return -EINVAL; diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index bc78c606c12..ca4e03a1c73 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h @@ -28,7 +28,7 @@  struct uvc_request_data  { -	unsigned int length; +	__s32 length;  	__u8 data[60];  }; diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index d776adb2da6..0cdf89d32a1 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ done:  	return ret;  } +/* called with queue->irqlock held.. */  static struct uvc_buffer *  uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)  {  	struct uvc_buffer *nextbuf; -	unsigned long flags;  	if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&  	    buf->buf.length != buf->buf.bytesused) { @@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)  		return buf;  	} -	spin_lock_irqsave(&queue->irqlock, flags);  	list_del(&buf->queue);  	if (!list_empty(&queue->irqqueue))  		nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,  					   queue);  	else  		nextbuf = NULL; -	spin_unlock_irqrestore(&queue->irqlock, flags);  	buf->buf.sequence = queue->sequence++;  	do_gettimeofday(&buf->buf.timestamp); diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index f6e083b5019..54d7ca559cb 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c @@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)  	if (data->length < 0)  		return usb_ep_set_halt(cdev->gadget->ep0); -	req->length = min(uvc->event_length, data->length); +	req->length = min_t(unsigned int, uvc->event_length, data->length);  	req->zero = data->length < uvc->event_length;  	req->dma = DMA_ADDR_INVALID; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3e7345172e0..d0a84bd3f3e 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,  	u32 portsc;  	struct usb_hcd *hcd = ehci_to_hcd(ehci);  	void __iomem *non_ehci = hcd->regs; +	struct fsl_usb2_platform_data *pdata; + +	pdata = hcd->self.controller->platform_data;  	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);  	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,  		/* fall through */  	case FSL_USB2_PHY_UTMI:  		/* enable UTMI PHY */ -		setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); +		if (pdata->have_sysif_regs) +			setbits32(non_ehci + FSL_SOC_USB_CTRL, +				  CTRL_UTMI_PHY_EN);  		portsc |= PORT_PTS_UTMI;  		break;  	case FSL_USB2_PHY_NONE: diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 806cc95317a..4a3bc5b7a06 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -858,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  		goto dead;  	} +	/* +	 * We don't use STS_FLR, but some controllers don't like it to +	 * remain on, so mask it out along with the other status bits. +	 */ +	masked_status = status & (INTR_MASK | STS_FLR); +  	/* Shared IRQ? */ -	masked_status = status & INTR_MASK;  	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {  		spin_unlock(&ehci->lock);  		return IRQ_NONE; @@ -910,7 +915,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  		pcd_status = status;  		/* resume root hub? */ -		if (!(cmd & CMD_RUN)) +		if (ehci->rh_state == EHCI_RH_SUSPENDED)  			usb_hcd_resume_root_hub(hcd);  		/* get per-port change detect bits */ diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bba9850f32f..5c78f9e7146 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -42,6 +42,7 @@  #include <plat/usb.h>  #include <linux/regulator/consumer.h>  #include <linux/pm_runtime.h> +#include <linux/gpio.h>  /* EHCI Register Set */  #define EHCI_INSNREG04					(0xA0) @@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  		}  	} +	if (pdata->phy_reset) { +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_request_one(pdata->reset_gpio_port[0], +					 GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_request_one(pdata->reset_gpio_port[1], +					 GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + +		/* Hold the PHY in RESET for enough time till DIR is high */ +		udelay(10); +	} +  	pm_runtime_enable(dev);  	pm_runtime_get_sync(dev); @@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  	/* root ports should always stay powered */  	ehci_port_power(omap_ehci, 1); +	if (pdata->phy_reset) { +		/* Hold the PHY in RESET for enough time till +		 * PHY is settled and ready +		 */ +		udelay(10); + +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_set_value(pdata->reset_gpio_port[0], 1); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_set_value(pdata->reset_gpio_port[1], 1); +	} +  	return 0;  err_add_hcd: @@ -259,8 +286,9 @@ err_io:   */  static int ehci_hcd_omap_remove(struct platform_device *pdev)  { -	struct device *dev	= &pdev->dev; -	struct usb_hcd *hcd	= dev_get_drvdata(dev); +	struct device *dev				= &pdev->dev; +	struct usb_hcd *hcd				= dev_get_drvdata(dev); +	struct ehci_hcd_omap_platform_data *pdata	= dev->platform_data;  	usb_remove_hcd(hcd);  	disable_put_regulator(dev->platform_data); @@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)  	pm_runtime_put_sync(dev);  	pm_runtime_disable(dev); +	if (pdata->phy_reset) { +		if (gpio_is_valid(pdata->reset_gpio_port[0])) +			gpio_free(pdata->reset_gpio_port[0]); + +		if (gpio_is_valid(pdata->reset_gpio_port[1])) +			gpio_free(pdata->reset_gpio_port[1]); +	}  	return 0;  } diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 01bb7241d6e..fe8dc069164 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd *hcd)  			hcd->has_tt = 1;  			tdi_reset(ehci);  		} +		if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { +			/* EHCI #1 or #2 on 6 Series/C200 Series chipset */ +			if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { +				ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); +				hcd->broken_pci_sleep = 1; +				device_set_wakeup_capable(&pdev->dev, false); +			} +		}  		break;  	case PCI_VENDOR_ID_TDI:  		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 73544bd440b..86183366647 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -731,7 +731,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		err = -ENODEV;  		goto fail;  	} -	set_irq_flags(irq, IRQF_VALID);  #ifdef CONFIG_USB_OTG_UTILS  	if (pdata->operating_mode == TEGRA_USB_OTG) { diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 09f597ad6e0..13ebeca8e73 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);  /* configure so an HC device and id are always provided */  /* always called with process context; sleeping is OK */ @@ -108,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);   * then invokes the start() method for the HCD associated with it   * through the hotplug entry's driver_data.   */ -static int usb_hcd_at91_probe(const struct hc_driver *driver, +static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,  			struct platform_device *pdev)  {  	int retval; @@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,   * context, "rmmod" or something similar.   *   */ -static void usb_hcd_at91_remove(struct usb_hcd *hcd, +static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,  				struct platform_device *pdev)  {  	usb_remove_hcd(hcd); @@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)  {  	struct at91_usbh_data	*pdata;  	int			i; @@ -620,7 +620,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)  	return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);  } -static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)  {  	struct at91_usbh_data	*pdata = pdev->dev.platform_data;  	int			i; @@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");  static struct platform_driver ohci_hcd_at91_driver = {  	.probe		= ohci_hcd_at91_drv_probe, -	.remove		= ohci_hcd_at91_drv_remove, +	.remove		= __devexit_p(ohci_hcd_at91_drv_remove),  	.shutdown	= usb_hcd_platform_shutdown,  	.suspend	= ohci_hcd_at91_drv_suspend,  	.resume		= ohci_hcd_at91_drv_resume, diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 959145baf3c..9dcb68f04f0 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)  	unsigned		i;  	unsigned		size = max; -	sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); +	sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);  	if (!sg)  		return NULL;  	sg_init_table(sg, nents); @@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)  	struct ctrl_ctx		context;  	int			i; +	if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) +		return -EOPNOTSUPP; +  	spin_lock_init(&context.lock);  	context.dev = dev;  	init_completion(&context.complete); @@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)  	/* queued control messaging */  	case 10: -		if (param->sglen == 0) -			break;  		retval = 0;  		dev_info(&intf->dev,  				"TEST 10:  queue %d control calls, %d times\n", @@ -2276,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)  			if (status < 0) {  				WARNING(dev, "couldn't get endpoints, %d\n",  						status); +				kfree(dev->buf); +				kfree(dev);  				return status;  			}  			/* may find bulk or ISO pipes */ diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 897edda4227..70201462e19 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)  	usb_put_dev(dev->udev);  	if (dev->cntl_urb) {  		usb_kill_urb(dev->cntl_urb); -		if (dev->cntl_req) -			usb_free_coherent(dev->udev, YUREX_BUF_SIZE, -				dev->cntl_req, dev->cntl_urb->setup_dma); +		kfree(dev->cntl_req);  		if (dev->cntl_buffer)  			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,  				dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_  	}  	/* allocate buffer for control req */ -	dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, -					   GFP_KERNEL, -					   &dev->cntl_urb->setup_dma); +	dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);  	if (!dev->cntl_req) {  		err("Could not allocate cntl_req");  		goto error; @@ -286,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_  			 usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),  			 dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,  			 dev, 1); -	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; +	dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;  	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {  		retval = -EIO;  		err("Could not submitting URB"); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 97ab975fa44..768b4b55c81 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -386,7 +386,7 @@ static int davinci_musb_init(struct musb *musb)  	usb_nop_xceiv_register();  	musb->xceiv = usb_get_transceiver();  	if (!musb->xceiv) -		return -ENODEV; +		goto unregister;  	musb->mregs += DAVINCI_BASE_OFFSET; @@ -444,6 +444,7 @@ static int davinci_musb_init(struct musb *musb)  fail:  	usb_put_transceiver(musb->xceiv); +unregister:  	usb_nop_xceiv_unregister();  	return -ENODEV;  } diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0f8b82918a4..66aaccf0449 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)  	int	i = 0;  	u8	r;  	u8	power; +	int	ret; + +	pm_runtime_get_sync(phy->io_dev);  	/* Make sure the transceiver is not in low power mode */  	power = musb_readb(addr, MUSB_POWER); @@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)  	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)  				& MUSB_ULPI_REG_CMPLT)) {  		i++; -		if (i == 10000) -			return -ETIMEDOUT; +		if (i == 10000) { +			ret = -ETIMEDOUT; +			goto out; +		}  	}  	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);  	r &= ~MUSB_ULPI_REG_CMPLT;  	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -	return musb_readb(addr, MUSB_ULPI_REG_DATA); +	ret = musb_readb(addr, MUSB_ULPI_REG_DATA); + +out: +	pm_runtime_put(phy->io_dev); + +	return ret;  }  static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)  	int	i = 0;  	u8	r = 0;  	u8	power; +	int	ret = 0; + +	pm_runtime_get_sync(phy->io_dev);  	/* Make sure the transceiver is not in low power mode */  	power = musb_readb(addr, MUSB_POWER); @@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)  	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)  				& MUSB_ULPI_REG_CMPLT)) {  		i++; -		if (i == 10000) -			return -ETIMEDOUT; +		if (i == 10000) { +			ret = -ETIMEDOUT; +			goto out; +		}  	}  	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);  	r &= ~MUSB_ULPI_REG_CMPLT;  	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -	return 0; +out: +	pm_runtime_put(phy->io_dev); + +	return ret;  }  #else  #define musb_ulpi_read		NULL @@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  	if (!musb->isr) {  		status = -ENODEV; -		goto fail3; +		goto fail2;  	}  	if (!musb->xceiv->io_ops) { +		musb->xceiv->io_dev = musb->controller;  		musb->xceiv->io_priv = musb->mregs;  		musb->xceiv->io_ops = &musb_ulpi_access;  	} +	pm_runtime_get_sync(musb->controller); +  #ifndef CONFIG_MUSB_PIO_ONLY  	if (use_dma && dev->dma_mask) {  		struct dma_controller	*c; @@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)  		goto fail5;  #endif +	pm_runtime_put(musb->controller); +  	dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",  			({char *s;  			 switch (musb->board_mode) { @@ -2047,6 +2070,9 @@ fail4:  		musb_gadget_cleanup(musb);  fail3: +	pm_runtime_put_sync(musb->controller); + +fail2:  	if (musb->irq_wake)  		device_init_wakeup(dev, 0);  	musb_platform_exit(musb); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 93de517a32a..f4a40f001c8 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -449,7 +449,7 @@ struct musb {  	 * We added this flag to forcefully disable double  	 * buffering until we get it working.  	 */ -	unsigned                double_buffer_not_ok:1 __deprecated; +	unsigned                double_buffer_not_ok:1;  	struct musb_hdrc_config	*config; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 79cb0af779f..ef8d744800a 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)  	}  	/* turn off DMA requests, discard state, stop polling ... */ -	if (is_in) { +	if (ep->epnum && is_in) {  		/* giveback saves bulk toggle */  		csr = musb_h_flush_rxfifo(ep, 0); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2ae0bb30999..c7785e81254 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)  static int omap2430_musb_init(struct musb *musb)  { -	u32 l, status = 0; +	u32 l; +	int status = 0;  	struct device *dev = musb->controller;  	struct musb_hdrc_platform_data *plat = dev->platform_data;  	struct omap_musb_board_data *data = plat->board_data; @@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)  	status = pm_runtime_get_sync(dev);  	if (status < 0) { -		dev_err(dev, "pm_runtime_get_sync FAILED"); +		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);  		goto err1;  	} @@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)  	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); +	pm_runtime_put_noidle(musb->controller);  	return 0;  err1: @@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)  		goto err2;  	} +	pm_runtime_enable(&pdev->dev); +  	ret = platform_device_add(musb);  	if (ret) {  		dev_err(&pdev->dev, "failed to register musb device\n");  		goto err2;  	} -	pm_runtime_enable(&pdev->dev); -  	return 0;  err2: @@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)  	platform_device_del(glue->musb);  	platform_device_put(glue->musb); -	pm_runtime_put(&pdev->dev);  	kfree(glue);  	return 0; @@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)  	struct omap2430_glue		*glue = dev_get_drvdata(dev);  	struct musb			*musb = glue_to_musb(glue); -	musb->context.otg_interfsel = musb_readl(musb->mregs, -						OTG_INTERFSEL); +	if (musb) { +		musb->context.otg_interfsel = musb_readl(musb->mregs, +				OTG_INTERFSEL); -	omap2430_low_level_exit(musb); -	usb_phy_set_suspend(musb->xceiv, 1); +		omap2430_low_level_exit(musb); +		usb_phy_set_suspend(musb->xceiv, 1); +	}  	return 0;  } @@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)  	struct omap2430_glue		*glue = dev_get_drvdata(dev);  	struct musb			*musb = glue_to_musb(glue); -	omap2430_low_level_init(musb); -	musb_writel(musb->mregs, OTG_INTERFSEL, -					musb->context.otg_interfsel); +	if (musb) { +		omap2430_low_level_init(musb); +		musb_writel(musb->mregs, OTG_INTERFSEL, +				musb->context.otg_interfsel); -	usb_phy_set_suspend(musb->xceiv, 0); +		usb_phy_set_suspend(musb->xceiv, 0); +	}  	return 0;  } diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 3ece43a2e4c..a0a2178974f 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work)  	struct gpio_vbus_data *gpio_vbus =  		container_of(work, struct gpio_vbus_data, work);  	struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; -	int gpio; +	int gpio, status;  	if (!gpio_vbus->phy.otg->gadget)  		return; @@ -108,7 +108,9 @@ static void gpio_vbus_work(struct work_struct *work)  	 */  	gpio = pdata->gpio_pullup;  	if (is_vbus_powered(pdata)) { +		status = USB_EVENT_VBUS;  		gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; +		gpio_vbus->phy.last_event = status;  		usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget);  		/* drawing a "unit load" is *always* OK, except for OTG */ @@ -117,6 +119,9 @@ static void gpio_vbus_work(struct work_struct *work)  		/* optionally enable D+ pullup */  		if (gpio_is_valid(gpio))  			gpio_set_value(gpio, !pdata->gpio_pullup_inverted); + +		atomic_notifier_call_chain(&gpio_vbus->phy.notifier, +					   status, gpio_vbus->phy.otg->gadget);  	} else {  		/* optionally disable D+ pullup */  		if (gpio_is_valid(gpio)) @@ -125,7 +130,12 @@ static void gpio_vbus_work(struct work_struct *work)  		set_vbus_draw(gpio_vbus, 0);  		usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); +		status = USB_EVENT_NONE;  		gpio_vbus->phy.state = OTG_STATE_B_IDLE; +		gpio_vbus->phy.last_event = status; + +		atomic_notifier_call_chain(&gpio_vbus->phy.notifier, +					   status, gpio_vbus->phy.otg->gadget);  	}  } @@ -287,6 +297,9 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)  			irq, err);  		goto err_irq;  	} + +	ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); +  	INIT_WORK(&gpio_vbus->work, gpio_vbus_work);  	gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 0310e2df59f..ec30f95ef39 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,  	/* Issue the request, attempting to read 'size' bytes */  	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),  				request, REQTYPE_DEVICE_TO_HOST, 0x0000, -				port_priv->bInterfaceNumber, buf, size, 300); +				port_priv->bInterfaceNumber, buf, size, +				USB_CTRL_GET_TIMEOUT);  	/* Convert data into an array of integers */  	for (i = 0; i < length; i++) @@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,  		result = usb_control_msg(serial->dev,  				usb_sndctrlpipe(serial->dev, 0),  				request, REQTYPE_HOST_TO_DEVICE, 0x0000, -				port_priv->bInterfaceNumber, buf, size, 300); +				port_priv->bInterfaceNumber, buf, size, +				USB_CTRL_SET_TIMEOUT);  	} else {  		result = usb_control_msg(serial->dev,  				usb_sndctrlpipe(serial->dev, 0),  				request, REQTYPE_HOST_TO_DEVICE, data[0], -				port_priv->bInterfaceNumber, NULL, 0, 300); +				port_priv->bInterfaceNumber, NULL, 0, +				USB_CTRL_SET_TIMEOUT);  	}  	kfree(buf); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index fdd5aa2c8d8..8c8bf806f6f 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {  };  /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };  static const struct sierra_iface_info direct_ip_interface_blacklist = {  	.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),  	.ifaceinfo = direct_ip_non_serial_ifaces, @@ -289,7 +289,6 @@ static const struct usb_device_id id_table[] = {  	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */  	{ USB_DEVICE(0x1199, 0x6859) },	/* Sierra Wireless AirCard 885 E */  	{ USB_DEVICE(0x1199, 0x685A) },	/* Sierra Wireless AirCard 885 E */ -	{ USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */  	/* Sierra Wireless C885 */  	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},  	/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ @@ -299,6 +298,9 @@ static const struct usb_device_id id_table[] = {  	/* Sierra Wireless HSPA Non-Composite Device */  	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},  	{ USB_DEVICE(0x1199, 0x6893) },	/* Sierra Wireless Device */ +	{ USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */ +	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist +	},  	{ USB_DEVICE(0x1199, 0x68A3), 	/* Sierra Wireless Direct IP modems */  	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist  	}, diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 66797e9c501..810c90ae2c5 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb)  		dev_err(dev, "NEEP: URB error %d\n", urb->status);  	}  	result = usb_submit_urb(urb, GFP_ATOMIC); -	if (result < 0) { +	if (result < 0 && result != -ENODEV && result != -EPERM) { +		/* ignoring unrecoverable errors */  		dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",  			result);  		goto error; diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index a269937be1b..8cb71bb333c 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -107,6 +107,7 @@ struct uwb_rc_neh {  	u8 evt_type;  	__le16 evt;  	u8 context; +	u8 completed;  	uwb_rc_cmd_cb_f cb;  	void *arg; @@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size  	struct device *dev = &rc->uwb_dev.dev;  	struct uwb_rc_neh *neh;  	struct uwb_rceb *notif; +	unsigned long flags;  	if (rceb->bEventContext == 0) {  		notif = kmalloc(size, GFP_ATOMIC); @@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size  	} else {  		neh = uwb_rc_neh_lookup(rc, rceb);  		if (neh) { -			del_timer_sync(&neh->timer); +			spin_lock_irqsave(&rc->neh_lock, flags); +			/* to guard against a timeout */ +			neh->completed = 1; +			del_timer(&neh->timer); +			spin_unlock_irqrestore(&rc->neh_lock, flags);  			uwb_rc_neh_cb(neh, rceb, size);  		} else  			dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg)  	unsigned long flags;  	spin_lock_irqsave(&rc->neh_lock, flags); +	if (neh->completed) { +		spin_unlock_irqrestore(&rc->neh_lock, flags); +		return; +	}  	if (neh->context)  		__uwb_rc_neh_rm(rc, neh);  	else diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index f0da2c32fbd..1f21d2a1e52 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net)  				vq->heads[vq->upend_idx].len = len;  				ubuf->callback = vhost_zerocopy_callback; -				ubuf->arg = vq->ubufs; +				ubuf->ctx = vq->ubufs;  				ubuf->desc = vq->upend_idx;  				msg.msg_control = ubuf;  				msg.msg_controllen = sizeof(ubuf); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 947f00d8e09..51e4c1eeec4 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1598,10 +1598,9 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs)  	kfree(ubufs);  } -void vhost_zerocopy_callback(void *arg) +void vhost_zerocopy_callback(struct ubuf_info *ubuf)  { -	struct ubuf_info *ubuf = arg; -	struct vhost_ubuf_ref *ubufs = ubuf->arg; +	struct vhost_ubuf_ref *ubufs = ubuf->ctx;  	struct vhost_virtqueue *vq = ubufs->vq;  	/* set len = 1 to mark this desc buffers done DMA */ diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 8dcf4cca6bf..8de1fd5b8ef 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -188,7 +188,7 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *);  int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,  		    unsigned int log_num, u64 len); -void vhost_zerocopy_callback(void *arg); +void vhost_zerocopy_callback(struct ubuf_info *);  int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq);  #define vq_err(vq, fmt, ...) do {                                  \ diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index 86922ac8441..353c02fe8a9 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c @@ -13,6 +13,7 @@  #include <linux/errno.h>  #include <linux/string.h>  #include <linux/fb.h> +#include <linux/gpio.h>  #include <linux/slab.h>  #include <linux/init.h>  #include <linux/types.h> diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index cbc7ceef278..9f13b897fd6 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -435,16 +435,16 @@ static void hpwdt_start(void)  {  	reload = SECS_TO_TICKS(soft_margin);  	iowrite16(reload, hpwdt_timer_reg); -	iowrite16(0x85, hpwdt_timer_con); +	iowrite8(0x85, hpwdt_timer_con);  }  static void hpwdt_stop(void)  {  	unsigned long data; -	data = ioread16(hpwdt_timer_con); +	data = ioread8(hpwdt_timer_con);  	data &= 0xFE; -	iowrite16(data, hpwdt_timer_con); +	iowrite8(data, hpwdt_timer_con);  }  static void hpwdt_ping(void) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 4b33acd8ed4..0a8a17cd80b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -274,7 +274,7 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn)  static bool pirq_check_eoi_map(unsigned irq)  { -	return test_bit(irq, pirq_eoi_map); +	return test_bit(pirq_from_irq(irq), pirq_eoi_map);  }  static bool pirq_needs_eoi_flag(unsigned irq) diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 99d8151c824..1ffd03bf8e1 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)  	vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;  	if (use_ptemod) -		vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; +		vma->vm_flags |= VM_DONTCOPY;  	vma->vm_private_data = map; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index b4d4eac761d..f100ce20b16 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -1029,6 +1029,7 @@ int gnttab_init(void)  	int i;  	unsigned int max_nr_glist_frames, nr_glist_frames;  	unsigned int nr_init_grefs; +	int ret;  	nr_grant_frames = 1;  	boot_max_nr_grant_frames = __max_nr_grant_frames(); @@ -1047,12 +1048,16 @@ int gnttab_init(void)  	nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;  	for (i = 0; i < nr_glist_frames; i++) {  		gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); -		if (gnttab_list[i] == NULL) +		if (gnttab_list[i] == NULL) { +			ret = -ENOMEM;  			goto ini_nomem; +		}  	} -	if (gnttab_resume() < 0) -		return -ENODEV; +	if (gnttab_resume() < 0) { +		ret = -ENODEV; +		goto ini_nomem; +	}  	nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; @@ -1070,7 +1075,7 @@ int gnttab_init(void)  	for (i--; i >= 0; i--)  		free_page((unsigned long)gnttab_list[i]);  	kfree(gnttab_list); -	return -ENOMEM; +	return ret;  }  EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 9e14ae6cd49..412b96cc530 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -132,6 +132,7 @@ static void do_suspend(void)  	err = dpm_suspend_end(PMSG_FREEZE);  	if (err) {  		printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); +		si.cancelled = 0;  		goto out_resume;  	} diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 174b5653cd8..0b48579a9cd 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -128,7 +128,10 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr)  			pr_debug("     C%d: %s %d uS\n",  				 cx->type, cx->desc, (u32)cx->latency);  		} -	} else +	} else if (ret != -EINVAL) +		/* EINVAL means the ACPI ID is incorrect - meaning the ACPI +		 * table is referencing a non-existing CPU - which can happen +		 * with broken ACPI tables. */  		pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n",  		       ret, _pr->acpi_id); diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index f20c5f178b4..a31b54d4883 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)  	return xenbus_read_otherend_details(xendev, "backend-id", "backend");  } -static int is_device_connecting(struct device *dev, void *data) +static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)  {  	struct xenbus_device *xendev = to_xenbus_device(dev);  	struct device_driver *drv = data; @@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)  	if (drv && (dev->driver != drv))  		return 0; +	if (ignore_nonessential) { +		/* With older QEMU, for PVonHVM guests the guest config files +		 * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] +		 * which is nonsensical as there is no PV FB (there can be +		 * a PVKB) running as HVM guest. */ + +		if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) +			return 0; + +		if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) +			return 0; +	}  	xendrv = to_xenbus_driver(dev->driver);  	return (xendev->state < XenbusStateConnected ||  		(xendev->state == XenbusStateConnected &&  		 xendrv->is_ready && !xendrv->is_ready(xendev)));  } +static int essential_device_connecting(struct device *dev, void *data) +{ +	return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); +} +static int non_essential_device_connecting(struct device *dev, void *data) +{ +	return is_device_connecting(dev, data, false); +} -static int exists_connecting_device(struct device_driver *drv) +static int exists_essential_connecting_device(struct device_driver *drv) +{ +	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, +				essential_device_connecting); +} +static int exists_non_essential_connecting_device(struct device_driver *drv)  {  	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, -				is_device_connecting); +				non_essential_device_connecting);  }  static int print_device_status(struct device *dev, void *data) @@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data)  /* We only wait for device setup after most initcalls have run. */  static int ready_to_wait_for_devices; +static bool wait_loop(unsigned long start, unsigned int max_delay, +		     unsigned int *seconds_waited) +{ +	if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { +		if (!*seconds_waited) +			printk(KERN_WARNING "XENBUS: Waiting for " +			       "devices to initialise: "); +		*seconds_waited += 5; +		printk("%us...", max_delay - *seconds_waited); +		if (*seconds_waited == max_delay) +			return true; +	} + +	schedule_timeout_interruptible(HZ/10); + +	return false; +}  /*   * On a 5-minute timeout, wait for all devices currently configured.  We need   * to do this to guarantee that the filesystems and / or network devices @@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv)  	if (!ready_to_wait_for_devices || !xen_domain())  		return; -	while (exists_connecting_device(drv)) { -		if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { -			if (!seconds_waited) -				printk(KERN_WARNING "XENBUS: Waiting for " -				       "devices to initialise: "); -			seconds_waited += 5; -			printk("%us...", 300 - seconds_waited); -			if (seconds_waited == 300) -				break; -		} +	while (exists_non_essential_connecting_device(drv)) +		if (wait_loop(start, 30, &seconds_waited)) +			break; -		schedule_timeout_interruptible(HZ/10); -	} +	/* Skips PVKB and PVFB check.*/ +	while (exists_essential_connecting_device(drv)) +		if (wait_loop(start, 270, &seconds_waited)) +			break;  	if (seconds_waited)  		printk("\n"); @@ -93,9 +93,8 @@ static void aio_free_ring(struct kioctx *ctx)  		put_page(info->ring_pages[i]);  	if (info->mmap_size) { -		down_write(&ctx->mm->mmap_sem); -		do_munmap(ctx->mm, info->mmap_base, info->mmap_size); -		up_write(&ctx->mm->mmap_sem); +		BUG_ON(ctx->mm != current->mm); +		vm_munmap(info->mmap_base, info->mmap_size);  	}  	if (info->ring_pages && info->ring_pages != info->internal_pages) @@ -389,6 +388,17 @@ void exit_aio(struct mm_struct *mm)  				"exit_aio:ioctx still alive: %d %d %d\n",  				atomic_read(&ctx->users), ctx->dead,  				ctx->reqs_active); +		/* +		 * We don't need to bother with munmap() here - +		 * exit_mmap(mm) is coming and it'll unmap everything. +		 * Since aio_free_ring() uses non-zero ->mmap_size +		 * as indicator that it needs to unmap the area, +		 * just set it to 0; aio_free_ring() is the only +		 * place that uses ->mmap_size, so it's safe. +		 * That way we get all munmap done to current->mm - +		 * all other callers have ctx->mm == current->mm. +		 */ +		ctx->ring_info.mmap_size = 0;  		put_ioctx(ctx);  	}  } diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index eb1cc92cd67..908e1845541 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -110,7 +110,6 @@ struct autofs_sb_info {  	int sub_version;  	int min_proto;  	int max_proto; -	int compat_daemon;  	unsigned long exp_timeout;  	unsigned int type;  	int reghost_enabled; @@ -270,6 +269,17 @@ int autofs4_fill_super(struct super_block *, void *, int);  struct autofs_info *autofs4_new_ino(struct autofs_sb_info *);  void autofs4_clean_ino(struct autofs_info *); +static inline int autofs_prepare_pipe(struct file *pipe) +{ +	if (!pipe->f_op || !pipe->f_op->write) +		return -EINVAL; +	if (!S_ISFIFO(pipe->f_dentry->d_inode->i_mode)) +		return -EINVAL; +	/* We want a packet pipe */ +	pipe->f_flags |= O_DIRECT; +	return 0; +} +  /* Queue management functions */  int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 9dacb858670..aa9103f8f01 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -376,7 +376,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,  			err = -EBADF;  			goto out;  		} -		if (!pipe->f_op || !pipe->f_op->write) { +		if (autofs_prepare_pipe(pipe) < 0) {  			err = -EPIPE;  			fput(pipe);  			goto out; @@ -385,7 +385,6 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,  		sbi->pipefd = pipefd;  		sbi->pipe = pipe;  		sbi->catatonic = 0; -		sbi->compat_daemon = is_compat_task();  	}  out:  	mutex_unlock(&sbi->wq_mutex); diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index d8dc002e9cc..6e488ebe778 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c @@ -19,7 +19,6 @@  #include <linux/parser.h>  #include <linux/bitops.h>  #include <linux/magic.h> -#include <linux/compat.h>  #include "autofs_i.h"  #include <linux/module.h> @@ -225,7 +224,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)  	set_autofs_type_indirect(&sbi->type);  	sbi->min_proto = 0;  	sbi->max_proto = 0; -	sbi->compat_daemon = is_compat_task();  	mutex_init(&sbi->wq_mutex);  	mutex_init(&sbi->pipe_mutex);  	spin_lock_init(&sbi->fs_lock); @@ -292,7 +290,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)  		printk("autofs: could not open pipe file descriptor\n");  		goto fail_dput;  	} -	if (!pipe->f_op || !pipe->f_op->write) +	if (autofs_prepare_pipe(pipe) < 0)  		goto fail_fput;  	sbi->pipe = pipe;  	sbi->pipefd = pipefd; diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 9c098db4334..da8876d38a7 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -91,24 +91,7 @@ static int autofs4_write(struct autofs_sb_info *sbi,  	return (bytes > 0);  } - -/* - * The autofs_v5 packet was misdesigned. - * - * The packets are identical on x86-32 and x86-64, but have different - * alignment. Which means that 'sizeof()' will give different results. - * Fix it up for the case of running 32-bit user mode on a 64-bit kernel. - */ -static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi) -{ -	size_t pktsz = sizeof(struct autofs_v5_packet); -#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) -	if (sbi->compat_daemon > 0) -		pktsz -= 4; -#endif -	return pktsz; -} - +	  static void autofs4_notify_daemon(struct autofs_sb_info *sbi,  				 struct autofs_wait_queue *wq,  				 int type) @@ -172,7 +155,8 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,  	{  		struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; -		pktsz = autofs_v5_packet_size(sbi); +		pktsz = sizeof(*packet); +  		packet->wait_queue_token = wq->wait_queue_token;  		packet->len = wq->name.len;  		memcpy(packet->name, wq->name.name, wq->name.len); diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 2eb12f13593..d146e181d10 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end)  	end = PAGE_ALIGN(end);  	if (end > start) {  		unsigned long addr; -		down_write(¤t->mm->mmap_sem); -		addr = do_brk(start, end - start); -		up_write(¤t->mm->mmap_sem); +		addr = vm_brk(start, end - start);  		if (BAD_ADDR(addr))  			return addr;  	} @@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)  		pos = 32;  		map_size = ex.a_text+ex.a_data;  #endif -		down_write(¤t->mm->mmap_sem); -		error = do_brk(text_addr & PAGE_MASK, map_size); -		up_write(¤t->mm->mmap_sem); +		error = vm_brk(text_addr & PAGE_MASK, map_size);  		if (error != (text_addr & PAGE_MASK)) {  			send_sig(SIGKILL, current, 0);  			return error; @@ -313,9 +309,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)  		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {  			loff_t pos = fd_offset; -			down_write(¤t->mm->mmap_sem); -			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); -			up_write(¤t->mm->mmap_sem); +			vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);  			bprm->file->f_op->read(bprm->file,  					(char __user *)N_TXTADDR(ex),  					ex.a_text+ex.a_data, &pos); @@ -325,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)  			goto beyond_if;  		} -		down_write(¤t->mm->mmap_sem); -		error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, +		error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,  			PROT_READ | PROT_EXEC,  			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,  			fd_offset); -		up_write(¤t->mm->mmap_sem);  		if (error != N_TXTADDR(ex)) {  			send_sig(SIGKILL, current, 0);  			return error;  		} -		down_write(¤t->mm->mmap_sem); - 		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, +		error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,  				PROT_READ | PROT_WRITE | PROT_EXEC,  				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,  				fd_offset + ex.a_text); -		up_write(¤t->mm->mmap_sem);  		if (error != N_DATADDR(ex)) {  			send_sig(SIGKILL, current, 0);  			return error; @@ -412,9 +402,7 @@ static int load_aout_library(struct file *file)  			       "N_TXTOFF is not page aligned. Please convert library: %s\n",  			       file->f_path.dentry->d_name.name);  		} -		down_write(¤t->mm->mmap_sem); -		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); -		up_write(¤t->mm->mmap_sem); +		vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);  		file->f_op->read(file, (char __user *)start_addr,  			ex.a_text + ex.a_data, &pos); @@ -425,12 +413,10 @@ static int load_aout_library(struct file *file)  		goto out;  	}  	/* Now use mmap to map the library into memory. */ -	down_write(¤t->mm->mmap_sem); -	error = do_mmap(file, start_addr, ex.a_text + ex.a_data, +	error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,  			PROT_READ | PROT_WRITE | PROT_EXEC,  			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,  			N_TXTOFF(ex)); -	up_write(¤t->mm->mmap_sem);  	retval = error;  	if (error != start_addr)  		goto out; @@ -438,9 +424,7 @@ static int load_aout_library(struct file *file)  	len = PAGE_ALIGN(ex.a_text + ex.a_data);  	bss = ex.a_text + ex.a_data + ex.a_bss;  	if (bss > len) { -		down_write(¤t->mm->mmap_sem); -		error = do_brk(start_addr + len, bss - len); -		up_write(¤t->mm->mmap_sem); +		error = vm_brk(start_addr + len, bss - len);  		retval = error;  		if (error != start_addr + len)  			goto out; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 48ffb3dc610..16f73541707 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end)  	end = ELF_PAGEALIGN(end);  	if (end > start) {  		unsigned long addr; -		down_write(¤t->mm->mmap_sem); -		addr = do_brk(start, end - start); -		up_write(¤t->mm->mmap_sem); +		addr = vm_brk(start, end - start);  		if (BAD_ADDR(addr))  			return addr;  	} @@ -514,9 +512,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,  		elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);  		/* Map the last of the bss segment */ -		down_write(¤t->mm->mmap_sem); -		error = do_brk(elf_bss, last_bss - elf_bss); -		up_write(¤t->mm->mmap_sem); +		error = vm_brk(elf_bss, last_bss - elf_bss);  		if (BAD_ADDR(error))  			goto out_close;  	} @@ -962,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)  		   and some applications "depend" upon this behavior.  		   Since we do not have the power to recompile these, we  		   emulate the SVr4 behavior. Sigh. */ -		down_write(¤t->mm->mmap_sem); -		error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, +		error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,  				MAP_FIXED | MAP_PRIVATE, 0); -		up_write(¤t->mm->mmap_sem);  	}  #ifdef ELF_PLAT_INIT @@ -1050,8 +1044,7 @@ static int load_elf_library(struct file *file)  		eppnt++;  	/* Now use mmap to map the library into memory. */ -	down_write(¤t->mm->mmap_sem); -	error = do_mmap(file, +	error = vm_mmap(file,  			ELF_PAGESTART(eppnt->p_vaddr),  			(eppnt->p_filesz +  			 ELF_PAGEOFFSET(eppnt->p_vaddr)), @@ -1059,7 +1052,6 @@ static int load_elf_library(struct file *file)  			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,  			(eppnt->p_offset -  			 ELF_PAGEOFFSET(eppnt->p_vaddr))); -	up_write(¤t->mm->mmap_sem);  	if (error != ELF_PAGESTART(eppnt->p_vaddr))  		goto out_free_ph; @@ -1072,11 +1064,8 @@ static int load_elf_library(struct file *file)  	len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +  			    ELF_MIN_ALIGN - 1);  	bss = eppnt->p_memsz + eppnt->p_vaddr; -	if (bss > len) { -		down_write(¤t->mm->mmap_sem); -		do_brk(len, bss - len); -		up_write(¤t->mm->mmap_sem); -	} +	if (bss > len) +		vm_brk(len, bss - len);  	error = 0;  out_free_ph: diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 9bd5612a822..d390a0fffc6 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,  	    (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))  		stack_prot |= PROT_EXEC; -	down_write(¤t->mm->mmap_sem); -	current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, +	current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot,  					 MAP_PRIVATE | MAP_ANONYMOUS |  					 MAP_UNINITIALIZED | MAP_GROWSDOWN,  					 0);  	if (IS_ERR_VALUE(current->mm->start_brk)) { -		up_write(¤t->mm->mmap_sem);  		retval = current->mm->start_brk;  		current->mm->start_brk = 0;  		goto error_kill;  	} -	up_write(¤t->mm->mmap_sem); -  	current->mm->brk = current->mm->start_brk;  	current->mm->context.end_brk = current->mm->start_brk;  	current->mm->context.end_brk += @@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(  	if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)  		mflags |= MAP_EXECUTABLE; -	down_write(&mm->mmap_sem); -	maddr = do_mmap(NULL, load_addr, top - base, +	maddr = vm_mmap(NULL, load_addr, top - base,  			PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); -	up_write(&mm->mmap_sem);  	if (IS_ERR_VALUE(maddr))  		return (int) maddr; @@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,  		/* create the mapping */  		disp = phdr->p_vaddr & ~PAGE_MASK; -		down_write(&mm->mmap_sem); -		maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, +		maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,  				phdr->p_offset - disp); -		up_write(&mm->mmap_sem);  		kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",  		       loop, phdr->p_memsz + disp, prot, flags, @@ -1143,10 +1135,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,  			unsigned long xmaddr;  			flags |= MAP_FIXED | MAP_ANONYMOUS; -			down_write(&mm->mmap_sem); -			xmaddr = do_mmap(NULL, xaddr, excess - excess1, +			xmaddr = vm_mmap(NULL, xaddr, excess - excess1,  					 prot, flags, 0); -			up_write(&mm->mmap_sem);  			kdebug("mmap[%d] <anon>"  			       " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 024d20ee3ca..6b2daf99fab 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm,  		 */  		DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); -		down_write(¤t->mm->mmap_sem); -		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, +		textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,  				  MAP_PRIVATE|MAP_EXECUTABLE, 0); -		up_write(¤t->mm->mmap_sem);  		if (!textpos || IS_ERR_VALUE(textpos)) {  			if (!textpos)  				textpos = (unsigned long) -ENOMEM; @@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm,  		len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);  		len = PAGE_ALIGN(len); -		down_write(¤t->mm->mmap_sem); -		realdatastart = do_mmap(0, 0, len, +		realdatastart = vm_mmap(0, 0, len,  			PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); -		up_write(¤t->mm->mmap_sem);  		if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {  			if (!realdatastart) @@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm,  		len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);  		len = PAGE_ALIGN(len); -		down_write(¤t->mm->mmap_sem); -		textpos = do_mmap(0, 0, len, +		textpos = vm_mmap(0, 0, len,  			PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); -		up_write(¤t->mm->mmap_sem);  		if (!textpos || IS_ERR_VALUE(textpos)) {  			if (!textpos) diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index e4fc746629a..4517aaff61b 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c @@ -147,10 +147,8 @@ static int map_som_binary(struct file *file,  	code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);  	current->mm->start_code = code_start;  	current->mm->end_code = code_start + code_size; -	down_write(¤t->mm->mmap_sem); -	retval = do_mmap(file, code_start, code_size, prot, +	retval = vm_mmap(file, code_start, code_size, prot,  			flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); -	up_write(¤t->mm->mmap_sem);  	if (retval < 0 && retval > -1024)  		goto out; @@ -158,20 +156,16 @@ static int map_som_binary(struct file *file,  	data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);  	current->mm->start_data = data_start;  	current->mm->end_data = bss_start = data_start + data_size; -	down_write(¤t->mm->mmap_sem); -	retval = do_mmap(file, data_start, data_size, +	retval = vm_mmap(file, data_start, data_size,  			prot | PROT_WRITE, flags,  			SOM_PAGESTART(hpuxhdr->exec_dfile)); -	up_write(¤t->mm->mmap_sem);  	if (retval < 0 && retval > -1024)  		goto out;  	som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);  	current->mm->start_brk = current->mm->brk = som_brk; -	down_write(¤t->mm->mmap_sem); -	retval = do_mmap(NULL, bss_start, som_brk - bss_start, +	retval = vm_mmap(NULL, bss_start, som_brk - bss_start,  			prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); -	up_write(¤t->mm->mmap_sem);  	if (retval > 0 || retval < -1024)  		retval = 0;  out: diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index f4e90748940..bcec0675023 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -22,6 +22,7 @@  #include "ulist.h"  #include "transaction.h"  #include "delayed-ref.h" +#include "locking.h"  /*   * this structure records all encountered refs on the way up to the root @@ -893,18 +894,22 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,  	s64 bytes_left = size - 1;  	struct extent_buffer *eb = eb_in;  	struct btrfs_key found_key; +	int leave_spinning = path->leave_spinning;  	if (bytes_left >= 0)  		dest[bytes_left] = '\0'; +	path->leave_spinning = 1;  	while (1) {  		len = btrfs_inode_ref_name_len(eb, iref);  		bytes_left -= len;  		if (bytes_left >= 0)  			read_extent_buffer(eb, dest + bytes_left,  						(unsigned long)(iref + 1), len); -		if (eb != eb_in) +		if (eb != eb_in) { +			btrfs_tree_read_unlock_blocking(eb);  			free_extent_buffer(eb); +		}  		ret = inode_ref_info(parent, 0, fs_root, path, &found_key);  		if (ret > 0)  			ret = -ENOENT; @@ -919,8 +924,11 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,  		slot = path->slots[0];  		eb = path->nodes[0];  		/* make sure we can use eb after releasing the path */ -		if (eb != eb_in) +		if (eb != eb_in) {  			atomic_inc(&eb->refs); +			btrfs_tree_read_lock(eb); +			btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); +		}  		btrfs_release_path(path);  		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); @@ -931,6 +939,7 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,  	}  	btrfs_release_path(path); +	path->leave_spinning = leave_spinning;  	if (ret)  		return ERR_PTR(ret); @@ -1247,7 +1256,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,  				struct btrfs_path *path,  				iterate_irefs_t *iterate, void *ctx)  { -	int ret; +	int ret = 0;  	int slot;  	u32 cur;  	u32 len; @@ -1259,7 +1268,8 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,  	struct btrfs_inode_ref *iref;  	struct btrfs_key found_key; -	while (1) { +	while (!ret) { +		path->leave_spinning = 1;  		ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path,  					&found_key);  		if (ret < 0) @@ -1275,6 +1285,8 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,  		eb = path->nodes[0];  		/* make sure we can use eb after releasing the path */  		atomic_inc(&eb->refs); +		btrfs_tree_read_lock(eb); +		btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);  		btrfs_release_path(path);  		item = btrfs_item_nr(eb, slot); @@ -1288,13 +1300,12 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,  				 (unsigned long long)found_key.objectid,  				 (unsigned long long)fs_root->objectid);  			ret = iterate(parent, iref, eb, ctx); -			if (ret) { -				free_extent_buffer(eb); +			if (ret)  				break; -			}  			len = sizeof(*iref) + name_len;  			iref = (struct btrfs_inode_ref *)((char *)iref + len);  		} +		btrfs_tree_read_unlock_blocking(eb);  		free_extent_buffer(eb);  	} @@ -1414,6 +1425,8 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,  void free_ipath(struct inode_fs_paths *ipath)  { +	if (!ipath) +		return;  	kfree(ipath->fspath);  	kfree(ipath);  } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3f65a812e28..8fd72331d60 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1078,7 +1078,7 @@ struct btrfs_fs_info {  	 * is required instead of the faster short fsync log commits  	 */  	u64 last_trans_log_full_commit; -	unsigned long mount_opt:21; +	unsigned long mount_opt;  	unsigned long compress_type:4;  	u64 max_inline;  	u64 alloc_start; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 20196f41120..d0c969beaad 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -383,17 +383,16 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,  		if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags))  			break; -		if (!failed_mirror) { -			failed = 1; -			printk(KERN_ERR "failed mirror was %d\n", eb->failed_mirror); -			failed_mirror = eb->failed_mirror; -		} -  		num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,  					      eb->start, eb->len);  		if (num_copies == 1)  			break; +		if (!failed_mirror) { +			failed = 1; +			failed_mirror = eb->read_mirror; +		} +  		mirror_num++;  		if (mirror_num == failed_mirror)  			mirror_num++; @@ -564,7 +563,7 @@ struct extent_buffer *find_eb_for_page(struct extent_io_tree *tree,  }  static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, -			       struct extent_state *state) +			       struct extent_state *state, int mirror)  {  	struct extent_io_tree *tree;  	u64 found_start; @@ -589,6 +588,7 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,  	if (!reads_done)  		goto err; +	eb->read_mirror = mirror;  	if (test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) {  		ret = -EIO;  		goto err; @@ -652,7 +652,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)  	eb = (struct extent_buffer *)page->private;  	set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); -	eb->failed_mirror = failed_mirror; +	eb->read_mirror = failed_mirror;  	if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags))  		btree_readahead_hook(root, eb, eb->start, -EIO);  	return -EIO;	/* we fixed nothing */ @@ -2254,9 +2254,9 @@ int open_ctree(struct super_block *sb,  		goto fail_sb_buffer;  	} -	if (sectorsize < PAGE_SIZE) { -		printk(KERN_WARNING "btrfs: Incompatible sector size " -		       "found on %s\n", sb->s_id); +	if (sectorsize != PAGE_SIZE) { +		printk(KERN_WARNING "btrfs: Incompatible sector size(%lu) " +		       "found on %s\n", (unsigned long)sectorsize, sb->s_id);  		goto fail_sb_buffer;  	} diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 2b35f8d14bb..6fc2e6f5aab 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2301,6 +2301,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,  				if (ret) {  					printk(KERN_DEBUG "btrfs: run_delayed_extent_op returned %d\n", ret); +					spin_lock(&delayed_refs->lock);  					return ret;  				} @@ -2331,6 +2332,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,  		if (ret) {  			printk(KERN_DEBUG "btrfs: run_one_delayed_ref returned %d\n", ret); +			spin_lock(&delayed_refs->lock);  			return ret;  		} @@ -3769,13 +3771,10 @@ again:  		 */  		if (current->journal_info)  			return -EAGAIN; -		ret = wait_event_interruptible(space_info->wait, -					       !space_info->flush); -		/* Must have been interrupted, return */ -		if (ret) { -			printk(KERN_DEBUG "btrfs: %s returning -EINTR\n", __func__); +		ret = wait_event_killable(space_info->wait, !space_info->flush); +		/* Must have been killed, return */ +		if (ret)  			return -EINTR; -		}  		spin_lock(&space_info->lock);  	} @@ -4215,8 +4214,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)  	num_bytes = calc_global_metadata_size(fs_info); -	spin_lock(&block_rsv->lock);  	spin_lock(&sinfo->lock); +	spin_lock(&block_rsv->lock);  	block_rsv->size = num_bytes; @@ -4242,8 +4241,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)  		block_rsv->full = 1;  	} -	spin_unlock(&sinfo->lock);  	spin_unlock(&block_rsv->lock); +	spin_unlock(&sinfo->lock);  }  static void init_global_block_rsv(struct btrfs_fs_info *fs_info) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index cd4b5e40022..198c2ba2fa4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -402,20 +402,28 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig,  	return 0;  } +static struct extent_state *next_state(struct extent_state *state) +{ +	struct rb_node *next = rb_next(&state->rb_node); +	if (next) +		return rb_entry(next, struct extent_state, rb_node); +	else +		return NULL; +} +  /*   * utility function to clear some bits in an extent state struct. - * it will optionally wake up any one waiting on this state (wake == 1), or - * forcibly remove the state from the tree (delete == 1). + * it will optionally wake up any one waiting on this state (wake == 1)   *   * If no bits are set on the state struct after clearing things, the   * struct is freed and removed from the tree   */ -static int clear_state_bit(struct extent_io_tree *tree, -			    struct extent_state *state, -			    int *bits, int wake) +static struct extent_state *clear_state_bit(struct extent_io_tree *tree, +					    struct extent_state *state, +					    int *bits, int wake)  { +	struct extent_state *next;  	int bits_to_clear = *bits & ~EXTENT_CTLBITS; -	int ret = state->state & bits_to_clear;  	if ((bits_to_clear & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) {  		u64 range = state->end - state->start + 1; @@ -427,6 +435,7 @@ static int clear_state_bit(struct extent_io_tree *tree,  	if (wake)  		wake_up(&state->wq);  	if (state->state == 0) { +		next = next_state(state);  		if (state->tree) {  			rb_erase(&state->rb_node, &tree->state);  			state->tree = NULL; @@ -436,8 +445,9 @@ static int clear_state_bit(struct extent_io_tree *tree,  		}  	} else {  		merge_state(tree, state); +		next = next_state(state);  	} -	return ret; +	return next;  }  static struct extent_state * @@ -476,7 +486,6 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,  	struct extent_state *state;  	struct extent_state *cached;  	struct extent_state *prealloc = NULL; -	struct rb_node *next_node;  	struct rb_node *node;  	u64 last_end;  	int err; @@ -528,14 +537,11 @@ hit_next:  	WARN_ON(state->end < start);  	last_end = state->end; -	if (state->end < end && !need_resched()) -		next_node = rb_next(&state->rb_node); -	else -		next_node = NULL; -  	/* the state doesn't have the wanted bits, go ahead */ -	if (!(state->state & bits)) +	if (!(state->state & bits)) { +		state = next_state(state);  		goto next; +	}  	/*  	 *     | ---- desired range ---- | @@ -593,16 +599,13 @@ hit_next:  		goto out;  	} -	clear_state_bit(tree, state, &bits, wake); +	state = clear_state_bit(tree, state, &bits, wake);  next:  	if (last_end == (u64)-1)  		goto out;  	start = last_end + 1; -	if (start <= end && next_node) { -		state = rb_entry(next_node, struct extent_state, -				 rb_node); +	if (start <= end && state && !need_resched())  		goto hit_next; -	}  	goto search_again;  out: @@ -2301,7 +2304,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)  	u64 start;  	u64 end;  	int whole_page; -	int failed_mirror; +	int mirror;  	int ret;  	if (err) @@ -2340,20 +2343,18 @@ static void end_bio_extent_readpage(struct bio *bio, int err)  		}  		spin_unlock(&tree->lock); +		mirror = (int)(unsigned long)bio->bi_bdev;  		if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {  			ret = tree->ops->readpage_end_io_hook(page, start, end, -							      state); +							      state, mirror);  			if (ret)  				uptodate = 0;  			else  				clean_io_failure(start, page);  		} -		if (!uptodate) -			failed_mirror = (int)(unsigned long)bio->bi_bdev; -  		if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) { -			ret = tree->ops->readpage_io_failed_hook(page, failed_mirror); +			ret = tree->ops->readpage_io_failed_hook(page, mirror);  			if (!ret && !err &&  			    test_bit(BIO_UPTODATE, &bio->bi_flags))  				uptodate = 1; @@ -2368,8 +2369,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)  			 * can't handle the error it will return -EIO and we  			 * remain responsible for that page.  			 */ -			ret = bio_readpage_error(bio, page, start, end, -							failed_mirror, NULL); +			ret = bio_readpage_error(bio, page, start, end, mirror, NULL);  			if (ret == 0) {  				uptodate =  					test_bit(BIO_UPTODATE, &bio->bi_flags); @@ -4462,7 +4462,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,  	}  	clear_bit(EXTENT_BUFFER_IOERR, &eb->bflags); -	eb->failed_mirror = 0; +	eb->read_mirror = 0;  	atomic_set(&eb->io_pages, num_reads);  	for (i = start_i; i < num_pages; i++) {  		page = extent_buffer_page(eb, i); diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index faf10eb57f7..b516c3b8dec 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -79,7 +79,7 @@ struct extent_io_ops {  					u64 start, u64 end,  				       struct extent_state *state);  	int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end, -				    struct extent_state *state); +				    struct extent_state *state, int mirror);  	int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,  				      struct extent_state *state, int uptodate);  	void (*set_bit_hook)(struct inode *inode, struct extent_state *state, @@ -135,7 +135,7 @@ struct extent_buffer {  	spinlock_t refs_lock;  	atomic_t refs;  	atomic_t io_pages; -	int failed_mirror; +	int read_mirror;  	struct list_head leak_list;  	struct rcu_head rcu_head;  	pid_t lock_owner; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index d83260d7498..53bf2d764bb 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -567,6 +567,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,  	int extent_type;  	int recow;  	int ret; +	int modify_tree = -1;  	if (drop_cache)  		btrfs_drop_extent_cache(inode, start, end - 1, 0); @@ -575,10 +576,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,  	if (!path)  		return -ENOMEM; +	if (start >= BTRFS_I(inode)->disk_i_size) +		modify_tree = 0; +  	while (1) {  		recow = 0;  		ret = btrfs_lookup_file_extent(trans, root, path, ino, -					       search_start, -1); +					       search_start, modify_tree);  		if (ret < 0)  			break;  		if (ret > 0 && path->slots[0] > 0 && search_start == start) { @@ -634,7 +638,8 @@ next_slot:  		}  		search_start = max(key.offset, start); -		if (recow) { +		if (recow || !modify_tree) { +			modify_tree = -1;  			btrfs_release_path(path);  			continue;  		} diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 115bc05e42b..61b16c641ce 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1947,7 +1947,7 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,   * extent_io.c will try to find good copies for us.   */  static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, -			       struct extent_state *state) +			       struct extent_state *state, int mirror)  {  	size_t offset = start - ((u64)page->index << PAGE_CACHE_SHIFT);  	struct inode *inode = page->mapping->host; @@ -4069,7 +4069,7 @@ static struct inode *new_simple_dir(struct super_block *s,  	BTRFS_I(inode)->dummy_inode = 1;  	inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; -	inode->i_op = &simple_dir_inode_operations; +	inode->i_op = &btrfs_dir_ro_inode_operations;  	inode->i_fop = &simple_dir_operations;  	inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;  	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; @@ -4140,14 +4140,18 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)  static int btrfs_dentry_delete(const struct dentry *dentry)  {  	struct btrfs_root *root; +	struct inode *inode = dentry->d_inode; -	if (!dentry->d_inode && !IS_ROOT(dentry)) -		dentry = dentry->d_parent; +	if (!inode && !IS_ROOT(dentry)) +		inode = dentry->d_parent->d_inode; -	if (dentry->d_inode) { -		root = BTRFS_I(dentry->d_inode)->root; +	if (inode) { +		root = BTRFS_I(inode)->root;  		if (btrfs_root_refs(&root->root_item) == 0)  			return 1; + +		if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) +			return 1;  	}  	return 0;  } @@ -4188,7 +4192,6 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,  	struct btrfs_path *path;  	struct list_head ins_list;  	struct list_head del_list; -	struct qstr q;  	int ret;  	struct extent_buffer *leaf;  	int slot; @@ -4279,7 +4282,6 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,  		while (di_cur < di_total) {  			struct btrfs_key location; -			struct dentry *tmp;  			if (verify_dir_item(root, leaf, di))  				break; @@ -4300,35 +4302,15 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,  			d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];  			btrfs_dir_item_key_to_cpu(leaf, di, &location); -			q.name = name_ptr; -			q.len = name_len; -			q.hash = full_name_hash(q.name, q.len); -			tmp = d_lookup(filp->f_dentry, &q); -			if (!tmp) { -				struct btrfs_key *newkey; -				newkey = kzalloc(sizeof(struct btrfs_key), -						 GFP_NOFS); -				if (!newkey) -					goto no_dentry; -				tmp = d_alloc(filp->f_dentry, &q); -				if (!tmp) { -					kfree(newkey); -					dput(tmp); -					goto no_dentry; -				} -				memcpy(newkey, &location, -				       sizeof(struct btrfs_key)); -				tmp->d_fsdata = newkey; -				tmp->d_flags |= DCACHE_NEED_LOOKUP; -				d_rehash(tmp); -				dput(tmp); -			} else { -				dput(tmp); -			} -no_dentry:  			/* is this a reference to our own snapshot? If so -			 * skip it +			 * skip it. +			 * +			 * In contrast to old kernels, we insert the snapshot's +			 * dir item and dir index after it has been created, so +			 * we won't find a reference to our own snapshot. We +			 * still keep the following code for backward +			 * compatibility.  			 */  			if (location.type == BTRFS_ROOT_ITEM_KEY &&  			    location.objectid == root->root_key.objectid) { diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 18cc23d164a..14f8e1faa46 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -2262,7 +2262,10 @@ static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg)  	di_args->bytes_used = dev->bytes_used;  	di_args->total_bytes = dev->total_bytes;  	memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid)); -	strncpy(di_args->path, dev->name, sizeof(di_args->path)); +	if (dev->name) +		strncpy(di_args->path, dev->name, sizeof(di_args->path)); +	else +		di_args->path[0] = '\0';  out:  	if (ret == 0 && copy_to_user(arg, di_args, sizeof(*di_args))) diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index dc5d33146fd..ac5d0108588 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c @@ -250,14 +250,12 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info,  					  struct btrfs_bio *bbio)  {  	int ret; -	int looped = 0;  	struct reada_zone *zone;  	struct btrfs_block_group_cache *cache = NULL;  	u64 start;  	u64 end;  	int i; -again:  	zone = NULL;  	spin_lock(&fs_info->reada_lock);  	ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, @@ -274,9 +272,6 @@ again:  		spin_unlock(&fs_info->reada_lock);  	} -	if (looped) -		return NULL; -  	cache = btrfs_lookup_block_group(fs_info, logical);  	if (!cache)  		return NULL; @@ -307,13 +302,15 @@ again:  	ret = radix_tree_insert(&dev->reada_zones,  				(unsigned long)(zone->end >> PAGE_CACHE_SHIFT),  				zone); -	spin_unlock(&fs_info->reada_lock); -	if (ret) { +	if (ret == -EEXIST) {  		kfree(zone); -		looped = 1; -		goto again; +		ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, +					     logical >> PAGE_CACHE_SHIFT, 1); +		if (ret == 1) +			kref_get(&zone->refcnt);  	} +	spin_unlock(&fs_info->reada_lock);  	return zone;  } @@ -323,26 +320,26 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,  					      struct btrfs_key *top, int level)  {  	int ret; -	int looped = 0;  	struct reada_extent *re = NULL; +	struct reada_extent *re_exist = NULL;  	struct btrfs_fs_info *fs_info = root->fs_info;  	struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;  	struct btrfs_bio *bbio = NULL;  	struct btrfs_device *dev; +	struct btrfs_device *prev_dev;  	u32 blocksize;  	u64 length;  	int nzones = 0;  	int i;  	unsigned long index = logical >> PAGE_CACHE_SHIFT; -again:  	spin_lock(&fs_info->reada_lock);  	re = radix_tree_lookup(&fs_info->reada_tree, index);  	if (re)  		kref_get(&re->refcnt);  	spin_unlock(&fs_info->reada_lock); -	if (re || looped) +	if (re)  		return re;  	re = kzalloc(sizeof(*re), GFP_NOFS); @@ -398,16 +395,31 @@ again:  	/* insert extent in reada_tree + all per-device trees, all or nothing */  	spin_lock(&fs_info->reada_lock);  	ret = radix_tree_insert(&fs_info->reada_tree, index, re); +	if (ret == -EEXIST) { +		re_exist = radix_tree_lookup(&fs_info->reada_tree, index); +		BUG_ON(!re_exist); +		kref_get(&re_exist->refcnt); +		spin_unlock(&fs_info->reada_lock); +		goto error; +	}  	if (ret) {  		spin_unlock(&fs_info->reada_lock); -		if (ret != -ENOMEM) { -			/* someone inserted the extent in the meantime */ -			looped = 1; -		}  		goto error;  	} +	prev_dev = NULL;  	for (i = 0; i < nzones; ++i) {  		dev = bbio->stripes[i].dev; +		if (dev == prev_dev) { +			/* +			 * in case of DUP, just add the first zone. As both +			 * are on the same device, there's nothing to gain +			 * from adding both. +			 * Also, it wouldn't work, as the tree is per device +			 * and adding would fail with EEXIST +			 */ +			continue; +		} +		prev_dev = dev;  		ret = radix_tree_insert(&dev->reada_extents, index, re);  		if (ret) {  			while (--i >= 0) { @@ -450,9 +462,7 @@ error:  	}  	kfree(bbio);  	kfree(re); -	if (looped) -		goto again; -	return NULL; +	return re_exist;  }  static void reada_kref_dummy(struct kref *kr) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 017281dbb2a..646ee21bb03 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -1279,7 +1279,9 @@ static int __update_reloc_root(struct btrfs_root *root, int del)  		if (rb_node)  			backref_tree_panic(rb_node, -EEXIST, node->bytenr);  	} else { +		spin_lock(&root->fs_info->trans_lock);  		list_del_init(&root->root_list); +		spin_unlock(&root->fs_info->trans_lock);  		kfree(node);  	}  	return 0; @@ -3811,7 +3813,7 @@ restart:  		ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5);  		if (ret < 0) { -			if (ret != -EAGAIN) { +			if (ret != -ENOSPC) {  				err = ret;  				WARN_ON(1);  				break; diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index bc015f77f3e..4f76fc3f8e8 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -1257,12 +1257,6 @@ static int scrub_checksum_data(struct scrub_block *sblock)  	if (memcmp(csum, on_disk_csum, sdev->csum_size))  		fail = 1; -	if (fail) { -		spin_lock(&sdev->stat_lock); -		++sdev->stat.csum_errors; -		spin_unlock(&sdev->stat_lock); -	} -  	return fail;  } @@ -1335,15 +1329,6 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock)  	if (memcmp(calculated_csum, on_disk_csum, sdev->csum_size))  		++crc_fail; -	if (crc_fail || fail) { -		spin_lock(&sdev->stat_lock); -		if (crc_fail) -			++sdev->stat.csum_errors; -		if (fail) -			++sdev->stat.verify_errors; -		spin_unlock(&sdev->stat_lock); -	} -  	return fail || crc_fail;  } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8d5d380f7bd..c5f8fca4195 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -815,7 +815,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)  		return 0;  	} -	btrfs_start_delalloc_inodes(root, 0);  	btrfs_wait_ordered_extents(root, 0, 0);  	trans = btrfs_start_transaction(root, 0); @@ -1148,13 +1147,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)  		if (ret)  			goto restore;  	} else { -		if (fs_info->fs_devices->rw_devices == 0) +		if (fs_info->fs_devices->rw_devices == 0) {  			ret = -EACCES;  			goto restore; +		} -		if (btrfs_super_log_root(fs_info->super_copy) != 0) +		if (btrfs_super_log_root(fs_info->super_copy) != 0) {  			ret = -EINVAL;  			goto restore; +		}  		ret = btrfs_cleanup_fs_roots(fs_info);  		if (ret) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 11b77a59db6..36422254ef6 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -73,8 +73,10 @@ loop:  	cur_trans = root->fs_info->running_transaction;  	if (cur_trans) { -		if (cur_trans->aborted) +		if (cur_trans->aborted) { +			spin_unlock(&root->fs_info->trans_lock);  			return cur_trans->aborted; +		}  		atomic_inc(&cur_trans->use_count);  		atomic_inc(&cur_trans->num_writers);  		cur_trans->num_joined++; @@ -1400,6 +1402,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,  	ret = commit_fs_roots(trans, root);  	if (ret) {  		mutex_unlock(&root->fs_info->tree_log_mutex); +		mutex_unlock(&root->fs_info->reloc_mutex);  		goto cleanup_transaction;  	} @@ -1411,6 +1414,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,  	ret = commit_cowonly_roots(trans, root);  	if (ret) {  		mutex_unlock(&root->fs_info->tree_log_mutex); +		mutex_unlock(&root->fs_info->reloc_mutex);  		goto cleanup_transaction;  	} diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 759d02486d7..1411b99555a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -3324,12 +3324,14 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,  	stripe_size = devices_info[ndevs-1].max_avail;  	num_stripes = ndevs * dev_stripes; -	if (stripe_size * num_stripes > max_chunk_size * ncopies) { +	if (stripe_size * ndevs > max_chunk_size * ncopies) {  		stripe_size = max_chunk_size * ncopies; -		do_div(stripe_size, num_stripes); +		do_div(stripe_size, ndevs);  	}  	do_div(stripe_size, dev_stripes); + +	/* align to BTRFS_STRIPE_LEN */  	do_div(stripe_size, BTRFS_STRIPE_LEN);  	stripe_size *= BTRFS_STRIPE_LEN; @@ -3805,10 +3807,11 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,  		else if (mirror_num)  			stripe_index += mirror_num - 1;  		else { +			int old_stripe_index = stripe_index;  			stripe_index = find_live_mirror(map, stripe_index,  					      map->sub_stripes, stripe_index +  					      current->pid % map->sub_stripes); -			mirror_num = stripe_index + 1; +			mirror_num = stripe_index - old_stripe_index + 1;  		}  	} else {  		/* @@ -4350,8 +4353,10 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid)  	ret = __btrfs_open_devices(fs_devices, FMODE_READ,  				   root->fs_info->bdev_holder); -	if (ret) +	if (ret) { +		free_fs_devices(fs_devices);  		goto out; +	}  	if (!fs_devices->seeding) {  		__btrfs_close_devices(fs_devices); diff --git a/fs/buffer.c b/fs/buffer.c index 36d66653b93..351e18ea2e5 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -985,7 +985,6 @@ grow_dev_page(struct block_device *bdev, sector_t block,  	return page;  failed: -	BUG();  	unlock_page(page);  	page_cache_release(page);  	return NULL; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d3421282244..811245b1ff2 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -370,13 +370,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root)  				   (int)(srcaddr->sa_family));  	} -	seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); +	seq_printf(s, ",uid=%u", cifs_sb->mnt_uid);  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)  		seq_printf(s, ",forceuid");  	else  		seq_printf(s, ",noforceuid"); -	seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); +	seq_printf(s, ",gid=%u", cifs_sb->mnt_gid);  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)  		seq_printf(s, ",forcegid");  	else @@ -434,9 +434,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root)  		seq_printf(s, ",noperm");  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)  		seq_printf(s, ",strictcache"); +	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) +		seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); +	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) +		seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid); -	seq_printf(s, ",rsize=%d", cifs_sb->rsize); -	seq_printf(s, ",wsize=%d", cifs_sb->wsize); +	seq_printf(s, ",rsize=%u", cifs_sb->rsize); +	seq_printf(s, ",wsize=%u", cifs_sb->wsize);  	/* convert actimeo and display it in seconds */  		seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f31dc9ac37b..f4d381e331c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3228,10 +3228,6 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,  	cifs_sb->mnt_uid = pvolume_info->linux_uid;  	cifs_sb->mnt_gid = pvolume_info->linux_gid; -	if (pvolume_info->backupuid_specified) -		cifs_sb->mnt_backupuid = pvolume_info->backupuid; -	if (pvolume_info->backupgid_specified) -		cifs_sb->mnt_backupgid = pvolume_info->backupgid;  	cifs_sb->mnt_file_mode = pvolume_info->file_mode;  	cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;  	cFYI(1, "file mode: 0x%hx  dir mode: 0x%hx", @@ -3262,10 +3258,14 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,  		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;  	if (pvolume_info->cifs_acl)  		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; -	if (pvolume_info->backupuid_specified) +	if (pvolume_info->backupuid_specified) {  		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; -	if (pvolume_info->backupgid_specified) +		cifs_sb->mnt_backupuid = pvolume_info->backupuid; +	} +	if (pvolume_info->backupgid_specified) {  		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; +		cifs_sb->mnt_backupgid = pvolume_info->backupgid; +	}  	if (pvolume_info->override_uid)  		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;  	if (pvolume_info->override_gid) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index fae765dac93..81725e9286e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2178,7 +2178,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,  	unsigned long nr_pages, i;  	size_t copied, len, cur_len;  	ssize_t total_written = 0; -	loff_t offset = *poffset; +	loff_t offset;  	struct iov_iter it;  	struct cifsFileInfo *open_file;  	struct cifs_tcon *tcon; @@ -2200,6 +2200,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,  	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);  	open_file = file->private_data;  	tcon = tlink_tcon(open_file->tlink); +	offset = *poffset;  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)  		pid = open_file->pid; diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index fa5c07d51dc..4c58d4a3adc 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1737,6 +1737,18 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)  		return 1;  	/* +	 * Even if the convert is compat with all granted locks, +	 * QUECVT forces it behind other locks on the convert queue. +	 */ + +	if (now && conv && (lkb->lkb_exflags & DLM_LKF_QUECVT)) { +		if (list_empty(&r->res_convertqueue)) +			return 1; +		else +			goto out; +	} + +	/*  	 * The NOORDER flag is set to avoid the standard vms rules on grant  	 * order.  	 */ diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 739b0985b39..c0b3c70ee87 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1663,8 +1663,10 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,  	if (op == EPOLL_CTL_ADD) {  		if (is_file_epoll(tfile)) {  			error = -ELOOP; -			if (ep_loop_check(ep, tfile) != 0) +			if (ep_loop_check(ep, tfile) != 0) { +				clear_tfile_check_list();  				goto error_tgt_fput; +			}  		} else  			list_add(&tfile->f_tfile_llink, &tfile_check_list);  	} diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6da193564e4..e1fb1d5de58 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1597,7 +1597,9 @@ static int parse_options(char *options, struct super_block *sb,  			 unsigned int *journal_ioprio,  			 int is_remount)  { +#ifdef CONFIG_QUOTA  	struct ext4_sb_info *sbi = EXT4_SB(sb); +#endif  	char *p;  	substring_t args[MAX_OPT_ARGS];  	int token; diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index f8411bd1b80..5f5e70e047d 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -200,10 +200,11 @@ static int make_mode(const unsigned int lmstate)  	return -1;  } -static u32 make_flags(const u32 lkid, const unsigned int gfs_flags, +static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags,  		      const int req)  {  	u32 lkf = DLM_LKF_VALBLK; +	u32 lkid = gl->gl_lksb.sb_lkid;  	if (gfs_flags & LM_FLAG_TRY)  		lkf |= DLM_LKF_NOQUEUE; @@ -227,8 +228,11 @@ static u32 make_flags(const u32 lkid, const unsigned int gfs_flags,  			BUG();  	} -	if (lkid != 0)  +	if (lkid != 0) {  		lkf |= DLM_LKF_CONVERT; +		if (test_bit(GLF_BLOCKING, &gl->gl_flags)) +			lkf |= DLM_LKF_QUECVT; +	}  	return lkf;  } @@ -250,7 +254,7 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,  	char strname[GDLM_STRNAME_BYTES] = "";  	req = make_mode(req_state); -	lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); +	lkf = make_flags(gl, flags, req);  	gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);  	gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);  	if (gl->gl_lksb.sb_lkid) { diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 28cf06e4ec8..001ef01d2fe 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -485,6 +485,7 @@ static struct inode *hugetlbfs_get_root(struct super_block *sb,  		inode->i_fop = &simple_dir_operations;  		/* directory inodes start off with i_nlink == 2 (for "." entry) */  		inc_nlink(inode); +		lockdep_annotate_inode_mutex_key(inode);  	}  	return inode;  } diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 806525a7269..840f70f5079 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -723,7 +723,7 @@ start_journal_io:  	if (commit_transaction->t_need_data_flush &&  	    (journal->j_fs_dev != journal->j_dev) &&  	    (journal->j_flags & JBD2_BARRIER)) -		blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); +		blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);  	/* Done it all: now write the commit record asynchronously. */  	if (JBD2_HAS_INCOMPAT_FEATURE(journal, @@ -859,7 +859,7 @@ wait_for_iobuf:  	if (JBD2_HAS_INCOMPAT_FEATURE(journal,  				      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) &&  	    journal->j_flags & JBD2_BARRIER) { -		blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL); +		blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL);  	}  	if (err) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 4aaf0316d76..8789210c690 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1429,7 +1429,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry  	}  	open_flags = nd->intent.open.flags; -	attr.ia_valid = 0; +	attr.ia_valid = ATTR_OPEN;  	ctx = create_nfs_open_context(dentry, open_flags);  	res = ERR_CAST(ctx); @@ -1536,7 +1536,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)  	if (IS_ERR(ctx))  		goto out; -	attr.ia_valid = 0; +	attr.ia_valid = ATTR_OPEN;  	if (openflags & O_TRUNC) {  		attr.ia_valid |= ATTR_SIZE;  		attr.ia_size = 0; diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 97ecc863dd7..b6db9e33fb7 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -59,6 +59,7 @@ struct nfs_unique_id {  #define NFS_SEQID_CONFIRMED 1  struct nfs_seqid_counter { +	ktime_t create_time;  	int owner_id;  	int flags;  	u32 counter; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f82bde005a8..60d5f4c26dd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -838,7 +838,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,  	p->o_arg.open_flags = flags;  	p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);  	p->o_arg.clientid = server->nfs_client->cl_clientid; -	p->o_arg.id = sp->so_seqid.owner_id; +	p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time); +	p->o_arg.id.uniquifier = sp->so_seqid.owner_id;  	p->o_arg.name = &dentry->d_name;  	p->o_arg.server = server;  	p->o_arg.bitmask = server->attr_bitmask; @@ -1466,8 +1467,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)  			goto unlock_no_action;  		rcu_read_unlock();  	} -	/* Update sequence id. */ -	data->o_arg.id = sp->so_seqid.owner_id; +	/* Update client id. */  	data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;  	if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {  		task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; @@ -1954,10 +1954,19 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,  	};  	int err;  	do { -		err = nfs4_handle_exception(server, -				_nfs4_do_setattr(inode, cred, fattr, sattr, state), -				&exception); +		err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); +		switch (err) { +		case -NFS4ERR_OPENMODE: +			if (state && !(state->state & FMODE_WRITE)) { +				err = -EBADF; +				if (sattr->ia_valid & ATTR_OPEN) +					err = -EACCES; +				goto out; +			} +		} +		err = nfs4_handle_exception(server, err, &exception);  	} while (exception.retry); +out:  	return err;  } @@ -4558,7 +4567,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f  static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)  {  	struct nfs_server *server = NFS_SERVER(state->inode); -	struct nfs4_exception exception = { }; +	struct nfs4_exception exception = { +		.inode = state->inode, +	};  	int err;  	do { @@ -4576,7 +4587,9 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request  static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)  {  	struct nfs_server *server = NFS_SERVER(state->inode); -	struct nfs4_exception exception = { }; +	struct nfs4_exception exception = { +		.inode = state->inode, +	};  	int err;  	err = nfs4_set_lock_state(state, request); @@ -4676,6 +4689,7 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *  {  	struct nfs4_exception exception = {  		.state = state, +		.inode = state->inode,  	};  	int err; @@ -4721,6 +4735,20 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)  	if (state == NULL)  		return -ENOLCK; +	/* +	 * Don't rely on the VFS having checked the file open mode, +	 * since it won't do this for flock() locks. +	 */ +	switch (request->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) { +	case F_RDLCK: +		if (!(filp->f_mode & FMODE_READ)) +			return -EBADF; +		break; +	case F_WRLCK: +		if (!(filp->f_mode & FMODE_WRITE)) +			return -EBADF; +	} +  	do {  		status = nfs4_proc_setlk(state, cmd, request);  		if ((status != -EAGAIN) || IS_SETLK(cmd)) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 0f43414eb25..7f0fcfc1fe9 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -393,6 +393,7 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)  static void  nfs4_init_seqid_counter(struct nfs_seqid_counter *sc)  { +	sc->create_time = ktime_get();  	sc->flags = 0;  	sc->counter = 0;  	spin_lock_init(&sc->lock); @@ -434,13 +435,17 @@ nfs4_alloc_state_owner(struct nfs_server *server,  static void  nfs4_drop_state_owner(struct nfs4_state_owner *sp)  { -	if (!RB_EMPTY_NODE(&sp->so_server_node)) { +	struct rb_node *rb_node = &sp->so_server_node; + +	if (!RB_EMPTY_NODE(rb_node)) {  		struct nfs_server *server = sp->so_server;  		struct nfs_client *clp = server->nfs_client;  		spin_lock(&clp->cl_lock); -		rb_erase(&sp->so_server_node, &server->state_owners); -		RB_CLEAR_NODE(&sp->so_server_node); +		if (!RB_EMPTY_NODE(rb_node)) { +			rb_erase(rb_node, &server->state_owners); +			RB_CLEAR_NODE(rb_node); +		}  		spin_unlock(&clp->cl_lock);  	}  } @@ -516,6 +521,14 @@ out:  /**   * nfs4_put_state_owner - Release a nfs4_state_owner   * @sp: state owner data to release + * + * Note that we keep released state owners on an LRU + * list. + * This caches valid state owners so that they can be + * reused, to avoid the OPEN_CONFIRM on minor version 0. + * It also pins the uniquifier of dropped state owners for + * a while, to ensure that those state owner names are + * never reused.   */  void nfs4_put_state_owner(struct nfs4_state_owner *sp)  { @@ -525,15 +538,9 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)  	if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))  		return; -	if (!RB_EMPTY_NODE(&sp->so_server_node)) { -		sp->so_expires = jiffies; -		list_add_tail(&sp->so_lru, &server->state_owners_lru); -		spin_unlock(&clp->cl_lock); -	} else { -		nfs4_remove_state_owner_locked(sp); -		spin_unlock(&clp->cl_lock); -		nfs4_free_state_owner(sp); -	} +	sp->so_expires = jiffies; +	list_add_tail(&sp->so_lru, &server->state_owners_lru); +	spin_unlock(&clp->cl_lock);  }  /** diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c74fdb114b4..77fc5f959c4 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -74,7 +74,7 @@ static int nfs4_stat_to_errno(int);  /* lock,open owner id:   * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT  >> 2)   */ -#define open_owner_id_maxsz	(1 + 1 + 4) +#define open_owner_id_maxsz	(1 + 2 + 1 + 1 + 2)  #define lock_owner_id_maxsz	(1 + 1 + 4)  #define decode_lockowner_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))  #define compound_encode_hdr_maxsz	(3 + (NFS4_MAXTAGLEN >> 2)) @@ -1340,12 +1340,13 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena   */  	encode_nfs4_seqid(xdr, arg->seqid);  	encode_share_access(xdr, arg->fmode); -	p = reserve_space(xdr, 32); +	p = reserve_space(xdr, 36);  	p = xdr_encode_hyper(p, arg->clientid); -	*p++ = cpu_to_be32(20); +	*p++ = cpu_to_be32(24);  	p = xdr_encode_opaque_fixed(p, "open id:", 8);  	*p++ = cpu_to_be32(arg->server->s_dev); -	xdr_encode_hyper(p, arg->id); +	*p++ = cpu_to_be32(arg->id.uniquifier); +	xdr_encode_hyper(p, arg->id.create_time);  }  static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 9a0e8ef4a40..0a4be28c2ea 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -322,7 +322,7 @@ out_bad:  	while (!list_empty(res)) {  		data = list_entry(res->next, struct nfs_read_data, list);  		list_del(&data->list); -		nfs_readdata_free(data); +		nfs_readdata_release(data);  	}  	nfs_readpage_release(req);  	return -ENOMEM; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 37412f706b3..1e6715f0616 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2767,11 +2767,15 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type,  	char *root_devname;  	size_t len; -	len = strlen(hostname) + 3; +	len = strlen(hostname) + 5;  	root_devname = kmalloc(len, GFP_KERNEL);  	if (root_devname == NULL)  		return ERR_PTR(-ENOMEM); -	snprintf(root_devname, len, "%s:/", hostname); +	/* Does hostname needs to be enclosed in brackets? */ +	if (strchr(hostname, ':')) +		snprintf(root_devname, len, "[%s]:/", hostname); +	else +		snprintf(root_devname, len, "%s:/", hostname);  	root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);  	kfree(root_devname);  	return root_mnt; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 2c68818f68a..c07462320f6 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -682,7 +682,8 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,  		req->wb_bytes = rqend - req->wb_offset;  out_unlock:  	spin_unlock(&inode->i_lock); -	nfs_clear_request_commit(req); +	if (req) +		nfs_clear_request_commit(req);  	return req;  out_flushme:  	spin_unlock(&inode->i_lock); @@ -1018,7 +1019,7 @@ out_bad:  	while (!list_empty(res)) {  		data = list_entry(res->next, struct nfs_write_data, list);  		list_del(&data->list); -		nfs_writedata_free(data); +		nfs_writedata_release(data);  	}  	nfs_redirty_request(req);  	return -ENOMEM; diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 4767429264a..ed3f9206a0e 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -577,7 +577,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)  	struct cld_net *cn = nn->cld_net;  	if (mlen != sizeof(*cmsg)) { -		dprintk("%s: got %lu bytes, expected %lu\n", __func__, mlen, +		dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,  			sizeof(*cmsg));  		return -EINVAL;  	} diff --git a/fs/pipe.c b/fs/pipe.c index 25feaa3faac..fec5e4ad071 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -346,6 +346,16 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {  	.get = generic_pipe_buf_get,  }; +static const struct pipe_buf_operations packet_pipe_buf_ops = { +	.can_merge = 0, +	.map = generic_pipe_buf_map, +	.unmap = generic_pipe_buf_unmap, +	.confirm = generic_pipe_buf_confirm, +	.release = anon_pipe_buf_release, +	.steal = generic_pipe_buf_steal, +	.get = generic_pipe_buf_get, +}; +  static ssize_t  pipe_read(struct kiocb *iocb, const struct iovec *_iov,  	   unsigned long nr_segs, loff_t pos) @@ -407,6 +417,13 @@ redo:  			ret += chars;  			buf->offset += chars;  			buf->len -= chars; + +			/* Was it a packet buffer? Clean up and exit */ +			if (buf->flags & PIPE_BUF_FLAG_PACKET) { +				total_len = chars; +				buf->len = 0; +			} +  			if (!buf->len) {  				buf->ops = NULL;  				ops->release(pipe, buf); @@ -459,6 +476,11 @@ redo:  	return ret;  } +static inline int is_packetized(struct file *file) +{ +	return (file->f_flags & O_DIRECT) != 0; +} +  static ssize_t  pipe_write(struct kiocb *iocb, const struct iovec *_iov,  	    unsigned long nr_segs, loff_t ppos) @@ -593,6 +615,11 @@ redo2:  			buf->ops = &anon_pipe_buf_ops;  			buf->offset = 0;  			buf->len = chars; +			buf->flags = 0; +			if (is_packetized(filp)) { +				buf->ops = &packet_pipe_buf_ops; +				buf->flags = PIPE_BUF_FLAG_PACKET; +			}  			pipe->nrbufs = ++bufs;  			pipe->tmp_page = NULL; @@ -1013,7 +1040,7 @@ struct file *create_write_pipe(int flags)  		goto err_dentry;  	f->f_mapping = inode->i_mapping; -	f->f_flags = O_WRONLY | (flags & O_NONBLOCK); +	f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));  	f->f_version = 0;  	return f; @@ -1057,7 +1084,7 @@ int do_pipe_flags(int *fd, int flags)  	int error;  	int fdw, fdr; -	if (flags & ~(O_CLOEXEC | O_NONBLOCK)) +	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))  		return -EINVAL;  	fw = create_write_pipe(flags); diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 2b9a7607cbd..2d60492d6df 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -597,9 +597,6 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,  		if (!page)  			continue; -		if (PageReserved(page)) -			continue; -  		/* Clear accessed and referenced bits. */  		ptep_test_and_clear_young(vma, addr, pte);  		ClearPageReferenced(page); diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h index 0dd4e87f6fb..5e5e3865f1e 100644 --- a/include/asm-generic/siginfo.h +++ b/include/asm-generic/siginfo.h @@ -35,6 +35,14 @@ typedef union sigval {  #define __ARCH_SI_BAND_T long  #endif +#ifndef __ARCH_SI_CLOCK_T +#define __ARCH_SI_CLOCK_T __kernel_clock_t +#endif + +#ifndef __ARCH_SI_ATTRIBUTES +#define __ARCH_SI_ATTRIBUTES +#endif +  #ifndef HAVE_ARCH_SIGINFO_T  typedef struct siginfo { @@ -72,8 +80,8 @@ typedef struct siginfo {  			__kernel_pid_t _pid;	/* which child */  			__ARCH_SI_UID_T _uid;	/* sender's uid */  			int _status;		/* exit code */ -			__kernel_clock_t _utime; -			__kernel_clock_t _stime; +			__ARCH_SI_CLOCK_T _utime; +			__ARCH_SI_CLOCK_T _stime;  		} _sigchld;  		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -91,7 +99,7 @@ typedef struct siginfo {  			int _fd;  		} _sigpoll;  	} _sifields; -} siginfo_t; +} __ARCH_SI_ATTRIBUTES siginfo_t;  #endif diff --git a/include/linux/efi.h b/include/linux/efi.h index 88ec80670d5..ec45ccd8708 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -554,7 +554,18 @@ extern int __init efi_setup_pcdp_console(char *);  #define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001  #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002  #define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 +#define EFI_VARIABLE_APPEND_WRITE	0x0000000000000040 +#define EFI_VARIABLE_MASK 	(EFI_VARIABLE_NON_VOLATILE | \ +				EFI_VARIABLE_BOOTSERVICE_ACCESS | \ +				EFI_VARIABLE_RUNTIME_ACCESS | \ +				EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ +				EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ +				EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ +				EFI_VARIABLE_APPEND_WRITE)  /*   * The type of search to perform when calling boottime->locate_handle   */ diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h index 05071ee34c3..d755b28ba63 100644 --- a/include/linux/gpio-pxa.h +++ b/include/linux/gpio-pxa.h @@ -13,4 +13,8 @@ extern int pxa_last_gpio;  extern int pxa_irq_to_gpio(int irq); +struct pxa_gpio_platform_data { +	int (*gpio_set_wake)(unsigned int gpio, unsigned int on); +}; +  #endif /* __GPIO_PXA_H */ diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h index 4b178067f40..56fae865e27 100644 --- a/include/linux/hsi/hsi.h +++ b/include/linux/hsi/hsi.h @@ -26,9 +26,9 @@  #include <linux/device.h>  #include <linux/mutex.h>  #include <linux/scatterlist.h> -#include <linux/spinlock.h>  #include <linux/list.h>  #include <linux/module.h> +#include <linux/notifier.h>  /* HSI message ttype */  #define HSI_MSG_READ	0 @@ -121,18 +121,18 @@ static inline int hsi_register_board_info(struct hsi_board_info const *info,   * @device: Driver model representation of the device   * @tx_cfg: HSI TX configuration   * @rx_cfg: HSI RX configuration - * @hsi_start_rx: Called after incoming wake line goes high - * @hsi_stop_rx: Called after incoming wake line goes low + * @e_handler: Callback for handling port events (RX Wake High/Low) + * @pclaimed: Keeps tracks if the clients claimed its associated HSI port + * @nb: Notifier block for port events   */  struct hsi_client {  	struct device		device;  	struct hsi_config	tx_cfg;  	struct hsi_config	rx_cfg; -	void			(*hsi_start_rx)(struct hsi_client *cl); -	void			(*hsi_stop_rx)(struct hsi_client *cl);  	/* private: */ +	void			(*ehandler)(struct hsi_client *, unsigned long);  	unsigned int		pclaimed:1; -	struct list_head	link; +	struct notifier_block	nb;  };  #define to_hsi_client(dev) container_of(dev, struct hsi_client, device) @@ -147,6 +147,10 @@ static inline void *hsi_client_drvdata(struct hsi_client *cl)  	return dev_get_drvdata(&cl->device);  } +int hsi_register_port_event(struct hsi_client *cl, +			void (*handler)(struct hsi_client *, unsigned long)); +int hsi_unregister_port_event(struct hsi_client *cl); +  /**   * struct hsi_client_driver - Driver associated to an HSI client   * @driver: Driver model representation of the driver @@ -214,8 +218,7 @@ void hsi_free_msg(struct hsi_msg *msg);   * @start_tx: Callback to inform that a client wants to TX data   * @stop_tx: Callback to inform that a client no longer wishes to TX data   * @release: Callback to inform that a client no longer uses the port - * @clients: List of hsi_clients using the port. - * @clock: Lock to serialize access to the clients list. + * @n_head: Notifier chain for signaling port events to the clients.   */  struct hsi_port {  	struct device			device; @@ -231,14 +234,14 @@ struct hsi_port {  	int				(*start_tx)(struct hsi_client *cl);  	int				(*stop_tx)(struct hsi_client *cl);  	int				(*release)(struct hsi_client *cl); -	struct list_head		clients; -	spinlock_t			clock; +	/* private */ +	struct atomic_notifier_head	n_head;  };  #define to_hsi_port(dev) container_of(dev, struct hsi_port, device)  #define hsi_get_port(cl) to_hsi_port((cl)->device.parent) -void hsi_event(struct hsi_port *port, unsigned int event); +int hsi_event(struct hsi_port *port, unsigned long event);  int hsi_claim_port(struct hsi_client *cl, unsigned int share);  void hsi_release_port(struct hsi_client *cl); @@ -270,13 +273,13 @@ struct hsi_controller {  	struct module		*owner;  	unsigned int		id;  	unsigned int		num_ports; -	struct hsi_port		*port; +	struct hsi_port		**port;  };  #define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device)  struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); -void hsi_free_controller(struct hsi_controller *hsi); +void hsi_put_controller(struct hsi_controller *hsi);  int hsi_register_controller(struct hsi_controller *hsi);  void hsi_unregister_controller(struct hsi_controller *hsi); @@ -294,7 +297,7 @@ static inline void *hsi_controller_drvdata(struct hsi_controller *hsi)  static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi,  							unsigned int num)  { -	return (num < hsi->num_ports) ? &hsi->port[num] : NULL; +	return (num < hsi->num_ports) ? hsi->port[num] : NULL;  }  /* diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 2463b610033..1f90de0cfdb 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -666,23 +666,11 @@ struct twl4030_codec_data {  	unsigned int check_defaults:1;  	unsigned int reset_registers:1;  	unsigned int hs_extmute:1; -	u16 hs_left_step; -	u16 hs_right_step; -	u16 hf_left_step; -	u16 hf_right_step;  	void (*set_hs_extmute)(int mute);  };  struct twl4030_vibra_data {  	unsigned int	coexist; - -	/* twl6040 */ -	unsigned int vibldrv_res;	/* left driver resistance */ -	unsigned int vibrdrv_res;	/* right driver resistance */ -	unsigned int viblmotor_res;	/* left motor resistance */ -	unsigned int vibrmotor_res;	/* right motor resistance */ -	int vddvibl_uV;			/* VDDVIBL volt, set 0 for fixed reg */ -	int vddvibr_uV;			/* VDDVIBR volt, set 0 for fixed reg */  };  struct twl4030_audio_data { diff --git a/include/linux/irq.h b/include/linux/irq.h index 7810406f3d8..b27cfcfd3a5 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -49,6 +49,12 @@ typedef	void (*irq_preflow_handler_t)(struct irq_data *data);   * IRQ_TYPE_LEVEL_LOW		- low level triggered   * IRQ_TYPE_LEVEL_MASK		- Mask to filter out the level bits   * IRQ_TYPE_SENSE_MASK		- Mask for all the above bits + * IRQ_TYPE_DEFAULT		- For use by some PICs to ask irq_set_type + *				  to setup the HW to a sane default (used + *                                by irqdomain map() callbacks to synchronize + *                                the HW state and SW flags for a newly + *                                allocated descriptor). + *   * IRQ_TYPE_PROBE		- Special flag for probing in progress   *   * Bits which can be modified via irq_set/clear/modify_status_flags() @@ -77,6 +83,7 @@ enum {  	IRQ_TYPE_LEVEL_LOW	= 0x00000008,  	IRQ_TYPE_LEVEL_MASK	= (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),  	IRQ_TYPE_SENSE_MASK	= 0x0000000f, +	IRQ_TYPE_DEFAULT	= IRQ_TYPE_SENSE_MASK,  	IRQ_TYPE_PROBE		= 0x00000010, diff --git a/include/linux/mfd/db5500-prcmu.h b/include/linux/mfd/db5500-prcmu.h index 9890687f582..5a049dfaf15 100644 --- a/include/linux/mfd/db5500-prcmu.h +++ b/include/linux/mfd/db5500-prcmu.h @@ -8,41 +8,14 @@  #ifndef __MFD_DB5500_PRCMU_H  #define __MFD_DB5500_PRCMU_H -#ifdef CONFIG_MFD_DB5500_PRCMU - -void db5500_prcmu_early_init(void); -int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state); -int db5500_prcmu_set_display_clocks(void); -int db5500_prcmu_disable_dsipll(void); -int db5500_prcmu_enable_dsipll(void); -int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); -int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); -void db5500_prcmu_enable_wakeups(u32 wakeups); -int db5500_prcmu_request_clock(u8 clock, bool enable); -void db5500_prcmu_config_abb_event_readout(u32 abb_events); -void db5500_prcmu_get_abb_event_buffer(void __iomem **buf); -int prcmu_resetout(u8 resoutn, u8 state); -int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, -	bool keep_ap_pll); -int db5500_prcmu_config_esram0_deep_sleep(u8 state); -void db5500_prcmu_system_reset(u16 reset_code); -u16 db5500_prcmu_get_reset_code(void); -bool db5500_prcmu_is_ac_wake_requested(void); -int db5500_prcmu_set_arm_opp(u8 opp); -int db5500_prcmu_get_arm_opp(void); - -#else /* !CONFIG_UX500_SOC_DB5500 */ - -static inline void db5500_prcmu_early_init(void) {} - -static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +static inline int prcmu_resetout(u8 resoutn, u8 state)  { -	return -ENOSYS; +	return 0;  } -static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)  { -	return -ENOSYS; +	return 0;  }  static inline int db5500_prcmu_request_clock(u8 clock, bool enable) @@ -50,69 +23,82 @@ static inline int db5500_prcmu_request_clock(u8 clock, bool enable)  	return 0;  } -static inline int db5500_prcmu_set_display_clocks(void) +static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, +	bool keep_ap_pll)  {  	return 0;  } -static inline int db5500_prcmu_disable_dsipll(void) +static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)  {  	return 0;  } -static inline int db5500_prcmu_enable_dsipll(void) +static inline u16 db5500_prcmu_get_reset_code(void)  {  	return 0;  } -static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) +static inline bool db5500_prcmu_is_ac_wake_requested(void)  {  	return 0;  } -static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} - -static inline int prcmu_resetout(u8 resoutn, u8 state) +static inline int db5500_prcmu_set_arm_opp(u8 opp)  {  	return 0;  } -static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) +static inline int db5500_prcmu_get_arm_opp(void)  {  	return 0;  } -static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}  static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} -static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, -	bool keep_ap_pll) -{ -	return 0; -} +static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}  static inline void db5500_prcmu_system_reset(u16 reset_code) {} -static inline u16 db5500_prcmu_get_reset_code(void) +static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} + +#ifdef CONFIG_MFD_DB5500_PRCMU + +void db5500_prcmu_early_init(void); +int db5500_prcmu_set_display_clocks(void); +int db5500_prcmu_disable_dsipll(void); +int db5500_prcmu_enable_dsipll(void); +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); + +#else /* !CONFIG_UX500_SOC_DB5500 */ + +static inline void db5500_prcmu_early_init(void) {} + +static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)  { -	return 0; +	return -ENOSYS;  } -static inline bool db5500_prcmu_is_ac_wake_requested(void) +static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)  { -	return 0; +	return -ENOSYS;  } -static inline int db5500_prcmu_set_arm_opp(u8 opp) +static inline int db5500_prcmu_set_display_clocks(void)  {  	return 0;  } -static inline int db5500_prcmu_get_arm_opp(void) +static inline int db5500_prcmu_disable_dsipll(void)  {  	return 0;  } +static inline int db5500_prcmu_enable_dsipll(void) +{ +	return 0; +}  #endif /* CONFIG_MFD_DB5500_PRCMU */ diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h index a2c61609d21..0b64b19d81a 100644 --- a/include/linux/mfd/rc5t583.h +++ b/include/linux/mfd/rc5t583.h @@ -26,6 +26,7 @@  #include <linux/mutex.h>  #include <linux/types.h> +#include <linux/regmap.h>  #define RC5T583_MAX_REGS		0xF8 @@ -279,14 +280,44 @@ struct rc5t583_platform_data {  	bool		enable_shutdown;  }; -int rc5t583_write(struct device *dev, u8 reg, uint8_t val); -int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val); -int rc5t583_set_bits(struct device *dev, unsigned int reg, -		unsigned int bit_mask); -int rc5t583_clear_bits(struct device *dev, unsigned int reg, -		unsigned int bit_mask); -int rc5t583_update(struct device *dev, unsigned int reg, -		unsigned int val, unsigned int mask); +static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) +{ +	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); +	return regmap_write(rc5t583->regmap, reg, val); +} + +static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) +{ +	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); +	unsigned int ival; +	int ret; +	ret = regmap_read(rc5t583->regmap, reg, &ival); +	if (!ret) +		*val = (uint8_t)ival; +	return ret; +} + +static inline int rc5t583_set_bits(struct device *dev, unsigned int reg, +			unsigned int bit_mask) +{ +	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); +	return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); +} + +static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg, +			unsigned int bit_mask) +{ +	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); +	return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); +} + +static inline int rc5t583_update(struct device *dev, unsigned int reg, +		unsigned int val, unsigned int mask) +{ +	struct rc5t583 *rc5t583 = dev_get_drvdata(dev); +	return regmap_update_bits(rc5t583->regmap, reg, mask, val); +} +  int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,  	int ext_pwr_req, int deepsleep_slot_nr);  int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base); diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 9bc9ac651da..b15b5f03f5c 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -174,8 +174,35 @@  #define TWL6040_SYSCLK_SEL_LPPLL	0  #define TWL6040_SYSCLK_SEL_HPPLL	1 +struct twl6040_codec_data { +	u16 hs_left_step; +	u16 hs_right_step; +	u16 hf_left_step; +	u16 hf_right_step; +}; + +struct twl6040_vibra_data { +	unsigned int vibldrv_res;	/* left driver resistance */ +	unsigned int vibrdrv_res;	/* right driver resistance */ +	unsigned int viblmotor_res;	/* left motor resistance */ +	unsigned int vibrmotor_res;	/* right motor resistance */ +	int vddvibl_uV;			/* VDDVIBL volt, set 0 for fixed reg */ +	int vddvibr_uV;			/* VDDVIBR volt, set 0 for fixed reg */ +}; + +struct twl6040_platform_data { +	int audpwron_gpio;	/* audio power-on gpio */ +	unsigned int irq_base; + +	struct twl6040_codec_data *codec; +	struct twl6040_vibra_data *vibra; +}; + +struct regmap; +  struct twl6040 {  	struct device *dev; +	struct regmap *regmap;  	struct mutex mutex;  	struct mutex io_mutex;  	struct mutex irq_mutex; diff --git a/include/linux/mm.h b/include/linux/mm.h index d8738a464b9..74aa71bea1e 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1393,29 +1393,20 @@ extern int install_special_mapping(struct mm_struct *mm,  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, -	unsigned long len, unsigned long prot, -	unsigned long flag, unsigned long pgoff);  extern unsigned long mmap_region(struct file *file, unsigned long addr,  	unsigned long len, unsigned long flags,  	vm_flags_t vm_flags, unsigned long pgoff); - -static inline unsigned long do_mmap(struct file *file, unsigned long addr, -	unsigned long len, unsigned long prot, -	unsigned long flag, unsigned long offset) -{ -	unsigned long ret = -EINVAL; -	if ((offset + PAGE_ALIGN(len)) < offset) -		goto out; -	if (!(offset & ~PAGE_MASK)) -		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -out: -	return ret; -} - +extern unsigned long do_mmap(struct file *, unsigned long, +        unsigned long, unsigned long, +        unsigned long, unsigned long);  extern int do_munmap(struct mm_struct *, unsigned long, size_t); -extern unsigned long do_brk(unsigned long, unsigned long); +/* These take the mm semaphore themselves */ +extern unsigned long vm_brk(unsigned long, unsigned long); +extern int vm_munmap(unsigned long, size_t); +extern unsigned long vm_mmap(struct file *, unsigned long, +        unsigned long, unsigned long, +        unsigned long, unsigned long);  /* truncate.c */  extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 01beae78f07..629b823f883 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -481,7 +481,7 @@ struct mmc_driver {  	struct device_driver drv;  	int (*probe)(struct mmc_card *);  	void (*remove)(struct mmc_card *); -	int (*suspend)(struct mmc_card *, pm_message_t); +	int (*suspend)(struct mmc_card *);  	int (*resume)(struct mmc_card *);  }; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index bfd0d1bf670..7ba3551a041 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -312,6 +312,11 @@ struct nfs4_layoutreturn {  	int rpc_status;  }; +struct stateowner_id { +	__u64	create_time; +	__u32	uniquifier; +}; +  /*   * Arguments to the open call.   */ @@ -321,7 +326,7 @@ struct nfs_openargs {  	int			open_flags;  	fmode_t			fmode;  	__u64                   clientid; -	__u64                   id; +	struct stateowner_id	id;  	union {  		struct {  			struct iattr *  attrs;    /* UNCHECKED, GUARDED */ diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index fee4349364f..e4d1de74250 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -12,6 +12,8 @@  #ifndef __LINUX_PINCTRL_MACHINE_H  #define __LINUX_PINCTRL_MACHINE_H +#include <linux/bug.h> +  #include "pinctrl-state.h"  enum pinctrl_map_type { @@ -148,7 +150,7 @@ struct pinctrl_map {  #define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs)		\  	PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs) -#ifdef CONFIG_PINMUX +#ifdef CONFIG_PINCTRL  extern int pinctrl_register_mappings(struct pinctrl_map const *map,  				unsigned num_maps); diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 6d626ff0cfd..e1ac1ce16fb 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -6,6 +6,7 @@  #define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */  #define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */  #define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */ +#define PIPE_BUF_FLAG_PACKET	0x08	/* read() as a packet */  /**   *	struct pipe_buffer - a linux kernel pipe buffer diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 70a3f8d4911..775292a66fa 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -238,11 +238,12 @@ enum {  /*   * The callback notifies userspace to release buffers when skb DMA is done in   * lower device, the skb last reference should be 0 when calling this. - * The desc is used to track userspace buffer index. + * The ctx field is used to track device context. + * The desc field is used to track userspace buffer index.   */  struct ubuf_info { -	void (*callback)(void *); -	void *arg; +	void (*callback)(struct ubuf_info *); +	void *ctx;  	unsigned long desc;  }; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 98679b061b6..fa702aeb503 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -254,7 +254,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)   *	driver is finished with this message, it must call   *	spi_finalize_current_message() so the subsystem can issue the next   *	transfer - * @prepare_transfer_hardware: there are currently no more messages on the + * @unprepare_transfer_hardware: there are currently no more messages on the   *	queue so the subsystem notifies the driver that it may relax the   *	hardware by issuing this call   * diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 5de415707c2..d28cc78a38e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -126,6 +126,8 @@ struct usb_hcd {  	unsigned		wireless:1;	/* Wireless USB HCD */  	unsigned		authorized_default:1;  	unsigned		has_tt:1;	/* Integrated TT in root hub */ +	unsigned		broken_pci_sleep:1;	/* Don't put the +			controller in PCI-D3 for system sleep */  	unsigned int		irq;		/* irq allocated */  	void __iomem		*regs;		/* device memory/io */ diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index f67810f8f21..38ab3f46346 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -94,6 +94,7 @@ struct usb_phy {  	struct usb_otg		*otg; +	struct device		*io_dev;  	struct usb_phy_io_ops	*io_ops;  	void __iomem		*io_priv; diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 03b90cdc192..06f8e385825 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -26,13 +26,14 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,  		PGFREE, PGACTIVATE, PGDEACTIVATE,  		PGFAULT, PGMAJFAULT,  		FOR_ALL_ZONES(PGREFILL), -		FOR_ALL_ZONES(PGSTEAL), +		FOR_ALL_ZONES(PGSTEAL_KSWAPD), +		FOR_ALL_ZONES(PGSTEAL_DIRECT),  		FOR_ALL_ZONES(PGSCAN_KSWAPD),  		FOR_ALL_ZONES(PGSCAN_DIRECT),  #ifdef CONFIG_NUMA  		PGSCAN_ZONE_RECLAIM_FAILED,  #endif -		PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, +		PGINODESTEAL, SLABS_SCANNED, KSWAPD_INODESTEAL,  		KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY,  		KSWAPD_SKIP_CONGESTION_WAIT,  		PAGEOUTRUN, ALLOCSTALL, PGROTATED, diff --git a/include/net/dst.h b/include/net/dst.h index 59c5d18cc38..ff4da42fcfc 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -36,7 +36,11 @@ struct dst_entry {  	struct net_device       *dev;  	struct  dst_ops	        *ops;  	unsigned long		_metrics; -	unsigned long		expires; +	union { +		unsigned long           expires; +		/* point to where the dst_entry copied from */ +		struct dst_entry        *from; +	};  	struct dst_entry	*path;  	struct neighbour __rcu	*_neighbour;  #ifdef CONFIG_XFRM diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index b26bb810198..0ae759a6c76 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -123,6 +123,54 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)  	return ((struct rt6_info *)dst)->rt6i_idev;  } +static inline void rt6_clean_expires(struct rt6_info *rt) +{ +	if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) +		dst_release(rt->dst.from); + +	rt->rt6i_flags &= ~RTF_EXPIRES; +	rt->dst.from = NULL; +} + +static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) +{ +	if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) +		dst_release(rt->dst.from); + +	rt->rt6i_flags |= RTF_EXPIRES; +	rt->dst.expires = expires; +} + +static inline void rt6_update_expires(struct rt6_info *rt, int timeout) +{ +	if (!(rt->rt6i_flags & RTF_EXPIRES)) { +		if (rt->dst.from) +			dst_release(rt->dst.from); +		/* dst_set_expires relies on expires == 0  +		 * if it has not been set previously. +		 */ +		rt->dst.expires = 0; +	} + +	dst_set_expires(&rt->dst, timeout); +	rt->rt6i_flags |= RTF_EXPIRES; +} + +static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) +{ +	struct dst_entry *new = (struct dst_entry *) from; + +	if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) { +		if (new == rt->dst.from) +			return; +		dst_release(rt->dst.from); +	} + +	rt->rt6i_flags &= ~RTF_EXPIRES; +	rt->dst.from = new; +	dst_hold(new); +} +  struct fib6_walker_t {  	struct list_head lh;  	struct fib6_node *root, *node; diff --git a/include/net/red.h b/include/net/red.h index 77d4c3745cb..ef46058d35b 100644 --- a/include/net/red.h +++ b/include/net/red.h @@ -245,7 +245,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(const struct red_parms  	 *  	 * dummy packets as a burst after idle time, i.e.  	 * -	 * 	p->qavg *= (1-W)^m +	 * 	v->qavg *= (1-W)^m  	 *  	 * This is an apparently overcomplicated solution (f.e. we have to  	 * precompute a table to make this calculation in reasonable time) @@ -279,7 +279,7 @@ static inline unsigned long red_calc_qavg_no_idle_time(const struct red_parms *p  						       unsigned int backlog)  {  	/* -	 * NOTE: p->qavg is fixed point number with point at Wlog. +	 * NOTE: v->qavg is fixed point number with point at Wlog.  	 * The formula below is equvalent to floating point  	 * version:  	 * @@ -390,7 +390,7 @@ static inline void red_adaptative_algo(struct red_parms *p, struct red_vars *v)  	if (red_is_idling(v))  		qavg = red_calc_qavg_from_idle_time(p, v); -	/* p->qavg is fixed point number with point at Wlog */ +	/* v->qavg is fixed point number with point at Wlog */  	qavg >>= p->Wlog;  	if (qavg > p->target_max && p->max_P <= MAX_P_MAX) diff --git a/include/net/sock.h b/include/net/sock.h index a6ba1f8871f..188532ee88b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -246,6 +246,7 @@ struct cg_proto;    *	@sk_user_data: RPC layer private data    *	@sk_sndmsg_page: cached page for sendmsg    *	@sk_sndmsg_off: cached offset for sendmsg +  *	@sk_peek_off: current peek_offset value    *	@sk_send_head: front of stuff to transmit    *	@sk_security: used by security modules    *	@sk_mark: generic packet mark diff --git a/init/main.c b/init/main.c index 9d454f09f3b..44b2433334c 100644 --- a/init/main.c +++ b/init/main.c @@ -225,13 +225,9 @@ static int __init loglevel(char *str)  early_param("loglevel", loglevel); -/* - * Unknown boot options get handed to init, unless they look like - * unused parameters (modprobe will find them in /proc/cmdline). - */ -static int __init unknown_bootoption(char *param, char *val) +/* Change NUL term back to "=", to make "param" the whole string. */ +static int __init repair_env_string(char *param, char *val)  { -	/* Change NUL term back to "=", to make "param" the whole string. */  	if (val) {  		/* param=val or param="val"? */  		if (val == param+strlen(param)+1) @@ -243,6 +239,16 @@ static int __init unknown_bootoption(char *param, char *val)  		} else  			BUG();  	} +	return 0; +} + +/* + * Unknown boot options get handed to init, unless they look like + * unused parameters (modprobe will find them in /proc/cmdline). + */ +static int __init unknown_bootoption(char *param, char *val) +{ +	repair_env_string(param, val);  	/* Handle obsolete-style parameters */  	if (obsolete_checksetup(param)) @@ -732,11 +738,6 @@ static char *initcall_level_names[] __initdata = {  	"late parameters",  }; -static int __init ignore_unknown_bootoption(char *param, char *val) -{ -	return 0; -} -  static void __init do_initcall_level(int level)  {  	extern const struct kernel_param __start___param[], __stop___param[]; @@ -747,7 +748,7 @@ static void __init do_initcall_level(int level)  		   static_command_line, __start___param,  		   __stop___param - __start___param,  		   level, level, -		   ignore_unknown_bootoption); +		   repair_env_string);  	for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)  		do_one_initcall(*fn); diff --git a/kernel/events/core.c b/kernel/events/core.c index a6a9ec4cd8f..fd126f82b57 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3183,7 +3183,7 @@ static void perf_event_for_each(struct perf_event *event,  	perf_event_for_each_child(event, func);  	func(event);  	list_for_each_entry(sibling, &event->sibling_list, group_entry) -		perf_event_for_each_child(event, func); +		perf_event_for_each_child(sibling, func);  	mutex_unlock(&ctx->mutex);  } diff --git a/kernel/irq/debug.h b/kernel/irq/debug.h index 97a8bfadc88..e75e29e4434 100644 --- a/kernel/irq/debug.h +++ b/kernel/irq/debug.h @@ -4,10 +4,10 @@  #include <linux/kallsyms.h> -#define P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) -#define PS(f) if (desc->istate & f) printk("%14s set\n", #f) +#define ___P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) +#define ___PS(f) if (desc->istate & f) printk("%14s set\n", #f)  /* FIXME */ -#define PD(f) do { } while (0) +#define ___PD(f) do { } while (0)  static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)  { @@ -23,23 +23,23 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)  		print_symbol("%s\n", (unsigned long)desc->action->handler);  	} -	P(IRQ_LEVEL); -	P(IRQ_PER_CPU); -	P(IRQ_NOPROBE); -	P(IRQ_NOREQUEST); -	P(IRQ_NOTHREAD); -	P(IRQ_NOAUTOEN); +	___P(IRQ_LEVEL); +	___P(IRQ_PER_CPU); +	___P(IRQ_NOPROBE); +	___P(IRQ_NOREQUEST); +	___P(IRQ_NOTHREAD); +	___P(IRQ_NOAUTOEN); -	PS(IRQS_AUTODETECT); -	PS(IRQS_REPLAY); -	PS(IRQS_WAITING); -	PS(IRQS_PENDING); +	___PS(IRQS_AUTODETECT); +	___PS(IRQS_REPLAY); +	___PS(IRQS_WAITING); +	___PS(IRQS_PENDING); -	PD(IRQS_INPROGRESS); -	PD(IRQS_DISABLED); -	PD(IRQS_MASKED); +	___PD(IRQS_INPROGRESS); +	___PD(IRQS_DISABLED); +	___PD(IRQS_MASKED);  } -#undef P -#undef PS -#undef PD +#undef ___P +#undef ___PS +#undef ___PD diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 8742fd013a9..eef311a58a6 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -51,6 +51,23 @@  #define MAP_PAGE_ENTRIES	(PAGE_SIZE / sizeof(sector_t) - 1) +/* + * Number of free pages that are not high. + */ +static inline unsigned long low_free_pages(void) +{ +	return nr_free_pages() - nr_free_highpages(); +} + +/* + * Number of pages required to be kept free while writing the image. Always + * half of all available low pages before the writing starts. + */ +static inline unsigned long reqd_free_pages(void) +{ +	return low_free_pages() / 2; +} +  struct swap_map_page {  	sector_t entries[MAP_PAGE_ENTRIES];  	sector_t next_swap; @@ -72,7 +89,7 @@ struct swap_map_handle {  	sector_t cur_swap;  	sector_t first_sector;  	unsigned int k; -	unsigned long nr_free_pages, written; +	unsigned long reqd_free_pages;  	u32 crc32;  }; @@ -316,8 +333,7 @@ static int get_swap_writer(struct swap_map_handle *handle)  		goto err_rel;  	}  	handle->k = 0; -	handle->nr_free_pages = nr_free_pages() >> 1; -	handle->written = 0; +	handle->reqd_free_pages = reqd_free_pages();  	handle->first_sector = handle->cur_swap;  	return 0;  err_rel: @@ -352,11 +368,11 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,  		handle->cur_swap = offset;  		handle->k = 0;  	} -	if (bio_chain && ++handle->written > handle->nr_free_pages) { +	if (bio_chain && low_free_pages() <= handle->reqd_free_pages) {  		error = hib_wait_on_bio_chain(bio_chain);  		if (error)  			goto out; -		handle->written = 0; +		handle->reqd_free_pages = reqd_free_pages();  	}   out:  	return error; @@ -618,7 +634,7 @@ static int save_image_lzo(struct swap_map_handle *handle,  	 * Adjust number of free pages after all allocations have been done.  	 * We don't want to run out of pages when writing.  	 */ -	handle->nr_free_pages = nr_free_pages() >> 1; +	handle->reqd_free_pages = reqd_free_pages();  	/*  	 * Start the CRC32 thread. diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 1050d6d3922..d0c5baf1ab1 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1820,7 +1820,6 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),  	 * a quiescent state betweentimes.  	 */  	local_irq_save(flags); -	WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));  	rdp = this_cpu_ptr(rsp->rda);  	/* Add the callback to our list. */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4603b9d8f30..0533a688ce2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6405,16 +6405,26 @@ static void __sdt_free(const struct cpumask *cpu_map)  		struct sd_data *sdd = &tl->data;  		for_each_cpu(j, cpu_map) { -			struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j); -			if (sd && (sd->flags & SD_OVERLAP)) -				free_sched_groups(sd->groups, 0); -			kfree(*per_cpu_ptr(sdd->sd, j)); -			kfree(*per_cpu_ptr(sdd->sg, j)); -			kfree(*per_cpu_ptr(sdd->sgp, j)); +			struct sched_domain *sd; + +			if (sdd->sd) { +				sd = *per_cpu_ptr(sdd->sd, j); +				if (sd && (sd->flags & SD_OVERLAP)) +					free_sched_groups(sd->groups, 0); +				kfree(*per_cpu_ptr(sdd->sd, j)); +			} + +			if (sdd->sg) +				kfree(*per_cpu_ptr(sdd->sg, j)); +			if (sdd->sgp) +				kfree(*per_cpu_ptr(sdd->sgp, j));  		}  		free_percpu(sdd->sd); +		sdd->sd = NULL;  		free_percpu(sdd->sg); +		sdd->sg = NULL;  		free_percpu(sdd->sgp); +		sdd->sgp = NULL;  	}  } diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0d97ebdc58f..e9553640c1c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -784,7 +784,7 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se)  		update_load_add(&rq_of(cfs_rq)->load, se->load.weight);  #ifdef CONFIG_SMP  	if (entity_is_task(se)) -		list_add_tail(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); +		list_add(&se->group_node, &rq_of(cfs_rq)->cfs_tasks);  #endif  	cfs_rq->nr_running++;  } @@ -3215,6 +3215,8 @@ static int move_one_task(struct lb_env *env)  static unsigned long task_h_load(struct task_struct *p); +static const unsigned int sched_nr_migrate_break = 32; +  /*   * move_tasks tries to move up to load_move weighted load from busiest to   * this_rq, as part of a balancing operation within domain "sd". @@ -3242,7 +3244,7 @@ static int move_tasks(struct lb_env *env)  		/* take a breather every nr_migrate tasks */  		if (env->loop > env->loop_break) { -			env->loop_break += sysctl_sched_nr_migrate; +			env->loop_break += sched_nr_migrate_break;  			env->flags |= LBF_NEED_BREAK;  			break;  		} @@ -3252,7 +3254,7 @@ static int move_tasks(struct lb_env *env)  		load = task_h_load(p); -		if (load < 16 && !env->sd->nr_balance_failed) +		if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed)  			goto next;  		if ((load / 2) > env->load_move) @@ -4407,7 +4409,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,  		.dst_cpu	= this_cpu,  		.dst_rq		= this_rq,  		.idle		= idle, -		.loop_break	= sysctl_sched_nr_migrate, +		.loop_break	= sched_nr_migrate_break,  	};  	cpumask_copy(cpus, cpu_active_mask); @@ -4445,10 +4447,10 @@ redo:  		 * correctly treated as an imbalance.  		 */  		env.flags |= LBF_ALL_PINNED; -		env.load_move = imbalance; -		env.src_cpu = busiest->cpu; -		env.src_rq = busiest; -		env.loop_max = busiest->nr_running; +		env.load_move	= imbalance; +		env.src_cpu	= busiest->cpu; +		env.src_rq	= busiest; +		env.loop_max	= min_t(unsigned long, sysctl_sched_nr_migrate, busiest->nr_running);  more_balance:  		local_irq_save(flags); diff --git a/kernel/sched/features.h b/kernel/sched/features.h index e61fd73913d..de00a486c5c 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -68,3 +68,4 @@ SCHED_FEAT(TTWU_QUEUE, true)  SCHED_FEAT(FORCE_SD_OVERLAP, false)  SCHED_FEAT(RT_RUNTIME_SHARE, true) +SCHED_FEAT(LB_MIN, false) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index bf57abdc7bd..f113755695e 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -346,7 +346,8 @@ int tick_resume_broadcast(void)  						     tick_get_broadcast_mask());  			break;  		case TICKDEV_MODE_ONESHOT: -			broadcast = tick_resume_broadcast_oneshot(bc); +			if (!cpumask_empty(tick_get_broadcast_mask())) +				broadcast = tick_resume_broadcast_oneshot(bc);  			break;  		}  	} @@ -373,6 +374,9 @@ static int tick_broadcast_set_event(ktime_t expires, int force)  {  	struct clock_event_device *bc = tick_broadcast_device.evtdev; +	if (bc->mode != CLOCK_EVT_MODE_ONESHOT) +		clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); +  	return clockevents_program_event(bc, expires, force);  } @@ -531,7 +535,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)  		int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;  		bc->event_handler = tick_handle_oneshot_broadcast; -		clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);  		/* Take the do_timer update */  		tick_do_timer_cpu = cpu; @@ -549,6 +552,7 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)  			   to_cpumask(tmpmask));  		if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { +			clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);  			tick_broadcast_init_next_event(to_cpumask(tmpmask),  						       tick_next_period);  			tick_broadcast_set_event(tick_next_period, 1); @@ -577,15 +581,10 @@ void tick_broadcast_switch_to_oneshot(void)  	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);  	tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; - -	if (cpumask_empty(tick_get_broadcast_mask())) -		goto end; -  	bc = tick_broadcast_device.evtdev;  	if (bc)  		tick_broadcast_setup_oneshot(bc); -end:  	raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);  } diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ed7b5d1e12f..2a22255c101 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4629,7 +4629,8 @@ static ssize_t  rb_simple_read(struct file *filp, char __user *ubuf,  	       size_t cnt, loff_t *ppos)  { -	struct ring_buffer *buffer = filp->private_data; +	struct trace_array *tr = filp->private_data; +	struct ring_buffer *buffer = tr->buffer;  	char buf[64];  	int r; @@ -4647,7 +4648,8 @@ static ssize_t  rb_simple_write(struct file *filp, const char __user *ubuf,  		size_t cnt, loff_t *ppos)  { -	struct ring_buffer *buffer = filp->private_data; +	struct trace_array *tr = filp->private_data; +	struct ring_buffer *buffer = tr->buffer;  	unsigned long val;  	int ret; @@ -4734,7 +4736,7 @@ static __init int tracer_init_debugfs(void)  			  &trace_clock_fops);  	trace_create_file("tracing_on", 0644, d_tracer, -			    global_trace.buffer, &rb_simple_fops); +			    &global_trace, &rb_simple_fops);  #ifdef CONFIG_DYNAMIC_FTRACE  	trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 95059f091a2..f95d65da6db 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -836,11 +836,11 @@ extern const char *__stop___trace_bprintk_fmt[];  		     filter)  #include "trace_entries.h" -#ifdef CONFIG_FUNCTION_TRACER +#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_FUNCTION_TRACER)  int perf_ftrace_event_register(struct ftrace_event_call *call,  			       enum trace_reg type, void *data);  #else  #define perf_ftrace_event_register NULL -#endif /* CONFIG_FUNCTION_TRACER */ +#endif  #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 859fae6b182..df611a0e76c 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -652,6 +652,8 @@ int trace_print_lat_context(struct trace_iterator *iter)  {  	u64 next_ts;  	int ret; +	/* trace_find_next_entry will reset ent_size */ +	int ent_size = iter->ent_size;  	struct trace_seq *s = &iter->seq;  	struct trace_entry *entry = iter->ent,  			   *next_entry = trace_find_next_entry(iter, NULL, @@ -660,6 +662,9 @@ int trace_print_lat_context(struct trace_iterator *iter)  	unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);  	unsigned long rel_usecs; +	/* Restore the original ent_size */ +	iter->ent_size = ent_size; +  	if (!next_entry)  		next_ts = iter->ts;  	rel_usecs = ns2usecs(next_ts - iter->ts); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index cd65cb19c94..5a16423a512 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -532,7 +532,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h,  				struct vm_area_struct *vma,  				unsigned long address, int avoid_reserve)  { -	struct page *page; +	struct page *page = NULL;  	struct mempolicy *mpol;  	nodemask_t *nodemask;  	struct zonelist *zonelist; diff --git a/mm/memblock.c b/mm/memblock.c index 99f28559950..a44eab3157f 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -330,6 +330,9 @@ static int __init_memblock memblock_add_region(struct memblock_type *type,  	phys_addr_t end = base + memblock_cap_size(base, &size);  	int i, nr_new; +	if (!size) +		return 0; +  	/* special case for empty array */  	if (type->regions[0].size == 0) {  		WARN_ON(type->cnt != 1 || type->total_size); @@ -430,6 +433,9 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type,  	*start_rgn = *end_rgn = 0; +	if (!size) +		return 0; +  	/* we'll create at most two more regions */  	while (type->cnt + 2 > type->max)  		if (memblock_double_array(type) < 0) @@ -514,7 +520,6 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)  		     (unsigned long long)base,  		     (unsigned long long)base + size,  		     (void *)_RET_IP_); -	BUG_ON(0 == size);  	return memblock_add_region(_rgn, base, size, MAX_NUMNODES);  } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index b868def9bcc..31ab9c3f017 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2476,10 +2476,10 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)  static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,  				       struct page *page,  				       unsigned int nr_pages, -				       struct page_cgroup *pc,  				       enum charge_type ctype,  				       bool lrucare)  { +	struct page_cgroup *pc = lookup_page_cgroup(page);  	struct zone *uninitialized_var(zone);  	bool was_on_lru = false;  	bool anon; @@ -2716,7 +2716,6 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,  {  	struct mem_cgroup *memcg = NULL;  	unsigned int nr_pages = 1; -	struct page_cgroup *pc;  	bool oom = true;  	int ret; @@ -2730,11 +2729,10 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,  		oom = false;  	} -	pc = lookup_page_cgroup(page);  	ret = __mem_cgroup_try_charge(mm, gfp_mask, nr_pages, &memcg, oom);  	if (ret == -ENOMEM)  		return ret; -	__mem_cgroup_commit_charge(memcg, page, nr_pages, pc, ctype, false); +	__mem_cgroup_commit_charge(memcg, page, nr_pages, ctype, false);  	return 0;  } @@ -2831,16 +2829,13 @@ static void  __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg,  					enum charge_type ctype)  { -	struct page_cgroup *pc; -  	if (mem_cgroup_disabled())  		return;  	if (!memcg)  		return;  	cgroup_exclude_rmdir(&memcg->css); -	pc = lookup_page_cgroup(page); -	__mem_cgroup_commit_charge(memcg, page, 1, pc, ctype, true); +	__mem_cgroup_commit_charge(memcg, page, 1, ctype, true);  	/*  	 * Now swap is on-memory. This means this page may be  	 * counted both as mem and swap....double count. @@ -3298,14 +3293,13 @@ int mem_cgroup_prepare_migration(struct page *page,  	 * page. In the case new page is migrated but not remapped, new page's  	 * mapcount will be finally 0 and we call uncharge in end_migration().  	 */ -	pc = lookup_page_cgroup(newpage);  	if (PageAnon(page))  		ctype = MEM_CGROUP_CHARGE_TYPE_MAPPED;  	else if (page_is_file_cache(page))  		ctype = MEM_CGROUP_CHARGE_TYPE_CACHE;  	else  		ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM; -	__mem_cgroup_commit_charge(memcg, newpage, 1, pc, ctype, false); +	__mem_cgroup_commit_charge(memcg, newpage, 1, ctype, false);  	return ret;  } @@ -3392,8 +3386,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage,  	 * the newpage may be on LRU(or pagevec for LRU) already. We lock  	 * LRU while we overwrite pc->mem_cgroup.  	 */ -	pc = lookup_page_cgroup(newpage); -	__mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true); +	__mem_cgroup_commit_charge(memcg, newpage, 1, type, true);  }  #ifdef CONFIG_DEBUG_VM diff --git a/mm/mempolicy.c b/mm/mempolicy.c index cfb6c867875..b1956913752 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1361,11 +1361,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,  	mm = get_task_mm(task);  	put_task_struct(task); -	if (mm) -		err = do_migrate_pages(mm, old, new, -			capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); -	else + +	if (!mm) {  		err = -EINVAL; +		goto out; +	} + +	err = do_migrate_pages(mm, old, new, +		capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);  	mmput(mm);  out: diff --git a/mm/migrate.c b/mm/migrate.c index 51c08a0c6f6..11072383ae1 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1388,14 +1388,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,  	mm = get_task_mm(task);  	put_task_struct(task); -	if (mm) { -		if (nodes) -			err = do_pages_move(mm, task_nodes, nr_pages, pages, -					    nodes, status, flags); -		else -			err = do_pages_stat(mm, nr_pages, pages, status); -	} else -		err = -EINVAL; +	if (!mm) +		return -EINVAL; + +	if (nodes) +		err = do_pages_move(mm, task_nodes, nr_pages, pages, +				    nodes, status, flags); +	else +		err = do_pages_stat(mm, nr_pages, pages, status);  	mmput(mm);  	return err; diff --git a/mm/mmap.c b/mm/mmap.c index a7bf6a31c9f..848ef52d960 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)  	return next;  } +static unsigned long do_brk(unsigned long addr, unsigned long len); +  SYSCALL_DEFINE1(brk, unsigned long, brk)  {  	unsigned long rlim, retval; @@ -951,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint)   * The caller must hold down_write(¤t->mm->mmap_sem).   */ -unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,  			unsigned long len, unsigned long prot,  			unsigned long flags, unsigned long pgoff)  { @@ -1087,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,  	return mmap_region(file, addr, len, flags, vm_flags, pgoff);  } -EXPORT_SYMBOL(do_mmap_pgoff); + +unsigned long do_mmap(struct file *file, unsigned long addr, +	unsigned long len, unsigned long prot, +	unsigned long flag, unsigned long offset) +{ +	if (unlikely(offset + PAGE_ALIGN(len) < offset)) +		return -EINVAL; +	if (unlikely(offset & ~PAGE_MASK)) +		return -EINVAL; +	return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +} +EXPORT_SYMBOL(do_mmap); + +unsigned long vm_mmap(struct file *file, unsigned long addr, +	unsigned long len, unsigned long prot, +	unsigned long flag, unsigned long offset) +{ +	unsigned long ret; +	struct mm_struct *mm = current->mm; + +	down_write(&mm->mmap_sem); +	ret = do_mmap(file, addr, len, prot, flag, offset); +	up_write(&mm->mmap_sem); +	return ret; +} +EXPORT_SYMBOL(vm_mmap);  SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,  		unsigned long, prot, unsigned long, flags, @@ -2105,21 +2132,25 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)  	return 0;  } -  EXPORT_SYMBOL(do_munmap); -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +int vm_munmap(unsigned long start, size_t len)  {  	int ret;  	struct mm_struct *mm = current->mm; -	profile_munmap(addr); -  	down_write(&mm->mmap_sem); -	ret = do_munmap(mm, addr, len); +	ret = do_munmap(mm, start, len);  	up_write(&mm->mmap_sem);  	return ret;  } +EXPORT_SYMBOL(vm_munmap); + +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +{ +	profile_munmap(addr); +	return vm_munmap(addr, len); +}  static inline void verify_mm_writelocked(struct mm_struct *mm)  { @@ -2136,7 +2167,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)   *  anonymous maps.  eventually we may be able to do some   *  brk-specific accounting here.   */ -unsigned long do_brk(unsigned long addr, unsigned long len) +static unsigned long do_brk(unsigned long addr, unsigned long len)  {  	struct mm_struct * mm = current->mm;  	struct vm_area_struct * vma, * prev; @@ -2232,7 +2263,17 @@ out:  	return addr;  } -EXPORT_SYMBOL(do_brk); +unsigned long vm_brk(unsigned long addr, unsigned long len) +{ +	struct mm_struct *mm = current->mm; +	unsigned long ret; + +	down_write(&mm->mmap_sem); +	ret = do_brk(addr, len); +	up_write(&mm->mmap_sem); +	return ret; +} +EXPORT_SYMBOL(vm_brk);  /* Release all mmaps. */  void exit_mmap(struct mm_struct *mm) diff --git a/mm/nobootmem.c b/mm/nobootmem.c index 24f0fc1a56d..e53bb8a256b 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c @@ -298,13 +298,19 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,  	if (WARN_ON_ONCE(slab_is_available()))  		return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id); +again:  	ptr = __alloc_memory_core_early(pgdat->node_id, size, align,  					 goal, -1ULL);  	if (ptr)  		return ptr; -	return __alloc_memory_core_early(MAX_NUMNODES, size, align, -					 goal, -1ULL); +	ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, +					goal, -1ULL); +	if (!ptr && goal) { +		goal = 0; +		goto again; +	} +	return ptr;  }  void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size, diff --git a/mm/nommu.c b/mm/nommu.c index f59e170fceb..bb8f4f004a8 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1233,7 +1233,7 @@ enomem:  /*   * handle mapping creation for uClinux   */ -unsigned long do_mmap_pgoff(struct file *file, +static unsigned long do_mmap_pgoff(struct file *file,  			    unsigned long addr,  			    unsigned long len,  			    unsigned long prot, @@ -1470,7 +1470,32 @@ error_getting_region:  	show_free_areas(0);  	return -ENOMEM;  } -EXPORT_SYMBOL(do_mmap_pgoff); + +unsigned long do_mmap(struct file *file, unsigned long addr, +	unsigned long len, unsigned long prot, +	unsigned long flag, unsigned long offset) +{ +	if (unlikely(offset + PAGE_ALIGN(len) < offset)) +		return -EINVAL; +	if (unlikely(offset & ~PAGE_MASK)) +		return -EINVAL; +	return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +} +EXPORT_SYMBOL(do_mmap); + +unsigned long vm_mmap(struct file *file, unsigned long addr, +	unsigned long len, unsigned long prot, +	unsigned long flag, unsigned long offset) +{ +	unsigned long ret; +	struct mm_struct *mm = current->mm; + +	down_write(&mm->mmap_sem); +	ret = do_mmap(file, addr, len, prot, flag, offset); +	up_write(&mm->mmap_sem); +	return ret; +} +EXPORT_SYMBOL(vm_mmap);  SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,  		unsigned long, prot, unsigned long, flags, @@ -1709,16 +1734,22 @@ erase_whole_vma:  }  EXPORT_SYMBOL(do_munmap); -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +int vm_munmap(unsigned long addr, size_t len)  { -	int ret;  	struct mm_struct *mm = current->mm; +	int ret;  	down_write(&mm->mmap_sem);  	ret = do_munmap(mm, addr, len);  	up_write(&mm->mmap_sem);  	return ret;  } +EXPORT_SYMBOL(vm_munmap); + +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +{ +	return vm_munmap(addr, len); +}  /*   * release all the mappings made in a process's VM space @@ -1744,7 +1775,7 @@ void exit_mmap(struct mm_struct *mm)  	kleave("");  } -unsigned long do_brk(unsigned long addr, unsigned long len) +unsigned long vm_brk(unsigned long addr, unsigned long len)  {  	return -ENOMEM;  } diff --git a/mm/swap_state.c b/mm/swap_state.c index 9d3dd3763cf..4c5ff7f284d 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -26,7 +26,7 @@   */  static const struct address_space_operations swap_aops = {  	.writepage	= swap_writepage, -	.set_page_dirty	= __set_page_dirty_nobuffers, +	.set_page_dirty	= __set_page_dirty_no_writeback,  	.migratepage	= migrate_page,  }; diff --git a/mm/vmscan.c b/mm/vmscan.c index 1a518684a32..33dc256033b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1568,9 +1568,14 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz,  	reclaim_stat->recent_scanned[0] += nr_anon;  	reclaim_stat->recent_scanned[1] += nr_file; -	if (current_is_kswapd()) -		__count_vm_events(KSWAPD_STEAL, nr_reclaimed); -	__count_zone_vm_events(PGSTEAL, zone, nr_reclaimed); +	if (global_reclaim(sc)) { +		if (current_is_kswapd()) +			__count_zone_vm_events(PGSTEAL_KSWAPD, zone, +					       nr_reclaimed); +		else +			__count_zone_vm_events(PGSTEAL_DIRECT, zone, +					       nr_reclaimed); +	}  	putback_inactive_pages(mz, &page_list); diff --git a/mm/vmstat.c b/mm/vmstat.c index f600557a765..7db1b9bab49 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -738,7 +738,8 @@ const char * const vmstat_text[] = {  	"pgmajfault",  	TEXTS_FOR_ZONES("pgrefill") -	TEXTS_FOR_ZONES("pgsteal") +	TEXTS_FOR_ZONES("pgsteal_kswapd") +	TEXTS_FOR_ZONES("pgsteal_direct")  	TEXTS_FOR_ZONES("pgscan_kswapd")  	TEXTS_FOR_ZONES("pgscan_direct") @@ -747,7 +748,6 @@ const char * const vmstat_text[] = {  #endif  	"pginodesteal",  	"slabs_scanned", -	"kswapd_steal",  	"kswapd_inodesteal",  	"kswapd_low_wmark_hit_quickly",  	"kswapd_high_wmark_hit_quickly", diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 0906c194a41..9d9a6a3edbd 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -2011,16 +2011,17 @@ static void __exit ax25_exit(void)  	proc_net_remove(&init_net, "ax25_route");  	proc_net_remove(&init_net, "ax25");  	proc_net_remove(&init_net, "ax25_calls"); -	ax25_rt_free(); -	ax25_uid_free(); -	ax25_dev_free(); -	ax25_unregister_sysctl();  	unregister_netdevice_notifier(&ax25_dev_notifier); +	ax25_unregister_sysctl();  	dev_remove_pack(&ax25_packet_type);  	sock_unregister(PF_AX25);  	proto_unregister(&ax25_proto); + +	ax25_rt_free(); +	ax25_uid_free(); +	ax25_dev_free();  }  module_exit(ax25_exit); diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 20618dd3088..d09340e1523 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c @@ -103,6 +103,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)  		skb->protocol = htons(ETH_P_IPV6);  		break;  	default: +		kfree_skb(skb);  		priv->netdev->stats.rx_errors++;  		return -EINVAL;  	} @@ -220,14 +221,16 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)  	if (skb->len > priv->netdev->mtu) {  		pr_warn("Size of skb exceeded MTU\n"); +		kfree_skb(skb);  		dev->stats.tx_errors++; -		return -ENOSPC; +		return NETDEV_TX_OK;  	}  	if (!priv->flowenabled) {  		pr_debug("dropping packets flow off\n"); +		kfree_skb(skb);  		dev->stats.tx_dropped++; -		return NETDEV_TX_BUSY; +		return NETDEV_TX_OK;  	}  	if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) @@ -242,7 +245,7 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)  	result = priv->chnl.dn->transmit(priv->chnl.dn, pkt);  	if (result) {  		dev->stats.tx_dropped++; -		return result; +		return NETDEV_TX_OK;  	}  	/* Update statistics. */ diff --git a/net/core/dev.c b/net/core/dev.c index c25d453b280..9bb8f87c4cd 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1409,14 +1409,34 @@ EXPORT_SYMBOL(register_netdevice_notifier);   *	register_netdevice_notifier(). The notifier is unlinked into the   *	kernel structures and may then be reused. A negative errno code   *	is returned on a failure. + * + * 	After unregistering unregister and down device events are synthesized + *	for all devices on the device list to the removed notifier to remove + *	the need for special case cleanup code.   */  int unregister_netdevice_notifier(struct notifier_block *nb)  { +	struct net_device *dev; +	struct net *net;  	int err;  	rtnl_lock();  	err = raw_notifier_chain_unregister(&netdev_chain, nb); +	if (err) +		goto unlock; + +	for_each_net(net) { +		for_each_netdev(net, dev) { +			if (dev->flags & IFF_UP) { +				nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); +				nb->notifier_call(nb, NETDEV_DOWN, dev); +			} +			nb->notifier_call(nb, NETDEV_UNREGISTER, dev); +			nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev); +		} +	} +unlock:  	rtnl_unlock();  	return err;  } diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 7f36b38e060..5c3c81a609e 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -150,6 +150,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)  	for (i = 0; i < msg->entries; i++) {  		if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {  			msg->points[i].count++; +			atomic_inc(&data->dm_hit_count);  			goto out;  		}  	} diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 0e950fda9a0..31a5ae51a45 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -83,21 +83,29 @@ assign:  static int ops_init(const struct pernet_operations *ops, struct net *net)  { -	int err; +	int err = -ENOMEM; +	void *data = NULL; +  	if (ops->id && ops->size) { -		void *data = kzalloc(ops->size, GFP_KERNEL); +		data = kzalloc(ops->size, GFP_KERNEL);  		if (!data) -			return -ENOMEM; +			goto out;  		err = net_assign_generic(net, *ops->id, data); -		if (err) { -			kfree(data); -			return err; -		} +		if (err) +			goto cleanup;  	} +	err = 0;  	if (ops->init) -		return ops->init(net); -	return 0; +		err = ops->init(net); +	if (!err) +		return 0; + +cleanup: +	kfree(data); + +out: +	return err;  }  static void ops_free(const struct pernet_operations *ops, struct net *net) @@ -448,12 +456,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops)  static int __register_pernet_operations(struct list_head *list,  					struct pernet_operations *ops)  { -	int err = 0; -	err = ops_init(ops, &init_net); -	if (err) -		ops_free(ops, &init_net); -	return err; -	 +	return ops_init(ops, &init_net);  }  static void __unregister_pernet_operations(struct pernet_operations *ops) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9944c1d9a21..3ff36406537 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -335,6 +335,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb)  			incr = __tcp_grow_window(sk, skb);  		if (incr) { +			incr = max_t(int, incr, 2 * skb->len);  			tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr,  					       tp->window_clamp);  			inet_csk(sk)->icsk_ack.quick |= 1; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 376b2cfbb68..7ac6423117a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1096,6 +1096,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)  	eat = min_t(int, len, skb_headlen(skb));  	if (eat) {  		__skb_pull(skb, eat); +		skb->avail_size -= eat;  		len -= eat;  		if (!len)  			return; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6a3bb6077e1..7d5cb975cc6 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -803,8 +803,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)  				ip6_del_rt(rt);  				rt = NULL;  			} else if (!(rt->rt6i_flags & RTF_EXPIRES)) { -				rt->dst.expires = expires; -				rt->rt6i_flags |= RTF_EXPIRES; +				rt6_set_expires(rt, expires);  			}  		}  		dst_release(&rt->dst); @@ -1887,11 +1886,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)  				rt = NULL;  			} else if (addrconf_finite_timeout(rt_expires)) {  				/* not infinity */ -				rt->dst.expires = jiffies + rt_expires; -				rt->rt6i_flags |= RTF_EXPIRES; +				rt6_set_expires(rt, jiffies + rt_expires);  			} else { -				rt->rt6i_flags &= ~RTF_EXPIRES; -				rt->dst.expires = 0; +				rt6_clean_expires(rt);  			}  		} else if (valid_lft) {  			clock_t expires = 0; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 5b27fbcae34..93717435013 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -673,11 +673,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,  					    &rt->rt6i_gateway)) {  				if (!(iter->rt6i_flags & RTF_EXPIRES))  					return -EEXIST; -				iter->dst.expires = rt->dst.expires; -				if (!(rt->rt6i_flags & RTF_EXPIRES)) { -					iter->rt6i_flags &= ~RTF_EXPIRES; -					iter->dst.expires = 0; -				} +				if (!(rt->rt6i_flags & RTF_EXPIRES)) +					rt6_clean_expires(iter); +				else +					rt6_set_expires(iter, rt->dst.expires);  				return -EEXIST;  			}  		} diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 3dcdb81ec3e..176b469322a 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1264,8 +1264,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)  	}  	if (rt) -		rt->dst.expires = jiffies + (HZ * lifetime); - +		rt6_set_expires(rt, jiffies + (HZ * lifetime));  	if (ra_msg->icmph.icmp6_hop_limit) {  		in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;  		if (rt) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3992e26a603..bc4888d902b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -62,7 +62,7 @@  #include <linux/sysctl.h>  #endif -static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, +static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,  				    const struct in6_addr *dest);  static struct dst_entry	*ip6_dst_check(struct dst_entry *dst, u32 cookie);  static unsigned int	 ip6_default_advmss(const struct dst_entry *dst); @@ -285,6 +285,10 @@ static void ip6_dst_destroy(struct dst_entry *dst)  		rt->rt6i_idev = NULL;  		in6_dev_put(idev);  	} + +	if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) +		dst_release(dst->from); +  	if (peer) {  		rt->rt6i_peer = NULL;  		inet_putpeer(peer); @@ -329,8 +333,17 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,  static __inline__ int rt6_check_expired(const struct rt6_info *rt)  { -	return (rt->rt6i_flags & RTF_EXPIRES) && -		time_after(jiffies, rt->dst.expires); +	struct rt6_info *ort = NULL; + +	if (rt->rt6i_flags & RTF_EXPIRES) { +		if (time_after(jiffies, rt->dst.expires)) +			return 1; +	} else if (rt->dst.from) { +		ort = (struct rt6_info *) rt->dst.from; +		return (ort->rt6i_flags & RTF_EXPIRES) && +			time_after(jiffies, ort->dst.expires); +	} +	return 0;  }  static inline int rt6_need_strict(const struct in6_addr *daddr) @@ -620,12 +633,11 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,  				 (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);  	if (rt) { -		if (!addrconf_finite_timeout(lifetime)) { -			rt->rt6i_flags &= ~RTF_EXPIRES; -		} else { -			rt->dst.expires = jiffies + HZ * lifetime; -			rt->rt6i_flags |= RTF_EXPIRES; -		} +		if (!addrconf_finite_timeout(lifetime)) +			rt6_clean_expires(rt); +		else +			rt6_set_expires(rt, jiffies + HZ * lifetime); +  		dst_release(&rt->dst);  	}  	return 0; @@ -730,7 +742,7 @@ int ip6_ins_rt(struct rt6_info *rt)  	return __ip6_ins_rt(rt, &info);  } -static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, +static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort,  				      const struct in6_addr *daddr,  				      const struct in6_addr *saddr)  { @@ -954,10 +966,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori  		rt->rt6i_idev = ort->rt6i_idev;  		if (rt->rt6i_idev)  			in6_dev_hold(rt->rt6i_idev); -		rt->dst.expires = 0;  		rt->rt6i_gateway = ort->rt6i_gateway; -		rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; +		rt->rt6i_flags = ort->rt6i_flags; +		rt6_clean_expires(rt);  		rt->rt6i_metric = 0;  		memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); @@ -1019,10 +1031,9 @@ static void ip6_link_failure(struct sk_buff *skb)  	rt = (struct rt6_info *) skb_dst(skb);  	if (rt) { -		if (rt->rt6i_flags & RTF_CACHE) { -			dst_set_expires(&rt->dst, 0); -			rt->rt6i_flags |= RTF_EXPIRES; -		} else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) +		if (rt->rt6i_flags & RTF_CACHE) +			rt6_update_expires(rt, 0); +		else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))  			rt->rt6i_node->fn_sernum = -1;  	}  } @@ -1289,9 +1300,12 @@ int ip6_route_add(struct fib6_config *cfg)  	}  	rt->dst.obsolete = -1; -	rt->dst.expires = (cfg->fc_flags & RTF_EXPIRES) ? -				jiffies + clock_t_to_jiffies(cfg->fc_expires) : -				0; + +	if (cfg->fc_flags & RTF_EXPIRES) +		rt6_set_expires(rt, jiffies + +				clock_t_to_jiffies(cfg->fc_expires)); +	else +		rt6_clean_expires(rt);  	if (cfg->fc_protocol == RTPROT_UNSPEC)  		cfg->fc_protocol = RTPROT_BOOT; @@ -1736,8 +1750,8 @@ again:  			features |= RTAX_FEATURE_ALLFRAG;  			dst_metric_set(&rt->dst, RTAX_FEATURES, features);  		} -		dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); -		rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; +		rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); +		rt->rt6i_flags |= RTF_MODIFIED;  		goto out;  	} @@ -1765,9 +1779,8 @@ again:  		 * which is 10 mins. After 10 mins the decreased pmtu is expired  		 * and detecting PMTU increase will be automatically happened.  		 */ -		dst_set_expires(&nrt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); -		nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; - +		rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires); +		nrt->rt6i_flags |= RTF_DYNAMIC;  		ip6_ins_rt(nrt);  	}  out: @@ -1799,7 +1812,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad   *	Misc support functions   */ -static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, +static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,  				    const struct in6_addr *dest)  {  	struct net *net = dev_net(ort->dst.dev); @@ -1819,10 +1832,14 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,  		if (rt->rt6i_idev)  			in6_dev_hold(rt->rt6i_idev);  		rt->dst.lastuse = jiffies; -		rt->dst.expires = 0;  		rt->rt6i_gateway = ort->rt6i_gateway; -		rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; +		rt->rt6i_flags = ort->rt6i_flags; +		if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == +		    (RTF_DEFAULT | RTF_ADDRCONF)) +			rt6_set_from(rt, ort); +		else +			rt6_clean_expires(rt);  		rt->rt6i_metric = 0;  #ifdef CONFIG_IPV6_SUBTREES diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 86cfe6005f4..98256cf72f9 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1383,6 +1383,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,  	tcp_mtup_init(newsk);  	tcp_sync_mss(newsk, dst_mtu(dst));  	newtp->advmss = dst_metric_advmss(dst); +	if (tcp_sk(sk)->rx_opt.user_mss && +	    tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) +		newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; +  	tcp_initialize_rcv_mss(newsk);  	if (tcp_rsk(req)->snt_synack)  		tcp_valid_rtt_meas(newsk, diff --git a/net/key/af_key.c b/net/key/af_key.c index 11dbb2255cc..7e5d927b576 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -3480,7 +3480,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,  	/* Addresses to be used by KM for negotiation, if ext is available */  	if (k != NULL && (set_sadb_kmaddress(skb, k) < 0)) -		return -EINVAL; +		goto err;  	/* selector src */  	set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel); diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 55670ec3cd0..585d93ecee2 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -232,7 +232,7 @@ static void l2tp_ip_close(struct sock *sk, long timeout)  {  	write_lock_bh(&l2tp_ip_lock);  	hlist_del_init(&sk->sk_bind_node); -	hlist_del_init(&sk->sk_node); +	sk_del_node_init(sk);  	write_unlock_bh(&l2tp_ip_lock);  	sk_common_release(sk);  } @@ -271,7 +271,8 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)  	    chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)  		goto out; -	inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; +	if (addr->l2tp_addr.s_addr) +		inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr;  	if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)  		inet->inet_saddr = 0;  /* Use device */  	sk_dst_reset(sk); diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 33fd8d9f714..cef7c29214a 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -457,8 +457,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  			 * fall back to HT20 if we don't use or use  			 * the other extension channel  			 */ -			if ((channel_type == NL80211_CHAN_HT40MINUS || -			     channel_type == NL80211_CHAN_HT40PLUS) && +			if (!(channel_type == NL80211_CHAN_HT40MINUS || +			      channel_type == NL80211_CHAN_HT40PLUS) ||  			    channel_type != sdata->u.ibss.channel_type)  				sta_ht_cap_new.cap &=  					~IEEE80211_HT_CAP_SUP_WIDTH_20_40; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bcfe8c77c83..d64e285400a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -103,7 +103,7 @@ static void  ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,  				 struct sk_buff *skb,  				 struct ieee80211_rate *rate, -				 int rtap_len) +				 int rtap_len, bool has_fcs)  {  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);  	struct ieee80211_radiotap_header *rthdr; @@ -134,7 +134,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,  	}  	/* IEEE80211_RADIOTAP_FLAGS */ -	if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) +	if (has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS))  		*pos |= IEEE80211_RADIOTAP_F_FCS;  	if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))  		*pos |= IEEE80211_RADIOTAP_F_BADFCS; @@ -294,7 +294,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,  	}  	/* prepend radiotap information */ -	ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); +	ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, +					 true);  	skb_reset_mac_header(skb);  	skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2571,7 +2572,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,  		goto out_free_skb;  	/* prepend radiotap information */ -	ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); +	ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, +					 false);  	skb_set_mac_header(skb, 0);  	skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 9b9a85ecc4c..bf5cf69c820 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -331,23 +331,6 @@ static int __net_init phonet_init_net(struct net *net)  static void __net_exit phonet_exit_net(struct net *net)  { -	struct phonet_net *pnn = phonet_pernet(net); -	struct net_device *dev; -	unsigned i; - -	rtnl_lock(); -	for_each_netdev(net, dev) -		phonet_device_destroy(dev); - -	for (i = 0; i < 64; i++) { -		dev = pnn->routes.table[i]; -		if (dev) { -			rtm_phonet_notify(RTM_DELROUTE, dev, i); -			dev_put(dev); -		} -	} -	rtnl_unlock(); -  	proc_net_remove(net, "phonet");  } @@ -361,7 +344,7 @@ static struct pernet_operations phonet_net_ops = {  /* Initialize Phonet devices list */  int __init phonet_device_init(void)  { -	int err = register_pernet_device(&phonet_net_ops); +	int err = register_pernet_subsys(&phonet_net_ops);  	if (err)  		return err; @@ -377,7 +360,7 @@ void phonet_device_exit(void)  {  	rtnl_unregister_all(PF_PHONET);  	unregister_netdevice_notifier(&phonet_device_notifier); -	unregister_pernet_device(&phonet_net_ops); +	unregister_pernet_subsys(&phonet_net_ops);  	proc_net_remove(&init_net, "pnresource");  } diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 0b15236be7b..8179494c269 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -565,11 +565,8 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)  		opt.packets	= q->packetsin;  		opt.bytesin	= q->bytesin; -		if (gred_wred_mode(table)) { -			q->vars.qidlestart = -				table->tab[table->def]->vars.qidlestart; -			q->vars.qavg = table->tab[table->def]->vars.qavg; -		} +		if (gred_wred_mode(table)) +			gred_load_wred_set(table, q);  		opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 8adfc88e793..3d6498af9ad 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -75,20 +75,21 @@ static struct pernet_operations sunrpc_net_ops = {  static int __init  init_sunrpc(void)  { -	int err = register_rpc_pipefs(); +	int err = rpc_init_mempool();  	if (err)  		goto out; -	err = rpc_init_mempool(); -	if (err) -		goto out2;  	err = rpcauth_init_module();  	if (err) -		goto out3; +		goto out2;  	cache_initialize();  	err = register_pernet_subsys(&sunrpc_net_ops);  	if (err) +		goto out3; + +	err = register_rpc_pipefs(); +	if (err)  		goto out4;  #ifdef RPC_DEBUG  	rpc_register_sysctl(); @@ -98,11 +99,11 @@ init_sunrpc(void)  	return 0;  out4: -	rpcauth_remove_module(); +	unregister_pernet_subsys(&sunrpc_net_ops);  out3: -	rpc_destroy_mempool(); +	rpcauth_remove_module();  out2: -	unregister_rpc_pipefs(); +	rpc_destroy_mempool();  out:  	return err;  } diff --git a/net/wireless/util.c b/net/wireless/util.c index 1b7a08df933..957f2562161 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -989,7 +989,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,  			if (rdev->wiphy.software_iftypes & BIT(iftype))  				continue;  			for (j = 0; j < c->n_limits; j++) { -				if (!(limits[j].types & iftype)) +				if (!(limits[j].types & BIT(iftype)))  					continue;  				if (limits[j].max < num[iftype])  					goto cont; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8e730ccc3f2..44ddaa542db 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1100,6 +1100,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,  	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)  		return; +	/* We're looking for an object */ +	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) +		return; +  	/* All our symbols are of form <prefix>__mod_XXX_device_table. */  	name = strstr(symname, "__mod_");  	if (!name) diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 14a286a7bf2..857586135d1 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -419,6 +419,7 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master);   * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control   * @kcontrol: vmaster kctl element   * @hook: the hook function + * @private_data: the private_data pointer to be saved   *   * Adds the given hook to the vmaster control element so that it's called   * at each time when the value is changed. diff --git a/sound/last.c b/sound/last.c index bdd0857b887..7ffc182e084 100644 --- a/sound/last.c +++ b/sound/last.c @@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void)  	return 0;  } -__initcall(alsa_sound_last_init); +late_initcall_sync(alsa_sound_last_init); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a36488d94aa..d906c5b74cf 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3971,9 +3971,14 @@ static void cx_auto_init_output(struct hda_codec *codec)  	int i;  	mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); -	for (i = 0; i < cfg->hp_outs; i++) +	for (i = 0; i < cfg->hp_outs; i++) { +		unsigned int val = PIN_OUT; +		if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & +		    AC_PINCAP_HP_DRV) +			val |= AC_PINCTL_HP_EN;  		snd_hda_codec_write(codec, cfg->hp_pins[i], 0, -				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); +				    AC_VERB_SET_PIN_WIDGET_CONTROL, val); +	}  	mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);  	mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);  	mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); @@ -4391,8 +4396,10 @@ static void apply_pin_fixup(struct hda_codec *codec,  enum {  	CXT_PINCFG_LENOVO_X200, +	CXT_PINCFG_LENOVO_TP410,  }; +/* ThinkPad X200 & co with cxt5051 */  static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {  	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */  	{ 0x17, 0x21a11000 }, /* dock-mic */ @@ -4401,15 +4408,33 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {  	{}  }; +/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */ +static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = { +	{ 0x19, 0x042110ff }, /* HP (seq# overridden) */ +	{ 0x1a, 0x21a190f0 }, /* dock-mic */ +	{ 0x1c, 0x212140ff }, /* dock-HP */ +	{} +}; +  static const struct cxt_pincfg *cxt_pincfg_tbl[] = {  	[CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, +	[CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,  }; -static const struct snd_pci_quirk cxt_fixups[] = { +static const struct snd_pci_quirk cxt5051_fixups[] = {  	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),  	{}  }; +static const struct snd_pci_quirk cxt5066_fixups[] = { +	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), +	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), +	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), +	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), +	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), +	{} +}; +  /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches   * can be created (bko#42825)   */ @@ -4446,13 +4471,13 @@ static int patch_conexant_auto(struct hda_codec *codec)  	case 0x14f15051:  		add_cx5051_fake_mutes(codec);  		codec->pin_amp_workaround = 1; +		apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);  		break;  	default:  		codec->pin_amp_workaround = 1; +		apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);  	} -	apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); -  	/* Show mute-led control only on HP laptops  	 * This is a sort of white-list: on HP laptops, EAPD corresponds  	 * only to the mute-LED without actualy amp function.  Meanwhile, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2508f8109f1..818f90bc7d5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1445,6 +1445,13 @@ enum {  	ALC_FIXUP_ACT_BUILD,  }; +static void alc_apply_pincfgs(struct hda_codec *codec, +			      const struct alc_pincfg *cfg) +{ +	for (; cfg->nid; cfg++) +		snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); +} +  static void alc_apply_fixup(struct hda_codec *codec, int action)  {  	struct alc_spec *spec = codec->spec; @@ -1478,9 +1485,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)  			snd_printdd(KERN_INFO "hda_codec: %s: "  				    "Apply pincfg for %s\n",  				    codec->chip_name, modelname); -			for (; cfg->nid; cfg++) -				snd_hda_codec_set_pincfg(codec, cfg->nid, -							 cfg->val); +			alc_apply_pincfgs(codec, cfg);  			break;  		case ALC_FIXUP_VERBS:  			if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) @@ -4861,6 +4866,7 @@ enum {  	ALC260_FIXUP_GPIO1_TOGGLE,  	ALC260_FIXUP_REPLACER,  	ALC260_FIXUP_HP_B1900, +	ALC260_FIXUP_KN1,  };  static void alc260_gpio1_automute(struct hda_codec *codec) @@ -4888,6 +4894,36 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,  	}  } +static void alc260_fixup_kn1(struct hda_codec *codec, +			     const struct alc_fixup *fix, int action) +{ +	struct alc_spec *spec = codec->spec; +	static const struct alc_pincfg pincfgs[] = { +		{ 0x0f, 0x02214000 }, /* HP/speaker */ +		{ 0x12, 0x90a60160 }, /* int mic */ +		{ 0x13, 0x02a19000 }, /* ext mic */ +		{ 0x18, 0x01446000 }, /* SPDIF out */ +		/* disable bogus I/O pins */ +		{ 0x10, 0x411111f0 }, +		{ 0x11, 0x411111f0 }, +		{ 0x14, 0x411111f0 }, +		{ 0x15, 0x411111f0 }, +		{ 0x16, 0x411111f0 }, +		{ 0x17, 0x411111f0 }, +		{ 0x19, 0x411111f0 }, +		{ } +	}; + +	switch (action) { +	case ALC_FIXUP_ACT_PRE_PROBE: +		alc_apply_pincfgs(codec, pincfgs); +		break; +	case ALC_FIXUP_ACT_PROBE: +		spec->init_amp = ALC_INIT_NONE; +		break; +	} +} +  static const struct alc_fixup alc260_fixups[] = {  	[ALC260_FIXUP_HP_DC5750] = {  		.type = ALC_FIXUP_PINS, @@ -4938,7 +4974,11 @@ static const struct alc_fixup alc260_fixups[] = {  		.v.func = alc260_fixup_gpio1_toggle,  		.chained = true,  		.chain_id = ALC260_FIXUP_COEF, -	} +	}, +	[ALC260_FIXUP_KN1] = { +		.type = ALC_FIXUP_FUNC, +		.v.func = alc260_fixup_kn1, +	},  };  static const struct snd_pci_quirk alc260_fixup_tbl[] = { @@ -4948,6 +4988,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {  	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),  	SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),  	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), +	SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),  	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),  	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),  	{} @@ -6068,6 +6109,7 @@ static const struct alc_fixup alc269_fixups[] = {  static const struct snd_pci_quirk alc269_fixup_tbl[] = {  	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), +	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),  	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),  	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),  	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 33a9946b492..4742cac26aa 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5063,12 +5063,11 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)  	if (spec->gpio_led_polarity)  		muted = !muted; -	/*polarity defines *not* muted state level*/  	if (!spec->vref_mute_led_nid) {  		if (muted) -			spec->gpio_data &= ~spec->gpio_led; /* orange */ +			spec->gpio_data |= spec->gpio_led;  		else -			spec->gpio_data |= spec->gpio_led; /* white */ +			spec->gpio_data &= ~spec->gpio_led;  		stac_gpio_set(codec, spec->gpio_mask,  				spec->gpio_dir, spec->gpio_data);  	} else { diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6508e8b790b..59d8efaa17e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS  	select SND_SOC_TPA6130A2 if I2C  	select SND_SOC_TLV320DAC33 if I2C  	select SND_SOC_TWL4030 if TWL4030_CORE -	select SND_SOC_TWL6040 if TWL4030_CORE +	select SND_SOC_TWL6040 if TWL6040_CORE  	select SND_SOC_UDA134X  	select SND_SOC_UDA1380 if I2C  	select SND_SOC_WL1273 if MFD_WL1273_CORE @@ -276,7 +276,6 @@ config SND_SOC_TWL4030  	tristate  config SND_SOC_TWL6040 -	select TWL6040_CORE  	tristate  config SND_SOC_UDA134X diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 78979b3e0e9..07c44b71f09 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -929,6 +929,8 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)  	/* MCLKX -> MCLK */  	mclkx_coeff = cs42l73_get_mclkx_coeff(freq); +	if (mclkx_coeff < 0) +		return mclkx_coeff;  	mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx /  		cs42l73_mclkx_coeffs[mclkx_coeff].ratio; diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 2d8c6b825e5..dc7509b9d53 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -26,7 +26,6 @@  #include <linux/pm.h>  #include <linux/platform_device.h>  #include <linux/slab.h> -#include <linux/i2c/twl.h>  #include <linux/mfd/twl6040.h>  #include <sound/core.h> @@ -1528,7 +1527,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)  static int twl6040_probe(struct snd_soc_codec *codec)  {  	struct twl6040_data *priv; -	struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); +	struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);  	struct platform_device *pdev = container_of(codec->dev,  						   struct platform_device, dev);  	int ret = 0; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 7c49642af05..6c1fe3afd4b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1000,61 +1000,170 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)  	}  } -static int late_enable_ev(struct snd_soc_dapm_widget *w, -			  struct snd_kcontrol *kcontrol, int event) +static int aif1clk_ev(struct snd_soc_dapm_widget *w, +		      struct snd_kcontrol *kcontrol, int event)  {  	struct snd_soc_codec *codec = w->codec; -	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); +	struct wm8994 *control = codec->control_data; +	int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; +	int dac; +	int adc; +	int val; + +	switch (control->type) { +	case WM8994: +	case WM8958: +		mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA; +		break; +	default: +		break; +	}  	switch (event) {  	case SND_SOC_DAPM_PRE_PMU: -		if (wm8994->aif1clk_enable) { -			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, -					    WM8994_AIF1CLK_ENA_MASK, -					    WM8994_AIF1CLK_ENA); -			wm8994->aif1clk_enable = 0; -		} -		if (wm8994->aif2clk_enable) { -			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, -					    WM8994_AIF2CLK_ENA_MASK, -					    WM8994_AIF2CLK_ENA); -			wm8994->aif2clk_enable = 0; -		} +		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1); +		if ((val & WM8994_AIF1ADCL_SRC) && +		    (val & WM8994_AIF1ADCR_SRC)) +			adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA; +		else if (!(val & WM8994_AIF1ADCL_SRC) && +			 !(val & WM8994_AIF1ADCR_SRC)) +			adc = WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; +		else +			adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA | +				WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; + +		val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2); +		if ((val & WM8994_AIF1DACL_SRC) && +		    (val & WM8994_AIF1DACR_SRC)) +			dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA; +		else if (!(val & WM8994_AIF1DACL_SRC) && +			 !(val & WM8994_AIF1DACR_SRC)) +			dac = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA; +		else +			dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA | +				WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA; + +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, +				    mask, adc); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, +				    mask, dac); +		snd_soc_update_bits(codec, WM8994_CLOCKING_1, +				    WM8994_AIF1DSPCLK_ENA | +				    WM8994_SYSDSPCLK_ENA, +				    WM8994_AIF1DSPCLK_ENA | +				    WM8994_SYSDSPCLK_ENA); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask, +				    WM8994_AIF1ADC1R_ENA | +				    WM8994_AIF1ADC1L_ENA | +				    WM8994_AIF1ADC2R_ENA | +				    WM8994_AIF1ADC2L_ENA); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask, +				    WM8994_AIF1DAC1R_ENA | +				    WM8994_AIF1DAC1L_ENA | +				    WM8994_AIF1DAC2R_ENA | +				    WM8994_AIF1DAC2L_ENA);  		break; -	} -	/* We may also have postponed startup of DSP, handle that. */ -	wm8958_aif_ev(w, kcontrol, event); +	case SND_SOC_DAPM_PRE_PMD: +	case SND_SOC_DAPM_POST_PMD: +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, +				    mask, 0); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, +				    mask, 0); + +		val = snd_soc_read(codec, WM8994_CLOCKING_1); +		if (val & WM8994_AIF2DSPCLK_ENA) +			val = WM8994_SYSDSPCLK_ENA; +		else +			val = 0; +		snd_soc_update_bits(codec, WM8994_CLOCKING_1, +				    WM8994_SYSDSPCLK_ENA | +				    WM8994_AIF1DSPCLK_ENA, val); +		break; +	}  	return 0;  } -static int late_disable_ev(struct snd_soc_dapm_widget *w, -			   struct snd_kcontrol *kcontrol, int event) +static int aif2clk_ev(struct snd_soc_dapm_widget *w, +		      struct snd_kcontrol *kcontrol, int event)  {  	struct snd_soc_codec *codec = w->codec; -	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); +	int dac; +	int adc; +	int val;  	switch (event) { +	case SND_SOC_DAPM_PRE_PMU: +		val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1); +		if ((val & WM8994_AIF2ADCL_SRC) && +		    (val & WM8994_AIF2ADCR_SRC)) +			adc = WM8994_AIF2ADCR_ENA; +		else if (!(val & WM8994_AIF2ADCL_SRC) && +			 !(val & WM8994_AIF2ADCR_SRC)) +			adc = WM8994_AIF2ADCL_ENA; +		else +			adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA; + + +		val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2); +		if ((val & WM8994_AIF2DACL_SRC) && +		    (val & WM8994_AIF2DACR_SRC)) +			dac = WM8994_AIF2DACR_ENA; +		else if (!(val & WM8994_AIF2DACL_SRC) && +			 !(val & WM8994_AIF2DACR_SRC)) +			dac = WM8994_AIF2DACL_ENA; +		else +			dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA; + +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, +				    WM8994_AIF2ADCL_ENA | +				    WM8994_AIF2ADCR_ENA, adc); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, +				    WM8994_AIF2DACL_ENA | +				    WM8994_AIF2DACR_ENA, dac); +		snd_soc_update_bits(codec, WM8994_CLOCKING_1, +				    WM8994_AIF2DSPCLK_ENA | +				    WM8994_SYSDSPCLK_ENA, +				    WM8994_AIF2DSPCLK_ENA | +				    WM8994_SYSDSPCLK_ENA); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, +				    WM8994_AIF2ADCL_ENA | +				    WM8994_AIF2ADCR_ENA, +				    WM8994_AIF2ADCL_ENA | +				    WM8994_AIF2ADCR_ENA); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, +				    WM8994_AIF2DACL_ENA | +				    WM8994_AIF2DACR_ENA, +				    WM8994_AIF2DACL_ENA | +				    WM8994_AIF2DACR_ENA); +		break; + +	case SND_SOC_DAPM_PRE_PMD:  	case SND_SOC_DAPM_POST_PMD: -		if (wm8994->aif1clk_disable) { -			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, -					    WM8994_AIF1CLK_ENA_MASK, 0); -			wm8994->aif1clk_disable = 0; -		} -		if (wm8994->aif2clk_disable) { -			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, -					    WM8994_AIF2CLK_ENA_MASK, 0); -			wm8994->aif2clk_disable = 0; -		} +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, +				    WM8994_AIF2DACL_ENA | +				    WM8994_AIF2DACR_ENA, 0); +		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, +				    WM8994_AIF2ADCL_ENA | +				    WM8994_AIF2ADCR_ENA, 0); + +		val = snd_soc_read(codec, WM8994_CLOCKING_1); +		if (val & WM8994_AIF1DSPCLK_ENA) +			val = WM8994_SYSDSPCLK_ENA; +		else +			val = 0; +		snd_soc_update_bits(codec, WM8994_CLOCKING_1, +				    WM8994_SYSDSPCLK_ENA | +				    WM8994_AIF2DSPCLK_ENA, val);  		break;  	}  	return 0;  } -static int aif1clk_ev(struct snd_soc_dapm_widget *w, -		      struct snd_kcontrol *kcontrol, int event) +static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, +			   struct snd_kcontrol *kcontrol, int event)  {  	struct snd_soc_codec *codec = w->codec;  	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -1071,8 +1180,8 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,  	return 0;  } -static int aif2clk_ev(struct snd_soc_dapm_widget *w, -		      struct snd_kcontrol *kcontrol, int event) +static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, +			   struct snd_kcontrol *kcontrol, int event)  {  	struct snd_soc_codec *codec = w->codec;  	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -1089,6 +1198,63 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,  	return 0;  } +static int late_enable_ev(struct snd_soc_dapm_widget *w, +			  struct snd_kcontrol *kcontrol, int event) +{ +	struct snd_soc_codec *codec = w->codec; +	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + +	switch (event) { +	case SND_SOC_DAPM_PRE_PMU: +		if (wm8994->aif1clk_enable) { +			aif1clk_ev(w, kcontrol, event); +			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, +					    WM8994_AIF1CLK_ENA_MASK, +					    WM8994_AIF1CLK_ENA); +			wm8994->aif1clk_enable = 0; +		} +		if (wm8994->aif2clk_enable) { +			aif2clk_ev(w, kcontrol, event); +			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, +					    WM8994_AIF2CLK_ENA_MASK, +					    WM8994_AIF2CLK_ENA); +			wm8994->aif2clk_enable = 0; +		} +		break; +	} + +	/* We may also have postponed startup of DSP, handle that. */ +	wm8958_aif_ev(w, kcontrol, event); + +	return 0; +} + +static int late_disable_ev(struct snd_soc_dapm_widget *w, +			   struct snd_kcontrol *kcontrol, int event) +{ +	struct snd_soc_codec *codec = w->codec; +	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + +	switch (event) { +	case SND_SOC_DAPM_POST_PMD: +		if (wm8994->aif1clk_disable) { +			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, +					    WM8994_AIF1CLK_ENA_MASK, 0); +			aif1clk_ev(w, kcontrol, event); +			wm8994->aif1clk_disable = 0; +		} +		if (wm8994->aif2clk_disable) { +			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, +					    WM8994_AIF2CLK_ENA_MASK, 0); +			aif2clk_ev(w, kcontrol, event); +			wm8994->aif2clk_disable = 0; +		} +		break; +	} + +	return 0; +} +  static int adc_mux_ev(struct snd_soc_dapm_widget *w,  		      struct snd_kcontrol *kcontrol, int event)  { @@ -1385,9 +1551,9 @@ static const struct snd_kcontrol_new aif2dacr_src_mux =  	SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);  static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = { -SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev, +SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_late_ev,  	SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev, +SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_late_ev,  	SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),  SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, @@ -1416,8 +1582,10 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)  };  static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { -SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, +		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, +		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),  SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),  SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,  		   left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), @@ -1470,30 +1638,30 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,  SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,  		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSPINTCLK", SND_SOC_NOPM, 1, 0, NULL, 0),  SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, -		     0, WM8994_POWER_MANAGEMENT_4, 9, 0), +		     0, SND_SOC_NOPM, 9, 0),  SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, -		     0, WM8994_POWER_MANAGEMENT_4, 8, 0), +		     0, SND_SOC_NOPM, 8, 0),  SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, -		      WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, +		      SND_SOC_NOPM, 9, 0, wm8958_aif_ev,  		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),  SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, -		      WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, +		      SND_SOC_NOPM, 8, 0, wm8958_aif_ev,  		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),  SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL, -		     0, WM8994_POWER_MANAGEMENT_4, 11, 0), +		     0, SND_SOC_NOPM, 11, 0),  SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL, -		     0, WM8994_POWER_MANAGEMENT_4, 10, 0), +		     0, SND_SOC_NOPM, 10, 0),  SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, -		      WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, +		      SND_SOC_NOPM, 11, 0, wm8958_aif_ev,  		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),  SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0, -		      WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev, +		      SND_SOC_NOPM, 10, 0, wm8958_aif_ev,  		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),  SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, @@ -1520,14 +1688,14 @@ SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,  		   dac1r_mix, ARRAY_SIZE(dac1r_mix)),  SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0, -		     WM8994_POWER_MANAGEMENT_4, 13, 0), +		     SND_SOC_NOPM, 13, 0),  SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, -		     WM8994_POWER_MANAGEMENT_4, 12, 0), +		     SND_SOC_NOPM, 12, 0),  SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0, -		      WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev, +		      SND_SOC_NOPM, 13, 0, wm8958_aif_ev,  		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),  SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, -		      WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, +		      SND_SOC_NOPM, 12, 0, wm8958_aif_ev,  		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),  SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index e00dd0b1139..deafbfaacdb 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430  config SND_OMAP_SOC_OMAP_ABE_TWL6040  	tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" -	depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4 +	depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4  	select SND_OMAP_SOC_DMIC  	select SND_OMAP_SOC_MCPDM  	select SND_SOC_TWL6040 diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 378cc5b056d..74ed2dffbff 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1001,11 +1001,10 @@ static void fsi_dma_do_tasklet(unsigned long data)  	sg_dma_address(&sg) = buf;  	sg_dma_len(&sg) = len; -	desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir, -						  DMA_PREP_INTERRUPT | -						  DMA_CTRL_ACK); +	desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, +				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);  	if (!desc) { -		dev_err(dai->dev, "device_prep_slave_sg() fail\n"); +		dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");  		return;  	} diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index accdcb7d4d9..1d6a80c9f4c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3113,6 +3113,7 @@ int snd_soc_register_card(struct snd_soc_card *card)  				 GFP_KERNEL);  	if (card->rtd == NULL)  		return -ENOMEM; +	card->num_rtd = 0;  	card->rtd_aux = &card->rtd[card->num_links];  	for (i = 0; i < card->num_links; i++) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 5cbd2d7623b..1bb6d4a63cd 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -67,6 +67,7 @@ static int dapm_up_seq[] = {  	[snd_soc_dapm_out_drv] = 10,  	[snd_soc_dapm_hp] = 10,  	[snd_soc_dapm_spk] = 10, +	[snd_soc_dapm_line] = 10,  	[snd_soc_dapm_post] = 11,  }; @@ -75,6 +76,7 @@ static int dapm_down_seq[] = {  	[snd_soc_dapm_adc] = 1,  	[snd_soc_dapm_hp] = 2,  	[snd_soc_dapm_spk] = 2, +	[snd_soc_dapm_line] = 2,  	[snd_soc_dapm_out_drv] = 2,  	[snd_soc_dapm_pga] = 4,  	[snd_soc_dapm_mixer_named_ctl] = 5, diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 03059e75665..9bf3fc75934 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -234,8 +234,8 @@ endif  export PERL_PATH -FLEX = $(CROSS_COMPILE)flex -BISON= $(CROSS_COMPILE)bison +FLEX = flex +BISON= bison  $(OUTPUT)util/parse-events-flex.c: util/parse-events.l  	$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2e317438980..cdae9b2db1c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -374,16 +374,23 @@ static int __cmd_report(struct perf_report *rep)  	    (kernel_map->dso->hit &&  	     (kernel_kmap->ref_reloc_sym == NULL ||  	      kernel_kmap->ref_reloc_sym->addr == 0))) { -		const struct dso *kdso = kernel_map->dso; +		const char *desc = +		    "As no suitable kallsyms nor vmlinux was found, kernel samples\n" +		    "can't be resolved."; + +		if (kernel_map) { +			const struct dso *kdso = kernel_map->dso; +			if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) { +				desc = "If some relocation was applied (e.g. " +				       "kexec) symbols may be misresolved."; +			} +		}  		ui__warning(  "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"  "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"  "Samples in kernel modules can't be resolved as well.\n\n", -			    RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? -"As no suitable kallsyms nor vmlinux was found, kernel samples\n" -"can't be resolved." : -"If some relocation was applied (e.g. kexec) symbols may be misresolved."); +		desc);  	}  	if (dump_trace) { diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 1c5b9801ac6..223ffdcc0fd 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -851,6 +851,28 @@ static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist)  	return test__checkevent_symbolic_name(evlist);  } +static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) +{ +	struct perf_evsel *evsel = list_entry(evlist->entries.next, +					      struct perf_evsel, node); + +	TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); +	TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + +	return test__checkevent_symbolic_name(evlist); +} + +static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) +{ +	struct perf_evsel *evsel = list_entry(evlist->entries.next, +					      struct perf_evsel, node); + +	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); +	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + +	return test__checkevent_symbolic_name(evlist); +} +  static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist)  {  	struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -1091,6 +1113,14 @@ static struct test__event_st {  		.name  = "r1,syscalls:sys_enter_open:k,1:1:hp",  		.check = test__checkevent_list,  	}, +	{ +		.name  = "instructions:G", +		.check = test__checkevent_exclude_host_modifier, +	}, +	{ +		.name  = "instructions:H", +		.check = test__checkevent_exclude_guest_modifier, +	},  };  #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 05d766e3ecb..1fcf1bbc545 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -54,7 +54,7 @@ num_dec		[0-9]+  num_hex		0x[a-fA-F0-9]+  num_raw_hex	[a-fA-F0-9]+  name		[a-zA-Z_*?][a-zA-Z0-9_*?]* -modifier_event	[ukhp]{1,5} +modifier_event	[ukhpGH]{1,8}  modifier_bp	[rwx]  %% diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c0a028c3eba..ab9867b2b43 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -977,8 +977,9 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,   * And always look at the original dso, not at debuginfo packages, that   * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).   */ -static int dso__synthesize_plt_symbols(struct  dso *dso, struct map *map, -				       symbol_filter_t filter) +static int +dso__synthesize_plt_symbols(struct dso *dso, char *name, struct map *map, +			    symbol_filter_t filter)  {  	uint32_t nr_rel_entries, idx;  	GElf_Sym sym; @@ -993,10 +994,7 @@ static int dso__synthesize_plt_symbols(struct  dso *dso, struct map *map,  	char sympltname[1024];  	Elf *elf;  	int nr = 0, symidx, fd, err = 0; -	char name[PATH_MAX]; -	snprintf(name, sizeof(name), "%s%s", -		 symbol_conf.symfs, dso->long_name);  	fd = open(name, O_RDONLY);  	if (fd < 0)  		goto out; @@ -1703,8 +1701,9 @@ restart:  			continue;  		if (ret > 0) { -			int nr_plt = dso__synthesize_plt_symbols(dso, map, -								 filter); +			int nr_plt; + +			nr_plt = dso__synthesize_plt_symbols(dso, name, map, filter);  			if (nr_plt > 0)  				ret += nr_plt;  			break;  |