diff options
297 files changed, 2367 insertions, 1809 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 428676cfa61..25be3250f7d 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -133,46 +133,6 @@ Description: The symbolic link points to the PCI device sysfs entry of the Physical Function this device associates with. - -What: /sys/bus/pci/slots/... -Date: April 2005 (possibly older) -KernelVersion: 2.6.12 (possibly older) -Contact: linux-pci@vger.kernel.org -Description: - When the appropriate driver is loaded, it will create a - directory per claimed physical PCI slot in - /sys/bus/pci/slots/. The names of these directories are - specific to the driver, which in turn, are specific to the - platform, but in general, should match the label on the - machine's physical chassis. - - The drivers that can create slot directories include the - PCI hotplug drivers, and as of 2.6.27, the pci_slot driver. - - The slot directories contain, at a minimum, a file named - 'address' which contains the PCI bus:device:function tuple. - Other files may appear as well, but are specific to the - driver. - -What: /sys/bus/pci/slots/.../function[0-7] -Date: March 2010 -KernelVersion: 2.6.35 -Contact: linux-pci@vger.kernel.org -Description: - If PCI slot directories (as described above) are created, - and the physical slot is actually populated with a device, - symbolic links in the slot directory pointing to the - device's PCI functions are created as well. - -What: /sys/bus/pci/devices/.../slot -Date: March 2010 -KernelVersion: 2.6.35 -Contact: linux-pci@vger.kernel.org -Description: - If PCI slot directories (as described above) are created, - a symbolic link pointing to the slot directory will be - created as well. - What: /sys/bus/pci/slots/.../module Date: June 2009 Contact: linux-pci@vger.kernel.org diff --git a/MAINTAINERS b/MAINTAINERS index 67accd730ac..b15f01e3a0d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1581,7 +1581,7 @@ F: include/linux/coda*.h COMMON INTERNET FILE SYSTEM (CIFS) M: Steve French <sfrench@samba.org> -L: linux-cifs-client@lists.samba.org (moderated for non-subscribers) +L: linux-cifs@vger.kernel.org L: samba-technical@lists.samba.org (moderated for non-subscribers) W: http://linux-cifs.samba.org/ Q: http://patchwork.ozlabs.org/project/linux-cifs-client/list/ @@ -2978,7 +2978,6 @@ F: drivers/net/ixgb/ F: drivers/net/ixgbe/ INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT -M: Zhu Yi <yi.zhu@intel.com> M: Reinette Chatre <reinette.chatre@intel.com> M: Intel Linux Wireless <ilw@linux.intel.com> L: linux-wireless@vger.kernel.org @@ -2988,7 +2987,6 @@ F: Documentation/networking/README.ipw2100 F: drivers/net/wireless/ipw2x00/ipw2100.* INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT -M: Zhu Yi <yi.zhu@intel.com> M: Reinette Chatre <reinette.chatre@intel.com> M: Intel Linux Wireless <ilw@linux.intel.com> L: linux-wireless@vger.kernel.org @@ -3019,8 +3017,8 @@ F: drivers/net/wimax/i2400m/ F: include/linux/wimax/i2400m.h INTEL WIRELESS WIFI LINK (iwlwifi) -M: Zhu Yi <yi.zhu@intel.com> M: Reinette Chatre <reinette.chatre@intel.com> +M: Wey-Yi Guy <wey-yi.w.guy@intel.com> M: Intel Linux Wireless <ilw@linux.intel.com> L: linux-wireless@vger.kernel.org W: http://intellinuxwireless.org @@ -3030,7 +3028,6 @@ F: drivers/net/wireless/iwlwifi/ INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi) M: Samuel Ortiz <samuel.ortiz@intel.com> -M: Zhu Yi <yi.zhu@intel.com> M: Intel Linux Wireless <ilw@linux.intel.com> L: linux-wireless@vger.kernel.org S: Supported @@ -4215,6 +4212,7 @@ OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Grant Likely <grant.likely@secretlab.ca> L: devicetree-discuss@lists.ozlabs.org W: http://fdt.secretlab.ca +T: git git://git.secretlab.ca/git/linux-2.6.git S: Maintained F: drivers/of F: include/linux/of*.h @@ -5387,6 +5385,7 @@ M: David Brownell <dbrownell@users.sourceforge.net> M: Grant Likely <grant.likely@secretlab.ca> L: spi-devel-general@lists.sourceforge.net Q: http://patchwork.kernel.org/project/spi-devel-general/list/ +T: git git://git.secretlab.ca/git/linux-2.6.git S: Maintained F: Documentation/spi/ F: drivers/spi/ @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 35 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Sheep on Meth # *DOCUMENTATION* @@ -944,7 +944,7 @@ ifdef CONFIG_LOCALVERSION_AUTO localver-extra = $(scm-identifier) else ifneq ($(scm-identifier),) - ifeq ($(LOCALVERSION),) + ifeq ("$(origin LOCALVERSION)", "undefined") localver-extra = + endif endif @@ -1095,7 +1095,7 @@ all: modules # using awk while concatenating to the final file. PHONY += modules -modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) +modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost @@ -1117,7 +1117,7 @@ PHONY += modules_install modules_install: _modinst_ _modinst_post PHONY += _modinst_ -_modinst_: modules.builtin +_modinst_: @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \ echo "Warning: you may need to install module-init-tools"; \ echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\ diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h index 1dce24bc455..adfab8a21df 100644 --- a/arch/alpha/include/asm/bitops.h +++ b/arch/alpha/include/asm/bitops.h @@ -410,7 +410,7 @@ static inline unsigned long __arch_hweight64(unsigned long w) return __kernel_ctpop(w); } -static inline unsigned int __arch_weight32(unsigned int w) +static inline unsigned int __arch_hweight32(unsigned int w) { return __arch_hweight64(w); } diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 7739a62440a..5a62fb46ef2 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -35,7 +35,7 @@ endif obj-y += irq_pyxis.o irq_i8259.o irq_srm.o obj-y += err_ev6.o -obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o +obj-y += es1888.o smc37c669.o smc37c93x.o pc873xx.o gct.o obj-y += srmcons.o else @@ -63,11 +63,11 @@ obj-$(CONFIG_ALPHA_WILDFIRE) += core_wildfire.o # Board support obj-$(CONFIG_ALPHA_ALCOR) += sys_alcor.o irq_i8259.o irq_srm.o obj-$(CONFIG_ALPHA_CABRIOLET) += sys_cabriolet.o irq_i8259.o irq_srm.o \ - ns87312.o + pc873xx.o obj-$(CONFIG_ALPHA_EB164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ - ns87312.o + pc873xx.o obj-$(CONFIG_ALPHA_EB66P) += sys_cabriolet.o irq_i8259.o irq_srm.o \ - ns87312.o + pc873xx.o obj-$(CONFIG_ALPHA_LX164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ smc37c93x.o obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ @@ -90,14 +90,14 @@ obj-$(CONFIG_ALPHA_RUFFIAN) += sys_ruffian.o irq_pyxis.o irq_i8259.o obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o irq_i8259.o obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o obj-$(CONFIG_ALPHA_LYNX) += sys_sable.o -obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o +obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o obj-$(CONFIG_ALPHA_SX164) += sys_sx164.o irq_pyxis.o irq_i8259.o \ irq_srm.o smc37c669.o -obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o ns87312.o +obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o pc873xx.o obj-$(CONFIG_ALPHA_WILDFIRE) += sys_wildfire.o irq_i8259.o # Error support diff --git a/arch/alpha/kernel/ns87312.c b/arch/alpha/kernel/ns87312.c deleted file mode 100644 index 342b56d24c2..00000000000 --- a/arch/alpha/kernel/ns87312.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * linux/arch/alpha/kernel/ns87312.c - */ - -#include <linux/init.h> -#include <asm/io.h> -#include "proto.h" - - -/* - * The SRM console *disables* the IDE interface, this code ensures it's - * enabled. - * - * This code bangs on a control register of the 87312 Super I/O chip - * that implements parallel port/serial ports/IDE/FDI. Depending on - * the motherboard, the Super I/O chip can be configured through a - * pair of registers that are located either at I/O ports 0x26e/0x26f - * or 0x398/0x399. Unfortunately, autodetecting which base address is - * in use works only once (right after a reset). The Super I/O chip - * has the additional quirk that configuration register data must be - * written twice (I believe this is a safety feature to prevent - * accidental modification---fun, isn't it?). - */ - -void __init -ns87312_enable_ide(long ide_base) -{ - int data; - unsigned long flags; - - local_irq_save(flags); - outb(0, ide_base); /* set the index register for reg #0 */ - data = inb(ide_base+1); /* read the current contents */ - outb(0, ide_base); /* set the index register for reg #0 */ - outb(data | 0x40, ide_base+1); /* turn on IDE */ - outb(data | 0x40, ide_base+1); /* turn on IDE, really! */ - local_irq_restore(flags); -} diff --git a/arch/alpha/kernel/pc873xx.c b/arch/alpha/kernel/pc873xx.c new file mode 100644 index 00000000000..27dcbff8561 --- /dev/null +++ b/arch/alpha/kernel/pc873xx.c @@ -0,0 +1,88 @@ +#include <linux/ioport.h> +#include <asm/io.h> + +#include "pc873xx.h" + +static unsigned pc873xx_probelist[] = {0x398, 0x26e, 0}; + +static char *pc873xx_names[] = { + "PC87303", "PC87306", "PC87312", "PC87332", "PC87334" +}; + +static unsigned int base, model; + + +unsigned int __init pc873xx_get_base() +{ + return base; +} + +char *__init pc873xx_get_model() +{ + return pc873xx_names[model]; +} + +static unsigned char __init pc873xx_read(unsigned int base, int reg) +{ + outb(reg, base); + return inb(base + 1); +} + +static void __init pc873xx_write(unsigned int base, int reg, unsigned char data) +{ + unsigned long flags; + + local_irq_save(flags); + outb(reg, base); + outb(data, base + 1); + outb(data, base + 1); /* Must be written twice */ + local_irq_restore(flags); +} + +int __init pc873xx_probe(void) +{ + int val, index = 0; + + while ((base = pc873xx_probelist[index++])) { + + if (request_region(base, 2, "Super IO PC873xx") == NULL) + continue; + + val = pc873xx_read(base, REG_SID); + if ((val & 0xf0) == 0x10) { + model = PC87332; + break; + } else if ((val & 0xf8) == 0x70) { + model = PC87306; + break; + } else if ((val & 0xf8) == 0x50) { + model = PC87334; + break; + } else if ((val & 0xf8) == 0x40) { + model = PC87303; + break; + } + + release_region(base, 2); + } + + return (base == 0) ? -1 : 1; +} + +void __init pc873xx_enable_epp19(void) +{ + unsigned char data; + + printk(KERN_INFO "PC873xx enabling EPP v1.9\n"); + data = pc873xx_read(base, REG_PCR); + pc873xx_write(base, REG_PCR, (data & 0xFC) | 0x02); +} + +void __init pc873xx_enable_ide(void) +{ + unsigned char data; + + printk(KERN_INFO "PC873xx enabling IDE interrupt\n"); + data = pc873xx_read(base, REG_FER); + pc873xx_write(base, REG_FER, data | 0x40); +} diff --git a/arch/alpha/kernel/pc873xx.h b/arch/alpha/kernel/pc873xx.h new file mode 100644 index 00000000000..25e16956fe3 --- /dev/null +++ b/arch/alpha/kernel/pc873xx.h @@ -0,0 +1,35 @@ + +#ifndef _PC873xx_H_ +#define _PC873xx_H_ + +/* + * Control Register Values + */ +#define REG_FER 0x00 +#define REG_FAR 0x01 +#define REG_PTR 0x02 +#define REG_FCR 0x03 +#define REG_PCR 0x04 +#define REG_KRR 0x05 +#define REG_PMC 0x06 +#define REG_TUP 0x07 +#define REG_SID 0x08 +#define REG_ASC 0x09 +#define REG_IRC 0x0e + +/* + * Model numbers + */ +#define PC87303 0 +#define PC87306 1 +#define PC87312 2 +#define PC87332 3 +#define PC87334 4 + +int pc873xx_probe(void); +unsigned int pc873xx_get_base(void); +char *pc873xx_get_model(void); +void pc873xx_enable_epp19(void); +void pc873xx_enable_ide(void); + +#endif diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index a5fffc882c7..738fc824e2e 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -53,7 +53,6 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, /** * pci_mmap_resource - map a PCI resource into user memory space - * @filp: open sysfs file * @kobj: kobject for mapping * @attr: struct bin_attribute for the file being mapped * @vma: struct vm_area_struct passed into the mmap @@ -61,7 +60,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, * * Use the bus mapping routines to map a PCI resource into userspace. */ -static int pci_mmap_resource(struct file *filp, struct kobject *kobj, +static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index d4327e461c2..85b4aea01ef 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -34,6 +34,7 @@ #include "irq_impl.h" #include "pci_impl.h" #include "machvec_impl.h" +#include "pc873xx.h" #if defined(ALPHA_RESTORE_SRM_SETUP) /* Save LCA configuration data as the console had it set up. */ @@ -208,7 +209,27 @@ noname_init_pci(void) common_init_pci(); sio_pci_route(); sio_fixup_irq_levels(sio_collect_irq_levels()); - ns87312_enable_ide(0x26e); + + if (pc873xx_probe() == -1) { + printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); + } else { + printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", + pc873xx_get_model(), pc873xx_get_base()); + + /* Enabling things in the Super IO chip doesn't actually + * configure and enable things, the legacy drivers still + * need to do the actual configuration and enabling. + * This only unblocks them. + */ + +#if !defined(CONFIG_ALPHA_AVANTI) + /* Don't bother on the Avanti family. + * None of them had on-board IDE. + */ + pc873xx_enable_ide(); +#endif + pc873xx_enable_epp19(); + } } static inline void __init diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index a52a27c1d9b..6f80665f477 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -951,8 +951,6 @@ static int sa1111_resume(struct platform_device *dev) if (!save) return 0; - spin_lock_irqsave(&sachip->lock, flags); - /* * Ensure that the SA1111 is still here. * FIXME: shouldn't do this here. @@ -969,6 +967,13 @@ static int sa1111_resume(struct platform_device *dev) * First of all, wake up the chip. */ sa1111_wake(sachip); + + /* + * Only lock for write ops. Also, sa1111_wake must be called with + * released spinlock! + */ + spin_lock_irqsave(&sachip->lock, flags); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index d029d1f5f9e..02cae5e2951 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -17,6 +17,7 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/interrupt.h> +#include <linux/completion.h> #include <mach/dma.h> #define MSM_DMOV_CHANNEL_COUNT 16 diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c index 2c471fc451d..f035f418527 100644 --- a/arch/arm/mach-nomadik/clock.c +++ b/arch/arm/mach-nomadik/clock.c @@ -32,7 +32,10 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -/* We have a fixed clock alone, for now */ +static struct clk clk_24 = { + .rate = 2400000, +}; + static struct clk clk_48 = { .rate = 48 * 1000 * 1000, }; @@ -50,6 +53,8 @@ static struct clk clk_default; } static struct clk_lookup lookups[] = { + CLK(&clk_24, "mtu0"), + CLK(&clk_24, "mtu1"), CLK(&clk_48, "uart0"), CLK(&clk_48, "uart1"), CLK(&clk_default, "gpio.0"), @@ -59,10 +64,8 @@ static struct clk_lookup lookups[] = { CLK(&clk_default, "rng"), }; -static int __init clk_init(void) +int __init clk_init(void) { clkdev_add_table(lookups, ARRAY_SIZE(lookups)); return 0; } - -arch_initcall(clk_init); diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h index 5563985a2cc..78da2e7c398 100644 --- a/arch/arm/mach-nomadik/clock.h +++ b/arch/arm/mach-nomadik/clock.h @@ -11,3 +11,5 @@ struct clk { unsigned long rate; }; + +int __init clk_init(void); diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 91c3c901b46..ac58e3b03b1 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -31,6 +31,8 @@ #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> +#include "clock.h" + #define __MEM_4K_RESOURCE(x) \ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} @@ -143,6 +145,12 @@ void __init cpu8815_init_irq(void) /* This modified VIC cell has two register blocks, at 0 and 0x20 */ vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0); vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0); + + /* + * Init clocks here so that they are available for system timer + * initialization. + */ + clk_init(); } /* diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 033b567e50b..ce1104d1bc1 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -263,11 +263,11 @@ const struct matrix_keymap_data palmtc_keymap_data = { .keymap_size = ARRAY_SIZE(palmtc_matrix_keys), }; -const static unsigned int palmtc_keypad_row_gpios[] = { +static const unsigned int palmtc_keypad_row_gpios[] = { 0, 9, 10, 11 }; -const static unsigned int palmtc_keypad_col_gpios[] = { +static const unsigned int palmtc_keypad_col_gpios[] = { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80 }; diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 4d2413ed0ff..c1048a35f18 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -818,6 +818,9 @@ static struct i2c_board_info akita_i2c_board_info[] = { .type = "max7310", .addr = 0x18, .platform_data = &akita_ioexp, + }, { + .type = "wm8750", + .addr = 0x1b, }, }; diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index c7bc4199e3a..4556aea9c3c 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o obj-$(CONFIG_MACH_U5500) += board-u5500.o -obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o +obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 6544855af2f..fe84b9021c7 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -16,6 +16,7 @@ #include <asm/clkdev.h> +#include <plat/mtu.h> #include <mach/hardware.h> #include "clock.h" @@ -59,6 +60,9 @@ #define PRCM_DMACLK_MGT 0x074 #define PRCM_B2R2CLK_MGT 0x078 #define PRCM_TVCLK_MGT 0x07C +#define PRCM_TCR 0x1C8 +#define PRCM_TCR_STOPPED (1 << 16) +#define PRCM_TCR_DOZE_MODE (1 << 17) #define PRCM_UNIPROCLK_MGT 0x278 #define PRCM_SSPCLK_MGT 0x280 #define PRCM_RNGCLK_MGT 0x284 @@ -120,10 +124,95 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); +/* + * The MTU has a separate, rather complex muxing setup + * with alternative parents (peripheral cluster or + * ULP or fixed 32768 Hz) depending on settings + */ +static unsigned long clk_mtu_get_rate(struct clk *clk) +{ + void __iomem *addr = __io_address(U8500_PRCMU_BASE) + + PRCM_TCR; + u32 tcr = readl(addr); + int mtu = (int) clk->data; + /* + * One of these is selected eventually + * TODO: Replace the constant with a reference + * to the ULP source once this is modeled. + */ + unsigned long clk32k = 32768; + unsigned long mturate; + unsigned long retclk; + + /* Get the rate from the parent as a default */ + if (clk->parent_periph) + mturate = clk_get_rate(clk->parent_periph); + else if (clk->parent_cluster) + mturate = clk_get_rate(clk->parent_cluster); + else + /* We need to be connected SOMEWHERE */ + BUG(); + + /* + * Are we in doze mode? + * In this mode the parent peripheral or the fixed 32768 Hz + * clock is fed into the block. + */ + if (!(tcr & PRCM_TCR_DOZE_MODE)) { + /* + * Here we're using the clock input from the APE ULP + * clock domain. But first: are the timers stopped? + */ + if (tcr & PRCM_TCR_STOPPED) { + clk32k = 0; + mturate = 0; + } else { + /* Else default mode: 0 and 2.4 MHz */ + clk32k = 0; + if (cpu_is_u5500()) + /* DB5500 divides by 8 */ + mturate /= 8; + else if (cpu_is_u8500ed()) { + /* + * This clocking setting must not be used + * in the ED chip, it is simply not + * connected anywhere! + */ + mturate = 0; + BUG(); + } else + /* + * In this mode the ulp38m4 clock is divided + * by a factor 16, on the DB8500 typically + * 38400000 / 16 ~ 2.4 MHz. + * TODO: Replace the constant with a reference + * to the ULP source once this is modeled. + */ + mturate = 38400000 / 16; + } + } + + /* Return the clock selected for this MTU */ + if (tcr & (1 << mtu)) + retclk = clk32k; + else + retclk = mturate; + + pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk); + return retclk; +} + unsigned long clk_get_rate(struct clk *clk) { unsigned long rate; + /* + * If there is a custom getrate callback for this clock, + * it will take precedence. + */ + if (clk->get_rate) + return clk->get_rate(clk); + if (clk->ops && clk->ops->get_rate) return clk->ops->get_rate(clk); @@ -341,8 +430,9 @@ static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); /* Peripheral Cluster #6 */ -static DEFINE_PRCC_CLK(6, mtu1_v1, 8, -1, NULL); -static DEFINE_PRCC_CLK(6, mtu0_v1, 7, -1, NULL); +/* MTU ID in data */ +static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); +static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); @@ -357,8 +447,9 @@ static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); /* Peripheral Cluster #7 */ static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); -static DEFINE_PRCC_CLK(7, mtu1_ed, 3, -1, NULL); -static DEFINE_PRCC_CLK(7, mtu0_ed, 2, -1, NULL); +/* MTU ID in data */ +static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); +static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); @@ -503,15 +594,17 @@ static struct clk_lookup u8500_v1_clks[] = { CLK(uiccclk, "uicc", NULL), }; -static int __init clk_init(void) +int __init clk_init(void) { if (cpu_is_u8500ed()) { clk_prcmu_ops.enable = clk_prcmu_ed_enable; clk_prcmu_ops.disable = clk_prcmu_ed_disable; + clk_per6clk.rate = 100000000; } else if (cpu_is_u5500()) { /* Clock tree for U5500 not implemented yet */ clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; + clk_per6clk.rate = 26000000; } clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); @@ -522,4 +615,3 @@ static int __init clk_init(void) return 0; } -arch_initcall(clk_init); diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h index e4f99b65026..a0580250152 100644 --- a/arch/arm/mach-ux500/clock.h +++ b/arch/arm/mach-ux500/clock.h @@ -28,6 +28,9 @@ struct clkops { * @ops: pointer to clkops struct used to control this clock * @name: name, for debugging * @enabled: refcount. positive if enabled, zero if disabled + * @get_rate: custom callback for getting the clock rate + * @data: custom per-clock data for example for the get_rate + * callback * @rate: fixed rate for clocks which don't implement * ops->getrate * @prcmu_cg_off: address offset of the combined enable/disable register @@ -67,6 +70,8 @@ struct clk { const struct clkops *ops; const char *name; unsigned int enabled; + unsigned long (*get_rate)(struct clk *); + void *data; unsigned long rate; struct list_head list; @@ -117,9 +122,26 @@ struct clk clk_##_name = { \ .parent_periph = _kernclk \ } +#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \ +struct clk clk_##_name = { \ + .name = #_name, \ + .ops = &clk_prcc_ops, \ + .cluster = _pclust, \ + .prcc_bus = _bus_en, \ + .prcc_kernel = _kernel_en, \ + .parent_cluster = &clk_per##_pclust##clk, \ + .parent_periph = _kernclk, \ + .get_rate = _callback, \ + .data = (void *) _data \ + } + + #define CLK(_clk, _devname, _conname) \ { \ .clk = &clk_##_clk, \ .dev_id = _devname, \ .con_id = _conname, \ } + +int __init clk_db8500_ed_fixup(void); +int __init clk_init(void); diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index d81ad023963..e0fd747e447 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -62,6 +62,12 @@ void __init ux500_init_irq(void) { gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); + + /* + * Init clocks here so that they are available for system timer + * initialization. + */ + clk_init(); } #ifdef CONFIG_CACHE_L2X0 diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c index 5eb4fd93893..ac163de7dc0 100644 --- a/arch/arm/mm/copypage-feroceon.c +++ b/arch/arm/mm/copypage-feroceon.c @@ -18,7 +18,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4-r9, lr} \n\ - mov ip, %0 \n\ + mov ip, %2 \n\ 1: mov lr, r1 \n\ ldmia r1!, {r2 - r9} \n\ pld [lr, #32] \n\ @@ -64,7 +64,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom) mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\ ldmfd sp!, {r4-r9, pc}" : - : "I" (PAGE_SIZE)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE)); } void feroceon_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c index 7c2eb55cd4a..cb589cbb2b6 100644 --- a/arch/arm/mm/copypage-v4wb.c +++ b/arch/arm/mm/copypage-v4wb.c @@ -27,7 +27,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4, lr} @ 2\n\ - mov r2, %0 @ 1\n\ + mov r2, %2 @ 1\n\ ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ stmia r0!, {r3, r4, ip, lr} @ 4\n\ @@ -44,7 +44,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom) mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\ ldmfd sp!, {r4, pc} @ 3" : - : "I" (PAGE_SIZE / 64)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); } void v4wb_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c index 172e6a55458..30c7d048a32 100644 --- a/arch/arm/mm/copypage-v4wt.c +++ b/arch/arm/mm/copypage-v4wt.c @@ -25,7 +25,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4, lr} @ 2\n\ - mov r2, %0 @ 1\n\ + mov r2, %2 @ 1\n\ ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 1: stmia r0!, {r3, r4, ip, lr} @ 4\n\ ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\ @@ -40,7 +40,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom) mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\ ldmfd sp!, {r4, pc} @ 3" : - : "I" (PAGE_SIZE / 64)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); } void v4wt_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c index 747ad4140fc..f9cde0702f1 100644 --- a/arch/arm/mm/copypage-xsc3.c +++ b/arch/arm/mm/copypage-xsc3.c @@ -34,7 +34,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4, r5, lr} \n\ - mov lr, %0 \n\ + mov lr, %2 \n\ \n\ pld [r1, #0] \n\ pld [r1, #32] \n\ @@ -67,7 +67,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom) \n\ ldmfd sp!, {r4, r5, pc}" : - : "I" (PAGE_SIZE / 64 - 1)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1)); } void xsc3_mc_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 92f5801f99c..cbfb2edcf7d 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -393,6 +393,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); + if (user_mode(regs)) + goto bad_area; + index = pgd_index(addr); /* diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 77b030f5ec0..086816b205b 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -48,7 +48,16 @@ void *kmap_atomic(struct page *page, enum km_type type) debug_kmap_atomic(type); - kmap = kmap_high_get(page); +#ifdef CONFIG_DEBUG_HIGHMEM + /* + * There is no cache coherency issue when non VIVT, so force the + * dedicated kmap usage for better debugging purposes in that case. + */ + if (!cache_is_vivt()) + kmap = NULL; + else +#endif + kmap = kmap_high_get(page); if (kmap) return kmap; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 1ba6cf5a2c0..f6a99946532 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -678,10 +678,10 @@ void __init mem_init(void) void free_initmem(void) { #ifdef CONFIG_HAVE_TCM - extern char *__tcm_start, *__tcm_end; + extern char __tcm_start, __tcm_end; - totalram_pages += free_area(__phys_to_pfn(__pa(__tcm_start)), - __phys_to_pfn(__pa(__tcm_end)), + totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), + __phys_to_pfn(__pa(&__tcm_end)), "TCM link"); #endif diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index 0ff3798769a..08aaa4a7f65 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -13,7 +13,9 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/clockchips.h> +#include <linux/clk.h> #include <linux/jiffies.h> +#include <linux/err.h> #include <asm/mach/time.h> #include <plat/mtu.h> @@ -124,13 +126,25 @@ static struct irqaction nmdk_timer_irq = { void __init nmdk_timer_init(void) { unsigned long rate; - u32 cr = MTU_CRn_32BITS;; + struct clk *clk0; + struct clk *clk1; + u32 cr; + + clk0 = clk_get_sys("mtu0", NULL); + BUG_ON(IS_ERR(clk0)); + + clk1 = clk_get_sys("mtu1", NULL); + BUG_ON(IS_ERR(clk1)); + + clk_enable(clk0); + clk_enable(clk1); /* * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: * use a divide-by-16 counter if it's more than 16MHz */ - rate = CLOCK_TICK_RATE; + cr = MTU_CRn_32BITS;; + rate = clk_get_rate(clk0); if (rate > 16 << 20) { rate /= 16; cr |= MTU_CRn_PRESCALE_16; @@ -153,6 +167,14 @@ void __init nmdk_timer_init(void) nmdk_clksrc.name); /* Timer 1 is used for events, fix according to rate */ + cr = MTU_CRn_32BITS; + rate = clk_get_rate(clk1); + if (rate > 16 << 20) { + rate /= 16; + cr |= MTU_CRn_PRESCALE_16; + } else { + cr |= MTU_CRn_PRESCALE_1; + } writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); nmdk_clkevt.max_delta_ns = diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 66dc2d03b7f..d66cead97d2 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -277,7 +277,7 @@ ENTRY(vfp_put_double) #ifdef CONFIG_VFPv3 @ d16 - d31 registers .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr +1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr mov pc, lr .org 1b + 8 .endr diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c index 84d103c33c9..a4dba6b20bd 100644 --- a/arch/frv/kernel/gdb-stub.c +++ b/arch/frv/kernel/gdb-stub.c @@ -1789,6 +1789,12 @@ void gdbstub(int sigval) flush_cache = 1; break; + /* pNN: Read value of reg N and return it */ + case 'p': + /* return no value, indicating that we don't support + * this command and that gdb should use 'g' instead */ + break; + /* PNN,=RRRRRRRR: Write value R to reg N return OK */ case 'P': ptr = &input_buffer[1]; diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index d5f4e916120..21b701374f7 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -144,6 +144,7 @@ int kvm_arch_hardware_enable(void *garbage) VP_INIT_ENV : VP_INIT_ENV_INITALIZE, __pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base); if (status != 0) { + spin_unlock(&vp_lock); printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n"); return -EINVAL; } diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index de493f86d28..464ff32bee3 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -34,6 +34,8 @@ /* MS be sure that SLAB allocates aligned objects */ #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES + #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 9dcd90b5df5..79c74659f20 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -90,7 +90,6 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, /* FIXME this part of code is untested */ for_each_sg(sgl, sg, nents, i) { sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); - sg->dma_length = sg->length; __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset, sg->length, direction); } diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 9cb782b8e03..23be25fec4d 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -1277,6 +1277,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) printk(KERN_WARNING "PCI: Cannot allocate resource region " "%d of PCI bridge %d, will remap\n", i, bus->number); clear_resource: + res->start = res->end = 0; res->flags = 0; } diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index d6119b879a9..45b40ac6c46 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -117,6 +117,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) * Invalidate the resource to prevent * child resource allocations in this * range. */ + r->start = r->end = 0; r->flags = 0; } } diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 53696da4518..2d38a50e66b 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -135,13 +135,6 @@ config DEBUGGER depends on KGDB || XMON default y -config IRQSTACKS - bool "Use separate kernel stacks when processing interrupts" - help - If you say Y here the kernel will use separate kernel stacks - for handling hard and soft interrupts. This can help avoid - overflowing the process kernel stacks. - config VIRQ_DEBUG bool "Expose hardware/virtual IRQ mapping via debugfs" depends on DEBUG_FS diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index ad0df7d0a64..fae8192c8fc 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -141,7 +141,7 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE $(obj)/wrapper.a: $(obj-wlib) FORCE $(call if_changed,bootar) -hostprogs-y := addnote addRamDisk hack-coff mktree +hostprogs-y := addnote hack-coff mktree targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ diff --git a/arch/powerpc/boot/addRamDisk.c b/arch/powerpc/boot/addRamDisk.c deleted file mode 100644 index 893f446cbd2..00000000000 --- a/arch/powerpc/boot/addRamDisk.c +++ /dev/null @@ -1,311 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <netinet/in.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <elf.h> - -#define ElfHeaderSize (64 * 1024) -#define ElfPages (ElfHeaderSize / 4096) -#define KERNELBASE (0xc000000000000000) -#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) - -struct addr_range { - unsigned long long addr; - unsigned long memsize; - unsigned long offset; -}; - -static int check_elf64(void *p, int size, struct addr_range *r) -{ - Elf64_Ehdr *elf64 = p; - Elf64_Phdr *elf64ph; - - if (elf64->e_ident[EI_MAG0] != ELFMAG0 || - elf64->e_ident[EI_MAG1] != ELFMAG1 || - elf64->e_ident[EI_MAG2] != ELFMAG2 || - elf64->e_ident[EI_MAG3] != ELFMAG3 || - elf64->e_ident[EI_CLASS] != ELFCLASS64 || - elf64->e_ident[EI_DATA] != ELFDATA2MSB || - elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64) - return 0; - - if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size) - return 0; - - elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 + - (unsigned long)elf64->e_phoff); - - r->memsize = (unsigned long)elf64ph->p_memsz; - r->offset = (unsigned long)elf64ph->p_offset; - r->addr = (unsigned long long)elf64ph->p_vaddr; - -#ifdef DEBUG - printf("PPC64 ELF file, ph:\n"); - printf("p_type 0x%08x\n", elf64ph->p_type); - printf("p_flags 0x%08x\n", elf64ph->p_flags); - printf("p_offset 0x%016llx\n", elf64ph->p_offset); - printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr); - printf("p_paddr 0x%016llx\n", elf64ph->p_paddr); - printf("p_filesz 0x%016llx\n", elf64ph->p_filesz); - printf("p_memsz 0x%016llx\n", elf64ph->p_memsz); - printf("p_align 0x%016llx\n", elf64ph->p_align); - printf("... skipping 0x%08lx bytes of ELF header\n", - (unsigned long)elf64ph->p_offset); -#endif - - return 64; -} -static void get4k(FILE *file, char *buf ) -{ - unsigned j; - unsigned num = fread(buf, 1, 4096, file); - for ( j=num; j<4096; ++j ) - buf[j] = 0; -} - -static void put4k(FILE *file, char *buf ) -{ - fwrite(buf, 1, 4096, file); -} - -static void death(const char *msg, FILE *fdesc, const char *fname) -{ - fprintf(stderr, msg); - fclose(fdesc); - unlink(fname); - exit(1); -} - -int main(int argc, char **argv) -{ - char inbuf[4096]; - struct addr_range vmlinux; - FILE *ramDisk; - FILE *inputVmlinux; - FILE *outputVmlinux; - - char *rd_name, *lx_name, *out_name; - - size_t i; - unsigned long ramFileLen; - unsigned long ramLen; - unsigned long roundR; - unsigned long offset_end; - - unsigned long kernelLen; - unsigned long actualKernelLen; - unsigned long round; - unsigned long roundedKernelLen; - unsigned long ramStartOffs; - unsigned long ramPages; - unsigned long roundedKernelPages; - unsigned long hvReleaseData; - u_int32_t eyeCatcher = 0xc8a5d9c4; - unsigned long naca; - unsigned long xRamDisk; - unsigned long xRamDiskSize; - long padPages; - - - if (argc < 2) { - fprintf(stderr, "Name of RAM disk file missing.\n"); - exit(1); - } - rd_name = argv[1]; - - if (argc < 3) { - fprintf(stderr, "Name of vmlinux file missing.\n"); - exit(1); - } - lx_name = argv[2]; - - if (argc < 4) { - fprintf(stderr, "Name of vmlinux output file missing.\n"); - exit(1); - } - out_name = argv[3]; - - - ramDisk = fopen(rd_name, "r"); - if ( ! ramDisk ) { - fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name); - exit(1); - } - - inputVmlinux = fopen(lx_name, "r"); - if ( ! inputVmlinux ) { - fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name); - exit(1); - } - - outputVmlinux = fopen(out_name, "w+"); - if ( ! outputVmlinux ) { - fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name); - exit(1); - } - - i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux); - if (i != sizeof(inbuf)) { - fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i); - exit(1); - } - - i = check_elf64(inbuf, sizeof(inbuf), &vmlinux); - if (i == 0) { - fprintf(stderr, "You must have a linux kernel specified as argv[2]\n"); - exit(1); - } - - /* Input Vmlinux file */ - fseek(inputVmlinux, 0, SEEK_END); - kernelLen = ftell(inputVmlinux); - fseek(inputVmlinux, 0, SEEK_SET); - printf("kernel file size = %lu\n", kernelLen); - - actualKernelLen = kernelLen - ElfHeaderSize; - - printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen); - - round = actualKernelLen % 4096; - roundedKernelLen = actualKernelLen; - if ( round ) - roundedKernelLen += (4096 - round); - printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen); - roundedKernelPages = roundedKernelLen / 4096; - printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); - - offset_end = _ALIGN_UP(vmlinux.memsize, 4096); - /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ - padPages = offset_end/4096 - roundedKernelPages; - - /* Check and see if the vmlinux is already larger than _end in System.map */ - if (padPages < 0) { - /* vmlinux is larger than _end - adjust the offset to the start of the embedded ram disk */ - offset_end = roundedKernelLen; - printf("vmlinux is larger than _end indicates it needs to be - offset_end = %lx \n", offset_end); - padPages = 0; - printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); - } - else { - /* _end is larger than vmlinux - use the offset to _end that we calculated from the system map */ - printf("vmlinux is smaller than _end indicates is needed - offset_end = %lx \n", offset_end); - printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); - } - - - - /* Input Ram Disk file */ - // Set the offset that the ram disk will be started at. - ramStartOffs = offset_end; /* determined from the input vmlinux file and the system map */ - printf("Ram Disk will start at offset = 0x%lx \n", ramStartOffs); - - fseek(ramDisk, 0, SEEK_END); - ramFileLen = ftell(ramDisk); - fseek(ramDisk, 0, SEEK_SET); - printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen); - - ramLen = ramFileLen; - - roundR = 4096 - (ramLen % 4096); - if ( roundR ) { - printf("Rounding RAM disk file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR); - ramLen += roundR; - } - - printf("Rounded RAM disk size is %ld/0x%lx \n", ramLen, ramLen); - ramPages = ramLen / 4096; - printf("RAM disk pages to copy = %ld/0x%lx\n", ramPages, ramPages); - - - - // Copy 64K ELF header - for (i=0; i<(ElfPages); ++i) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - /* Copy the vmlinux (as full pages). */ - fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); - for ( i=0; i<roundedKernelPages; ++i ) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - /* Insert pad pages (if appropriate) that are needed between */ - /* | the end of the vmlinux and the ram disk. */ - for (i=0; i<padPages; ++i) { - memset(inbuf, 0, 4096); - put4k(outputVmlinux, inbuf); - } - - /* Copy the ram disk (as full pages). */ - for ( i=0; i<ramPages; ++i ) { - get4k( ramDisk, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - /* Close the input files */ - fclose(ramDisk); - fclose(inputVmlinux); - /* And flush the written output file */ - fflush(outputVmlinux); - - - - /* Fixup the new vmlinux to contain the ram disk starting offset (xRamDisk) and the ram disk size (xRamDiskSize) */ - /* fseek to the hvReleaseData pointer */ - fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); - if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { - death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name); - } - hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ - printf("hvReleaseData is at %08lx\n", hvReleaseData); - - /* fseek to the hvReleaseData */ - fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); - if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { - death("Could not read hvReleaseData\n", outputVmlinux, out_name); - } - /* Check hvReleaseData sanity */ - if (memcmp(inbuf, &eyeCatcher, 4) != 0) { - death("hvReleaseData is invalid\n", outputVmlinux, out_name); - } - /* Get the naca pointer */ - naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; - printf("Naca is at offset 0x%lx \n", naca); - - /* fseek to the naca */ - fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); - if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { - death("Could not read naca\n", outputVmlinux, out_name); - } - xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); - xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); - /* Make sure a RAM disk isn't already present */ - if ((xRamDisk != 0) || (xRamDiskSize != 0)) { - death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name); - } - /* Fill in the values */ - *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); - *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); - - /* Write out the new naca */ - fflush(outputVmlinux); - fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); - if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { - death("Could not write naca\n", outputVmlinux, out_name); - } - printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n", - ramPages, ramStartOffs); - - /* Done */ - fclose(outputVmlinux); - /* Set permission to executable */ - chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); - - return 0; -} - diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts index 82ff2b13bc3..179a1785d64 100644 --- a/arch/powerpc/boot/dts/lite5200.dts +++ b/arch/powerpc/boot/dts/lite5200.dts @@ -134,12 +134,16 @@ compatible = "fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; gpio@c00 { compatible = "fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; spi@f00 { @@ -230,8 +234,8 @@ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - phy0: ethernet-phy@1 { - reg = <1>; + phy0: ethernet-phy@0 { + reg = <0>; }; }; @@ -255,7 +259,13 @@ compatible = "fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + }; }; + sram@8000 { compatible = "fsl,mpc5200-sram"; reg = <0x8000 0x4000>; @@ -281,4 +291,18 @@ 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; }; + + localbus { + compatible = "fsl,mpc5200-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <0 0 0xff000000 0x01000000>; + + flash@0,0 { + compatible = "amd,am29lv652d", "cfi-flash"; + reg = <0 0 0x01000000>; + bank-width = <1>; + }; + }; }; diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts index e45a63be3a8..59702ace900 100644 --- a/arch/powerpc/boot/dts/lite5200b.dts +++ b/arch/powerpc/boot/dts/lite5200b.dts @@ -259,6 +259,11 @@ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + }; }; sram@8000 { diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig index 8e95f8d227b..4aa17b676a3 100644 --- a/arch/powerpc/configs/40x/acadia_defconfig +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -98,8 +98,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig index 918f23fd2b1..9a5f1ab777e 100644 --- a/arch/powerpc/configs/40x/ep405_defconfig +++ b/arch/powerpc/configs/40x/ep405_defconfig @@ -98,8 +98,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig index f87ef038228..0b452135d1d 100644 --- a/arch/powerpc/configs/40x/hcu4_defconfig +++ b/arch/powerpc/configs/40x/hcu4_defconfig @@ -98,8 +98,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index 19fbcb07537..4d2de0bed60 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -98,8 +98,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig index eb41cd69597..a1f3f505e4a 100644 --- a/arch/powerpc/configs/40x/makalu_defconfig +++ b/arch/powerpc/configs/40x/makalu_defconfig @@ -98,8 +98,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig index 416e79ac071..c7631357714 100644 --- a/arch/powerpc/configs/40x/virtex_defconfig +++ b/arch/powerpc/configs/40x/virtex_defconfig @@ -77,8 +77,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig index bfff0eae39d..6597b2f1d1a 100644 --- a/arch/powerpc/configs/40x/walnut_defconfig +++ b/arch/powerpc/configs/40x/walnut_defconfig @@ -98,8 +98,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/arches_defconfig b/arch/powerpc/configs/44x/arches_defconfig index 1f6d0490e28..2d3dfb55fbe 100644 --- a/arch/powerpc/configs/44x/arches_defconfig +++ b/arch/powerpc/configs/44x/arches_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/bamboo_defconfig b/arch/powerpc/configs/44x/bamboo_defconfig index 788faac6c27..51a00c46df1 100644 --- a/arch/powerpc/configs/44x/bamboo_defconfig +++ b/arch/powerpc/configs/44x/bamboo_defconfig @@ -102,8 +102,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig index 4ef8bcab61f..1028b1bfb60 100644 --- a/arch/powerpc/configs/44x/canyonlands_defconfig +++ b/arch/powerpc/configs/44x/canyonlands_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/ebony_defconfig b/arch/powerpc/configs/44x/ebony_defconfig index ca17b1496e3..69f5633cbd4 100644 --- a/arch/powerpc/configs/44x/ebony_defconfig +++ b/arch/powerpc/configs/44x/ebony_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig index e3149bade0b..dcd859c8b4a 100644 --- a/arch/powerpc/configs/44x/eiger_defconfig +++ b/arch/powerpc/configs/44x/eiger_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig index af244e1d255..a2c24d1e051 100644 --- a/arch/powerpc/configs/44x/katmai_defconfig +++ b/arch/powerpc/configs/44x/katmai_defconfig @@ -97,8 +97,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/rainier_defconfig b/arch/powerpc/configs/44x/rainier_defconfig index 8fed3b26af2..3bb55b57077 100644 --- a/arch/powerpc/configs/44x/rainier_defconfig +++ b/arch/powerpc/configs/44x/rainier_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig index a67ec91a28c..684f40dc8a4 100644 --- a/arch/powerpc/configs/44x/redwood_defconfig +++ b/arch/powerpc/configs/44x/redwood_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/sam440ep_defconfig b/arch/powerpc/configs/44x/sam440ep_defconfig index 886cb6aa643..e202924e617 100644 --- a/arch/powerpc/configs/44x/sam440ep_defconfig +++ b/arch/powerpc/configs/44x/sam440ep_defconfig @@ -103,8 +103,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig index 1b2f41dbcaf..c348a4662a9 100644 --- a/arch/powerpc/configs/44x/sequoia_defconfig +++ b/arch/powerpc/configs/44x/sequoia_defconfig @@ -102,8 +102,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/taishan_defconfig b/arch/powerpc/configs/44x/taishan_defconfig index 12041d355b8..f4cb7e84cb8 100644 --- a/arch/powerpc/configs/44x/taishan_defconfig +++ b/arch/powerpc/configs/44x/taishan_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/virtex5_defconfig b/arch/powerpc/configs/44x/virtex5_defconfig index 2518b8568c7..c7ead0ec00b 100644 --- a/arch/powerpc/configs/44x/virtex5_defconfig +++ b/arch/powerpc/configs/44x/virtex5_defconfig @@ -80,8 +80,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig index 218d49b36a0..7664c83c17c 100644 --- a/arch/powerpc/configs/52xx/cm5200_defconfig +++ b/arch/powerpc/configs/52xx/cm5200_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig index 90492ff2523..eac7c17eef3 100644 --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -96,8 +96,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index dffc8cac825..27afb6ecdf6 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig index 3cb2a522046..5fe39ddb4e1 100644 --- a/arch/powerpc/configs/52xx/pcm030_defconfig +++ b/arch/powerpc/configs/52xx/pcm030_defconfig @@ -98,8 +98,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index 96181c62abf..a108b84c007 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig index 183c59c6d89..b728a7d6425 100644 --- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig +++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig index 1524d948a2b..8e738de5f6a 100644 --- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig +++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig index 767c204c060..59bf9e27d7f 100644 --- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig +++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig index 55b9e4e867a..4e8b01e7324 100644 --- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig +++ b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig @@ -98,8 +98,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig index 1be38eb0578..20fde6374aa 100644 --- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig +++ b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig index a6300945732..74f714d8593 100644 --- a/arch/powerpc/configs/86xx/sbc8641d_defconfig +++ b/arch/powerpc/configs/86xx/sbc8641d_defconfig @@ -102,8 +102,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig index 9f89d5c9c0b..a670cee255b 100644 --- a/arch/powerpc/configs/adder875_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -92,8 +92,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig index b63cc38df6b..851287e78fc 100644 --- a/arch/powerpc/configs/amigaone_defconfig +++ b/arch/powerpc/configs/amigaone_defconfig @@ -87,8 +87,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig index 4ab6074db3c..b429a655b54 100644 --- a/arch/powerpc/configs/c2k_defconfig +++ b/arch/powerpc/configs/c2k_defconfig @@ -102,8 +102,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index c6d2baa7aae..94337195431 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -83,8 +83,7 @@ CONFIG_CPUSETS=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_PROC_PID_CPUSET=y # CONFIG_RELAY is not set CONFIG_NAMESPACES=y diff --git a/arch/powerpc/configs/celleb_defconfig b/arch/powerpc/configs/celleb_defconfig index d2123779512..6be6c09eba6 100644 --- a/arch/powerpc/configs/celleb_defconfig +++ b/arch/powerpc/configs/celleb_defconfig @@ -78,8 +78,7 @@ CONFIG_LOG_BUF_SHIFT=15 # CONFIG_GROUP_SCHED is not set # CONFIG_USER_SCHED is not set # CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index 5094a65a449..2fdab660fce 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig @@ -77,8 +77,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig index 81e904e9f39..6b708395a7c 100644 --- a/arch/powerpc/configs/ep8248e_defconfig +++ b/arch/powerpc/configs/ep8248e_defconfig @@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig index c5af46ef5f4..1cee889dd9e 100644 --- a/arch/powerpc/configs/ep88xc_defconfig +++ b/arch/powerpc/configs/ep88xc_defconfig @@ -91,8 +91,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 826a65d3f00..57d3ffa3026 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -82,8 +82,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig index 942e1193e9e..1c2dbf07ac3 100644 --- a/arch/powerpc/configs/gamecube_defconfig +++ b/arch/powerpc/configs/gamecube_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig index a211a79959c..a60d61bee48 100644 --- a/arch/powerpc/configs/holly_defconfig +++ b/arch/powerpc/configs/holly_defconfig @@ -73,7 +73,6 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set # CONFIG_FAIR_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index 76982c51a4c..151c8e14f3a 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig @@ -81,8 +81,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig index 588a2add393..8ecacf74d3e 100644 --- a/arch/powerpc/configs/linkstation_defconfig +++ b/arch/powerpc/configs/linkstation_defconfig @@ -97,8 +97,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 8b244003b9e..dc50eec58e7 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -78,8 +78,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig index 0cbd56fe2e1..b36ebb7e843 100644 --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig @@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/mgsuvd_defconfig b/arch/powerpc/configs/mgsuvd_defconfig index c1be2615102..0dd5015ea81 100644 --- a/arch/powerpc/configs/mgsuvd_defconfig +++ b/arch/powerpc/configs/mgsuvd_defconfig @@ -90,8 +90,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index a04727295d4..aa2654e6ede 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig @@ -97,8 +97,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=16 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 7012ac0134f..f875ec21c91 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -97,8 +97,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index 27c63ceeb45..b1e88fe1d9f 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 20ba0cfff8b..74a7216183e 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=64 CONFIG_LOG_BUF_SHIFT=17 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index ea8870a3448..753bb7912e2 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -93,8 +93,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig index 35b60683cde..afb4d1bb2ba 100644 --- a/arch/powerpc/configs/ppc40x_defconfig +++ b/arch/powerpc/configs/ppc40x_defconfig @@ -99,8 +99,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 46f5c47e9f8..bd3d23fb4dd 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -103,8 +103,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index dad617e2a88..369f4e02c5d 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -93,8 +93,7 @@ CONFIG_CPUSETS=y # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_PROC_PID_CPUSET=y CONFIG_RELAY=y CONFIG_NAMESPACES=y diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 8195f1650cb..403e82e2e83 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -107,8 +107,7 @@ CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig index 68c175ea427..12c8ee8dd12 100644 --- a/arch/powerpc/configs/pq2fads_defconfig +++ b/arch/powerpc/configs/pq2fads_defconfig @@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig index 93f4505b5ac..a18f597c6e5 100644 --- a/arch/powerpc/configs/prpmc2800_defconfig +++ b/arch/powerpc/configs/prpmc2800_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 16a14589bd4..16ae717d195 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -92,8 +92,7 @@ CONFIG_CPUSETS=y # CONFIG_GROUP_SCHED is not set CONFIG_CGROUP_CPUACCT=y # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_PROC_PID_CPUSET=y CONFIG_RELAY=y CONFIG_NAMESPACES=y diff --git a/arch/powerpc/configs/storcenter_defconfig b/arch/powerpc/configs/storcenter_defconfig index b1625801526..01be0e207f4 100644 --- a/arch/powerpc/configs/storcenter_defconfig +++ b/arch/powerpc/configs/storcenter_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig index c386828c639..ee054f8118b 100644 --- a/arch/powerpc/configs/wii_defconfig +++ b/arch/powerpc/configs/wii_defconfig @@ -102,8 +102,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e054baef184..ecba37a9174 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -358,7 +358,6 @@ extern void exc_lvl_ctx_init(void); #define exc_lvl_ctx_init() #endif -#ifdef CONFIG_IRQSTACKS /* * Per-cpu stacks for handling hard and soft interrupts. */ @@ -369,11 +368,6 @@ extern void irq_ctx_init(void); extern void call_do_softirq(struct thread_info *tp); extern int call_handle_irq(int irq, void *p1, struct thread_info *tp, void *func); -#else -#define irq_ctx_init() - -#endif /* CONFIG_IRQSTACKS */ - extern void do_IRQ(struct pt_regs *regs); #endif /* _ASM_IRQ_H */ diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index 5ebfe5d3c61..6857af58b02 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h @@ -3,8 +3,17 @@ #include <asm/page.h> -/* Kdump kernel runs at 32 MB, change at your peril. */ +/* + * If CONFIG_RELOCATABLE is enabled we can place the kdump kernel anywhere. + * To keep enough space in the RMO for the first stage kernel on 64bit, we + * place it at 64MB. If CONFIG_RELOCATABLE is not enabled we must place + * the second stage at 32MB. + */ +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC64) +#define KDUMP_KERNELBASE 0x4000000 +#else #define KDUMP_KERNELBASE 0x2000000 +#endif /* How many bytes to reserve at zero for kdump. The reserve limit should * be greater or equal to the trampoline's end address. diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 30817d9b20c..3333bbdd23e 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -317,7 +317,6 @@ void fixup_irqs(const struct cpumask *map) } #endif -#ifdef CONFIG_IRQSTACKS static inline void handle_one_irq(unsigned int irq) { struct thread_info *curtp, *irqtp; @@ -358,12 +357,6 @@ static inline void handle_one_irq(unsigned int irq) if (irqtp->flags) set_bits(irqtp->flags, &curtp->flags); } -#else -static inline void handle_one_irq(unsigned int irq) -{ - generic_handle_irq(irq); -} -#endif static inline void check_stack_overflow(void) { @@ -455,7 +448,6 @@ void exc_lvl_ctx_init(void) } #endif -#ifdef CONFIG_IRQSTACKS struct thread_info *softirq_ctx[NR_CPUS] __read_mostly; struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly; @@ -492,10 +484,6 @@ static inline void do_softirq_onstack(void) irqtp->task = NULL; } -#else -#define do_softirq_onstack() __do_softirq() -#endif /* CONFIG_IRQSTACKS */ - void do_softirq(void) { unsigned long flags; diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 26f9900f773..ed31a29c4ff 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -182,28 +182,12 @@ static void kexec_prepare_cpus_wait(int wait_state) my_cpu = get_cpu(); /* Make sure each CPU has atleast made it to the state we need */ - for (i=0; i < NR_CPUS; i++) { + for_each_online_cpu(i) { if (i == my_cpu) continue; while (paca[i].kexec_state < wait_state) { barrier(); - if (!cpu_possible(i)) { - printk("kexec: cpu %d hw_cpu_id %d is not" - " possible, ignoring\n", - i, paca[i].hw_cpu_id); - break; - } - if (!cpu_online(i)) { - /* Fixme: this can be spinning in - * pSeries_secondary_wait with a paca - * waiting for it to go online. - */ - printk("kexec: cpu %d hw_cpu_id %d is not" - " online, ignoring\n", - i, paca[i].hw_cpu_id); - break; - } if (i != notified) { printk( "kexec: waiting for cpu %d (physical" " %d) to enter %i state\n", diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index dc66d52dcff..6bbd7a604d2 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -33,7 +33,6 @@ .text -#ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) mflr r0 stw r0,4(r1) @@ -56,7 +55,6 @@ _GLOBAL(call_handle_irq) lwz r0,4(r1) mtlr r0 blr -#endif /* CONFIG_IRQSTACKS */ /* * This returns the high 64 bits of the product of two 64-bit numbers. diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index a2b18dffa03..e5144906a56 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -28,7 +28,6 @@ .text -#ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) mflr r0 std r0,16(r1) @@ -52,7 +51,6 @@ _GLOBAL(call_handle_irq) ld r0,16(r1) mtlr r0 blr -#endif /* CONFIG_IRQSTACKS */ .section ".toc","aw" PPC64_CACHES: diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 6646005dffb..5b38f6ae2b2 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1309,6 +1309,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) printk(KERN_WARNING "PCI: Cannot allocate resource region " "%d of PCI bridge %d, will remap\n", i, bus->number); clear_resource: + res->start = res->end = 0; res->flags = 0; } diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9d255b4f0a0..773424df828 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1005,7 +1005,6 @@ out: return error; } -#ifdef CONFIG_IRQSTACKS static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, unsigned long nbytes) { @@ -1030,10 +1029,6 @@ static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, return 0; } -#else -#define valid_irq_stack(sp, p, nb) 0 -#endif /* CONFIG_IRQSTACKS */ - int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index bfc2abafac4..67a84d8f118 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -94,12 +94,8 @@ struct flash_block_list { struct flash_block_list *next; struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; }; -struct flash_block_list_header { /* just the header of flash_block_list */ - unsigned long num_blocks; - struct flash_block_list *next; -}; -static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; +static struct flash_block_list *rtas_firmware_flash_list; /* Use slab cache to guarantee 4k alignment */ static struct kmem_cache *flash_block_cache = NULL; @@ -108,13 +104,14 @@ static struct kmem_cache *flash_block_cache = NULL; /* Local copy of the flash block list. * We only allow one open of the flash proc file and create this - * list as we go. This list will be put in the - * rtas_firmware_flash_list var once it is fully read. + * list as we go. The rtas_firmware_flash_list varable will be + * set once the data is fully read. * * For convenience as we build the list we use virtual addrs, * we do not fill in the version number, and the length field * is treated as the number of entries currently in the block - * (i.e. not a byte count). This is all fixed on release. + * (i.e. not a byte count). This is all fixed when calling + * the flash routine. */ /* Status int must be first member of struct */ @@ -201,16 +198,16 @@ static int rtas_flash_release(struct inode *inode, struct file *file) if (uf->flist) { /* File was opened in write mode for a new flash attempt */ /* Clear saved list */ - if (rtas_firmware_flash_list.next) { - free_flash_list(rtas_firmware_flash_list.next); - rtas_firmware_flash_list.next = NULL; + if (rtas_firmware_flash_list) { + free_flash_list(rtas_firmware_flash_list); + rtas_firmware_flash_list = NULL; } if (uf->status != FLASH_AUTH) uf->status = flash_list_valid(uf->flist); if (uf->status == FLASH_IMG_READY) - rtas_firmware_flash_list.next = uf->flist; + rtas_firmware_flash_list = uf->flist; else free_flash_list(uf->flist); @@ -593,7 +590,7 @@ static void rtas_flash_firmware(int reboot_type) unsigned long rtas_block_list; int i, status, update_token; - if (rtas_firmware_flash_list.next == NULL) + if (rtas_firmware_flash_list == NULL) return; /* nothing to do */ if (reboot_type != SYS_RESTART) { @@ -610,20 +607,25 @@ static void rtas_flash_firmware(int reboot_type) return; } - /* NOTE: the "first" block list is a global var with no data - * blocks in the kernel data segment. We do this because - * we want to ensure this block_list addr is under 4GB. + /* + * NOTE: the "first" block must be under 4GB, so we create + * an entry with no data blocks in the reserved buffer in + * the kernel data segment. */ - rtas_firmware_flash_list.num_blocks = 0; - flist = (struct flash_block_list *)&rtas_firmware_flash_list; + spin_lock(&rtas_data_buf_lock); + flist = (struct flash_block_list *)&rtas_data_buf[0]; + flist->num_blocks = 0; + flist->next = rtas_firmware_flash_list; rtas_block_list = virt_to_abs(flist); if (rtas_block_list >= 4UL*1024*1024*1024) { printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); + spin_unlock(&rtas_data_buf_lock); return; } printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n"); /* Update the block_list in place. */ + rtas_firmware_flash_list = NULL; /* too hard to backout on error */ image_size = 0; for (f = flist; f; f = next) { /* Translate data addrs to absolute */ @@ -664,6 +666,7 @@ static void rtas_flash_firmware(int reboot_type) printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status); break; } + spin_unlock(&rtas_data_buf_lock); } static void remove_flash_pde(struct proc_dir_entry *dp) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 8f58986c2ad..7d84b210f16 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -241,7 +241,6 @@ int __init ppc_init(void) arch_initcall(ppc_init); -#ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { unsigned int i; @@ -255,9 +254,6 @@ static void __init irqstack_early_init(void) __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE)); } } -#else -#define irqstack_early_init() -#endif #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) static void __init exc_lvl_early_init(void) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index f3fb5a79de5..643dcac40fc 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -432,7 +432,6 @@ static u64 slb0_limit(void) return 1UL << SID_SHIFT; } -#ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { u64 limit = slb0_limit(); @@ -451,9 +450,6 @@ static void __init irqstack_early_init(void) THREAD_SIZE, limit)); } } -#else -#define irqstack_early_init() -#endif #ifdef CONFIG_PPC_BOOK3E static void __init exc_lvl_early_init(void) diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index bc2b4004eb2..e8a00b0c444 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -164,7 +164,7 @@ static int __init kvmppc_e500_init(void) return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); } -static void __init kvmppc_e500_exit(void) +static void __exit kvmppc_e500_exit(void) { kvmppc_booke_exit(); } diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 9fc02dc72ce..34347b2e7e3 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -115,11 +115,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { struct page *ptepage; -#ifdef CONFIG_HIGHPTE - gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT | __GFP_ZERO; -#else gfp_t flags = GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO; -#endif ptepage = alloc_pages(flags, 0); if (!ptepage) diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 2c9e5226729..7fd90d02d8c 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1077,7 +1077,7 @@ static int calculate_lfsr(int n) index = ENTRIES-1; /* make sure index is valid */ - if ((index > ENTRIES) || (index < 0)) + if ((index >= ENTRIES) || (index < 0)) index = ENTRIES-1; return initial_lfsr[index]; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index a55b0b6813e..76722532bd9 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c @@ -64,10 +64,19 @@ int mpc52xx_pm_prepare(void) { .type = "builtin", .compatible = "mpc5200", }, /* efika */ {} }; + struct resource res; /* map the whole register space */ np = of_find_matching_node(NULL, immr_ids); - mbar = of_iomap(np, 0); + + if (of_address_to_resource(np, 0, &res)) { + pr_err("mpc52xx_pm_prepare(): could not get IMMR address\n"); + of_node_put(np); + return -ENOSYS; + } + + mbar = ioremap(res.start, 0xc000); /* we should map whole region including SRAM */ + of_node_put(np); if (!mbar) { pr_err("mpc52xx_pm_prepare(): could not map registers\n"); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 2102487612a..20b73c025a4 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1666,7 +1666,7 @@ static int mpic_resume(struct sys_device *dev) mpic->save_data[i].dest); #ifdef CONFIG_MPIC_U3_HT_IRQS - { + if (mpic->fixups) { struct mpic_irq_fixup *fixup = &mpic->fixups[i]; if (fixup->base) { diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 55c80ffd42b..92f1cb745d6 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -181,7 +181,7 @@ static int __init appldata_os_init(void) goto out; } - appldata_os_data = kzalloc(max_size, GFP_DMA); + appldata_os_data = kzalloc(max_size, GFP_KERNEL | GFP_DMA); if (appldata_os_data == NULL) { rc = -ENOMEM; goto out; diff --git a/arch/s390/defconfig b/arch/s390/defconfig index bcd6884985a..253f158db66 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.34-rc3 -# Fri Apr 9 09:57:10 2010 +# Linux kernel version: 2.6.35-rc1 +# Fri Jun 4 11:32:40 2010 # CONFIG_SCHED_MC=y CONFIG_MMU=y @@ -35,11 +35,13 @@ CONFIG_CONSTRUCTORS=y CONFIG_EXPERIMENTAL=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set @@ -77,6 +79,7 @@ CONFIG_CGROUP_NS=y # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set # CONFIG_CGROUP_SCHED is not set +# CONFIG_BLK_CGROUP is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -157,7 +160,6 @@ CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_CGROUP is not set CONFIG_BLOCK_COMPAT=y # @@ -166,7 +168,6 @@ CONFIG_BLOCK_COMPAT=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_CFQ_GROUP_IOSCHED is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set @@ -247,7 +248,6 @@ CONFIG_64BIT=y CONFIG_SMP=y CONFIG_NR_CPUS=32 CONFIG_HOTPLUG_CPU=y -# CONFIG_SCHED_BOOK is not set CONFIG_COMPAT=y CONFIG_SYSVIPC_COMPAT=y CONFIG_AUDIT_ARCH=y @@ -320,7 +320,6 @@ CONFIG_COMPAT_BINFMT_ELF=y # CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=m CONFIG_FORCE_MAX_ZONEORDER=9 -# CONFIG_PROCESS_DEBUG is not set CONFIG_PFAULT=y # CONFIG_SHARED_KERNEL is not set # CONFIG_CMM is not set @@ -457,6 +456,7 @@ CONFIG_NF_CONNTRACK=m # CONFIG_IP6_NF_IPTABLES is not set # CONFIG_IP_DCCP is not set CONFIG_IP_SCTP=m +# CONFIG_NET_SCTPPROBE is not set # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_SCTP_HMAC_NONE is not set @@ -465,6 +465,7 @@ CONFIG_SCTP_HMAC_MD5=y # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set +# CONFIG_L2TP is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set @@ -525,6 +526,7 @@ CONFIG_NET_ACT_NAT=m # CONFIG_NET_CLS_IND is not set CONFIG_NET_SCH_FIFO=y # CONFIG_DCB is not set +CONFIG_RPS=y # # Network testing @@ -546,6 +548,7 @@ CONFIG_CAN_VCAN=m # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set +# CONFIG_CAIF is not set # CONFIG_PCMCIA is not set CONFIG_CCW=y @@ -728,6 +731,7 @@ CONFIG_VIRTIO_NET=m # Character devices # CONFIG_DEVKMEM=y +# CONFIG_N_GSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y @@ -775,6 +779,7 @@ CONFIG_S390_TAPE_34XX=m # CONFIG_MONREADER is not set CONFIG_MONWRITER=m CONFIG_S390_VMUR=m +# CONFIG_RAMOOPS is not set # # PPS support @@ -788,10 +793,6 @@ CONFIG_S390_VMUR=m # CONFIG_NEW_LEDS is not set CONFIG_ACCESSIBILITY=y # CONFIG_AUXDISPLAY is not set - -# -# TI VLYNQ -# # CONFIG_STAGING is not set # @@ -976,6 +977,7 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y # CONFIG_LKDTM is not set +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y @@ -1010,6 +1012,7 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_KPROBE_EVENT=y # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set CONFIG_SAMPLES=y # CONFIG_SAMPLE_TRACEPOINTS is not set # CONFIG_SAMPLE_TRACE_EVENTS is not set diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 639380a0c45..22cfd634c35 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -55,8 +55,10 @@ void *module_alloc(unsigned long size) /* Free memory returned from module_alloc */ void module_free(struct module *mod, void *module_region) { - vfree(mod->arch.syminfo); - mod->arch.syminfo = NULL; + if (mod) { + vfree(mod->arch.syminfo); + mod->arch.syminfo = NULL; + } vfree(module_region); } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 8093e6f47f4..ae370581687 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -761,7 +761,7 @@ static int __init kvm_s390_init(void) * to hold the maximum amount of facilites. On the other hand, we * only set facilities that are known to work in KVM. */ - facilities = (unsigned long long *) get_zeroed_page(GFP_DMA); + facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); if (!facilities) { kvm_exit(); return -ENOMEM; diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index eff3c5989b4..702276f5e2f 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -113,7 +113,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) { struct kvm_s390_interrupt_info *inti; - inti = kzalloc(sizeof(*inti), GFP_KERNEL); + inti = kzalloc(sizeof(*inti), GFP_ATOMIC); if (!inti) return -ENOMEM; inti->type = KVM_S390_SIGP_STOP; diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 6409fd57eb0..3cc95dd0a3a 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -105,7 +105,7 @@ static int dcss_set_subcodes(void) { #ifdef CONFIG_64BIT - char *name = kmalloc(8 * sizeof(char), GFP_DMA); + char *name = kmalloc(8 * sizeof(char), GFP_KERNEL | GFP_DMA); unsigned long rx, ry; int rc; @@ -252,12 +252,13 @@ dcss_diag_translate_rc (int vm_rc) { static int query_segment_type (struct dcss_segment *seg) { - struct qin64 *qin = kmalloc (sizeof(struct qin64), GFP_DMA); - struct qout64 *qout = kmalloc (sizeof(struct qout64), GFP_DMA); - - int diag_cc, rc, i; unsigned long dummy, vmrc; + int diag_cc, rc, i; + struct qout64 *qout; + struct qin64 *qin; + qin = kmalloc(sizeof(*qin), GFP_KERNEL | GFP_DMA); + qout = kmalloc(sizeof(*qout), GFP_KERNEL | GFP_DMA); if ((qin == NULL) || (qout == NULL)) { rc = -ENOMEM; goto out_free; @@ -286,7 +287,7 @@ query_segment_type (struct dcss_segment *seg) copy data for the new format. */ if (segext_scode == DCSS_SEGEXT) { struct qout64_old *qout_old; - qout_old = kzalloc(sizeof(struct qout64_old), GFP_DMA); + qout_old = kzalloc(sizeof(*qout_old), GFP_KERNEL | GFP_DMA); if (qout_old == NULL) { rc = -ENOMEM; goto out_free; @@ -407,11 +408,11 @@ segment_overlaps_others (struct dcss_segment *seg) static int __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end) { - struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment), - GFP_DMA); - int rc, diag_cc; unsigned long start_addr, end_addr, dummy; + struct dcss_segment *seg; + int rc, diag_cc; + seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA); if (seg == NULL) { rc = -ENOMEM; goto out; diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b49d8ca228f..8c7ae431862 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -110,6 +110,7 @@ #define MSR_AMD64_PATCH_LOADER 0xc0010020 #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 #define MSR_AMD64_OSVW_STATUS 0xc0010141 +#define MSR_AMD64_DC_CFG 0xc0011022 #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 #define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index 48dcfa62ea0..fd921c3a684 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h @@ -15,6 +15,8 @@ static inline int arch_prepare_suspend(void) { return 0; } struct saved_context { u16 es, fs, gs, ss; unsigned long cr0, cr2, cr3, cr4; + u64 misc_enable; + bool misc_enable_saved; struct desc_ptr gdt; struct desc_ptr idt; u16 ldt; diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index 06284f42b75..8d942afae68 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -27,6 +27,8 @@ struct saved_context { u16 ds, es, fs, gs, ss; unsigned long gs_base, gs_kernel_base, fs_base; unsigned long cr0, cr2, cr3, cr4, cr8; + u64 misc_enable; + bool misc_enable_saved; unsigned long efer; u16 gdt_pad; u16 gdt_limit; diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 7bca3c6a02f..0d6fc71bedb 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(void) struct e820entry *ei = &e820.map[i]; if (ei->type == E820_NVS) - hibernate_nvs_register(ei->addr, ei->size); + suspend_nvs_register(ei->addr, ei->size); } return 0; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 81563e76e28..a6f695d7692 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1815,6 +1815,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, spte |= PT_WRITABLE_MASK; + if (!tdp_enabled && !(pte_access & ACC_WRITE_MASK)) + spte &= ~PT_USER_MASK; + /* * Optimization: for pte sync, if spte was writable the hash * lookup is unnecessary (and expensive). Write protection @@ -1870,6 +1873,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, child = page_header(pte & PT64_BASE_ADDR_MASK); mmu_page_remove_parent_pte(child, sptep); + __set_spte(sptep, shadow_trap_nonpresent_pte); + kvm_flush_remote_tlbs(vcpu->kvm); } else if (pfn != spte_to_pfn(*sptep)) { pgprintk("hfn old %lx new %lx\n", spte_to_pfn(*sptep), pfn); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 96dc232bfc5..ce438e0fdd2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -28,6 +28,7 @@ #include <linux/ftrace_event.h> #include <linux/slab.h> +#include <asm/tlbflush.h> #include <asm/desc.h> #include <asm/virtext.h> @@ -56,6 +57,8 @@ MODULE_LICENSE("GPL"); #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) +static bool erratum_383_found __read_mostly; + static const u32 host_save_user_msrs[] = { #ifdef CONFIG_X86_64 MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, @@ -374,6 +377,31 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, svm->vmcb->control.event_inj_err = error_code; } +static void svm_init_erratum_383(void) +{ + u32 low, high; + int err; + u64 val; + + /* Only Fam10h is affected */ + if (boot_cpu_data.x86 != 0x10) + return; + + /* Use _safe variants to not break nested virtualization */ + val = native_read_msr_safe(MSR_AMD64_DC_CFG, &err); + if (err) + return; + + val |= (1ULL << 47); + + low = lower_32_bits(val); + high = upper_32_bits(val); + + native_write_msr_safe(MSR_AMD64_DC_CFG, low, high); + + erratum_383_found = true; +} + static int has_svm(void) { const char *msg; @@ -429,6 +457,8 @@ static int svm_hardware_enable(void *garbage) wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT); + svm_init_erratum_383(); + return 0; } @@ -1410,8 +1440,59 @@ static int nm_interception(struct vcpu_svm *svm) return 1; } -static int mc_interception(struct vcpu_svm *svm) +static bool is_erratum_383(void) { + int err, i; + u64 value; + + if (!erratum_383_found) + return false; + + value = native_read_msr_safe(MSR_IA32_MC0_STATUS, &err); + if (err) + return false; + + /* Bit 62 may or may not be set for this mce */ + value &= ~(1ULL << 62); + + if (value != 0xb600000000010015ULL) + return false; + + /* Clear MCi_STATUS registers */ + for (i = 0; i < 6; ++i) + native_write_msr_safe(MSR_IA32_MCx_STATUS(i), 0, 0); + + value = native_read_msr_safe(MSR_IA32_MCG_STATUS, &err); + if (!err) { + u32 low, high; + + value &= ~(1ULL << 2); + low = lower_32_bits(value); + high = upper_32_bits(value); + + native_write_msr_safe(MSR_IA32_MCG_STATUS, low, high); + } + + /* Flush tlb to evict multi-match entries */ + __flush_tlb_all(); + + return true; +} + +static void svm_handle_mce(struct vcpu_svm *svm) +{ + if (is_erratum_383()) { + /* + * Erratum 383 triggered. Guest state is corrupt so kill the + * guest. + */ + pr_err("KVM: Guest triggered AMD Erratum 383\n"); + + set_bit(KVM_REQ_TRIPLE_FAULT, &svm->vcpu.requests); + + return; + } + /* * On an #MC intercept the MCE handler is not called automatically in * the host. So do it by hand here. @@ -1420,6 +1501,11 @@ static int mc_interception(struct vcpu_svm *svm) "int $0x12\n"); /* not sure if we ever come back to this point */ + return; +} + +static int mc_interception(struct vcpu_svm *svm) +{ return 1; } @@ -3088,6 +3174,14 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); } + + /* + * We need to handle MC intercepts here before the vcpu has a chance to + * change the physical cpu + */ + if (unlikely(svm->vmcb->control.exit_code == + SVM_EXIT_EXCP_BASE + MC_VECTOR)) + svm_handle_mce(svm); } #undef R diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 97da2ba9344..6fdb3ec30c3 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -96,6 +96,7 @@ EXPORT_SYMBOL(pcibios_align_resource); * the fact the PCI specs explicitly allow address decoders to be * shared between expansion ROMs and other resource regions, it's * at least dangerous) + * - bad resource sizes or overlaps with other regions * * Our solution: * (1) Allocate resources for all buses behind PCI-to-PCI bridges. @@ -136,6 +137,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) * child resource allocations in this * range. */ + r->start = r->end = 0; r->flags = 0; } } diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 0a979f3e5b8..1290ba54b35 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -105,6 +105,8 @@ static void __save_processor_state(struct saved_context *ctxt) ctxt->cr4 = read_cr4(); ctxt->cr8 = read_cr8(); #endif + ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE, + &ctxt->misc_enable); } /* Needed by apm.c */ @@ -152,6 +154,8 @@ static void fix_processor_context(void) */ static void __restore_processor_state(struct saved_context *ctxt) { + if (ctxt->misc_enable_saved) + wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable); /* * control registers */ diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index d269a8f3329..446aced33af 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -46,6 +46,8 @@ static unsigned long power_saving_mwait_eax; static unsigned char tsc_detected_unstable; static unsigned char tsc_marked_unstable; +static unsigned char lapic_detected_unstable; +static unsigned char lapic_marked_unstable; static void power_saving_mwait_init(void) { @@ -75,9 +77,6 @@ static void power_saving_mwait_init(void) power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | (highest_subcstate - 1); - for_each_online_cpu(i) - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i); - #if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: @@ -86,13 +85,15 @@ static void power_saving_mwait_init(void) * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. */ - if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) - return; - - /*FALL THROUGH*/ + if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) + tsc_detected_unstable = 1; + if (!boot_cpu_has(X86_FEATURE_ARAT)) + lapic_detected_unstable = 1; + break; default: - /* TSC could halt in idle */ + /* TSC & LAPIC could halt in idle */ tsc_detected_unstable = 1; + lapic_detected_unstable = 1; } #endif } @@ -180,10 +181,20 @@ static int power_saving_thread(void *data) mark_tsc_unstable("TSC halts in idle"); tsc_marked_unstable = 1; } + if (lapic_detected_unstable && !lapic_marked_unstable) { + int i; + /* LAPIC could halt in idle, so notify users */ + for_each_online_cpu(i) + clockevents_notify( + CLOCK_EVT_NOTIFY_BROADCAST_ON, + &i); + lapic_marked_unstable = 1; + } local_irq_disable(); cpu = smp_processor_id(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, - &cpu); + if (lapic_marked_unstable) + clockevents_notify( + CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); stop_critical_timings(); __monitor((void *)¤t_thread_info()->flags, 0, 0); @@ -192,8 +203,9 @@ static int power_saving_thread(void *data) __mwait(power_saving_mwait_eax, 1); start_critical_timings(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, - &cpu); + if (lapic_marked_unstable) + clockevents_notify( + CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); local_irq_enable(); if (jiffies > expire_time) { diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index 33181ad350d..b17d8de9f6f 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -119,6 +119,10 @@ #define ACPI_MAX_LOOP_ITERATIONS 0xFFFF +/* Maximum sleep allowed via Sleep() operator */ + +#define ACPI_MAX_SLEEP 20000 /* Two seconds */ + /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 64d1e5c2d4a..c3f43daa8be 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -80,10 +80,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); acpi_status acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); -acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); - -acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); - struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 9070f1fe8f1..899d68afc3c 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -125,6 +125,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); +/* + * Optionally truncate I/O addresses to 16 bits. Provides compatibility + * with other ACPI implementations. NOTE: During ACPICA initialization, + * this value is set to TRUE if any Windows OSI strings have been + * requested by the BIOS. + */ +u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); + /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ struct acpi_table_fadt acpi_gbl_FADT; diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 5900f135dc6..32391588e16 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -90,7 +90,11 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); /* * hwgpe - GPE support */ -acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); +u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, + struct acpi_gpe_register_info *gpe_register_info); + +acpi_status +acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); acpi_status acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index a221ad40416..7c2c336006a 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -69,7 +69,7 @@ acpi_status acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) { struct acpi_gpe_register_info *gpe_register_info; - u8 register_bit; + u32 register_bit; ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); @@ -78,9 +78,8 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_NOT_EXIST); } - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); /* Clear the wake/run bits up front */ @@ -100,106 +99,6 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_enable_gpe - * - * PARAMETERS: gpe_event_info - GPE to enable - * - * RETURN: Status - * - * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless - * of type or number of references. - * - * Note: The GPE lock should be already acquired when this function is called. - * - ******************************************************************************/ - -acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) -{ - acpi_status status; - - - ACPI_FUNCTION_TRACE(ev_enable_gpe); - - - /* - * We will only allow a GPE to be enabled if it has either an - * associated method (_Lxx/_Exx) or a handler. Otherwise, the - * GPE will be immediately disabled by acpi_ev_gpe_dispatch the - * first time it fires. - */ - if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { - return_ACPI_STATUS(AE_NO_HANDLER); - } - - /* Ensure the HW enable masks are current */ - - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Clear the GPE (of stale events) */ - - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Enable the requested GPE */ - - status = acpi_hw_write_gpe_enable_reg(gpe_event_info); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ev_disable_gpe - * - * PARAMETERS: gpe_event_info - GPE to disable - * - * RETURN: Status - * - * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE, - * regardless of the type or number of references. - * - * Note: The GPE lock should be already acquired when this function is called. - * - ******************************************************************************/ - -acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(ev_disable_gpe); - - - /* - * Note: Always disable the GPE, even if we think that that it is already - * disabled. It is possible that the AML or some other code has enabled - * the GPE behind our back. - */ - - /* Ensure the HW enable masks are current */ - - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Always H/W disable this GPE, even if we don't know the GPE type. - * Simply clear the enable bit for this particular GPE, but do not - * write out the current GPE enable mask since this may inadvertently - * enable GPEs too early. An example is a rogue GPE that has arrived - * during ACPICA initialization - possibly because AML or other code - * has enabled the GPE. - */ - status = acpi_hw_low_disable_gpe(gpe_event_info); - return_ACPI_STATUS(status); -} - /******************************************************************************* * @@ -451,10 +350,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) return_VOID; } - /* Update the GPE register masks for return to enabled state */ - - (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); - /* * Take a snapshot of the GPE info for this level - we copy the info to * prevent a race condition with remove_handler/remove_block. @@ -607,7 +502,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) * Disable the GPE, so it doesn't keep firing before the method has a * chance to run (it runs asynchronously with interrupts enabled). */ - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to disable GPE[0x%2X]", @@ -644,7 +539,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) * Disable the GPE. The GPE will remain disabled a handler * is installed or ACPICA is restarted. */ - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to disable GPE[0x%2X]", diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 7c28f2d9fd3..341a38ce8aa 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -500,6 +500,19 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; + gpe_number = gpe_index + gpe_block->block_base_number; + + /* + * If the GPE has already been enabled for runtime + * signaling, make sure it remains enabled, but do not + * increment its reference counter. + */ + if (gpe_event_info->runtime_count) { + acpi_set_gpe(gpe_device, gpe_number, + ACPI_GPE_ENABLE); + gpe_enabled_count++; + continue; + } if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { wake_gpe_count++; @@ -516,7 +529,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, /* Enable this GPE */ - gpe_number = gpe_index + gpe_block->block_base_number; status = acpi_enable_gpe(gpe_device, gpe_number, ACPI_GPE_TYPE_RUNTIME); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index cc825023012..4a531cdf794 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -719,13 +719,6 @@ acpi_install_gpe_handler(acpi_handle gpe_device, handler->context = context; handler->method_node = gpe_event_info->dispatch.method_node; - /* Disable the GPE before installing the handler */ - - status = acpi_ev_disable_gpe(gpe_event_info); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - /* Install the handler */ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d5a5efc043b..d97b8dce166 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -210,6 +210,44 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) /******************************************************************************* * + * FUNCTION: acpi_clear_and_enable_gpe + * + * PARAMETERS: gpe_event_info - GPE to enable + * + * RETURN: Status + * + * DESCRIPTION: Clear the given GPE from stale events and enable it. + * + ******************************************************************************/ +static acpi_status +acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + /* + * We will only allow a GPE to be enabled if it has either an + * associated method (_Lxx/_Exx) or a handler. Otherwise, the + * GPE will be immediately disabled by acpi_ev_gpe_dispatch the + * first time it fires. + */ + if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { + return_ACPI_STATUS(AE_NO_HANDLER); + } + + /* Clear the GPE (of stale events) */ + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Enable the requested GPE */ + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * * FUNCTION: acpi_set_gpe * * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 @@ -249,11 +287,11 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) switch (action) { case ACPI_GPE_ENABLE: - status = acpi_ev_enable_gpe(gpe_event_info); + status = acpi_clear_and_enable_gpe(gpe_event_info); break; case ACPI_GPE_DISABLE: - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); break; default: @@ -316,7 +354,11 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) gpe_event_info->runtime_count++; if (gpe_event_info->runtime_count == 1) { - status = acpi_ev_enable_gpe(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_clear_and_enable_gpe(gpe_event_info); + } + if (ACPI_FAILURE(status)) { gpe_event_info->runtime_count--; goto unlock_and_exit; @@ -343,7 +385,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) */ gpe_event_info->wakeup_count++; if (gpe_event_info->wakeup_count == 1) { - (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); } } @@ -403,7 +445,12 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type gpe_event_info->runtime_count--; if (!gpe_event_info->runtime_count) { - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_hw_low_set_gpe(gpe_event_info, + ACPI_GPE_DISABLE); + } + if (ACPI_FAILURE(status)) { gpe_event_info->runtime_count++; goto unlock_and_exit; @@ -424,7 +471,7 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type gpe_event_info->wakeup_count--; if (!gpe_event_info->wakeup_count) { - (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); } } diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 6d32e09327f..675aaa91a77 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -201,6 +201,14 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long) acpi_ex_relinquish_interpreter(); + /* + * For compatibility with other ACPI implementations and to prevent + * accidental deep sleeps, limit the sleep time to something reasonable. + */ + if (how_long > ACPI_MAX_SLEEP) { + how_long = ACPI_MAX_SLEEP; + } + acpi_os_sleep(how_long); /* And now we must get the interpreter again */ diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index bd72319a38f..3450309c278 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -57,21 +57,47 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /****************************************************************************** * - * FUNCTION: acpi_hw_low_disable_gpe + * FUNCTION: acpi_hw_gpe_register_bit + * + * PARAMETERS: gpe_event_info - Info block for the GPE + * gpe_register_info - Info block for the GPE register + * + * RETURN: Status + * + * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given + * GPE set. + * + ******************************************************************************/ + +u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, + struct acpi_gpe_register_info *gpe_register_info) +{ + return (u32)1 << (gpe_event_info->gpe_number - + gpe_register_info->base_gpe_number); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_low_set_gpe * * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled + * action - Enable or disable * * RETURN: Status * - * DESCRIPTION: Disable a single GPE in the enable register. + * DESCRIPTION: Enable or disable a single GPE in its enable register. * ******************************************************************************/ -acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) +acpi_status +acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) { struct acpi_gpe_register_info *gpe_register_info; acpi_status status; u32 enable_mask; + u32 register_bit; + + ACPI_FUNCTION_ENTRY(); /* Get the info block for the entire GPE register */ @@ -87,11 +113,27 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) return (status); } - /* Clear just the bit that corresponds to this GPE */ + /* Set ot clear just the bit that corresponds to this GPE */ - ACPI_CLEAR_BIT(enable_mask, ((u32)1 << - (gpe_event_info->gpe_number - - gpe_register_info->base_gpe_number))); + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); + switch (action) { + case ACPI_GPE_COND_ENABLE: + if (!(register_bit & gpe_register_info->enable_for_run)) + return (AE_BAD_PARAMETER); + + case ACPI_GPE_ENABLE: + ACPI_SET_BIT(enable_mask, register_bit); + break; + + case ACPI_GPE_DISABLE: + ACPI_CLEAR_BIT(enable_mask, register_bit); + break; + + default: + ACPI_ERROR((AE_INFO, "Invalid action\n")); + return (AE_BAD_PARAMETER); + } /* Write the updated enable mask */ @@ -116,23 +158,11 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) acpi_status acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) { - struct acpi_gpe_register_info *gpe_register_info; acpi_status status; ACPI_FUNCTION_ENTRY(); - /* Get the info block for the entire GPE register */ - - gpe_register_info = gpe_event_info->register_info; - if (!gpe_register_info) { - return (AE_NOT_EXIST); - } - - /* Write the entire GPE (runtime) enable register */ - - status = acpi_hw_write(gpe_register_info->enable_for_run, - &gpe_register_info->enable_address); - + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); return (status); } @@ -150,21 +180,28 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) { + struct acpi_gpe_register_info *gpe_register_info; acpi_status status; - u8 register_bit; + u32 register_bit; ACPI_FUNCTION_ENTRY(); - register_bit = (u8)(1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + /* Get the info block for the entire GPE register */ + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return (AE_NOT_EXIST); + } + + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); /* * Write a one to the appropriate bit in the status register to * clear this GPE. */ status = acpi_hw_write(register_bit, - &gpe_event_info->register_info->status_address); + &gpe_register_info->status_address); return (status); } @@ -187,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, acpi_event_status * event_status) { u32 in_byte; - u8 register_bit; + u32 register_bit; struct acpi_gpe_register_info *gpe_register_info; acpi_status status; acpi_event_status local_event_status = 0; @@ -204,9 +241,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Get the register bitmask for this GPE */ - register_bit = (u8)(1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); /* GPE currently enabled? (enabled for runtime?) */ diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index c10d587c164..e1d9c777b21 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -222,6 +222,12 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) u32 one_byte; u32 i; + /* Truncate address to 16 bits if requested */ + + if (acpi_gbl_truncate_io_addresses) { + address &= ACPI_UINT16_MAX; + } + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); @@ -279,6 +285,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) acpi_status status; u32 i; + /* Truncate address to 16 bits if requested */ + + if (acpi_gbl_truncate_io_addresses) { + address &= ACPI_UINT16_MAX; + } + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 9bd6f050f29..4e5272c313e 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -193,6 +193,15 @@ acpi_status acpi_ns_initialize_devices(void) acpi_ns_init_one_device, NULL, &info, NULL); + /* + * Any _OSI requests should be completed by now. If the BIOS has + * requested any Windows OSI strings, we will always truncate + * I/O addresses to 16 bits -- for Windows compatibility. + */ + if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) { + acpi_gbl_truncate_io_addresses = TRUE; + } + ACPI_FREE(info.evaluate_info); if (ACPI_FAILURE(status)) { goto error_exit; diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2815df66f6f..01381be05e9 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -218,6 +218,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { + .callback = dmi_disable_osi_vista, + .ident = "VGN-NS50B_L", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), + }, + }, + { .callback = dmi_disable_osi_win7, .ident = "ASUS K50IJ", .matches = { diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index fd51c4ab482..7d857dabdde 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -425,7 +425,7 @@ static int acpi_button_add(struct acpi_device *device) /* Button's GPE is run-wake GPE */ acpi_enable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); + ACPI_GPE_TYPE_RUNTIME); device->wakeup.run_wake_count++; device->wakeup.state.enabled = 1; } @@ -449,7 +449,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) if (device->wakeup.flags.valid) { acpi_disable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); + ACPI_GPE_TYPE_RUNTIME); device->wakeup.run_wake_count--; device->wakeup.state.enabled = 0; } diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index acf2ab24984..8a3b840c0bb 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -347,7 +347,6 @@ static int __init acpi_fan_init(void) { int result = 0; - #ifdef CONFIG_ACPI_PROCFS acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); if (!acpi_fan_dir) @@ -356,7 +355,9 @@ static int __init acpi_fan_init(void) result = acpi_bus_register_driver(&acpi_fan_driver); if (result < 0) { +#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); +#endif return -ENODEV; } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index b1034a9ada4..38ea0cc6dc4 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -581,6 +581,11 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return 0; } +#ifdef CONFIG_SMP + if (pr->id >= setup_max_cpus && pr->id != 0) + return 0; +#endif + BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); /* diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 3fb4bdea7e0..5b7c52e4a00 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -114,6 +114,8 @@ static int __acpi_pm_prepare(void) { int error = acpi_sleep_prepare(acpi_target_sleep_state); + suspend_nvs_save(); + if (error) acpi_target_sleep_state = ACPI_STATE_S0; return error; @@ -143,6 +145,9 @@ static void acpi_pm_finish(void) { u32 acpi_state = acpi_target_sleep_state; + suspend_nvs_free(); + acpi_ec_unblock_transactions(); + if (acpi_state == ACPI_STATE_S0) return; @@ -192,6 +197,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state) u32 acpi_state = acpi_suspend_states[pm_state]; int error = 0; + error = suspend_nvs_alloc(); + + if (error) + return error; + if (sleep_states[acpi_state]) { acpi_target_sleep_state = acpi_state; acpi_sleep_tts_switch(acpi_target_sleep_state); @@ -269,12 +279,13 @@ static int acpi_suspend_enter(suspend_state_t pm_state) if (acpi_state == ACPI_STATE_S3) acpi_restore_state_mem(); + suspend_nvs_restore(); + return ACPI_SUCCESS(status) ? 0 : -EFAULT; } static void acpi_suspend_finish(void) { - acpi_ec_unblock_transactions(); acpi_pm_finish(); } @@ -404,7 +415,7 @@ static int acpi_hibernation_begin(void) { int error; - error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); + error = s4_no_nvs ? 0 : suspend_nvs_alloc(); if (!error) { acpi_target_sleep_state = ACPI_STATE_S4; acpi_sleep_tts_switch(acpi_target_sleep_state); @@ -418,7 +429,7 @@ static int acpi_hibernation_pre_snapshot(void) int error = acpi_pm_prepare(); if (!error) - hibernate_nvs_save(); + suspend_nvs_save(); return error; } @@ -441,13 +452,6 @@ static int acpi_hibernation_enter(void) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } -static void acpi_hibernation_finish(void) -{ - hibernate_nvs_free(); - acpi_ec_unblock_transactions(); - acpi_pm_finish(); -} - static void acpi_hibernation_leave(void) { /* @@ -464,7 +468,7 @@ static void acpi_hibernation_leave(void) panic("ACPI S4 hardware signature mismatch"); } /* Restore the NVS memory area */ - hibernate_nvs_restore(); + suspend_nvs_restore(); /* Allow EC transactions to happen. */ acpi_ec_unblock_transactions_early(); } @@ -479,7 +483,7 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { .begin = acpi_hibernation_begin, .end = acpi_pm_end, .pre_snapshot = acpi_hibernation_pre_snapshot, - .finish = acpi_hibernation_finish, + .finish = acpi_pm_finish, .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, @@ -507,7 +511,7 @@ static int acpi_hibernation_begin_old(void) if (!error) { if (!s4_no_nvs) - error = hibernate_nvs_alloc(); + error = suspend_nvs_alloc(); if (!error) acpi_target_sleep_state = ACPI_STATE_S4; } @@ -517,7 +521,7 @@ static int acpi_hibernation_begin_old(void) static int acpi_hibernation_pre_snapshot_old(void) { acpi_pm_freeze(); - hibernate_nvs_save(); + suspend_nvs_save(); return 0; } @@ -529,8 +533,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { .begin = acpi_hibernation_begin_old, .end = acpi_pm_end, .pre_snapshot = acpi_hibernation_pre_snapshot_old, - .finish = acpi_hibernation_finish, .prepare = acpi_pm_freeze, + .finish = acpi_pm_finish, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, .pre_restore = acpi_pm_freeze, diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index c79e789ed03..f8db50a0941 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -388,10 +388,12 @@ static ssize_t counter_set(struct kobject *kobj, if (index < num_gpes) { if (!strcmp(buf, "disable\n") && (status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE); + result = acpi_disable_gpe(handle, index, + ACPI_GPE_TYPE_RUNTIME); else if (!strcmp(buf, "enable\n") && !(status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE); + result = acpi_enable_gpe(handle, index, + ACPI_GPE_TYPE_RUNTIME); else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_gpe(handle, index); diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 4b9d339a6e2..388747a7ef4 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -64,16 +64,13 @@ void acpi_enable_wakeup_device(u8 sleep_state) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid) - continue; - - if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) + if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled || sleep_state > (u32) dev->wakeup.sleep_state) continue; /* The wake-up power should have been enabled already. */ - acpi_set_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_ENABLE); + acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_TYPE_WAKE); } } @@ -96,6 +93,8 @@ void acpi_disable_wakeup_device(u8 sleep_state) || (sleep_state > (u32) dev->wakeup.sleep_state)) continue; + acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_TYPE_WAKE); acpi_disable_wakeup_device_power(dev); } } @@ -109,13 +108,8 @@ int __init acpi_wakeup_device_init(void) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - /* In case user doesn't load button driver */ - if (!dev->wakeup.flags.always_enabled || - dev->wakeup.state.enabled) - continue; - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - dev->wakeup.state.enabled = 1; + if (dev->wakeup.flags.always_enabled) + dev->wakeup.state.enabled = 1; } mutex_unlock(&acpi_device_lock); return 0; diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 1984a6e89e8..261f86d102e 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -541,29 +541,11 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) return -EINVAL; } -static int ahci_is_device_present(void __iomem *port_mmio) -{ - u8 status = readl(port_mmio + PORT_TFDATA) & 0xff; - - /* Make sure PxTFD.STS.BSY and PxTFD.STS.DRQ are 0 */ - if (status & (ATA_BUSY | ATA_DRQ)) - return 0; - - /* Make sure PxSSTS.DET is 3h */ - status = readl(port_mmio + PORT_SCR_STAT) & 0xf; - if (status != 3) - return 0; - return 1; -} - void ahci_start_engine(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; - if (!ahci_is_device_present(port_mmio)) - return; - /* start DMA */ tmp = readl(port_mmio + PORT_CMD); tmp |= PORT_CMD_START; @@ -1892,6 +1874,9 @@ static void ahci_error_handler(struct ata_port *ap) } sata_pmp_error_handler(ap); + + if (!ata_dev_enabled(ap->link.device)) + ahci_stop_engine(ap); } static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index e9250514734..be7726d7686 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -539,12 +539,12 @@ static void sil24_config_port(struct ata_port *ap) writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); /* zero error counters. */ - writel(0x8000, port + PORT_DECODE_ERR_THRESH); - writel(0x8000, port + PORT_CRC_ERR_THRESH); - writel(0x8000, port + PORT_HSHK_ERR_THRESH); - writel(0x0000, port + PORT_DECODE_ERR_CNT); - writel(0x0000, port + PORT_CRC_ERR_CNT); - writel(0x0000, port + PORT_HSHK_ERR_CNT); + writew(0x8000, port + PORT_DECODE_ERR_THRESH); + writew(0x8000, port + PORT_CRC_ERR_THRESH); + writew(0x8000, port + PORT_HSHK_ERR_THRESH); + writew(0x0000, port + PORT_DECODE_ERR_CNT); + writew(0x0000, port + PORT_CRC_ERR_CNT); + writew(0x0000, port + PORT_HSHK_ERR_CNT); /* always use 64bit activation */ writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR); @@ -622,6 +622,11 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp, irq_enabled = readl(port + PORT_IRQ_ENABLE_SET); writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR); + /* + * The barrier is required to ensure that writes to cmd_block reach + * the memory before the write to PORT_CMD_ACTIVATE. + */ + wmb(); writel((u32)paddr, port + PORT_CMD_ACTIVATE); writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); @@ -865,7 +870,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) } else { prb = &cb->atapi.prb; sge = cb->atapi.sge; - memset(cb->atapi.cdb, 0, 32); + memset(cb->atapi.cdb, 0, sizeof(cb->atapi.cdb)); memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len); if (ata_is_data(qc->tf.protocol)) { @@ -895,6 +900,11 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) paddr = pp->cmd_block_dma + tag * sizeof(*pp->cmd_block); activate = port + PORT_CMD_ACTIVATE + tag * 8; + /* + * The barrier is required to ensure that writes to cmd_block reach + * the memory before the write to PORT_CMD_ACTIVATE. + */ + wmb(); writel((u32)paddr, activate); writel((u64)paddr >> 32, activate + 4); diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 0ecd0f6aa2c..4730c42a5ee 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -578,10 +578,24 @@ static void svia_configure(struct pci_dev *pdev) /* * vt6421 has problems talking to some drives. The following - * is the magic fix from Joseph Chan <JosephChan@via.com.tw>. - * Please add proper documentation if possible. + * is the fix from Joseph Chan <JosephChan@via.com.tw>. + * + * When host issues HOLD, device may send up to 20DW of data + * before acknowledging it with HOLDA and the host should be + * able to buffer them in FIFO. Unfortunately, some WD drives + * send upto 40DW before acknowledging HOLD and, in the + * default configuration, this ends up overflowing vt6421's + * FIFO, making the controller abort the transaction with + * R_ERR. + * + * Rx52[2] is the internal 128DW FIFO Flow control watermark + * adjusting mechanism enable bit and the default value 0 + * means host will issue HOLD to device when the left FIFO + * size goes below 32DW. Setting it to 1 makes the watermark + * 64DW. * * https://bugzilla.kernel.org/show_bug.cgi?id=15173 + * http://article.gmane.org/gmane.linux.ide/46352 */ if (pdev->device == 0x3249) { pci_read_config_byte(pdev, 0x52, &tmp8); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 8e00b4ddd08..792868d24f2 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -224,6 +224,7 @@ struct tpm_readpubek_params_out { u8 algorithm[4]; u8 encscheme[2]; u8 sigscheme[2]; + __be32 paramsize; u8 parameters[12]; /*assuming RSA*/ __be32 keysize; u8 modulus[256]; diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 1296c42ed5c..7cdb6ee569c 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -304,7 +304,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); - scr_memsetw(d + (b - t - nr) * vc->vc_size_row, vc->vc_video_erase_char, + scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, vc->vc_size_row * nr); } diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 9dcb30466ec..371713ff026 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -231,7 +231,7 @@ void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) static void fw_card_bm_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, work.work); - struct fw_device *root_device; + struct fw_device *root_device, *irm_device; struct fw_node *root_node; unsigned long flags; int root_id, new_root_id, irm_id, local_id; @@ -239,6 +239,7 @@ static void fw_card_bm_work(struct work_struct *work) bool do_reset = false; bool root_device_is_running; bool root_device_is_cmc; + bool irm_is_1394_1995_only; spin_lock_irqsave(&card->lock, flags); @@ -248,12 +249,18 @@ static void fw_card_bm_work(struct work_struct *work) } generation = card->generation; + root_node = card->root_node; fw_node_get(root_node); root_device = root_node->data; root_device_is_running = root_device && atomic_read(&root_device->state) == FW_DEVICE_RUNNING; root_device_is_cmc = root_device && root_device->cmc; + + irm_device = card->irm_node->data; + irm_is_1394_1995_only = irm_device && irm_device->config_rom && + (irm_device->config_rom[2] & 0x000000f0) == 0; + root_id = root_node->node_id; irm_id = card->irm_node->node_id; local_id = card->local_node->node_id; @@ -276,8 +283,15 @@ static void fw_card_bm_work(struct work_struct *work) if (!card->irm_node->link_on) { new_root_id = local_id; - fw_notify("IRM has link off, making local node (%02x) root.\n", - new_root_id); + fw_notify("%s, making local node (%02x) root.\n", + "IRM has link off", new_root_id); + goto pick_me; + } + + if (irm_is_1394_1995_only) { + new_root_id = local_id; + fw_notify("%s, making local node (%02x) root.\n", + "IRM is not 1394a compliant", new_root_id); goto pick_me; } @@ -316,8 +330,8 @@ static void fw_card_bm_work(struct work_struct *work) * root, and thus, IRM. */ new_root_id = local_id; - fw_notify("BM lock failed, making local node (%02x) root.\n", - new_root_id); + fw_notify("%s, making local node (%02x) root.\n", + "BM lock failed", new_root_id); goto pick_me; } } else if (card->bm_generation != generation) { diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 994d23beeb1..57cea01c4ff 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1840,8 +1840,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); - if (ret) + if (ret) { + ret = -EFAULT; goto out_err2; + } } if (fb->funcs->dirty) { diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index b3779d243ae..08c4c926e65 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -264,7 +264,7 @@ bool drm_fb_helper_force_kernel_mode(void) int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed, void *panic_str) { - DRM_ERROR("panic occurred, switching back to text console\n"); + printk(KERN_ERR "panic occurred, switching back to text console\n"); return drm_fb_helper_force_kernel_mode(); return 0; } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b2ebf02e4f8..59a2bf8592e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1402,19 +1402,19 @@ static int i915_load_modeset_init(struct drm_device *dev, /* if we have > 1 VGA cards, then disable the radeon VGA resources */ ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); if (ret) - goto destroy_ringbuffer; + goto cleanup_ringbuffer; ret = vga_switcheroo_register_client(dev->pdev, i915_switcheroo_set_state, i915_switcheroo_can_switch); if (ret) - goto destroy_ringbuffer; + goto cleanup_vga_client; intel_modeset_init(dev); ret = drm_irq_install(dev); if (ret) - goto destroy_ringbuffer; + goto cleanup_vga_switcheroo; /* Always safe in the mode setting case. */ /* FIXME: do pre/post-mode set stuff in core KMS code */ @@ -1426,11 +1426,20 @@ static int i915_load_modeset_init(struct drm_device *dev, I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); - intel_fbdev_init(dev); + ret = intel_fbdev_init(dev); + if (ret) + goto cleanup_irq; + drm_kms_helper_poll_init(dev); return 0; -destroy_ringbuffer: +cleanup_irq: + drm_irq_uninstall(dev); +cleanup_vga_switcheroo: + vga_switcheroo_unregister_client(dev->pdev); +cleanup_vga_client: + vga_client_register(dev->pdev, NULL, NULL, NULL); +cleanup_ringbuffer: mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9ed8ecd9580..27658315984 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -278,6 +278,7 @@ typedef struct drm_i915_private { struct mem_block *agp_heap; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; + int num_pipe; /* For hangcheck timer */ #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 04e1bb499ff..cc8131ff319 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3653,6 +3653,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, pipeconf &= ~PIPEACONF_DOUBLE_WIDE; } + dspcntr |= DISPLAY_PLANE_ENABLE; + pipeconf |= PIPEACONF_ENABLE; + dpll |= DPLL_VCO_ENABLE; + + /* Disable the panel fitter if it was on our pipe */ if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe) I915_WRITE(PFIT_CONTROL, 0); @@ -5470,7 +5475,6 @@ static void intel_init_display(struct drm_device *dev) void intel_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int num_pipe; int i; drm_mode_config_init(dev); @@ -5500,13 +5504,13 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0); if (IS_MOBILE(dev) || IS_I9XX(dev)) - num_pipe = 2; + dev_priv->num_pipe = 2; else - num_pipe = 1; + dev_priv->num_pipe = 1; DRM_DEBUG_KMS("%d display pipe%s available.\n", - num_pipe, num_pipe > 1 ? "s" : ""); + dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); - for (i = 0; i < num_pipe; i++) { + for (i = 0; i < dev_priv->num_pipe; i++) { intel_crtc_init(dev, i); } diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index f8c76e64bb7..c3c505244e0 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -245,6 +245,7 @@ int intel_fbdev_init(struct drm_device *dev) { struct intel_fbdev *ifbdev; drm_i915_private_t *dev_priv = dev->dev_private; + int ret; ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL); if (!ifbdev) @@ -253,8 +254,13 @@ int intel_fbdev_init(struct drm_device *dev) dev_priv->fbdev = ifbdev; ifbdev->helper.funcs = &intel_fb_helper_funcs; - drm_fb_helper_init(dev, &ifbdev->helper, 2, - INTELFB_CONN_LIMIT); + ret = drm_fb_helper_init(dev, &ifbdev->helper, + dev_priv->num_pipe, + INTELFB_CONN_LIMIT); + if (ret) { + kfree(ifbdev); + return ret; + } drm_fb_helper_single_add_all_connectors(&ifbdev->helper); drm_fb_helper_initial_config(&ifbdev->helper, 32); diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 9ba2deaadcc..fc924b64919 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -834,7 +834,7 @@ init_i2c_device_find(struct drm_device *dev, int i2c_index) if (i2c_index == 0x81) i2c_index = (dcb->i2c_default_indices & 0xf0) >> 4; - if (i2c_index > DCB_MAX_NUM_I2C_ENTRIES) { + if (i2c_index >= DCB_MAX_NUM_I2C_ENTRIES) { NV_ERROR(dev, "invalid i2c_index 0x%x\n", i2c_index); return NULL; } @@ -3920,7 +3920,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b static uint8_t * bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, - uint16_t record, int record_len, int record_nr) + uint16_t record, int record_len, int record_nr, + bool match_link) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvbios *bios = &dev_priv->vbios; @@ -3928,12 +3929,28 @@ bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, uint16_t table; int i, v; + switch (dcbent->type) { + case OUTPUT_TMDS: + case OUTPUT_LVDS: + case OUTPUT_DP: + break; + default: + match_link = false; + break; + } + for (i = 0; i < record_nr; i++, record += record_len) { table = ROM16(bios->data[record]); if (!table) continue; entry = ROM32(bios->data[table]); + if (match_link) { + v = (entry & 0x00c00000) >> 22; + if (!(v & dcbent->sorconf.link)) + continue; + } + v = (entry & 0x000f0000) >> 16; if (!(v & dcbent->or)) continue; @@ -3975,7 +3992,7 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, *length = table[4]; return bios_output_config_match(dev, dcbent, bios->display.dp_table_ptr + table[1], - table[2], table[3]); + table[2], table[3], table[0] >= 0x21); } int @@ -4064,7 +4081,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, dcbent->type, dcbent->location, dcbent->or); otable = bios_output_config_match(dev, dcbent, table[1] + bios->display.script_table_ptr, - table[2], table[3]); + table[2], table[3], table[0] >= 0x21); if (!otable) { NV_ERROR(dev, "Couldn't find matching output script table\n"); return 1; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index fd4a2df715e..c9a4a0d2a11 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -377,6 +377,7 @@ int nouveau_fbcon_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fbdev *nfbdev; + int ret; nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); if (!nfbdev) @@ -386,7 +387,12 @@ int nouveau_fbcon_init(struct drm_device *dev) dev_priv->nfbdev = nfbdev; nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; - drm_fb_helper_init(dev, &nfbdev->helper, 2, 4); + ret = drm_fb_helper_init(dev, &nfbdev->helper, 2, 4); + if (ret) { + kfree(nfbdev); + return ret; + } + drm_fb_helper_single_add_all_connectors(&nfbdev->helper); drm_fb_helper_initial_config(&nfbdev->helper, 32); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 147e59c4015..b02a231d693 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -779,29 +779,24 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) return ret; } - /* map larger RAMIN aperture on NV40 cards */ - dev_priv->ramin = NULL; + /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ if (dev_priv->card_type >= NV_40) { int ramin_bar = 2; if (pci_resource_len(dev->pdev, ramin_bar) == 0) ramin_bar = 3; dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar); - dev_priv->ramin = ioremap( - pci_resource_start(dev->pdev, ramin_bar), + dev_priv->ramin = + ioremap(pci_resource_start(dev->pdev, ramin_bar), dev_priv->ramin_size); if (!dev_priv->ramin) { - NV_ERROR(dev, "Failed to init RAMIN mapping, " - "limited instance memory available\n"); + NV_ERROR(dev, "Failed to PRAMIN BAR"); + return -ENOMEM; } - } - - /* On older cards (or if the above failed), create a map covering - * the BAR0 PRAMIN aperture */ - if (!dev_priv->ramin) { + } else { dev_priv->ramin_size = 1 * 1024 * 1024; dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN, - dev_priv->ramin_size); + dev_priv->ramin_size); if (!dev_priv->ramin) { NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c index a95e6941ba8..32611bd30e6 100644 --- a/drivers/gpu/drm/nouveau/nv50_fb.c +++ b/drivers/gpu/drm/nouveau/nv50_fb.c @@ -6,10 +6,16 @@ int nv50_fb_init(struct drm_device *dev) { - /* This is needed to get meaningful information from 100c90 - * on traps. No idea what these values mean exactly. */ struct drm_nouveau_private *dev_priv = dev->dev_private; + /* Not a clue what this is exactly. Without pointing it at a + * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) + * cause IOMMU "read from address 0" errors (rh#561267) + */ + nv_wr32(dev, 0x100c08, dev_priv->gart_info.sg_dummy_bus >> 8); + + /* This is needed to get meaningful information from 100c90 + * on traps. No idea what these values mean exactly. */ switch (dev_priv->chipset) { case 0x50: nv_wr32(dev, 0x100c90, 0x0707ff); diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index c61782b314e..bb47ad73726 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -31,7 +31,7 @@ nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift) { const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; - if (gpio->line > 32) + if (gpio->line >= 32) return -EINVAL; *reg = nv50_gpio_reg[gpio->line >> 3]; diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 0440c0939bd..4b6623df3b9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -41,12 +41,18 @@ void evergreen_fini(struct radeon_device *rdev); void evergreen_pm_misc(struct radeon_device *rdev) { - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) - radeon_atom_set_voltage(rdev, voltage->voltage); + int req_ps_idx = rdev->pm.requested_power_state_index; + int req_cm_idx = rdev->pm.requested_clock_mode_index; + struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; + struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; + + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { + if (voltage->voltage != rdev->pm.current_vddc) { + radeon_atom_set_voltage(rdev, voltage->voltage); + rdev->pm.current_vddc = voltage->voltage; + DRM_DEBUG("Setting: v: %d\n", voltage->voltage); + } + } } void evergreen_pm_prepare(struct radeon_device *rdev) @@ -2153,7 +2159,7 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; - rdev->accel_working = false; + rdev->accel_working = true; r = evergreen_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cc004b05d63..cf89aa2eb28 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -162,6 +162,11 @@ void r100_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; @@ -172,6 +177,11 @@ void r100_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* mid mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 4415a5ee587..e6c89142bb4 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -45,9 +45,14 @@ void r420_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; /* low sh */ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; @@ -58,6 +63,11 @@ void r420_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* mid mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index e14f59748e6..0e91871f45b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -291,6 +291,11 @@ void rs780_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1; @@ -301,6 +306,11 @@ void rs780_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* mid mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 1; @@ -317,6 +327,11 @@ void rs780_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 2; @@ -327,6 +342,11 @@ void rs780_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* mid mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2; @@ -343,6 +363,11 @@ void rs780_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 2; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 2; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 2; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 2; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 3; @@ -353,6 +378,11 @@ void rs780_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* mid mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 2; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 3; @@ -375,6 +405,11 @@ void r600_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; @@ -385,6 +420,11 @@ void r600_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* mid mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; @@ -401,7 +441,12 @@ void r600_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 1; + rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + /* mid sh */ + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1; rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1; @@ -411,7 +456,12 @@ void r600_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 2; rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 1; + rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + /* low mh */ + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 2; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 2; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2; rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2; @@ -430,14 +480,30 @@ void r600_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 1; + rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; } else { rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 1; + rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; + } + /* mid sh */ + if (rdev->flags & RADEON_IS_MOBILITY) { + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; + } else { + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; } /* high sh */ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = @@ -453,14 +519,30 @@ void r600_pm_init_profile(struct radeon_device *rdev) rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 2; + rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; } else { rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 1; + rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; + } + /* mid mh */ + if (rdev->flags & RADEON_IS_MOBILITY) { + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; + } else { + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = + r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; + rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; } /* high mh */ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = @@ -475,13 +557,18 @@ void r600_pm_init_profile(struct radeon_device *rdev) void r600_pm_misc(struct radeon_device *rdev) { - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) - radeon_atom_set_voltage(rdev, voltage->voltage); + int req_ps_idx = rdev->pm.requested_power_state_index; + int req_cm_idx = rdev->pm.requested_clock_mode_index; + struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; + struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { + if (voltage->voltage != rdev->pm.current_vddc) { + radeon_atom_set_voltage(rdev, voltage->voltage); + rdev->pm.current_vddc = voltage->voltage; + DRM_DEBUG("Setting: v: %d\n", voltage->voltage); + } + } } bool r600_gui_idle(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5f96fe871b3..8e1d44ca26e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -648,15 +648,18 @@ enum radeon_pm_profile_type { PM_PROFILE_DEFAULT, PM_PROFILE_AUTO, PM_PROFILE_LOW, + PM_PROFILE_MID, PM_PROFILE_HIGH, }; #define PM_PROFILE_DEFAULT_IDX 0 #define PM_PROFILE_LOW_SH_IDX 1 -#define PM_PROFILE_HIGH_SH_IDX 2 -#define PM_PROFILE_LOW_MH_IDX 3 -#define PM_PROFILE_HIGH_MH_IDX 4 -#define PM_PROFILE_MAX 5 +#define PM_PROFILE_MID_SH_IDX 2 +#define PM_PROFILE_HIGH_SH_IDX 3 +#define PM_PROFILE_LOW_MH_IDX 4 +#define PM_PROFILE_MID_MH_IDX 5 +#define PM_PROFILE_HIGH_MH_IDX 6 +#define PM_PROFILE_MAX 7 struct radeon_pm_profile { int dpms_off_ps_idx; @@ -745,6 +748,7 @@ struct radeon_pm { int default_power_state_index; u32 current_sclk; u32 current_mclk; + u32 current_vddc; struct radeon_i2c_chan *i2c_bus; /* selected pm method */ enum radeon_pm_method pm_method; diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 4305cd55d0a..99bd8a9c56b 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1833,10 +1833,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) /* skip invalid modes */ if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) continue; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - clock_info->usVDDC; + /* voltage works differently on IGPs */ mode_index++; } else if (ASIC_IS_DCE4(rdev)) { struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = @@ -1969,6 +1966,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; rdev->pm.current_clock_mode_index = 0; + rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; } void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 102c744eaf5..1bee2f9e24a 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2026,6 +2026,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); break; default: + ddc_i2c.valid = false; break; } @@ -2339,6 +2340,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) if (RBIOS8(tv_info + 6) == 'T') { if (radeon_apply_legacy_tv_quirks(dev)) { hpd.hpd = RADEON_HPD_NONE; + ddc_i2c.valid = false; radeon_add_legacy_encoder(dev, radeon_get_encoder_id (dev, @@ -2455,7 +2457,7 @@ default_mode: rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; if ((state_index > 0) && - (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO)) + (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO)) rdev->pm.power_state[state_index].clock_info[0].voltage = rdev->pm.power_state[0].clock_info[0].voltage; else diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1006549d157..8154cdf796e 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -284,8 +284,7 @@ static const char *connector_names[15] = { "eDP", }; -static const char *hpd_names[7] = { - "NONE", +static const char *hpd_names[6] = { "HPD1", "HPD2", "HPD3", diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 902d1731a65..e166fe4d7c3 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -45,9 +45,10 @@ * - 2.2.0 - add r6xx/r7xx const buffer support * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs * - 2.4.0 - add crtc id query + * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 4 +#define KMS_DRIVER_MINOR 5 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index e192acfbf0c..dc1634bb0c1 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -363,6 +363,7 @@ int radeon_fbdev_init(struct radeon_device *rdev) { struct radeon_fbdev *rfbdev; int bpp_sel = 32; + int ret; /* select 8 bpp console on RN50 or 16MB cards */ if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024)) @@ -376,9 +377,14 @@ int radeon_fbdev_init(struct radeon_device *rdev) rdev->mode_info.rfbdev = rfbdev; rfbdev->helper.funcs = &radeon_fb_helper_funcs; - drm_fb_helper_init(rdev->ddev, &rfbdev->helper, - rdev->num_crtc, - RADEONFB_CONN_LIMIT); + ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, + rdev->num_crtc, + RADEONFB_CONN_LIMIT); + if (ret) { + kfree(rfbdev); + return ret; + } + drm_fb_helper_single_add_all_connectors(&rfbdev->helper); drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); return 0; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 04068352ccd..6a70c0dc7f9 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -118,7 +118,11 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) value = rdev->num_z_pipes; break; case RADEON_INFO_ACCEL_WORKING: - value = rdev->accel_working; + /* xf86-video-ati 6.13.0 relies on this being false for evergreen */ + if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) + value = false; + else + value = rdev->accel_working; break; case RADEON_INFO_CRTC_FROM_ID: for (i = 0, found = 0; i < rdev->num_crtc; i++) { @@ -134,6 +138,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return -EINVAL; } break; + case RADEON_INFO_ACCEL_WORKING2: + value = rdev->accel_working; + break; default: DRM_DEBUG("Invalid request %d\n", info->request); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 5a13b3eeef1..5b07b8848e0 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -1168,6 +1168,17 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; bool color = true; + struct drm_crtc *crtc; + + /* find out if crtc2 is in use or if this encoder is using it */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + if ((radeon_crtc->crtc_id == 1) && crtc->enabled) { + if (encoder->crtc != crtc) { + return connector_status_disconnected; + } + } + } if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO || connector->connector_type == DRM_MODE_CONNECTOR_Composite || diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 02281269a88..63f679a04b2 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -33,6 +33,14 @@ #define RADEON_WAIT_VBLANK_TIMEOUT 200 #define RADEON_WAIT_IDLE_TIMEOUT 200 +static const char *radeon_pm_state_type_name[5] = { + "Default", + "Powersave", + "Battery", + "Balanced", + "Performance", +}; + static void radeon_dynpm_idle_work_handler(struct work_struct *work); static int radeon_debugfs_pm_init(struct radeon_device *rdev); static bool radeon_pm_in_vbl(struct radeon_device *rdev); @@ -84,9 +92,9 @@ static void radeon_pm_update_profile(struct radeon_device *rdev) rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX; } else { if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX; + rdev->pm.profile_index = PM_PROFILE_MID_MH_IDX; else - rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; + rdev->pm.profile_index = PM_PROFILE_MID_SH_IDX; } break; case PM_PROFILE_LOW: @@ -95,6 +103,12 @@ static void radeon_pm_update_profile(struct radeon_device *rdev) else rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; break; + case PM_PROFILE_MID: + if (rdev->pm.active_crtc_count > 1) + rdev->pm.profile_index = PM_PROFILE_MID_MH_IDX; + else + rdev->pm.profile_index = PM_PROFILE_MID_SH_IDX; + break; case PM_PROFILE_HIGH: if (rdev->pm.active_crtc_count > 1) rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX; @@ -127,15 +141,6 @@ static void radeon_unmap_vram_bos(struct radeon_device *rdev) if (bo->tbo.mem.mem_type == TTM_PL_VRAM) ttm_bo_unmap_virtual(&bo->tbo); } - - if (rdev->gart.table.vram.robj) - ttm_bo_unmap_virtual(&rdev->gart.table.vram.robj->tbo); - - if (rdev->stollen_vga_memory) - ttm_bo_unmap_virtual(&rdev->stollen_vga_memory->tbo); - - if (rdev->r600_blit.shader_obj) - ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo); } static void radeon_sync_with_vblank(struct radeon_device *rdev) @@ -281,6 +286,42 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) mutex_unlock(&rdev->ddev->struct_mutex); } +static void radeon_pm_print_states(struct radeon_device *rdev) +{ + int i, j; + struct radeon_power_state *power_state; + struct radeon_pm_clock_info *clock_info; + + DRM_DEBUG("%d Power State(s)\n", rdev->pm.num_power_states); + for (i = 0; i < rdev->pm.num_power_states; i++) { + power_state = &rdev->pm.power_state[i]; + DRM_DEBUG("State %d: %s\n", i, + radeon_pm_state_type_name[power_state->type]); + if (i == rdev->pm.default_power_state_index) + DRM_DEBUG("\tDefault"); + if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) + DRM_DEBUG("\t%d PCIE Lanes\n", power_state->pcie_lanes); + if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) + DRM_DEBUG("\tSingle display only\n"); + DRM_DEBUG("\t%d Clock Mode(s)\n", power_state->num_clock_modes); + for (j = 0; j < power_state->num_clock_modes; j++) { + clock_info = &(power_state->clock_info[j]); + if (rdev->flags & RADEON_IS_IGP) + DRM_DEBUG("\t\t%d e: %d%s\n", + j, + clock_info->sclk * 10, + clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); + else + DRM_DEBUG("\t\t%d e: %d\tm: %d\tv: %d%s\n", + j, + clock_info->sclk * 10, + clock_info->mclk * 10, + clock_info->voltage.voltage, + clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); + } + } +} + static ssize_t radeon_get_pm_profile(struct device *dev, struct device_attribute *attr, char *buf) @@ -311,6 +352,8 @@ static ssize_t radeon_set_pm_profile(struct device *dev, rdev->pm.profile = PM_PROFILE_AUTO; else if (strncmp("low", buf, strlen("low")) == 0) rdev->pm.profile = PM_PROFILE_LOW; + else if (strncmp("mid", buf, strlen("mid")) == 0) + rdev->pm.profile = PM_PROFILE_MID; else if (strncmp("high", buf, strlen("high")) == 0) rdev->pm.profile = PM_PROFILE_HIGH; else { @@ -377,15 +420,19 @@ void radeon_pm_suspend(struct radeon_device *rdev) { mutex_lock(&rdev->pm.mutex); cancel_delayed_work(&rdev->pm.dynpm_idle_work); - rdev->pm.current_power_state_index = -1; - rdev->pm.current_clock_mode_index = -1; - rdev->pm.current_sclk = 0; - rdev->pm.current_mclk = 0; mutex_unlock(&rdev->pm.mutex); } void radeon_pm_resume(struct radeon_device *rdev) { + /* asic init will reset the default power state */ + mutex_lock(&rdev->pm.mutex); + rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; + rdev->pm.current_clock_mode_index = 0; + rdev->pm.current_sclk = rdev->clock.default_sclk; + rdev->pm.current_mclk = rdev->clock.default_mclk; + rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; + mutex_unlock(&rdev->pm.mutex); radeon_pm_compute_clocks(rdev); } @@ -394,32 +441,24 @@ int radeon_pm_init(struct radeon_device *rdev) int ret; /* default to profile method */ rdev->pm.pm_method = PM_METHOD_PROFILE; + rdev->pm.profile = PM_PROFILE_DEFAULT; rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; rdev->pm.dynpm_can_upclock = true; rdev->pm.dynpm_can_downclock = true; - rdev->pm.current_sclk = 0; - rdev->pm.current_mclk = 0; + rdev->pm.current_sclk = rdev->clock.default_sclk; + rdev->pm.current_mclk = rdev->clock.default_mclk; if (rdev->bios) { if (rdev->is_atom_bios) radeon_atombios_get_power_modes(rdev); else radeon_combios_get_power_modes(rdev); + radeon_pm_print_states(rdev); radeon_pm_init_profile(rdev); - rdev->pm.current_power_state_index = -1; - rdev->pm.current_clock_mode_index = -1; } if (rdev->pm.num_power_states > 1) { - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - mutex_lock(&rdev->pm.mutex); - rdev->pm.profile = PM_PROFILE_DEFAULT; - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - mutex_unlock(&rdev->pm.mutex); - } - /* where's the best place to put these? */ ret = device_create_file(rdev->dev, &dev_attr_power_profile); if (ret) @@ -705,6 +744,8 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); if (rdev->asic->get_memory_clock) seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); + if (rdev->pm.current_vddc) + seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc); if (rdev->asic->get_pcie_lanes) seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev)); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 33952da6534..cec536c222c 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -44,12 +44,18 @@ void rv770_fini(struct radeon_device *rdev); void rv770_pm_misc(struct radeon_device *rdev) { - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) - radeon_atom_set_voltage(rdev, voltage->voltage); + int req_ps_idx = rdev->pm.requested_power_state_index; + int req_cm_idx = rdev->pm.requested_clock_mode_index; + struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; + struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; + + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { + if (voltage->voltage != rdev->pm.current_vddc) { + radeon_atom_set_voltage(rdev, voltage->voltage); + rdev->pm.current_vddc = voltage->voltage; + DRM_DEBUG("Setting: v: %d\n", voltage->voltage); + } + } } /* diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index bdd67cf8331..8e396850513 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -644,6 +644,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, ret = copy_from_user(cmd, user_cmd, arg->command_size); if (unlikely(ret != 0)) { + ret = -EFAULT; DRM_ERROR("Failed copying commands.\n"); goto out_commit; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index f8fbbc67a40..8612378b131 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -597,8 +597,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ret = copy_from_user(srf->sizes, user_sizes, srf->num_sizes * sizeof(*srf->sizes)); - if (unlikely(ret != 0)) + if (unlikely(ret != 0)) { + ret = -EFAULT; goto out_err1; + } if (srf->scanout && srf->num_sizes == 1 && @@ -697,9 +699,11 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, if (user_sizes) ret = copy_to_user(user_sizes, srf->sizes, srf->num_sizes * sizeof(*srf->sizes)); - if (unlikely(ret != 0)) + if (unlikely(ret != 0)) { DRM_ERROR("copy_to_user failed %p %u\n", user_sizes, srf->num_sizes); + ret = -EFAULT; + } out_bad_resource: out_no_reference: ttm_base_object_unref(&base); diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index e880e2c3871..937983407e2 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -289,6 +289,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_label; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -303,6 +304,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_amb_temp; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -318,6 +320,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_min; iattr->s_attr.dev_attr.store = store_amb_min; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -333,6 +336,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_mid; iattr->s_attr.dev_attr.store = store_amb_mid; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -348,6 +352,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_max; iattr->s_attr.dev_attr.store = store_amb_max; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -362,6 +367,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_amb_alarm; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 099a2138cdf..da5a2404cd3 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -112,11 +112,21 @@ static bool __devinit has_erratum_319(struct pci_dev *pdev) if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3) return false; - /* Differentiate between AM2+ (bad) and AM3 (good) */ + /* DDR3 memory implies socket AM3, which is good */ pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2), REG_DCT0_CONFIG_HIGH, ®_dram_cfg); - return !(reg_dram_cfg & DDR3_MODE); + if (reg_dram_cfg & DDR3_MODE) + return false; + + /* + * Unfortunately it is possible to run a socket AM3 CPU with DDR2 + * memory. We blacklist all the cores which do exist in socket AM2+ + * format. It still isn't perfect, as RB-C2 cores exist in both AM2+ + * and AM3 formats, but that's the best we can do. + */ + return boot_cpu_data.x86_model < 4 || + (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask <= 2); } static int __devinit k10temp_probe(struct pci_dev *pdev, diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 0ceb6d6200a..f26acdb1168 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -120,7 +120,7 @@ static ssize_t show_temp(struct device *dev, int temp; struct k8temp_data *data = k8temp_update_device(dev); - if (data->swap_core_select) + if (data->swap_core_select && (data->sensorsp & SEL_CORE)) core = core ? 0 : 1; temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index e00a1cc79c0..c1906647905 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -678,7 +678,7 @@ static const struct file_operations hp_sdc_rtc_fops = { .llseek = no_llseek, .read = hp_sdc_rtc_read, .poll = hp_sdc_rtc_poll, - .unlocked_ioctl = hp_sdc_rtc_ioctl, + .unlocked_ioctl = hp_sdc_rtc_unlocked_ioctl, .open = hp_sdc_rtc_open, .fasync = hp_sdc_rtc_fasync, }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index e171e77f612..f06d06e7fdf 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -249,7 +249,7 @@ config MMC_IMX config MMC_MSM7X00A tristate "Qualcomm MSM 7X00A SDCC Controller Support" - depends on MMC && ARCH_MSM + depends on MMC && ARCH_MSM && !ARCH_MSM7X30 help This provides support for the SD/MMC cell found in the MSM 7X00A controllers from Qualcomm. diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 000d65ea55a..91c8013cf0d 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -404,14 +404,9 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd, if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) return -EINVAL; - ops.oobbuf = kmalloc(length, GFP_KERNEL); - if (!ops.oobbuf) - return -ENOMEM; - - if (copy_from_user(ops.oobbuf, ptr, length)) { - kfree(ops.oobbuf); - return -EFAULT; - } + ops.oobbuf = memdup_user(ptr, length); + if (IS_ERR(ops.oobbuf)) + return PTR_ERR(ops.oobbuf); start &= ~((uint64_t)mtd->oobsize - 1); ret = mtd->write_oob(mtd, start, &ops); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 98a04b3c952..ffc3720929f 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,13 +1,3 @@ -menuconfig MTD_NAND - tristate "NAND Device Support" - depends on MTD - select MTD_NAND_IDS - select MTD_NAND_ECC - help - This enables support for accessing all type of NAND flash - devices. For further information see - <http://www.linux-mtd.infradead.org/doc/nand.html>. - config MTD_NAND_ECC tristate @@ -19,6 +9,17 @@ config MTD_NAND_ECC_SMC Software ECC according to the Smart Media Specification. The original Linux implementation had byte 0 and 1 swapped. + +menuconfig MTD_NAND + tristate "NAND Device Support" + depends on MTD + select MTD_NAND_IDS + select MTD_NAND_ECC + help + This enables support for accessing all type of NAND flash + devices. For further information see + <http://www.linux-mtd.infradead.org/doc/nand.html>. + if MTD_NAND config MTD_NAND_VERIFY_WRITE diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 78a42329547..bcfc851fe55 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -150,7 +150,6 @@ static void r852_dma_done(struct r852_device *dev, int error) if (dev->phys_dma_addr && dev->phys_dma_addr != dev->phys_bounce_buffer) pci_unmap_single(dev->pci_dev, dev->phys_dma_addr, R852_DMA_LEN, dev->dma_dir ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); - complete(&dev->dma_done); } /* @@ -182,6 +181,7 @@ static void r852_do_dma(struct r852_device *dev, uint8_t *buf, int do_read) /* Set dma direction */ dev->dma_dir = do_read; dev->dma_stage = 1; + INIT_COMPLETION(dev->dma_done); dbg_verbose("doing dma %s ", do_read ? "read" : "write"); @@ -494,6 +494,11 @@ int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, if (dev->card_unstable) return 0; + if (dev->dma_error) { + dev->dma_error = 0; + return -1; + } + r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS); ecc_reg = r852_read_reg_dword(dev, R852_DATALINE); r852_write_reg(dev, R852_CTL, dev->ctlreg); @@ -707,6 +712,7 @@ void r852_card_detect_work(struct work_struct *work) container_of(work, struct r852_device, card_detect_work.work); r852_card_update_present(dev); + r852_update_card_detect(dev); dev->card_unstable = 0; /* False alarm */ @@ -722,7 +728,6 @@ void r852_card_detect_work(struct work_struct *work) else r852_unregister_nand_device(dev); exit: - /* Update detection logic */ r852_update_card_detect(dev); } @@ -796,6 +801,7 @@ static irqreturn_t r852_irq(int irq, void *data) if (dma_status & R852_DMA_IRQ_ERROR) { dbg("recieved dma error IRQ"); r852_dma_done(dev, -EIO); + complete(&dev->dma_done); goto out; } @@ -825,8 +831,10 @@ static irqreturn_t r852_irq(int irq, void *data) r852_dma_enable(dev); /* Operation done */ - if (dev->dma_stage == 3) + if (dev->dma_stage == 3) { r852_dma_done(dev, 0); + complete(&dev->dma_done); + } goto out; } @@ -940,18 +948,19 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) r852_dma_test(dev); + dev->irq = pci_dev->irq; + spin_lock_init(&dev->irqlock); + + dev->card_detected = 0; + r852_card_update_present(dev); + /*register irq handler*/ error = -ENODEV; if (request_irq(pci_dev->irq, &r852_irq, IRQF_SHARED, DRV_NAME, dev)) goto error10; - dev->irq = pci_dev->irq; - spin_lock_init(&dev->irqlock); - /* kick initial present test */ - dev->card_detected = 0; - r852_card_update_present(dev); queue_delayed_work(dev->card_workqueue, &dev->card_detect_work, 0); @@ -1081,7 +1090,7 @@ int r852_resume(struct device *device) dev->card_detected ? "added" : "removed"); queue_delayed_work(dev->card_workqueue, - &dev->card_detect_work, 1000); + &dev->card_detect_work, msecs_to_jiffies(1000)); return 0; } diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 9c149750e2b..284a5f4a63a 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -598,8 +598,8 @@ rx_next: goto rx_status_loop; spin_lock_irqsave(&cp->lock, flags); - cpw16_f(IntrMask, cp_intr_mask); __napi_complete(napi); + cpw16_f(IntrMask, cp_intr_mask); spin_unlock_irqrestore(&cp->lock, flags); } diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 4ba72933f0d..97d8068b372 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -860,6 +860,7 @@ retry: } /* if unknown chip, assume array element #0, original RTL-8139 in this case */ + i = 0; dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n"); dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig)); tp->chipset = 0; @@ -2088,8 +2089,8 @@ static int rtl8139_poll(struct napi_struct *napi, int budget) * again when we think we are done. */ spin_lock_irqsave(&tp->lock, flags); - RTL_W16_F(IntrMask, rtl8139_intr_mask); __napi_complete(napi); + RTL_W16_F(IntrMask, rtl8139_intr_mask); spin_unlock_irqrestore(&tp->lock, flags); } spin_unlock(&tp->rx_lock); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1830f3199cb..46c69cd0655 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -747,8 +747,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | - FSL_GIANFAR_DEV_HAS_EXTENDED_HASH | - FSL_GIANFAR_DEV_HAS_TIMER; + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; ctype = of_get_property(np, "phy-connection-type", NULL); diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 7b6fe89f9db..64e6a84bbbb 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -322,6 +322,7 @@ static int smc91c92_probe(struct pcmcia_device *link) return -ENOMEM; smc = netdev_priv(dev); smc->p_dev = link; + link->priv = dev; spin_lock_init(&smc->lock); link->io.NumPorts1 = 16; diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index 8ee929b796d..dbd00345373 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -53,6 +53,9 @@ #define MII_LXT971_ISR 19 /* Interrupt Status Register */ +/* register definitions for the 973 */ +#define MII_LXT973_PCR 16 /* Port Configuration Register */ +#define PCR_FIBER_SELECT 1 MODULE_DESCRIPTION("Intel LXT PHY driver"); MODULE_AUTHOR("Andy Fleming"); @@ -119,6 +122,33 @@ static int lxt971_config_intr(struct phy_device *phydev) return err; } +static int lxt973_probe(struct phy_device *phydev) +{ + int val = phy_read(phydev, MII_LXT973_PCR); + + if (val & PCR_FIBER_SELECT) { + /* + * If fiber is selected, then the only correct setting + * is 100Mbps, full duplex, and auto negotiation off. + */ + val = phy_read(phydev, MII_BMCR); + val |= (BMCR_SPEED100 | BMCR_FULLDPLX); + val &= ~BMCR_ANENABLE; + phy_write(phydev, MII_BMCR, val); + /* Remember that the port is in fiber mode. */ + phydev->priv = lxt973_probe; + } else { + phydev->priv = NULL; + } + return 0; +} + +static int lxt973_config_aneg(struct phy_device *phydev) +{ + /* Do nothing if port is in fiber mode. */ + return phydev->priv ? 0 : genphy_config_aneg(phydev); +} + static struct phy_driver lxt970_driver = { .phy_id = 0x78100000, .name = "LXT970", @@ -146,6 +176,18 @@ static struct phy_driver lxt971_driver = { .driver = { .owner = THIS_MODULE,}, }; +static struct phy_driver lxt973_driver = { + .phy_id = 0x00137a10, + .name = "LXT973", + .phy_id_mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .flags = 0, + .probe = lxt973_probe, + .config_aneg = lxt973_config_aneg, + .read_status = genphy_read_status, + .driver = { .owner = THIS_MODULE,}, +}; + static int __init lxt_init(void) { int ret; @@ -157,9 +199,15 @@ static int __init lxt_init(void) ret = phy_driver_register(&lxt971_driver); if (ret) goto err2; + + ret = phy_driver_register(&lxt973_driver); + if (ret) + goto err3; return 0; - err2: + err3: + phy_driver_unregister(&lxt971_driver); + err2: phy_driver_unregister(&lxt970_driver); err1: return ret; @@ -169,6 +217,7 @@ static void __exit lxt_exit(void) { phy_driver_unregister(&lxt970_driver); phy_driver_unregister(&lxt971_driver); + phy_driver_unregister(&lxt973_driver); } module_init(lxt_init); diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 217e709bda3..96b6cfbf0a3 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -559,6 +559,11 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) break; udelay(25); } + /* + * According to hardware specs a 20us delay is required after write + * complete indication, but before sending next command. + */ + udelay(20); } static int mdio_read(void __iomem *ioaddr, int reg_addr) @@ -578,6 +583,12 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr) } udelay(25); } + /* + * According to hardware specs a 20us delay is required after read + * complete indication, but before sending next command. + */ + udelay(20); + return value; } diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index c0e70006374..06b552fca63 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -367,8 +367,8 @@ static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; -#define dr32(reg) readl(de->regs + (reg)) -#define dw32(reg,val) writel((val), de->regs + (reg)) +#define dr32(reg) ioread32(de->regs + (reg)) +#define dw32(reg, val) iowrite32((val), de->regs + (reg)) static void de_rx_err_acct (struct de_private *de, unsigned rx_tail, @@ -1706,6 +1706,7 @@ static void __devinit de21040_get_mac_address (struct de_private *de) int value, boguscnt = 100000; do { value = dr32(ROMCmd); + rmb(); } while (value < 0 && --boguscnt > 0); de->dev->dev_addr[i] = value; udelay(1); diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1f802e90474..9516f382a6b 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -344,7 +344,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 2; } - if (size > ETH_FRAME_LEN) { + if (size > dev->net->mtu + ETH_HLEN) { netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", size); return 0; diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 3f283bff0ff..11491354e5b 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -1192,7 +1192,7 @@ int i2400m_fw_hdr_check(struct i2400m *i2400m, unsigned module_type, header_len, major_version, minor_version, module_id, module_vendor, date, size; - module_type = bcf_hdr->module_type; + module_type = le32_to_cpu(bcf_hdr->module_type); header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len); major_version = (le32_to_cpu(bcf_hdr->header_version) & 0xffff0000) >> 16; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2978359c436..648972df369 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = { static int __devinit ath5k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void __devexit ath5k_pci_remove(struct pci_dev *pdev); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ath5k_pci_suspend(struct device *dev); static int ath5k_pci_resume(struct device *dev); @@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); #define ATH5K_PM_OPS (&ath5k_pm_ops) #else #define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static struct pci_driver ath5k_pci_driver = { .name = KBUILD_MODNAME, @@ -708,7 +708,7 @@ ath5k_pci_remove(struct pci_dev *pdev) ieee80211_free_hw(hw); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ath5k_pci_suspend(struct device *dev) { struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); @@ -734,7 +734,7 @@ static int ath5k_pci_resume(struct device *dev) ath5k_led_enable(sc); return 0; } -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ /***********************\ @@ -3140,13 +3140,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { if (*new_flags & FIF_PROMISC_IN_BSS) { - rfilt |= AR5K_RX_FILTER_PROM; __set_bit(ATH_STAT_PROMISC, sc->status); } else { __clear_bit(ATH_STAT_PROMISC, sc->status); } } + if (test_bit(ATH_STAT_PROMISC, sc->status)) + rfilt |= AR5K_RX_FILTER_PROM; + /* Note, AR5K_RX_FILTER_MCAST is already enabled */ if (*new_flags & FIF_ALLMULTI) { mfilt[0] = ~0; diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 1b81c477880..492cbb15720 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1814,6 +1814,13 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) u8 def_ant, tx_ant, ee_mode; u32 sta_id1 = 0; + /* if channel is not initialized yet we can't set the antennas + * so just store the mode. it will be set on the next reset */ + if (channel == NULL) { + ah->ah_ant_mode = ant_mode; + return; + } + def_ant = ah->ah_def_ant; ATH5K_TRACE(ah->ah_sc); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index d7073281942..ff9b5c88218 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2618,15 +2618,6 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id) int events = 0; u16 ev; - /* Detect early interrupt before driver is fully configued */ - if (!dev->base_addr) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n", - dev->name); - } - return IRQ_HANDLED; - } - iface = netdev_priv(dev); local = iface->local; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 068f7f8435c..c44a303e62e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2852,6 +2852,7 @@ static struct iwl_lib_ops iwl3945_lib = { .isr = iwl_isr_legacy, .config_ap = iwl3945_config_ap, .manage_ibss_station = iwl3945_manage_ibss_station, + .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl3945_good_plcp_health, .debugfs_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 1004cfc403b..0f292a210ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1119,10 +1119,9 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, struct iwl_scan_channel *scan_ch) { const struct ieee80211_supported_band *sband; - const struct iwl_channel_info *ch_info; u16 passive_dwell = 0; u16 active_dwell = 0; - int i, added = 0; + int added = 0; u16 channel = 0; sband = iwl_get_hw_mode(priv, band); @@ -1137,32 +1136,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, if (passive_dwell <= active_dwell) passive_dwell = active_dwell + 1; - /* only scan single channel, good enough to reset the RF */ - /* pick the first valid not in-use channel */ - if (band == IEEE80211_BAND_5GHZ) { - for (i = 14; i < priv->channel_count; i++) { - if (priv->channel_info[i].channel != - le16_to_cpu(priv->staging_rxon.channel)) { - channel = priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, - band, channel); - if (is_channel_valid(ch_info)) - break; - } - } - } else { - for (i = 0; i < 14; i++) { - if (priv->channel_info[i].channel != - le16_to_cpu(priv->staging_rxon.channel)) { - channel = - priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, - band, channel); - if (is_channel_valid(ch_info)) - break; - } - } - } + channel = iwl_get_single_channel_number(priv, band); if (channel) { scan_ch->channel = cpu_to_le16(channel); scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c402bfc83f3..a732f1094e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1125,6 +1125,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) struct ieee80211_sta *sta; struct iwl_station_priv *sta_priv; + rcu_read_lock(); sta = ieee80211_find_sta(priv->vif, hdr->addr1); if (sta) { sta_priv = (void *)sta->drv_priv; @@ -1133,6 +1134,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) atomic_dec_return(&sta_priv->pending_frames) == 0) ieee80211_sta_block_awake(priv->hw, sta, false); } + rcu_read_unlock(); ieee80211_tx_status_irqsafe(priv->hw, skb); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index aef4f71f198..7726e67044c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1484,6 +1484,156 @@ bool iwl_good_ack_health(struct iwl_priv *priv, } +/***************************************************************************** + * + * sysfs attributes + * + *****************************************************************************/ + +#ifdef CONFIG_IWLWIFI_DEBUG + +/* + * The following adds a new attribute to the sysfs representation + * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) + * used for controlling the debug level. + * + * See the level definitions in iwl for details. + * + * The debug_level being managed using sysfs below is a per device debug + * level that is used instead of the global debug level if it (the per + * device debug level) is set. + */ +static ssize_t show_debug_level(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); +} +static ssize_t store_debug_level(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 0, &val); + if (ret) + IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); + else { + priv->debug_level = val; + if (iwl_alloc_traffic_mem(priv)) + IWL_ERR(priv, + "Not enough memory to generate traffic log\n"); + } + return strnlen(buf, count); +} + +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, + show_debug_level, store_debug_level); + + +#endif /* CONFIG_IWLWIFI_DEBUG */ + + +static ssize_t show_temperature(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + return sprintf(buf, "%d\n", priv->temperature); +} + +static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); + +static ssize_t show_tx_power(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_is_ready_rf(priv)) + return sprintf(buf, "off\n"); + else + return sprintf(buf, "%d\n", priv->tx_power_user_lmt); +} + +static ssize_t store_tx_power(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + IWL_INFO(priv, "%s is not in decimal form.\n", buf); + else { + ret = iwl_set_tx_power(priv, val, false); + if (ret) + IWL_ERR(priv, "failed setting tx power (0x%d).\n", + ret); + else + ret = count; + } + return ret; +} + +static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); + +static ssize_t show_rts_ht_protection(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + return sprintf(buf, "%s\n", + priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); +} + +static ssize_t store_rts_ht_protection(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + IWL_INFO(priv, "Input is not in decimal form.\n"); + else { + if (!iwl_is_associated(priv)) + priv->cfg->use_rts_for_ht = val ? true : false; + else + IWL_ERR(priv, "Sta associated with AP - " + "Change protection mechanism is not allowed\n"); + ret = count; + } + return ret; +} + +static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, + show_rts_ht_protection, store_rts_ht_protection); + + +static struct attribute *iwl_sysfs_entries[] = { + &dev_attr_temperature.attr, + &dev_attr_tx_power.attr, + &dev_attr_rts_ht_protection.attr, +#ifdef CONFIG_IWLWIFI_DEBUG + &dev_attr_debug_level.attr, +#endif + NULL +}; + +static struct attribute_group iwl_attribute_group = { + .name = NULL, /* put in device directory */ + .attrs = iwl_sysfs_entries, +}; + /****************************************************************************** * * uCode download functions @@ -1965,6 +2115,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (err) IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + err = sysfs_create_group(&priv->pci_dev->dev.kobj, + &iwl_attribute_group); + if (err) { + IWL_ERR(priv, "failed to create sysfs device attributes\n"); + goto out_unbind; + } + /* We have our copies now, allow OS release its copies */ release_firmware(ucode_raw); complete(&priv->_agn.firmware_loading_complete); @@ -3264,141 +3421,6 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, /***************************************************************************** * - * sysfs attributes - * - *****************************************************************************/ - -#ifdef CONFIG_IWLWIFI_DEBUG - -/* - * The following adds a new attribute to the sysfs representation - * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) - * used for controlling the debug level. - * - * See the level definitions in iwl for details. - * - * The debug_level being managed using sysfs below is a per device debug - * level that is used instead of the global debug level if it (the per - * device debug level) is set. - */ -static ssize_t show_debug_level(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); -} -static ssize_t store_debug_level(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 0, &val); - if (ret) - IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); - else { - priv->debug_level = val; - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, - "Not enough memory to generate traffic log\n"); - } - return strnlen(buf, count); -} - -static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, - show_debug_level, store_debug_level); - - -#endif /* CONFIG_IWLWIFI_DEBUG */ - - -static ssize_t show_temperature(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - return sprintf(buf, "%d\n", priv->temperature); -} - -static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); - -static ssize_t show_tx_power(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_ready_rf(priv)) - return sprintf(buf, "off\n"); - else - return sprintf(buf, "%d\n", priv->tx_power_user_lmt); -} - -static ssize_t store_tx_power(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - IWL_INFO(priv, "%s is not in decimal form.\n", buf); - else { - ret = iwl_set_tx_power(priv, val, false); - if (ret) - IWL_ERR(priv, "failed setting tx power (0x%d).\n", - ret); - else - ret = count; - } - return ret; -} - -static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); - -static ssize_t show_rts_ht_protection(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - return sprintf(buf, "%s\n", - priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); -} - -static ssize_t store_rts_ht_protection(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - IWL_INFO(priv, "Input is not in decimal form.\n"); - else { - if (!iwl_is_associated(priv)) - priv->cfg->use_rts_for_ht = val ? true : false; - else - IWL_ERR(priv, "Sta associated with AP - " - "Change protection mechanism is not allowed\n"); - ret = count; - } - return ret; -} - -static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, - show_rts_ht_protection, store_rts_ht_protection); - - -/***************************************************************************** - * * driver setup and teardown * *****************************************************************************/ @@ -3550,21 +3572,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); } -static struct attribute *iwl_sysfs_entries[] = { - &dev_attr_temperature.attr, - &dev_attr_tx_power.attr, - &dev_attr_rts_ht_protection.attr, -#ifdef CONFIG_IWLWIFI_DEBUG - &dev_attr_debug_level.attr, -#endif - NULL -}; - -static struct attribute_group iwl_attribute_group = { - .name = NULL, /* put in device directory */ - .attrs = iwl_sysfs_entries, -}; - static struct ieee80211_ops iwl_hw_ops = { .tx = iwl_mac_tx, .start = iwl_mac_start, @@ -3750,11 +3757,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); goto out_disable_msi; } - err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); - if (err) { - IWL_ERR(priv, "failed to create sysfs device attributes\n"); - goto out_free_irq; - } iwl_setup_deferred_work(priv); iwl_setup_rx_handlers(priv); @@ -3788,15 +3790,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = iwl_request_firmware(priv, true); if (err) - goto out_remove_sysfs; + goto out_destroy_workqueue; return 0; - out_remove_sysfs: + out_destroy_workqueue: destroy_workqueue(priv->workqueue); priv->workqueue = NULL; - sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); - out_free_irq: free_irq(priv->pci_dev->irq, priv); iwl_free_isr_ict(priv); out_disable_msi: diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5a7eca8fb78..426e95567de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -854,6 +854,45 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_set_rxon_chain); +/* Return valid channel */ +u8 iwl_get_single_channel_number(struct iwl_priv *priv, + enum ieee80211_band band) +{ + const struct iwl_channel_info *ch_info; + int i; + u8 channel = 0; + + /* only scan single channel, good enough to reset the RF */ + /* pick the first valid not in-use channel */ + if (band == IEEE80211_BAND_5GHZ) { + for (i = 14; i < priv->channel_count; i++) { + if (priv->channel_info[i].channel != + le16_to_cpu(priv->staging_rxon.channel)) { + channel = priv->channel_info[i].channel; + ch_info = iwl_get_channel_info(priv, + band, channel); + if (is_channel_valid(ch_info)) + break; + } + } + } else { + for (i = 0; i < 14; i++) { + if (priv->channel_info[i].channel != + le16_to_cpu(priv->staging_rxon.channel)) { + channel = + priv->channel_info[i].channel; + ch_info = iwl_get_channel_info(priv, + band, channel); + if (is_channel_valid(ch_info)) + break; + } + } + } + + return channel; +} +EXPORT_SYMBOL(iwl_get_single_channel_number); + /** * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7e5a5ba41fd..31775bd9c36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -343,6 +343,8 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv); int iwl_full_rxon_required(struct iwl_priv *priv); void iwl_set_rxon_chain(struct iwl_priv *priv); int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); +u8 iwl_get_single_channel_number(struct iwl_priv *priv, + enum ieee80211_band band); void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *sta_ht_inf); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 3e5bffb6034..6c353cacc8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1844,6 +1844,49 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) #endif } +static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl3945_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u8 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + + channel = iwl_get_single_channel_number(priv, band); + + if (channel) { + scan_ch->channel = channel; + scan_ch->type = 0; /* passive */ + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, enum ieee80211_band band, u8 is_active, u8 n_probes, @@ -2992,9 +3035,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); - scan->channel_count = - iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl3945_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, + (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); + } if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5b197b4d5b..73073259f50 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -80,6 +80,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ + {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ {} diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index d234285c2c8..c561332e700 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -259,6 +259,7 @@ disable: sdio_disable_func(func); release: sdio_release_host(func); + wl1251_free_hw(wl); return ret; } diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index b3e5580c837..4952c3b9379 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -828,7 +828,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_name(pdev), err); return err; } + bus = pdev->subordinate; + if (!bus) { + dev_notice(&pdev->dev, "the device is not a bridge, " + "skipping\n"); + rc = -ENODEV; + goto err_disable_device; + } /* Need to read VID early b/c it's used to differentiate CPQ and INTC * discovery diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 796828fce34..c9171be7456 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -340,7 +340,7 @@ int dmar_disabled = 0; int dmar_disabled = 1; #endif /*CONFIG_DMAR_DEFAULT_ON*/ -static int __initdata dmar_map_gfx = 1; +static int dmar_map_gfx = 1; static int dmar_forcedac; static int intel_iommu_strict; @@ -1874,14 +1874,15 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) } } if (found) { + spin_unlock_irqrestore(&device_domain_lock, flags); free_devinfo_mem(info); domain_exit(domain); domain = found; } else { list_add(&info->link, &domain->devices); list_add(&info->global, &device_domain_list); + spin_unlock_irqrestore(&device_domain_lock, flags); } - spin_unlock_irqrestore(&device_domain_lock, flags); } found_domain: @@ -3603,7 +3604,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, pte = dmar_domain->pgd; if (dma_pte_present(pte)) { free_pgtable_page(dmar_domain->pgd); - dmar_domain->pgd = (struct dma_pte *)dma_pte_addr(pte); + dmar_domain->pgd = (struct dma_pte *) + phys_to_virt(dma_pte_addr(pte)); } dmar_domain->agaw--; } @@ -3719,6 +3721,12 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) */ printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); rwbf_quirk = 1; + + /* https://bugzilla.redhat.com/show_bug.cgi?id=538163 */ + if (dev->revision == 0x07) { + printk(KERN_INFO "DMAR: Disabling IOMMU for graphics on this chipset\n"); + dmar_map_gfx = 0; + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index afd2fbf7d79..c9957f68ac9 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1035,39 +1035,6 @@ error: return retval; } -static void pci_remove_slot_links(struct pci_dev *dev) -{ - char func[10]; - struct pci_slot *slot; - - sysfs_remove_link(&dev->dev.kobj, "slot"); - list_for_each_entry(slot, &dev->bus->slots, list) { - if (slot->number != PCI_SLOT(dev->devfn)) - continue; - snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); - sysfs_remove_link(&slot->kobj, func); - } -} - -static int pci_create_slot_links(struct pci_dev *dev) -{ - int result = 0; - char func[10]; - struct pci_slot *slot; - - list_for_each_entry(slot, &dev->bus->slots, list) { - if (slot->number != PCI_SLOT(dev->devfn)) - continue; - result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot"); - if (result) - goto out; - snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); - result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func); - } -out: - return result; -} - int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) { int retval; @@ -1130,8 +1097,6 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) if (retval) goto err_vga_file; - pci_create_slot_links(pdev); - return 0; err_vga_file: @@ -1181,8 +1146,6 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) if (!sysfs_initialized) return; - pci_remove_slot_links(pdev); - pci_remove_capabilities_sysfs(pdev); if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b7512cf08c5..477345d4164 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1457,7 +1457,8 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) conf5 &= ~(1 << 24); /* Clear bit 24 */ switch (pdev->device) { - case PCI_DEVICE_ID_JMICRON_JMB360: + case PCI_DEVICE_ID_JMICRON_JMB360: /* SATA single port */ + case PCI_DEVICE_ID_JMICRON_JMB362: /* SATA dual ports */ /* The controller should be in single function ahci mode */ conf1 |= 0x0002A100; /* Set 8, 13, 15, 17 */ break; @@ -1493,12 +1494,14 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 17bed18d24a..92379e2d37e 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -97,16 +97,16 @@ int pci_claim_resource(struct pci_dev *dev, int resource) root = pci_find_parent_resource(dev, res); if (!root) { - dev_err(&dev->dev, "no compatible bridge window for %pR\n", - res); + dev_info(&dev->dev, "no compatible bridge window for %pR\n", + res); return -EINVAL; } conflict = request_resource_conflict(root, res); if (conflict) { - dev_err(&dev->dev, - "address space collision: %pR conflicts with %s %pR\n", - res, conflict->name, conflict); + dev_info(&dev->dev, + "address space collision: %pR conflicts with %s %pR\n", + res, conflict->name, conflict); return -EBUSY; } diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index e0189cf7c55..659eaa0fc48 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -97,50 +97,6 @@ static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf) return bus_speed_read(slot->bus->cur_bus_speed, buf); } -static void remove_sysfs_files(struct pci_slot *slot) -{ - char func[10]; - struct list_head *tmp; - - list_for_each(tmp, &slot->bus->devices) { - struct pci_dev *dev = pci_dev_b(tmp); - if (PCI_SLOT(dev->devfn) != slot->number) - continue; - sysfs_remove_link(&dev->dev.kobj, "slot"); - - snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); - sysfs_remove_link(&slot->kobj, func); - } -} - -static int create_sysfs_files(struct pci_slot *slot) -{ - int result; - char func[10]; - struct list_head *tmp; - - list_for_each(tmp, &slot->bus->devices) { - struct pci_dev *dev = pci_dev_b(tmp); - if (PCI_SLOT(dev->devfn) != slot->number) - continue; - - result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot"); - if (result) - goto fail; - - snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); - result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func); - if (result) - goto fail; - } - - return 0; - -fail: - remove_sysfs_files(slot); - return result; -} - static void pci_slot_release(struct kobject *kobj) { struct pci_dev *dev; @@ -153,8 +109,6 @@ static void pci_slot_release(struct kobject *kobj) if (PCI_SLOT(dev->devfn) == slot->number) dev->slot = NULL; - remove_sysfs_files(slot); - list_del(&slot->list); kfree(slot); @@ -346,8 +300,6 @@ placeholder: INIT_LIST_HEAD(&slot->list); list_add(&slot->list, &parent->slots); - create_sysfs_files(slot); - list_for_each_entry(dev, &parent->devices, bus_list) if (PCI_SLOT(dev->devfn) == slot_nr) dev->slot = slot; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 7ef7adee5e4..9fc33984553 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -671,6 +671,7 @@ static void pcmcia_requery(struct pcmcia_socket *s) if (old_funcs != new_funcs) { /* we need to re-start */ pcmcia_card_remove(s, NULL); + s->functions = 0; pcmcia_card_add(s); } } diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 424e576f3ac..f1d41374eea 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -880,6 +880,12 @@ static struct cardbus_type cardbus_type[] = { .restore_state = ti_restore_state, .sock_init = ti_init, }, + [CARDBUS_TYPE_ENE] = { + .override = ene_override, + .save_state = ti_save_state, + .restore_state = ti_restore_state, + .sock_init = ti_init, + }, #endif #ifdef CONFIG_YENTA_RICOH [CARDBUS_TYPE_RICOH] = { @@ -902,14 +908,6 @@ static struct cardbus_type cardbus_type[] = { .restore_state = o2micro_restore_state, }, #endif -#ifdef CONFIG_YENTA_TI - [CARDBUS_TYPE_ENE] = { - .override = ene_override, - .save_state = ti_save_state, - .restore_state = ti_restore_state, - .sock_init = ti_init, - }, -#endif }; @@ -975,7 +973,7 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id) /* probes the PCI interrupt, use only on override functions */ static int yenta_probe_cb_irq(struct yenta_socket *socket) { - u8 reg; + u8 reg = 0; if (!socket->cb_irq) return -1; @@ -989,7 +987,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) } /* generate interrupt, wait */ - reg = exca_readb(socket, I365_CSCINT); + if (!socket->dev->irq) + reg = exca_readb(socket, I365_CSCINT); exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG); cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); diff --git a/drivers/s390/cio/itcw.c b/drivers/s390/cio/itcw.c index 17da9ab932e..a0ae2956477 100644 --- a/drivers/s390/cio/itcw.c +++ b/drivers/s390/cio/itcw.c @@ -42,7 +42,7 @@ * size_t size; * * size = itcw_calc_size(1, 2, 0); - * buffer = kmalloc(size, GFP_DMA); + * buffer = kmalloc(size, GFP_KERNEL | GFP_DMA); * if (!buffer) * return -ENOMEM; * itcw = itcw_init(buffer, size, ITCW_OP_READ, 1, 2, 0); diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 0f41c9195e9..df5b6b971f2 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -637,7 +637,7 @@ const static struct file_operations vhost_net_fops = { }; static struct miscdevice vhost_net_misc = { - VHOST_NET_MINOR, + MISC_DYNAMIC_MINOR, "vhost-net", &vhost_net_fops, }; diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index 43ab7d8b66b..7767338f8b1 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c @@ -572,22 +572,12 @@ static enum omapfb_update_mode omap_lcdc_get_update_mode(void) /* PM code called only in internal controller mode */ static void omap_lcdc_suspend(void) { - if (lcdc.update_mode == OMAPFB_AUTO_UPDATE) { - disable_controller(); - omap_stop_lcd_dma(); - } + omap_lcdc_set_update_mode(OMAPFB_UPDATE_DISABLED); } static void omap_lcdc_resume(void) { - if (lcdc.update_mode == OMAPFB_AUTO_UPDATE) { - setup_regs(); - load_palette(); - setup_lcd_dma(); - set_load_mode(OMAP_LCDC_LOAD_FRAME); - enable_irqs(OMAP_LCDC_IRQ_DONE); - enable_controller(); - } + omap_lcdc_set_update_mode(OMAPFB_AUTO_UPDATE); } static void omap_lcdc_get_caps(int plane, struct omapfb_caps *caps) diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 1162603c72e..eada9f12efc 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/platform_device.h> #include "omapfb.h" #include "dispc.h" @@ -83,13 +84,13 @@ static inline u32 rfbi_read_reg(int idx) static int rfbi_get_clocks(void) { - rfbi.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); + rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick"); if (IS_ERR(rfbi.dss_ick)) { dev_err(rfbi.fbdev->dev, "can't get ick\n"); return PTR_ERR(rfbi.dss_ick); } - rfbi.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); + rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "dss1_fck"); if (IS_ERR(rfbi.dss1_fck)) { dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); clk_put(rfbi.dss_ick); diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index 1cddf92cb9a..750bc5281d7 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c @@ -346,9 +346,13 @@ static int __init at32_wdt_probe(struct platform_device *pdev) } else { wdt->users = 0; } - wdt->miscdev.minor = WATCHDOG_MINOR; - wdt->miscdev.name = "watchdog"; - wdt->miscdev.fops = &at32_wdt_fops; + + wdt->miscdev.minor = WATCHDOG_MINOR; + wdt->miscdev.name = "watchdog"; + wdt->miscdev.fops = &at32_wdt_fops; + wdt->miscdev.parent = &pdev->dev; + + platform_set_drvdata(pdev, wdt); if (at32_wdt_settimeout(timeout)) { at32_wdt_settimeout(TIMEOUT_DEFAULT); @@ -360,17 +364,17 @@ static int __init at32_wdt_probe(struct platform_device *pdev) ret = misc_register(&wdt->miscdev); if (ret) { dev_dbg(&pdev->dev, "failed to register wdt miscdev\n"); - goto err_iounmap; + goto err_register; } - platform_set_drvdata(pdev, wdt); - wdt->miscdev.parent = &pdev->dev; dev_info(&pdev->dev, "AT32AP700X WDT at 0x%p, timeout %d sec (nowayout=%d)\n", wdt->regs, wdt->timeout, nowayout); return 0; +err_register: + platform_set_drvdata(pdev, NULL); err_iounmap: iounmap(wdt->regs); err_free: diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index ea25885781b..2ee7dac55a3 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -330,7 +330,6 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) } static struct platform_driver imx2_wdt_driver = { - .probe = imx2_wdt_probe, .remove = __exit_p(imx2_wdt_remove), .shutdown = imx2_wdt_shutdown, .driver = { diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index 89dd7b03529..b68d928c8f9 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c @@ -284,7 +284,7 @@ static int __devinit wm8350_wdt_probe(struct platform_device *pdev) struct wm8350 *wm8350 = platform_get_drvdata(pdev); if (!wm8350) { - dev_err(wm8350->dev, "No driver data supplied\n"); + pr_err("No driver data supplied\n"); return -ENODEV; } diff --git a/fs/block_dev.c b/fs/block_dev.c index 7346c96308a..99d6af81174 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -706,8 +706,13 @@ retry: * @bdev is about to be opened exclusively. Check @bdev can be opened * exclusively and mark that an exclusive open is in progress. Each * successful call to this function must be matched with a call to - * either bd_claim() or bd_abort_claiming(). If this function - * succeeds, the matching bd_claim() is guaranteed to succeed. + * either bd_finish_claiming() or bd_abort_claiming() (which do not + * fail). + * + * This function is used to gain exclusive access to the block device + * without actually causing other exclusive open attempts to fail. It + * should be used when the open sequence itself requires exclusive + * access but may subsequently fail. * * CONTEXT: * Might sleep. @@ -734,6 +739,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, return ERR_PTR(-ENXIO); whole = bdget_disk(disk, 0); + module_put(disk->fops->owner); put_disk(disk); if (!whole) return ERR_PTR(-ENOMEM); @@ -782,15 +788,46 @@ static void bd_abort_claiming(struct block_device *whole, void *holder) __bd_abort_claiming(whole, holder); /* releases bdev_lock */ } +/* increment holders when we have a legitimate claim. requires bdev_lock */ +static void __bd_claim(struct block_device *bdev, struct block_device *whole, + void *holder) +{ + /* note that for a whole device bd_holders + * will be incremented twice, and bd_holder will + * be set to bd_claim before being set to holder + */ + whole->bd_holders++; + whole->bd_holder = bd_claim; + bdev->bd_holders++; + bdev->bd_holder = holder; +} + +/** + * bd_finish_claiming - finish claiming a block device + * @bdev: block device of interest (passed to bd_start_claiming()) + * @whole: whole block device returned by bd_start_claiming() + * @holder: holder trying to claim @bdev + * + * Finish a claiming block started by bd_start_claiming(). + * + * CONTEXT: + * Grabs and releases bdev_lock. + */ +static void bd_finish_claiming(struct block_device *bdev, + struct block_device *whole, void *holder) +{ + spin_lock(&bdev_lock); + BUG_ON(!bd_may_claim(bdev, whole, holder)); + __bd_claim(bdev, whole, holder); + __bd_abort_claiming(whole, holder); /* not actually an abort */ +} + /** * bd_claim - claim a block device * @bdev: block device to claim * @holder: holder trying to claim @bdev * - * Try to claim @bdev which must have been opened successfully. This - * function may be called with or without preceding - * blk_start_claiming(). In the former case, this function is always - * successful and terminates the claiming block. + * Try to claim @bdev which must have been opened successfully. * * CONTEXT: * Might sleep. @@ -806,23 +843,10 @@ int bd_claim(struct block_device *bdev, void *holder) might_sleep(); spin_lock(&bdev_lock); - res = bd_prepare_to_claim(bdev, whole, holder); - if (res == 0) { - /* note that for a whole device bd_holders - * will be incremented twice, and bd_holder will - * be set to bd_claim before being set to holder - */ - whole->bd_holders++; - whole->bd_holder = bd_claim; - bdev->bd_holders++; - bdev->bd_holder = holder; - } - - if (whole->bd_claiming) - __bd_abort_claiming(whole, holder); /* releases bdev_lock */ - else - spin_unlock(&bdev_lock); + if (res == 0) + __bd_claim(bdev, whole, holder); + spin_unlock(&bdev_lock); return res; } @@ -1476,7 +1500,7 @@ static int blkdev_open(struct inode * inode, struct file * filp) if (whole) { if (res == 0) - BUG_ON(bd_claim(bdev, filp) != 0); + bd_finish_claiming(bdev, whole, filp); else bd_abort_claiming(whole, filp); } @@ -1712,7 +1736,7 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) goto out_blkdev_put; - BUG_ON(bd_claim(bdev, holder) != 0); + bd_finish_claiming(bdev, whole, holder); return bdev; out_blkdev_put: diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 8d432cd9d58..2222d161c7b 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -60,6 +60,8 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) size = __btrfs_getxattr(inode, name, value, size); if (size > 0) { acl = posix_acl_from_xattr(value, size); + if (IS_ERR(acl)) + return acl; set_cached_acl(inode, type, acl); } kfree(value); @@ -160,6 +162,12 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, int ret; struct posix_acl *acl = NULL; + if (!is_owner_or_cap(dentry->d_inode)) + return -EPERM; + + if (!IS_POSIXACL(dentry->d_inode)) + return -EOPNOTSUPP; + if (value) { acl = posix_acl_from_xattr(value, size); if (acl == NULL) { diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index f3b287c22ca..34f7c375567 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1941,8 +1941,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, btrfs_level_size(tree_root, btrfs_super_log_root_level(disk_super)); - log_tree_root = kzalloc(sizeof(struct btrfs_root), - GFP_NOFS); + log_tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); + if (!log_tree_root) { + err = -ENOMEM; + goto fail_trans_kthread; + } __setup_root(nodesize, leafsize, sectorsize, stripesize, log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); @@ -1982,6 +1985,10 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); if (!fs_info->fs_root) goto fail_trans_kthread; + if (IS_ERR(fs_info->fs_root)) { + err = PTR_ERR(fs_info->fs_root); + goto fail_trans_kthread; + } if (!(sb->s_flags & MS_RDONLY)) { down_read(&fs_info->cleanup_work_sem); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b9080d71991..32d094002a5 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4360,7 +4360,8 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, block_rsv = get_block_rsv(trans, root); cache = btrfs_lookup_block_group(root->fs_info, buf->start); - BUG_ON(block_rsv->space_info != cache->space_info); + if (block_rsv->space_info != cache->space_info) + goto out; if (btrfs_header_generation(buf) == trans->transid) { if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 787b50a16a1..e354c33df08 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1140,7 +1140,7 @@ int btrfs_sync_file(struct file *file, int datasync) /* * ok we haven't committed the transaction yet, lets do a commit */ - if (file && file->private_data) + if (file->private_data) btrfs_ioctl_trans_end(file); trans = btrfs_start_transaction(root, 0); @@ -1190,14 +1190,22 @@ static const struct vm_operations_struct btrfs_file_vm_ops = { static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) { - vma->vm_ops = &btrfs_file_vm_ops; + struct address_space *mapping = filp->f_mapping; + + if (!mapping->a_ops->readpage) + return -ENOEXEC; + file_accessed(filp); + vma->vm_ops = &btrfs_file_vm_ops; + vma->vm_flags |= VM_CAN_NONLINEAR; + return 0; } const struct file_operations btrfs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, + .write = do_sync_write, .aio_read = generic_file_aio_read, .splice_read = generic_file_splice_read, .aio_write = btrfs_file_aio_write, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fa6ccc1bfe2..1bff92ad474 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2673,7 +2673,7 @@ static int check_path_shared(struct btrfs_root *root, struct extent_buffer *eb; int level; int ret; - u64 refs; + u64 refs = 1; for (level = 0; level < BTRFS_MAX_LEVEL; level++) { if (!path->nodes[level]) @@ -6884,7 +6884,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, if (em->block_start == EXTENT_MAP_HOLE || (cur_offset >= inode->i_size && !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { - ret = btrfs_prealloc_file_range(inode, 0, cur_offset, + ret = btrfs_prealloc_file_range(inode, mode, cur_offset, last_byte - cur_offset, 1 << inode->i_blkbits, offset + len, diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4cdb98cf26d..4dbaf89b133 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1280,7 +1280,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { err = PTR_ERR(trans); - goto out; + goto out_up_write; } trans->block_rsv = &root->fs_info->global_block_rsv; @@ -1845,7 +1845,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, dir_id, "default", 7, 1); - if (!di) { + if (IS_ERR_OR_NULL(di)) { btrfs_free_path(path); btrfs_end_transaction(trans, root); printk(KERN_ERR "Umm, you don't have the default dir item, " diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 05d41e56923..b37d723b9d4 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -784,16 +784,17 @@ again: struct btrfs_extent_ref_v0 *ref0; ref0 = btrfs_item_ptr(eb, path1->slots[0], struct btrfs_extent_ref_v0); - root = find_tree_root(rc, eb, ref0); - if (!root->ref_cows) - cur->cowonly = 1; if (key.objectid == key.offset) { + root = find_tree_root(rc, eb, ref0); if (root && !should_ignore_root(root)) cur->root = root; else list_add(&cur->list, &useless); break; } + if (is_cowonly_root(btrfs_ref_root_v0(eb, + ref0))) + cur->cowonly = 1; } #else BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY); diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index b91ccd97264..2d958be761c 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -330,7 +330,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, { struct btrfs_path *path; int ret; - u32 refs; struct btrfs_root_item *ri; struct extent_buffer *leaf; @@ -344,8 +343,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, leaf = path->nodes[0]; ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item); - refs = btrfs_disk_root_refs(leaf, ri); - BUG_ON(refs != 0); ret = btrfs_del_item(trans, root, path); out: btrfs_free_path(path); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index d34b2dfc962..f2393b39031 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -360,6 +360,8 @@ static struct dentry *get_default_root(struct super_block *sb, */ dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); + if (IS_ERR(di)) + return ERR_CAST(di); if (!di) { /* * Ok the default dir item isn't there. This is weird since @@ -390,8 +392,8 @@ setup_root: location.offset = 0; inode = btrfs_iget(sb, &location, new_root, &new); - if (!inode) - return ERR_PTR(-ENOMEM); + if (IS_ERR(inode)) + return ERR_CAST(inode); /* * If we're just mounting the root most subvol put the inode and return diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index ae3e3a30644..619b61655ee 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -981,6 +981,46 @@ static int send_cap_msg(struct ceph_mds_session *session, return 0; } +static void __queue_cap_release(struct ceph_mds_session *session, + u64 ino, u64 cap_id, u32 migrate_seq, + u32 issue_seq) +{ + struct ceph_msg *msg; + struct ceph_mds_cap_release *head; + struct ceph_mds_cap_item *item; + + spin_lock(&session->s_cap_lock); + BUG_ON(!session->s_num_cap_releases); + msg = list_first_entry(&session->s_cap_releases, + struct ceph_msg, list_head); + + dout(" adding %llx release to mds%d msg %p (%d left)\n", + ino, session->s_mds, msg, session->s_num_cap_releases); + + BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); + head = msg->front.iov_base; + head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); + item = msg->front.iov_base + msg->front.iov_len; + item->ino = cpu_to_le64(ino); + item->cap_id = cpu_to_le64(cap_id); + item->migrate_seq = cpu_to_le32(migrate_seq); + item->seq = cpu_to_le32(issue_seq); + + session->s_num_cap_releases--; + + msg->front.iov_len += sizeof(*item); + if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { + dout(" release msg %p full\n", msg); + list_move_tail(&msg->list_head, &session->s_cap_releases_done); + } else { + dout(" release msg %p at %d/%d (%d)\n", msg, + (int)le32_to_cpu(head->num), + (int)CEPH_CAPS_PER_RELEASE, + (int)msg->front.iov_len); + } + spin_unlock(&session->s_cap_lock); +} + /* * Queue cap releases when an inode is dropped from our cache. Since * inode is about to be destroyed, there is no need for i_lock. @@ -994,41 +1034,9 @@ void ceph_queue_caps_release(struct inode *inode) while (p) { struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); struct ceph_mds_session *session = cap->session; - struct ceph_msg *msg; - struct ceph_mds_cap_release *head; - struct ceph_mds_cap_item *item; - spin_lock(&session->s_cap_lock); - BUG_ON(!session->s_num_cap_releases); - msg = list_first_entry(&session->s_cap_releases, - struct ceph_msg, list_head); - - dout(" adding %p release to mds%d msg %p (%d left)\n", - inode, session->s_mds, msg, session->s_num_cap_releases); - - BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); - head = msg->front.iov_base; - head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); - item = msg->front.iov_base + msg->front.iov_len; - item->ino = cpu_to_le64(ceph_ino(inode)); - item->cap_id = cpu_to_le64(cap->cap_id); - item->migrate_seq = cpu_to_le32(cap->mseq); - item->seq = cpu_to_le32(cap->issue_seq); - - session->s_num_cap_releases--; - - msg->front.iov_len += sizeof(*item); - if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { - dout(" release msg %p full\n", msg); - list_move_tail(&msg->list_head, - &session->s_cap_releases_done); - } else { - dout(" release msg %p at %d/%d (%d)\n", msg, - (int)le32_to_cpu(head->num), - (int)CEPH_CAPS_PER_RELEASE, - (int)msg->front.iov_len); - } - spin_unlock(&session->s_cap_lock); + __queue_cap_release(session, ceph_ino(inode), cap->cap_id, + cap->mseq, cap->issue_seq); p = rb_next(p); __ceph_remove_cap(cap); } @@ -2655,7 +2663,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, struct ceph_mds_caps *h; int mds = session->s_mds; int op; - u32 seq; + u32 seq, mseq; struct ceph_vino vino; u64 cap_id; u64 size, max_size; @@ -2675,6 +2683,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, vino.snap = CEPH_NOSNAP; cap_id = le64_to_cpu(h->cap_id); seq = le32_to_cpu(h->seq); + mseq = le32_to_cpu(h->migrate_seq); size = le64_to_cpu(h->size); max_size = le64_to_cpu(h->max_size); @@ -2689,6 +2698,18 @@ void ceph_handle_caps(struct ceph_mds_session *session, vino.snap, inode); if (!inode) { dout(" i don't have ino %llx\n", vino.ino); + + if (op == CEPH_CAP_OP_IMPORT) + __queue_cap_release(session, vino.ino, cap_id, + mseq, seq); + + /* + * send any full release message to try to move things + * along for the mds (who clearly thinks we still have this + * cap). + */ + ceph_add_cap_releases(mdsc, session, -1); + ceph_send_cap_releases(mdsc, session); goto done; } @@ -2714,7 +2735,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, spin_lock(&inode->i_lock); cap = __get_cap_for_mds(ceph_inode(inode), mds); if (!cap) { - dout("no cap on %p ino %llx.%llx from mds%d, releasing\n", + dout(" no cap on %p ino %llx.%llx from mds%d\n", inode, ceph_ino(inode), ceph_snap(inode), mds); spin_unlock(&inode->i_lock); goto done; diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 226f5a50d36..ab47f46ca28 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -827,7 +827,7 @@ static void ceph_set_dentry_offset(struct dentry *dn) spin_lock(&dcache_lock); spin_lock(&dn->d_lock); - list_move_tail(&dir->d_subdirs, &dn->d_u.d_child); + list_move(&dn->d_u.d_child, &dir->d_subdirs); dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, dn->d_u.d_child.prev, dn->d_u.d_child.next); spin_unlock(&dn->d_lock); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index b49f12822cb..1766947fc07 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1066,9 +1066,9 @@ static int trim_caps(struct ceph_mds_client *mdsc, * * Called under s_mutex. */ -static int add_cap_releases(struct ceph_mds_client *mdsc, - struct ceph_mds_session *session, - int extra) +int ceph_add_cap_releases(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + int extra) { struct ceph_msg *msg; struct ceph_mds_cap_release *head; @@ -1176,8 +1176,8 @@ static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq) /* * called under s_mutex */ -static void send_cap_releases(struct ceph_mds_client *mdsc, - struct ceph_mds_session *session) +void ceph_send_cap_releases(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) { struct ceph_msg *msg; @@ -1980,7 +1980,7 @@ out_err: } mutex_unlock(&mdsc->mutex); - add_cap_releases(mdsc, req->r_session, -1); + ceph_add_cap_releases(mdsc, req->r_session, -1); mutex_unlock(&session->s_mutex); /* kick calling process */ @@ -2433,6 +2433,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, struct ceph_dentry_info *di; int mds = session->s_mds; struct ceph_mds_lease *h = msg->front.iov_base; + u32 seq; struct ceph_vino vino; int mask; struct qstr dname; @@ -2446,6 +2447,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, vino.ino = le64_to_cpu(h->ino); vino.snap = CEPH_NOSNAP; mask = le16_to_cpu(h->mask); + seq = le32_to_cpu(h->seq); dname.name = (void *)h + sizeof(*h) + sizeof(u32); dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32); if (dname.len != get_unaligned_le32(h+1)) @@ -2456,8 +2458,9 @@ static void handle_lease(struct ceph_mds_client *mdsc, /* lookup inode */ inode = ceph_find_inode(sb, vino); - dout("handle_lease '%s', mask %d, ino %llx %p\n", - ceph_lease_op_name(h->action), mask, vino.ino, inode); + dout("handle_lease %s, mask %d, ino %llx %p %.*s\n", + ceph_lease_op_name(h->action), mask, vino.ino, inode, + dname.len, dname.name); if (inode == NULL) { dout("handle_lease no inode %llx\n", vino.ino); goto release; @@ -2482,7 +2485,8 @@ static void handle_lease(struct ceph_mds_client *mdsc, switch (h->action) { case CEPH_MDS_LEASE_REVOKE: if (di && di->lease_session == session) { - h->seq = cpu_to_le32(di->lease_seq); + if (ceph_seq_cmp(di->lease_seq, seq) > 0) + h->seq = cpu_to_le32(di->lease_seq); __ceph_mdsc_drop_dentry_lease(dentry); } release = 1; @@ -2496,7 +2500,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, unsigned long duration = le32_to_cpu(h->duration_ms) * HZ / 1000; - di->lease_seq = le32_to_cpu(h->seq); + di->lease_seq = seq; dentry->d_time = di->lease_renew_from + duration; di->lease_renew_after = di->lease_renew_from + (duration >> 1); @@ -2686,10 +2690,10 @@ static void delayed_work(struct work_struct *work) send_renew_caps(mdsc, s); else ceph_con_keepalive(&s->s_con); - add_cap_releases(mdsc, s, -1); + ceph_add_cap_releases(mdsc, s, -1); if (s->s_state == CEPH_MDS_SESSION_OPEN || s->s_state == CEPH_MDS_SESSION_HUNG) - send_cap_releases(mdsc, s); + ceph_send_cap_releases(mdsc, s); mutex_unlock(&s->s_mutex); ceph_put_mds_session(s); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index d9936c4f121..b292fa42a66 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -322,6 +322,12 @@ static inline void ceph_mdsc_put_request(struct ceph_mds_request *req) kref_put(&req->r_kref, ceph_mdsc_release_request); } +extern int ceph_add_cap_releases(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + int extra); +extern void ceph_send_cap_releases(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session); + extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 21c62e9b7d1..07a539906e6 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -400,6 +400,8 @@ static void release_generic_request(struct kref *kref) ceph_msg_put(req->reply); if (req->request) ceph_msg_put(req->request); + + kfree(req); } static void put_generic_request(struct ceph_mon_generic_request *req) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 4e0bee240b9..fa87f51e38e 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -89,7 +89,7 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_files = le64_to_cpu(st.num_objects); buf->f_ffree = -1; - buf->f_namelen = PATH_MAX; + buf->f_namelen = NAME_MAX; buf->f_frsize = PAGE_CACHE_SIZE; /* leave fsid little-endian, regardless of host endianness */ @@ -926,7 +926,7 @@ static int ceph_compare_super(struct super_block *sb, void *data) /* * construct our own bdi so we can control readahead, etc. */ -static atomic_long_t bdi_seq = ATOMIC_INIT(0); +static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) { diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 78c02eb4cb1..484e52bb40b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -473,14 +473,24 @@ static int cifs_remount(struct super_block *sb, int *flags, char *data) return 0; } +void cifs_drop_inode(struct inode *inode) +{ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) + return generic_drop_inode(inode); + + return generic_delete_inode(inode); +} + static const struct super_operations cifs_super_ops = { .put_super = cifs_put_super, .statfs = cifs_statfs, .alloc_inode = cifs_alloc_inode, .destroy_inode = cifs_destroy_inode, -/* .drop_inode = generic_delete_inode, - .delete_inode = cifs_delete_inode, */ /* Do not need above two - functions unless later we add lazy close of inodes or unless the + .drop_inode = cifs_drop_inode, +/* .delete_inode = cifs_delete_inode, */ /* Do not need above + function unless later we add lazy close of inodes or unless the kernel forgets to call us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fb1657e0fdb..fb6318b8150 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -106,7 +106,6 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, struct vfsmount *mnt, unsigned int oflags); extern int cifs_posix_open(char *full_path, struct inode **pinode, - struct vfsmount *mnt, struct super_block *sb, int mode, int oflags, __u32 *poplock, __u16 *pnetfid, int xid); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 391816b461c..e7ae78b66fa 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/namei.h> #include <linux/mount.h> +#include <linux/file.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" @@ -184,12 +185,13 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, } write_unlock(&GlobalSMBSeslock); + file->private_data = pCifsFile; + return pCifsFile; } int cifs_posix_open(char *full_path, struct inode **pinode, - struct vfsmount *mnt, struct super_block *sb, - int mode, int oflags, + struct super_block *sb, int mode, int oflags, __u32 *poplock, __u16 *pnetfid, int xid) { int rc; @@ -258,19 +260,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, cifs_fattr_to_inode(*pinode, &fattr); } - /* - * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to - * file->private_data. - */ - if (mnt) { - struct cifsFileInfo *pfile_info; - - pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, - oflags); - if (pfile_info == NULL) - rc = -ENOMEM; - } - posix_open_ret: kfree(presp_data); return rc; @@ -298,7 +287,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, int create_options = CREATE_NOT_DIR; __u32 oplock = 0; int oflags; - bool posix_create = false; /* * BB below access is probably too much for mknod to request * but we have to do query and setpathinfo so requesting @@ -339,7 +327,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { rc = cifs_posix_open(full_path, &newinode, - nd ? nd->path.mnt : NULL, inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); /* EIO could indicate that (posix open) operation is not supported, despite what server claimed in capability @@ -347,7 +334,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, handled in posix open */ if (rc == 0) { - posix_create = true; if (newinode == NULL) /* query inode info */ goto cifs_create_get_file_info; else /* success, no need to query */ @@ -478,21 +464,28 @@ cifs_create_set_dentry: else cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); - /* nfsd case - nfs srv does not set nd */ - if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { - /* mknod case - do not leave file open */ - CIFSSMBClose(xid, tcon, fileHandle); - } else if (!(posix_create) && (newinode)) { + if (newinode && nd && (nd->flags & LOOKUP_OPEN)) { struct cifsFileInfo *pfile_info; - /* - * cifs_fill_filedata() takes care of setting cifsFileInfo - * pointer to file->private_data. - */ - pfile_info = cifs_new_fileinfo(newinode, fileHandle, NULL, + struct file *filp; + + filp = lookup_instantiate_filp(nd, direntry, generic_file_open); + if (IS_ERR(filp)) { + rc = PTR_ERR(filp); + CIFSSMBClose(xid, tcon, fileHandle); + goto cifs_create_out; + } + + pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, nd->path.mnt, oflags); - if (pfile_info == NULL) + if (pfile_info == NULL) { + fput(filp); + CIFSSMBClose(xid, tcon, fileHandle); rc = -ENOMEM; + } + } else { + CIFSSMBClose(xid, tcon, fileHandle); } + cifs_create_out: kfree(buf); kfree(full_path); @@ -636,6 +629,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, bool posix_open = false; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; + struct cifsFileInfo *cfile; struct inode *newInode = NULL; char *full_path = NULL; struct file *filp; @@ -703,7 +697,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && (nd->intent.open.flags & O_CREAT)) { - rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, + rc = cifs_posix_open(full_path, &newInode, parent_dir_inode->i_sb, nd->intent.open.create_mode, nd->intent.open.flags, &oplock, @@ -733,8 +727,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, else direntry->d_op = &cifs_dentry_ops; d_add(direntry, newInode); - if (posix_open) - filp = lookup_instantiate_filp(nd, direntry, NULL); + if (posix_open) { + filp = lookup_instantiate_filp(nd, direntry, + generic_file_open); + if (IS_ERR(filp)) { + rc = PTR_ERR(filp); + CIFSSMBClose(xid, pTcon, fileHandle); + goto lookup_out; + } + + cfile = cifs_new_fileinfo(newInode, fileHandle, filp, + nd->path.mnt, + nd->intent.open.flags); + if (cfile == NULL) { + fput(filp); + CIFSSMBClose(xid, pTcon, fileHandle); + rc = -ENOMEM; + goto lookup_out; + } + } /* since paths are not looked up by component - the parent directories are presumed to be good here */ renew_parental_timestamps(direntry); @@ -755,6 +766,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, is a common return code */ } +lookup_out: kfree(full_path); FreeXid(xid); return ERR_PTR(rc); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 75541af4b3d..409e4f523e6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -162,44 +162,12 @@ psx_client_can_cache: return 0; } -static struct cifsFileInfo * -cifs_fill_filedata(struct file *file) -{ - struct list_head *tmp; - struct cifsFileInfo *pCifsFile = NULL; - struct cifsInodeInfo *pCifsInode = NULL; - - /* search inode for this file and fill in file->private_data */ - pCifsInode = CIFS_I(file->f_path.dentry->d_inode); - read_lock(&GlobalSMBSeslock); - list_for_each(tmp, &pCifsInode->openFileList) { - pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); - if ((pCifsFile->pfile == NULL) && - (pCifsFile->pid == current->tgid)) { - /* mode set in cifs_create */ - - /* needed for writepage */ - pCifsFile->pfile = file; - file->private_data = pCifsFile; - break; - } - } - read_unlock(&GlobalSMBSeslock); - - if (file->private_data != NULL) { - return pCifsFile; - } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) - cERROR(1, "could not find file instance for " - "new file %p", file); - return NULL; -} - /* all arguments to this function must be checked for validity in caller */ -static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, - struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, +static inline int cifs_open_inode_helper(struct inode *inode, struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, char *full_path, int xid) { + struct cifsInodeInfo *pCifsInode = CIFS_I(inode); struct timespec temp; int rc; @@ -213,36 +181,35 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, /* if not oplocked, invalidate inode pages if mtime or file size changed */ temp = cifs_NTtimeToUnix(buf->LastWriteTime); - if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && - (file->f_path.dentry->d_inode->i_size == + if (timespec_equal(&inode->i_mtime, &temp) && + (inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) { cFYI(1, "inode unchanged on server"); } else { - if (file->f_path.dentry->d_inode->i_mapping) { + if (inode->i_mapping) { /* BB no need to lock inode until after invalidate since namei code should already have it locked? */ - rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); + rc = filemap_write_and_wait(inode->i_mapping); if (rc != 0) - CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; + pCifsInode->write_behind_rc = rc; } cFYI(1, "invalidating remote inode since open detected it " "changed"); - invalidate_remote_inode(file->f_path.dentry->d_inode); + invalidate_remote_inode(inode); } client_can_cache: if (pTcon->unix_ext) - rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, - full_path, inode->i_sb, xid); + rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, + xid); else - rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, - full_path, buf, inode->i_sb, xid, NULL); + rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, + xid, NULL); if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { pCifsInode->clientCanCacheAll = true; pCifsInode->clientCanCacheRead = true; - cFYI(1, "Exclusive Oplock granted on inode %p", - file->f_path.dentry->d_inode); + cFYI(1, "Exclusive Oplock granted on inode %p", inode); } else if ((*oplock & 0xF) == OPLOCK_READ) pCifsInode->clientCanCacheRead = true; @@ -256,7 +223,7 @@ int cifs_open(struct inode *inode, struct file *file) __u32 oplock; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *tcon; - struct cifsFileInfo *pCifsFile; + struct cifsFileInfo *pCifsFile = NULL; struct cifsInodeInfo *pCifsInode; char *full_path = NULL; int desiredAccess; @@ -270,12 +237,6 @@ int cifs_open(struct inode *inode, struct file *file) tcon = cifs_sb->tcon; pCifsInode = CIFS_I(file->f_path.dentry->d_inode); - pCifsFile = cifs_fill_filedata(file); - if (pCifsFile) { - rc = 0; - FreeXid(xid); - return rc; - } full_path = build_path_from_dentry(file->f_path.dentry); if (full_path == NULL) { @@ -299,8 +260,7 @@ int cifs_open(struct inode *inode, struct file *file) int oflags = (int) cifs_posix_convert_flags(file->f_flags); oflags |= SMB_O_CREAT; /* can not refresh inode info since size could be stale */ - rc = cifs_posix_open(full_path, &inode, file->f_path.mnt, - inode->i_sb, + rc = cifs_posix_open(full_path, &inode, inode->i_sb, cifs_sb->mnt_file_mode /* ignored */, oflags, &oplock, &netfid, xid); if (rc == 0) { @@ -308,9 +268,20 @@ int cifs_open(struct inode *inode, struct file *file) /* no need for special case handling of setting mode on read only files needed here */ - pCifsFile = cifs_fill_filedata(file); - cifs_posix_open_inode_helper(inode, file, pCifsInode, - oplock, netfid); + rc = cifs_posix_open_inode_helper(inode, file, + pCifsInode, oplock, netfid); + if (rc != 0) { + CIFSSMBClose(xid, tcon, netfid); + goto out; + } + + pCifsFile = cifs_new_fileinfo(inode, netfid, file, + file->f_path.mnt, + oflags); + if (pCifsFile == NULL) { + CIFSSMBClose(xid, tcon, netfid); + rc = -ENOMEM; + } goto out; } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { if (tcon->ses->serverNOS) @@ -391,17 +362,17 @@ int cifs_open(struct inode *inode, struct file *file) goto out; } + rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid); + if (rc != 0) + goto out; + pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, file->f_flags); - file->private_data = pCifsFile; - if (file->private_data == NULL) { + if (pCifsFile == NULL) { rc = -ENOMEM; goto out; } - rc = cifs_open_inode_helper(inode, file, pCifsInode, pCifsFile, tcon, - &oplock, buf, full_path, xid); - if (oplock & CIFS_CREATE_ACTION) { /* time to set mode which we can not set earlier due to problems creating new read-only files */ @@ -513,8 +484,7 @@ reopen_error_exit: le64_to_cpu(tcon->fsUnixInfo.Capability))) { int oflags = (int) cifs_posix_convert_flags(file->f_flags); /* can not refresh inode info since size could be stale */ - rc = cifs_posix_open(full_path, NULL, file->f_path.mnt, - inode->i_sb, + rc = cifs_posix_open(full_path, NULL, inode->i_sb, cifs_sb->mnt_file_mode /* ignored */, oflags, &oplock, &netfid, xid); if (rc == 0) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 62b324f26a5..6f0683c6895 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1401,6 +1401,10 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, if (rc == 0 || rc != -ETXTBSY) return rc; + /* open-file renames don't work across directories */ + if (to_dentry->d_parent != from_dentry->d_parent) + return rc; + /* open the file to be renamed -- we need DELETE perms */ rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, CREATE_NOT_DIR, &srcfid, &oplock, NULL, diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 7707389bdf2..0a57cb7db5d 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -730,15 +730,7 @@ ssetup_ntlmssp_authenticate: /* calculate session key */ setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); - if (first_time) /* should this be moved into common code - with similar ntlmv2 path? */ - /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, - response BB FIXME, v2_sess_key); */ - - /* copy session key */ - - /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); - bcc_ptr += LM2_SESS_KEY_SIZE; */ + /* FIXME: calculate MAC key */ memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp)); bcc_ptr += sizeof(struct ntlmv2_resp); diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index a33aab6b5e6..54a92fd02bb 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -234,8 +234,9 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (inode->i_mode != mode) { struct iattr attr; - attr.ia_valid = ATTR_MODE; + attr.ia_valid = ATTR_MODE | ATTR_CTIME; attr.ia_mode = mode; + attr.ia_ctime = CURRENT_TIME_SEC; rc = jffs2_do_setattr(inode, &attr); if (rc < 0) return rc; diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 7aa4417e085..166062a6823 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -222,15 +222,18 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); jffs2_free_raw_inode(ri); - d_instantiate(dentry, inode); D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->pino_nlink, inode->i_mapping->nrpages)); + + d_instantiate(dentry, inode); + unlock_new_inode(inode); return 0; fail: make_bad_inode(inode); + unlock_new_inode(inode); iput(inode); jffs2_free_raw_inode(ri); return ret; @@ -360,8 +363,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char /* Eeek. Wave bye bye */ mutex_unlock(&f->sem); jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return PTR_ERR(fn); + ret = PTR_ERR(fn); + goto fail; } /* We use f->target field to store the target path. */ @@ -370,8 +373,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); mutex_unlock(&f->sem); jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } memcpy(f->target, target, targetlen + 1); @@ -386,30 +389,24 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char jffs2_complete_reservation(c); ret = jffs2_init_security(inode, dir_i); - if (ret) { - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; + ret = jffs2_init_acl_post(inode); - if (ret) { - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); - if (ret) { - /* Eep. */ - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; rd = jffs2_alloc_raw_dirent(); if (!rd) { /* Argh. Now we treat it like a normal delete */ jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } dir_f = JFFS2_INODE_INFO(dir_i); @@ -437,8 +434,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char jffs2_complete_reservation(c); jffs2_free_raw_dirent(rd); mutex_unlock(&dir_f->sem); - jffs2_clear_inode(inode); - return PTR_ERR(fd); + ret = PTR_ERR(fd); + goto fail; } dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); @@ -453,7 +450,14 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char jffs2_complete_reservation(c); d_instantiate(dentry, inode); + unlock_new_inode(inode); return 0; + + fail: + make_bad_inode(inode); + unlock_new_inode(inode); + iput(inode); + return ret; } @@ -519,8 +523,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) /* Eeek. Wave bye bye */ mutex_unlock(&f->sem); jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return PTR_ERR(fn); + ret = PTR_ERR(fn); + goto fail; } /* No data here. Only a metadata node, which will be obsoleted by the first data write @@ -531,30 +535,24 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) jffs2_complete_reservation(c); ret = jffs2_init_security(inode, dir_i); - if (ret) { - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; + ret = jffs2_init_acl_post(inode); - if (ret) { - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); - if (ret) { - /* Eep. */ - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; rd = jffs2_alloc_raw_dirent(); if (!rd) { /* Argh. Now we treat it like a normal delete */ jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } dir_f = JFFS2_INODE_INFO(dir_i); @@ -582,8 +580,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) jffs2_complete_reservation(c); jffs2_free_raw_dirent(rd); mutex_unlock(&dir_f->sem); - jffs2_clear_inode(inode); - return PTR_ERR(fd); + ret = PTR_ERR(fd); + goto fail; } dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); @@ -599,7 +597,14 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) jffs2_complete_reservation(c); d_instantiate(dentry, inode); + unlock_new_inode(inode); return 0; + + fail: + make_bad_inode(inode); + unlock_new_inode(inode); + iput(inode); + return ret; } static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) @@ -693,8 +698,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de /* Eeek. Wave bye bye */ mutex_unlock(&f->sem); jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return PTR_ERR(fn); + ret = PTR_ERR(fn); + goto fail; } /* No data here. Only a metadata node, which will be obsoleted by the first data write @@ -705,30 +710,24 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de jffs2_complete_reservation(c); ret = jffs2_init_security(inode, dir_i); - if (ret) { - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; + ret = jffs2_init_acl_post(inode); - if (ret) { - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); - if (ret) { - /* Eep. */ - jffs2_clear_inode(inode); - return ret; - } + if (ret) + goto fail; rd = jffs2_alloc_raw_dirent(); if (!rd) { /* Argh. Now we treat it like a normal delete */ jffs2_complete_reservation(c); - jffs2_clear_inode(inode); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } dir_f = JFFS2_INODE_INFO(dir_i); @@ -759,8 +758,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de jffs2_complete_reservation(c); jffs2_free_raw_dirent(rd); mutex_unlock(&dir_f->sem); - jffs2_clear_inode(inode); - return PTR_ERR(fd); + ret = PTR_ERR(fd); + goto fail; } dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); @@ -775,8 +774,14 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de jffs2_complete_reservation(c); d_instantiate(dentry, inode); - + unlock_new_inode(inode); return 0; + + fail: + make_bad_inode(inode); + unlock_new_inode(inode); + iput(inode); + return ret; } static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 8bc2c80ab15..459d39d1ea0 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -465,7 +465,12 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i inode->i_blocks = 0; inode->i_size = 0; - insert_inode_hash(inode); + if (insert_inode_locked(inode) < 0) { + make_bad_inode(inode); + unlock_new_inode(inode); + iput(inode); + return ERR_PTR(-EINVAL); + } return inode; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 12f7109720c..4a273475877 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4122,8 +4122,8 @@ nfs4_state_shutdown(void) nfs4_lock_state(); nfs4_release_reclaim(); __nfs4_state_shutdown(); - nfsd4_destroy_callback_queue(); nfs4_unlock_state(); + nfsd4_destroy_callback_queue(); } /* diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index ebbf3b6b245..3c111120b61 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -443,8 +443,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, if (size_change) put_write_access(inode); if (!err) - if (EX_ISSYNC(fhp->fh_export)) - write_inode_now(inode, 1); + commit_metadata(fhp); out: return err; diff --git a/fs/pipe.c b/fs/pipe.c index 69c4c7c13ea..279eef96c51 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1145,13 +1145,20 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) * and adjust the indexes. */ if (pipe->nrbufs) { - const unsigned int tail = pipe->nrbufs & (pipe->buffers - 1); - const unsigned int head = pipe->nrbufs - tail; + unsigned int tail; + unsigned int head; + tail = pipe->curbuf + pipe->nrbufs; + if (tail < pipe->buffers) + tail = 0; + else + tail &= (pipe->buffers - 1); + + head = pipe->nrbufs - tail; if (head) memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); if (tail) - memcpy(bufs + head, pipe->bufs + pipe->curbuf, tail * sizeof(struct pipe_buffer)); + memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer)); } pipe->curbuf = 0; @@ -1208,12 +1215,13 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) size = round_pipe_size(arg); nr_pages = size >> PAGE_SHIFT; + ret = -EINVAL; + if (!nr_pages) + goto out; + if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { ret = -EPERM; goto out; - } else if (nr_pages < PAGE_SIZE) { - ret = -EINVAL; - goto out; } ret = pipe_set_size(pipe, nr_pages); break; diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index ce94801f48c..d9396a4fc7f 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c @@ -209,6 +209,9 @@ void proc_device_tree_add_node(struct device_node *np, for (pp = np->properties; pp != NULL; pp = pp->next) { p = pp->name; + if (strchr(p, '/')) + continue; + if (duplicate_name(de, p)) p = fixup_name(np, de, p); diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index a0fa3bf0d1b..34640d6dbdc 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1381,14 +1381,6 @@ xfs_vm_writepage( if (!page_has_buffers(page)) create_empty_buffers(page, 1 << inode->i_blkbits, 0); - - /* - * VM calculation for nr_to_write seems off. Bump it way - * up, this gets simple streaming writes zippy again. - * To be reviewed again after Jens' writeback changes. - */ - wbc->nr_to_write *= 4; - /* * Convert delayed allocate, unwritten or unmapped space * to real space and flush out to disk. diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 5958d7845bd..17714beb868 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -212,7 +212,7 @@ char const *acpi_gbl_exception_names_env[] = { "AE_NO_GLOBAL_LOCK", "AE_ABORT_METHOD", "AE_SAME_HANDLER", - "AE_WAKE_ONLY_GPE", + "AE_NO_HANDLER", "AE_OWNER_ID_LIMIT" }; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 0e4ab1fe596..1371cc99739 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -69,6 +69,7 @@ extern acpi_name acpi_gbl_trace_method_name; extern u32 acpi_gbl_trace_flags; extern u8 acpi_gbl_enable_aml_debug_object; extern u8 acpi_gbl_copy_dsdt_locally; +extern u8 acpi_gbl_truncate_io_addresses; extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index bade172cad4..d55f4a7b824 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -663,10 +663,11 @@ typedef u32 acpi_event_status; #define ACPI_GPE_MAX 0xFF #define ACPI_NUM_GPE 256 -/* Actions for acpi_set_gpe */ +/* Actions for acpi_set_gpe and acpi_hw_low_set_gpe */ #define ACPI_GPE_ENABLE 0 #define ACPI_GPE_DISABLE 1 +#define ACPI_GPE_COND_ENABLE 2 /* gpe_types for acpi_enable_gpe and acpi_disable_gpe */ diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 3ff9fc071df..5347063e9d5 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -903,6 +903,7 @@ struct drm_radeon_cs { #define RADEON_INFO_NUM_Z_PIPES 0x02 #define RADEON_INFO_ACCEL_WORKING 0x03 #define RADEON_INFO_CRTC_FROM_ID 0x04 +#define RADEON_INFO_ACCEL_WORKING2 0x05 struct drm_radeon_info { uint32_t request; diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index b631c46cffd..f6c9b7dcb9f 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -3,6 +3,12 @@ #include <linux/module.h> #include <linux/major.h> +/* + * These allocations are managed by device@lanana.org. If you use an + * entry that is not in assigned your entry may well be moved and + * reassigned, or set dynamic if a fixed value is not justified. + */ + #define PSMOUSE_MINOR 1 #define MS_BUSMOUSE_MINOR 2 #define ATIXL_BUSMOUSE_MINOR 3 @@ -30,7 +36,6 @@ #define HPET_MINOR 228 #define FUSE_MINOR 229 #define KVM_MINOR 232 -#define VHOST_NET_MINOR 233 #define BTRFS_MINOR 234 #define AUTOFS_MINOR 235 #define MISC_DYNAMIC_MINOR 255 diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f149dd10908..4eb467910a4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2321,6 +2321,7 @@ #define PCI_VENDOR_ID_JMICRON 0x197B #define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 #define PCI_DEVICE_ID_JMICRON_JMB361 0x2361 +#define PCI_DEVICE_ID_JMICRON_JMB362 0x2362 #define PCI_DEVICE_ID_JMICRON_JMB363 0x2363 #define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index bf243fc5495..f89e7fd59a4 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -380,7 +380,10 @@ struct sk_buff { kmemcheck_bitfield_begin(flags2); __u16 queue_mapping:16; #ifdef CONFIG_IPV6_NDISC_NODETYPE - __u8 ndisc_nodetype:2; + __u8 ndisc_nodetype:2, + deliver_no_wcard:1; +#else + __u8 deliver_no_wcard:1; #endif kmemcheck_bitfield_end(flags2); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5e781d824e6..bc7d6bb4cd8 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -256,22 +256,22 @@ static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } #endif /* CONFIG_HIBERNATION */ -#ifdef CONFIG_HIBERNATION_NVS -extern int hibernate_nvs_register(unsigned long start, unsigned long size); -extern int hibernate_nvs_alloc(void); -extern void hibernate_nvs_free(void); -extern void hibernate_nvs_save(void); -extern void hibernate_nvs_restore(void); -#else /* CONFIG_HIBERNATION_NVS */ -static inline int hibernate_nvs_register(unsigned long a, unsigned long b) +#ifdef CONFIG_SUSPEND_NVS +extern int suspend_nvs_register(unsigned long start, unsigned long size); +extern int suspend_nvs_alloc(void); +extern void suspend_nvs_free(void); +extern void suspend_nvs_save(void); +extern void suspend_nvs_restore(void); +#else /* CONFIG_SUSPEND_NVS */ +static inline int suspend_nvs_register(unsigned long a, unsigned long b) { return 0; } -static inline int hibernate_nvs_alloc(void) { return 0; } -static inline void hibernate_nvs_free(void) {} -static inline void hibernate_nvs_save(void) {} -static inline void hibernate_nvs_restore(void) {} -#endif /* CONFIG_HIBERNATION_NVS */ +static inline int suspend_nvs_alloc(void) { return 0; } +static inline void suspend_nvs_free(void) {} +static inline void suspend_nvs_save(void) {} +static inline void suspend_nvs_restore(void) {} +#endif /* CONFIG_SUSPEND_NVS */ #ifdef CONFIG_PM_SLEEP void save_processor_state(void); diff --git a/include/linux/writeback.h b/include/linux/writeback.h index f64134653a8..d63ef8f9609 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -56,15 +56,6 @@ struct writeback_control { unsigned for_reclaim:1; /* Invoked from the page allocator */ unsigned range_cyclic:1; /* range_start is cyclic */ unsigned more_io:1; /* more io to be dispatched */ - /* - * write_cache_pages() won't update wbc->nr_to_write and - * mapping->writeback_index if no_nrwrite_index_update - * is set. write_cache_pages() may write more than we - * requested and we want to make sure nr_to_write and - * writeback_index are updated in a consistent manner - * so we use a single control to update them - */ - unsigned no_nrwrite_index_update:1; }; /* diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index f5b1ba90e95..f3865c7b416 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -306,7 +306,6 @@ TRACE_EVENT(ext4_da_writepages_result, __field( int, pages_written ) __field( long, pages_skipped ) __field( char, more_io ) - __field( char, no_nrwrite_index_update ) __field( pgoff_t, writeback_index ) ), @@ -317,16 +316,14 @@ TRACE_EVENT(ext4_da_writepages_result, __entry->pages_written = pages_written; __entry->pages_skipped = wbc->pages_skipped; __entry->more_io = wbc->more_io; - __entry->no_nrwrite_index_update = wbc->no_nrwrite_index_update; __entry->writeback_index = inode->i_mapping->writeback_index; ), - TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld more_io %d no_nrwrite_index_update %d writeback_index %lu", + TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld more_io %d writeback_index %lu", jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino, __entry->ret, __entry->pages_written, __entry->pages_skipped, __entry->more_io, - __entry->no_nrwrite_index_update, (unsigned long) __entry->writeback_index) ); diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h index 814566c99d2..17df43464df 100644 --- a/include/trace/events/signal.h +++ b/include/trace/events/signal.h @@ -10,7 +10,8 @@ #define TP_STORE_SIGINFO(__entry, info) \ do { \ - if (info == SEND_SIG_NOINFO) { \ + if (info == SEND_SIG_NOINFO || \ + info == SEND_SIG_FORCED) { \ __entry->errno = 0; \ __entry->code = SI_USER; \ } else if (info == SEND_SIG_PRIV) { \ diff --git a/init/main.c b/init/main.c index 3bdb152f412..ac2e4a5f59e 100644 --- a/init/main.c +++ b/init/main.c @@ -125,7 +125,9 @@ static char *ramdisk_execute_command; #ifdef CONFIG_SMP /* Setup configured maximum number of CPUs to activate */ -unsigned int __initdata setup_max_cpus = NR_CPUS; +unsigned int setup_max_cpus = NR_CPUS; +EXPORT_SYMBOL(setup_max_cpus); + /* * Setup routine for controlling SMP activation diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 31d6afe9259..ff86c558af4 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -1507,6 +1507,9 @@ do { \ divisor = nsec * frequency; } + if (!divisor) + return dividend; + return div64_u64(dividend, divisor); } @@ -1529,7 +1532,7 @@ static int perf_event_start(struct perf_event *event) static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) { struct hw_perf_event *hwc = &event->hw; - u64 period, sample_period; + s64 period, sample_period; s64 delta; period = perf_calculate_period(event, nsec, count); diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 5c36ea9d55d..ca6066a6952 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG depends on PM_ADVANCED_DEBUG default n +config SUSPEND_NVS + bool + config SUSPEND bool "Suspend to RAM and standby" depends on PM && ARCH_SUSPEND_POSSIBLE + select SUSPEND_NVS if HAS_IOMEM default y ---help--- Allow the system to enter sleep states in which main memory is @@ -130,13 +134,10 @@ config SUSPEND_FREEZER Turning OFF this setting is NOT recommended! If in doubt, say Y. -config HIBERNATION_NVS - bool - config HIBERNATION bool "Hibernation (aka 'suspend to disk')" depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE - select HIBERNATION_NVS if HAS_IOMEM + select SUSPEND_NVS if HAS_IOMEM ---help--- Enable the suspend to disk (STD) functionality, which is usually called "hibernation" in user interfaces. STD checkpoints the diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 524e058dcf0..f9063c6b185 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -10,6 +10,6 @@ obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ block_io.o -obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o +obj-$(CONFIG_SUSPEND_NVS) += nvs.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff --git a/kernel/power/hibernate_nvs.c b/kernel/power/nvs.c index fdcad9ed5a7..1836db60bbb 100644 --- a/kernel/power/hibernate_nvs.c +++ b/kernel/power/nvs.c @@ -15,7 +15,7 @@ /* * Platforms, like ACPI, may want us to save some memory used by them during - * hibernation and to restore the contents of this memory during the subsequent + * suspend and to restore the contents of this memory during the subsequent * resume. The code below implements a mechanism allowing us to do that. */ @@ -30,7 +30,7 @@ struct nvs_page { static LIST_HEAD(nvs_list); /** - * hibernate_nvs_register - register platform NVS memory region to save + * suspend_nvs_register - register platform NVS memory region to save * @start - physical address of the region * @size - size of the region * @@ -38,7 +38,7 @@ static LIST_HEAD(nvs_list); * things so that the data from page-aligned addresses in this region will * be copied into separate RAM pages. */ -int hibernate_nvs_register(unsigned long start, unsigned long size) +int suspend_nvs_register(unsigned long start, unsigned long size) { struct nvs_page *entry, *next; @@ -68,9 +68,9 @@ int hibernate_nvs_register(unsigned long start, unsigned long size) } /** - * hibernate_nvs_free - free data pages allocated for saving NVS regions + * suspend_nvs_free - free data pages allocated for saving NVS regions */ -void hibernate_nvs_free(void) +void suspend_nvs_free(void) { struct nvs_page *entry; @@ -86,16 +86,16 @@ void hibernate_nvs_free(void) } /** - * hibernate_nvs_alloc - allocate memory necessary for saving NVS regions + * suspend_nvs_alloc - allocate memory necessary for saving NVS regions */ -int hibernate_nvs_alloc(void) +int suspend_nvs_alloc(void) { struct nvs_page *entry; list_for_each_entry(entry, &nvs_list, node) { entry->data = (void *)__get_free_page(GFP_KERNEL); if (!entry->data) { - hibernate_nvs_free(); + suspend_nvs_free(); return -ENOMEM; } } @@ -103,9 +103,9 @@ int hibernate_nvs_alloc(void) } /** - * hibernate_nvs_save - save NVS memory regions + * suspend_nvs_save - save NVS memory regions */ -void hibernate_nvs_save(void) +void suspend_nvs_save(void) { struct nvs_page *entry; @@ -119,12 +119,12 @@ void hibernate_nvs_save(void) } /** - * hibernate_nvs_restore - restore NVS memory regions + * suspend_nvs_restore - restore NVS memory regions * * This function is going to be called with interrupts disabled, so it * cannot iounmap the virtual addresses used to access the NVS region. */ -void hibernate_nvs_restore(void) +void suspend_nvs_restore(void) { struct nvs_page *entry; diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 56e7dbb8b99..f37cb7dd440 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -16,6 +16,12 @@ #include <linux/cpu.h> #include <linux/syscalls.h> #include <linux/gfp.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/suspend.h> #include "power.h" diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 5fa63bdf52e..bbd396ac954 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -835,7 +835,6 @@ int write_cache_pages(struct address_space *mapping, pgoff_t done_index; int cycled; int range_whole = 0; - long nr_to_write = wbc->nr_to_write; pagevec_init(&pvec, 0); if (wbc->range_cyclic) { @@ -852,7 +851,22 @@ int write_cache_pages(struct address_space *mapping, if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; cycled = 1; /* ignore range_cyclic tests */ + + /* + * If this is a data integrity sync, cap the writeback to the + * current end of file. Any extension to the file that occurs + * after this is a new write and we don't need to write those + * pages out to fulfil our data integrity requirements. If we + * try to write them out, we can get stuck in this scan until + * the concurrent writer stops adding dirty pages and extending + * EOF. + */ + if (wbc->sync_mode == WB_SYNC_ALL && + wbc->range_end == LLONG_MAX) { + end = i_size_read(mapping->host) >> PAGE_CACHE_SHIFT; + } } + retry: done_index = index; while (!done && (index <= end)) { @@ -935,11 +949,10 @@ continue_unlock: done = 1; break; } - } + } - if (nr_to_write > 0) { - nr_to_write--; - if (nr_to_write == 0 && + if (wbc->nr_to_write > 0) { + if (--wbc->nr_to_write == 0 && wbc->sync_mode == WB_SYNC_NONE) { /* * We stop writing back only if we are @@ -970,11 +983,8 @@ continue_unlock: end = writeback_index - 1; goto retry; } - if (!wbc->no_nrwrite_index_update) { - if (wbc->range_cyclic || (range_whole && nr_to_write > 0)) - mapping->writeback_index = done_index; - wbc->nr_to_write = nr_to_write; - } + if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) + mapping->writeback_index = done_index; return ret; } diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index bd537fc1025..50f58f5f1c3 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -12,7 +12,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return NET_RX_DROP; if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) - goto drop; + skb->deliver_no_wcard = 1; skb->skb_iif = skb->dev->ifindex; __vlan_hwaccel_put_tag(skb, vlan_tci); @@ -84,7 +84,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, struct sk_buff *p; if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) - goto drop; + skb->deliver_no_wcard = 1; skb->skb_iif = skb->dev->ifindex; __vlan_hwaccel_put_tag(skb, vlan_tci); diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index cd2830fec93..fd27b172fb5 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -83,7 +83,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) if (!cfsrvl_ready(service, &ret)) return ret; - if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { + if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { pr_err("CAIF: %s():Packet too large - size=%d\n", __func__, cfpkt_getlen(pkt)); return -EOVERFLOW; diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index 0fd827f4949..e04f7d964e8 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -84,7 +84,7 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) return ret; caif_assert(layr->dn != NULL); caif_assert(layr->dn->transmit != NULL); - if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { + if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { pr_warning("CAIF: %s(): Packet too large - size=%d\n", __func__, cfpkt_getlen(pkt)); return -EOVERFLOW; diff --git a/net/core/dev.c b/net/core/dev.c index d03470f5260..2b3bf53bc68 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2253,11 +2253,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (skb_rx_queue_recorded(skb)) { u16 index = skb_get_rx_queue(skb); if (unlikely(index >= dev->num_rx_queues)) { - if (net_ratelimit()) { - pr_warning("%s received packet on queue " - "%u, but number of RX queues is %u\n", - dev->name, index, dev->num_rx_queues); - } + WARN_ONCE(dev->num_rx_queues > 1, "%s received packet " + "on queue %u, but number of RX queues is %u\n", + dev->name, index, dev->num_rx_queues); goto done; } rxqueue = dev->_rx + index; @@ -2812,13 +2810,24 @@ static int __netif_receive_skb(struct sk_buff *skb) if (!skb->skb_iif) skb->skb_iif = skb->dev->ifindex; + /* + * bonding note: skbs received on inactive slaves should only + * be delivered to pkt handlers that are exact matches. Also + * the deliver_no_wcard flag will be set. If packet handlers + * are sensitive to duplicate packets these skbs will need to + * be dropped at the handler. The vlan accel path may have + * already set the deliver_no_wcard flag. + */ null_or_orig = NULL; orig_dev = skb->dev; master = ACCESS_ONCE(orig_dev->master); - if (master) { - if (skb_bond_should_drop(skb, master)) + if (skb->deliver_no_wcard) + null_or_orig = orig_dev; + else if (master) { + if (skb_bond_should_drop(skb, master)) { + skb->deliver_no_wcard = 1; null_or_orig = orig_dev; /* deliver only exact match */ - else + } else skb->dev = master; } diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index cf8e70392fe..785e5276a30 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -107,6 +107,7 @@ static DEFINE_RWLOCK(est_lock); /* Protects against soft lockup during large deletion */ static struct rb_root est_root = RB_ROOT; +static DEFINE_SPINLOCK(est_tree_lock); static void est_timer(unsigned long arg) { @@ -201,7 +202,6 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats * * Returns 0 on success or a negative error code. * - * NOTE: Called under rtnl_mutex */ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est, @@ -232,6 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, est->last_packets = bstats->packets; est->avpps = rate_est->pps<<10; + spin_lock(&est_tree_lock); if (!elist[idx].timer.function) { INIT_LIST_HEAD(&elist[idx].list); setup_timer(&elist[idx].timer, est_timer, idx); @@ -242,6 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, list_add_rcu(&est->list, &elist[idx].list); gen_add_node(est); + spin_unlock(&est_tree_lock); return 0; } @@ -261,13 +263,13 @@ static void __gen_kill_estimator(struct rcu_head *head) * * Removes the rate estimator specified by &bstats and &rate_est. * - * NOTE: Called under rtnl_mutex */ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est) { struct gen_estimator *e; + spin_lock(&est_tree_lock); while ((e = gen_find_node(bstats, rate_est))) { rb_erase(&e->node, &est_root); @@ -278,6 +280,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, list_del_rcu(&e->list); call_rcu(&e->e_rcu, __gen_kill_estimator); } + spin_unlock(&est_tree_lock); } EXPORT_SYMBOL(gen_kill_estimator); @@ -312,8 +315,14 @@ EXPORT_SYMBOL(gen_replace_estimator); bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, const struct gnet_stats_rate_est *rate_est) { + bool res; + ASSERT_RTNL(); - return gen_find_node(bstats, rate_est) != NULL; + spin_lock(&est_tree_lock); + res = gen_find_node(bstats, rate_est) != NULL; + spin_unlock(&est_tree_lock); + + return res; } EXPORT_SYMBOL(gen_estimator_active); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2ad68da418d..1dacd7ba8db 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2170,7 +2170,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) end_time = ktime_now(); pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time)); - pkt_dev->next_tx = ktime_add_ns(end_time, pkt_dev->delay); + pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay); } static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 856123fe32f..757f25eb9b4 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -267,8 +267,10 @@ static void __net_exit ipmr_rules_exit(struct net *net) { struct mr_table *mrt, *next; - list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) + list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { + list_del(&mrt->list); kfree(mrt); + } fib_rules_unregister(net->ipv4.mr_rules_ops); } #else diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index ce799298255..03e62f94ff8 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -483,7 +483,7 @@ route_done: np->tclass, NULL, &fl, (struct rt6_info*)dst, MSG_DONTWAIT, np->dontfrag); if (err) { - ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); + ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); ip6_flush_pending_frames(sk); goto out_put; } @@ -565,7 +565,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) np->dontfrag); if (err) { - ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); + ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); ip6_flush_pending_frames(sk); goto out_put; } diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 073071f2b75..66078dad7fe 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -120,7 +120,7 @@ static void mroute_clean_tables(struct mr6_table *mrt); static void ipmr_expire_process(unsigned long arg); #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES -#define ip6mr_for_each_table(mrt, met) \ +#define ip6mr_for_each_table(mrt, net) \ list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list) static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) @@ -254,8 +254,10 @@ static void __net_exit ip6mr_rules_exit(struct net *net) { struct mr6_table *mrt, *next; - list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) + list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) { + list_del(&mrt->list); ip6mr_free_table(mrt); + } fib_rules_unregister(net->ipv6.mr6_rules_ops); } #else diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 59f1881968c..ab1622d7d40 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1356,7 +1356,10 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) IPV6_TLV_PADN, 0 }; /* we assume size > sizeof(ra) here */ - skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err); + size += LL_ALLOCATED_SPACE(dev); + /* limit our allocations to order-0 page */ + size = min_t(int, size, SKB_MAX_ORDER(0, 0)); + skb = sock_alloc_send_skb(sk, size, 1, &err); if (!skb) return NULL; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4f227131665..9c1da080916 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -349,7 +349,7 @@ static inline int drv_get_survey(struct ieee80211_local *local, int idx, struct survey_info *survey) { int ret = -EOPNOTSUPP; - if (local->ops->conf_tx) + if (local->ops->get_survey) ret = local->ops->get_survey(&local->hw, idx, survey); /* trace_drv_get_survey(local, idx, survey, ret); */ return ret; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0839c4e8fd2..f803f8b72a9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1692,14 +1692,52 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); break; case IEEE80211_STYPE_ACTION: - if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) + switch (mgmt->u.action.category) { + case WLAN_CATEGORY_BACK: { + struct ieee80211_local *local = sdata->local; + int len = skb->len; + struct sta_info *sta; + + rcu_read_lock(); + sta = sta_info_get(sdata, mgmt->sa); + if (!sta) { + rcu_read_unlock(); + break; + } + + local_bh_disable(); + + switch (mgmt->u.action.u.addba_req.action_code) { + case WLAN_ACTION_ADDBA_REQ: + if (len < (IEEE80211_MIN_ACTION_SIZE + + sizeof(mgmt->u.action.u.addba_req))) + break; + ieee80211_process_addba_request(local, sta, mgmt, len); + break; + case WLAN_ACTION_ADDBA_RESP: + if (len < (IEEE80211_MIN_ACTION_SIZE + + sizeof(mgmt->u.action.u.addba_resp))) + break; + ieee80211_process_addba_resp(local, sta, mgmt, len); + break; + case WLAN_ACTION_DELBA: + if (len < (IEEE80211_MIN_ACTION_SIZE + + sizeof(mgmt->u.action.u.delba))) + break; + ieee80211_process_delba(sdata, sta, mgmt, len); + break; + } + local_bh_enable(); + rcu_read_unlock(); break; - - ieee80211_sta_process_chanswitch(sdata, - &mgmt->u.action.u.chan_switch.sw_elem, - (void *)ifmgd->associated->priv, - rx_status->mactime); - break; + } + case WLAN_CATEGORY_SPECTRUM_MGMT: + ieee80211_sta_process_chanswitch(sdata, + &mgmt->u.action.u.chan_switch.sw_elem, + (void *)ifmgd->associated->priv, + rx_status->mactime); + break; + } } mutex_unlock(&ifmgd->mtx); @@ -1722,9 +1760,45 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, mutex_unlock(&ifmgd->mtx); if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && - (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) - cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); + (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) { + struct ieee80211_local *local = sdata->local; + struct ieee80211_work *wk; + + mutex_lock(&local->work_mtx); + list_for_each_entry(wk, &local->work_list, list) { + if (wk->sdata != sdata) + continue; + + if (wk->type != IEEE80211_WORK_ASSOC) + continue; + + if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) + continue; + if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN)) + continue; + /* + * Printing the message only here means we can't + * spuriously print it, but it also means that it + * won't be printed when the frame comes in before + * we even tried to associate or in similar cases. + * + * Ultimately, I suspect cfg80211 should print the + * messages instead. + */ + printk(KERN_DEBUG + "%s: deauthenticated from %pM (Reason: %u)\n", + sdata->name, mgmt->bssid, + le16_to_cpu(mgmt->u.deauth.reason_code)); + + list_del_rcu(&wk->list); + free_work(wk); + break; + } + mutex_unlock(&local->work_mtx); + + cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); + } out: kfree_skb(skb); } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5e0b65406c4..be9abc2e634 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1944,6 +1944,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (len < IEEE80211_MIN_ACTION_SIZE + 1) break; + if (sdata->vif.type == NL80211_IFTYPE_STATION) + return ieee80211_sta_rx_mgmt(sdata, rx->skb); + switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: if (len < (IEEE80211_MIN_ACTION_SIZE + diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin index 102a276f6ee..1adb974e695 100644 --- a/scripts/Makefile.modbuiltin +++ b/scripts/Makefile.modbuiltin @@ -14,6 +14,11 @@ __modbuiltin: include scripts/Kbuild.include +ifneq ($(KBUILD_SRC),) +# Create output directory if not already present +_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) +endif + # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3318692e4e7..f8779006986 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1342,7 +1342,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = sechdr->sh_info; return (void *)elf->hdr + sechdrs[section].sh_offset + - (r->r_offset - sechdrs[section].sh_addr); + r->r_offset - sechdrs[section].sh_addr; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 13074b45474..6261745e445 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -33,7 +33,7 @@ static int key_get_type_from_user(char *type, ret = strncpy_from_user(type, _type, len); if (ret < 0) - return -EFAULT; + return ret; if (ret == 0 || ret >= len) return -EINVAL; @@ -1080,7 +1080,7 @@ set: return old_setting; error: abort_creds(new); - return -EINVAL; + return ret; } /* end keyctl_set_reqkey_keyring() */ diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 22208b373fb..e1ec6d91ea3 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h @@ -73,7 +73,7 @@ struct psc_dma { }; /* Utility for retrieving psc_dma_stream structure from a substream */ -inline struct psc_dma_stream * +static inline struct psc_dma_stream * to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma) { if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 1941a357e8c..d256f5f313b 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -328,38 +328,6 @@ static struct snd_soc_device spitz_snd_devdata = { .codec_dev = &soc_codec_dev_wm8750, }; -/* - * FIXME: This is a temporary bodge to avoid cross-tree merge issues. - * New drivers should register the wm8750 I2C device in the machine - * setup code (under arch/arm for ARM systems). - */ -static int wm8750_i2c_register(void) -{ - struct i2c_board_info info; - struct i2c_adapter *adapter; - struct i2c_client *client; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = 0x1b; - strlcpy(info.type, "wm8750", I2C_NAME_SIZE); - - adapter = i2c_get_adapter(0); - if (!adapter) { - printk(KERN_ERR "can't get i2c adapter 0\n"); - return -ENODEV; - } - - client = i2c_new_device(adapter, &info); - i2c_put_adapter(adapter); - if (!client) { - printk(KERN_ERR "can't add i2c device at 0x%x\n", - (unsigned int)info.addr); - return -ENODEV; - } - - return 0; -} - static struct platform_device *spitz_snd_device; static int __init spitz_init(void) @@ -369,10 +337,6 @@ static int __init spitz_init(void) if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) return -ENODEV; - ret = wm8750_i2c_setup(); - if (ret != 0) - return ret; - spitz_snd_device = platform_device_alloc("soc-audio", -1); if (!spitz_snd_device) return -ENOMEM; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 7fd6b151feb..b63e5713849 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1745,7 +1745,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, if (symbol_conf.vmlinux_name != NULL) { err = dso__load_vmlinux(self, map, symbol_conf.vmlinux_name, filter); - goto out_try_fixup; + if (err > 0) { + dso__set_long_name(self, + strdup(symbol_conf.vmlinux_name)); + goto out_fixup; + } + return err; } if (vmlinux_path != NULL) { @@ -1806,7 +1811,6 @@ do_kallsyms: pr_debug("Using %s for symbols\n", kallsyms_filename); free(kallsyms_allocated_filename); -out_try_fixup: if (err > 0) { out_fixup: if (kallsyms_filename != NULL) diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 7c79c1d76d0..3500dee9cf2 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -192,12 +192,13 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) { - u32 old_irr = ioapic->irr; + u32 old_irr; u32 mask = 1 << irq; union kvm_ioapic_redirect_entry entry; int ret = 1; spin_lock(&ioapic->lock); + old_irr = ioapic->irr; if (irq >= 0 && irq < IOAPIC_NUM_PINS) { entry = ioapic->redirtbl[irq]; level ^= entry.fields.polarity; diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index d2f06be6335..96048ee9e39 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c @@ -271,7 +271,7 @@ static void kvm_iommu_put_pages(struct kvm *kvm, pfn = phys >> PAGE_SHIFT; /* Unmap address from IO address space */ - order = iommu_unmap(domain, gfn_to_gpa(gfn), PAGE_SIZE); + order = iommu_unmap(domain, gfn_to_gpa(gfn), 0); unmap_pages = 1ULL << order; /* Unpin all pages we just unmapped to not leak any memory */ |