diff --git a/[refs] b/[refs] index bfcbc576d2e1..f15de3eadfda 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 39ef13a4ac28aa64cfe1bc36e6e00f1096707a28 +refs/heads/master: 167a58f10d9cd1bdf6a911aa1eecbdff596de156 diff --git a/trunk/Documentation/watchdog/watchdog-parameters.txt b/trunk/Documentation/watchdog/watchdog-parameters.txt index 17ddd822b456..41c95cc1dc1f 100644 --- a/trunk/Documentation/watchdog/watchdog-parameters.txt +++ b/trunk/Documentation/watchdog/watchdog-parameters.txt @@ -125,11 +125,6 @@ ibmasr: nowayout: Watchdog cannot be stopped once started (default=kernel config parameter) ------------------------------------------------- -imx2_wdt: -timeout: Watchdog timeout in seconds (default 60 s) -nowayout: Watchdog cannot be stopped once started - (default=kernel config parameter) -------------------------------------------------- indydog: nowayout: Watchdog cannot be stopped once started (default=kernel config parameter) diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 9f90de2e00f8..f9730fa0b24c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -896,13 +896,11 @@ S: Maintained ARM/SAMSUNG ARM ARCHITECTURES M: Ben Dooks -M: Kukjin Kim L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.fluff.org/ben/linux/ S: Maintained -F: arch/arm/plat-samsung/ +F: arch/arm/plat-s3c/ F: arch/arm/plat-s3c24xx/ -F: arch/arm/plat-s5p/ ARM/S3C2410 ARM ARCHITECTURE M: Ben Dooks @@ -1150,7 +1148,7 @@ F: drivers/mmc/host/atmel-mci.c F: drivers/mmc/host/atmel-mci-regs.h ATMEL AT91 / AT32 SERIAL DRIVER -M: Nicolas Ferre +M: Haavard Skinnemoen S: Supported F: drivers/serial/atmel_serial.c @@ -1162,18 +1160,18 @@ F: drivers/video/atmel_lcdfb.c F: include/video/atmel_lcdc.h ATMEL MACB ETHERNET DRIVER -M: Nicolas Ferre +M: Haavard Skinnemoen S: Supported F: drivers/net/macb.* ATMEL SPI DRIVER -M: Nicolas Ferre +M: Haavard Skinnemoen S: Supported F: drivers/spi/atmel_spi.* ATMEL USBA UDC DRIVER -M: Nicolas Ferre -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +M: Haavard Skinnemoen +L: kernel@avr32linux.org W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver S: Supported F: drivers/usb/gadget/atmel_usba_udc.* @@ -2111,18 +2109,11 @@ F: drivers/edac/i5000_edac.c EDAC-I5400 M: Mauro Carvalho Chehab -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/i5400_edac.c -EDAC-I7CORE -M: Mauro Carvalho Chehab -L: linux-edac@vger.kernel.org -W: bluesmoke.sourceforge.net -S: Maintained -F: drivers/edac/i7core_edac.c linux/edac_mce.h drivers/edac/edac_mce.c - EDAC-I82975X M: Ranganathan Desikan M: "Arvind R." @@ -3382,7 +3373,7 @@ KPROBES M: Ananth N Mavinakayanahalli M: Anil S Keshavamurthy M: "David S. Miller" -M: Masami Hiramatsu +M: Masami Hiramatsu S: Maintained F: Documentation/kprobes.txt F: include/linux/kprobes.h @@ -4630,12 +4621,6 @@ M: Robert Jarzmik L: rtc-linux@googlegroups.com S: Maintained -QLOGIC QLA1280 SCSI DRIVER -M: Michael Reed -L: linux-scsi@vger.kernel.org -S: Maintained -F: drivers/scsi/qla1280.[ch] - QLOGIC QLA2XXX FC-SCSI DRIVER M: Andrew Vasquez M: linux-driver@qlogic.com diff --git a/trunk/Makefile b/trunk/Makefile index 0a20cd413b02..f6c206a5b01a 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 35 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc3 NAME = Sheep on Meth # *DOCUMENTATION* @@ -883,10 +883,80 @@ PHONY += $(vmlinux-dirs) $(vmlinux-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ +# Build the kernel release string +# +# The KERNELRELEASE value built here is stored in the file +# include/config/kernel.release, and is used when executing several +# make targets, such as "make install" or "make modules_install." +# +# The eventual kernel release string consists of the following fields, +# shown in a hierarchical format to show how smaller parts are concatenated +# to form the larger and final value, with values coming from places like +# the Makefile, kernel config options, make command line options and/or +# SCM tag information. +# +# $(KERNELVERSION) +# $(VERSION) eg, 2 +# $(PATCHLEVEL) eg, 6 +# $(SUBLEVEL) eg, 18 +# $(EXTRAVERSION) eg, -rc6 +# $(localver-full) +# $(localver) +# localversion* (files without backups, containing '~') +# $(CONFIG_LOCALVERSION) (from kernel config setting) +# $(LOCALVERSION) (from make command line, if provided) +# $(localver-extra) +# $(scm-identifier) (unique SCM tag, if one exists) +# ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO) +# .scmversion (only with CONFIG_LOCALVERSION_AUTO) +# + (only without CONFIG_LOCALVERSION_AUTO +# and without LOCALVERSION= and +# repository is at non-tagged commit) +# +# For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has +# been revised beyond a tagged commit, `+' is appended to the version string +# when not overridden by using "make LOCALVERSION=". This indicates that the +# kernel is not a vanilla release version and has been modified. + +pattern = ".*/localversion[^~]*" +string = $(shell cat /dev/null \ + `find $(objtree) $(srctree) -maxdepth 1 -regex $(pattern) | sort -u`) + +localver = $(subst $(space),, $(string) \ + $(patsubst "%",%,$(CONFIG_LOCALVERSION))) + +# scripts/setlocalversion is called to create a unique identifier if the source +# is managed by a known SCM and the repository has been revised since the last +# tagged (release) commit. The format of the identifier is determined by the +# SCM's implementation. +# +# .scmversion is used when generating rpm packages so we do not loose +# the version information from the SCM when we do the build of the kernel +# from the copied source +ifeq ($(wildcard .scmversion),) + scm-identifier = $(shell $(CONFIG_SHELL) \ + $(srctree)/scripts/setlocalversion $(srctree)) +else + scm-identifier = $(shell cat .scmversion 2> /dev/null) +endif + +ifdef CONFIG_LOCALVERSION_AUTO + localver-extra = $(scm-identifier) +else + ifneq ($(scm-identifier),) + ifeq ("$(origin LOCALVERSION)", "undefined") + localver-extra = + + endif + endif +endif + +localver-full = $(localver)$(LOCALVERSION)$(localver-extra) + # Store (new) KERNELRELASE string in include/config/kernel.release +kernelrelease = $(KERNELVERSION)$(localver-full) include/config/kernel.release: include/config/auto.conf FORCE $(Q)rm -f $@ - $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) scripts/setlocalversion $(srctree))" > $@ + $(Q)echo $(kernelrelease) > $@ # Things we need to do before we recursively start building the kernel diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 98922f7d2d12..1f254bd6c937 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -955,8 +955,7 @@ config XSCALE_PMU default y config CPU_HAS_PMU - depends on (CPU_V6 || CPU_V7 || XSCALE_PMU) && \ - (!ARCH_OMAP3 || OMAP3_EMU) + depends on CPU_V6 || CPU_V7 || XSCALE_PMU default y bool diff --git a/trunk/arch/arm/include/asm/mach/udc_pxa2xx.h b/trunk/arch/arm/include/asm/mach/udc_pxa2xx.h index 833306ee9e7f..f3eabf1ecec3 100644 --- a/trunk/arch/arm/include/asm/mach/udc_pxa2xx.h +++ b/trunk/arch/arm/include/asm/mach/udc_pxa2xx.h @@ -21,8 +21,8 @@ struct pxa2xx_udc_mach_info { * here. Note that sometimes the signals go through inverters... */ bool gpio_vbus_inverted; - int gpio_vbus; /* high == vbus present */ + u16 gpio_vbus; /* high == vbus present */ bool gpio_pullup_inverted; - int gpio_pullup; /* high == pullup activated */ + u16 gpio_pullup; /* high == pullup activated */ }; diff --git a/trunk/arch/arm/include/asm/processor.h b/trunk/arch/arm/include/asm/processor.h index 7bed3daf83b8..6a89567ffc5b 100644 --- a/trunk/arch/arm/include/asm/processor.h +++ b/trunk/arch/arm/include/asm/processor.h @@ -91,11 +91,7 @@ extern void release_thread(struct task_struct *); unsigned long get_wchan(struct task_struct *p); -#if __LINUX_ARM_ARCH__ == 6 -#define cpu_relax() smp_mb() -#else #define cpu_relax() barrier() -#endif /* * Create a new kernel thread diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 417c392ddf1c..5b7cfafc0720 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -201,7 +201,7 @@ armpmu_event_update(struct perf_event *event, { int shift = 64 - 32; s64 prev_raw_count, new_raw_count; - u64 delta; + s64 delta; again: prev_raw_count = local64_read(&hwc->prev_count); diff --git a/trunk/arch/arm/mach-mx3/mach-mx31lilly.c b/trunk/arch/arm/mach-mx3/mach-mx31lilly.c index b2c7f512070f..d3d5877c750e 100644 --- a/trunk/arch/arm/mach-mx3/mach-mx31lilly.c +++ b/trunk/arch/arm/mach-mx3/mach-mx31lilly.c @@ -115,8 +115,6 @@ static struct platform_device physmap_flash_device = { /* USB */ -#if defined(CONFIG_USB_ULPI) - #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) @@ -246,20 +244,10 @@ static struct mxc_usbh_platform_data usbh2_pdata = { .flags = MXC_EHCI_POWER_PINS_ENABLED, }; -static void lilly1131_usb_init(void) -{ - usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, - USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); - usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, - USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); - - mxc_register_device(&mxc_usbh1, &usbh1_pdata); - mxc_register_device(&mxc_usbh2, &usbh2_pdata); -} - -#else -static inline void lilly1131_usb_init(void) {} -#endif /* CONFIG_USB_ULPI */ +static struct platform_device *devices[] __initdata = { + &smsc91x_device, + &physmap_flash_device, +}; /* SPI */ @@ -291,11 +279,6 @@ static struct spi_board_info mc13783_dev __initdata = { .platform_data = &mc13783_pdata, }; -static struct platform_device *devices[] __initdata = { - &smsc91x_device, - &physmap_flash_device, -}; - static int mx31lilly_baseboard; core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444); @@ -338,7 +321,13 @@ static void __init mx31lilly_board_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); /* USB */ - lilly1131_usb_init(); + usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_usbh1, &usbh1_pdata); + mxc_register_device(&mxc_usbh2, &usbh2_pdata); } static void __init mx31lilly_timer_init(void) diff --git a/trunk/arch/arm/mach-omap2/board-omap3stalker.c b/trunk/arch/arm/mach-omap2/board-omap3stalker.c index a04cffd691c5..f848ba8dbc16 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3stalker.c +++ b/trunk/arch/arm/mach-omap2/board-omap3stalker.c @@ -538,7 +538,9 @@ static void ads7846_dev_init(void) printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); gpio_direction_input(OMAP3_STALKER_TS_GPIO); - gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310); + + omap_set_gpio_debounce(OMAP3_STALKER_TS_GPIO, 1); + omap_set_gpio_debounce_time(OMAP3_STALKER_TS_GPIO, 0xa); } static int ads7846_get_pendown_state(void) diff --git a/trunk/arch/arm/mach-omap2/clock44xx_data.c b/trunk/arch/arm/mach-omap2/clock44xx_data.c index e10db7a90cb2..02804224517b 100644 --- a/trunk/arch/arm/mach-omap2/clock44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clock44xx_data.c @@ -1369,7 +1369,6 @@ static struct clk emif1_ick = { .ops = &clkops_omap2_dflt, .enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL, .enable_bit = OMAP4430_MODULEMODE_HWCTRL, - .flags = ENABLE_ON_INIT, .clkdm_name = "l3_emif_clkdm", .parent = &ddrphy_ck, .recalc = &followparent_recalc, @@ -1380,7 +1379,6 @@ static struct clk emif2_ick = { .ops = &clkops_omap2_dflt, .enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL, .enable_bit = OMAP4430_MODULEMODE_HWCTRL, - .flags = ENABLE_ON_INIT, .clkdm_name = "l3_emif_clkdm", .parent = &ddrphy_ck, .recalc = &followparent_recalc, diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index b7a4133267d8..95c9a5f774e1 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -409,11 +409,10 @@ static int _init_main_clk(struct omap_hwmod *oh) return 0; oh->_clk = omap_clk_get_by_name(oh->main_clk); - if (!oh->_clk) { + if (!oh->_clk) pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", oh->name, oh->main_clk); return -EINVAL; - } if (!oh->_clk->clkdm) pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n", @@ -445,11 +444,10 @@ static int _init_interface_clks(struct omap_hwmod *oh) continue; c = omap_clk_get_by_name(os->clk); - if (!c) { + if (!c) pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n", oh->name, os->clk); ret = -EINVAL; - } os->_clk = c; } @@ -472,11 +470,10 @@ static int _init_opt_clks(struct omap_hwmod *oh) for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { c = omap_clk_get_by_name(oc->clk); - if (!c) { + if (!c) pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n", oh->name, oc->clk); ret = -EINVAL; - } oc->_clk = c; } diff --git a/trunk/arch/arm/mach-omap2/pm34xx.c b/trunk/arch/arm/mach-omap2/pm34xx.c index b88737fd6cfe..2e967716cc3f 100644 --- a/trunk/arch/arm/mach-omap2/pm34xx.c +++ b/trunk/arch/arm/mach-omap2/pm34xx.c @@ -99,7 +99,7 @@ static void omap3_enable_io_chain(void) /* Do a readback to assure write has been done */ prm_read_mod_reg(WKUP_MOD, PM_WKEN); - while (!(prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) & OMAP3430_ST_IO_CHAIN_MASK)) { timeout++; if (timeout > 1000) { @@ -108,7 +108,7 @@ static void omap3_enable_io_chain(void) return; } prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + WKUP_MOD, PM_WKST); } } } diff --git a/trunk/arch/arm/mach-omap2/usb-ehci.c b/trunk/arch/arm/mach-omap2/usb-ehci.c index d72d1ac30333..c68f799e83c5 100644 --- a/trunk/arch/arm/mach-omap2/usb-ehci.c +++ b/trunk/arch/arm/mach-omap2/usb-ehci.c @@ -20,8 +20,6 @@ #include #include #include -#include - #include #include diff --git a/trunk/arch/arm/mach-pxa/mioa701.c b/trunk/arch/arm/mach-pxa/mioa701.c index fa6a708b4099..d60db87dde08 100644 --- a/trunk/arch/arm/mach-pxa/mioa701.c +++ b/trunk/arch/arm/mach-pxa/mioa701.c @@ -697,7 +697,7 @@ static struct i2c_board_info __initdata mioa701_pi2c_devices[] = { }; /* Board I2C devices. */ -static struct i2c_board_info mioa701_i2c_devices[] = { +static struct i2c_board_info __initdata mioa701_i2c_devices[] = { { I2C_BOARD_INFO("mt9m111", 0x5d), }, diff --git a/trunk/arch/arm/mach-pxa/z2.c b/trunk/arch/arm/mach-pxa/z2.c index d303c6929d32..f5d1ae3db3a4 100644 --- a/trunk/arch/arm/mach-pxa/z2.c +++ b/trunk/arch/arm/mach-pxa/z2.c @@ -3,9 +3,8 @@ * * Support for the Zipit Z2 Handheld device. * - * Copyright (C) 2009-2010 Marek Vasut - * - * Based on research and code by: Ken McGuire + * Author: Ken McGuire + * Created: Jan 25, 2009 * Based on mainstone.c as modified for the Zipit Z2. * * This program is free software; you can redistribute it and/or modify @@ -158,14 +157,21 @@ static struct mtd_partition z2_flash_parts[] = { { .name = "U-Boot Bootloader", .offset = 0x0, - .size = 0x40000, - }, { + .size = 0x20000, + }, + { + .name = "Linux Kernel", + .offset = 0x20000, + .size = 0x220000, + }, + { + .name = "Filesystem", + .offset = 0x240000, + .size = 0x5b0000, + }, + { .name = "U-Boot Environment", - .offset = 0x40000, - .size = 0x60000, - }, { - .name = "Flash", - .offset = 0x60000, + .offset = 0x7f0000, .size = MTDPART_SIZ_FULL, }, }; diff --git a/trunk/arch/arm/mach-realview/Kconfig b/trunk/arch/arm/mach-realview/Kconfig index b4575ae9648e..ee5e392430e8 100644 --- a/trunk/arch/arm/mach-realview/Kconfig +++ b/trunk/arch/arm/mach-realview/Kconfig @@ -18,7 +18,6 @@ config REALVIEW_EB_ARM11MP bool "Support ARM11MPCore tile" depends on MACH_REALVIEW_EB select CPU_V6 - select ARCH_HAS_BARRIERS if SMP help Enable support for the ARM11MPCore tile on the Realview platform. @@ -36,7 +35,6 @@ config MACH_REALVIEW_PB11MP select CPU_V6 select ARM_GIC select HAVE_PATA_PLATFORM - select ARCH_HAS_BARRIERS if SMP help Include support for the ARM(R) RealView MPCore Platform Baseboard. PB11MPCore is a platform with an on-board ARM11MPCore and has diff --git a/trunk/arch/arm/mach-realview/include/mach/barriers.h b/trunk/arch/arm/mach-realview/include/mach/barriers.h deleted file mode 100644 index 0c5d749d7b5f..000000000000 --- a/trunk/arch/arm/mach-realview/include/mach/barriers.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Barriers redefined for RealView ARM11MPCore platforms with L220 cache - * controller to work around hardware errata causing the outer_sync() - * operation to deadlock the system. - */ -#define mb() dsb() -#define rmb() dmb() -#define wmb() mb() diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index 4425018fab82..422ccd70d5f5 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -458,7 +457,7 @@ static void __init realview_eb_init(void) MACHINE_START(REALVIEW_EB, "ARM-RealView EB") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .phys_io = REALVIEW_EB_UART0_BASE & SECTION_MASK, + .phys_io = REALVIEW_EB_UART0_BASE, .io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x00000100, .fixup = realview_fixup, diff --git a/trunk/arch/arm/mach-realview/realview_pb1176.c b/trunk/arch/arm/mach-realview/realview_pb1176.c index 099a1f125cf8..96568ebfa2bb 100644 --- a/trunk/arch/arm/mach-realview/realview_pb1176.c +++ b/trunk/arch/arm/mach-realview/realview_pb1176.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -352,7 +351,7 @@ static void __init realview_pb1176_init(void) MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .phys_io = REALVIEW_PB1176_UART0_BASE & SECTION_MASK, + .phys_io = REALVIEW_PB1176_UART0_BASE, .io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x00000100, .fixup = realview_pb1176_fixup, diff --git a/trunk/arch/arm/mach-realview/realview_pb11mp.c b/trunk/arch/arm/mach-realview/realview_pb11mp.c index 0e07a5ccb75f..7fbefbbebaf0 100644 --- a/trunk/arch/arm/mach-realview/realview_pb11mp.c +++ b/trunk/arch/arm/mach-realview/realview_pb11mp.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -374,7 +373,7 @@ static void __init realview_pb11mp_init(void) MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .phys_io = REALVIEW_PB11MP_UART0_BASE & SECTION_MASK, + .phys_io = REALVIEW_PB11MP_UART0_BASE, .io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x00000100, .fixup = realview_fixup, diff --git a/trunk/arch/arm/mach-realview/realview_pba8.c b/trunk/arch/arm/mach-realview/realview_pba8.c index ac2f06f1ca50..d3c113b3dfce 100644 --- a/trunk/arch/arm/mach-realview/realview_pba8.c +++ b/trunk/arch/arm/mach-realview/realview_pba8.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -324,7 +323,7 @@ static void __init realview_pba8_init(void) MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .phys_io = REALVIEW_PBA8_UART0_BASE & SECTION_MASK, + .phys_io = REALVIEW_PBA8_UART0_BASE, .io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x00000100, .fixup = realview_fixup, diff --git a/trunk/arch/arm/mach-realview/realview_pbx.c b/trunk/arch/arm/mach-realview/realview_pbx.c index 08fd683adc4c..a235ba30996b 100644 --- a/trunk/arch/arm/mach-realview/realview_pbx.c +++ b/trunk/arch/arm/mach-realview/realview_pbx.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -410,7 +409,7 @@ static void __init realview_pbx_init(void) MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .phys_io = REALVIEW_PBX_UART0_BASE & SECTION_MASK, + .phys_io = REALVIEW_PBX_UART0_BASE, .io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x00000100, .fixup = realview_pbx_fixup, diff --git a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c index 6353459bb567..9b11eedba65f 100644 --- a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -237,7 +236,7 @@ static void ct_ca9x4_init(void) } MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") - .phys_io = V2M_UART0 & SECTION_MASK, + .phys_io = V2M_UART0, .io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x00000100, .map_io = ct_ca9x4_map_io, diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 101105e52610..346ae14824a5 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -735,25 +735,6 @@ config NEEDS_SYSCALL_FOR_CMPXCHG Forget about fast user space cmpxchg support. It is just not possible. -config DMA_CACHE_RWFO - bool "Enable read/write for ownership DMA cache maintenance" - depends on CPU_V6 && SMP - default y - help - The Snoop Control Unit on ARM11MPCore does not detect the - cache maintenance operations and the dma_{map,unmap}_area() - functions may leave stale cache entries on other CPUs. By - enabling this option, Read or Write For Ownership in the ARMv6 - DMA cache maintenance functions is performed. These LDR/STR - instructions change the cache line state to shared or modified - so that the cache operation has the desired effect. - - Note that the workaround is only valid on processors that do - not perform speculative loads into the D-cache. For such - processors, if cache maintenance operations are not broadcast - in hardware, other workarounds are needed (e.g. cache - maintenance broadcasting in software via FIQ). - config OUTER_CACHE bool @@ -813,8 +794,6 @@ config ARM_L1_CACHE_SHIFT config ARM_DMA_MEM_BUFFERABLE bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7 - depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \ - MACH_REALVIEW_PB11MP) default y if CPU_V6 || CPU_V7 help Historically, the kernel has used strongly ordered mappings to diff --git a/trunk/arch/arm/mm/cache-v6.S b/trunk/arch/arm/mm/cache-v6.S index 86aa689ef1aa..e46ecd847138 100644 --- a/trunk/arch/arm/mm/cache-v6.S +++ b/trunk/arch/arm/mm/cache-v6.S @@ -211,9 +211,8 @@ v6_dma_inv_range: mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line #endif 1: -#ifdef CONFIG_DMA_CACHE_RWFO - ldr r2, [r0] @ read for ownership - str r2, [r0] @ write for ownership +#ifdef CONFIG_SMP + str r0, [r0] @ write for ownership #endif #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c6, 1 @ invalidate D line @@ -235,7 +234,7 @@ v6_dma_inv_range: v6_dma_clean_range: bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: -#ifdef CONFIG_DMA_CACHE_RWFO +#ifdef CONFIG_SMP ldr r2, [r0] @ read for ownership #endif #ifdef HARVARD_CACHE @@ -258,7 +257,7 @@ v6_dma_clean_range: ENTRY(v6_dma_flush_range) bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: -#ifdef CONFIG_DMA_CACHE_RWFO +#ifdef CONFIG_SMP ldr r2, [r0] @ read for ownership str r2, [r0] @ write for ownership #endif @@ -284,13 +283,9 @@ ENTRY(v6_dma_map_area) add r1, r1, r0 teq r2, #DMA_FROM_DEVICE beq v6_dma_inv_range -#ifndef CONFIG_DMA_CACHE_RWFO - b v6_dma_clean_range -#else teq r2, #DMA_TO_DEVICE beq v6_dma_clean_range b v6_dma_flush_range -#endif ENDPROC(v6_dma_map_area) /* @@ -300,11 +295,6 @@ ENDPROC(v6_dma_map_area) * - dir - DMA direction */ ENTRY(v6_dma_unmap_area) -#ifndef CONFIG_DMA_CACHE_RWFO - add r1, r1, r0 - teq r2, #DMA_TO_DEVICE - bne v6_dma_inv_range -#endif mov pc, lr ENDPROC(v6_dma_unmap_area) diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index 9e7742f0a102..13fa536d82e6 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -24,6 +24,15 @@ #include #include +/* Sanity check size */ +#if (CONSISTENT_DMA_SIZE % SZ_2M) +#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB" +#endif + +#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) +#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) +#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) + static u64 get_coherent_dma_mask(struct device *dev) { u64 mask = ISA_DMA_THRESHOLD; @@ -114,15 +123,6 @@ static void __dma_free_buffer(struct page *page, size_t size) } #ifdef CONFIG_MMU -/* Sanity check size */ -#if (CONSISTENT_DMA_SIZE % SZ_2M) -#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB" -#endif - -#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) -#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) -#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) - /* * These are the page tables (2MB each) covering uncached, DMA consistent allocations */ diff --git a/trunk/arch/arm/plat-omap/dmtimer.c b/trunk/arch/arm/plat-omap/dmtimer.c index 44bafdab2dce..c64875f11fac 100644 --- a/trunk/arch/arm/plat-omap/dmtimer.c +++ b/trunk/arch/arm/plat-omap/dmtimer.c @@ -541,11 +541,11 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer) * timer is stopped */ udelay(3500000 / clk_get_rate(timer->fclk) + 1); + /* Ack possibly pending interrupt */ + omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, + OMAP_TIMER_INT_OVERFLOW); #endif } - /* Ack possibly pending interrupt */ - omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, - OMAP_TIMER_INT_OVERFLOW); } EXPORT_SYMBOL_GPL(omap_dm_timer_stop); diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 9b7e3545f325..393e9219a5b6 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -673,7 +673,6 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, if (cpu_is_omap34xx() || cpu_is_omap44xx()) clk_disable(bank->dbck); } - bank->dbck_enable_mask = val; __raw_writel(val, reg); } diff --git a/trunk/arch/arm/plat-omap/iovmm.c b/trunk/arch/arm/plat-omap/iovmm.c index 8ce0de247c71..e43983ba59c5 100644 --- a/trunk/arch/arm/plat-omap/iovmm.c +++ b/trunk/arch/arm/plat-omap/iovmm.c @@ -140,10 +140,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) return ERR_PTR(-ENOMEM); err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL); - if (err) { - kfree(sgt); + if (err) return ERR_PTR(err); - } pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries); diff --git a/trunk/arch/arm/plat-pxa/Makefile b/trunk/arch/arm/plat-pxa/Makefile index a17cc0c6a6b0..6187edfbcb77 100644 --- a/trunk/arch/arm/plat-pxa/Makefile +++ b/trunk/arch/arm/plat-pxa/Makefile @@ -2,9 +2,8 @@ # Makefile for code common across different PXA processor families # -obj-y := dma.o +obj-y := dma.o pmu.o -obj-$(CONFIG_ARCH_PXA) += pmu.o obj-$(CONFIG_GENERIC_GPIO) += gpio.o obj-$(CONFIG_PXA3xx) += mfp.o obj-$(CONFIG_ARCH_MMP) += mfp.o diff --git a/trunk/arch/ia64/mm/tlb.c b/trunk/arch/ia64/mm/tlb.c index 7b3cdc6c6d91..5dfd916e9ea6 100644 --- a/trunk/arch/ia64/mm/tlb.c +++ b/trunk/arch/ia64/mm/tlb.c @@ -121,7 +121,7 @@ static inline void down_spin(struct spinaphore *ss) ia64_invala(); for (;;) { - asm volatile ("ld8.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); + asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); if (time_before(t, serve)) return; cpu_relax(); diff --git a/trunk/arch/um/os-Linux/mem.c b/trunk/arch/um/os-Linux/mem.c index e696144d2be3..93a11d7edfa0 100644 --- a/trunk/arch/um/os-Linux/mem.c +++ b/trunk/arch/um/os-Linux/mem.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include "init.h" diff --git a/trunk/arch/x86/include/asm/perf_event_p4.h b/trunk/arch/x86/include/asm/perf_event_p4.h index def500776b16..64a8ebff06fc 100644 --- a/trunk/arch/x86/include/asm/perf_event_p4.h +++ b/trunk/arch/x86/include/asm/perf_event_p4.h @@ -19,6 +19,7 @@ #define ARCH_P4_RESERVED_ESCR (2) /* IQ_ESCR(0,1) not always present */ #define ARCH_P4_MAX_ESCR (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR) #define ARCH_P4_MAX_CCCR (18) +#define ARCH_P4_MAX_COUNTER (ARCH_P4_MAX_CCCR / 2) #define P4_ESCR_EVENT_MASK 0x7e000000U #define P4_ESCR_EVENT_SHIFT 25 @@ -70,6 +71,10 @@ #define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) #define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT) +/* Custom bits in reerved CCCR area */ +#define P4_CCCR_CACHE_OPS_MASK 0x0000003fU + + /* Non HT mask */ #define P4_CCCR_MASK \ (P4_CCCR_OVF | \ @@ -101,7 +106,8 @@ * ESCR and CCCR but rather an only packed value should * be unpacked and written to a proper addresses * - * the base idea is to pack as much info as possible + * the base idea is to pack as much info as + * possible */ #define p4_config_pack_escr(v) (((u64)(v)) << 32) #define p4_config_pack_cccr(v) (((u64)(v)) & 0xffffffffULL) @@ -124,6 +130,8 @@ t; \ }) +#define p4_config_unpack_cache_event(v) (((u64)(v)) & P4_CCCR_CACHE_OPS_MASK) + #define P4_CONFIG_HT_SHIFT 63 #define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT) @@ -206,12 +214,6 @@ static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr) return escr; } -/* - * This are the events which should be used in "Event Select" - * field of ESCR register, they are like unique keys which allow - * the kernel to determinate which CCCR and COUNTER should be - * used to track an event - */ enum P4_EVENTS { P4_EVENT_TC_DELIVER_MODE, P4_EVENT_BPU_FETCH_REQUEST, @@ -559,7 +561,7 @@ enum P4_EVENT_OPCODES { * a caller should use P4_ESCR_EMASK_NAME helper to * pick the EventMask needed, for example * - * P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD) + * P4_ESCR_EMASK_NAME(P4_EVENT_TC_DELIVER_MODE, DD) */ enum P4_ESCR_EMASKS { P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DD, 0), @@ -751,50 +753,43 @@ enum P4_ESCR_EMASKS { P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, BOGUS, 1), }; -/* - * P4 PEBS specifics (Replay Event only) - * - * Format (bits): - * 0-6: metric from P4_PEBS_METRIC enum - * 7 : reserved - * 8 : reserved - * 9-11 : reserved - * - * Note we have UOP and PEBS bits reserved for now - * just in case if we will need them once - */ -#define P4_PEBS_CONFIG_ENABLE (1 << 7) -#define P4_PEBS_CONFIG_UOP_TAG (1 << 8) -#define P4_PEBS_CONFIG_METRIC_MASK 0x3f -#define P4_PEBS_CONFIG_MASK 0xff - -/* - * mem: Only counters MSR_IQ_COUNTER4 (16) and - * MSR_IQ_COUNTER5 (17) are allowed for PEBS sampling - */ -#define P4_PEBS_ENABLE 0x02000000U -#define P4_PEBS_ENABLE_UOP_TAG 0x01000000U - -#define p4_config_unpack_metric(v) (((u64)(v)) & P4_PEBS_CONFIG_METRIC_MASK) -#define p4_config_unpack_pebs(v) (((u64)(v)) & P4_PEBS_CONFIG_MASK) - -#define p4_config_pebs_has(v, mask) (p4_config_unpack_pebs(v) & (mask)) - -enum P4_PEBS_METRIC { - P4_PEBS_METRIC__none, - - P4_PEBS_METRIC__1stl_cache_load_miss_retired, - P4_PEBS_METRIC__2ndl_cache_load_miss_retired, - P4_PEBS_METRIC__dtlb_load_miss_retired, - P4_PEBS_METRIC__dtlb_store_miss_retired, - P4_PEBS_METRIC__dtlb_all_miss_retired, - P4_PEBS_METRIC__tagged_mispred_branch, - P4_PEBS_METRIC__mob_load_replay_retired, - P4_PEBS_METRIC__split_load_retired, - P4_PEBS_METRIC__split_store_retired, - - P4_PEBS_METRIC__max +/* P4 PEBS: stale for a while */ +#define P4_PEBS_METRIC_MASK 0x00001fffU +#define P4_PEBS_UOB_TAG 0x01000000U +#define P4_PEBS_ENABLE 0x02000000U + +/* Replay metrics for MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT */ +#define P4_PEBS__1stl_cache_load_miss_retired 0x3000001 +#define P4_PEBS__2ndl_cache_load_miss_retired 0x3000002 +#define P4_PEBS__dtlb_load_miss_retired 0x3000004 +#define P4_PEBS__dtlb_store_miss_retired 0x3000004 +#define P4_PEBS__dtlb_all_miss_retired 0x3000004 +#define P4_PEBS__tagged_mispred_branch 0x3018000 +#define P4_PEBS__mob_load_replay_retired 0x3000200 +#define P4_PEBS__split_load_retired 0x3000400 +#define P4_PEBS__split_store_retired 0x3000400 + +#define P4_VERT__1stl_cache_load_miss_retired 0x0000001 +#define P4_VERT__2ndl_cache_load_miss_retired 0x0000001 +#define P4_VERT__dtlb_load_miss_retired 0x0000001 +#define P4_VERT__dtlb_store_miss_retired 0x0000002 +#define P4_VERT__dtlb_all_miss_retired 0x0000003 +#define P4_VERT__tagged_mispred_branch 0x0000010 +#define P4_VERT__mob_load_replay_retired 0x0000001 +#define P4_VERT__split_load_retired 0x0000001 +#define P4_VERT__split_store_retired 0x0000002 + +enum P4_CACHE_EVENTS { + P4_CACHE__NONE, + + P4_CACHE__1stl_cache_load_miss_retired, + P4_CACHE__2ndl_cache_load_miss_retired, + P4_CACHE__dtlb_load_miss_retired, + P4_CACHE__dtlb_store_miss_retired, + P4_CACHE__itlb_reference_hit, + P4_CACHE__itlb_reference_miss, + + P4_CACHE__MAX }; #endif /* PERF_EVENT_P4_H */ - diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd.c b/trunk/arch/x86/kernel/cpu/perf_event_amd.c index c2897b7b4a3b..611df11ba15e 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_amd.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_amd.c @@ -102,8 +102,8 @@ static const u64 amd_perfmon_event_map[] = [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080, [PERF_COUNT_HW_CACHE_MISSES] = 0x0081, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, - [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, }; static u64 amd_pmu_event_map(int hw_event) diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p4.c b/trunk/arch/x86/kernel/cpu/perf_event_p4.c index 107711bf0ee8..9286e736a70a 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p4.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p4.c @@ -21,36 +21,22 @@ struct p4_event_bind { char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */ }; -struct p4_pebs_bind { +struct p4_cache_event_bind { unsigned int metric_pebs; unsigned int metric_vert; }; -/* it sets P4_PEBS_ENABLE_UOP_TAG as well */ -#define P4_GEN_PEBS_BIND(name, pebs, vert) \ - [P4_PEBS_METRIC__##name] = { \ - .metric_pebs = pebs | P4_PEBS_ENABLE_UOP_TAG, \ - .metric_vert = vert, \ +#define P4_GEN_CACHE_EVENT_BIND(name) \ + [P4_CACHE__##name] = { \ + .metric_pebs = P4_PEBS__##name, \ + .metric_vert = P4_VERT__##name, \ } -/* - * note we have P4_PEBS_ENABLE_UOP_TAG always set here - * - * it's needed for mapping P4_PEBS_CONFIG_METRIC_MASK bits of - * event configuration to find out which values are to be - * written into MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT - * resgisters - */ -static struct p4_pebs_bind p4_pebs_bind_map[] = { - P4_GEN_PEBS_BIND(1stl_cache_load_miss_retired, 0x0000001, 0x0000001), - P4_GEN_PEBS_BIND(2ndl_cache_load_miss_retired, 0x0000002, 0x0000001), - P4_GEN_PEBS_BIND(dtlb_load_miss_retired, 0x0000004, 0x0000001), - P4_GEN_PEBS_BIND(dtlb_store_miss_retired, 0x0000004, 0x0000002), - P4_GEN_PEBS_BIND(dtlb_all_miss_retired, 0x0000004, 0x0000003), - P4_GEN_PEBS_BIND(tagged_mispred_branch, 0x0018000, 0x0000010), - P4_GEN_PEBS_BIND(mob_load_replay_retired, 0x0000200, 0x0000001), - P4_GEN_PEBS_BIND(split_load_retired, 0x0000400, 0x0000001), - P4_GEN_PEBS_BIND(split_store_retired, 0x0000400, 0x0000002), +static struct p4_cache_event_bind p4_cache_event_bind_map[] = { + P4_GEN_CACHE_EVENT_BIND(1stl_cache_load_miss_retired), + P4_GEN_CACHE_EVENT_BIND(2ndl_cache_load_miss_retired), + P4_GEN_CACHE_EVENT_BIND(dtlb_load_miss_retired), + P4_GEN_CACHE_EVENT_BIND(dtlb_store_miss_retired), }; /* @@ -295,10 +281,10 @@ static struct p4_event_bind p4_event_bind_map[] = { }, }; -#define P4_GEN_CACHE_EVENT(event, bit, metric) \ +#define P4_GEN_CACHE_EVENT(event, bit, cache_event) \ p4_config_pack_escr(P4_ESCR_EVENT(event) | \ P4_ESCR_EMASK_BIT(event, bit)) | \ - p4_config_pack_cccr(metric | \ + p4_config_pack_cccr(cache_event | \ P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event)))) static __initconst const u64 p4_hw_cache_event_ids @@ -310,34 +296,34 @@ static __initconst const u64 p4_hw_cache_event_ids [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0, [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, - P4_PEBS_METRIC__1stl_cache_load_miss_retired), + P4_CACHE__1stl_cache_load_miss_retired), }, }, [ C(LL ) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0, [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, - P4_PEBS_METRIC__2ndl_cache_load_miss_retired), + P4_CACHE__2ndl_cache_load_miss_retired), }, }, [ C(DTLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = 0x0, [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, - P4_PEBS_METRIC__dtlb_load_miss_retired), + P4_CACHE__dtlb_load_miss_retired), }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = 0x0, [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS, - P4_PEBS_METRIC__dtlb_store_miss_retired), + P4_CACHE__dtlb_store_miss_retired), }, }, [ C(ITLB) ] = { [ C(OP_READ) ] = { [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT, - P4_PEBS_METRIC__none), + P4_CACHE__itlb_reference_hit), [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS, - P4_PEBS_METRIC__none), + P4_CACHE__itlb_reference_miss), }, [ C(OP_WRITE) ] = { [ C(RESULT_ACCESS) ] = -1, @@ -428,37 +414,11 @@ static u64 p4_pmu_event_map(int hw_event) return config; } -static int p4_validate_raw_event(struct perf_event *event) -{ - unsigned int v; - - /* user data may have out-of-bound event index */ - v = p4_config_unpack_event(event->attr.config); - if (v >= ARRAY_SIZE(p4_event_bind_map)) { - pr_warning("P4 PMU: Unknown event code: %d\n", v); - return -EINVAL; - } - - /* - * it may have some screwed PEBS bits - */ - if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE)) { - pr_warning("P4 PMU: PEBS are not supported yet\n"); - return -EINVAL; - } - v = p4_config_unpack_metric(event->attr.config); - if (v >= ARRAY_SIZE(p4_pebs_bind_map)) { - pr_warning("P4 PMU: Unknown metric code: %d\n", v); - return -EINVAL; - } - - return 0; -} - static int p4_hw_config(struct perf_event *event) { int cpu = get_cpu(); int rc = 0; + unsigned int evnt; u32 escr, cccr; /* @@ -478,9 +438,12 @@ static int p4_hw_config(struct perf_event *event) if (event->attr.type == PERF_TYPE_RAW) { - rc = p4_validate_raw_event(event); - if (rc) + /* user data may have out-of-bound event index */ + evnt = p4_config_unpack_event(event->attr.config); + if (evnt >= ARRAY_SIZE(p4_event_bind_map)) { + rc = -EINVAL; goto out; + } /* * We don't control raw events so it's up to the caller @@ -488,15 +451,12 @@ static int p4_hw_config(struct perf_event *event) * on HT machine but allow HT-compatible specifics to be * passed on) * - * Note that for RAW events we allow user to use P4_CCCR_RESERVED - * bits since we keep additional info here (for cache events and etc) - * * XXX: HT wide things should check perf_paranoid_cpu() && * CAP_SYS_ADMIN */ event->hw.config |= event->attr.config & (p4_config_pack_escr(P4_ESCR_MASK_HT) | - p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED)); + p4_config_pack_cccr(P4_CCCR_MASK_HT)); } rc = x86_setup_perfctr(event); @@ -522,29 +482,6 @@ static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) return overflow; } -static void p4_pmu_disable_pebs(void) -{ - /* - * FIXME - * - * It's still allowed that two threads setup same cache - * events so we can't simply clear metrics until we knew - * noone is depending on us, so we need kind of counter - * for "ReplayEvent" users. - * - * What is more complex -- RAW events, if user (for some - * reason) will pass some cache event metric with improper - * event opcode -- it's fine from hardware point of view - * but completely nonsence from "meaning" of such action. - * - * So at moment let leave metrics turned on forever -- it's - * ok for now but need to be revisited! - * - * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0); - * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0); - */ -} - static inline void p4_pmu_disable_event(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; @@ -570,26 +507,6 @@ static void p4_pmu_disable_all(void) continue; p4_pmu_disable_event(event); } - - p4_pmu_disable_pebs(); -} - -/* configuration must be valid */ -static void p4_pmu_enable_pebs(u64 config) -{ - struct p4_pebs_bind *bind; - unsigned int idx; - - BUILD_BUG_ON(P4_PEBS_METRIC__max > P4_PEBS_CONFIG_METRIC_MASK); - - idx = p4_config_unpack_metric(config); - if (idx == P4_PEBS_METRIC__none) - return; - - bind = &p4_pebs_bind_map[idx]; - - (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); - (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); } static void p4_pmu_enable_event(struct perf_event *event) @@ -598,7 +515,9 @@ static void p4_pmu_enable_event(struct perf_event *event) int thread = p4_ht_config_thread(hwc->config); u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config)); unsigned int idx = p4_config_unpack_event(hwc->config); + unsigned int idx_cache = p4_config_unpack_cache_event(hwc->config); struct p4_event_bind *bind; + struct p4_cache_event_bind *bind_cache; u64 escr_addr, cccr; bind = &p4_event_bind_map[idx]; @@ -618,10 +537,16 @@ static void p4_pmu_enable_event(struct perf_event *event) cccr = p4_config_unpack_cccr(hwc->config); /* - * it could be Cache event so we need to write metrics - * into additional MSRs + * it could be Cache event so that we need to + * set metrics into additional MSRs */ - p4_pmu_enable_pebs(hwc->config); + BUILD_BUG_ON(P4_CACHE__MAX > P4_CCCR_CACHE_OPS_MASK); + if (idx_cache > P4_CACHE__NONE && + idx_cache < ARRAY_SIZE(p4_cache_event_bind_map)) { + bind_cache = &p4_cache_event_bind_map[idx_cache]; + (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind_cache->metric_pebs); + (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind_cache->metric_vert); + } (void)checking_wrmsrl(escr_addr, escr_conf); (void)checking_wrmsrl(hwc->config_base + hwc->idx, diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index 725ef4d17cd5..142d70c74b02 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -526,7 +526,6 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) { struct task_struct *tsk = current; - int user_icebp = 0; unsigned long dr6; int si_code; @@ -535,14 +534,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) /* Filter out all the reserved bits which are preset to 1 */ dr6 &= ~DR6_RESERVED; - /* - * If dr6 has no reason to give us about the origin of this trap, - * then it's very likely the result of an icebp/int01 trap. - * User wants a sigtrap for that. - */ - if (!dr6 && user_mode(regs)) - user_icebp = 1; - /* Catch kmemcheck conditions first of all! */ if ((dr6 & DR_STEP) && kmemcheck_trap(regs)) return; @@ -584,7 +575,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) regs->flags &= ~X86_EFLAGS_TF; } si_code = get_si_code(tsk->thread.debugreg6); - if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) + if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS)) send_sigtrap(tsk, regs, error_code, si_code); preempt_conditional_cli(regs); diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index f0640d7f800f..f84cce42fc58 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -1149,10 +1149,13 @@ void init_request_from_bio(struct request *req, struct bio *bio) else req->cmd_flags |= bio->bi_rw & REQ_FAILFAST_MASK; - if (bio_rw_flagged(bio, BIO_RW_DISCARD)) + if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) { req->cmd_flags |= REQ_DISCARD; - if (bio_rw_flagged(bio, BIO_RW_BARRIER)) + if (bio_rw_flagged(bio, BIO_RW_BARRIER)) + req->cmd_flags |= REQ_SOFTBARRIER; + } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) req->cmd_flags |= REQ_HARDBARRIER; + if (bio_rw_flagged(bio, BIO_RW_SYNCIO)) req->cmd_flags |= REQ_RW_SYNC; if (bio_rw_flagged(bio, BIO_RW_META)) @@ -1583,7 +1586,7 @@ void submit_bio(int rw, struct bio *bio) * If it's a regular read/write or a barrier with data attached, * go through the normal accounting stuff before submission. */ - if (bio_has_data(bio) && !(rw & (1 << BIO_RW_DISCARD))) { + if (bio_has_data(bio)) { if (rw & WRITE) { count_vm_events(PGPGOUT, count); } else { diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 7982b830db58..5ff4f4850e71 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -14,7 +14,7 @@ #include #include #include -#include "cfq.h" +#include "blk-cgroup.h" /* * tunables @@ -879,7 +879,7 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg) if (!RB_EMPTY_NODE(&cfqg->rb_node)) cfq_rb_erase(&cfqg->rb_node, st); cfqg->saved_workload_slice = 0; - cfq_blkiocg_update_dequeue_stats(&cfqg->blkg, 1); + blkiocg_update_dequeue_stats(&cfqg->blkg, 1); } static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq) @@ -939,8 +939,8 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg, cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime, st->min_vdisktime); - cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl); - cfq_blkiocg_set_start_empty_time(&cfqg->blkg); + blkiocg_update_timeslice_used(&cfqg->blkg, used_sl); + blkiocg_set_start_empty_time(&cfqg->blkg); } #ifdef CONFIG_CFQ_GROUP_IOSCHED @@ -995,7 +995,7 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) /* Add group onto cgroup list */ sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); - cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, + blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, MKDEV(major, minor)); cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev); @@ -1079,7 +1079,7 @@ static void cfq_release_cfq_groups(struct cfq_data *cfqd) * it from cgroup list, then it will take care of destroying * cfqg also. */ - if (!cfq_blkiocg_del_blkio_group(&cfqg->blkg)) + if (!blkiocg_del_blkio_group(&cfqg->blkg)) cfq_destroy_cfqg(cfqd, cfqg); } } @@ -1421,10 +1421,10 @@ static void cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq) { elv_rb_del(&cfqq->sort_list, rq); cfqq->queued[rq_is_sync(rq)]--; - cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, - rq_data_dir(rq), rq_is_sync(rq)); + blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(rq), + rq_is_sync(rq)); cfq_add_rq_rb(rq); - cfq_blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg, + blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg, &cfqq->cfqd->serving_group->blkg, rq_data_dir(rq), rq_is_sync(rq)); } @@ -1482,8 +1482,8 @@ static void cfq_remove_request(struct request *rq) cfq_del_rq_rb(rq); cfqq->cfqd->rq_queued--; - cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, - rq_data_dir(rq), rq_is_sync(rq)); + blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(rq), + rq_is_sync(rq)); if (rq_is_meta(rq)) { WARN_ON(!cfqq->meta_pending); cfqq->meta_pending--; @@ -1518,8 +1518,8 @@ static void cfq_merged_request(struct request_queue *q, struct request *req, static void cfq_bio_merged(struct request_queue *q, struct request *req, struct bio *bio) { - cfq_blkiocg_update_io_merged_stats(&(RQ_CFQG(req))->blkg, - bio_data_dir(bio), cfq_bio_sync(bio)); + blkiocg_update_io_merged_stats(&(RQ_CFQG(req))->blkg, bio_data_dir(bio), + cfq_bio_sync(bio)); } static void @@ -1539,8 +1539,8 @@ cfq_merged_requests(struct request_queue *q, struct request *rq, if (cfqq->next_rq == next) cfqq->next_rq = rq; cfq_remove_request(next); - cfq_blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg, - rq_data_dir(next), rq_is_sync(next)); + blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(next), + rq_is_sync(next)); } static int cfq_allow_merge(struct request_queue *q, struct request *rq, @@ -1571,7 +1571,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, static inline void cfq_del_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) { del_timer(&cfqd->idle_slice_timer); - cfq_blkiocg_update_idle_time_stats(&cfqq->cfqg->blkg); + blkiocg_update_idle_time_stats(&cfqq->cfqg->blkg); } static void __cfq_set_active_queue(struct cfq_data *cfqd, @@ -1580,7 +1580,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, if (cfqq) { cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d", cfqd->serving_prio, cfqd->serving_type); - cfq_blkiocg_update_avg_queue_size_stats(&cfqq->cfqg->blkg); + blkiocg_update_avg_queue_size_stats(&cfqq->cfqg->blkg); cfqq->slice_start = 0; cfqq->dispatch_start = jiffies; cfqq->allocated_slice = 0; @@ -1911,7 +1911,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) sl = cfqd->cfq_slice_idle; mod_timer(&cfqd->idle_slice_timer, jiffies + sl); - cfq_blkiocg_update_set_idle_time_stats(&cfqq->cfqg->blkg); + blkiocg_update_set_idle_time_stats(&cfqq->cfqg->blkg); cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu", sl); } @@ -1931,7 +1931,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq) elv_dispatch_sort(q, rq); cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++; - cfq_blkiocg_update_dispatch_stats(&cfqq->cfqg->blkg, blk_rq_bytes(rq), + blkiocg_update_dispatch_stats(&cfqq->cfqg->blkg, blk_rq_bytes(rq), rq_data_dir(rq), rq_is_sync(rq)); } @@ -1986,15 +1986,6 @@ static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq) int process_refs, new_process_refs; struct cfq_queue *__cfqq; - /* - * If there are no process references on the new_cfqq, then it is - * unsafe to follow the ->new_cfqq chain as other cfqq's in the - * chain may have dropped their last reference (not just their - * last process reference). - */ - if (!cfqq_process_refs(new_cfqq)) - return; - /* Avoid a circular list and skip interim queue merges */ while ((__cfqq = new_cfqq->new_cfqq)) { if (__cfqq == cfqq) @@ -2003,17 +1994,17 @@ static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq) } process_refs = cfqq_process_refs(cfqq); - new_process_refs = cfqq_process_refs(new_cfqq); /* * If the process for the cfqq has gone away, there is no * sense in merging the queues. */ - if (process_refs == 0 || new_process_refs == 0) + if (process_refs == 0) return; /* * Merge in the direction of the lesser amount of work. */ + new_process_refs = cfqq_process_refs(new_cfqq); if (new_process_refs >= process_refs) { cfqq->new_cfqq = new_cfqq; atomic_add(process_refs, &new_cfqq->ref); @@ -3257,7 +3248,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfq_clear_cfqq_wait_request(cfqq); __blk_run_queue(cfqd->queue); } else { - cfq_blkiocg_update_idle_time_stats( + blkiocg_update_idle_time_stats( &cfqq->cfqg->blkg); cfq_mark_cfqq_must_dispatch(cfqq); } @@ -3285,7 +3276,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq) rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]); list_add_tail(&rq->queuelist, &cfqq->fifo); cfq_add_rq_rb(rq); - cfq_blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg, + blkiocg_update_io_add_stats(&(RQ_CFQG(rq))->blkg, &cfqd->serving_group->blkg, rq_data_dir(rq), rq_is_sync(rq)); cfq_rq_enqueued(cfqd, cfqq, rq); @@ -3373,9 +3364,9 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) WARN_ON(!cfqq->dispatched); cfqd->rq_in_driver--; cfqq->dispatched--; - cfq_blkiocg_update_completion_stats(&cfqq->cfqg->blkg, - rq_start_time_ns(rq), rq_io_start_time_ns(rq), - rq_data_dir(rq), rq_is_sync(rq)); + blkiocg_update_completion_stats(&cfqq->cfqg->blkg, rq_start_time_ns(rq), + rq_io_start_time_ns(rq), rq_data_dir(rq), + rq_is_sync(rq)); cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--; @@ -3739,7 +3730,7 @@ static void cfq_exit_queue(struct elevator_queue *e) cfq_put_async_queues(cfqd); cfq_release_cfq_groups(cfqd); - cfq_blkiocg_del_blkio_group(&cfqd->root_group.blkg); + blkiocg_del_blkio_group(&cfqd->root_group.blkg); spin_unlock_irq(q->queue_lock); @@ -3807,8 +3798,8 @@ static void *cfq_init_queue(struct request_queue *q) */ atomic_set(&cfqg->ref, 1); rcu_read_lock(); - cfq_blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, - (void *)cfqd, 0); + blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, (void *)cfqd, + 0); rcu_read_unlock(); #endif /* diff --git a/trunk/block/cfq.h b/trunk/block/cfq.h deleted file mode 100644 index 93448e5a2e41..000000000000 --- a/trunk/block/cfq.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef _CFQ_H -#define _CFQ_H -#include "blk-cgroup.h" - -#ifdef CONFIG_CFQ_GROUP_IOSCHED -static inline void cfq_blkiocg_update_io_add_stats(struct blkio_group *blkg, - struct blkio_group *curr_blkg, bool direction, bool sync) -{ - blkiocg_update_io_add_stats(blkg, curr_blkg, direction, sync); -} - -static inline void cfq_blkiocg_update_dequeue_stats(struct blkio_group *blkg, - unsigned long dequeue) -{ - blkiocg_update_dequeue_stats(blkg, dequeue); -} - -static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg, - unsigned long time) -{ - blkiocg_update_timeslice_used(blkg, time); -} - -static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg) -{ - blkiocg_set_start_empty_time(blkg); -} - -static inline void cfq_blkiocg_update_io_remove_stats(struct blkio_group *blkg, - bool direction, bool sync) -{ - blkiocg_update_io_remove_stats(blkg, direction, sync); -} - -static inline void cfq_blkiocg_update_io_merged_stats(struct blkio_group *blkg, - bool direction, bool sync) -{ - blkiocg_update_io_merged_stats(blkg, direction, sync); -} - -static inline void cfq_blkiocg_update_idle_time_stats(struct blkio_group *blkg) -{ - blkiocg_update_idle_time_stats(blkg); -} - -static inline void -cfq_blkiocg_update_avg_queue_size_stats(struct blkio_group *blkg) -{ - blkiocg_update_avg_queue_size_stats(blkg); -} - -static inline void -cfq_blkiocg_update_set_idle_time_stats(struct blkio_group *blkg) -{ - blkiocg_update_set_idle_time_stats(blkg); -} - -static inline void cfq_blkiocg_update_dispatch_stats(struct blkio_group *blkg, - uint64_t bytes, bool direction, bool sync) -{ - blkiocg_update_dispatch_stats(blkg, bytes, direction, sync); -} - -static inline void cfq_blkiocg_update_completion_stats(struct blkio_group *blkg, uint64_t start_time, uint64_t io_start_time, bool direction, bool sync) -{ - blkiocg_update_completion_stats(blkg, start_time, io_start_time, - direction, sync); -} - -static inline void cfq_blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, - struct blkio_group *blkg, void *key, dev_t dev) { - blkiocg_add_blkio_group(blkcg, blkg, key, dev); -} - -static inline int cfq_blkiocg_del_blkio_group(struct blkio_group *blkg) -{ - return blkiocg_del_blkio_group(blkg); -} - -#else /* CFQ_GROUP_IOSCHED */ -static inline void cfq_blkiocg_update_io_add_stats(struct blkio_group *blkg, - struct blkio_group *curr_blkg, bool direction, bool sync) {} - -static inline void cfq_blkiocg_update_dequeue_stats(struct blkio_group *blkg, - unsigned long dequeue) {} - -static inline void cfq_blkiocg_update_timeslice_used(struct blkio_group *blkg, - unsigned long time) {} -static inline void cfq_blkiocg_set_start_empty_time(struct blkio_group *blkg) {} -static inline void cfq_blkiocg_update_io_remove_stats(struct blkio_group *blkg, - bool direction, bool sync) {} -static inline void cfq_blkiocg_update_io_merged_stats(struct blkio_group *blkg, - bool direction, bool sync) {} -static inline void cfq_blkiocg_update_idle_time_stats(struct blkio_group *blkg) -{ -} -static inline void -cfq_blkiocg_update_avg_queue_size_stats(struct blkio_group *blkg) {} - -static inline void -cfq_blkiocg_update_set_idle_time_stats(struct blkio_group *blkg) {} - -static inline void cfq_blkiocg_update_dispatch_stats(struct blkio_group *blkg, - uint64_t bytes, bool direction, bool sync) {} -static inline void cfq_blkiocg_update_completion_stats(struct blkio_group *blkg, uint64_t start_time, uint64_t io_start_time, bool direction, bool sync) {} - -static inline void cfq_blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, - struct blkio_group *blkg, void *key, dev_t dev) {} -static inline int cfq_blkiocg_del_blkio_group(struct blkio_group *blkg) -{ - return 0; -} - -#endif /* CFQ_GROUP_IOSCHED */ -#endif diff --git a/trunk/drivers/acpi/apei/erst.c b/trunk/drivers/acpi/apei/erst.c index 864dd46c346f..2ebc39115507 100644 --- a/trunk/drivers/acpi/apei/erst.c +++ b/trunk/drivers/acpi/apei/erst.c @@ -781,7 +781,7 @@ static int __init erst_init(void) status = acpi_get_table(ACPI_SIG_ERST, 0, (struct acpi_table_header **)&erst_tab); if (status == AE_NOT_FOUND) { - pr_info(ERST_PFX "Table is not found!\n"); + pr_err(ERST_PFX "Table is not found!\n"); goto err; } else if (ACPI_FAILURE(status)) { const char *msg = acpi_format_exception(status); diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index f2522534ae63..8ca16f54e1ed 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -1053,16 +1053,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable) return -ENODEV; - /* - * For some reason, MCP89 on MacBook 7,1 doesn't work with - * ahci, use ata_generic instead. - */ - if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && - pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA && - pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE && - pdev->subsystem_device == 0xcb89) - return -ENODEV; - /* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode. * At the moment, we can only use the AHCI mode. Let the users know * that for SAS drives they're out of luck. diff --git a/trunk/drivers/ata/ata_generic.c b/trunk/drivers/ata/ata_generic.c index 7107a6929deb..573158a9668d 100644 --- a/trunk/drivers/ata/ata_generic.c +++ b/trunk/drivers/ata/ata_generic.c @@ -32,11 +32,6 @@ * A generic parallel ATA driver using libata */ -enum { - ATA_GEN_CLASS_MATCH = (1 << 0), - ATA_GEN_FORCE_DMA = (1 << 1), -}; - /** * generic_set_mode - mode setting * @link: link to set up @@ -51,17 +46,13 @@ enum { static int generic_set_mode(struct ata_link *link, struct ata_device **unused) { struct ata_port *ap = link->ap; - const struct pci_device_id *id = ap->host->private_data; int dma_enabled = 0; struct ata_device *dev; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (id->driver_data & ATA_GEN_FORCE_DMA) { - dma_enabled = 0xff; - } else if (ap->ioaddr.bmdma_addr) { - /* Bits 5 and 6 indicate if DMA is active on master/slave */ + /* Bits 5 and 6 indicate if DMA is active on master/slave */ + if (ap->ioaddr.bmdma_addr) dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - } if (pdev->vendor == PCI_VENDOR_ID_CENATEK) dma_enabled = 0xFF; @@ -135,7 +126,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id const struct ata_port_info *ppi[] = { &info, NULL }; /* Don't use the generic entry unless instructed to do so */ - if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0) + if (id->driver_data == 1 && all_generic_ide == 0) return -ENODEV; /* Devices that need care */ @@ -164,7 +155,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id return rc; pcim_pin_device(dev); } - return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, (void *)id, 0); + return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, NULL, 0); } static struct pci_device_id ata_generic[] = { @@ -176,15 +167,7 @@ static struct pci_device_id ata_generic[] = { { PCI_DEVICE(PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561), }, { PCI_DEVICE(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558), }, - { PCI_DEVICE(PCI_VENDOR_ID_CENATEK,PCI_DEVICE_ID_CENATEK_IDE), - .driver_data = ATA_GEN_FORCE_DMA }, - /* - * For some reason, MCP89 on MacBook 7,1 doesn't work with - * ahci, use ata_generic instead. - */ - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA, - PCI_VENDOR_ID_APPLE, 0xcb89, - .driver_data = ATA_GEN_FORCE_DMA }, + { PCI_DEVICE(PCI_VENDOR_ID_CENATEK,PCI_DEVICE_ID_CENATEK_IDE), }, #if !defined(CONFIG_PATA_TOSHIBA) && !defined(CONFIG_PATA_TOSHIBA_MODULE) { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), }, { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, @@ -192,8 +175,7 @@ static struct pci_device_id ata_generic[] = { { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_5), }, #endif /* Must come last. If you add entries adjust this table appropriately */ - { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL), - .driver_data = ATA_GEN_CLASS_MATCH }, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1}, { 0, }, }; diff --git a/trunk/drivers/ata/libahci.c b/trunk/drivers/ata/libahci.c index 81e772a94d59..261f86d102e8 100644 --- a/trunk/drivers/ata/libahci.c +++ b/trunk/drivers/ata/libahci.c @@ -324,7 +324,6 @@ static ssize_t ahci_store_em_buffer(struct device *dev, struct ahci_host_priv *hpriv = ap->host->private_data; void __iomem *mmio = hpriv->mmio; void __iomem *em_mmio = mmio + hpriv->em_loc; - const unsigned char *msg_buf = buf; u32 em_ctl, msg; unsigned long flags; int i; @@ -344,8 +343,8 @@ static ssize_t ahci_store_em_buffer(struct device *dev, } for (i = 0; i < size; i += 4) { - msg = msg_buf[i] | msg_buf[i + 1] << 8 | - msg_buf[i + 2] << 16 | msg_buf[i + 3] << 24; + msg = buf[i] | buf[i + 1] << 8 | + buf[i + 2] << 16 | buf[i + 3] << 24; writel(msg, em_mmio + i); } diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index 72dae92f3cab..3381505c8a6c 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -861,7 +861,6 @@ cciss_scsi_detect(int ctlr) sh->n_io_port = 0; // I don't think we use these two... sh->this_id = SELF_SCSI_ID; sh->sg_tablesize = hba[ctlr]->maxsgentries; - sh->max_cmd_len = MAX_COMMAND_SIZE; ((struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr)->scsi_host = sh; diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index abb4ec6690fc..91d11631cec9 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -386,7 +386,7 @@ static void __devexit cpqarray_remove_one_eisa (int i) } /* pdev is NULL for eisa */ -static int __devinit cpqarray_register_ctlr( int i, struct pci_dev *pdev) +static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) { struct request_queue *q; int j; @@ -503,7 +503,7 @@ static int __devinit cpqarray_register_ctlr( int i, struct pci_dev *pdev) return -1; } -static int __devinit cpqarray_init_one( struct pci_dev *pdev, +static int __init cpqarray_init_one( struct pci_dev *pdev, const struct pci_device_id *ent) { int i; @@ -740,7 +740,7 @@ __setup("smart2=", cpqarray_setup); /* * Find an EISA controller's signature. Set up an hba if we find it. */ -static int __devinit cpqarray_eisa_detect(void) +static int __init cpqarray_eisa_detect(void) { int i=0, j; __u32 board_id; diff --git a/trunk/drivers/block/drbd/drbd_main.c b/trunk/drivers/block/drbd/drbd_main.c index 7258c95e895e..6b077f93acc6 100644 --- a/trunk/drivers/block/drbd/drbd_main.c +++ b/trunk/drivers/block/drbd/drbd_main.c @@ -1236,6 +1236,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, /* Last part of the attaching process ... */ if (ns.conn >= C_CONNECTED && os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) { + kfree(mdev->p_uuid); /* We expect to receive up-to-date UUIDs soon. */ + mdev->p_uuid = NULL; /* ...to not use the old ones in the mean time */ drbd_send_sizes(mdev, 0, 0); /* to start sync... */ drbd_send_uuids(mdev); drbd_send_state(mdev); diff --git a/trunk/drivers/block/drbd/drbd_nl.c b/trunk/drivers/block/drbd/drbd_nl.c index 2151f18b21de..632e3245d1bb 100644 --- a/trunk/drivers/block/drbd/drbd_nl.c +++ b/trunk/drivers/block/drbd/drbd_nl.c @@ -1114,12 +1114,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp mdev->new_state_tmp.i = ns.i; ns.i = os.i; ns.disk = D_NEGOTIATING; - - /* We expect to receive up-to-date UUIDs soon. - To avoid a race in receive_state, free p_uuid while - holding req_lock. I.e. atomic with the state change */ - kfree(mdev->p_uuid); - mdev->p_uuid = NULL; } rv = _drbd_set_state(mdev, ns, CS_VERBOSE, NULL); diff --git a/trunk/drivers/char/agp/generic.c b/trunk/drivers/char/agp/generic.c index d2abf5143983..4b51982fd23a 100644 --- a/trunk/drivers/char/agp/generic.c +++ b/trunk/drivers/char/agp/generic.c @@ -97,18 +97,20 @@ EXPORT_SYMBOL(agp_flush_chipset); void agp_alloc_page_array(size_t size, struct agp_memory *mem) { mem->pages = NULL; + mem->vmalloc_flag = false; if (size <= 2*PAGE_SIZE) - mem->pages = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); + mem->pages = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); if (mem->pages == NULL) { mem->pages = vmalloc(size); + mem->vmalloc_flag = true; } } EXPORT_SYMBOL(agp_alloc_page_array); void agp_free_page_array(struct agp_memory *mem) { - if (is_vmalloc_addr(mem->pages)) { + if (mem->vmalloc_flag) { vfree(mem->pages); } else { kfree(mem->pages); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 094bdc355b1f..35603dd4e6c5 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -302,12 +302,6 @@ struct smi_info { static int force_kipmid[SI_MAX_PARMS]; static int num_force_kipmid; -#ifdef CONFIG_PCI -static int pci_registered; -#endif -#ifdef CONFIG_PPC_OF -static int of_registered; -#endif static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; static int num_max_busy_us; @@ -1024,7 +1018,7 @@ static int ipmi_thread(void *data) else if (smi_result == SI_SM_IDLE) schedule_timeout_interruptible(100); else - schedule_timeout_interruptible(1); + schedule_timeout_interruptible(0); } return 0; } @@ -3320,8 +3314,6 @@ static __devinit int init_ipmi_si(void) rv = pci_register_driver(&ipmi_pci_driver); if (rv) printk(KERN_ERR PFX "Unable to register PCI driver: %d\n", rv); - else - pci_registered = 1; #endif #ifdef CONFIG_ACPI @@ -3338,7 +3330,6 @@ static __devinit int init_ipmi_si(void) #ifdef CONFIG_PPC_OF of_register_platform_driver(&ipmi_of_platform_driver); - of_registered = 1; #endif /* We prefer devices with interrupts, but in the case of a machine @@ -3392,13 +3383,11 @@ static __devinit int init_ipmi_si(void) if (unload_when_empty && list_empty(&smi_infos)) { mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI - if (pci_registered) - pci_unregister_driver(&ipmi_pci_driver); + pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_PPC_OF - if (of_registered) - of_unregister_platform_driver(&ipmi_of_platform_driver); + of_unregister_platform_driver(&ipmi_of_platform_driver); #endif driver_unregister(&ipmi_driver.driver); printk(KERN_WARNING PFX @@ -3489,16 +3478,14 @@ static __exit void cleanup_ipmi_si(void) return; #ifdef CONFIG_PCI - if (pci_registered) - pci_unregister_driver(&ipmi_pci_driver); + pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_ACPI pnp_unregister_driver(&ipmi_pnp_driver); #endif #ifdef CONFIG_PPC_OF - if (of_registered) - of_unregister_platform_driver(&ipmi_of_platform_driver); + of_unregister_platform_driver(&ipmi_of_platform_driver); #endif mutex_lock(&smi_infos_lock); diff --git a/trunk/drivers/cpuidle/governors/menu.c b/trunk/drivers/cpuidle/governors/menu.c index 1b128702d300..52ff8aa63f84 100644 --- a/trunk/drivers/cpuidle/governors/menu.c +++ b/trunk/drivers/cpuidle/governors/menu.c @@ -143,7 +143,7 @@ static inline int which_bucket(unsigned int duration) * This allows us to calculate * E(duration)|iowait */ - if (nr_iowait_cpu(smp_processor_id())) + if (nr_iowait_cpu()) bucket = BUCKETS/2; if (duration < 10) @@ -175,7 +175,7 @@ static inline int performance_multiplier(void) mult += 2 * get_loadavg(); /* for IO wait tasks (per cpu!) we add 5x each */ - mult += 10 * nr_iowait_cpu(smp_processor_id()); + mult += 10 * nr_iowait_cpu(); return mult; } diff --git a/trunk/drivers/dma/ppc4xx/adma.c b/trunk/drivers/dma/ppc4xx/adma.c index 7c3747902a37..5a22ca6927e5 100644 --- a/trunk/drivers/dma/ppc4xx/adma.c +++ b/trunk/drivers/dma/ppc4xx/adma.c @@ -4257,12 +4257,10 @@ static int ppc440spe_adma_setup_irqs(struct ppc440spe_adma_device *adev, struct ppc440spe_adma_chan *chan, int *initcode) { - struct of_device *ofdev; struct device_node *np; int ret; - ofdev = container_of(adev->dev, struct of_device, dev); - np = ofdev->dev.of_node; + np = container_of(adev->dev, struct of_device, dev)->node; if (adev->id != PPC440SPE_XOR_ID) { adev->err_irq = irq_of_parse_and_map(np, 1); if (adev->err_irq == NO_IRQ) { diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index ac9f7985096d..cf17dbb8014f 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -1958,20 +1958,20 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *mci, u16 syndrome) u32 value = 0; int err_sym = 0; - if (boot_cpu_data.x86 == 0x10) { + amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value); - amd64_read_pci_cfg(pvt->misc_f3_ctl, 0x180, &value); - - /* F3x180[EccSymbolSize]=1 => x8 symbols */ - if (boot_cpu_data.x86_model > 7 && - value & BIT(25)) { - err_sym = decode_syndrome(syndrome, x8_vectors, - ARRAY_SIZE(x8_vectors), 8); - return map_err_sym_to_channel(err_sym, 8); - } + /* F3x180[EccSymbolSize]=1, x8 symbols */ + if (boot_cpu_data.x86 == 0x10 && + boot_cpu_data.x86_model > 7 && + value & BIT(25)) { + err_sym = decode_syndrome(syndrome, x8_vectors, + ARRAY_SIZE(x8_vectors), 8); + return map_err_sym_to_channel(err_sym, 8); + } else { + err_sym = decode_syndrome(syndrome, x4_vectors, + ARRAY_SIZE(x4_vectors), 4); + return map_err_sym_to_channel(err_sym, 4); } - err_sym = decode_syndrome(syndrome, x4_vectors, ARRAY_SIZE(x4_vectors), 4); - return map_err_sym_to_channel(err_sym, 4); } /* diff --git a/trunk/drivers/edac/i7core_edac.c b/trunk/drivers/edac/i7core_edac.c index cc9357da0e34..6b8b7b41ec5f 100644 --- a/trunk/drivers/edac/i7core_edac.c +++ b/trunk/drivers/edac/i7core_edac.c @@ -1233,28 +1233,10 @@ static void __init i7core_xeon_pci_fixup(struct pci_id_table *table) for (i = 0; i < MAX_SOCKET_BUSES; i++) pcibios_scan_specific_bus(255-i); } - pci_dev_put(pdev); table++; } } -static unsigned i7core_pci_lastbus(void) -{ - int last_bus = 0, bus; - struct pci_bus *b = NULL; - - while ((b = pci_find_next_bus(b)) != NULL) { - bus = b->number; - debugf0("Found bus %d\n", bus); - if (bus > last_bus) - last_bus = bus; - } - - debugf0("Last bus %d\n", last_bus); - - return last_bus; -} - /* * i7core_get_devices Find and perform 'get' operation on the MCH's * device/functions we want to reference for this driver @@ -1262,8 +1244,7 @@ static unsigned i7core_pci_lastbus(void) * Need to 'get' device 16 func 1 and func 2 */ int i7core_get_onedevice(struct pci_dev **prev, int devno, - struct pci_id_descr *dev_descr, unsigned n_devs, - unsigned last_bus) + struct pci_id_descr *dev_descr, unsigned n_devs) { struct i7core_dev *i7core_dev; @@ -1310,7 +1291,10 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, } bus = pdev->bus->number; - socket = last_bus - bus; + if (bus == 0x3f) + socket = 0; + else + socket = 255 - bus; i7core_dev = get_i7core_dev(socket); if (!i7core_dev) { @@ -1374,21 +1358,17 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, static int i7core_get_devices(struct pci_id_table *table) { - int i, rc, last_bus; + int i, rc; struct pci_dev *pdev = NULL; struct pci_id_descr *dev_descr; - last_bus = i7core_pci_lastbus(); - while (table && table->descr) { dev_descr = table->descr; for (i = 0; i < table->n_devs; i++) { pdev = NULL; do { - rc = i7core_get_onedevice(&pdev, i, - &dev_descr[i], - table->n_devs, - last_bus); + rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], + table->n_devs); if (rc < 0) { if (i == 0) { i = table->n_devs; @@ -1947,26 +1927,21 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, * 0 for FOUND a device * < 0 for error code */ - -static int probed = 0; - static int __devinit i7core_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + int dev_idx = id->driver_data; int rc; struct i7core_dev *i7core_dev; - /* get the pci devices we want to reserve for our use */ - mutex_lock(&i7core_edac_lock); - /* * All memory controllers are allocated at the first pass. */ - if (unlikely(probed >= 1)) { - mutex_unlock(&i7core_edac_lock); + if (unlikely(dev_idx >= 1)) return -EINVAL; - } - probed++; + + /* get the pci devices we want to reserve for our use */ + mutex_lock(&i7core_edac_lock); rc = i7core_get_devices(pci_dev_table); if (unlikely(rc < 0)) @@ -2038,8 +2013,6 @@ static void __devexit i7core_remove(struct pci_dev *pdev) i7core_dev->socket); } } - probed--; - mutex_unlock(&i7core_edac_lock); } diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 7face915b963..724038dab4ca 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -1,5 +1,5 @@ # -# platform-neutral GPIO infrastructure and expanders +# GPIO infrastructure and expanders # config ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile index e53dcff49b4f..51c3cdd41b5a 100644 --- a/trunk/drivers/gpio/Makefile +++ b/trunk/drivers/gpio/Makefile @@ -1,8 +1,4 @@ -# generic gpio support: dedicated expander chips, etc -# -# NOTE: platform-specific GPIO drivers don't belong in the -# drivers/gpio directory; put them with other platform setup -# code, IRQ controllers, board init, etc. +# gpio support: dedicated expander chips, etc ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c index 1f2cc6b09623..08c4c926e65f 100644 --- a/trunk/drivers/gpu/drm/drm_fb_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_helper.c @@ -146,7 +146,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn cvt = 1; break; case 'R': - if (cvt) + if (!cvt) rb = 1; break; case 'm': @@ -1024,18 +1024,11 @@ static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_conne } create_mode: - if (cmdline_mode->cvt) - mode = drm_cvt_mode(fb_helper_conn->connector->dev, - cmdline_mode->xres, cmdline_mode->yres, - cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, - cmdline_mode->rb, cmdline_mode->interlace, - cmdline_mode->margins); - else - mode = drm_gtf_mode(fb_helper_conn->connector->dev, - cmdline_mode->xres, cmdline_mode->yres, - cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, - cmdline_mode->interlace, - cmdline_mode->margins); + mode = drm_cvt_mode(fb_helper_conn->connector->dev, cmdline_mode->xres, + cmdline_mode->yres, + cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, + cmdline_mode->rb, cmdline_mode->interlace, + cmdline_mode->margins); drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); list_add(&mode->head, &fb_helper_conn->connector->modes); return mode; diff --git a/trunk/drivers/gpu/drm/i915/dvo_tfp410.c b/trunk/drivers/gpu/drm/i915/dvo_tfp410.c index 56f66426207f..66c697bc9b22 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/trunk/drivers/gpu/drm/i915/dvo_tfp410.c @@ -208,7 +208,7 @@ static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo) uint8_t ctl2; if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) { - if (ctl2 & TFP410_CTL_2_RSEN) + if (ctl2 & TFP410_CTL_2_HTPLG) ret = connector_status_connected; else ret = connector_status_disconnected; diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index aee83fa178f6..52510ad8b25d 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -620,7 +620,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) drm_i915_private_t *dev_priv = dev->dev_private; bool sr_enabled = false; - if (IS_I965GM(dev) || IS_I945G(dev) || IS_I945GM(dev)) + if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev)) sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; else if (IS_I915GM(dev)) sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index f00c5ae9556c..59a2bf8592ec 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -128,11 +128,9 @@ static int i915_dma_cleanup(struct drm_device * dev) if (dev->irq_enabled) drm_irq_uninstall(dev); - mutex_lock(&dev->struct_mutex); intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); if (HAS_BSD(dev)) intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); - mutex_unlock(&dev->struct_mutex); /* Clear the HWS virtual address at teardown */ if (I915_NEED_GFX_HWS(dev)) @@ -1231,7 +1229,7 @@ static void i915_warn_stolen(struct drm_device *dev) static void i915_setup_compression(struct drm_device *dev, int size) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); + struct drm_mm_node *compressed_fb, *compressed_llb; unsigned long cfb_base; unsigned long ll_base = 0; @@ -1412,10 +1410,6 @@ static int i915_load_modeset_init(struct drm_device *dev, if (ret) goto cleanup_vga_client; - /* IIR "flip pending" bit means done if this bit is set */ - if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) - dev_priv->flip_pending_is_done = true; - intel_modeset_init(dev); ret = drm_irq_install(dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index d147ab2f5bfc..276583159847 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -596,7 +596,6 @@ typedef struct drm_i915_private { struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; wait_queue_head_t pending_flip_queue; - bool flip_pending_is_done; /* Reclocking support */ bool render_reclock_avail; @@ -1077,7 +1076,7 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); drm_i915_private_t *dev_priv = dev->dev_private; \ if (I915_VERBOSE) \ DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ - intel_ring_begin(dev, &dev_priv->render_ring, (n)); \ + intel_ring_begin(dev, &dev_priv->render_ring, 4*(n)); \ } while (0) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 074385882ccf..9ded3dae6c87 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -2239,7 +2239,7 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, mapping = inode->i_mapping; for (i = 0; i < page_count; i++) { page = read_cache_page_gfp(mapping, i, - GFP_HIGHUSER | + mapping_gfp_mask (mapping) | __GFP_COLD | gfpmask); if (IS_ERR(page)) diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index dba53d4b9fb3..2479be001e40 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -940,30 +940,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); - if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { + if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) intel_prepare_page_flip(dev, 0); - if (dev_priv->flip_pending_is_done) - intel_finish_page_flip_plane(dev, 0); - } - if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) { + if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) intel_prepare_page_flip(dev, 1); - if (dev_priv->flip_pending_is_done) - intel_finish_page_flip_plane(dev, 1); - } if (pipea_stats & vblank_status) { vblank++; drm_handle_vblank(dev, 0); - if (!dev_priv->flip_pending_is_done) - intel_finish_page_flip(dev, 0); + intel_finish_page_flip(dev, 0); } if (pipeb_stats & vblank_status) { vblank++; drm_handle_vblank(dev, 1); - if (!dev_priv->flip_pending_is_done) - intel_finish_page_flip(dev, 1); + intel_finish_page_flip(dev, 1); } if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || @@ -1395,10 +1387,29 @@ int i915_driver_irq_postinstall(struct drm_device *dev) dev_priv->pipestat[1] = 0; if (I915_HAS_HOTPLUG(dev)) { + u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); + + /* Note HDMI and DP share bits */ + if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) + hotplug_en |= HDMIC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) + hotplug_en |= HDMID_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) + hotplug_en |= SDVOC_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) + hotplug_en |= SDVOB_HOTPLUG_INT_EN; + if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) + hotplug_en |= CRT_HOTPLUG_INT_EN; + /* Ignore TV since it's buggy */ + + I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); + /* Enable in IER... */ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; /* and unmask in IMR */ - dev_priv->irq_mask_reg &= ~I915_DISPLAY_PORT_INTERRUPT; + i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); } /* @@ -1416,41 +1427,16 @@ int i915_driver_irq_postinstall(struct drm_device *dev) } I915_WRITE(EMR, error_mask); - I915_WRITE(IMR, dev_priv->irq_mask_reg); + /* Disable pipe interrupt enables, clear pending pipe status */ + I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); + I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); + /* Clear pending interrupt status */ + I915_WRITE(IIR, I915_READ(IIR)); + I915_WRITE(IER, enable_mask); + I915_WRITE(IMR, dev_priv->irq_mask_reg); (void) I915_READ(IER); - if (I915_HAS_HOTPLUG(dev)) { - u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); - - /* Note HDMI and DP share bits */ - if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) - hotplug_en |= HDMIB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) - hotplug_en |= HDMIC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) - hotplug_en |= HDMID_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) - hotplug_en |= SDVOC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) - hotplug_en |= SDVOB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { - hotplug_en |= CRT_HOTPLUG_INT_EN; - - /* Programming the CRT detection parameters tends - to generate a spurious hotplug event about three - seconds later. So just do it once. - */ - if (IS_G4X(dev)) - hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; - hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; - } - - /* Ignore TV since it's buggy */ - - I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); - } - opregion_enable_asle(dev); return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 150400f40534..64b0a3afd92b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -178,7 +178,6 @@ #define MI_OVERLAY_OFF (0x2<<21) #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) -#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ @@ -369,9 +368,6 @@ #define CM0_RC_OP_FLUSH_DISABLE (1<<0) #define BB_ADDR 0x02140 /* 8 bytes */ #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ -#define ECOSKPD 0x021d0 -#define ECO_GATING_CX_ONLY (1<<3) -#define ECO_FLIP_DONE (1<<0) /* GEN6 interrupt control */ #define GEN6_RENDER_HWSTAM 0x2098 @@ -1134,6 +1130,7 @@ #define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) +#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ #define PORT_HOTPLUG_STAT 0x61114 #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index ee0732b222a1..22ff38455731 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -234,8 +234,14 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) else tries = 1; hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); + hotplug_en &= CRT_HOTPLUG_MASK; hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; + if (IS_G4X(dev)) + hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; + + hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; + for (i = 0; i < tries ; i++) { unsigned long timeout; /* turn on the FORCE_DETECT */ diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 68dcf36e2793..cc8131ff319f 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -2970,13 +2970,11 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, if (srwm < 0) srwm = 1; srwm &= 0x3f; - if (IS_I965GM(dev)) - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); } else { /* Turn off self refresh if both pipes are enabled */ - if (IS_I965GM(dev)) - I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) - & ~FW_BLC_SELF_EN); + I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) + & ~FW_BLC_SELF_EN); } DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", @@ -4485,7 +4483,6 @@ static void intel_idle_update(struct work_struct *work) struct drm_device *dev = dev_priv->dev; struct drm_crtc *crtc; struct intel_crtc *intel_crtc; - int enabled = 0; if (!i915_powersave) return; @@ -4494,22 +4491,21 @@ static void intel_idle_update(struct work_struct *work) i915_update_gfx_val(dev_priv); + if (IS_I945G(dev) || IS_I945GM(dev)) { + DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); + } + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { /* Skip inactive CRTCs */ if (!crtc->fb) continue; - enabled++; intel_crtc = to_intel_crtc(crtc); if (!intel_crtc->busy) intel_decrease_pllclock(crtc); } - if ((enabled == 1) && (IS_I945G(dev) || IS_I945GM(dev))) { - DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); - } - mutex_unlock(&dev->struct_mutex); } @@ -4605,10 +4601,10 @@ static void intel_unpin_work_fn(struct work_struct *__work) kfree(work); } -static void do_intel_finish_page_flip(struct drm_device *dev, - struct drm_crtc *crtc) +void intel_finish_page_flip(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; struct drm_i915_gem_object *obj_priv; @@ -4652,22 +4648,6 @@ static void do_intel_finish_page_flip(struct drm_device *dev, schedule_work(&work->work); } -void intel_finish_page_flip(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - - do_intel_finish_page_flip(dev, crtc); -} - -void intel_finish_page_flip_plane(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; - - do_intel_finish_page_flip(dev, crtc); -} - void intel_prepare_page_flip(struct drm_device *dev, int plane) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -4698,7 +4678,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, unsigned long flags; int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; int ret, pipesrc; - u32 flip_mask; work = kzalloc(sizeof *work, GFP_KERNEL); if (work == NULL) @@ -4752,28 +4731,15 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, atomic_inc(&obj_priv->pending_flip); work->pending_flip_obj = obj; - if (intel_crtc->plane) - flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; - else - flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; - - /* Wait for any previous flip to finish */ - if (IS_GEN3(dev)) - while (I915_READ(ISR) & flip_mask) - ; - BEGIN_LP_RING(4); + OUT_RING(MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch); if (IS_I965G(dev)) { - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch); OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); pipesrc = I915_READ(pipesrc_reg); OUT_RING(pipesrc & 0x0fff0fff); } else { - OUT_RING(MI_DISPLAY_FLIP_I915 | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch); OUT_RING(obj_priv->gtt_offset); OUT_RING(MI_NOOP); } diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 1aac59e83bff..49b54f05d3cf 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -135,12 +135,6 @@ intel_dp_link_required(struct drm_device *dev, return pixel_clock * 3; } -static int -intel_dp_max_data_rate(int max_link_clock, int max_lanes) -{ - return (max_link_clock * max_lanes * 8) / 10; -} - static int intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -150,11 +144,8 @@ intel_dp_mode_valid(struct drm_connector *connector, int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); int max_lanes = intel_dp_max_lane_count(intel_encoder); - /* only refuse the mode on non eDP since we have seen some wierd eDP panels - which are outside spec tolerances but somehow work by magic */ - if (!IS_eDP(intel_encoder) && - (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) - > intel_dp_max_data_rate(max_link_clock, max_lanes))) + if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) + > max_link_clock * max_lanes) return MODE_CLOCK_HIGH; if (mode->clock < 10000) @@ -515,7 +506,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { - int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); + int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) <= link_avail) { @@ -530,18 +521,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, } } } - - if (IS_eDP(intel_encoder)) { - /* okay we failed just pick the highest */ - dp_priv->lane_count = max_lane_count; - dp_priv->link_bw = bws[max_clock]; - adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); - DRM_DEBUG_KMS("Force picking display port link bw %02x lane " - "count %d clock %d\n", - dp_priv->link_bw, dp_priv->lane_count, - adjusted_mode->clock); - return true; - } return false; } diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 72206f37c4fb..df931f787665 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -224,7 +224,6 @@ extern void intel_fbdev_fini(struct drm_device *dev); extern void intel_prepare_page_flip(struct drm_device *dev, int plane); extern void intel_finish_page_flip(struct drm_device *dev, int pipe); -extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); extern void intel_setup_overlay(struct drm_device *dev); extern void intel_cleanup_overlay(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 31df55f0a0a7..6a1accd83aec 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -983,8 +983,8 @@ void intel_lvds_init(struct drm_device *dev) drm_connector_attach_property(&intel_connector->base, dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_ASPECT); - lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; + DRM_MODE_SCALE_FULLSCREEN); + lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; /* * LVDS discovery: * 1) check for EDID on DDC diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 26362f8495a8..cea4f1a8709e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -94,7 +94,7 @@ render_ring_flush(struct drm_device *dev, #if WATCH_EXEC DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); #endif - intel_ring_begin(dev, ring, 2); + intel_ring_begin(dev, ring, 8); intel_ring_emit(dev, ring, cmd); intel_ring_emit(dev, ring, MI_NOOP); intel_ring_advance(dev, ring); @@ -358,7 +358,7 @@ bsd_ring_flush(struct drm_device *dev, u32 invalidate_domains, u32 flush_domains) { - intel_ring_begin(dev, ring, 2); + intel_ring_begin(dev, ring, 8); intel_ring_emit(dev, ring, MI_FLUSH); intel_ring_emit(dev, ring, MI_NOOP); intel_ring_advance(dev, ring); @@ -687,7 +687,6 @@ int intel_wrap_ring_buffer(struct drm_device *dev, *virt++ = MI_NOOP; ring->tail = 0; - ring->space = ring->head - 8; return 0; } @@ -722,9 +721,8 @@ int intel_wait_ring_buffer(struct drm_device *dev, } void intel_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, int num_dwords) + struct intel_ring_buffer *ring, int n) { - int n = 4*num_dwords; if (unlikely(ring->tail + n > ring->size)) intel_wrap_ring_buffer(dev, ring); if (unlikely(ring->space < n)) @@ -754,7 +752,7 @@ void intel_fill_struct(struct drm_device *dev, { unsigned int *virt = ring->virtual_start + ring->tail; BUG_ON((len&~(4-1)) != 0); - intel_ring_begin(dev, ring, len/4); + intel_ring_begin(dev, ring, len); memcpy(virt, data, len); ring->tail += len; ring->tail &= ring->size - 1; diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 8c2d6478a221..f3f2827017ef 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -498,7 +498,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, if ((rdev->family == CHIP_RS600) || (rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) - pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ + pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV | RADEON_PLL_PREFER_CLOSEST_LOWER); if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 1caf625e472b..4b6623df3b96 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -607,7 +607,7 @@ static void evergreen_mc_program(struct radeon_device *rdev) WREG32(MC_VM_FB_LOCATION, tmp); WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); WREG32(HDP_NONSURFACE_INFO, (2 << 7)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); + WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); if (rdev->flags & RADEON_IS_AGP) { WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); @@ -1222,11 +1222,11 @@ static void evergreen_gpu_init(struct radeon_device *rdev) ps_thread_count = 128; sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); - sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt |= NUM_GS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt |= NUM_ES_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt_2 = NUM_HS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt_2 |= NUM_LS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); + sq_thread_resource_mgmt |= NUM_VS_THREADS(((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8; + sq_thread_resource_mgmt |= NUM_GS_THREADS(((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8; + sq_thread_resource_mgmt |= NUM_ES_THREADS(((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8; + sq_thread_resource_mgmt_2 = NUM_HS_THREADS(((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8; + sq_thread_resource_mgmt_2 |= NUM_LS_THREADS(((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8; sq_stack_resource_mgmt_1 = NUM_PS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); sq_stack_resource_mgmt_1 |= NUM_VS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); @@ -1260,9 +1260,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(VGT_GS_VERTEX_REUSE, 16); WREG32(PA_SC_LINE_STIPPLE_STATE, 0); - WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); - WREG32(VGT_OUT_DEALLOC_CNTL, 16); - WREG32(CB_PERF_CTR0_SEL_0, 0); WREG32(CB_PERF_CTR0_SEL_1, 0); WREG32(CB_PERF_CTR1_SEL_0, 0); @@ -1272,26 +1269,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(CB_PERF_CTR3_SEL_0, 0); WREG32(CB_PERF_CTR3_SEL_1, 0); - /* clear render buffer base addresses */ - WREG32(CB_COLOR0_BASE, 0); - WREG32(CB_COLOR1_BASE, 0); - WREG32(CB_COLOR2_BASE, 0); - WREG32(CB_COLOR3_BASE, 0); - WREG32(CB_COLOR4_BASE, 0); - WREG32(CB_COLOR5_BASE, 0); - WREG32(CB_COLOR6_BASE, 0); - WREG32(CB_COLOR7_BASE, 0); - WREG32(CB_COLOR8_BASE, 0); - WREG32(CB_COLOR9_BASE, 0); - WREG32(CB_COLOR10_BASE, 0); - WREG32(CB_COLOR11_BASE, 0); - - /* set the shader const cache sizes to 0 */ - for (i = SQ_ALU_CONST_BUFFER_SIZE_PS_0; i < 0x28200; i += 4) - WREG32(i, 0); - for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) - WREG32(i, 0); - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index 010963d4570f..64516b950891 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -1197,7 +1197,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad SET_RESOURCE (tex)\n"); return -EINVAL; } - ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) @@ -1209,7 +1209,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad SET_RESOURCE (tex)\n"); return -EINVAL; } - ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + ib[idx+1+(i*8)+4] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); mipmap = reloc->robj; r = evergreen_check_texture_resource(p, idx+1+(i*8), texture, mipmap); diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index a1cd621780e2..79683f6b4452 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -713,9 +713,6 @@ #define SQ_GSVS_RING_OFFSET_2 0x28930 #define SQ_GSVS_RING_OFFSET_3 0x28934 -#define SQ_ALU_CONST_BUFFER_SIZE_PS_0 0x28140 -#define SQ_ALU_CONST_BUFFER_SIZE_HS_0 0x28f80 - #define SQ_ALU_CONST_CACHE_PS_0 0x28940 #define SQ_ALU_CONST_CACHE_PS_1 0x28944 #define SQ_ALU_CONST_CACHE_PS_2 0x28948 diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index 3970e62eaab8..cf89aa2eb28c 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -1628,7 +1628,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, case RADEON_TXFORMAT_RGB332: case RADEON_TXFORMAT_Y8: track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case RADEON_TXFORMAT_AI88: case RADEON_TXFORMAT_ARGB1555: @@ -1640,14 +1639,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p, case RADEON_TXFORMAT_LDUDV655: case RADEON_TXFORMAT_DUDV88: track->textures[i].cpp = 2; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case RADEON_TXFORMAT_ARGB8888: case RADEON_TXFORMAT_RGBA8888: case RADEON_TXFORMAT_SHADOW32: case RADEON_TXFORMAT_LDUDUV8888: track->textures[i].cpp = 4; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case RADEON_TXFORMAT_DXT1: track->textures[i].cpp = 1; @@ -2607,6 +2604,12 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, int surf_index = reg * 16; int flags = 0; + /* r100/r200 divide by 16 */ + if (rdev->family < CHIP_R300) + flags = pitch / 16; + else + flags = pitch / 8; + if (rdev->family <= CHIP_RS200) { if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) == (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) @@ -2630,20 +2633,6 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, if (tiling_flags & RADEON_TILING_SWAP_32BIT) flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP; - /* when we aren't tiling the pitch seems to needs to be furtherdivided down. - tested on power5 + rn50 server */ - if (tiling_flags & (RADEON_TILING_SWAP_16BIT | RADEON_TILING_SWAP_32BIT)) { - if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) - if (ASIC_IS_RN50(rdev)) - pitch /= 16; - } - - /* r100/r200 divide by 16 */ - if (rdev->family < CHIP_R300) - flags |= pitch / 16; - else - flags |= pitch / 8; - - DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); WREG32(RADEON_SURFACE0_INFO + surf_index, flags); WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); @@ -3158,6 +3147,33 @@ static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) DRM_ERROR("compress format %d\n", t->compress_format); } +static int r100_cs_track_cube(struct radeon_device *rdev, + struct r100_cs_track *track, unsigned idx) +{ + unsigned face, w, h; + struct radeon_bo *cube_robj; + unsigned long size; + + for (face = 0; face < 5; face++) { + cube_robj = track->textures[idx].cube_info[face].robj; + w = track->textures[idx].cube_info[face].width; + h = track->textures[idx].cube_info[face].height; + + size = w * h; + size *= track->textures[idx].cpp; + + size += track->textures[idx].cube_info[face].offset; + + if (size > radeon_bo_size(cube_robj)) { + DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", + size, radeon_bo_size(cube_robj)); + r100_cs_track_texture_print(&track->textures[idx]); + return -1; + } + } + return 0; +} + static int r100_track_compress_size(int compress_format, int w, int h) { int block_width, block_height, block_bytes; @@ -3188,37 +3204,6 @@ static int r100_track_compress_size(int compress_format, int w, int h) return sz; } -static int r100_cs_track_cube(struct radeon_device *rdev, - struct r100_cs_track *track, unsigned idx) -{ - unsigned face, w, h; - struct radeon_bo *cube_robj; - unsigned long size; - unsigned compress_format = track->textures[idx].compress_format; - - for (face = 0; face < 5; face++) { - cube_robj = track->textures[idx].cube_info[face].robj; - w = track->textures[idx].cube_info[face].width; - h = track->textures[idx].cube_info[face].height; - - if (compress_format) { - size = r100_track_compress_size(compress_format, w, h); - } else - size = w * h; - size *= track->textures[idx].cpp; - - size += track->textures[idx].cube_info[face].offset; - - if (size > radeon_bo_size(cube_robj)) { - DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", - size, radeon_bo_size(cube_robj)); - r100_cs_track_texture_print(&track->textures[idx]); - return -1; - } - } - return 0; -} - static int r100_cs_track_texture_check(struct radeon_device *rdev, struct r100_cs_track *track) { diff --git a/trunk/drivers/gpu/drm/radeon/r200.c b/trunk/drivers/gpu/drm/radeon/r200.c index 0266d72e0a4c..85617c311212 100644 --- a/trunk/drivers/gpu/drm/radeon/r200.c +++ b/trunk/drivers/gpu/drm/radeon/r200.c @@ -415,8 +415,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, /* 2D, 3D, CUBE */ switch (tmp) { case 0: - case 3: - case 4: case 5: case 6: case 7: @@ -452,7 +450,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_TXFORMAT_RGB332: case R200_TXFORMAT_Y8: track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R200_TXFORMAT_AI88: case R200_TXFORMAT_ARGB1555: @@ -464,7 +461,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_TXFORMAT_DVDU88: case R200_TXFORMAT_AVYU4444: track->textures[i].cpp = 2; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R200_TXFORMAT_ARGB8888: case R200_TXFORMAT_RGBA8888: @@ -472,7 +468,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_TXFORMAT_BGR111110: case R200_TXFORMAT_LDVDU8888: track->textures[i].cpp = 4; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R200_TXFORMAT_DXT1: track->textures[i].cpp = 1; diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index 7e81db5eb804..b2f9efe2897c 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -881,7 +881,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case R300_TX_FORMAT_Y4X4: case R300_TX_FORMAT_Z3Y3X2: track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_X16: case R300_TX_FORMAT_Y8X8: @@ -893,7 +892,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case R300_TX_FORMAT_B8G8_B8G8: case R300_TX_FORMAT_G8R8_G8B8: track->textures[i].cpp = 2; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_Y16X16: case R300_TX_FORMAT_Z11Y11X10: @@ -904,17 +902,14 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case R300_TX_FORMAT_FL_I32: case 0x1e: track->textures[i].cpp = 4; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_W16Z16Y16X16: case R300_TX_FORMAT_FL_R16G16B16A16: case R300_TX_FORMAT_FL_I32A32: track->textures[i].cpp = 8; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_FL_R32G32B32A32: track->textures[i].cpp = 16; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_DXT1: track->textures[i].cpp = 1; diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 3d6645ce2151..0e91871f45be 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -130,14 +130,9 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev) break; } } - } else { - if (rdev->pm.current_power_state_index == 0) - rdev->pm.requested_power_state_index = - rdev->pm.num_power_states - 1; - else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index - 1; - } + } else + rdev->pm.requested_power_state_index = + rdev->pm.current_power_state_index - 1; } rdev->pm.requested_clock_mode_index = 0; /* don't use the power state if crtcs are active and no display flag is set */ @@ -1102,7 +1097,7 @@ static void r600_mc_program(struct radeon_device *rdev) WREG32(MC_VM_FB_LOCATION, tmp); WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); WREG32(HDP_NONSURFACE_INFO, (2 << 7)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); + WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF); if (rdev->flags & RADEON_IS_AGP) { WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22); WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22); @@ -1224,10 +1219,8 @@ int r600_mc_init(struct radeon_device *rdev) rdev->mc.visible_vram_size = rdev->mc.aper_size; r600_vram_gtt_location(rdev, &rdev->mc); - if (rdev->flags & RADEON_IS_IGP) { - rs690_pm_info(rdev); + if (rdev->flags & RADEON_IS_IGP) rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - } radeon_update_bandwidth_info(rdev); return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index ab61aaa887bb..8e1d44ca26ec 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -177,7 +177,6 @@ void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); -void rs690_pm_info(struct radeon_device *rdev); /* * Fences. @@ -620,8 +619,7 @@ enum radeon_dynpm_state { DYNPM_STATE_DISABLED, DYNPM_STATE_MINIMUM, DYNPM_STATE_PAUSED, - DYNPM_STATE_ACTIVE, - DYNPM_STATE_SUSPENDED, + DYNPM_STATE_ACTIVE }; enum radeon_dynpm_action { DYNPM_ACTION_NONE, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c index 646f96f97c77..87f7e2cc52d4 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c @@ -780,13 +780,6 @@ int radeon_asic_init(struct radeon_device *rdev) case CHIP_R423: case CHIP_RV410: rdev->asic = &r420_asic; - /* handle macs */ - if (rdev->bios == NULL) { - rdev->asic->get_engine_clock = &radeon_legacy_get_engine_clock; - rdev->asic->set_engine_clock = &radeon_legacy_set_engine_clock; - rdev->asic->get_memory_clock = &radeon_legacy_get_memory_clock; - rdev->asic->set_memory_clock = NULL; - } break; case CHIP_RS400: case CHIP_RS480: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index 2c9213739999..fbba938f8048 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -48,10 +48,6 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) resource_size_t vram_base; resource_size_t size = 256 * 1024; /* ??? */ - if (!(rdev->flags & RADEON_IS_IGP)) - if (!radeon_card_posted(rdev)) - return false; - rdev->bios = NULL; vram_base = drm_get_resource_start(rdev->ddev, 0); bios = ioremap(vram_base, size); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index d1c1d8dd93ce..1bee2f9e24a5 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -1411,11 +1411,6 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; } else #endif /* CONFIG_PPC_PMAC */ -#ifdef CONFIG_PPC64 - if (ASIC_IS_RN50(rdev)) - rdev->mode_info.connector_table = CT_RN50_POWER; - else -#endif rdev->mode_info.connector_table = CT_GENERIC; } @@ -1858,33 +1853,6 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) CONNECTOR_OBJECT_ID_SVIDEO, &hpd); break; - case CT_RN50_POWER: - DRM_INFO("Connector Table: %d (rn50-power)\n", - rdev->mode_info.connector_table); - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_id(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_id(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - break; default: DRM_INFO("Connector table: %d (invalid)\n", rdev->mode_info.connector_table); @@ -1938,6 +1906,15 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, return false; } + /* Some RV100 cards with 2 VGA ports show up with DVI+VGA */ + if (dev->pdev->device == 0x5159 && + dev->pdev->subsystem_vendor == 0x1002 && + dev->pdev->subsystem_device == 0x013a) { + if (*legacy_connector == CONNECTOR_DVI_I_LEGACY) + *legacy_connector = CONNECTOR_CRT_LEGACY; + + } + /* X300 card with extra non-existent DVI port */ if (dev->pdev->device == 0x5B60 && dev->pdev->subsystem_vendor == 0x17af && @@ -3042,14 +3019,6 @@ void radeon_combios_asic_init(struct drm_device *dev) combios_write_ram_size(dev); } - /* quirk for rs4xx HP nx6125 laptop to make it resume - * - it hangs on resume inside the dynclk 1 table. - */ - if (rdev->family == CHIP_RS480 && - rdev->pdev->subsystem_vendor == 0x103c && - rdev->pdev->subsystem_device == 0x308b) - return; - /* DYN CLK 1 */ table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); if (table) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c index 4eb67c0e0996..b7023fff89eb 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c @@ -194,7 +194,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, fail: drm_gem_object_unreference_unlocked(obj); - return ret; + return 0; } int radeon_crtc_cursor_move(struct drm_crtc *crtc, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 5f317317aba2..f10faed21567 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -779,7 +779,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) int radeon_resume_kms(struct drm_device *dev) { - struct drm_connector *connector; struct radeon_device *rdev = dev->dev_private; if (rdev->powered_down) @@ -798,12 +797,6 @@ int radeon_resume_kms(struct drm_device *dev) radeon_resume(rdev); radeon_pm_resume(rdev); radeon_restore_bios_scratch_regs(rdev); - - /* turn on display hw */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - radeon_fbdev_set_suspend(rdev, 0); release_console_sem(); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index e0b30b264c28..1ebb100015b7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1072,8 +1072,6 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) if (is_dig) { switch (mode) { case DRM_MODE_DPMS_ON: - if (!ASIC_IS_DCE4(rdev)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); @@ -1081,6 +1079,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); } + if (!ASIC_IS_DCE4(rdev)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index bad77f40a9da..5b07b8848e09 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -928,13 +928,15 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, if (ASIC_IS_R300(rdev)) { gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - } else if (rdev->family != CHIP_R200) - disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - else if (rdev->family == CHIP_R200) - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); + } - if (rdev->family >= CHIP_R200) + if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL); + else + disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); + + if (rdev->family == CHIP_R200) + fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); if (is_tv) { uint32_t dac_cntl; @@ -1000,13 +1002,15 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, if (ASIC_IS_R300(rdev)) { WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - } else if (rdev->family != CHIP_R200) - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - else if (rdev->family == CHIP_R200) - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); + } if (rdev->family >= CHIP_R200) WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl); + else + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); + + if (rdev->family == CHIP_R200) + WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); if (is_tv) radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index 95696aa57ac8..67358baf28b2 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -206,7 +206,6 @@ enum radeon_connector_table { CT_MINI_INTERNAL, CT_IMAC_G5_ISIGHT, CT_EMAC, - CT_RN50_POWER, }; enum radeon_dvo_chip { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c index 115d26b762cc..63f679a04b25 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c @@ -397,20 +397,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; mutex_unlock(&rdev->pm.mutex); } else if (strncmp("profile", buf, strlen("profile")) == 0) { - bool flush_wq = false; - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - flush_wq = true; - } + rdev->pm.pm_method = PM_METHOD_PROFILE; /* disable dynpm */ rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - rdev->pm.pm_method = PM_METHOD_PROFILE; + cancel_delayed_work(&rdev->pm.dynpm_idle_work); mutex_unlock(&rdev->pm.mutex); - if (flush_wq) - flush_workqueue(rdev->wq); } else { DRM_ERROR("invalid power method!\n"); goto fail; @@ -425,18 +418,9 @@ static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon void radeon_pm_suspend(struct radeon_device *rdev) { - bool flush_wq = false; - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) - rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; - flush_wq = true; - } + cancel_delayed_work(&rdev->pm.dynpm_idle_work); mutex_unlock(&rdev->pm.mutex); - if (flush_wq) - flush_workqueue(rdev->wq); } void radeon_pm_resume(struct radeon_device *rdev) @@ -448,12 +432,6 @@ void radeon_pm_resume(struct radeon_device *rdev) 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; - if (rdev->pm.pm_method == PM_METHOD_DYNPM - && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; - queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - } mutex_unlock(&rdev->pm.mutex); radeon_pm_compute_clocks(rdev); } @@ -508,8 +486,6 @@ int radeon_pm_init(struct radeon_device *rdev) void radeon_pm_fini(struct radeon_device *rdev) { if (rdev->pm.num_power_states > 1) { - bool flush_wq = false; - mutex_lock(&rdev->pm.mutex); if (rdev->pm.pm_method == PM_METHOD_PROFILE) { rdev->pm.profile = PM_PROFILE_DEFAULT; @@ -517,16 +493,13 @@ void radeon_pm_fini(struct radeon_device *rdev) radeon_pm_set_clocks(rdev); } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { /* cancel work */ - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - flush_wq = true; + cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); /* reset default clocks */ rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; radeon_pm_set_clocks(rdev); } mutex_unlock(&rdev->pm.mutex); - if (flush_wq) - flush_workqueue(rdev->wq); device_remove_file(rdev->dev, &dev_attr_power_profile); device_remove_file(rdev->dev, &dev_attr_power_method); @@ -747,12 +720,12 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) radeon_pm_get_dynpm_state(rdev); radeon_pm_set_clocks(rdev); } - - queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); } mutex_unlock(&rdev->pm.mutex); ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); + + queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, + msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); } /* diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen b/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen index f78fd592544d..b5c757f68d3c 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen @@ -80,8 +80,8 @@ evergreen 0x9400 0x00028010 DB_RENDER_OVERRIDE2 0x00028028 DB_STENCIL_CLEAR 0x0002802C DB_DEPTH_CLEAR -0x00028030 PA_SC_SCREEN_SCISSOR_TL 0x00028034 PA_SC_SCREEN_SCISSOR_BR +0x00028030 PA_SC_SCREEN_SCISSOR_TL 0x0002805C DB_DEPTH_SLICE 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 @@ -460,8 +460,8 @@ evergreen 0x9400 0x00028844 SQ_PGM_RESOURCES_PS 0x00028848 SQ_PGM_RESOURCES_2_PS 0x0002884C SQ_PGM_EXPORTS_PS -0x00028860 SQ_PGM_RESOURCES_VS -0x00028864 SQ_PGM_RESOURCES_2_VS +0x0002885C SQ_PGM_RESOURCES_VS +0x00028860 SQ_PGM_RESOURCES_2_VS 0x00028878 SQ_PGM_RESOURCES_GS 0x0002887C SQ_PGM_RESOURCES_2_GS 0x00028890 SQ_PGM_RESOURCES_ES @@ -469,8 +469,8 @@ evergreen 0x9400 0x000288A8 SQ_PGM_RESOURCES_FS 0x000288BC SQ_PGM_RESOURCES_HS 0x000288C0 SQ_PGM_RESOURCES_2_HS -0x000288D4 SQ_PGM_RESOURCES_LS -0x000288D8 SQ_PGM_RESOURCES_2_LS +0x000288D0 SQ_PGM_RESOURCES_LS +0x000288D4 SQ_PGM_RESOURCES_2_LS 0x000288E8 SQ_LDS_ALLOC 0x000288EC SQ_LDS_ALLOC_PS 0x000288F0 SQ_VTX_SEMANTIC_CLEAR diff --git a/trunk/drivers/gpu/drm/radeon/rs690.c b/trunk/drivers/gpu/drm/radeon/rs690.c index f4f0a61bcdce..bcc33195ebc2 100644 --- a/trunk/drivers/gpu/drm/radeon/rs690.c +++ b/trunk/drivers/gpu/drm/radeon/rs690.c @@ -79,13 +79,7 @@ void rs690_pm_info(struct radeon_device *rdev) tmp.full = dfixed_const(100); rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info.ulBootUpMemoryClock); rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (info->info.usK8MemoryClock) - rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); - else if (rdev->clock.default_mclk) { - rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); - rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - } else - rdev->pm.igp_system_mclk.full = dfixed_const(400); + rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); rdev->pm.igp_ht_link_clk.full = dfixed_const(le16_to_cpu(info->info.usFSBClock)); rdev->pm.igp_ht_link_width.full = dfixed_const(info->info.ucHTLinkWidth); break; @@ -93,31 +87,34 @@ void rs690_pm_info(struct radeon_device *rdev) tmp.full = dfixed_const(100); rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info_v2.ulBootUpSidePortClock); rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (info->info_v2.ulBootUpUMAClock) - rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock); - else if (rdev->clock.default_mclk) - rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); - else - rdev->pm.igp_system_mclk.full = dfixed_const(66700); + rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock); rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); rdev->pm.igp_ht_link_clk.full = dfixed_const(info->info_v2.ulHTLinkFreq); rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); break; default: + tmp.full = dfixed_const(100); /* We assume the slower possible clock ie worst case */ - rdev->pm.igp_sideport_mclk.full = dfixed_const(200); - rdev->pm.igp_system_mclk.full = dfixed_const(200); - rdev->pm.igp_ht_link_clk.full = dfixed_const(1000); + /* DDR 333Mhz */ + rdev->pm.igp_sideport_mclk.full = dfixed_const(333); + /* FIXME: system clock ? */ + rdev->pm.igp_system_mclk.full = dfixed_const(100); + rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = dfixed_const(200); rdev->pm.igp_ht_link_width.full = dfixed_const(8); DRM_ERROR("No integrated system info for your GPU, using safe default\n"); break; } } else { + tmp.full = dfixed_const(100); /* We assume the slower possible clock ie worst case */ - rdev->pm.igp_sideport_mclk.full = dfixed_const(200); - rdev->pm.igp_system_mclk.full = dfixed_const(200); - rdev->pm.igp_ht_link_clk.full = dfixed_const(1000); + /* DDR 333Mhz */ + rdev->pm.igp_sideport_mclk.full = dfixed_const(333); + /* FIXME: system clock ? */ + rdev->pm.igp_system_mclk.full = dfixed_const(100); + rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = dfixed_const(200); rdev->pm.igp_ht_link_width.full = dfixed_const(8); DRM_ERROR("No integrated system info for your GPU, using safe default\n"); } @@ -231,6 +228,10 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, fixed20_12 a, b, c; fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width; fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency; + /* FIXME: detect IGP with sideport memory, i don't think there is any + * such product available + */ + bool sideport = false; if (!crtc->base.enabled) { /* FIXME: wouldn't it better to set priority mark to maximum */ @@ -299,7 +300,7 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, /* Maximun bandwidth is the minimun bandwidth of all component */ rdev->pm.max_bandwidth = rdev->pm.core_bandwidth; - if (rdev->mc.igp_sideport_enabled) { + if (sideport) { if (rdev->pm.max_bandwidth.full > rdev->pm.sideport_bandwidth.full && rdev->pm.sideport_bandwidth.full) rdev->pm.max_bandwidth = rdev->pm.sideport_bandwidth; diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index b7fd82064922..cec536c222c5 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -224,7 +224,7 @@ static void rv770_mc_program(struct radeon_device *rdev) WREG32(MC_VM_FB_LOCATION, tmp); WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); WREG32(HDP_NONSURFACE_INFO, (2 << 7)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); + WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); if (rdev->flags & RADEON_IS_AGP) { WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); diff --git a/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c b/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c index 2f047577b1e3..ef910694bd63 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -667,7 +667,7 @@ int ttm_get_pages(struct list_head *pages, int flags, { struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); struct page *p = NULL; - int gfp_flags = GFP_USER; + int gfp_flags = 0; int r; /* set zero flag for page allocation if required */ diff --git a/trunk/drivers/power/z2_battery.c b/trunk/drivers/power/z2_battery.c index 85064a9f649e..9cca465436e3 100644 --- a/trunk/drivers/power/z2_battery.c +++ b/trunk/drivers/power/z2_battery.c @@ -9,13 +9,19 @@ * */ +#include +#include #include -#include +#include +#include #include +#include +#include +#include #include #include -#include -#include +#include +#include #include #define Z2_DEFAULT_NAME "Z2" diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index d827ce570a8c..de033b7ac21f 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -777,7 +777,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, read_rtc: /* read RTC registers */ - tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, buf); + tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf); if (tmp != 8) { pr_debug("read error %d\n", tmp); err = -EIO; @@ -862,7 +862,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) tmp += 12; i2c_smbus_write_byte_data(client, - ds1307->offset + DS1307_REG_HOUR, + DS1307_REG_HOUR, bin2bcd(tmp)); } diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c index cd6cf575902e..9eb62a256e9a 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c @@ -930,83 +930,6 @@ static void cpm_uart_config_port(struct uart_port *port, int flags) } } -#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) -/* - * Write a string to the serial port - * Note that this is called with interrupts already disabled - */ -static void cpm_uart_early_write(struct uart_cpm_port *pinfo, - const char *string, u_int count) -{ - unsigned int i; - cbd_t __iomem *bdp, *bdbase; - unsigned char *cpm_outp_addr; - - /* Get the address of the host memory buffer. - */ - bdp = pinfo->tx_cur; - bdbase = pinfo->tx_bd_base; - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, string++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - /* Send the character out. - * If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), - pinfo); - *cpm_outp_addr = *string; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*string == 10) { - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), - pinfo); - *cpm_outp_addr = 13; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - pinfo->tx_cur = bdp; -} -#endif - #ifdef CONFIG_CONSOLE_POLL /* Serial polling routines for writing and reading from the uart while * in an interrupt or debug context. @@ -1076,7 +999,7 @@ static void cpm_put_poll_char(struct uart_port *port, static char ch[2]; ch[0] = (char)c; - cpm_uart_early_write(pinfo, ch, 1); + cpm_uart_early_write(pinfo->port.line, ch, 1); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1207,6 +1130,9 @@ static void cpm_uart_console_write(struct console *co, const char *s, u_int count) { struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; + unsigned int i; + cbd_t __iomem *bdp, *bdbase; + unsigned char *cp; unsigned long flags; int nolock = oops_in_progress; @@ -1216,7 +1142,66 @@ static void cpm_uart_console_write(struct console *co, const char *s, spin_lock_irqsave(&pinfo->port.lock, flags); } - cpm_uart_early_write(pinfo, s, count); + /* Get the address of the host memory buffer. + */ + bdp = pinfo->tx_cur; + bdbase = pinfo->tx_bd_base; + + /* + * Now, do each character. This is not as bad as it looks + * since this is a holding FIFO and not a transmitting FIFO. + * We could add the complexity of filling the entire transmit + * buffer, but we would just wait longer between accesses...... + */ + for (i = 0; i < count; i++, s++) { + /* Wait for transmitter fifo to empty. + * Ready indicates output is ready, and xmt is doing + * that, not that it is ready for us to send. + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + /* Send the character out. + * If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); + *cp = *s; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + + /* if a LF, also do CR... */ + if (*s == 10) { + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); + *cp = 13; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + pinfo->tx_cur = bdp; if (unlikely(nolock)) { local_irq_restore(flags); diff --git a/trunk/drivers/staging/batman-adv/bat_sysfs.c b/trunk/drivers/staging/batman-adv/bat_sysfs.c index 212bc21e6d68..e2c000b80ca0 100644 --- a/trunk/drivers/staging/batman-adv/bat_sysfs.c +++ b/trunk/drivers/staging/batman-adv/bat_sysfs.c @@ -225,9 +225,9 @@ static struct bat_attribute *mesh_attrs[] = { NULL, }; -static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t transtable_local_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); @@ -235,9 +235,9 @@ static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj, return hna_local_fill_buffer_text(net_dev, buff, count, off); } -static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t transtable_global_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); @@ -245,9 +245,9 @@ static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj, return hna_global_fill_buffer_text(net_dev, buff, count, off); } -static ssize_t originators_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t originators_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); @@ -255,9 +255,9 @@ static ssize_t originators_read(struct file *filp, struct kobject *kobj, return orig_fill_buffer_text(net_dev, buff, count, off); } -static ssize_t vis_data_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t vis_data_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); diff --git a/trunk/drivers/staging/batman-adv/device.c b/trunk/drivers/staging/batman-adv/device.c index 32204b5572d0..7eb6559e0315 100644 --- a/trunk/drivers/staging/batman-adv/device.c +++ b/trunk/drivers/staging/batman-adv/device.c @@ -196,7 +196,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, kfree(device_packet); if (error) - return -EFAULT; + return error; return sizeof(struct icmp_packet); } diff --git a/trunk/drivers/staging/comedi/drivers/adl_pci9111.c b/trunk/drivers/staging/comedi/drivers/adl_pci9111.c index 39d112b708e3..36a254cd4413 100644 --- a/trunk/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/trunk/drivers/staging/comedi/drivers/adl_pci9111.c @@ -824,12 +824,9 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, plx9050_interrupt_control(dev_private->lcr_io_base, true, true, false, true, true); - if (async_cmd->scan_begin_src == TRIG_TIMER) { - dev_private->scan_delay = - (async_cmd->scan_begin_arg / - (async_cmd->convert_arg * - async_cmd->chanlist_len)) - 1; - } + dev_private->scan_delay = + (async_cmd->scan_begin_arg / (async_cmd->convert_arg * + async_cmd->chanlist_len)) - 1; break; diff --git a/trunk/drivers/staging/comedi/drivers/cb_pcidda.c b/trunk/drivers/staging/comedi/drivers/cb_pcidda.c index c374bee25068..81829d6fd287 100644 --- a/trunk/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/trunk/drivers/staging/comedi/drivers/cb_pcidda.c @@ -52,6 +52,7 @@ Please report success/failure with other different cards to #include "8255.h" #define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */ +#define N_BOARDS 10 /* Number of boards in cb_pcidda_boards */ #define EEPROM_SIZE 128 /* number of entries in eeprom */ #define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */ @@ -306,7 +307,7 @@ static int cb_pcidda_attach(struct comedi_device *dev, continue; } } - for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) { + for (index = 0; index < N_BOARDS; index++) { if (cb_pcidda_boards[index].device_id == pcidev->device) { goto found; diff --git a/trunk/drivers/staging/hv/channel_mgmt.c b/trunk/drivers/staging/hv/channel_mgmt.c index 12db555a3a5d..3f53b4d1e4cf 100644 --- a/trunk/drivers/staging/hv/channel_mgmt.c +++ b/trunk/drivers/staging/hv/channel_mgmt.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "osd.h" #include "logging.h" #include "vmbus_private.h" @@ -294,25 +293,6 @@ void FreeVmbusChannel(struct vmbus_channel *Channel) Channel); } - -DECLARE_COMPLETION(hv_channel_ready); - -/* - * Count initialized channels, and ensure all channels are ready when hv_vmbus - * module loading completes. - */ -static void count_hv_channel(void) -{ - static int counter; - unsigned long flags; - - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - if (++counter == MAX_MSG_TYPES) - complete(&hv_channel_ready); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); -} - - /* * VmbusChannelProcessOffer - Process the offer by creating a channel/device * associated with this offer @@ -393,21 +373,22 @@ static void VmbusChannelProcessOffer(void *context) * can cleanup properly */ newChannel->State = CHANNEL_OPEN_STATE; + cnt = 0; - /* Open IC channels */ - for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { + while (cnt != MAX_MSG_TYPES) { if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType, &hv_cb_utils[cnt].data, - sizeof(struct hv_guid)) == 0 && - VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, - 2 * PAGE_SIZE, NULL, 0, - hv_cb_utils[cnt].callback, - newChannel) == 0) { - hv_cb_utils[cnt].channel = newChannel; + sizeof(struct hv_guid)) == 0) { DPRINT_INFO(VMBUS, "%s", - hv_cb_utils[cnt].log_msg); - count_hv_channel(); + hv_cb_utils[cnt].log_msg); + + if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, + 2 * PAGE_SIZE, NULL, 0, + hv_cb_utils[cnt].callback, + newChannel) == 0) + hv_cb_utils[cnt].channel = newChannel; } + cnt++; } } DPRINT_EXIT(VMBUS); diff --git a/trunk/drivers/staging/hv/hv_utils.c b/trunk/drivers/staging/hv/hv_utils.c index 2adc9b48ca9c..8a49aafea37a 100644 --- a/trunk/drivers/staging/hv/hv_utils.c +++ b/trunk/drivers/staging/hv/hv_utils.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include "logging.h" #include "osd.h" @@ -253,36 +251,10 @@ static void heartbeat_onchannelcallback(void *context) DPRINT_EXIT(VMBUS); } -static const struct pci_device_id __initconst -hv_utils_pci_table[] __maybe_unused = { - { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, hv_utils_pci_table); - - -static const struct dmi_system_id __initconst -hv_utils_dmi_table[] __maybe_unused = { - { - .ident = "Hyper-V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), - }, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); - - static int __init init_hyperv_utils(void) { printk(KERN_INFO "Registering HyperV Utility Driver\n"); - if (!dmi_check_system(hv_utils_dmi_table)) - return -ENODEV; - hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = &shutdown_onchannelcallback; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; diff --git a/trunk/drivers/staging/hv/vmbus.h b/trunk/drivers/staging/hv/vmbus.h index 3c14b2926e00..0c6ee0f487f3 100644 --- a/trunk/drivers/staging/hv/vmbus.h +++ b/trunk/drivers/staging/hv/vmbus.h @@ -74,6 +74,4 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx); void vmbus_child_driver_unregister(struct driver_context *driver_ctx); void vmbus_get_interface(struct vmbus_channel_interface *interface); -extern struct completion hv_channel_ready; - #endif /* _VMBUS_H_ */ diff --git a/trunk/drivers/staging/hv/vmbus_drv.c b/trunk/drivers/staging/hv/vmbus_drv.c index 22c80ece6388..c21731a12ca7 100644 --- a/trunk/drivers/staging/hv/vmbus_drv.c +++ b/trunk/drivers/staging/hv/vmbus_drv.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "version_info.h" #include "osd.h" #include "logging.h" @@ -357,8 +356,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) vmbus_drv_obj->GetChannelOffers(); - wait_for_completion(&hv_channel_ready); - cleanup: DPRINT_EXIT(VMBUS_DRV); diff --git a/trunk/drivers/staging/mrst-touchscreen/intel-mid-touch.c b/trunk/drivers/staging/mrst-touchscreen/intel-mid-touch.c index abba22f921be..1db00975a594 100644 --- a/trunk/drivers/staging/mrst-touchscreen/intel-mid-touch.c +++ b/trunk/drivers/staging/mrst-touchscreen/intel-mid-touch.c @@ -817,9 +817,9 @@ static int mrstouch_remove(struct spi_device *spi) free_irq(mrstouchdevp->irq, mrstouchdevp); input_unregister_device(mrstouchdevp->input); input_free_device(mrstouchdevp->input); + kfree(mrstouchdevp); if (mrstouchdevp->pendet_thrd) kthread_stop(mrstouchdevp->pendet_thrd); - kfree(mrstouchdevp); return 0; } diff --git a/trunk/drivers/staging/rt2860/usb_main_dev.c b/trunk/drivers/staging/rt2860/usb_main_dev.c index 674769d2b59b..b740662d095a 100644 --- a/trunk/drivers/staging/rt2860/usb_main_dev.c +++ b/trunk/drivers/staging/rt2860/usb_main_dev.c @@ -77,7 +77,6 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */ {USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */ {USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */ - {USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */ {USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */ {USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */ {USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */ diff --git a/trunk/drivers/staging/rtl8187se/r8180_core.c b/trunk/drivers/staging/rtl8187se/r8180_core.c index 49ab9fa9ffa7..dacefea78113 100644 --- a/trunk/drivers/staging/rtl8187se/r8180_core.c +++ b/trunk/drivers/staging/rtl8187se/r8180_core.c @@ -66,6 +66,8 @@ static int hwseqnum = 0; static int hwwep = 0; static int channels = 0x3fff; +#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) +#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5]) MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl); MODULE_AUTHOR("Andrea Merello "); diff --git a/trunk/drivers/staging/rtl8192su/r8192U_core.c b/trunk/drivers/staging/rtl8192su/r8192U_core.c index 1b6890611fb6..447d6474a70c 100644 --- a/trunk/drivers/staging/rtl8192su/r8192U_core.c +++ b/trunk/drivers/staging/rtl8192su/r8192U_core.c @@ -112,29 +112,28 @@ u32 rt_global_debug_component = \ #define CAM_CONTENT_COUNT 8 static const struct usb_device_id rtl8192_usb_id_tbl[] = { - {USB_DEVICE(0x0bda, 0x8171)}, /* Realtek */ - {USB_DEVICE(0x0bda, 0x8172)}, - {USB_DEVICE(0x0bda, 0x8173)}, - {USB_DEVICE(0x0bda, 0x8174)}, - {USB_DEVICE(0x0bda, 0x8712)}, - {USB_DEVICE(0x0bda, 0x8713)}, - {USB_DEVICE(0x07aa, 0x0047)}, - {USB_DEVICE(0x07d1, 0x3303)}, - {USB_DEVICE(0x07d1, 0x3302)}, - {USB_DEVICE(0x07d1, 0x3300)}, - {USB_DEVICE(0x1740, 0x9603)}, - {USB_DEVICE(0x1740, 0x9605)}, - {USB_DEVICE(0x050d, 0x815F)}, + /* Realtek */ + {USB_DEVICE(0x0bda, 0x8171)}, + {USB_DEVICE(0x0bda, 0x8192)}, + {USB_DEVICE(0x0bda, 0x8709)}, + /* Corega */ + {USB_DEVICE(0x07aa, 0x0043)}, + /* Belkin */ + {USB_DEVICE(0x050d, 0x805E)}, + {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */ + /* Sitecom */ + {USB_DEVICE(0x0df6, 0x0031)}, + {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */ + /* EnGenius */ + {USB_DEVICE(0x1740, 0x9201)}, + /* Dlink */ + {USB_DEVICE(0x2001, 0x3301)}, + /* Zinwell */ + {USB_DEVICE(0x5a57, 0x0290)}, + /* Guillemot */ {USB_DEVICE(0x06f8, 0xe031)}, - {USB_DEVICE(0x7392, 0x7611)}, - {USB_DEVICE(0x7392, 0x7612)}, - {USB_DEVICE(0x7392, 0x7622)}, - {USB_DEVICE(0x0DF6, 0x0045)}, - {USB_DEVICE(0x0E66, 0x0015)}, - {USB_DEVICE(0x0E66, 0x0016)}, - {USB_DEVICE(0x0b05, 0x1786)}, - /* these are not in the official list */ - {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */ + //92SU + {USB_DEVICE(0x0bda, 0x8172)}, {} }; diff --git a/trunk/drivers/staging/rtl8192u/r8192U_core.c b/trunk/drivers/staging/rtl8192u/r8192U_core.c index f38472c2e75c..2bede271a2f0 100644 --- a/trunk/drivers/staging/rtl8192u/r8192U_core.c +++ b/trunk/drivers/staging/rtl8192u/r8192U_core.c @@ -121,8 +121,6 @@ static const struct usb_device_id rtl8192_usb_id_tbl[] = { {USB_DEVICE(0x2001, 0x3301)}, /* Zinwell */ {USB_DEVICE(0x5a57, 0x0290)}, - /* LG */ - {USB_DEVICE(0x043e, 0x7a01)}, {} }; diff --git a/trunk/drivers/staging/usbip/usbip_common.c b/trunk/drivers/staging/usbip/usbip_common.c index 6a499f0eb594..52408164036f 100644 --- a/trunk/drivers/staging/usbip/usbip_common.c +++ b/trunk/drivers/staging/usbip/usbip_common.c @@ -378,67 +378,47 @@ int usbip_thread(void *param) complete_and_exit(&ut->thread_done, 0); } -static void stop_rx_thread(struct usbip_device *ud) -{ - if (ud->tcp_rx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_rx.thread, 1); - wait_for_completion(&ud->tcp_rx.thread_done); - usbip_udbg("rx_thread for ud %p has finished\n", ud); - } -} - -static void stop_tx_thread(struct usbip_device *ud) -{ - if (ud->tcp_tx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_tx.thread, 1); - wait_for_completion(&ud->tcp_tx.thread_done); - usbip_udbg("tx_thread for ud %p has finished\n", ud); - } -} - int usbip_start_threads(struct usbip_device *ud) { /* * threads are invoked per one device (per one connection). */ struct task_struct *th; - int err = 0; th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip"); if (IS_ERR(th)) { printk(KERN_WARNING "Unable to start control thread\n"); - err = PTR_ERR(th); - goto ust_exit; + return PTR_ERR(th); } - th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip"); if (IS_ERR(th)) { printk(KERN_WARNING "Unable to start control thread\n"); - err = PTR_ERR(th); - goto tx_thread_err; + return PTR_ERR(th); } /* confirm threads are starting */ wait_for_completion(&ud->tcp_rx.thread_done); wait_for_completion(&ud->tcp_tx.thread_done); - return 0; - -tx_thread_err: - stop_rx_thread(ud); - -ust_exit: - return err; } EXPORT_SYMBOL_GPL(usbip_start_threads); void usbip_stop_threads(struct usbip_device *ud) { /* kill threads related to this sdev, if v.c. exists */ - stop_rx_thread(ud); - stop_tx_thread(ud); + if (ud->tcp_rx.thread != NULL) { + send_sig(SIGKILL, ud->tcp_rx.thread, 1); + wait_for_completion(&ud->tcp_rx.thread_done); + usbip_udbg("rx_thread for ud %p has finished\n", ud); + } + + if (ud->tcp_tx.thread != NULL) { + send_sig(SIGKILL, ud->tcp_tx.thread, 1); + wait_for_completion(&ud->tcp_tx.thread_done); + usbip_udbg("tx_thread for ud %p has finished\n", ud); + } } EXPORT_SYMBOL_GPL(usbip_stop_threads); diff --git a/trunk/drivers/staging/wlags49_h2/wl_enc.c b/trunk/drivers/staging/wlags49_h2/wl_enc.c index 26cf5486edd6..48c44c8fdb28 100644 --- a/trunk/drivers/staging/wlags49_h2/wl_enc.c +++ b/trunk/drivers/staging/wlags49_h2/wl_enc.c @@ -62,7 +62,6 @@ /******************************************************************************* * include files ******************************************************************************/ -#include #include #include diff --git a/trunk/drivers/staging/wlags49_h2/wl_sysfs.h b/trunk/drivers/staging/wlags49_h2/wl_sysfs.h index fa658c38001e..6d96d03cf490 100644 --- a/trunk/drivers/staging/wlags49_h2/wl_sysfs.h +++ b/trunk/drivers/staging/wlags49_h2/wl_sysfs.h @@ -2,6 +2,6 @@ extern void register_wlags_sysfs(struct net_device *); extern void unregister_wlags_sysfs(struct net_device *); #else -static inline void register_wlags_sysfs(struct net_device *net) { } -static inline void unregister_wlags_sysfs(struct net_device *net) { } +static void register_wlags_sysfs(struct net_device *) { return; }; +static void unregister_wlags_sysfs(struct net_device *) { return; }; #endif diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index a6bd53ace035..de98a94d1853 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -1272,7 +1272,8 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) static void choose_wakeup(struct usb_device *udev, pm_message_t msg) { - int w; + int w, i; + struct usb_interface *intf; /* Remote wakeup is needed only when we actually go to sleep. * For things like FREEZE and QUIESCE, if the device is already @@ -1284,10 +1285,16 @@ static void choose_wakeup(struct usb_device *udev, pm_message_t msg) return; } - /* Enable remote wakeup if it is allowed, even if no interface drivers + /* If remote wakeup is permitted, see whether any interface drivers * actually want it. */ - w = device_may_wakeup(&udev->dev); + w = 0; + if (device_may_wakeup(&udev->dev) && udev->actconfig) { + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + w |= intf->needs_remote_wakeup; + } + } /* If the device is autosuspended with the wrong wakeup setting, * autoresume now so the setting can be changed. diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index fd4c36ea5e46..a73e08fdab36 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -416,11 +416,8 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, /* A length of zero means transfer the whole sg list */ len = length; if (len == 0) { - struct scatterlist *sg2; - int j; - - for_each_sg(sg, sg2, nents, j) - len += sg2->length; + for_each_sg(sg, sg, nents, i) + len += sg->length; } } else { /* diff --git a/trunk/drivers/usb/gadget/f_eem.c b/trunk/drivers/usb/gadget/f_eem.c index 95dd4662d6a8..38226e9a371d 100644 --- a/trunk/drivers/usb/gadget/f_eem.c +++ b/trunk/drivers/usb/gadget/f_eem.c @@ -469,7 +469,8 @@ static int eem_unwrap(struct gether *port, crc = get_unaligned_le32(skb->data + len - ETH_FCS_LEN); crc2 = ~crc32_le(~0, - skb->data, len - ETH_FCS_LEN); + skb->data, + skb->len - ETH_FCS_LEN); } else { crc = get_unaligned_be32(skb->data + len - ETH_FCS_LEN); diff --git a/trunk/drivers/usb/gadget/f_mass_storage.c b/trunk/drivers/usb/gadget/f_mass_storage.c index 4ce899c9b165..7d05a0be5c60 100644 --- a/trunk/drivers/usb/gadget/f_mass_storage.c +++ b/trunk/drivers/usb/gadget/f_mass_storage.c @@ -321,8 +321,8 @@ struct fsg_dev; /* Data shared by all the FSG instances. */ struct fsg_common { struct usb_gadget *gadget; - struct fsg_dev *fsg, *new_fsg; - wait_queue_head_t fsg_wait; + struct fsg_dev *fsg; + struct fsg_dev *prev_fsg; /* filesem protects: backing files in use */ struct rw_semaphore filesem; @@ -351,6 +351,7 @@ struct fsg_common { enum fsg_state state; /* For exception handling */ unsigned int exception_req_tag; + u8 config, new_config; enum data_direction data_dir; u32 data_size; u32 data_size_from_cmnd; @@ -594,7 +595,7 @@ static int fsg_setup(struct usb_function *f, u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); - if (!fsg_is_set(fsg->common)) + if (!fsg->common->config) return -EOPNOTSUPP; switch (ctrl->bRequest) { @@ -2302,20 +2303,24 @@ static int alloc_request(struct fsg_common *common, struct usb_ep *ep, return -ENOMEM; } -/* Reset interface setting and re-init endpoint state (toggle etc). */ -static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) +/* + * Reset interface setting and re-init endpoint state (toggle etc). + * Call with altsetting < 0 to disable the interface. The only other + * available altsetting is 0, which enables the interface. + */ +static int do_set_interface(struct fsg_common *common, int altsetting) { - const struct usb_endpoint_descriptor *d; - struct fsg_dev *fsg; - int i, rc = 0; + int rc = 0; + int i; + const struct usb_endpoint_descriptor *d; if (common->running) DBG(common, "reset interface\n"); reset: /* Deallocate the requests */ - if (common->fsg) { - fsg = common->fsg; + if (common->prev_fsg) { + struct fsg_dev *fsg = common->prev_fsg; for (i = 0; i < FSG_NUM_BUFFERS; ++i) { struct fsg_buffhd *bh = &common->buffhds[i]; @@ -2340,53 +2345,88 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) fsg->bulk_out_enabled = 0; } - common->fsg = NULL; - wake_up(&common->fsg_wait); + common->prev_fsg = 0; } common->running = 0; - if (!new_fsg || rc) + if (altsetting < 0 || rc != 0) return rc; - common->fsg = new_fsg; - fsg = common->fsg; + DBG(common, "set interface %d\n", altsetting); - /* Enable the endpoints */ - d = fsg_ep_desc(common->gadget, - &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); - rc = enable_endpoint(common, fsg->bulk_in, d); - if (rc) - goto reset; - fsg->bulk_in_enabled = 1; - - d = fsg_ep_desc(common->gadget, - &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); - rc = enable_endpoint(common, fsg->bulk_out, d); - if (rc) - goto reset; - fsg->bulk_out_enabled = 1; - common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); - clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); + if (fsg_is_set(common)) { + struct fsg_dev *fsg = common->fsg; + common->prev_fsg = common->fsg; - /* Allocate the requests */ - for (i = 0; i < FSG_NUM_BUFFERS; ++i) { - struct fsg_buffhd *bh = &common->buffhds[i]; - - rc = alloc_request(common, fsg->bulk_in, &bh->inreq); + /* Enable the endpoints */ + d = fsg_ep_desc(common->gadget, + &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); + rc = enable_endpoint(common, fsg->bulk_in, d); if (rc) goto reset; - rc = alloc_request(common, fsg->bulk_out, &bh->outreq); + fsg->bulk_in_enabled = 1; + + d = fsg_ep_desc(common->gadget, + &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); + rc = enable_endpoint(common, fsg->bulk_out, d); if (rc) goto reset; - bh->inreq->buf = bh->outreq->buf = bh->buf; - bh->inreq->context = bh->outreq->context = bh; - bh->inreq->complete = bulk_in_complete; - bh->outreq->complete = bulk_out_complete; + fsg->bulk_out_enabled = 1; + common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); + clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); + + /* Allocate the requests */ + for (i = 0; i < FSG_NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &common->buffhds[i]; + + rc = alloc_request(common, fsg->bulk_in, &bh->inreq); + if (rc) + goto reset; + rc = alloc_request(common, fsg->bulk_out, &bh->outreq); + if (rc) + goto reset; + bh->inreq->buf = bh->outreq->buf = bh->buf; + bh->inreq->context = bh->outreq->context = bh; + bh->inreq->complete = bulk_in_complete; + bh->outreq->complete = bulk_out_complete; + } + + common->running = 1; + for (i = 0; i < common->nluns; ++i) + common->luns[i].unit_attention_data = SS_RESET_OCCURRED; + return rc; + } else { + return -EIO; + } +} + + +/* + * Change our operational configuration. This code must agree with the code + * that returns config descriptors, and with interface altsetting code. + * + * It's also responsible for power management interactions. Some + * configurations might not work with our current power sources. + * For now we just assume the gadget is always self-powered. + */ +static int do_set_config(struct fsg_common *common, u8 new_config) +{ + int rc = 0; + + /* Disable the single interface */ + if (common->config != 0) { + DBG(common, "reset config\n"); + common->config = 0; + rc = do_set_interface(common, -1); } - common->running = 1; - for (i = 0; i < common->nluns; ++i) - common->luns[i].unit_attention_data = SS_RESET_OCCURRED; + /* Enable the interface */ + if (new_config != 0) { + common->config = new_config; + rc = do_set_interface(common, 0); + if (rc != 0) + common->config = 0; /* Reset on errors */ + } return rc; } @@ -2397,7 +2437,9 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->new_fsg = fsg; + fsg->common->prev_fsg = fsg->common->fsg; + fsg->common->fsg = fsg; + fsg->common->new_config = 1; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); return 0; } @@ -2405,7 +2447,9 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) static void fsg_disable(struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->new_fsg = NULL; + fsg->common->prev_fsg = fsg->common->fsg; + fsg->common->fsg = fsg; + fsg->common->new_config = 0; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); } @@ -2415,17 +2459,19 @@ static void fsg_disable(struct usb_function *f) static void handle_exception(struct fsg_common *common) { siginfo_t info; + int sig; int i; struct fsg_buffhd *bh; enum fsg_state old_state; + u8 new_config; struct fsg_lun *curlun; unsigned int exception_req_tag; + int rc; /* Clear the existing signals. Anything but SIGUSR1 is converted * into a high-priority EXIT exception. */ for (;;) { - int sig = - dequeue_signal_lock(current, ¤t->blocked, &info); + sig = dequeue_signal_lock(current, ¤t->blocked, &info); if (!sig) break; if (sig != SIGUSR1) { @@ -2436,7 +2482,7 @@ static void handle_exception(struct fsg_common *common) } /* Cancel all the pending transfers */ - if (likely(common->fsg)) { + if (fsg_is_set(common)) { for (i = 0; i < FSG_NUM_BUFFERS; ++i) { bh = &common->buffhds[i]; if (bh->inreq_busy) @@ -2477,6 +2523,7 @@ static void handle_exception(struct fsg_common *common) common->next_buffhd_to_fill = &common->buffhds[0]; common->next_buffhd_to_drain = &common->buffhds[0]; exception_req_tag = common->exception_req_tag; + new_config = common->new_config; old_state = common->state; if (old_state == FSG_STATE_ABORT_BULK_OUT) @@ -2526,12 +2573,12 @@ static void handle_exception(struct fsg_common *common) break; case FSG_STATE_CONFIG_CHANGE: - do_set_interface(common, common->new_fsg); + rc = do_set_config(common, new_config); break; case FSG_STATE_EXIT: case FSG_STATE_TERMINATED: - do_set_interface(common, NULL); /* Free resources */ + do_set_config(common, 0); /* Free resources */ spin_lock_irq(&common->lock); common->state = FSG_STATE_TERMINATED; /* Stop the thread */ spin_unlock_irq(&common->lock); @@ -2816,7 +2863,6 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, goto error_release; } init_completion(&common->thread_notifier); - init_waitqueue_head(&common->fsg_wait); #undef OR @@ -2911,17 +2957,9 @@ static void fsg_common_release(struct kref *ref) static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); - struct fsg_common *common = fsg->common; DBG(fsg, "unbind\n"); - if (fsg->common->fsg == fsg) { - fsg->common->new_fsg = NULL; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); - /* FIXME: make interruptible or killable somehow? */ - wait_event(common->fsg_wait, common->fsg != fsg); - } - - fsg_common_put(common); + fsg_common_put(fsg->common); usb_free_descriptors(fsg->function.descriptors); usb_free_descriptors(fsg->function.hs_descriptors); kfree(fsg); @@ -2932,6 +2970,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); struct usb_gadget *gadget = c->cdev->gadget; + int rc; int i; struct usb_ep *ep; @@ -2957,11 +2996,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; - /* Copy descriptors */ - f->descriptors = usb_copy_descriptors(fsg_fs_function); - if (unlikely(!f->descriptors)) - return -ENOMEM; - if (gadget_is_dualspeed(gadget)) { /* Assume endpoint addresses are the same for both speeds */ fsg_hs_bulk_in_desc.bEndpointAddress = @@ -2969,17 +3003,16 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) fsg_hs_bulk_out_desc.bEndpointAddress = fsg_fs_bulk_out_desc.bEndpointAddress; f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); - if (unlikely(!f->hs_descriptors)) { - usb_free_descriptors(f->descriptors); + if (unlikely(!f->hs_descriptors)) return -ENOMEM; - } } return 0; autoconf_fail: ERROR(fsg, "unable to autoconfigure all endpoints\n"); - return -ENOTSUPP; + rc = -ENOTSUPP; + return rc; } @@ -3003,6 +3036,11 @@ static int fsg_add(struct usb_composite_dev *cdev, fsg->function.name = FSG_DRIVER_DESC; fsg->function.strings = fsg_strings_array; + fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function); + if (unlikely(!fsg->function.descriptors)) { + rc = -ENOMEM; + goto error_free_fsg; + } fsg->function.bind = fsg_bind; fsg->function.unbind = fsg_unbind; fsg->function.setup = fsg_setup; @@ -3018,9 +3056,19 @@ static int fsg_add(struct usb_composite_dev *cdev, rc = usb_add_function(c, &fsg->function); if (unlikely(rc)) - kfree(fsg); - else - fsg_common_get(fsg->common); + goto error_free_all; + + fsg_common_get(fsg->common); + return 0; + +error_free_all: + usb_free_descriptors(fsg->function.descriptors); + /* fsg_bind() might have copied those; or maybe not? who cares + * -- free it just in case. */ + usb_free_descriptors(fsg->function.hs_descriptors); +error_free_fsg: + kfree(fsg); + return rc; } diff --git a/trunk/drivers/usb/gadget/g_ffs.c b/trunk/drivers/usb/gadget/g_ffs.c index d1af253a9105..4b0e4a040d6f 100644 --- a/trunk/drivers/usb/gadget/g_ffs.c +++ b/trunk/drivers/usb/gadget/g_ffs.c @@ -392,17 +392,6 @@ static int __gfs_do_config(struct usb_configuration *c, if (unlikely(ret < 0)) return ret; - /* After previous do_configs there may be some invalid - * pointers in c->interface array. This happens every time - * a user space function with fewer interfaces than a user - * space function that was run before the new one is run. The - * compasit's set_config() assumes that if there is no more - * then MAX_CONFIG_INTERFACES interfaces in a configuration - * then there is a NULL pointer after the last interface in - * c->interface array. We need to make sure this is true. */ - if (c->next_interface_id < ARRAY_SIZE(c->interface)) - c->interface[c->next_interface_id] = NULL; - return 0; } diff --git a/trunk/drivers/usb/gadget/printer.c b/trunk/drivers/usb/gadget/printer.c index 4c3ac5c42237..43abf55d8c60 100644 --- a/trunk/drivers/usb/gadget/printer.c +++ b/trunk/drivers/usb/gadget/printer.c @@ -82,7 +82,7 @@ static struct class *usb_gadget_class; struct printer_dev { spinlock_t lock; /* lock this structure */ /* lock buffer lists during read/write calls */ - struct mutex lock_printer_io; + spinlock_t lock_printer_io; struct usb_gadget *gadget; struct usb_request *req; /* for control responses */ u8 config; @@ -567,7 +567,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) DBG(dev, "printer_read trying to read %d bytes\n", (int)len); - mutex_lock(&dev->lock_printer_io); + spin_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); /* We will use this flag later to check if a printer reset happened @@ -601,7 +601,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) * call or not. */ if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -648,7 +648,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) if (dev->reset_printer) { list_add(¤t_rx_req->list, &dev->rx_reqs); spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -673,7 +673,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) dev->current_rx_buf = current_rx_buf; spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); @@ -697,7 +697,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (len == 0) return -EINVAL; - mutex_lock(&dev->lock_printer_io); + spin_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); /* Check if a printer reset happens while we have interrupts on */ @@ -713,7 +713,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) * a NON-Blocking call or not. */ if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -752,7 +752,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (copy_from_user(req->buf, buf, size)) { list_add(&req->list, &dev->tx_reqs); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); return bytes_copied; } @@ -766,14 +766,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (dev->reset_printer) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); return -EAGAIN; } if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -782,7 +782,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) } spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); @@ -820,11 +820,11 @@ printer_poll(struct file *fd, poll_table *wait) unsigned long flags; int status = 0; - mutex_lock(&dev->lock_printer_io); + spin_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); setup_rx_reqs(dev); spin_unlock_irqrestore(&dev->lock, flags); - mutex_unlock(&dev->lock_printer_io); + spin_unlock(&dev->lock_printer_io); poll_wait(fd, &dev->rx_wait, wait); poll_wait(fd, &dev->tx_wait, wait); @@ -1461,7 +1461,7 @@ printer_bind(struct usb_gadget *gadget) } spin_lock_init(&dev->lock); - mutex_init(&dev->lock_printer_io); + spin_lock_init(&dev->lock_printer_io); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->tx_reqs_active); INIT_LIST_HEAD(&dev->rx_reqs); @@ -1594,7 +1594,7 @@ cleanup(void) { int status; - mutex_lock(&usb_printer_gadget.lock_printer_io); + spin_lock(&usb_printer_gadget.lock_printer_io); class_destroy(usb_gadget_class); unregister_chrdev_region(g_printer_devno, 2); @@ -1602,6 +1602,6 @@ cleanup(void) if (status) ERROR(dev, "usb_gadget_unregister_driver %x\n", status); - mutex_unlock(&usb_printer_gadget.lock_printer_io); + spin_unlock(&usb_printer_gadget.lock_printer_io); } module_exit(cleanup); diff --git a/trunk/drivers/usb/gadget/s3c2410_udc.c b/trunk/drivers/usb/gadget/s3c2410_udc.c index e724a051bfdd..d5f4c1d45c97 100644 --- a/trunk/drivers/usb/gadget/s3c2410_udc.c +++ b/trunk/drivers/usb/gadget/s3c2410_udc.c @@ -1700,13 +1700,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!driver || driver != udc->driver || !driver->unbind) return -EINVAL; - dprintk(DEBUG_NORMAL, "usb_gadget_unregister_driver() '%s'\n", + dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n", driver->driver.name); - /* report disconnect */ - if (driver->disconnect) - driver->disconnect(&udc->gadget); - driver->unbind(&udc->gadget); device_del(&udc->gadget.dev); diff --git a/trunk/drivers/usb/gadget/u_serial.c b/trunk/drivers/usb/gadget/u_serial.c index 3e8dcb5455e3..16bdf77f582a 100644 --- a/trunk/drivers/usb/gadget/u_serial.c +++ b/trunk/drivers/usb/gadget/u_serial.c @@ -536,11 +536,17 @@ static void gs_rx_push(unsigned long _port) list_move(&req->list, &port->read_pool); } - /* Push from tty to ldisc; without low_latency set this is handled by - * a workqueue, so we won't get callbacks and can hold port_lock + /* Push from tty to ldisc; this is immediate with low_latency, and + * may trigger callbacks to this driver ... so drop the spinlock. */ if (tty && do_push) { + spin_unlock_irq(&port->port_lock); tty_flip_buffer_push(tty); + wake_up_interruptible(&tty->read_wait); + spin_lock_irq(&port->port_lock); + + /* tty may have been closed */ + tty = port->port_tty; } @@ -778,6 +784,11 @@ static int gs_open(struct tty_struct *tty, struct file *file) port->open_count = 1; port->openclose = false; + /* low_latency means ldiscs work in tasklet context, without + * needing a workqueue schedule ... easier to keep up. + */ + tty->low_latency = 1; + /* if connected, start the I/O stream */ if (port->port_usb) { struct gserial *gser = port->port_usb; @@ -1184,7 +1195,6 @@ void gserial_cleanup(void) n_ports = 0; tty_unregister_driver(gs_tty_driver); - put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; pr_debug("%s: cleaned up ttyGS* support\n", __func__); diff --git a/trunk/drivers/usb/host/ehci-mxc.c b/trunk/drivers/usb/host/ehci-mxc.c index bd4027745aa7..544ccfd7056e 100644 --- a/trunk/drivers/usb/host/ehci-mxc.c +++ b/trunk/drivers/usb/host/ehci-mxc.c @@ -207,17 +207,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) /* Initialize the transceiver */ if (pdata->otg) { pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; - ret = otg_init(pdata->otg); - if (ret) { - dev_err(dev, "unable to init transceiver, probably missing\n"); - ret = -ENODEV; - goto err_add; - } - ret = otg_set_vbus(pdata->otg, 1); - if (ret) { + if (otg_init(pdata->otg) != 0) + dev_err(dev, "unable to init transceiver\n"); + else if (otg_set_vbus(pdata->otg, 1) != 0) dev_err(dev, "unable to enable vbus on transceiver\n"); - goto err_add; - } } priv->hcd = hcd; diff --git a/trunk/drivers/usb/host/isp1362-hcd.c b/trunk/drivers/usb/host/isp1362-hcd.c index 0587ad4ce5c2..20a0dfe0fe36 100644 --- a/trunk/drivers/usb/host/isp1362-hcd.c +++ b/trunk/drivers/usb/host/isp1362-hcd.c @@ -2224,9 +2224,12 @@ static void remove_debug_file(struct isp1362_hcd *isp1362_hcd) /*-------------------------------------------------------------------------*/ -static void __isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) +static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) { int tmp = 20; + unsigned long flags; + + spin_lock_irqsave(&isp1362_hcd->lock, flags); isp1362_write_reg16(isp1362_hcd, HCSWRES, HCSWRES_MAGIC); isp1362_write_reg32(isp1362_hcd, HCCMDSTAT, OHCI_HCR); @@ -2237,14 +2240,6 @@ static void __isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) } if (!tmp) pr_err("Software reset timeout\n"); -} - -static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) -{ - unsigned long flags; - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - __isp1362_sw_reset(isp1362_hcd); spin_unlock_irqrestore(&isp1362_hcd->lock, flags); } @@ -2423,7 +2418,7 @@ static void isp1362_hc_stop(struct usb_hcd *hcd) if (isp1362_hcd->board && isp1362_hcd->board->reset) isp1362_hcd->board->reset(hcd->self.controller, 1); else - __isp1362_sw_reset(isp1362_hcd); + isp1362_sw_reset(isp1362_hcd); if (isp1362_hcd->board && isp1362_hcd->board->clock) isp1362_hcd->board->clock(hcd->self.controller, 0); diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index 77be3c24a427..1a2bb4ce638f 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -1065,7 +1065,7 @@ static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port) else if (speed == LSMODE) rh->port |= USB_PORT_STAT_LOW_SPEED; - rh->port &= ~USB_PORT_STAT_RESET; + rh->port &= USB_PORT_STAT_RESET; rh->port |= USB_PORT_STAT_ENABLE; } diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 94e6934edb09..9012098add6b 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -182,12 +182,8 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer * set, but other sections talk about dealing with the chain bit set. This was * fixed in the 0.96 specification errata, but we have to assume that all 0.95 * xHCI hardware can't handle the chain bit being cleared on a link TRB. - * - * @more_trbs_coming: Will you enqueue more TRBs before calling - * prepare_transfer()? */ -static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, - bool consumer, bool more_trbs_coming) +static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) { u32 chain; union xhci_trb *next; @@ -203,28 +199,15 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, while (last_trb(xhci, ring, ring->enq_seg, next)) { if (!consumer) { if (ring != xhci->event_ring) { - /* - * If the caller doesn't plan on enqueueing more - * TDs before ringing the doorbell, then we - * don't want to give the link TRB to the - * hardware just yet. We'll give the link TRB - * back in prepare_ring() just before we enqueue - * the TD at the top of the ring. - */ - if (!chain && !more_trbs_coming) - break; + if (chain) { + next->link.control |= TRB_CHAIN; - /* If we're not dealing with 0.95 hardware, - * carry over the chain bit of the previous TRB - * (which may mean the chain bit is cleared). - */ - if (!xhci_link_trb_quirk(xhci)) { - next->link.control &= ~TRB_CHAIN; - next->link.control |= chain; + /* Give this link TRB to the hardware */ + wmb(); + next->link.control ^= TRB_CYCLE; + } else { + break; } - /* Give this link TRB to the hardware */ - wmb(); - next->link.control ^= TRB_CYCLE; } /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { @@ -1724,12 +1707,9 @@ void xhci_handle_event(struct xhci_hcd *xhci) /* * Generic function for queueing a TRB on a ring. * The caller must have checked to make sure there's room on the ring. - * - * @more_trbs_coming: Will you enqueue more TRBs before calling - * prepare_transfer()? */ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, - bool consumer, bool more_trbs_coming, + bool consumer, u32 field1, u32 field2, u32 field3, u32 field4) { struct xhci_generic_trb *trb; @@ -1739,7 +1719,7 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, trb->field[1] = field2; trb->field[2] = field3; trb->field[3] = field4; - inc_enq(xhci, ring, consumer, more_trbs_coming); + inc_enq(xhci, ring, consumer); } /* @@ -2008,7 +1988,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int trb_buff_len, this_sg_len, running_total; bool first_trb; u64 addr; - bool more_trbs_coming; struct xhci_generic_trb *start_trb; int start_cycle; @@ -2094,11 +2073,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); - if (num_trbs > 1) - more_trbs_coming = true; - else - more_trbs_coming = false; - queue_trb(xhci, ep_ring, false, more_trbs_coming, + queue_trb(xhci, ep_ring, false, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -2149,7 +2124,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int num_trbs; struct xhci_generic_trb *start_trb; bool first_trb; - bool more_trbs_coming; int start_cycle; u32 field, length_field; @@ -2238,11 +2212,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); - if (num_trbs > 1) - more_trbs_coming = true; - else - more_trbs_coming = false; - queue_trb(xhci, ep_ring, false, more_trbs_coming, + queue_trb(xhci, ep_ring, false, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -2321,7 +2291,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Queue setup TRB - see section 6.4.1.2.1 */ /* FIXME better way to translate setup_packet into two u32 fields? */ setup = (struct usb_ctrlrequest *) urb->setup_packet; - queue_trb(xhci, ep_ring, false, true, + queue_trb(xhci, ep_ring, false, /* FIXME endianness is probably going to bite my ass here. */ setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16, setup->wIndex | setup->wLength << 16, @@ -2337,7 +2307,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_DIR_IN; - queue_trb(xhci, ep_ring, false, true, + queue_trb(xhci, ep_ring, false, lower_32_bits(urb->transfer_dma), upper_32_bits(urb->transfer_dma), length_field, @@ -2354,7 +2324,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field = 0; else field = TRB_DIR_IN; - queue_trb(xhci, ep_ring, false, false, + queue_trb(xhci, ep_ring, false, 0, 0, TRB_INTR_TARGET(0), @@ -2391,7 +2361,7 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, "unfailable commands failed.\n"); return -ENOMEM; } - queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3, + queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3, field4 | xhci->cmd_ring->cycle_state); return 0; } diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index 3b795c56221f..fad70bc83555 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -219,8 +219,8 @@ static int musb_ulpi_write(struct otg_transceiver *otg, return 0; } #else -#define musb_ulpi_read NULL -#define musb_ulpi_write NULL +#define musb_ulpi_read(a, b) NULL +#define musb_ulpi_write(a, b, c) NULL #endif static struct otg_io_access_ops musb_ulpi_access = { @@ -451,6 +451,10 @@ void musb_hnp_stop(struct musb *musb) * @param power */ +#define STAGE0_MASK (MUSB_INTR_RESUME | MUSB_INTR_SESSREQ \ + | MUSB_INTR_VBUSERROR | MUSB_INTR_CONNECT \ + | MUSB_INTR_RESET) + static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl, u8 power) { @@ -638,7 +642,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, handled = IRQ_HANDLED; } -#endif + if (int_usb & MUSB_INTR_SUSPEND) { DBG(1, "SUSPEND (%s) devctl %02x power %02x\n", otg_state_string(musb), devctl, power); @@ -701,7 +705,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } } -#ifdef CONFIG_USB_MUSB_HDRC_HCD if (int_usb & MUSB_INTR_CONNECT) { struct usb_hcd *hcd = musb_to_hcd(musb); void __iomem *mbase = musb->mregs; @@ -1594,7 +1597,7 @@ irqreturn_t musb_interrupt(struct musb *musb) /* the core can interrupt us for multiple reasons; docs have * a generic interrupt flowchart to follow */ - if (musb->int_usb) + if (musb->int_usb & STAGE0_MASK) retval |= musb_stage0_irq(musb, musb->int_usb, devctl, power); diff --git a/trunk/drivers/usb/musb/musb_core.h b/trunk/drivers/usb/musb/musb_core.h index 91d67794e350..b22d02dea7d3 100644 --- a/trunk/drivers/usb/musb/musb_core.h +++ b/trunk/drivers/usb/musb/musb_core.h @@ -470,8 +470,7 @@ struct musb_csr_regs { struct musb_context_registers { -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_PM u32 otg_sysconfig, otg_forcestandby; #endif u8 power; @@ -485,8 +484,7 @@ struct musb_context_registers { struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_PM extern void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context); extern void musb_platform_restore_context(struct musb *musb, diff --git a/trunk/drivers/usb/musb/musbhsdma.c b/trunk/drivers/usb/musb/musbhsdma.c index dc66e4376d49..1008044a3bbc 100644 --- a/trunk/drivers/usb/musb/musbhsdma.c +++ b/trunk/drivers/usb/musb/musbhsdma.c @@ -132,9 +132,18 @@ static void configure_channel(struct dma_channel *channel, if (mode) { csr |= 1 << MUSB_HSDMA_MODE1_SHIFT; BUG_ON(len < packet_sz); + + if (packet_sz >= 64) { + csr |= MUSB_HSDMA_BURSTMODE_INCR16 + << MUSB_HSDMA_BURSTMODE_SHIFT; + } else if (packet_sz >= 32) { + csr |= MUSB_HSDMA_BURSTMODE_INCR8 + << MUSB_HSDMA_BURSTMODE_SHIFT; + } else if (packet_sz >= 16) { + csr |= MUSB_HSDMA_BURSTMODE_INCR4 + << MUSB_HSDMA_BURSTMODE_SHIFT; + } } - csr |= MUSB_HSDMA_BURSTMODE_INCR16 - << MUSB_HSDMA_BURSTMODE_SHIFT; csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) | (1 << MUSB_HSDMA_ENABLE_SHIFT) diff --git a/trunk/drivers/usb/otg/ulpi.c b/trunk/drivers/usb/otg/ulpi.c index d331b222ad21..b1b346932946 100644 --- a/trunk/drivers/usb/otg/ulpi.c +++ b/trunk/drivers/usb/otg/ulpi.c @@ -59,17 +59,12 @@ static int ulpi_set_flags(struct otg_transceiver *otg) static int ulpi_init(struct otg_transceiver *otg) { - int i, vid, pid, ret; - u32 ulpi_id = 0; - - for (i = 0; i < 4; i++) { - ret = otg_io_read(otg, ULPI_PRODUCT_ID_HIGH - i); - if (ret < 0) - return ret; - ulpi_id = (ulpi_id << 8) | ret; - } - vid = ulpi_id & 0xffff; - pid = ulpi_id >> 16; + int i, vid, pid; + + vid = (otg_io_read(otg, ULPI_VENDOR_ID_HIGH) << 8) | + otg_io_read(otg, ULPI_VENDOR_ID_LOW); + pid = (otg_io_read(otg, ULPI_PRODUCT_ID_HIGH) << 8) | + otg_io_read(otg, ULPI_PRODUCT_ID_LOW); pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index da7e334b0407..79dd1ae195e5 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -653,6 +653,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, + { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index bbc159a1df45..94d86c3febcb 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -500,6 +500,13 @@ #define CONTEC_VID 0x06CE /* Vendor ID */ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ +/* + * Contec products (http://www.contec.com) + * Submitted by Daniel Sangorrin + */ +#define CONTEC_VID 0x06CE /* Vendor ID */ +#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ + /* * Definitions for B&B Electronics products. */ diff --git a/trunk/drivers/usb/serial/qcserial.c b/trunk/drivers/usb/serial/qcserial.c index 93d72eb8cafc..04bb759536bb 100644 --- a/trunk/drivers/usb/serial/qcserial.c +++ b/trunk/drivers/usb/serial/qcserial.c @@ -139,7 +139,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) "Could not set interface, error %d\n", retval); retval = -ENODEV; - kfree(data); } return retval; } @@ -156,7 +155,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) "Could not set interface, error %d\n", retval); retval = -ENODEV; - kfree(data); } return retval; } @@ -165,7 +163,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) default: dev_err(&serial->dev->dev, "unknown number of interfaces: %d\n", nintf); - kfree(data); return -ENODEV; } diff --git a/trunk/drivers/video/geode/gxfb_core.c b/trunk/drivers/video/geode/gxfb_core.c index 70b1d9d51c96..76e7dac6f259 100644 --- a/trunk/drivers/video/geode/gxfb_core.c +++ b/trunk/drivers/video/geode/gxfb_core.c @@ -40,7 +40,7 @@ static int vram; static int vt_switch; /* Modes relevant to the GX (taken from modedb.c) */ -static struct fb_videomode gx_modedb[] __devinitdata = { +static struct fb_videomode gx_modedb[] __initdata = { /* 640x480-60 VESA */ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, @@ -110,15 +110,14 @@ static struct fb_videomode gx_modedb[] __devinitdata = { #ifdef CONFIG_OLPC #include -static struct fb_videomode gx_dcon_modedb[] __devinitdata = { +static struct fb_videomode gx_dcon_modedb[] __initdata = { /* The only mode the DCON has is 1200x900 */ { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0 } }; -static void __devinit get_modedb(struct fb_videomode **modedb, - unsigned int *size) +static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) { if (olpc_has_dcon()) { *modedb = (struct fb_videomode *) gx_dcon_modedb; @@ -130,8 +129,7 @@ static void __devinit get_modedb(struct fb_videomode **modedb, } #else -static void __devinit get_modedb(struct fb_videomode **modedb, - unsigned int *size) +static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) { *modedb = (struct fb_videomode *) gx_modedb; *size = ARRAY_SIZE(gx_modedb); @@ -228,8 +226,7 @@ static int gxfb_blank(int blank_mode, struct fb_info *info) return gx_blank_display(info, blank_mode); } -static int __devinit gxfb_map_video_memory(struct fb_info *info, - struct pci_dev *dev) +static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev) { struct gxfb_par *par = info->par; int ret; @@ -293,7 +290,7 @@ static struct fb_ops gxfb_ops = { .fb_imageblit = cfb_imageblit, }; -static struct fb_info *__devinit gxfb_init_fbinfo(struct device *dev) +static struct fb_info * __init gxfb_init_fbinfo(struct device *dev) { struct gxfb_par *par; struct fb_info *info; @@ -374,8 +371,7 @@ static int gxfb_resume(struct pci_dev *pdev) } #endif -static int __devinit gxfb_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct gxfb_par *par; struct fb_info *info; @@ -455,7 +451,7 @@ static int __devinit gxfb_probe(struct pci_dev *pdev, return ret; } -static void __devexit gxfb_remove(struct pci_dev *pdev) +static void gxfb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); struct gxfb_par *par = info->par; diff --git a/trunk/drivers/video/geode/lxfb_core.c b/trunk/drivers/video/geode/lxfb_core.c index 39bdbedf43b4..1a18da86d3fa 100644 --- a/trunk/drivers/video/geode/lxfb_core.c +++ b/trunk/drivers/video/geode/lxfb_core.c @@ -35,7 +35,7 @@ static int vt_switch; * we try to make it something sane - 640x480-60 is sane */ -static struct fb_videomode geode_modedb[] __devinitdata = { +static struct fb_videomode geode_modedb[] __initdata = { /* 640x480-60 */ { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, @@ -219,15 +219,14 @@ static struct fb_videomode geode_modedb[] __devinitdata = { #ifdef CONFIG_OLPC #include -static struct fb_videomode olpc_dcon_modedb[] __devinitdata = { +static struct fb_videomode olpc_dcon_modedb[] __initdata = { /* The only mode the DCON has is 1200x900 */ { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0 } }; -static void __devinit get_modedb(struct fb_videomode **modedb, - unsigned int *size) +static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) { if (olpc_has_dcon()) { *modedb = (struct fb_videomode *) olpc_dcon_modedb; @@ -239,8 +238,7 @@ static void __devinit get_modedb(struct fb_videomode **modedb, } #else -static void __devinit get_modedb(struct fb_videomode **modedb, - unsigned int *size) +static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) { *modedb = (struct fb_videomode *) geode_modedb; *size = ARRAY_SIZE(geode_modedb); @@ -336,7 +334,7 @@ static int lxfb_blank(int blank_mode, struct fb_info *info) } -static int __devinit lxfb_map_video_memory(struct fb_info *info, +static int __init lxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev) { struct lxfb_par *par = info->par; @@ -414,7 +412,7 @@ static struct fb_ops lxfb_ops = { .fb_imageblit = cfb_imageblit, }; -static struct fb_info * __devinit lxfb_init_fbinfo(struct device *dev) +static struct fb_info * __init lxfb_init_fbinfo(struct device *dev) { struct lxfb_par *par; struct fb_info *info; @@ -498,7 +496,7 @@ static int lxfb_resume(struct pci_dev *pdev) #define lxfb_resume NULL #endif -static int __devinit lxfb_probe(struct pci_dev *pdev, +static int __init lxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct lxfb_par *par; @@ -590,7 +588,7 @@ static int __devinit lxfb_probe(struct pci_dev *pdev, return ret; } -static void __devexit lxfb_remove(struct pci_dev *pdev) +static void lxfb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); struct lxfb_par *par = info->par; diff --git a/trunk/drivers/video/nuc900fb.c b/trunk/drivers/video/nuc900fb.c index 81687ed26ba9..d4cde79ea15e 100644 --- a/trunk/drivers/video/nuc900fb.c +++ b/trunk/drivers/video/nuc900fb.c @@ -596,6 +596,8 @@ static int __devinit nuc900fb_probe(struct platform_device *pdev) goto release_regs; } + nuc900_driver_clksrc_div(&pdev->dev, "ext", 0x2); + fbi->clk = clk_get(&pdev->dev, NULL); if (!fbi->clk || IS_ERR(fbi->clk)) { printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n"); diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 811384bec8de..b6ab27ccf214 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -68,7 +68,11 @@ * Here we can be a bit looser than the data sections since this * needs to only meet arch ABI requirements. */ -#define FLAT_STACK_ALIGN max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN) +#ifdef ARCH_SLAB_MINALIGN +#define FLAT_STACK_ALIGN (ARCH_SLAB_MINALIGN) +#else +#define FLAT_STACK_ALIGN (sizeof(void *)) +#endif #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index c8c78ba07827..d96047b4a633 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -590,8 +590,6 @@ static void prune_dcache(int count) up_read(&sb->s_umount); } spin_lock(&sb_lock); - /* lock was dropped, must reset next */ - list_safe_reset_next(sb, n, s_list); count -= pruned; __put_super(sb); /* more work left to do? */ diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index 9d175d623aab..51e11bf5708f 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -733,14 +733,12 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) { while (fa) { struct fown_struct *fown; - unsigned long flags; - if (fa->magic != FASYNC_MAGIC) { printk(KERN_ERR "kill_fasync: bad magic number in " "fasync_struct!\n"); return; } - spin_lock_irqsave(&fa->fa_lock, flags); + spin_lock(&fa->fa_lock); if (fa->fa_file) { fown = &fa->fa_file->f_owner; /* Don't send SIGURG to processes which have not set a @@ -749,7 +747,7 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) if (!(sig == SIGURG && fown->signum == 0)) send_sigio(fown, fa->fa_fd, band); } - spin_unlock_irqrestore(&fa->fa_lock, flags); + spin_unlock(&fa->fa_lock); fa = rcu_dereference(fa->fa_next); } } diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index 0609607d3955..1d1088f48bc2 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -63,16 +63,24 @@ struct bdi_work { }; enum { - WS_INPROGRESS = 0, - WS_ONSTACK, + WS_USED_B = 0, + WS_ONSTACK_B, }; +#define WS_USED (1 << WS_USED_B) +#define WS_ONSTACK (1 << WS_ONSTACK_B) + +static inline bool bdi_work_on_stack(struct bdi_work *work) +{ + return test_bit(WS_ONSTACK_B, &work->state); +} + static inline void bdi_work_init(struct bdi_work *work, struct wb_writeback_args *args) { INIT_RCU_HEAD(&work->rcu_head); work->args = *args; - __set_bit(WS_INPROGRESS, &work->state); + work->state = WS_USED; } /** @@ -87,16 +95,43 @@ int writeback_in_progress(struct backing_dev_info *bdi) return !list_empty(&bdi->work_list); } +static void bdi_work_clear(struct bdi_work *work) +{ + clear_bit(WS_USED_B, &work->state); + smp_mb__after_clear_bit(); + /* + * work can have disappeared at this point. bit waitq functions + * should be able to tolerate this, provided bdi_sched_wait does + * not dereference it's pointer argument. + */ + wake_up_bit(&work->state, WS_USED_B); +} + static void bdi_work_free(struct rcu_head *head) { struct bdi_work *work = container_of(head, struct bdi_work, rcu_head); - clear_bit(WS_INPROGRESS, &work->state); - smp_mb__after_clear_bit(); - wake_up_bit(&work->state, WS_INPROGRESS); - - if (!test_bit(WS_ONSTACK, &work->state)) + if (!bdi_work_on_stack(work)) kfree(work); + else + bdi_work_clear(work); +} + +static void wb_work_complete(struct bdi_work *work) +{ + const enum writeback_sync_modes sync_mode = work->args.sync_mode; + int onstack = bdi_work_on_stack(work); + + /* + * For allocated work, we can clear the done/seen bit right here. + * For on-stack work, we need to postpone both the clear and free + * to after the RCU grace period, since the stack could be invalidated + * as soon as bdi_work_clear() has done the wakeup. + */ + if (!onstack) + bdi_work_clear(work); + if (sync_mode == WB_SYNC_NONE || onstack) + call_rcu(&work->rcu_head, bdi_work_free); } static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work) @@ -112,7 +147,7 @@ static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work) list_del_rcu(&work->list); spin_unlock(&bdi->wb_lock); - call_rcu(&work->rcu_head, bdi_work_free); + wb_work_complete(work); } } @@ -150,9 +185,9 @@ static void bdi_queue_work(struct backing_dev_info *bdi, struct bdi_work *work) * Used for on-stack allocated work items. The caller needs to wait until * the wb threads have acked the work before it's safe to continue. */ -static void bdi_wait_on_work_done(struct bdi_work *work) +static void bdi_wait_on_work_clear(struct bdi_work *work) { - wait_on_bit(&work->state, WS_INPROGRESS, bdi_sched_wait, + wait_on_bit(&work->state, WS_USED_B, bdi_sched_wait, TASK_UNINTERRUPTIBLE); } @@ -178,28 +213,37 @@ static void bdi_alloc_queue_work(struct backing_dev_info *bdi, } /** - * bdi_queue_work_onstack - start and wait for writeback + * bdi_sync_writeback - start and wait for writeback + * @bdi: the backing device to write from * @sb: write inodes from this super_block * * Description: - * This function initiates writeback and waits for the operation to - * complete. Callers must hold the sb s_umount semaphore for + * This does WB_SYNC_ALL data integrity writeback and waits for the + * IO to complete. Callers must hold the sb s_umount semaphore for * reading, to avoid having the super disappear before we are done. */ -static void bdi_queue_work_onstack(struct wb_writeback_args *args) +static void bdi_sync_writeback(struct backing_dev_info *bdi, + struct super_block *sb) { + struct wb_writeback_args args = { + .sb = sb, + .sync_mode = WB_SYNC_ALL, + .nr_pages = LONG_MAX, + .range_cyclic = 0, + }; struct bdi_work work; - bdi_work_init(&work, args); - __set_bit(WS_ONSTACK, &work.state); + bdi_work_init(&work, &args); + work.state |= WS_ONSTACK; - bdi_queue_work(args->sb->s_bdi, &work); - bdi_wait_on_work_done(&work); + bdi_queue_work(bdi, &work); + bdi_wait_on_work_clear(&work); } /** * bdi_start_writeback - start writeback * @bdi: the backing device to write from + * @sb: write inodes from this super_block * @nr_pages: the number of pages to write * * Description: @@ -208,34 +252,25 @@ static void bdi_queue_work_onstack(struct wb_writeback_args *args) * completion. Caller need not hold sb s_umount semaphore. * */ -void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages) +void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, + long nr_pages) { struct wb_writeback_args args = { + .sb = sb, .sync_mode = WB_SYNC_NONE, .nr_pages = nr_pages, .range_cyclic = 1, }; - bdi_alloc_queue_work(bdi, &args); -} + /* + * We treat @nr_pages=0 as the special case to do background writeback, + * ie. to sync pages until the background dirty threshold is reached. + */ + if (!nr_pages) { + args.nr_pages = LONG_MAX; + args.for_background = 1; + } -/** - * bdi_start_background_writeback - start background writeback - * @bdi: the backing device to write from - * - * Description: - * This does WB_SYNC_NONE background writeback. The IO is only - * started when this function returns, we make no guarentees on - * completion. Caller need not hold sb s_umount semaphore. - */ -void bdi_start_background_writeback(struct backing_dev_info *bdi) -{ - struct wb_writeback_args args = { - .sync_mode = WB_SYNC_NONE, - .nr_pages = LONG_MAX, - .for_background = 1, - .range_cyclic = 1, - }; bdi_alloc_queue_work(bdi, &args); } @@ -526,30 +561,48 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) return ret; } +static void unpin_sb_for_writeback(struct super_block *sb) +{ + up_read(&sb->s_umount); + put_super(sb); +} + +enum sb_pin_state { + SB_PINNED, + SB_NOT_PINNED, + SB_PIN_FAILED +}; + /* - * For background writeback the caller does not have the sb pinned + * For WB_SYNC_NONE writeback, the caller does not have the sb pinned * before calling writeback. So make sure that we do pin it, so it doesn't * go away while we are writing inodes from it. */ -static bool pin_sb_for_writeback(struct super_block *sb) +static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc, + struct super_block *sb) { - spin_lock(&sb_lock); - if (list_empty(&sb->s_instances)) { - spin_unlock(&sb_lock); - return false; + /* + * Caller must already hold the ref for this + */ + if (wbc->sync_mode == WB_SYNC_ALL) { + WARN_ON(!rwsem_is_locked(&sb->s_umount)); + return SB_NOT_PINNED; } - + spin_lock(&sb_lock); sb->s_count++; - spin_unlock(&sb_lock); - if (down_read_trylock(&sb->s_umount)) { - if (sb->s_root) - return true; + if (sb->s_root) { + spin_unlock(&sb_lock); + return SB_PINNED; + } + /* + * umounted, drop rwsem again and fall through to failure + */ up_read(&sb->s_umount); } - - put_super(sb); - return false; + sb->s_count--; + spin_unlock(&sb_lock); + return SB_PIN_FAILED; } /* @@ -628,31 +681,24 @@ static void writeback_inodes_wb(struct bdi_writeback *wb, struct inode *inode = list_entry(wb->b_io.prev, struct inode, i_list); struct super_block *sb = inode->i_sb; + enum sb_pin_state state; - if (wbc->sb) { - /* - * We are requested to write out inodes for a specific - * superblock. This means we already have s_umount - * taken by the caller which also waits for us to - * complete the writeout. - */ - if (sb != wbc->sb) { - redirty_tail(inode); - continue; - } - - WARN_ON(!rwsem_is_locked(&sb->s_umount)); + if (wbc->sb && sb != wbc->sb) { + /* super block given and doesn't + match, skip this inode */ + redirty_tail(inode); + continue; + } + state = pin_sb_for_writeback(wbc, sb); - ret = writeback_sb_inodes(sb, wb, wbc); - } else { - if (!pin_sb_for_writeback(sb)) { - requeue_io(inode); - continue; - } - ret = writeback_sb_inodes(sb, wb, wbc); - drop_super(sb); + if (state == SB_PIN_FAILED) { + requeue_io(inode); + continue; } + ret = writeback_sb_inodes(sb, wb, wbc); + if (state == SB_PINNED) + unpin_sb_for_writeback(sb); if (ret) break; } @@ -865,7 +911,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) * If this isn't a data integrity operation, just notify * that we have seen this work and we are now starting it. */ - if (!test_bit(WS_ONSTACK, &work->state)) + if (args.sync_mode == WB_SYNC_NONE) wb_clear_pending(wb, work); wrote += wb_writeback(wb, &args); @@ -874,7 +920,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) * This is a data integrity writeback, so only do the * notification when we have completed the work. */ - if (test_bit(WS_ONSTACK, &work->state)) + if (args.sync_mode == WB_SYNC_ALL) wb_clear_pending(wb, work); } @@ -932,32 +978,42 @@ int bdi_writeback_task(struct bdi_writeback *wb) } /* - * Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back - * the whole world. + * Schedule writeback for all backing devices. This does WB_SYNC_NONE + * writeback, for integrity writeback see bdi_sync_writeback(). */ -void wakeup_flusher_threads(long nr_pages) +static void bdi_writeback_all(struct super_block *sb, long nr_pages) { - struct backing_dev_info *bdi; struct wb_writeback_args args = { + .sb = sb, + .nr_pages = nr_pages, .sync_mode = WB_SYNC_NONE, }; - - if (nr_pages) { - args.nr_pages = nr_pages; - } else { - args.nr_pages = global_page_state(NR_FILE_DIRTY) + - global_page_state(NR_UNSTABLE_NFS); - } + struct backing_dev_info *bdi; rcu_read_lock(); + list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) { if (!bdi_has_dirty_io(bdi)) continue; + bdi_alloc_queue_work(bdi, &args); } + rcu_read_unlock(); } +/* + * Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back + * the whole world. + */ +void wakeup_flusher_threads(long nr_pages) +{ + if (nr_pages == 0) + nr_pages = global_page_state(NR_FILE_DIRTY) + + global_page_state(NR_UNSTABLE_NFS); + bdi_writeback_all(NULL, nr_pages); +} + static noinline void block_dump___mark_inode_dirty(struct inode *inode) { if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { @@ -1162,17 +1218,12 @@ void writeback_inodes_sb(struct super_block *sb) { unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); - struct wb_writeback_args args = { - .sb = sb, - .sync_mode = WB_SYNC_NONE, - }; - - WARN_ON(!rwsem_is_locked(&sb->s_umount)); + long nr_to_write; - args.nr_pages = nr_dirty + nr_unstable + + nr_to_write = nr_dirty + nr_unstable + (inodes_stat.nr_inodes - inodes_stat.nr_unused); - bdi_queue_work_onstack(&args); + bdi_start_writeback(sb->s_bdi, sb, nr_to_write); } EXPORT_SYMBOL(writeback_inodes_sb); @@ -1186,9 +1237,7 @@ EXPORT_SYMBOL(writeback_inodes_sb); int writeback_inodes_sb_if_idle(struct super_block *sb) { if (!writeback_in_progress(sb->s_bdi)) { - down_read(&sb->s_umount); writeback_inodes_sb(sb); - up_read(&sb->s_umount); return 1; } else return 0; @@ -1204,16 +1253,7 @@ EXPORT_SYMBOL(writeback_inodes_sb_if_idle); */ void sync_inodes_sb(struct super_block *sb) { - struct wb_writeback_args args = { - .sb = sb, - .sync_mode = WB_SYNC_ALL, - .nr_pages = LONG_MAX, - .range_cyclic = 0, - }; - - WARN_ON(!rwsem_is_locked(&sb->s_umount)); - - bdi_queue_work_onstack(&args); + bdi_sync_writeback(sb->s_bdi, sb); wait_sb_inodes(sb); } EXPORT_SYMBOL(sync_inodes_sb); diff --git a/trunk/fs/proc/task_nommu.c b/trunk/fs/proc/task_nommu.c index cb6306e63843..46d4b5d72bd3 100644 --- a/trunk/fs/proc/task_nommu.c +++ b/trunk/fs/proc/task_nommu.c @@ -122,20 +122,11 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, return size; } -static void pad_len_spaces(struct seq_file *m, int len) -{ - len = 25 + sizeof(void*) * 6 - len; - if (len < 1) - len = 1; - seq_printf(m, "%*c", len, ' '); -} - /* * display a single VMA to a sequenced file */ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) { - struct mm_struct *mm = vma->vm_mm; unsigned long ino = 0; struct file *file; dev_t dev = 0; @@ -164,14 +155,11 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) MAJOR(dev), MINOR(dev), ino, &len); if (file) { - pad_len_spaces(m, len); + len = 25 + sizeof(void *) * 6 - len; + if (len < 1) + len = 1; + seq_printf(m, "%*c", len, ' '); seq_path(m, &file->f_path, ""); - } else if (mm) { - if (vma->vm_start <= mm->start_stack && - vma->vm_end >= mm->start_stack) { - pad_len_spaces(m, len); - seq_puts(m, "[stack]"); - } } seq_putc(m, '\n'); diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 938119ab8dcb..5c35bc7a499e 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -374,8 +374,6 @@ void sync_supers(void) up_read(&sb->s_umount); spin_lock(&sb_lock); - /* lock was dropped, must reset next */ - list_safe_reset_next(sb, n, s_list); __put_super(sb); } } @@ -407,8 +405,6 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg) up_read(&sb->s_umount); spin_lock(&sb_lock); - /* lock was dropped, must reset next */ - list_safe_reset_next(sb, n, s_list); __put_super(sb); } spin_unlock(&sb_lock); @@ -589,8 +585,6 @@ static void do_emergency_remount(struct work_struct *work) } up_write(&sb->s_umount); spin_lock(&sb_lock); - /* lock was dropped, must reset next */ - list_safe_reset_next(sb, n, s_list); __put_super(sb); } spin_unlock(&sb_lock); diff --git a/trunk/fs/sysv/ialloc.c b/trunk/fs/sysv/ialloc.c index fcc498ec9b33..bbd69bdb0fa8 100644 --- a/trunk/fs/sysv/ialloc.c +++ b/trunk/fs/sysv/ialloc.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "sysv.h" /* We don't trust the value of @@ -140,9 +139,6 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) struct inode *inode; sysv_ino_t ino; unsigned count; - struct writeback_control wbc = { - .sync_mode = WB_SYNC_NONE - }; inode = new_inode(sb); if (!inode) @@ -172,7 +168,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) insert_inode_hash(inode); mark_inode_dirty(inode); - sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */ + sysv_write_inode(inode, 0); /* ensure inode not allocated again */ mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ /* That's it. */ unlock_super(sb); diff --git a/trunk/fs/ubifs/budget.c b/trunk/fs/ubifs/budget.c index c8ff0d1ae5d3..076ca50e9933 100644 --- a/trunk/fs/ubifs/budget.c +++ b/trunk/fs/ubifs/budget.c @@ -62,9 +62,7 @@ */ static void shrink_liability(struct ubifs_info *c, int nr_to_write) { - down_read(&c->vfs_sb->s_umount); writeback_inodes_sb(c->vfs_sb); - up_read(&c->vfs_sb->s_umount); } /** diff --git a/trunk/fs/xfs/linux-2.6/xfs_export.c b/trunk/fs/xfs/linux-2.6/xfs_export.c index e7839ee49e43..846b75aeb2ab 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_export.c +++ b/trunk/fs/xfs/linux-2.6/xfs_export.c @@ -128,12 +128,13 @@ xfs_nfs_get_inode( return ERR_PTR(-ESTALE); /* - * The XFS_IGET_UNTRUSTED means that an invalid inode number is just - * fine and not an indication of a corrupted filesystem as clients can - * send invalid file handles and we have to handle it gracefully.. + * The XFS_IGET_BULKSTAT means that an invalid inode number is just + * fine and not an indication of a corrupted filesystem. Because + * clients can send any kind of invalid file handle, e.g. after + * a restore on the server we have to deal with this case gracefully. */ - error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED, - XFS_ILOCK_SHARED, &ip); + error = xfs_iget(mp, NULL, ino, XFS_IGET_BULKSTAT, + XFS_ILOCK_SHARED, &ip, 0); if (error) { /* * EINVAL means the inode cluster doesn't exist anymore. diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index e59a81062830..699b60cbab9c 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -679,9 +679,10 @@ xfs_ioc_bulkstat( error = xfs_bulkstat_single(mp, &inlast, bulkreq.ubuffer, &done); else /* XFS_IOC_FSBULKSTAT */ - error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one, - sizeof(xfs_bstat_t), bulkreq.ubuffer, - &done); + error = xfs_bulkstat(mp, &inlast, &count, + (bulkstat_one_pf)xfs_bulkstat_one, NULL, + sizeof(xfs_bstat_t), bulkreq.ubuffer, + BULKSTAT_FG_QUICK, &done); if (error) return -error; diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c index 52ed49e6465c..9287135e9bfc 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -237,12 +237,15 @@ xfs_bulkstat_one_compat( xfs_ino_t ino, /* inode number to get data for */ void __user *buffer, /* buffer to place output in */ int ubsize, /* size of buffer */ + void *private_data, /* my private data */ + xfs_daddr_t bno, /* starting bno of inode cluster */ int *ubused, /* bytes used by me */ + void *dibuff, /* on-disk inode buffer */ int *stat) /* BULKSTAT_RV_... */ { return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, - xfs_bulkstat_one_fmt_compat, - ubused, stat); + xfs_bulkstat_one_fmt_compat, bno, + ubused, dibuff, stat); } /* copied from xfs_ioctl.c */ @@ -295,11 +298,13 @@ xfs_compat_ioc_bulkstat( int res; error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer, - sizeof(compat_xfs_bstat_t), 0, &res); + sizeof(compat_xfs_bstat_t), + NULL, 0, NULL, NULL, &res); } else if (cmd == XFS_IOC_FSBULKSTAT_32) { error = xfs_bulkstat(mp, &inlast, &count, - xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t), - bulkreq.ubuffer, &done); + xfs_bulkstat_one_compat, NULL, + sizeof(compat_xfs_bstat_t), bulkreq.ubuffer, + BULKSTAT_FG_QUICK, &done); } else error = XFS_ERROR(EINVAL); if (error) diff --git a/trunk/fs/xfs/quota/xfs_qm.c b/trunk/fs/xfs/quota/xfs_qm.c index 8c117ff2e3ab..2d8b7bc792c9 100644 --- a/trunk/fs/xfs/quota/xfs_qm.c +++ b/trunk/fs/xfs/quota/xfs_qm.c @@ -1632,7 +1632,10 @@ xfs_qm_dqusage_adjust( xfs_ino_t ino, /* inode number to get data for */ void __user *buffer, /* not used */ int ubsize, /* not used */ + void *private_data, /* not used */ + xfs_daddr_t bno, /* starting block of inode cluster */ int *ubused, /* not used */ + void *dip, /* on-disk inode pointer (not used) */ int *res) /* result code value */ { xfs_inode_t *ip; @@ -1657,7 +1660,7 @@ xfs_qm_dqusage_adjust( * the case in all other instances. It's OK that we do this because * quotacheck is done only at mount time. */ - if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip))) { + if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip, bno))) { *res = BULKSTAT_RV_NOTHING; return error; } @@ -1793,13 +1796,12 @@ xfs_qm_quotacheck( * Iterate thru all the inodes in the file system, * adjusting the corresponding dquot counters in core. */ - error = xfs_bulkstat(mp, &lastino, &count, - xfs_qm_dqusage_adjust, - structsz, NULL, &done); - if (error) + if ((error = xfs_bulkstat(mp, &lastino, &count, + xfs_qm_dqusage_adjust, NULL, + structsz, NULL, BULKSTAT_FG_IGET, &done))) break; - } while (!done); + } while (! done); /* * We've made all the changes that we need to make incore. @@ -1887,14 +1889,14 @@ xfs_qm_init_quotainos( mp->m_sb.sb_uquotino != NULLFSINO) { ASSERT(mp->m_sb.sb_uquotino > 0); if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, - 0, 0, &uip))) + 0, 0, &uip, 0))) return XFS_ERROR(error); } if (XFS_IS_OQUOTA_ON(mp) && mp->m_sb.sb_gquotino != NULLFSINO) { ASSERT(mp->m_sb.sb_gquotino > 0); if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, - 0, 0, &gip))) { + 0, 0, &gip, 0))) { if (uip) IRELE(uip); return XFS_ERROR(error); diff --git a/trunk/fs/xfs/quota/xfs_qm_syscalls.c b/trunk/fs/xfs/quota/xfs_qm_syscalls.c index b4487764e923..92b002f1805f 100644 --- a/trunk/fs/xfs/quota/xfs_qm_syscalls.c +++ b/trunk/fs/xfs/quota/xfs_qm_syscalls.c @@ -262,7 +262,7 @@ xfs_qm_scall_trunc_qfiles( } if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) { - error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip); + error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0); if (!error) { error = xfs_truncate_file(mp, qip); IRELE(qip); @@ -271,7 +271,7 @@ xfs_qm_scall_trunc_qfiles( if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && mp->m_sb.sb_gquotino != NULLFSINO) { - error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip); + error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); if (!error2) { error2 = xfs_truncate_file(mp, qip); IRELE(qip); @@ -417,12 +417,12 @@ xfs_qm_scall_getqstat( } if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, - 0, 0, &uip) == 0) + 0, 0, &uip, 0) == 0) tempuqip = B_TRUE; } if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, - 0, 0, &gip) == 0) + 0, 0, &gip, 0) == 0) tempgqip = B_TRUE; } if (uip) { @@ -1109,7 +1109,10 @@ xfs_qm_internalqcheck_adjust( xfs_ino_t ino, /* inode number to get data for */ void __user *buffer, /* not used */ int ubsize, /* not used */ + void *private_data, /* not used */ + xfs_daddr_t bno, /* starting block of inode cluster */ int *ubused, /* not used */ + void *dip, /* not used */ int *res) /* bulkstat result code */ { xfs_inode_t *ip; @@ -1131,7 +1134,7 @@ xfs_qm_internalqcheck_adjust( ipreleased = B_FALSE; again: lock_flags = XFS_ILOCK_SHARED; - if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip))) { + if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip, bno))) { *res = BULKSTAT_RV_NOTHING; return (error); } @@ -1202,15 +1205,15 @@ xfs_qm_internalqcheck( * Iterate thru all the inodes in the file system, * adjusting the corresponding dquot counters */ - error = xfs_bulkstat(mp, &lastino, &count, - xfs_qm_internalqcheck_adjust, - 0, NULL, &done); - if (error) { - cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error); + if ((error = xfs_bulkstat(mp, &lastino, &count, + xfs_qm_internalqcheck_adjust, NULL, + 0, NULL, BULKSTAT_FG_IGET, &done))) { break; } - } while (!done); - + } while (! done); + if (error) { + cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error); + } cmn_err(CE_DEBUG, "Checking results against system dquots"); for (i = 0; i < qmtest_hashmask; i++) { xfs_dqtest_t *d, *n; diff --git a/trunk/fs/xfs/xfs_dfrag.c b/trunk/fs/xfs/xfs_dfrag.c index 7f159d2a429a..5bba29a07812 100644 --- a/trunk/fs/xfs/xfs_dfrag.c +++ b/trunk/fs/xfs/xfs_dfrag.c @@ -69,9 +69,7 @@ xfs_swapext( goto out; } - if (!(file->f_mode & FMODE_WRITE) || - !(file->f_mode & FMODE_READ) || - (file->f_flags & O_APPEND)) { + if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) { error = XFS_ERROR(EBADF); goto out_put_file; } @@ -83,7 +81,6 @@ xfs_swapext( } if (!(tmp_file->f_mode & FMODE_WRITE) || - !(tmp_file->f_mode & FMODE_READ) || (tmp_file->f_flags & O_APPEND)) { error = XFS_ERROR(EBADF); goto out_put_tmp_file; diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index c7142a064c48..9d884c127bb9 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -1203,63 +1203,6 @@ xfs_difree( return error; } -STATIC int -xfs_imap_lookup( - struct xfs_mount *mp, - struct xfs_trans *tp, - xfs_agnumber_t agno, - xfs_agino_t agino, - xfs_agblock_t agbno, - xfs_agblock_t *chunk_agbno, - xfs_agblock_t *offset_agbno, - int flags) -{ - struct xfs_inobt_rec_incore rec; - struct xfs_btree_cur *cur; - struct xfs_buf *agbp; - xfs_agino_t startino; - int error; - int i; - - error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); - if (error) { - xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " - "xfs_ialloc_read_agi() returned " - "error %d, agno %d", - error, agno); - return error; - } - - /* - * derive and lookup the exact inode record for the given agino. If the - * record cannot be found, then it's an invalid inode number and we - * should abort. - */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); - startino = agino & ~(XFS_IALLOC_INODES(mp) - 1); - error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i); - if (!error) { - if (i) - error = xfs_inobt_get_rec(cur, &rec, &i); - if (!error && i == 0) - error = EINVAL; - } - - xfs_trans_brelse(tp, agbp); - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); - if (error) - return error; - - /* for untrusted inodes check it is allocated first */ - if ((flags & XFS_IGET_UNTRUSTED) && - (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) - return EINVAL; - - *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino); - *offset_agbno = agbno - *chunk_agbno; - return 0; -} - /* * Return the location of the inode in imap, for mapping it into a buffer. */ @@ -1292,11 +1235,8 @@ xfs_imap( if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || ino != XFS_AGINO_TO_INO(mp, agno, agino)) { #ifdef DEBUG - /* - * Don't output diagnostic information for untrusted inodes - * as they can be invalid without implying corruption. - */ - if (flags & XFS_IGET_UNTRUSTED) + /* no diagnostics for bulkstat, ino comes from userspace */ + if (flags & XFS_IGET_BULKSTAT) return XFS_ERROR(EINVAL); if (agno >= mp->m_sb.sb_agcount) { xfs_fs_cmn_err(CE_ALERT, mp, @@ -1323,23 +1263,6 @@ xfs_imap( return XFS_ERROR(EINVAL); } - blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; - - /* - * For bulkstat and handle lookups, we have an untrusted inode number - * that we have to verify is valid. We cannot do this just by reading - * the inode buffer as it may have been unlinked and removed leaving - * inodes in stale state on disk. Hence we have to do a btree lookup - * in all cases where an untrusted inode number is passed. - */ - if (flags & XFS_IGET_UNTRUSTED) { - error = xfs_imap_lookup(mp, tp, agno, agino, agbno, - &chunk_agbno, &offset_agbno, flags); - if (error) - return error; - goto out_map; - } - /* * If the inode cluster size is the same as the blocksize or * smaller we get to the buffer by simple arithmetics. @@ -1354,6 +1277,24 @@ xfs_imap( return 0; } + blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog; + + /* + * If we get a block number passed from bulkstat we can use it to + * find the buffer easily. + */ + if (imap->im_blkno) { + offset = XFS_INO_TO_OFFSET(mp, ino); + ASSERT(offset < mp->m_sb.sb_inopblock); + + cluster_agbno = xfs_daddr_to_agbno(mp, imap->im_blkno); + offset += (agbno - cluster_agbno) * mp->m_sb.sb_inopblock; + + imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); + imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog); + return 0; + } + /* * If the inode chunks are aligned then use simple maths to * find the location. Otherwise we have to do a btree @@ -1363,13 +1304,50 @@ xfs_imap( offset_agbno = agbno & mp->m_inoalign_mask; chunk_agbno = agbno - offset_agbno; } else { - error = xfs_imap_lookup(mp, tp, agno, agino, agbno, - &chunk_agbno, &offset_agbno, flags); + xfs_btree_cur_t *cur; /* inode btree cursor */ + xfs_inobt_rec_incore_t chunk_rec; + xfs_buf_t *agbp; /* agi buffer */ + int i; /* temp state */ + + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); + if (error) { + xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " + "xfs_ialloc_read_agi() returned " + "error %d, agno %d", + error, agno); + return error; + } + + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); + error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); + if (error) { + xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " + "xfs_inobt_lookup() failed"); + goto error0; + } + + error = xfs_inobt_get_rec(cur, &chunk_rec, &i); + if (error) { + xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " + "xfs_inobt_get_rec() failed"); + goto error0; + } + if (i == 0) { +#ifdef DEBUG + xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " + "xfs_inobt_get_rec() failed"); +#endif /* DEBUG */ + error = XFS_ERROR(EINVAL); + } + error0: + xfs_trans_brelse(tp, agbp); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); if (error) return error; + chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino); + offset_agbno = agbno - chunk_agbno; } -out_map: ASSERT(agbno >= chunk_agbno); cluster_agbno = chunk_agbno + ((offset_agbno / blks_per_cluster) * blks_per_cluster); diff --git a/trunk/fs/xfs/xfs_iget.c b/trunk/fs/xfs/xfs_iget.c index 8f8b91be2c99..75df75f43d48 100644 --- a/trunk/fs/xfs/xfs_iget.c +++ b/trunk/fs/xfs/xfs_iget.c @@ -259,6 +259,7 @@ xfs_iget_cache_miss( xfs_trans_t *tp, xfs_ino_t ino, struct xfs_inode **ipp, + xfs_daddr_t bno, int flags, int lock_flags) { @@ -271,7 +272,7 @@ xfs_iget_cache_miss( if (!ip) return ENOMEM; - error = xfs_iread(mp, tp, ip, flags); + error = xfs_iread(mp, tp, ip, bno, flags); if (error) goto out_destroy; @@ -357,6 +358,8 @@ xfs_iget_cache_miss( * within the file system for the inode being requested. * lock_flags -- flags indicating how to lock the inode. See the comment * for xfs_ilock() for a list of valid values. + * bno -- the block number starting the buffer containing the inode, + * if known (as by bulkstat), else 0. */ int xfs_iget( @@ -365,7 +368,8 @@ xfs_iget( xfs_ino_t ino, uint flags, uint lock_flags, - xfs_inode_t **ipp) + xfs_inode_t **ipp, + xfs_daddr_t bno) { xfs_inode_t *ip; int error; @@ -393,7 +397,7 @@ xfs_iget( read_unlock(&pag->pag_ici_lock); XFS_STATS_INC(xs_ig_missed); - error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, + error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, bno, flags, lock_flags); if (error) goto out_error_or_again; diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index b76a829d7e20..d53c39de7d05 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -177,7 +177,7 @@ xfs_imap_to_bp( if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, XFS_RANDOM_ITOBP_INOTOBP))) { - if (iget_flags & XFS_IGET_UNTRUSTED) { + if (iget_flags & XFS_IGET_BULKSTAT) { xfs_trans_brelse(tp, bp); return XFS_ERROR(EINVAL); } @@ -787,6 +787,7 @@ xfs_iread( xfs_mount_t *mp, xfs_trans_t *tp, xfs_inode_t *ip, + xfs_daddr_t bno, uint iget_flags) { xfs_buf_t *bp; @@ -796,9 +797,11 @@ xfs_iread( /* * Fill in the location information in the in-core inode. */ + ip->i_imap.im_blkno = bno; error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); if (error) return error; + ASSERT(bno == 0 || bno == ip->i_imap.im_blkno); /* * Get pointers to the on-disk inode and the buffer containing it. diff --git a/trunk/fs/xfs/xfs_inode.h b/trunk/fs/xfs/xfs_inode.h index 78550df13cd6..9965e40a4615 100644 --- a/trunk/fs/xfs/xfs_inode.h +++ b/trunk/fs/xfs/xfs_inode.h @@ -442,7 +442,7 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) * xfs_iget.c prototypes. */ int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, - uint, uint, xfs_inode_t **); + uint, uint, xfs_inode_t **, xfs_daddr_t); void xfs_iput(xfs_inode_t *, uint); void xfs_iput_new(xfs_inode_t *, uint); void xfs_ilock(xfs_inode_t *, uint); @@ -500,7 +500,7 @@ do { \ * Flags for xfs_iget() */ #define XFS_IGET_CREATE 0x1 -#define XFS_IGET_UNTRUSTED 0x2 +#define XFS_IGET_BULKSTAT 0x2 int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, struct xfs_dinode **, @@ -509,7 +509,7 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, struct xfs_dinode **, struct xfs_buf **, uint); int xfs_iread(struct xfs_mount *, struct xfs_trans *, - struct xfs_inode *, uint); + struct xfs_inode *, xfs_daddr_t, uint); void xfs_dinode_to_disk(struct xfs_dinode *, struct xfs_icdinode *); void xfs_idestroy_fork(struct xfs_inode *, int); diff --git a/trunk/fs/xfs/xfs_itable.c b/trunk/fs/xfs/xfs_itable.c index 2b86f8610512..b1b801e4a28e 100644 --- a/trunk/fs/xfs/xfs_itable.c +++ b/trunk/fs/xfs/xfs_itable.c @@ -49,40 +49,24 @@ xfs_internal_inum( (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); } -/* - * Return stat information for one inode. - * Return 0 if ok, else errno. - */ -int -xfs_bulkstat_one_int( - struct xfs_mount *mp, /* mount point for filesystem */ - xfs_ino_t ino, /* inode to get data for */ - void __user *buffer, /* buffer to place output in */ - int ubsize, /* size of buffer */ - bulkstat_one_fmt_pf formatter, /* formatter, copy to user */ - int *ubused, /* bytes used by me */ - int *stat) /* BULKSTAT_RV_... */ +STATIC int +xfs_bulkstat_one_iget( + xfs_mount_t *mp, /* mount point for filesystem */ + xfs_ino_t ino, /* inode number to get data for */ + xfs_daddr_t bno, /* starting bno of inode cluster */ + xfs_bstat_t *buf, /* return buffer */ + int *stat) /* BULKSTAT_RV_... */ { - struct xfs_icdinode *dic; /* dinode core info pointer */ - struct xfs_inode *ip; /* incore inode pointer */ - struct inode *inode; - struct xfs_bstat *buf; /* return buffer */ - int error = 0; /* error value */ - - *stat = BULKSTAT_RV_NOTHING; - - if (!buffer || xfs_internal_inum(mp, ino)) - return XFS_ERROR(EINVAL); - - buf = kmem_alloc(sizeof(*buf), KM_SLEEP | KM_MAYFAIL); - if (!buf) - return XFS_ERROR(ENOMEM); + xfs_icdinode_t *dic; /* dinode core info pointer */ + xfs_inode_t *ip; /* incore inode pointer */ + struct inode *inode; + int error; error = xfs_iget(mp, NULL, ino, - XFS_IGET_UNTRUSTED, XFS_ILOCK_SHARED, &ip); + XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno); if (error) { *stat = BULKSTAT_RV_NOTHING; - goto out_free; + return error; } ASSERT(ip != NULL); @@ -143,16 +127,77 @@ xfs_bulkstat_one_int( buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks; break; } + xfs_iput(ip, XFS_ILOCK_SHARED); + return error; +} - error = formatter(buffer, ubsize, ubused, buf); +STATIC void +xfs_bulkstat_one_dinode( + xfs_mount_t *mp, /* mount point for filesystem */ + xfs_ino_t ino, /* inode number to get data for */ + xfs_dinode_t *dic, /* dinode inode pointer */ + xfs_bstat_t *buf) /* return buffer */ +{ + /* + * The inode format changed when we moved the link count and + * made it 32 bits long. If this is an old format inode, + * convert it in memory to look like a new one. If it gets + * flushed to disk we will convert back before flushing or + * logging it. We zero out the new projid field and the old link + * count field. We'll handle clearing the pad field (the remains + * of the old uuid field) when we actually convert the inode to + * the new format. We don't change the version number so that we + * can distinguish this from a real new format inode. + */ + if (dic->di_version == 1) { + buf->bs_nlink = be16_to_cpu(dic->di_onlink); + buf->bs_projid = 0; + } else { + buf->bs_nlink = be32_to_cpu(dic->di_nlink); + buf->bs_projid = be16_to_cpu(dic->di_projid); + } - if (!error) - *stat = BULKSTAT_RV_DIDONE; + buf->bs_ino = ino; + buf->bs_mode = be16_to_cpu(dic->di_mode); + buf->bs_uid = be32_to_cpu(dic->di_uid); + buf->bs_gid = be32_to_cpu(dic->di_gid); + buf->bs_size = be64_to_cpu(dic->di_size); + buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec); + buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec); + buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec); + buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); + buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); + buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); + buf->bs_xflags = xfs_dic2xflags(dic); + buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; + buf->bs_extents = be32_to_cpu(dic->di_nextents); + buf->bs_gen = be32_to_cpu(dic->di_gen); + memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); + buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask); + buf->bs_dmstate = be16_to_cpu(dic->di_dmstate); + buf->bs_aextents = be16_to_cpu(dic->di_anextents); + buf->bs_forkoff = XFS_DFORK_BOFF(dic); - out_free: - kmem_free(buf); - return error; + switch (dic->di_format) { + case XFS_DINODE_FMT_DEV: + buf->bs_rdev = xfs_dinode_get_rdev(dic); + buf->bs_blksize = BLKDEV_IOSIZE; + buf->bs_blocks = 0; + break; + case XFS_DINODE_FMT_LOCAL: + case XFS_DINODE_FMT_UUID: + buf->bs_rdev = 0; + buf->bs_blksize = mp->m_sb.sb_blocksize; + buf->bs_blocks = 0; + break; + case XFS_DINODE_FMT_EXTENTS: + case XFS_DINODE_FMT_BTREE: + buf->bs_rdev = 0; + buf->bs_blksize = mp->m_sb.sb_blocksize; + buf->bs_blocks = be64_to_cpu(dic->di_nblocks); + break; + } } /* Return 0 on success or positive error */ @@ -172,17 +217,118 @@ xfs_bulkstat_one_fmt( return 0; } +/* + * Return stat information for one inode. + * Return 0 if ok, else errno. + */ +int /* error status */ +xfs_bulkstat_one_int( + xfs_mount_t *mp, /* mount point for filesystem */ + xfs_ino_t ino, /* inode number to get data for */ + void __user *buffer, /* buffer to place output in */ + int ubsize, /* size of buffer */ + bulkstat_one_fmt_pf formatter, /* formatter, copy to user */ + xfs_daddr_t bno, /* starting bno of inode cluster */ + int *ubused, /* bytes used by me */ + void *dibuff, /* on-disk inode buffer */ + int *stat) /* BULKSTAT_RV_... */ +{ + xfs_bstat_t *buf; /* return buffer */ + int error = 0; /* error value */ + xfs_dinode_t *dip; /* dinode inode pointer */ + + dip = (xfs_dinode_t *)dibuff; + *stat = BULKSTAT_RV_NOTHING; + + if (!buffer || xfs_internal_inum(mp, ino)) + return XFS_ERROR(EINVAL); + + buf = kmem_alloc(sizeof(*buf), KM_SLEEP); + + if (dip == NULL) { + /* We're not being passed a pointer to a dinode. This happens + * if BULKSTAT_FG_IGET is selected. Do the iget. + */ + error = xfs_bulkstat_one_iget(mp, ino, bno, buf, stat); + if (error) + goto out_free; + } else { + xfs_bulkstat_one_dinode(mp, ino, dip, buf); + } + + error = formatter(buffer, ubsize, ubused, buf); + if (error) + goto out_free; + + *stat = BULKSTAT_RV_DIDONE; + + out_free: + kmem_free(buf); + return error; +} + int xfs_bulkstat_one( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t ino, /* inode number to get data for */ void __user *buffer, /* buffer to place output in */ int ubsize, /* size of buffer */ + void *private_data, /* my private data */ + xfs_daddr_t bno, /* starting bno of inode cluster */ int *ubused, /* bytes used by me */ + void *dibuff, /* on-disk inode buffer */ int *stat) /* BULKSTAT_RV_... */ { return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, - xfs_bulkstat_one_fmt, ubused, stat); + xfs_bulkstat_one_fmt, bno, + ubused, dibuff, stat); +} + +/* + * Test to see whether we can use the ondisk inode directly, based + * on the given bulkstat flags, filling in dipp accordingly. + * Returns zero if the inode is dodgey. + */ +STATIC int +xfs_bulkstat_use_dinode( + xfs_mount_t *mp, + int flags, + xfs_buf_t *bp, + int clustidx, + xfs_dinode_t **dipp) +{ + xfs_dinode_t *dip; + unsigned int aformat; + + *dipp = NULL; + if (!bp || (flags & BULKSTAT_FG_IGET)) + return 1; + dip = (xfs_dinode_t *) + xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); + /* + * Check the buffer containing the on-disk inode for di_mode == 0. + * This is to prevent xfs_bulkstat from picking up just reclaimed + * inodes that have their in-core state initialized but not flushed + * to disk yet. This is a temporary hack that would require a proper + * fix in the future. + */ + if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || + !XFS_DINODE_GOOD_VERSION(dip->di_version) || + !dip->di_mode) + return 0; + if (flags & BULKSTAT_FG_QUICK) { + *dipp = dip; + return 1; + } + /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ + aformat = dip->di_aformat; + if ((XFS_DFORK_Q(dip) == 0) || + (aformat == XFS_DINODE_FMT_LOCAL) || + (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_anextents)) { + *dipp = dip; + return 1; + } + return 1; } #define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) @@ -196,8 +342,10 @@ xfs_bulkstat( xfs_ino_t *lastinop, /* last inode returned */ int *ubcountp, /* size of buffer/count returned */ bulkstat_one_pf formatter, /* func that'd fill a single buf */ + void *private_data,/* private data for formatter */ size_t statstruct_size, /* sizeof struct filling */ char __user *ubuffer, /* buffer with inode stats */ + int flags, /* defined in xfs_itable.h */ int *done) /* 1 if there are more stats to get */ { xfs_agblock_t agbno=0;/* allocation group block number */ @@ -232,12 +380,14 @@ xfs_bulkstat( int ubelem; /* spaces used in user's buffer */ int ubused; /* bytes used by formatter */ xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ + xfs_dinode_t *dip; /* ptr into bp for specific inode */ /* * Get the last inode value, see if there's nothing to do. */ ino = (xfs_ino_t)*lastinop; lastino = ino; + dip = NULL; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); if (agno >= mp->m_sb.sb_agcount || @@ -462,6 +612,37 @@ xfs_bulkstat( irbp->ir_startino) + ((chunkidx & nimask) >> mp->m_sb.sb_inopblog); + + if (flags & (BULKSTAT_FG_QUICK | + BULKSTAT_FG_INLINE)) { + int offset; + + ino = XFS_AGINO_TO_INO(mp, agno, + agino); + bno = XFS_AGB_TO_DADDR(mp, agno, + agbno); + + /* + * Get the inode cluster buffer + */ + if (bp) + xfs_buf_relse(bp); + + error = xfs_inotobp(mp, NULL, ino, &dip, + &bp, &offset, + XFS_IGET_BULKSTAT); + + if (!error) + clustidx = offset / mp->m_sb.sb_inodesize; + if (XFS_TEST_ERROR(error != 0, + mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK, + XFS_RANDOM_BULKSTAT_READ_CHUNK)) { + bp = NULL; + ubleft = 0; + rval = error; + break; + } + } } ino = XFS_AGINO_TO_INO(mp, agno, agino); bno = XFS_AGB_TO_DADDR(mp, agno, agbno); @@ -477,13 +658,35 @@ xfs_bulkstat( * when the chunk is used up. */ irbp->ir_freecount++; + if (!xfs_bulkstat_use_dinode(mp, flags, bp, + clustidx, &dip)) { + lastino = ino; + continue; + } + /* + * If we need to do an iget, cannot hold bp. + * Drop it, until starting the next cluster. + */ + if ((flags & BULKSTAT_FG_INLINE) && !dip) { + if (bp) + xfs_buf_relse(bp); + bp = NULL; + } /* * Get the inode and fill in a single buffer. + * BULKSTAT_FG_QUICK uses dip to fill it in. + * BULKSTAT_FG_IGET uses igets. + * BULKSTAT_FG_INLINE uses dip if we have an + * inline attr fork, else igets. + * See: xfs_bulkstat_one & xfs_dm_bulkstat_one. + * This is also used to count inodes/blks, etc + * in xfs_qm_quotacheck. */ ubused = statstruct_size; - error = formatter(mp, ino, ubufp, ubleft, - &ubused, &fmterror); + error = formatter(mp, ino, ubufp, + ubleft, private_data, + bno, &ubused, dip, &fmterror); if (fmterror == BULKSTAT_RV_NOTHING) { if (error && error != ENOENT && error != EINVAL) { @@ -575,7 +778,8 @@ xfs_bulkstat_single( */ ino = (xfs_ino_t)*lastinop; - error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 0, &res); + error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), + NULL, 0, NULL, NULL, &res); if (error) { /* * Special case way failed, do it the "long" way @@ -584,7 +788,8 @@ xfs_bulkstat_single( (*lastinop)--; count = 1; if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one, - sizeof(xfs_bstat_t), buffer, done)) + NULL, sizeof(xfs_bstat_t), buffer, + BULKSTAT_FG_IGET, done)) return error; if (count == 0 || (xfs_ino_t)*lastinop != ino) return error == EFSCORRUPTED ? diff --git a/trunk/fs/xfs/xfs_itable.h b/trunk/fs/xfs/xfs_itable.h index 97295d91d170..20792bf45946 100644 --- a/trunk/fs/xfs/xfs_itable.h +++ b/trunk/fs/xfs/xfs_itable.h @@ -27,7 +27,10 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, xfs_ino_t ino, void __user *buffer, int ubsize, + void *private_data, + xfs_daddr_t bno, int *ubused, + void *dip, int *stat); /* @@ -37,6 +40,13 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, #define BULKSTAT_RV_DIDONE 1 #define BULKSTAT_RV_GIVEUP 2 +/* + * Values for bulkstat flag argument. + */ +#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ +#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ +#define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */ + /* * Return stat information in bulk (by-inode) for the filesystem. */ @@ -46,8 +56,10 @@ xfs_bulkstat( xfs_ino_t *lastino, /* last inode returned */ int *count, /* size of buffer/count returned */ bulkstat_one_pf formatter, /* func that'd fill a single buf */ + void *private_data, /* private data for formatter */ size_t statstruct_size,/* sizeof struct that we're filling */ char __user *ubuffer,/* buffer with inode stats */ + int flags, /* flag to control access method */ int *done); /* 1 if there are more stats to get */ int @@ -70,7 +82,9 @@ xfs_bulkstat_one_int( void __user *buffer, int ubsize, bulkstat_one_fmt_pf formatter, + xfs_daddr_t bno, int *ubused, + void *dibuff, int *stat); int @@ -79,7 +93,10 @@ xfs_bulkstat_one( xfs_ino_t ino, void __user *buffer, int ubsize, + void *private_data, + xfs_daddr_t bno, int *ubused, + void *dibuff, int *stat); typedef int (*inumbers_fmt_pf)( diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index 9ac5cfab27b9..ed0684cc50ee 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -3198,7 +3198,7 @@ xlog_recover_process_one_iunlink( int error; ino = XFS_AGINO_TO_INO(mp, agno, agino); - error = xfs_iget(mp, NULL, ino, 0, 0, &ip); + error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0); if (error) goto fail; diff --git a/trunk/fs/xfs/xfs_mount.c b/trunk/fs/xfs/xfs_mount.c index 69f62d8b2816..d59f4e8bedcf 100644 --- a/trunk/fs/xfs/xfs_mount.c +++ b/trunk/fs/xfs/xfs_mount.c @@ -1300,7 +1300,7 @@ xfs_mountfs( * Get and sanity-check the root inode. * Save the pointer to it in the mount structure. */ - error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip); + error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); if (error) { cmn_err(CE_WARN, "XFS: failed to read root inode"); goto out_log_dealloc; diff --git a/trunk/fs/xfs/xfs_rtalloc.c b/trunk/fs/xfs/xfs_rtalloc.c index a2d32ce335aa..16445518506d 100644 --- a/trunk/fs/xfs/xfs_rtalloc.c +++ b/trunk/fs/xfs/xfs_rtalloc.c @@ -2277,12 +2277,12 @@ xfs_rtmount_inodes( sbp = &mp->m_sb; if (sbp->sb_rbmino == NULLFSINO) return 0; - error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); + error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip, 0); if (error) return error; ASSERT(mp->m_rbmip != NULL); ASSERT(sbp->sb_rsumino != NULLFSINO); - error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); + error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip, 0); if (error) { IRELE(mp->m_rbmip); return error; diff --git a/trunk/fs/xfs/xfs_trans_inode.c b/trunk/fs/xfs/xfs_trans_inode.c index 2559dfec946b..785ff101da0a 100644 --- a/trunk/fs/xfs/xfs_trans_inode.c +++ b/trunk/fs/xfs/xfs_trans_inode.c @@ -62,7 +62,7 @@ xfs_trans_iget( { int error; - error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp); + error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0); if (!error && tp) xfs_trans_ijoin(tp, *ipp, lock_flags); return error; diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index c1646838898f..a06bd62504fc 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -1269,7 +1269,7 @@ xfs_lookup( if (error) goto out; - error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp); + error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp, 0); if (error) goto out_free_name; diff --git a/trunk/include/linux/agp_backend.h b/trunk/include/linux/agp_backend.h index 09ea4a1e9505..9101ed64f803 100644 --- a/trunk/include/linux/agp_backend.h +++ b/trunk/include/linux/agp_backend.h @@ -79,6 +79,7 @@ struct agp_memory { u32 physical; bool is_bound; bool is_flushed; + bool vmalloc_flag; /* list of agp_memory mapped to the aperture */ struct list_head mapped_list; /* DMA-mapped addresses */ diff --git a/trunk/include/linux/backing-dev.h b/trunk/include/linux/backing-dev.h index 9ae2889096b6..aee5f6ce166e 100644 --- a/trunk/include/linux/backing-dev.h +++ b/trunk/include/linux/backing-dev.h @@ -105,8 +105,8 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent, int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); void bdi_unregister(struct backing_dev_info *bdi); int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); -void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages); -void bdi_start_background_writeback(struct backing_dev_info *bdi); +void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, + long nr_pages); int bdi_writeback_task(struct bdi_writeback *wb); int bdi_has_dirty_io(struct backing_dev_info *bdi); void bdi_arm_supers_timer(void); diff --git a/trunk/include/linux/compiler-gcc.h b/trunk/include/linux/compiler-gcc.h index 0da5b187f124..73dcf804bc94 100644 --- a/trunk/include/linux/compiler-gcc.h +++ b/trunk/include/linux/compiler-gcc.h @@ -58,12 +58,8 @@ * naked functions because then mcount is called without stack and frame pointer * being set up and there is no chance to restore the lr register to the value * before mcount was called. - * - * The asm() bodies of naked functions often depend on standard calling conventions, - * therefore they must be noinline and noclone. GCC 4.[56] currently fail to enforce - * this, so we must do so ourselves. See GCC PR44290. */ -#define __naked __attribute__((naked)) noinline __noclone notrace +#define __naked __attribute__((naked)) notrace #define __noreturn __attribute__((noreturn)) @@ -89,7 +85,3 @@ #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h) #define gcc_header(x) _gcc_header(x) #include gcc_header(__GNUC__) - -#if !defined(__noclone) -#define __noclone /* not needed */ -#endif diff --git a/trunk/include/linux/compiler-gcc4.h b/trunk/include/linux/compiler-gcc4.h index fcfa5b9a4317..94dea3ffbfa1 100644 --- a/trunk/include/linux/compiler-gcc4.h +++ b/trunk/include/linux/compiler-gcc4.h @@ -48,10 +48,6 @@ * unreleased. Really, we need to have autoconf for the kernel. */ #define unreachable() __builtin_unreachable() - -/* Mark a function definition as prohibited from being cloned. */ -#define __noclone __attribute__((__noclone__)) - #endif #endif diff --git a/trunk/include/linux/drbd.h b/trunk/include/linux/drbd.h index b8d2516668aa..30da4ae48972 100644 --- a/trunk/include/linux/drbd.h +++ b/trunk/include/linux/drbd.h @@ -53,7 +53,7 @@ extern const char *drbd_buildtag(void); -#define REL_VERSION "8.3.8" +#define REL_VERSION "8.3.8rc2" #define API_VERSION 88 #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 94 diff --git a/trunk/include/linux/dynamic_debug.h b/trunk/include/linux/dynamic_debug.h index 52c0da4bdd18..b3cd4de9432b 100644 --- a/trunk/include/linux/dynamic_debug.h +++ b/trunk/include/linux/dynamic_debug.h @@ -40,7 +40,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, const char *modname); #if defined(CONFIG_DYNAMIC_DEBUG) -extern int ddebug_remove_module(const char *mod_name); +extern int ddebug_remove_module(char *mod_name); #define __dynamic_dbg_enabled(dd) ({ \ int __ret = 0; \ @@ -73,7 +73,7 @@ extern int ddebug_remove_module(const char *mod_name); #else -static inline int ddebug_remove_module(const char *mod) +static inline int ddebug_remove_module(char *mod) { return 0; } diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index 8e5a9dfb76bf..907ace3a64c8 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -786,6 +786,8 @@ struct fb_tile_ops { #define FBINFO_MISC_USEREVENT 0x10000 /* event request from userspace */ #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ +#define FBINFO_MISC_FIRMWARE 0x40000 /* a replaceable firmware + inited framebuffer */ /* A driver may set this flag to indicate that it does want a set_par to be * called every time when fbcon_switch is executed. The advantage is that with @@ -799,8 +801,6 @@ struct fb_tile_ops { */ #define FBINFO_MISC_ALWAYS_SETPAR 0x40000 -/* where the fb is a firmware driver, and can be replaced with a proper one */ -#define FBINFO_MISC_FIRMWARE 0x80000 /* * Host and GPU endianness differ. */ diff --git a/trunk/include/linux/list.h b/trunk/include/linux/list.h index 5d57a3a1fa1b..8392884a2977 100644 --- a/trunk/include/linux/list.h +++ b/trunk/include/linux/list.h @@ -544,21 +544,6 @@ static inline void list_splice_tail_init(struct list_head *list, &pos->member != (head); \ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) -/** - * list_safe_reset_next - reset a stale list_for_each_entry_safe loop - * @pos: the loop cursor used in the list_for_each_entry_safe loop - * @n: temporary storage used in list_for_each_entry_safe - * @member: the name of the list_struct within the struct. - * - * list_safe_reset_next is not safe to use in general if the list may be - * modified concurrently (eg. the lock is dropped in the loop body). An - * exception to this is if the cursor element (pos) is pinned in the list, - * and list_safe_reset_next is called after re-taking the lock and before - * completing the current iteration of the loop body. - */ -#define list_safe_reset_next(pos, n, member) \ - n = list_entry(pos->member.next, typeof(*pos), member) - /* * Double linked lists with a single pointer list head. * Mostly useful for hash tables where the two pointer list head is diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 3bedcc149c84..4eb467910a45 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1261,7 +1261,6 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA 0x0D85 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_TT128 0x9128 diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 747fcaedddb7..f118809c953f 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -139,7 +139,7 @@ extern int nr_processes(void); extern unsigned long nr_running(void); extern unsigned long nr_uninterruptible(void); extern unsigned long nr_iowait(void); -extern unsigned long nr_iowait_cpu(int cpu); +extern unsigned long nr_iowait_cpu(void); extern unsigned long this_cpu_load(void); diff --git a/trunk/init/main.c b/trunk/init/main.c index 4ab5124a2952..e407a05adc29 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -422,26 +422,18 @@ static void __init setup_command_line(char *command_line) * gcc-3.4 accidentally inlines this function, so use noinline. */ -static __initdata DECLARE_COMPLETION(kthreadd_done); - static noinline void __init_refok rest_init(void) __releases(kernel_lock) { int pid; rcu_scheduler_starting(); - /* - * We need to spawn init first so that it obtains pid 1, however - * the init task will end up wanting to create kthreads, which, if - * we schedule it before we create kthreadd, will OOPS. - */ kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); numa_default_policy(); pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); rcu_read_lock(); kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); rcu_read_unlock(); - complete(&kthreadd_done); unlock_kernel(); /* @@ -857,10 +849,6 @@ static noinline int init_post(void) static int __init kernel_init(void * unused) { - /* - * Wait until kthreadd is all set-up. - */ - wait_for_completion(&kthreadd_done); lock_kernel(); /* diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 6a3a5fa1526d..e7a35f1039e7 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -429,11 +429,20 @@ static void free_pi_state(struct futex_pi_state *pi_state) static struct task_struct * futex_find_get_task(pid_t pid) { struct task_struct *p; + const struct cred *cred = current_cred(), *pcred; rcu_read_lock(); p = find_task_by_vpid(pid); - if (p) - get_task_struct(p); + if (!p) { + p = ERR_PTR(-ESRCH); + } else { + pcred = __task_cred(p); + if (cred->euid != pcred->euid && + cred->euid != pcred->uid) + p = ERR_PTR(-ESRCH); + else + get_task_struct(p); + } rcu_read_unlock(); @@ -555,8 +564,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, if (!pid) return -ESRCH; p = futex_find_get_task(pid); - if (!p) - return -ESRCH; + if (IS_ERR(p)) + return PTR_ERR(p); /* * We need to look at the task state flags to figure out, diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index 131b1703936f..474a84715eac 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -1089,10 +1089,9 @@ void crash_kexec(struct pt_regs *regs) size_t crash_get_memory_size(void) { - size_t size = 0; + size_t size; mutex_lock(&kexec_mutex); - if (crashk_res.end != crashk_res.start) - size = crashk_res.end - crashk_res.start + 1; + size = crashk_res.end - crashk_res.start + 1; mutex_unlock(&kexec_mutex); return size; } @@ -1135,7 +1134,7 @@ int crash_shrink_memory(unsigned long new_size) free_reserved_phys_range(end, crashk_res.end); - if ((start == end) && (crashk_res.parent != NULL)) + if (start == end) release_resource(&crashk_res); crashk_res.end = end - 1; diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 5d2d28197c82..8c6b42840dd1 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2062,12 +2062,6 @@ static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num) #endif } -static void dynamic_debug_remove(struct _ddebug *debug) -{ - if (debug) - ddebug_remove_module(debug->modname); -} - static void *module_alloc_update_bounds(unsigned long size) { void *ret = module_alloc(size); @@ -2130,8 +2124,6 @@ static noinline struct module *load_module(void __user *umod, void *ptr = NULL; /* Stops spurious gcc warning */ unsigned long symoffs, stroffs, *strmap; void __percpu *percpu; - struct _ddebug *debug = NULL; - unsigned int num_debug = 0; mm_segment_t old_fs; @@ -2484,9 +2476,15 @@ static noinline struct module *load_module(void __user *umod, kfree(strmap); strmap = NULL; - if (!mod->taints) + if (!mod->taints) { + struct _ddebug *debug; + unsigned int num_debug; + debug = section_objs(hdr, sechdrs, secstrings, "__verbose", sizeof(*debug), &num_debug); + if (debug) + dynamic_debug_setup(debug, num_debug); + } err = module_finalize(hdr, sechdrs, mod); if (err < 0) @@ -2528,13 +2526,10 @@ static noinline struct module *load_module(void __user *umod, goto unlock; } - if (debug) - dynamic_debug_setup(debug, num_debug); - /* Find duplicate symbols */ err = verify_export_symbols(mod); if (err < 0) - goto ddebug; + goto unlock; list_add_rcu(&mod->list, &modules); mutex_unlock(&module_mutex); @@ -2562,8 +2557,6 @@ static noinline struct module *load_module(void __user *umod, mutex_lock(&module_mutex); /* Unlink carefully: kallsyms could be walking list. */ list_del_rcu(&mod->list); - ddebug: - dynamic_debug_remove(debug); unlock: mutex_unlock(&module_mutex); synchronize_sched(); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 265cf3a2b5d8..8c473adbf223 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -2873,9 +2873,9 @@ unsigned long nr_iowait(void) return sum; } -unsigned long nr_iowait_cpu(int cpu) +unsigned long nr_iowait_cpu(void) { - struct rq *this = cpu_rq(cpu); + struct rq *this = this_rq(); return atomic_read(&this->nr_iowait); } diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index 813993b5fb61..783fbadf2202 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -154,14 +154,14 @@ static void tick_nohz_update_jiffies(ktime_t now) * Updates the per cpu time idle statistics counters */ static void -update_ts_time_stats(int cpu, struct tick_sched *ts, ktime_t now, u64 *last_update_time) +update_ts_time_stats(struct tick_sched *ts, ktime_t now, u64 *last_update_time) { ktime_t delta; if (ts->idle_active) { delta = ktime_sub(now, ts->idle_entrytime); ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); - if (nr_iowait_cpu(cpu) > 0) + if (nr_iowait_cpu() > 0) ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta); ts->idle_entrytime = now; } @@ -175,19 +175,19 @@ static void tick_nohz_stop_idle(int cpu, ktime_t now) { struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); - update_ts_time_stats(cpu, ts, now, NULL); + update_ts_time_stats(ts, now, NULL); ts->idle_active = 0; sched_clock_idle_wakeup_event(0); } -static ktime_t tick_nohz_start_idle(int cpu, struct tick_sched *ts) +static ktime_t tick_nohz_start_idle(struct tick_sched *ts) { ktime_t now; now = ktime_get(); - update_ts_time_stats(cpu, ts, now, NULL); + update_ts_time_stats(ts, now, NULL); ts->idle_entrytime = now; ts->idle_active = 1; @@ -216,7 +216,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) if (!tick_nohz_enabled) return -1; - update_ts_time_stats(cpu, ts, ktime_get(), last_update_time); + update_ts_time_stats(ts, ktime_get(), last_update_time); return ktime_to_us(ts->idle_sleeptime); } @@ -242,7 +242,7 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time) if (!tick_nohz_enabled) return -1; - update_ts_time_stats(cpu, ts, ktime_get(), last_update_time); + update_ts_time_stats(ts, ktime_get(), last_update_time); return ktime_to_us(ts->iowait_sleeptime); } @@ -284,7 +284,7 @@ void tick_nohz_stop_sched_tick(int inidle) */ ts->inidle = 1; - now = tick_nohz_start_idle(cpu, ts); + now = tick_nohz_start_idle(ts); /* * If this cpu is offline and it is the one which updates diff --git a/trunk/lib/dynamic_debug.c b/trunk/lib/dynamic_debug.c index 02afc2533728..3df8eb17a607 100644 --- a/trunk/lib/dynamic_debug.c +++ b/trunk/lib/dynamic_debug.c @@ -692,7 +692,7 @@ static void ddebug_table_free(struct ddebug_table *dt) * Called in response to a module being unloaded. Removes * any ddebug_table's which point at the module. */ -int ddebug_remove_module(const char *mod_name) +int ddebug_remove_module(char *mod_name) { struct ddebug_table *dt, *nextdt; int ret = -ENOENT; diff --git a/trunk/lib/genalloc.c b/trunk/lib/genalloc.c index 1923f1490e72..736c3b06398e 100644 --- a/trunk/lib/genalloc.c +++ b/trunk/lib/genalloc.c @@ -128,6 +128,7 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); end_bit = (chunk->end_addr - chunk->start_addr) >> order; + end_bit -= nbits + 1; spin_lock_irqsave(&chunk->lock, flags); start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0, diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 20a8193a7af8..c6ece0a57595 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -1370,7 +1370,7 @@ static void memcg_wakeup_oom(struct mem_cgroup *mem) static void memcg_oom_recover(struct mem_cgroup *mem) { - if (atomic_read(&mem->oom_lock)) + if (mem->oom_kill_disable && atomic_read(&mem->oom_lock)) memcg_wakeup_oom(mem); } @@ -3781,8 +3781,6 @@ static int mem_cgroup_oom_control_write(struct cgroup *cgrp, return -EINVAL; } mem->oom_kill_disable = val; - if (!val) - memcg_oom_recover(mem); cgroup_unlock(); return 0; } diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 5bc0a96beb51..5d6fb339de03 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -2094,7 +2094,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) NODEMASK_SCRATCH(scratch); if (!scratch) - goto put_mpol; + return; /* contextualize the tmpfs mount point mempolicy */ new = mpol_new(mpol->mode, mpol->flags, &mpol->w.user_nodemask); if (IS_ERR(new)) @@ -2103,20 +2103,19 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) task_lock(current); ret = mpol_set_nodemask(new, &mpol->w.user_nodemask, scratch); task_unlock(current); + mpol_put(mpol); /* drop our ref on sb mpol */ if (ret) - goto put_new; + goto put_free; /* Create pseudo-vma that contains just the policy */ memset(&pvma, 0, sizeof(struct vm_area_struct)); pvma.vm_end = TASK_SIZE; /* policy covers entire file */ mpol_set_shared_policy(sp, &pvma, new); /* adds ref */ -put_new: +put_free: mpol_put(new); /* drop initial ref */ free_scratch: NODEMASK_SCRATCH_FREE(scratch); -put_mpol: - mpol_put(mpol); /* drop our incoming ref on sb mpol */ } } diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 54f28bd493d3..bbd396ac9546 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -597,7 +597,7 @@ static void balance_dirty_pages(struct address_space *mapping, (!laptop_mode && ((global_page_state(NR_FILE_DIRTY) + global_page_state(NR_UNSTABLE_NFS)) > background_thresh))) - bdi_start_background_writeback(bdi); + bdi_start_writeback(bdi, NULL, 0); } void set_page_dirty_balance(struct page *page, int page_mkwrite) @@ -705,8 +705,9 @@ void laptop_mode_timer_fn(unsigned long data) * We want to write everything out, not just down to the dirty * threshold */ + if (bdi_has_dirty_io(&q->backing_dev_info)) - bdi_start_writeback(&q->backing_dev_info, nr_pages); + bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages); } /* diff --git a/trunk/scripts/package/Makefile b/trunk/scripts/package/Makefile index cea12744a671..18513b0191db 100644 --- a/trunk/scripts/package/Makefile +++ b/trunk/scripts/package/Makefile @@ -44,7 +44,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE fi $(MAKE) clean $(PREV) ln -sf $(srctree) $(KERNELPATH) - $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --scm-only > $(objtree)/.scmversion + $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. $(PREV) rm $(KERNELPATH) rm -f $(objtree)/.scmversion diff --git a/trunk/scripts/setlocalversion b/trunk/scripts/setlocalversion index d6a866ed1835..46989b88d734 100755 --- a/trunk/scripts/setlocalversion +++ b/trunk/scripts/setlocalversion @@ -10,158 +10,73 @@ # usage() { - echo "Usage: $0 [--scm-only] [srctree]" >&2 + echo "Usage: $0 [srctree]" >&2 exit 1 } -scm_only=false -srctree=. -if test "$1" = "--scm-only"; then - scm_only=true - shift -fi -if test $# -gt 0; then - srctree=$1 - shift -fi -if test $# -gt 0 -o ! -d "$srctree"; then - usage -fi +cd "${1:-.}" || usage -scm_version() -{ - local short=false +# Check for git and a git repo. +if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then - cd "$srctree" - if test -e .scmversion; then - cat "$_" - return - fi - if test "$1" = "--short"; then - short=true - fi + # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it, + # because this version is defined in the top level Makefile. + if [ -z "`git describe --exact-match 2>/dev/null`" ]; then - # Check for git and a git repo. - if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then - - # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore - # it, because this version is defined in the top level Makefile. - if [ -z "`git describe --exact-match 2>/dev/null`" ]; then - - # If only the short version is requested, don't bother - # running further git commands - if $short; then - echo "+" - return - fi - # If we are past a tagged commit (like - # "v2.6.30-rc5-302-g72357d5"), we pretty print it. - if atag="`git describe 2>/dev/null`"; then - echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' - - # If we don't have a tag at all we print -g{commitish}. - else - printf '%s%s' -g $head - fi - fi + # If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"), + # we pretty print it. + if atag="`git describe 2>/dev/null`"; then + echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' - # Is this git on svn? - if git config --get svn-remote.svn.url >/dev/null; then - printf -- '-svn%s' "`git svn find-rev $head`" + # If we don't have a tag at all we print -g{commitish}. + else + printf '%s%s' -g $head fi - - # Update index only on r/w media - [ -w . ] && git update-index --refresh --unmerged > /dev/null - - # Check for uncommitted changes - if git diff-index --name-only HEAD | grep -v "^scripts/package" \ - | read dummy; then - printf '%s' -dirty - fi - - # All done with git - return fi - # Check for mercurial and a mercurial repo. - if hgid=`hg id 2>/dev/null`; then - tag=`printf '%s' "$hgid" | cut -d' ' -f2` - - # Do we have an untagged version? - if [ -z "$tag" -o "$tag" = tip ]; then - id=`printf '%s' "$hgid" | sed 's/[+ ].*//'` - printf '%s%s' -hg "$id" - fi + # Is this git on svn? + if git config --get svn-remote.svn.url >/dev/null; then + printf -- '-svn%s' "`git svn find-rev $head`" + fi - # Are there uncommitted changes? - # These are represented by + after the changeset id. - case "$hgid" in - *+|*+\ *) printf '%s' -dirty ;; - esac + # Update index only on r/w media + [ -w . ] && git update-index --refresh --unmerged > /dev/null - # All done with mercurial - return + # Check for uncommitted changes + if git diff-index --name-only HEAD | grep -v "^scripts/package" \ + | read dummy; then + printf '%s' -dirty fi - # Check for svn and a svn repo. - if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then - rev=`echo $rev | awk '{print $NF}'` - printf -- '-svn%s' "$rev" + # All done with git + exit +fi - # All done with svn - return +# Check for mercurial and a mercurial repo. +if hgid=`hg id 2>/dev/null`; then + tag=`printf '%s' "$hgid" | cut -d' ' -f2` + + # Do we have an untagged version? + if [ -z "$tag" -o "$tag" = tip ]; then + id=`printf '%s' "$hgid" | sed 's/[+ ].*//'` + printf '%s%s' -hg "$id" fi -} -collect_files() -{ - local file res - - for file; do - case "$file" in - *\~*) - continue - ;; - esac - if test -e "$file"; then - res="$res$(cat "$file")" - fi - done - echo "$res" -} + # Are there uncommitted changes? + # These are represented by + after the changeset id. + case "$hgid" in + *+|*+\ *) printf '%s' -dirty ;; + esac -if $scm_only; then - scm_version + # All done with mercurial exit fi -if test -e include/config/auto.conf; then - source "$_" -else - echo "Error: kernelrelease not valid - run 'make prepare' to update it" - exit 1 -fi - -# localversion* files in the build and source directory -res="$(collect_files localversion*)" -if test ! "$srctree" -ef .; then - res="$res$(collect_files "$srctree"/localversion*)" -fi +# Check for svn and a svn repo. +if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then + rev=`echo $rev | awk '{print $NF}'` + printf -- '-svn%s' "$rev" -# CONFIG_LOCALVERSION and LOCALVERSION (if set) -res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}" - -# scm version string if not at a tagged commit -if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then - # full scm version string - res="$res$(scm_version)" -else - # apped a plus sign if the repository is not in a clean tagged - # state and LOCALVERSION= is not specified - if test "${LOCALVERSION+set}" != "set"; then - scm=$(scm_version --short) - res="$res${scm:++}" - fi + # All done with svn + exit fi - -echo "$res" diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 17a3692397c5..26f626d45a9e 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -605,33 +605,35 @@ endif ifdef NO_DEMANGLE BASIC_CFLAGS += -DNO_DEMANGLE -else ifdef HAVE_CPLUS_DEMANGLE - EXTLIBS += -liberty - BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE else - FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd - has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) - ifeq ($(has_bfd),y) - EXTLIBS += -lbfd - else - FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty - has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY)) - ifeq ($(has_bfd_iberty),y) - EXTLIBS += -lbfd -liberty + ifdef HAVE_CPLUS_DEMANGLE + EXTLIBS += -liberty + BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE + else + FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd + has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) + ifeq ($(has_bfd),y) + EXTLIBS += -lbfd else - FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz - has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z)) - ifeq ($(has_bfd_iberty_z),y) - EXTLIBS += -lbfd -liberty -lz + FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty + has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY)) + ifeq ($(has_bfd_iberty),y) + EXTLIBS += -lbfd -liberty else - FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty - has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE)) - ifeq ($(has_cplus_demangle),y) - EXTLIBS += -liberty - BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE + FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz + has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z)) + ifeq ($(has_bfd_iberty_z),y) + EXTLIBS += -lbfd -liberty -lz else - msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling) - BASIC_CFLAGS += -DNO_DEMANGLE + FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty + has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE)) + ifeq ($(has_cplus_demangle),y) + EXTLIBS += -liberty + BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE + else + msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling) + BASIC_CFLAGS += -DNO_DEMANGLE + endif endif endif endif diff --git a/trunk/tools/perf/util/thread.c b/trunk/tools/perf/util/thread.c index 9a448b47400c..1f7ecd47f499 100644 --- a/trunk/tools/perf/util/thread.c +++ b/trunk/tools/perf/util/thread.c @@ -7,15 +7,6 @@ #include "util.h" #include "debug.h" -/* Skip "." and ".." directories */ -static int filter(const struct dirent *dir) -{ - if (dir->d_name[0] == '.') - return 0; - else - return 1; -} - int find_all_tid(int pid, pid_t ** all_tid) { char name[256]; @@ -25,7 +16,7 @@ int find_all_tid(int pid, pid_t ** all_tid) int i; sprintf(name, "/proc/%d/task", pid); - items = scandir(name, &namelist, filter, NULL); + items = scandir(name, &namelist, NULL, NULL); if (items <= 0) return -ENOENT; *all_tid = malloc(sizeof(pid_t) * items);