diff --git a/Documentation/ABI/obsolete/proc-pid-oom_adj b/Documentation/ABI/obsolete/proc-pid-oom_adj deleted file mode 100644 index cf63f26..0000000 --- a/Documentation/ABI/obsolete/proc-pid-oom_adj +++ /dev/null @@ -1,22 +0,0 @@ -What: /proc//oom_adj -When: August 2012 -Why: /proc//oom_adj allows userspace to influence the oom killer's - badness heuristic used to determine which task to kill when the kernel - is out of memory. - - The badness heuristic has since been rewritten since the introduction of - this tunable such that its meaning is deprecated. The value was - implemented as a bitshift on a score generated by the badness() - function that did not have any precise units of measure. With the - rewrite, the score is given as a proportion of available memory to the - task allocating pages, so using a bitshift which grows the score - exponentially is, thus, impossible to tune with fine granularity. - - A much more powerful interface, /proc//oom_score_adj, was - introduced with the oom killer rewrite that allows users to increase or - decrease the badness() score linearly. This interface will replace - /proc//oom_adj. - - A warning will be emitted to the kernel log if an application uses this - deprecated interface. After it is printed once, future warnings will be - suppressed until the kernel is rebooted. diff --git a/Documentation/arm/OMAP/DSS b/Documentation/arm/OMAP/DSS index 888ae7b..0af0e9e 100644 --- a/Documentation/arm/OMAP/DSS +++ b/Documentation/arm/OMAP/DSS @@ -255,10 +255,9 @@ framebuffer parameters. Kernel boot arguments --------------------- -vram=[,] - - Amount of total VRAM to preallocate and optionally a physical start - memory address. For example, "10M". omapfb allocates memory for - framebuffers from VRAM. +vram= + - Amount of total VRAM to preallocate. For example, "10M". omapfb + allocates memory for framebuffers from VRAM. omapfb.mode=:[,...] - Default video mode for specified displays. For example, diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt index 71cfbdc..d5af3f6 100644 --- a/Documentation/block/switching-sched.txt +++ b/Documentation/block/switching-sched.txt @@ -16,7 +16,7 @@ you can do so by typing: As of the Linux 2.6.10 kernel, it is now possible to change the IO scheduler for a given block device on the fly (thus making it possible, for instance, to set the CFQ scheduler for the system default, but -set a specific device to use the deadline or noop schedulers - which +set a specific device to use the anticipatory or noop schedulers - which can improve that device's throughput). To set a specific scheduler, simply do this: @@ -31,7 +31,7 @@ a "cat /sys/block/DEV/queue/scheduler" - the list of valid names will be displayed, with the currently selected scheduler in brackets: # cat /sys/block/hda/queue/scheduler -noop deadline [cfq] -# echo deadline > /sys/block/hda/queue/scheduler +noop anticipatory deadline [cfq] +# echo anticipatory > /sys/block/hda/queue/scheduler # cat /sys/block/hda/queue/scheduler -noop [deadline] cfq +noop [anticipatory] deadline cfq diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 6c2f55e..d8f36f9 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -554,13 +554,3 @@ Why: This is a legacy interface which have been replaced by a more Who: NeilBrown ---------------------------- - -What: i2c_adapter.id -When: June 2011 -Why: This field is deprecated. I2C device drivers shouldn't change their - behavior based on the underlying I2C adapter. Instead, the I2C - adapter driver should instantiate the I2C devices and provide the - needed platform-specific information. -Who: Jean Delvare - ----------------------------- diff --git a/Documentation/filesystems/xfs-delayed-logging-design.txt b/Documentation/filesystems/xfs-delayed-logging-design.txt index 7445bf3..96d0df2 100644 --- a/Documentation/filesystems/xfs-delayed-logging-design.txt +++ b/Documentation/filesystems/xfs-delayed-logging-design.txt @@ -794,6 +794,17 @@ designed. Roadmap: +2.6.37 Remove experimental tag from mount option + => should be roughly 6 months after initial merge + => enough time to: + => gain confidence and fix problems reported by early + adopters (a.k.a. guinea pigs) + => address worst performance regressions and undesired + behaviours + => start tuning/optimising code for parallelism + => start tuning/optimising algorithms consuming + excessive CPU time + 2.6.39 Switch default mount option to use delayed logging => should be roughly 12 months after initial merge => enough time to shake out remaining problems before next round of diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 92e83e5..ed45e98 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -706,7 +706,7 @@ and is between 256 and 4096 characters. It is defined in the file arch/x86/kernel/cpu/cpufreq/elanfreq.c. elevator= [IOSCHED] - Format: {"cfq" | "deadline" | "noop"} + Format: {"anticipatory" | "cfq" | "deadline" | "noop"} See Documentation/block/as-iosched.txt and Documentation/block/deadline-iosched.txt for details. diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 58b266b..8fd5ca2 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds-class.txt @@ -60,18 +60,15 @@ Hardware accelerated blink of LEDs Some LEDs can be programmed to blink without any CPU interaction. To support this feature, a LED driver can optionally implement the -blink_set() function (see ). To set an LED to blinking, -however, it is better to use use the API function led_blink_set(), -as it will check and implement software fallback if necessary. - -To turn off blinking again, use the API function led_brightness_set() -as that will not just set the LED brightness but also stop any software -timers that may have been required for blinking. - -The blink_set() function should choose a user friendly blinking value -if it is called with *delay_on==0 && *delay_off==0 parameters. In this -case the driver should give back the chosen value through delay_on and -delay_off parameters to the leds subsystem. +blink_set() function (see ). If implemented, triggers can +attempt to use it before falling back to software timers. The blink_set() +function should return 0 if the blink setting is supported, or -EINVAL +otherwise, which means that LED blinking will be handled by software. + +The blink_set() function should choose a user friendly blinking +value if it is called with *delay_on==0 && *delay_off==0 parameters. In +this case the driver should give back the chosen value through delay_on +and delay_off parameters to the leds subsystem. Setting the brightness to zero with brightness_set() callback function should completely turn off the LED and cancel the previously programmed diff --git a/Documentation/leds/leds-lp5521.txt b/Documentation/leds/leds-lp5521.txt deleted file mode 100644 index c4d8d15..0000000 --- a/Documentation/leds/leds-lp5521.txt +++ /dev/null @@ -1,88 +0,0 @@ -Kernel driver for lp5521 -======================== - -* National Semiconductor LP5521 led driver chip -* Datasheet: http://www.national.com/pf/LP/LP5521.html - -Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo -Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) - -Description ------------ - -LP5521 can drive up to 3 channels. Leds can be controlled directly via -the led class control interface. Channels have generic names: -lp5521:channelx, where x is 0 .. 2 - -All three channels can be also controlled using the engine micro programs. -More details of the instructions can be found from the public data sheet. - -Control interface for the engines: -x is 1 .. 3 -enginex_mode : disabled, load, run -enginex_load : store program (visible only in engine load mode) - -Example (start to blink the channel 2 led): -cd /sys/class/leds/lp5521:channel2/device -echo "load" > engine3_mode -echo "037f4d0003ff6000" > engine3_load -echo "run" > engine3_mode - -stop the engine: -echo "disabled" > engine3_mode - -sysfs contains a selftest entry. -The test communicates with the chip and checks that -the clock mode is automatically set to the requested one. - -Each channel has its own led current settings. -/sys/class/leds/lp5521:channel0/led_current - RW -/sys/class/leds/lp5521:channel0/max_current - RO -Format: 10x mA i.e 10 means 1.0 mA - -example platform data: - -Note: chan_nr can have values between 0 and 2. - -static struct lp5521_led_config lp5521_led_config[] = { - { - .chan_nr = 0, - .led_current = 50, - .max_current = 130, - }, { - .chan_nr = 1, - .led_current = 0, - .max_current = 130, - }, { - .chan_nr = 2, - .led_current = 0, - .max_current = 130, - } -}; - -static int lp5521_setup(void) -{ - /* setup HW resources */ -} - -static void lp5521_release(void) -{ - /* Release HW resources */ -} - -static void lp5521_enable(bool state) -{ - /* Control of chip enable signal */ -} - -static struct lp5521_platform_data lp5521_platform_data = { - .led_config = lp5521_led_config, - .num_channels = ARRAY_SIZE(lp5521_led_config), - .clock_mode = LP5521_CLOCK_EXT, - .setup_resources = lp5521_setup, - .release_resources = lp5521_release, - .enable = lp5521_enable, -}; - -If the current is set to 0 in the platform data, that channel is -disabled and it is not visible in the sysfs. diff --git a/Documentation/leds/leds-lp5523.txt b/Documentation/leds/leds-lp5523.txt deleted file mode 100644 index fad2feb..0000000 --- a/Documentation/leds/leds-lp5523.txt +++ /dev/null @@ -1,83 +0,0 @@ -Kernel driver for lp5523 -======================== - -* National Semiconductor LP5523 led driver chip -* Datasheet: http://www.national.com/pf/LP/LP5523.html - -Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo -Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) - -Description ------------ -LP5523 can drive up to 9 channels. Leds can be controlled directly via -the led class control interface. Channels have generic names: -lp5523:channelx where x is 0...8 - -The chip provides 3 engines. Each engine can control channels without -interaction from the main CPU. Details of the micro engine code can be found -from the public data sheet. Leds can be muxed to different channels. - -Control interface for the engines: -x is 1 .. 3 -enginex_mode : disabled, load, run -enginex_load : microcode load (visible only in load mode) -enginex_leds : led mux control (visible only in load mode) - -cd /sys/class/leds/lp5523:channel2/device -echo "load" > engine3_mode -echo "9d80400004ff05ff437f0000" > engine3_load -echo "111111111" > engine3_leds -echo "run" > engine3_mode - -sysfs contains a selftest entry. It measures each channel -voltage level and checks if it looks reasonable. If the level is too high, -the led is missing; if the level is too low, there is a short circuit. - -Selftest uses always the current from the platform data. - -Each channel contains led current settings. -/sys/class/leds/lp5523:channel2/led_current - RW -/sys/class/leds/lp5523:channel2/max_current - RO -Format: 10x mA i.e 10 means 1.0 mA - -Example platform data: - -Note - chan_nr can have values between 0 and 8. - -static struct lp5523_led_config lp5523_led_config[] = { - { - .chan_nr = 0, - .led_current = 50, - .max_current = 130, - }, -... - }, { - .chan_nr = 8, - .led_current = 50, - .max_current = 130, - } -}; - -static int lp5523_setup(void) -{ - /* Setup HW resources */ -} - -static void lp5523_release(void) -{ - /* Release HW resources */ -} - -static void lp5523_enable(bool state) -{ - /* Control chip enable signal */ -} - -static struct lp5523_platform_data lp5523_platform_data = { - .led_config = lp5523_led_config, - .num_channels = ARRAY_SIZE(lp5523_led_config), - .clock_mode = LP5523_CLOCK_EXT, - .setup_resources = lp5523_setup, - .release_resources = lp5523_release, - .enable = lp5523_enable, -}; diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fe95105..c7165f4 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -20,15 +20,6 @@ ip_no_pmtu_disc - BOOLEAN min_pmtu - INTEGER default 562 - minimum discovered Path MTU -route/max_size - INTEGER - Maximum number of routes allowed in the kernel. Increase - this when using large numbers of interfaces and/or routes. - -neigh/default/gc_thresh3 - INTEGER - Maximum number of neighbor entries allowed. Increase this - when using large numbers of interfaces and when communicating - with large numbers of directly-connected peers. - mtu_expires - INTEGER Time, in seconds, that cached PMTU information is kept. diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt index 19f8278..221f38b 100644 --- a/Documentation/rbtree.txt +++ b/Documentation/rbtree.txt @@ -21,8 +21,8 @@ three rotations, respectively, to balance the tree), with slightly slower To quote Linux Weekly News: There are a number of red-black trees in use in the kernel. - The deadline and CFQ I/O schedulers employ rbtrees to - track requests; the packet CD/DVD driver does the same. + The anticipatory, deadline, and CFQ I/O schedulers all employ + rbtrees to track requests; the packet CD/DVD driver does the same. The high-resolution timer code uses an rbtree to organize outstanding timer requests. The ext3 filesystem tracks directory entries in a red-black tree. Virtual memory areas (VMAs) are tracked with red-black diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 209e158..3894eaa 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -28,7 +28,6 @@ show up in /proc/sys/kernel: - core_uses_pid - ctrl-alt-del - dentry-state -- dmesg_restrict - domainname - hostname - hotplug @@ -214,19 +213,6 @@ to decide what to do with it. ============================================================== -dmesg_restrict: - -This toggle indicates whether unprivileged users are prevented from using -dmesg(8) to view messages from the kernel's log buffer. When -dmesg_restrict is set to (0) there are no restrictions. When -dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use -dmesg(8). - -The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default -value of dmesg_restrict. - -============================================================== - domainname & hostname: These files can be used to set the NIS/YP domainname and the diff --git a/MAINTAINERS b/MAINTAINERS index 8e6548d..0094224 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -161,7 +161,7 @@ M: Greg Kroah-Hartman L: linux-serial@vger.kernel.org W: http://serial.sourceforge.net S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ F: drivers/serial/8250* F: include/linux/serial_8250.h @@ -945,7 +945,7 @@ M: Magnus Damm L: linux-sh@vger.kernel.org W: http://oss.renesas.com Q: http://patchwork.kernel.org/project/linux-sh/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git rmobile-latest +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git S: Supported F: arch/arm/mach-shmobile/ F: drivers/sh/ @@ -2435,7 +2435,6 @@ F: drivers/net/wan/sdla.c FRAMEBUFFER LAYER L: linux-fbdev@vger.kernel.org W: http://linux-fbdev.sourceforge.net/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git S: Orphan F: Documentation/fb/ F: drivers/video/fb* @@ -5677,7 +5676,7 @@ S: Maintained STAGING SUBSYSTEM M: Greg Kroah-Hartman -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-next-2.6.git L: devel@driverdev.osuosl.org S: Maintained F: drivers/staging/ @@ -5706,7 +5705,7 @@ M: Paul Mundt L: linux-sh@vger.kernel.org W: http://www.linux-sh.org Q: http://patchwork.kernel.org/project/linux-sh/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git sh-latest +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git S: Supported F: Documentation/sh/ F: arch/sh/ @@ -5911,7 +5910,7 @@ S: Maintained TTY LAYER M: Greg Kroah-Hartman S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ F: drivers/char/tty_* F: drivers/serial/serial_core.c F: include/linux/serial_core.h @@ -6234,7 +6233,7 @@ USB SUBSYSTEM M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org W: http://www.linux-usb.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ S: Supported F: Documentation/usb/ F: drivers/net/usb/ @@ -6599,14 +6598,14 @@ F: drivers/platform/x86 XEN PCI SUBSYSTEM M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: xen-devel@lists.xensource.com S: Supported F: arch/x86/pci/*xen* F: drivers/pci/*xen* XEN SWIOTLB SUBSYSTEM M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: xen-devel@lists.xensource.com S: Supported F: arch/x86/xen/*swiotlb* F: drivers/xen/*swiotlb* @@ -6614,7 +6613,7 @@ F: drivers/xen/*swiotlb* XEN HYPERVISOR INTERFACE M: Jeremy Fitzhardinge M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: xen-devel@lists.xen.org L: virtualization@lists.osdl.org S: Supported F: arch/x86/xen/ diff --git a/Makefile b/Makefile index ab5359d..6619720 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 37 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc1 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index db524e7..a19a526 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -6,7 +6,7 @@ config ARM select HAVE_MEMBLOCK select RTC_LIB select SYS_SUPPORTS_APM_EMULATION - select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI) + select GENERIC_ATOMIC64 if (!CPU_32v6K) select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_ARCH_KGDB select HAVE_KPROBES if (!XIP_KERNEL) @@ -646,7 +646,7 @@ config ARCH_S3C2410 select ARCH_HAS_CPUFREQ select HAVE_CLK select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C + select HAVE_S3C2410_I2C help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (), the IPAQ 1940 or @@ -676,8 +676,8 @@ config ARCH_S3C64XX select S3C_DEV_NAND select USB_ARCH_HAS_OHCI select SAMSUNG_GPIOLIB_4BIT - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_I2C + select HAVE_S3C2410_WATCHDOG help Samsung S3C64XX series based systems @@ -686,10 +686,10 @@ config ARCH_S5P64X0 select CPU_V6 select GENERIC_GPIO select HAVE_CLK - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_WATCHDOG select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C_RTC if RTC_CLASS + select HAVE_S3C2410_I2C + select HAVE_S3C_RTC help Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, SMDK6450. @@ -700,7 +700,7 @@ config ARCH_S5P6442 select GENERIC_GPIO select HAVE_CLK select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_WATCHDOG help Samsung S5P6442 CPU based systems @@ -711,9 +711,9 @@ config ARCH_S5PC100 select CPU_V7 select ARM_L1_CACHE_SHIFT_6 select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C_RTC if RTC_CLASS - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_I2C + select HAVE_S3C_RTC + select HAVE_S3C2410_WATCHDOG help Samsung S5PC100 series based systems @@ -726,9 +726,9 @@ config ARCH_S5PV210 select ARM_L1_CACHE_SHIFT_6 select ARCH_HAS_CPUFREQ select ARCH_USES_GETTIMEOFFSET - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C_RTC if RTC_CLASS - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_I2C + select HAVE_S3C_RTC + select HAVE_S3C2410_WATCHDOG help Samsung S5PV210/S5PC110 series based systems @@ -739,9 +739,9 @@ config ARCH_S5PV310 select GENERIC_GPIO select HAVE_CLK select GENERIC_CLOCKEVENTS - select HAVE_S3C_RTC if RTC_CLASS - select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C_RTC + select HAVE_S3C2410_I2C + select HAVE_S3C2410_WATCHDOG help Samsung S5PV310 series based systems diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 772f95f..ada6359 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -251,16 +251,15 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); /* - * Set priority on all global interrupts. + * Set priority on all interrupts. */ - for (i = 32; i < max_irq; i += 4) + for (i = 0; i < max_irq; i += 4) writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); /* - * Disable all interrupts. Leave the PPI and SGIs alone - * as these enables are banked registers. + * Disable all interrupts. */ - for (i = 32; i < max_irq; i += 32) + for (i = 0; i < max_irq; i += 32) writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); /* @@ -278,30 +277,11 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) { - void __iomem *dist_base; - int i; - if (gic_nr >= MAX_GIC_NR) BUG(); - dist_base = gic_data[gic_nr].dist_base; - BUG_ON(!dist_base); - gic_data[gic_nr].cpu_base = base; - /* - * Deal with the banked PPI and SGI interrupts - disable all - * PPI interrupts, ensure all SGI interrupts are enabled. - */ - writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); - writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); - - /* - * Set priority on PPI and SGI interrupts - */ - for (i = 0; i < 32; i += 4) - writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); - writel(0xf0, base + GIC_CPU_PRIMASK); writel(1, base + GIC_CPU_CTRL); } diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 21fa272..6700c7f 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -75,7 +75,7 @@ extern unsigned long it8152_base_address; IT8152_PD_IRQ(1) USB (USBR) IT8152_PD_IRQ(0) Audio controller (ACR) */ -#define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) +#define IT8152_IRQ(x) (IRQ_BOARD_END + (x)) /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ #define IT8152_LD_IRQ_COUNT 9 diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 21e3a4a..54593b0 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -748,7 +748,8 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, breakpoint_handler(addr, regs); break; case ARM_ENTRY_ASYNC_WATCHPOINT: - WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n"); + WARN_ON("Asynchronous watchpoint exception taken. " + "Debugging results may be unreliable"); case ARM_ENTRY_SYNC_WATCHPOINT: watchpoint_handler(addr, regs); break; diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 07a5035..49643b1 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -1749,7 +1749,7 @@ static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, enum armv7_counters counter) { - int ret = 0; + int ret; if (counter == ARMV7_CYCLE_COUNTER) ret = pmnc & ARMV7_FLAG_C; diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index c2e112e..20b7411 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -28,7 +28,7 @@ int notrace unwind_frame(struct stackframe *frame) /* only go to a higher address on the stack */ low = frame->sp; - high = ALIGN(low, THREAD_SIZE); + high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; /* check current frame pointer is within bounds */ if (fp < (low + 12) || fp + 4 >= high) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 446aee9..cda78d5 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -53,7 +53,10 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long); void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS - printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); + char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN]; + sprint_symbol(sym1, where); + sprint_symbol(sym2, from); + printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2); #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index d2cb0b3..2a16176 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -279,7 +279,7 @@ int unwind_frame(struct stackframe *frame) /* only go to a higher address on the stack */ low = frame->sp; - high = ALIGN(low, THREAD_SIZE); + high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, frame->pc, frame->lr, frame->sp); diff --git a/arch/arm/mach-ep93xx/include/mach/dma.h b/arch/arm/mach-ep93xx/include/mach/dma.h index 5e31b2b..3a5961d 100644 --- a/arch/arm/mach-ep93xx/include/mach/dma.h +++ b/arch/arm/mach-ep93xx/include/mach/dma.h @@ -1,13 +1,5 @@ -/** - * DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine - * - * The EP93xx DMA M2P subsystem handles DMA transfers between memory and - * peripherals. DMA M2P channels are available for audio, UARTs and IrDA. - * See chapter 10 of the EP93xx users guide for full details on the DMA M2P - * engine. - * - * See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code. - * +/* + * arch/arm/mach-ep93xx/include/mach/dma.h */ #ifndef __ASM_ARCH_DMA_H @@ -16,34 +8,12 @@ #include #include -/** - * struct ep93xx_dma_buffer - Information about a buffer to be transferred - * using the DMA M2P engine - * - * @list: Entry in DMA buffer list - * @bus_addr: Physical address of the buffer - * @size: Size of the buffer in bytes - */ struct ep93xx_dma_buffer { struct list_head list; u32 bus_addr; u16 size; }; -/** - * struct ep93xx_dma_m2p_client - Information about a DMA M2P client - * - * @name: Unique name for this client - * @flags: Client flags - * @cookie: User data to pass to callback functions - * @buffer_started: Non NULL function to call when a transfer is started. - * The arguments are the user data cookie and the DMA - * buffer which is starting. - * @buffer_finished: Non NULL function to call when a transfer is completed. - * The arguments are the user data cookie, the DMA buffer - * which has completed, and a boolean flag indicating if - * the transfer had an error. - */ struct ep93xx_dma_m2p_client { char *name; u8 flags; @@ -54,11 +24,10 @@ struct ep93xx_dma_m2p_client { struct ep93xx_dma_buffer *buf, int bytes, int error); - /* private: Internal use only */ + /* Internal to the DMA code. */ void *channel; }; -/* DMA M2P ports */ #define EP93XX_DMA_M2P_PORT_I2S1 0x00 #define EP93XX_DMA_M2P_PORT_I2S2 0x01 #define EP93XX_DMA_M2P_PORT_AAC1 0x02 @@ -70,80 +39,18 @@ struct ep93xx_dma_m2p_client { #define EP93XX_DMA_M2P_PORT_UART3 0x08 #define EP93XX_DMA_M2P_PORT_IRDA 0x09 #define EP93XX_DMA_M2P_PORT_MASK 0x0f +#define EP93XX_DMA_M2P_TX 0x00 +#define EP93XX_DMA_M2P_RX 0x10 +#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 +#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 +#define EP93XX_DMA_M2P_ERROR_MASK 0x60 -/* DMA M2P client flags */ -#define EP93XX_DMA_M2P_TX 0x00 /* Memory to peripheral */ -#define EP93XX_DMA_M2P_RX 0x10 /* Peripheral to memory */ - -/* - * DMA M2P client error handling flags. See the EP93xx users guide - * documentation on the DMA M2P CONTROL register for more details - */ -#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 /* Abort on peripheral error */ -#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 /* Ignore peripheral errors */ -#define EP93XX_DMA_M2P_ERROR_MASK 0x60 /* Mask of error bits */ - -/** - * ep93xx_dma_m2p_client_register - Register a client with the DMA M2P - * subsystem - * - * @m2p: Client information to register - * returns 0 on success - * - * The DMA M2P subsystem allocates a channel and an interrupt line for the DMA - * client - */ -int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p); - -/** - * ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P - * subsystem - * - * @m2p: Client to unregister - * - * Any transfers currently in progress will be completed in hardware, but - * ignored in software. - */ +int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p); void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p); - -/** - * ep93xx_dma_m2p_submit - Submit a DMA M2P transfer - * - * @m2p: DMA Client to submit the transfer on - * @buf: DMA Buffer to submit - * - * If the current or next transfer positions are free on the M2P client then - * the transfer is started immediately. If not, the transfer is added to the - * list of pending transfers. This function must not be called from the - * buffer_finished callback for an M2P channel. - * - */ void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p, struct ep93xx_dma_buffer *buf); - -/** - * ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list - * for an M2P channel - * - * @m2p: DMA Client to submit the transfer on - * @buf: DMA Buffer to submit - * - * This function must only be called from the buffer_finished callback for an - * M2P channel. It is commonly used to add the next transfer in a chained list - * of DMA transfers. - */ void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p, struct ep93xx_dma_buffer *buf); - -/** - * ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client - * - * @m2p: DMA client to flush transfers on - * - * Any transfers currently in progress will be completed in hardware, but - * ignored in software. - * - */ void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p); #endif /* __ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 3688123..51ff23b 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -854,9 +854,10 @@ int __init kirkwood_find_tclk(void) kirkwood_pcie_id(&dev, &rev); - if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID) - if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0) - return 200000000; + if ((dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 || + rev == MV88F6281_REV_A1)) || + (dev == MV88F6282_DEV_ID)) + return 200000000; return 166666667; } diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c index a31c949..4aa86e4 100644 --- a/arch/arm/mach-kirkwood/d2net_v2-setup.c +++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c @@ -225,5 +225,5 @@ MACHINE_START(D2NET_V2, "LaCie d2 Network v2") .init_machine = d2net_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c index 285edab..d3ea1b6 100644 --- a/arch/arm/mach-kirkwood/lacie_v2-common.c +++ b/arch/arm/mach-kirkwood/lacie_v2-common.c @@ -111,3 +111,17 @@ void __init lacie_v2_hdd_power_init(int hdd_num) pr_err("Failed to power up HDD%d\n", i + 1); } } + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void lacie_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer lacie_v2_timer = { + .init = lacie_v2_timer_init, +}; diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h index fc64f57..af52131 100644 --- a/arch/arm/mach-kirkwood/lacie_v2-common.h +++ b/arch/arm/mach-kirkwood/lacie_v2-common.h @@ -13,4 +13,6 @@ void lacie_v2_register_flash(void); void lacie_v2_register_i2c_devices(void); void lacie_v2_hdd_power_init(int hdd_num); +extern struct sys_timer lacie_v2_timer; + #endif diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c index 27901f7..065187d 100644 --- a/arch/arm/mach-kirkwood/mpp.c +++ b/arch/arm/mach-kirkwood/mpp.c @@ -59,7 +59,7 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list) } printk("\n"); - for ( ; *mpp_list; mpp_list++) { + while (*mpp_list) { unsigned int num = MPP_NUM(*mpp_list); unsigned int sel = MPP_SEL(*mpp_list); int shift, gpio_mode; @@ -88,6 +88,8 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list) if (sel != 0) gpio_mode = 0; orion_gpio_set_valid(num, gpio_mode); + + mpp_list++; } printk(KERN_DEBUG " final MPP regs:"); diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c index 65ee21f..5ea66f1 100644 --- a/arch/arm/mach-kirkwood/netspace_v2-setup.c +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c @@ -262,7 +262,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -272,7 +272,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -282,6 +282,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c index 93afd3c..a1b45d5 100644 --- a/arch/arm/mach-kirkwood/netxbig_v2-setup.c +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c @@ -403,7 +403,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") .init_machine = netxbig_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -413,6 +413,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") .init_machine = netxbig_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c index 3587a28..8be09a0 100644 --- a/arch/arm/mach-kirkwood/ts41x-setup.c +++ b/arch/arm/mach-kirkwood/ts41x-setup.c @@ -27,10 +27,6 @@ #include "mpp.h" #include "tsx1x-common.h" -/* for the PCIe reset workaround */ -#include - - #define QNAP_TS41X_JUMPER_JP1 45 static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = { @@ -144,16 +140,8 @@ static void __init qnap_ts41x_init(void) static int __init ts41x_pci_init(void) { - if (machine_is_ts41x()) { - /* - * Without this explicit reset, the PCIe SATA controller - * (Marvell 88sx7042/sata_mv) is known to stop working - * after a few minutes. - */ - orion_pcie_reset((void __iomem *)PCIE_VIRT_BASE); - + if (machine_is_ts41x()) kirkwood_pcie_init(KW_PCIE0); - } return 0; } diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h index 8a3b56d..f43a68b 100644 --- a/arch/arm/mach-mmp/include/mach/cputype.h +++ b/arch/arm/mach-mmp/include/mach/cputype.h @@ -46,8 +46,7 @@ static inline int cpu_is_pxa910(void) #ifdef CONFIG_CPU_MMP2 static inline int cpu_is_mmp2(void) { - return (((read_cpuid_id() >> 8) & 0xff) == 0x58); -} + return (((cpu_readid_id() >> 8) & 0xff) == 0x58); #else #define cpu_is_mmp2() (0) #endif diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c index 84db2df..354ac51 100644 --- a/arch/arm/mach-mv78xx0/mpp.c +++ b/arch/arm/mach-mv78xx0/mpp.c @@ -54,7 +54,7 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list) } printk("\n"); - for ( ; *mpp_list; mpp_list++) { + while (*mpp_list) { unsigned int num = MPP_NUM(*mpp_list); unsigned int sel = MPP_SEL(*mpp_list); int shift, gpio_mode; @@ -83,6 +83,8 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list) if (sel != 0) gpio_mode = 0; orion_gpio_set_valid(num, gpio_mode); + + mpp_list++; } printk(KERN_DEBUG " final MPP regs:"); diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index e7f9ee6..ea0d80a 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -321,9 +321,10 @@ static struct platform_device omap_wdt_device = { static int __init omap_init_wdt(void) { if (!cpu_is_omap16xx()) - return -ENODEV; + return; - return platform_device_register(&omap_wdt_device); + platform_device_register(&omap_wdt_device); + return 0; } subsys_initcall(omap_init_wdt); #endif diff --git a/arch/arm/mach-omap1/include/mach/camera.h b/arch/arm/mach-omap1/include/mach/camera.h index 847d00f..fd54b45 100644 --- a/arch/arm/mach-omap1/include/mach/camera.h +++ b/arch/arm/mach-omap1/include/mach/camera.h @@ -1,8 +1,6 @@ #ifndef __ASM_ARCH_CAMERA_H_ #define __ASM_ARCH_CAMERA_H_ -#include - void omap1_camera_init(void *); static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info) diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 53ac762..067f437 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -242,6 +242,9 @@ static int devkit8000_twl_gpio_setup(struct device *dev, mmc[0].gpio_cd = gpio + 0; omap2_hsmmc_init(mmc); + /* link regulators to MMC adapters */ + devkit8000_vmmc1_supply.dev = mmc[0].dev; + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c index db485d3..bc4c3b9 100644 --- a/arch/arm/mach-orion5x/mpp.c +++ b/arch/arm/mach-orion5x/mpp.c @@ -127,7 +127,7 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) /* Initialize gpiolib. */ orion_gpio_init(); - for ( ; mode->mpp >= 0; mode++) { + while (mode->mpp >= 0) { u32 *reg; int num_type; int shift; @@ -160,6 +160,8 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) orion_gpio_set_unused(mode->mpp); orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); + + mode++; } writel(mpp_0_7_ctrl, MPP_0_7_CTRL); diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index c1c1cd0..16f1bd5 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -239,7 +239,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = { static struct resource ts78xx_ts_nand_resources = { .start = TS_NAND_DATA, .end = TS_NAND_DATA + 4, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }; static struct platform_device ts78xx_ts_nand_device = { diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index d34b99f..ac5598c 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -476,6 +476,8 @@ static void __init cmx2xx_init(void) static void __init cmx2xx_init_irq(void) { + pxa27x_init_irq(); + if (cpu_is_pxa25x()) { pxa25x_init_irq(); cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ); diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index ffa50e6..4b521e0 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -116,7 +116,7 @@ static struct platform_device smc91x_device = { }, }; -#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULE) static uint16_t lcd_power_on[] = { /* single frame */ SMART_CMD_NOOP, diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 579d2f0..1ca7bdc 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -143,7 +143,7 @@ config MACH_SMDK6410 select S3C_DEV_USB_HSOTG select S3C_DEV_WDT select SAMSUNG_DEV_KEYPAD - select HAVE_S3C2410_WATCHDOG if WATCHDOG + select HAVE_S3C2410_WATCHDOG select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_I2C1 select S3C64XX_SETUP_IDE diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index d326054..32d9e28 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -163,13 +163,11 @@ static struct mtd_partition nor_flash_partitions[] = { .name = "loader", .offset = 0x00000000, .size = 512 * 1024, - .mask_flags = MTD_WRITEABLE, }, { .name = "bootenv", .offset = MTDPART_OFS_APPEND, .size = 512 * 1024, - .mask_flags = MTD_WRITEABLE, }, { .name = "kernel_ro", @@ -583,10 +581,6 @@ static int fsi_set_rate(int is_porta, int rate) return -EINVAL; switch (rate) { - case 44100: - clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); - ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; - break; case 48000: clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 30b2f40..4cd3cae 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -98,7 +98,7 @@ static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0), INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220), INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260), - INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ21A, 0x32a0), + INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0), INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0), INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320), INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360), diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index fd25ccd..c2e405a 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -54,9 +54,7 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = { static void __init ct_ca9x4_map_io(void) { -#ifdef CONFIG_LOCAL_TIMERS twd_base = MMIO_P2V(A9_MPCORE_TWD); -#endif v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index ac6a361..e4dd064 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -198,7 +198,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) * fragmentation of the DMA space, and also prevents allocations * smaller than a section from crossing a section boundary. */ - bit = fls(size - 1); + bit = fls(size - 1) + 1; if (bit > SECTION_SHIFT) bit = SECTION_SHIFT; align = 1 << bit; diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index fc81912..6f42a18 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -284,14 +284,12 @@ void __init omap_dsp_reserve_sdram_memblock(void) if (!size) return; - paddr = memblock_alloc(size, SZ_1M); + paddr = __memblock_alloc_base(size, SZ_1M, MEMBLOCK_REAL_LIMIT); if (!paddr) { pr_err("%s: failed to reserve %x bytes\n", __func__, size); return; } - memblock_free(paddr, size); - memblock_remove(paddr, size); omap_dsp_phys_mempool_base = paddr; } diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 2c28265..f5c5b8d 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1983,8 +1983,6 @@ static int omap2_dma_handle_ch(int ch) dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch)); dma_write(1 << ch, IRQSTATUS_L0); - /* read back the register to flush the write */ - dma_read(IRQSTATUS_L0); /* If the ch is not chained then chain_id will be -1 */ if (dma_chan[ch].chain_id != -1) { diff --git a/arch/arm/plat-orion/include/plat/pcie.h b/arch/arm/plat-orion/include/plat/pcie.h index cc99163..3ebfef7 100644 --- a/arch/arm/plat-orion/include/plat/pcie.h +++ b/arch/arm/plat-orion/include/plat/pcie.h @@ -11,15 +11,12 @@ #ifndef __PLAT_PCIE_H #define __PLAT_PCIE_H -struct pci_bus; - u32 orion_pcie_dev_id(void __iomem *base); u32 orion_pcie_rev(void __iomem *base); int orion_pcie_link_up(void __iomem *base); int orion_pcie_x4_mode(void __iomem *base); int orion_pcie_get_local_bus_nr(void __iomem *base); void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); -void orion_pcie_reset(void __iomem *base); void orion_pcie_setup(void __iomem *base, struct mbus_dram_target_info *dram); int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index af2d733..779553a 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c @@ -182,6 +182,11 @@ void __init orion_pcie_setup(void __iomem *base, u32 mask; /* + * soft reset PCIe unit + */ + orion_pcie_reset(base); + + /* * Point PCIe unit MBUS decode windows to DRAM space. */ orion_pcie_setup_wins(base, dram); diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index b7c5bab..2cd899f 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -38,8 +38,8 @@ struct pt_regs { struct task_struct; -extern long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data); +extern long subarch_ptrace(struct task_struct *child, long request, long addr, + long data); extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); extern int get_fpregs(struct user_i387_struct __user *buf, diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 701b672..a5e33f2 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -122,7 +122,7 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_SET_THREAD_AREA: - ret = ptrace_set_thread_area(child, addr, vp); + ret = ptrace_set_thread_area(child, addr, datavp); break; case PTRACE_FAULTINFO: { diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index f6ce0bd..286de34 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -141,13 +141,13 @@ static inline void native_apic_msr_write(u32 reg, u32 v) static inline u32 native_apic_msr_read(u32 reg) { - u64 msr; + u32 low, high; if (reg == APIC_DFR) return -1; - rdmsrl(APIC_BASE_MSR + (reg >> 4), msr); - return (u32)msr; + rdmsr(APIC_BASE_MSR + (reg >> 4), low, high); + return low; } static inline void native_x2apic_wait_icr_idle(void) @@ -181,12 +181,12 @@ extern void enable_x2apic(void); extern void x2apic_icr_write(u32 low, u32 id); static inline int x2apic_enabled(void) { - u64 msr; + int msr, msr2; if (!cpu_has_x2apic) return 0; - rdmsrl(MSR_IA32_APICBASE, msr); + rdmsr(MSR_IA32_APICBASE, msr, msr2); if (msr & X2APIC_ENABLE) return 1; return 0; diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index 6d90adf..b2f2d2e 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h @@ -806,78 +806,6 @@ union uvh_node_present_table_u { }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x16000c8UL - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_alias210_overlay_config_0_mmr_u { - unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23: 24; /* */ - unsigned long base : 8; /* RW */ - unsigned long rsvd_32_47: 16; /* */ - unsigned long m_alias : 5; /* RW */ - unsigned long rsvd_53_62: 10; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x16000d8UL - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_alias210_overlay_config_1_mmr_u { - unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_1_mmr_s { - unsigned long rsvd_0_23: 24; /* */ - unsigned long base : 8; /* RW */ - unsigned long rsvd_32_47: 16; /* */ - unsigned long m_alias : 5; /* RW */ - unsigned long rsvd_53_62: 10; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x16000e8UL - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_alias210_overlay_config_2_mmr_u { - unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_2_mmr_s { - unsigned long rsvd_0_23: 24; /* */ - unsigned long base : 8; /* RW */ - unsigned long rsvd_32_47: 16; /* */ - unsigned long m_alias : 5; /* RW */ - unsigned long rsvd_53_62: 10; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ /* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL @@ -929,29 +857,6 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { }; /* ========================================================================= */ -/* UVH_RH_GAM_CONFIG_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_CONFIG_MMR 0x1600000UL - -#define UVH_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 -#define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL -#define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL -#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 -#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL - -union uvh_rh_gam_config_mmr_u { - unsigned long v; - struct uvh_rh_gam_config_mmr_s { - unsigned long m_skt : 6; /* RW */ - unsigned long n_skt : 4; /* RW */ - unsigned long rsvd_10_11: 2; /* */ - unsigned long mmiol_cfg : 1; /* RW */ - unsigned long rsvd_13_63: 51; /* */ - } s; -}; - -/* ========================================================================= */ /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL @@ -1082,5 +987,97 @@ union uvh_rtc1_int_config_u { } s; }; +/* ========================================================================= */ +/* UVH_SI_ADDR_MAP_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL + +#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_SHFT 0 +#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL +#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_SHFT 8 +#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_MASK 0x0000000000000f00UL + +union uvh_si_addr_map_config_u { + unsigned long v; + struct uvh_si_addr_map_config_s { + unsigned long m_skt : 6; /* RW */ + unsigned long rsvd_6_7: 2; /* */ + unsigned long n_skt : 4; /* RW */ + unsigned long rsvd_12_63: 52; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS0_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS0_OVERLAY_CONFIG 0xc80008UL + +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias0_overlay_config_u { + unsigned long v; + struct uvh_si_alias0_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS1_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS1_OVERLAY_CONFIG 0xc80010UL + +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias1_overlay_config_u { + unsigned long v; + struct uvh_si_alias1_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS2_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS2_OVERLAY_CONFIG 0xc80018UL + +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias2_overlay_config_u { + unsigned long v; + struct uvh_si_alias2_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + -#endif /* __ASM_UV_MMRS_X86_H__ */ +#endif /* _ASM_X86_UV_UV_MMRS_H */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 3f838d5..850657d 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -52,6 +52,7 @@ #include #include #include +#include unsigned int num_processors; diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 194539a..ed4118d 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -379,14 +379,14 @@ struct redir_addr { #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT static __initdata struct redir_addr redir_addrs[] = { - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR}, - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR}, - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, }; static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) { - union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias; + union uvh_si_alias0_overlay_config_u alias; union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; int i; @@ -660,7 +660,7 @@ void uv_nmi_init(void) void __init uv_system_init(void) { - union uvh_rh_gam_config_mmr_u m_n_config; + union uvh_si_addr_map_config_u m_n_config; union uvh_node_id_u node_id; unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; @@ -670,7 +670,7 @@ void __init uv_system_init(void) map_low_mmrs(); - m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); + m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); m_val = m_n_config.s.m_skt; n_val = m_n_config.s.n_skt; mmr_base = diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index e421b8c..46d5844 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -280,11 +280,11 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) struct amd_nb *nb; int i; - nb = kmalloc_node(sizeof(struct amd_nb), GFP_KERNEL | __GFP_ZERO, - cpu_to_node(cpu)); + nb = kmalloc(sizeof(struct amd_nb), GFP_KERNEL); if (!nb) return NULL; + memset(nb, 0, sizeof(*nb)); nb->nb_id = nb_id; /* diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index ce0cb47..e1af7c0 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -212,7 +212,7 @@ static int install_equiv_cpu_table(const u8 *buf) return 0; } - equiv_cpu_table = vmalloc(size); + equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); if (!equiv_cpu_table) { pr_err("failed to allocate equivalent CPU table\n"); return 0; diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index 6da143c..7182580 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c @@ -217,13 +217,13 @@ void __cpuinit fam10h_check_enable_mmcfg(void) wrmsrl(address, val); } -static int __init set_check_enable_amd_mmconf(const struct dmi_system_id *d) +static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d) { pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; return 0; } -static const struct dmi_system_id __initconst mmconf_dmi_table[] = { +static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = { { .callback = set_check_enable_amd_mmconf, .ident = "Sun Microsystems Machine", @@ -234,8 +234,7 @@ static const struct dmi_system_id __initconst mmconf_dmi_table[] = { {} }; -/* Called from a __cpuinit function, but only on the BSP. */ -void __ref check_enable_amd_mmconf_dmi(void) +void __cpuinit check_enable_amd_mmconf_dmi(void) { dmi_check_system(mmconf_dmi_table); } diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 008b91e..bab3b9e 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -41,6 +41,44 @@ void pvclock_set_flags(u8 flags) valid_flags = flags; } +/* + * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, + * yielding a 64-bit result. + */ +static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) +{ + u64 product; +#ifdef __i386__ + u32 tmp1, tmp2; +#endif + + if (shift < 0) + delta >>= -shift; + else + delta <<= shift; + +#ifdef __i386__ + __asm__ ( + "mul %5 ; " + "mov %4,%%eax ; " + "mov %%edx,%4 ; " + "mul %5 ; " + "xor %5,%5 ; " + "add %4,%%eax ; " + "adc %5,%%edx ; " + : "=A" (product), "=r" (tmp1), "=r" (tmp2) + : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); +#elif defined(__x86_64__) + __asm__ ( + "mul %%rdx ; shrd $32,%%rdx,%%rax" + : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); +#else +#error implement me! +#endif + + return product; +} + static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow) { u64 delta = native_read_tsc() - shadow->tsc_timestamp; diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 12cdbb1..4935848 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -251,7 +251,7 @@ static void __cpuinit calculate_tlb_offset(void) } } -static int __cpuinit tlb_cpuhp_notify(struct notifier_block *n, +static int tlb_cpuhp_notify(struct notifier_block *n, unsigned long action, void *hcpu) { switch (action & 0xf) { diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 0972315..15466c0 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -138,6 +138,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) struct acpi_resource_address64 addr; acpi_status status; unsigned long flags; + struct resource *root, *conflict; u64 start, end; status = resource_to_addr(acpi_res, &addr); @@ -145,10 +146,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data) return AE_OK; if (addr.resource_type == ACPI_MEMORY_RANGE) { + root = &iomem_resource; flags = IORESOURCE_MEM; if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY) flags |= IORESOURCE_PREFETCH; } else if (addr.resource_type == ACPI_IO_RANGE) { + root = &ioport_resource; flags = IORESOURCE_IO; } else return AE_OK; @@ -169,90 +172,25 @@ setup_resource(struct acpi_resource *acpi_res, void *data) return AE_OK; } - info->res_num++; - if (addr.translation_offset) - dev_info(&info->bridge->dev, "host bridge window %pR " - "(PCI address [%#llx-%#llx])\n", - res, res->start - addr.translation_offset, - res->end - addr.translation_offset); - else - dev_info(&info->bridge->dev, "host bridge window %pR\n", res); - - return AE_OK; -} - -static bool resource_contains(struct resource *res, resource_size_t point) -{ - if (res->start <= point && point <= res->end) - return true; - return false; -} - -static void coalesce_windows(struct pci_root_info *info, int type) -{ - int i, j; - struct resource *res1, *res2; - - for (i = 0; i < info->res_num; i++) { - res1 = &info->res[i]; - if (!(res1->flags & type)) - continue; - - for (j = i + 1; j < info->res_num; j++) { - res2 = &info->res[j]; - if (!(res2->flags & type)) - continue; - - /* - * I don't like throwing away windows because then - * our resources no longer match the ACPI _CRS, but - * the kernel resource tree doesn't allow overlaps. - */ - if (resource_contains(res1, res2->start) || - resource_contains(res1, res2->end) || - resource_contains(res2, res1->start) || - resource_contains(res2, res1->end)) { - res1->start = min(res1->start, res2->start); - res1->end = max(res1->end, res2->end); - dev_info(&info->bridge->dev, - "host bridge window expanded to %pR; %pR ignored\n", - res1, res2); - res2->flags = 0; - } - } - } -} - -static void add_resources(struct pci_root_info *info) -{ - int i; - struct resource *res, *root, *conflict; - - if (!pci_use_crs) - return; - - coalesce_windows(info, IORESOURCE_MEM); - coalesce_windows(info, IORESOURCE_IO); - - for (i = 0; i < info->res_num; i++) { - res = &info->res[i]; - - if (res->flags & IORESOURCE_MEM) - root = &iomem_resource; - else if (res->flags & IORESOURCE_IO) - root = &ioport_resource; - else - continue; - - conflict = insert_resource_conflict(root, res); - if (conflict) - dev_err(&info->bridge->dev, - "address space collision: host bridge window %pR " - "conflicts with %s %pR\n", - res, conflict->name, conflict); + conflict = insert_resource_conflict(root, res); + if (conflict) { + dev_err(&info->bridge->dev, + "address space collision: host bridge window %pR " + "conflicts with %s %pR\n", + res, conflict->name, conflict); + } else { + pci_bus_add_resource(info->bus, res, 0); + info->res_num++; + if (addr.translation_offset) + dev_info(&info->bridge->dev, "host bridge window %pR " + "(PCI address [%#llx-%#llx])\n", + res, res->start - addr.translation_offset, + res->end - addr.translation_offset); else - pci_bus_add_resource(info->bus, res, 0); + dev_info(&info->bridge->dev, + "host bridge window %pR\n", res); } + return AE_OK; } static void @@ -286,7 +224,6 @@ get_current_resources(struct acpi_device *device, int busnum, acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, &info); - add_resources(&info); return; name_alloc_fail: diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index d7b5109..117f5b8 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -147,10 +147,8 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) irq = xen_allocate_pirq(v[i], 0, /* not sharable */ (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi"); - if (irq < 0) { - ret = -1; - goto free; - } + if (irq < 0) + return -1; ret = set_irq_msi(irq, msidesc); if (ret) @@ -166,7 +164,7 @@ error: if (ret == -ENODEV) dev_err(&dev->dev, "Xen PCI frontend has not registered" \ " MSI/MSI-X support!\n"); -free: + kfree(v); return ret; } diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index a318194..20ea20a 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -1343,8 +1343,8 @@ uv_activation_descriptor_init(int node, int pnode) * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub */ - bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE - * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); + bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)* + UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); BUG_ON(!bau_desc); pa = uv_gpa(bau_desc); /* need the real nasid*/ @@ -1402,9 +1402,9 @@ uv_payload_queue_init(int node, int pnode) struct bau_payload_queue_entry *pqp_malloc; struct bau_control *bcp; - pqp = kmalloc_node((DEST_Q_SIZE + 1) - * sizeof(struct bau_payload_queue_entry), - GFP_KERNEL, node); + pqp = (struct bau_payload_queue_entry *) kmalloc_node( + (DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry), + GFP_KERNEL, node); BUG_ON(!pqp); pqp_malloc = pqp; @@ -1520,7 +1520,8 @@ static void __init uv_init_per_cpu(int nuvhubs) timeout_us = calculate_destination_timeout(); - uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); + uvhub_descs = (struct uvhub_desc *) + kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); for_each_present_cpu(cpu) { diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 21ed8d7..c237b81 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -2126,7 +2126,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, { pmd_t *kernel_pmd; - level2_kernel_pgt = extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); + level2_kernel_pgt = extend_brk(sizeof(pmd_t *) * PTRS_PER_PMD, PAGE_SIZE); max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + xen_start_info->nr_pt_frames * PAGE_SIZE + diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 769c4b0..b1dbdaa 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -118,18 +118,16 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, const struct e820map *e820) { phys_addr_t max_addr = PFN_PHYS(max_pfn); - phys_addr_t last_end = ISA_END_ADDRESS; + phys_addr_t last_end = 0; unsigned long released = 0; int i; - /* Free any unused memory above the low 1Mbyte. */ for (i = 0; i < e820->nr_map && last_end < max_addr; i++) { phys_addr_t end = e820->map[i].addr; end = min(max_addr, end); - if (last_end < end) - released += xen_release_chunk(last_end, end); - last_end = max(last_end, e820->map[i].addr + e820->map[i].size); + released += xen_release_chunk(last_end, end); + last_end = e820->map[i].addr + e820->map[i].size; } if (last_end < max_addr) @@ -166,7 +164,6 @@ char * __init xen_memory_setup(void) XENMEM_memory_map; rc = HYPERVISOR_memory_op(op, &memmap); if (rc == -ENOSYS) { - BUG_ON(xen_initial_domain()); memmap.nr_entries = 1; map[0].addr = 0ULL; map[0].size = mem_end; @@ -204,13 +201,12 @@ char * __init xen_memory_setup(void) } /* - * In domU, the ISA region is normal, usable memory, but we - * reserve ISA memory anyway because too many things poke + * Even though this is normal, usable memory under Xen, reserve + * ISA memory anyway because too many things think they can poke * about in there. * - * In Dom0, the host E820 information can leave gaps in the - * ISA range, which would cause us to release those pages. To - * avoid this, we unconditionally reserve them here. + * In a dom0 kernel, this region is identity mapped with the + * hardware ISA area, so it really is out of bounds. */ e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_RESERVED); diff --git a/block/blk-core.c b/block/blk-core.c index 4ce953f..f0834e2 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1194,6 +1194,13 @@ static int __make_request(struct request_queue *q, struct bio *bio) int where = ELEVATOR_INSERT_SORT; int rw_flags; + /* REQ_HARDBARRIER is no more */ + if (WARN_ONCE(bio->bi_rw & REQ_HARDBARRIER, + "block: HARDBARRIER is deprecated, use FLUSH/FUA instead\n")) { + bio_endio(bio, -EOPNOTSUPP); + return 0; + } + /* * low level driver can indicate that it wants pages above a * certain limit bounced to low memory (ie for highmem, or even @@ -1344,7 +1351,7 @@ static void handle_bad_sector(struct bio *bio) bdevname(bio->bi_bdev, b), bio->bi_rw, (unsigned long long)bio->bi_sector + bio_sectors(bio), - (long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9)); + (long long)(bio->bi_bdev->bd_inode->i_size >> 9)); set_bit(BIO_EOF, &bio->bi_flags); } @@ -1397,7 +1404,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors) return 0; /* Test device or partition size, when known. */ - maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; + maxsector = bio->bi_bdev->bd_inode->i_size >> 9; if (maxsector) { sector_t sector = bio->bi_sector; diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 3c7a339..d22c4c5 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -153,6 +153,20 @@ struct io_context *get_io_context(gfp_t gfp_flags, int node) } EXPORT_SYMBOL(get_io_context); +void copy_io_context(struct io_context **pdst, struct io_context **psrc) +{ + struct io_context *src = *psrc; + struct io_context *dst = *pdst; + + if (src) { + BUG_ON(atomic_long_read(&src->refcount) == 0); + atomic_long_inc(&src->refcount); + put_io_context(dst); + *pdst = src; + } +} +EXPORT_SYMBOL(copy_io_context); + static int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", diff --git a/block/blk-map.c b/block/blk-map.c index 5d5dbe4..d4a586d 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -205,8 +205,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, unaligned = 1; break; } - if (!iov[i].iov_len) - return -EINVAL; } if (unaligned || (q->dma_pad_mask & len) || map_data) diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 58c6ee5..119f07b 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -744,13 +744,13 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; return 0; case BLKGETSIZE: - size = i_size_read(bdev->bd_inode); + size = bdev->bd_inode->i_size; if ((size >> 9) > ~0UL) return -EFBIG; return compat_put_ulong(arg, size >> 9); case BLKGETSIZE64_32: - return compat_put_u64(arg, i_size_read(bdev->bd_inode)); + return compat_put_u64(arg, bdev->bd_inode->i_size); case BLKTRACESETUP32: case BLKTRACESTART: /* compatible */ diff --git a/block/elevator.c b/block/elevator.c index 2569512..282e830 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -429,7 +429,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) q->nr_sorted--; boundary = q->end_sector; - stop_flags = REQ_SOFTBARRIER | REQ_STARTED; + stop_flags = REQ_SOFTBARRIER | REQ_HARDBARRIER | REQ_STARTED; list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); @@ -691,7 +691,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) void __elv_add_request(struct request_queue *q, struct request *rq, int where, int plug) { - if (rq->cmd_flags & REQ_SOFTBARRIER) { + if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { /* barriers are scheduling boundary, update end_sector */ if (rq->cmd_type == REQ_TYPE_FS || (rq->cmd_flags & REQ_DISCARD)) { diff --git a/block/ioctl.c b/block/ioctl.c index 3d866d0..d724ceb 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -125,7 +125,7 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, start >>= 9; len >>= 9; - if (start + len > (i_size_read(bdev->bd_inode) >> 9)) + if (start + len > (bdev->bd_inode->i_size >> 9)) return -EINVAL; if (secure) flags |= BLKDEV_DISCARD_SECURE; @@ -242,7 +242,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, * We need to set the startsect first, the driver may * want to override it. */ - memset(&geo, 0, sizeof(geo)); geo.start = get_start_sect(bdev); ret = disk->fops->getgeo(bdev, &geo); if (ret) @@ -308,12 +307,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, ret = blkdev_reread_part(bdev); break; case BLKGETSIZE: - size = i_size_read(bdev->bd_inode); + size = bdev->bd_inode->i_size; if ((size >> 9) > ~0UL) return -EFBIG; return put_ulong(arg, size >> 9); case BLKGETSIZE64: - return put_u64(arg, i_size_read(bdev->bd_inode)); + return put_u64(arg, bdev->bd_inode->i_size); case BLKTRACESTART: case BLKTRACESTOP: case BLKTRACESETUP: diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 4f4230b..a8b5a10 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -321,47 +321,33 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->iovec_count) { const int size = sizeof(struct sg_iovec) * hdr->iovec_count; size_t iov_data_len; - struct sg_iovec *sg_iov; - struct iovec *iov; - int i; + struct sg_iovec *iov; - sg_iov = kmalloc(size, GFP_KERNEL); - if (!sg_iov) { + iov = kmalloc(size, GFP_KERNEL); + if (!iov) { ret = -ENOMEM; goto out; } - if (copy_from_user(sg_iov, hdr->dxferp, size)) { - kfree(sg_iov); + if (copy_from_user(iov, hdr->dxferp, size)) { + kfree(iov); ret = -EFAULT; goto out; } - /* - * Sum up the vecs, making sure they don't overflow - */ - iov = (struct iovec *) sg_iov; - iov_data_len = 0; - for (i = 0; i < hdr->iovec_count; i++) { - if (iov_data_len + iov[i].iov_len < iov_data_len) { - kfree(sg_iov); - ret = -EINVAL; - goto out; - } - iov_data_len += iov[i].iov_len; - } - /* SG_IO howto says that the shorter of the two wins */ + iov_data_len = iov_length((struct iovec *)iov, + hdr->iovec_count); if (hdr->dxfer_len < iov_data_len) { - hdr->iovec_count = iov_shorten(iov, + hdr->iovec_count = iov_shorten((struct iovec *)iov, hdr->iovec_count, hdr->dxfer_len); iov_data_len = hdr->dxfer_len; } - ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count, + ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, iov_data_len, GFP_KERNEL); - kfree(sg_iov); + kfree(iov); } else if (hdr->dxfer_len) ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, GFP_KERNEL); diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index 75586f1..de30782 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c @@ -504,6 +504,7 @@ err: static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt) { + kobject_put(&pcrypt->pinst->kobj); free_cpumask_var(pcrypt->cb_cpumask->mask); kfree(pcrypt->cb_cpumask); diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1..6355b57 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -80,7 +80,7 @@ int __init acpi_debugfs_init(void) if (!acpi_dir) goto err; - cm_dentry = debugfs_create_file("custom_method", S_IWUSR, + cm_dentry = debugfs_create_file("custom_method", S_IWUGO, acpi_dir, NULL, &cm_fops); if (!cm_dentry) goto err; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3f91c01..d050e07 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2552,11 +2552,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) * * If door lock fails, always clear sdev->locked to * avoid this infinite loop. - * - * This may happen before SCSI scan is complete. Make - * sure qc->dev->sdev isn't NULL before dereferencing. */ - if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev) + if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) qc->dev->sdev->locked = 0; qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 6bd9425..eaf1941 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -142,7 +142,7 @@ static int autospeed; /* Chip present which snoops speed changes */ static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ -#ifdef CONFIG_PATA_WINBOND_VLB_MODULE +#ifdef PATA_WINBOND_VLB_MODULE static int winbond = 1; /* Set to probe Winbond controllers, give I/O port if non standard */ #else diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index fa1b95a..74b8298 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -653,6 +653,8 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) ap = host->ports[i]; ocd = ap->dev->platform_data; + + ocd = ap->dev->platform_data; cf_port = ap->private_data; dma_int.u64 = cvmx_read_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine)); diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c index 9a676ee..1a9332e 100644 --- a/drivers/atm/solos-attrlist.c +++ b/drivers/atm/solos-attrlist.c @@ -1,7 +1,6 @@ SOLOS_ATTR_RO(DriverVersion) SOLOS_ATTR_RO(APIVersion) SOLOS_ATTR_RO(FirmwareVersion) -SOLOS_ATTR_RO(Version) // SOLOS_ATTR_RO(DspVersion) // SOLOS_ATTR_RO(CommonHandshake) SOLOS_ATTR_RO(Connected) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 2e08c99..f46138a 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -1161,14 +1161,6 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", major_ver, minor_ver, fpga_ver); - if (fpga_ver < 37 && (fpga_upgrade || firmware_upgrade || - db_fpga_upgrade || db_firmware_upgrade)) { - dev_warn(&dev->dev, - "FPGA too old; cannot upgrade flash. Use JTAG.\n"); - fpga_upgrade = firmware_upgrade = 0; - db_fpga_upgrade = db_firmware_upgrade = 0; - } - if (card->fpga_version >= DMA_SUPPORTED){ card->using_dma = 1; } else { diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 528f631..541e188 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -180,6 +180,9 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) BUG(); bio_endio(bio, -ENXIO); return 0; + } else if (bio->bi_rw & REQ_HARDBARRIER) { + bio_endio(bio, -EOPNOTSUPP); + return 0; } else if (bio->bi_io_vec == NULL) { printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); BUG(); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a67d0a6..2cc4dda 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -113,8 +113,6 @@ static struct board_type products[] = { {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, {0x40910E11, "Smart Array 6i", &SA5_access}, {0x3225103C, "Smart Array P600", &SA5_access}, - {0x3223103C, "Smart Array P800", &SA5_access}, - {0x3234103C, "Smart Array P400", &SA5_access}, {0x3235103C, "Smart Array P400i", &SA5_access}, {0x3211103C, "Smart Array E200i", &SA5_access}, {0x3212103C, "Smart Array E200", &SA5_access}, @@ -3755,7 +3753,7 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) for (i = 0; i < MAX_CONFIG_WAIT; i++) { if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; - usleep_range(10000, 20000); + msleep(10); } } @@ -3939,9 +3937,10 @@ static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id) *board_id = ((subsystem_device_id << 16) & 0xffff0000) | subsystem_vendor_id; - for (i = 0; i < ARRAY_SIZE(products); i++) + for (i = 0; i < ARRAY_SIZE(products); i++) { if (*board_id == products[i].board_id) return i; + } dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n", *board_id); return -ENODEV; @@ -3972,31 +3971,18 @@ static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, return -ENODEV; } -static int __devinit cciss_wait_for_board_state(struct pci_dev *pdev, - void __iomem *vaddr, int wait_for_ready) -#define BOARD_READY 1 -#define BOARD_NOT_READY 0 +static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) { - int i, iterations; + int i; u32 scratchpad; - if (wait_for_ready) - iterations = CCISS_BOARD_READY_ITERATIONS; - else - iterations = CCISS_BOARD_NOT_READY_ITERATIONS; - - for (i = 0; i < iterations; i++) { - scratchpad = readl(vaddr + SA5_SCRATCHPAD_OFFSET); - if (wait_for_ready) { - if (scratchpad == CCISS_FIRMWARE_READY) - return 0; - } else { - if (scratchpad != CCISS_FIRMWARE_READY) - return 0; - } + for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) { + scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == CCISS_FIRMWARE_READY) + return 0; msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); } - dev_warn(&pdev->dev, "board not ready, timed out.\n"); + dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); return -ENODEV; } @@ -4045,11 +4031,6 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) { h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); - - /* Limit commands in memory limited kdump scenario. */ - if (reset_devices && h->max_commands > 32) - h->max_commands = 32; - if (h->max_commands < 16) { dev_warn(&h->pdev->dev, "Controller reports " "max supported commands of %d, an obvious lie. " @@ -4167,7 +4148,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h) err = -ENOMEM; goto err_out_free_res; } - err = cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY); + err = cciss_wait_for_board_ready(h); if (err) goto err_out_free_res; err = cciss_find_cfgtables(h); @@ -4332,6 +4313,36 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u #define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) #define cciss_noop(p) cciss_message(p, 3, 0) +static __devinit int cciss_reset_msi(struct pci_dev *pdev) +{ +/* the #defines are stolen from drivers/pci/msi.h. */ +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + + int pos; + u16 control = 0; + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI\n"); + pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); + } + } + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSIX_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI-X\n"); + pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); + } + } + + return 0; +} + static int cciss_controller_hard_reset(struct pci_dev *pdev, void * __iomem vaddr, bool use_doorbell) { @@ -4386,17 +4397,17 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev, * states or using the doorbell register. */ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) { + u16 saved_config_space[32]; u64 cfg_offset; u32 cfg_base_addr; u64 cfg_base_addr_index; void __iomem *vaddr; unsigned long paddr; u32 misc_fw_support, active_transport; - int rc; + int rc, i; CfgTable_struct __iomem *cfgtable; bool use_doorbell; u32 board_id; - u16 command_register; /* For controllers as old a the p600, this is very nearly * the same thing as @@ -4406,6 +4417,14 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) * pci_set_power_state(pci_dev, PCI_D0); * pci_restore_state(pci_dev); * + * but we can't use these nice canned kernel routines on + * kexec, because they also check the MSI/MSI-X state in PCI + * configuration space and do the wrong thing when it is + * set/cleared. Also, the pci_save/restore_state functions + * violate the ordering requirements for restoring the + * configuration space from the CCISS document (see the + * comment below). So we roll our own .... + * * For controllers newer than the P600, the pci power state * method of resetting doesn't work so we have another way * using the doorbell register. @@ -4424,13 +4443,8 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) return -ENODEV; } - /* Save the PCI command register */ - pci_read_config_word(pdev, 4, &command_register); - /* Turn the board off. This is so that later pci_restore_state() - * won't turn the board on before the rest of config space is ready. - */ - pci_disable_device(pdev); - pci_save_state(pdev); + for (i = 0; i < 32; i++) + pci_read_config_word(pdev, 2*i, &saved_config_space[i]); /* find the first memory BAR, so we can find the cfg table */ rc = cciss_pci_find_memory_BAR(pdev, &paddr); @@ -4465,32 +4479,26 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); if (rc) goto unmap_cfgtable; - pci_restore_state(pdev); - rc = pci_enable_device(pdev); - if (rc) { - dev_warn(&pdev->dev, "failed to enable device.\n"); - goto unmap_cfgtable; + + /* Restore the PCI configuration space. The Open CISS + * Specification says, "Restore the PCI Configuration + * Registers, offsets 00h through 60h. It is important to + * restore the command register, 16-bits at offset 04h, + * last. Do not restore the configuration status register, + * 16-bits at offset 06h." Note that the offset is 2*i. + */ + for (i = 0; i < 32; i++) { + if (i == 2 || i == 3) + continue; + pci_write_config_word(pdev, 2*i, saved_config_space[i]); } - pci_write_config_word(pdev, 4, command_register); + wmb(); + pci_write_config_word(pdev, 4, saved_config_space[2]); /* Some devices (notably the HP Smart Array 5i Controller) need a little pause here */ msleep(CCISS_POST_RESET_PAUSE_MSECS); - /* Wait for board to become not ready, then ready. */ - dev_info(&pdev->dev, "Waiting for board to become ready.\n"); - rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY); - if (rc) /* Don't bail, might be E500, etc. which can't be reset */ - dev_warn(&pdev->dev, - "failed waiting for board to become not ready\n"); - rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_READY); - if (rc) { - dev_warn(&pdev->dev, - "failed waiting for board to become ready\n"); - goto unmap_cfgtable; - } - dev_info(&pdev->dev, "board ready.\n"); - /* Controller should be in simple mode at this point. If it's not, * It means we're on one of those controllers which doesn't support * the doorbell reset method and on which the PCI power management reset @@ -4531,6 +4539,8 @@ static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) return 0; /* just try to do the kdump anyhow. */ if (rc) return -ENODEV; + if (cciss_reset_msi(pdev)) + return -ENODEV; /* Now try to get the controller to respond to a no-op */ for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { @@ -4926,8 +4936,7 @@ static void __exit cciss_cleanup(void) } } kthread_stop(cciss_scan_thread); - if (proc_cciss) - remove_proc_entry("driver/cciss", NULL); + remove_proc_entry("driver/cciss", NULL); bus_unregister(&cciss_bus_type); } diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 4b8933d..ae340ff 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -200,14 +200,10 @@ struct ctlr_info * the above. */ #define CCISS_BOARD_READY_WAIT_SECS (120) -#define CCISS_BOARD_NOT_READY_WAIT_SECS (10) #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) #define CCISS_BOARD_READY_ITERATIONS \ ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ CCISS_BOARD_READY_POLL_INTERVAL_MSECS) -#define CCISS_BOARD_NOT_READY_ITERATIONS \ - ((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \ - CCISS_BOARD_READY_POLL_INTERVAL_MSECS) #define CCISS_POST_RESET_PAUSE_MSECS (3000) #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) #define CCISS_POST_RESET_NOOP_RETRIES (12) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index ba95cba..ac04ef9 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -78,10 +78,11 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, init_completion(&md_io.event); md_io.error = 0; - if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) - rw |= REQ_FUA; + if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags)) + rw |= REQ_HARDBARRIER; rw |= REQ_UNPLUG | REQ_SYNC; + retry: bio = bio_alloc(GFP_NOIO, 1); bio->bi_bdev = bdev->md_bdev; bio->bi_sector = sector; @@ -99,6 +100,17 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, wait_for_completion(&md_io.event); ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; + /* check for unsupported barrier op. + * would rather check on EOPNOTSUPP, but that is not reliable. + * don't try again for ANY return value != 0 */ + if (unlikely((bio->bi_rw & REQ_HARDBARRIER) && !ok)) { + /* Try again with no barrier */ + dev_warn(DEV, "Barriers not supported on meta data device - disabling\n"); + set_bit(MD_NO_BARRIER, &mdev->flags); + rw &= ~REQ_HARDBARRIER; + bio_put(bio); + goto retry; + } out: bio_put(bio); return ok; @@ -272,32 +284,18 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) u32 xor_sum = 0; if (!get_ldev(mdev)) { - dev_err(DEV, - "disk is %s, cannot start al transaction (-%d +%d)\n", - drbd_disk_str(mdev->state.disk), evicted, new_enr); + dev_err(DEV, "get_ldev() failed in w_al_write_transaction\n"); complete(&((struct update_al_work *)w)->event); return 1; } /* do we have to do a bitmap write, first? * TODO reduce maximum latency: * submit both bios, then wait for both, - * instead of doing two synchronous sector writes. - * For now, we must not write the transaction, - * if we cannot write out the bitmap of the evicted extent. */ + * instead of doing two synchronous sector writes. */ if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); - /* The bitmap write may have failed, causing a state change. */ - if (mdev->state.disk < D_INCONSISTENT) { - dev_err(DEV, - "disk is %s, cannot write al transaction (-%d +%d)\n", - drbd_disk_str(mdev->state.disk), evicted, new_enr); - complete(&((struct update_al_work *)w)->event); - put_ldev(mdev); - return 1; - } - - mutex_lock(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ + mutex_lock(&mdev->md_io_mutex); /* protects md_io_page, al_tr_cycle, ... */ buffer = (struct al_transaction *)page_address(mdev->md_io_page); buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); @@ -741,7 +739,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) unsigned int enr; unsigned long add = 0; char ppb[10]; - int i, tmp; + int i; wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); @@ -749,9 +747,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) enr = lc_element_by_index(mdev->act_log, i)->lc_number; if (enr == LC_FREE) continue; - tmp = drbd_bm_ALe_set_all(mdev, enr); - dynamic_dev_dbg(DEV, "AL: set %d bits in extent %u\n", tmp, enr); - add += tmp; + add += drbd_bm_ALe_set_all(mdev, enr); } lc_unlock(mdev->act_log); diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 1ea1a34..9bdcf43 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -114,11 +114,11 @@ struct drbd_conf; #define D_ASSERT(exp) if (!(exp)) \ dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) -#define ERR_IF(exp) if (({ \ - int _b = (exp) != 0; \ - if (_b) dev_err(DEV, "ASSERT FAILED: %s: (%s) in %s:%d\n", \ - __func__, #exp, __FILE__, __LINE__); \ - _b; \ +#define ERR_IF(exp) if (({ \ + int _b = (exp) != 0; \ + if (_b) dev_err(DEV, "%s: (%s) in %s:%d\n", \ + __func__, #exp, __FILE__, __LINE__); \ + _b; \ })) /* Defines to control fault insertion */ @@ -749,12 +749,17 @@ struct drbd_epoch { /* drbd_epoch flag bits */ enum { + DE_BARRIER_IN_NEXT_EPOCH_ISSUED, + DE_BARRIER_IN_NEXT_EPOCH_DONE, + DE_CONTAINS_A_BARRIER, DE_HAVE_BARRIER_NUMBER, + DE_IS_FINISHING, }; enum epoch_event { EV_PUT, EV_GOT_BARRIER_NR, + EV_BARRIER_DONE, EV_BECAME_LAST, EV_CLEANUP = 32, /* used as flag */ }; @@ -796,6 +801,11 @@ enum { __EE_CALL_AL_COMPLETE_IO, __EE_MAY_SET_IN_SYNC, + /* This epoch entry closes an epoch using a barrier. + * On sucessful completion, the epoch is released, + * and the P_BARRIER_ACK send. */ + __EE_IS_BARRIER, + /* In case a barrier failed, * we need to resubmit without the barrier flag. */ __EE_RESUBMITTED, @@ -810,6 +820,7 @@ enum { }; #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) +#define EE_IS_BARRIER (1<<__EE_IS_BARRIER) #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) @@ -832,15 +843,16 @@ enum { * Gets cleared when the state.conn * goes into C_CONNECTED state. */ WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ + NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ CONSIDER_RESYNC, - MD_NO_FUA, /* Users wants us to not use FUA/FLUSH on meta data dev */ + MD_NO_BARRIER, /* meta data device does not support barriers, + so don't even try */ SUSPEND_IO, /* suspend application io */ BITMAP_IO, /* suspend application io; once no more io in flight, start bitmap io */ BITMAP_IO_QUEUED, /* Started bitmap IO */ - GO_DISKLESS, /* Disk is being detached, on io-error or admin request. */ - WAS_IO_ERROR, /* Local disk failed returned IO error */ + GO_DISKLESS, /* Disk failed, local_cnt reached zero, we are going diskless */ RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ NET_CONGESTED, /* The data socket is congested */ @@ -935,6 +947,7 @@ enum write_ordering_e { WO_none, WO_drain_io, WO_bdev_flush, + WO_bio_barrier }; struct fifo_buffer { @@ -1268,7 +1281,6 @@ extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); extern void drbd_go_diskless(struct drbd_conf *mdev); -extern void drbd_ldev_destroy(struct drbd_conf *mdev); /* Meta data layout @@ -1786,17 +1798,17 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, case EP_PASS_ON: if (!forcedetach) { if (__ratelimit(&drbd_ratelimit_state)) - dev_err(DEV, "Local IO failed in %s.\n", where); + dev_err(DEV, "Local IO failed in %s." + "Passing error on...\n", where); break; } /* NOTE fall through to detach case if forcedetach set */ case EP_DETACH: case EP_CALL_HELPER: - set_bit(WAS_IO_ERROR, &mdev->flags); if (mdev->state.disk > D_FAILED) { _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL); - dev_err(DEV, - "Local IO failed in %s. Detaching...\n", where); + dev_err(DEV, "Local IO failed in %s." + "Detaching...\n", where); } break; } @@ -1862,7 +1874,7 @@ static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) static inline sector_t drbd_get_capacity(struct block_device *bdev) { /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ - return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0; + return bdev ? bdev->bd_inode->i_size >> 9 : 0; } /** @@ -2115,11 +2127,7 @@ static inline void put_ldev(struct drbd_conf *mdev) __release(local); D_ASSERT(i >= 0); if (i == 0) { - if (mdev->state.disk == D_DISKLESS) - /* even internal references gone, safe to destroy */ - drbd_ldev_destroy(mdev); if (mdev->state.disk == D_FAILED) - /* all application IO references gone. */ drbd_go_diskless(mdev); wake_up(&mdev->misc_wait); } @@ -2130,10 +2138,6 @@ static inline int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_stat { int io_allowed; - /* never get a reference while D_DISKLESS */ - if (mdev->state.disk == D_DISKLESS) - return 0; - atomic_inc(&mdev->local_cnt); io_allowed = (mdev->state.disk >= mins); if (!io_allowed) @@ -2402,12 +2406,12 @@ static inline void drbd_md_flush(struct drbd_conf *mdev) { int r; - if (test_bit(MD_NO_FUA, &mdev->flags)) + if (test_bit(MD_NO_BARRIER, &mdev->flags)) return; r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL); if (r) { - set_bit(MD_NO_FUA, &mdev->flags); + set_bit(MD_NO_BARRIER, &mdev->flags); dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r); } } diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 6be5401..25c7a73 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -835,15 +835,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) ns.conn = os.conn; - /* we cannot fail (again) if we already detached */ - if (ns.disk == D_FAILED && os.disk == D_DISKLESS) - ns.disk = D_DISKLESS; - - /* if we are only D_ATTACHING yet, - * we can (and should) go directly to D_DISKLESS. */ - if (ns.disk == D_FAILED && os.disk == D_ATTACHING) - ns.disk = D_DISKLESS; - /* After C_DISCONNECTING only C_STANDALONE may follow */ if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) ns.conn = os.conn; @@ -1065,15 +1056,7 @@ int __drbd_set_state(struct drbd_conf *mdev, !test_and_set_bit(CONFIG_PENDING, &mdev->flags)) set_bit(DEVICE_DYING, &mdev->flags); - /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference - * on the ldev here, to be sure the transition -> D_DISKLESS resp. - * drbd_ldev_destroy() won't happen before our corresponding - * after_state_ch works run, where we put_ldev again. */ - if ((os.disk != D_FAILED && ns.disk == D_FAILED) || - (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) - atomic_inc(&mdev->local_cnt); - - mdev->state = ns; + mdev->state.i = ns.i; wake_up(&mdev->misc_wait); wake_up(&mdev->state_wait); @@ -1285,6 +1268,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (test_bit(NEW_CUR_UUID, &mdev->flags)) { drbd_uuid_new_current(mdev); clear_bit(NEW_CUR_UUID, &mdev->flags); + drbd_md_sync(mdev); } spin_lock_irq(&mdev->req_lock); _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); @@ -1381,64 +1365,63 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); - /* first half of local IO error, failure to attach, - * or administrative detach */ - if (os.disk != D_FAILED && ns.disk == D_FAILED) { - enum drbd_io_error_p eh; - int was_io_error; - /* corresponding get_ldev was in __drbd_set_state, to serialize - * our cleanup here with the transition to D_DISKLESS, - * so it is safe to dreference ldev here. */ - eh = mdev->ldev->dc.on_io_error; - was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags); - - /* current state still has to be D_FAILED, - * there is only one way out: to D_DISKLESS, - * and that may only happen after our put_ldev below. */ - if (mdev->state.disk != D_FAILED) - dev_err(DEV, - "ASSERT FAILED: disk is %s during detach\n", - drbd_disk_str(mdev->state.disk)); + /* first half of local IO error */ + if (os.disk > D_FAILED && ns.disk == D_FAILED) { + enum drbd_io_error_p eh = EP_PASS_ON; if (drbd_send_state(mdev)) - dev_warn(DEV, "Notified peer that I am detaching my disk\n"); + dev_warn(DEV, "Notified peer that my disk is broken.\n"); else - dev_err(DEV, "Sending state for detaching disk failed\n"); + dev_err(DEV, "Sending state for drbd_io_error() failed\n"); drbd_rs_cancel_all(mdev); - /* In case we want to get something to stable storage still, - * this may be the last chance. - * Following put_ldev may transition to D_DISKLESS. */ - drbd_md_sync(mdev); - put_ldev(mdev); - - if (was_io_error && eh == EP_CALL_HELPER) + if (get_ldev_if_state(mdev, D_FAILED)) { + eh = mdev->ldev->dc.on_io_error; + put_ldev(mdev); + } + if (eh == EP_CALL_HELPER) drbd_khelper(mdev, "local-io-error"); } - /* second half of local IO error, failure to attach, - * or administrative detach, - * after local_cnt references have reached zero again */ - if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) { - /* We must still be diskless, - * re-attach has to be serialized with this! */ - if (mdev->state.disk != D_DISKLESS) - dev_err(DEV, - "ASSERT FAILED: disk is %s while going diskless\n", - drbd_disk_str(mdev->state.disk)); - mdev->rs_total = 0; - mdev->rs_failed = 0; - atomic_set(&mdev->rs_pending_cnt, 0); + /* second half of local IO error handling, + * after local_cnt references have reached zero: */ + if (os.disk == D_FAILED && ns.disk == D_DISKLESS) { + mdev->rs_total = 0; + mdev->rs_failed = 0; + atomic_set(&mdev->rs_pending_cnt, 0); + } + + if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) { + /* We must still be diskless, + * re-attach has to be serialized with this! */ + if (mdev->state.disk != D_DISKLESS) + dev_err(DEV, + "ASSERT FAILED: disk is %s while going diskless\n", + drbd_disk_str(mdev->state.disk)); + /* we cannot assert local_cnt == 0 here, as get_ldev_if_state + * will inc/dec it frequently. Since we became D_DISKLESS, no + * one has touched the protected members anymore, though, so we + * are safe to free them here. */ if (drbd_send_state(mdev)) - dev_warn(DEV, "Notified peer that I'm now diskless.\n"); + dev_warn(DEV, "Notified peer that I detached my disk.\n"); else - dev_err(DEV, "Sending state for being diskless failed\n"); - /* corresponding get_ldev in __drbd_set_state - * this may finaly trigger drbd_ldev_destroy. */ - put_ldev(mdev); + dev_err(DEV, "Sending state for detach failed\n"); + + lc_destroy(mdev->resync); + mdev->resync = NULL; + lc_destroy(mdev->act_log); + mdev->act_log = NULL; + __no_warn(local, + drbd_free_bc(mdev->ldev); + mdev->ldev = NULL;); + + if (mdev->md_io_tmpp) { + __free_page(mdev->md_io_tmpp); + mdev->md_io_tmpp = NULL; + } } /* Disks got bigger while they were detached */ @@ -2789,6 +2772,11 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) drbd_set_defaults(mdev); + /* for now, we do NOT yet support it, + * even though we start some framework + * to eventually support barriers */ + set_bit(NO_BARRIER_SUPP, &mdev->flags); + atomic_set(&mdev->ap_bio_cnt, 0); atomic_set(&mdev->ap_pending_cnt, 0); atomic_set(&mdev->rs_pending_cnt, 0); @@ -2854,7 +2842,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) drbd_thread_init(mdev, &mdev->asender, drbd_asender); mdev->agreed_pro_version = PRO_VERSION_MAX; - mdev->write_ordering = WO_bdev_flush; + mdev->write_ordering = WO_bio_barrier; mdev->resync_wenr = LC_FREE; } @@ -2911,6 +2899,7 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev) D_ASSERT(list_empty(&mdev->resync_work.list)); D_ASSERT(list_empty(&mdev->unplug_work.list)); D_ASSERT(list_empty(&mdev->go_diskless.list)); + } @@ -3671,8 +3660,6 @@ void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) get_random_bytes(&val, sizeof(u64)); _drbd_uuid_set(mdev, UI_CURRENT, val); - /* get it to stable storage _now_ */ - drbd_md_sync(mdev); } void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) @@ -3769,31 +3756,19 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) return 1; } -void drbd_ldev_destroy(struct drbd_conf *mdev) -{ - lc_destroy(mdev->resync); - mdev->resync = NULL; - lc_destroy(mdev->act_log); - mdev->act_log = NULL; - __no_warn(local, - drbd_free_bc(mdev->ldev); - mdev->ldev = NULL;); - - if (mdev->md_io_tmpp) { - __free_page(mdev->md_io_tmpp); - mdev->md_io_tmpp = NULL; - } - clear_bit(GO_DISKLESS, &mdev->flags); -} - static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) { D_ASSERT(mdev->state.disk == D_FAILED); /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will * inc/dec it frequently. Once we are D_DISKLESS, no one will touch - * the protected members anymore, though, so once put_ldev reaches zero - * again, it will be safe to free them. */ + * the protected members anymore, though, so in the after_state_ch work + * it will be safe to free them. */ drbd_force_state(mdev, NS(disk, D_DISKLESS)); + /* We need to wait for return of references checked out while we still + * have been D_FAILED, though (drbd_md_sync, bitmap io). */ + wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); + + clear_bit(GO_DISKLESS, &mdev->flags); return 1; } @@ -3802,6 +3777,9 @@ void drbd_go_diskless(struct drbd_conf *mdev) D_ASSERT(mdev->state.disk == D_FAILED); if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) drbd_queue_work(&mdev->data.work, &mdev->go_diskless); + /* don't drbd_queue_work_front, + * we need to serialize with the after_state_ch work + * of the -> D_FAILED transition. */ } /** diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 29e5c70..87925e9 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -870,11 +870,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp retcode = ERR_DISK_CONFIGURED; goto fail; } - /* It may just now have detached because of IO error. Make sure - * drbd_ldev_destroy is done already, we may end up here very fast, - * e.g. if someone calls attach from the on-io-error handler, - * to realize a "hot spare" feature (not that I'd recommend that) */ - wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); /* allocation not in the IO path, cqueue thread context */ nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); @@ -1103,9 +1098,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp /* Reset the "barriers don't work" bits here, then force meta data to * be written, to ensure we determine if barriers are supported. */ if (nbc->dc.no_md_flush) - set_bit(MD_NO_FUA, &mdev->flags); + set_bit(MD_NO_BARRIER, &mdev->flags); else - clear_bit(MD_NO_FUA, &mdev->flags); + clear_bit(MD_NO_BARRIER, &mdev->flags); /* Point of no return reached. * Devices and memory are no longer released by error cleanup below. @@ -1117,8 +1112,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp nbc = NULL; resync_lru = NULL; - mdev->write_ordering = WO_bdev_flush; - drbd_bump_write_ordering(mdev, WO_bdev_flush); + mdev->write_ordering = WO_bio_barrier; + drbd_bump_write_ordering(mdev, WO_bio_barrier); if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY)) set_bit(CRASHED_PRIMARY, &mdev->flags); @@ -1267,7 +1262,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp force_diskless_dec: put_ldev(mdev); force_diskless: - drbd_force_state(mdev, NS(disk, D_FAILED)); + drbd_force_state(mdev, NS(disk, D_DISKLESS)); drbd_md_sync(mdev); release_bdev2_fail: if (nbc) @@ -1290,19 +1285,10 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp return 0; } -/* Detaching the disk is a process in multiple stages. First we need to lock - * out application IO, in-flight IO, IO stuck in drbd_al_begin_io. - * Then we transition to D_DISKLESS, and wait for put_ldev() to return all - * internal references as well. - * Only then we have finally detached. */ static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply) { - drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS)); - if (mdev->state.disk == D_DISKLESS) - wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); - drbd_resume_io(mdev); return 0; } @@ -1967,6 +1953,7 @@ static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp if (test_bit(NEW_CUR_UUID, &mdev->flags)) { drbd_uuid_new_current(mdev); clear_bit(NEW_CUR_UUID, &mdev->flags); + drbd_md_sync(mdev); } drbd_suspend_io(mdev); reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0)); diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index 7e6ac30..ad325c5 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -158,6 +158,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) [WO_none] = 'n', [WO_drain_io] = 'd', [WO_bdev_flush] = 'f', + [WO_bio_barrier] = 'b', }; seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d299fe9..efd6169 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -49,6 +49,11 @@ #include "drbd_vli.h" +struct flush_work { + struct drbd_work w; + struct drbd_epoch *epoch; +}; + enum finish_epoch { FE_STILL_LIVE, FE_DESTROYED, @@ -61,6 +66,16 @@ static int drbd_do_auth(struct drbd_conf *mdev); static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event); static int e_end_block(struct drbd_conf *, struct drbd_work *, int); +static struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) +{ + struct drbd_epoch *prev; + spin_lock(&mdev->epoch_lock); + prev = list_entry(epoch->list.prev, struct drbd_epoch, list); + if (prev == epoch || prev == mdev->current_epoch) + prev = NULL; + spin_unlock(&mdev->epoch_lock); + return prev; +} #define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) @@ -966,7 +981,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi return TRUE; } -static void drbd_flush(struct drbd_conf *mdev) +static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) { int rv; @@ -982,6 +997,24 @@ static void drbd_flush(struct drbd_conf *mdev) } put_ldev(mdev); } + + return drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE); +} + +static int w_flush(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct flush_work *fw = (struct flush_work *)w; + struct drbd_epoch *epoch = fw->epoch; + + kfree(w); + + if (!test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags)) + drbd_flush_after_epoch(mdev, epoch); + + drbd_may_finish_epoch(mdev, epoch, EV_PUT | + (mdev->state.conn < C_CONNECTED ? EV_CLEANUP : 0)); + + return 1; } /** @@ -994,13 +1027,15 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch, enum epoch_event ev) { - int epoch_size; + int finish, epoch_size; struct drbd_epoch *next_epoch; + int schedule_flush = 0; enum finish_epoch rv = FE_STILL_LIVE; spin_lock(&mdev->epoch_lock); do { next_epoch = NULL; + finish = 0; epoch_size = atomic_read(&epoch->epoch_size); @@ -1010,6 +1045,16 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, break; case EV_GOT_BARRIER_NR: set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags); + + /* Special case: If we just switched from WO_bio_barrier to + WO_bdev_flush we should not finish the current epoch */ + if (test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) && epoch_size == 1 && + mdev->write_ordering != WO_bio_barrier && + epoch == mdev->current_epoch) + clear_bit(DE_CONTAINS_A_BARRIER, &epoch->flags); + break; + case EV_BARRIER_DONE: + set_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags); break; case EV_BECAME_LAST: /* nothing to do*/ @@ -1018,7 +1063,23 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, if (epoch_size != 0 && atomic_read(&epoch->active) == 0 && - test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags)) { + test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) && + epoch->list.prev == &mdev->current_epoch->list && + !test_bit(DE_IS_FINISHING, &epoch->flags)) { + /* Nearly all conditions are met to finish that epoch... */ + if (test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) || + mdev->write_ordering == WO_none || + (epoch_size == 1 && test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) || + ev & EV_CLEANUP) { + finish = 1; + set_bit(DE_IS_FINISHING, &epoch->flags); + } else if (!test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) && + mdev->write_ordering == WO_bio_barrier) { + atomic_inc(&epoch->active); + schedule_flush = 1; + } + } + if (finish) { if (!(ev & EV_CLEANUP)) { spin_unlock(&mdev->epoch_lock); drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size); @@ -1041,7 +1102,6 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, /* atomic_set(&epoch->active, 0); is already zero */ if (rv == FE_STILL_LIVE) rv = FE_RECYCLED; - wake_up(&mdev->ee_wait); } } @@ -1053,6 +1113,22 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, spin_unlock(&mdev->epoch_lock); + if (schedule_flush) { + struct flush_work *fw; + fw = kmalloc(sizeof(*fw), GFP_ATOMIC); + if (fw) { + fw->w.cb = w_flush; + fw->epoch = epoch; + drbd_queue_work(&mdev->data.work, &fw->w); + } else { + dev_warn(DEV, "Could not kmalloc a flush_work obj\n"); + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + /* That is not a recursion, only one level */ + drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE); + drbd_may_finish_epoch(mdev, epoch, EV_PUT); + } + } + return rv; } @@ -1068,16 +1144,19 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) [WO_none] = "none", [WO_drain_io] = "drain", [WO_bdev_flush] = "flush", + [WO_bio_barrier] = "barrier", }; pwo = mdev->write_ordering; wo = min(pwo, wo); + if (wo == WO_bio_barrier && mdev->ldev->dc.no_disk_barrier) + wo = WO_bdev_flush; if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush) wo = WO_drain_io; if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain) wo = WO_none; mdev->write_ordering = wo; - if (pwo != mdev->write_ordering || wo == WO_bdev_flush) + if (pwo != mdev->write_ordering || wo == WO_bio_barrier) dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); } @@ -1113,7 +1192,7 @@ next_bio: bio->bi_sector = sector; bio->bi_bdev = mdev->ldev->backing_bdev; /* we special case some flags in the multi-bio case, see below - * (REQ_UNPLUG) */ + * (REQ_UNPLUG, REQ_HARDBARRIER) */ bio->bi_rw = rw; bio->bi_private = e; bio->bi_end_io = drbd_endio_sec; @@ -1147,6 +1226,11 @@ next_bio: bio->bi_rw &= ~REQ_UNPLUG; drbd_generic_make_request(mdev, fault_type, bio); + + /* strip off REQ_HARDBARRIER, + * unless it is the first or last bio */ + if (bios && bios->bi_next) + bios->bi_rw &= ~REQ_HARDBARRIER; } while (bios); maybe_kick_lo(mdev); return 0; @@ -1160,9 +1244,45 @@ fail: return -ENOMEM; } +/** + * w_e_reissue() - Worker callback; Resubmit a bio, without REQ_HARDBARRIER set + * @mdev: DRBD device. + * @w: work object. + * @cancel: The connection will be closed anyways (unused in this callback) + */ +int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local) +{ + struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; + /* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place, + (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) + so that we can finish that epoch in drbd_may_finish_epoch(). + That is necessary if we already have a long chain of Epochs, before + we realize that REQ_HARDBARRIER is actually not supported */ + + /* As long as the -ENOTSUPP on the barrier is reported immediately + that will never trigger. If it is reported late, we will just + print that warning and continue correctly for all future requests + with WO_bdev_flush */ + if (previous_epoch(mdev, e->epoch)) + dev_warn(DEV, "Write ordering was not enforced (one time event)\n"); + + /* we still have a local reference, + * get_ldev was done in receive_Data. */ + + e->w.cb = e_end_block; + if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_DT_WR) != 0) { + /* drbd_submit_ee fails for one reason only: + * if was not able to allocate sufficient bios. + * requeue, try again later. */ + e->w.cb = w_e_reissue; + drbd_queue_work(&mdev->data.work, &e->w); + } + return 1; +} + static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) { - int rv; + int rv, issue_flush; struct p_barrier *p = &mdev->data.rbuf.barrier; struct drbd_epoch *epoch; @@ -1180,40 +1300,44 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign * Therefore we must send the barrier_ack after the barrier request was * completed. */ switch (mdev->write_ordering) { + case WO_bio_barrier: case WO_none: if (rv == FE_RECYCLED) return TRUE; - - /* receiver context, in the writeout path of the other node. - * avoid potential distributed deadlock */ - epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); - if (epoch) - break; - else - dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); - /* Fall through */ + break; case WO_bdev_flush: case WO_drain_io: - drbd_wait_ee_list_empty(mdev, &mdev->active_ee); - drbd_flush(mdev); - - if (atomic_read(&mdev->current_epoch->epoch_size)) { - epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); - if (epoch) - break; + if (rv == FE_STILL_LIVE) { + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); + drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); } + if (rv == FE_RECYCLED) + return TRUE; + + /* The asender will send all the ACKs and barrier ACKs out, since + all EEs moved from the active_ee to the done_ee. We need to + provide a new epoch object for the EEs that come in soon */ + break; + } - epoch = mdev->current_epoch; - wait_event(mdev->ee_wait, atomic_read(&epoch->epoch_size) == 0); + /* receiver context, in the writeout path of the other node. + * avoid potential distributed deadlock */ + epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); + if (!epoch) { + dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); + issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); + drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + if (issue_flush) { + rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); + if (rv == FE_RECYCLED) + return TRUE; + } - D_ASSERT(atomic_read(&epoch->active) == 0); - D_ASSERT(epoch->flags == 0); + drbd_wait_ee_list_empty(mdev, &mdev->done_ee); return TRUE; - default: - dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering); - return FALSE; } epoch->flags = 0; @@ -1528,8 +1652,15 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel) { struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; sector_t sector = e->sector; + struct drbd_epoch *epoch; int ok = 1, pcmd; + if (e->flags & EE_IS_BARRIER) { + epoch = previous_epoch(mdev, e->epoch); + if (epoch) + drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE + (cancel ? EV_CLEANUP : 0)); + } + if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { if (likely((e->flags & EE_WAS_ERROR) == 0)) { pcmd = (mdev->state.conn >= C_SYNC_SOURCE && @@ -1686,6 +1817,27 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned e->epoch = mdev->current_epoch; atomic_inc(&e->epoch->epoch_size); atomic_inc(&e->epoch->active); + + if (mdev->write_ordering == WO_bio_barrier && atomic_read(&e->epoch->epoch_size) == 1) { + struct drbd_epoch *epoch; + /* Issue a barrier if we start a new epoch, and the previous epoch + was not a epoch containing a single request which already was + a Barrier. */ + epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list); + if (epoch == e->epoch) { + set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); + rw |= REQ_HARDBARRIER; + e->flags |= EE_IS_BARRIER; + } else { + if (atomic_read(&epoch->epoch_size) > 1 || + !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) { + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); + rw |= REQ_HARDBARRIER; + e->flags |= EE_IS_BARRIER; + } + } + } spin_unlock(&mdev->epoch_lock); dp_flags = be32_to_cpu(p->dp_flags); @@ -1843,11 +1995,10 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned break; } - if (mdev->state.pdsk < D_INCONSISTENT) { + if (mdev->state.pdsk == D_DISKLESS) { /* In case we have the only disk of the cluster, */ drbd_set_out_of_sync(mdev, e->sector, e->size); e->flags |= EE_CALL_AL_COMPLETE_IO; - e->flags &= ~EE_MAY_SET_IN_SYNC; drbd_al_begin_io(mdev, e->sector); } @@ -3211,7 +3362,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned if (ns.conn == C_MASK) { ns.conn = C_CONNECTED; if (mdev->state.disk == D_NEGOTIATING) { - drbd_force_state(mdev, NS(disk, D_FAILED)); + drbd_force_state(mdev, NS(disk, D_DISKLESS)); } else if (peer_state.disk == D_NEGOTIATING) { dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); peer_state.disk = D_DISKLESS; diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 11a75d3..9e91a25 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -258,7 +258,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) if (!hlist_unhashed(&req->colision)) hlist_del(&req->colision); else - D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); + D_ASSERT((s & RQ_NET_MASK) == 0); /* for writes we need to do some extra housekeeping */ if (rw == WRITE) @@ -813,8 +813,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) mdev->state.conn >= C_CONNECTED)); if (!(local || remote) && !is_susp(mdev->state)) { - if (__ratelimit(&drbd_ratelimit_state)) - dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); + dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); goto fail_free_complete; } @@ -943,21 +942,12 @@ allocate_barrier: if (local) { req->private_bio->bi_bdev = mdev->ldev->backing_bdev; - /* State may have changed since we grabbed our reference on the - * mdev->ldev member. Double check, and short-circuit to endio. - * In case the last activity log transaction failed to get on - * stable storage, and this is a WRITE, we may not even submit - * this bio. */ - if (get_ldev(mdev)) { - if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR - : rw == READ ? DRBD_FAULT_DT_RD - : DRBD_FAULT_DT_RA)) - bio_endio(req->private_bio, -EIO); - else - generic_make_request(req->private_bio); - put_ldev(mdev); - } else + if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR + : rw == READ ? DRBD_FAULT_DT_RD + : DRBD_FAULT_DT_RA)) bio_endio(req->private_bio, -EIO); + else + generic_make_request(req->private_bio); } /* we need to plug ALWAYS since we possibly need to kick lo_dev. @@ -1032,6 +1022,20 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio) return 0; } + /* Reject barrier requests if we know the underlying device does + * not support them. + * XXX: Need to get this info from peer as well some how so we + * XXX: reject if EITHER side/data/metadata area does not support them. + * + * because of those XXX, this is not yet enabled, + * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. + */ + if (unlikely(bio->bi_rw & REQ_HARDBARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags)) { + /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */ + bio_endio(bio, -EOPNOTSUPP); + return 0; + } + /* * what we "blindly" assume: */ diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b0551ba..108d580 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -102,6 +102,12 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local) put_ldev(mdev); } +static int is_failed_barrier(int ee_flags) +{ + return (ee_flags & (EE_IS_BARRIER|EE_WAS_ERROR|EE_RESUBMITTED)) + == (EE_IS_BARRIER|EE_WAS_ERROR); +} + /* writes on behalf of the partner, or resync writes, * "submitted" by the receiver, final stage. */ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local) @@ -113,6 +119,21 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo int is_syncer_req; int do_al_complete_io; + /* if this is a failed barrier request, disable use of barriers, + * and schedule for resubmission */ + if (is_failed_barrier(e->flags)) { + drbd_bump_write_ordering(mdev, WO_bdev_flush); + spin_lock_irqsave(&mdev->req_lock, flags); + list_del(&e->w.list); + e->flags = (e->flags & ~EE_WAS_ERROR) | EE_RESUBMITTED; + e->w.cb = w_e_reissue; + /* put_ldev actually happens below, once we come here again. */ + __release(local); + spin_unlock_irqrestore(&mdev->req_lock, flags); + drbd_queue_work(&mdev->data.work, &e->w); + return; + } + D_ASSERT(e->block_id != ID_VACANT); /* after we moved e to done_ee, @@ -904,7 +925,7 @@ out: drbd_md_sync(mdev); if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { - dev_info(DEV, "Writing the whole bitmap\n"); + dev_warn(DEV, "Writing the whole bitmap, due to failed kmalloc\n"); drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 7ea0bea..1e5284e 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -481,6 +481,12 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) if (bio_rw(bio) == WRITE) { struct file *file = lo->lo_backing_file; + /* REQ_HARDBARRIER is deprecated */ + if (bio->bi_rw & REQ_HARDBARRIER) { + ret = -EOPNOTSUPP; + goto out; + } + if (bio->bi_rw & REQ_FLUSH) { ret = vfs_fsync(file, 0); if (unlikely(ret && ret != -EINVAL)) { diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 255035c..06e2812 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -289,6 +289,8 @@ static int blkif_queue_request(struct request *req) ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; + if (req->cmd_flags & REQ_HARDBARRIER) + ring_req->operation = BLKIF_OP_WRITE_BARRIER; ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ab3894f..d120a5c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -68,9 +68,6 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookPro6,2 */ { USB_DEVICE(0x05ac, 0x8218) }, - /* Apple MacBookAir3,1, MacBookAir3,2 */ - { USB_DEVICE(0x05ac, 0x821b) }, - /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, @@ -1032,8 +1029,6 @@ static int btusb_probe(struct usb_interface *intf, usb_set_intfdata(intf, data); - usb_enable_autosuspend(interface_to_usbdev(intf)); - return 0; } diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9272c38..6b6760e 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1210,14 +1210,14 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry, unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; u32 pte_flags; - if (type_mask == AGP_USER_MEMORY) + if (type_mask == AGP_USER_UNCACHED_MEMORY) pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { - pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; + pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; if (gfdt) pte_flags |= GEN6_PTE_GFDT; } else { /* set 'normal'/'cached' to LLC by default */ - pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; + pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; if (gfdt) pte_flags |= GEN6_PTE_GFDT; } diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index c0bd6f4..b0a7046 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -1299,6 +1299,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, { struct async_struct * info = tty->driver_data; struct async_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct icount; void __user *argp = (void __user *)arg; unsigned long flags; diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index d72433f..3bc0eef 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -120,7 +120,7 @@ static int i8k_smm(struct smm_regs *regs) int eax = regs->eax; #if defined(CONFIG_X86_64) - asm volatile("pushq %%rax\n\t" + asm("pushq %%rax\n\t" "movl 0(%%rax),%%edx\n\t" "pushq %%rdx\n\t" "movl 4(%%rax),%%ebx\n\t" @@ -146,7 +146,7 @@ static int i8k_smm(struct smm_regs *regs) : "a"(regs) : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); #else - asm volatile("pushl %%eax\n\t" + asm("pushl %%eax\n\t" "movl 0(%%eax),%%edx\n\t" "push %%edx\n\t" "movl 4(%%eax),%%ebx\n\t" @@ -167,8 +167,7 @@ static int i8k_smm(struct smm_regs *regs) "movl %%edx,0(%%eax)\n\t" "lahf\n\t" "shrl $8,%%eax\n\t" - "andl $1,%%eax\n" - :"=a"(rc) + "andl $1,%%eax\n":"=a"(rc) : "a"(regs) : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); #endif diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 294d03e..dd3f9b1 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -1828,6 +1828,7 @@ static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct port *port = tty->driver_data; + void __user *argp = (void __user *)arg; int rval = -ENOIOCTLCMD; DBG1("******** IOCTL, cmd: %d", cmd); diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 777181a..d962f25 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -979,9 +979,8 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, if (dev->flags0 & 1) { set_bit(IS_CMM_ABSENT, &dev->flags); rc = -ENODEV; - } else { - rc = -EIO; } + rc = -EIO; goto release_io; } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index eaa4199..bfc10f8 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2796,7 +2796,6 @@ static const struct tty_operations mgslpc_ops = { .hangup = mgslpc_hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .get_icount = mgslpc_get_icount, .proc_fops = &mgslpc_proc_fops, }; diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 7614126..88ee015 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1832,7 +1832,7 @@ static int __devinit get_irq_props(struct mdesc_handle *mdesc, u64 node, return -ENODEV; ino = mdesc_get_property(mdesc, node, "ino", &ino_len); - if (!ino) + if (!intr) return -ENODEV; if (intr_len != ino_len) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 8a515ba..2e992bc 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -286,7 +286,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, if (initial) asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) - : "d" (control_word), "b" (key), "c" (initial)); + : "d" (control_word), "b" (key), "c" (count)); asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f7af91c..dcbeb98 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -276,7 +276,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *tmp; int crtc_mask = 1; - WARN(!crtc, "checking null crtc?\n"); + WARN(!crtc, "checking null crtc?"); dev = crtc->dev; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a245d17..c1a2621 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -240,7 +240,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, .addr = DDC_ADDR, .flags = I2C_M_RD, .len = len, - .buf = buf, + .buf = buf + start, } }; @@ -253,7 +253,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, static u8 * drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { - int i, j = 0, valid_extensions = 0; + int i, j = 0; u8 *block, *new; if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) @@ -280,28 +280,14 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) for (j = 1; j <= block[0x7e]; j++) { for (i = 0; i < 4; i++) { - if (drm_do_probe_ddc_edid(adapter, - block + (valid_extensions + 1) * EDID_LENGTH, - j, EDID_LENGTH)) + if (drm_do_probe_ddc_edid(adapter, block, j, + EDID_LENGTH)) goto out; - if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { - valid_extensions++; + if (drm_edid_block_valid(block + j * EDID_LENGTH)) break; - } } if (i == 4) - dev_warn(connector->dev->dev, - "%s: Ignoring invalid EDID block %d.\n", - drm_get_connector_name(connector), j); - } - - if (valid_extensions != block[0x7e]) { - block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; - block[0x7e] = valid_extensions; - new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto out; - block = new; + goto carp; } return block; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 80745f8..3467dd4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -44,7 +44,7 @@ unsigned int i915_fbpercrtc = 0; module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; -module_param_named(powersave, i915_powersave, int, 0600); +module_param_named(powersave, i915_powersave, int, 0400); unsigned int i915_lvds_downclock = 0; module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 90414ae..2c2c19b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1321,7 +1321,6 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) -#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ef188e3..8eb8453 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2172,7 +2172,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) static int i915_ring_idle(struct drm_device *dev, struct intel_ring_buffer *ring) { - if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) + if (list_empty(&ring->gpu_write_list)) return 0; i915_gem_flush_ring(dev, NULL, ring, @@ -2190,7 +2190,9 @@ i915_gpu_idle(struct drm_device *dev) int ret; lists_empty = (list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); if (lists_empty) return 0; @@ -3106,8 +3108,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * write domain */ if (obj->write_domain && - (obj->write_domain != obj->pending_read_domains || - obj_priv->ring != ring)) { + obj->write_domain != obj->pending_read_domains) { flush_domains |= obj->write_domain; invalidate_domains |= obj->pending_read_domains & ~obj->write_domain; @@ -3496,52 +3497,6 @@ i915_gem_execbuffer_pin(struct drm_device *dev, return 0; } -static int -i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, - struct drm_file *file, - struct intel_ring_buffer *ring, - struct drm_gem_object **objects, - int count) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret, i; - - /* Zero the global flush/invalidate flags. These - * will be modified as new domains are computed - * for each object - */ - dev->invalidate_domains = 0; - dev->flush_domains = 0; - dev_priv->mm.flush_rings = 0; - for (i = 0; i < count; i++) - i915_gem_object_set_to_gpu_domain(objects[i], ring); - - if (dev->invalidate_domains | dev->flush_domains) { -#if WATCH_EXEC - DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", - __func__, - dev->invalidate_domains, - dev->flush_domains); -#endif - i915_gem_flush(dev, file, - dev->invalidate_domains, - dev->flush_domains, - dev_priv->mm.flush_rings); - } - - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(objects[i]); - /* XXX replace with semaphores */ - if (obj->ring && ring != obj->ring) { - ret = i915_gem_object_wait_rendering(&obj->base, true); - if (ret) - return ret; - } - } - - return 0; -} - /* Throttle our rendering by waiting until the ring has completed our requests * emitted over 20 msec ago. * @@ -3802,10 +3757,33 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, - object_list, args->buffer_count); - if (ret) - goto err; + /* Zero the global flush/invalidate flags. These + * will be modified as new domains are computed + * for each object + */ + dev->invalidate_domains = 0; + dev->flush_domains = 0; + dev_priv->mm.flush_rings = 0; + + for (i = 0; i < args->buffer_count; i++) { + struct drm_gem_object *obj = object_list[i]; + + /* Compute new gpu domains and update invalidate/flush */ + i915_gem_object_set_to_gpu_domain(obj, ring); + } + + if (dev->invalidate_domains | dev->flush_domains) { +#if WATCH_EXEC + DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", + __func__, + dev->invalidate_domains, + dev->flush_domains); +#endif + i915_gem_flush(dev, file, + dev->invalidate_domains, + dev->flush_domains, + dev_priv->mm.flush_rings); + } for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; @@ -4065,7 +4043,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) alignment = i915_gem_get_gtt_alignment(obj); if (obj_priv->gtt_offset & (alignment - 1)) { WARN(obj_priv->pin_count, - "bo is already pinned with incorrect alignment: offset=%x, req.alignment=%x\n", + "bo is already pinned with incorrect alignment:" + " offset=%x, req.alignment=%x\n", obj_priv->gtt_offset, alignment); ret = i915_gem_object_unbind(obj); if (ret) @@ -4877,24 +4856,17 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_file *file_priv) { struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset; - char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; - - DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size); + void *obj_addr; + int ret; + char __user *user_data; - if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { - unsigned long unwritten; + user_data = (char __user *) (uintptr_t) args->data_ptr; + obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; - /* The physical object once assigned is fixed for the lifetime - * of the obj, so we can safely drop the lock and continue - * to access vaddr. - */ - mutex_unlock(&dev->struct_mutex); - unwritten = copy_from_user(vaddr, user_data, args->size); - mutex_lock(&dev->struct_mutex); - if (unwritten) - return -EFAULT; - } + DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size); + ret = copy_from_user(obj_addr, user_data, args->size); + if (ret) + return -EFAULT; drm_agp_chipset_flush(dev); return 0; @@ -4928,7 +4900,9 @@ i915_gpu_is_active(struct drm_device *dev) int lists_empty; lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list); return !lists_empty; } diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index d8ae7d1..43a4013 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -165,7 +165,9 @@ i915_gem_evict_everything(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); if (lists_empty) return -ENOSPC; @@ -182,7 +184,9 @@ i915_gem_evict_everything(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); BUG_ON(!lists_empty); return 0; diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 454c064..989c19d 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -862,10 +862,8 @@ int i915_restore_state(struct drm_device *dev) /* Clock gating state */ intel_init_clock_gating(dev); - if (HAS_PCH_SPLIT(dev)) { + if (HAS_PCH_SPLIT(dev)) ironlake_enable_drps(dev); - intel_init_emon(dev); - } /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 48d8fd6..990f065 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1681,37 +1681,6 @@ static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) udelay(500); } -static void intel_fdi_normal_train(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp; - - /* enable normal train */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_NORMAL_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE; - } - I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); - - /* wait one idle pattern time */ - POSTING_READ(reg); - udelay(1000); -} - /* The FDI link training functions for ILK/Ibexpeak. */ static void ironlake_fdi_link_train(struct drm_crtc *crtc) { @@ -1798,6 +1767,27 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) DRM_DEBUG_KMS("FDI train done\n"); + /* enable normal train */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; + I915_WRITE(reg, temp); + + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); + if (HAS_PCH_CPT(dev)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_NORMAL_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE; + } + I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); + + /* wait one idle pattern time */ + POSTING_READ(reg); + udelay(1000); } static const int const snb_b_fdi_train_param [] = { @@ -2100,8 +2090,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); - intel_fdi_normal_train(crtc); - /* For PCH DP, enable TRANS_DP_CTL */ if (HAS_PCH_CPT(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { @@ -2212,10 +2200,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) udelay(100); /* Ironlake workaround, disable clock pointer after downing FDI */ - if (HAS_PCH_IBX(dev)) - I915_WRITE(FDI_RX_CHICKEN(pipe), - I915_READ(FDI_RX_CHICKEN(pipe) & - ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); + I915_WRITE(FDI_RX_CHICKEN(pipe), + I915_READ(FDI_RX_CHICKEN(pipe) & + ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); /* still set train pattern 1 */ reg = FDI_TX_CTL(pipe); @@ -5594,19 +5581,20 @@ void ironlake_enable_drps(struct drm_device *dev) fmin = (rgvmodectl & MEMMODE_FMIN_MASK); fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT; + fstart = fmax; vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT; - dev_priv->fmax = fmax; /* IPS callback will increase this */ + dev_priv->fmax = fstart; /* IPS callback will increase this */ dev_priv->fstart = fstart; - dev_priv->max_delay = fstart; + dev_priv->max_delay = fmax; dev_priv->min_delay = fmin; dev_priv->cur_delay = fstart; - DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", - fmax, fmin, fstart); + DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, + fstart); I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c8e0055..891f4f1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1517,7 +1517,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) status = connector_status_connected; } - return status; + return bit; } /** diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 21551fe..9af9f86 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -296,7 +296,6 @@ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, extern void intel_init_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); -extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4324a32..f1a6499 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -481,8 +481,11 @@ static int intel_lvds_get_modes(struct drm_connector *connector) struct drm_device *dev = connector->dev; struct drm_display_mode *mode; - if (intel_lvds->edid) + if (intel_lvds->edid) { + drm_mode_connector_update_edid_property(connector, + intel_lvds->edid); return drm_add_edid_modes(connector, intel_lvds->edid); + } mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); if (mode == 0) @@ -936,16 +939,7 @@ void intel_lvds_init(struct drm_device *dev) */ intel_lvds->edid = drm_get_edid(connector, &dev_priv->gmbus[pin].adapter); - if (intel_lvds->edid) { - if (drm_add_edid_modes(connector, - intel_lvds->edid)) { - drm_mode_connector_update_edid_property(connector, - intel_lvds->edid); - } else { - kfree(intel_lvds->edid); - intel_lvds->edid = NULL; - } - } + if (!intel_lvds->edid) { /* Didn't get an EDID, so * Set wide sync ranges so we get all modes diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 9b0d9a8..917c7dc 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -512,6 +512,6 @@ int intel_opregion_setup(struct drm_device *dev) return 0; err_out: - iounmap(base); + iounmap(opregion->header); return err; } diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 02ff0a4..afb96d2 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -946,9 +946,7 @@ static int check_overlay_src(struct drm_device *dev, { int uv_hscale = uv_hsubsampling(rec->flags); int uv_vscale = uv_vsubsampling(rec->flags); - u32 stride_mask; - int depth; - u32 tmp; + u32 stride_mask, depth, tmp; /* check src dimensions */ if (IS_845G(dev) || IS_I830(dev)) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f..09f2dc3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -177,7 +177,7 @@ static int init_ring_common(struct drm_device *dev, I915_WRITE_CTL(ring, ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) - | RING_REPORT_64K | RING_VALID); + | RING_NO_REPORT | RING_VALID); head = I915_READ_HEAD(ring) & HEAD_ADDR; /* If the head is still not zero, the ring is dead */ @@ -654,10 +654,6 @@ void intel_cleanup_ring_buffer(struct drm_device *dev, i915_gem_object_unpin(ring->gem_object); drm_gem_object_unreference(ring->gem_object); ring->gem_object = NULL; - - if (ring->cleanup) - ring->cleanup(ring); - cleanup_status_page(dev, ring); } @@ -692,17 +688,6 @@ int intel_wait_ring_buffer(struct drm_device *dev, { unsigned long end; drm_i915_private_t *dev_priv = dev->dev_private; - u32 head; - - head = intel_read_status_page(ring, 4); - if (head) { - ring->head = head & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->size; - if (ring->space >= n) - return 0; - } trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; @@ -869,125 +854,19 @@ blt_ring_put_user_irq(struct drm_device *dev, /* do nothing */ } - -/* Workaround for some stepping of SNB, - * each time when BLT engine ring tail moved, - * the first command in the ring to be parsed - * should be MI_BATCH_BUFFER_START - */ -#define NEED_BLT_WORKAROUND(dev) \ - (IS_GEN6(dev) && (dev->pdev->revision < 8)) - -static inline struct drm_i915_gem_object * -to_blt_workaround(struct intel_ring_buffer *ring) -{ - return ring->private; -} - -static int blt_ring_init(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - if (NEED_BLT_WORKAROUND(dev)) { - struct drm_i915_gem_object *obj; - u32 __iomem *ptr; - int ret; - - obj = to_intel_bo(i915_gem_alloc_object(dev, 4096)); - if (obj == NULL) - return -ENOMEM; - - ret = i915_gem_object_pin(&obj->base, 4096); - if (ret) { - drm_gem_object_unreference(&obj->base); - return ret; - } - - ptr = kmap(obj->pages[0]); - iowrite32(MI_BATCH_BUFFER_END, ptr); - iowrite32(MI_NOOP, ptr+1); - kunmap(obj->pages[0]); - - ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); - if (ret) { - i915_gem_object_unpin(&obj->base); - drm_gem_object_unreference(&obj->base); - return ret; - } - - ring->private = obj; - } - - return init_ring_common(dev, ring); -} - -static void blt_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, - int num_dwords) -{ - if (ring->private) { - intel_ring_begin(dev, ring, num_dwords+2); - intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START); - intel_ring_emit(dev, ring, to_blt_workaround(ring)->gtt_offset); - } else - intel_ring_begin(dev, ring, 4); -} - -static void blt_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) -{ - blt_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_FLUSH_DW); - intel_ring_emit(dev, ring, 0); - intel_ring_emit(dev, ring, 0); - intel_ring_emit(dev, ring, 0); - intel_ring_advance(dev, ring); -} - -static u32 -blt_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 flush_domains) -{ - u32 seqno = i915_gem_get_seqno(dev); - - blt_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(dev, ring, - I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(dev, ring, seqno); - intel_ring_emit(dev, ring, MI_USER_INTERRUPT); - intel_ring_advance(dev, ring); - - DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); - return seqno; -} - -static void blt_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring->private) - return; - - i915_gem_object_unpin(ring->private); - drm_gem_object_unreference(ring->private); - ring->private = NULL; -} - static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", .id = RING_BLT, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = blt_ring_init, + .init = init_ring_common, .write_tail = ring_write_tail, - .flush = blt_ring_flush, - .add_request = blt_ring_add_request, + .flush = gen6_ring_flush, + .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, .user_irq_get = blt_ring_get_user_irq, .user_irq_put = blt_ring_put_user_irq, .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, - .cleanup = blt_ring_cleanup, }; int intel_init_render_ring_buffer(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c26..a05aff0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -63,7 +63,6 @@ struct intel_ring_buffer { struct drm_i915_gem_execbuffer2 *exec, struct drm_clip_rect *cliprects, uint64_t exec_offset); - void (*cleanup)(struct intel_ring_buffer *ring); /** * List of objects currently involved in rendering from the @@ -99,8 +98,6 @@ struct intel_ring_buffer { wait_queue_head_t irq_queue; drm_local_map_t map; - - void *private; }; static inline u32 diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 488c36c..f12a5b3 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2033,7 +2033,7 @@ int evergreen_irq_set(struct radeon_device *rdev) u32 grbm_int_cntl = 0; if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); return -EINVAL; } /* don't enable anything if the ih is disabled */ @@ -2295,7 +2295,6 @@ restart_ih: case 0: /* D1 vblank */ if (disp_int & LB_D1_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); @@ -2317,7 +2316,6 @@ restart_ih: case 0: /* D2 vblank */ if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); @@ -2339,7 +2337,6 @@ restart_ih: case 0: /* D3 vblank */ if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; DRM_DEBUG("IH: D3 vblank\n"); @@ -2361,7 +2358,6 @@ restart_ih: case 0: /* D4 vblank */ if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; DRM_DEBUG("IH: D4 vblank\n"); @@ -2383,7 +2379,6 @@ restart_ih: case 0: /* D5 vblank */ if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; DRM_DEBUG("IH: D5 vblank\n"); @@ -2405,7 +2400,6 @@ restart_ih: case 0: /* D6 vblank */ if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; DRM_DEBUG("IH: D6 vblank\n"); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8e10aa9..0e8f28a 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -442,7 +442,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.ram.ptr) { - WARN(1, "R100 PCI GART already initialized\n"); + WARN(1, "R100 PCI GART already initialized.\n"); return 0; } /* Initialize common gart structure */ @@ -516,7 +516,7 @@ int r100_irq_set(struct radeon_device *rdev) uint32_t tmp = 0; if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); WREG32(R_000040_GEN_INT_CNTL, 0); return -EINVAL; } diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index cde1d34..34527e6 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -91,7 +91,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.vram.robj) { - WARN(1, "RV370 PCIE GART already initialized\n"); + WARN(1, "RV370 PCIE GART already initialized.\n"); return 0; } /* Initialize common gart structure */ diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 0f806cc..33952a1 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -97,8 +97,14 @@ u32 rv6xx_get_temp(struct radeon_device *rdev) { u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> ASIC_T_SHIFT; + u32 actual_temp = 0; - return temp * 1000; + if ((temp >> 7) & 1) + actual_temp = 0; + else + actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; } void r600_pm_get_dynpm_state(struct radeon_device *rdev) @@ -913,7 +919,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.vram.robj) { - WARN(1, "R600 PCIE GART already initialized\n"); + WARN(1, "R600 PCIE GART already initialized.\n"); return 0; } /* Initialize common gart structure */ @@ -2989,7 +2995,7 @@ int r600_irq_set(struct radeon_device *rdev) u32 hdmi1, hdmi2; if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); return -EINVAL; } /* don't enable anything if the ih is disabled */ diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 87ead09..04cac7e 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -526,6 +526,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) if (crev < 2) return false; + router.valid = false; + obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset); path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) (ctx->bios + data_offset + @@ -622,8 +624,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) if (connector_type == DRM_MODE_CONNECTOR_Unknown) continue; - router.ddc_valid = false; - router.cd_valid = false; for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { uint8_t grph_obj_id, grph_obj_num, grph_obj_type; @@ -647,8 +647,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) usDeviceTag)); } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { + router.valid = false; for (k = 0; k < router_obj->ucNumberOfObjects; k++) { - u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); + u16 router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID); if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) { ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) (ctx->bios + data_offset + @@ -656,7 +657,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ATOM_I2C_RECORD *i2c_record; ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path; - ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path; ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) (ctx->bios + data_offset + @@ -690,18 +690,10 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *) record; - router.ddc_valid = true; - router.ddc_mux_type = ddc_path->ucMuxType; - router.ddc_mux_control_pin = ddc_path->ucMuxControlPin; - router.ddc_mux_state = ddc_path->ucMuxState[enum_id]; - break; - case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE: - cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *) - record; - router.cd_valid = true; - router.cd_mux_type = cd_path->ucMuxType; - router.cd_mux_control_pin = cd_path->ucMuxControlPin; - router.cd_mux_state = cd_path->ucMuxState[enum_id]; + router.valid = true; + router.mux_type = ddc_path->ucMuxType; + router.mux_control_pin = ddc_path->ucMuxControlPin; + router.mux_state = ddc_path->ucMuxState[enum_id]; break; } record = (ATOM_COMMON_RECORD_HEADER *) @@ -868,8 +860,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; struct radeon_router router; - router.ddc_valid = false; - router.cd_valid = false; + router.valid = false; bios_connectors = kzalloc(bc_size, GFP_KERNEL); if (!bios_connectors) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fe6c747..4dac4b0 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -183,13 +183,13 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, continue; if (priority == true) { - DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector)); + DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); + DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); conflict->status = connector_status_disconnected; radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); } else { - DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict)); + DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); + DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict)); current_status = connector_status_disconnected; } break; @@ -432,13 +432,13 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, mode->vdisplay == native_mode->vdisplay) { *native_mode = *mode; drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); - DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n"); + DRM_INFO("Determined LVDS native mode details from EDID\n"); break; } } } if (!native_mode->clock) { - DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); + DRM_INFO("No LVDS native mode details, disabling RMX\n"); radeon_encoder->rmx_type = RMX_OFF; } } @@ -1116,7 +1116,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->shared_ddc = true; shared_ddc = true; } - if (radeon_connector->router_bus && router->ddc_valid && + if (radeon_connector->router_bus && router->valid && (radeon_connector->router.router_id == router->router_id)) { radeon_connector->shared_ddc = false; shared_ddc = false; @@ -1136,7 +1136,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; radeon_connector->router = *router; - if (router->ddc_valid || router->cd_valid) { + if (router->valid) { radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); if (!radeon_connector->router_bus) goto failed; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1df4dc6..0383631 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -315,14 +315,10 @@ static void radeon_print_display_setup(struct drm_device *dev) radeon_connector->ddc_bus->rec.en_data_reg, radeon_connector->ddc_bus->rec.y_clk_reg, radeon_connector->ddc_bus->rec.y_data_reg); - if (radeon_connector->router.ddc_valid) + if (radeon_connector->router_bus) DRM_INFO(" DDC Router 0x%x/0x%x\n", - radeon_connector->router.ddc_mux_control_pin, - radeon_connector->router.ddc_mux_state); - if (radeon_connector->router.cd_valid) - DRM_INFO(" Clock/Data Router 0x%x/0x%x\n", - radeon_connector->router.cd_mux_control_pin, - radeon_connector->router.cd_mux_state); + radeon_connector->router.mux_control_pin, + radeon_connector->router.mux_state); } else { if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || connector->connector_type == DRM_MODE_CONNECTOR_DVII || @@ -402,8 +398,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) int ret = 0; /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); + if (radeon_connector->router.valid) + radeon_router_select_port(radeon_connector); if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { @@ -436,8 +432,8 @@ static int radeon_ddc_dump(struct drm_connector *connector) int ret = 0; /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); + if (radeon_connector->router.valid) + radeon_router_select_port(radeon_connector); if (!radeon_connector->ddc_bus) return -1; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index f678257..ae58b68 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1520,7 +1520,6 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); if (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { @@ -1532,13 +1531,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) radeon_atom_output_lock(encoder, true); radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); - /* select the clock/data port if it uses a router */ - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - if (radeon_connector->router.cd_valid) - radeon_router_select_cd_port(radeon_connector); - } - /* this is needed for the pll/ss setup to work correctly in some cases */ atombios_set_encoder_crtc_source(encoder); } @@ -1555,23 +1547,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig; - - /* check for pre-DCE3 cards with shared encoders; - * can't really use the links individually, so don't disable - * the encoder if it's in use by another connector - */ - if (!ASIC_IS_DCE3(rdev)) { - struct drm_encoder *other_encoder; - struct radeon_encoder *other_radeon_encoder; - - list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { - other_radeon_encoder = to_radeon_encoder(other_encoder); - if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && - drm_helper_encoder_in_use(other_encoder)) - goto disable_done; - } - } - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); switch (radeon_encoder->encoder_id) { @@ -1611,7 +1586,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) break; } -disable_done: if (radeon_encoder_is_digital(encoder)) { if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) r600_hdmi_disable(encoder); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index daacb28..216392d 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -240,8 +240,7 @@ retry: */ if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { /* good news we believe it's a lockup */ - WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", - fence->seq, seq); + WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); /* FIXME: what should we do ? marking everyone * as signaled for now */ diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 0cfbba0..6a13ee3 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -53,8 +53,8 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) }; /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); + if (radeon_connector->router.valid) + radeon_router_select_port(radeon_connector); ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); if (ret == 2) @@ -1084,51 +1084,26 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, addr, val); } -/* ddc router switching */ -void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) +/* router switching */ +void radeon_router_select_port(struct radeon_connector *radeon_connector) { u8 val; - if (!radeon_connector->router.ddc_valid) + if (!radeon_connector->router.valid) return; radeon_i2c_get_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x3, &val); - val &= ~radeon_connector->router.ddc_mux_control_pin; + val &= radeon_connector->router.mux_control_pin; radeon_i2c_put_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x3, val); radeon_i2c_get_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x1, &val); - val &= ~radeon_connector->router.ddc_mux_control_pin; - val |= radeon_connector->router.ddc_mux_state; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, val); -} - -/* clock/data router switching */ -void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) -{ - u8 val; - - if (!radeon_connector->router.cd_valid) - return; - - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, &val); - val &= ~radeon_connector->router.cd_mux_control_pin; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, val); - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, &val); - val &= ~radeon_connector->router.cd_mux_control_pin; - val |= radeon_connector->router.cd_mux_state; + val &= radeon_connector->router.mux_control_pin; + val |= radeon_connector->router.mux_state; radeon_i2c_put_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x1, val); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 680f576..9245716 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -401,19 +401,13 @@ struct radeon_hpd { }; struct radeon_router { + bool valid; u32 router_id; struct radeon_i2c_bus_rec i2c_info; u8 i2c_addr; - /* i2c mux */ - bool ddc_valid; - u8 ddc_mux_type; - u8 ddc_mux_control_pin; - u8 ddc_mux_state; - /* clock/data mux */ - bool cd_valid; - u8 cd_mux_type; - u8 cd_mux_control_pin; - u8 cd_mux_state; + u8 mux_type; + u8 mux_control_pin; + u8 mux_state; }; struct radeon_connector { @@ -494,8 +488,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, u8 slave_addr, u8 addr, u8 val); -extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); -extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); +extern void radeon_router_select_port(struct radeon_connector *radeon_connector); extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8eb1834..d7ab914 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -102,8 +102,6 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, type = ttm_bo_type_device; } *bo_ptr = NULL; - -retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) return -ENOMEM; @@ -111,6 +109,8 @@ retry: bo->gobj = gobj; bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); + +retry: radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 01c2c73..fe95bb3 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -689,8 +689,7 @@ static int radeon_ttm_backend_bind(struct ttm_backend *backend, gtt = container_of(backend, struct radeon_ttm_backend, backend); gtt->offset = bo_mem->start << PAGE_SHIFT; if (!gtt->num_pages) { - WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", - gtt->num_pages, bo_mem, backend); + WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", gtt->num_pages, bo_mem, backend); } r = radeon_gart_bind(gtt->rdev, gtt->offset, gtt->num_pages, gtt->pages); diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 5512e4e..f683e51 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -78,7 +78,7 @@ int rs400_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.ram.ptr) { - WARN(1, "RS400 GART already initialized\n"); + WARN(1, "RS400 GART already initialized.\n"); return 0; } /* Check gart size */ diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index f1c6e02..b091a1f 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -375,7 +375,7 @@ int rs600_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.vram.robj) { - WARN(1, "RS600 GART already initialized\n"); + WARN(1, "RS600 GART already initialized.\n"); return 0; } /* Initialize common gart structure */ @@ -505,7 +505,7 @@ int rs600_irq_set(struct radeon_device *rdev) ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); WREG32(R_000040_GEN_INT_CNTL, 0); return -EINVAL; } diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 3ca77dc..a1cb783 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -27,6 +27,14 @@ /* * Authors: Thomas Hellstrom */ +/* Notes: + * + * We store bo pointer in drm_mm_node struct so we know which bo own a + * specific node. There is no protection on the pointer, thus to make + * sure things don't go berserk you have to access this pointer while + * holding the global lru lock and make sure anytime you free a node you + * reset the pointer to NULL. + */ #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" @@ -37,7 +45,6 @@ #include #include #include -#include #define TTM_ASSERT_LOCKED(param) #define TTM_DEBUG(fmt, arg...) @@ -445,11 +452,6 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) ttm_bo_mem_put(bo, &bo->mem); atomic_set(&bo->reserved, 0); - - /* - * Make processes trying to reserve really pick it up. - */ - smp_mb__after_atomic_dec(); wake_up_all(&bo->event_queue); } @@ -458,7 +460,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) struct ttm_bo_device *bdev = bo->bdev; struct ttm_bo_global *glob = bo->glob; struct ttm_bo_driver *driver; - void *sync_obj = NULL; + void *sync_obj; void *sync_obj_arg; int put_count; int ret; @@ -493,20 +495,17 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) spin_lock(&glob->lru_lock); } queue: - driver = bdev->driver; - if (bo->sync_obj) - sync_obj = driver->sync_obj_ref(bo->sync_obj); + sync_obj = bo->sync_obj; sync_obj_arg = bo->sync_obj_arg; + driver = bdev->driver; kref_get(&bo->list_kref); list_add_tail(&bo->ddestroy, &bdev->ddestroy); spin_unlock(&glob->lru_lock); spin_unlock(&bo->lock); - if (sync_obj) { + if (sync_obj) driver->sync_obj_flush(sync_obj, sync_obj_arg); - driver->sync_obj_unref(&sync_obj); - } schedule_delayed_work(&bdev->wq, ((HZ / 100) < 1) ? 1 : HZ / 100); } @@ -823,6 +822,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, bool no_wait_gpu) { struct ttm_bo_device *bdev = bo->bdev; + struct ttm_bo_global *glob = bdev->glob; struct ttm_mem_type_manager *man = &bdev->man[mem_type]; int ret; @@ -832,6 +832,12 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, return ret; if (mem->mm_node) break; + spin_lock(&glob->lru_lock); + if (list_empty(&man->lru)) { + spin_unlock(&glob->lru_lock); + break; + } + spin_unlock(&glob->lru_lock); ret = ttm_mem_evict_first(bdev, mem_type, interruptible, no_wait_reserve, no_wait_gpu); if (unlikely(ret != 0)) @@ -1119,9 +1125,35 @@ EXPORT_SYMBOL(ttm_bo_validate); int ttm_bo_check_placement(struct ttm_buffer_object *bo, struct ttm_placement *placement) { - BUG_ON((placement->fpfn || placement->lpfn) && - (bo->mem.num_pages > (placement->lpfn - placement->fpfn))); + int i; + if (placement->fpfn || placement->lpfn) { + if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) { + printk(KERN_ERR TTM_PFX "Page number range to small " + "Need %lu pages, range is [%u, %u]\n", + bo->mem.num_pages, placement->fpfn, + placement->lpfn); + return -EINVAL; + } + } + for (i = 0; i < placement->num_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } + for (i = 0; i < placement->num_busy_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } return 0; } @@ -1144,10 +1176,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; if (num_pages == 0) { printk(KERN_ERR TTM_PFX "Illegal buffer object size.\n"); - if (destroy) - (*destroy)(bo); - else - kfree(bo); return -EINVAL; } bo->destroy = destroy; @@ -1341,9 +1369,18 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, int ret = -EINVAL; struct ttm_mem_type_manager *man; - BUG_ON(type >= TTM_NUM_MEM_TYPES); + if (type >= TTM_NUM_MEM_TYPES) { + printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", type); + return ret; + } + man = &bdev->man[type]; - BUG_ON(man->has_type); + if (man->has_type) { + printk(KERN_ERR TTM_PFX + "Memory manager already initialized for type %d\n", + type); + return ret; + } ret = bdev->driver->init_mem_type(bdev, type, man); if (ret) @@ -1352,6 +1389,13 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, ret = 0; if (type != TTM_PL_SYSTEM) { + if (!p_size) { + printk(KERN_ERR TTM_PFX + "Zero size memory manager type %d\n", + type); + return ret; + } + ret = (*man->func->init)(man, p_size); if (ret) return ret; diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c index 038e947..7410c19 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_manager.c +++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright (c) 2007-2010 VMware, Inc., Palo Alto, CA., USA + * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -31,29 +31,20 @@ #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" #include "ttm/ttm_placement.h" -#include "drm_mm.h" +#include #include -#include +#include +#include +#include #include -/** - * Currently we use a spinlock for the lock, but a mutex *may* be - * more appropriate to reduce scheduling latency if the range manager - * ends up with very fragmented allocation patterns. - */ - -struct ttm_range_manager { - struct drm_mm mm; - spinlock_t lock; -}; - static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; - struct drm_mm *mm = &rman->mm; + struct ttm_bo_global *glob = man->bdev->glob; + struct drm_mm *mm = man->priv; struct drm_mm_node *node = NULL; unsigned long lpfn; int ret; @@ -66,19 +57,19 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, if (unlikely(ret)) return ret; - spin_lock(&rman->lock); + spin_lock(&glob->lru_lock); node = drm_mm_search_free_in_range(mm, mem->num_pages, mem->page_alignment, placement->fpfn, lpfn, 1); if (unlikely(node == NULL)) { - spin_unlock(&rman->lock); + spin_unlock(&glob->lru_lock); return 0; } node = drm_mm_get_block_atomic_range(node, mem->num_pages, - mem->page_alignment, - placement->fpfn, - lpfn); - spin_unlock(&rman->lock); + mem->page_alignment, + placement->fpfn, + lpfn); + spin_unlock(&glob->lru_lock); } while (node == NULL); mem->mm_node = node; @@ -89,12 +80,12 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; + struct ttm_bo_global *glob = man->bdev->glob; if (mem->mm_node) { - spin_lock(&rman->lock); + spin_lock(&glob->lru_lock); drm_mm_put_block(mem->mm_node); - spin_unlock(&rman->lock); + spin_unlock(&glob->lru_lock); mem->mm_node = NULL; } } @@ -102,49 +93,49 @@ static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, static int ttm_bo_man_init(struct ttm_mem_type_manager *man, unsigned long p_size) { - struct ttm_range_manager *rman; + struct drm_mm *mm; int ret; - rman = kzalloc(sizeof(*rman), GFP_KERNEL); - if (!rman) + mm = kzalloc(sizeof(*mm), GFP_KERNEL); + if (!mm) return -ENOMEM; - ret = drm_mm_init(&rman->mm, 0, p_size); + ret = drm_mm_init(mm, 0, p_size); if (ret) { - kfree(rman); + kfree(mm); return ret; } - spin_lock_init(&rman->lock); - man->priv = rman; + man->priv = mm; return 0; } static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; - struct drm_mm *mm = &rman->mm; + struct ttm_bo_global *glob = man->bdev->glob; + struct drm_mm *mm = man->priv; + int ret = 0; - spin_lock(&rman->lock); + spin_lock(&glob->lru_lock); if (drm_mm_clean(mm)) { drm_mm_takedown(mm); - spin_unlock(&rman->lock); - kfree(rman); + kfree(mm); man->priv = NULL; - return 0; - } - spin_unlock(&rman->lock); - return -EBUSY; + } else + ret = -EBUSY; + spin_unlock(&glob->lru_lock); + return ret; } static void ttm_bo_man_debug(struct ttm_mem_type_manager *man, const char *prefix) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; + struct ttm_bo_global *glob = man->bdev->glob; + struct drm_mm *mm = man->priv; - spin_lock(&rman->lock); - drm_mm_debug_table(&rman->mm, prefix); - spin_unlock(&rman->lock); + spin_lock(&glob->lru_lock); + drm_mm_debug_table(mm, prefix); + spin_unlock(&glob->lru_lock); } const struct ttm_mem_type_manager_func ttm_bo_manager_func = { diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index af789dc..a7bab87 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -440,8 +440,10 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) return ret; ret = be->func->bind(be, bo_mem); - if (unlikely(ret != 0)) + if (ret) { + printk(KERN_ERR TTM_PFX "Couldn't bind backend.\n"); return ret; + } ttm->state = tt_bound; diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 3e038a3..9b5b4d9 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c @@ -235,9 +235,9 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - first_pfn + 1; - vsg->pages = vzalloc(sizeof(struct page *) * vsg->num_pages); - if (NULL == vsg->pages) + if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) return -ENOMEM; + memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages); down_read(¤t->mm->mmap_sem); ret = get_user_pages(current, current->mm, (unsigned long)xfer->mem_addr, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 76954e3..51d9f9f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -691,7 +691,6 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, fence_rep.error = ret; fence_rep.fence_seq = (uint64_t) sequence; - fence_rep.pad64 = 0; user_fence_rep = (struct drm_vmw_fence_rep __user *) (unsigned long)arg->fence_rep; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index cceeb42..87c6e61 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -720,8 +720,6 @@ static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb) &vmw_vram_ne_placement, false, &vmw_dmabuf_bo_free); vmw_overlay_resume_all(dev_priv); - if (unlikely(ret != 0)) - vfbs->buffer = NULL; return ret; } @@ -732,9 +730,6 @@ static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb) struct vmw_framebuffer_surface *vfbs = vmw_framebuffer_to_vfbs(&vfb->base); - if (unlikely(vfbs->buffer == NULL)) - return 0; - bo = &vfbs->buffer->base; ttm_bo_unref(&bo); vfbs->buffer = NULL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 29113c9..a01c47d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -557,7 +557,7 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) return -EINVAL; } - dev_priv->ldu_priv = kmalloc(sizeof(*dev_priv->ldu_priv), GFP_KERNEL); + dev_priv->ldu_priv = kmalloc(GFP_KERNEL, sizeof(*dev_priv->ldu_priv)); if (!dev_priv->ldu_priv) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index f1a52f9..df2036e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -585,7 +585,7 @@ int vmw_overlay_init(struct vmw_private *dev_priv) return -ENOSYS; } - overlay = kmalloc(sizeof(*overlay), GFP_KERNEL); + overlay = kmalloc(GFP_KERNEL, sizeof(*overlay)); if (!overlay) return -ENOMEM; diff --git a/drivers/gpu/stub/Kconfig b/drivers/gpu/stub/Kconfig index 0e1edd7..742c423 100644 --- a/drivers/gpu/stub/Kconfig +++ b/drivers/gpu/stub/Kconfig @@ -3,9 +3,6 @@ config STUB_POULSBO depends on PCI # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI - select BACKLIGHT_CLASS_DEVICE if ACPI - select INPUT if ACPI select ACPI_VIDEO if ACPI help Choose this option if you have a system that has Intel GMA500 diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index 86d822a..1e4c21f 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c @@ -178,13 +178,11 @@ static int ad7414_probe(struct i2c_client *client, { struct ad7414_data *data; int conf; - int err; + int err = 0; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_READ_WORD_DATA)) { - err = -EOPNOTSUPP; + I2C_FUNC_SMBUS_READ_WORD_DATA)) goto exit; - } data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); if (!data) { diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 87d92a5..9e77571 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -1286,10 +1286,8 @@ static int adt7470_probe(struct i2c_client *client, init_completion(&data->auto_update_stop); data->auto_update = kthread_run(adt7470_update_thread, client, dev_name(data->hwmon_dev)); - if (IS_ERR(data->auto_update)) { - err = PTR_ERR(data->auto_update); + if (IS_ERR(data->auto_update)) goto exit_unregister; - } return 0; diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index 4033974..fa9708c 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -4,7 +4,7 @@ Copyright (C) 2009 T. Mertelj Based on max6650.c: - Copyright (C) 2007 Hans J. Koch + Copyright (C) 2007 Hans J. Koch This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index f141a1d..aa701a1 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -376,6 +376,10 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, } } + err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); + if (err) + goto err_free_gpio; + fan_data->num_ctrl = num_ctrl; fan_data->ctrl = ctrl; fan_data->num_speed = pdata->num_speed; @@ -387,10 +391,6 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, goto err_free_gpio; } - err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); - if (err) - goto err_free_gpio; - return 0; err_free_gpio: diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index c9ed14e..6669255 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -20,7 +20,7 @@ Adapted to 2.6.20 by Carsten Emde Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab - Modified for mainline integration by Hans J. Koch + Modified for mainline integration by Hans J. Koch Copyright (c) 2007 Hans J. Koch, Linutronix GmbH This program is free software; you can redistribute it and/or modify @@ -2629,7 +2629,7 @@ static void __exit lm93_exit(void) } MODULE_AUTHOR("Mark M. Hoffman , " - "Hans J. Koch "); + "Hans J. Koch interval = val * HZ / 1000; + strict_strtol(buf, 10, &data->interval); + data->interval = data->interval * HZ / 1000; return count; } @@ -191,9 +188,7 @@ static ssize_t set_type##flag(struct device *dev, \ struct lm95241_data *data = i2c_get_clientdata(client); \ \ long val; \ -\ - if (strict_strtol(buf, 10, &val) < 0) \ - return -EINVAL; \ + strict_strtol(buf, 10, &val); \ \ if ((val == 1) || (val == 2)) { \ \ @@ -232,9 +227,7 @@ static ssize_t set_min##flag(struct device *dev, \ struct lm95241_data *data = i2c_get_clientdata(client); \ \ long val; \ -\ - if (strict_strtol(buf, 10, &val) < 0) \ - return -EINVAL;\ + strict_strtol(buf, 10, &val); \ \ mutex_lock(&data->update_lock); \ \ @@ -263,9 +256,7 @@ static ssize_t set_max##flag(struct device *dev, \ struct lm95241_data *data = i2c_get_clientdata(client); \ \ long val; \ -\ - if (strict_strtol(buf, 10, &val) < 0) \ - return -EINVAL; \ + strict_strtol(buf, 10, &val); \ \ mutex_lock(&data->update_lock); \ \ diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 9a11532..a0160ee 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -2,7 +2,7 @@ * max6650.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring. * - * (C) 2007 by Hans J. Koch + * (C) 2007 by Hans J. Koch * * based on code written by John Morris * Copyright (c) 2003 Spirent Communications diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index cdbc744..1d840aa 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c @@ -165,14 +165,10 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { #define W83795_REG_VID_CTRL 0x6A -#define W83795_REG_ALARM_CTRL 0x40 -#define ALARM_CTRL_RTSACS (1 << 7) #define W83795_REG_ALARM(index) (0x41 + (index)) -#define W83795_REG_CLR_CHASSIS 0x4D #define W83795_REG_BEEP(index) (0x50 + (index)) -#define W83795_REG_OVT_CFG 0x58 -#define OVT_CFG_SEL (1 << 7) +#define W83795_REG_CLR_CHASSIS 0x4D #define W83795_REG_FCMS1 0x201 @@ -182,14 +178,6 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { #define W83795_REG_TSS(index) (0x209 + (index)) -#define TSS_MAP_RESERVED 0xff -static const u8 tss_map[4][6] = { - { 0, 1, 2, 3, 4, 5}, - { 6, 7, 8, 9, 0, 1}, - {10, 11, 12, 13, 2, 3}, - { 4, 5, 4, 5, TSS_MAP_RESERVED, TSS_MAP_RESERVED}, -}; - #define PWM_OUTPUT 0 #define PWM_FREQ 1 #define PWM_START 2 @@ -381,7 +369,6 @@ struct w83795_data { u8 setup_pwm[3]; /* Register value */ u8 alarms[6]; /* Register value */ - u8 enable_beep; u8 beeps[6]; /* Register value */ char valid; @@ -512,11 +499,8 @@ static void w83795_update_limits(struct i2c_client *client) } /* Read beep settings */ - if (data->enable_beep) { - for (i = 0; i < ARRAY_SIZE(data->beeps); i++) - data->beeps[i] = - w83795_read(client, W83795_REG_BEEP(i)); - } + for (i = 0; i < ARRAY_SIZE(data->beeps); i++) + data->beeps[i] = w83795_read(client, W83795_REG_BEEP(i)); data->valid_limits = 1; } @@ -593,7 +577,6 @@ static struct w83795_data *w83795_update_device(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct w83795_data *data = i2c_get_clientdata(client); u16 tmp; - u8 intrusion; int i; mutex_lock(&data->update_lock); @@ -665,24 +648,9 @@ static struct w83795_data *w83795_update_device(struct device *dev) w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); } - /* Update intrusion and alarms - * It is important to read intrusion first, because reading from - * register SMI STS6 clears the interrupt status temporarily. */ - tmp = w83795_read(client, W83795_REG_ALARM_CTRL); - /* Switch to interrupt status for intrusion if needed */ - if (tmp & ALARM_CTRL_RTSACS) - w83795_write(client, W83795_REG_ALARM_CTRL, - tmp & ~ALARM_CTRL_RTSACS); - intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6); - /* Switch to real-time alarms */ - w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS); + /* update alarm */ for (i = 0; i < ARRAY_SIZE(data->alarms); i++) data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); - data->alarms[5] |= intrusion; - /* Restore original configuration if needed */ - if (!(tmp & ALARM_CTRL_RTSACS)) - w83795_write(client, W83795_REG_ALARM_CTRL, - tmp & ~ALARM_CTRL_RTSACS); data->last_updated = jiffies; data->valid = 1; @@ -762,10 +730,6 @@ store_chassis_clear(struct device *dev, val = w83795_read(client, W83795_REG_CLR_CHASSIS); val |= 0x80; w83795_write(client, W83795_REG_CLR_CHASSIS, val); - - /* Clear status and force cache refresh */ - w83795_read(client, W83795_REG_ALARM(5)); - data->valid = 0; mutex_unlock(&data->update_lock); return count; } @@ -893,20 +857,20 @@ show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) int index = sensor_attr->index; u8 tmp; - /* Speed cruise mode */ - if (data->pwm_fcms[0] & (1 << index)) { + if (1 == (data->pwm_fcms[0] & (1 << index))) { tmp = 2; goto out; } - /* Thermal cruise or SmartFan IV mode */ for (tmp = 0; tmp < 6; tmp++) { if (data->pwm_tfmr[tmp] & (1 << index)) { tmp = 3; goto out; } } - /* Manual mode */ - tmp = 1; + if (data->pwm_fomc & (1 << index)) + tmp = 0; + else + tmp = 1; out: return sprintf(buf, "%u\n", tmp); @@ -926,21 +890,23 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, if (strict_strtoul(buf, 10, &val) < 0) return -EINVAL; - if (val < 1 || val > 2) + if (val > 2) return -EINVAL; mutex_lock(&data->update_lock); switch (val) { + case 0: case 1: - /* Clear speed cruise mode bits */ data->pwm_fcms[0] &= ~(1 << index); w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); - /* Clear thermal cruise mode bits */ for (i = 0; i < 6; i++) { data->pwm_tfmr[i] &= ~(1 << index); w83795_write(client, W83795_REG_TFMR(i), data->pwm_tfmr[i]); } + data->pwm_fomc |= 1 << index; + data->pwm_fomc ^= val << index; + w83795_write(client, W83795_REG_FOMC, data->pwm_fomc); break; case 2: data->pwm_fcms[0] |= (1 << index); @@ -952,60 +918,23 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, } static ssize_t -show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct w83795_data *data = w83795_update_pwm_config(dev); - int index = to_sensor_dev_attr_2(attr)->index; - unsigned int mode; - - if (data->pwm_fomc & (1 << index)) - mode = 0; /* DC */ - else - mode = 1; /* PWM */ - - return sprintf(buf, "%u\n", mode); -} - -/* - * Check whether a given temperature source can ever be useful. - * Returns the number of selectable temperature channels which are - * enabled. - */ -static int w83795_tss_useful(const struct w83795_data *data, int tsrc) -{ - int useful = 0, i; - - for (i = 0; i < 4; i++) { - if (tss_map[i][tsrc] == TSS_MAP_RESERVED) - continue; - if (tss_map[i][tsrc] < 6) /* Analog */ - useful += (data->has_temp >> tss_map[i][tsrc]) & 1; - else /* Digital */ - useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1; - } - - return useful; -} - -static ssize_t show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) { struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); struct w83795_data *data = w83795_update_pwm_config(dev); int index = sensor_attr->index; - u8 tmp = data->temp_src[index / 2]; + u8 val = index / 2; + u8 tmp = data->temp_src[val]; if (index & 1) - tmp >>= 4; /* Pick high nibble */ + val = 4; else - tmp &= 0x0f; /* Pick low nibble */ - - /* Look-up the actual temperature channel number */ - if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED) - return -EINVAL; /* Shouldn't happen */ + val = 0; + tmp >>= val; + tmp &= 0x0f; - return sprintf(buf, "%u\n", (unsigned int)tss_map[tmp][index] + 1); + return sprintf(buf, "%u\n", tmp); } static ssize_t @@ -1017,21 +946,12 @@ store_temp_src(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); int index = sensor_attr->index; - int tmp; - unsigned long channel; + unsigned long tmp; u8 val = index / 2; - if (strict_strtoul(buf, 10, &channel) < 0 || - channel < 1 || channel > 14) - return -EINVAL; - - /* Check if request can be fulfilled */ - for (tmp = 0; tmp < 4; tmp++) { - if (tss_map[tmp][index] == channel - 1) - break; - } - if (tmp == 4) /* No match */ + if (strict_strtoul(buf, 10, &tmp) < 0) return -EINVAL; + tmp = SENSORS_LIMIT(tmp, 0, 15); mutex_lock(&data->update_lock); if (index & 1) { @@ -1595,7 +1515,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, #define NOT_USED -1 -/* Don't change the attribute order, _max, _min and _beep are accessed by index +/* Don't change the attribute order, _max and _min are accessed by index * somewhere else in the code */ #define SENSOR_ATTR_IN(index) { \ SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ @@ -1610,8 +1530,6 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, show_alarm_beep, store_beep, BEEP_ENABLE, \ index + ((index > 14) ? 1 : 0)) } -/* Don't change the attribute order, _beep is accessed by index - * somewhere else in the code */ #define SENSOR_ATTR_FAN(index) { \ SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ NULL, FAN_INPUT, index - 1), \ @@ -1635,13 +1553,9 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, show_pwm, store_pwm, PWM_FREQ, index - 1), \ SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ - SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ - show_pwm_mode, NULL, NOT_USED, index - 1), \ SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ show_fanin, store_fanin, FANIN_TARGET, index - 1) } -/* Don't change the attribute order, _beep is accessed by index - * somewhere else in the code */ #define SENSOR_ATTR_DTS(index) { \ SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ show_dts_mode, NULL, NOT_USED, index - 7), \ @@ -1660,8 +1574,6 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } -/* Don't change the attribute order, _beep is accessed by index - * somewhere else in the code */ #define SENSOR_ATTR_TEMP(index) { \ SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ @@ -1681,6 +1593,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ show_alarm_beep, store_beep, BEEP_ENABLE, \ index + (index > 4 ? 11 : 17)), \ + SENSOR_ATTR_2(temp##index##_source_sel, S_IWUSR | S_IRUGO, \ + show_temp_src, store_temp_src, NOT_USED, index - 1), \ SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ show_temp_pwm_enable, store_temp_pwm_enable, \ TEMP_PWM_ENABLE, index - 1), \ @@ -1766,7 +1680,7 @@ static const struct sensor_device_attribute_2 w83795_fan[][4] = { SENSOR_ATTR_FAN(14), }; -static const struct sensor_device_attribute_2 w83795_temp[][28] = { +static const struct sensor_device_attribute_2 w83795_temp[][29] = { SENSOR_ATTR_TEMP(1), SENSOR_ATTR_TEMP(2), SENSOR_ATTR_TEMP(3), @@ -1786,7 +1700,7 @@ static const struct sensor_device_attribute_2 w83795_dts[][8] = { SENSOR_ATTR_DTS(14), }; -static const struct sensor_device_attribute_2 w83795_pwm[][8] = { +static const struct sensor_device_attribute_2 w83795_pwm[][7] = { SENSOR_ATTR_PWM(1), SENSOR_ATTR_PWM(2), SENSOR_ATTR_PWM(3), @@ -1797,24 +1711,13 @@ static const struct sensor_device_attribute_2 w83795_pwm[][8] = { SENSOR_ATTR_PWM(8), }; -static const struct sensor_device_attribute_2 w83795_tss[6] = { - SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO, - show_temp_src, store_temp_src, NOT_USED, 0), - SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO, - show_temp_src, store_temp_src, NOT_USED, 1), - SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO, - show_temp_src, store_temp_src, NOT_USED, 2), - SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO, - show_temp_src, store_temp_src, NOT_USED, 3), - SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO, - show_temp_src, store_temp_src, NOT_USED, 4), - SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO, - show_temp_src, store_temp_src, NOT_USED, 5), -}; - static const struct sensor_device_attribute_2 sda_single_files[] = { SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, store_chassis_clear, ALARM_STATUS, 46), + SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, + store_beep, BEEP_ENABLE, 46), + SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, + store_beep, BEEP_ENABLE, 47), #ifdef CONFIG_SENSORS_W83795_FANCTRL SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, store_fanin, FANIN_TOL, NOT_USED), @@ -1827,13 +1730,6 @@ static const struct sensor_device_attribute_2 sda_single_files[] = { #endif }; -static const struct sensor_device_attribute_2 sda_beep_files[] = { - SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, - store_beep, BEEP_ENABLE, 46), - SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, - store_beep, BEEP_ENABLE, 47), -}; - /* * Driver interface */ @@ -1963,8 +1859,6 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, if (!(data->has_in & (1 << i))) continue; for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { - if (j == 4 && !data->enable_beep) - continue; err = fn(dev, &w83795_in[i][j].dev_attr); if (err) return err; @@ -1975,37 +1869,18 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, if (!(data->has_fan & (1 << i))) continue; for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { - if (j == 3 && !data->enable_beep) - continue; err = fn(dev, &w83795_fan[i][j].dev_attr); if (err) return err; } } - for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) { - j = w83795_tss_useful(data, i); - if (!j) - continue; - err = fn(dev, &w83795_tss[i].dev_attr); - if (err) - return err; - } - for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { err = fn(dev, &sda_single_files[i].dev_attr); if (err) return err; } - if (data->enable_beep) { - for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) { - err = fn(dev, &sda_beep_files[i].dev_attr); - if (err) - return err; - } - } - #ifdef CONFIG_SENSORS_W83795_FANCTRL for (i = 0; i < data->has_pwm; i++) { for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { @@ -2024,8 +1899,6 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, #else for (j = 0; j < 8; j++) { #endif - if (j == 7 && !data->enable_beep) - continue; err = fn(dev, &w83795_temp[i][j].dev_attr); if (err) return err; @@ -2037,8 +1910,6 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, if (!(data->has_dts & (1 << i))) continue; for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { - if (j == 7 && !data->enable_beep) - continue; err = fn(dev, &w83795_dts[i][j].dev_attr); if (err) return err; @@ -2178,18 +2049,6 @@ static int w83795_probe(struct i2c_client *client, else data->has_pwm = 2; - /* Check if BEEP pin is available */ - if (data->chip_type == w83795g) { - /* The W83795G has a dedicated BEEP pin */ - data->enable_beep = 1; - } else { - /* The W83795ADG has a shared pin for OVT# and BEEP, so you - * can't have both */ - tmp = w83795_read(client, W83795_REG_OVT_CFG); - if ((tmp & OVT_CFG_SEL) == 0) - data->enable_beep = 1; - } - err = w83795_handle_files(dev, device_create_file); if (err) goto exit_remove; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6b4cc56..d231f68 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -848,18 +848,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } - /* Sanity checks */ - if (unlikely(adap->name[0] == '\0')) { - pr_err("i2c-core: Attempt to register an adapter with " - "no name!\n"); - return -EINVAL; - } - if (unlikely(!adap->algo)) { - pr_err("i2c-core: Attempt to register adapter '%s' with " - "no algo!\n", adap->name); - return -EINVAL; - } - rt_mutex_init(&adap->bus_lock); mutex_init(&adap->userspace_clients_lock); INIT_LIST_HEAD(&adap->userspace_clients); diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index d7a4833..d32a484 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -120,6 +120,7 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, snprintf(priv->adap.name, sizeof(priv->adap.name), "i2c-%d-mux (chan_id %d)", i2c_adapter_id(parent), chan_id); priv->adap.owner = THIS_MODULE; + priv->adap.id = parent->id; priv->adap.algo = &priv->algo; priv->adap.algo_data = priv; priv->adap.dev.parent = &parent->dev; diff --git a/drivers/input/input.c b/drivers/input/input.c index 7f26ca6..d092ef9 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -74,7 +74,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) * dev->event_lock held and interrupts disabled. */ static void input_pass_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { struct input_handler *handler; @@ -93,15 +92,6 @@ static void input_pass_event(struct input_dev *dev, continue; handler = handle->handler; - - /* - * If this is the handler that injected this - * particular event we want to skip it to avoid - * filters firing again and again. - */ - if (handler == src_handler) - continue; - if (!handler->filter) { if (filtered) break; @@ -131,7 +121,7 @@ static void input_repeat_key(unsigned long data) if (test_bit(dev->repeat_key, dev->key) && is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { - input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); + input_pass_event(dev, EV_KEY, dev->repeat_key, 2); if (dev->sync) { /* @@ -140,7 +130,7 @@ static void input_repeat_key(unsigned long data) * Otherwise assume that the driver will send * SYN_REPORT once it's done. */ - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } if (dev->rep[REP_PERIOD]) @@ -173,7 +163,6 @@ static void input_stop_autorepeat(struct input_dev *dev) #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) static int input_handle_abs_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int code, int *pval) { bool is_mt_event; @@ -217,15 +206,13 @@ static int input_handle_abs_event(struct input_dev *dev, /* Flush pending "slot" event */ if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); - input_pass_event(dev, src_handler, - EV_ABS, ABS_MT_SLOT, dev->slot); + input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); } return INPUT_PASS_TO_HANDLERS; } static void input_handle_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { int disposition = INPUT_IGNORE_EVENT; @@ -278,8 +265,7 @@ static void input_handle_event(struct input_dev *dev, case EV_ABS: if (is_event_supported(code, dev->absbit, ABS_MAX)) - disposition = input_handle_abs_event(dev, src_handler, - code, &value); + disposition = input_handle_abs_event(dev, code, &value); break; @@ -337,7 +323,7 @@ static void input_handle_event(struct input_dev *dev, dev->event(dev, type, code, value); if (disposition & INPUT_PASS_TO_HANDLERS) - input_pass_event(dev, src_handler, type, code, value); + input_pass_event(dev, type, code, value); } /** @@ -366,7 +352,7 @@ void input_event(struct input_dev *dev, spin_lock_irqsave(&dev->event_lock, flags); add_input_randomness(type, code, value); - input_handle_event(dev, NULL, type, code, value); + input_handle_event(dev, type, code, value); spin_unlock_irqrestore(&dev->event_lock, flags); } } @@ -396,8 +382,7 @@ void input_inject_event(struct input_handle *handle, rcu_read_lock(); grab = rcu_dereference(dev->grab); if (!grab || grab == handle) - input_handle_event(dev, handle->handler, - type, code, value); + input_handle_event(dev, type, code, value); rcu_read_unlock(); spin_unlock_irqrestore(&dev->event_lock, flags); @@ -610,10 +595,10 @@ static void input_dev_release_keys(struct input_dev *dev) for (code = 0; code <= KEY_MAX; code++) { if (is_event_supported(code, dev->keybit, KEY_MAX) && __test_and_clear_bit(code, dev->key)) { - input_pass_event(dev, NULL, EV_KEY, code, 0); + input_pass_event(dev, EV_KEY, code, 0); } } - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } } @@ -888,9 +873,9 @@ int input_set_keycode(struct input_dev *dev, !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && __test_and_clear_bit(old_keycode, dev->key)) { - input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); + input_pass_event(dev, EV_KEY, old_keycode, 0); if (dev->sync) - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } out: @@ -1580,7 +1565,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) } \ } while (0) -static void input_dev_toggle(struct input_dev *dev, bool activate) +#ifdef CONFIG_PM +static void input_dev_reset(struct input_dev *dev, bool activate) { if (!dev->event) return; @@ -1594,44 +1580,12 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) } } -/** - * input_reset_device() - reset/restore the state of input device - * @dev: input device whose state needs to be reset - * - * This function tries to reset the state of an opened input device and - * bring internal state and state if the hardware in sync with each other. - * We mark all keys as released, restore LED state, repeat rate, etc. - */ -void input_reset_device(struct input_dev *dev) -{ - mutex_lock(&dev->mutex); - - if (dev->users) { - input_dev_toggle(dev, true); - - /* - * Keys that have been pressed at suspend time are unlikely - * to be still pressed when we resume. - */ - spin_lock_irq(&dev->event_lock); - input_dev_release_keys(dev); - spin_unlock_irq(&dev->event_lock); - } - - mutex_unlock(&dev->mutex); -} -EXPORT_SYMBOL(input_reset_device); - -#ifdef CONFIG_PM static int input_dev_suspend(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); mutex_lock(&input_dev->mutex); - - if (input_dev->users) - input_dev_toggle(input_dev, false); - + input_dev_reset(input_dev, false); mutex_unlock(&input_dev->mutex); return 0; @@ -1641,7 +1595,18 @@ static int input_dev_resume(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - input_reset_device(input_dev); + mutex_lock(&input_dev->mutex); + input_dev_reset(input_dev, true); + + /* + * Keys that have been pressed at suspend time are unlikely + * to be still pressed when we resume. + */ + spin_lock_irq(&input_dev->event_lock); + input_dev_release_keys(input_dev); + spin_unlock_irq(&input_dev->event_lock); + + mutex_unlock(&input_dev->mutex); return 0; } diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index af45d27..b92d1cd 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -4,7 +4,7 @@ * I2C QWERTY Keypad and IO Expander * Bugs: Enter bugs at http://blackfin.uclinux.org/ * - * Copyright (C) 2008-2010 Analog Devices Inc. + * Copyright (C) 2008-2009 Analog Devices Inc. * Licensed under the GPL-2 or later. */ @@ -24,6 +24,29 @@ #include + /* Configuration Register1 */ +#define AUTO_INC (1 << 7) +#define GPIEM_CFG (1 << 6) +#define OVR_FLOW_M (1 << 5) +#define INT_CFG (1 << 4) +#define OVR_FLOW_IEN (1 << 3) +#define K_LCK_IM (1 << 2) +#define GPI_IEN (1 << 1) +#define KE_IEN (1 << 0) + +/* Interrupt Status Register */ +#define CMP2_INT (1 << 5) +#define CMP1_INT (1 << 4) +#define OVR_FLOW_INT (1 << 3) +#define K_LCK_INT (1 << 2) +#define GPI_INT (1 << 1) +#define KE_INT (1 << 0) + +/* Key Lock and Event Counter Register */ +#define K_LCK_EN (1 << 6) +#define LCK21 0x30 +#define KEC 0xF + /* Key Event Register xy */ #define KEY_EV_PRESSED (1 << 7) #define KEY_EV_MASK (0x7F) @@ -32,6 +55,10 @@ #define KEYP_MAX_EVENT 10 +#define MAXGPIO 18 +#define ADP_BANK(offs) ((offs) >> 3) +#define ADP_BIT(offs) (1u << ((offs) & 0x7)) + /* * Early pre 4.0 Silicon required to delay readout by at least 25ms, * since the Event Counter Register updated 25ms after the interrupt @@ -48,7 +75,7 @@ struct adp5588_kpad { const struct adp5588_gpi_map *gpimap; unsigned short gpimapsize; #ifdef CONFIG_GPIOLIB - unsigned char gpiomap[ADP5588_MAXGPIO]; + unsigned char gpiomap[MAXGPIO]; bool export_gpio; struct gpio_chip gc; struct mutex gpio_lock; /* Protect cached dir, dat_out */ @@ -76,8 +103,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); } @@ -86,8 +113,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, unsigned off, int val) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); mutex_lock(&kpad->gpio_lock); @@ -105,8 +132,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); int ret; mutex_lock(&kpad->gpio_lock); @@ -123,8 +150,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, unsigned off, int val) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); int ret; mutex_lock(&kpad->gpio_lock); @@ -149,7 +176,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, const struct adp5588_kpad_platform_data *pdata) { - bool pin_used[ADP5588_MAXGPIO]; + bool pin_used[MAXGPIO]; int n_unused = 0; int i; @@ -164,7 +191,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, for (i = 0; i < kpad->gpimapsize; i++) pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; - for (i = 0; i < ADP5588_MAXGPIO; i++) + for (i = 0; i < MAXGPIO; i++) if (!pin_used[i]) kpad->gpiomap[n_unused++] = i; @@ -207,7 +234,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) return error; } - for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { kpad->dat_out[i] = adp5588_read(kpad->client, GPIO_DAT_OUT1 + i); kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); @@ -291,11 +318,11 @@ static void adp5588_work(struct work_struct *work) status = adp5588_read(client, INT_STAT); - if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */ + if (status & OVR_FLOW_INT) /* Unlikely and should never happen */ dev_err(&client->dev, "Event Overflow Error\n"); - if (status & ADP5588_KE_INT) { - ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC; + if (status & KE_INT) { + ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; if (ev_cnt) { adp5588_report_events(kpad, ev_cnt); input_sync(kpad->input); @@ -333,7 +360,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) if (pdata->en_keylock) { ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); - ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); + ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN); } for (i = 0; i < KEYP_MAX_EVENT; i++) @@ -357,7 +384,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) } if (gpio_data) { - for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { int pull_mask = gpio_data->pullup_dis_mask; ret |= adp5588_write(client, GPIO_PULL1 + i, @@ -365,14 +392,11 @@ static int __devinit adp5588_setup(struct i2c_client *client) } } - ret |= adp5588_write(client, INT_STAT, - ADP5588_CMP2_INT | ADP5588_CMP1_INT | - ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | - ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ + ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | + OVR_FLOW_INT | K_LCK_INT | + GPI_INT | KE_INT); /* Status is W1C */ - ret |= adp5588_write(client, CFG, ADP5588_INT_CFG | - ADP5588_OVR_FLOW_IEN | - ADP5588_KE_IEN); + ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN); if (ret < 0) { dev_err(&client->dev, "Write Error\n"); diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 11478eb..d358ef8 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -63,10 +63,6 @@ static bool atkbd_extra; module_param_named(extra, atkbd_extra, bool, 0); MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); -static bool atkbd_terminal; -module_param_named(terminal, atkbd_terminal, bool, 0); -MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); - /* * Scancode to keycode tables. These are just the default setting, and * are loadable via a userland utility. @@ -140,8 +136,7 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_CMD_ENABLE 0x00f4 #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ -#define ATKBD_CMD_SETALL_MB 0x00f8 /* Set all keys to give break codes */ -#define ATKBD_CMD_SETALL_MBR 0x00fa /* ... and repeat */ +#define ATKBD_CMD_SETALL_MBR 0x00fa #define ATKBD_CMD_RESET_BAT 0x02ff #define ATKBD_CMD_RESEND 0x00fe #define ATKBD_CMD_EX_ENABLE 0x10ea @@ -769,11 +764,6 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra } } - if (atkbd_terminal) { - ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB); - return 3; - } - if (target_set != 3) return 2; diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index d1583ae..4b42ffc 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -127,6 +127,14 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 idev->id.product = 0x0001; idev->id.version = 0x0100; + input_set_drvdata(idev, lp); + + ret = input_register_device(idev); + if (ret) { + dev_err(&client->dev, "input_register_device() failed\n"); + goto fail_register; + } + lp->laststate = read_state(lp); ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, @@ -134,21 +142,16 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 DRV_NAME, lp); if (ret) { dev_err(&client->dev, "IRQ %d is not free\n", client->irq); - goto fail_free_device; - } - - ret = input_register_device(idev); - if (ret) { - dev_err(&client->dev, "input_register_device() failed\n"); - goto fail_free_irq; + goto fail_irq; } i2c_set_clientdata(client, lp); return 0; - fail_free_irq: - free_irq(client->irq, lp); - fail_free_device: + fail_irq: + input_unregister_device(idev); + fail_register: + input_set_drvdata(idev, NULL); input_free_device(idev); fail_allocate: kfree(lp); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a5475b5..ed7ad74 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -351,17 +351,6 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { }, }, { - /* - * Most (all?) VAIOs do not have external PS/2 ports nor - * they implement active multiplexing properly, and - * MUX discovery usually messes up keyboard/touchpad. - */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "VAIO"), - }, - }, - { /* Amoi M636/A737 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index d94f7e9..aea9a93 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -229,13 +229,12 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ err = input_register_device(acecad->input); if (err) - goto fail3; + goto fail2; usb_set_intfdata(intf, acecad); return 0; - fail3: usb_free_urb(acecad->irq); fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); fail1: input_free_device(input_dev); kfree(acecad); diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 77b8fd2..cc2a88d 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -10,7 +10,7 @@ menuconfig NEW_LEDS if NEW_LEDS config LEDS_CLASS - bool "LED Class Support" + tristate "LED Class Support" help This option enables the led sysfs class in /sys/class/leds. You'll need this to do anything useful with LEDs. If unsure, say N. @@ -176,24 +176,6 @@ config LEDS_LP3944 To compile this driver as a module, choose M here: the module will be called leds-lp3944. -config LEDS_LP5521 - tristate "LED Support for N.S. LP5521 LED driver chip" - depends on LEDS_CLASS && I2C - help - If you say yes here you get support for the National Semiconductor - LP5521 LED driver. It is 3 channel chip with programmable engines. - Driver provides direct control via LED class and interface for - programming the engines. - -config LEDS_LP5523 - tristate "LED Support for N.S. LP5523 LED driver chip" - depends on LEDS_CLASS && I2C - help - If you say yes here you get support for the National Semiconductor - LP5523 LED driver. It is 9 channel chip with programmable engines. - Driver provides direct control via LED class and interface for - programming the engines. - config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" depends on X86 && SERIO_I8042 && DMI diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index aae6989..9c96db4 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -23,8 +23,6 @@ obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o -obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o -obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 211e21f..2606600 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -81,79 +81,6 @@ static struct device_attribute led_class_attrs[] = { __ATTR_NULL, }; -static void led_timer_function(unsigned long data) -{ - struct led_classdev *led_cdev = (void *)data; - unsigned long brightness; - unsigned long delay; - - if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { - led_set_brightness(led_cdev, LED_OFF); - return; - } - - brightness = led_get_brightness(led_cdev); - if (!brightness) { - /* Time to switch the LED on. */ - brightness = led_cdev->blink_brightness; - delay = led_cdev->blink_delay_on; - } else { - /* Store the current brightness value to be able - * to restore it when the delay_off period is over. - */ - led_cdev->blink_brightness = brightness; - brightness = LED_OFF; - delay = led_cdev->blink_delay_off; - } - - led_set_brightness(led_cdev, brightness); - - mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); -} - -static void led_stop_software_blink(struct led_classdev *led_cdev) -{ - /* deactivate previous settings */ - del_timer_sync(&led_cdev->blink_timer); - led_cdev->blink_delay_on = 0; - led_cdev->blink_delay_off = 0; -} - -static void led_set_software_blink(struct led_classdev *led_cdev, - unsigned long delay_on, - unsigned long delay_off) -{ - int current_brightness; - - current_brightness = led_get_brightness(led_cdev); - if (current_brightness) - led_cdev->blink_brightness = current_brightness; - if (!led_cdev->blink_brightness) - led_cdev->blink_brightness = led_cdev->max_brightness; - - if (delay_on == led_cdev->blink_delay_on && - delay_off == led_cdev->blink_delay_off) - return; - - led_stop_software_blink(led_cdev); - - led_cdev->blink_delay_on = delay_on; - led_cdev->blink_delay_off = delay_off; - - /* never on - don't blink */ - if (!delay_on) - return; - - /* never off - just set to brightness */ - if (!delay_off) { - led_set_brightness(led_cdev, led_cdev->blink_brightness); - return; - } - - mod_timer(&led_cdev->blink_timer, jiffies + 1); -} - - /** * led_classdev_suspend - suspend an led_classdev. * @led_cdev: the led_classdev to suspend. @@ -221,10 +148,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) led_update_brightness(led_cdev); - init_timer(&led_cdev->blink_timer); - led_cdev->blink_timer.function = led_timer_function; - led_cdev->blink_timer.data = (unsigned long)led_cdev; - #ifdef CONFIG_LEDS_TRIGGERS led_trigger_set_default(led_cdev); #endif @@ -234,6 +157,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) return 0; } + EXPORT_SYMBOL_GPL(led_classdev_register); /** @@ -251,9 +175,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); #endif - /* Stop blinking */ - led_brightness_set(led_cdev, LED_OFF); - device_unregister(led_cdev->dev); down_write(&leds_list_lock); @@ -262,30 +183,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev) } EXPORT_SYMBOL_GPL(led_classdev_unregister); -void led_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - if (led_cdev->blink_set && - led_cdev->blink_set(led_cdev, delay_on, delay_off)) - return; - - /* blink with 1 Hz as default if nothing specified */ - if (!*delay_on && !*delay_off) - *delay_on = *delay_off = 500; - - led_set_software_blink(led_cdev, *delay_on, *delay_off); -} -EXPORT_SYMBOL(led_blink_set); - -void led_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - led_stop_software_blink(led_cdev); - led_cdev->brightness_set(led_cdev, brightness); -} -EXPORT_SYMBOL(led_brightness_set); - static int __init leds_init(void) { leds_class = class_create(THIS_MODULE, "leds"); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index c41eb61..f1c00db 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -113,7 +113,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); led_cdev->trigger = NULL; - led_brightness_set(led_cdev, LED_OFF); + led_set_brightness(led_cdev, LED_OFF); } if (trigger) { write_lock_irqsave(&trigger->leddev_list_lock, flags); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 4d9fa38..ea57e05 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -316,7 +316,7 @@ static struct of_platform_driver of_gpio_leds_driver = { static int __init gpio_led_init(void) { - int ret = 0; + int ret; #ifdef CONFIG_LEDS_GPIO_PLATFORM ret = platform_driver_register(&gpio_led_driver); diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c deleted file mode 100644 index 3782f31..0000000 --- a/drivers/leds/leds-lp5521.c +++ /dev/null @@ -1,821 +0,0 @@ -/* - * LP5521 LED chip driver. - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LP5521_PROGRAM_LENGTH 32 /* in bytes */ - -#define LP5521_MAX_LEDS 3 /* Maximum number of LEDs */ -#define LP5521_MAX_ENGINES 3 /* Maximum number of engines */ - -#define LP5521_ENG_MASK_BASE 0x30 /* 00110000 */ -#define LP5521_ENG_STATUS_MASK 0x07 /* 00000111 */ - -#define LP5521_CMD_LOAD 0x15 /* 00010101 */ -#define LP5521_CMD_RUN 0x2a /* 00101010 */ -#define LP5521_CMD_DIRECT 0x3f /* 00111111 */ -#define LP5521_CMD_DISABLED 0x00 /* 00000000 */ - -/* Registers */ -#define LP5521_REG_ENABLE 0x00 -#define LP5521_REG_OP_MODE 0x01 -#define LP5521_REG_R_PWM 0x02 -#define LP5521_REG_G_PWM 0x03 -#define LP5521_REG_B_PWM 0x04 -#define LP5521_REG_R_CURRENT 0x05 -#define LP5521_REG_G_CURRENT 0x06 -#define LP5521_REG_B_CURRENT 0x07 -#define LP5521_REG_CONFIG 0x08 -#define LP5521_REG_R_CHANNEL_PC 0x09 -#define LP5521_REG_G_CHANNEL_PC 0x0A -#define LP5521_REG_B_CHANNEL_PC 0x0B -#define LP5521_REG_STATUS 0x0C -#define LP5521_REG_RESET 0x0D -#define LP5521_REG_GPO 0x0E -#define LP5521_REG_R_PROG_MEM 0x10 -#define LP5521_REG_G_PROG_MEM 0x30 -#define LP5521_REG_B_PROG_MEM 0x50 - -#define LP5521_PROG_MEM_BASE LP5521_REG_R_PROG_MEM -#define LP5521_PROG_MEM_SIZE 0x20 - -/* Base register to set LED current */ -#define LP5521_REG_LED_CURRENT_BASE LP5521_REG_R_CURRENT - -/* Base register to set the brightness */ -#define LP5521_REG_LED_PWM_BASE LP5521_REG_R_PWM - -/* Bits in ENABLE register */ -#define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */ -#define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */ -#define LP5521_EXEC_RUN 0x2A - -/* Bits in CONFIG register */ -#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */ -#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */ -#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */ -#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */ -#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */ -#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */ -#define LP5521_R_TO_BATT 4 /* R out: 0 = CP, 1 = Vbat */ -#define LP5521_CLK_SRC_EXT 0 /* Ext-clk source (CLK_32K) */ -#define LP5521_CLK_INT 1 /* Internal clock */ -#define LP5521_CLK_AUTO 2 /* Automatic clock selection */ - -/* Status */ -#define LP5521_EXT_CLK_USED 0x08 - -struct lp5521_engine { - const struct attribute_group *attributes; - int id; - u8 mode; - u8 prog_page; - u8 engine_mask; -}; - -struct lp5521_led { - int id; - u8 chan_nr; - u8 led_current; - u8 max_current; - struct led_classdev cdev; - struct work_struct brightness_work; - u8 brightness; -}; - -struct lp5521_chip { - struct lp5521_platform_data *pdata; - struct mutex lock; /* Serialize control */ - struct i2c_client *client; - struct lp5521_engine engines[LP5521_MAX_ENGINES]; - struct lp5521_led leds[LP5521_MAX_LEDS]; - u8 num_channels; - u8 num_leds; -}; - -#define cdev_to_led(c) container_of(c, struct lp5521_led, cdev) -#define engine_to_lp5521(eng) container_of((eng), struct lp5521_chip, \ - engines[(eng)->id - 1]) -#define led_to_lp5521(led) container_of((led), struct lp5521_chip, \ - leds[(led)->id]) - -static void lp5521_led_brightness_work(struct work_struct *work); - -static inline int lp5521_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf) -{ - s32 ret; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) - return -EIO; - - *buf = ret; - return 0; -} - -static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode) -{ - struct lp5521_chip *chip = engine_to_lp5521(engine); - struct i2c_client *client = chip->client; - int ret; - u8 engine_state; - - /* Only transition between RUN and DIRECT mode are handled here */ - if (mode == LP5521_CMD_LOAD) - return 0; - - if (mode == LP5521_CMD_DISABLED) - mode = LP5521_CMD_DIRECT; - - ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); - - /* set mode only for this engine */ - engine_state &= ~(engine->engine_mask); - mode &= engine->engine_mask; - engine_state |= mode; - ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state); - - return ret; -} - -static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) -{ - struct lp5521_chip *chip = engine_to_lp5521(eng); - struct i2c_client *client = chip->client; - int ret; - int addr; - u8 mode; - - /* move current engine to direct mode and remember the state */ - ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT); - usleep_range(1000, 10000); - ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode); - - /* For loading, all the engines to load mode */ - lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); - usleep_range(1000, 10000); - lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD); - usleep_range(1000, 10000); - - addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE; - i2c_smbus_write_i2c_block_data(client, - addr, - LP5521_PROG_MEM_SIZE, - pattern); - - ret |= lp5521_write(client, LP5521_REG_OP_MODE, mode); - return ret; -} - -static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) -{ - return lp5521_write(chip->client, - LP5521_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, - curr); -} - -static void lp5521_init_engine(struct lp5521_chip *chip, - const struct attribute_group *attr_group) -{ - int i; - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { - chip->engines[i].id = i + 1; - chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); - chip->engines[i].prog_page = i; - chip->engines[i].attributes = &attr_group[i]; - } -} - -static int lp5521_configure(struct i2c_client *client, - const struct attribute_group *attr_group) -{ - struct lp5521_chip *chip = i2c_get_clientdata(client); - int ret; - - lp5521_init_engine(chip, attr_group); - - lp5521_write(client, LP5521_REG_RESET, 0xff); - - usleep_range(10000, 20000); - - /* Set all PWMs to direct control mode */ - ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); - - /* Enable auto-powersave, set charge pump to auto, red to battery */ - ret |= lp5521_write(client, LP5521_REG_CONFIG, - LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); - - /* Initialize all channels PWM to zero -> leds off */ - ret |= lp5521_write(client, LP5521_REG_R_PWM, 0); - ret |= lp5521_write(client, LP5521_REG_G_PWM, 0); - ret |= lp5521_write(client, LP5521_REG_B_PWM, 0); - - /* Set engines are set to run state when OP_MODE enables engines */ - ret |= lp5521_write(client, LP5521_REG_ENABLE, - LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM | - LP5521_EXEC_RUN); - /* enable takes 500us */ - usleep_range(500, 20000); - - return ret; -} - -static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf) -{ - int ret; - u8 status; - - ret = lp5521_read(chip->client, LP5521_REG_STATUS, &status); - if (ret < 0) - return ret; - - /* Check that ext clock is really in use if requested */ - if (chip->pdata && chip->pdata->clock_mode == LP5521_CLOCK_EXT) - if ((status & LP5521_EXT_CLK_USED) == 0) - return -EIO; - return 0; -} - -static void lp5521_set_brightness(struct led_classdev *cdev, - enum led_brightness brightness) -{ - struct lp5521_led *led = cdev_to_led(cdev); - led->brightness = (u8)brightness; - schedule_work(&led->brightness_work); -} - -static void lp5521_led_brightness_work(struct work_struct *work) -{ - struct lp5521_led *led = container_of(work, - struct lp5521_led, - brightness_work); - struct lp5521_chip *chip = led_to_lp5521(led); - struct i2c_client *client = chip->client; - - mutex_lock(&chip->lock); - lp5521_write(client, LP5521_REG_LED_PWM_BASE + led->chan_nr, - led->brightness); - mutex_unlock(&chip->lock); -} - -/* Detect the chip by setting its ENABLE register and reading it back. */ -static int lp5521_detect(struct i2c_client *client) -{ - int ret; - u8 buf; - - ret = lp5521_write(client, LP5521_REG_ENABLE, - LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM); - if (ret) - return ret; - usleep_range(1000, 10000); - ret = lp5521_read(client, LP5521_REG_ENABLE, &buf); - if (ret) - return ret; - if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)) - return -ENODEV; - - return 0; -} - -/* Set engine mode and create appropriate sysfs attributes, if required. */ -static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) -{ - struct lp5521_chip *chip = engine_to_lp5521(engine); - struct i2c_client *client = chip->client; - struct device *dev = &client->dev; - int ret = 0; - - /* if in that mode already do nothing, except for run */ - if (mode == engine->mode && mode != LP5521_CMD_RUN) - return 0; - - if (mode == LP5521_CMD_RUN) { - ret = lp5521_set_engine_mode(engine, LP5521_CMD_RUN); - } else if (mode == LP5521_CMD_LOAD) { - lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); - lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); - - ret = sysfs_create_group(&dev->kobj, engine->attributes); - if (ret) - return ret; - } else if (mode == LP5521_CMD_DISABLED) { - lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); - } - - /* remove load attribute from sysfs if not in load mode */ - if (engine->mode == LP5521_CMD_LOAD && mode != LP5521_CMD_LOAD) - sysfs_remove_group(&dev->kobj, engine->attributes); - - engine->mode = mode; - - return ret; -} - -static int lp5521_do_store_load(struct lp5521_engine *engine, - const char *buf, size_t len) -{ - struct lp5521_chip *chip = engine_to_lp5521(engine); - struct i2c_client *client = chip->client; - int ret, nrchars, offset = 0, i = 0; - char c[3]; - unsigned cmd; - u8 pattern[LP5521_PROGRAM_LENGTH] = {0}; - - while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) { - /* separate sscanfs because length is working only for %s */ - ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); - ret = sscanf(c, "%2x", &cmd); - if (ret != 1) - goto fail; - pattern[i] = (u8)cmd; - - offset += nrchars; - i++; - } - - /* Each instruction is 16bit long. Check that length is even */ - if (i % 2) - goto fail; - - mutex_lock(&chip->lock); - ret = lp5521_load_program(engine, pattern); - mutex_unlock(&chip->lock); - - if (ret) { - dev_err(&client->dev, "failed loading pattern\n"); - return ret; - } - - return len; -fail: - dev_err(&client->dev, "wrong pattern format\n"); - return -EINVAL; -} - -static ssize_t store_engine_load(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - return lp5521_do_store_load(&chip->engines[nr - 1], buf, len); -} - -#define store_load(nr) \ -static ssize_t store_engine##nr##_load(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_load(dev, attr, buf, len, nr); \ -} -store_load(1) -store_load(2) -store_load(3) - -static ssize_t show_engine_mode(struct device *dev, - struct device_attribute *attr, - char *buf, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - switch (chip->engines[nr - 1].mode) { - case LP5521_CMD_RUN: - return sprintf(buf, "run\n"); - case LP5521_CMD_LOAD: - return sprintf(buf, "load\n"); - case LP5521_CMD_DISABLED: - return sprintf(buf, "disabled\n"); - default: - return sprintf(buf, "disabled\n"); - } -} - -#define show_mode(nr) \ -static ssize_t show_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_engine_mode(dev, attr, buf, nr); \ -} -show_mode(1) -show_mode(2) -show_mode(3) - -static ssize_t store_engine_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - struct lp5521_engine *engine = &chip->engines[nr - 1]; - mutex_lock(&chip->lock); - - if (!strncmp(buf, "run", 3)) - lp5521_set_mode(engine, LP5521_CMD_RUN); - else if (!strncmp(buf, "load", 4)) - lp5521_set_mode(engine, LP5521_CMD_LOAD); - else if (!strncmp(buf, "disabled", 8)) - lp5521_set_mode(engine, LP5521_CMD_DISABLED); - - mutex_unlock(&chip->lock); - return len; -} - -#define store_mode(nr) \ -static ssize_t store_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_mode(dev, attr, buf, len, nr); \ -} -store_mode(1) -store_mode(2) -store_mode(3) - -static ssize_t show_max_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5521_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->max_current); -} - -static ssize_t show_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5521_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->led_current); -} - -static ssize_t store_current(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5521_led *led = cdev_to_led(led_cdev); - struct lp5521_chip *chip = led_to_lp5521(led); - ssize_t ret; - unsigned long curr; - - if (strict_strtoul(buf, 0, &curr)) - return -EINVAL; - - if (curr > led->max_current) - return -EINVAL; - - mutex_lock(&chip->lock); - ret = lp5521_set_led_current(chip, led->id, curr); - mutex_unlock(&chip->lock); - - if (ret < 0) - return ret; - - led->led_current = (u8)curr; - - return len; -} - -static ssize_t lp5521_selftest(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - int ret; - - mutex_lock(&chip->lock); - ret = lp5521_run_selftest(chip, buf); - mutex_unlock(&chip->lock); - return sprintf(buf, "%s\n", ret ? "FAIL" : "OK"); -} - -/* led class device attributes */ -static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); -static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); - -static struct attribute *lp5521_led_attributes[] = { - &dev_attr_led_current.attr, - &dev_attr_max_current.attr, - NULL, -}; - -static struct attribute_group lp5521_led_attribute_group = { - .attrs = lp5521_led_attributes -}; - -/* device attributes */ -static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, - show_engine1_mode, store_engine1_mode); -static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, - show_engine2_mode, store_engine2_mode); -static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, - show_engine3_mode, store_engine3_mode); -static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); -static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); -static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); -static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); - -static struct attribute *lp5521_attributes[] = { - &dev_attr_engine1_mode.attr, - &dev_attr_engine2_mode.attr, - &dev_attr_engine3_mode.attr, - &dev_attr_selftest.attr, - NULL -}; - -static struct attribute *lp5521_engine1_attributes[] = { - &dev_attr_engine1_load.attr, - NULL -}; - -static struct attribute *lp5521_engine2_attributes[] = { - &dev_attr_engine2_load.attr, - NULL -}; - -static struct attribute *lp5521_engine3_attributes[] = { - &dev_attr_engine3_load.attr, - NULL -}; - -static const struct attribute_group lp5521_group = { - .attrs = lp5521_attributes, -}; - -static const struct attribute_group lp5521_engine_group[] = { - {.attrs = lp5521_engine1_attributes }, - {.attrs = lp5521_engine2_attributes }, - {.attrs = lp5521_engine3_attributes }, -}; - -static int lp5521_register_sysfs(struct i2c_client *client) -{ - struct device *dev = &client->dev; - return sysfs_create_group(&dev->kobj, &lp5521_group); -} - -static void lp5521_unregister_sysfs(struct i2c_client *client) -{ - struct lp5521_chip *chip = i2c_get_clientdata(client); - struct device *dev = &client->dev; - int i; - - sysfs_remove_group(&dev->kobj, &lp5521_group); - - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { - if (chip->engines[i].mode == LP5521_CMD_LOAD) - sysfs_remove_group(&dev->kobj, - chip->engines[i].attributes); - } - - for (i = 0; i < chip->num_leds; i++) - sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, - &lp5521_led_attribute_group); -} - -static int __init lp5521_init_led(struct lp5521_led *led, - struct i2c_client *client, - int chan, struct lp5521_platform_data *pdata) -{ - struct device *dev = &client->dev; - char name[32]; - int res; - - if (chan >= LP5521_MAX_LEDS) - return -EINVAL; - - if (pdata->led_config[chan].led_current == 0) - return 0; - - led->led_current = pdata->led_config[chan].led_current; - led->max_current = pdata->led_config[chan].max_current; - led->chan_nr = pdata->led_config[chan].chan_nr; - - if (led->chan_nr >= LP5521_MAX_LEDS) { - dev_err(dev, "Use channel numbers between 0 and %d\n", - LP5521_MAX_LEDS - 1); - return -EINVAL; - } - - snprintf(name, sizeof(name), "%s:channel%d", client->name, chan); - led->cdev.brightness_set = lp5521_set_brightness; - led->cdev.name = name; - res = led_classdev_register(dev, &led->cdev); - if (res < 0) { - dev_err(dev, "couldn't register led on channel %d\n", chan); - return res; - } - - res = sysfs_create_group(&led->cdev.dev->kobj, - &lp5521_led_attribute_group); - if (res < 0) { - dev_err(dev, "couldn't register current attribute\n"); - led_classdev_unregister(&led->cdev); - return res; - } - return 0; -} - -static int lp5521_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp5521_chip *chip; - struct lp5521_platform_data *pdata; - int ret, i, led; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - i2c_set_clientdata(client, chip); - chip->client = client; - - pdata = client->dev.platform_data; - - if (!pdata) { - dev_err(&client->dev, "no platform data\n"); - ret = -EINVAL; - goto fail1; - } - - mutex_init(&chip->lock); - - chip->pdata = pdata; - - if (pdata->setup_resources) { - ret = pdata->setup_resources(); - if (ret < 0) - goto fail1; - } - - if (pdata->enable) { - pdata->enable(0); - usleep_range(1000, 10000); - pdata->enable(1); - usleep_range(1000, 10000); /* Spec says min 500us */ - } - - ret = lp5521_detect(client); - - if (ret) { - dev_err(&client->dev, "Chip not found\n"); - goto fail2; - } - - dev_info(&client->dev, "%s programmable led chip found\n", id->name); - - ret = lp5521_configure(client, lp5521_engine_group); - if (ret < 0) { - dev_err(&client->dev, "error configuring chip\n"); - goto fail2; - } - - /* Initialize leds */ - chip->num_channels = pdata->num_channels; - chip->num_leds = 0; - led = 0; - for (i = 0; i < pdata->num_channels; i++) { - /* Do not initialize channels that are not connected */ - if (pdata->led_config[i].led_current == 0) - continue; - - ret = lp5521_init_led(&chip->leds[led], client, i, pdata); - if (ret) { - dev_err(&client->dev, "error initializing leds\n"); - goto fail3; - } - chip->num_leds++; - - chip->leds[led].id = led; - /* Set initial LED current */ - lp5521_set_led_current(chip, led, - chip->leds[led].led_current); - - INIT_WORK(&(chip->leds[led].brightness_work), - lp5521_led_brightness_work); - - led++; - } - - ret = lp5521_register_sysfs(client); - if (ret) { - dev_err(&client->dev, "registering sysfs failed\n"); - goto fail3; - } - return ret; -fail3: - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } -fail2: - if (pdata->enable) - pdata->enable(0); - if (pdata->release_resources) - pdata->release_resources(); -fail1: - kfree(chip); - return ret; -} - -static int lp5521_remove(struct i2c_client *client) -{ - struct lp5521_chip *chip = i2c_get_clientdata(client); - int i; - - lp5521_unregister_sysfs(client); - - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } - - if (chip->pdata->enable) - chip->pdata->enable(0); - if (chip->pdata->release_resources) - chip->pdata->release_resources(); - kfree(chip); - return 0; -} - -static const struct i2c_device_id lp5521_id[] = { - { "lp5521", 0 }, /* Three channel chip */ - { } -}; -MODULE_DEVICE_TABLE(i2c, lp5521_id); - -static struct i2c_driver lp5521_driver = { - .driver = { - .name = "lp5521", - }, - .probe = lp5521_probe, - .remove = lp5521_remove, - .id_table = lp5521_id, -}; - -static int __init lp5521_init(void) -{ - int ret; - - ret = i2c_add_driver(&lp5521_driver); - - if (ret < 0) - printk(KERN_ALERT "Adding lp5521 driver failed\n"); - - return ret; -} - -static void __exit lp5521_exit(void) -{ - i2c_del_driver(&lp5521_driver); -} - -module_init(lp5521_init); -module_exit(lp5521_exit); - -MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo"); -MODULE_DESCRIPTION("LP5521 LED engine"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c deleted file mode 100644 index 1e11fcc..0000000 --- a/drivers/leds/leds-lp5523.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * lp5523.c - LP5523 LED Driver - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LP5523_REG_ENABLE 0x00 -#define LP5523_REG_OP_MODE 0x01 -#define LP5523_REG_RATIOMETRIC_MSB 0x02 -#define LP5523_REG_RATIOMETRIC_LSB 0x03 -#define LP5523_REG_ENABLE_LEDS_MSB 0x04 -#define LP5523_REG_ENABLE_LEDS_LSB 0x05 -#define LP5523_REG_LED_CNTRL_BASE 0x06 -#define LP5523_REG_LED_PWM_BASE 0x16 -#define LP5523_REG_LED_CURRENT_BASE 0x26 -#define LP5523_REG_CONFIG 0x36 -#define LP5523_REG_CHANNEL1_PC 0x37 -#define LP5523_REG_CHANNEL2_PC 0x38 -#define LP5523_REG_CHANNEL3_PC 0x39 -#define LP5523_REG_STATUS 0x3a -#define LP5523_REG_GPO 0x3b -#define LP5523_REG_VARIABLE 0x3c -#define LP5523_REG_RESET 0x3d -#define LP5523_REG_TEMP_CTRL 0x3e -#define LP5523_REG_TEMP_READ 0x3f -#define LP5523_REG_TEMP_WRITE 0x40 -#define LP5523_REG_LED_TEST_CTRL 0x41 -#define LP5523_REG_LED_TEST_ADC 0x42 -#define LP5523_REG_ENG1_VARIABLE 0x45 -#define LP5523_REG_ENG2_VARIABLE 0x46 -#define LP5523_REG_ENG3_VARIABLE 0x47 -#define LP5523_REG_MASTER_FADER1 0x48 -#define LP5523_REG_MASTER_FADER2 0x49 -#define LP5523_REG_MASTER_FADER3 0x4a -#define LP5523_REG_CH1_PROG_START 0x4c -#define LP5523_REG_CH2_PROG_START 0x4d -#define LP5523_REG_CH3_PROG_START 0x4e -#define LP5523_REG_PROG_PAGE_SEL 0x4f -#define LP5523_REG_PROG_MEM 0x50 - -#define LP5523_CMD_LOAD 0x15 /* 00010101 */ -#define LP5523_CMD_RUN 0x2a /* 00101010 */ -#define LP5523_CMD_DISABLED 0x00 /* 00000000 */ - -#define LP5523_ENABLE 0x40 -#define LP5523_AUTO_INC 0x40 -#define LP5523_PWR_SAVE 0x20 -#define LP5523_PWM_PWR_SAVE 0x04 -#define LP5523_CP_1 0x08 -#define LP5523_CP_1_5 0x10 -#define LP5523_CP_AUTO 0x18 -#define LP5523_INT_CLK 0x01 -#define LP5523_AUTO_CLK 0x02 -#define LP5523_EN_LEDTEST 0x80 -#define LP5523_LEDTEST_DONE 0x80 - -#define LP5523_DEFAULT_CURRENT 50 /* microAmps */ -#define LP5523_PROGRAM_LENGTH 32 /* in bytes */ -#define LP5523_PROGRAM_PAGES 6 -#define LP5523_ADC_SHORTCIRC_LIM 80 - -#define LP5523_LEDS 9 -#define LP5523_ENGINES 3 - -#define LP5523_ENG_MASK_BASE 0x30 /* 00110000 */ - -#define LP5523_ENG_STATUS_MASK 0x07 /* 00000111 */ - -#define LP5523_IRQ_FLAGS IRQF_TRIGGER_FALLING - -#define LP5523_EXT_CLK_USED 0x08 - -#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) -#define SHIFT_MASK(id) (((id) - 1) * 2) - -struct lp5523_engine { - const struct attribute_group *attributes; - int id; - u8 mode; - u8 prog_page; - u8 mux_page; - u16 led_mux; - u8 engine_mask; -}; - -struct lp5523_led { - int id; - u8 chan_nr; - u8 led_current; - u8 max_current; - struct led_classdev cdev; - struct work_struct brightness_work; - u8 brightness; -}; - -struct lp5523_chip { - struct mutex lock; /* Serialize control */ - struct i2c_client *client; - struct lp5523_engine engines[LP5523_ENGINES]; - struct lp5523_led leds[LP5523_LEDS]; - struct lp5523_platform_data *pdata; - u8 num_channels; - u8 num_leds; -}; - -#define cdev_to_led(c) container_of(c, struct lp5523_led, cdev) - -static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine) -{ - return container_of(engine, struct lp5523_chip, - engines[engine->id - 1]); -} - -static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led) -{ - return container_of(led, struct lp5523_chip, - leds[led->id]); -} - -static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode); -static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode); -static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern); - -static void lp5523_led_brightness_work(struct work_struct *work); - -static int lp5523_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int lp5523_read(struct i2c_client *client, u8 reg, u8 *buf) -{ - s32 ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) - return -EIO; - - *buf = ret; - return 0; -} - -static int lp5523_detect(struct i2c_client *client) -{ - int ret; - u8 buf; - - ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40); - if (ret) - return ret; - ret = lp5523_read(client, LP5523_REG_ENABLE, &buf); - if (ret) - return ret; - if (buf == 0x40) - return 0; - else - return -ENODEV; -} - -static int lp5523_configure(struct i2c_client *client) -{ - struct lp5523_chip *chip = i2c_get_clientdata(client); - int ret = 0; - u8 status; - - /* one pattern per engine setting led mux start and stop addresses */ - u8 pattern[][LP5523_PROGRAM_LENGTH] = { - { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0}, - { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0}, - { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, - }; - - lp5523_write(client, LP5523_REG_RESET, 0xff); - - usleep_range(10000, 100000); - - ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE); - /* Chip startup time after reset is 500 us */ - usleep_range(1000, 10000); - - ret |= lp5523_write(client, LP5523_REG_CONFIG, - LP5523_AUTO_INC | LP5523_PWR_SAVE | - LP5523_CP_AUTO | LP5523_AUTO_CLK | - LP5523_PWM_PWR_SAVE); - - /* turn on all leds */ - ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_MSB, 0x01); - ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_LSB, 0xff); - - /* hardcode 32 bytes of memory for each engine from program memory */ - ret |= lp5523_write(client, LP5523_REG_CH1_PROG_START, 0x00); - ret |= lp5523_write(client, LP5523_REG_CH2_PROG_START, 0x10); - ret |= lp5523_write(client, LP5523_REG_CH3_PROG_START, 0x20); - - /* write led mux address space for each channel */ - ret |= lp5523_load_program(&chip->engines[0], pattern[0]); - ret |= lp5523_load_program(&chip->engines[1], pattern[1]); - ret |= lp5523_load_program(&chip->engines[2], pattern[2]); - - if (ret) { - dev_err(&client->dev, "could not load mux programs\n"); - return -1; - } - - /* set all engines exec state and mode to run 00101010 */ - ret |= lp5523_write(client, LP5523_REG_ENABLE, - (LP5523_CMD_RUN | LP5523_ENABLE)); - - ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_RUN); - - if (ret) { - dev_err(&client->dev, "could not start mux programs\n"); - return -1; - } - - /* Wait 3ms and check the engine status */ - usleep_range(3000, 20000); - lp5523_read(client, LP5523_REG_STATUS, &status); - status &= LP5523_ENG_STATUS_MASK; - - if (status == LP5523_ENG_STATUS_MASK) { - dev_dbg(&client->dev, "all engines configured\n"); - } else { - dev_info(&client->dev, "status == %x\n", status); - dev_err(&client->dev, "cound not configure LED engine\n"); - return -1; - } - - dev_info(&client->dev, "disabling engines\n"); - - ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED); - - return ret; -} - -static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret; - u8 engine_state; - - ret = lp5523_read(client, LP5523_REG_OP_MODE, &engine_state); - if (ret) - goto fail; - - engine_state &= ~(engine->engine_mask); - - /* set mode only for this engine */ - mode &= engine->engine_mask; - - engine_state |= mode; - - ret |= lp5523_write(client, LP5523_REG_OP_MODE, engine_state); -fail: - return ret; -} - -static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret = 0; - - ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); - - ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, engine->mux_page); - ret |= lp5523_write(client, LP5523_REG_PROG_MEM, - (u8)(mux >> 8)); - ret |= lp5523_write(client, LP5523_REG_PROG_MEM + 1, (u8)(mux)); - engine->led_mux = mux; - - return ret; -} - -static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - - int ret = 0; - - ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); - - ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, - engine->prog_page); - ret |= i2c_smbus_write_i2c_block_data(client, LP5523_REG_PROG_MEM, - LP5523_PROGRAM_LENGTH, pattern); - - return ret; -} - -static int lp5523_run_program(struct lp5523_engine *engine) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret; - - ret = lp5523_write(client, LP5523_REG_ENABLE, - LP5523_CMD_RUN | LP5523_ENABLE); - if (ret) - goto fail; - - ret = lp5523_set_engine_mode(engine, LP5523_CMD_RUN); -fail: - return ret; -} - -static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len) -{ - int i; - u16 tmp_mux = 0; - len = len < LP5523_LEDS ? len : LP5523_LEDS; - for (i = 0; i < len; i++) { - switch (buf[i]) { - case '1': - tmp_mux |= (1 << i); - break; - case '0': - break; - case '\n': - i = len; - break; - default: - return -1; - } - } - *mux = tmp_mux; - - return 0; -} - -static void lp5523_mux_to_array(u16 led_mux, char *array) -{ - int i, pos = 0; - for (i = 0; i < LP5523_LEDS; i++) - pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i)); - - array[pos] = '\0'; -} - -/*--------------------------------------------------------------*/ -/* Sysfs interface */ -/*--------------------------------------------------------------*/ - -static ssize_t show_engine_leds(struct device *dev, - struct device_attribute *attr, - char *buf, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - char mux[LP5523_LEDS + 1]; - - lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux); - - return sprintf(buf, "%s\n", mux); -} - -#define show_leds(nr) \ -static ssize_t show_engine##nr##_leds(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_engine_leds(dev, attr, buf, nr); \ -} -show_leds(1) -show_leds(2) -show_leds(3) - -static ssize_t store_engine_leds(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - u16 mux = 0; - - if (lp5523_mux_parse(buf, &mux, len)) - return -EINVAL; - - if (lp5523_load_mux(&chip->engines[nr - 1], mux)) - return -EINVAL; - - return len; -} - -#define store_leds(nr) \ -static ssize_t store_engine##nr##_leds(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_leds(dev, attr, buf, len, nr); \ -} -store_leds(1) -store_leds(2) -store_leds(3) - -static ssize_t lp5523_selftest(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - int i, ret, pos = 0; - int led = 0; - u8 status, adc, vdd; - - mutex_lock(&chip->lock); - - ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); - if (ret < 0) - goto fail; - - /* Check that ext clock is really in use if requested */ - if ((chip->pdata) && (chip->pdata->clock_mode == LP5523_CLOCK_EXT)) - if ((status & LP5523_EXT_CLK_USED) == 0) - goto fail; - - /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ - lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL, - LP5523_EN_LEDTEST | 16); - usleep_range(3000, 10000); - ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); - if (!(status & LP5523_LEDTEST_DONE)) - usleep_range(3000, 10000); - - ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd); - vdd--; /* There may be some fluctuation in measurement */ - - for (i = 0; i < LP5523_LEDS; i++) { - /* Skip non-existing channels */ - if (chip->pdata->led_config[i].led_current == 0) - continue; - - /* Set default current */ - lp5523_write(chip->client, - LP5523_REG_LED_CURRENT_BASE + i, - chip->pdata->led_config[i].led_current); - - lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff); - /* let current stabilize 2ms before measurements start */ - usleep_range(2000, 10000); - lp5523_write(chip->client, - LP5523_REG_LED_TEST_CTRL, - LP5523_EN_LEDTEST | i); - /* ledtest takes 2.7ms */ - usleep_range(3000, 10000); - ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); - if (!(status & LP5523_LEDTEST_DONE)) - usleep_range(3000, 10000); - ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc); - - if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) - pos += sprintf(buf + pos, "LED %d FAIL\n", i); - - lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0x00); - - /* Restore current */ - lp5523_write(chip->client, - LP5523_REG_LED_CURRENT_BASE + i, - chip->leds[led].led_current); - led++; - } - if (pos == 0) - pos = sprintf(buf, "OK\n"); - goto release_lock; -fail: - pos = sprintf(buf, "FAIL\n"); - -release_lock: - mutex_unlock(&chip->lock); - - return pos; -} - -static void lp5523_set_brightness(struct led_classdev *cdev, - enum led_brightness brightness) -{ - struct lp5523_led *led = cdev_to_led(cdev); - - led->brightness = (u8)brightness; - - schedule_work(&led->brightness_work); -} - -static void lp5523_led_brightness_work(struct work_struct *work) -{ - struct lp5523_led *led = container_of(work, - struct lp5523_led, - brightness_work); - struct lp5523_chip *chip = led_to_lp5523(led); - struct i2c_client *client = chip->client; - - mutex_lock(&chip->lock); - - lp5523_write(client, LP5523_REG_LED_PWM_BASE + led->chan_nr, - led->brightness); - - mutex_unlock(&chip->lock); -} - -static int lp5523_do_store_load(struct lp5523_engine *engine, - const char *buf, size_t len) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret, nrchars, offset = 0, i = 0; - char c[3]; - unsigned cmd; - u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; - - while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) { - /* separate sscanfs because length is working only for %s */ - ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); - ret = sscanf(c, "%2x", &cmd); - if (ret != 1) - goto fail; - pattern[i] = (u8)cmd; - - offset += nrchars; - i++; - } - - /* Each instruction is 16bit long. Check that length is even */ - if (i % 2) - goto fail; - - mutex_lock(&chip->lock); - - ret = lp5523_load_program(engine, pattern); - mutex_unlock(&chip->lock); - - if (ret) { - dev_err(&client->dev, "failed loading pattern\n"); - return ret; - } - - return len; -fail: - dev_err(&client->dev, "wrong pattern format\n"); - return -EINVAL; -} - -static ssize_t store_engine_load(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - return lp5523_do_store_load(&chip->engines[nr - 1], buf, len); -} - -#define store_load(nr) \ -static ssize_t store_engine##nr##_load(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_load(dev, attr, buf, len, nr); \ -} -store_load(1) -store_load(2) -store_load(3) - -static ssize_t show_engine_mode(struct device *dev, - struct device_attribute *attr, - char *buf, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - switch (chip->engines[nr - 1].mode) { - case LP5523_CMD_RUN: - return sprintf(buf, "run\n"); - case LP5523_CMD_LOAD: - return sprintf(buf, "load\n"); - case LP5523_CMD_DISABLED: - return sprintf(buf, "disabled\n"); - default: - return sprintf(buf, "disabled\n"); - } -} - -#define show_mode(nr) \ -static ssize_t show_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_engine_mode(dev, attr, buf, nr); \ -} -show_mode(1) -show_mode(2) -show_mode(3) - -static ssize_t store_engine_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - struct lp5523_engine *engine = &chip->engines[nr - 1]; - mutex_lock(&chip->lock); - - if (!strncmp(buf, "run", 3)) - lp5523_set_mode(engine, LP5523_CMD_RUN); - else if (!strncmp(buf, "load", 4)) - lp5523_set_mode(engine, LP5523_CMD_LOAD); - else if (!strncmp(buf, "disabled", 8)) - lp5523_set_mode(engine, LP5523_CMD_DISABLED); - - mutex_unlock(&chip->lock); - return len; -} - -#define store_mode(nr) \ -static ssize_t store_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_mode(dev, attr, buf, len, nr); \ -} -store_mode(1) -store_mode(2) -store_mode(3) - -static ssize_t show_max_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5523_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->max_current); -} - -static ssize_t show_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5523_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->led_current); -} - -static ssize_t store_current(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5523_led *led = cdev_to_led(led_cdev); - struct lp5523_chip *chip = led_to_lp5523(led); - ssize_t ret; - unsigned long curr; - - if (strict_strtoul(buf, 0, &curr)) - return -EINVAL; - - if (curr > led->max_current) - return -EINVAL; - - mutex_lock(&chip->lock); - ret = lp5523_write(chip->client, - LP5523_REG_LED_CURRENT_BASE + led->chan_nr, - (u8)curr); - mutex_unlock(&chip->lock); - - if (ret < 0) - return ret; - - led->led_current = (u8)curr; - - return len; -} - -/* led class device attributes */ -static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); -static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); - -static struct attribute *lp5523_led_attributes[] = { - &dev_attr_led_current.attr, - &dev_attr_max_current.attr, - NULL, -}; - -static struct attribute_group lp5523_led_attribute_group = { - .attrs = lp5523_led_attributes -}; - -/* device attributes */ -static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, - show_engine1_mode, store_engine1_mode); -static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, - show_engine2_mode, store_engine2_mode); -static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, - show_engine3_mode, store_engine3_mode); -static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO, - show_engine1_leds, store_engine1_leds); -static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO, - show_engine2_leds, store_engine2_leds); -static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO, - show_engine3_leds, store_engine3_leds); -static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); -static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); -static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); -static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL); - -static struct attribute *lp5523_attributes[] = { - &dev_attr_engine1_mode.attr, - &dev_attr_engine2_mode.attr, - &dev_attr_engine3_mode.attr, - &dev_attr_selftest.attr, - NULL -}; - -static struct attribute *lp5523_engine1_attributes[] = { - &dev_attr_engine1_load.attr, - &dev_attr_engine1_leds.attr, - NULL -}; - -static struct attribute *lp5523_engine2_attributes[] = { - &dev_attr_engine2_load.attr, - &dev_attr_engine2_leds.attr, - NULL -}; - -static struct attribute *lp5523_engine3_attributes[] = { - &dev_attr_engine3_load.attr, - &dev_attr_engine3_leds.attr, - NULL -}; - -static const struct attribute_group lp5523_group = { - .attrs = lp5523_attributes, -}; - -static const struct attribute_group lp5523_engine_group[] = { - {.attrs = lp5523_engine1_attributes }, - {.attrs = lp5523_engine2_attributes }, - {.attrs = lp5523_engine3_attributes }, -}; - -static int lp5523_register_sysfs(struct i2c_client *client) -{ - struct device *dev = &client->dev; - int ret; - - ret = sysfs_create_group(&dev->kobj, &lp5523_group); - if (ret < 0) - return ret; - - return 0; -} - -static void lp5523_unregister_sysfs(struct i2c_client *client) -{ - struct lp5523_chip *chip = i2c_get_clientdata(client); - struct device *dev = &client->dev; - int i; - - sysfs_remove_group(&dev->kobj, &lp5523_group); - - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) - if (chip->engines[i].mode == LP5523_CMD_LOAD) - sysfs_remove_group(&dev->kobj, &lp5523_engine_group[i]); - - for (i = 0; i < chip->num_leds; i++) - sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, - &lp5523_led_attribute_group); -} - -/*--------------------------------------------------------------*/ -/* Set chip operating mode */ -/*--------------------------------------------------------------*/ -static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) -{ - /* engine to chip */ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - struct device *dev = &client->dev; - int ret = 0; - - /* if in that mode already do nothing, except for run */ - if (mode == engine->mode && mode != LP5523_CMD_RUN) - return 0; - - if (mode == LP5523_CMD_RUN) { - ret = lp5523_run_program(engine); - } else if (mode == LP5523_CMD_LOAD) { - lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); - lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); - - ret = sysfs_create_group(&dev->kobj, engine->attributes); - if (ret) - return ret; - } else if (mode == LP5523_CMD_DISABLED) { - lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); - } - - /* remove load attribute from sysfs if not in load mode */ - if (engine->mode == LP5523_CMD_LOAD && mode != LP5523_CMD_LOAD) - sysfs_remove_group(&dev->kobj, engine->attributes); - - engine->mode = mode; - - return ret; -} - -/*--------------------------------------------------------------*/ -/* Probe, Attach, Remove */ -/*--------------------------------------------------------------*/ -static int __init lp5523_init_engine(struct lp5523_engine *engine, int id) -{ - if (id < 1 || id > LP5523_ENGINES) - return -1; - engine->id = id; - engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); - engine->prog_page = id - 1; - engine->mux_page = id + 2; - engine->attributes = &lp5523_engine_group[id - 1]; - - return 0; -} - -static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev, - int chan, struct lp5523_platform_data *pdata) -{ - char name[32]; - int res; - - if (chan >= LP5523_LEDS) - return -EINVAL; - - if (pdata->led_config[chan].led_current) { - led->led_current = pdata->led_config[chan].led_current; - led->max_current = pdata->led_config[chan].max_current; - led->chan_nr = pdata->led_config[chan].chan_nr; - - if (led->chan_nr >= LP5523_LEDS) { - dev_err(dev, "Use channel numbers between 0 and %d\n", - LP5523_LEDS - 1); - return -EINVAL; - } - - snprintf(name, 32, "lp5523:channel%d", chan); - - led->cdev.name = name; - led->cdev.brightness_set = lp5523_set_brightness; - res = led_classdev_register(dev, &led->cdev); - if (res < 0) { - dev_err(dev, "couldn't register led on channel %d\n", - chan); - return res; - } - res = sysfs_create_group(&led->cdev.dev->kobj, - &lp5523_led_attribute_group); - if (res < 0) { - dev_err(dev, "couldn't register current attribute\n"); - led_classdev_unregister(&led->cdev); - return res; - } - } else { - led->led_current = 0; - } - return 0; -} - -static struct i2c_driver lp5523_driver; - -static int lp5523_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp5523_chip *chip; - struct lp5523_platform_data *pdata; - int ret, i, led; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - i2c_set_clientdata(client, chip); - chip->client = client; - - pdata = client->dev.platform_data; - - if (!pdata) { - dev_err(&client->dev, "no platform data\n"); - ret = -EINVAL; - goto fail1; - } - - mutex_init(&chip->lock); - - chip->pdata = pdata; - - if (pdata->setup_resources) { - ret = pdata->setup_resources(); - if (ret < 0) - goto fail1; - } - - if (pdata->enable) { - pdata->enable(0); - usleep_range(1000, 10000); - pdata->enable(1); - usleep_range(1000, 10000); /* Spec says min 500us */ - } - - ret = lp5523_detect(client); - if (ret) - goto fail2; - - dev_info(&client->dev, "LP5523 Programmable led chip found\n"); - - /* Initialize engines */ - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { - ret = lp5523_init_engine(&chip->engines[i], i + 1); - if (ret) { - dev_err(&client->dev, "error initializing engine\n"); - goto fail2; - } - } - ret = lp5523_configure(client); - if (ret < 0) { - dev_err(&client->dev, "error configuring chip\n"); - goto fail2; - } - - /* Initialize leds */ - chip->num_channels = pdata->num_channels; - chip->num_leds = 0; - led = 0; - for (i = 0; i < pdata->num_channels; i++) { - /* Do not initialize channels that are not connected */ - if (pdata->led_config[i].led_current == 0) - continue; - - ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata); - if (ret) { - dev_err(&client->dev, "error initializing leds\n"); - goto fail3; - } - chip->num_leds++; - - chip->leds[led].id = led; - /* Set LED current */ - lp5523_write(client, - LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, - chip->leds[led].led_current); - - INIT_WORK(&(chip->leds[led].brightness_work), - lp5523_led_brightness_work); - - led++; - } - - ret = lp5523_register_sysfs(client); - if (ret) { - dev_err(&client->dev, "registering sysfs failed\n"); - goto fail3; - } - return ret; -fail3: - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } -fail2: - if (pdata->enable) - pdata->enable(0); - if (pdata->release_resources) - pdata->release_resources(); -fail1: - kfree(chip); - return ret; -} - -static int lp5523_remove(struct i2c_client *client) -{ - struct lp5523_chip *chip = i2c_get_clientdata(client); - int i; - - lp5523_unregister_sysfs(client); - - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } - - if (chip->pdata->enable) - chip->pdata->enable(0); - if (chip->pdata->release_resources) - chip->pdata->release_resources(); - kfree(chip); - return 0; -} - -static const struct i2c_device_id lp5523_id[] = { - { "lp5523", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, lp5523_id); - -static struct i2c_driver lp5523_driver = { - .driver = { - .name = "lp5523", - }, - .probe = lp5523_probe, - .remove = lp5523_remove, - .id_table = lp5523_id, -}; - -static int __init lp5523_init(void) -{ - int ret; - - ret = i2c_add_driver(&lp5523_driver); - - if (ret < 0) - printk(KERN_ALERT "Adding lp5523 driver failed\n"); - - return ret; -} - -static void __exit lp5523_exit(void) -{ - i2c_del_driver(&lp5523_driver); -} - -module_init(lp5523_init); -module_exit(lp5523_exit); - -MODULE_AUTHOR("Mathias Nyman "); -MODULE_DESCRIPTION("LP5523 LED engine"); -MODULE_LICENSE("GPL"); diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index b09bcbe..82b77bd 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -12,25 +12,73 @@ */ #include +#include #include #include +#include +#include #include +#include +#include #include #include +#include #include "leds.h" +struct timer_trig_data { + int brightness_on; /* LED brightness during "on" period. + * (LED_OFF < brightness_on <= LED_FULL) + */ + unsigned long delay_on; /* milliseconds on */ + unsigned long delay_off; /* milliseconds off */ + struct timer_list timer; +}; + +static void led_timer_function(unsigned long data) +{ + struct led_classdev *led_cdev = (struct led_classdev *) data; + struct timer_trig_data *timer_data = led_cdev->trigger_data; + unsigned long brightness; + unsigned long delay; + + if (!timer_data->delay_on || !timer_data->delay_off) { + led_set_brightness(led_cdev, LED_OFF); + return; + } + + brightness = led_get_brightness(led_cdev); + if (!brightness) { + /* Time to switch the LED on. */ + brightness = timer_data->brightness_on; + delay = timer_data->delay_on; + } else { + /* Store the current brightness value to be able + * to restore it when the delay_off period is over. + */ + timer_data->brightness_on = brightness; + brightness = LED_OFF; + delay = timer_data->delay_off; + } + + led_set_brightness(led_cdev, brightness); + + mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); +} + static ssize_t led_delay_on_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; - return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); + return sprintf(buf, "%lu\n", timer_data->delay_on); } static ssize_t led_delay_on_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; int ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); @@ -40,7 +88,21 @@ static ssize_t led_delay_on_store(struct device *dev, count++; if (count == size) { - led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); + if (timer_data->delay_on != state) { + /* the new value differs from the previous */ + timer_data->delay_on = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + /* try to activate hardware acceleration, if any */ + if (!led_cdev->blink_set || + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off)) { + /* no hardware acceleration, blink via timer */ + mod_timer(&timer_data->timer, jiffies + 1); + } + } ret = count; } @@ -51,14 +113,16 @@ static ssize_t led_delay_off_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; - return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); + return sprintf(buf, "%lu\n", timer_data->delay_off); } static ssize_t led_delay_off_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; int ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); @@ -68,7 +132,21 @@ static ssize_t led_delay_off_store(struct device *dev, count++; if (count == size) { - led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); + if (timer_data->delay_off != state) { + /* the new value differs from the previous */ + timer_data->delay_off = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + /* try to activate hardware acceleration, if any */ + if (!led_cdev->blink_set || + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off)) { + /* no hardware acceleration, blink via timer */ + mod_timer(&timer_data->timer, jiffies + 1); + } + } ret = count; } @@ -80,34 +158,60 @@ static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); static void timer_trig_activate(struct led_classdev *led_cdev) { + struct timer_trig_data *timer_data; int rc; - led_cdev->trigger_data = NULL; + timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); + if (!timer_data) + return; + + timer_data->brightness_on = led_get_brightness(led_cdev); + if (timer_data->brightness_on == LED_OFF) + timer_data->brightness_on = led_cdev->max_brightness; + led_cdev->trigger_data = timer_data; + + init_timer(&timer_data->timer); + timer_data->timer.function = led_timer_function; + timer_data->timer.data = (unsigned long) led_cdev; rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); if (rc) - return; + goto err_out; rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); if (rc) goto err_out_delayon; - led_cdev->trigger_data = (void *)1; + /* If there is hardware support for blinking, start one + * user friendly blink rate chosen by the driver. + */ + if (led_cdev->blink_set) + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off); return; err_out_delayon: device_remove_file(led_cdev->dev, &dev_attr_delay_on); +err_out: + led_cdev->trigger_data = NULL; + kfree(timer_data); } static void timer_trig_deactivate(struct led_classdev *led_cdev) { - if (led_cdev->trigger_data) { + struct timer_trig_data *timer_data = led_cdev->trigger_data; + unsigned long on = 0, off = 0; + + if (timer_data) { device_remove_file(led_cdev->dev, &dev_attr_delay_on); device_remove_file(led_cdev->dev, &dev_attr_delay_off); + del_timer_sync(&timer_data->timer); + kfree(timer_data); } - /* Stop blinking */ - led_brightness_set(led_cdev, LED_OFF); + /* If there is hardware support for blinking, stop it */ + if (led_cdev->blink_set) + led_cdev->blink_set(led_cdev, &on, &off); } static struct led_trigger timer_led_trigger = { diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index f5f4da3..4446966 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c @@ -80,7 +80,7 @@ static void adb_iop_end_req(struct adb_request *req, int state) static void adb_iop_complete(struct iop_msg *msg) { struct adb_request *req; - unsigned long flags; + uint flags; local_irq_save(flags); @@ -103,7 +103,7 @@ static void adb_iop_listen(struct iop_msg *msg) { struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; - unsigned long flags; + uint flags; #ifdef DEBUG_ADB_IOP int i; #endif diff --git a/drivers/md/md.c b/drivers/md/md.c index 324a366..4e957f3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -706,7 +706,7 @@ static struct mdk_personality *find_pers(int level, char *clevel) /* return the offset of the super block in 512byte sectors */ static inline sector_t calc_dev_sboffset(struct block_device *bdev) { - sector_t num_sectors = i_size_read(bdev->bd_inode) / 512; + sector_t num_sectors = bdev->bd_inode->i_size / 512; return MD_NEW_SIZE_SECTORS(num_sectors); } @@ -1386,7 +1386,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) */ switch(minor_version) { case 0: - sb_start = i_size_read(rdev->bdev->bd_inode) >> 9; + sb_start = rdev->bdev->bd_inode->i_size >> 9; sb_start -= 8*2; sb_start &= ~(sector_t)(4*2-1); break; @@ -1472,7 +1472,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) ret = 0; } if (minor_version) - rdev->sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - + rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) - le64_to_cpu(sb->data_offset); else rdev->sectors = rdev->sb_start; @@ -1680,7 +1680,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) return 0; /* component must fit device */ if (rdev->sb_start < rdev->data_offset) { /* minor versions 1 and 2; superblock before data */ - max_sectors = i_size_read(rdev->bdev->bd_inode) >> 9; + max_sectors = rdev->bdev->bd_inode->i_size >> 9; max_sectors -= rdev->data_offset; if (!num_sectors || num_sectors > max_sectors) num_sectors = max_sectors; @@ -1690,7 +1690,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) } else { /* minor version 0; superblock after data */ sector_t sb_start; - sb_start = (i_size_read(rdev->bdev->bd_inode) >> 9) - 8*2; + sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2; sb_start &= ~(sector_t)(4*2 - 1); max_sectors = rdev->sectors + sb_start - rdev->sb_start; if (!num_sectors || num_sectors > max_sectors) @@ -2584,7 +2584,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) if (!sectors) return -EBUSY; } else if (!sectors) - sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - + sectors = (rdev->bdev->bd_inode->i_size >> 9) - rdev->data_offset; } if (sectors < my_mddev->dev_sectors) @@ -2797,7 +2797,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi kobject_init(&rdev->kobj, &rdev_ktype); - size = i_size_read(rdev->bdev->bd_inode) >> BLOCK_SIZE_BITS; + size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; if (!size) { printk(KERN_WARNING "md: %s has zero or unknown size, marking faulty!\n", @@ -5235,8 +5235,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) if (!mddev->persistent) { printk(KERN_INFO "md: nonpersistent superblock ...\n"); - rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512; - } else + rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; + } else rdev->sb_start = calc_dev_sboffset(rdev->bdev); rdev->sectors = rdev->sb_start; @@ -5306,7 +5306,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) if (mddev->persistent) rdev->sb_start = calc_dev_sboffset(rdev->bdev); else - rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512; + rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; rdev->sectors = rdev->sb_start; diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index a28541b..bad2ced 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -19,6 +19,7 @@ comment "Multimedia core support" config VIDEO_DEV tristate "Video For Linux" + depends on BKL # used in many drivers for ioctl handling, need to kill ---help--- V4L core support for video capture and overlay devices, webcams and AM/FM radio cards. diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 74ee172..3d88542 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -391,6 +391,7 @@ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, in /*****************************************************************************/ /* i2c-adapter helper functions */ +#include /* exported algorithm data */ static struct i2c_algorithm saa7146_algo = { diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 2311c0a..a499102 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c @@ -130,7 +130,6 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct dibx000_i2c_master *mst) { strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); - i2c_adap->algo = algo; i2c_adap->algo_data = NULL; i2c_set_adapdata(i2c_adap, mst); if (i2c_add_adapter(i2c_adap) < 0) diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 7bc3667..2934770 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2065,9 +2065,8 @@ static int cafe_pci_probe(struct pci_dev *pdev, sensor_cfg.clock_speed = 45; cam->sensor_addr = 0x42; - cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter, - "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr, - NULL); + cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter, + NULL, "ov7670", cam->sensor_addr, NULL); if (cam->sensor == NULL) { ret = -ENODEV; goto out_smbus; diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c index 4c7cac3..aab21f3 100644 --- a/drivers/media/video/cx231xx/cx231xx-417.c +++ b/drivers/media/video/cx231xx/cx231xx-417.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1926,9 +1927,10 @@ static int mpeg_open(struct file *file) dev = h; } - if (dev == NULL) + if (dev == NULL) { + unlock_kernel(); return -ENODEV; - + } mutex_lock(&dev->lock); /* allocate + initialize per filehandle data */ diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 9a98dc5..a6cc12f 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1575,8 +1576,12 @@ static int mpeg_open(struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (!fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; + } + + lock_kernel(); file->private_data = fh; fh->dev = dev; @@ -1587,6 +1592,8 @@ static int mpeg_open(struct file *file) V4L2_FIELD_INTERLACED, sizeof(struct cx23885_buffer), fh, NULL); + unlock_kernel(); + return 0; } diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 3cc9f46..93af9c6 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -742,6 +743,8 @@ static int video_open(struct file *file) if (NULL == fh) return -ENOMEM; + lock_kernel(); + file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -759,6 +762,8 @@ static int video_open(struct file *file) dprintk(1, "post videobuf_queue_init()\n"); + unlock_kernel(); + return 0; } diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c index 27b5dfd..380e459 100644 --- a/drivers/media/video/imx074.c +++ b/drivers/media/video/imx074.c @@ -451,6 +451,7 @@ static int imx074_probe(struct i2c_client *client, ret = imx074_video_probe(icd, client); if (ret < 0) { icd->ops = NULL; + i2c_set_clientdata(client, NULL); kfree(priv); return ret; } @@ -467,6 +468,7 @@ static int imx074_remove(struct i2c_client *client) icd->ops = NULL; if (icl->free_bus) icl->free_bus(icl); + i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(priv); diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index ce4a753..5a000c6 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 072bd2d..4a27862 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -904,6 +903,8 @@ static int mx2_camera_set_crop(struct soc_camera_device *icd, static int mx2_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; @@ -942,6 +943,8 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd, static int mx2_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; @@ -1021,13 +1024,13 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, return 0; } -static int mx2_camera_reqbufs(struct soc_camera_device *icd, +static int mx2_camera_reqbufs(struct soc_camera_file *icf, struct v4l2_requestbuffers *p) { int i; for (i = 0; i < p->count; i++) { - struct mx2_buffer *buf = container_of(icd->vb_vidq.bufs[i], + struct mx2_buffer *buf = container_of(icf->vb_vidq.bufs[i], struct mx2_buffer, vb); INIT_LIST_HEAD(&buf->vb.queue); } @@ -1148,9 +1151,9 @@ err_out: static unsigned int mx2_camera_poll(struct file *file, poll_table *pt) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_file *icf = file->private_data; - return videobuf_poll_stream(file, &icd->vb_vidq, pt); + return videobuf_poll_stream(file, &icf->vb_vidq, pt); } static struct soc_camera_host_ops mx2_soc_camera_host_ops = { diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index aa871c2..29c5fc3 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -27,7 +27,6 @@ #include #include -#include #define MX3_CAM_DRV_NAME "mx3-camera" @@ -639,9 +638,6 @@ static bool chan_filter(struct dma_chan *chan, void *arg) struct dma_chan_request *rq = arg; struct mx3_camera_pdata *pdata; - if (!imx_dma_is_ipu(chan)) - return false; - if (!rq) return false; diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c index cbfd07f..7c30e62 100644 --- a/drivers/media/video/omap1_camera.c +++ b/drivers/media/video/omap1_camera.c @@ -235,7 +235,7 @@ static void free_buffer(struct videobuf_queue *vq, struct omap1_cam_buf *buf, BUG_ON(in_interrupt()); - videobuf_waiton(vq, vb, 0, 0); + videobuf_waiton(vb, 0, 0); if (vb_mode == OMAP1_CAM_DMA_CONTIG) { videobuf_dma_contig_free(vq, vb); @@ -504,7 +504,7 @@ static void omap1_videobuf_queue(struct videobuf_queue *vq, * empty. Since the transfer of the DMA programming register set * content to the DMA working register set is done automatically * by the DMA hardware, this can pretty well happen while we - * are keeping the lock here. Leave fetching it from the queue + * are keeping the lock here. Levae fetching it from the queue * to be done when a next DMA interrupt occures instead. */ return; @@ -1365,12 +1365,12 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q, videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, icd->dev.parent, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, - sizeof(struct omap1_cam_buf), icd, NULL); + sizeof(struct omap1_cam_buf), icd); else videobuf_queue_sg_init(q, &omap1_videobuf_ops, icd->dev.parent, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, - sizeof(struct omap1_cam_buf), icd, NULL); + sizeof(struct omap1_cam_buf), icd); /* use videobuf mode (auto)selected with the module parameter */ pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; @@ -1386,7 +1386,7 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q, } } -static int omap1_cam_reqbufs(struct soc_camera_device *icd, +static int omap1_cam_reqbufs(struct soc_camera_file *icf, struct v4l2_requestbuffers *p) { int i; @@ -1398,7 +1398,7 @@ static int omap1_cam_reqbufs(struct soc_camera_device *icd, * it hadn't triggered */ for (i = 0; i < p->count; i++) { - struct omap1_cam_buf *buf = container_of(icd->vb_vidq.bufs[i], + struct omap1_cam_buf *buf = container_of(icf->vb_vidq.bufs[i], struct omap1_cam_buf, vb); buf->inwork = 0; INIT_LIST_HEAD(&buf->vb.queue); @@ -1485,10 +1485,10 @@ static int omap1_cam_set_bus_param(struct soc_camera_device *icd, static unsigned int omap1_cam_poll(struct file *file, poll_table *pt) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_file *icf = file->private_data; struct omap1_cam_buf *buf; - buf = list_entry(icd->vb_vidq.stream.next, struct omap1_cam_buf, + buf = list_entry(icf->vb_vidq.stream.next, struct omap1_cam_buf, vb.stream); poll_wait(file, &buf->vb.done, pt); diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c index cf93de9..b7cfeab 100644 --- a/drivers/media/video/ov6650.c +++ b/drivers/media/video/ov6650.c @@ -754,7 +754,7 @@ static int ov6650_g_fmt(struct v4l2_subdev *sd, static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect) { - return width > rect->width >> 1 || height > rect->height >> 1; + return (width > rect->width >> 1 || height > rect->height >> 1); } static u8 to_clkrc(struct v4l2_fract *timeperframe, @@ -840,6 +840,8 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; coma_set |= COMA_RAW_RGB | COMA_RGB; break; + case 0: + break; default: dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code); return -EINVAL; @@ -1174,6 +1176,7 @@ static int ov6650_probe(struct i2c_client *client, if (ret) { icd->ops = NULL; + i2c_set_clientdata(client, NULL); kfree(priv); } @@ -1184,6 +1187,7 @@ static int ov6650_remove(struct i2c_client *client) { struct ov6650 *priv = to_ov6650(client); + i2c_set_clientdata(client, NULL); kfree(priv); return 0; } diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 0911cb5..10a6cbf 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -6661,18 +6661,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x2804, .driver_data = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000, }, { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ - .subdevice = 0x7190, - .driver_data = SAA7134_BOARD_BEHOLD_H7, - }, { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ - .subdevice = 0x7090, - .driver_data = SAA7134_BOARD_BEHOLD_A7, - }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -6710,6 +6698,18 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = SAA7134_BOARD_UNKNOWN, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ + .subdevice = 0x7190, + .driver_data = SAA7134_BOARD_BEHOLD_H7, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, /* Beholder Intl. Ltd. */ + .subdevice = 0x7090, + .driver_data = SAA7134_BOARD_BEHOLD_A7, },{ /* --- end of list --- */ } diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index 41360d7..41d0166 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c @@ -31,6 +31,7 @@ static const char version[] = "0.24"; #include #include #include +#include #include #include #include "se401.h" @@ -950,9 +951,9 @@ static int se401_open(struct file *file) struct usb_se401 *se401 = (struct usb_se401 *)dev; int err = 0; - mutex_lock(&se401->lock); + lock_kernel(); if (se401->user) { - mutex_unlock(&se401->lock); + unlock_kernel(); return -EBUSY; } se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); @@ -961,7 +962,7 @@ static int se401_open(struct file *file) else err = -ENOMEM; se401->user = !err; - mutex_unlock(&se401->lock); + unlock_kernel(); return err; } diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index b5afe5f..f07a0f6 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -672,11 +673,14 @@ static int v4l_stk_open(struct file *fp) vdev = video_devdata(fp); dev = vdev_to_camera(vdev); + lock_kernel(); if (dev == NULL || !is_present(dev)) { + unlock_kernel(); return -ENXIO; } fp->private_data = dev; usb_autopm_get_interface(dev->interface); + unlock_kernel(); return 0; } diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c index c91424c..4555f4a 100644 --- a/drivers/media/video/tlg2300/pd-main.c +++ b/drivers/media/video/tlg2300/pd-main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "vendorcmds.h" #include "pd-common.h" @@ -484,11 +485,15 @@ static void poseidon_disconnect(struct usb_interface *interface) /*unregister v4l2 device */ v4l2_device_unregister(&pd->v4l2_dev); - pd_dvb_usb_device_exit(pd); - poseidon_fm_exit(pd); + lock_kernel(); + { + pd_dvb_usb_device_exit(pd); + poseidon_fm_exit(pd); - poseidon_audio_free(pd); - pd_video_exit(pd); + poseidon_audio_free(pd); + pd_video_exit(pd); + } + unlock_kernel(); usb_set_intfdata(interface, NULL); kref_put(&pd->kref, poseidon_delete); diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index dc17cce..5d6fd01 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -482,28 +483,29 @@ vicam_open(struct file *file) return -EINVAL; } - /* cam_lock/open_count protects us from simultaneous opens - * ... for now. we probably shouldn't rely on this fact forever. + /* the videodev_lock held above us protects us from + * simultaneous opens...for now. we probably shouldn't + * rely on this fact forever. */ - mutex_lock(&cam->cam_lock); + lock_kernel(); if (cam->open_count > 0) { printk(KERN_INFO "vicam_open called on already opened camera"); - mutex_unlock(&cam->cam_lock); + unlock_kernel(); return -EBUSY; } cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); if (!cam->raw_image) { - mutex_unlock(&cam->cam_lock); + unlock_kernel(); return -ENOMEM; } cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); if (!cam->framebuf) { kfree(cam->raw_image); - mutex_unlock(&cam->cam_lock); + unlock_kernel(); return -ENOMEM; } @@ -511,17 +513,10 @@ vicam_open(struct file *file) if (!cam->cntrlbuf) { kfree(cam->raw_image); rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); - mutex_unlock(&cam->cam_lock); + unlock_kernel(); return -ENOMEM; } - cam->needsDummyRead = 1; - cam->open_count++; - - file->private_data = cam; - mutex_unlock(&cam->cam_lock); - - // First upload firmware, then turn the camera on if (!cam->is_initialized) { @@ -532,6 +527,12 @@ vicam_open(struct file *file) set_camera_power(cam, 1); + cam->needsDummyRead = 1; + cam->open_count++; + + file->private_data = cam; + unlock_kernel(); + return 0; } diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 03f7f46..0ca7978 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -246,12 +247,10 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) mutex_unlock(vdev->lock); } else if (vdev->fops->ioctl) { /* TODO: convert all drivers to unlocked_ioctl */ - static DEFINE_MUTEX(v4l2_ioctl_mutex); - - mutex_lock(&v4l2_ioctl_mutex); + lock_kernel(); if (video_is_registered(vdev)) ret = vdev->fops->ioctl(filp, cmd, arg); - mutex_unlock(&v4l2_ioctl_mutex); + unlock_kernel(); } else ret = -ENOTTY; diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 27f0555..37fe161 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -388,7 +388,6 @@ struct zoran { struct videocodec *vfe; /* video front end */ struct mutex resource_lock; /* prevent evil stuff */ - struct mutex other_lock; /* please merge with above */ u8 initialized; /* flag if zoran has been correctly initialized */ int user; /* number of current users */ diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 7e6d624..0aac376 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -1227,7 +1227,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); spin_lock_init(&zr->spinlock); mutex_init(&zr->resource_lock); - mutex_init(&zr->other_lock); if (pci_enable_device(pdev)) goto zr_unreg; pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 67a52e8..401082b 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -912,7 +913,7 @@ static int zoran_open(struct file *file) dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n", ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1); - mutex_lock(&zr->other_lock); + lock_kernel(); if (zr->user >= 2048) { dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", @@ -962,14 +963,14 @@ static int zoran_open(struct file *file) file->private_data = fh; fh->zr = zr; zoran_open_init_session(fh); - mutex_unlock(&zr->other_lock); + unlock_kernel(); return 0; fail_fh: kfree(fh); fail_unlock: - mutex_unlock(&zr->other_lock); + unlock_kernel(); dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", ZR_DEVNAME(zr), res, zr->user); @@ -988,7 +989,7 @@ zoran_close(struct file *file) /* kernel locks (fs/device.c), so don't do that ourselves * (prevents deadlocks) */ - mutex_lock(&zr->other_lock); + /*mutex_lock(&zr->resource_lock);*/ zoran_close_end_session(fh); @@ -1022,7 +1023,6 @@ zoran_close(struct file *file) encoder_call(zr, video, s_routing, 2, 0, 0); } } - mutex_unlock(&zr->other_lock); file->private_data = NULL; kfree(fh->overlay_mask); @@ -3370,26 +3370,11 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = { #endif }; -/* please use zr->resource_lock consistently and kill this wrapper */ -static long zoran_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct zoran_fh *fh = file->private_data; - struct zoran *zr = fh->zr; - int ret; - - mutex_lock(&zr->other_lock); - ret = video_ioctl2(file, cmd, arg); - mutex_unlock(&zr->other_lock); - - return ret; -} - static const struct v4l2_file_operations zoran_fops = { .owner = THIS_MODULE, .open = zoran_open, .release = zoran_close, - .unlocked_ioctl = zoran_ioctl, + .ioctl = video_ioctl2, .read = zoran_read, .write = zoran_write, .mmap = zoran_mmap, diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 644d4cd..f9b91ba 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -123,7 +123,7 @@ static ssize_t als_sensing_range_store(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct als_data *data = i2c_get_clientdata(client); - int ret_val; + unsigned int ret_val; unsigned long val; if (strict_strtoul(buf, 10, &val)) @@ -251,6 +251,7 @@ static int apds9802als_probe(struct i2c_client *client, return res; als_error1: + i2c_set_clientdata(client, NULL); kfree(data); return res; } diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index d79a972..cee632e 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -649,7 +649,7 @@ static ssize_t bh1770_power_state_store(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; - ssize_t ret; + size_t ret; if (strict_strtoul(buf, 0, &value)) return -EINVAL; @@ -659,12 +659,8 @@ static ssize_t bh1770_power_state_store(struct device *dev, pm_runtime_get_sync(dev); ret = bh1770_lux_rate(chip, chip->lux_rate_index); - if (ret < 0) { - pm_runtime_put(dev); - goto leave; - } + ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE); - ret = bh1770_lux_interrupt_control(chip, BH1770_ENABLE); if (ret < 0) { pm_runtime_put(dev); goto leave; diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index ca47e62..34fe835 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -87,7 +87,7 @@ static ssize_t als_sensing_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); - int ret_val; + unsigned int ret_val; unsigned long val; if (strict_strtoul(buf, 10, &val)) @@ -106,8 +106,6 @@ static ssize_t als_sensing_range_store(struct device *dev, val = 4; ret_val = i2c_smbus_read_byte_data(client, 0x00); - if (ret_val < 0) - return ret_val; ret_val &= 0xFC; /*reset the bit before setting them */ ret_val |= val - 1; diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59..459614d 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1680,7 +1680,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) rc = XMIT_PLAIN; else { - if (vlan_get_protocol(skb) == htons(ETH_P_IPV6)) { + if (skb->protocol == htons(ETH_P_IPV6)) { rc = XMIT_CSUM_V6; if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) rc |= XMIT_CSUM_TCP; diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index c3449bb..6de5e2e 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -753,9 +753,7 @@ static int cxgb4vf_open(struct net_device *dev) if (err) return err; set_bit(pi->port_id, &adapter->open_device_map); - err = link_start(dev); - if (err) - return err; + link_start(dev); netif_tx_start_all_queues(dev); return 0; } @@ -1105,6 +1103,18 @@ static int cxgb4vf_set_mac_addr(struct net_device *dev, void *_addr) return 0; } +/* + * Return a TX Queue on which to send the specified skb. + */ +static u16 cxgb4vf_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + /* + * XXX For now just use the default hash but we probably want to + * XXX look at other possibilities ... + */ + return skb_tx_hash(dev, skb); +} + #ifdef CONFIG_NET_POLL_CONTROLLER /* * Poll all of our receive queues. This is called outside of normal interrupt @@ -2065,22 +2075,6 @@ static int adap_init0(struct adapter *adapter) } /* - * Some environments do not properly handle PCIE FLRs -- e.g. in Linux - * 2.6.31 and later we can't call pci_reset_function() in order to - * issue an FLR because of a self- deadlock on the device semaphore. - * Meanwhile, the OS infrastructure doesn't issue FLRs in all the - * cases where they're needed -- for instance, some versions of KVM - * fail to reset "Assigned Devices" when the VM reboots. Therefore we - * use the firmware based reset in order to reset any per function - * state. - */ - err = t4vf_fw_reset(adapter); - if (err < 0) { - dev_err(adapter->pdev_dev, "FW reset failed: err=%d\n", err); - return err; - } - - /* * Grab basic operational parameters. These will predominantly have * been set up by the Physical Function Driver or will be hard coded * into the adapter. We just have to live with them ... Note that @@ -2423,6 +2417,7 @@ static const struct net_device_ops cxgb4vf_netdev_ops = { .ndo_get_stats = cxgb4vf_get_stats, .ndo_set_rx_mode = cxgb4vf_set_rxmode, .ndo_set_mac_address = cxgb4vf_set_mac_addr, + .ndo_select_queue = cxgb4vf_select_queue, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = cxgb4vf_do_ioctl, .ndo_change_mtu = cxgb4vf_change_mtu, @@ -2629,6 +2624,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netdev->do_ioctl = cxgb4vf_do_ioctl; netdev->change_mtu = cxgb4vf_change_mtu; netdev->set_mac_address = cxgb4vf_set_mac_addr; + netdev->select_queue = cxgb4vf_select_queue; #ifdef CONFIG_NET_POLL_CONTROLLER netdev->poll_controller = cxgb4vf_poll_controller; #endif @@ -2847,14 +2843,6 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = { CH_DEVICE(0x4800, 0), /* T440-dbg */ CH_DEVICE(0x4801, 0), /* T420-cr */ CH_DEVICE(0x4802, 0), /* T422-cr */ - CH_DEVICE(0x4803, 0), /* T440-cr */ - CH_DEVICE(0x4804, 0), /* T420-bch */ - CH_DEVICE(0x4805, 0), /* T440-bch */ - CH_DEVICE(0x4806, 0), /* T460-ch */ - CH_DEVICE(0x4807, 0), /* T420-so */ - CH_DEVICE(0x4808, 0), /* T420-cx */ - CH_DEVICE(0x4809, 0), /* T420-bt */ - CH_DEVICE(0x480a, 0), /* T404-bt */ { 0, } }; diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index ecf0770..f10864d 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -154,16 +154,15 @@ enum { */ RX_COPY_THRES = 256, RX_PULL_LEN = 128, - - /* - * Main body length for sk_buffs used for RX Ethernet packets with - * fragments. Should be >= RX_PULL_LEN but possibly bigger to give - * pskb_may_pull() some room. - */ - RX_SKB_LEN = 512, }; /* + * Can't define this in the above enum because PKTSHIFT isn't a constant in + * the VF Driver ... + */ +#define RX_PKT_PULL_LEN (RX_PULL_LEN + PKTSHIFT) + +/* * Software state per TX descriptor. */ struct tx_sw_desc { @@ -1356,67 +1355,6 @@ out_free: } /** - * t4vf_pktgl_to_skb - build an sk_buff from a packet gather list - * @gl: the gather list - * @skb_len: size of sk_buff main body if it carries fragments - * @pull_len: amount of data to move to the sk_buff's main body - * - * Builds an sk_buff from the given packet gather list. Returns the - * sk_buff or %NULL if sk_buff allocation failed. - */ -struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl, - unsigned int skb_len, unsigned int pull_len) -{ - struct sk_buff *skb; - struct skb_shared_info *ssi; - - /* - * If the ingress packet is small enough, allocate an skb large enough - * for all of the data and copy it inline. Otherwise, allocate an skb - * with enough room to pull in the header and reference the rest of - * the data via the skb fragment list. - * - * Below we rely on RX_COPY_THRES being less than the smallest Rx - * buff! size, which is expected since buffers are at least - * PAGE_SIZEd. In this case packets up to RX_COPY_THRES have only one - * fragment. - */ - if (gl->tot_len <= RX_COPY_THRES) { - /* small packets have only one fragment */ - skb = alloc_skb(gl->tot_len, GFP_ATOMIC); - if (unlikely(!skb)) - goto out; - __skb_put(skb, gl->tot_len); - skb_copy_to_linear_data(skb, gl->va, gl->tot_len); - } else { - skb = alloc_skb(skb_len, GFP_ATOMIC); - if (unlikely(!skb)) - goto out; - __skb_put(skb, pull_len); - skb_copy_to_linear_data(skb, gl->va, pull_len); - - ssi = skb_shinfo(skb); - ssi->frags[0].page = gl->frags[0].page; - ssi->frags[0].page_offset = gl->frags[0].page_offset + pull_len; - ssi->frags[0].size = gl->frags[0].size - pull_len; - if (gl->nfrags > 1) - memcpy(&ssi->frags[1], &gl->frags[1], - (gl->nfrags-1) * sizeof(skb_frag_t)); - ssi->nr_frags = gl->nfrags; - - skb->len = gl->tot_len; - skb->data_len = skb->len - pull_len; - skb->truesize += skb->data_len; - - /* Get a reference for the last page, we don't own it */ - get_page(gl->frags[gl->nfrags - 1].page); - } - -out: - return skb; -} - -/** * t4vf_pktgl_free - free a packet gather list * @gl: the gather list * @@ -1525,8 +1463,10 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, { struct sk_buff *skb; struct port_info *pi; + struct skb_shared_info *ssi; const struct cpl_rx_pkt *pkt = (void *)&rsp[1]; bool csum_ok = pkt->csum_calc && !pkt->err_vec; + unsigned int len = be16_to_cpu(pkt->len); struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq); /* @@ -1541,14 +1481,42 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } /* - * Convert the Packet Gather List into an skb. + * If the ingress packet is small enough, allocate an skb large enough + * for all of the data and copy it inline. Otherwise, allocate an skb + * with enough room to pull in the header and reference the rest of + * the data via the skb fragment list. */ - skb = t4vf_pktgl_to_skb(gl, RX_SKB_LEN, RX_PULL_LEN); - if (unlikely(!skb)) { - t4vf_pktgl_free(gl); - rxq->stats.rx_drops++; - return 0; + if (len <= RX_COPY_THRES) { + /* small packets have only one fragment */ + skb = alloc_skb(gl->frags[0].size, GFP_ATOMIC); + if (!skb) + goto nomem; + __skb_put(skb, gl->frags[0].size); + skb_copy_to_linear_data(skb, gl->va, gl->frags[0].size); + } else { + skb = alloc_skb(RX_PKT_PULL_LEN, GFP_ATOMIC); + if (!skb) + goto nomem; + __skb_put(skb, RX_PKT_PULL_LEN); + skb_copy_to_linear_data(skb, gl->va, RX_PKT_PULL_LEN); + + ssi = skb_shinfo(skb); + ssi->frags[0].page = gl->frags[0].page; + ssi->frags[0].page_offset = (gl->frags[0].page_offset + + RX_PKT_PULL_LEN); + ssi->frags[0].size = gl->frags[0].size - RX_PKT_PULL_LEN; + if (gl->nfrags > 1) + memcpy(&ssi->frags[1], &gl->frags[1], + (gl->nfrags-1) * sizeof(skb_frag_t)); + ssi->nr_frags = gl->nfrags; + skb->len = len + PKTSHIFT; + skb->data_len = skb->len - RX_PKT_PULL_LEN; + skb->truesize += skb->data_len; + + /* Get a reference for the last page, we don't own it */ + get_page(gl->frags[gl->nfrags - 1].page); } + __skb_pull(skb, PKTSHIFT); skb->protocol = eth_type_trans(skb, rspq->netdev); skb_record_rx_queue(skb, rspq->idx); @@ -1581,6 +1549,11 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, netif_receive_skb(skb); return 0; + +nomem: + t4vf_pktgl_free(gl); + rxq->stats.rx_drops++; + return 0; } /** @@ -1706,7 +1679,6 @@ int process_responses(struct sge_rspq *rspq, int budget) } len = RSPD_LEN(len); } - gl.tot_len = len; /* * Gather packet fragments. diff --git a/drivers/net/cxgb4vf/t4vf_common.h b/drivers/net/cxgb4vf/t4vf_common.h index a65c80a..873cb7d 100644 --- a/drivers/net/cxgb4vf/t4vf_common.h +++ b/drivers/net/cxgb4vf/t4vf_common.h @@ -235,7 +235,6 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd, int __devinit t4vf_wait_dev_ready(struct adapter *); int __devinit t4vf_port_init(struct adapter *, int); -int t4vf_fw_reset(struct adapter *); int t4vf_query_params(struct adapter *, unsigned int, const u32 *, u32 *); int t4vf_set_params(struct adapter *, unsigned int, const u32 *, const u32 *); diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index e306c20..ea1c123 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c @@ -326,25 +326,6 @@ int __devinit t4vf_port_init(struct adapter *adapter, int pidx) } /** - * t4vf_fw_reset - issue a reset to FW - * @adapter: the adapter - * - * Issues a reset command to FW. For a Physical Function this would - * result in the Firmware reseting all of its state. For a Virtual - * Function this just resets the state associated with the VF. - */ -int t4vf_fw_reset(struct adapter *adapter) -{ - struct fw_reset_cmd cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) | - FW_CMD_WRITE); - cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); - return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); -} - -/** * t4vf_query_params - query FW or device parameters * @adapter: the adapter * @nparams: the number of parameters diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 3bc8e27..5c566eb 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -635,10 +635,9 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; - device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC); - spin_lock_irqsave(&priv->bflock, flags); - priv->wol_en = !!device_may_wakeup(&dev->dev); + priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0; + device_set_wakeup_enable(&dev->dev, priv->wol_en); spin_unlock_irqrestore(&priv->bflock, flags); return 0; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbad4d8..2bd3eb4 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -764,9 +764,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE /* adjust for FCoE Sequence Offload */ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) - && skb_is_gso(skb) - && vlan_get_protocol(skb) == - htons(ETH_P_FCOE)) { + && (skb->protocol == htons(ETH_P_FCOE)) && + skb_is_gso(skb)) { hlen = skb_transport_offset(skb) + sizeof(struct fc_frame_header) + sizeof(struct fcoe_crc_eof); @@ -5824,7 +5823,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) static int ixgbe_tso(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, struct sk_buff *skb, - u32 tx_flags, u8 *hdr_len, __be16 protocol) + u32 tx_flags, u8 *hdr_len) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -5842,7 +5841,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, l4len = tcp_hdrlen(skb); *hdr_len += l4len; - if (protocol == htons(ETH_P_IP)) { + if (skb->protocol == htons(ETH_P_IP)) { struct iphdr *iph = ip_hdr(skb); iph->tot_len = 0; iph->check = 0; @@ -5881,7 +5880,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT); - if (protocol == htons(ETH_P_IP)) + if (skb->protocol == htons(ETH_P_IP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); @@ -5907,10 +5906,16 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, return false; } -static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, - __be16 protocol) +static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb) { u32 rtn = 0; + __be16 protocol; + + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) + protocol = ((const struct vlan_ethhdr *)skb->data)-> + h_vlan_encapsulated_proto; + else + protocol = skb->protocol; switch (protocol) { case cpu_to_be16(ETH_P_IP): @@ -5938,7 +5943,7 @@ static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, default: if (unlikely(net_ratelimit())) e_warn(probe, "partial checksum but proto=%x!\n", - protocol); + skb->protocol); break; } @@ -5947,8 +5952,7 @@ static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - __be16 protocol) + struct sk_buff *skb, u32 tx_flags) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -5977,7 +5981,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, IXGBE_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) - type_tucmd_mlhl |= ixgbe_psum(adapter, skb, protocol); + type_tucmd_mlhl |= ixgbe_psum(adapter, skb); context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); /* use index zero for tx checksum offload */ @@ -6175,7 +6179,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, } static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, - int queue, u32 tx_flags, __be16 protocol) + int queue, u32 tx_flags) { struct ixgbe_atr_input atr_input; struct tcphdr *th; @@ -6186,7 +6190,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, u8 l4type = 0; /* Right now, we support IPv4 only */ - if (protocol != htons(ETH_P_IP)) + if (skb->protocol != htons(ETH_P_IP)) return; /* check if we're UDP or TCP */ if (iph->protocol == IPPROTO_TCP) { @@ -6253,13 +6257,10 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) { struct ixgbe_adapter *adapter = netdev_priv(dev); int txq = smp_processor_id(); -#ifdef IXGBE_FCOE - __be16 protocol; - protocol = vlan_get_protocol(skb); - - if ((protocol == htons(ETH_P_FCOE)) || - (protocol == htons(ETH_P_FIP))) { +#ifdef IXGBE_FCOE + if ((skb->protocol == htons(ETH_P_FCOE)) || + (skb->protocol == htons(ETH_P_FIP))) { if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); txq += adapter->ring_feature[RING_F_FCOE].mask; @@ -6302,9 +6303,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev int tso; int count = 0; unsigned int f; - __be16 protocol; - - protocol = vlan_get_protocol(skb); if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); @@ -6325,8 +6323,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev /* for FCoE with DCB, we force the priority to what * was specified by the switch */ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && - (protocol == htons(ETH_P_FCOE) || - protocol == htons(ETH_P_FIP))) { + (skb->protocol == htons(ETH_P_FCOE) || + skb->protocol == htons(ETH_P_FIP))) { #ifdef CONFIG_IXGBE_DCB if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK @@ -6336,7 +6334,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev } #endif /* flag for FCoE offloads */ - if (protocol == htons(ETH_P_FCOE)) + if (skb->protocol == htons(ETH_P_FCOE)) tx_flags |= IXGBE_TX_FLAGS_FCOE; } #endif @@ -6370,10 +6368,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev tx_flags |= IXGBE_TX_FLAGS_FSO; #endif /* IXGBE_FCOE */ } else { - if (protocol == htons(ETH_P_IP)) + if (skb->protocol == htons(ETH_P_IP)) tx_flags |= IXGBE_TX_FLAGS_IPV4; - tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len, - protocol); + tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len); if (tso < 0) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -6381,8 +6378,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev if (tso) tx_flags |= IXGBE_TX_FLAGS_TSO; - else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags, - protocol) && + else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) && (skb->ip_summed == CHECKSUM_PARTIAL)) tx_flags |= IXGBE_TX_FLAGS_CSUM; } @@ -6396,7 +6392,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev test_bit(__IXGBE_FDIR_INIT_DONE, &tx_ring->reinit_state)) { ixgbe_atr(adapter, skb, tx_ring->queue_index, - tx_flags, protocol); + tx_flags); tx_ring->atr_count = 0; } } diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8a4d19e..d2e166e 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -111,14 +111,13 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id); typedef struct axnet_dev_t { struct pcmcia_device *p_dev; - caddr_t base; - struct timer_list watchdog; - int stale, fast_poll; - u_short link_status; - u_char duplex_flag; - int phy_id; - int flags; - int active_low; + caddr_t base; + struct timer_list watchdog; + int stale, fast_poll; + u_short link_status; + u_char duplex_flag; + int phy_id; + int flags; } axnet_dev_t; static inline axnet_dev_t *PRIV(struct net_device *dev) @@ -323,8 +322,6 @@ static int axnet_config(struct pcmcia_device *link) if (info->flags & IS_AX88790) outb(0x10, dev->base_addr + AXNET_GPIO); /* select Internal PHY */ - info->active_low = 0; - for (i = 0; i < 32; i++) { j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); @@ -332,18 +329,15 @@ static int axnet_config(struct pcmcia_device *link) if ((j != 0) && (j != 0xffff)) break; } + /* Maybe PHY is in power down mode. (PPD_SET = 1) + Bit 2 of CCSR is active low. */ if (i == 32) { - /* Maybe PHY is in power down mode. (PPD_SET = 1) - Bit 2 of CCSR is active low. */ pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); for (i = 0; i < 32; i++) { j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); if (j == j2) continue; - if ((j != 0) && (j != 0xffff)) { - info->active_low = 1; - break; - } + if ((j != 0) && (j != 0xffff)) break; } } @@ -389,12 +383,8 @@ static int axnet_suspend(struct pcmcia_device *link) static int axnet_resume(struct pcmcia_device *link) { struct net_device *dev = link->priv; - axnet_dev_t *info = PRIV(dev); if (link->open) { - if (info->active_low == 1) - pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); - axnet_reset_8390(dev); AX88190_init(dev, 1); netif_device_attach(dev); diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4c4d169..d88ce9f 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -846,10 +846,10 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) else tp->features &= ~RTL_FEATURE_WOL; __rtl8169_set_wol(tp, wol->wolopts); - spin_unlock_irq(&tp->lock); - device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); + spin_unlock_irq(&tp->lock); + return 0; } @@ -2931,7 +2931,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8168, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | + .intr_event = SYSErr | RxFIFOOver | LinkChg | RxOverflow | TxErr | TxOK | RxOK | RxErr, .napi_event = TxErr | TxOK | RxOK | RxOverflow, .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, @@ -4588,8 +4588,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) } /* Work around for rx fifo overflow */ - if (unlikely(status & RxFIFOOver) && - (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + if (unlikely(status & RxFIFOOver)) { netif_stop_queue(dev); rtl8169_tx_timeout(dev); break; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 220e039..bfec2e0 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3858,6 +3858,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, /* device is off until link detection */ netif_carrier_off(dev); + netif_stop_queue(dev); return dev; } diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index acbdab3..a4c3f57 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -2050,16 +2050,12 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) ugeth_vdbg("%s: IN", __func__); - /* - * Tell the kernel the link is down. - * Must be done before disabling the controller - * or deadlock may happen. - */ - phy_stop(phydev); - /* Disable the controller */ ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + /* Tell the kernel the link is down */ + phy_stop(phydev); + /* Mask all interrupts */ out_be32(ugeth->uccf->p_uccm, 0x00000000); @@ -2069,6 +2065,9 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) /* Disable Rx and Tx */ clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); + phy_disconnect(ugeth->phydev); + ugeth->phydev = NULL; + ucc_geth_memclean(ugeth); } @@ -3551,10 +3550,7 @@ static int ucc_geth_close(struct net_device *dev) napi_disable(&ugeth->napi); - cancel_work_sync(&ugeth->timeout_work); ucc_geth_stop(ugeth); - phy_disconnect(ugeth->phydev); - ugeth->phydev = NULL; free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev); @@ -3583,12 +3579,8 @@ static void ucc_geth_timeout_work(struct work_struct *work) * Must reset MAC *and* PHY. This is done by reopening * the device. */ - netif_tx_stop_all_queues(dev); - ucc_geth_stop(ugeth); - ucc_geth_init_mac(ugeth); - /* Must start PHY here */ - phy_start(ugeth->phydev); - netif_tx_start_all_queues(dev); + ucc_geth_close(dev); + ucc_geth_open(dev); } netif_tx_schedule_all(dev); @@ -3602,6 +3594,7 @@ static void ucc_geth_timeout(struct net_device *dev) { struct ucc_geth_private *ugeth = netdev_priv(dev); + netif_carrier_off(dev); schedule_work(&ugeth->timeout_work); } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b6d4028..bb6b67f 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -986,15 +986,9 @@ static int virtnet_probe(struct virtio_device *vdev) goto unregister; } - /* Assume link up if device can't report link status, - otherwise get link status from config. */ - if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { - netif_carrier_off(dev); - virtnet_update_status(vi); - } else { - vi->status = VIRTIO_NET_S_LINK_UP; - netif_carrier_on(dev); - } + vi->status = VIRTIO_NET_S_LINK_UP; + virtnet_update_status(vi); + netif_carrier_on(dev); pr_debug("virtnet: registered device %s\n", dev->name); return 0; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 48261b7..a0471f2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -410,9 +410,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, val &= ~(AR_WA_BIT6 | AR_WA_BIT7); } - if (AR_SREV_9280(ah)) - val |= AR_WA_BIT22; - if (AR_SREV_9285E_20(ah)) val |= AR_WA_BIT23; diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 170d44a..9b8e7e3 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -675,7 +675,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) } extern struct ieee80211_ops ath9k_ops; -extern struct pm_qos_request_list ath9k_pm_qos_req; extern int modparam_nohwcrypt; extern int led_blink; diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f7ec31b..6576f68 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -35,7 +35,6 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ - { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ { }, @@ -541,11 +540,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) return; } - usb_fill_bulk_urb(urb, hif_dev->udev, + usb_fill_int_urb(urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, nskb); + ath9k_hif_usb_reg_in_cb, nskb, 1); ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { @@ -721,11 +720,11 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) if (!skb) goto err; - usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, + usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb); + ath9k_hif_usb_reg_in_cb, skb, 1); if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) goto err; @@ -844,6 +843,14 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) goto err_fw_req; } + /* Alloc URBs */ + ret = ath9k_hif_usb_alloc_urbs(hif_dev); + if (ret) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Unable to allocate URBs\n"); + goto err_urb; + } + /* Download firmware */ ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { @@ -859,22 +866,16 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) */ for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) { endp = &alt->endpoint[idx].desc; - if ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT) { + if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) + == 0x04) && + ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT)) { endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK; endp->bmAttributes |= USB_ENDPOINT_XFER_BULK; endp->bInterval = 0; } } - /* Alloc URBs */ - ret = ath9k_hif_usb_alloc_urbs(hif_dev); - if (ret) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: Unable to allocate URBs\n"); - goto err_urb; - } - return 0; err_fw_download: diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ebc68b..cc13ee1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -484,7 +484,6 @@ static int ath9k_hw_post_init(struct ath_hw *ah) ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, "Failed allocating banks for " "external radio\n"); - ath9k_hw_rf_free_ext_banks(ah); return ecode; } @@ -953,12 +952,9 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_MONITOR: REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); break; - default: - if (ah->is_monitoring) - REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); - break; } } @@ -1638,6 +1634,7 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) switch (ah->opmode) { case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_MONITOR: REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); @@ -1666,14 +1663,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; break; default: - if (ah->is_monitoring) { - REG_WRITE(ah, AR_NEXT_TBTT_TIMER, - TU_TO_USEC(next_beacon)); - REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); - REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); - flags |= AR_TBTT_TIMER_EN; - break; - } ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON, "%s: unsupported opmode: %d\n", __func__, ah->opmode); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index d47d1b4..d032939 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -622,7 +622,6 @@ struct ath_hw { bool sw_mgmt_crypto; bool is_pciexpress; - bool is_monitoring; bool need_an_top2_fixup; u16 tx_trig_level; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 6a0d99e..95b41db 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -15,7 +15,6 @@ */ #include -#include #include "ath9k.h" @@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = { .write = ath9k_iowrite32, }; -struct pm_qos_request_list ath9k_pm_qos_req; - /**************************/ /* Initialization */ /**************************/ @@ -759,9 +756,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ath_init_leds(sc); ath_start_rfkill_poll(sc); - pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - return 0; error_world: @@ -817,8 +811,6 @@ void ath9k_deinit_device(struct ath_softc *sc) ath9k_ps_wakeup(sc); - pm_qos_remove_request(&ath9k_pm_qos_req); - wiphy_rfkill_stop_polling(sc->hw->wiphy); ath_deinit_leds(sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 25d3ef4..b52f1cf 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -15,7 +15,6 @@ */ #include -#include #include "ath9k.h" #include "btcoex.h" @@ -94,13 +93,11 @@ void ath9k_ps_wakeup(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; - enum ath9k_power_mode power_mode; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (++sc->ps_usecount != 1) goto unlock; - power_mode = sc->sc_ah->power_mode; ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); /* @@ -108,12 +105,10 @@ void ath9k_ps_wakeup(struct ath_softc *sc) * useful data. Better clear them now so that they don't mess up * survey data results. */ - if (power_mode != ATH9K_PM_AWAKE) { - spin_lock(&common->cc_lock); - ath_hw_cycle_counters_update(common); - memset(&common->cc_survey, 0, sizeof(common->cc_survey)); - spin_unlock(&common->cc_lock); - } + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + spin_unlock(&common->cc_lock); unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); @@ -1222,7 +1217,6 @@ static int ath9k_start(struct ieee80211_hw *hw) ah->imask |= ATH9K_INT_CST; sc->sc_flags &= ~SC_OP_INVALID; - sc->sc_ah->is_monitoring = false; /* Disable BMISS interrupt when we're not associated */ ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); @@ -1244,8 +1238,6 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } - pm_qos_update_request(&ath9k_pm_qos_req, 55); - mutex_unlock: mutex_unlock(&sc->mutex); @@ -1423,8 +1415,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) sc->sc_flags |= SC_OP_INVALID; - pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE); - mutex_unlock(&sc->mutex); ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); @@ -1503,7 +1493,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ath9k_hw_set_interrupts(ah, ah->imask); if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { + vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MONITOR) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); } @@ -1653,12 +1644,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { ath_print(common, ATH_DBG_CONFIG, - "Monitor mode is enabled\n"); - sc->sc_ah->is_monitoring = true; - } else { - ath_print(common, ATH_DBG_CONFIG, - "Monitor mode is disabled\n"); - sc->sc_ah->is_monitoring = false; + "HW opmode set to Monitor mode\n"); + sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; } } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c76ea53..fddb012 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -441,7 +441,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) */ if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || - (sc->sc_ah->is_monitoring)) + (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) rfilt |= ATH9K_RX_FILTER_PROM; if (sc->rx.rxfilter & FIF_CONTROL) @@ -897,7 +897,7 @@ static bool ath9k_rx_accept(struct ath_common *common, * decryption and MIC failures. For monitor mode, * we also ignore the CRC error. */ - if (ah->is_monitoring) { + if (ah->opmode == NL80211_IFTYPE_MONITOR) { if (rx_stats->rs_status & ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ATH9K_RXERR_CRC)) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index fa05b71..42976b0 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -703,7 +703,6 @@ #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ #define AR_WA_ANALOG_SHIFT (1 << 20) #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ -#define AR_WA_BIT22 (1 << 22) #define AR9285_WA_DEFAULT 0x004a050b #define AR9280_WA_DEFAULT 0x0040073b #define AR_WA_DEFAULT 0x0000073f diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 3317039..d8607f4 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -82,11 +82,9 @@ static struct usb_device_id carl9170_usb_ids[] = { { USB_DEVICE(0x07d1, 0x3c10) }, /* D-Link DWA 160 A2 */ { USB_DEVICE(0x07d1, 0x3a09) }, - /* D-Link DWA 130 D */ - { USB_DEVICE(0x07d1, 0x3a0f) }, /* Netgear WNA1000 */ { USB_DEVICE(0x0846, 0x9040) }, - /* Netgear WNDA3100 (v1) */ + /* Netgear WNDA3100 */ { USB_DEVICE(0x0846, 0x9010) }, /* Netgear WN111 v2 */ { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED }, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 7edf8c2..8f8c4b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4000,8 +4000,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * "the hard way", rather than using device's scan. */ if (iwl3945_mod_params.disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); + IWL_ERR(priv, "sw scan support is deprecated\n"); iwl3945_hw_ops.hw_scan = NULL; } diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 373930a..5046a00 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -700,9 +700,8 @@ static void lbs_scan_worker(struct work_struct *work) if (priv->scan_channel < priv->scan_req->n_channels) { cancel_delayed_work(&priv->scan_work); - if (!priv->stopping) - queue_delayed_work(priv->work_thread, &priv->scan_work, - msecs_to_jiffies(300)); + queue_delayed_work(priv->work_thread, &priv->scan_work, + msecs_to_jiffies(300)); } /* This is the final data we are about to send */ diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index cb14c38..f062ed5 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -36,7 +36,6 @@ struct lbs_private { /* CFG80211 */ struct wireless_dev *wdev; bool wiphy_registered; - bool stopping; struct cfg80211_scan_request *scan_req; u8 assoc_bss[ETH_ALEN]; u8 disassoc_reason; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 46b88b1..47ce5a6 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -104,7 +104,6 @@ static int lbs_dev_open(struct net_device *dev) lbs_deb_enter(LBS_DEB_NET); spin_lock_irq(&priv->driver_lock); - priv->stopping = false; if (priv->connect_status == LBS_CONNECTED) netif_carrier_on(dev); @@ -132,16 +131,10 @@ static int lbs_eth_stop(struct net_device *dev) lbs_deb_enter(LBS_DEB_NET); spin_lock_irq(&priv->driver_lock); - priv->stopping = true; netif_stop_queue(dev); spin_unlock_irq(&priv->driver_lock); schedule_work(&priv->mcast_work); - cancel_delayed_work_sync(&priv->scan_work); - if (priv->scan_req) { - cfg80211_scan_done(priv->scan_req, false); - priv->scan_req = NULL; - } lbs_deb_leave(LBS_DEB_NET); return 0; diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 4396d4b..eea1ef2 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -221,6 +221,9 @@ config RT2X00_LIB_LEDS boolean default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) +comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00" + depends on RT2X00_LIB=y && LEDS_CLASS=m + config RT2X00_LIB_DEBUGFS bool "Ralink debugfs support" depends on RT2X00_LIB && MAC80211_DEBUGFS diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 003170e..5624db8 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -64,57 +64,17 @@ void pci_bus_remove_resources(struct pci_bus *bus) } } -static bool pci_bus_resource_better(struct resource *res1, bool pos1, - struct resource *res2, bool pos2) -{ - /* If exactly one is positive decode, always prefer that one */ - if (pos1 != pos2) - return pos1 ? true : false; - - /* Prefer the one that contains the highest address */ - if (res1->end != res2->end) - return (res1->end > res2->end) ? true : false; - - /* Otherwise, prefer the one with highest "center of gravity" */ - if (res1->start != res2->start) - return (res1->start > res2->start) ? true : false; - - /* Otherwise, choose one arbitrarily (but consistently) */ - return (res1 > res2) ? true : false; -} - -static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res) -{ - struct pci_bus_resource *bus_res; - - /* - * This relies on the fact that pci_bus.resource[] refers to P2P or - * CardBus bridge base/limit registers, which are always positively - * decoded. The pci_bus.resources list contains host bridge or - * subtractively decoded resources. - */ - list_for_each_entry(bus_res, &bus->resources, list) { - if (bus_res->res == res) - return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ? - false : true; - } - return true; -} - /* - * Find the next-best bus resource after the cursor "res". If the cursor is - * NULL, return the best resource. "Best" means that we prefer positive - * decode regions over subtractive decode, then those at higher addresses. + * Find the highest-address bus resource below the cursor "res". If the + * cursor is NULL, return the highest resource. */ static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, unsigned int type, struct resource *res) { - bool res_pos, r_pos, prev_pos = false; struct resource *r, *prev = NULL; int i; - res_pos = pci_bus_resource_positive(bus, res); pci_bus_for_each_resource(bus, r, i) { if (!r) continue; @@ -122,14 +82,26 @@ static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, if ((r->flags & IORESOURCE_TYPE_BITS) != type) continue; - r_pos = pci_bus_resource_positive(bus, r); - if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) { - if (!prev || pci_bus_resource_better(r, r_pos, - prev, prev_pos)) { - prev = r; - prev_pos = r_pos; - } + /* If this resource is at or past the cursor, skip it */ + if (res) { + if (r == res) + continue; + if (r->end > res->end) + continue; + if (r->end == res->end && r->start > res->start) + continue; } + + if (!prev) + prev = r; + + /* + * A small resource is higher than a large one that ends at + * the same address. + */ + if (r->end > prev->end || + (r->end == prev->end && r->start > prev->start)) + prev = r; } return prev; diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 2850e64..5becbde 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -276,12 +276,6 @@ int __init ibmphp_access_ebda (void) for (;;) { offset = next_offset; - - /* Make sure what we read is still in the mapped section */ - if (WARN(offset > (ebda_sz * 1024 - 4), - "ibmphp_ebda: next read is beyond ebda_sz\n")) - break; - next_offset = readw (io_mem + offset); /* offset of next blk */ offset += 2; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 95712a3..b5a7d9b 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -705,21 +705,17 @@ void pci_remove_legacy_files(struct pci_bus *b) #ifdef HAVE_PCI_MMAP -int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, - enum pci_mmap_api mmap_api) +int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) { - unsigned long nr, start, size, pci_start; + unsigned long nr, start, size; - if (pci_resource_len(pdev, resno) == 0) - return 0; nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; - pci_start = (mmap_api == PCI_MMAP_SYSFS) ? - pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; - if (start >= pci_start && start < pci_start + size && - start + nr <= pci_start + size) + if (start < size && size - start >= nr) return 1; + WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", + current->comm, start, start+nr, pci_name(pdev), resno, size); return 0; } @@ -749,15 +745,8 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, if (i >= PCI_ROM_RESOURCE) return -ENODEV; - if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) { - WARN(1, "process \"%s\" tried to map 0x%08lx bytes " - "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", - current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, - pci_name(pdev), i, - (u64)pci_resource_start(pdev, i), - (u64)pci_resource_len(pdev, i)); + if (!pci_mmap_fits(pdev, i, vma)) return -EINVAL; - } /* pci_mmap_page_range() expects the same kind of entry as coming * from /proc/bus/pci/ which is a "user visible" value. If this is diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 710c8a2..e98c810 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1007,18 +1007,6 @@ static int __pci_enable_device_flags(struct pci_dev *dev, int err; int i, bars = 0; - /* - * Power state could be unknown at this point, either due to a fresh - * boot or a device removal call. So get the current power state - * so that things like MSI message writing will behave as expected - * (e.g. if the device really is in D0 at enable time). - */ - if (dev->pm_cap) { - u16 pmcsr; - pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); - dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); - } - if (atomic_add_return(1, &dev->enable_cnt) > 1) return 0; /* already enabled */ diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 7d33f66..f5c7c38 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -22,13 +22,8 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev); #endif extern void pci_cleanup_rom(struct pci_dev *dev); #ifdef HAVE_PCI_MMAP -enum pci_mmap_api { - PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices//resource */ - PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/ */ -}; extern int pci_mmap_fits(struct pci_dev *pdev, int resno, - struct vm_area_struct *vmai, - enum pci_mmap_api mmap_api); + struct vm_area_struct *vma); #endif int pci_probe_reset_function(struct pci_dev *dev); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index ea00647..297b72c 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -257,7 +257,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) /* Make sure the caller is mapping a real resource for this device */ for (i = 0; i < PCI_ROM_RESOURCE; i++) { - if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) + if (pci_mmap_fits(dev, i, vma)) break; } diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 3a5a6fc..a87c498 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -575,9 +576,8 @@ static pci_ers_result_t pcifront_common_process(int cmd, pcidev = pci_get_bus_and_slot(bus, devfn); if (!pcidev || !pcidev->driver) { - dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); - if (pcidev) - pci_dev_put(pcidev); + dev_err(&pcidev->dev, + "device or driver is NULL\n"); return result; } pdrv = pcidev->driver; diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 96c72e9..8cbfa06 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -725,17 +725,17 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, return 0; -err_out_free_res2: + err_out_free_res2: if (irq_mode == 1) free_irq(dev->irq, socket); else del_timer_sync(&socket->poll_timer); -err_out_free_res: + err_out_free_res: pci_release_regions(dev); -err_out_disable: + err_out_disable: pci_disable_device(dev); -err_out_free_mem: + err_out_free_mem: kfree(socket); return ret; } diff --git a/drivers/pcmcia/pd6729.h b/drivers/pcmcia/pd6729.h index c8e84bd..41418d3 100644 --- a/drivers/pcmcia/pd6729.h +++ b/drivers/pcmcia/pd6729.h @@ -15,7 +15,7 @@ struct pd6729_socket { int number; int card_irq; - unsigned long io_base; /* base io address of the socket */ + unsigned long io_base; /* base io address of the socket */ struct pcmcia_socket socket; struct timer_list poll_timer; }; diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 81af2b3..0ea3b29 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -237,7 +237,7 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { #ifdef CONFIG_SA1100_COLLIE #include "sa11xx_base.h" -int __devinit pcmcia_collie_init(struct device *dev) +int __init pcmcia_collie_init(struct device *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c index f1e8822..fd013a1 100644 --- a/drivers/pcmcia/sa1100_assabet.c +++ b/drivers/pcmcia/sa1100_assabet.c @@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = { .socket_suspend = assabet_pcmcia_socket_suspend, }; -int __devinit pcmcia_assabet_init(struct device *dev) +int pcmcia_assabet_init(struct device *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index 30560df..9bf088b 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c @@ -97,7 +97,7 @@ static struct pcmcia_low_level cerf_pcmcia_ops = { .socket_suspend = cerf_pcmcia_socket_suspend, }; -int __devinit pcmcia_cerf_init(struct device *dev) +int __init pcmcia_cerf_init(struct device *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 6b22859..945857f 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -64,7 +64,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { #endif }; -static int __devinit sa11x0_drv_pcmcia_probe(struct platform_device *dev) +static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) { int i, ret = -ENODEV; diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index edf8f00..56329ad 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c @@ -219,7 +219,7 @@ struct pcmcia_low_level h3600_pcmcia_ops = { .socket_suspend = h3600_pcmcia_socket_suspend, }; -int __devinit pcmcia_h3600_init(struct device *dev) +int __init pcmcia_h3600_init(struct device *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c index 7ff1b43..c4d5186 100644 --- a/drivers/pcmcia/sa1100_shannon.c +++ b/drivers/pcmcia/sa1100_shannon.c @@ -113,7 +113,7 @@ static struct pcmcia_low_level shannon_pcmcia_ops = { .socket_suspend = shannon_pcmcia_socket_suspend, }; -int __devinit pcmcia_shannon_init(struct device *dev) +int __init pcmcia_shannon_init(struct device *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c index c998f7a..05bd504 100644 --- a/drivers/pcmcia/sa1100_simpad.c +++ b/drivers/pcmcia/sa1100_simpad.c @@ -123,7 +123,7 @@ static struct pcmcia_low_level simpad_pcmcia_ops = { .socket_suspend = simpad_pcmcia_socket_suspend, }; -int __devinit pcmcia_simpad_init(struct device *dev) +int __init pcmcia_simpad_init(struct device *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 3753fd0..689e3c0 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -57,16 +57,11 @@ module_param(pc_debug, int, 0644); void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, int lvl, const char *fmt, ...) { - struct va_format vaf; va_list args; if (pc_debug > lvl) { + printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func); va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - printk(KERN_DEBUG "skt%u: %s: %pV", skt->nr, func, &vaf); - + vprintk(fmt, args); va_end(args); } } diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 7b5080c..68cf0c9 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -1159,11 +1159,11 @@ int __devinit rio_init_mports(void) list_for_each_entry(port, &rio_mports, node) { if (!request_mem_region(port->iores.start, - resource_size(&port->iores), + port->iores.end - port->iores.start, port->name)) { printk(KERN_ERR "RIO: Error requesting master port region 0x%016llx-0x%016llx\n", - (u64)port->iores.start, (u64)port->iores.end); + (u64)port->iores.start, (u64)port->iores.end - 1); rc = -ENOMEM; goto out; } diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 06e41ed..5efbd59 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -761,7 +761,7 @@ err_unmap: clk_put(rtc->clk); iounmap(rtc->regbase); err_badmap: - release_mem_region(rtc->res->start, rtc->regsize); + release_resource(rtc->res); err_badres: kfree(rtc); @@ -786,7 +786,7 @@ static int __exit sh_rtc_remove(struct platform_device *pdev) } iounmap(rtc->regbase); - release_mem_region(rtc->res->start, rtc->regsize); + release_resource(rtc->res); clk_disable(rtc->clk); clk_put(rtc->clk); diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index f47a714..6be43eb 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -440,6 +440,7 @@ struct qeth_qdio_out_q { * index of buffer to be filled by driver; state EMPTY or PACKING */ int next_buf_to_fill; + int sync_iqdio_error; /* * number of buffers that are currently filled (PRIMED) * -> these buffers are hardware-owned @@ -694,6 +695,14 @@ struct qeth_mc_mac { int is_vmac; }; +struct qeth_skb_data { + __u32 magic; + int count; +}; + +#define QETH_SKB_MAGIC 0x71657468 +#define QETH_SIGA_CC2_RETRIES 3 + struct qeth_rx { int b_count; int b_index; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e6b2df0..7642670 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -877,8 +877,8 @@ out: return; } -static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, - struct qeth_qdio_out_buffer *buf) +static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, + struct qeth_qdio_out_buffer *buf, unsigned int qeth_skip_skb) { int i; struct sk_buff *skb; @@ -887,11 +887,13 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, if (buf->buffer->element[0].flags & 0x40) atomic_dec(&queue->set_pci_flags_count); - skb = skb_dequeue(&buf->skb_list); - while (skb) { - atomic_dec(&skb->users); - dev_kfree_skb_any(skb); + if (!qeth_skip_skb) { skb = skb_dequeue(&buf->skb_list); + while (skb) { + atomic_dec(&skb->users); + dev_kfree_skb_any(skb); + skb = skb_dequeue(&buf->skb_list); + } } for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) { if (buf->buffer->element[i].addr && buf->is_header[i]) @@ -907,6 +909,12 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); } +static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, + struct qeth_qdio_out_buffer *buf) +{ + __qeth_clear_output_buffer(queue, buf, 0); +} + void qeth_clear_qdio_buffers(struct qeth_card *card) { int i, j; @@ -2825,6 +2833,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, } } + queue->sync_iqdio_error = 0; queue->card->dev->trans_start = jiffies; if (queue->card->options.performance_stats) { queue->card->perf_stats.outbound_do_qdio_cnt++; @@ -2840,6 +2849,10 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - queue->card->perf_stats.outbound_do_qdio_start_time; + if (rc > 0) { + if (!(rc & QDIO_ERROR_SIGA_BUSY)) + queue->sync_iqdio_error = rc & 3; + } if (rc) { queue->card->stats.tx_errors += count; /* ignore temporary SIGA errors without busy condition */ @@ -2903,7 +2916,7 @@ void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue, { struct qeth_card *card = (struct qeth_card *)card_ptr; - if (card->dev && (card->dev->flags & IFF_UP)) + if (card->dev) napi_schedule(&card->napi); } EXPORT_SYMBOL_GPL(qeth_qdio_start_poll); @@ -2927,6 +2940,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue]; struct qeth_qdio_out_buffer *buffer; int i; + unsigned qeth_send_err; QETH_CARD_TEXT(card, 6, "qdouhdl"); if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { @@ -2942,8 +2956,9 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, } for (i = first_element; i < (first_element + count); ++i) { buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; - qeth_handle_send_error(card, buffer, qdio_error); - qeth_clear_output_buffer(queue, buffer); + qeth_send_err = qeth_handle_send_error(card, buffer, qdio_error); + __qeth_clear_output_buffer(queue, buffer, + (qeth_send_err == QETH_SEND_ERROR_RETRY) ? 1 : 0); } atomic_sub(count, &queue->used_buffers); /* check if we need to do something on this outbound queue */ @@ -3168,7 +3183,10 @@ int qeth_do_send_packet_fast(struct qeth_card *card, int offset, int hd_len) { struct qeth_qdio_out_buffer *buffer; + struct sk_buff *skb1; + struct qeth_skb_data *retry_ctrl; int index; + int rc; /* spin until we get the queue ... */ while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, @@ -3187,6 +3205,25 @@ int qeth_do_send_packet_fast(struct qeth_card *card, atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len); qeth_flush_buffers(queue, index, 1); + if (queue->sync_iqdio_error == 2) { + skb1 = skb_dequeue(&buffer->skb_list); + while (skb1) { + atomic_dec(&skb1->users); + skb1 = skb_dequeue(&buffer->skb_list); + } + retry_ctrl = (struct qeth_skb_data *) &skb->cb[16]; + if (retry_ctrl->magic != QETH_SKB_MAGIC) { + retry_ctrl->magic = QETH_SKB_MAGIC; + retry_ctrl->count = 0; + } + if (retry_ctrl->count < QETH_SIGA_CC2_RETRIES) { + retry_ctrl->count++; + rc = dev_queue_xmit(skb); + } else { + dev_kfree_skb_any(skb); + QETH_CARD_TEXT(card, 2, "qrdrop"); + } + } return 0; out: atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index f3cf924..1de30eb 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -320,11 +320,19 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) "changed. The Linux SCSI layer does not " "automatically adjust these parameters.\n"); - /* - * Pass the UA upwards for a determination in the completion - * functions. - */ - return SUCCESS; + if (scmd->request->cmd_flags & REQ_HARDBARRIER) + /* + * barrier requests should always retry on UA + * otherwise block will get a spurious error + */ + return NEEDS_RETRY; + else + /* + * for normal (non barrier) commands, pass the + * UA upwards for a determination in the + * completion functions + */ + return SUCCESS; /* these three are not supported */ case COPY_ABORTED: diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 842e3b2..53be4d3 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -2285,8 +2285,6 @@ static struct pciserial_board pci_boards[] __devinitdata = { static const struct pci_device_id softmodem_blacklist[] = { { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ - { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ - { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ }; /* @@ -2865,9 +2863,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, 0, 0, pbn_b0_4_1152000 }, - { PCI_VENDOR_ID_OXSEMI, 0x9505, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_bt_2_921600 }, /* * The below card is a little controversial since it is the diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 19cac9f..a9eff2b 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -23,7 +23,6 @@ #include #include #include -#include #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) @@ -34,10 +33,12 @@ #include #include -#include +#ifdef CONFIG_SERIAL_BFIN_DMA +#include #include #include #include +#endif #ifdef CONFIG_SERIAL_BFIN_MODULE # undef CONFIG_EARLY_PRINTK @@ -359,6 +360,7 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); uart->port.icount.tx++; + SSYNC(); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -686,13 +688,6 @@ static int bfin_serial_startup(struct uart_port *port) # ifdef CONFIG_BF54x { - /* - * UART2 and UART3 on BF548 share interrupt PINs and DMA - * controllers with SPORT2 and SPORT3. UART rx and tx - * interrupts are generated in PIO mode only when configure - * their peripheral mapping registers properly, which means - * request corresponding DMA channels in PIO mode as well. - */ unsigned uart_dma_ch_rx, uart_dma_ch_tx; switch (uart->port.irq) { @@ -739,7 +734,8 @@ static int bfin_serial_startup(struct uart_port *port) IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { uart->cts_pin = -1; - pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); + pr_info("Unable to attach BlackFin UART CTS interrupt.\ + So, disable it.\n"); } } if (uart->rts_pin >= 0) { @@ -751,7 +747,8 @@ static int bfin_serial_startup(struct uart_port *port) if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { - pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); + pr_info("Unable to attach BlackFin UART Modem \ + Status interrupt.\n"); } /* CTS RTS PINs are negative assertive. */ @@ -849,8 +846,6 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_cflag & CMSPAR) lcr |= STP; - spin_lock_irqsave(&uart->port.lock, flags); - port->read_status_mask = OE; if (termios->c_iflag & INPCK) port->read_status_mask |= (FE | PE); @@ -880,6 +875,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_line != N_IRDA) quot -= ANOMALY_05000230; + spin_lock_irqsave(&uart->port.lock, flags); + UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); /* Disable UART */ @@ -1324,14 +1321,6 @@ struct console __init *bfin_earlyserial_init(unsigned int port, struct bfin_serial_port *uart; struct ktermios t; -#ifdef CONFIG_SERIAL_BFIN_CONSOLE - /* - * If we are using early serial, don't let the normal console rewind - * log buffer, since that causes things to be printed multiple times - */ - bfin_serial_console.flags &= ~CON_PRINTBUFFER; -#endif - if (port == -1 || port >= nr_active_ports) port = 0; bfin_serial_init_ports(); diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 3374618..d4b711c 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c @@ -18,7 +18,6 @@ #include #include #include -#include #define MAX_CONFIG_LEN 40 @@ -38,61 +37,6 @@ static struct tty_driver *kgdb_tty_driver; static int kgdb_tty_line; #ifdef CONFIG_KDB_KEYBOARD -static int kgdboc_reset_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - input_reset_device(dev); - - /* Retrun an error - we do not want to bind, just to reset */ - return -ENODEV; -} - -static void kgdboc_reset_disconnect(struct input_handle *handle) -{ - /* We do not expect anyone to actually bind to us */ - BUG(); -} - -static const struct input_device_id kgdboc_reset_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_KEY) }, - }, - { } -}; - -static struct input_handler kgdboc_reset_handler = { - .connect = kgdboc_reset_connect, - .disconnect = kgdboc_reset_disconnect, - .name = "kgdboc_reset", - .id_table = kgdboc_reset_ids, -}; - -static DEFINE_MUTEX(kgdboc_reset_mutex); - -static void kgdboc_restore_input_helper(struct work_struct *dummy) -{ - /* - * We need to take a mutex to prevent several instances of - * this work running on different CPUs so they don't try - * to register again already registered handler. - */ - mutex_lock(&kgdboc_reset_mutex); - - if (input_register_handler(&kgdboc_reset_handler) == 0) - input_unregister_handler(&kgdboc_reset_handler); - - mutex_unlock(&kgdboc_reset_mutex); -} - -static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); - -static void kgdboc_restore_input(void) -{ - schedule_work(&kgdboc_restore_input_work); -} - static int kgdboc_register_kbd(char **cptr) { if (strncmp(*cptr, "kbd", 3) == 0) { @@ -120,12 +64,10 @@ static void kgdboc_unregister_kbd(void) i--; } } - flush_work_sync(&kgdboc_restore_input_work); } #else /* ! CONFIG_KDB_KEYBOARD */ #define kgdboc_register_kbd(x) 0 #define kgdboc_unregister_kbd() -#define kgdboc_restore_input() #endif /* ! CONFIG_KDB_KEYBOARD */ static int kgdboc_option_setup(char *opt) @@ -289,7 +231,6 @@ static void kgdboc_post_exp_handler(void) dbg_restore_graphics = 0; con_debug_leave(); } - kgdboc_restore_input(); } static struct kgdb_io kgdboc_io_ops = { diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index cb12a8e..09615b5 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -571,7 +571,7 @@ long clk_round_parent(struct clk *clk, unsigned long target, *best_freq = freq_max; } - pr_debug("too low freq %u, error %lu\n", freq->frequency, + pr_debug("too low freq %lu, error %lu\n", freq->frequency, target - freq_max); if (!error) @@ -591,7 +591,7 @@ long clk_round_parent(struct clk *clk, unsigned long target, *best_freq = freq_min; } - pr_debug("too high freq %u, error %lu\n", freq->frequency, + pr_debug("too high freq %lu, error %lu\n", freq->frequency, freq_min - target); if (!error) diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index 4e0ff71..e5bf5d3 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -215,7 +215,7 @@ restart: entry = radix_tree_deref_slot((void **)entries[i]); if (unlikely(!entry)) continue; - if (radix_tree_deref_retry(entry)) + if (unlikely(entry == RADIX_TREE_RETRY)) goto restart; irq = create_irq(); diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig index 8a5caa3..ae2cdf4 100644 --- a/drivers/staging/ath6kl/Kconfig +++ b/drivers/staging/ath6kl/Kconfig @@ -102,7 +102,7 @@ config AR600x_BT_RESET_PIN config ATH6KL_CFG80211 bool "CFG80211 support" - depends on ATH6K_LEGACY && CFG80211 + depends on ATH6K_LEGACY help Enables support for CFG80211 APIs. The default option is to use WEXT. Even with this option enabled, WEXT is not explicitly disabled and the onus of not exercising WEXT lies on the application(s) running in the user space. diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index a659f70..c5a6d6c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1126,7 +1126,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { A_UINT32 param; - status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size); + status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(((A_UINT32)fw_entry->data) + board_data_size), board_ext_data_size); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); @@ -3030,8 +3030,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) A_UINT8 csumDest=0; A_UINT8 csum=skb->ip_summed; if(csumOffload && (csum==CHECKSUM_PARTIAL)){ - csumStart = (skb->head + skb->csum_start - skb_network_header(skb) + - sizeof(ATH_LLC_SNAP_HDR)); + csumStart=skb->csum_start-(skb->network_header-skb->head)+sizeof(ATH_LLC_SNAP_HDR); csumDest=skb->csum_offset+csumStart; } #endif diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 7269d0a..c94ad29 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -808,7 +808,7 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status) static int ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr, + A_UINT8 key_index, const A_UINT8 *mac_addr, struct key_params *params) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); @@ -901,7 +901,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr) + A_UINT8 key_index, const A_UINT8 *mac_addr) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); @@ -936,8 +936,7 @@ ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr, - void *cookie, + A_UINT8 key_index, const A_UINT8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params*)) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index b68a7e5..80cfa86 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -165,7 +165,7 @@ static void update_mac_addresses(struct batman_if *batman_if) batman_if->net_dev->dev_addr, ETH_ALEN); } -static void check_known_mac_addr(struct net_device *net_dev) +static void check_known_mac_addr(uint8_t *addr) { struct batman_if *batman_if; @@ -175,16 +175,11 @@ static void check_known_mac_addr(struct net_device *net_dev) (batman_if->if_status != IF_TO_BE_ACTIVATED)) continue; - if (batman_if->net_dev == net_dev) - continue; - - if (!compare_orig(batman_if->net_dev->dev_addr, - net_dev->dev_addr)) + if (!compare_orig(batman_if->net_dev->dev_addr, addr)) continue; pr_warning("The newly added mac address (%pM) already exists " - "on: %s\n", net_dev->dev_addr, - batman_if->net_dev->name); + "on: %s\n", addr, batman_if->net_dev->name); pr_warning("It is strongly recommended to keep mac addresses " "unique to avoid problems!\n"); } @@ -435,7 +430,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) atomic_set(&batman_if->refcnt, 0); hardif_hold(batman_if); - check_known_mac_addr(batman_if->net_dev); + check_known_mac_addr(batman_if->net_dev->dev_addr); spin_lock(&if_list_lock); list_add_tail_rcu(&batman_if->list, &if_list); @@ -520,7 +515,7 @@ static int hard_if_event(struct notifier_block *this, goto out; } - check_known_mac_addr(batman_if->net_dev); + check_known_mac_addr(batman_if->net_dev->dev_addr); update_mac_addresses(batman_if); bat_priv = netdev_priv(batman_if->soft_iface); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 657b69e..9010263 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1000,10 +1000,10 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) /* find a suitable router for this originator, and use * bonding if possible. */ -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, +struct neigh_node *find_router(struct orig_node *orig_node, struct batman_if *recv_if) { + struct bat_priv *bat_priv; struct orig_node *primary_orig_node; struct orig_node *router_orig; struct neigh_node *router, *first_candidate, *best_router; @@ -1019,9 +1019,13 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, /* without bonding, the first node should * always choose the default router. */ + if (!recv_if) + return orig_node->router; + + bat_priv = netdev_priv(recv_if->soft_iface); bonding_enabled = atomic_read(&bat_priv->bonding_enabled); - if ((!recv_if) && (!bonding_enabled)) + if (!bonding_enabled) return orig_node->router; router_orig = orig_node->router->orig_node; @@ -1150,7 +1154,7 @@ static int route_unicast_packet(struct sk_buff *skb, orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, unicast_packet->dest)); - router = find_router(bat_priv, orig_node, recv_if); + router = find_router(orig_node, recv_if); if (!router) { spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h index 92674c8..06ea99d 100644 --- a/drivers/staging/batman-adv/routing.h +++ b/drivers/staging/batman-adv/routing.h @@ -38,8 +38,8 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if); -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, struct batman_if *recv_if); +struct neigh_node *find_router(struct orig_node *orig_node, + struct batman_if *recv_if); void update_bonding_candidates(struct bat_priv *bat_priv, struct orig_node *orig_node); diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 0459413..0dac50d 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -224,7 +224,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) if (!orig_node) orig_node = transtable_search(bat_priv, ethhdr->h_dest); - router = find_router(bat_priv, orig_node, NULL); + router = find_router(orig_node, NULL); if (!router) goto unlock; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index fead9c5..77fdfe2 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -1001,15 +1001,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } #endif case IOCTL_BE_BUCKET_SIZE: - Status = 0; - if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) - Status = -EFAULT; + Adapter->BEBucketSize = *(PULONG)arg; + Status = STATUS_SUCCESS; break; case IOCTL_RTPS_BUCKET_SIZE: - Status = 0; - if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) - Status = -EFAULT; + Adapter->rtPSBucketSize = *(PULONG)arg; + Status = STATUS_SUCCESS; break; case IOCTL_CHIP_RESET: { @@ -1030,15 +1028,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_QOS_THRESHOLD: { USHORT uiLoopIndex; - - Status = 0; - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { - if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, - (unsigned long __user *)arg)) { - Status = -EFAULT; - break; - } + for(uiLoopIndex = 0 ; uiLoopIndex < NO_OF_QUEUES ; uiLoopIndex++) + { + Adapter->PackInfo[uiLoopIndex].uiThreshold = *(PULONG)arg; } + Status = STATUS_SUCCESS; break; } @@ -1099,8 +1093,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } case IOCTL_BCM_GET_CURRENT_STATUS: { - LINK_STATE plink_state; - + LINK_STATE *plink_state = NULL; /* Copy Ioctl Buffer structure */ if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { @@ -1108,19 +1101,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = -EFAULT; break; } - if (IoBuffer.OutputLength != sizeof(plink_state)) { - Status = -EINVAL; - break; - } - - if (copy_from_user(&plink_state, (void __user *)arg, sizeof(plink_state))) { - Status = -EFAULT; - break; - } - plink_state.bIdleMode = (UCHAR)Adapter->IdleMode; - plink_state.bShutdownMode = Adapter->bShutStatus; - plink_state.ucLinkStatus = (UCHAR)Adapter->LinkStatus; - if (copy_to_user(IoBuffer.OutputBuffer, &plink_state, IoBuffer.OutputLength)) { + plink_state = (LINK_STATE*)arg; + plink_state->bIdleMode = (UCHAR)Adapter->IdleMode; + plink_state->bShutdownMode = Adapter->bShutStatus; + plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus; + if(copy_to_user(IoBuffer.OutputBuffer, + (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength)) + { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); Status = -EFAULT; break; @@ -1344,9 +1331,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status); return -EFAULT; } - if (get_user(uiSectorSize, (unsigned int __user *)IoBuffer.InputBuffer)) - return -EFAULT; - + uiSectorSize = *((PUINT)(IoBuffer.InputBuffer)); /* FIXME: unchecked __user access */ if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) { diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index c8f1cf1..c3ba9bb 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -90,5 +90,5 @@ Contact Info: ============= Brett Rudley brudley@broadcom.com Henry Ptasinski henryp@broadcom.com -Dowan Kim dowan@broadcom.com +Nohee Ko noheek@broadcom.com diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index dbf9041..8803d30 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -45,5 +45,5 @@ Contact ===== Brett Rudley Henry Ptasinski -Dowan Kim +Nohee Ko diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 9335f02..bbbe7c5 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2222,6 +2222,8 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) ASSERT(net); ASSERT(!net->netdev_ops); + net->netdev_ops = &dhd_ops_virt; + net->netdev_ops = &dhd_ops_pri; /* diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index ea08252..3f29488 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -95,12 +95,12 @@ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx); static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, + u8 key_idx, const u8 *mac_addr, struct key_params *params); static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr); + u8 key_idx, const u8 *mac_addr); static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, + u8 key_idx, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params * @@ -1615,7 +1615,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, + u8 key_idx, const u8 *mac_addr, struct key_params *params) { struct wl_wsec_key key; @@ -1700,7 +1700,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr) + u8 key_idx, const u8 *mac_addr) { struct wl_wsec_key key; s32 err = 0; @@ -1756,7 +1756,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, + u8 key_idx, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params * params)) { struct key_params params; diff --git a/drivers/staging/cpia/cpia.c b/drivers/staging/cpia/cpia.c index 0e740b8..933ae4c 100644 --- a/drivers/staging/cpia/cpia.c +++ b/drivers/staging/cpia/cpia.c @@ -3184,9 +3184,13 @@ static int cpia_open(struct file *file) goto oops; } + err = -EINTR; + if(signal_pending(current)) + goto oops; + /* Set ownership of /proc/cpia/videoX to current user */ if(cam->proc_entry) - cam->proc_entry->uid = current_euid(); + cam->proc_entry->uid = current_uid(); /* set mark for loading first frame uncompressed */ cam->first_frame = 1; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 20d5098..87a6487 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -286,6 +286,7 @@ int ft1000_CreateDevice(struct ft1000_device *dev) pid = kernel_thread (exec_mknod, (void *)info, 0); // initialize application information + info->appcnt = 0; // if (ft1000_flarion_cnt == 0) { // diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index a99e900..702a478 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -212,6 +212,9 @@ static void heartbeat_onchannelcallback(void *context) recvlen, requestid); icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index 9618c79..463e5cb 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -244,12 +244,12 @@ static int intel_sst_mmap_play_capture(u32 str_id, int retval, i; struct stream_info *stream; struct snd_sst_mmap_buff_entry *buf_entry; - struct snd_sst_mmap_buff_entry *tmp_buf; pr_debug("sst:called for str_id %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return -EINVAL; + BUG_ON(!mmap_buf); stream = &sst_drv_ctx->streams[str_id]; if (stream->mmapped != true) @@ -262,24 +262,14 @@ static int intel_sst_mmap_play_capture(u32 str_id, stream->curr_bytes = 0; stream->cumm_bytes = 0; - tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL); - if (!tmp_buf) - return -ENOMEM; - if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff, - mmap_buf->entries * sizeof(*tmp_buf))) { - retval = -EFAULT; - goto out_free; - } - pr_debug("sst:new buffers count %d status %d\n", mmap_buf->entries, stream->status); - buf_entry = tmp_buf; + buf_entry = mmap_buf->buff; for (i = 0; i < mmap_buf->entries; i++) { + BUG_ON(!buf_entry); bufs = kzalloc(sizeof(*bufs), GFP_KERNEL); - if (!bufs) { - retval = -ENOMEM; - goto out_free; - } + if (!bufs) + return -ENOMEM; bufs->size = buf_entry->size; bufs->offset = buf_entry->offset; bufs->addr = sst_drv_ctx->mmap_mem; @@ -303,15 +293,13 @@ static int intel_sst_mmap_play_capture(u32 str_id, if (sst_play_frame(str_id) < 0) { pr_warn("sst: play frames fail\n"); mutex_unlock(&stream->lock); - retval = -EIO; - goto out_free; + return -EIO; } } else if (stream->ops == STREAM_OPS_CAPTURE) { if (sst_capture_frame(str_id) < 0) { pr_warn("sst: capture frame fail\n"); mutex_unlock(&stream->lock); - retval = -EIO; - goto out_free; + return -EIO; } } } @@ -326,9 +314,6 @@ static int intel_sst_mmap_play_capture(u32 str_id, if (retval >= 0) retval = stream->cumm_bytes; pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval); - -out_free: - kfree(tmp_buf); return retval; } @@ -392,7 +377,7 @@ static int snd_sst_fill_kernel_list(struct stream_info *stream, { struct sst_stream_bufs *stream_bufs; unsigned long index, mmap_len; - unsigned char __user *bufp; + unsigned char *bufp; unsigned long size, copied_size; int retval = 0, add_to_list = 0; static int sent_offset; @@ -527,7 +512,9 @@ static int snd_sst_copy_userbuf_capture(struct stream_info *stream, /* copy to user */ list_for_each_entry_safe(entry, _entry, copy_to_list, node) { - if (copy_to_user(iovec[entry->iov_index].iov_base + entry->iov_offset, + if (copy_to_user((void *) + iovec[entry->iov_index].iov_base + + entry->iov_offset, kbufs->addr + entry->offset, entry->size)) { /* Clean up the list and return error */ @@ -603,7 +590,7 @@ static int intel_sst_read_write(unsigned int str_id, char __user *buf, buf, (int) count, (int) stream->status); stream->buf_type = SST_BUF_USER_STATIC; - iovec.iov_base = buf; + iovec.iov_base = (void *)buf; iovec.iov_len = count; nr_segs = 1; @@ -851,7 +838,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): { - struct snd_sst_params str_param; + struct snd_sst_params *str_param = (struct snd_sst_params *)arg; pr_debug("sst: IOCTL_SET_PARAMS recieved!\n"); if (minor != STREAM_MODULE) { @@ -859,25 +846,17 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } - if (copy_from_user(&str_param, (void __user *)arg, - sizeof(str_param))) { - retval = -EFAULT; - break; - } - if (!str_id) { - retval = sst_get_stream(&str_param); + retval = sst_get_stream(str_param); if (retval > 0) { struct stream_info *str_info; - char __user *dest; - sst_drv_ctx->stream_cnt++; data->str_id = retval; str_info = &sst_drv_ctx->streams[retval]; str_info->src = SST_DRV; - dest = (char __user *)arg + offsetof(struct snd_sst_params, stream_id); - retval = copy_to_user(dest, &retval, sizeof(__u32)); + retval = copy_to_user(&str_param->stream_id, + &retval, sizeof(__u32)); if (retval) retval = -EFAULT; } else { @@ -887,14 +866,16 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } else { pr_debug("sst: SET_STREAM_PARAMS recieved!\n"); /* allocated set params only */ - retval = sst_set_stream_param(str_id, &str_param); + retval = sst_set_stream_param(str_id, str_param); /* Block the call for reply */ if (!retval) { int sfreq = 0, word_size = 0, num_channel = 0; - sfreq = str_param.sparams.uc.pcm_params.sfreq; - word_size = str_param.sparams.uc.pcm_params.pcm_wd_sz; - num_channel = str_param.sparams.uc.pcm_params.num_chan; - if (str_param.ops == STREAM_OPS_CAPTURE) { + sfreq = str_param->sparams.uc.pcm_params.sfreq; + word_size = str_param->sparams. + uc.pcm_params.pcm_wd_sz; + num_channel = str_param-> + sparams.uc.pcm_params.num_chan; + if (str_param->ops == STREAM_OPS_CAPTURE) { sst_drv_ctx->scard_ops->\ set_pcm_audio_params(sfreq, word_size, num_channel); @@ -904,39 +885,41 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } case _IOC_NR(SNDRV_SST_SET_VOL): { - struct snd_sst_vol set_vol; - - if (copy_from_user(&set_vol, (void __user *)arg, - sizeof(set_vol))) { - pr_debug("sst: copy failed\n"); - retval = -EFAULT; - break; - } + struct snd_sst_vol *set_vol; + struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; pr_debug("sst: SET_VOLUME recieved for %d!\n", - set_vol.stream_id); - if (minor == STREAM_MODULE && set_vol.stream_id == 0) { + rec_vol->stream_id); + if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { pr_debug("sst: invalid operation!\n"); retval = -EPERM; break; } - retval = sst_set_vol(&set_vol); + set_vol = kzalloc(sizeof(*set_vol), GFP_ATOMIC); + if (!set_vol) { + pr_debug("sst: mem allocation failed\n"); + retval = -ENOMEM; + break; + } + if (copy_from_user(set_vol, rec_vol, sizeof(*set_vol))) { + pr_debug("sst: copy failed\n"); + retval = -EFAULT; + break; + } + retval = sst_set_vol(set_vol); + kfree(set_vol); break; } case _IOC_NR(SNDRV_SST_GET_VOL): { + struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; struct snd_sst_vol get_vol; - - if (copy_from_user(&get_vol, (void __user *)arg, - sizeof(get_vol))) { - retval = -EFAULT; - break; - } pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n", - get_vol.stream_id); - if (minor == STREAM_MODULE && get_vol.stream_id == 0) { + rec_vol->stream_id); + if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { pr_debug("sst: invalid operation!\n"); retval = -EPERM; break; } + get_vol.stream_id = rec_vol->stream_id; retval = sst_get_vol(&get_vol); if (retval) { retval = -EIO; @@ -945,7 +928,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n", get_vol.stream_id, get_vol.volume, get_vol.ramp_duration, get_vol.ramp_type); - if (copy_to_user((struct snd_sst_vol __user *)arg, + if (copy_to_user((struct snd_sst_vol *)arg, &get_vol, sizeof(get_vol))) { retval = -EFAULT; break; @@ -955,20 +938,25 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_MUTE): { - struct snd_sst_mute set_mute; - - if (copy_from_user(&set_mute, (void __user *)arg, - sizeof(set_mute))) { - retval = -EFAULT; - break; - } + struct snd_sst_mute *set_mute; + struct snd_sst_vol *rec_mute = (struct snd_sst_vol *)arg; pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n", - set_mute.stream_id); - if (minor == STREAM_MODULE && set_mute.stream_id == 0) { + rec_mute->stream_id); + if (minor == STREAM_MODULE && rec_mute->stream_id == 0) { retval = -EPERM; break; } - retval = sst_set_mute(&set_mute); + set_mute = kzalloc(sizeof(*set_mute), GFP_ATOMIC); + if (!set_mute) { + retval = -ENOMEM; + break; + } + if (copy_from_user(set_mute, rec_mute, sizeof(*set_mute))) { + retval = -EFAULT; + break; + } + retval = sst_set_mute(set_mute); + kfree(set_mute); break; } case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): { @@ -985,7 +973,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EIO; break; } - if (copy_to_user((struct snd_sst_get_stream_params __user *)arg, + if (copy_to_user((struct snd_sst_get_stream_params *)arg, &get_params, sizeof(get_params))) { retval = -EFAULT; break; @@ -995,22 +983,16 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_MMAP_PLAY): - case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): { - struct snd_sst_mmap_buffs mmap_buf; - + case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; } - if (copy_from_user(&mmap_buf, (void __user *)arg, - sizeof(mmap_buf))) { - retval = -EFAULT; - break; - } - retval = intel_sst_mmap_play_capture(str_id, &mmap_buf); + retval = intel_sst_mmap_play_capture(str_id, + (struct snd_sst_mmap_buffs *)arg); break; - } + case _IOC_NR(SNDRV_SST_STREAM_DROP): pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n"); if (minor != STREAM_MODULE) { @@ -1021,6 +1003,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): { + unsigned long long *ms = (unsigned long long *)arg; struct snd_sst_tstamp tstamp = {0}; unsigned long long time, freq, mod; @@ -1030,14 +1013,14 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } memcpy_fromio(&tstamp, - sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp), + ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP) + +(str_id * sizeof(tstamp))), sizeof(tstamp)); time = tstamp.samples_rendered; freq = (unsigned long long) tstamp.sampling_frequency; time = time * 1000; /* converting it to ms */ mod = do_div(time, freq); - if (copy_to_user((void __user *)arg, &time, - sizeof(unsigned long long))) + if (copy_to_user(ms, &time, sizeof(*ms))) retval = -EFAULT; break; } @@ -1082,118 +1065,92 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): { - struct snd_sst_target_device target_device; + struct snd_sst_target_device *target_device; pr_debug("sst: SET_TARGET_DEVICE recieved!\n"); - if (copy_from_user(&target_device, (void __user *)arg, - sizeof(target_device))) { - retval = -EFAULT; - break; - } + target_device = (struct snd_sst_target_device *)arg; + BUG_ON(!target_device); if (minor != AM_MODULE) { retval = -EBADRQC; break; } - retval = sst_target_device_select(&target_device); + retval = sst_target_device_select(target_device); break; } case _IOC_NR(SNDRV_SST_DRIVER_INFO): { - struct snd_sst_driver_info info; + struct snd_sst_driver_info *info = + (struct snd_sst_driver_info *)arg; pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n"); - info.version = SST_VERSION_NUM; + info->version = SST_VERSION_NUM; /* hard coding, shud get sumhow later */ - info.active_pcm_streams = sst_drv_ctx->stream_cnt - + info->active_pcm_streams = sst_drv_ctx->stream_cnt - sst_drv_ctx->encoded_cnt; - info.active_enc_streams = sst_drv_ctx->encoded_cnt; - info.max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM; - info.max_enc_streams = MAX_ENC_STREAM; - info.buf_per_stream = sst_drv_ctx->mmap_len; - if (copy_to_user((void __user *)arg, &info, - sizeof(info))) - retval = -EFAULT; + info->active_enc_streams = sst_drv_ctx->encoded_cnt; + info->max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM; + info->max_enc_streams = MAX_ENC_STREAM; + info->buf_per_stream = sst_drv_ctx->mmap_len; break; } case _IOC_NR(SNDRV_SST_STREAM_DECODE): { - struct snd_sst_dbufs param; - struct snd_sst_dbufs dbufs_local; + struct snd_sst_dbufs *param = + (struct snd_sst_dbufs *)arg, dbufs_local; + int i; struct snd_sst_buffs ibufs, obufs; - struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp; - char __user *dest; + struct snd_sst_buff_entry ibuf_temp[param->ibufs->entries], + obuf_temp[param->obufs->entries]; pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; } - if (copy_from_user(¶m, (void __user *)arg, - sizeof(param))) { - retval = -EFAULT; + if (!param) { + retval = -EINVAL; break; } - dbufs_local.input_bytes_consumed = param.input_bytes_consumed; + dbufs_local.input_bytes_consumed = param->input_bytes_consumed; dbufs_local.output_bytes_produced = - param.output_bytes_produced; - - if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) { - retval = -EFAULT; - break; - } - if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) { - retval = -EFAULT; - break; - } - - ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL); - obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL); - if (!ibuf_tmp || !obuf_tmp) { - retval = -ENOMEM; - goto free_iobufs; - } - - if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry, - ibufs.entries * sizeof(*ibuf_tmp))) { - retval = -EFAULT; - goto free_iobufs; - } - ibufs.buff_entry = ibuf_tmp; + param->output_bytes_produced; dbufs_local.ibufs = &ibufs; - - if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry, - obufs.entries * sizeof(*obuf_tmp))) { - retval = -EFAULT; - goto free_iobufs; - } - obufs.buff_entry = obuf_tmp; dbufs_local.obufs = &obufs; - - retval = sst_decode(str_id, &dbufs_local); - if (retval) { - retval = -EAGAIN; - goto free_iobufs; + dbufs_local.ibufs->entries = param->ibufs->entries; + dbufs_local.ibufs->type = param->ibufs->type; + dbufs_local.obufs->entries = param->obufs->entries; + dbufs_local.obufs->type = param->obufs->type; + + dbufs_local.ibufs->buff_entry = ibuf_temp; + for (i = 0; i < dbufs_local.ibufs->entries; i++) { + ibuf_temp[i].buffer = + param->ibufs->buff_entry[i].buffer; + ibuf_temp[i].size = + param->ibufs->buff_entry[i].size; } - - dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed); - if (copy_to_user(dest, + dbufs_local.obufs->buff_entry = obuf_temp; + for (i = 0; i < dbufs_local.obufs->entries; i++) { + obuf_temp[i].buffer = + param->obufs->buff_entry[i].buffer; + obuf_temp[i].size = + param->obufs->buff_entry[i].size; + } + retval = sst_decode(str_id, &dbufs_local); + if (retval) + retval = -EAGAIN; + if (copy_to_user(¶m->input_bytes_consumed, &dbufs_local.input_bytes_consumed, sizeof(unsigned long long))) { - retval = -EFAULT; - goto free_iobufs; + retval = -EFAULT; + break; } - - dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed); - if (copy_to_user(dest, + if (copy_to_user(¶m->output_bytes_produced, &dbufs_local.output_bytes_produced, sizeof(unsigned long long))) { - retval = -EFAULT; - goto free_iobufs; + retval = -EFAULT; + break; } -free_iobufs: - kfree(ibuf_tmp); - kfree(obuf_tmp); break; } @@ -1207,7 +1164,7 @@ free_iobufs: break; case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): { - unsigned long long __user *bytes = (unsigned long long __user *)arg; + unsigned long long *bytes = (unsigned long long *)arg; struct snd_sst_tstamp tstamp = {0}; pr_debug("sst: STREAM_BYTES_DECODED recieved!\n"); @@ -1216,7 +1173,8 @@ free_iobufs: break; } memcpy_fromio(&tstamp, - sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp), + ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP) + +(str_id * sizeof(tstamp))), sizeof(tstamp)); if (copy_to_user(bytes, &tstamp.bytes_processed, sizeof(*bytes))) @@ -1239,7 +1197,7 @@ free_iobufs: kfree(fw_info); break; } - if (copy_to_user((struct snd_sst_dbufs __user *)arg, + if (copy_to_user((struct snd_sst_dbufs *)arg, fw_info, sizeof(*fw_info))) { kfree(fw_info); retval = -EFAULT; diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h index bf0ead7..73a98c8 100644 --- a/drivers/staging/intel_sst/intel_sst_common.h +++ b/drivers/staging/intel_sst/intel_sst_common.h @@ -231,8 +231,8 @@ struct stream_info { spinlock_t pcm_lock; bool mmapped; unsigned int sg_index; /* current buf Index */ - unsigned char __user *cur_ptr; /* Current static bufs */ - struct snd_sst_buf_entry __user *buf_entry; + unsigned char *cur_ptr; /* Current static bufs */ + struct snd_sst_buf_entry *buf_entry; struct sst_block data_blk; /* stream ops block */ struct sst_block ctrl_blk; /* stream control cmd block */ enum snd_sst_buf_type buf_type; diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index 978bf87..1934805 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -22,7 +22,7 @@ int ENE_InitMedia(struct us_data *us) int result; BYTE MiscReg03 = 0; - printk("--- Init Media ---\n"); + printk("--- Initial Nedia ---\n"); result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03); if (result != USB_STOR_XFER_GOOD) { @@ -64,7 +64,7 @@ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf) struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x01; bcb->Flags = 0x80; @@ -92,7 +92,7 @@ int ENE_SDInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->Flags = 0x80; bcb->CDB[0] = 0xF2; @@ -112,7 +112,7 @@ int ENE_SDInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -161,7 +161,7 @@ int ENE_MSInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -219,7 +219,7 @@ int ENE_SMInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -341,7 +341,7 @@ int ENE_LoadBinCode(struct us_data *us, BYTE flag) break; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x800; bcb->Flags =0x00; @@ -433,7 +433,7 @@ int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length) //printk("transport --- ENE_Read_Data\n"); // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = length; bcb->Flags =0x80; @@ -470,7 +470,7 @@ int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length) //printk("transport --- ENE_Write_Data\n"); // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = length; bcb->Flags =0x00; diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c index 9a3fdb4..d4340a9 100644 --- a/drivers/staging/keucr/ms.c +++ b/drivers/staging/keucr/ms.c @@ -15,7 +15,7 @@ int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlo if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*len; bcb->Flags = 0x00; @@ -53,7 +53,7 @@ int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWO return USB_STOR_TRANSPORT_ERROR; // Read Page Data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -69,7 +69,7 @@ int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWO return USB_STOR_TRANSPORT_ERROR; // Read Extra Data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4; bcb->Flags = 0x80; @@ -108,7 +108,7 @@ int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr) if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -673,7 +673,7 @@ int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); // Read Extra Data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4 * blen; bcb->Flags = 0x80; @@ -700,7 +700,7 @@ int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibType BYTE ExtBuf[4]; //printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4; bcb->Flags = 0x80; @@ -807,7 +807,7 @@ int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, B if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4; bcb->Flags = 0x80; diff --git a/drivers/staging/keucr/msscsi.c b/drivers/staging/keucr/msscsi.c index cb92d25..ad0c5c6 100644 --- a/drivers/staging/keucr/msscsi.c +++ b/drivers/staging/keucr/msscsi.c @@ -145,7 +145,7 @@ int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) } // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x80; @@ -193,7 +193,7 @@ int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) blkno = phyblk * 0x20 + PageNum; // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200 * len; bcb->Flags = 0x80; @@ -250,7 +250,7 @@ int MS_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) } // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x00; diff --git a/drivers/staging/keucr/sdscsi.c b/drivers/staging/keucr/sdscsi.c index d646507..6c332f8 100644 --- a/drivers/staging/keucr/sdscsi.c +++ b/drivers/staging/keucr/sdscsi.c @@ -152,7 +152,7 @@ int SD_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) bnByte = bn; // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x80; @@ -192,7 +192,7 @@ int SD_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) bnByte = bn; // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x00; diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index 1b52535..844b659 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -266,7 +266,7 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; // Read sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -281,7 +281,7 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_ERROR; // Read redundant - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; @@ -319,7 +319,7 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; // Read sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*count; bcb->Flags = 0x80; @@ -334,7 +334,7 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_ERROR; // Read redundant - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; @@ -536,7 +536,7 @@ int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors; // Write sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*count; bcb->Flags = 0x00; @@ -754,7 +754,7 @@ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; // Write sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x00; @@ -791,7 +791,7 @@ int Ssfdc_D_EraseBlock(struct us_data *us) addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; addr=addr*(WORD)Ssfdc.MaxSectors; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -827,7 +827,7 @@ int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant) addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; @@ -870,7 +870,7 @@ int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant) addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; diff --git a/drivers/staging/keucr/transport.c b/drivers/staging/keucr/transport.c index 111160c..fd98df6 100644 --- a/drivers/staging/keucr/transport.c +++ b/drivers/staging/keucr/transport.c @@ -40,7 +40,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) us->current_urb->error_count = 0; us->current_urb->status = 0; - us->current_urb->transfer_flags = 0; +// us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP; if (us->current_urb->transfer_buffer == us->iobuf) us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; us->current_urb->transfer_dma = us->iobuf_dma; diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 4ca45ec..75aa7a3 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -732,6 +733,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) edev: platform_device_unregister(dcon_device); dcon_device = NULL; + i2c_set_clientdata(client, NULL); eirq: free_irq(DCON_IRQ, &dcon_driver); einit: @@ -755,6 +757,8 @@ static int dcon_remove(struct i2c_client *client) platform_device_unregister(dcon_device); cancel_work_sync(&dcon_work); + i2c_set_clientdata(client, NULL); + return 0; } diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c index a99879b..1d159ff 100644 --- a/drivers/staging/rt2860/common/cmm_aes.c +++ b/drivers/staging/rt2860/common/cmm_aes.c @@ -330,6 +330,8 @@ void construct_mic_iv(unsigned char *mic_iv, for (i = 8; i < 14; i++) mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ #endif + i = (payload_length / 256); + i = (payload_length % 256); mic_iv[14] = (unsigned char)(payload_length / 256); mic_iv[15] = (unsigned char)(payload_length % 256); diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index ddacfc6..ebf9074 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -65,7 +65,6 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x14B2, 0x3C07)}, /* AL */ {USB_DEVICE(0x050D, 0x8053)}, /* Belkin */ {USB_DEVICE(0x050D, 0x825B)}, /* Belkin */ - {USB_DEVICE(0x050D, 0x935A)}, /* Belkin F6D4050 v1 */ {USB_DEVICE(0x050D, 0x935B)}, /* Belkin F6D4050 v2 */ {USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */ {USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index b1786dc..a202194 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5829,9 +5829,6 @@ static void rtl8192_rx(struct net_device *dev) } } - pci_unmap_single(priv->pdev, *((dma_addr_t *) skb->cb), - priv->rxbuffersize, PCI_DMA_FROMDEVICE); - skb = new_skb; priv->rx_buf[priv->rx_idx] = skb; *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); diff --git a/drivers/staging/stradis/stradis.c b/drivers/staging/stradis/stradis.c index 807dd7e..a057824 100644 --- a/drivers/staging/stradis/stradis.c +++ b/drivers/staging/stradis/stradis.c @@ -1286,7 +1286,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGCAP: { struct video_capability b; - memset(&b, 0, sizeof(b)); strcpy(b.name, saa->video_dev.name); b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM | @@ -1417,7 +1416,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGWIN: { struct video_window vw; - memset(&vw, 0, sizeof(vw)); vw.x = saa->win.x; vw.y = saa->win.y; vw.width = saa->win.width; @@ -1450,7 +1448,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGFBUF: { struct video_buffer v; - memset(&v, 0, sizeof(v)); v.base = (void *)saa->win.vidadr; v.height = saa->win.sheight; v.width = saa->win.swidth; @@ -1495,7 +1492,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGAUDIO: { struct video_audio v; - memset(&v, 0, sizeof(v)); v = saa->audio_dev; v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; @@ -1538,7 +1534,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGUNIT: { struct video_unit vu; - memset(&vu, 0, sizeof(vu)); vu.video = saa->video_dev.minor; vu.vbi = VIDEO_NO_UNIT; vu.radio = VIDEO_NO_UNIT; @@ -1893,7 +1888,6 @@ static int saa_open(struct file *file) saa->user++; if (saa->user > 1) { - saa->user--; unlock_kernel(); return 0; /* device open already, don't reset */ } @@ -2006,13 +2000,10 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num) if (retval < 0) { dev_err(&pdev->dev, "%d: error in registering video device!\n", num); - goto errirq; + goto errio; } return 0; - -errirq: - free_irq(saa->irq, saa); errio: iounmap(saa->saa7146_mem); err: diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig index 93de4f2..ff64d46 100644 --- a/drivers/staging/tidspbridge/Kconfig +++ b/drivers/staging/tidspbridge/Kconfig @@ -6,6 +6,7 @@ menuconfig TIDSPBRIDGE tristate "DSP Bridge driver" depends on ARCH_OMAP3 select OMAP_MBOX_FWK + select OMAP_IOMMU help DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more attached DSPs. The GPP is considered the master or diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index 41c644c..50decc2 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -2,19 +2,18 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ - core/tiomap3430_pwr.o core/tiomap_io.o \ + core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ - pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o + pmgr/cmm.o pmgr/dbll.o librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \ rmgr/nldr.o rmgr/drv_interface.o libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \ dynload/tramp.o -libhw = hw/hw_mmu.o bridgedriver-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ - $(libdload) $(libhw) + $(libdload) #Machine dependent ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index 16723cd..8ae2633 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h @@ -27,9 +27,8 @@ struct deh_mgr { struct bridge_dev_context *hbridge_context; /* Bridge context. */ struct ntfy_object *ntfy_obj; /* NTFY object */ - - /* MMU Fault DPC */ - struct tasklet_struct dpc_tasklet; }; +int mmu_fault_isr(struct iommu *mmu); + #endif /* _DEH_ */ diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 1c1f157..e0a801c 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -23,8 +23,8 @@ #include #include #include +#include #include -#include #include /* for bridge_ioctl_extproc defn */ #include #include @@ -306,6 +306,18 @@ static const struct bpwr_clk_t bpwr_clks[] = { #define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index))) +struct shm_segs { + u32 seg0_da; + u32 seg0_pa; + u32 seg0_va; + u32 seg0_size; + u32 seg1_da; + u32 seg1_pa; + u32 seg1_va; + u32 seg1_size; +}; + + /* This Bridge driver's device context: */ struct bridge_dev_context { struct dev_object *hdev_obj; /* Handle to Bridge device object. */ @@ -316,7 +328,6 @@ struct bridge_dev_context { */ u32 dw_dsp_ext_base_addr; /* See the comment above */ u32 dw_api_reg_base; /* API mem map'd registers */ - void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ u32 dw_api_clk_base; /* CLK Registers */ u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 dw_public_rhea; /* Pub Rhea */ @@ -328,7 +339,8 @@ struct bridge_dev_context { u32 dw_internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ - + struct iommu *dsp_mmu; /* iommu for iva2 handler */ + struct shm_segs sh_s; struct cfg_hostres *resources; /* Host Resources */ /* @@ -341,7 +353,6 @@ struct bridge_dev_context { /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ - struct pg_table_attrs *pt_attrs; u32 dsp_per_clks; }; diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c new file mode 100644 index 0000000..983c95a --- /dev/null +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -0,0 +1,317 @@ +/* + * dsp-mmu.c + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include "_tiomap.h" + +#include + +#define MMU_CNTL_TWL_EN (1 << 2) + +static struct tasklet_struct mmu_tasklet; + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE +static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) +{ + void *dummy_addr; + u32 fa, tmp; + struct iotlb_entry e; + struct iommu *mmu = dev_context->dsp_mmu; + dummy_addr = (void *)__get_free_page(GFP_ATOMIC); + + /* + * Before acking the MMU fault, let's make sure MMU can only + * access entry #0. Then add a new entry so that the DSP OS + * can continue in order to dump the stack. + */ + tmp = iommu_read_reg(mmu, MMU_CNTL); + tmp &= ~MMU_CNTL_TWL_EN; + iommu_write_reg(mmu, tmp, MMU_CNTL); + fa = iommu_read_reg(mmu, MMU_FAULT_AD); + e.da = fa & PAGE_MASK; + e.pa = virt_to_phys(dummy_addr); + e.valid = 1; + e.prsvd = 1; + e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK; + e.endian = MMU_RAM_ENDIAN_LITTLE; + e.elsz = MMU_RAM_ELSZ_32; + e.mixed = 0; + + load_iotlb_entry(mmu, &e); + + dsp_clk_enable(DSP_CLK_GPT8); + + dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); + + /* Clear MMU interrupt */ + tmp = iommu_read_reg(mmu, MMU_IRQSTATUS); + iommu_write_reg(mmu, tmp, MMU_IRQSTATUS); + + dump_dsp_stack(dev_context); + dsp_clk_disable(DSP_CLK_GPT8); + + iopgtable_clear_entry(mmu, fa); + free_page((unsigned long)dummy_addr); +} +#endif + + +static void fault_tasklet(unsigned long data) +{ + struct iommu *mmu = (struct iommu *)data; + struct bridge_dev_context *dev_ctx; + struct deh_mgr *dm; + u32 fa; + dev_get_deh_mgr(dev_get_first(), &dm); + dev_get_bridge_context(dev_get_first(), &dev_ctx); + + if (!dm || !dev_ctx) + return; + + fa = iommu_read_reg(mmu, MMU_FAULT_AD); + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE + print_dsp_trace_buffer(dev_ctx); + dump_dl_modules(dev_ctx); + mmu_fault_print_stack(dev_ctx); +#endif + + bridge_deh_notify(dm, DSP_MMUFAULT, fa); +} + +/* + * ======== mmu_fault_isr ======== + * ISR to be triggered by a DSP MMU fault interrupt. + */ +static int mmu_fault_callback(struct iommu *mmu) +{ + if (!mmu) + return -EPERM; + + iommu_write_reg(mmu, 0, MMU_IRQENABLE); + tasklet_schedule(&mmu_tasklet); + return 0; +} + +/** + * dsp_mmu_init() - initialize dsp_mmu module and returns a handle + * + * This function initialize dsp mmu module and returns a struct iommu + * handle to use it for dsp maps. + * + */ +struct iommu *dsp_mmu_init() +{ + struct iommu *mmu; + + mmu = iommu_get("iva2"); + + if (!IS_ERR(mmu)) { + tasklet_init(&mmu_tasklet, fault_tasklet, (unsigned long)mmu); + mmu->isr = mmu_fault_callback; + } + + return mmu; +} + +/** + * dsp_mmu_exit() - destroy dsp mmu module + * @mmu: Pointer to iommu handle. + * + * This function destroys dsp mmu module. + * + */ +void dsp_mmu_exit(struct iommu *mmu) +{ + if (mmu) + iommu_put(mmu); + tasklet_kill(&mmu_tasklet); +} + +/** + * user_va2_pa() - get physical address from userspace address. + * @mm: mm_struct Pointer of the process. + * @address: Virtual user space address. + * + */ +static u32 user_va2_pa(struct mm_struct *mm, u32 address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(mm, address); + if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { + pmd = pmd_offset(pgd, address); + if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { + ptep = pte_offset_map(pmd, address); + if (ptep) { + pte = *ptep; + if (pte_present(pte)) + return pte & PAGE_MASK; + } + } + } + + return 0; +} + +/** + * get_io_pages() - pin and get pages of io user's buffer. + * @mm: mm_struct Pointer of the process. + * @uva: Virtual user space address. + * @pages Pages to be pined. + * @usr_pgs struct page array pointer where the user pages will be stored + * + */ +static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, + struct page **usr_pgs) +{ + u32 pa; + int i; + struct page *pg; + + for (i = 0; i < pages; i++) { + pa = user_va2_pa(mm, uva); + + if (!pfn_valid(__phys_to_pfn(pa))) + break; + + pg = phys_to_page(pa); + usr_pgs[i] = pg; + get_page(pg); + } + return i; +} + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgs struct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs) +{ + int res, w; + unsigned pages; + int i; + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + struct sg_table *sgt; + struct scatterlist *sg; + + if (!size || !usr_pgs) + return -EINVAL; + + pages = size / PG_SIZE4K; + + down_read(&mm->mmap_sem); + vma = find_vma(mm, uva); + while (vma && (uva + size > vma->vm_end)) + vma = find_vma(mm, vma->vm_end + 1); + + if (!vma) { + pr_err("%s: Failed to get VMA region for 0x%x (%d)\n", + __func__, uva, size); + up_read(&mm->mmap_sem); + return -EINVAL; + } + if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) + w = 1; + + if (vma->vm_flags & VM_IO) + i = get_io_pages(mm, uva, pages, usr_pgs); + else + i = get_user_pages(current, mm, uva, pages, w, 1, + usr_pgs, NULL); + up_read(&mm->mmap_sem); + + if (i < 0) + return i; + + if (i < pages) { + res = -EFAULT; + goto err_pages; + } + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) { + res = -ENOMEM; + goto err_pages; + } + + res = sg_alloc_table(sgt, pages, GFP_KERNEL); + + if (res < 0) + goto err_sg; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0); + + da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + + if (!IS_ERR_VALUE(da)) + return da; + res = (int)da; + + sg_free_table(sgt); +err_sg: + kfree(sgt); + i = pages; +err_pages: + while (i--) + put_page(usr_pgs[i]); + return res; +} + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da) +{ + unsigned i; + struct sg_table *sgt; + struct scatterlist *sg; + + sgt = iommu_vunmap(mmu, da); + if (!sgt) + return -EFAULT; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + put_page(sg_page(sg)); + sg_free_table(sgt); + kfree(sgt); + + return 0; +} diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 5718645..194bada 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -39,10 +39,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - /* Bridge Driver */ #include #include @@ -291,6 +287,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; + struct shm_segs *sm_sg; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -313,18 +310,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB]; struct cfg_hostres *host_res; struct bridge_dev_context *pbridge_context; - u32 map_attrs; u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; - u32 pa_curr = 0; - u32 va_curr = 0; - u32 gpp_va_curr = 0; - u32 num_bytes = 0; - u32 all_bits = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context); if (!pbridge_context) { @@ -337,6 +325,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } + sm_sg = &pbridge_context->sh_s; + status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { status = -EFAULT; @@ -471,129 +461,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) if (status) goto func_end; - pa_curr = ul_gpp_pa; - va_curr = ul_dyn_ext_base * hio_mgr->word_size; - gpp_va_curr = ul_gpp_va; - num_bytes = ul_seg1_size; - - /* - * Try to fit into TLB entries. If not possible, push them to page - * tables. It is quite possible that if sections are not on - * bigger page boundary, we may end up making several small pages. - * So, push them onto page tables, if that is the case. - */ - map_attrs = 0x00000000; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - while (num_bytes) { - /* - * To find the max. page size with which both PA & VA are - * aligned. - */ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, " - "num_bytes %x\n", all_bits, pa_curr, va_curr, - num_bytes); - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & - (page_size[i] - - 1)) == 0)) { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - if (status) - goto func_end; - pa_curr += page_size[i]; - va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* - * Don't try smaller sizes. Hopefully we have - * reached an address aligned to a bigger page - * size. - */ - break; - } - } - } - pa_curr += ul_pad_size; - va_curr += ul_pad_size; - gpp_va_curr += ul_pad_size; - - /* Configure the TLB entries for the next cacheable segment */ - num_bytes = ul_seg_size; - va_curr = ul_dsp_va * hio_mgr->word_size; - while (num_bytes) { - /* - * To find the max. page size with which both PA & VA are - * aligned. - */ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, " - "va_curr %x, num_bytes %x\n", all_bits, pa_curr, - va_curr, num_bytes); - for (i = 0; i < 4; i++) { - if (!(num_bytes >= page_size[i]) || - !((all_bits & (page_size[i] - 1)) == 0)) - continue; - if (ndx < MAX_LOCK_TLB_ENTRIES) { - /* - * This is the physical address written to - * DSP MMU. - */ - ae_proc[ndx].ul_gpp_pa = pa_curr; - /* - * This is the virtual uncached ioremapped - * address!!! - */ - ae_proc[ndx].ul_gpp_va = gpp_va_curr; - ae_proc[ndx].ul_dsp_va = - va_curr / hio_mgr->word_size; - ae_proc[ndx].ul_size = page_size[i]; - ae_proc[ndx].endianism = HW_LITTLE_ENDIAN; - ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT; - ae_proc[ndx].mixed_mode = HW_MMU_CPUES; - dev_dbg(bridge, "shm MMU TLB entry PA %x" - " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].ul_gpp_pa, - ae_proc[ndx].ul_gpp_va, - ae_proc[ndx].ul_dsp_va * - hio_mgr->word_size, page_size[i]); - ndx++; - } else { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - dev_dbg(bridge, - "shm MMU PTE entry PA %x" - " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].ul_gpp_pa, - ae_proc[ndx].ul_gpp_va, - ae_proc[ndx].ul_dsp_va * - hio_mgr->word_size, page_size[i]); - if (status) - goto func_end; - } - pa_curr += page_size[i]; - va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* - * Don't try smaller sizes. Hopefully we have reached - * an address aligned to a bigger page size. - */ - break; - } - } + sm_sg->seg1_pa = ul_gpp_pa; + sm_sg->seg1_da = ul_dyn_ext_base; + sm_sg->seg1_va = ul_gpp_va; + sm_sg->seg1_size = ul_seg1_size; + sm_sg->seg0_pa = ul_gpp_pa + ul_pad_size + ul_seg1_size; + sm_sg->seg0_da = ul_dsp_va; + sm_sg->seg0_va = ul_gpp_va + ul_pad_size + ul_seg1_size; + sm_sg->seg0_size = ul_seg_size; /* * Copy remaining entries from CDB. All entries are 1 MB and @@ -634,38 +509,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) "DSP_VA 0x%x\n", ae_proc[ndx].ul_gpp_pa, ae_proc[ndx].ul_dsp_va); ndx++; - } else { - status = hio_mgr->intf_fxns->pfn_brd_mem_map - (hio_mgr->hbridge_context, - hio_mgr->ext_proc_info.ty_tlb[i]. - ul_gpp_phys, - hio_mgr->ext_proc_info.ty_tlb[i]. - ul_dsp_virt, 0x100000, map_attrs, - NULL); } } if (status) goto func_end; } - map_attrs = 0x00000000; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - /* Map the L4 peripherals */ - i = 0; - while (l4_peripheral_table[i].phys_addr) { - status = hio_mgr->intf_fxns->pfn_brd_mem_map - (hio_mgr->hbridge_context, l4_peripheral_table[i].phys_addr, - l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB, - map_attrs, NULL); - if (status) - goto func_end; - i++; - } - for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) { ae_proc[i].ul_dsp_va = 0; ae_proc[i].ul_gpp_pa = 0; @@ -688,12 +537,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } else { - if (ae_proc[0].ul_dsp_va > ul_shm_base) { + if (sm_sg->seg0_da > ul_shm_base) { status = -EPERM; goto func_end; } /* ul_shm_base may not be at ul_dsp_va address */ - ul_shm_base_offset = (ul_shm_base - ae_proc[0].ul_dsp_va) * + ul_shm_base_offset = (ul_shm_base - sm_sg->seg0_da) * hio_mgr->word_size; /* * bridge_dev_ctrl() will set dev context dsp-mmu info. In @@ -717,8 +566,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) goto func_end; } /* Register SM */ - status = - register_shm_segs(hio_mgr, cod_man, ae_proc[0].ul_gpp_pa); + status = register_shm_segs(hio_mgr, cod_man, sm_sg->seg0_pa); } hio_mgr->shared_mem = (struct shm *)ul_shm_base; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 1be081f..f22bc12 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -23,6 +23,7 @@ #include #include #include +#include /* ----------------------------------- DSP/BIOS Bridge */ #include @@ -34,10 +35,6 @@ #include #include -/* ------------------------------------ Hardware Abstraction Layer */ -#include -#include - /* ----------------------------------- Link Driver */ #include #include @@ -50,7 +47,6 @@ /* ----------------------------------- Platform Manager */ #include #include -#include #include /* ----------------------------------- Local */ @@ -71,20 +67,6 @@ #define MMU_SMALL_PAGE_MASK 0xFFFFF000 #define OMAP3_IVA2_BOOTADDR_MASK 0xFFFFFC00 #define PAGES_II_LVL_TABLE 512 -#define PHYS_TO_PAGE(phys) pfn_to_page((phys) >> PAGE_SHIFT) - -/* - * This is a totally ugly layer violation, but needed until - * omap_ctrl_set_dsp_boot*() are provided. - */ -#define OMAP3_IVA2_BOOTMOD_IDLE 1 -#define OMAP2_CONTROL_GENERAL 0x270 -#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); @@ -109,12 +91,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages); -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 virt_addr, u32 ul_num_bytes); static int bridge_dev_create(struct bridge_dev_context **dev_cntxt, struct dev_object *hdev_obj, @@ -122,57 +98,8 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, - u32 va, u32 size, - struct hw_mmu_map_attrs_t *map_attrs); -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs); -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs); - bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); -/* ----------------------------------- Globals */ - -/* Attributes of L2 page tables for DSP MMU */ -struct page_info { - u32 num_entries; /* Number of valid PTEs in the L2 PT */ -}; - -/* Attributes used to manage the DSP MMU page tables */ -struct pg_table_attrs { - spinlock_t pg_lock; /* Critical section object handle */ - - u32 l1_base_pa; /* Physical address of the L1 PT */ - u32 l1_base_va; /* Virtual address of the L1 PT */ - u32 l1_size; /* Size of the L1 PT */ - u32 l1_tbl_alloc_pa; - /* Physical address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_va; - /* Virtual address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_sz; - /* Size of consistent memory allocated for L1 table. - * May not be aligned */ - - u32 l2_base_pa; /* Physical address of the L2 PT */ - u32 l2_base_va; /* Virtual address of the L2 PT */ - u32 l2_size; /* Size of the L2 PT */ - u32 l2_tbl_alloc_pa; - /* Physical address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_va; - /* Virtual address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_sz; - /* Size of consistent memory allocated for L2 table. - * May not be aligned */ - - u32 l2_num_pages; /* Number of allocated L2 PT */ - /* Array [l2_num_pages] of L2 PT info structs */ - struct page_info *pg_info; -}; - /* * This Bridge driver's function interface table. */ @@ -192,8 +119,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_brd_set_state, bridge_brd_mem_copy, bridge_brd_mem_write, - bridge_brd_mem_map, - bridge_brd_mem_un_map, /* The following CHNL functions are provided by chnl_io.lib: */ bridge_chnl_create, bridge_chnl_destroy, @@ -223,27 +148,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_msg_set_queue_id, }; -static inline void flush_all(struct bridge_dev_context *dev_context) -{ - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) - wake_dsp(dev_context, NULL); - - hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base); -} - -static void bad_page_dump(u32 pa, struct page *pg) -{ - pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); - pr_emerg("Bad page state in process '%s'\n" - "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" - "Backtrace:\n", - current->comm, pg, (int)(2 * sizeof(unsigned long)), - (unsigned long)pg->flags, pg->mapping, - page_mapcount(pg), page_count(pg)); - dump_stack(); -} - /* * ======== bridge_drv_entry ======== * purpose: @@ -299,8 +203,7 @@ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt) (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); } - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + dsp_clk_enable(DSP_CLK_IVA2); /* set the device state to IDLE */ @@ -371,14 +274,17 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, { int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; + struct iommu *mmu = NULL; + struct shm_segs *sm_sg; + int l4_i = 0, tlb_i = 0; + u32 sg0_da = 0, sg1_da = 0; + struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry; u32 dw_sync_addr = 0; u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */ u32 ul_shm_base_virt; /* Dsp Virt SM base addr */ u32 ul_tlb_base_virt; /* Base of MMU TLB entry */ /* Offset of shm_base_virt from tlb_base_virt */ u32 ul_shm_offset_virt; - s32 entry_ndx; - s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */ struct cfg_hostres *resources = NULL; u32 temp; u32 ul_dsp_clk_rate; @@ -399,12 +305,12 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, ul_shm_base_virt *= DSPWORDSIZE; DBC_ASSERT(ul_shm_base_virt != 0); /* DSP Virtual address */ - ul_tlb_base_virt = dev_context->atlb_entry[0].ul_dsp_va; + ul_tlb_base_virt = dev_context->sh_s.seg0_da; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); ul_shm_offset_virt = ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE); /* Kernel logical address */ - ul_shm_base = dev_context->atlb_entry[0].ul_gpp_va + ul_shm_offset_virt; + ul_shm_base = dev_context->sh_s.seg0_va + ul_shm_offset_virt; DBC_ASSERT(ul_shm_base != 0); /* 2nd wd is used as sync field */ @@ -439,78 +345,83 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, OMAP343X_CONTROL_IVA2_BOOTMOD)); } } + if (!status) { - /* Reset and Unreset the RST2, so that BOOTADDR is copied to - * IVA2 SYSC register */ - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, - OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - udelay(100); (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - udelay(100); - - /* Disbale the DSP MMU */ - hw_mmu_disable(resources->dw_dmmu_base); - /* Disable TWL */ - hw_mmu_twl_disable(resources->dw_dmmu_base); - - /* Only make TLB entry if both addresses are non-zero */ - for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; - entry_ndx++) { - struct bridge_ioctl_extproc *e = &dev_context->atlb_entry[entry_ndx]; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = e->endianism, - .element_size = e->elem_size, - .mixed_size = e->mixed_mode, - }; - - if (!e->ul_gpp_pa || !e->ul_dsp_va) + mmu = dev_context->dsp_mmu; + if (mmu) + dsp_mmu_exit(mmu); + mmu = dsp_mmu_init(); + if (IS_ERR(mmu)) { + dev_err(bridge, "dsp_mmu_init failed!\n"); + dev_context->dsp_mmu = NULL; + status = (int)mmu; + } + } + if (!status) { + dev_context->dsp_mmu = mmu; + sm_sg = &dev_context->sh_s; + sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, + sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(sg0_da)) { + status = (int)sg0_da; + sg0_da = 0; + } + } + if (!status) { + sg1_da = iommu_kmap(mmu, sm_sg->seg1_da, sm_sg->seg1_pa, + sm_sg->seg1_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(sg1_da)) { + status = (int)sg1_da; + sg1_da = 0; + } + } + if (!status) { + u32 da; + for (tlb_i = 0; tlb_i < BRDIOCTL_NUMOFMMUTLB; tlb_i++) { + if (!tlb[tlb_i].ul_gpp_pa) continue; - dev_dbg(bridge, - "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x", - itmp_entry_ndx, - e->ul_gpp_pa, - e->ul_dsp_va, - e->ul_size); - - hw_mmu_tlb_add(dev_context->dw_dsp_mmu_base, - e->ul_gpp_pa, - e->ul_dsp_va, - e->ul_size, - itmp_entry_ndx, - &map_attrs, 1, 1); - - itmp_entry_ndx++; + dev_dbg(bridge, "IOMMU %d GppPa: 0x%x DspVa 0x%x Size" + " 0x%x\n", tlb_i, tlb[tlb_i].ul_gpp_pa, + tlb[tlb_i].ul_dsp_va, tlb[tlb_i].ul_size); + + da = iommu_kmap(mmu, tlb[tlb_i].ul_dsp_va, + tlb[tlb_i].ul_gpp_pa, PAGE_SIZE, + IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(da)) { + status = (int)da; + break; + } + } + } + if (!status) { + u32 da; + l4_i = 0; + while (l4_peripheral_table[l4_i].phys_addr) { + da = iommu_kmap(mmu, l4_peripheral_table[l4_i]. + dsp_virt_addr, l4_peripheral_table[l4_i]. + phys_addr, PAGE_SIZE, + IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(da)) { + status = (int)da; + break; + } + l4_i++; } } /* Lock the above TLB entries and get the BIOS and load monitor timer * information */ if (!status) { - hw_mmu_num_locked_set(resources->dw_dmmu_base, itmp_entry_ndx); - hw_mmu_victim_num_set(resources->dw_dmmu_base, itmp_entry_ndx); - hw_mmu_ttb_set(resources->dw_dmmu_base, - dev_context->pt_attrs->l1_base_pa); - hw_mmu_twl_enable(resources->dw_dmmu_base); - /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */ - - temp = __raw_readl((resources->dw_dmmu_base) + 0x10); - temp = (temp & 0xFFFFFFEF) | 0x11; - __raw_writel(temp, (resources->dw_dmmu_base) + 0x10); - - /* Let the DSP MMU run */ - hw_mmu_enable(resources->dw_dmmu_base); - /* Enable the BIOS clock */ (void)dev_get_symbol(dev_context->hdev_obj, BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer); (void)dev_get_symbol(dev_context->hdev_obj, BRIDGEINIT_LOADMON_GPTIMER, &ul_load_monitor_timer); - } - if (!status) { if (ul_load_monitor_timer != 0xFFFF) { clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) | ul_load_monitor_timer; @@ -519,9 +430,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dev_dbg(bridge, "Not able to get the symbol for Load " "Monitor Timer\n"); } - } - if (!status) { if (ul_bios_gp_timer != 0xFFFF) { clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) | ul_bios_gp_timer; @@ -530,9 +439,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dev_dbg(bridge, "Not able to get the symbol for BIOS Timer\n"); } - } - if (!status) { /* Set the DSP clock rate */ (void)dev_get_symbol(dev_context->hdev_obj, "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr); @@ -585,9 +492,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Let DSP go */ dev_dbg(bridge, "%s Unreset\n", __func__); - /* Enable DSP MMU Interrupts */ - hw_mmu_event_enable(resources->dw_dmmu_base, - HW_MMU_ALL_INTERRUPTS); /* release the RST1, DSP starts executing now .. */ (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); @@ -617,11 +521,23 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* update board state */ dev_context->dw_brd_state = BRD_RUNNING; - /* (void)chnlsm_enable_interrupt(dev_context); */ + return 0; } else { dev_context->dw_brd_state = BRD_UNKNOWN; } } + + while (tlb_i--) { + if (!tlb[tlb_i].ul_gpp_pa) + continue; + iommu_kunmap(mmu, tlb[tlb_i].ul_gpp_va); + } + while (l4_i--) + iommu_kunmap(mmu, l4_peripheral_table[l4_i].dsp_virt_addr); + if (sg0_da) + iommu_kunmap(mmu, sg0_da); + if (sg1_da) + iommu_kunmap(mmu, sg1_da); return status; } @@ -637,8 +553,9 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) { int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; - struct pg_table_attrs *pt_attrs; u32 dsp_pwr_state; + int i; + struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry; struct omap_dsp_platform_data *pdata = omap_dspbridge_dev->dev.platform_data; @@ -674,23 +591,37 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) dsp_wdt_enable(false); - /* This is a good place to clear the MMU page tables as well */ - if (dev_context->pt_attrs) { - pt_attrs = dev_context->pt_attrs; - memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size); - memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size); - memset((u8 *) pt_attrs->pg_info, 0x00, - (pt_attrs->l2_num_pages * sizeof(struct page_info))); - } + /* Reset DSP */ + (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, + OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + /* Disable the mailbox interrupts */ if (dev_context->mbox) { omap_mbox_disable_irq(dev_context->mbox, IRQ_RX); omap_mbox_put(dev_context->mbox); dev_context->mbox = NULL; } - /* Reset IVA2 clocks*/ - (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK | OMAP3430_RST2_IVA2_MASK | - OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + if (dev_context->dsp_mmu) { + pr_err("Proc stop mmu if statement\n"); + for (i = 0; i < BRDIOCTL_NUMOFMMUTLB; i++) { + if (!tlb[i].ul_gpp_pa) + continue; + iommu_kunmap(dev_context->dsp_mmu, tlb[i].ul_gpp_va); + } + i = 0; + while (l4_peripheral_table[i].phys_addr) { + iommu_kunmap(dev_context->dsp_mmu, + l4_peripheral_table[i].dsp_virt_addr); + i++; + } + iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da); + iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg1_da); + dsp_mmu_exit(dev_context->dsp_mmu); + dev_context->dsp_mmu = NULL; + } + /* Reset IVA IOMMU*/ + (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, + OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); dsp_clock_disable_all(dev_context->dsp_per_clks); dsp_clk_disable(DSP_CLK_IVA2); @@ -750,10 +681,6 @@ static int bridge_dev_create(struct bridge_dev_context struct bridge_dev_context *dev_context = NULL; s32 entry_ndx; struct cfg_hostres *resources = config_param; - struct pg_table_attrs *pt_attrs; - u32 pg_tbl_pa; - u32 pg_tbl_va; - u32 align_size; struct drv_data *drv_datap = dev_get_drvdata(bridge); /* Allocate and initialize a data structure to contain the bridge driver @@ -784,97 +711,8 @@ static int bridge_dev_create(struct bridge_dev_context if (!dev_context->dw_dsp_base_addr) status = -EPERM; - pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); - if (pt_attrs != NULL) { - /* Assuming that we use only DSP's memory map - * until 0x4000:0000 , we would need only 1024 - * L1 enties i.e L1 size = 4K */ - pt_attrs->l1_size = 0x1000; - align_size = pt_attrs->l1_size; - /* Align sizes are expected to be power of 2 */ - /* we like to get aligned on L1 table size */ - pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l1_size, - align_size, &pg_tbl_pa); - - /* Check if the PA is aligned for us */ - if ((pg_tbl_pa) & (align_size - 1)) { - /* PA not aligned to page table size , - * try with more allocation and align */ - mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa, - pt_attrs->l1_size); - /* we like to get aligned on L1 table size */ - pg_tbl_va = - (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2, - align_size, &pg_tbl_pa); - /* We should be able to get aligned table now */ - pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l1_tbl_alloc_va = pg_tbl_va; - pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2; - /* Align the PA to the next 'align' boundary */ - pt_attrs->l1_base_pa = - ((pg_tbl_pa) + - (align_size - 1)) & (~(align_size - 1)); - pt_attrs->l1_base_va = - pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa); - } else { - /* We got aligned PA, cool */ - pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l1_tbl_alloc_va = pg_tbl_va; - pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size; - pt_attrs->l1_base_pa = pg_tbl_pa; - pt_attrs->l1_base_va = pg_tbl_va; - } - if (pt_attrs->l1_base_va) - memset((u8 *) pt_attrs->l1_base_va, 0x00, - pt_attrs->l1_size); - - /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM + - * L4 pages */ - pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6); - pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE * - pt_attrs->l2_num_pages; - align_size = 4; /* Make it u32 aligned */ - /* we like to get aligned on L1 table size */ - pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l2_size, - align_size, &pg_tbl_pa); - pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l2_tbl_alloc_va = pg_tbl_va; - pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size; - pt_attrs->l2_base_pa = pg_tbl_pa; - pt_attrs->l2_base_va = pg_tbl_va; - - if (pt_attrs->l2_base_va) - memset((u8 *) pt_attrs->l2_base_va, 0x00, - pt_attrs->l2_size); - - pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages * - sizeof(struct page_info), GFP_KERNEL); - dev_dbg(bridge, - "L1 pa %x, va %x, size %x\n L2 pa %x, va " - "%x, size %x\n", pt_attrs->l1_base_pa, - pt_attrs->l1_base_va, pt_attrs->l1_size, - pt_attrs->l2_base_pa, pt_attrs->l2_base_va, - pt_attrs->l2_size); - dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n", - pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info); - } - if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) && - (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL)) - dev_context->pt_attrs = pt_attrs; - else - status = -ENOMEM; - if (!status) { - spin_lock_init(&pt_attrs->pg_lock); dev_context->tc_word_swap_on = drv_datap->tc_wordswapon; - - /* Set the Clock Divisor for the DSP module */ - udelay(5); - /* MMU address is obtained from the host - * resources struct */ - dev_context->dw_dsp_mmu_base = resources->dw_dmmu_base; - } - if (!status) { dev_context->hdev_obj = hdev_obj; /* Store current board state. */ dev_context->dw_brd_state = BRD_UNKNOWN; @@ -884,23 +722,6 @@ static int bridge_dev_create(struct bridge_dev_context /* Return ptr to our device state to the DSP API for storage */ *dev_cntxt = dev_context; } else { - if (pt_attrs != NULL) { - kfree(pt_attrs->pg_info); - - if (pt_attrs->l2_tbl_alloc_va) { - mem_free_phys_mem((void *) - pt_attrs->l2_tbl_alloc_va, - pt_attrs->l2_tbl_alloc_pa, - pt_attrs->l2_tbl_alloc_sz); - } - if (pt_attrs->l1_tbl_alloc_va) { - mem_free_phys_mem((void *) - pt_attrs->l1_tbl_alloc_va, - pt_attrs->l1_tbl_alloc_pa, - pt_attrs->l1_tbl_alloc_sz); - } - } - kfree(pt_attrs); kfree(dev_context); } func_end: @@ -968,7 +789,6 @@ static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, */ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) { - struct pg_table_attrs *pt_attrs; int status = 0; struct bridge_dev_context *dev_context = (struct bridge_dev_context *) dev_ctxt; @@ -982,23 +802,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) /* first put the device to stop state */ bridge_brd_stop(dev_context); - if (dev_context->pt_attrs) { - pt_attrs = dev_context->pt_attrs; - kfree(pt_attrs->pg_info); - - if (pt_attrs->l2_tbl_alloc_va) { - mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va, - pt_attrs->l2_tbl_alloc_pa, - pt_attrs->l2_tbl_alloc_sz); - } - if (pt_attrs->l1_tbl_alloc_va) { - mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va, - pt_attrs->l1_tbl_alloc_pa, - pt_attrs->l1_tbl_alloc_sz); - } - kfree(pt_attrs); - - } if (dev_context->resources) { host_res = dev_context->resources; @@ -1029,8 +832,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) iounmap((void *)host_res->dw_mem_base[3]); if (host_res->dw_mem_base[4]) iounmap((void *)host_res->dw_mem_base[4]); - if (host_res->dw_dmmu_base) - iounmap(host_res->dw_dmmu_base); if (host_res->dw_per_base) iounmap(host_res->dw_per_base); if (host_res->dw_per_pm_base) @@ -1044,7 +845,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) host_res->dw_mem_base[2] = (u32) NULL; host_res->dw_mem_base[3] = (u32) NULL; host_res->dw_mem_base[4] = (u32) NULL; - host_res->dw_dmmu_base = NULL; host_res->dw_sys_ctrl_base = NULL; kfree(host_res); @@ -1128,673 +928,6 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, } /* - * ======== bridge_brd_mem_map ======== - * This function maps MPU buffer to the DSP address space. It performs - * linear to physical address translation if required. It translates each - * page since linear addresses can be physically non-contiguous - * All address & size arguments are assumed to be page aligned (in proc.c) - * - * TODO: Disable MMU while updating the page tables (but that'll stall DSP) - */ -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages) -{ - u32 attrs; - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct hw_mmu_map_attrs_t hw_attrs; - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; - u32 write = 0; - u32 num_usr_pgs = 0; - struct page *mapped_page, *pg; - s32 pg_num; - u32 va = virt_addr; - struct task_struct *curr_task = current; - u32 pg_i = 0; - u32 mpu_addr, pa; - - dev_dbg(bridge, - "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n", - __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes, - ul_map_attr); - if (ul_num_bytes == 0) - return -EINVAL; - - if (ul_map_attr & DSP_MAP_DIR_MASK) { - attrs = ul_map_attr; - } else { - /* Assign default attributes */ - attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16); - } - /* Take mapping properties */ - if (attrs & DSP_MAPBIGENDIAN) - hw_attrs.endianism = HW_BIG_ENDIAN; - else - hw_attrs.endianism = HW_LITTLE_ENDIAN; - - hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t) - ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2); - /* Ignore element_size if mixed_size is enabled */ - if (hw_attrs.mixed_size == 0) { - if (attrs & DSP_MAPELEMSIZE8) { - /* Size is 8 bit */ - hw_attrs.element_size = HW_ELEM_SIZE8BIT; - } else if (attrs & DSP_MAPELEMSIZE16) { - /* Size is 16 bit */ - hw_attrs.element_size = HW_ELEM_SIZE16BIT; - } else if (attrs & DSP_MAPELEMSIZE32) { - /* Size is 32 bit */ - hw_attrs.element_size = HW_ELEM_SIZE32BIT; - } else if (attrs & DSP_MAPELEMSIZE64) { - /* Size is 64 bit */ - hw_attrs.element_size = HW_ELEM_SIZE64BIT; - } else { - /* - * Mixedsize isn't enabled, so size can't be - * zero here - */ - return -EINVAL; - } - } - if (attrs & DSP_MAPDONOTLOCK) - hw_attrs.donotlockmpupage = 1; - else - hw_attrs.donotlockmpupage = 0; - - if (attrs & DSP_MAPVMALLOCADDR) { - return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr, - ul_num_bytes, &hw_attrs); - } - /* - * Do OS-specific user-va to pa translation. - * Combine physically contiguous regions to reduce TLBs. - * Pass the translated pa to pte_update. - */ - if ((attrs & DSP_MAPPHYSICALADDR)) { - status = pte_update(dev_context, ul_mpu_addr, virt_addr, - ul_num_bytes, &hw_attrs); - goto func_cont; - } - - /* - * Important Note: ul_mpu_addr is mapped from user application process - * to current process - it must lie completely within the current - * virtual memory address space in order to be of use to us here! - */ - down_read(&mm->mmap_sem); - vma = find_vma(mm, ul_mpu_addr); - if (vma) - dev_dbg(bridge, - "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, " - "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr, - ul_num_bytes, vma->vm_start, vma->vm_end, - vma->vm_flags); - - /* - * It is observed that under some circumstances, the user buffer is - * spread across several VMAs. So loop through and check if the entire - * user buffer is covered - */ - while ((vma) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) { - /* jump to the next VMA region */ - vma = find_vma(mm, vma->vm_end + 1); - dev_dbg(bridge, - "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, " - "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr, - ul_num_bytes, vma->vm_start, vma->vm_end, - vma->vm_flags); - } - if (!vma) { - pr_err("%s: Failed to get VMA region for 0x%x (%d)\n", - __func__, ul_mpu_addr, ul_num_bytes); - status = -EINVAL; - up_read(&mm->mmap_sem); - goto func_cont; - } - - if (vma->vm_flags & VM_IO) { - num_usr_pgs = ul_num_bytes / PG_SIZE4K; - mpu_addr = ul_mpu_addr; - - /* Get the physical addresses for user buffer */ - for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) { - pa = user_va2_pa(mm, mpu_addr); - if (!pa) { - status = -EPERM; - pr_err("DSPBRIDGE: VM_IO mapping physical" - "address is invalid\n"); - break; - } - if (pfn_valid(__phys_to_pfn(pa))) { - pg = PHYS_TO_PAGE(pa); - get_page(pg); - if (page_count(pg) < 1) { - pr_err("Bad page in VM_IO buffer\n"); - bad_page_dump(pa, pg); - } - } - status = pte_set(dev_context->pt_attrs, pa, - va, HW_PAGE_SIZE4KB, &hw_attrs); - if (status) - break; - - va += HW_PAGE_SIZE4KB; - mpu_addr += HW_PAGE_SIZE4KB; - pa += HW_PAGE_SIZE4KB; - } - } else { - num_usr_pgs = ul_num_bytes / PG_SIZE4K; - if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) - write = 1; - - for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) { - pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1, - write, 1, &mapped_page, NULL); - if (pg_num > 0) { - if (page_count(mapped_page) < 1) { - pr_err("Bad page count after doing" - "get_user_pages on" - "user buffer\n"); - bad_page_dump(page_to_phys(mapped_page), - mapped_page); - } - status = pte_set(dev_context->pt_attrs, - page_to_phys(mapped_page), va, - HW_PAGE_SIZE4KB, &hw_attrs); - if (status) - break; - - if (mapped_pages) - mapped_pages[pg_i] = mapped_page; - - va += HW_PAGE_SIZE4KB; - ul_mpu_addr += HW_PAGE_SIZE4KB; - } else { - pr_err("DSPBRIDGE: get_user_pages FAILED," - "MPU addr = 0x%x," - "vma->vm_flags = 0x%lx," - "get_user_pages Err" - "Value = %d, Buffer" - "size=0x%x\n", ul_mpu_addr, - vma->vm_flags, pg_num, ul_num_bytes); - status = -EPERM; - break; - } - } - } - up_read(&mm->mmap_sem); -func_cont: - if (status) { - /* - * Roll out the mapped pages incase it failed in middle of - * mapping - */ - if (pg_i) { - bridge_brd_mem_un_map(dev_context, virt_addr, - (pg_i * PG_SIZE4K)); - } - status = -EPERM; - } - /* - * In any case, flush the TLB - * This is called from here instead from pte_update to avoid unnecessary - * repetition while mapping non-contiguous physical regions of a virtual - * region - */ - flush_all(dev_context); - dev_dbg(bridge, "%s status %x\n", __func__, status); - return status; -} - -/* - * ======== bridge_brd_mem_un_map ======== - * Invalidate the PTEs for the DSP VA block to be unmapped. - * - * PTEs of a mapped memory block are contiguous in any page table - * So, instead of looking up the PTE address for every 4K block, - * we clear consecutive PTEs until we unmap all the bytes - */ -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 virt_addr, u32 ul_num_bytes) -{ - u32 l1_base_va; - u32 l2_base_va; - u32 l2_base_pa; - u32 l2_page_num; - u32 pte_val; - u32 pte_size; - u32 pte_count; - u32 pte_addr_l1; - u32 pte_addr_l2 = 0; - u32 rem_bytes; - u32 rem_bytes_l2; - u32 va_curr; - struct page *pg = NULL; - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct pg_table_attrs *pt = dev_context->pt_attrs; - u32 temp; - u32 paddr; - u32 numof4k_pages = 0; - - va_curr = virt_addr; - rem_bytes = ul_num_bytes; - rem_bytes_l2 = 0; - l1_base_va = pt->l1_base_va; - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr); - dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, " - "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr, - ul_num_bytes, l1_base_va, pte_addr_l1); - - while (rem_bytes && !status) { - u32 va_curr_orig = va_curr; - /* Find whether the L1 PTE points to a valid L2 PT */ - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr); - pte_val = *(u32 *) pte_addr_l1; - pte_size = hw_mmu_pte_size_l1(pte_val); - - if (pte_size != HW_MMU_COARSE_PAGE_SIZE) - goto skip_coarse_page; - - /* - * Get the L2 PA from the L1 PTE, and find - * corresponding L2 VA - */ - l2_base_pa = hw_mmu_pte_coarse_l1(pte_val); - l2_base_va = l2_base_pa - pt->l2_base_pa + pt->l2_base_va; - l2_page_num = - (l2_base_pa - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE; - /* - * Find the L2 PTE address from which we will start - * clearing, the number of PTEs to be cleared on this - * page, and the size of VA space that needs to be - * cleared on this L2 page - */ - pte_addr_l2 = hw_mmu_pte_addr_l2(l2_base_va, va_curr); - pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1); - pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) / sizeof(u32); - if (rem_bytes < (pte_count * PG_SIZE4K)) - pte_count = rem_bytes / PG_SIZE4K; - rem_bytes_l2 = pte_count * PG_SIZE4K; - - /* - * Unmap the VA space on this L2 PT. A quicker way - * would be to clear pte_count entries starting from - * pte_addr_l2. However, below code checks that we don't - * clear invalid entries or less than 64KB for a 64KB - * entry. Similar checking is done for L1 PTEs too - * below - */ - while (rem_bytes_l2 && !status) { - pte_val = *(u32 *) pte_addr_l2; - pte_size = hw_mmu_pte_size_l2(pte_val); - /* va_curr aligned to pte_size? */ - if (pte_size == 0 || rem_bytes_l2 < pte_size || - va_curr & (pte_size - 1)) { - status = -EPERM; - break; - } - - /* Collect Physical addresses from VA */ - paddr = (pte_val & ~(pte_size - 1)); - if (pte_size == HW_PAGE_SIZE64KB) - numof4k_pages = 16; - else - numof4k_pages = 1; - temp = 0; - while (temp++ < numof4k_pages) { - if (!pfn_valid(__phys_to_pfn(paddr))) { - paddr += HW_PAGE_SIZE4KB; - continue; - } - pg = PHYS_TO_PAGE(paddr); - if (page_count(pg) < 1) { - pr_info("DSPBRIDGE: UNMAP function: " - "COUNT 0 FOR PA 0x%x, size = " - "0x%x\n", paddr, ul_num_bytes); - bad_page_dump(paddr, pg); - } else { - set_page_dirty(pg); - page_cache_release(pg); - } - paddr += HW_PAGE_SIZE4KB; - } - if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) { - status = -EPERM; - goto EXIT_LOOP; - } - - status = 0; - rem_bytes_l2 -= pte_size; - va_curr += pte_size; - pte_addr_l2 += (pte_size >> 12) * sizeof(u32); - } - spin_lock(&pt->pg_lock); - if (rem_bytes_l2 == 0) { - pt->pg_info[l2_page_num].num_entries -= pte_count; - if (pt->pg_info[l2_page_num].num_entries == 0) { - /* - * Clear the L1 PTE pointing to the L2 PT - */ - if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig, - HW_MMU_COARSE_PAGE_SIZE)) - status = 0; - else { - status = -EPERM; - spin_unlock(&pt->pg_lock); - goto EXIT_LOOP; - } - } - rem_bytes -= pte_count * PG_SIZE4K; - } else - status = -EPERM; - - spin_unlock(&pt->pg_lock); - continue; -skip_coarse_page: - /* va_curr aligned to pte_size? */ - /* pte_size = 1 MB or 16 MB */ - if (pte_size == 0 || rem_bytes < pte_size || - va_curr & (pte_size - 1)) { - status = -EPERM; - break; - } - - if (pte_size == HW_PAGE_SIZE1MB) - numof4k_pages = 256; - else - numof4k_pages = 4096; - temp = 0; - /* Collect Physical addresses from VA */ - paddr = (pte_val & ~(pte_size - 1)); - while (temp++ < numof4k_pages) { - if (pfn_valid(__phys_to_pfn(paddr))) { - pg = PHYS_TO_PAGE(paddr); - if (page_count(pg) < 1) { - pr_info("DSPBRIDGE: UNMAP function: " - "COUNT 0 FOR PA 0x%x, size = " - "0x%x\n", paddr, ul_num_bytes); - bad_page_dump(paddr, pg); - } else { - set_page_dirty(pg); - page_cache_release(pg); - } - } - paddr += HW_PAGE_SIZE4KB; - } - if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) { - status = 0; - rem_bytes -= pte_size; - va_curr += pte_size; - } else { - status = -EPERM; - goto EXIT_LOOP; - } - } - /* - * It is better to flush the TLB here, so that any stale old entries - * get flushed - */ -EXIT_LOOP: - flush_all(dev_context); - dev_dbg(bridge, - "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x," - " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1, - pte_addr_l2, rem_bytes, rem_bytes_l2, status); - return status; -} - -/* - * ======== user_va2_pa ======== - * Purpose: - * This function walks through the page tables to convert a userland - * virtual address to physical address - */ -static u32 user_va2_pa(struct mm_struct *mm, u32 address) -{ - pgd_t *pgd; - pmd_t *pmd; - pte_t *ptep, pte; - - pgd = pgd_offset(mm, address); - if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { - pmd = pmd_offset(pgd, address); - if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { - ptep = pte_offset_map(pmd, address); - if (ptep) { - pte = *ptep; - if (pte_present(pte)) - return pte & PAGE_MASK; - } - } - } - - return 0; -} - -/* - * ======== pte_update ======== - * This function calculates the optimum page-aligned addresses and sizes - * Caller must pass page-aligned values - */ -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, - u32 va, u32 size, - struct hw_mmu_map_attrs_t *map_attrs) -{ - u32 i; - u32 all_bits; - u32 pa_curr = pa; - u32 va_curr = va; - u32 num_bytes = size; - struct bridge_dev_context *dev_context = dev_ctxt; - int status = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; - - while (num_bytes && !status) { - /* To find the max. page size with which both PA & VA are - * aligned */ - all_bits = pa_curr | va_curr; - - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & - (page_size[i] - - 1)) == 0)) { - status = - pte_set(dev_context->pt_attrs, pa_curr, - va_curr, page_size[i], map_attrs); - pa_curr += page_size[i]; - va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* Don't try smaller sizes. Hopefully we have - * reached an address aligned to a bigger page - * size */ - break; - } - } - } - - return status; -} - -/* - * ======== pte_set ======== - * This function calculates PTE address (MPU virtual) to be updated - * It also manages the L2 page tables - */ -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs) -{ - u32 i; - u32 pte_val; - u32 pte_addr_l1; - u32 pte_size; - /* Base address of the PT that will be updated */ - u32 pg_tbl_va; - u32 l1_base_va; - /* Compiler warns that the next three variables might be used - * uninitialized in this function. Doesn't seem so. Working around, - * anyways. */ - u32 l2_base_va = 0; - u32 l2_base_pa = 0; - u32 l2_page_num = 0; - int status = 0; - - l1_base_va = pt->l1_base_va; - pg_tbl_va = l1_base_va; - if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) { - /* Find whether the L1 PTE points to a valid L2 PT */ - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va); - if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) { - pte_val = *(u32 *) pte_addr_l1; - pte_size = hw_mmu_pte_size_l1(pte_val); - } else { - return -EPERM; - } - spin_lock(&pt->pg_lock); - if (pte_size == HW_MMU_COARSE_PAGE_SIZE) { - /* Get the L2 PA from the L1 PTE, and find - * corresponding L2 VA */ - l2_base_pa = hw_mmu_pte_coarse_l1(pte_val); - l2_base_va = - l2_base_pa - pt->l2_base_pa + pt->l2_base_va; - l2_page_num = - (l2_base_pa - - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE; - } else if (pte_size == 0) { - /* L1 PTE is invalid. Allocate a L2 PT and - * point the L1 PTE to it */ - /* Find a free L2 PT. */ - for (i = 0; (i < pt->l2_num_pages) && - (pt->pg_info[i].num_entries != 0); i++) - ;; - if (i < pt->l2_num_pages) { - l2_page_num = i; - l2_base_pa = pt->l2_base_pa + (l2_page_num * - HW_MMU_COARSE_PAGE_SIZE); - l2_base_va = pt->l2_base_va + (l2_page_num * - HW_MMU_COARSE_PAGE_SIZE); - /* Endianness attributes are ignored for - * HW_MMU_COARSE_PAGE_SIZE */ - status = - hw_mmu_pte_set(l1_base_va, l2_base_pa, va, - HW_MMU_COARSE_PAGE_SIZE, - attrs); - } else { - status = -ENOMEM; - } - } else { - /* Found valid L1 PTE of another size. - * Should not overwrite it. */ - status = -EPERM; - } - if (!status) { - pg_tbl_va = l2_base_va; - if (size == HW_PAGE_SIZE64KB) - pt->pg_info[l2_page_num].num_entries += 16; - else - pt->pg_info[l2_page_num].num_entries++; - dev_dbg(bridge, "PTE: L2 BaseVa %x, BasePa %x, PageNum " - "%x, num_entries %x\n", l2_base_va, - l2_base_pa, l2_page_num, - pt->pg_info[l2_page_num].num_entries); - } - spin_unlock(&pt->pg_lock); - } - if (!status) { - dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n", - pg_tbl_va, pa, va, size); - dev_dbg(bridge, "PTE: endianism %x, element_size %x, " - "mixed_size %x\n", attrs->endianism, - attrs->element_size, attrs->mixed_size); - status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs); - } - - return status; -} - -/* Memory map kernel VA -- memory allocated with vmalloc */ -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs) -{ - int status = 0; - struct page *page[1]; - u32 i; - u32 pa_curr; - u32 pa_next; - u32 va_curr; - u32 size_curr; - u32 num_pages; - u32 pa; - u32 num_of4k_pages; - u32 temp = 0; - - /* - * Do Kernel va to pa translation. - * Combine physically contiguous regions to reduce TLBs. - * Pass the translated pa to pte_update. - */ - num_pages = ul_num_bytes / PAGE_SIZE; /* PAGE_SIZE = OS page size */ - i = 0; - va_curr = ul_mpu_addr; - page[0] = vmalloc_to_page((void *)va_curr); - pa_next = page_to_phys(page[0]); - while (!status && (i < num_pages)) { - /* - * Reuse pa_next from the previous iteraion to avoid - * an extra va2pa call - */ - pa_curr = pa_next; - size_curr = PAGE_SIZE; - /* - * If the next page is physically contiguous, - * map it with the current one by increasing - * the size of the region to be mapped - */ - while (++i < num_pages) { - page[0] = - vmalloc_to_page((void *)(va_curr + size_curr)); - pa_next = page_to_phys(page[0]); - - if (pa_next == (pa_curr + size_curr)) - size_curr += PAGE_SIZE; - else - break; - - } - if (pa_next == 0) { - status = -ENOMEM; - break; - } - pa = pa_curr; - num_of4k_pages = size_curr / HW_PAGE_SIZE4KB; - while (temp++ < num_of4k_pages) { - get_page(PHYS_TO_PAGE(pa)); - pa += HW_PAGE_SIZE4KB; - } - status = pte_update(dev_context, pa_curr, virt_addr + - (va_curr - ul_mpu_addr), size_curr, - hw_attrs); - va_curr += size_curr; - } - /* - * In any case, flush the TLB - * This is called from here instead from pte_update to avoid unnecessary - * repetition while mapping non-contiguous physical regions of a virtual - * region - */ - flush_all(dev_context); - dev_dbg(bridge, "%s status %x\n", __func__, status); - return status; -} - -/* * ======== wait_for_start ======== * Wait for the singal from DSP that it has started, or time out. */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index fb9026e..b57a9fd 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -31,10 +31,6 @@ #include #include -/* ------------------------------------ Hardware Abstraction Layer */ -#include -#include - #include /* ----------------------------------- Bridge Driver */ diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index ba29610..66dbf02 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -134,17 +134,16 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, if (!status) { ul_tlb_base_virt = - dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE; + dev_context->sh_s.seg0_da * DSPWORDSIZE; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); - dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].ul_gpp_va; + dw_ext_prog_virt_mem = dev_context->sh_s.seg0_va; if (!trace_read) { ul_shm_offset_virt = ul_shm_base_virt - ul_tlb_base_virt; ul_shm_offset_virt += PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base + - 1, HW_PAGE_SIZE64KB); + 1, PAGE_SIZE * 16); dw_ext_prog_virt_mem -= ul_shm_offset_virt; dw_ext_prog_virt_mem += (ul_ext_base - ul_dyn_ext_base); @@ -318,8 +317,9 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, ret = -EPERM; if (!ret) { - ul_tlb_base_virt = - dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE; + ul_tlb_base_virt = dev_context->sh_s.seg0_da * + DSPWORDSIZE; + DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); if (symbols_reloaded) { @@ -337,7 +337,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, ul_shm_base_virt - ul_tlb_base_virt; if (trace_load) { dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].ul_gpp_va; + dev_context->sh_s.seg0_va; } else { dw_ext_prog_virt_mem = host_res->dw_mem_base[1]; dw_ext_prog_virt_mem += @@ -393,7 +393,6 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_dspbridge_dev->dev.platform_data; struct cfg_hostres *resources = dev_context->resources; int status = 0; - u32 temp; if (!dev_context->mbox) return 0; @@ -437,7 +436,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_mbox_restore_ctx(dev_context->mbox); /* Access MMU SYS CONFIG register to generate a short wakeup */ - temp = readl(resources->dw_dmmu_base + 0x10); + iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG); dev_context->dw_brd_state = BRD_RUNNING; } else if (dev_context->dw_brd_state == BRD_RETENTION) { diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 3430418..e24ea0c 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -31,57 +31,6 @@ #include #include -static u32 fault_addr; - -static void mmu_fault_dpc(unsigned long data) -{ - struct deh_mgr *deh = (void *)data; - - if (!deh) - return; - - bridge_deh_notify(deh, DSP_MMUFAULT, 0); -} - -static irqreturn_t mmu_fault_isr(int irq, void *data) -{ - struct deh_mgr *deh = data; - struct cfg_hostres *resources; - u32 event; - - if (!deh) - return IRQ_HANDLED; - - resources = deh->hbridge_context->resources; - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources\n", - __func__); - return IRQ_HANDLED; - } - - hw_mmu_event_status(resources->dw_dmmu_base, &event); - if (event == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); - dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, - event, fault_addr); - /* - * Schedule a DPC directly. In the future, it may be - * necessary to check if DSP MMU fault is intended for - * Bridge. - */ - tasklet_schedule(&deh->dpc_tasklet); - - /* Disable the MMU events, else once we clear it will - * start to raise INTs again */ - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_TRANSLATION_FAULT); - } else { - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_ALL_INTERRUPTS); - } - return IRQ_HANDLED; -} - int bridge_deh_create(struct deh_mgr **ret_deh, struct dev_object *hdev_obj) { @@ -109,18 +58,9 @@ int bridge_deh_create(struct deh_mgr **ret_deh, } ntfy_init(deh->ntfy_obj); - /* Create a MMUfault DPC */ - tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh); - /* Fill in context structure */ deh->hbridge_context = hbridge_context; - /* Install ISR function for DSP MMU fault */ - status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0, - "DspBridge\tiommu fault", deh); - if (status < 0) - goto err; - *ret_deh = deh; return 0; @@ -140,11 +80,6 @@ int bridge_deh_destroy(struct deh_mgr *deh) ntfy_delete(deh->ntfy_obj); kfree(deh->ntfy_obj); } - /* Disable DSP MMU fault */ - free_irq(INT_DSP_MMU_IRQ, deh); - - /* Free DPC object */ - tasklet_kill(&deh->dpc_tasklet); /* Deallocate the DEH manager object */ kfree(deh); @@ -166,48 +101,6 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask, return ntfy_unregister(deh->ntfy_obj, hnotification); } -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) -{ - struct cfg_hostres *resources; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = HW_LITTLE_ENDIAN, - .element_size = HW_ELEM_SIZE16BIT, - .mixed_size = HW_MMU_CPUES, - }; - void *dummy_va_addr; - - resources = dev_context->resources; - dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC); - - /* - * Before acking the MMU fault, let's make sure MMU can only - * access entry #0. Then add a new entry so that the DSP OS - * can continue in order to dump the stack. - */ - hw_mmu_twl_disable(resources->dw_dmmu_base); - hw_mmu_tlb_flush_all(resources->dw_dmmu_base); - - hw_mmu_tlb_add(resources->dw_dmmu_base, - virt_to_phys(dummy_va_addr), fault_addr, - HW_PAGE_SIZE4KB, 1, - &map_attrs, HW_SET, HW_SET); - - dsp_clk_enable(DSP_CLK_GPT8); - - dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); - - /* Clear MMU interrupt */ - hw_mmu_event_ack(resources->dw_dmmu_base, - HW_MMU_TRANSLATION_FAULT); - dump_dsp_stack(dev_context); - dsp_clk_disable(DSP_CLK_GPT8); - - hw_mmu_disable(resources->dw_dmmu_base); - free_page((unsigned long)dummy_va_addr); -} -#endif - static inline const char *event_to_string(int event) { switch (event) { @@ -240,13 +133,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) #endif break; case DSP_MMUFAULT: - dev_err(bridge, "%s: %s, addr=0x%x", __func__, - str, fault_addr); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - print_dsp_trace_buffer(dev_context); - dump_dl_modules(dev_context); - mmu_fault_print_stack(dev_context); -#endif + dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, info); break; default: dev_err(bridge, "%s: %s", __func__, str); diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h deleted file mode 100644 index e48d7f6..0000000 --- a/drivers/staging/tidspbridge/hw/EasiGlobal.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * EasiGlobal.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _EASIGLOBAL_H -#define _EASIGLOBAL_H -#include - -/* - * DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE - * - * DESCRIPTION: Defines used to describe register types for EASI-checker tests. - */ - -#define READ_ONLY 1 -#define WRITE_ONLY 2 -#define READ_WRITE 3 - -/* - * MACRO: _DEBUG_LEVEL1_EASI - * - * DESCRIPTION: A MACRO which can be used to indicate that a particular beach - * register access function was called. - * - * NOTE: We currently dont use this functionality. - */ -#define _DEBUG_LEVEL1_EASI(easi_num) ((void)0) - -#endif /* _EASIGLOBAL_H */ diff --git a/drivers/staging/tidspbridge/hw/MMUAccInt.h b/drivers/staging/tidspbridge/hw/MMUAccInt.h deleted file mode 100644 index 1cefca3..0000000 --- a/drivers/staging/tidspbridge/hw/MMUAccInt.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * MMUAccInt.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _MMU_ACC_INT_H -#define _MMU_ACC_INT_H - -/* Mappings of level 1 EASI function numbers to function names */ - -#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3) -#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32 (MMU_BASE_EASIL1 + 17) -#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32 (MMU_BASE_EASIL1 + 39) -#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 51) -#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102) -#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103) -#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156) -#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174) -#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 180) -#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 190) -#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32 (MMU_BASE_EASIL1 + 194) -#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 198) -#define EASIL1_MMUMMU_LOCK_READ_REGISTER32 (MMU_BASE_EASIL1 + 203) -#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 204) -#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32 (MMU_BASE_EASIL1 + 205) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32 (MMU_BASE_EASIL1 + 212) -#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32 (MMU_BASE_EASIL1 + 213) -#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 214) -#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 226) -#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268) -#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 322) - -/* Register offset address definitions */ -#define MMU_MMU_SYSCONFIG_OFFSET 0x10 -#define MMU_MMU_IRQSTATUS_OFFSET 0x18 -#define MMU_MMU_IRQENABLE_OFFSET 0x1c -#define MMU_MMU_WALKING_ST_OFFSET 0x40 -#define MMU_MMU_CNTL_OFFSET 0x44 -#define MMU_MMU_FAULT_AD_OFFSET 0x48 -#define MMU_MMU_TTB_OFFSET 0x4c -#define MMU_MMU_LOCK_OFFSET 0x50 -#define MMU_MMU_LD_TLB_OFFSET 0x54 -#define MMU_MMU_CAM_OFFSET 0x58 -#define MMU_MMU_RAM_OFFSET 0x5c -#define MMU_MMU_GFLUSH_OFFSET 0x60 -#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64 -/* Bitfield mask and offset declarations */ -#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK 0x18 -#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET 3 -#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK 0x1 -#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET 0 -#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1 -#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET 0 -#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4 -#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2 -#define MMU_MMU_CNTL_MMU_ENABLE_MASK 0x2 -#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET 1 -#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00 -#define MMU_MMU_LOCK_BASE_VALUE_OFFSET 10 -#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK 0x3f0 -#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET 4 - -#endif /* _MMU_ACC_INT_H */ diff --git a/drivers/staging/tidspbridge/hw/MMURegAcM.h b/drivers/staging/tidspbridge/hw/MMURegAcM.h deleted file mode 100644 index ab1a16d..0000000 --- a/drivers/staging/tidspbridge/hw/MMURegAcM.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * MMURegAcM.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _MMU_REG_ACM_H -#define _MMU_REG_ACM_H - -#include -#include - -#include "MMUAccInt.h" - -#if defined(USE_LEVEL_1_MACROS) - -#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET)) - -#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\ - data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\ - new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\ - new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\ - data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\ - new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\ - new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\ - __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET)) - -#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET)) - -#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\ - & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\ - MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET)) - -#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\ - MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\ - MMU_MMU_CNTL_TWL_ENABLE_OFFSET)) - -#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CNTL_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\ - data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\ - new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\ - new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CNTL_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\ - data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\ - new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\ - new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET)) - -#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_TTB_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_LOCK_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET)) - -#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ - MMU_MMU_LOCK_BASE_VALUE_MASK) >>\ - MMU_MMU_LOCK_BASE_VALUE_OFFSET)) - -#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\ - data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\ - new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\ - new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ - MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\ - MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET)) - -#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\ - data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\ - new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\ - new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\ - (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\ - (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\ - MMU_MMU_LOCK_CURRENT_VICTIM_MASK))) - -#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET)) - -#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LD_TLB_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CAM_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_RAM_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#endif /* USE_LEVEL_1_MACROS */ - -#endif /* _MMU_REG_ACM_H */ diff --git a/drivers/staging/tidspbridge/hw/hw_defs.h b/drivers/staging/tidspbridge/hw/hw_defs.h deleted file mode 100644 index d5266d4..0000000 --- a/drivers/staging/tidspbridge/hw/hw_defs.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * hw_defs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global HW definitions - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _HW_DEFS_H -#define _HW_DEFS_H - -/* Page size */ -#define HW_PAGE_SIZE4KB 0x1000 -#define HW_PAGE_SIZE64KB 0x10000 -#define HW_PAGE_SIZE1MB 0x100000 -#define HW_PAGE_SIZE16MB 0x1000000 - -/* hw_status: return type for HW API */ -typedef long hw_status; - -/* Macro used to set and clear any bit */ -#define HW_CLEAR 0 -#define HW_SET 1 - -/* hw_endianism_t: Enumerated Type used to specify the endianism - * Do NOT change these values. They are used as bit fields. */ -enum hw_endianism_t { - HW_LITTLE_ENDIAN, - HW_BIG_ENDIAN -}; - -/* hw_element_size_t: Enumerated Type used to specify the element size - * Do NOT change these values. They are used as bit fields. */ -enum hw_element_size_t { - HW_ELEM_SIZE8BIT, - HW_ELEM_SIZE16BIT, - HW_ELEM_SIZE32BIT, - HW_ELEM_SIZE64BIT -}; - -/* hw_idle_mode_t: Enumerated Type used to specify Idle modes */ -enum hw_idle_mode_t { - HW_FORCE_IDLE, - HW_NO_IDLE, - HW_SMART_IDLE -}; - -#endif /* _HW_DEFS_H */ diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c deleted file mode 100644 index 014f5d5..0000000 --- a/drivers/staging/tidspbridge/hw/hw_mmu.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * hw_mmu.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * API definitions to setup MMU TLB and PTE - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include "MMURegAcM.h" -#include -#include -#include -#include - -#define MMU_BASE_VAL_MASK 0xFC00 -#define MMU_PAGE_MAX 3 -#define MMU_ELEMENTSIZE_MAX 3 -#define MMU_ADDR_MASK 0xFFFFF000 -#define MMU_TTB_MASK 0xFFFFC000 -#define MMU_SECTION_ADDR_MASK 0xFFF00000 -#define MMU_SSECTION_ADDR_MASK 0xFF000000 -#define MMU_PAGE_TABLE_MASK 0xFFFFFC00 -#define MMU_LARGE_PAGE_MASK 0xFFFF0000 -#define MMU_SMALL_PAGE_MASK 0xFFFFF000 - -#define MMU_LOAD_TLB 0x00000001 -#define MMU_GFLUSH 0x60 - -/* - * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS) - */ -enum hw_mmu_page_size_t { - HW_MMU_SECTION, - HW_MMU_LARGE_PAGE, - HW_MMU_SMALL_PAGE, - HW_MMU_SUPERSECTION -}; - -/* - * FUNCTION : mmu_flush_entry - * - * INPUTS: - * - * Identifier : base_address - * Type : const u32 - * Description : Base Address of instance of MMU module - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occured - * RET_BAD_NULL_PARAM -- A Pointer - * Paramater was set to NULL - * - * PURPOSE: : Flush the TLB entry pointed by the - * lock counter register - * even if this entry is set protected - * - * METHOD: : Check the Input parameter and Flush a - * single entry in the TLB. - */ -static hw_status mmu_flush_entry(const void __iomem *base_address); - -/* - * FUNCTION : mmu_set_cam_entry - * - * INPUTS: - * - * Identifier : base_address - * TypE : const u32 - * Description : Base Address of instance of MMU module - * - * Identifier : page_sz - * TypE : const u32 - * Description : It indicates the page size - * - * Identifier : preserved_bit - * Type : const u32 - * Description : It indicates the TLB entry is preserved entry - * or not - * - * Identifier : valid_bit - * Type : const u32 - * Description : It indicates the TLB entry is valid entry or not - * - * - * Identifier : virtual_addr_tag - * Type : const u32 - * Description : virtual Address - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occured - * RET_BAD_NULL_PARAM -- A Pointer Paramater - * was set to NULL - * RET_PARAM_OUT_OF_RANGE -- Input Parameter out - * of Range - * - * PURPOSE: : Set MMU_CAM reg - * - * METHOD: : Check the Input parameters and set the CAM entry. - */ -static hw_status mmu_set_cam_entry(const void __iomem *base_address, - const u32 page_sz, - const u32 preserved_bit, - const u32 valid_bit, - const u32 virtual_addr_tag); - -/* - * FUNCTION : mmu_set_ram_entry - * - * INPUTS: - * - * Identifier : base_address - * Type : const u32 - * Description : Base Address of instance of MMU module - * - * Identifier : physical_addr - * Type : const u32 - * Description : Physical Address to which the corresponding - * virtual Address shouldpoint - * - * Identifier : endianism - * Type : hw_endianism_t - * Description : endianism for the given page - * - * Identifier : element_size - * Type : hw_element_size_t - * Description : The element size ( 8,16, 32 or 64 bit) - * - * Identifier : mixed_size - * Type : hw_mmu_mixed_size_t - * Description : Element Size to follow CPU or TLB - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occured - * RET_BAD_NULL_PARAM -- A Pointer Paramater - * was set to NULL - * RET_PARAM_OUT_OF_RANGE -- Input Parameter - * out of Range - * - * PURPOSE: : Set MMU_CAM reg - * - * METHOD: : Check the Input parameters and set the RAM entry. - */ -static hw_status mmu_set_ram_entry(const void __iomem *base_address, - const u32 physical_addr, - enum hw_endianism_t endianism, - enum hw_element_size_t element_size, - enum hw_mmu_mixed_size_t mixed_size); - -/* HW FUNCTIONS */ - -hw_status hw_mmu_enable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET); - - return status; -} - -hw_status hw_mmu_disable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR); - - return status; -} - -hw_status hw_mmu_num_locked_set(const void __iomem *base_address, - u32 num_locked_entries) -{ - hw_status status = 0; - - MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries); - - return status; -} - -hw_status hw_mmu_victim_num_set(const void __iomem *base_address, - u32 victim_entry_num) -{ - hw_status status = 0; - - MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num); - - return status; -} - -hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - - MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask); - - return status; -} - -hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - u32 irq_reg; - - irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address); - - MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask); - - return status; -} - -hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - u32 irq_reg; - - irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address); - - MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask); - - return status; -} - -hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask) -{ - hw_status status = 0; - - *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address); - - return status; -} - -hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr) -{ - hw_status status = 0; - - /* read values from register */ - *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address); - - return status; -} - -hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr) -{ - hw_status status = 0; - u32 load_ttb; - - load_ttb = ttb_phys_addr & ~0x7FUL; - /* write values to register */ - MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb); - - return status; -} - -hw_status hw_mmu_twl_enable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET); - - return status; -} - -hw_status hw_mmu_twl_disable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR); - - return status; -} - -hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr, - u32 page_sz) -{ - hw_status status = 0; - u32 virtual_addr_tag; - enum hw_mmu_page_size_t pg_size_bits; - - switch (page_sz) { - case HW_PAGE_SIZE4KB: - pg_size_bits = HW_MMU_SMALL_PAGE; - break; - - case HW_PAGE_SIZE64KB: - pg_size_bits = HW_MMU_LARGE_PAGE; - break; - - case HW_PAGE_SIZE1MB: - pg_size_bits = HW_MMU_SECTION; - break; - - case HW_PAGE_SIZE16MB: - pg_size_bits = HW_MMU_SUPERSECTION; - break; - - default: - return -EINVAL; - } - - /* Generate the 20-bit tag from virtual address */ - virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); - - mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag); - - mmu_flush_entry(base_address); - - return status; -} - -hw_status hw_mmu_tlb_add(const void __iomem *base_address, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - u32 entry_num, - struct hw_mmu_map_attrs_t *map_attrs, - s8 preserved_bit, s8 valid_bit) -{ - hw_status status = 0; - u32 lock_reg; - u32 virtual_addr_tag; - enum hw_mmu_page_size_t mmu_pg_size; - - /*Check the input Parameters */ - switch (page_sz) { - case HW_PAGE_SIZE4KB: - mmu_pg_size = HW_MMU_SMALL_PAGE; - break; - - case HW_PAGE_SIZE64KB: - mmu_pg_size = HW_MMU_LARGE_PAGE; - break; - - case HW_PAGE_SIZE1MB: - mmu_pg_size = HW_MMU_SECTION; - break; - - case HW_PAGE_SIZE16MB: - mmu_pg_size = HW_MMU_SUPERSECTION; - break; - - default: - return -EINVAL; - } - - lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address); - - /* Generate the 20-bit tag from virtual address */ - virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); - - /* Write the fields in the CAM Entry Register */ - mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit, - virtual_addr_tag); - - /* Write the different fields of the RAM Entry Register */ - /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */ - mmu_set_ram_entry(base_address, physical_addr, map_attrs->endianism, - map_attrs->element_size, map_attrs->mixed_size); - - /* Update the MMU Lock Register */ - /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */ - MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num); - - /* Enable loading of an entry in TLB by writing 1 - into LD_TLB_REG register */ - MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB); - - MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg); - - return status; -} - -hw_status hw_mmu_pte_set(const u32 pg_tbl_va, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs) -{ - hw_status status = 0; - u32 pte_addr, pte_val; - s32 num_entries = 1; - - switch (page_sz) { - case HW_PAGE_SIZE4KB: - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_SMALL_PAGE_MASK); - pte_val = - ((physical_addr & MMU_SMALL_PAGE_MASK) | - (map_attrs->endianism << 9) | (map_attrs-> - element_size << 4) | - (map_attrs->mixed_size << 11) | 2); - break; - - case HW_PAGE_SIZE64KB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_LARGE_PAGE_MASK); - pte_val = - ((physical_addr & MMU_LARGE_PAGE_MASK) | - (map_attrs->endianism << 9) | (map_attrs-> - element_size << 4) | - (map_attrs->mixed_size << 11) | 1); - break; - - case HW_PAGE_SIZE1MB: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - pte_val = - ((((physical_addr & MMU_SECTION_ADDR_MASK) | - (map_attrs->endianism << 15) | (map_attrs-> - element_size << 10) | - (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2); - break; - - case HW_PAGE_SIZE16MB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SSECTION_ADDR_MASK); - pte_val = - (((physical_addr & MMU_SSECTION_ADDR_MASK) | - (map_attrs->endianism << 15) | (map_attrs-> - element_size << 10) | - (map_attrs->mixed_size << 17) - ) | 0x40000 | 0x2); - break; - - case HW_MMU_COARSE_PAGE_SIZE: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1; - break; - - default: - return -EINVAL; - } - - while (--num_entries >= 0) - ((u32 *) pte_addr)[num_entries] = pte_val; - - return status; -} - -hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size) -{ - hw_status status = 0; - u32 pte_addr; - s32 num_entries = 1; - - switch (page_size) { - case HW_PAGE_SIZE4KB: - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_SMALL_PAGE_MASK); - break; - - case HW_PAGE_SIZE64KB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_LARGE_PAGE_MASK); - break; - - case HW_PAGE_SIZE1MB: - case HW_MMU_COARSE_PAGE_SIZE: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - break; - - case HW_PAGE_SIZE16MB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SSECTION_ADDR_MASK); - break; - - default: - return -EINVAL; - } - - while (--num_entries >= 0) - ((u32 *) pte_addr)[num_entries] = 0; - - return status; -} - -/* mmu_flush_entry */ -static hw_status mmu_flush_entry(const void __iomem *base_address) -{ - hw_status status = 0; - u32 flush_entry_data = 0x1; - - /* write values to register */ - MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data); - - return status; -} - -/* mmu_set_cam_entry */ -static hw_status mmu_set_cam_entry(const void __iomem *base_address, - const u32 page_sz, - const u32 preserved_bit, - const u32 valid_bit, - const u32 virtual_addr_tag) -{ - hw_status status = 0; - u32 mmu_cam_reg; - - mmu_cam_reg = (virtual_addr_tag << 12); - mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) | - (preserved_bit << 3); - - /* write values to register */ - MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg); - - return status; -} - -/* mmu_set_ram_entry */ -static hw_status mmu_set_ram_entry(const void __iomem *base_address, - const u32 physical_addr, - enum hw_endianism_t endianism, - enum hw_element_size_t element_size, - enum hw_mmu_mixed_size_t mixed_size) -{ - hw_status status = 0; - u32 mmu_ram_reg; - - mmu_ram_reg = (physical_addr & MMU_ADDR_MASK); - mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) | - (mixed_size << 6)); - - /* write values to register */ - MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg); - - return status; - -} - -void hw_mmu_tlb_flush_all(const void __iomem *base) -{ - __raw_writeb(1, base + MMU_GFLUSH); -} diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h deleted file mode 100644 index 1458a2c..0000000 --- a/drivers/staging/tidspbridge/hw/hw_mmu.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * hw_mmu.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * MMU types and API declarations - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _HW_MMU_H -#define _HW_MMU_H - -#include - -/* Bitmasks for interrupt sources */ -#define HW_MMU_TRANSLATION_FAULT 0x2 -#define HW_MMU_ALL_INTERRUPTS 0x1F - -#define HW_MMU_COARSE_PAGE_SIZE 0x400 - -/* hw_mmu_mixed_size_t: Enumerated Type used to specify whether to follow - CPU/TLB Element size */ -enum hw_mmu_mixed_size_t { - HW_MMU_TLBES, - HW_MMU_CPUES -}; - -/* hw_mmu_map_attrs_t: Struct containing MMU mapping attributes */ -struct hw_mmu_map_attrs_t { - enum hw_endianism_t endianism; - enum hw_element_size_t element_size; - enum hw_mmu_mixed_size_t mixed_size; - bool donotlockmpupage; -}; - -extern hw_status hw_mmu_enable(const void __iomem *base_address); - -extern hw_status hw_mmu_disable(const void __iomem *base_address); - -extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address, - u32 num_locked_entries); - -extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address, - u32 victim_entry_num); - -/* For MMU faults */ -extern hw_status hw_mmu_event_ack(const void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_disable(const void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_enable(const void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_status(const void __iomem *base_address, - u32 *irq_mask); - -extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, - u32 *addr); - -/* Set the TT base address */ -extern hw_status hw_mmu_ttb_set(const void __iomem *base_address, - u32 ttb_phys_addr); - -extern hw_status hw_mmu_twl_enable(const void __iomem *base_address); - -extern hw_status hw_mmu_twl_disable(const void __iomem *base_address); - -extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address, - u32 virtual_addr, u32 page_sz); - -extern hw_status hw_mmu_tlb_add(const void __iomem *base_address, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - u32 entry_num, - struct hw_mmu_map_attrs_t *map_attrs, - s8 preserved_bit, s8 valid_bit); - -/* For PTEs */ -extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - struct hw_mmu_map_attrs_t *map_attrs); - -extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, - u32 virtual_addr, u32 page_size); - -void hw_mmu_tlb_flush_all(const void __iomem *base); - -static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) -{ - u32 pte_addr; - u32 va31_to20; - - va31_to20 = va >> (20 - 2); /* Left-shift by 2 here itself */ - va31_to20 &= 0xFFFFFFFCUL; - pte_addr = l1_base + va31_to20; - - return pte_addr; -} - -static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va) -{ - u32 pte_addr; - - pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC); - - return pte_addr; -} - -static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val) -{ - u32 pte_coarse; - - pte_coarse = pte_val & 0xFFFFFC00; - - return pte_coarse; -} - -static inline u32 hw_mmu_pte_size_l1(u32 pte_val) -{ - u32 pte_size = 0; - - if ((pte_val & 0x3) == 0x1) { - /* Points to L2 PT */ - pte_size = HW_MMU_COARSE_PAGE_SIZE; - } - - if ((pte_val & 0x3) == 0x2) { - if (pte_val & (1 << 18)) - pte_size = HW_PAGE_SIZE16MB; - else - pte_size = HW_PAGE_SIZE1MB; - } - - return pte_size; -} - -static inline u32 hw_mmu_pte_size_l2(u32 pte_val) -{ - u32 pte_size = 0; - - if (pte_val & 0x2) - pte_size = HW_PAGE_SIZE4KB; - else if (pte_val & 0x1) - pte_size = HW_PAGE_SIZE64KB; - - return pte_size; -} - -#endif /* _HW_MMU_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 38122db..dfb55cc 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -68,7 +68,6 @@ struct cfg_hostres { void __iomem *dw_per_base; u32 dw_per_pm_base; u32 dw_core_pm_base; - void __iomem *dw_dmmu_base; void __iomem *dw_sys_ctrl_base; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index 357458f..9bdd48f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -27,7 +27,6 @@ #include #include #include -#include #include /* ----------------------------------- This */ @@ -234,29 +233,6 @@ extern int dev_get_cmm_mgr(struct dev_object *hdev_obj, struct cmm_object **mgr); /* - * ======== dev_get_dmm_mgr ======== - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr); - -/* * ======== dev_get_cod_mgr ======== * Purpose: * Retrieve the COD manager create for this device. diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h deleted file mode 100644 index 6c58335..0000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dmm.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * dmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DMM_ -#define DMM_ - -#include - -struct dmm_object; - -/* DMM attributes used in dmm_create() */ -struct dmm_mgrattrs { - u32 reserved; -}; - -#define DMMPOOLSIZE 0x4000000 - -/* - * ======== dmm_get_handle ======== - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ - -extern int dmm_get_handle(void *hprocessor, - struct dmm_object **dmm_manager); - -extern int dmm_reserve_memory(struct dmm_object *dmm_mgr, - u32 size, u32 *prsv_addr); - -extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, - u32 rsv_addr); - -extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, - u32 size); - -extern int dmm_un_map_memory(struct dmm_object *dmm_mgr, - u32 addr, u32 *psize); - -extern int dmm_destroy(struct dmm_object *dmm_mgr); - -extern int dmm_delete_tables(struct dmm_object *dmm_mgr); - -extern int dmm_create(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts); - -extern bool dmm_init(void); - -extern void dmm_exit(void); - -extern int dmm_create_tables(struct dmm_object *dmm_mgr, - u32 addr, u32 size); - -#ifdef DSP_DMM_DEBUG -u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr); -#endif - -#endif /* DMM_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index c1f363e..75a2c9b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -108,12 +108,6 @@ struct dmm_map_object { struct bridge_dma_map_info dma_info; }; -/* Used for DMM reserved memory accounting */ -struct dmm_rsv_object { - struct list_head link; - u32 dsp_reserved_addr; -}; - /* New structure (member of process context) abstracts DMM resource info */ struct dspheap_res_object { s32 heap_allocated; /* DMM status */ @@ -165,10 +159,6 @@ struct process_context { struct list_head dmm_map_list; spinlock_t dmm_map_lock; - /* DMM reserved memory resources */ - struct list_head dmm_rsv_list; - spinlock_t dmm_rsv_lock; - /* DSP Heap resources */ struct dspheap_res_object *pdspheap_list; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h b/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h new file mode 100644 index 0000000..cb38d4c --- /dev/null +++ b/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h @@ -0,0 +1,67 @@ +/* + * dsp-mmu.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2005-2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _DSP_MMU_ +#define _DSP_MMU_ + +#include +#include + +/** + * dsp_mmu_init() - initialize dsp_mmu module and returns a handle + * + * This function initialize dsp mmu module and returns a struct iommu + * handle to use it for dsp maps. + * + */ +struct iommu *dsp_mmu_init(void); + +/** + * dsp_mmu_exit() - destroy dsp mmu module + * @mmu: Pointer to iommu handle. + * + * This function destroys dsp mmu module. + * + */ +void dsp_mmu_exit(struct iommu *mmu); + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgs struct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + +#endif diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 0ae7d16..6153634 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -162,48 +162,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context u32 mem_type); /* - * ======== bridge_brd_mem_map ======== - * Purpose: - * Map a MPU memory region to a DSP/IVA memory space - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * ul_mpu_addr: MPU memory region start address. - * virt_addr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to map. - * map_attrs: Mapping attributes (e.g. endianness). - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memmap) (struct bridge_dev_context - * dev_ctxt, u32 ul_mpu_addr, - u32 virt_addr, u32 ul_num_bytes, - u32 map_attr, - struct page **mapped_pages); - -/* - * ======== bridge_brd_mem_un_map ======== - * Purpose: - * UnMap an MPU memory region from DSP/IVA memory space - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * virt_addr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to unmap. - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memunmap) (struct bridge_dev_context - * dev_ctxt, - u32 virt_addr, u32 ul_num_bytes); - -/* * ======== bridge_brd_stop ======== * Purpose: * Bring board to the BRD_STOPPED state. @@ -993,8 +951,6 @@ struct bridge_drv_interface { fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */ fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */ - fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */ - fxn_brd_memunmap pfn_brd_mem_un_map; /* Unmaps MPU mem to DSP mem */ fxn_chnl_create pfn_chnl_create; /* Create channel manager. */ fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ fxn_chnl_open pfn_chnl_open; /* Create a new channel. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index 41e0594..bad1801 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -19,10 +19,6 @@ #ifndef DSPIOCTL_ #define DSPIOCTL_ -/* ------------------------------------ Hardware Abstraction Layer */ -#include -#include - /* * Any IOCTLS at or above this value are reserved for standard Bridge driver * interfaces. @@ -65,9 +61,6 @@ struct bridge_ioctl_extproc { /* GPP virtual address. __va does not work for ioremapped addresses */ u32 ul_gpp_va; u32 ul_size; /* Size of the mapped memory in bytes */ - enum hw_endianism_t endianism; - enum hw_mmu_mixed_size_t mixed_mode; - enum hw_element_size_t elem_size; }; #endif /* DSPIOCTL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index 5e09fd1..2d12aab 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -551,29 +551,6 @@ extern int proc_map(void *hprocessor, struct process_context *pr_ctxt); /* - * ======== proc_reserve_memory ======== - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * ul_size : Size of the address space to reserve. - * pp_rsv_addr : Ptr to DSP side reserved u8 address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOMEM : Cannot reserve chunk of this size. - * Requires: - * pp_rsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_reserve_memory(void *hprocessor, - u32 ul_size, void **pp_rsv_addr, - struct process_context *pr_ctxt); - -/* * ======== proc_un_map ======== * Purpose: * Removes a MPU buffer mapping from the DSP address space. @@ -595,27 +572,4 @@ extern int proc_reserve_memory(void *hprocessor, extern int proc_un_map(void *hprocessor, void *map_addr, struct process_context *pr_ctxt); -/* - * ======== proc_un_reserve_memory ======== - * Purpose: - * Frees a previously reserved region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * prsv_addr : Ptr to DSP side reservedBYTE address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOENT : Cannot find a reserved region starting with this - * : address. - * Requires: - * prsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_un_reserve_memory(void *hprocessor, - void *prsv_addr, - struct process_context *pr_ctxt); - #endif /* PROC_ */ diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 132e960..7b30267 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -34,7 +34,6 @@ #include #include #include -#include /* ----------------------------------- Resource Manager */ #include @@ -75,7 +74,6 @@ struct dev_object { struct msg_mgr *hmsg_mgr; /* Message manager. */ struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */ struct cmm_object *hcmm_mgr; /* SM memory manager. */ - struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ struct ldr_module *module_obj; /* Bridge Module handle. */ u32 word_size; /* DSP word size: quick access. */ struct drv_object *hdrv_obj; /* Driver Object */ @@ -250,9 +248,6 @@ int dev_create_device(struct dev_object **device_obj, /* Instantiate the DEH module */ status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj); } - /* Create DMM mgr . */ - status = dmm_create(&dev_obj->dmm_mgr, - (struct dev_object *)dev_obj, NULL); } /* Add the new DEV_Object to the global list: */ if (!status) { @@ -278,8 +273,6 @@ leave: kfree(dev_obj->proc_list); if (dev_obj->cod_mgr) cod_delete(dev_obj->cod_mgr); - if (dev_obj->dmm_mgr) - dmm_destroy(dev_obj->dmm_mgr); kfree(dev_obj); } @@ -389,11 +382,6 @@ int dev_destroy_device(struct dev_object *hdev_obj) dev_obj->hcmm_mgr = NULL; } - if (dev_obj->dmm_mgr) { - dmm_destroy(dev_obj->dmm_mgr); - dev_obj->dmm_mgr = NULL; - } - /* Call the driver's bridge_dev_destroy() function: */ /* Require of DevDestroy */ if (dev_obj->hbridge_context) { @@ -474,32 +462,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj, } /* - * ======== dev_get_dmm_mgr ======== - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - */ -int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(mgr != NULL); - - if (hdev_obj) { - *mgr = dev_obj->dmm_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL)); - return status; -} - -/* * ======== dev_get_cod_mgr ======== * Purpose: * Retrieve the COD manager create for this device. @@ -751,10 +713,8 @@ void dev_exit(void) refs--; - if (refs == 0) { + if (refs == 0) cmm_exit(); - dmm_exit(); - } DBC_ENSURE(refs >= 0); } @@ -766,25 +726,12 @@ void dev_exit(void) */ bool dev_init(void) { - bool cmm_ret, dmm_ret, ret = true; + bool ret = true; DBC_REQUIRE(refs >= 0); - if (refs == 0) { - cmm_ret = cmm_init(); - dmm_ret = dmm_init(); - - ret = cmm_ret && dmm_ret; - - if (!ret) { - if (cmm_ret) - cmm_exit(); - - if (dmm_ret) - dmm_exit(); - - } - } + if (refs == 0) + ret = cmm_init(); if (ret) refs++; @@ -1118,8 +1065,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, STORE_FXN(fxn_brd_setstate, pfn_brd_set_state); STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy); STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write); - STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map); - STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map); STORE_FXN(fxn_chnl_create, pfn_chnl_create); STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy); STORE_FXN(fxn_chnl_open, pfn_chnl_open); diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c deleted file mode 100644 index 8685233..0000000 --- a/drivers/staging/tidspbridge/pmgr/dmm.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * dmm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region - * - * Notes: - * Region: Generic memory entitiy having a start address and a size - * Chunk: Reserved region - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include - -/* ----------------------------------- Host OS */ -#include - -/* ----------------------------------- DSP/BIOS Bridge */ -#include - -/* ----------------------------------- Trace & Debug */ -#include - -/* ----------------------------------- OS Adaptation Layer */ -#include - -/* ----------------------------------- Platform Manager */ -#include -#include - -/* ----------------------------------- This */ -#include - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define DMM_ADDR_VIRTUAL(a) \ - (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\ - dyn_mem_map_beg) -#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K) - -/* DMM Mgr */ -struct dmm_object { - /* Dmm Lock is used to serialize access mem manager for - * multi-threads. */ - spinlock_t dmm_lock; /* Lock to access dmm mgr */ -}; - -/* ----------------------------------- Globals */ -static u32 refs; /* module reference count */ -struct map_page { - u32 region_size:15; - u32 mapped_size:15; - u32 reserved:1; - u32 mapped:1; -}; - -/* Create the free list */ -static struct map_page *virtual_mapping_table; -static u32 free_region; /* The index of free region */ -static u32 free_size; -static u32 dyn_mem_map_beg; /* The Beginning of dynamic memory mapping */ -static u32 table_size; /* The size of virt and phys pages tables */ - -/* ----------------------------------- Function Prototypes */ -static struct map_page *get_region(u32 addr); -static struct map_page *get_free_region(u32 len); -static struct map_page *get_mapped_region(u32 addrs); - -/* ======== dmm_create_tables ======== - * Purpose: - * Create table to hold the information of physical address - * the buffer pages that is passed by the user, and the table - * to hold the information of the virtual memory that is reserved - * for DSP. - */ -int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - int status = 0; - - status = dmm_delete_tables(dmm_obj); - if (!status) { - dyn_mem_map_beg = addr; - table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K; - /* Create the free list */ - virtual_mapping_table = __vmalloc(table_size * - sizeof(struct map_page), GFP_KERNEL | - __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); - if (virtual_mapping_table == NULL) - status = -ENOMEM; - else { - /* On successful allocation, - * all entries are zero ('free') */ - free_region = 0; - free_size = table_size * PG_SIZE4K; - virtual_mapping_table[0].region_size = table_size; - } - } - - if (status) - pr_err("%s: failure, status 0x%x\n", __func__, status); - - return status; -} - -/* - * ======== dmm_create ======== - * Purpose: - * Create a dynamic memory manager object. - */ -int dmm_create(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts) -{ - struct dmm_object *dmm_obj = NULL; - int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dmm_manager != NULL); - - *dmm_manager = NULL; - /* create, zero, and tag a cmm mgr object */ - dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL); - if (dmm_obj != NULL) { - spin_lock_init(&dmm_obj->dmm_lock); - *dmm_manager = dmm_obj; - } else { - status = -ENOMEM; - } - - return status; -} - -/* - * ======== dmm_destroy ======== - * Purpose: - * Release the communication memory manager resources. - */ -int dmm_destroy(struct dmm_object *dmm_mgr) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - int status = 0; - - DBC_REQUIRE(refs > 0); - if (dmm_mgr) { - status = dmm_delete_tables(dmm_obj); - if (!status) - kfree(dmm_obj); - } else - status = -EFAULT; - - return status; -} - -/* - * ======== dmm_delete_tables ======== - * Purpose: - * Delete DMM Tables. - */ -int dmm_delete_tables(struct dmm_object *dmm_mgr) -{ - int status = 0; - - DBC_REQUIRE(refs > 0); - /* Delete all DMM tables */ - if (dmm_mgr) - vfree(virtual_mapping_table); - else - status = -EFAULT; - return status; -} - -/* - * ======== dmm_exit ======== - * Purpose: - * Discontinue usage of module; free resources when reference count - * reaches 0. - */ -void dmm_exit(void) -{ - DBC_REQUIRE(refs > 0); - - refs--; -} - -/* - * ======== dmm_get_handle ======== - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ -int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager) -{ - int status = 0; - struct dev_object *hdev_obj; - - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dmm_manager != NULL); - if (hprocessor != NULL) - status = proc_get_dev_object(hprocessor, &hdev_obj); - else - hdev_obj = dev_get_first(); /* default */ - - if (!status) - status = dev_get_dmm_mgr(hdev_obj, dmm_manager); - - return status; -} - -/* - * ======== dmm_init ======== - * Purpose: - * Initializes private state of DMM module. - */ -bool dmm_init(void) -{ - bool ret = true; - - DBC_REQUIRE(refs >= 0); - - if (ret) - refs++; - - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - - virtual_mapping_table = NULL; - table_size = 0; - - return ret; -} - -/* - * ======== dmm_map_memory ======== - * Purpose: - * Add a mapping block to the reserved chunk. DMM assumes that this block - * will be mapped in the DSP/IVA's address space. DMM returns an error if a - * mapping overlaps another one. This function stores the info that will be - * required later while unmapping the block. - */ -int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - int status = 0; - - spin_lock(&dmm_obj->dmm_lock); - /* Find the Reserved memory chunk containing the DSP block to - * be mapped */ - chunk = (struct map_page *)get_region(addr); - if (chunk != NULL) { - /* Mark the region 'mapped', leave the 'reserved' info as-is */ - chunk->mapped = true; - chunk->mapped_size = (size / PG_SIZE4K); - } else - status = -ENOENT; - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, " - "chunk %p", __func__, dmm_mgr, addr, size, status, chunk); - - return status; -} - -/* - * ======== dmm_reserve_memory ======== - * Purpose: - * Reserve a chunk of virtually contiguous DSP/IVA address space. - */ -int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size, - u32 *prsv_addr) -{ - int status = 0; - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *node; - u32 rsv_addr = 0; - u32 rsv_size = 0; - - spin_lock(&dmm_obj->dmm_lock); - - /* Try to get a DSP chunk from the free list */ - node = get_free_region(size); - if (node != NULL) { - /* DSP chunk of given size is available. */ - rsv_addr = DMM_ADDR_VIRTUAL(node); - /* Calculate the number entries to use */ - rsv_size = size / PG_SIZE4K; - if (rsv_size < node->region_size) { - /* Mark remainder of free region */ - node[rsv_size].mapped = false; - node[rsv_size].reserved = false; - node[rsv_size].region_size = - node->region_size - rsv_size; - node[rsv_size].mapped_size = 0; - } - /* get_region will return first fit chunk. But we only use what - is requested. */ - node->mapped = false; - node->reserved = true; - node->region_size = rsv_size; - node->mapped_size = 0; - /* Return the chunk's starting address */ - *prsv_addr = rsv_addr; - } else - /*dSP chunk of given size is not available */ - status = -ENOMEM; - - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, " - "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size, - prsv_addr, status, rsv_addr, rsv_size); - - return status; -} - -/* - * ======== dmm_un_map_memory ======== - * Purpose: - * Remove the mapped block from the reserved chunk. - */ -int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - int status = 0; - - spin_lock(&dmm_obj->dmm_lock); - chunk = get_mapped_region(addr); - if (chunk == NULL) - status = -ENOENT; - - if (!status) { - /* Unmap the region */ - *psize = chunk->mapped_size * PG_SIZE4K; - chunk->mapped = false; - chunk->mapped_size = 0; - } - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, " - "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk); - - return status; -} - -/* - * ======== dmm_un_reserve_memory ======== - * Purpose: - * Free a chunk of reserved DSP/IVA address space. - */ -int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - u32 i; - int status = 0; - u32 chunk_size; - - spin_lock(&dmm_obj->dmm_lock); - - /* Find the chunk containing the reserved address */ - chunk = get_mapped_region(rsv_addr); - if (chunk == NULL) - status = -ENOENT; - - if (!status) { - /* Free all the mapped pages for this reserved region */ - i = 0; - while (i < chunk->region_size) { - if (chunk[i].mapped) { - /* Remove mapping from the page tables. */ - chunk_size = chunk[i].mapped_size; - /* Clear the mapping flags */ - chunk[i].mapped = false; - chunk[i].mapped_size = 0; - i += chunk_size; - } else - i++; - } - /* Clear the flags (mark the region 'free') */ - chunk->reserved = false; - /* NOTE: We do NOT coalesce free regions here. - * Free regions are coalesced in get_region(), as it traverses - *the whole mapping table - */ - } - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p", - __func__, dmm_mgr, rsv_addr, status, chunk); - - return status; -} - -/* - * ======== get_region ======== - * Purpose: - * Returns a region containing the specified memory region - */ -static struct map_page *get_region(u32 addr) -{ - struct map_page *curr_region = NULL; - u32 i = 0; - - if (virtual_mapping_table != NULL) { - /* find page mapped by this address */ - i = DMM_ADDR_TO_INDEX(addr); - if (i < table_size) - curr_region = virtual_mapping_table + i; - } - - dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n", - __func__, curr_region, free_region, free_size); - return curr_region; -} - -/* - * ======== get_free_region ======== - * Purpose: - * Returns the requested free region - */ -static struct map_page *get_free_region(u32 len) -{ - struct map_page *curr_region = NULL; - u32 i = 0; - u32 region_size = 0; - u32 next_i = 0; - - if (virtual_mapping_table == NULL) - return curr_region; - if (len > free_size) { - /* Find the largest free region - * (coalesce during the traversal) */ - while (i < table_size) { - region_size = virtual_mapping_table[i].region_size; - next_i = i + region_size; - if (virtual_mapping_table[i].reserved == false) { - /* Coalesce, if possible */ - if (next_i < table_size && - virtual_mapping_table[next_i].reserved - == false) { - virtual_mapping_table[i].region_size += - virtual_mapping_table - [next_i].region_size; - continue; - } - region_size *= PG_SIZE4K; - if (region_size > free_size) { - free_region = i; - free_size = region_size; - } - } - i = next_i; - } - } - if (len <= free_size) { - curr_region = virtual_mapping_table + free_region; - free_region += (len / PG_SIZE4K); - free_size -= len; - } - return curr_region; -} - -/* - * ======== get_mapped_region ======== - * Purpose: - * Returns the requestedmapped region - */ -static struct map_page *get_mapped_region(u32 addrs) -{ - u32 i = 0; - struct map_page *curr_region = NULL; - - if (virtual_mapping_table == NULL) - return curr_region; - - i = DMM_ADDR_TO_INDEX(addrs); - if (i < table_size && (virtual_mapping_table[i].mapped || - virtual_mapping_table[i].reserved)) - curr_region = virtual_mapping_table + i; - return curr_region; -} - -#ifdef DSP_DMM_DEBUG -u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr) -{ - struct map_page *curr_node = NULL; - u32 i; - u32 freemem = 0; - u32 bigsize = 0; - - spin_lock(&dmm_mgr->dmm_lock); - - if (virtual_mapping_table != NULL) { - for (i = 0; i < table_size; i += - virtual_mapping_table[i].region_size) { - curr_node = virtual_mapping_table + i; - if (curr_node->reserved) { - /*printk("RESERVED size = 0x%x, " - "Map size = 0x%x\n", - (curr_node->region_size * PG_SIZE4K), - (curr_node->mapped == false) ? 0 : - (curr_node->mapped_size * PG_SIZE4K)); - */ - } else { -/* printk("UNRESERVED size = 0x%x\n", - (curr_node->region_size * PG_SIZE4K)); - */ - freemem += (curr_node->region_size * PG_SIZE4K); - if (curr_node->region_size > bigsize) - bigsize = curr_node->region_size; - } - } - } - spin_unlock(&dmm_mgr->dmm_lock); - printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n", - freemem / (1024 * 1024)); - printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n", - (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024)); - printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n", - (bigsize * PG_SIZE4K / (1024 * 1024))); - - return 0; -} -#endif diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 86ca785..981551c 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -993,27 +993,10 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) /* * ======== procwrap_reserve_memory ======== */ -u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - if ((args->args_proc_rsvmem.ul_size <= 0) || - (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, - args->args_proc_rsvmem.ul_size, &prsv_addr, - pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - hprocessor, prsv_addr, pr_ctxt); - } - } - return status; + return 0; } /* @@ -1042,15 +1025,10 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) /* * ======== procwrap_un_reserve_memory ======== */ -u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.prsv_addr, - pr_ctxt); - return status; + return 0; } /* diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 81b1b90..91cc168 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -146,7 +146,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) struct process_context *ctxt = (struct process_context *)process_ctxt; int status = 0; struct dmm_map_object *temp_map, *map_obj; - struct dmm_rsv_object *temp_rsv, *rsv_obj; /* Free DMM mapped memory resources */ list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) { @@ -156,16 +155,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) pr_err("%s: proc_un_map failed!" " status = 0x%xn", __func__, status); } - - /* Free DMM reserved memory resources */ - list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) { - status = proc_un_reserve_memory(ctxt->hprocessor, (void *) - rsv_obj->dsp_reserved_addr, - ctxt); - if (status) - pr_err("%s: proc_un_reserve_memory failed!" - " status = 0x%xn", __func__, status); - } return status; } @@ -743,7 +732,6 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); /* for 24xx base port is not mapping the mamory for DSP * internal memory TODO Do a ioremap here */ @@ -797,8 +785,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) OMAP_PER_PRM_SIZE); host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, OMAP_CORE_PRM_SIZE); - host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE, - OMAP_DMMU_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); @@ -810,7 +796,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) host_res->dw_mem_base[3]); dev_dbg(bridge, "dw_mem_base[4] 0x%x\n", host_res->dw_mem_base[4]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); shm_size = drv_datap->shm_size; if (shm_size >= 0x10000) { diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 324fcdf..34be43f 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -509,8 +509,6 @@ static int bridge_open(struct inode *ip, struct file *filp) pr_ctxt->res_state = PROC_RES_ALLOCATED; spin_lock_init(&pr_ctxt->dmm_map_lock); INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); - spin_lock_init(&pr_ctxt->dmm_rsv_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); if (pr_ctxt->node_id) { diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 1562f3c..a660247 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -56,7 +56,6 @@ /* ----------------------------------- This */ #include #include -#include /* Static/Dynamic Loader includes */ #include @@ -317,10 +316,6 @@ int node_allocate(struct proc_object *hprocessor, u32 mapped_addr = 0; u32 map_attrs = 0x0; struct dsp_processorstate proc_state; -#ifdef DSP_DMM_DEBUG - struct dmm_object *dmm_mgr; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; -#endif void *node_res; @@ -430,34 +425,12 @@ int node_allocate(struct proc_object *hprocessor, if (status) goto func_cont; - status = proc_reserve_memory(hprocessor, - pnode->create_args.asa.task_arg_obj. - heap_size + PAGE_SIZE, - (void **)&(pnode->create_args.asa. - task_arg_obj.udsp_heap_res_addr), - pr_ctxt); - if (status) { - pr_err("%s: Failed to reserve memory for heap: 0x%x\n", - __func__, status); - goto func_cont; - } -#ifdef DSP_DMM_DEBUG - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = DSP_EHANDLE; - goto func_cont; - } - - dmm_mem_map_dump(dmm_mgr); -#endif - map_attrs |= DSP_MAPLITTLEENDIAN; map_attrs |= DSP_MAPELEMSIZE32; map_attrs |= DSP_MAPVIRTUALADDR; status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, pnode->create_args.asa.task_arg_obj.heap_size, - (void *)pnode->create_args.asa.task_arg_obj. - udsp_heap_res_addr, (void **)&mapped_addr, map_attrs, + NULL, (void **)&mapped_addr, map_attrs, pr_ctxt); if (status) pr_err("%s: Failed to map memory for Heap: 0x%x\n", @@ -2511,11 +2484,7 @@ static void delete_node(struct node_object *hnode, struct stream_chnl stream; struct node_msgargs node_msg_args; struct node_taskargs task_arg_obj; -#ifdef DSP_DMM_DEBUG - struct dmm_object *dmm_mgr; - struct proc_object *p_proc_object = - (struct proc_object *)hnode->hprocessor; -#endif + int status; if (!hnode) goto func_end; @@ -2576,19 +2545,6 @@ static void delete_node(struct node_object *hnode, status = proc_un_map(hnode->hprocessor, (void *) task_arg_obj.udsp_heap_addr, pr_ctxt); - - status = proc_un_reserve_memory(hnode->hprocessor, - (void *) - task_arg_obj. - udsp_heap_res_addr, - pr_ctxt); -#ifdef DSP_DMM_DEBUG - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (dmm_mgr) - dmm_mem_map_dump(dmm_mgr); - else - status = DSP_EHANDLE; -#endif } } if (node_type != NODE_MESSAGE) { diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index b47d7aa..7a15a02 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -39,7 +39,6 @@ #include #include #include -#include /* ----------------------------------- Resource Manager */ #include @@ -52,6 +51,7 @@ #include #include #include +#include <_tiomap.h> /* ----------------------------------- This */ #include @@ -151,34 +151,21 @@ static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt, return map_obj; } -static int match_exact_map_obj(struct dmm_map_object *map_obj, - u32 dsp_addr, u32 size) -{ - if (map_obj->dsp_addr == dsp_addr && map_obj->size != size) - pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n", - __func__, dsp_addr, map_obj->size, size); - - return map_obj->dsp_addr == dsp_addr && - map_obj->size == size; -} - static void remove_mapping_information(struct process_context *pr_ctxt, - u32 dsp_addr, u32 size) + u32 dsp_addr) { struct dmm_map_object *map_obj; - pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__, - dsp_addr, size); + pr_debug("%s: looking for virt 0x%x\n", __func__, dsp_addr); spin_lock(&pr_ctxt->dmm_map_lock); list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) { - pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n", + pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x\n", __func__, map_obj->mpu_addr, - map_obj->dsp_addr, - map_obj->size); + map_obj->dsp_addr); - if (match_exact_map_obj(map_obj, dsp_addr, size)) { + if (map_obj->dsp_addr == dsp_addr) { pr_debug("%s: match, deleting map info\n", __func__); list_del(&map_obj->link); kfree(map_obj->dma_info.sg); @@ -1090,7 +1077,6 @@ int proc_load(void *hprocessor, const s32 argc_index, s32 cnew_envp; /* " " in new_envp[] */ s32 nproc_id = 0; /* Anticipate MP version. */ struct dcd_manager *hdcd_handle; - struct dmm_object *dmm_mgr; u32 dw_ext_end; u32 proc_id; int brd_state; @@ -1281,25 +1267,6 @@ int proc_load(void *hprocessor, const s32 argc_index, if (!status) status = cod_get_sym_value(cod_mgr, EXTEND, &dw_ext_end); - - /* Reset DMM structs and add an initial free chunk */ - if (!status) { - status = - dev_get_dmm_mgr(p_proc_object->hdev_obj, - &dmm_mgr); - if (dmm_mgr) { - /* Set dw_ext_end to DMM START u8 - * address */ - dw_ext_end = - (dw_ext_end + 1) * DSPWORDSIZE; - /* DMM memory is from EXT_END */ - status = dmm_create_tables(dmm_mgr, - dw_ext_end, - DMMPOOLSIZE); - } else { - status = -EFAULT; - } - } } } /* Restore the original argv[0] */ @@ -1352,12 +1319,10 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, { u32 va_align; u32 pa_align; - struct dmm_object *dmm_mgr; u32 size_align; int status = 0; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; struct dmm_map_object *map_obj; - u32 tmp_addr = 0; #ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK if ((ul_map_attr & BUFMODE_MASK) != RBUF) { @@ -1382,33 +1347,30 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, } /* Critical section */ mutex_lock(&proc_lock); - dmm_get_handle(p_proc_object, &dmm_mgr); - if (dmm_mgr) - status = dmm_map_memory(dmm_mgr, va_align, size_align); - else - status = -EFAULT; /* Add mapping to the page tables. */ if (!status) { - - /* Mapped address = MSB of VA | LSB of PA */ - tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1))); /* mapped memory resource tracking */ - map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr, + map_obj = add_mapping_info(pr_ctxt, pa_align, va_align, size_align); - if (!map_obj) + if (!map_obj) { status = -ENOMEM; - else - status = (*p_proc_object->intf_fxns->pfn_brd_mem_map) - (p_proc_object->hbridge_context, pa_align, va_align, - size_align, ul_map_attr, map_obj->pages); + } else { + va_align = user_to_dsp_map( + p_proc_object->hbridge_context->dsp_mmu, + pa_align, va_align, size_align, + map_obj->pages); + if (IS_ERR_VALUE(va_align)) + status = (int)va_align; + } } if (!status) { /* Mapped address = MSB of VA | LSB of PA */ - *pp_map_addr = (void *) tmp_addr; + map_obj->dsp_addr = (va_align | + ((u32)pmpu_addr & (PG_SIZE4K - 1))); + *pp_map_addr = (void *)map_obj->dsp_addr; } else { - remove_mapping_information(pr_ctxt, tmp_addr, size_align); - dmm_un_map_memory(dmm_mgr, va_align, &size_align); + remove_mapping_information(pr_ctxt, va_align); } mutex_unlock(&proc_lock); @@ -1501,55 +1463,6 @@ func_end: } /* - * ======== proc_reserve_memory ======== - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - */ -int proc_reserve_memory(void *hprocessor, u32 ul_size, - void **pp_rsv_addr, - struct process_context *pr_ctxt) -{ - struct dmm_object *dmm_mgr; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr); - if (status != 0) - goto func_end; - - /* - * A successful reserve should be followed by insertion of rsv_obj - * into dmm_rsv_list, so that reserved memory resource tracking - * remains uptodate - */ - rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL); - if (rsv_obj) { - rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr; - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list); - spin_unlock(&pr_ctxt->dmm_rsv_lock); - } - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p " - "status 0x%x\n", __func__, hprocessor, - ul_size, pp_rsv_addr, status); - return status; -} - -/* * ======== proc_start ======== * Purpose: * Start a processor running. @@ -1697,9 +1610,7 @@ int proc_un_map(void *hprocessor, void *map_addr, { int status = 0; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_object *dmm_mgr; u32 va_align; - u32 size_align; va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K); if (!p_proc_object) { @@ -1707,24 +1618,11 @@ int proc_un_map(void *hprocessor, void *map_addr, goto func_end; } - status = dmm_get_handle(hprocessor, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - /* Critical section */ mutex_lock(&proc_lock); - /* - * Update DMM structures. Get the size to unmap. - * This function returns error if the VA is not mapped - */ - status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align); /* Remove mapping from the page tables. */ - if (!status) { - status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map) - (p_proc_object->hbridge_context, va_align, size_align); - } + status = user_to_dsp_unmap(p_proc_object->hbridge_context->dsp_mmu, + va_align); mutex_unlock(&proc_lock); if (status) @@ -1735,7 +1633,7 @@ int proc_un_map(void *hprocessor, void *map_addr, * from dmm_map_list, so that mapped memory resource tracking * remains uptodate */ - remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); + remove_mapping_information(pr_ctxt, (u32) map_addr); func_end: dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", @@ -1744,55 +1642,6 @@ func_end: } /* - * ======== proc_un_reserve_memory ======== - * Purpose: - * Frees a previously reserved region of DSP address space. - */ -int proc_un_reserve_memory(void *hprocessor, void *prsv_addr, - struct process_context *pr_ctxt) -{ - struct dmm_object *dmm_mgr; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr); - if (status != 0) - goto func_end; - - /* - * A successful unreserve should be followed by removal of rsv_obj - * from dmm_rsv_list, so that reserved memory resource tracking - * remains uptodate - */ - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) { - if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) { - list_del(&rsv_obj->link); - kfree(rsv_obj); - break; - } - } - spin_unlock(&pr_ctxt->dmm_rsv_lock); - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n", - __func__, hprocessor, prsv_addr, status); - return status; -} - -/* * ======== = proc_monitor ======== == * Purpose: * Place the Processor in Monitor State. This is an internal diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index c5690b2..9ec8279 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -1032,7 +1032,6 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm) struct tm6000_fh *fh=priv; struct tm6000_core *dev = fh->dev; - dev->norm = *norm; rc = tm6000_init_analog_mode(dev); fh->width = dev->width; diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index fed2510..5969e84 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -887,7 +887,7 @@ static int dlfb_ops_open(struct fb_info *info, int user) struct fb_deferred_io *fbdefio; - fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); + fbdefio = kmalloc(GFP_KERNEL, sizeof(struct fb_deferred_io)); if (fbdefio) { fbdefio->delay = DL_DEFIO_WRITE_DELAY; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 7cc3d24..e992d5d 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1675,14 +1675,13 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { { char essid[IW_ESSID_MAX_SIZE+1]; - if (wrq->u.essid.pointer) { + if (wrq->u.essid.pointer) rc = iwctl_giwessid(dev, NULL, &(wrq->u.essid), essid); if (copy_to_user(wrq->u.essid.pointer, essid, wrq->u.essid.length) ) rc = -EFAULT; - } } break; diff --git a/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/drivers/staging/westbridge/astoria/api/src/cyasusb.c index 7777d9a..5a21970 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasusb.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasusb.c @@ -1417,6 +1417,7 @@ cy_as_usb_set_enum_config(cy_as_device_handle handle, */ bus_mask = 0; media_mask = 0; + media_mask = 0; for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) { for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++) { if (config_p->devices_to_enumerate[bus][device] == diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 6a71f52..4af83d5 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -139,7 +139,7 @@ exit: } int prism2_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_index, bool pairwise, const u8 *mac_addr, + u8 key_index, const u8 *mac_addr, struct key_params *params) { wlandevice_t *wlandev = dev->ml_priv; @@ -198,7 +198,7 @@ exit: } int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, + u8 key_index, const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params*)) { wlandevice_t *wlandev = dev->ml_priv; @@ -227,7 +227,7 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, } int prism2_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_index, bool pairwise, const u8 *mac_addr) + u8 key_index, const u8 *mac_addr) { wlandevice_t *wlandev = dev->ml_priv; u32 did; diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index b7b4a73..aa1792c 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -522,8 +522,8 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr) if (copy_to_user(useraddr, &edata, sizeof(edata))) return -EFAULT; return 0; -#endif } +#endif return -EOPNOTSUPP; } diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 81b4658..04ef3ef 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) if (msg->len < 128) *--dp = (msg->len << 1) | EA; else { - *--dp = ((msg->len & 127) << 1) | EA; - *--dp = (msg->len >> 6) & 0xfe; + *--dp = (msg->len >> 6) | EA; + *--dp = (msg->len & 127) << 1; } } @@ -2375,7 +2375,6 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm, gsm->mru = c->mru; gsm->encoding = c->encapsulation; gsm->adaption = c->adaption; - gsm->n2 = c->n2; if (c->i == 1) gsm->ftype = UIH; diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index d8210ca..cc1e985 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -413,8 +413,7 @@ static void flush_to_ldisc(struct work_struct *work) spin_lock_irqsave(&tty->buf.lock, flags); if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { - struct tty_buffer *head, *tail = tty->buf.tail; - int seen_tail = 0; + struct tty_buffer *head; while ((head = tty->buf.head) != NULL) { int count; char *char_buf; @@ -424,15 +423,6 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) { if (head->next == NULL) break; - /* - There's a possibility tty might get new buffer - added during the unlock window below. We could - end up spinning in here forever hogging the CPU - completely. To avoid this let's have a rest each - time we processed the tail buffer. - */ - if (tail == head) - seen_tail = 1; tty->buf.head = head->next; tty_buffer_free(tty, head); continue; @@ -442,7 +432,7 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; - if (!tty->receive_room || seen_tail) { + if (!tty->receive_room) { schedule_delayed_work(&tty->buf.work, 1); break; } diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index d8e96b0..412f977 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -47,7 +47,6 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle); /* Line disc dispatch table */ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; @@ -84,7 +83,6 @@ static void put_ldisc(struct tty_ldisc *ld) return; } local_irq_restore(flags); - wake_up(&tty_ldisc_idle); } /** @@ -533,23 +531,6 @@ static int tty_ldisc_halt(struct tty_struct *tty) } /** - * tty_ldisc_wait_idle - wait for the ldisc to become idle - * @tty: tty to wait for - * - * Wait for the line discipline to become idle. The discipline must - * have been halted for this to guarantee it remains idle. - */ -static int tty_ldisc_wait_idle(struct tty_struct *tty) -{ - int ret; - ret = wait_event_interruptible_timeout(tty_ldisc_idle, - atomic_read(&tty->ldisc->users) == 1, 5 * HZ); - if (ret < 0) - return ret; - return ret > 0 ? 0 : -EBUSY; -} - -/** * tty_set_ldisc - set line discipline * @tty: the terminal to set * @ldisc: the line discipline @@ -653,17 +634,8 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) flush_scheduled_work(); - retval = tty_ldisc_wait_idle(tty); - tty_lock(); mutex_lock(&tty->ldisc_mutex); - - /* handle wait idle failure locked */ - if (retval) { - tty_ldisc_put(new_ldisc); - goto enable; - } - if (test_bit(TTY_HUPPED, &tty->flags)) { /* We were raced by the hangup method. It will have stomped the ldisc data and closed the ldisc down */ @@ -697,7 +669,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_put(o_ldisc); -enable: /* * Allow ldisc referencing to occur again */ @@ -743,12 +714,9 @@ static void tty_reset_termios(struct tty_struct *tty) * state closed */ -static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) +static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) { - struct tty_ldisc *ld = tty_ldisc_get(ldisc); - - if (IS_ERR(ld)) - return -1; + struct tty_ldisc *ld; tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); @@ -756,10 +724,10 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) /* * Switch the line discipline back */ + ld = tty_ldisc_get(ldisc); + BUG_ON(IS_ERR(ld)); tty_ldisc_assign(tty, ld); tty_set_termios_ldisc(tty, ldisc); - - return 0; } /** @@ -834,16 +802,13 @@ void tty_ldisc_hangup(struct tty_struct *tty) a FIXME */ if (tty->ldisc) { /* Not yet closed */ if (reset == 0) { - - if (!tty_ldisc_reinit(tty, tty->termios->c_line)) - err = tty_ldisc_open(tty, tty->ldisc); - else - err = 1; + tty_ldisc_reinit(tty, tty->termios->c_line); + err = tty_ldisc_open(tty, tty->ldisc); } /* If the re-open fails or we reset then go to N_TTY. The N_TTY open cannot fail */ if (reset || err) { - BUG_ON(tty_ldisc_reinit(tty, N_TTY)); + tty_ldisc_reinit(tty, N_TTY); WARN_ON(tty_ldisc_open(tty, tty->ldisc)); } tty_ldisc_enable(tty); diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index eab3a1f..273ab44 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -553,12 +553,12 @@ static unsigned int vcs_poll(struct file *file, poll_table *wait) { struct vcs_poll_data *poll = vcs_poll_data_get(file); - int ret = DEFAULT_POLLMASK|POLLERR|POLLPRI; + int ret = 0; if (poll) { poll_wait(file, &poll->waitq, wait); - if (poll->seen_last_update) - ret = DEFAULT_POLLMASK; + if (!poll->seen_last_update) + ret = POLLIN | POLLRDNORM; } return ret; } diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 045bb4b..f1aaff6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -965,11 +965,10 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; return 0; diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 607d0db..b739ca8 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -158,7 +158,7 @@ config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC select USB_GADGET_DUALSPEED - select USB_FSL_MPH_DR_OF if OF + select USB_FSL_MPH_DR_OF help Some of Freescale PowerPC processors have a High Speed Dual-Role(DR) USB controller, which supports device mode. diff --git a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/goku_udc.h index e7e0c69..566cb23 100644 --- a/drivers/usb/gadget/goku_udc.h +++ b/drivers/usb/gadget/goku_udc.h @@ -251,8 +251,7 @@ struct goku_udc { got_region:1, req_config:1, configured:1, - enabled:1, - registered:1; + enabled:1; /* pci state used to access those endpoints */ struct pci_dev *pdev; diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 40f7716..01e5354 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -105,15 +105,11 @@ struct gs_port { wait_queue_head_t close_wait; /* wait for last close */ struct list_head read_pool; - int read_started; - int read_allocated; struct list_head read_queue; unsigned n_read; struct tasklet_struct push; struct list_head write_pool; - int write_started; - int write_allocated; struct gs_buf port_write_buf; wait_queue_head_t drain_wait; /* wait while writes drain */ @@ -367,9 +363,6 @@ __acquires(&port->port_lock) struct usb_request *req; int len; - if (port->write_started >= QUEUE_SIZE) - break; - req = list_entry(pool->next, struct usb_request, list); len = gs_send_packet(port, req->buf, in->maxpacket); if (len == 0) { @@ -404,8 +397,6 @@ __acquires(&port->port_lock) break; } - port->write_started++; - /* abort immediately after disconnect */ if (!port->port_usb) break; @@ -427,6 +418,7 @@ __acquires(&port->port_lock) { struct list_head *pool = &port->read_pool; struct usb_ep *out = port->port_usb->out; + unsigned started = 0; while (!list_empty(pool)) { struct usb_request *req; @@ -438,9 +430,6 @@ __acquires(&port->port_lock) if (!tty) break; - if (port->read_started >= QUEUE_SIZE) - break; - req = list_entry(pool->next, struct usb_request, list); list_del(&req->list); req->length = out->maxpacket; @@ -458,13 +447,13 @@ __acquires(&port->port_lock) list_add(&req->list, pool); break; } - port->read_started++; + started++; /* abort immediately after disconnect */ if (!port->port_usb) break; } - return port->read_started; + return started; } /* @@ -546,7 +535,6 @@ static void gs_rx_push(unsigned long _port) } recycle: list_move(&req->list, &port->read_pool); - port->read_started--; } /* Push from tty to ldisc; without low_latency set this is handled by @@ -599,7 +587,6 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) spin_lock(&port->port_lock); list_add(&req->list, &port->write_pool); - port->write_started--; switch (req->status) { default: @@ -621,8 +608,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) spin_unlock(&port->port_lock); } -static void gs_free_requests(struct usb_ep *ep, struct list_head *head, - int *allocated) +static void gs_free_requests(struct usb_ep *ep, struct list_head *head) { struct usb_request *req; @@ -630,31 +616,25 @@ static void gs_free_requests(struct usb_ep *ep, struct list_head *head, req = list_entry(head->next, struct usb_request, list); list_del(&req->list); gs_free_req(ep, req); - if (allocated) - (*allocated)--; } } static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head, - void (*fn)(struct usb_ep *, struct usb_request *), - int *allocated) + void (*fn)(struct usb_ep *, struct usb_request *)) { int i; struct usb_request *req; - int n = allocated ? QUEUE_SIZE - *allocated : QUEUE_SIZE; /* Pre-allocate up to QUEUE_SIZE transfers, but if we can't * do quite that many this time, don't fail ... we just won't * be as speedy as we might otherwise be. */ - for (i = 0; i < n; i++) { + for (i = 0; i < QUEUE_SIZE; i++) { req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC); if (!req) return list_empty(head) ? -ENOMEM : 0; req->complete = fn; list_add_tail(&req->list, head); - if (allocated) - (*allocated)++; } return 0; } @@ -681,15 +661,14 @@ static int gs_start_io(struct gs_port *port) * configurations may use different endpoints with a given port; * and high speed vs full speed changes packet sizes too. */ - status = gs_alloc_requests(ep, head, gs_read_complete, - &port->read_allocated); + status = gs_alloc_requests(ep, head, gs_read_complete); if (status) return status; status = gs_alloc_requests(port->port_usb->in, &port->write_pool, - gs_write_complete, &port->write_allocated); + gs_write_complete); if (status) { - gs_free_requests(ep, head, &port->read_allocated); + gs_free_requests(ep, head); return status; } @@ -701,9 +680,8 @@ static int gs_start_io(struct gs_port *port) if (started) { tty_wakeup(port->port_tty); } else { - gs_free_requests(ep, head, &port->read_allocated); - gs_free_requests(port->port_usb->in, &port->write_pool, - &port->write_allocated); + gs_free_requests(ep, head); + gs_free_requests(port->port_usb->in, &port->write_pool); status = -EIO; } @@ -1337,12 +1315,8 @@ void gserial_disconnect(struct gserial *gser) spin_lock_irqsave(&port->port_lock, flags); if (port->open_count == 0 && !port->openclose) gs_buf_free(&port->port_write_buf); - gs_free_requests(gser->out, &port->read_pool, NULL); - gs_free_requests(gser->out, &port->read_queue, NULL); - gs_free_requests(gser->in, &port->write_pool, NULL); - - port->read_allocated = port->read_started = - port->write_allocated = port->write_started = 0; - + gs_free_requests(gser->out, &port->read_pool); + gs_free_requests(gser->out, &port->read_queue); + gs_free_requests(gser->in, &port->write_pool); spin_unlock_irqrestore(&port->port_lock, flags); } diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 6f4f8e6..2391c39 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -122,7 +122,7 @@ config USB_EHCI_FSL bool "Support for Freescale on-chip EHCI USB controller" depends on USB_EHCI_HCD && FSL_SOC select USB_EHCI_ROOT_HUB_TT - select USB_FSL_MPH_DR_OF if OF + select USB_FSL_MPH_DR_OF ---help--- Variation of ARC USB block used in some Freescale chips. diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index bce8505..ac9c4d7 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -36,8 +36,6 @@ struct ehci_mxc_priv { static int ehci_mxc_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct device *dev = hcd->self.controller; - struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev); int retval; /* EHCI registers start at offset 0x100 */ @@ -65,12 +63,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd) ehci_reset(ehci); - /* set up the PORTSCx register */ - ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); - - /* is this really needed? */ - msleep(10); - ehci_port_power(ehci, 0); return 0; } @@ -122,7 +114,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; - int irq, ret; + int irq, ret, temp; struct ehci_mxc_priv *priv; struct device *dev = &pdev->dev; @@ -196,6 +188,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) clk_enable(priv->ahbclk); } + /* set up the PORTSCx register */ + ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); + mdelay(10); + /* setup specific usb hw */ ret = mxc_initialize_usb_hw(pdev->id, pdata->flags); if (ret < 0) diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index 931d588..10e1872 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -273,4 +273,4 @@ static struct platform_driver ohci_hcd_jz4740_driver = { }, }; -MODULE_ALIAS("platform:jz4740-ohci"); +MODULE_ALIAS("platfrom:jz4740-ohci"); diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index c9078e4..3756641 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -553,7 +553,6 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, /* needed for power consumption */ struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc; - memset(&info, 0, sizeof(info)); /* directly from the descriptor */ info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); info.product = dev->product_id; diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index dd573ab..70d00e9 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3008,7 +3008,6 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) #else x.sisusb_conactive = 0; #endif - memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); if (copy_to_user((void __user *)arg, &x, sizeof(x))) retval = -EFAULT; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index fcb5206..611a9d2 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -171,9 +171,8 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci) } /* Start sampling ID pin, when plug is removed from MUSB */ - if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE - || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) || - (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) { + if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE + || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); musb->a_wait_bcon = TIMER_DELAY; } @@ -324,8 +323,30 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) return -EIO; } -static void musb_platform_reg_init(struct musb *musb) +int __init musb_platform_init(struct musb *musb, void *board_data) { + + /* + * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE + * and OTG HOST modes, while rev 1.1 and greater require PE7 to + * be low for DEVICE mode and high for HOST mode. We set it high + * here because we are in host mode + */ + + if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { + printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n", + musb->config->gpio_vrsel); + return -ENODEV; + } + gpio_direction_output(musb->config->gpio_vrsel, 0); + + usb_nop_xceiv_register(); + musb->xceiv = otg_get_transceiver(); + if (!musb->xceiv) { + gpio_free(musb->config->gpio_vrsel); + return -ENODEV; + } + if (ANOMALY_05000346) { bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); SSYNC(); @@ -337,8 +358,7 @@ static void musb_platform_reg_init(struct musb *musb) } /* Configure PLL oscillator register */ - bfin_write_USB_PLLOSC_CTRL(0x3080 | - ((480/musb->config->clkin) << 1)); + bfin_write_USB_PLLOSC_CTRL(0x30a8); SSYNC(); bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); @@ -360,33 +380,6 @@ static void musb_platform_reg_init(struct musb *musb) EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); SSYNC(); -} - -int __init musb_platform_init(struct musb *musb, void *board_data) -{ - - /* - * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE - * and OTG HOST modes, while rev 1.1 and greater require PE7 to - * be low for DEVICE mode and high for HOST mode. We set it high - * here because we are in host mode - */ - - if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { - printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n", - musb->config->gpio_vrsel); - return -ENODEV; - } - gpio_direction_output(musb->config->gpio_vrsel, 0); - - usb_nop_xceiv_register(); - musb->xceiv = otg_get_transceiver(); - if (!musb->xceiv) { - gpio_free(musb->config->gpio_vrsel); - return -ENODEV; - } - - musb_platform_reg_init(musb); if (is_host_enabled(musb)) { musb->board_set_vbus = bfin_set_vbus; @@ -401,27 +394,6 @@ int __init musb_platform_init(struct musb *musb, void *board_data) return 0; } -#ifdef CONFIG_PM -void musb_platform_save_context(struct musb *musb, - struct musb_context_registers *musb_context) -{ - if (is_host_active(musb)) - /* - * During hibernate gpio_vrsel will change from high to low - * low which will generate wakeup event resume the system - * immediately. Set it to 0 before hibernate to avoid this - * wakeup event. - */ - gpio_set_value(musb->config->gpio_vrsel, 0); -} - -void musb_platform_restore_context(struct musb *musb, - struct musb_context_registers *musb_context) -{ - musb_platform_reg_init(musb); -} -#endif - int musb_platform_exit(struct musb *musb) { gpio_free(musb->config->gpio_vrsel); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e6669fc..c9f9024 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -552,8 +552,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_SESSREQ) { void __iomem *mbase = musb->mregs; - if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS - && (devctl & MUSB_DEVCTL_BDEVICE)) { + if (devctl & MUSB_DEVCTL_BDEVICE) { DBG(3, "SessReq while on B state\n"); return IRQ_HANDLED; } @@ -1053,11 +1052,6 @@ static void musb_shutdown(struct platform_device *pdev) clk_put(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); - if (!is_otg_enabled(musb) && is_host_enabled(musb)) - usb_remove_hcd(musb_to_hcd(musb)); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); - musb_platform_exit(musb); - /* FIXME power down */ } @@ -2250,6 +2244,13 @@ static int __exit musb_remove(struct platform_device *pdev) */ musb_exit_debugfs(musb); musb_shutdown(pdev); +#ifdef CONFIG_USB_MUSB_HDRC_HCD + if (musb->board_mode == MUSB_HOST) + usb_remove_hcd(musb_to_hcd(musb)); +#endif + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_platform_exit(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_free(musb); iounmap(ctrl_base); @@ -2410,6 +2411,9 @@ static int musb_suspend(struct device *dev) unsigned long flags; struct musb *musb = dev_to_musb(&pdev->dev); + if (!musb->clock) + return 0; + spin_lock_irqsave(&musb->lock, flags); if (is_peripheral_active(musb)) { @@ -2424,12 +2428,10 @@ static int musb_suspend(struct device *dev) musb_save_context(musb); - if (musb->clock) { - if (musb->set_clock) - musb->set_clock(musb->clock, 0); - else - clk_disable(musb->clock); - } + if (musb->set_clock) + musb->set_clock(musb->clock, 0); + else + clk_disable(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); return 0; } @@ -2439,12 +2441,13 @@ static int musb_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct musb *musb = dev_to_musb(&pdev->dev); - if (musb->clock) { - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - else - clk_enable(musb->clock); - } + if (!musb->clock) + return 0; + + if (musb->set_clock) + musb->set_clock(musb->clock, 1); + else + clk_enable(musb->clock); musb_restore_context(musb); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index febaabc..69797e5 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -487,7 +487,7 @@ struct musb_context_registers { }; #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_BLACKFIN) + defined(CONFIG_ARCH_OMAP4) extern void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context); extern void musb_platform_restore_context(struct musb *musb, diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 36cfd06..5d81504 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -644,8 +644,10 @@ static void rxstate(struct musb *musb, struct musb_request *req) */ csr |= MUSB_RXCSR_DMAENAB; + if (!musb_ep->hb_mult && + musb_ep->hw_ep->rx_double_buffered) + csr |= MUSB_RXCSR_AUTOCLEAR; #ifdef USE_MODE1 - csr |= MUSB_RXCSR_AUTOCLEAR; /* csr |= MUSB_RXCSR_DMAMODE; */ /* this special sequence (enabling and then @@ -654,10 +656,6 @@ static void rxstate(struct musb *musb, struct musb_request *req) */ musb_writew(epio, MUSB_RXCSR, csr | MUSB_RXCSR_DMAMODE); -#else - if (!musb_ep->hb_mult && - musb_ep->hw_ep->rx_double_buffered) - csr |= MUSB_RXCSR_AUTOCLEAR; #endif musb_writew(epio, MUSB_RXCSR, csr); @@ -809,7 +807,7 @@ void musb_g_rx(struct musb *musb, u8 epnum) #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) /* Autoclear doesn't clear RxPktRdy for short packets */ - if ((dma->desired_mode == 0 && !hw_ep->rx_double_buffered) + if ((dma->desired_mode == 0) || (dma->actual_len & (musb_ep->packet_sz - 1))) { /* ack the read! */ @@ -820,16 +818,8 @@ void musb_g_rx(struct musb *musb, u8 epnum) /* incomplete, and not short? wait for next IN packet */ if ((request->actual < request->length) && (musb_ep->dma->actual_len - == musb_ep->packet_sz)) { - /* In double buffer case, continue to unload fifo if - * there is Rx packet in FIFO. - **/ - csr = musb_readw(epio, MUSB_RXCSR); - if ((csr & MUSB_RXCSR_RXPKTRDY) && - hw_ep->rx_double_buffered) - goto exit; + == musb_ep->packet_sz)) return; - } #endif musb_g_giveback(musb_ep, request, 0); @@ -837,7 +827,7 @@ void musb_g_rx(struct musb *musb, u8 epnum) if (!request) return; } -exit: + /* Analyze request */ rxstate(musb, to_musb_request(request)); } @@ -926,9 +916,13 @@ static int musb_gadget_enable(struct usb_ep *ep, * likewise high bandwidth periodic tx */ /* Set TXMAXP with the FIFO size of the endpoint - * to disable double buffering mode. + * to disable double buffering mode. Currently, It seems that double + * buffering has problem if musb RTL revision number < 2.0. */ - musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); + if (musb->hwvers < MUSB_HWVERS_2000) + musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); + else + musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; if (musb_readw(regs, MUSB_TXCSR) @@ -964,7 +958,10 @@ static int musb_gadget_enable(struct usb_ep *ep, /* Set RXMAXP with the FIFO size of the endpoint * to disable double buffering mode. */ - musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); + if (musb->hwvers < MUSB_HWVERS_2000) + musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx); + else + musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); /* force shared fifo to OUT-only mode */ if (hw_ep->is_shared_fifo) { @@ -1169,6 +1166,8 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, : DMA_FROM_DEVICE); request->mapped = 0; } + } else if (!req->buf) { + return -ENODATA; } else request->mapped = 0; @@ -1696,10 +1695,8 @@ int __init musb_gadget_setup(struct musb *musb) musb_platform_try_idle(musb, 0); status = device_register(&musb->g.dev); - if (status != 0) { - put_device(&musb->g.dev); + if (status != 0) the_gadget = NULL; - } return status; } diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 5a727c5..2442675 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -633,9 +633,8 @@ static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) return 0; } -static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) +static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) { - return 0; } #endif /* CONFIG_BLACKFIN */ diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 563114d..6f771af 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -158,8 +158,6 @@ static int dma_channel_program(struct dma_channel *channel, dma_addr_t dma_addr, u32 len) { struct musb_dma_channel *musb_channel = channel->private_data; - struct musb_dma_controller *controller = musb_channel->controller; - struct musb *musb = controller->private_data; DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n", musb_channel->epnum, @@ -169,18 +167,6 @@ static int dma_channel_program(struct dma_channel *channel, BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || channel->status == MUSB_DMA_STATUS_BUSY); - /* - * The DMA engine in RTL1.8 and above cannot handle - * DMA addresses that are not aligned to a 4 byte boundary. - * It ends up masking the last two bits of the address - * programmed in DMA_ADDR. - * - * Fail such DMA transfers, so that the backup PIO mode - * can carry out the transfer - */ - if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4)) - return false; - channel->actual_len = 0; musb_channel->start_addr = dma_addr; musb_channel->len = len; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 76f8b35..89a9a58 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -794,8 +794,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, - { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 263f625..7dfe02f 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1100,10 +1100,3 @@ #define FTDI_SCIENCESCOPE_LOGBOOKML_PID 0xFF18 #define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID 0xFF1C #define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D - -/* - * Milkymist One JTAG/Serial - */ -#define QIHARDWARE_VID 0x20B7 -#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 - diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ef2977d..2297fb1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -518,7 +518,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, + { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index d126819..2054b1e 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -331,7 +331,10 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, iu->iu_id = IU_ID_COMMAND; iu->tag = cpu_to_be16(stream_id); - iu->prio_attr = UAS_SIMPLE_TAG; + if (sdev->ordered_tags && (cmnd->request->cmd_flags & REQ_HARDBARRIER)) + iu->prio_attr = UAS_ORDERED_TAG; + else + iu->prio_attr = UAS_SIMPLE_TAG; iu->len = len; int_to_scsilun(sdev->lun, &iu->lun); memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c index e45e673..436e4f7 100644 --- a/drivers/uwb/allocator.c +++ b/drivers/uwb/allocator.c @@ -326,8 +326,7 @@ int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *availab int bit_index; ai = kzalloc(sizeof(struct uwb_rsv_alloc_info), GFP_KERNEL); - if (!ai) - return UWB_RSV_ALLOC_NOT_FOUND; + ai->min_mas = rsv->min_mas; ai->max_mas = rsv->max_mas; ai->max_interval = rsv->max_interval; diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 734c650..3ec2460 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -502,10 +502,8 @@ static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct adp8860_bl *data = dev_get_drvdata(dev); - int ret = strict_strtoul(buf, 10, &data->cached_daylight_max); - if (ret) - return ret; + strict_strtoul(buf, 10, &data->cached_daylight_max); return adp8860_store(dev, buf, count, ADP8860_BLMX1); } static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show, @@ -616,7 +614,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, if (val == 0) { /* Enable automatic ambient light sensing */ adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); - } else if ((val > 0) && (val <= 3)) { + } else if ((val > 0) && (val < 6)) { /* Disable automatic ambient light sensing */ adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); @@ -624,7 +622,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, mutex_lock(&data->lock); adp8860_read(data->client, ADP8860_CFGR, ®_val); reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); - reg_val |= (val - 1) << CFGR_BLV_SHIFT; + reg_val |= val << CFGR_BLV_SHIFT; adp8860_write(data->client, ADP8860_CFGR, reg_val); mutex_unlock(&data->lock); } diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index c67801e..9093ef0 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -78,7 +78,7 @@ static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) const u16 slpin = 0x10; const u16 disoff = 0x28; - if (power <= FB_BLANK_NORMAL) { + if (power) { if (priv->lcd_on) return 0; diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index 5d3cf33..abc43a0 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c @@ -129,7 +129,7 @@ static int lms283gf05_power_set(struct lcd_device *ld, int power) struct spi_device *spi = st->spi; struct lms283gf05_pdata *pdata = spi->dev.platform_data; - if (power <= FB_BLANK_NORMAL) { + if (power) { if (pdata) lms283gf05_reset(pdata->reset_gpio, pdata->reset_inverted); diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 1485f73..9fb533f 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -335,24 +335,6 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { }, .driver_data = (void *)&nvidia_chipset_data, }, - { - .callback = mbp_dmi_match, - .ident = "MacBookAir 3,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"), - }, - .driver_data = (void *)&nvidia_chipset_data, - }, - { - .callback = mbp_dmi_match, - .ident = "MacBookAir 3,2", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"), - }, - .driver_data = (void *)&nvidia_chipset_data, - }, { } }; diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 21866ec..5504435 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -25,7 +25,6 @@ struct pwm_bl_data { struct pwm_device *pwm; struct device *dev; unsigned int period; - unsigned int lth_brightness; int (*notify)(struct device *, int brightness); }; @@ -49,9 +48,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); } else { - brightness = pb->lth_brightness + - (brightness * (pb->period - pb->lth_brightness) / max); - pwm_config(pb->pwm, brightness, pb->period); + pwm_config(pb->pwm, brightness * pb->period / max, pb->period); pwm_enable(pb->pwm); } return 0; @@ -95,8 +92,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->period = data->pwm_period_ns; pb->notify = data->notify; - pb->lth_brightness = data->lth_brightness * - (data->pwm_period_ns / data->max_brightness); pb->dev = &pdev->dev; pb->pwm = pwm_request(data->pwm_id, "backlight"); diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c index 5927db0..a3128c9 100644 --- a/drivers/video/backlight/s6e63m0.c +++ b/drivers/video/backlight/s6e63m0.c @@ -729,10 +729,10 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev, return strlen(buf); } -static DEVICE_ATTR(gamma_table, 0444, +static DEVICE_ATTR(gamma_table, 0644, s6e63m0_sysfs_show_gamma_table, NULL); -static int __devinit s6e63m0_probe(struct spi_device *spi) +static int __init s6e63m0_probe(struct spi_device *spi) { int ret = 0; struct s6e63m0 *lcd = NULL; @@ -829,9 +829,6 @@ static int __devexit s6e63m0_remove(struct spi_device *spi) struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); s6e63m0_power(lcd, FB_BLANK_POWERDOWN); - device_remove_file(&spi->dev, &dev_attr_gamma_table); - device_remove_file(&spi->dev, &dev_attr_gamma_mode); - backlight_device_unregister(lcd->bd); lcd_device_unregister(lcd->ld); kfree(lcd); diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c index 2fd7e52..fed2a72 100644 --- a/drivers/video/omap2/vram.c +++ b/drivers/video/omap2/vram.c @@ -554,15 +554,9 @@ void __init omap_vram_reserve_sdram_memblock(void) size = PAGE_ALIGN(size); if (paddr) { - if (paddr & ~PAGE_MASK) { - pr_err("VRAM start address 0x%08x not page aligned\n", - paddr); - return; - } - - if (!memblock_is_region_memory(paddr, size)) { - pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n", - paddr, paddr + size - 1); + if ((paddr & ~PAGE_MASK) || + !memblock_is_region_memory(paddr, size)) { + pr_err("Illegal SDRAM region for VRAM\n"); return; } @@ -576,12 +570,9 @@ void __init omap_vram_reserve_sdram_memblock(void) return; } } else { - paddr = memblock_alloc(size, PAGE_SIZE); + paddr = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_REAL_LIMIT); } - memblock_free(paddr, size); - memblock_remove(paddr, size); - omap_vram_add_region(paddr, size); pr_info("Reserving %u bytes SDRAM for VRAM\n", size); diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 167400e..a0e22ac 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c @@ -94,6 +94,7 @@ static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan, strcpy(chan->adapter.name, name); chan->adapter.owner = THIS_MODULE; + chan->adapter.id = I2C_HW_B_RIVA; chan->adapter.class = i2c_class; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = &chan->par->pdev->dev; diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index d7df103..55b3077 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -1071,10 +1071,6 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) if (!hdmi->info) goto out; - hdmi->monspec.modedb_len = 0; - fb_destroy_modedb(hdmi->monspec.modedb); - hdmi->monspec.modedb = NULL; - acquire_console_sem(); /* HDMI disconnect */ @@ -1082,6 +1078,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) release_console_sem(); pm_runtime_put(hdmi->dev); + fb_destroy_modedb(hdmi->monspec.modedb); } out: diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 9b13647..5096373 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -115,16 +115,15 @@ static const struct fb_videomode default_720p = { .xres = 1280, .yres = 720, - .left_margin = 220, - .right_margin = 110, - .hsync_len = 40, + .left_margin = 200, + .right_margin = 88, + .hsync_len = 48, .upper_margin = 20, .lower_margin = 5, .vsync_len = 5, .pixclock = 13468, - .refresh = 60, .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, }; @@ -1198,7 +1197,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) const struct fb_videomode *mode = cfg->lcd_cfg; unsigned long max_size = 0; int k; - int num_cfg; ch->info = framebuffer_alloc(0, &pdev->dev); if (!ch->info) { @@ -1234,14 +1232,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) info->fix = sh_mobile_lcdc_fix; info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; - if (!mode) { + if (!mode) mode = &default_720p; - num_cfg = 1; - } else { - num_cfg = ch->cfg.num_cfg; - } - - fb_videomode_to_modelist(mode, num_cfg, &info->modelist); fb_videomode_to_var(var, mode); /* Default Y virtual resolution is 2x panel size */ @@ -1289,6 +1281,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) for (i = 0; i < j; i++) { struct sh_mobile_lcdc_chan *ch = priv->ch + i; + const struct fb_videomode *mode = ch->cfg.lcd_cfg; + + if (!mode) + mode = &default_720p; info = ch->info; @@ -1301,6 +1297,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) } } + fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist); error = register_framebuffer(info); if (error < 0) goto err1; diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 3dde12b..b52f8e4 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -4181,9 +4181,6 @@ static void __devinit sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize, unsigned int min) { - if (*mapsize < (min << 20)) - return; - ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize)); if(!ivideo->video_vbase) { @@ -4517,7 +4514,7 @@ sisfb_post_sis300(struct pci_dev *pdev) } else { #endif /* Need to map max FB size for finding out about RAM size */ - mapsize = ivideo->video_size; + mapsize = 64 << 20; sisfb_post_map_vram(ivideo, &mapsize, 4); if(ivideo->video_vbase) { @@ -4683,7 +4680,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) orSISIDXREG(SISSR, 0x20, (0x80 | 0x04)); /* Need to map max FB size for finding out about RAM size */ - mapsize = ivideo->video_size; + mapsize = 256 << 20; sisfb_post_map_vram(ivideo, &mapsize, 32); if(!ivideo->video_vbase) { @@ -5939,7 +5936,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } ivideo->video_base = pci_resource_start(pdev, 0); - ivideo->video_size = pci_resource_len(pdev, 0); ivideo->mmio_base = pci_resource_start(pdev, 1); ivideo->mmio_size = pci_resource_len(pdev, 1); ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30; diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 321a0c8..97612f5 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -1299,6 +1299,9 @@ static void restore_cpu_virqs(unsigned int cpu) evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_virq_info(evtchn, virq); bind_evtchn_to_cpu(evtchn, cpu); + + /* Ready for use. */ + unmask_evtchn(evtchn); } } @@ -1324,6 +1327,10 @@ static void restore_cpu_ipis(unsigned int cpu) evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_ipi_info(evtchn, ipi); bind_evtchn_to_cpu(evtchn, cpu); + + /* Ready for use. */ + unmask_evtchn(evtchn); + } } @@ -1383,7 +1390,6 @@ void xen_poll_irq(int irq) void xen_irq_resume(void) { unsigned int cpu, irq, evtchn; - struct irq_desc *desc; init_evtchn_cpu_bindings(); @@ -1402,23 +1408,6 @@ void xen_irq_resume(void) restore_cpu_virqs(cpu); restore_cpu_ipis(cpu); } - - /* - * Unmask any IRQF_NO_SUSPEND IRQs which are enabled. These - * are not handled by the IRQ core. - */ - for_each_irq_desc(irq, desc) { - if (!desc->action || !(desc->action->flags & IRQF_NO_SUSPEND)) - continue; - if (desc->status & IRQ_DISABLED) - continue; - - evtchn = evtchn_from_irq(irq); - if (evtchn == -1) - continue; - - unmask_evtchn(evtchn); - } } static struct irq_chip xen_dynamic_chip __read_mostly = { diff --git a/fs/bio.c b/fs/bio.c index 4bd454f..8abb2df 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -370,9 +370,6 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) { struct bio *bio; - if (nr_iovecs > UIO_MAXIOV) - return NULL; - bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec), gfp_mask); if (unlikely(!bio)) @@ -700,12 +697,8 @@ static void bio_free_map_data(struct bio_map_data *bmd) static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count, gfp_t gfp_mask) { - struct bio_map_data *bmd; + struct bio_map_data *bmd = kmalloc(sizeof(*bmd), gfp_mask); - if (iov_count > UIO_MAXIOV) - return NULL; - - bmd = kmalloc(sizeof(*bmd), gfp_mask); if (!bmd) return NULL; @@ -834,12 +827,6 @@ struct bio *bio_copy_user_iov(struct request_queue *q, end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT; start = uaddr >> PAGE_SHIFT; - /* - * Overflow, abort - */ - if (end < start) - return ERR_PTR(-EINVAL); - nr_pages += end - start; len += iov[i].iov_len; } @@ -968,12 +955,6 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned long start = uaddr >> PAGE_SHIFT; - /* - * Overflow, abort - */ - if (end < start) - return ERR_PTR(-EINVAL); - nr_pages += end - start; /* * buffer must be aligned to at least hardsector size for now @@ -1001,7 +982,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, unsigned long start = uaddr >> PAGE_SHIFT; const int local_nr_pages = end - start; const int page_limit = cur_page + local_nr_pages; - + ret = get_user_pages_fast(uaddr, local_nr_pages, write_to_vm, &pages[cur_page]); if (ret < local_nr_pages) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ef3a55b..39869c3 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2177,6 +2177,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) setattr_copy(inode, attrs); mark_inode_dirty(inode); + return 0; cifs_setattr_exit: kfree(full_path); diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 0c98672..2fa22f2 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -38,10 +38,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) struct cifs_sb_info *cifs_sb; #ifdef CONFIG_CIFS_POSIX struct cifsFileInfo *pSMBFile = filep->private_data; - struct cifsTconInfo *tcon; + struct cifsTconInfo *tcon = tlink_tcon(pSMBFile->tlink); __u64 ExtAttrBits = 0; __u64 ExtAttrMask = 0; - __u64 caps; + __u64 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); #endif /* CONFIG_CIFS_POSIX */ xid = GetXid(); @@ -62,10 +62,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) break; #ifdef CONFIG_CIFS_POSIX case FS_IOC_GETFLAGS: - if (pSMBFile == NULL) - break; - tcon = tlink_tcon(pSMBFile->tlink); - caps = le64_to_cpu(tcon->fsUnixInfo.Capability); if (CIFS_UNIX_EXTATTR_CAP & caps) { rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, &ExtAttrBits, &ExtAttrMask); @@ -77,10 +73,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) break; case FS_IOC_SETFLAGS: - if (pSMBFile == NULL) - break; - tcon = tlink_tcon(pSMBFile->tlink); - caps = le64_to_cpu(tcon->fsUnixInfo.Capability); if (CIFS_UNIX_EXTATTR_CAP & caps) { if (get_user(ExtAttrBits, (int __user *)arg)) { rc = -EFAULT; diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 5ab3839..06d5827 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c @@ -138,8 +138,10 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, struct gfs2_inum_host *inum) { struct gfs2_sbd *sdp = sb->s_fs_info; + struct gfs2_holder i_gh; struct inode *inode; struct dentry *dentry; + int error; inode = gfs2_ilookup(sb, inum->no_addr); if (inode) { @@ -150,16 +152,52 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, goto out_inode; } - inode = gfs2_lookup_by_inum(sdp, inum->no_addr, &inum->no_formal_ino, - GFS2_BLKST_DINODE); - if (IS_ERR(inode)) - return ERR_CAST(inode); + error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops, + LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return ERR_PTR(error); + + error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE); + if (error) + goto fail; + + inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0); + if (IS_ERR(inode)) { + error = PTR_ERR(inode); + goto fail; + } + + error = gfs2_inode_refresh(GFS2_I(inode)); + if (error) { + iput(inode); + goto fail; + } + + /* Pick up the works we bypass in gfs2_inode_lookup */ + if (inode->i_state & I_NEW) + gfs2_set_iop(inode); + + if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { + iput(inode); + goto fail; + } + + error = -EIO; + if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) { + iput(inode); + goto fail; + } + + gfs2_glock_dq_uninit(&i_gh); out_inode: dentry = d_obtain_alias(inode); if (!IS_ERR(dentry)) dentry->d_op = &gfs2_dops; return dentry; +fail: + gfs2_glock_dq_uninit(&i_gh); + return ERR_PTR(error); } static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f92c177..8777885 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -686,20 +686,21 @@ static void delete_work_func(struct work_struct *work) { struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete); struct gfs2_sbd *sdp = gl->gl_sbd; - struct gfs2_inode *ip; + struct gfs2_inode *ip = NULL; struct inode *inode; - u64 no_addr = gl->gl_name.ln_number; - - ip = gl->gl_object; - /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ + u64 no_addr = 0; + spin_lock(&gl->gl_spin); + ip = (struct gfs2_inode *)gl->gl_object; if (ip) + no_addr = ip->i_no_addr; + spin_unlock(&gl->gl_spin); + if (ip) { inode = gfs2_ilookup(sdp->sd_vfs, no_addr); - else - inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED); - if (inode && !IS_ERR(inode)) { - d_prune_aliases(inode); - iput(inode); + if (inode) { + d_prune_aliases(inode); + iput(inode); + } } gfs2_glock_put(gl); } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index e1213f7..06370f8 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -73,6 +73,49 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); } +struct gfs2_skip_data { + u64 no_addr; + int skipped; +}; + +static int iget_skip_test(struct inode *inode, void *opaque) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_skip_data *data = opaque; + + if (ip->i_no_addr == data->no_addr) { + if (inode->i_state & (I_FREEING|I_WILL_FREE)){ + data->skipped = 1; + return 0; + } + return 1; + } + return 0; +} + +static int iget_skip_set(struct inode *inode, void *opaque) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_skip_data *data = opaque; + + if (data->skipped) + return 1; + inode->i_ino = (unsigned long)(data->no_addr); + ip->i_no_addr = data->no_addr; + return 0; +} + +static struct inode *gfs2_iget_skip(struct super_block *sb, + u64 no_addr) +{ + struct gfs2_skip_data data; + unsigned long hash = (unsigned long)no_addr; + + data.no_addr = no_addr; + data.skipped = 0; + return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data); +} + /** * GFS2 lookup code fills in vfs inode contents based on info obtained * from directory entry inside gfs2_inode_lookup(). This has caused issues @@ -200,54 +243,93 @@ fail: return ERR_PTR(error); } -struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, - u64 *no_formal_ino, unsigned int blktype) +/** + * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation + * and try to reclaim it by doing iput. + * + * This function assumes no rgrp locks are currently held. + * + * @sb: The super block + * no_addr: The inode number + * + */ + +void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) { - struct super_block *sb = sdp->sd_vfs; - struct gfs2_holder i_gh; - struct inode *inode; + struct gfs2_sbd *sdp; + struct gfs2_inode *ip; + struct gfs2_glock *io_gl = NULL; int error; + struct gfs2_holder gh; + struct inode *inode; - error = gfs2_glock_nq_num(sdp, no_addr, &gfs2_inode_glops, - LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return ERR_PTR(error); + inode = gfs2_iget_skip(sb, no_addr); - error = gfs2_check_blk_type(sdp, no_addr, blktype); - if (error) - goto fail; + if (!inode) + return; - inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0); - if (IS_ERR(inode)) + /* If it's not a new inode, someone's using it, so leave it alone. */ + if (!(inode->i_state & I_NEW)) { + iput(inode); + return; + } + + ip = GFS2_I(inode); + sdp = GFS2_SB(inode); + ip->i_no_formal_ino = -1; + + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); + if (unlikely(error)) goto fail; + ip->i_gl->gl_object = ip; - error = gfs2_inode_refresh(GFS2_I(inode)); - if (error) - goto fail_iput; + error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); + if (unlikely(error)) + goto fail_put; - /* Pick up the works we bypass in gfs2_inode_lookup */ - if (inode->i_state & I_NEW) - gfs2_set_iop(inode); + set_bit(GIF_INVALID, &ip->i_flags); + error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, + &ip->i_iopen_gh); + if (unlikely(error)) + goto fail_iopen; - /* Two extra checks for NFS only */ - if (no_formal_ino) { - error = -ESTALE; - if (GFS2_I(inode)->i_no_formal_ino != *no_formal_ino) - goto fail_iput; + ip->i_iopen_gh.gh_gl->gl_object = ip; + gfs2_glock_put(io_gl); + io_gl = NULL; - error = -EIO; - if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) - goto fail_iput; + inode->i_mode = DT2IF(DT_UNKNOWN); - error = 0; - } + /* + * We must read the inode in order to work out its type in + * this case. Note that this doesn't happen often as we normally + * know the type beforehand. This code path only occurs during + * unlinked inode recovery (where it is safe to do this glock, + * which is not true in the general case). + */ + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, + &gh); + if (unlikely(error)) + goto fail_glock; -fail: - gfs2_glock_dq_uninit(&i_gh); - return error ? ERR_PTR(error) : inode; -fail_iput: + /* Inode is now uptodate */ + gfs2_glock_dq_uninit(&gh); + gfs2_set_iop(inode); + + /* The iput will cause it to be deleted. */ iput(inode); - goto fail; + return; + +fail_glock: + gfs2_glock_dq(&ip->i_iopen_gh); +fail_iopen: + if (io_gl) + gfs2_glock_put(io_gl); +fail_put: + ip->i_gl->gl_object = NULL; + gfs2_glock_put(ip->i_gl); +fail: + iget_failed(inode); + return; } static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index d8499fa..6720d7d 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -99,9 +99,7 @@ err: extern void gfs2_set_iop(struct inode *inode); extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, u64 no_addr, u64 no_formal_ino); -extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, - u64 *no_formal_ino, - unsigned int blktype); +extern void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr); extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); extern int gfs2_inode_refresh(struct gfs2_inode *ip); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 33c8407..bef3ab6 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -963,18 +963,17 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) * The inode, if one has been found, in inode. */ -static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) +static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, + u64 skip) { u32 goal = 0, block; u64 no_addr; struct gfs2_sbd *sdp = rgd->rd_sbd; unsigned int n; - struct gfs2_glock *gl; - struct gfs2_inode *ip; - int error; - int found = 0; - while (goal < rgd->rd_data) { + for(;;) { + if (goal >= rgd->rd_data) + break; down_write(&sdp->sd_log_flush_lock); n = 1; block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, @@ -991,32 +990,11 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip if (no_addr == skip) continue; *last_unlinked = no_addr; - - error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &gl); - if (error) - continue; - - /* If the inode is already in cache, we can ignore it here - * because the existing inode disposal code will deal with - * it when all refs have gone away. Accessing gl_object like - * this is not safe in general. Here it is ok because we do - * not dereference the pointer, and we only need an approx - * answer to whether it is NULL or not. - */ - ip = gl->gl_object; - - if (ip || queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) - gfs2_glock_put(gl); - else - found++; - - /* Limit reclaim to sensible number of tasks */ - if (found > 2*NR_CPUS) - return; + return no_addr; } rgd->rd_flags &= ~GFS2_RDF_CHECK; - return; + return 0; } /** @@ -1097,9 +1075,11 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) * Try to acquire rgrp in way which avoids contending with others. * * Returns: errno + * unlinked: the block address of an unlinked block to be reclaimed */ -static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) +static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, + u64 *last_unlinked) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_rgrpd *rgd, *begin = NULL; @@ -1109,6 +1089,7 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) int loops = 0; int error, rg_locked; + *unlinked = 0; rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); while (rgd) { @@ -1125,10 +1106,17 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) case 0: if (try_rgrp_fit(rgd, al)) goto out; - if (rgd->rd_flags & GFS2_RDF_CHECK) - try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); + /* If the rg came in already locked, there's no + way we can recover from a failed try_rgrp_unlink + because that would require an iput which can only + happen after the rgrp is unlocked. */ + if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) + *unlinked = try_rgrp_unlink(rgd, last_unlinked, + ip->i_no_addr); if (!rg_locked) gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (*unlinked) + return -EAGAIN; /* fall through */ case GLR_TRYFAILED: rgd = recent_rgrp_next(rgd); @@ -1157,10 +1145,13 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) case 0: if (try_rgrp_fit(rgd, al)) goto out; - if (rgd->rd_flags & GFS2_RDF_CHECK) - try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); + if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) + *unlinked = try_rgrp_unlink(rgd, last_unlinked, + ip->i_no_addr); if (!rg_locked) gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (*unlinked) + return -EAGAIN; break; case GLR_TRYFAILED: @@ -1213,12 +1204,12 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_alloc *al = ip->i_alloc; int error = 0; - u64 last_unlinked = NO_BLOCK; - int tries = 0; + u64 last_unlinked = NO_BLOCK, unlinked; if (gfs2_assert_warn(sdp, al->al_requested)) return -EINVAL; +try_again: if (hold_rindex) { /* We need to hold the rindex unless the inode we're using is the rindex itself, in which case it's already held. */ @@ -1227,23 +1218,31 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ error = gfs2_ri_update_special(ip); - if (error) - return error; } - do { - error = get_local_rgrp(ip, &last_unlinked); - /* If there is no space, flushing the log may release some */ - if (error) - gfs2_log_flush(sdp, NULL); - } while (error && tries++ < 3); + if (error) + return error; + /* Find an rgrp suitable for allocation. If it encounters any unlinked + dinodes along the way, error will equal -EAGAIN and unlinked will + contains it block address. We then need to look up that inode and + try to free it, and try the allocation again. */ + error = get_local_rgrp(ip, &unlinked, &last_unlinked); if (error) { if (hold_rindex && ip != GFS2_I(sdp->sd_rindex)) gfs2_glock_dq_uninit(&al->al_ri_gh); - return error; - } + if (error != -EAGAIN) + return error; + gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked); + /* regardless of whether or not gfs2_process_unlinked_inode + was successful, we don't want to repeat it again. */ + last_unlinked = unlinked; + gfs2_log_flush(sdp, NULL); + error = 0; + + goto try_again; + } /* no error, so we have the rgrp set in the inode's allocation. */ al->al_file = file; al->al_line = line; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index a5fe681..d6cfac1 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -932,7 +932,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { *user = current_user(); if (user_shm_lock(size, *user)) { - printk_once(KERN_WARNING "Using mlock ulimits for SHM_HUGETLB is deprecated\n"); + WARN_ONCE(1, + "Using mlock ulimits for SHM_HUGETLB deprecated\n"); } else { *user = NULL; return ERR_PTR(-EPERM); diff --git a/fs/ioprio.c b/fs/ioprio.c index 2f7d05c..748cfb9 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -111,14 +111,12 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: - rcu_read_lock(); if (!who) p = current; else p = find_task_by_vpid(who); if (p) ret = set_task_ioprio(p, ioprio); - rcu_read_unlock(); break; case IOPRIO_WHO_PGRP: if (!who) @@ -141,12 +139,7 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) break; do_each_thread(g, p) { - int match; - - rcu_read_lock(); - match = __task_cred(p)->uid == who; - rcu_read_unlock(); - if (!match) + if (__task_cred(p)->uid != who) continue; ret = set_task_ioprio(p, ioprio); if (ret) @@ -207,14 +200,12 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: - rcu_read_lock(); if (!who) p = current; else p = find_task_by_vpid(who); if (p) ret = get_task_ioprio(p); - rcu_read_unlock(); break; case IOPRIO_WHO_PGRP: if (!who) @@ -241,12 +232,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) break; do_each_thread(g, p) { - int match; - - rcu_read_lock(); - match = __task_cred(p)->uid == user->uid; - rcu_read_unlock(); - if (!match) + if (__task_cred(p)->uid != user->uid) continue; tmpio = get_task_ioprio(p); if (tmpio < 0) diff --git a/fs/locks.c b/fs/locks.c index 0e62dd3..65765cb 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1504,8 +1504,9 @@ static int do_fcntl_delete_lease(struct file *filp) static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) { - struct file_lock *fl, *ret; + struct file_lock *fl; struct fasync_struct *new; + struct inode *inode = filp->f_path.dentry->d_inode; int error; fl = lease_alloc(filp, arg); @@ -1517,16 +1518,13 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) locks_free_lock(fl); return -ENOMEM; } - ret = fl; lock_flocks(); - error = __vfs_setlease(filp, arg, &ret); + error = __vfs_setlease(filp, arg, &fl); if (error) { unlock_flocks(); locks_free_lock(fl); goto out_free_fasync; } - if (ret != fl) - locks_free_lock(fl); /* * fasync_insert_entry() returns the old entry if any. @@ -1534,10 +1532,17 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) * inserted it into the fasync list. Clear new so that * we don't release it here. */ - if (!fasync_insert_entry(fd, filp, &ret->fl_fasync, new)) + if (!fasync_insert_entry(fd, filp, &fl->fl_fasync, new)) new = NULL; - error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); + if (error < 0) { + /* remove lease just inserted by setlease */ + fl->fl_type = F_UNLCK | F_INPROGRESS; + fl->fl_break_time = jiffies - 10; + time_out_leases(inode); + } else { + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); + } unlock_flocks(); out_free_fasync: diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ad2bfa6..f1e5ec6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -673,17 +673,16 @@ static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) spin_unlock(&clp->cl_lock); } -static int nfsd4_register_conn(struct nfsd4_conn *conn) +static void nfsd4_register_conn(struct nfsd4_conn *conn) { conn->cn_xpt_user.callback = nfsd4_conn_lost; - return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); + register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); } static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) { struct nfsd4_conn *conn; u32 flags = NFS4_CDFC4_FORE; - int ret; if (ses->se_flags & SESSION4_BACK_CHAN) flags |= NFS4_CDFC4_BACK; @@ -691,10 +690,7 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) if (!conn) return nfserr_jukebox; nfsd4_hash_conn(conn, ses); - ret = nfsd4_register_conn(conn); - if (ret) - /* oops; xprt is already down: */ - nfsd4_conn_lost(&conn->cn_xpt_user); + nfsd4_register_conn(conn); return nfs_ok; } @@ -1648,7 +1644,6 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi { struct nfs4_client *clp = ses->se_client; struct nfsd4_conn *c; - int ret; spin_lock(&clp->cl_lock); c = __nfsd4_find_conn(new->cn_xprt, ses); @@ -1659,10 +1654,7 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi } __nfsd4_hash_conn(new, ses); spin_unlock(&clp->cl_lock); - ret = nfsd4_register_conn(new); - if (ret) - /* oops; xprt is already down: */ - nfsd4_conn_lost(&new->cn_xpt_user); + nfsd4_register_conn(new); return; } diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 1efea36..d840821 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -159,9 +159,7 @@ struct ocfs2_lock_res { char l_name[OCFS2_LOCK_ID_MAX_LEN]; unsigned int l_ro_holders; unsigned int l_ex_holders; - char l_level; - char l_requested; - char l_blocking; + unsigned char l_level; /* Data packed - type enum ocfs2_lock_type */ unsigned char l_type; @@ -171,6 +169,8 @@ struct ocfs2_lock_res { unsigned char l_action; /* Data packed - enum type ocfs2_unlock_action */ unsigned char l_unlock_action; + unsigned char l_requested; + unsigned char l_blocking; unsigned int l_pending_gen; spinlock_t l_lock; diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 911e61f..ddb1f41 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -418,7 +418,7 @@ out_no_root: static struct dentry *openprom_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return mount_single(fs_type, flags, data, openprom_fill_super); + return mount_single(fs_type, flags, data, openprom_fill_super) } static struct file_system_type openprom_fs_type = { diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 7d287af..c9af48f 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1111,12 +1111,11 @@ xfs_vm_writepage( uptodate = 0; /* - * set_page_dirty dirties all buffers in a page, independent - * of their state. The dirty state however is entirely - * meaningless for holes (!mapped && uptodate), so skip - * buffers covering holes here. + * A hole may still be marked uptodate because discard_buffer + * leaves the flag set. */ if (!buffer_mapped(bh) && buffer_uptodate(bh)) { + ASSERT(!buffer_dirty(bh)); imap_valid = 0; continue; } diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index aa1d353..63fd2c0 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1781,6 +1781,7 @@ xfs_buf_delwri_split( INIT_LIST_HEAD(list); spin_lock(dwlk); list_for_each_entry_safe(bp, n, dwq, b_list) { + trace_xfs_buf_delwri_split(bp, _RET_IP_); ASSERT(bp->b_flags & XBF_DELWRI); if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { @@ -1794,7 +1795,6 @@ xfs_buf_delwri_split( _XBF_RUN_QUEUES); bp->b_flags |= XBF_WRITE; list_move_tail(&bp->b_list, list); - trace_xfs_buf_delwri_split(bp, _RET_IP_); } else skipped++; } diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index ad442d9..2ea238f 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -416,7 +416,7 @@ xfs_attrlist_by_handle( if (IS_ERR(dentry)) return PTR_ERR(dentry); - kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL); + kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); if (!kbuf) goto out_dput; diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 94d5fd6..96107ef 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -762,8 +762,7 @@ xfs_setup_inode( inode->i_state = I_NEW; inode_sb_list_add(inode); - /* make the inode look hashed for the writeback code */ - hlist_add_fake(&inode->i_hash); + insert_inode_hash(inode); inode->i_mode = ip->i_d.di_mode; inode->i_nlink = ip->i_d.di_nlink; diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 064f964..9f3a78f 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -353,6 +353,9 @@ xfs_parseargs( mp->m_qflags &= ~XFS_OQUOTA_ENFD; } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { mp->m_flags |= XFS_MOUNT_DELAYLOG; + cmn_err(CE_WARN, + "Enabling EXPERIMENTAL delayed logging feature " + "- use at your own risk.\n"); } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { mp->m_flags &= ~XFS_MOUNT_DELAYLOG; } else if (!strcmp(this_char, "ihashsize")) { diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index afb0d7c..37d3325 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -853,7 +853,6 @@ restart: if (trylock) { if (!mutex_trylock(&pag->pag_ici_reclaim_lock)) { skipped++; - xfs_perag_put(pag); continue; } first_index = pag->pag_ici_reclaim_cursor; diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 9124425..9b715dc 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -744,15 +744,9 @@ xfs_filestream_new_ag( * If the file's parent directory is known, take its iolock in exclusive * mode to prevent two sibling files from racing each other to migrate * themselves and their parent to different AGs. - * - * Note that we lock the parent directory iolock inside the child - * iolock here. That's fine as we never hold both parent and child - * iolock in any other place. This is different from the ilock, - * which requires locking of the child after the parent for namespace - * operations. */ if (pip) - xfs_ilock(pip, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT); + xfs_ilock(pip, XFS_IOLOCK_EXCL); /* * A new AG needs to be found for the file. If the file's parent diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 19e9dfa..b1498ab 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -275,7 +275,6 @@ xfs_free_perag( pag = radix_tree_delete(&mp->m_perag_tree, agno); spin_unlock(&mp->m_perag_lock); ASSERT(pag); - ASSERT(atomic_read(&pag->pag_ref) == 0); call_rcu(&pag->rcu_head, __xfs_free_perag); } } diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 9bb6eda..e0e64b1 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -346,17 +346,8 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid, #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta) #define xfs_trans_apply_dquot_deltas(tp) #define xfs_trans_unreserve_and_mod_dquots(tp) -static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp, - struct xfs_inode *ip, long nblks, long ninos, uint flags) -{ - return 0; -} -static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp, - struct xfs_mount *mp, struct xfs_dquot *udqp, - struct xfs_dquot *gdqp, long nblks, long nions, uint flags) -{ - return 0; -} +#define xfs_trans_reserve_quota_nblks(tp, ip, nblks, ninos, flags) (0) +#define xfs_trans_reserve_quota_bydquots(tp, mp, u, g, nb, ni, fl) (0) #define xfs_qm_vop_create_dqattach(tp, ip, u, g) #define xfs_qm_vop_rename_dqattach(it) (0) #define xfs_qm_vop_chown(tp, ip, old, new) (NULL) @@ -366,14 +357,11 @@ static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp, #define xfs_qm_dqdetach(ip) #define xfs_qm_dqrele(d) #define xfs_qm_statvfs(ip, s) -static inline int xfs_qm_sync(struct xfs_mount *mp, int flags) -{ - return 0; -} +#define xfs_qm_sync(mp, fl) (0) #define xfs_qm_newmount(mp, a, b) (0) #define xfs_qm_mount_quotas(mp) #define xfs_qm_unmount(mp) -#define xfs_qm_unmount_quotas(mp) +#define xfs_qm_unmount_quotas(mp) (0) #endif /* CONFIG_XFS_QUOTA */ #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \ diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index beafc15..5afa5b5 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -432,10 +432,6 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); * together with the @destroy function, * enables driver-specific objects derived from a ttm_buffer_object. * On successful return, the object kref and list_kref are set to 1. - * If a failure occurs, the function will call the @destroy function, or - * kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is - * illegal and will likely cause memory corruption. - * * Returns * -ENOMEM: Out of memory. * -EINVAL: Invalid placement flags. diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 8e0c848..d01b4dd 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -206,84 +206,14 @@ struct ttm_tt { struct ttm_mem_type_manager; struct ttm_mem_type_manager_func { - /** - * struct ttm_mem_type_manager member init - * - * @man: Pointer to a memory type manager. - * @p_size: Implementation dependent, but typically the size of the - * range to be managed in pages. - * - * Called to initialize a private range manager. The function is - * expected to initialize the man::priv member. - * Returns 0 on success, negative error code on failure. - */ int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size); - - /** - * struct ttm_mem_type_manager member takedown - * - * @man: Pointer to a memory type manager. - * - * Called to undo the setup done in init. All allocated resources - * should be freed. - */ int (*takedown)(struct ttm_mem_type_manager *man); - - /** - * struct ttm_mem_type_manager member get_node - * - * @man: Pointer to a memory type manager. - * @bo: Pointer to the buffer object we're allocating space for. - * @placement: Placement details. - * @mem: Pointer to a struct ttm_mem_reg to be filled in. - * - * This function should allocate space in the memory type managed - * by @man. Placement details if - * applicable are given by @placement. If successful, - * @mem::mm_node should be set to a non-null value, and - * @mem::start should be set to a value identifying the beginning - * of the range allocated, and the function should return zero. - * If the memory region accomodate the buffer object, @mem::mm_node - * should be set to NULL, and the function should return 0. - * If a system error occured, preventing the request to be fulfilled, - * the function should return a negative error code. - * - * Note that @mem::mm_node will only be dereferenced by - * struct ttm_mem_type_manager functions and optionally by the driver, - * which has knowledge of the underlying type. - * - * This function may not be called from within atomic context, so - * an implementation can and must use either a mutex or a spinlock to - * protect any data structures managing the space. - */ int (*get_node)(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem); - - /** - * struct ttm_mem_type_manager member put_node - * - * @man: Pointer to a memory type manager. - * @mem: Pointer to a struct ttm_mem_reg to be filled in. - * - * This function frees memory type resources previously allocated - * and that are identified by @mem::mm_node and @mem::start. May not - * be called from within atomic context. - */ void (*put_node)(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem); - - /** - * struct ttm_mem_type_manager member debug - * - * @man: Pointer to a memory type manager. - * @prefix: Prefix to be used in printout to identify the caller. - * - * This function is called to print out the state of the memory - * type manager to aid debugging of out-of-memory conditions. - * It may not be called from within atomic context. - */ void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); }; @@ -301,13 +231,14 @@ struct ttm_mem_type_manager { uint64_t size; uint32_t available_caching; uint32_t default_caching; - const struct ttm_mem_type_manager_func *func; - void *priv; /* - * Protected by the global->lru_lock. + * Protected by the bdev->lru_lock. + * TODO: Consider one lru_lock per ttm_mem_type_manager. + * Plays ill with list removal, though. */ - + const struct ttm_mem_type_manager_func *func; + void *priv; struct list_head lru; }; diff --git a/include/linux/atomic.h b/include/linux/atomic.h deleted file mode 100644 index 96c038e..0000000 --- a/include/linux/atomic.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _LINUX_ATOMIC_H -#define _LINUX_ATOMIC_H -#include - -/** - * atomic_inc_not_zero_hint - increment if not null - * @v: pointer of type atomic_t - * @hint: probable value of the atomic before the increment - * - * This version of atomic_inc_not_zero() gives a hint of probable - * value of the atomic. This helps processor to not read the memory - * before doing the atomic read/modify/write cycle, lowering - * number of bus transactions on some arches. - * - * Returns: 0 if increment was not done, 1 otherwise. - */ -#ifndef atomic_inc_not_zero_hint -static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) -{ - int val, c = hint; - - /* sanity test, should be removed by compiler if hint is a constant */ - if (!hint) - return atomic_inc_not_zero(v); - - do { - val = atomic_cmpxchg(v, c, c + 1); - if (val == c) - return 1; - c = val; - } while (c); - - return 0; -} -#endif - -#endif /* _LINUX_ATOMIC_H */ diff --git a/include/linux/bio.h b/include/linux/bio.h index 35dcdb3..ba67999 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -66,6 +66,10 @@ #define bio_offset(bio) bio_iovec((bio))->bv_offset #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) #define bio_sectors(bio) ((bio)->bi_size >> 9) +#define bio_empty_barrier(bio) \ + ((bio->bi_rw & REQ_HARDBARRIER) && \ + !bio_has_data(bio) && \ + !(bio->bi_rw & REQ_DISCARD)) static inline unsigned int bio_cur_bytes(struct bio *bio) { diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 46ad519..0437ab6 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -122,6 +122,7 @@ enum rq_flag_bits { __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ + __REQ_HARDBARRIER, /* may not be passed by drive either */ __REQ_SYNC, /* request is sync (sync write or read) */ __REQ_META, /* metadata io request */ __REQ_DISCARD, /* request to discard sectors */ @@ -158,6 +159,7 @@ enum rq_flag_bits { #define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV) #define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT) #define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) +#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER) #define REQ_SYNC (1 << __REQ_SYNC) #define REQ_META (1 << __REQ_META) #define REQ_DISCARD (1 << __REQ_DISCARD) @@ -166,8 +168,8 @@ enum rq_flag_bits { #define REQ_FAILFAST_MASK \ (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) #define REQ_COMMON_MASK \ - (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ - REQ_NOIDLE | REQ_FLUSH | REQ_FUA) + (REQ_WRITE | REQ_FAILFAST_MASK | REQ_HARDBARRIER | REQ_SYNC | \ + REQ_META | REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA) #define REQ_CLONE_MASK REQ_COMMON_MASK #define REQ_UNPLUG (1 << __REQ_UNPLUG) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aae86fd..5027a59 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -552,7 +552,8 @@ static inline void blk_clear_queue_full(struct request_queue *q, int sync) * it already be started by driver. */ #define RQ_NOMERGE_FLAGS \ - (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) + (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER | \ + REQ_FLUSH | REQ_FUA) #define rq_mergeable(rq) \ (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ (((rq)->cmd_flags & REQ_DISCARD) || \ diff --git a/include/linux/drbd.h b/include/linux/drbd.h index ef44c7a..9b2a015 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -53,7 +53,7 @@ extern const char *drbd_buildtag(void); -#define REL_VERSION "8.3.9" +#define REL_VERSION "8.3.9rc2" #define API_VERSION 88 #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 95 diff --git a/include/linux/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h index 781d467..fc295d7 100644 --- a/include/linux/fsl-diu-fb.h +++ b/include/linux/fsl-diu-fb.h @@ -54,6 +54,7 @@ struct aoi_display_offset { }; #define MFB_SET_CHROMA_KEY _IOW('M', 1, struct mfb_chroma_key) +#define MFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t) #define MFB_SET_BRIGHTNESS _IOW('M', 3, __u8) #define MFB_SET_ALPHA 0x80014d00 diff --git a/include/linux/highmem.h b/include/linux/highmem.h index b676c58..e913819 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -5,7 +5,6 @@ #include #include #include -#include #include diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 4bef5c5..e844a0b 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -32,6 +32,28 @@ */ /* --- Bit algorithm adapters */ +#define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ +#define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ +#define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ #define I2C_HW_B_CX2388x 0x01001b /* connexant 2388x based tv cards */ +#define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */ +#define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */ +#define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */ +#define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */ +#define I2C_HW_B_CX231XX 0x010024 /* Conexant CX231XX USB based cards */ +#define I2C_HW_B_HDPVR 0x010025 /* Hauppauge HD PVR */ + +/* --- SGI adapters */ +#define I2C_HW_SGI_VINO 0x160000 + +/* --- SMBus only adapters */ +#define I2C_HW_SMBUS_W9968CF 0x04000d +#define I2C_HW_SMBUS_OV511 0x04000e /* OV511(+) USB 1.1 webcam ICs */ +#define I2C_HW_SMBUS_OV518 0x04000f /* OV518(+) USB 1.1 webcam ICs */ +#define I2C_HW_SMBUS_CAFE 0x040012 /* Marvell 88ALP01 "CAFE" cam */ + +/* --- Miscellaneous adapters */ +#define I2C_HW_SAA7146 0x060000 /* SAA7146 video decoder bus */ +#define I2C_HW_SAA7134 0x090000 /* SAA7134 video decoder bus */ #endif /* LINUX_I2C_ID_H */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 56cfe23..889b35a 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -353,7 +353,7 @@ struct i2c_algorithm { */ struct i2c_adapter { struct module *owner; - unsigned int id __deprecated; + unsigned int id; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data; diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index cec17cf..3c5d6b6 100644 --- a/include/linux/i2c/adp5588.h +++ b/include/linux/i2c/adp5588.h @@ -1,7 +1,7 @@ /* * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller * - * Copyright 2009-2010 Analog Devices Inc. + * Copyright 2009 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -77,26 +77,13 @@ /* Configuration Register1 */ #define ADP5588_AUTO_INC (1 << 7) #define ADP5588_GPIEM_CFG (1 << 6) -#define ADP5588_OVR_FLOW_M (1 << 5) #define ADP5588_INT_CFG (1 << 4) -#define ADP5588_OVR_FLOW_IEN (1 << 3) -#define ADP5588_K_LCK_IM (1 << 2) #define ADP5588_GPI_IEN (1 << 1) -#define ADP5588_KE_IEN (1 << 0) /* Interrupt Status Register */ -#define ADP5588_CMP2_INT (1 << 5) -#define ADP5588_CMP1_INT (1 << 4) -#define ADP5588_OVR_FLOW_INT (1 << 3) -#define ADP5588_K_LCK_INT (1 << 2) #define ADP5588_GPI_INT (1 << 1) #define ADP5588_KE_INT (1 << 0) -/* Key Lock and Event Counter Register */ -#define ADP5588_K_LCK_EN (1 << 6) -#define ADP5588_LCK21 0x30 -#define ADP5588_KEC 0xF - #define ADP5588_MAXGPIO 18 #define ADP5588_BANK(offs) ((offs) >> 3) #define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 635e1fa..c2f3a72 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -339,31 +339,6 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) } } -/** - * vlan_get_protocol - get protocol EtherType. - * @skb: skbuff to query - * - * Returns the EtherType of the packet, regardless of whether it is - * vlan encapsulated (normal or hardware accelerated) or not. - */ -static inline __be16 vlan_get_protocol(const struct sk_buff *skb) -{ - __be16 protocol = 0; - - if (vlan_tx_tag_present(skb) || - skb->protocol != cpu_to_be16(ETH_P_8021Q)) - protocol = skb->protocol; - else { - __be16 proto, *protop; - protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr, - h_vlan_encapsulated_proto), - sizeof(proto), &proto); - if (likely(protop)) - protocol = *protop; - } - - return protocol; -} #endif /* __KERNEL__ */ /* VLAN IOCTLs are found in sockios.h */ diff --git a/include/linux/input.h b/include/linux/input.h index 6ef4446..51af441 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1406,8 +1406,6 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data) int __must_check input_register_device(struct input_dev *); void input_unregister_device(struct input_dev *); -void input_reset_device(struct input_dev *); - int __must_check input_register_handler(struct input_handler *); void input_unregister_handler(struct input_handler *); @@ -1423,7 +1421,7 @@ void input_release_device(struct input_handle *); int input_open_device(struct input_handle *); void input_close_device(struct input_handle *); -int input_flush_device(struct input_handle *handle, struct file *file); +int input_flush_device(struct input_handle* handle, struct file* file); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value); diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index b2eee89..3e70b21 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h @@ -76,6 +76,7 @@ int put_io_context(struct io_context *ioc); void exit_io_context(struct task_struct *task); struct io_context *get_io_context(gfp_t gfp_flags, int node); struct io_context *alloc_io_context(gfp_t gfp_flags, int node); +void copy_io_context(struct io_context **pdst, struct io_context **psrc); #else static inline void exit_io_context(struct task_struct *task) { diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b6de9a6..450092c 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -17,11 +17,13 @@ #include #include #include -#include #include #include #include +extern const char linux_banner[]; +extern const char linux_proc_banner[]; + #define USHRT_MAX ((u16)(~0U)) #define SHRT_MAX ((s16)(USHRT_MAX>>1)) #define SHRT_MIN ((s16)(-SHRT_MAX - 1)) @@ -58,7 +60,7 @@ #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define roundup(x, y) ( \ { \ - const typeof(y) __y = y; \ + typeof(y) __y = y; \ (((x) + (__y - 1)) / __y) * __y; \ } \ ) @@ -108,6 +110,31 @@ */ #define lower_32_bits(n) ((u32)(n)) +#define KERN_EMERG "<0>" /* system is unusable */ +#define KERN_ALERT "<1>" /* action must be taken immediately */ +#define KERN_CRIT "<2>" /* critical conditions */ +#define KERN_ERR "<3>" /* error conditions */ +#define KERN_WARNING "<4>" /* warning conditions */ +#define KERN_NOTICE "<5>" /* normal but significant condition */ +#define KERN_INFO "<6>" /* informational */ +#define KERN_DEBUG "<7>" /* debug-level messages */ + +/* Use the default kernel loglevel */ +#define KERN_DEFAULT "" +/* + * Annotation for a "continued" line of log printout (only done after a + * line that had no enclosing \n). Only to be used by core/arch code + * during early bootup (a continued line is not SMP-safe otherwise). + */ +#define KERN_CONT "" + +extern int console_printk[]; + +#define console_loglevel (console_printk[0]) +#define default_message_loglevel (console_printk[1]) +#define minimum_console_loglevel (console_printk[2]) +#define default_console_loglevel (console_printk[3]) + struct completion; struct pt_regs; struct user; @@ -160,6 +187,11 @@ static inline void might_fault(void) } #endif +struct va_format { + const char *fmt; + va_list *va; +}; + extern struct atomic_notifier_head panic_notifier_list; extern long (*panic_blink)(int state); NORET_TYPE void panic(const char * fmt, ...) @@ -213,8 +245,114 @@ extern int func_ptr_is_kernel_text(void *ptr); struct pid; extern struct pid *session_of_pgrp(struct pid *pgrp); +/* + * FW_BUG + * Add this to a message where you are sure the firmware is buggy or behaves + * really stupid or out of spec. Be aware that the responsible BIOS developer + * should be able to fix this issue or at least get a concrete idea of the + * problem by reading your message without the need of looking at the kernel + * code. + * + * Use it for definite and high priority BIOS bugs. + * + * FW_WARN + * Use it for not that clear (e.g. could the kernel messed up things already?) + * and medium priority BIOS bugs. + * + * FW_INFO + * Use this one if you want to tell the user or vendor about something + * suspicious, but generally harmless related to the firmware. + * + * Use it for information or very low priority BIOS bugs. + */ +#define FW_BUG "[Firmware Bug]: " +#define FW_WARN "[Firmware Warn]: " +#define FW_INFO "[Firmware Info]: " + +/* + * HW_ERR + * Add this to a message for hardware errors, so that user can report + * it to hardware vendor instead of LKML or software vendor. + */ +#define HW_ERR "[Hardware Error]: " + +#ifdef CONFIG_PRINTK +asmlinkage int vprintk(const char *fmt, va_list args) + __attribute__ ((format (printf, 1, 0))); +asmlinkage int printk(const char * fmt, ...) + __attribute__ ((format (printf, 1, 2))) __cold; + +/* + * Please don't use printk_ratelimit(), because it shares ratelimiting state + * with all other unrelated printk_ratelimit() callsites. Instead use + * printk_ratelimited() or plain old __ratelimit(). + */ +extern int __printk_ratelimit(const char *func); +#define printk_ratelimit() __printk_ratelimit(__func__) +extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, + unsigned int interval_msec); + +extern int printk_delay_msec; + +/* + * Print a one-time message (analogous to WARN_ONCE() et al): + */ +#define printk_once(x...) ({ \ + static bool __print_once; \ + \ + if (!__print_once) { \ + __print_once = true; \ + printk(x); \ + } \ +}) + +void log_buf_kexec_setup(void); +#else +static inline int vprintk(const char *s, va_list args) + __attribute__ ((format (printf, 1, 0))); +static inline int vprintk(const char *s, va_list args) { return 0; } +static inline int printk(const char *s, ...) + __attribute__ ((format (printf, 1, 2))); +static inline int __cold printk(const char *s, ...) { return 0; } +static inline int printk_ratelimit(void) { return 0; } +static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ + unsigned int interval_msec) \ + { return false; } + +/* No effect, but we still get type checking even in the !PRINTK case: */ +#define printk_once(x...) printk(x) + +static inline void log_buf_kexec_setup(void) +{ +} +#endif + +/* + * Dummy printk for disabled debugging statements to use whilst maintaining + * gcc's format and side-effect checking. + */ +static inline __attribute__ ((format (printf, 1, 2))) +int no_printk(const char *s, ...) { return 0; } + +extern int printk_needs_cpu(int cpu); +extern void printk_tick(void); + +extern void asmlinkage __attribute__((format(printf, 1, 2))) + early_printk(const char *fmt, ...); + unsigned long int_sqrt(unsigned long); +static inline void console_silent(void) +{ + console_loglevel = 0; +} + +static inline void console_verbose(void) +{ + if (console_loglevel) + console_loglevel = 15; +} + extern void bust_spinlocks(int yes); extern void wake_up_klogd(void); extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ @@ -251,6 +389,22 @@ extern enum system_states { #define TAINT_CRAP 10 #define TAINT_FIRMWARE_WORKAROUND 11 +extern void dump_stack(void) __cold; + +enum { + DUMP_PREFIX_NONE, + DUMP_PREFIX_ADDRESS, + DUMP_PREFIX_OFFSET +}; +extern void hex_dump_to_buffer(const void *buf, size_t len, + int rowsize, int groupsize, + char *linebuf, size_t linebuflen, bool ascii); +extern void print_hex_dump(const char *level, const char *prefix_str, + int prefix_type, int rowsize, int groupsize, + const void *buf, size_t len, bool ascii); +extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, + const void *buf, size_t len); + extern const char hex_asc[]; #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] @@ -264,6 +418,94 @@ static inline char *pack_hex_byte(char *buf, u8 byte) extern int hex_to_bin(char ch); +#ifndef pr_fmt +#define pr_fmt(fmt) fmt +#endif + +#define pr_emerg(fmt, ...) \ + printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) +#define pr_alert(fmt, ...) \ + printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_crit(fmt, ...) \ + printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_err(fmt, ...) \ + printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warning(fmt, ...) \ + printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warn pr_warning +#define pr_notice(fmt, ...) \ + printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) +#define pr_info(fmt, ...) \ + printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +#define pr_cont(fmt, ...) \ + printk(KERN_CONT fmt, ##__VA_ARGS__) + +/* pr_devel() should produce zero code unless DEBUG is defined */ +#ifdef DEBUG +#define pr_devel(fmt, ...) \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) +#else +#define pr_devel(fmt, ...) \ + ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) +#endif + +/* If you are writing a driver, please use dev_dbg instead */ +#if defined(DEBUG) +#define pr_debug(fmt, ...) \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) +#elif defined(CONFIG_DYNAMIC_DEBUG) +/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */ +#define pr_debug(fmt, ...) \ + dynamic_pr_debug(fmt, ##__VA_ARGS__) +#else +#define pr_debug(fmt, ...) \ + ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) +#endif + +/* + * ratelimited messages with local ratelimit_state, + * no local ratelimit_state used in the !PRINTK case + */ +#ifdef CONFIG_PRINTK +#define printk_ratelimited(fmt, ...) ({ \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + \ + if (__ratelimit(&_rs)) \ + printk(fmt, ##__VA_ARGS__); \ +}) +#else +/* No effect, but we still get type checking even in the !PRINTK case: */ +#define printk_ratelimited printk +#endif + +#define pr_emerg_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) +#define pr_alert_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_crit_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_err_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warning_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warn_ratelimited pr_warning_ratelimited +#define pr_notice_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) +#define pr_info_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +/* no pr_cont_ratelimited, don't do that... */ +/* If you are writing a driver, please use dev_dbg instead */ +#if defined(DEBUG) +#define pr_debug_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) +#else +#define pr_debug_ratelimited(fmt, ...) \ + ({ if (0) printk_ratelimited(KERN_DEBUG pr_fmt(fmt), \ + ##__VA_ARGS__); 0; }) +#endif + /* * General tracing related utility functions - trace_printk(), * tracing_on/tracing_off and tracing_start()/tracing_stop diff --git a/include/linux/leds-lp5521.h b/include/linux/leds-lp5521.h deleted file mode 100644 index 38368d7..0000000 --- a/include/linux/leds-lp5521.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * LP5521 LED chip driver. - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef __LINUX_LP5521_H -#define __LINUX_LP5521_H - -/* See Documentation/leds/leds-lp5521.txt */ - -struct lp5521_led_config { - u8 chan_nr; - u8 led_current; /* mA x10, 0 if led is not connected */ - u8 max_current; -}; - -#define LP5521_CLOCK_AUTO 0 -#define LP5521_CLOCK_INT 1 -#define LP5521_CLOCK_EXT 2 - -struct lp5521_platform_data { - struct lp5521_led_config *led_config; - u8 num_channels; - u8 clock_mode; - int (*setup_resources)(void); - void (*release_resources)(void); - void (*enable)(bool state); -}; - -#endif /* __LINUX_LP5521_H */ diff --git a/include/linux/leds-lp5523.h b/include/linux/leds-lp5523.h deleted file mode 100644 index 7967476..0000000 --- a/include/linux/leds-lp5523.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * LP5523 LED Driver - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef __LINUX_LP5523_H -#define __LINUX_LP5523_H - -/* See Documentation/leds/leds-lp5523.txt */ - -struct lp5523_led_config { - u8 chan_nr; - u8 led_current; /* mA x10, 0 if led is not connected */ - u8 max_current; -}; - -#define LP5523_CLOCK_AUTO 0 -#define LP5523_CLOCK_INT 1 -#define LP5523_CLOCK_EXT 2 - -struct lp5523_platform_data { - struct lp5523_led_config *led_config; - u8 num_channels; - u8 clock_mode; - int (*setup_resources)(void); - void (*release_resources)(void); - void (*enable)(bool state); -}; - -#endif /* __LINUX_LP5523_H */ diff --git a/include/linux/leds.h b/include/linux/leds.h index 0f19df9..ba6986a 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -15,7 +15,6 @@ #include #include #include -#include struct device; /* @@ -46,14 +45,10 @@ struct led_classdev { /* Get LED brightness level */ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); - /* - * Activate hardware accelerated blink, delays are in milliseconds - * and if both are zero then a sensible default should be chosen. - * The call should adjust the timings in that case and if it can't - * match the values specified exactly. - * Deactivate blinking again when the brightness is set to a fixed - * value via the brightness_set() callback. - */ + /* Activate hardware accelerated blink, delays are in + * miliseconds and if none is provided then a sensible default + * should be chosen. The call can adjust the timings if it can't + * match the values specified exactly. */ int (*blink_set)(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off); @@ -62,10 +57,6 @@ struct led_classdev { struct list_head node; /* LED Device list */ const char *default_trigger; /* Trigger to use */ - unsigned long blink_delay_on, blink_delay_off; - struct timer_list blink_timer; - int blink_brightness; - #ifdef CONFIG_LEDS_TRIGGERS /* Protects the trigger data below */ struct rw_semaphore trigger_lock; @@ -82,36 +73,6 @@ extern void led_classdev_unregister(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); -/** - * led_blink_set - set blinking with software fallback - * @led_cdev: the LED to start blinking - * @delay_on: the time it should be on (in ms) - * @delay_off: the time it should ble off (in ms) - * - * This function makes the LED blink, attempting to use the - * hardware acceleration if possible, but falling back to - * software blinking if there is no hardware blinking or if - * the LED refuses the passed values. - * - * Note that if software blinking is active, simply calling - * led_cdev->brightness_set() will not stop the blinking, - * use led_classdev_brightness_set() instead. - */ -extern void led_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off); -/** - * led_brightness_set - set LED brightness - * @led_cdev: the LED to set - * @brightness: the brightness to set it to - * - * Set an LED's brightness, and, if necessary, cancel the - * software blink timer that implements blinking when the - * hardware doesn't. - */ -extern void led_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness); - /* * LED Triggers */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d8fd2c2..072652d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1554,11 +1554,6 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev) static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue) { - if (WARN_ON(!dev_queue)) { - printk(KERN_INFO "netif_stop_queue() cannot be called before " - "register_netdev()"); - return; - } set_bit(__QUEUE_STATE_XOFF, &dev_queue->state); } diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 03317c8..89341c3 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -215,7 +215,7 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb, int ret; if (!cond || - ((ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN)) == 1)) + (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1)) ret = okfn(skb); return ret; } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 40150f3..057bf22 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -747,16 +747,6 @@ struct perf_event { u64 tstamp_running; u64 tstamp_stopped; - /* - * timestamp shadows the actual context timing but it can - * be safely used in NMI interrupt context. It reflects the - * context time as it was when the event was last scheduled in. - * - * ctx_time already accounts for ctx->timestamp. Therefore to - * compute ctx_time for a sample, simply add perf_clock(). - */ - u64 shadow_ctx_time; - struct perf_event_attr attr; struct hw_perf_event hw; diff --git a/include/linux/printk.h b/include/linux/printk.h deleted file mode 100644 index b772ca5..0000000 --- a/include/linux/printk.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef __KERNEL_PRINTK__ -#define __KERNEL_PRINTK__ - -extern const char linux_banner[]; -extern const char linux_proc_banner[]; - -#define KERN_EMERG "<0>" /* system is unusable */ -#define KERN_ALERT "<1>" /* action must be taken immediately */ -#define KERN_CRIT "<2>" /* critical conditions */ -#define KERN_ERR "<3>" /* error conditions */ -#define KERN_WARNING "<4>" /* warning conditions */ -#define KERN_NOTICE "<5>" /* normal but significant condition */ -#define KERN_INFO "<6>" /* informational */ -#define KERN_DEBUG "<7>" /* debug-level messages */ - -/* Use the default kernel loglevel */ -#define KERN_DEFAULT "" -/* - * Annotation for a "continued" line of log printout (only done after a - * line that had no enclosing \n). Only to be used by core/arch code - * during early bootup (a continued line is not SMP-safe otherwise). - */ -#define KERN_CONT "" - -extern int console_printk[]; - -#define console_loglevel (console_printk[0]) -#define default_message_loglevel (console_printk[1]) -#define minimum_console_loglevel (console_printk[2]) -#define default_console_loglevel (console_printk[3]) - -struct va_format { - const char *fmt; - va_list *va; -}; - -/* - * FW_BUG - * Add this to a message where you are sure the firmware is buggy or behaves - * really stupid or out of spec. Be aware that the responsible BIOS developer - * should be able to fix this issue or at least get a concrete idea of the - * problem by reading your message without the need of looking at the kernel - * code. - * - * Use it for definite and high priority BIOS bugs. - * - * FW_WARN - * Use it for not that clear (e.g. could the kernel messed up things already?) - * and medium priority BIOS bugs. - * - * FW_INFO - * Use this one if you want to tell the user or vendor about something - * suspicious, but generally harmless related to the firmware. - * - * Use it for information or very low priority BIOS bugs. - */ -#define FW_BUG "[Firmware Bug]: " -#define FW_WARN "[Firmware Warn]: " -#define FW_INFO "[Firmware Info]: " - -/* - * HW_ERR - * Add this to a message for hardware errors, so that user can report - * it to hardware vendor instead of LKML or software vendor. - */ -#define HW_ERR "[Hardware Error]: " - -#ifdef CONFIG_PRINTK -asmlinkage int vprintk(const char *fmt, va_list args) - __attribute__ ((format (printf, 1, 0))); -asmlinkage int printk(const char * fmt, ...) - __attribute__ ((format (printf, 1, 2))) __cold; - -/* - * Please don't use printk_ratelimit(), because it shares ratelimiting state - * with all other unrelated printk_ratelimit() callsites. Instead use - * printk_ratelimited() or plain old __ratelimit(). - */ -extern int __printk_ratelimit(const char *func); -#define printk_ratelimit() __printk_ratelimit(__func__) -extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, - unsigned int interval_msec); - -extern int printk_delay_msec; -extern int dmesg_restrict; - -/* - * Print a one-time message (analogous to WARN_ONCE() et al): - */ -#define printk_once(x...) ({ \ - static bool __print_once; \ - \ - if (!__print_once) { \ - __print_once = true; \ - printk(x); \ - } \ -}) - -void log_buf_kexec_setup(void); -#else -static inline int vprintk(const char *s, va_list args) - __attribute__ ((format (printf, 1, 0))); -static inline int vprintk(const char *s, va_list args) { return 0; } -static inline int printk(const char *s, ...) - __attribute__ ((format (printf, 1, 2))); -static inline int __cold printk(const char *s, ...) { return 0; } -static inline int printk_ratelimit(void) { return 0; } -static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ - unsigned int interval_msec) \ - { return false; } - -/* No effect, but we still get type checking even in the !PRINTK case: */ -#define printk_once(x...) printk(x) - -static inline void log_buf_kexec_setup(void) -{ -} -#endif - -/* - * Dummy printk for disabled debugging statements to use whilst maintaining - * gcc's format and side-effect checking. - */ -static inline __attribute__ ((format (printf, 1, 2))) -int no_printk(const char *s, ...) { return 0; } - -extern int printk_needs_cpu(int cpu); -extern void printk_tick(void); - -extern void asmlinkage __attribute__((format(printf, 1, 2))) - early_printk(const char *fmt, ...); - -static inline void console_silent(void) -{ - console_loglevel = 0; -} - -static inline void console_verbose(void) -{ - if (console_loglevel) - console_loglevel = 15; -} - -extern void dump_stack(void) __cold; - -enum { - DUMP_PREFIX_NONE, - DUMP_PREFIX_ADDRESS, - DUMP_PREFIX_OFFSET -}; -extern void hex_dump_to_buffer(const void *buf, size_t len, - int rowsize, int groupsize, - char *linebuf, size_t linebuflen, bool ascii); -extern void print_hex_dump(const char *level, const char *prefix_str, - int prefix_type, int rowsize, int groupsize, - const void *buf, size_t len, bool ascii); -extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - const void *buf, size_t len); - -#ifndef pr_fmt -#define pr_fmt(fmt) fmt -#endif - -#define pr_emerg(fmt, ...) \ - printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) -#define pr_alert(fmt, ...) \ - printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) -#define pr_crit(fmt, ...) \ - printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) -#define pr_err(fmt, ...) \ - printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warning(fmt, ...) \ - printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warn pr_warning -#define pr_notice(fmt, ...) \ - printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) -#define pr_info(fmt, ...) \ - printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) -#define pr_cont(fmt, ...) \ - printk(KERN_CONT fmt, ##__VA_ARGS__) - -/* pr_devel() should produce zero code unless DEBUG is defined */ -#ifdef DEBUG -#define pr_devel(fmt, ...) \ - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) -#else -#define pr_devel(fmt, ...) \ - ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) -#endif - -/* If you are writing a driver, please use dev_dbg instead */ -#if defined(DEBUG) -#define pr_debug(fmt, ...) \ - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) -#elif defined(CONFIG_DYNAMIC_DEBUG) -/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */ -#define pr_debug(fmt, ...) \ - dynamic_pr_debug(fmt, ##__VA_ARGS__) -#else -#define pr_debug(fmt, ...) \ - ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) -#endif - -/* - * ratelimited messages with local ratelimit_state, - * no local ratelimit_state used in the !PRINTK case - */ -#ifdef CONFIG_PRINTK -#define printk_ratelimited(fmt, ...) ({ \ - static DEFINE_RATELIMIT_STATE(_rs, \ - DEFAULT_RATELIMIT_INTERVAL, \ - DEFAULT_RATELIMIT_BURST); \ - \ - if (__ratelimit(&_rs)) \ - printk(fmt, ##__VA_ARGS__); \ -}) -#else -/* No effect, but we still get type checking even in the !PRINTK case: */ -#define printk_ratelimited printk -#endif - -#define pr_emerg_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) -#define pr_alert_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) -#define pr_crit_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) -#define pr_err_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warning_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warn_ratelimited pr_warning_ratelimited -#define pr_notice_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) -#define pr_info_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) -/* no pr_cont_ratelimited, don't do that... */ -/* If you are writing a driver, please use dev_dbg instead */ -#if defined(DEBUG) -#define pr_debug_ratelimited(fmt, ...) \ - printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) -#else -#define pr_debug_ratelimited(fmt, ...) \ - ({ if (0) printk_ratelimited(KERN_DEBUG pr_fmt(fmt), \ - ##__VA_ARGS__); 0; }) -#endif - -#endif diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index e031e1a..01b3d75 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h @@ -8,7 +8,6 @@ struct platform_pwm_backlight_data { int pwm_id; unsigned int max_brightness; unsigned int dft_brightness; - unsigned int lth_brightness; unsigned int pwm_period_ns; int (*init)(struct device *dev); int (*notify)(struct device *dev, int brightness); diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index ab2baa5..a39cbed 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -34,13 +34,19 @@ * needed for RCU lookups (because root->height is unreliable). The only * time callers need worry about this is when doing a lookup_slot under * RCU. - * - * Indirect pointer in fact is also used to tag the last pointer of a node - * when it is shrunk, before we rcu free the node. See shrink code for - * details. */ #define RADIX_TREE_INDIRECT_PTR 1 +#define RADIX_TREE_RETRY ((void *)-1UL) + +static inline void *radix_tree_ptr_to_indirect(void *ptr) +{ + return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); +} +static inline void *radix_tree_indirect_to_ptr(void *ptr) +{ + return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); +} #define radix_tree_indirect_to_ptr(ptr) \ radix_tree_indirect_to_ptr((void __force *)(ptr)) @@ -134,29 +140,16 @@ do { \ * removed. * * For use with radix_tree_lookup_slot(). Caller must hold tree at least read - * locked across slot lookup and dereference. Not required if write lock is - * held (ie. items cannot be concurrently inserted). - * - * radix_tree_deref_retry must be used to confirm validity of the pointer if - * only the read lock is held. + * locked across slot lookup and dereference. More likely, will be used with + * radix_tree_replace_slot(), as well, so caller will hold tree write locked. */ static inline void *radix_tree_deref_slot(void **pslot) { - return rcu_dereference(*pslot); + void *ret = rcu_dereference(*pslot); + if (unlikely(radix_tree_is_indirect_ptr(ret))) + ret = RADIX_TREE_RETRY; + return ret; } - -/** - * radix_tree_deref_retry - check radix_tree_deref_slot - * @arg: pointer returned by radix_tree_deref_slot - * Returns: 0 if retry is not required, otherwise retry is required - * - * radix_tree_deref_retry must be used with radix_tree_deref_slot. - */ -static inline int radix_tree_deref_retry(void *arg) -{ - return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR); -} - /** * radix_tree_replace_slot - replace item in a slot * @pslot: pointer to slot, returned by radix_tree_lookup_slot diff --git a/include/linux/resource.h b/include/linux/resource.h index d01c96c..88d36f9 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -2,7 +2,6 @@ #define _LINUX_RESOURCE_H #include -#include /* * Resource control/accounting header file for linux diff --git a/include/linux/sched.h b/include/linux/sched.h index d0036e5..6ef4a90 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1871,14 +1871,11 @@ extern void sched_clock_idle_sleep_event(void); extern void sched_clock_idle_wakeup_event(u64 delta_ns); #ifdef CONFIG_HOTPLUG_CPU -extern void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p); extern void idle_task_exit(void); #else static inline void idle_task_exit(void) {} #endif -extern void sched_idle_next(void); - #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) extern void wake_up_idle_cpu(int cpu); #else diff --git a/include/linux/security.h b/include/linux/security.h index fd4d55f..b8246a8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -77,6 +77,7 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, extern int cap_task_setscheduler(struct task_struct *p); extern int cap_task_setioprio(struct task_struct *p, int ioprio); extern int cap_task_setnice(struct task_struct *p, int nice); +extern int cap_syslog(int type, bool from_file); extern int cap_vm_enough_memory(struct mm_struct *mm, long pages); struct msghdr; @@ -1387,7 +1388,7 @@ struct security_operations { int (*sysctl) (struct ctl_table *table, int op); int (*quotactl) (int cmds, int type, int id, struct super_block *sb); int (*quota_on) (struct dentry *dentry); - int (*syslog) (int type); + int (*syslog) (int type, bool from_file); int (*settime) (struct timespec *ts, struct timezone *tz); int (*vm_enough_memory) (struct mm_struct *mm, long pages); @@ -1670,7 +1671,7 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap); int security_sysctl(struct ctl_table *table, int op); int security_quotactl(int cmds, int type, int id, struct super_block *sb); int security_quota_on(struct dentry *dentry); -int security_syslog(int type); +int security_syslog(int type, bool from_file); int security_settime(struct timespec *ts, struct timezone *tz); int security_vm_enough_memory(long pages); int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); @@ -1900,9 +1901,9 @@ static inline int security_quota_on(struct dentry *dentry) return 0; } -static inline int security_syslog(int type) +static inline int security_syslog(int type, bool from_file) { - return 0; + return cap_syslog(type, from_file); } static inline int security_settime(struct timespec *ts, struct timezone *tz) diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index 5812fef..f656d1a 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -79,7 +79,7 @@ struct intc_hw_desc { unsigned int nr_subgroups; }; -#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a) +#define _INTC_ARRAY(a) a, a == NULL ? 0 : sizeof(a)/sizeof(*a) #define INTC_HW_DESC(vectors, groups, mask_regs, \ prio_regs, sense_regs, ack_regs) \ diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index aea0d43..bbdb680 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -82,28 +82,18 @@ struct svc_xprt { struct net *xpt_net; }; -static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) +static inline void register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) { spin_lock(&xpt->xpt_lock); - list_del_init(&u->list); + list_add(&u->list, &xpt->xpt_users); spin_unlock(&xpt->xpt_lock); } -static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) +static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) { spin_lock(&xpt->xpt_lock); - if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) { - /* - * The connection is about to be deleted soon (or, - * worse, may already be deleted--in which case we've - * already notified the xpt_users). - */ - spin_unlock(&xpt->xpt_lock); - return -ENOTCONN; - } - list_add(&u->list, &xpt->xpt_users); + list_del_init(&u->list); spin_unlock(&xpt->xpt_lock); - return 0; } int svc_reg_xprt_class(struct svc_xprt_class *); diff --git a/include/linux/tty.h b/include/linux/tty.h index c7ea9bc..2a75474 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -50,7 +50,7 @@ #define N_V253 19 /* Codec control over voice modem */ #define N_CAIF 20 /* CAIF protocol for talking to modems */ #define N_GSM0710 21 /* GSM 0710 Mux */ -#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */ +#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */ /* * This character is the same as _POSIX_VDISABLE: it cannot be used as diff --git a/include/linux/usb.h b/include/linux/usb.h index 24300d8..35fe6ab 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -797,7 +797,7 @@ struct usbdrv_wrap { * @disconnect: Called when the interface is no longer accessible, usually * because its device has been (or is being) disconnected or the * driver module is being unloaded. - * @unlocked_ioctl: Used for drivers that want to talk to userspace through + * @ioctl: Used for drivers that want to talk to userspace through * the "usbfs" filesystem. This lets devices provide ways to * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index 2387f9f..ee2dd1d 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -89,8 +89,6 @@ struct musb_hdrc_config { /* A GPIO controlling VRSEL in Blackfin */ unsigned int gpio_vrsel; unsigned int gpio_vrsel_active; - /* musb CLKIN in Blackfin in MHZ */ - unsigned char clkin; #endif }; diff --git a/include/net/dn.h b/include/net/dn.h index a514a3c..e5469f7 100644 --- a/include/net/dn.h +++ b/include/net/dn.h @@ -225,7 +225,7 @@ extern int decnet_di_count; extern int decnet_dr_count; extern int decnet_no_fc_max_cwnd; -extern long sysctl_decnet_mem[3]; +extern int sysctl_decnet_mem[3]; extern int sysctl_decnet_wmem[3]; extern int sysctl_decnet_rmem[3]; diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index 51665b3..1fa5306 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -2,7 +2,6 @@ #define _NET_DST_OPS_H #include #include -#include struct dst_entry; struct kmem_cachep; diff --git a/include/net/sock.h b/include/net/sock.h index a6338d0..c7a7362 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -762,7 +762,7 @@ struct proto { /* Memory pressure */ void (*enter_memory_pressure)(struct sock *sk); - atomic_long_t *memory_allocated; /* Current allocated memory. */ + atomic_t *memory_allocated; /* Current allocated memory. */ struct percpu_counter *sockets_allocated; /* Current number of sockets. */ /* * Pressure flag: try to collapse. @@ -771,7 +771,7 @@ struct proto { * is strict, actions are advisory and have some latency. */ int *memory_pressure; - long *sysctl_mem; + int *sysctl_mem; int *sysctl_wmem; int *sysctl_rmem; int max_header; diff --git a/include/net/tcp.h b/include/net/tcp.h index e36c874..4fee042 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -224,7 +224,7 @@ extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; extern int sysctl_tcp_ecn; extern int sysctl_tcp_dsack; -extern long sysctl_tcp_mem[3]; +extern int sysctl_tcp_mem[3]; extern int sysctl_tcp_wmem[3]; extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; @@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size; extern int sysctl_tcp_thin_linear_timeouts; extern int sysctl_tcp_thin_dupack; -extern atomic_long_t tcp_memory_allocated; +extern atomic_t tcp_memory_allocated; extern struct percpu_counter tcp_sockets_allocated; extern int tcp_memory_pressure; @@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift) } if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) return true; return false; } diff --git a/include/net/udp.h b/include/net/udp.h index bb967dd..200b828 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table, extern struct proto udp_prot; -extern atomic_long_t udp_memory_allocated; +extern atomic_t udp_memory_allocated; /* sysctl variables for udp */ -extern long sysctl_udp_mem[3]; +extern int sysctl_udp_mem[3]; extern int sysctl_udp_rmem_min; extern int sysctl_udp_wmem_min; diff --git a/kernel/cpu.c b/kernel/cpu.c index f6e726f..8615aa6 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -189,7 +189,6 @@ static inline void check_for_tasks(int cpu) } struct take_cpu_down_param { - struct task_struct *caller; unsigned long mod; void *hcpu; }; @@ -208,11 +207,6 @@ static int __ref take_cpu_down(void *_param) cpu_notify(CPU_DYING | param->mod, param->hcpu); - if (task_cpu(param->caller) == cpu) - move_task_off_dead_cpu(cpu, param->caller); - /* Force idle task to run as soon as we yield: it should - immediately notice cpu is offline and die quickly. */ - sched_idle_next(); return 0; } @@ -223,7 +217,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) void *hcpu = (void *)(long)cpu; unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; struct take_cpu_down_param tcd_param = { - .caller = current, .mod = mod, .hcpu = hcpu, }; @@ -253,9 +246,12 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) } BUG_ON(cpu_online(cpu)); - /* Wait for it to sleep (leaving idle task). */ - while (!idle_cpu(cpu)) - yield(); + /* + * The migration_call() CPU_DYING callback will have removed all + * runnable tasks from the cpu, there's only the idle task left now + * that the migration thread is done doing the stop_machine thing. + */ + BUG_ON(!idle_cpu(cpu)); /* This actually kills the CPU. */ __cpu_die(cpu); diff --git a/kernel/latencytop.c b/kernel/latencytop.c index 17110a4..877fb30 100644 --- a/kernel/latencytop.c +++ b/kernel/latencytop.c @@ -194,7 +194,14 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) account_global_scheduler_latency(tsk, &lat); - for (i = 0; i < tsk->latency_record_count; i++) { + /* + * short term hack; if we're > 32 we stop; future we recycle: + */ + tsk->latency_record_count++; + if (tsk->latency_record_count >= LT_SAVECOUNT) + goto out_unlock; + + for (i = 0; i < LT_SAVECOUNT; i++) { struct latency_record *mylat; int same = 1; @@ -220,14 +227,8 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) } } - /* - * short term hack; if we're > 32 we stop; future we recycle: - */ - if (tsk->latency_record_count >= LT_SAVECOUNT) - goto out_unlock; - /* Allocated a new one: */ - i = tsk->latency_record_count++; + i = tsk->latency_record_count; memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record)); out_unlock: diff --git a/kernel/perf_event.c b/kernel/perf_event.c index cb6c0d2..517d827 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -674,8 +674,6 @@ event_sched_in(struct perf_event *event, event->tstamp_running += ctx->time - event->tstamp_stopped; - event->shadow_ctx_time = ctx->time - ctx->timestamp; - if (!is_software_event(event)) cpuctx->active_oncpu++; ctx->nr_active++; @@ -3398,8 +3396,7 @@ static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) } static void perf_output_read_one(struct perf_output_handle *handle, - struct perf_event *event, - u64 enabled, u64 running) + struct perf_event *event) { u64 read_format = event->attr.read_format; u64 values[4]; @@ -3407,11 +3404,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, values[n++] = perf_event_count(event); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { - values[n++] = enabled + + values[n++] = event->total_time_enabled + atomic64_read(&event->child_total_time_enabled); } if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { - values[n++] = running + + values[n++] = event->total_time_running + atomic64_read(&event->child_total_time_running); } if (read_format & PERF_FORMAT_ID) @@ -3424,8 +3421,7 @@ static void perf_output_read_one(struct perf_output_handle *handle, * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. */ static void perf_output_read_group(struct perf_output_handle *handle, - struct perf_event *event, - u64 enabled, u64 running) + struct perf_event *event) { struct perf_event *leader = event->group_leader, *sub; u64 read_format = event->attr.read_format; @@ -3435,10 +3431,10 @@ static void perf_output_read_group(struct perf_output_handle *handle, values[n++] = 1 + leader->nr_siblings; if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - values[n++] = enabled; + values[n++] = leader->total_time_enabled; if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - values[n++] = running; + values[n++] = leader->total_time_running; if (leader != event) leader->pmu->read(leader); @@ -3463,35 +3459,13 @@ static void perf_output_read_group(struct perf_output_handle *handle, } } -#define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\ - PERF_FORMAT_TOTAL_TIME_RUNNING) - static void perf_output_read(struct perf_output_handle *handle, struct perf_event *event) { - u64 enabled = 0, running = 0, now, ctx_time; - u64 read_format = event->attr.read_format; - - /* - * compute total_time_enabled, total_time_running - * based on snapshot values taken when the event - * was last scheduled in. - * - * we cannot simply called update_context_time() - * because of locking issue as we are called in - * NMI context - */ - if (read_format & PERF_FORMAT_TOTAL_TIMES) { - now = perf_clock(); - ctx_time = event->shadow_ctx_time + now; - enabled = ctx_time - event->tstamp_enabled; - running = ctx_time - event->tstamp_running; - } - if (event->attr.read_format & PERF_FORMAT_GROUP) - perf_output_read_group(handle, event, enabled, running); + perf_output_read_group(handle, event); else - perf_output_read_one(handle, event, enabled, running); + perf_output_read_one(handle, event); } void perf_output_sample(struct perf_output_handle *handle, diff --git a/kernel/printk.c b/kernel/printk.c index 9a2264f..b2ebaee 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -261,12 +261,6 @@ static inline void boot_delay_msec(void) } #endif -#ifdef CONFIG_SECURITY_DMESG_RESTRICT -int dmesg_restrict = 1; -#else -int dmesg_restrict; -#endif - int do_syslog(int type, char __user *buf, int len, bool from_file) { unsigned i, j, limit, count; @@ -274,20 +268,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) char c; int error = 0; - /* - * If this is from /proc/kmsg we only do the capabilities checks - * at open time. - */ - if (type == SYSLOG_ACTION_OPEN || !from_file) { - if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) - return -EPERM; - if ((type != SYSLOG_ACTION_READ_ALL && - type != SYSLOG_ACTION_SIZE_BUFFER) && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - } - - error = security_syslog(type); + error = security_syslog(type, from_file); if (error) return error; diff --git a/kernel/range.c b/kernel/range.c index 37fa9b9..471b66a 100644 --- a/kernel/range.c +++ b/kernel/range.c @@ -119,7 +119,7 @@ static int cmp_range(const void *x1, const void *x2) int clean_sort_range(struct range *range, int az) { - int i, j, k = az - 1, nr_range = az; + int i, j, k = az - 1, nr_range = 0; for (i = 0; i < k; i++) { if (range[i].end) diff --git a/kernel/sched.c b/kernel/sched.c index aa14a56..b6bec2c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2366,18 +2366,15 @@ static int select_fallback_rq(int cpu, struct task_struct *p) return dest_cpu; /* No more Mr. Nice Guy. */ - if (unlikely(dest_cpu >= nr_cpu_ids)) { - dest_cpu = cpuset_cpus_allowed_fallback(p); - /* - * Don't tell them about moving exiting tasks or - * kernel threads (both mm NULL), since they never - * leave kernel. - */ - if (p->mm && printk_ratelimit()) { - printk(KERN_INFO "process %d (%s) no " - "longer affine to cpu%d\n", - task_pid_nr(p), p->comm, cpu); - } + dest_cpu = cpuset_cpus_allowed_fallback(p); + /* + * Don't tell them about moving exiting tasks or + * kernel threads (both mm NULL), since they never + * leave kernel. + */ + if (p->mm && printk_ratelimit()) { + printk(KERN_INFO "process %d (%s) no longer affine to cpu%d\n", + task_pid_nr(p), p->comm, cpu); } return dest_cpu; @@ -5712,29 +5709,20 @@ static int migration_cpu_stop(void *data) } #ifdef CONFIG_HOTPLUG_CPU + /* - * Figure out where task on dead CPU should go, use force if necessary. + * Ensures that the idle task is using init_mm right before its cpu goes + * offline. */ -void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) +void idle_task_exit(void) { - struct rq *rq = cpu_rq(dead_cpu); - int needs_cpu, uninitialized_var(dest_cpu); - unsigned long flags; + struct mm_struct *mm = current->active_mm; - local_irq_save(flags); + BUG_ON(cpu_online(smp_processor_id())); - raw_spin_lock(&rq->lock); - needs_cpu = (task_cpu(p) == dead_cpu) && (p->state != TASK_WAKING); - if (needs_cpu) - dest_cpu = select_fallback_rq(dead_cpu, p); - raw_spin_unlock(&rq->lock); - /* - * It can only fail if we race with set_cpus_allowed(), - * in the racer should migrate the task anyway. - */ - if (needs_cpu) - __migrate_task(p, dead_cpu, dest_cpu); - local_irq_restore(flags); + if (mm != &init_mm) + switch_mm(mm, &init_mm, current); + mmdrop(mm); } /* @@ -5747,128 +5735,69 @@ void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) static void migrate_nr_uninterruptible(struct rq *rq_src) { struct rq *rq_dest = cpu_rq(cpumask_any(cpu_active_mask)); - unsigned long flags; - local_irq_save(flags); - double_rq_lock(rq_src, rq_dest); rq_dest->nr_uninterruptible += rq_src->nr_uninterruptible; rq_src->nr_uninterruptible = 0; - double_rq_unlock(rq_src, rq_dest); - local_irq_restore(flags); -} - -/* Run through task list and migrate tasks from the dead cpu. */ -static void migrate_live_tasks(int src_cpu) -{ - struct task_struct *p, *t; - - read_lock(&tasklist_lock); - - do_each_thread(t, p) { - if (p == current) - continue; - - if (task_cpu(p) == src_cpu) - move_task_off_dead_cpu(src_cpu, p); - } while_each_thread(t, p); - - read_unlock(&tasklist_lock); } /* - * Schedules idle task to be the next runnable task on current CPU. - * It does so by boosting its priority to highest possible. - * Used by CPU offline code. + * remove the tasks which were accounted by rq from calc_load_tasks. */ -void sched_idle_next(void) +static void calc_global_load_remove(struct rq *rq) { - int this_cpu = smp_processor_id(); - struct rq *rq = cpu_rq(this_cpu); - struct task_struct *p = rq->idle; - unsigned long flags; - - /* cpu has to be offline */ - BUG_ON(cpu_online(this_cpu)); - - /* - * Strictly not necessary since rest of the CPUs are stopped by now - * and interrupts disabled on the current cpu. - */ - raw_spin_lock_irqsave(&rq->lock, flags); - - __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1); - - activate_task(rq, p, 0); - - raw_spin_unlock_irqrestore(&rq->lock, flags); + atomic_long_sub(rq->calc_load_active, &calc_load_tasks); + rq->calc_load_active = 0; } /* - * Ensures that the idle task is using init_mm right before its cpu goes - * offline. + * Migrate all tasks from the rq, sleeping tasks will be migrated by + * try_to_wake_up()->select_task_rq(). + * + * Called with rq->lock held even though we'er in stop_machine() and + * there's no concurrency possible, we hold the required locks anyway + * because of lock validation efforts. */ -void idle_task_exit(void) -{ - struct mm_struct *mm = current->active_mm; - - BUG_ON(cpu_online(smp_processor_id())); - - if (mm != &init_mm) - switch_mm(mm, &init_mm, current); - mmdrop(mm); -} - -/* called under rq->lock with disabled interrupts */ -static void migrate_dead(unsigned int dead_cpu, struct task_struct *p) +static void migrate_tasks(unsigned int dead_cpu) { struct rq *rq = cpu_rq(dead_cpu); - - /* Must be exiting, otherwise would be on tasklist. */ - BUG_ON(!p->exit_state); - - /* Cannot have done final schedule yet: would have vanished. */ - BUG_ON(p->state == TASK_DEAD); - - get_task_struct(p); + struct task_struct *next, *stop = rq->stop; + int dest_cpu; /* - * Drop lock around migration; if someone else moves it, - * that's OK. No task can be added to this CPU, so iteration is - * fine. + * Fudge the rq selection such that the below task selection loop + * doesn't get stuck on the currently eligible stop task. + * + * We're currently inside stop_machine() and the rq is either stuck + * in the stop_machine_cpu_stop() loop, or we're executing this code, + * either way we should never end up calling schedule() until we're + * done here. */ - raw_spin_unlock_irq(&rq->lock); - move_task_off_dead_cpu(dead_cpu, p); - raw_spin_lock_irq(&rq->lock); - - put_task_struct(p); -} - -/* release_task() removes task from tasklist, so we won't find dead tasks. */ -static void migrate_dead_tasks(unsigned int dead_cpu) -{ - struct rq *rq = cpu_rq(dead_cpu); - struct task_struct *next; + rq->stop = NULL; for ( ; ; ) { - if (!rq->nr_running) + /* + * There's this thread running, bail when that's the only + * remaining thread. + */ + if (rq->nr_running == 1) break; + next = pick_next_task(rq); - if (!next) - break; + BUG_ON(!next); next->sched_class->put_prev_task(rq, next); - migrate_dead(dead_cpu, next); + /* Find suitable destination for @next, with force if needed. */ + dest_cpu = select_fallback_rq(dead_cpu, next); + raw_spin_unlock(&rq->lock); + + __migrate_task(next, dead_cpu, dest_cpu); + + raw_spin_lock(&rq->lock); } -} -/* - * remove the tasks which were accounted by rq from calc_load_tasks. - */ -static void calc_global_load_remove(struct rq *rq) -{ - atomic_long_sub(rq->calc_load_active, &calc_load_tasks); - rq->calc_load_active = 0; + rq->stop = stop; } + #endif /* CONFIG_HOTPLUG_CPU */ #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL) @@ -6078,15 +6007,13 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) unsigned long flags; struct rq *rq = cpu_rq(cpu); - switch (action) { + switch (action & ~CPU_TASKS_FROZEN) { case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: rq->calc_load_update = calc_load_update; break; case CPU_ONLINE: - case CPU_ONLINE_FROZEN: /* Update our root-domain */ raw_spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { @@ -6098,30 +6025,19 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) break; #ifdef CONFIG_HOTPLUG_CPU - case CPU_DEAD: - case CPU_DEAD_FROZEN: - migrate_live_tasks(cpu); - /* Idle task back to normal (off runqueue, low prio) */ - raw_spin_lock_irq(&rq->lock); - deactivate_task(rq, rq->idle, 0); - __setscheduler(rq, rq->idle, SCHED_NORMAL, 0); - rq->idle->sched_class = &idle_sched_class; - migrate_dead_tasks(cpu); - raw_spin_unlock_irq(&rq->lock); - migrate_nr_uninterruptible(rq); - BUG_ON(rq->nr_running != 0); - calc_global_load_remove(rq); - break; - case CPU_DYING: - case CPU_DYING_FROZEN: /* Update our root-domain */ raw_spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); set_rq_offline(rq); } + migrate_tasks(cpu); + BUG_ON(rq->nr_running != 1); /* the migration thread */ raw_spin_unlock_irqrestore(&rq->lock, flags); + + migrate_nr_uninterruptible(rq); + calc_global_load_remove(rq); break; #endif } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index b65bf63..c33a1ed 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -704,15 +704,6 @@ static struct ctl_table kern_table[] = { }, #endif { - .procname = "dmesg_restrict", - .data = &dmesg_restrict, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &zero, - .extra2 = &one, - }, - { .procname = "ngroups_max", .data = &ngroups_max, .maxlen = sizeof (int), diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 7b8ec02..bc251ed 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -168,6 +168,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) }; +#define BLK_TC_HARDBARRIER BLK_TC_BARRIER #define BLK_TC_RAHEAD BLK_TC_AHEAD /* The ilog2() calls fall out because they're constant */ @@ -195,6 +196,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, return; what |= ddir_act[rw & WRITE]; + what |= MASK_TC_BIT(rw, HARDBARRIER); what |= MASK_TC_BIT(rw, SYNC); what |= MASK_TC_BIT(rw, RAHEAD); what |= MASK_TC_BIT(rw, META); @@ -1805,6 +1807,8 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes) if (rw & REQ_RAHEAD) rwbs[i++] = 'A'; + if (rw & REQ_HARDBARRIER) + rwbs[i++] = 'B'; if (rw & REQ_SYNC) rwbs[i++] = 'S'; if (rw & REQ_META) diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 5086bb9..6f412ab 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -82,16 +82,6 @@ struct radix_tree_preload { }; static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; -static inline void *ptr_to_indirect(void *ptr) -{ - return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); -} - -static inline void *indirect_to_ptr(void *ptr) -{ - return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); -} - static inline gfp_t root_gfp_mask(struct radix_tree_root *root) { return root->gfp_mask & __GFP_BITS_MASK; @@ -275,7 +265,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) return -ENOMEM; /* Increase the height. */ - node->slots[0] = indirect_to_ptr(root->rnode); + node->slots[0] = radix_tree_indirect_to_ptr(root->rnode); /* Propagate the aggregated tag info into the new root */ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { @@ -286,7 +276,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) newheight = root->height+1; node->height = newheight; node->count = 1; - node = ptr_to_indirect(node); + node = radix_tree_ptr_to_indirect(node); rcu_assign_pointer(root->rnode, node); root->height = newheight; } while (height > root->height); @@ -319,7 +309,7 @@ int radix_tree_insert(struct radix_tree_root *root, return error; } - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); height = root->height; shift = (height-1) * RADIX_TREE_MAP_SHIFT; @@ -335,7 +325,8 @@ int radix_tree_insert(struct radix_tree_root *root, rcu_assign_pointer(node->slots[offset], slot); node->count++; } else - rcu_assign_pointer(root->rnode, ptr_to_indirect(slot)); + rcu_assign_pointer(root->rnode, + radix_tree_ptr_to_indirect(slot)); } /* Go a level down */ @@ -383,7 +374,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, return NULL; return is_slot ? (void *)&root->rnode : node; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); height = node->height; if (index > radix_tree_maxindex(height)) @@ -402,7 +393,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, height--; } while (height > 0); - return is_slot ? (void *)slot : indirect_to_ptr(node); + return is_slot ? (void *)slot:node; } /** @@ -464,7 +455,7 @@ void *radix_tree_tag_set(struct radix_tree_root *root, height = root->height; BUG_ON(index > radix_tree_maxindex(height)); - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); shift = (height - 1) * RADIX_TREE_MAP_SHIFT; while (height > 0) { @@ -518,7 +509,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root, shift = (height - 1) * RADIX_TREE_MAP_SHIFT; pathp->node = NULL; - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); while (height > 0) { int offset; @@ -588,7 +579,7 @@ int radix_tree_tag_get(struct radix_tree_root *root, if (!radix_tree_is_indirect_ptr(node)) return (index == 0); - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); height = node->height; if (index > radix_tree_maxindex(height)) @@ -675,7 +666,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, } shift = (height - 1) * RADIX_TREE_MAP_SHIFT; - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); /* * we fill the path from (root->height - 2) to 0, leaving the index at @@ -906,7 +897,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, results[0] = node; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -925,8 +916,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, slot = *(((void ***)results)[ret + i]); if (!slot) continue; - results[ret + nr_found] = - indirect_to_ptr(rcu_dereference_raw(slot)); + results[ret + nr_found] = rcu_dereference_raw(slot); nr_found++; } ret += nr_found; @@ -975,7 +965,7 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, results[0] = (void **)&root->rnode; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -1100,7 +1090,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, results[0] = node; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -1119,8 +1109,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, slot = *(((void ***)results)[ret + i]); if (!slot) continue; - results[ret + nr_found] = - indirect_to_ptr(rcu_dereference_raw(slot)); + results[ret + nr_found] = rcu_dereference_raw(slot); nr_found++; } ret += nr_found; @@ -1170,7 +1159,7 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, results[0] = (void **)&root->rnode; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -1206,7 +1195,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) void *newptr; BUG_ON(!radix_tree_is_indirect_ptr(to_free)); - to_free = indirect_to_ptr(to_free); + to_free = radix_tree_indirect_to_ptr(to_free); /* * The candidate node has more than one child, or its child @@ -1219,39 +1208,16 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) /* * We don't need rcu_assign_pointer(), since we are simply - * moving the node from one part of the tree to another: if it - * was safe to dereference the old pointer to it + * moving the node from one part of the tree to another. If + * it was safe to dereference the old pointer to it * (to_free->slots[0]), it will be safe to dereference the new - * one (root->rnode) as far as dependent read barriers go. + * one (root->rnode). */ newptr = to_free->slots[0]; if (root->height > 1) - newptr = ptr_to_indirect(newptr); + newptr = radix_tree_ptr_to_indirect(newptr); root->rnode = newptr; root->height--; - - /* - * We have a dilemma here. The node's slot[0] must not be - * NULLed in case there are concurrent lookups expecting to - * find the item. However if this was a bottom-level node, - * then it may be subject to the slot pointer being visible - * to callers dereferencing it. If item corresponding to - * slot[0] is subsequently deleted, these callers would expect - * their slot to become empty sooner or later. - * - * For example, lockless pagecache will look up a slot, deref - * the page pointer, and if the page is 0 refcount it means it - * was concurrently deleted from pagecache so try the deref - * again. Fortunately there is already a requirement for logic - * to retry the entire slot lookup -- the indirect pointer - * problem (replacing direct root node with an indirect pointer - * also results in a stale slot). So tag the slot as indirect - * to force callers to retry. - */ - if (root->height == 0) - *((unsigned long *)&to_free->slots[0]) |= - RADIX_TREE_INDIRECT_PTR; - radix_tree_node_free(to_free); } } @@ -1288,7 +1254,7 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) root->rnode = NULL; goto out; } - slot = indirect_to_ptr(slot); + slot = radix_tree_indirect_to_ptr(slot); shift = (height - 1) * RADIX_TREE_MAP_SHIFT; pathp->node = NULL; @@ -1330,7 +1296,8 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) radix_tree_node_free(to_free); if (pathp->node->count) { - if (pathp->node == indirect_to_ptr(root->rnode)) + if (pathp->node == + radix_tree_indirect_to_ptr(root->rnode)) radix_tree_shrink(root); goto out; } diff --git a/mm/filemap.c b/mm/filemap.c index ea89840..61ba5e4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -644,9 +644,7 @@ repeat: pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); if (pagep) { page = radix_tree_deref_slot(pagep); - if (unlikely(!page)) - goto out; - if (radix_tree_deref_retry(page)) + if (unlikely(!page || page == RADIX_TREE_RETRY)) goto repeat; if (!page_cache_get_speculative(page)) @@ -662,7 +660,6 @@ repeat: goto repeat; } } -out: rcu_read_unlock(); return page; @@ -780,11 +777,12 @@ repeat: page = radix_tree_deref_slot((void **)pages[i]); if (unlikely(!page)) continue; - if (radix_tree_deref_retry(page)) { - if (ret) - start = pages[ret-1]->index; + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) goto restart; - } if (!page_cache_get_speculative(page)) goto repeat; @@ -832,7 +830,11 @@ repeat: page = radix_tree_deref_slot((void **)pages[i]); if (unlikely(!page)) continue; - if (radix_tree_deref_retry(page)) + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) goto restart; if (page->mapping == NULL || page->index != index) @@ -885,7 +887,11 @@ repeat: page = radix_tree_deref_slot((void **)pages[i]); if (unlikely(!page)) continue; - if (radix_tree_deref_retry(page)) + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) goto restart; if (!page_cache_get_speculative(page)) @@ -1023,9 +1029,6 @@ find_page: goto page_not_up_to_date; if (!trylock_page(page)) goto page_not_up_to_date; - /* Did it get truncated before we got the lock? */ - if (!page->mapping) - goto page_not_up_to_date_locked; if (!mapping->a_ops->is_partially_uptodate(page, desc, offset)) goto page_not_up_to_date_locked; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 2efa8ea..9a99cfa 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4208,17 +4208,15 @@ static struct mem_cgroup *mem_cgroup_alloc(void) memset(mem, 0, size); mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu); - if (!mem->stat) - goto out_free; + if (!mem->stat) { + if (size < PAGE_SIZE) + kfree(mem); + else + vfree(mem); + mem = NULL; + } spin_lock_init(&mem->pcp_counter_lock); return mem; - -out_free: - if (size < PAGE_SIZE) - kfree(mem); - else - vfree(mem); - return NULL; } /* diff --git a/mm/mprotect.c b/mm/mprotect.c index 4c51338..2d1bf7c 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -211,7 +211,6 @@ success: mmu_notifier_invalidate_range_end(mm, start, end); vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); vm_stat_account(mm, newflags, vma->vm_file, nrpages); - perf_event_mmap(vma); return 0; fail: @@ -300,6 +299,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); if (error) goto out; + perf_event_mmap(vma); nstart = tmp; if (nstart < prev->vm_end) diff --git a/mm/slub.c b/mm/slub.c index 981fb73..8fd5401 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3273,9 +3273,9 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, kfree(n); kfree(s); } -err: up_write(&slub_lock); +err: if (flags & SLAB_PANIC) panic("Cannot create slabcache %s\n", name); else @@ -3862,7 +3862,6 @@ static ssize_t show_slab_objects(struct kmem_cache *s, x += sprintf(buf + x, " N%d=%lu", node, nodes[node]); #endif - up_read(&slub_lock); kfree(nodes); return x + sprintf(buf + x, "\n"); } diff --git a/mm/vmscan.c b/mm/vmscan.c index d31d7ce..b8a6fdc 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -913,7 +913,7 @@ keep_lumpy: * back off and wait for congestion to clear because further reclaim * will encounter the same problem */ - if (nr_dirty == nr_congested && nr_dirty != 0) + if (nr_dirty == nr_congested) zone_set_flag(zone, ZONE_CONGESTED); free_page_list(&free_pages); diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index bb86d29..26eaebf 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1392,7 +1392,6 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, ax25_cb *ax25; int err = 0; - memset(fsa, 0, sizeof(fsa)); lock_sock(sk); ax25 = ax25_sk(sk); @@ -1404,6 +1403,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, fsa->fsa_ax25.sax25_family = AF_AX25; fsa->fsa_ax25.sax25_call = ax25->dest_addr; + fsa->fsa_ax25.sax25_ndigis = 0; if (ax25->digipeat != NULL) { ndigi = ax25->digipeat->ndigi; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 84093b0..bfef5ba 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1175,12 +1175,6 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, sizeof(cp), &cp); - } else if (!ev->status && conn->out && - conn->sec_level == BT_SECURITY_HIGH) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); } else { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 86a9154..98fdfa1 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig @@ -1,6 +1,6 @@ config BT_HIDP tristate "HIDP protocol support" - depends on BT && BT_L2CAP && INPUT && HID_SUPPORT + depends on BT && BT_L2CAP && INPUT select HID help HIDP (Human Interface Device Protocol) is a transport layer diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index cd8f6ea..daa7a98 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -2421,11 +2421,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned break; case 2: - *val = get_unaligned_le16(opt->val); + *val = __le16_to_cpu(*((__le16 *) opt->val)); break; case 4: - *val = get_unaligned_le32(opt->val); + *val = __le32_to_cpu(*((__le32 *) opt->val)); break; default: @@ -2452,11 +2452,11 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) break; case 2: - put_unaligned_le16(val, opt->val); + *((__le16 *) opt->val) = cpu_to_le16(val); break; case 4: - put_unaligned_le32(val, opt->val); + *((__le32 *) opt->val) = cpu_to_le32(val); break; default: diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fa642aa..39a5d87 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -79,10 +79,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr); static void rfcomm_process_connect(struct rfcomm_session *s); -static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, - bdaddr_t *dst, - u8 sec_level, - int *err); +static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err); static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst); static void rfcomm_session_del(struct rfcomm_session *s); @@ -404,7 +401,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, s = rfcomm_session_get(src, dst); if (!s) { - s = rfcomm_session_create(src, dst, d->sec_level, &err); + s = rfcomm_session_create(src, dst, &err); if (!s) return err; } @@ -682,10 +679,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err) rfcomm_session_put(s); } -static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, - bdaddr_t *dst, - u8 sec_level, - int *err) +static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err) { struct rfcomm_session *s = NULL; struct sockaddr_l2 addr; @@ -710,7 +704,6 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, sk = sock->sk; lock_sock(sk); l2cap_pi(sk)->imtu = l2cap_mtu; - l2cap_pi(sk)->sec_level = sec_level; if (l2cap_ertm) l2cap_pi(sk)->mode = L2CAP_MODE_ERTM; release_sock(sk); diff --git a/net/can/bcm.c b/net/can/bcm.c index 6faa825..08ffe9e 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -125,7 +125,7 @@ struct bcm_sock { struct list_head tx_ops; unsigned long dropped_usr_msgs; struct proc_dir_entry *bcm_proc_read; - char procname [20]; /* pointer printed in ASCII with \0 */ + char procname [9]; /* pointer printed in ASCII with \0 */ }; static inline struct bcm_sock *bcm_sk(const struct sock *sk) diff --git a/net/core/dst.c b/net/core/dst.c index b99c7c7..8abe628 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -370,7 +370,6 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, static struct notifier_block dst_dev_notifier = { .notifier_call = dst_dev_event, - .priority = -10, /* must be called after other network notifiers */ }; void __init dst_init(void) diff --git a/net/core/filter.c b/net/core/filter.c index 23e9b2a..7beaec3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -112,41 +112,39 @@ EXPORT_SYMBOL(sk_filter); */ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) { + struct sock_filter *fentry; /* We walk down these */ void *ptr; u32 A = 0; /* Accumulator */ u32 X = 0; /* Index Register */ u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ - unsigned long memvalid = 0; u32 tmp; int k; int pc; - BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG); /* * Process array of filter instructions. */ for (pc = 0; pc < flen; pc++) { - const struct sock_filter *fentry = &filter[pc]; - u32 f_k = fentry->k; + fentry = &filter[pc]; switch (fentry->code) { case BPF_S_ALU_ADD_X: A += X; continue; case BPF_S_ALU_ADD_K: - A += f_k; + A += fentry->k; continue; case BPF_S_ALU_SUB_X: A -= X; continue; case BPF_S_ALU_SUB_K: - A -= f_k; + A -= fentry->k; continue; case BPF_S_ALU_MUL_X: A *= X; continue; case BPF_S_ALU_MUL_K: - A *= f_k; + A *= fentry->k; continue; case BPF_S_ALU_DIV_X: if (X == 0) @@ -154,49 +152,49 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int A /= X; continue; case BPF_S_ALU_DIV_K: - A /= f_k; + A /= fentry->k; continue; case BPF_S_ALU_AND_X: A &= X; continue; case BPF_S_ALU_AND_K: - A &= f_k; + A &= fentry->k; continue; case BPF_S_ALU_OR_X: A |= X; continue; case BPF_S_ALU_OR_K: - A |= f_k; + A |= fentry->k; continue; case BPF_S_ALU_LSH_X: A <<= X; continue; case BPF_S_ALU_LSH_K: - A <<= f_k; + A <<= fentry->k; continue; case BPF_S_ALU_RSH_X: A >>= X; continue; case BPF_S_ALU_RSH_K: - A >>= f_k; + A >>= fentry->k; continue; case BPF_S_ALU_NEG: A = -A; continue; case BPF_S_JMP_JA: - pc += f_k; + pc += fentry->k; continue; case BPF_S_JMP_JGT_K: - pc += (A > f_k) ? fentry->jt : fentry->jf; + pc += (A > fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGE_K: - pc += (A >= f_k) ? fentry->jt : fentry->jf; + pc += (A >= fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JEQ_K: - pc += (A == f_k) ? fentry->jt : fentry->jf; + pc += (A == fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JSET_K: - pc += (A & f_k) ? fentry->jt : fentry->jf; + pc += (A & fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGT_X: pc += (A > X) ? fentry->jt : fentry->jf; @@ -211,7 +209,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int pc += (A & X) ? fentry->jt : fentry->jf; continue; case BPF_S_LD_W_ABS: - k = f_k; + k = fentry->k; load_w: ptr = load_pointer(skb, k, 4, &tmp); if (ptr != NULL) { @@ -220,7 +218,7 @@ load_w: } break; case BPF_S_LD_H_ABS: - k = f_k; + k = fentry->k; load_h: ptr = load_pointer(skb, k, 2, &tmp); if (ptr != NULL) { @@ -229,7 +227,7 @@ load_h: } break; case BPF_S_LD_B_ABS: - k = f_k; + k = fentry->k; load_b: ptr = load_pointer(skb, k, 1, &tmp); if (ptr != NULL) { @@ -244,34 +242,32 @@ load_b: X = skb->len; continue; case BPF_S_LD_W_IND: - k = X + f_k; + k = X + fentry->k; goto load_w; case BPF_S_LD_H_IND: - k = X + f_k; + k = X + fentry->k; goto load_h; case BPF_S_LD_B_IND: - k = X + f_k; + k = X + fentry->k; goto load_b; case BPF_S_LDX_B_MSH: - ptr = load_pointer(skb, f_k, 1, &tmp); + ptr = load_pointer(skb, fentry->k, 1, &tmp); if (ptr != NULL) { X = (*(u8 *)ptr & 0xf) << 2; continue; } return 0; case BPF_S_LD_IMM: - A = f_k; + A = fentry->k; continue; case BPF_S_LDX_IMM: - X = f_k; + X = fentry->k; continue; case BPF_S_LD_MEM: - A = (memvalid & (1UL << f_k)) ? - mem[f_k] : 0; + A = mem[fentry->k]; continue; case BPF_S_LDX_MEM: - X = (memvalid & (1UL << f_k)) ? - mem[f_k] : 0; + X = mem[fentry->k]; continue; case BPF_S_MISC_TAX: X = A; @@ -280,16 +276,14 @@ load_b: A = X; continue; case BPF_S_RET_K: - return f_k; + return fentry->k; case BPF_S_RET_A: return A; case BPF_S_ST: - memvalid |= 1UL << f_k; - mem[f_k] = A; + mem[fentry->k] = A; continue; case BPF_S_STX: - memvalid |= 1UL << f_k; - mem[f_k] = X; + mem[fentry->k] = X; continue; default: WARN_ON(1); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 33bc382..fbce4b0 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -887,7 +887,7 @@ static ssize_t pktgen_if_write(struct file *file, i += len; if (debug) { - size_t copy = min_t(size_t, count, 1023); + size_t copy = min(count, 1023); char tb[copy + 1]; if (copy_from_user(tb, user_buffer, copy)) return -EFAULT; @@ -2612,8 +2612,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, /* Update any of the values, used when we're incrementing various * fields. */ - mod_cur_headers(pkt_dev); queue_map = pkt_dev->cur_queue_map; + mod_cur_headers(pkt_dev); datalen = (odev->hard_header_len + 16) & ~0xf; @@ -2976,8 +2976,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, /* Update any of the values, used when we're incrementing various * fields. */ - mod_cur_headers(pkt_dev); queue_map = pkt_dev->cur_queue_map; + mod_cur_headers(pkt_dev); skb = __netdev_alloc_skb(odev, pkt_dev->cur_pkt_size + 64 diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 841c287..8121268 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -347,17 +347,16 @@ static size_t rtnl_link_get_size(const struct net_device *dev) if (!ops) return 0; - size = nla_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */ - nla_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */ + size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */ + nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */ if (ops->get_size) /* IFLA_INFO_DATA + nested data */ - size += nla_total_size(sizeof(struct nlattr)) + + size += nlmsg_total_size(sizeof(struct nlattr)) + ops->get_size(dev); if (ops->get_xstats_size) - /* IFLA_INFO_XSTATS */ - size += nla_total_size(ops->get_xstats_size(dev)); + size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */ return size; } diff --git a/net/core/sock.c b/net/core/sock.c index fb60801..3eed542 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1653,10 +1653,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) { struct proto *prot = sk->sk_prot; int amt = sk_mem_pages(size); - long allocated; + int allocated; sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; - allocated = atomic_long_add_return(amt, prot->memory_allocated); + allocated = atomic_add_return(amt, prot->memory_allocated); /* Under limit. */ if (allocated <= prot->sysctl_mem[0]) { @@ -1714,7 +1714,7 @@ suppress_allocation: /* Alas. Undo changes. */ sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; - atomic_long_sub(amt, prot->memory_allocated); + atomic_sub(amt, prot->memory_allocated); return 0; } EXPORT_SYMBOL(__sk_mem_schedule); @@ -1727,12 +1727,12 @@ void __sk_mem_reclaim(struct sock *sk) { struct proto *prot = sk->sk_prot; - atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, + atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, prot->memory_allocated); sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; if (prot->memory_pressure && *prot->memory_pressure && - (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0])) + (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) *prot->memory_pressure = 0; } EXPORT_SYMBOL(__sk_mem_reclaim); @@ -2452,12 +2452,12 @@ static char proto_method_implemented(const void *method) static void proto_seq_printf(struct seq_file *seq, struct proto *proto) { - seq_printf(seq, "%-9s %4u %6d %6ld %-3s %6u %-3s %-10s " + seq_printf(seq, "%-9s %4u %6d %6d %-3s %6u %-3s %-10s " "%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n", proto->name, proto->obj_size, sock_prot_inuse_get(seq_file_net(seq), proto), - proto->memory_allocated != NULL ? atomic_long_read(proto->memory_allocated) : -1L, + proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1, proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI", proto->max_header, proto->slab == NULL ? "no" : "yes", diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index a76b78d..d6b93d1 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -155,7 +155,7 @@ static const struct proto_ops dn_proto_ops; static DEFINE_RWLOCK(dn_hash_lock); static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; static struct hlist_head dn_wild_sk; -static atomic_long_t decnet_memory_allocated; +static atomic_t decnet_memory_allocated; static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags); static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 28f8b5e..be3eb8e 100644 --- a/net/decnet/sysctl_net_decnet.c +++ b/net/decnet/sysctl_net_decnet.c @@ -38,7 +38,7 @@ int decnet_log_martians = 1; int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW; /* Reasonable defaults, I hope, based on tcp's defaults */ -long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; +int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; @@ -324,7 +324,7 @@ static ctl_table dn_table[] = { .data = &sysctl_decnet_mem, .maxlen = sizeof(sysctl_decnet_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax + .proc_handler = proc_dointvec, }, { .procname = "decnet_rmem", diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 3c53c2d..c8877c6 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2306,8 +2306,10 @@ void ip_mc_drop_socket(struct sock *sk) in_dev = inetdev_by_index(net, iml->multi.imr_ifindex); (void) ip_mc_leave_src(sk, iml, in_dev); - if (in_dev != NULL) + if (in_dev != NULL) { ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); + in_dev_put(in_dev); + } /* decrease mem now to avoid the memleak warning */ atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); call_rcu(&iml->rcu, ip_mc_socklist_reclaim); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b48eb1..4ae1f20 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -59,13 +59,13 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) local_bh_enable(); socket_seq_show(seq); - seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n", + seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", sock_prot_inuse_get(net, &tcp_prot), orphans, tcp_death_row.tw_count, sockets, - atomic_long_read(&tcp_memory_allocated)); - seq_printf(seq, "UDP: inuse %d mem %ld\n", + atomic_read(&tcp_memory_allocated)); + seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(net, &udp_prot), - atomic_long_read(&udp_memory_allocated)); + atomic_read(&udp_memory_allocated)); seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(net, &udplite_prot)); seq_printf(seq, "RAW: inuse %d\n", diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index e91911d..d96c1da 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -398,7 +398,7 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_tcp_mem, .maxlen = sizeof(sysctl_tcp_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax + .proc_handler = proc_dointvec }, { .procname = "tcp_wmem", @@ -602,7 +602,8 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_udp_mem, .maxlen = sizeof(sysctl_udp_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero }, { .procname = "udp_rmem_min", diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0814199..1664a05 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -282,7 +282,7 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; struct percpu_counter tcp_orphan_count; EXPORT_SYMBOL_GPL(tcp_orphan_count); -long sysctl_tcp_mem[3] __read_mostly; +int sysctl_tcp_mem[3] __read_mostly; int sysctl_tcp_wmem[3] __read_mostly; int sysctl_tcp_rmem[3] __read_mostly; @@ -290,7 +290,7 @@ EXPORT_SYMBOL(sysctl_tcp_mem); EXPORT_SYMBOL(sysctl_tcp_rmem); EXPORT_SYMBOL(sysctl_tcp_wmem); -atomic_long_t tcp_memory_allocated; /* Current allocated memory. */ +atomic_t tcp_memory_allocated; /* Current allocated memory. */ EXPORT_SYMBOL(tcp_memory_allocated); /* @@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, /* Values greater than interface MTU won't take effect. However * at the point when this call is done we typically don't yet * know which interface is going to be used */ - if (val < 64 || val > MAX_TCP_WINDOW) { + if (val < 8 || val > MAX_TCP_WINDOW) { err = -EINVAL; break; } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6d8ab1c..3357f69 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -259,11 +259,8 @@ static void tcp_fixup_sndbuf(struct sock *sk) int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff); - if (sk->sk_sndbuf < 3 * sndmem) { - sk->sk_sndbuf = 3 * sndmem; - if (sk->sk_sndbuf > sysctl_tcp_wmem[2]) - sk->sk_sndbuf = sysctl_tcp_wmem[2]; - } + if (sk->sk_sndbuf < 3 * sndmem) + sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -399,7 +396,7 @@ static void tcp_clamp_window(struct sock *sk) if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && !tcp_memory_pressure && - atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), sysctl_tcp_rmem[2]); } @@ -4864,7 +4861,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk) return 0; /* If we are under soft global TCP memory pressure, do not expand. */ - if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) + if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) return 0; /* If we filled the congestion window, do not expand. */ diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 69ccbc1..8f8527d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -415,9 +415,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) !icsk->icsk_backoff) break; - if (sock_owned_by_user(sk)) - break; - icsk->icsk_backoff--; inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << icsk->icsk_backoff; @@ -432,6 +429,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) if (remaining) { inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, remaining, TCP_RTO_MAX); + } else if (sock_owned_by_user(sk)) { + /* RTO revert clocked out retransmission, + * but socket is locked. Will defer. */ + inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, + HZ/20, TCP_RTO_MAX); } else { /* RTO revert clocked out retransmission. * Will retransmit now */ diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5e0a3a5..28cb2d7 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -110,7 +110,7 @@ struct udp_table udp_table __read_mostly; EXPORT_SYMBOL(udp_table); -long sysctl_udp_mem[3] __read_mostly; +int sysctl_udp_mem[3] __read_mostly; EXPORT_SYMBOL(sysctl_udp_mem); int sysctl_udp_rmem_min __read_mostly; @@ -119,7 +119,7 @@ EXPORT_SYMBOL(sysctl_udp_rmem_min); int sysctl_udp_wmem_min __read_mostly; EXPORT_SYMBOL(sysctl_udp_wmem_min); -atomic_long_t udp_memory_allocated; +atomic_t udp_memory_allocated; EXPORT_SYMBOL(udp_memory_allocated); #define MAX_UDP_PORTS 65536 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b41ce0f..e048ec6 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2740,6 +2740,10 @@ static int addrconf_ifdown(struct net_device *dev, int how) /* Flag it for later restoration when link comes up */ ifa->flags |= IFA_F_TENTATIVE; ifa->state = INET6_IFADDR_STATE_DAD; + + write_unlock_bh(&idev->lock); + + in6_ifa_hold(ifa); } else { list_del(&ifa->if_list); @@ -2754,15 +2758,19 @@ static int addrconf_ifdown(struct net_device *dev, int how) ifa->state = INET6_IFADDR_STATE_DEAD; spin_unlock_bh(&ifa->state_lock); - if (state == INET6_IFADDR_STATE_DEAD) { - in6_ifa_put(ifa); - } else { - __ipv6_ifa_notify(RTM_DELADDR, ifa); - atomic_notifier_call_chain(&inet6addr_chain, - NETDEV_DOWN, ifa); - } - write_lock_bh(&idev->lock); + if (state == INET6_IFADDR_STATE_DEAD) + goto put_ifa; } + + __ipv6_ifa_notify(RTM_DELADDR, ifa); + if (ifa->state == INET6_IFADDR_STATE_DEAD) + atomic_notifier_call_chain(&inet6addr_chain, + NETDEV_DOWN, ifa); + +put_ifa: + in6_ifa_put(ifa); + + write_lock_bh(&idev->lock); } list_splice(&keep_list, &idev->addr_list); diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 79d43aa..3a3f129 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -286,7 +286,7 @@ found: /* Check for overlap with preceding fragment. */ if (prev && - (NFCT_FRAG6_CB(prev)->offset + prev->len) > offset) + (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0) goto discard_fq; /* Look for overlap with succeeding segment. */ diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 0f27664..c7ba314 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -349,7 +349,7 @@ found: /* Check for overlap with preceding fragment. */ if (prev && - (FRAG6_CB(prev)->offset + prev->len) > offset) + (FRAG6_CB(prev)->offset + prev->len) - offset > 0) goto discard_fq; /* Look for overlap with succeeding segment. */ diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 96455ff..fc32833 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1945,12 +1945,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); struct neighbour *neigh; - if (rt == NULL) { - if (net_ratelimit()) - pr_warning("IPv6: Maximum number of routes reached," - " consider increasing route/max_size.\n"); + if (rt == NULL) return ERR_PTR(-ENOMEM); - } dev_hold(net->loopback_dev); in6_dev_hold(idev); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7aa8559..f9163b1 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -391,9 +391,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, u32 hw_reconf_flags = 0; int i; - if (local->scan_sdata == sdata) - ieee80211_scan_cancel(local); - clear_bit(SDATA_STATE_RUNNING, &sdata->state); /* @@ -526,6 +523,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, synchronize_rcu(); skb_queue_purge(&sdata->skb_queue); + if (local->scan_sdata == sdata) + ieee80211_scan_cancel(local); + /* * Disable beaconing here for mesh only, AP and IBSS * are already taken care of. diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8298e67..3616f27 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1610,11 +1610,9 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, err = -EINVAL; vnet_hdr_len = sizeof(vnet_hdr); - if (len < vnet_hdr_len) + if ((len -= vnet_hdr_len) < 0) goto out_free; - len -= vnet_hdr_len; - if (skb_is_gso(skb)) { struct skb_shared_info *sinfo = skb_shinfo(skb); @@ -1721,7 +1719,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); if (dev) - strncpy(uaddr->sa_data, dev->name, 14); + strlcpy(uaddr->sa_data, dev->name, 15); else memset(uaddr->sa_data, 0, 14); rcu_read_unlock(); @@ -1744,7 +1742,6 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, sll->sll_family = AF_PACKET; sll->sll_ifindex = po->ifindex; sll->sll_protocol = po->num; - sll->sll_pkttype = 0; rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex); if (dev) { diff --git a/net/rds/message.c b/net/rds/message.c index 1fd3d29..848cff4 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -249,10 +249,8 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); rm->data.op_nents = ceil(total_len, PAGE_SIZE); rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); - if (!rm->data.op_sg) { - rds_message_put(rm); + if (!rm->data.op_sg) return ERR_PTR(-ENOMEM); - } for (i = 0; i < rm->data.op_nents; ++i) { sg_set_page(&rm->data.op_sg[i], diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index f23d915..efd4f95 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -268,10 +268,6 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; nla_nest_end(skb, nest); - - if (tcf_exts_dump_stats(skb, &f->exts, &basic_ext_map) < 0) - goto nla_put_failure; - return skb->len; nla_put_failure: diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index e58f947..1ef29c7 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -92,7 +92,7 @@ static struct sctp_af *sctp_af_v6_specific; struct kmem_cache *sctp_chunk_cachep __read_mostly; struct kmem_cache *sctp_bucket_cachep __read_mostly; -long sysctl_sctp_mem[3]; +int sysctl_sctp_mem[3]; int sysctl_sctp_rmem[3]; int sysctl_sctp_wmem[3]; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6bd5543..e34ca9c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -111,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *, static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; extern struct kmem_cache *sctp_bucket_cachep; -extern long sysctl_sctp_mem[3]; +extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_wmem[3]; static int sctp_memory_pressure; -static atomic_long_t sctp_memory_allocated; +static atomic_t sctp_memory_allocated; struct percpu_counter sctp_sockets_allocated; static void sctp_enter_memory_pressure(struct sock *sk) diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 50cb57f..832590b 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -54,7 +54,7 @@ static int sack_timer_max = 500; static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ static int rwnd_scale_max = 16; -extern long sysctl_sctp_mem[3]; +extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_wmem[3]; @@ -203,7 +203,7 @@ static ctl_table sctp_table[] = { .data = &sysctl_sctp_mem, .maxlen = sizeof(sysctl_sctp_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax + .proc_handler = proc_dointvec, }, { .procname = "sctp_rmem", diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e9f0d50..33217fc 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -396,7 +396,6 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; struct tipc_sock *tsock = tipc_sk(sock->sk); - memset(addr, 0, sizeof(*addr)); if (peer) { if ((sock->state != SS_CONNECTED) && ((peer != 2) || (sock->state != SS_DISCONNECTING))) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4e78e3f..c506241 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -224,8 +224,8 @@ static int nl80211_prepare_netdev_dump(struct sk_buff *skb, } *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(*rdev)) { - err = PTR_ERR(*rdev); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); goto out_rtnl; } diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 55187c8..3a8c4c4 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -61,8 +61,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, while (len > 0) { switch (*p & X25_FAC_CLASS_MASK) { case X25_FAC_CLASS_A: - if (len < 2) - return 0; switch (*p) { case X25_FAC_REVERSE: if((p[1] & 0x81) == 0x81) { @@ -106,8 +104,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 2; break; case X25_FAC_CLASS_B: - if (len < 3) - return 0; switch (*p) { case X25_FAC_PACKET_SIZE: facilities->pacsize_in = p[1]; @@ -129,8 +125,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 3; break; case X25_FAC_CLASS_C: - if (len < 4) - return 0; printk(KERN_DEBUG "X.25: unknown facility %02X, " "values %02X, %02X, %02X\n", p[0], p[1], p[2], p[3]); @@ -138,8 +132,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 4; break; case X25_FAC_CLASS_D: - if (len < p[1] + 2) - return 0; switch (*p) { case X25_FAC_CALLING_AE: if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) @@ -157,7 +149,9 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, break; default: printk(KERN_DEBUG "X.25: unknown facility %02X," - "length %d\n", p[0], p[1]); + "length %d, values %02X, %02X, " + "%02X, %02X\n", + p[0], p[1], p[2], p[3], p[4], p[5]); break; } len -= p[1] + 2; diff --git a/security/Kconfig b/security/Kconfig index e80da95..bd72ae6 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -39,18 +39,6 @@ config KEYS_DEBUG_PROC_KEYS If you are unsure as to whether this is required, answer N. -config SECURITY_DMESG_RESTRICT - bool "Restrict unprivileged access to the kernel syslog" - default n - help - This enforces restrictions on unprivileged users reading the kernel - syslog via dmesg(8). - - If this option is not selected, no restrictions will be enforced - unless the dmesg_restrict sysctl is explicitly set to (1). - - If you are unsure how to answer this question, answer N. - config SECURITY bool "Enable different security models" depends on SYSFS diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index b7106f1..cf1de44 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -922,7 +922,7 @@ static int __init apparmor_init(void) error = register_security(&apparmor_ops); if (error) { AA_ERROR("Unable to register AppArmor\n"); - goto set_init_cxt_out; + goto register_security_out; } /* Report that AppArmor successfully initialized */ @@ -936,9 +936,6 @@ static int __init apparmor_init(void) return error; -set_init_cxt_out: - aa_free_task_context(current->real_cred->security); - register_security_out: aa_free_root_ns(); @@ -947,6 +944,7 @@ alloc_out: apparmor_enabled = 0; return error; + } security_initcall(apparmor_init); diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 4f0eade..52cc865 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -306,7 +306,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix, return ns; fail_unconfined: - kzfree(ns->base.hname); + kzfree(ns->base.name); fail_ns: kzfree(ns); return NULL; diff --git a/security/capability.c b/security/capability.c index c773635..30ae00f 100644 --- a/security/capability.c +++ b/security/capability.c @@ -17,11 +17,6 @@ static int cap_sysctl(ctl_table *table, int op) return 0; } -static int cap_syslog(int type) -{ - return 0; -} - static int cap_quotactl(int cmds, int type, int id, struct super_block *sb) { return 0; diff --git a/security/commoncap.c b/security/commoncap.c index 64c2ed9..5e632b4 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -27,6 +27,7 @@ #include #include #include +#include /* * If a non-root user executes a setuid-root binary in @@ -883,6 +884,24 @@ error: } /** + * cap_syslog - Determine whether syslog function is permitted + * @type: Function requested + * @from_file: Whether this request came from an open file (i.e. /proc) + * + * Determine whether the current process is permitted to use a particular + * syslog function, returning 0 if permission is granted, -ve if not. + */ +int cap_syslog(int type, bool from_file) +{ + if (type != SYSLOG_ACTION_OPEN && from_file) + return 0; + if ((type != SYSLOG_ACTION_READ_ALL && + type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) + return -EPERM; + return 0; +} + +/** * cap_vm_enough_memory - Determine whether a new virtual mapping is permitted * @mm: The VM space in which the new mapping is to be made * @pages: The size of the mapping diff --git a/security/security.c b/security/security.c index 1b798d3..3ef5e2a 100644 --- a/security/security.c +++ b/security/security.c @@ -197,9 +197,9 @@ int security_quota_on(struct dentry *dentry) return security_ops->quota_on(dentry); } -int security_syslog(int type) +int security_syslog(int type, bool from_file) { - return security_ops->syslog(type); + return security_ops->syslog(type, from_file); } int security_settime(struct timespec *ts, struct timezone *tz) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 65fa8bf..d9154cf 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1973,10 +1973,14 @@ static int selinux_quota_on(struct dentry *dentry) return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); } -static int selinux_syslog(int type) +static int selinux_syslog(int type, bool from_file) { int rc; + rc = cap_syslog(type, from_file); + if (rc) + return rc; + switch (type) { case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */ case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 489a85a..bc39f40 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -157,11 +157,15 @@ static int smack_ptrace_traceme(struct task_struct *ptp) * * Returns 0 on success, error code otherwise. */ -static int smack_syslog(int typefrom_file) +static int smack_syslog(int type, bool from_file) { - int rc = 0; + int rc; char *sp = current_security(); + rc = cap_syslog(type, from_file); + if (rc != 0) + return rc; + if (capable(CAP_MAC_OVERRIDE)) return 0; diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 26aff6b..122ec9d 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -8,11 +8,7 @@ perf-trace - Read perf.data (created by perf record) and display trace output SYNOPSIS -------- [verse] -'perf trace' [] -'perf trace' [] record