From 5dab0ac7b41dd2e4909af07acf95115d3b542253 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 6 Feb 2012 11:22:21 -0800 Subject: [PATCH] --- yaml --- r: 296629 b: refs/heads/master c: 18403424c4fe5bac509bf52343f5d5407d45ee3a h: refs/heads/master i: 296627: ef60019f66b59cf10bba9bddb0c073dc0870655c v: v3 --- [refs] | 2 +- .../ABI/testing/sysfs-devices-soc | 58 ---- trunk/Documentation/dynamic-debug-howto.txt | 30 +- trunk/Documentation/filesystems/debugfs.txt | 5 +- trunk/arch/arm/mach-ux500/board-mop500-sdi.c | 31 +- trunk/arch/arm/mach-ux500/board-mop500.c | 62 ++-- trunk/arch/arm/mach-ux500/board-mop500.h | 8 +- trunk/arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- trunk/arch/arm/mach-ux500/board-u5500.c | 23 +- trunk/arch/arm/mach-ux500/cpu-db5500.c | 18 +- trunk/arch/arm/mach-ux500/cpu-db8500.c | 15 +- trunk/arch/arm/mach-ux500/devices-common.c | 13 +- trunk/arch/arm/mach-ux500/devices-common.h | 39 +-- trunk/arch/arm/mach-ux500/devices-db5500.h | 116 ++++---- trunk/arch/arm/mach-ux500/devices-db8500.h | 166 ++++++----- trunk/arch/arm/mach-ux500/dma-db5500.c | 3 +- .../arch/arm/mach-ux500/include/mach/setup.h | 8 +- trunk/arch/arm/mach-ux500/include/mach/usb.h | 4 +- trunk/arch/arm/mach-ux500/usb.c | 4 +- trunk/arch/x86/Kconfig | 3 - trunk/arch/x86/crypto/aesni-intel_glue.c | 12 +- trunk/arch/x86/crypto/crc32c-intel.c | 11 +- .../x86/crypto/ghash-clmulni-intel_glue.c | 12 +- trunk/arch/x86/include/asm/cpu_device_id.h | 13 - trunk/arch/x86/include/asm/cpufeature.h | 1 - trunk/arch/x86/kernel/cpu/Makefile | 1 - trunk/arch/x86/kernel/cpu/match.c | 92 ------ trunk/arch/x86/kernel/cpu/scattered.c | 1 - trunk/arch/x86/kernel/microcode_core.c | 15 - trunk/drivers/acpi/processor_driver.c | 1 - trunk/drivers/acpi/processor_perflib.c | 22 -- trunk/drivers/base/Kconfig | 3 - trunk/drivers/base/Makefile | 1 - trunk/drivers/base/bus.c | 6 +- trunk/drivers/base/cpu.c | 11 - trunk/drivers/base/driver.c | 35 ++- trunk/drivers/base/soc.c | 183 ------------ trunk/drivers/cpufreq/cpufreq-nforce2.c | 8 - trunk/drivers/cpufreq/e_powersaver.c | 20 +- trunk/drivers/cpufreq/elanfreq.c | 14 +- trunk/drivers/cpufreq/gx-suspmod.c | 9 +- trunk/drivers/cpufreq/longhaul.c | 8 +- trunk/drivers/cpufreq/longrun.c | 13 +- trunk/drivers/cpufreq/p4-clockmod.c | 17 +- trunk/drivers/cpufreq/powernow-k6.c | 12 +- trunk/drivers/cpufreq/powernow-k7.c | 14 +- trunk/drivers/cpufreq/powernow-k8.c | 19 +- trunk/drivers/cpufreq/sc520_freq.c | 14 +- trunk/drivers/cpufreq/speedstep-centrino.c | 24 +- trunk/drivers/cpufreq/speedstep-ich.c | 15 - trunk/drivers/cpufreq/speedstep-lib.c | 1 - trunk/drivers/cpufreq/speedstep-smi.c | 15 - trunk/drivers/crypto/padlock-aes.c | 9 +- trunk/drivers/crypto/padlock-sha.c | 16 +- trunk/drivers/hid/hid-core.c | 6 +- trunk/drivers/hv/channel_mgmt.c | 87 ++++++ trunk/drivers/hv/hv.c | 4 +- trunk/drivers/hv/hv_kvp.c | 43 ++- trunk/drivers/hv/hv_kvp.h | 184 ++++++++++++ trunk/drivers/hv/hv_util.c | 3 + trunk/drivers/hv/hyperv_vmbus.h | 5 +- trunk/drivers/hwmon/coretemp.c | 17 +- trunk/drivers/hwmon/via-cputemp.c | 16 +- trunk/drivers/idle/intel_idle.c | 116 ++++---- trunk/drivers/input/gameport/gameport.c | 1 + trunk/drivers/input/serio/serio.c | 1 + .../drivers/media/video/cx18/cx18-alsa-main.c | 1 + trunk/drivers/media/video/ivtv/ivtvfb.c | 2 + .../media/video/s5p-fimc/fimc-mdevice.c | 5 +- .../drivers/media/video/s5p-tv/mixer_video.c | 1 + trunk/drivers/net/phy/phy_device.c | 6 +- trunk/drivers/pci/pci-driver.c | 52 ++-- trunk/drivers/pci/xen-pcifront.c | 3 +- trunk/drivers/pcmcia/ds.c | 11 +- trunk/drivers/s390/cio/ccwgroup.c | 2 + trunk/drivers/s390/cio/device.c | 8 +- trunk/drivers/s390/net/smsgiucv_app.c | 9 +- trunk/drivers/ssb/main.c | 20 +- trunk/drivers/usb/core/driver.c | 66 +++-- trunk/drivers/usb/dwc3/dwc3-pci.c | 12 +- trunk/drivers/w1/masters/w1-gpio.c | 3 +- trunk/fs/debugfs/inode.c | 149 +--------- trunk/fs/sysfs/dir.c | 228 +++++++-------- trunk/fs/sysfs/inode.c | 3 + trunk/fs/sysfs/mount.c | 2 +- trunk/fs/sysfs/sysfs.h | 18 +- trunk/include/acpi/processor.h | 1 - trunk/include/linux/connector.h | 1 - trunk/include/linux/cpu.h | 7 - trunk/include/linux/device.h | 10 +- trunk/include/linux/dynamic_debug.h | 19 +- trunk/include/linux/hyperv.h | 146 ---------- trunk/include/linux/mod_devicetable.h | 21 -- trunk/include/linux/netdevice.h | 8 +- trunk/include/linux/pci.h | 13 - trunk/include/linux/printk.h | 8 +- trunk/include/linux/sys_soc.h | 37 --- trunk/lib/dma-debug.c | 3 +- trunk/lib/dynamic_debug.c | 270 ++++++------------ trunk/scripts/mod/file2alias.c | 24 -- trunk/tools/hv/hv_kvp_daemon.c | 62 ++-- 101 files changed, 1205 insertions(+), 1769 deletions(-) delete mode 100644 trunk/Documentation/ABI/testing/sysfs-devices-soc delete mode 100644 trunk/arch/x86/include/asm/cpu_device_id.h delete mode 100644 trunk/arch/x86/kernel/cpu/match.c delete mode 100644 trunk/drivers/base/soc.c create mode 100644 trunk/drivers/hv/hv_kvp.h delete mode 100644 trunk/include/linux/sys_soc.h diff --git a/[refs] b/[refs] index 9dca3d2a209f..47a1b3821819 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: eaa5699e3bff8e8335757cf401451ffbd4a88109 +refs/heads/master: 18403424c4fe5bac509bf52343f5d5407d45ee3a diff --git a/trunk/Documentation/ABI/testing/sysfs-devices-soc b/trunk/Documentation/ABI/testing/sysfs-devices-soc deleted file mode 100644 index 6d9cc253f2b2..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-devices-soc +++ /dev/null @@ -1,58 +0,0 @@ -What: /sys/devices/socX -Date: January 2012 -contact: Lee Jones -Description: - The /sys/devices/ directory contains a sub-directory for each - System-on-Chip (SoC) device on a running platform. Information - regarding each SoC can be obtained by reading sysfs files. This - functionality is only available if implemented by the platform. - - The directory created for each SoC will also house information - about devices which are commonly contained in /sys/devices/platform. - It has been agreed that if an SoC device exists, its supported - devices would be better suited to appear as children of that SoC. - -What: /sys/devices/socX/machine -Date: January 2012 -contact: Lee Jones -Description: - Read-only attribute common to all SoCs. Contains the SoC machine - name (e.g. Ux500). - -What: /sys/devices/socX/family -Date: January 2012 -contact: Lee Jones -Description: - Read-only attribute common to all SoCs. Contains SoC family name - (e.g. DB8500). - -What: /sys/devices/socX/soc_id -Date: January 2012 -contact: Lee Jones -Description: - Read-only attribute supported by most SoCs. In the case of - ST-Ericsson's chips this contains the SoC serial number. - -What: /sys/devices/socX/revision -Date: January 2012 -contact: Lee Jones -Description: - Read-only attribute supported by most SoCs. Contains the SoC's - manufacturing revision number. - -What: /sys/devices/socX/process -Date: January 2012 -contact: Lee Jones -Description: - Read-only attribute supported ST-Ericsson's silicon. Contains the - the process by which the silicon chip was manufactured. - -What: /sys/bus/soc -Date: January 2012 -contact: Lee Jones -Description: - The /sys/bus/soc/ directory contains the usual sub-folders - expected under most buses. /sys/bus/soc/devices is of particular - interest, as it contains a symlink for each SoC device found on - the system. Each symlink points back into the aforementioned - /sys/devices/socX devices. diff --git a/trunk/Documentation/dynamic-debug-howto.txt b/trunk/Documentation/dynamic-debug-howto.txt index 74e6c7782678..f959909d7154 100644 --- a/trunk/Documentation/dynamic-debug-howto.txt +++ b/trunk/Documentation/dynamic-debug-howto.txt @@ -12,7 +12,7 @@ dynamically enabled per-callsite. Dynamic debug has even more useful features: * Simple query language allows turning on and off debugging statements by - matching any combination of 0 or 1 of: + matching any combination of: - source filename - function name @@ -79,24 +79,31 @@ Command Language Reference ========================== At the lexical level, a command comprises a sequence of words separated -by spaces or tabs. So these are all equivalent: +by whitespace characters. Note that newlines are treated as word +separators and do *not* end a command or allow multiple commands to +be done together. So these are all equivalent: nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' > /dynamic_debug/control nullarbor:~ # echo -c ' file svcsock.c line 1603 +p ' > /dynamic_debug/control +nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' > + /dynamic_debug/control nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' > /dynamic_debug/control -Command submissions are bounded by a write() system call. -Multiple commands can be written together, separated by ';' or '\n'. +Commands are bounded by a write() system call. If you want to do +multiple commands you need to do a separate "echo" for each, like: - ~# echo "func pnpacpi_get_resources +p; func pnp_assign_mem +p" \ - > /dynamic_debug/control +nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\ +> echo 'file svcsock.c line 1563 +p' > /proc/dprintk -If your query set is big, you can batch them too: +or even like: - ~# cat query-batch-file > /dynamic_debug/control +nullarbor:~ # ( +> echo 'file svcsock.c line 1603 +p' ;\ +> echo 'file svcsock.c line 1563 +p' ;\ +> ) > /proc/dprintk At the syntactical level, a command comprises a sequence of match specifications, followed by a flags change specification. @@ -137,12 +144,11 @@ func func svc_tcp_accept file - The given string is compared against either the full pathname, the - src-root relative pathname, or the basename of the source file of - each callsite. Examples: + The given string is compared against either the full + pathname or the basename of the source file of each + callsite. Examples: file svcsock.c - file kernel/freezer.c file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c module diff --git a/trunk/Documentation/filesystems/debugfs.txt b/trunk/Documentation/filesystems/debugfs.txt index 4e2575873187..6872c91bce35 100644 --- a/trunk/Documentation/filesystems/debugfs.txt +++ b/trunk/Documentation/filesystems/debugfs.txt @@ -14,10 +14,7 @@ Debugfs is typically mounted with a command like: mount -t debugfs none /sys/kernel/debug -(Or an equivalent /etc/fstab line). -The debugfs root directory is accessible by anyone by default. To -restrict access to the tree the "uid", "gid" and "mode" mount -options can be used. +(Or an equivalent /etc/fstab line). Note that the debugfs API is exported GPL-only to modules. diff --git a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c index 5dde4d4ebe88..479ebe04cf9c 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c @@ -104,7 +104,7 @@ static struct mmci_platform_data mop500_sdi0_data = { #endif }; -static void sdi0_configure(void) +static void sdi0_configure(struct device *parent) { int ret; @@ -123,15 +123,15 @@ static void sdi0_configure(void) gpio_direction_output(sdi0_en, 1); /* Add the device, force v2 to subrevision 1 */ - db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID); } -void mop500_sdi_tc35892_init(void) +void mop500_sdi_tc35892_init(struct device *parent) { mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD; sdi0_en = GPIO_SDMMC_EN; sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL; - sdi0_configure(); + sdi0_configure(parent); } /* @@ -246,12 +246,13 @@ static struct mmci_platform_data mop500_sdi4_data = { #endif }; -void __init mop500_sdi_init(void) +void __init mop500_sdi_init(struct device *parent) { /* PoP:ed eMMC */ - db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + /* * On boards with the TC35892 GPIO expander, sdi0 will finally * be added when the TC35892 initializes and calls @@ -259,31 +260,31 @@ void __init mop500_sdi_init(void) */ } -void __init snowball_sdi_init(void) +void __init snowball_sdi_init(struct device *parent) { /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */ mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED; /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; mop500_sdi0_data.cd_invert = true; sdi0_en = SNOWBALL_SDMMC_EN_GPIO; sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO; - sdi0_configure(); + sdi0_configure(parent); } -void __init hrefv60_sdi_init(void) +void __init hrefv60_sdi_init(struct device *parent) { /* PoP:ed eMMC */ - db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; sdi0_en = HREFV60_SDMMC_EN_GPIO; sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; - sdi0_configure(); + sdi0_configure(parent); /* WLAN SDIO channel */ - db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID); } diff --git a/trunk/arch/arm/mach-ux500/board-mop500.c b/trunk/arch/arm/mach-ux500/board-mop500.c index 5c00712907d1..f9ce2a1211c9 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.c +++ b/trunk/arch/arm/mach-ux500/board-mop500.c @@ -226,7 +226,12 @@ static struct tps6105x_platform_data mop500_tps61052_data = { static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base) { - mop500_sdi_tc35892_init(); + struct device *parent = NULL; +#if 0 + /* FIXME: Is the sdi actually part of tc3589x? */ + parent = tc3589x->dev; +#endif + mop500_sdi_tc35892_init(parent); } static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = { @@ -353,12 +358,12 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); -static void __init mop500_i2c_init(void) +static void __init mop500_i2c_init(struct device *parent) { - db8500_add_i2c0(&u8500_i2c0_data); - db8500_add_i2c1(&u8500_i2c1_data); - db8500_add_i2c2(&u8500_i2c2_data); - db8500_add_i2c3(&u8500_i2c3_data); + db8500_add_i2c0(parent, &u8500_i2c0_data); + db8500_add_i2c1(parent, &u8500_i2c1_data); + db8500_add_i2c2(parent, &u8500_i2c2_data); + db8500_add_i2c3(parent, &u8500_i2c3_data); } static struct gpio_keys_button mop500_gpio_keys[] = { @@ -451,9 +456,9 @@ static struct pl022_ssp_controller ssp0_platform_data = { .num_chipselect = 5, }; -static void __init mop500_spi_init(void) +static void __init mop500_spi_init(struct device *parent) { - db8500_add_ssp0(&ssp0_platform_data); + db8500_add_ssp0(parent, &ssp0_platform_data); } #ifdef CONFIG_STE_DMA40 @@ -587,11 +592,11 @@ static struct amba_pl011_data uart2_plat = { #endif }; -static void __init mop500_uart_init(void) +static void __init mop500_uart_init(struct device *parent) { - db8500_add_uart0(&uart0_plat); - db8500_add_uart1(&uart1_plat); - db8500_add_uart2(&uart2_plat); + db8500_add_uart0(parent, &uart0_plat); + db8500_add_uart1(parent, &uart1_plat); + db8500_add_uart2(parent, &uart2_plat); } static struct platform_device *snowball_platform_devs[] __initdata = { @@ -603,21 +608,22 @@ static struct platform_device *snowball_platform_devs[] __initdata = { static void __init mop500_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; - u8500_init_devices(); + parent = u8500_init_devices(); mop500_pins_init(); platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); - mop500_i2c_init(); - mop500_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + mop500_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); @@ -631,19 +637,20 @@ static void __init mop500_init_machine(void) static void __init snowball_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; - u8500_init_devices(); + parent = u8500_init_devices(); snowball_pins_init(); platform_add_devices(snowball_platform_devs, ARRAY_SIZE(snowball_platform_devs)); - mop500_i2c_init(); - snowball_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + snowball_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); @@ -656,6 +663,7 @@ static void __init snowball_init_machine(void) static void __init hrefv60_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; /* @@ -665,17 +673,17 @@ static void __init hrefv60_init_machine(void) */ mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - u8500_init_devices(); + parent = u8500_init_devices(); hrefv60_pins_init(); platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); - mop500_i2c_init(); - hrefv60_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + hrefv60_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); diff --git a/trunk/arch/arm/mach-ux500/board-mop500.h b/trunk/arch/arm/mach-ux500/board-mop500.h index f926d3db6207..3d594c24bfee 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.h +++ b/trunk/arch/arm/mach-ux500/board-mop500.h @@ -75,10 +75,10 @@ struct i2c_board_info; -extern void mop500_sdi_init(void); -extern void snowball_sdi_init(void); -extern void hrefv60_sdi_init(void); -extern void mop500_sdi_tc35892_init(void); +extern void mop500_sdi_init(struct device *parent); +extern void snowball_sdi_init(struct device *parent); +extern void hrefv60_sdi_init(struct device *parent); +extern void mop500_sdi_tc35892_init(struct device *parent); void __init mop500_u8500uib_init(void); void __init mop500_stuib_init(void); void __init mop500_pins_init(void); diff --git a/trunk/arch/arm/mach-ux500/board-u5500-sdi.c b/trunk/arch/arm/mach-ux500/board-u5500-sdi.c index 63c3f8058ffc..836112eedde7 100644 --- a/trunk/arch/arm/mach-ux500/board-u5500-sdi.c +++ b/trunk/arch/arm/mach-ux500/board-u5500-sdi.c @@ -66,9 +66,9 @@ static struct mmci_platform_data u5500_sdi0_data = { #endif }; -void __init u5500_sdi_init(void) +void __init u5500_sdi_init(struct device *parent) { nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); - db5500_add_sdi0(&u5500_sdi0_data); + db5500_add_sdi0(parent, &u5500_sdi0_data); } diff --git a/trunk/arch/arm/mach-ux500/board-u5500.c b/trunk/arch/arm/mach-ux500/board-u5500.c index 9de9e9c4dbbb..d7a9596ff664 100644 --- a/trunk/arch/arm/mach-ux500/board-u5500.c +++ b/trunk/arch/arm/mach-ux500/board-u5500.c @@ -97,9 +97,9 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = { }, }; -static void __init u5500_i2c_init(void) +static void __init u5500_i2c_init(struct device *parent) { - db5500_add_i2c2(&u5500_i2c2_data); + db5500_add_i2c2(parent, &u5500_i2c2_data); i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); } @@ -126,20 +126,23 @@ static struct platform_device *u5500_platform_devices[] __initdata = { &ab5500_device, }; -static void __init u5500_uart_init(void) +static void __init u5500_uart_init(struct device *parent) { - db5500_add_uart0(NULL); - db5500_add_uart1(NULL); - db5500_add_uart2(NULL); + db5500_add_uart0(parent, NULL); + db5500_add_uart1(parent, NULL); + db5500_add_uart2(parent, NULL); } static void __init u5500_init_machine(void) { - u5500_init_devices(); + struct device *parent = NULL; + + parent = u5500_init_devices(); nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins)); - u5500_i2c_init(); - u5500_sdi_init(); - u5500_uart_init(); + + u5500_i2c_init(parent); + u5500_sdi_init(parent); + u5500_uart_init(parent); platform_add_devices(u5500_platform_devices, ARRAY_SIZE(u5500_platform_devices)); diff --git a/trunk/arch/arm/mach-ux500/cpu-db5500.c b/trunk/arch/arm/mach-ux500/cpu-db5500.c index 18aa5c05c69e..c402fd6efe53 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db5500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db5500.c @@ -147,13 +147,13 @@ static resource_size_t __initdata db5500_gpio_base[] = { U5500_GPIOBANK7_BASE, }; -static void __init db5500_add_gpios(void) +static void __init db5500_add_gpios(struct device *parent) { struct nmk_gpio_platform_data pdata = { /* No custom data yet */ }; - dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base), + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base), IRQ_DB5500_GPIO0, &pdata); } @@ -212,14 +212,18 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -void __init u5500_init_devices(void) +struct device* __init u5500_init_devices(void) { - db5500_add_gpios(); + /* FIXME: First parameter to be a real parent. */ + db5500_add_gpios(NULL); db5500_pmu_init(); - db5500_dma_init(); - db5500_add_rtc(); - db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(NULL); + db5500_add_rtc(NULL); + db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); + + /* FIXME: Return value to be a real parent. */ + return NULL; } diff --git a/trunk/arch/arm/mach-ux500/cpu-db8500.c b/trunk/arch/arm/mach-ux500/cpu-db8500.c index 7176ee7491ab..1e8a2cb7e503 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db8500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db8500.c @@ -132,13 +132,13 @@ static resource_size_t __initdata db8500_gpio_base[] = { U8500_GPIOBANK8_BASE, }; -static void __init db8500_add_gpios(void) +static void __init db8500_add_gpios(struct device *parent) { struct nmk_gpio_platform_data pdata = { .supports_sleepmode = true, }; - dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base), IRQ_DB8500_GPIO0, &pdata); } @@ -167,14 +167,15 @@ static int usb_db8500_tx_dma_cfg[] = { /* * This function is called from the board init */ -void __init u8500_init_devices(void) +struct device* __init u8500_init_devices(void) { - db8500_add_rtc(); - db8500_add_gpios(); - db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + db8500_add_rtc(NULL); + db8500_add_gpios(NULL); + db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - return ; + /* FIXME: Return value to be a real parent. */ + return NULL; } diff --git a/trunk/arch/arm/mach-ux500/devices-common.c b/trunk/arch/arm/mach-ux500/devices-common.c index c563e5418d80..96be2482ea45 100644 --- a/trunk/arch/arm/mach-ux500/devices-common.c +++ b/trunk/arch/arm/mach-ux500/devices-common.c @@ -20,8 +20,9 @@ #include "devices-common.h" struct amba_device * -dbx500_add_amba_device(const char *name, resource_size_t base, - int irq, void *pdata, unsigned int periphid) +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid) { struct amba_device *dev; int ret; @@ -109,7 +110,7 @@ dbx500_add_platform_device_4k1irq(const char *name, int id, } static struct platform_device * -dbx500_add_gpio(int id, resource_size_t addr, int irq, +dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) { struct resource resources[] = { @@ -130,8 +131,8 @@ dbx500_add_gpio(int id, resource_size_t addr, int irq, pdata, sizeof(*pdata)); } -void dbx500_add_gpios(resource_size_t *base, int num, int irq, - struct nmk_gpio_platform_data *pdata) +void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, + int irq, struct nmk_gpio_platform_data *pdata) { int first = 0; int i; @@ -141,6 +142,6 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq, pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); pdata->num_gpio = 32; - dbx500_add_gpio(i, base[i], irq, pdata); + dbx500_add_gpio(parent, i, base[i], irq, pdata); } } diff --git a/trunk/arch/arm/mach-ux500/devices-common.h b/trunk/arch/arm/mach-ux500/devices-common.h index 7825705033bf..f8adff891a91 100644 --- a/trunk/arch/arm/mach-ux500/devices-common.h +++ b/trunk/arch/arm/mach-ux500/devices-common.h @@ -9,7 +9,7 @@ #define __DEVICES_COMMON_H extern struct amba_device * -dbx500_add_amba_device(const char *name, resource_size_t base, +dbx500_add_amba_device(struct device *parent, const char *name, resource_size_t base, int irq, void *pdata, unsigned int periphid); extern struct platform_device * @@ -20,43 +20,46 @@ dbx500_add_platform_device_4k1irq(const char *name, int id, struct spi_master_cntlr; static inline struct amba_device * -dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, +dbx500_add_msp_spi(struct device *parent, const char *name, + resource_size_t base, int irq, struct spi_master_cntlr *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, 0); } static inline struct amba_device * -dbx500_add_spi(const char *name, resource_size_t base, int irq, - struct spi_master_cntlr *pdata, +dbx500_add_spi(struct device *parent, const char *name, resource_size_t base, + int irq, struct spi_master_cntlr *pdata, u32 periphid) { - return dbx500_add_amba_device(name, base, irq, pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct mmci_platform_data; static inline struct amba_device * -dbx500_add_sdi(const char *name, resource_size_t base, int irq, - struct mmci_platform_data *pdata, - u32 periphid) +dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base, + int irq, struct mmci_platform_data *pdata, u32 periphid) { - return dbx500_add_amba_device(name, base, irq, pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct amba_pl011_data; static inline struct amba_device * -dbx500_add_uart(const char *name, resource_size_t base, int irq, - struct amba_pl011_data *pdata) +dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, + int irq, struct amba_pl011_data *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } struct nmk_i2c_controller; static inline struct platform_device * -dbx500_add_i2c(int id, resource_size_t base, int irq, +dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, struct nmk_i2c_controller *pdata) { return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq, @@ -74,14 +77,14 @@ dbx500_add_msp_i2s(int id, resource_size_t base, int irq, } static inline struct amba_device * -dbx500_add_rtc(resource_size_t base, int irq) +dbx500_add_rtc(struct device *parent, resource_size_t base, int irq) { - return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0); + return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0); } struct nmk_gpio_platform_data; -void dbx500_add_gpios(resource_size_t *base, int num, int irq, - struct nmk_gpio_platform_data *pdata); +void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, + int irq, struct nmk_gpio_platform_data *pdata); #endif diff --git a/trunk/arch/arm/mach-ux500/devices-db5500.h b/trunk/arch/arm/mach-ux500/devices-db5500.h index 0c4bccd02b90..e70955502c35 100644 --- a/trunk/arch/arm/mach-ux500/devices-db5500.h +++ b/trunk/arch/arm/mach-ux500/devices-db5500.h @@ -10,70 +10,90 @@ #include "devices-common.h" -#define db5500_add_i2c1(pdata) \ - dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) -#define db5500_add_i2c2(pdata) \ - dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) -#define db5500_add_i2c3(pdata) \ - dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) +#define db5500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) +#define db5500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) +#define db5500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) -#define db5500_add_msp0_i2s(pdata) \ - dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) -#define db5500_add_msp1_i2s(pdata) \ - dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) -#define db5500_add_msp2_i2s(pdata) \ - dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) -#define db5500_add_msp0_spi(pdata) \ - dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) -#define db5500_add_msp1_spi(pdata) \ - dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) -#define db5500_add_msp2_spi(pdata) \ - dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) -#define db5500_add_rtc() \ - dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); +#define db5500_add_rtc(parent) \ + dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC); -#define db5500_add_usb(rx_cfg, tx_cfg) \ - ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) +#define db5500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U5500_USBOTG_BASE, \ + IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) -#define db5500_add_sdi0(pdata) \ - dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \ +#define db5500_add_sdi0(parent, pdata) \ + dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \ + IRQ_DB5500_SDMMC0, pdata, \ 0x10480180) -#define db5500_add_sdi1(pdata) \ - dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \ +#define db5500_add_sdi1(parent, pdata) \ + dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \ + IRQ_DB5500_SDMMC1, pdata, \ 0x10480180) -#define db5500_add_sdi2(pdata) \ - dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \ +#define db5500_add_sdi2(parent, pdata) \ + dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \ + IRQ_DB5500_SDMMC2, pdata \ 0x10480180) -#define db5500_add_sdi3(pdata) \ - dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \ +#define db5500_add_sdi3(parent, pdata) \ + dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \ + IRQ_DB5500_SDMMC3, pdata \ 0x10480180) -#define db5500_add_sdi4(pdata) \ - dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \ +#define db5500_add_sdi4(parent, pdata) \ + dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \ + IRQ_DB5500_SDMMC4, pdata \ 0x10480180) /* This one has a bad peripheral ID in the U5500 silicon */ -#define db5500_add_spi0(pdata) \ - dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \ +#define db5500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \ + IRQ_DB5500_SPI0, pdata, \ 0x10080023) -#define db5500_add_spi1(pdata) \ - dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \ +#define db5500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \ + IRQ_DB5500_SPI1, pdata, \ 0x10080023) -#define db5500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \ +#define db5500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \ + IRQ_DB5500_SPI2, pdata \ 0x10080023) -#define db5500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \ +#define db5500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \ + IRQ_DB5500_SPI3, pdata \ 0x10080023) -#define db5500_add_uart0(plat) \ - dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat) -#define db5500_add_uart1(plat) \ - dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat) -#define db5500_add_uart2(plat) \ - dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat) -#define db5500_add_uart3(plat) \ - dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat) +#define db5500_add_uart0(parent, plat) \ + dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \ + IRQ_DB5500_UART0, plat) +#define db5500_add_uart1(parent, plat) \ + dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \ + IRQ_DB5500_UART1, plat) +#define db5500_add_uart2(parent, plat) \ + dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \ + IRQ_DB5500_UART2, plat) +#define db5500_add_uart3(parent, plat) \ + dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \ + IRQ_DB5500_UART3, plat) #endif diff --git a/trunk/arch/arm/mach-ux500/devices-db8500.h b/trunk/arch/arm/mach-ux500/devices-db8500.h index cbd4a9ae8109..9bd08ad70042 100644 --- a/trunk/arch/arm/mach-ux500/devices-db8500.h +++ b/trunk/arch/arm/mach-ux500/devices-db8500.h @@ -14,7 +14,9 @@ struct ske_keypad_platform_data; struct pl022_ssp_controller; static inline struct platform_device * -db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) +db8500_add_ske_keypad(struct device *parent, + struct ske_keypad_platform_data *pdata, + size_t size) { return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1, U8500_SKE_BASE, @@ -22,80 +24,100 @@ db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) } static inline struct amba_device * -db8500_add_ssp(const char *name, resource_size_t base, int irq, - struct pl022_ssp_controller *pdata) +db8500_add_ssp(struct device *parent, const char *name, resource_size_t base, + int irq, struct pl022_ssp_controller *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } -#define db8500_add_i2c0(pdata) \ - dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) -#define db8500_add_i2c1(pdata) \ - dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) -#define db8500_add_i2c2(pdata) \ - dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) -#define db8500_add_i2c3(pdata) \ - dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) -#define db8500_add_i2c4(pdata) \ - dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) - -#define db8500_add_msp0_i2s(pdata) \ - dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_i2s(pdata) \ - dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_i2s(pdata) \ - dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_i2s(pdata) \ - dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) - -#define db8500_add_msp0_spi(pdata) \ - dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_spi(pdata) \ - dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_spi(pdata) \ - dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_spi(pdata) \ - dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) - -#define db8500_add_rtc() \ - dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); - -#define db8500_add_usb(rx_cfg, tx_cfg) \ - ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) - -#define db8500_add_sdi0(pdata, pid) \ - dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid) -#define db8500_add_sdi1(pdata, pid) \ - dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid) -#define db8500_add_sdi2(pdata, pid) \ - dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid) -#define db8500_add_sdi3(pdata, pid) \ - dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid) -#define db8500_add_sdi4(pdata, pid) \ - dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid) -#define db8500_add_sdi5(pdata, pid) \ - dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid) - -#define db8500_add_ssp0(pdata) \ - db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) -#define db8500_add_ssp1(pdata) \ - db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) - -#define db8500_add_spi0(pdata) \ - dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0) -#define db8500_add_spi1(pdata) \ - dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0) -#define db8500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0) -#define db8500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0) - -#define db8500_add_uart0(pdata) \ - dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata) -#define db8500_add_uart1(pdata) \ - dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata) -#define db8500_add_uart2(pdata) \ - dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata) +#define db8500_add_i2c0(parent, pdata) \ + dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) +#define db8500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) +#define db8500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) +#define db8500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) +#define db8500_add_i2c4(parent, pdata) \ + dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) + +#define db8500_add_msp0_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) +#define db8500_add_msp1_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) +#define db8500_add_msp2_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) +#define db8500_add_msp3_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) + +#define db8500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \ + IRQ_DB8500_MSP0, pdata) +#define db8500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \ + IRQ_DB8500_MSP1, pdata) +#define db8500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \ + IRQ_DB8500_MSP2, pdata) +#define db8500_add_msp3_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \ + IRQ_DB8500_MSP1, pdata) + +#define db8500_add_rtc(parent) \ + dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC); + +#define db8500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U8500_USBOTG_BASE, \ + IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) + +#define db8500_add_sdi0(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \ + IRQ_DB8500_SDMMC0, pdata, pid) +#define db8500_add_sdi1(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \ + IRQ_DB8500_SDMMC1, pdata, pid) +#define db8500_add_sdi2(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \ + IRQ_DB8500_SDMMC2, pdata, pid) +#define db8500_add_sdi3(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \ + IRQ_DB8500_SDMMC3, pdata, pid) +#define db8500_add_sdi4(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \ + IRQ_DB8500_SDMMC4, pdata, pid) +#define db8500_add_sdi5(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \ + IRQ_DB8500_SDMMC5, pdata, pid) + +#define db8500_add_ssp0(parent, pdata) \ + db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \ + IRQ_DB8500_SSP0, pdata) +#define db8500_add_ssp1(parent, pdata) \ + db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \ + IRQ_DB8500_SSP1, pdata) + +#define db8500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \ + IRQ_DB8500_SPI0, pdata, 0) +#define db8500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \ + IRQ_DB8500_SPI1, pdata, 0) +#define db8500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \ + IRQ_DB8500_SPI2, pdata, 0) +#define db8500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \ + IRQ_DB8500_SPI3, pdata, 0) + +#define db8500_add_uart0(parent, pdata) \ + dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \ + IRQ_DB8500_UART0, pdata) +#define db8500_add_uart1(parent, pdata) \ + dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \ + IRQ_DB8500_UART1, pdata) +#define db8500_add_uart2(parent, pdata) \ + dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \ + IRQ_DB8500_UART2, pdata) #endif diff --git a/trunk/arch/arm/mach-ux500/dma-db5500.c b/trunk/arch/arm/mach-ux500/dma-db5500.c index 1cfab68ae417..41e9470fa0e6 100644 --- a/trunk/arch/arm/mach-ux500/dma-db5500.c +++ b/trunk/arch/arm/mach-ux500/dma-db5500.c @@ -125,10 +125,11 @@ static struct platform_device dma40_device = { .resource = dma40_resources }; -void __init db5500_dma_init(void) +void __init db5500_dma_init(struct device *parent) { int ret; + dma40_device.dev.parent = parent; ret = platform_device_register(&dma40_device); if (ret) dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); diff --git a/trunk/arch/arm/mach-ux500/include/mach/setup.h b/trunk/arch/arm/mach-ux500/include/mach/setup.h index a7d363fdb4cd..e46b8b12056d 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/setup.h +++ b/trunk/arch/arm/mach-ux500/include/mach/setup.h @@ -18,14 +18,14 @@ void __init ux500_map_io(void); extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); -extern void __init u5500_init_devices(void); -extern void __init u8500_init_devices(void); +extern struct device * __init u5500_init_devices(void); +extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); -extern void __init u5500_sdi_init(void); +extern void __init u5500_sdi_init(struct device *parent); -extern void __init db5500_dma_init(void); +extern void __init db5500_dma_init(struct device *parent); /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); diff --git a/trunk/arch/arm/mach-ux500/include/mach/usb.h b/trunk/arch/arm/mach-ux500/include/mach/usb.h index d3739d418813..4c1cc50a595a 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/usb.h +++ b/trunk/arch/arm/mach-ux500/include/mach/usb.h @@ -20,6 +20,6 @@ struct ux500_musb_board_data { bool (*dma_filter)(struct dma_chan *chan, void *filter_param); }; -void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, - int *dma_tx_cfg); +void ux500_add_usb(struct device *parent, resource_size_t base, + int irq, int *dma_rx_cfg, int *dma_tx_cfg); #endif diff --git a/trunk/arch/arm/mach-ux500/usb.c b/trunk/arch/arm/mach-ux500/usb.c index 9f9e1c203061..5329a2cc6807 100644 --- a/trunk/arch/arm/mach-ux500/usb.c +++ b/trunk/arch/arm/mach-ux500/usb.c @@ -140,8 +140,8 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type) musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx]; } -void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, - int *dma_tx_cfg) +void ux500_add_usb(struct device *parent, resource_size_t base, int irq, + int *dma_rx_cfg, int *dma_tx_cfg) { ux500_musb_device.resource[0].start = base; ux500_musb_device.resource[0].end = base + SZ_64K - 1; diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 6339aa496c4f..5bed94e189fa 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -179,9 +179,6 @@ config ARCH_HAS_DEFAULT_IDLE config ARCH_HAS_CACHE_LINE_SIZE def_bool y -config ARCH_HAS_CPU_AUTOPROBE - def_bool y - config HAVE_SETUP_PER_CPU_AREA def_bool y diff --git a/trunk/arch/x86/crypto/aesni-intel_glue.c b/trunk/arch/x86/crypto/aesni-intel_glue.c index b3350bd32c60..545d0ce59818 100644 --- a/trunk/arch/x86/crypto/aesni-intel_glue.c +++ b/trunk/arch/x86/crypto/aesni-intel_glue.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -1254,19 +1253,14 @@ static struct crypto_alg __rfc4106_alg = { }; #endif - -static const struct x86_cpu_id aesni_cpu_id[] = { - X86_FEATURE_MATCH(X86_FEATURE_AES), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id); - static int __init aesni_init(void) { int err; - if (!x86_match_cpu(aesni_cpu_id)) + if (!cpu_has_aes) { + printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); return -ENODEV; + } if ((err = crypto_fpu_init())) goto fpu_err; diff --git a/trunk/arch/x86/crypto/crc32c-intel.c b/trunk/arch/x86/crypto/crc32c-intel.c index 493f959261f7..b9d00261703c 100644 --- a/trunk/arch/x86/crypto/crc32c-intel.c +++ b/trunk/arch/x86/crypto/crc32c-intel.c @@ -31,7 +31,6 @@ #include #include -#include #define CHKSUM_BLOCK_SIZE 1 #define CHKSUM_DIGEST_SIZE 4 @@ -174,17 +173,13 @@ static struct shash_alg alg = { } }; -static const struct x86_cpu_id crc32c_cpu_id[] = { - X86_FEATURE_MATCH(X86_FEATURE_XMM4_2), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id); static int __init crc32c_intel_mod_init(void) { - if (!x86_match_cpu(crc32c_cpu_id)) + if (cpu_has_xmm4_2) + return crypto_register_shash(&alg); + else return -ENODEV; - return crypto_register_shash(&alg); } static void __exit crc32c_intel_mod_fini(void) diff --git a/trunk/arch/x86/crypto/ghash-clmulni-intel_glue.c b/trunk/arch/x86/crypto/ghash-clmulni-intel_glue.c index b4bf0a63b520..976aa64d9a20 100644 --- a/trunk/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/trunk/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -20,7 +20,6 @@ #include #include #include -#include #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -295,18 +294,15 @@ static struct ahash_alg ghash_async_alg = { }, }; -static const struct x86_cpu_id pcmul_cpu_id[] = { - X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */ - {} -}; -MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id); - static int __init ghash_pclmulqdqni_mod_init(void) { int err; - if (!x86_match_cpu(pcmul_cpu_id)) + if (!cpu_has_pclmulqdq) { + printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not" + " detected.\n"); return -ENODEV; + } err = crypto_register_shash(&ghash_alg); if (err) diff --git a/trunk/arch/x86/include/asm/cpu_device_id.h b/trunk/arch/x86/include/asm/cpu_device_id.h deleted file mode 100644 index ff501e511d91..000000000000 --- a/trunk/arch/x86/include/asm/cpu_device_id.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _CPU_DEVICE_ID -#define _CPU_DEVICE_ID 1 - -/* - * Declare drivers belonging to specific x86 CPUs - * Similar in spirit to pci_device_id and related PCI functions - */ - -#include - -extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); - -#endif diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h index dcb839eebc76..8d67d428b0f9 100644 --- a/trunk/arch/x86/include/asm/cpufeature.h +++ b/trunk/arch/x86/include/asm/cpufeature.h @@ -177,7 +177,6 @@ #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ #define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ -#define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */ /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ diff --git a/trunk/arch/x86/kernel/cpu/Makefile b/trunk/arch/x86/kernel/cpu/Makefile index 6ab6aa2fdfdd..25f24dccdcfa 100644 --- a/trunk/arch/x86/kernel/cpu/Makefile +++ b/trunk/arch/x86/kernel/cpu/Makefile @@ -16,7 +16,6 @@ obj-y := intel_cacheinfo.o scattered.o topology.o obj-y += proc.o capflags.o powerflags.o common.o obj-y += vmware.o hypervisor.o sched.o mshyperv.o obj-y += rdrand.o -obj-y += match.o obj-$(CONFIG_X86_32) += bugs.o obj-$(CONFIG_X86_64) += bugs_64.o diff --git a/trunk/arch/x86/kernel/cpu/match.c b/trunk/arch/x86/kernel/cpu/match.c deleted file mode 100644 index 940e2d483076..000000000000 --- a/trunk/arch/x86/kernel/cpu/match.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include -#include -#include - -/** - * x86_match_cpu - match current CPU again an array of x86_cpu_ids - * @match: Pointer to array of x86_cpu_ids. Last entry terminated with - * {}. - * - * Return the entry if the current CPU matches the entries in the - * passed x86_cpu_id match table. Otherwise NULL. The match table - * contains vendor (X86_VENDOR_*), family, model and feature bits or - * respective wildcard entries. - * - * A typical table entry would be to match a specific CPU - * { X86_VENDOR_INTEL, 6, 0x12 } - * or to match a specific CPU feature - * { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) } - * - * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY, - * %X86_MODEL_ANY, %X86_FEATURE_ANY or 0 (except for vendor) - * - * Arrays used to match for this should also be declared using - * MODULE_DEVICE_TABLE(x86_cpu, ...) - * - * This always matches against the boot cpu, assuming models and features are - * consistent over all CPUs. - */ -const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) -{ - const struct x86_cpu_id *m; - struct cpuinfo_x86 *c = &boot_cpu_data; - - for (m = match; m->vendor | m->family | m->model | m->feature; m++) { - if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) - continue; - if (m->family != X86_FAMILY_ANY && c->x86 != m->family) - continue; - if (m->model != X86_MODEL_ANY && c->x86_model != m->model) - continue; - if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) - continue; - return m; - } - return NULL; -} -EXPORT_SYMBOL(x86_match_cpu); - -ssize_t arch_print_cpu_modalias(struct device *dev, - struct device_attribute *attr, - char *bufptr) -{ - int size = PAGE_SIZE; - int i, n; - char *buf = bufptr; - - n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:" - "model:%04X:feature:", - boot_cpu_data.x86_vendor, - boot_cpu_data.x86, - boot_cpu_data.x86_model); - size -= n; - buf += n; - size -= 2; - for (i = 0; i < NCAPINTS*32; i++) { - if (boot_cpu_has(i)) { - n = snprintf(buf, size, ",%04X", i); - if (n < 0) { - WARN(1, "x86 features overflow page\n"); - break; - } - size -= n; - buf += n; - } - } - *buf++ = ','; - *buf++ = '\n'; - return buf - bufptr; -} - -int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (buf) { - arch_print_cpu_modalias(NULL, NULL, buf); - add_uevent_var(env, "MODALIAS=%s", buf); - kfree(buf); - } - return 0; -} diff --git a/trunk/arch/x86/kernel/cpu/scattered.c b/trunk/arch/x86/kernel/cpu/scattered.c index addf9e82a7f2..c7f64e6f537a 100644 --- a/trunk/arch/x86/kernel/cpu/scattered.c +++ b/trunk/arch/x86/kernel/cpu/scattered.c @@ -40,7 +40,6 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 }, { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, - { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 }, { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, diff --git a/trunk/arch/x86/kernel/microcode_core.c b/trunk/arch/x86/kernel/microcode_core.c index 87a0f8688301..fda91c307104 100644 --- a/trunk/arch/x86/kernel/microcode_core.c +++ b/trunk/arch/x86/kernel/microcode_core.c @@ -86,7 +86,6 @@ #include #include -#include MODULE_DESCRIPTION("Microcode Update Driver"); MODULE_AUTHOR("Tigran Aivazian "); @@ -505,20 +504,6 @@ static struct notifier_block __refdata mc_cpu_notifier = { .notifier_call = mc_cpu_callback, }; -#ifdef MODULE -/* Autoload on Intel and AMD systems */ -static const struct x86_cpu_id microcode_id[] = { -#ifdef CONFIG_MICROCODE_INTEL - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, -#endif -#ifdef CONFIG_MICROCODE_AMD - { X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, }, -#endif - {} -}; -MODULE_DEVICE_TABLE(x86cpu, microcode_id); -#endif - static int __init microcode_init(void) { struct cpuinfo_x86 *c = &cpu_data(0); diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index 2801b418d7bb..8ae05ce18500 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -474,7 +474,6 @@ static __ref int acpi_processor_start(struct acpi_processor *pr) #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); - acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 0af48a8554cd..85b32376dad7 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -240,28 +240,6 @@ void acpi_processor_ppc_exit(void) acpi_processor_ppc_status &= ~PPC_REGISTERED; } -/* - * Do a quick check if the systems looks like it should use ACPI - * cpufreq. We look at a _PCT method being available, but don't - * do a whole lot of sanity checks. - */ -void acpi_processor_load_module(struct acpi_processor *pr) -{ - static int requested; - acpi_status status = 0; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - - if (!arch_has_acpi_pdc() || requested) - return; - status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); - if (!ACPI_FAILURE(status)) { - printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); - request_module_nowait("acpi_cpufreq"); - requested = 1; - } - kfree(buffer.pointer); -} - static int acpi_processor_get_performance_control(struct acpi_processor *pr) { int result = 0; diff --git a/trunk/drivers/base/Kconfig b/trunk/drivers/base/Kconfig index 9aa618acfe97..7be9f79018e9 100644 --- a/trunk/drivers/base/Kconfig +++ b/trunk/drivers/base/Kconfig @@ -176,9 +176,6 @@ config GENERIC_CPU_DEVICES bool default n -config SOC_BUS - bool - source "drivers/base/regmap/Kconfig" config DMA_SHARED_BUFFER diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index b6d1b9c4200c..610f9997a403 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_MODULES) += module.o endif obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o obj-$(CONFIG_REGMAP) += regmap/ -obj-$(CONFIG_SOC_BUS) += soc.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 26a06b801b5b..40fb12288ce2 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -1194,15 +1194,13 @@ EXPORT_SYMBOL_GPL(subsys_interface_register); void subsys_interface_unregister(struct subsys_interface *sif) { - struct bus_type *subsys; + struct bus_type *subsys = sif->subsys; struct subsys_dev_iter iter; struct device *dev; - if (!sif || !sif->subsys) + if (!sif) return; - subsys = sif->subsys; - mutex_lock(&subsys->p->mutex); list_del_init(&sif->node); if (sif->remove_dev) { diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index 2a0c670c281d..db87e78d7459 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "base.h" @@ -224,9 +223,6 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) cpu->node_id = cpu_to_node(num); cpu->dev.id = num; cpu->dev.bus = &cpu_subsys; -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE - cpu->dev.bus->uevent = arch_cpu_uevent; -#endif error = device_register(&cpu->dev); if (!error && cpu->hotpluggable) register_cpu_control(cpu); @@ -251,10 +247,6 @@ struct device *get_cpu_device(unsigned cpu) } EXPORT_SYMBOL_GPL(get_cpu_device); -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE -static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); -#endif - static struct attribute *cpu_root_attrs[] = { #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE &dev_attr_probe.attr, @@ -265,9 +257,6 @@ static struct attribute *cpu_root_attrs[] = { &cpu_attrs[2].attr.attr, &dev_attr_kernel_max.attr, &dev_attr_offline.attr, -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE - &dev_attr_modalias.attr, -#endif NULL }; diff --git a/trunk/drivers/base/driver.c b/trunk/drivers/base/driver.c index 60e4f77ca662..b631f7c59453 100644 --- a/trunk/drivers/base/driver.c +++ b/trunk/drivers/base/driver.c @@ -153,6 +153,34 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, } EXPORT_SYMBOL_GPL(driver_add_kobj); +/** + * get_driver - increment driver reference count. + * @drv: driver. + */ +struct device_driver *get_driver(struct device_driver *drv) +{ + if (drv) { + struct driver_private *priv; + struct kobject *kobj; + + kobj = kobject_get(&drv->p->kobj); + priv = to_driver(kobj); + return priv->driver; + } + return NULL; +} +EXPORT_SYMBOL_GPL(get_driver); + +/** + * put_driver - decrement driver's refcount. + * @drv: driver. + */ +void put_driver(struct device_driver *drv) +{ + kobject_put(&drv->p->kobj); +} +EXPORT_SYMBOL_GPL(put_driver); + static int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups) { @@ -206,6 +234,7 @@ int driver_register(struct device_driver *drv) other = driver_find(drv->name, drv->bus); if (other) { + put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); return -EBUSY; @@ -246,9 +275,7 @@ EXPORT_SYMBOL_GPL(driver_unregister); * Call kset_find_obj() to iterate over list of drivers on * a bus to find driver by name. Return driver if found. * - * This routine provides no locking to prevent the driver it returns - * from being unregistered or unloaded while the caller is using it. - * The caller is responsible for preventing this. + * Note that kset_find_obj increments driver's reference count. */ struct device_driver *driver_find(const char *name, struct bus_type *bus) { @@ -256,8 +283,6 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus) struct driver_private *priv; if (k) { - /* Drop reference added by kset_find_obj() */ - kobject_put(k); priv = to_driver(k); return priv->driver; } diff --git a/trunk/drivers/base/soc.c b/trunk/drivers/base/soc.c deleted file mode 100644 index 05f150382da8..000000000000 --- a/trunk/drivers/base/soc.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * - * Author: Lee Jones for ST-Ericsson. - * License terms: GNU General Public License (GPL), version 2 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_IDR(soc_ida); -static DEFINE_SPINLOCK(soc_lock); - -static ssize_t soc_info_get(struct device *dev, - struct device_attribute *attr, - char *buf); - -struct soc_device { - struct device dev; - struct soc_device_attribute *attr; - int soc_dev_num; -}; - -static struct bus_type soc_bus_type = { - .name = "soc", -}; - -static DEVICE_ATTR(machine, S_IRUGO, soc_info_get, NULL); -static DEVICE_ATTR(family, S_IRUGO, soc_info_get, NULL); -static DEVICE_ATTR(soc_id, S_IRUGO, soc_info_get, NULL); -static DEVICE_ATTR(revision, S_IRUGO, soc_info_get, NULL); - -struct device *soc_device_to_device(struct soc_device *soc_dev) -{ - return &soc_dev->dev; -} - -static mode_t soc_attribute_mode(struct kobject *kobj, - struct attribute *attr, - int index) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); - - if ((attr == &dev_attr_machine.attr) - && (soc_dev->attr->machine != NULL)) - return attr->mode; - if ((attr == &dev_attr_family.attr) - && (soc_dev->attr->family != NULL)) - return attr->mode; - if ((attr == &dev_attr_revision.attr) - && (soc_dev->attr->revision != NULL)) - return attr->mode; - if ((attr == &dev_attr_soc_id.attr) - && (soc_dev->attr->soc_id != NULL)) - return attr->mode; - - /* Unknown or unfilled attribute. */ - return 0; -} - -static ssize_t soc_info_get(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); - - if (attr == &dev_attr_machine) - return sprintf(buf, "%s\n", soc_dev->attr->machine); - if (attr == &dev_attr_family) - return sprintf(buf, "%s\n", soc_dev->attr->family); - if (attr == &dev_attr_revision) - return sprintf(buf, "%s\n", soc_dev->attr->revision); - if (attr == &dev_attr_soc_id) - return sprintf(buf, "%s\n", soc_dev->attr->soc_id); - - return -EINVAL; - -} - -static struct attribute *soc_attr[] = { - &dev_attr_machine.attr, - &dev_attr_family.attr, - &dev_attr_soc_id.attr, - &dev_attr_revision.attr, - NULL, -}; - -static const struct attribute_group soc_attr_group = { - .attrs = soc_attr, - .is_visible = soc_attribute_mode, -}; - -static const struct attribute_group *soc_attr_groups[] = { - &soc_attr_group, - NULL, -}; - -static void soc_release(struct device *dev) -{ - struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); - - kfree(soc_dev); -} - -struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) -{ - struct soc_device *soc_dev; - int ret; - - soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL); - if (!soc_dev) { - ret = -ENOMEM; - goto out1; - } - - /* Fetch a unique (reclaimable) SOC ID. */ - do { - if (!ida_pre_get(&soc_ida, GFP_KERNEL)) { - ret = -ENOMEM; - goto out2; - } - - spin_lock(&soc_lock); - ret = ida_get_new(&soc_ida, &soc_dev->soc_dev_num); - spin_unlock(&soc_lock); - - } while (ret == -EAGAIN); - - if (ret) - goto out2; - - soc_dev->attr = soc_dev_attr; - soc_dev->dev.bus = &soc_bus_type; - soc_dev->dev.groups = soc_attr_groups; - soc_dev->dev.release = soc_release; - - dev_set_name(&soc_dev->dev, "soc%d", soc_dev->soc_dev_num); - - ret = device_register(&soc_dev->dev); - if (ret) - goto out3; - - return soc_dev; - -out3: - ida_remove(&soc_ida, soc_dev->soc_dev_num); -out2: - kfree(soc_dev); -out1: - return ERR_PTR(ret); -} - -/* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */ -void soc_device_unregister(struct soc_device *soc_dev) -{ - ida_remove(&soc_ida, soc_dev->soc_dev_num); - - device_unregister(&soc_dev->dev); -} - -static int __init soc_bus_register(void) -{ - spin_lock_init(&soc_lock); - - return bus_register(&soc_bus_type); -} -core_initcall(soc_bus_register); - -static void __exit soc_bus_unregister(void) -{ - ida_destroy(&soc_ida); - - bus_unregister(&soc_bus_type); -} -module_exit(soc_bus_unregister); diff --git a/trunk/drivers/cpufreq/cpufreq-nforce2.c b/trunk/drivers/cpufreq/cpufreq-nforce2.c index 13d311ee08b3..7bac808804f3 100644 --- a/trunk/drivers/cpufreq/cpufreq-nforce2.c +++ b/trunk/drivers/cpufreq/cpufreq-nforce2.c @@ -385,14 +385,6 @@ static struct cpufreq_driver nforce2_driver = { .owner = THIS_MODULE, }; -#ifdef MODULE -static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 }, - {} -}; -MODULE_DEVICE_TABLE(pci, nforce2_ids); -#endif - /** * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic * diff --git a/trunk/drivers/cpufreq/e_powersaver.c b/trunk/drivers/cpufreq/e_powersaver.c index 3fffbe6025cd..4bd6815d317b 100644 --- a/trunk/drivers/cpufreq/e_powersaver.c +++ b/trunk/drivers/cpufreq/e_powersaver.c @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -438,19 +437,18 @@ static struct cpufreq_driver eps_driver = { .attr = eps_attr, }; - -/* This driver will work only on Centaur C7 processors with - * Enhanced SpeedStep/PowerSaver registers */ -static const struct x86_cpu_id eps_cpu_id[] = { - { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id); - static int __init eps_init(void) { - if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10) + struct cpuinfo_x86 *c = &cpu_data(0); + + /* This driver will work only on Centaur C7 processors with + * Enhanced SpeedStep/PowerSaver registers */ + if (c->x86_vendor != X86_VENDOR_CENTAUR + || c->x86 != 6 || c->x86_model < 10) + return -ENODEV; + if (!cpu_has(c, X86_FEATURE_EST)) return -ENODEV; + if (cpufreq_register_driver(&eps_driver)) return -EINVAL; return 0; diff --git a/trunk/drivers/cpufreq/elanfreq.c b/trunk/drivers/cpufreq/elanfreq.c index 960671fd3d7e..c587db472a75 100644 --- a/trunk/drivers/cpufreq/elanfreq.c +++ b/trunk/drivers/cpufreq/elanfreq.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -278,16 +277,17 @@ static struct cpufreq_driver elanfreq_driver = { .attr = elanfreq_attr, }; -static const struct x86_cpu_id elan_id[] = { - { X86_VENDOR_AMD, 4, 10, }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, elan_id); static int __init elanfreq_init(void) { - if (!x86_match_cpu(elan_id)) + struct cpuinfo_x86 *c = &cpu_data(0); + + /* Test if we have the right hardware */ + if ((c->x86_vendor != X86_VENDOR_AMD) || + (c->x86 != 4) || (c->x86_model != 10)) { + printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); return -ENODEV; + } return cpufreq_register_driver(&elanfreq_driver); } diff --git a/trunk/drivers/cpufreq/gx-suspmod.c b/trunk/drivers/cpufreq/gx-suspmod.c index 456bee058fe6..ffe1f2c92ed3 100644 --- a/trunk/drivers/cpufreq/gx-suspmod.c +++ b/trunk/drivers/cpufreq/gx-suspmod.c @@ -82,7 +82,6 @@ #include #include -#include #include /* PCI config registers, all at F0 */ @@ -172,7 +171,6 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; -MODULE_DEVICE_TABLE(pci, gx_chipset_tbl); static void gx_write_byte(int reg, int value) { @@ -187,6 +185,13 @@ static __init struct pci_dev *gx_detect_chipset(void) { struct pci_dev *gx_pci = NULL; + /* check if CPU is a MediaGX or a Geode. */ + if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) && + (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { + pr_debug("error: no MediaGX/Geode processor found!\n"); + return NULL; + } + /* detect which companion chip is used */ for_each_pci_dev(gx_pci) { if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) diff --git a/trunk/drivers/cpufreq/longhaul.c b/trunk/drivers/cpufreq/longhaul.c index 53ddbc760af7..f47d26e2a135 100644 --- a/trunk/drivers/cpufreq/longhaul.c +++ b/trunk/drivers/cpufreq/longhaul.c @@ -35,7 +35,6 @@ #include #include -#include #include #include "longhaul.h" @@ -952,17 +951,12 @@ static struct cpufreq_driver longhaul_driver = { .attr = longhaul_attr, }; -static const struct x86_cpu_id longhaul_id[] = { - { X86_VENDOR_CENTAUR, 6 }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, longhaul_id); static int __init longhaul_init(void) { struct cpuinfo_x86 *c = &cpu_data(0); - if (!x86_match_cpu(longhaul_id)) + if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6) return -ENODEV; #ifdef CONFIG_SMP diff --git a/trunk/drivers/cpufreq/longrun.c b/trunk/drivers/cpufreq/longrun.c index 8bc9f5fbbaeb..34ea359b370e 100644 --- a/trunk/drivers/cpufreq/longrun.c +++ b/trunk/drivers/cpufreq/longrun.c @@ -14,7 +14,6 @@ #include #include -#include static struct cpufreq_driver longrun_driver; @@ -289,12 +288,6 @@ static struct cpufreq_driver longrun_driver = { .owner = THIS_MODULE, }; -static const struct x86_cpu_id longrun_ids[] = { - { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY, - X86_FEATURE_LONGRUN }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, longrun_ids); /** * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver @@ -303,8 +296,12 @@ MODULE_DEVICE_TABLE(x86cpu, longrun_ids); */ static int __init longrun_init(void) { - if (!x86_match_cpu(longrun_ids)) + struct cpuinfo_x86 *c = &cpu_data(0); + + if (c->x86_vendor != X86_VENDOR_TRANSMETA || + !cpu_has(c, X86_FEATURE_LONGRUN)) return -ENODEV; + return cpufreq_register_driver(&longrun_driver); } diff --git a/trunk/drivers/cpufreq/p4-clockmod.c b/trunk/drivers/cpufreq/p4-clockmod.c index 827629c9aad7..6be3e0760c26 100644 --- a/trunk/drivers/cpufreq/p4-clockmod.c +++ b/trunk/drivers/cpufreq/p4-clockmod.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "speedstep-lib.h" @@ -290,25 +289,21 @@ static struct cpufreq_driver p4clockmod_driver = { .attr = p4clockmod_attr, }; -static const struct x86_cpu_id cpufreq_p4_id[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC }, - {} -}; - -/* - * Intentionally no MODULE_DEVICE_TABLE here: this driver should not - * be auto loaded. Please don't add one. - */ static int __init cpufreq_p4_init(void) { + struct cpuinfo_x86 *c = &cpu_data(0); int ret; /* * THERM_CONTROL is architectural for IA32 now, so * we can rely on the capability checks */ - if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI)) + if (c->x86_vendor != X86_VENDOR_INTEL) + return -ENODEV; + + if (!test_cpu_cap(c, X86_FEATURE_ACPI) || + !test_cpu_cap(c, X86_FEATURE_ACC)) return -ENODEV; ret = cpufreq_register_driver(&p4clockmod_driver); diff --git a/trunk/drivers/cpufreq/powernow-k6.c b/trunk/drivers/cpufreq/powernow-k6.c index 54dd031394f6..b3379d6a5c57 100644 --- a/trunk/drivers/cpufreq/powernow-k6.c +++ b/trunk/drivers/cpufreq/powernow-k6.c @@ -16,7 +16,6 @@ #include #include -#include #include #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long @@ -211,12 +210,6 @@ static struct cpufreq_driver powernow_k6_driver = { .attr = powernow_k6_attr, }; -static const struct x86_cpu_id powernow_k6_ids[] = { - { X86_VENDOR_AMD, 5, 12 }, - { X86_VENDOR_AMD, 5, 13 }, - {} -}; - /** * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver @@ -227,7 +220,10 @@ static const struct x86_cpu_id powernow_k6_ids[] = { */ static int __init powernow_k6_init(void) { - if (!x86_match_cpu(powernow_k6_ids)) + struct cpuinfo_x86 *c = &cpu_data(0); + + if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || + ((c->x86_model != 12) && (c->x86_model != 13))) return -ENODEV; if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { diff --git a/trunk/drivers/cpufreq/powernow-k7.c b/trunk/drivers/cpufreq/powernow-k7.c index 501d167368d2..d71d9f372359 100644 --- a/trunk/drivers/cpufreq/powernow-k7.c +++ b/trunk/drivers/cpufreq/powernow-k7.c @@ -28,7 +28,6 @@ #include /* Needed for recalibrate_cpu_khz() */ #include #include -#include #ifdef CONFIG_X86_POWERNOW_K7_ACPI #include @@ -111,19 +110,18 @@ static int check_fsb(unsigned int fsbspeed) return delta < 5; } -static const struct x86_cpu_id powernow_k7_cpuids[] = { - { X86_VENDOR_AMD, 7, }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids); - static int check_powernow(void) { struct cpuinfo_x86 *c = &cpu_data(0); unsigned int maxei, eax, ebx, ecx, edx; - if (!x86_match_cpu(powernow_k7_cpuids)) + if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) { +#ifdef MODULE + printk(KERN_INFO PFX "This module only works with " + "AMD K7 CPUs\n"); +#endif return 0; + } /* Get maximum capabilities */ maxei = cpuid_eax(0x80000000); diff --git a/trunk/drivers/cpufreq/powernow-k8.c b/trunk/drivers/cpufreq/powernow-k8.c index c0e816468e30..8f9b2ceeec85 100644 --- a/trunk/drivers/cpufreq/powernow-k8.c +++ b/trunk/drivers/cpufreq/powernow-k8.c @@ -40,7 +40,6 @@ #include #include -#include #include #include @@ -521,15 +520,6 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, return 0; } -static const struct x86_cpu_id powernow_k8_ids[] = { - /* IO based frequency switching */ - { X86_VENDOR_AMD, 0xf }, - /* MSR based frequency switching supported */ - X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids); - static void check_supported_cpu(void *_rc) { u32 eax, ebx, ecx, edx; @@ -537,7 +527,13 @@ static void check_supported_cpu(void *_rc) *rc = -ENODEV; + if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD) + return; + eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); + if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) && + ((eax & CPUID_XFAM) < CPUID_XFAM_10H)) + return; if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || @@ -1557,9 +1553,6 @@ static int __cpuinit powernowk8_init(void) unsigned int i, supported_cpus = 0, cpu; int rv; - if (!x86_match_cpu(powernow_k8_ids)) - return -ENODEV; - for_each_online_cpu(i) { int rc; smp_call_function_single(i, check_supported_cpu, &rc, 1); diff --git a/trunk/drivers/cpufreq/sc520_freq.c b/trunk/drivers/cpufreq/sc520_freq.c index e42e073cd9b8..1e205e6b1727 100644 --- a/trunk/drivers/cpufreq/sc520_freq.c +++ b/trunk/drivers/cpufreq/sc520_freq.c @@ -22,7 +22,6 @@ #include #include -#include #include #define MMCR_BASE 0xfffef000 /* The default base address */ @@ -151,19 +150,18 @@ static struct cpufreq_driver sc520_freq_driver = { .attr = sc520_freq_attr, }; -static const struct x86_cpu_id sc520_ids[] = { - { X86_VENDOR_AMD, 4, 9 }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, sc520_ids); static int __init sc520_freq_init(void) { + struct cpuinfo_x86 *c = &cpu_data(0); int err; - if (!x86_match_cpu(sc520_ids)) + /* Test if we have the right hardware */ + if (c->x86_vendor != X86_VENDOR_AMD || + c->x86 != 4 || c->x86_model != 9) { + pr_debug("no Elan SC520 processor found!\n"); return -ENODEV; - + } cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); if (!cpuctl) { printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); diff --git a/trunk/drivers/cpufreq/speedstep-centrino.c b/trunk/drivers/cpufreq/speedstep-centrino.c index 3a953d519f46..6ea3455def21 100644 --- a/trunk/drivers/cpufreq/speedstep-centrino.c +++ b/trunk/drivers/cpufreq/speedstep-centrino.c @@ -25,7 +25,6 @@ #include #include #include -#include #define PFX "speedstep-centrino: " #define MAINTAINER "cpufreq@vger.kernel.org" @@ -596,24 +595,6 @@ static struct cpufreq_driver centrino_driver = { .owner = THIS_MODULE, }; -/* - * This doesn't replace the detailed checks above because - * the generic CPU IDs don't have a way to match for steppings - * or ASCII model IDs. - */ -static const struct x86_cpu_id centrino_ids[] = { - { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST }, - {} -}; -#if 0 -/* Autoload or not? Do not for now. */ -MODULE_DEVICE_TABLE(x86cpu, centrino_ids); -#endif /** * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver @@ -631,8 +612,11 @@ MODULE_DEVICE_TABLE(x86cpu, centrino_ids); */ static int __init centrino_init(void) { - if (!x86_match_cpu(centrino_ids)) + struct cpuinfo_x86 *cpu = &cpu_data(0); + + if (!cpu_has(cpu, X86_FEATURE_EST)) return -ENODEV; + return cpufreq_register_driver(¢rino_driver); } diff --git a/trunk/drivers/cpufreq/speedstep-ich.c b/trunk/drivers/cpufreq/speedstep-ich.c index 7432b3a72cd4..a748ce782fee 100644 --- a/trunk/drivers/cpufreq/speedstep-ich.c +++ b/trunk/drivers/cpufreq/speedstep-ich.c @@ -25,8 +25,6 @@ #include #include -#include - #include "speedstep-lib.h" @@ -390,16 +388,6 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; -static const struct x86_cpu_id ss_smi_ids[] = { - { X86_VENDOR_INTEL, 6, 0xb, }, - { X86_VENDOR_INTEL, 6, 0x8, }, - { X86_VENDOR_INTEL, 15, 2 }, - {} -}; -#if 0 -/* Autoload or not? Do not for now. */ -MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); -#endif /** * speedstep_init - initializes the SpeedStep CPUFreq driver @@ -410,9 +398,6 @@ MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); */ static int __init speedstep_init(void) { - if (!x86_match_cpu(ss_smi_ids)) - return -ENODEV; - /* detect processor */ speedstep_processor = speedstep_detect_processor(); if (!speedstep_processor) { diff --git a/trunk/drivers/cpufreq/speedstep-lib.c b/trunk/drivers/cpufreq/speedstep-lib.c index 7047821a7f8a..8af2d2fd9d51 100644 --- a/trunk/drivers/cpufreq/speedstep-lib.c +++ b/trunk/drivers/cpufreq/speedstep-lib.c @@ -249,7 +249,6 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency); * DETECT SPEEDSTEP-CAPABLE PROCESSOR * *********************************************************************/ -/* Keep in sync with the x86_cpu_id tables in the different modules */ unsigned int speedstep_detect_processor(void) { struct cpuinfo_x86 *c = &cpu_data(0); diff --git a/trunk/drivers/cpufreq/speedstep-smi.c b/trunk/drivers/cpufreq/speedstep-smi.c index 6a457fcaaad5..c76ead3490bf 100644 --- a/trunk/drivers/cpufreq/speedstep-smi.c +++ b/trunk/drivers/cpufreq/speedstep-smi.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "speedstep-lib.h" @@ -380,17 +379,6 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; -static const struct x86_cpu_id ss_smi_ids[] = { - { X86_VENDOR_INTEL, 6, 0xb, }, - { X86_VENDOR_INTEL, 6, 0x8, }, - { X86_VENDOR_INTEL, 15, 2 }, - {} -}; -#if 0 -/* Not auto loaded currently */ -MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); -#endif - /** * speedstep_init - initializes the SpeedStep CPUFreq driver * @@ -400,9 +388,6 @@ MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); */ static int __init speedstep_init(void) { - if (!x86_match_cpu(ss_smi_ids)) - return -ENODEV; - speedstep_processor = speedstep_detect_processor(); switch (speedstep_processor) { diff --git a/trunk/drivers/crypto/padlock-aes.c b/trunk/drivers/crypto/padlock-aes.c index 37b2e9406af6..29b9469f8378 100644 --- a/trunk/drivers/crypto/padlock-aes.c +++ b/trunk/drivers/crypto/padlock-aes.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -504,18 +503,12 @@ static struct crypto_alg cbc_aes_alg = { } }; -static struct x86_cpu_id padlock_cpu_id[] = { - X86_FEATURE_MATCH(X86_FEATURE_XCRYPT), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, padlock_cpu_id); - static int __init padlock_init(void) { int ret; struct cpuinfo_x86 *c = &cpu_data(0); - if (!x86_match_cpu(padlock_cpu_id)) + if (!cpu_has_xcrypt) return -ENODEV; if (!cpu_has_xcrypt_enabled) { diff --git a/trunk/drivers/crypto/padlock-sha.c b/trunk/drivers/crypto/padlock-sha.c index 9266c0e25492..06bdb4b2c6a6 100644 --- a/trunk/drivers/crypto/padlock-sha.c +++ b/trunk/drivers/crypto/padlock-sha.c @@ -22,7 +22,6 @@ #include #include #include -#include #include struct padlock_sha_desc { @@ -527,12 +526,6 @@ static struct shash_alg sha256_alg_nano = { } }; -static struct x86_cpu_id padlock_sha_ids[] = { - X86_FEATURE_MATCH(X86_FEATURE_PHE), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, padlock_sha_ids); - static int __init padlock_init(void) { int rc = -ENODEV; @@ -540,8 +533,15 @@ static int __init padlock_init(void) struct shash_alg *sha1; struct shash_alg *sha256; - if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled) + if (!cpu_has_phe) { + printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); + return -ENODEV; + } + + if (!cpu_has_phe_enabled) { + printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); return -ENODEV; + } /* Register the newly added algorithm module if on * * VIA Nano processor, or else just do as before */ diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index bce53fa0e166..af08ce7207d9 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1619,7 +1619,11 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf, list_add_tail(&dynid->list, &hdrv->dyn_list); spin_unlock(&hdrv->dyn_lock); - ret = driver_attach(&hdrv->driver); + ret = 0; + if (get_driver(&hdrv->driver)) { + ret = driver_attach(&hdrv->driver); + put_driver(&hdrv->driver); + } return ret ? : count; } diff --git a/trunk/drivers/hv/channel_mgmt.c b/trunk/drivers/hv/channel_mgmt.c index 9ffbfc575a0c..36484db36baf 100644 --- a/trunk/drivers/hv/channel_mgmt.c +++ b/trunk/drivers/hv/channel_mgmt.c @@ -37,6 +37,81 @@ struct vmbus_channel_message_table_entry { void (*message_handler)(struct vmbus_channel_message_header *msg); }; +#define MAX_MSG_TYPES 4 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 + +static const uuid_le + supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { + /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ + /* Storage - SCSI */ + { + .b = { + 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, + 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f + } + }, + + /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ + /* Network */ + { + .b = { + 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, + 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E + } + }, + + /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ + /* Input */ + { + .b = { + 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A + } + }, + + /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ + /* IDE */ + { + .b = { + 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 + } + }, + /* 0E0B6031-5213-4934-818B-38D90CED39DB */ + /* Shutdown */ + { + .b = { + 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB + } + }, + /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ + /* TimeSync */ + { + .b = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf + } + }, + /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ + /* Heartbeat */ + { + .b = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d + } + }, + /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ + /* KVP */ + { + .b = { + 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 + } + }, + +}; + /** * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message @@ -246,8 +321,20 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) struct vmbus_channel *newchannel; uuid_le *guidtype; uuid_le *guidinstance; + int i; + int fsupported = 0; offer = (struct vmbus_channel_offer_channel *)hdr; + for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { + if (!uuid_le_cmp(offer->offer.if_type, + supported_device_classes[i])) { + fsupported = 1; + break; + } + } + + if (!fsupported) + return; guidtype = &offer->offer.if_type; guidinstance = &offer->offer.if_instance; diff --git a/trunk/drivers/hv/hv.c b/trunk/drivers/hv/hv.c index 15956bd48b48..12aa97f31f93 100644 --- a/trunk/drivers/hv/hv.c +++ b/trunk/drivers/hv/hv.c @@ -155,9 +155,9 @@ int hv_init(void) union hv_x64_msr_hypercall_contents hypercall_msr; void *virtaddr = NULL; - memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); + memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS); memset(hv_context.synic_message_page, 0, - sizeof(void *) * NR_CPUS); + sizeof(void *) * MAX_NUM_CPUS); if (!query_hypervisor_presence()) goto cleanup; diff --git a/trunk/drivers/hv/hv_kvp.c b/trunk/drivers/hv/hv_kvp.c index 0ef4c1f6ca54..0e8343f585bb 100644 --- a/trunk/drivers/hv/hv_kvp.c +++ b/trunk/drivers/hv/hv_kvp.c @@ -28,6 +28,8 @@ #include #include +#include "hv_kvp.h" + /* @@ -71,20 +73,15 @@ kvp_register(void) { struct cn_msg *msg; - struct hv_kvp_msg *kvp_msg; - char *version; - msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg), GFP_ATOMIC); + msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC); if (msg) { - kvp_msg = (struct hv_kvp_msg *)msg->data; - version = kvp_msg->body.kvp_version; msg->id.idx = CN_KVP_IDX; msg->id.val = CN_KVP_VAL; - - kvp_msg->kvp_hdr.operation = KVP_OP_REGISTER; - strcpy(version, HV_DRV_VERSION); - msg->len = sizeof(struct hv_kvp_msg); + msg->seq = KVP_REGISTER; + strcpy(msg->data, HV_DRV_VERSION); + msg->len = strlen(HV_DRV_VERSION) + 1; cn_netlink_send(msg, 0, GFP_ATOMIC); kfree(msg); } @@ -106,24 +103,23 @@ kvp_work_func(struct work_struct *dummy) static void kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) { - struct hv_kvp_msg *message; - struct hv_kvp_msg_enumerate *data; + struct hv_ku_msg *message; - message = (struct hv_kvp_msg *)msg->data; - if (message->kvp_hdr.operation == KVP_OP_REGISTER) { + message = (struct hv_ku_msg *)msg->data; + if (msg->seq == KVP_REGISTER) { pr_info("KVP: user-mode registering done.\n"); kvp_register(); } - if (message->kvp_hdr.operation == KVP_OP_ENUMERATE) { - data = &message->body.kvp_enum_data; + if (msg->seq == KVP_USER_SET) { /* * Complete the transaction by forwarding the key value * to the host. But first, cancel the timeout. */ if (cancel_delayed_work_sync(&kvp_work)) - kvp_respond_to_host(data->data.key, data->data.value, - !strlen(data->data.key)); + kvp_respond_to_host(message->kvp_key, + message->kvp_value, + !strlen(message->kvp_key)); } } @@ -131,7 +127,6 @@ static void kvp_send_key(struct work_struct *dummy) { struct cn_msg *msg; - struct hv_kvp_msg *message; int index = kvp_transaction.index; msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); @@ -139,11 +134,9 @@ kvp_send_key(struct work_struct *dummy) if (msg) { msg->id.idx = CN_KVP_IDX; msg->id.val = CN_KVP_VAL; - - message = (struct hv_kvp_msg *)msg->data; - message->kvp_hdr.operation = KVP_OP_ENUMERATE; - message->body.kvp_enum_data.index = index; - msg->len = sizeof(struct hv_kvp_msg); + msg->seq = KVP_KERNEL_GET; + ((struct hv_ku_msg *)msg->data)->kvp_index = index; + msg->len = sizeof(struct hv_ku_msg); cn_netlink_send(msg, 0, GFP_ATOMIC); kfree(msg); } @@ -200,7 +193,7 @@ kvp_respond_to_host(char *key, char *value, int error) kvp_msg = (struct hv_kvp_msg *) &recv_buffer[sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; - kvp_data = &kvp_msg->body.kvp_enum_data; + kvp_data = &kvp_msg->kvp_data; key_name = key; /* @@ -275,7 +268,7 @@ void hv_kvp_onchannelcallback(void *context) sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; - kvp_data = &kvp_msg->body.kvp_enum_data; + kvp_data = &kvp_msg->kvp_data; /* * We only support the "get" operation on diff --git a/trunk/drivers/hv/hv_kvp.h b/trunk/drivers/hv/hv_kvp.h new file mode 100644 index 000000000000..9b765d7df838 --- /dev/null +++ b/trunk/drivers/hv/hv_kvp.h @@ -0,0 +1,184 @@ +/* + * An implementation of HyperV key value pair (KVP) functionality for Linux. + * + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _KVP_H +#define _KVP_H_ + +/* + * Maximum value size - used for both key names and value data, and includes + * any applicable NULL terminators. + * + * Note: This limit is somewhat arbitrary, but falls easily within what is + * supported for all native guests (back to Win 2000) and what is reasonable + * for the IC KVP exchange functionality. Note that Windows Me/98/95 are + * limited to 255 character key names. + * + * MSDN recommends not storing data values larger than 2048 bytes in the + * registry. + * + * Note: This value is used in defining the KVP exchange message - this value + * cannot be modified without affecting the message size and compatibility. + */ + +/* + * bytes, including any null terminators + */ +#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) + + +/* + * Maximum key size - the registry limit for the length of an entry name + * is 256 characters, including the null terminator + */ + +#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) + +/* + * In Linux, we implement the KVP functionality in two components: + * 1) The kernel component which is packaged as part of the hv_utils driver + * is responsible for communicating with the host and responsible for + * implementing the host/guest protocol. 2) A user level daemon that is + * responsible for data gathering. + * + * Host/Guest Protocol: The host iterates over an index and expects the guest + * to assign a key name to the index and also return the value corresponding to + * the key. The host will have atmost one KVP transaction outstanding at any + * given point in time. The host side iteration stops when the guest returns + * an error. Microsoft has specified the following mapping of key names to + * host specified index: + * + * Index Key Name + * 0 FullyQualifiedDomainName + * 1 IntegrationServicesVersion + * 2 NetworkAddressIPv4 + * 3 NetworkAddressIPv6 + * 4 OSBuildNumber + * 5 OSName + * 6 OSMajorVersion + * 7 OSMinorVersion + * 8 OSVersion + * 9 ProcessorArchitecture + * + * The Windows host expects the Key Name and Key Value to be encoded in utf16. + * + * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the + * data gathering functionality in a user mode daemon. The user level daemon + * is also responsible for binding the key name to the index as well. The + * kernel and user-level daemon communicate using a connector channel. + * + * The user mode component first registers with the + * the kernel component. Subsequently, the kernel component requests, data + * for the specified keys. In response to this message the user mode component + * fills in the value corresponding to the specified key. We overload the + * sequence field in the cn_msg header to define our KVP message types. + * + * + * The kernel component simply acts as a conduit for communication between the + * Windows host and the user-level daemon. The kernel component passes up the + * index received from the Host to the user-level daemon. If the index is + * valid (supported), the corresponding key as well as its + * value (both are strings) is returned. If the index is invalid + * (not supported), a NULL key string is returned. + */ + +/* + * + * The following definitions are shared with the user-mode component; do not + * change any of this without making the corresponding changes in + * the KVP user-mode component. + */ + +#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ +#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ + +enum hv_ku_op { + KVP_REGISTER = 0, /* Register the user mode component */ + KVP_KERNEL_GET, /* Kernel is requesting the value */ + KVP_KERNEL_SET, /* Kernel is providing the value */ + KVP_USER_GET, /* User is requesting the value */ + KVP_USER_SET /* User is providing the value */ +}; + +struct hv_ku_msg { + __u32 kvp_index; /* Key index */ + __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ + __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ +}; + + + + +#ifdef __KERNEL__ + +/* + * Registry value types. + */ + +#define REG_SZ 1 + +enum hv_kvp_exchg_op { + KVP_OP_GET = 0, + KVP_OP_SET, + KVP_OP_DELETE, + KVP_OP_ENUMERATE, + KVP_OP_COUNT /* Number of operations, must be last. */ +}; + +enum hv_kvp_exchg_pool { + KVP_POOL_EXTERNAL = 0, + KVP_POOL_GUEST, + KVP_POOL_AUTO, + KVP_POOL_AUTO_EXTERNAL, + KVP_POOL_AUTO_INTERNAL, + KVP_POOL_COUNT /* Number of pools, must be last. */ +}; + +struct hv_kvp_hdr { + u8 operation; + u8 pool; +}; + +struct hv_kvp_exchg_msg_value { + u32 value_type; + u32 key_size; + u32 value_size; + u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; + u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; +}; + +struct hv_kvp_msg_enumerate { + u32 index; + struct hv_kvp_exchg_msg_value data; +}; + +struct hv_kvp_msg { + struct hv_kvp_hdr kvp_hdr; + struct hv_kvp_msg_enumerate kvp_data; +}; + +int hv_kvp_init(struct hv_util_service *); +void hv_kvp_deinit(void); +void hv_kvp_onchannelcallback(void *); + +#endif /* __KERNEL__ */ +#endif /* _KVP_H */ + diff --git a/trunk/drivers/hv/hv_util.c b/trunk/drivers/hv/hv_util.c index dbb8b8eec210..55d58f21e6d4 100644 --- a/trunk/drivers/hv/hv_util.c +++ b/trunk/drivers/hv/hv_util.c @@ -28,6 +28,9 @@ #include #include +#include "hv_kvp.h" + + static void shutdown_onchannelcallback(void *context); static struct hv_util_service util_shutdown = { .util_cb = shutdown_onchannelcallback, diff --git a/trunk/drivers/hv/hyperv_vmbus.h b/trunk/drivers/hv/hyperv_vmbus.h index 699f0d8e59ed..6d7d286d5440 100644 --- a/trunk/drivers/hv/hyperv_vmbus.h +++ b/trunk/drivers/hv/hyperv_vmbus.h @@ -457,6 +457,7 @@ static const uuid_le VMBUS_SERVICE_ID = { }, }; +#define MAX_NUM_CPUS 32 struct hv_input_signal_event_buffer { @@ -482,8 +483,8 @@ struct hv_context { /* 8-bytes aligned of the buffer above */ struct hv_input_signal_event *signal_event_param; - void *synic_message_page[NR_CPUS]; - void *synic_event_page[NR_CPUS]; + void *synic_message_page[MAX_NUM_CPUS]; + void *synic_event_page[MAX_NUM_CPUS]; }; extern struct hv_context hv_context; diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index 249ac460e3d9..a6c6ec36615e 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -39,7 +39,6 @@ #include #include #include -#include #define DRVNAME "coretemp" @@ -760,23 +759,13 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; -static const struct x86_cpu_id coretemp_ids[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); - static int __init coretemp_init(void) { int i, err = -ENODEV; - /* - * CPUID.06H.EAX[0] indicates whether the CPU has thermal - * sensors. We check this bit only, all the early CPUs - * without thermal sensors will be filtered out. - */ - if (!x86_match_cpu(coretemp_ids)) - return -ENODEV; + /* quick check if we run Intel */ + if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) + goto exit; err = platform_driver_register(&coretemp_driver); if (err) diff --git a/trunk/drivers/hwmon/via-cputemp.c b/trunk/drivers/hwmon/via-cputemp.c index 8689664ef03c..8eac67d769fa 100644 --- a/trunk/drivers/hwmon/via-cputemp.c +++ b/trunk/drivers/hwmon/via-cputemp.c @@ -37,7 +37,6 @@ #include #include #include -#include #define DRVNAME "via_cputemp" @@ -309,20 +308,15 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; -static const struct x86_cpu_id cputemp_ids[] = { - { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ - { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ - { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */ - {} -}; -MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); - static int __init via_cputemp_init(void) { int i, err; - if (!x86_match_cpu(cputemp_ids)) - return -ENODEV; + if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) { + printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); + err = -ENODEV; + goto exit; + } err = platform_driver_register(&via_cputemp_driver); if (err) diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c index 237fe5785f01..54ab97bae042 100644 --- a/trunk/drivers/idle/intel_idle.c +++ b/trunk/drivers/idle/intel_idle.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include @@ -82,23 +81,18 @@ static unsigned int mwait_substates; /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ -struct idle_cpu { - struct cpuidle_state *state_table; - - /* - * Hardware C-state auto-demotion may not always be optimal. - * Indicate which enable bits to clear here. - */ - unsigned long auto_demotion_disable_flags; -}; - -static const struct idle_cpu *icpu; static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; static int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); static struct cpuidle_state *cpuidle_state_table; +/* + * Hardware C-state auto-demotion may not always be optimal. + * Indicate which enable bits to clear here. + */ +static unsigned long long auto_demotion_disable_flags; + /* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. @@ -325,72 +319,27 @@ static void auto_demotion_disable(void *dummy) unsigned long long msr_bits; rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); - msr_bits &= ~(icpu->auto_demotion_disable_flags); + msr_bits &= ~auto_demotion_disable_flags; wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); } -static const struct idle_cpu idle_cpu_nehalem = { - .state_table = nehalem_cstates, -}; - -static const struct idle_cpu idle_cpu_westmere = { - .state_table = nehalem_cstates, - .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, -}; - -static const struct idle_cpu idle_cpu_atom = { - .state_table = atom_cstates, -}; - -static const struct idle_cpu idle_cpu_lincroft = { - .state_table = atom_cstates, - .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, -}; - -static const struct idle_cpu idle_cpu_snb = { - .state_table = snb_cstates, -}; - -#define ICPU(model, cpu) \ - { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } - -static const struct x86_cpu_id intel_idle_ids[] = { - ICPU(0x1a, idle_cpu_nehalem), - ICPU(0x1e, idle_cpu_nehalem), - ICPU(0x1f, idle_cpu_nehalem), - ICPU(0x25, idle_cpu_westmere), - ICPU(0x2c, idle_cpu_westmere), - ICPU(0x2f, idle_cpu_westmere), - ICPU(0x1c, idle_cpu_atom), - ICPU(0x26, idle_cpu_lincroft), - ICPU(0x2f, idle_cpu_westmere), - ICPU(0x2a, idle_cpu_snb), - ICPU(0x2d, idle_cpu_snb), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); - /* * intel_idle_probe() */ static int intel_idle_probe(void) { unsigned int eax, ebx, ecx; - const struct x86_cpu_id *id; if (max_cstate == 0) { pr_debug(PREFIX "disabled\n"); return -EPERM; } - id = x86_match_cpu(intel_idle_ids); - if (!id) { - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 6) - pr_debug(PREFIX "does not run on family %d model %d\n", - boot_cpu_data.x86, boot_cpu_data.x86_model); + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return -ENODEV; + + if (!boot_cpu_has(X86_FEATURE_MWAIT)) return -ENODEV; - } if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) return -ENODEV; @@ -404,8 +353,43 @@ static int intel_idle_probe(void) pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); - icpu = (const struct idle_cpu *)id->driver_data; - cpuidle_state_table = icpu->state_table; + + if (boot_cpu_data.x86 != 6) /* family 6 */ + return -ENODEV; + + switch (boot_cpu_data.x86_model) { + + case 0x1A: /* Core i7, Xeon 5500 series */ + case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case 0x2E: /* Nehalem-EX Xeon */ + case 0x2F: /* Westmere-EX Xeon */ + case 0x25: /* Westmere */ + case 0x2C: /* Westmere */ + cpuidle_state_table = nehalem_cstates; + auto_demotion_disable_flags = + (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE); + break; + + case 0x1C: /* 28 - Atom Processor */ + cpuidle_state_table = atom_cstates; + break; + + case 0x26: /* 38 - Lincroft Atom Processor */ + cpuidle_state_table = atom_cstates; + auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE; + break; + + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + cpuidle_state_table = snb_cstates; + break; + + default: + pr_debug(PREFIX "does not run on family %d model %d\n", + boot_cpu_data.x86, boot_cpu_data.x86_model); + return -ENODEV; + } if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; @@ -486,7 +470,7 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count += 1; } - if (icpu->auto_demotion_disable_flags) + if (auto_demotion_disable_flags) on_each_cpu(auto_demotion_disable, NULL, 1); return 0; @@ -538,7 +522,7 @@ int intel_idle_cpu_init(int cpu) return -EIO; } - if (icpu->auto_demotion_disable_flags) + if (auto_demotion_disable_flags) smp_call_function_single(cpu, auto_demotion_disable, NULL, 1); return 0; diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c index da739d9d1905..c351aa421f8f 100644 --- a/trunk/drivers/input/gameport/gameport.c +++ b/trunk/drivers/input/gameport/gameport.c @@ -449,6 +449,7 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { gameport_disconnect_port(gameport); error = gameport_bind_driver(gameport, to_gameport_driver(drv)); + put_driver(drv); } else { error = -EINVAL; } diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index d0f7533dbf88..ba70058e2be3 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -441,6 +441,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { serio_disconnect_port(serio); error = serio_bind_driver(serio, to_serio_driver(drv)); + put_driver(drv); serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else { error = -EINVAL; diff --git a/trunk/drivers/media/video/cx18/cx18-alsa-main.c b/trunk/drivers/media/video/cx18/cx18-alsa-main.c index e118361c2e7b..a1e6c2a32478 100644 --- a/trunk/drivers/media/video/cx18/cx18-alsa-main.c +++ b/trunk/drivers/media/video/cx18/cx18-alsa-main.c @@ -285,6 +285,7 @@ static void __exit cx18_alsa_exit(void) drv = driver_find("cx18", &pci_bus_type); ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); + put_driver(drv); cx18_ext_init = NULL; printk(KERN_INFO "cx18-alsa: module unload complete\n"); diff --git a/trunk/drivers/media/video/ivtv/ivtvfb.c b/trunk/drivers/media/video/ivtv/ivtvfb.c index e5e7fa9e737b..d0fbfcf7133d 100644 --- a/trunk/drivers/media/video/ivtv/ivtvfb.c +++ b/trunk/drivers/media/video/ivtv/ivtvfb.c @@ -1293,6 +1293,7 @@ static int __init ivtvfb_init(void) drv = driver_find("ivtv", &pci_bus_type); err = driver_for_each_device(drv, NULL, ®istered, ivtvfb_callback_init); + put_driver(drv); if (!registered) { printk(KERN_ERR "ivtvfb: no cards found\n"); return -ENODEV; @@ -1309,6 +1310,7 @@ static void ivtvfb_cleanup(void) drv = driver_find("ivtv", &pci_bus_type); err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup); + put_driver(drv); } module_init(ivtvfb_init); diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c index 63eccb55728f..8ea4ee116e46 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -344,13 +344,16 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd) return -ENODEV; ret = driver_for_each_device(driver, NULL, fmd, fimc_register_callback); + put_driver(driver); if (ret) return ret; driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type); - if (driver) + if (driver) { ret = driver_for_each_device(driver, NULL, fmd, csis_register_callback); + put_driver(driver); + } return ret; } diff --git a/trunk/drivers/media/video/s5p-tv/mixer_video.c b/trunk/drivers/media/video/s5p-tv/mixer_video.c index f7ca5cc143c6..7884baeff76a 100644 --- a/trunk/drivers/media/video/s5p-tv/mixer_video.c +++ b/trunk/drivers/media/video/s5p-tv/mixer_video.c @@ -58,6 +58,7 @@ static struct v4l2_subdev *find_and_register_subdev( } done: + put_driver(drv); return sd; } diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index e8c42d6a7d1c..f320f466f03b 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -915,7 +915,9 @@ static int phy_probe(struct device *dev) phydev = to_phy_device(dev); - drv = phydev->dev.driver; + /* Make sure the driver is held. + * XXX -- Is this correct? */ + drv = get_driver(phydev->dev.driver); phydrv = to_phy_driver(drv); phydev->drv = phydrv; @@ -955,6 +957,8 @@ static int phy_remove(struct device *dev) if (phydev->drv->remove) phydev->drv->remove(phydev); + + put_driver(dev->driver); phydev->drv = NULL; return 0; diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 8d9616b821ca..3623d65f8b86 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -72,7 +72,9 @@ int pci_add_dynid(struct pci_driver *drv, list_add_tail(&dynid->node, &drv->dynids.list); spin_unlock(&drv->dynids.lock); + get_driver(&drv->driver); retval = driver_attach(&drv->driver); + put_driver(&drv->driver); return retval; } @@ -188,34 +190,43 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); static int -pci_create_newid_files(struct pci_driver *drv) +pci_create_newid_file(struct pci_driver *drv) { int error = 0; - - if (drv->probe != NULL) { + if (drv->probe != NULL) error = driver_create_file(&drv->driver, &driver_attr_new_id); - if (error == 0) { - error = driver_create_file(&drv->driver, - &driver_attr_remove_id); - if (error) - driver_remove_file(&drv->driver, - &driver_attr_new_id); - } - } return error; } -static void pci_remove_newid_files(struct pci_driver *drv) +static void pci_remove_newid_file(struct pci_driver *drv) { - driver_remove_file(&drv->driver, &driver_attr_remove_id); driver_remove_file(&drv->driver, &driver_attr_new_id); } + +static int +pci_create_removeid_file(struct pci_driver *drv) +{ + int error = 0; + if (drv->probe != NULL) + error = driver_create_file(&drv->driver,&driver_attr_remove_id); + return error; +} + +static void pci_remove_removeid_file(struct pci_driver *drv) +{ + driver_remove_file(&drv->driver, &driver_attr_remove_id); +} #else /* !CONFIG_HOTPLUG */ -static inline int pci_create_newid_files(struct pci_driver *drv) +static inline int pci_create_newid_file(struct pci_driver *drv) { return 0; } -static inline void pci_remove_newid_files(struct pci_driver *drv) {} +static inline void pci_remove_newid_file(struct pci_driver *drv) {} +static inline int pci_create_removeid_file(struct pci_driver *drv) +{ + return 0; +} +static inline void pci_remove_removeid_file(struct pci_driver *drv) {} #endif /** @@ -1127,12 +1138,18 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, if (error) goto out; - error = pci_create_newid_files(drv); + error = pci_create_newid_file(drv); if (error) goto out_newid; + + error = pci_create_removeid_file(drv); + if (error) + goto out_removeid; out: return error; +out_removeid: + pci_remove_newid_file(drv); out_newid: driver_unregister(&drv->driver); goto out; @@ -1151,7 +1168,8 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, void pci_unregister_driver(struct pci_driver *drv) { - pci_remove_newid_files(drv); + pci_remove_removeid_file(drv); + pci_remove_newid_file(drv); driver_unregister(&drv->driver); pci_free_dynids(drv); } diff --git a/trunk/drivers/pci/xen-pcifront.c b/trunk/drivers/pci/xen-pcifront.c index 98387caf59b3..7cf3d2fcf56a 100644 --- a/trunk/drivers/pci/xen-pcifront.c +++ b/trunk/drivers/pci/xen-pcifront.c @@ -593,7 +593,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, } pdrv = pcidev->driver; - if (pdrv) { + if (get_driver(&pdrv->driver)) { if (pdrv->err_handler && pdrv->err_handler->error_detected) { dev_dbg(&pcidev->dev, "trying to call AER service\n"); @@ -623,6 +623,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, } } } + put_driver(&pdrv->driver); } if (!flag) result = PCI_ERS_RESULT_NONE; diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 079629bff957..1932029de48d 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -127,7 +127,10 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) list_add_tail(&dynid->node, &pdrv->dynids.list); mutex_unlock(&pdrv->dynids.lock); - retval = driver_attach(&pdrv->drv); + if (get_driver(&pdrv->drv)) { + retval = driver_attach(&pdrv->drv); + put_driver(&pdrv->drv); + } if (retval) return retval; @@ -157,11 +160,6 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) return error; } -static void -pcmcia_remove_newid_file(struct pcmcia_driver *drv) -{ - driver_remove_file(&drv->drv, &driver_attr_new_id); -} /** * pcmcia_register_driver - register a PCMCIA driver with the bus core @@ -206,7 +204,6 @@ EXPORT_SYMBOL(pcmcia_register_driver); void pcmcia_unregister_driver(struct pcmcia_driver *driver) { pr_debug("unregistering driver %s\n", driver->name); - pcmcia_remove_newid_file(driver); driver_unregister(&driver->drv); pcmcia_free_dynids(driver); } diff --git a/trunk/drivers/s390/cio/ccwgroup.c b/trunk/drivers/s390/cio/ccwgroup.c index 5f1dc6fb5708..4f1989d27b1f 100644 --- a/trunk/drivers/s390/cio/ccwgroup.c +++ b/trunk/drivers/s390/cio/ccwgroup.c @@ -580,6 +580,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) struct device *dev; /* We don't want ccwgroup devices to live longer than their driver. */ + get_driver(&cdriver->driver); while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, __ccwgroup_match_all))) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); @@ -591,6 +592,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) mutex_unlock(&gdev->reg_mutex); put_device(dev); } + put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); } EXPORT_SYMBOL(ccwgroup_driver_unregister); diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 02d015259461..47269858ecb6 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1676,9 +1676,15 @@ struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) { struct device *dev; + struct device_driver *drv; - dev = driver_find_device(&cdrv->driver, NULL, (void *)bus_id, + drv = get_driver(&cdrv->driver); + if (!drv) + return NULL; + + dev = driver_find_device(drv, NULL, (void *)bus_id, __ccwdev_check_busid); + put_driver(drv); return dev ? to_ccwdev(dev) : NULL; } diff --git a/trunk/drivers/s390/net/smsgiucv_app.c b/trunk/drivers/s390/net/smsgiucv_app.c index 32515a201bbc..4d2ea4000422 100644 --- a/trunk/drivers/s390/net/smsgiucv_app.c +++ b/trunk/drivers/s390/net/smsgiucv_app.c @@ -168,7 +168,7 @@ static int __init smsgiucv_app_init(void) rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT); if (rc) { kfree(smsg_app_dev); - goto fail; + goto fail_put_driver; } smsg_app_dev->bus = &iucv_bus; smsg_app_dev->parent = iucv_root; @@ -177,7 +177,7 @@ static int __init smsgiucv_app_init(void) rc = device_register(smsg_app_dev); if (rc) { put_device(smsg_app_dev); - goto fail; + goto fail_put_driver; } /* convert sender to uppercase characters */ @@ -191,11 +191,12 @@ static int __init smsgiucv_app_init(void) rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback); if (rc) { device_unregister(smsg_app_dev); - goto fail; + goto fail_put_driver; } rc = 0; -fail: +fail_put_driver: + put_driver(smsgiucv_drv); return rc; } module_init(smsgiucv_app_init); diff --git a/trunk/drivers/ssb/main.c b/trunk/drivers/ssb/main.c index ff109ae94767..bb6317fb925c 100644 --- a/trunk/drivers/ssb/main.c +++ b/trunk/drivers/ssb/main.c @@ -140,6 +140,19 @@ static void ssb_device_put(struct ssb_device *dev) put_device(dev->dev); } +static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv) +{ + if (drv) + get_driver(&drv->drv); + return drv; +} + +static inline void ssb_driver_put(struct ssb_driver *drv) +{ + if (drv) + put_driver(&drv->drv); +} + static int ssb_device_resume(struct device *dev) { struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); @@ -237,9 +250,11 @@ int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx) ssb_device_put(sdev); continue; } - sdrv = drv_to_ssb_drv(sdev->dev->driver); - if (SSB_WARN_ON(!sdrv->remove)) + sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver)); + if (!sdrv || SSB_WARN_ON(!sdrv->remove)) { + ssb_device_put(sdev); continue; + } sdrv->remove(sdev); ctx->device_frozen[i] = 1; } @@ -278,6 +293,7 @@ int ssb_devices_thaw(struct ssb_freeze_context *ctx) dev_name(sdev->dev)); result = err; } + ssb_driver_put(sdrv); ssb_device_put(sdev); } diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index 4fee024ecc9b..d40ff9568813 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -71,7 +71,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, list_add_tail(&dynid->node, &dynids->list); spin_unlock(&dynids->lock); - retval = driver_attach(driver); + if (get_driver(driver)) { + retval = driver_attach(driver); + put_driver(driver); + } if (retval) return retval; @@ -129,39 +132,43 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) } static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); -static int usb_create_newid_files(struct usb_driver *usb_drv) +static int usb_create_newid_file(struct usb_driver *usb_drv) { int error = 0; if (usb_drv->no_dynamic_id) goto exit; - if (usb_drv->probe != NULL) { + if (usb_drv->probe != NULL) error = driver_create_file(&usb_drv->drvwrap.driver, &driver_attr_new_id); - if (error == 0) { - error = driver_create_file(&usb_drv->drvwrap.driver, - &driver_attr_remove_id); - if (error) - driver_remove_file(&usb_drv->drvwrap.driver, - &driver_attr_new_id); - } - } exit: return error; } -static void usb_remove_newid_files(struct usb_driver *usb_drv) +static void usb_remove_newid_file(struct usb_driver *usb_drv) { if (usb_drv->no_dynamic_id) return; - if (usb_drv->probe != NULL) { - driver_remove_file(&usb_drv->drvwrap.driver, - &driver_attr_remove_id); + if (usb_drv->probe != NULL) driver_remove_file(&usb_drv->drvwrap.driver, &driver_attr_new_id); - } +} + +static int +usb_create_removeid_file(struct usb_driver *drv) +{ + int error = 0; + if (drv->probe != NULL) + error = driver_create_file(&drv->drvwrap.driver, + &driver_attr_remove_id); + return error; +} + +static void usb_remove_removeid_file(struct usb_driver *drv) +{ + driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id); } static void usb_free_dynids(struct usb_driver *usb_drv) @@ -176,12 +183,22 @@ static void usb_free_dynids(struct usb_driver *usb_drv) spin_unlock(&usb_drv->dynids.lock); } #else -static inline int usb_create_newid_files(struct usb_driver *usb_drv) +static inline int usb_create_newid_file(struct usb_driver *usb_drv) { return 0; } -static void usb_remove_newid_files(struct usb_driver *usb_drv) +static void usb_remove_newid_file(struct usb_driver *usb_drv) +{ +} + +static int +usb_create_removeid_file(struct usb_driver *drv) +{ + return 0; +} + +static void usb_remove_removeid_file(struct usb_driver *drv) { } @@ -858,16 +875,22 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, usbfs_update_special(); - retval = usb_create_newid_files(new_driver); + retval = usb_create_newid_file(new_driver); if (retval) goto out_newid; + retval = usb_create_removeid_file(new_driver); + if (retval) + goto out_removeid; + pr_info("%s: registered new interface driver %s\n", usbcore_name, new_driver->name); out: return retval; +out_removeid: + usb_remove_newid_file(new_driver); out_newid: driver_unregister(&new_driver->drvwrap.driver); @@ -894,9 +917,10 @@ void usb_deregister(struct usb_driver *driver) pr_info("%s: deregistering interface driver %s\n", usbcore_name, driver->name); - usb_remove_newid_files(driver); - driver_unregister(&driver->drvwrap.driver); + usb_remove_removeid_file(driver); + usb_remove_newid_file(driver); usb_free_dynids(driver); + driver_unregister(&driver->drvwrap.driver); usbfs_update_special(); } diff --git a/trunk/drivers/usb/dwc3/dwc3-pci.c b/trunk/drivers/usb/dwc3/dwc3-pci.c index c68e4270457a..64e1f7c67b08 100644 --- a/trunk/drivers/usb/dwc3/dwc3-pci.c +++ b/trunk/drivers/usb/dwc3/dwc3-pci.c @@ -171,4 +171,14 @@ MODULE_AUTHOR("Felipe Balbi "); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); -module_pci_driver(dwc3_pci_driver); +static int __devinit dwc3_pci_init(void) +{ + return pci_register_driver(&dwc3_pci_driver); +} +module_init(dwc3_pci_init); + +static void __exit dwc3_pci_exit(void) +{ + pci_unregister_driver(&dwc3_pci_driver); +} +module_exit(dwc3_pci_exit); diff --git a/trunk/drivers/w1/masters/w1-gpio.c b/trunk/drivers/w1/masters/w1-gpio.c index df600d14974d..fcbe742188a5 100644 --- a/trunk/drivers/w1/masters/w1-gpio.c +++ b/trunk/drivers/w1/masters/w1-gpio.c @@ -13,11 +13,12 @@ #include #include #include -#include #include "../w1.h" #include "../w1_int.h" +#include + static void w1_gpio_write_bit_dir(void *data, u8 bit) { struct w1_gpio_platform_data *pdata = data; diff --git a/trunk/fs/debugfs/inode.c b/trunk/fs/debugfs/inode.c index b80bc846a15a..956d5ddddf6e 100644 --- a/trunk/fs/debugfs/inode.c +++ b/trunk/fs/debugfs/inode.c @@ -23,13 +23,9 @@ #include #include #include -#include -#include #include #include -#define DEBUGFS_DEFAULT_MODE 0755 - static struct vfsmount *debugfs_mount; static int debugfs_mount_count; static bool debugfs_registered; @@ -129,154 +125,11 @@ static inline int debugfs_positive(struct dentry *dentry) return dentry->d_inode && !d_unhashed(dentry); } -struct debugfs_mount_opts { - uid_t uid; - gid_t gid; - umode_t mode; -}; - -enum { - Opt_uid, - Opt_gid, - Opt_mode, - Opt_err -}; - -static const match_table_t tokens = { - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, - {Opt_mode, "mode=%o"}, - {Opt_err, NULL} -}; - -struct debugfs_fs_info { - struct debugfs_mount_opts mount_opts; -}; - -static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts) -{ - substring_t args[MAX_OPT_ARGS]; - int option; - int token; - char *p; - - opts->mode = DEBUGFS_DEFAULT_MODE; - - while ((p = strsep(&data, ",")) != NULL) { - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_uid: - if (match_int(&args[0], &option)) - return -EINVAL; - opts->uid = option; - break; - case Opt_gid: - if (match_octal(&args[0], &option)) - return -EINVAL; - opts->gid = option; - break; - case Opt_mode: - if (match_octal(&args[0], &option)) - return -EINVAL; - opts->mode = option & S_IALLUGO; - break; - /* - * We might like to report bad mount options here; - * but traditionally debugfs has ignored all mount options - */ - } - } - - return 0; -} - -static int debugfs_apply_options(struct super_block *sb) -{ - struct debugfs_fs_info *fsi = sb->s_fs_info; - struct inode *inode = sb->s_root->d_inode; - struct debugfs_mount_opts *opts = &fsi->mount_opts; - - inode->i_mode &= ~S_IALLUGO; - inode->i_mode |= opts->mode; - - inode->i_uid = opts->uid; - inode->i_gid = opts->gid; - - return 0; -} - -static int debugfs_remount(struct super_block *sb, int *flags, char *data) -{ - int err; - struct debugfs_fs_info *fsi = sb->s_fs_info; - - err = debugfs_parse_options(data, &fsi->mount_opts); - if (err) - goto fail; - - debugfs_apply_options(sb); - -fail: - return err; -} - -static int debugfs_show_options(struct seq_file *m, struct dentry *root) -{ - struct debugfs_fs_info *fsi = root->d_sb->s_fs_info; - struct debugfs_mount_opts *opts = &fsi->mount_opts; - - if (opts->uid != 0) - seq_printf(m, ",uid=%u", opts->uid); - if (opts->gid != 0) - seq_printf(m, ",gid=%u", opts->gid); - if (opts->mode != DEBUGFS_DEFAULT_MODE) - seq_printf(m, ",mode=%o", opts->mode); - - return 0; -} - -static const struct super_operations debugfs_super_operations = { - .statfs = simple_statfs, - .remount_fs = debugfs_remount, - .show_options = debugfs_show_options, -}; - static int debug_fill_super(struct super_block *sb, void *data, int silent) { static struct tree_descr debug_files[] = {{""}}; - struct debugfs_fs_info *fsi; - int err; - - save_mount_options(sb, data); - - fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL); - sb->s_fs_info = fsi; - if (!fsi) { - err = -ENOMEM; - goto fail; - } - - err = debugfs_parse_options(data, &fsi->mount_opts); - if (err) - goto fail; - - err = simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); - if (err) - goto fail; - - sb->s_op = &debugfs_super_operations; - - debugfs_apply_options(sb); - - return 0; -fail: - kfree(fsi); - sb->s_fs_info = NULL; - return err; + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); } static struct dentry *debug_mount(struct file_system_type *fs_type, diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index dd3779cf3a3b..7fdf6a7b7436 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -22,100 +22,76 @@ #include #include #include -#include #include "sysfs.h" DEFINE_MUTEX(sysfs_mutex); DEFINE_SPINLOCK(sysfs_assoc_lock); -#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb); - static DEFINE_SPINLOCK(sysfs_ino_lock); static DEFINE_IDA(sysfs_ino_ida); /** - * sysfs_name_hash - * @ns: Namespace tag to hash - * @name: Null terminated string to hash - * - * Returns 31 bit hash of ns + name (so it fits in an off_t ) - */ -static unsigned int sysfs_name_hash(const void *ns, const char *name) -{ - unsigned long hash = init_name_hash(); - unsigned int len = strlen(name); - while (len--) - hash = partial_name_hash(*name++, hash); - hash = ( end_name_hash(hash) ^ hash_ptr( (void *)ns, 31 ) ); - hash &= 0x7fffffffU; - /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */ - if (hash < 1) - hash += 2; - if (hash >= INT_MAX) - hash = INT_MAX - 1; - return hash; -} - -static int sysfs_name_compare(unsigned int hash, const void *ns, - const char *name, const struct sysfs_dirent *sd) -{ - if (hash != sd->s_hash) - return hash - sd->s_hash; - if (ns != sd->s_ns) - return ns - sd->s_ns; - return strcmp(name, sd->s_name); -} - -static int sysfs_sd_compare(const struct sysfs_dirent *left, - const struct sysfs_dirent *right) -{ - return sysfs_name_compare(left->s_hash, left->s_ns, left->s_name, - right); -} - -/** - * sysfs_link_subling - link sysfs_dirent into sibling rbtree + * sysfs_link_sibling - link sysfs_dirent into sibling list * @sd: sysfs_dirent of interest * - * Link @sd into its sibling rbtree which starts from + * Link @sd into its sibling list which starts from * sd->s_parent->s_dir.children. * * Locking: * mutex_lock(sysfs_mutex) - * - * RETURNS: - * 0 on susccess -EEXIST on failure. */ -static int sysfs_link_sibling(struct sysfs_dirent *sd) +static void sysfs_link_sibling(struct sysfs_dirent *sd) { - struct rb_node **node = &sd->s_parent->s_dir.children.rb_node; - struct rb_node *parent = NULL; - - while (*node) { - struct sysfs_dirent *pos; - int result; - - pos = to_sysfs_dirent(*node); - parent = *node; - result = sysfs_sd_compare(sd, pos); - if (result < 0) - node = &pos->s_rb.rb_left; - else if (result > 0) - node = &pos->s_rb.rb_right; - else - return -EEXIST; + struct sysfs_dirent *parent_sd = sd->s_parent; + + struct rb_node **p; + struct rb_node *parent; + + if (sysfs_type(sd) == SYSFS_DIR) + parent_sd->s_dir.subdirs++; + + p = &parent_sd->s_dir.inode_tree.rb_node; + parent = NULL; + while (*p) { + parent = *p; +#define node rb_entry(parent, struct sysfs_dirent, inode_node) + if (sd->s_ino < node->s_ino) { + p = &node->inode_node.rb_left; + } else if (sd->s_ino > node->s_ino) { + p = &node->inode_node.rb_right; + } else { + printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n", + (unsigned long) sd->s_ino); + BUG(); + } +#undef node } - /* add new node and rebalance the tree */ - rb_link_node(&sd->s_rb, parent, node); - rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children); - return 0; + rb_link_node(&sd->inode_node, parent, p); + rb_insert_color(&sd->inode_node, &parent_sd->s_dir.inode_tree); + + p = &parent_sd->s_dir.name_tree.rb_node; + parent = NULL; + while (*p) { + int c; + parent = *p; +#define node rb_entry(parent, struct sysfs_dirent, name_node) + c = strcmp(sd->s_name, node->s_name); + if (c < 0) { + p = &node->name_node.rb_left; + } else { + p = &node->name_node.rb_right; + } +#undef node + } + rb_link_node(&sd->name_node, parent, p); + rb_insert_color(&sd->name_node, &parent_sd->s_dir.name_tree); } /** - * sysfs_unlink_sibling - unlink sysfs_dirent from sibling rbtree + * sysfs_unlink_sibling - unlink sysfs_dirent from sibling list * @sd: sysfs_dirent of interest * - * Unlink @sd from its sibling rbtree which starts from + * Unlink @sd from its sibling list which starts from * sd->s_parent->s_dir.children. * * Locking: @@ -123,7 +99,11 @@ static int sysfs_link_sibling(struct sysfs_dirent *sd) */ static void sysfs_unlink_sibling(struct sysfs_dirent *sd) { - rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); + if (sysfs_type(sd) == SYSFS_DIR) + sd->s_parent->s_dir.subdirs--; + + rb_erase(&sd->inode_node, &sd->s_parent->s_dir.inode_tree); + rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree); } /** @@ -218,7 +198,7 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) rwsem_release(&sd->dep_map, 1, _RET_IP_); } -static int sysfs_alloc_ino(unsigned int *pino) +static int sysfs_alloc_ino(ino_t *pino) { int ino, rc; @@ -237,7 +217,7 @@ static int sysfs_alloc_ino(unsigned int *pino) return rc; } -static void sysfs_free_ino(unsigned int ino) +static void sysfs_free_ino(ino_t ino) { spin_lock(&sysfs_ino_lock); ida_remove(&sysfs_ino_ida, ino); @@ -422,7 +402,6 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) { struct sysfs_inode_attrs *ps_iattr; - int ret; if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", @@ -431,12 +410,12 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) return -EINVAL; } - sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); + if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name)) + return -EEXIST; + sd->s_parent = sysfs_get(acxt->parent_sd); - ret = sysfs_link_sibling(sd); - if (ret) - return ret; + sysfs_link_sibling(sd); /* Update timestamps on the parent */ ps_iattr = acxt->parent_sd->s_iattr; @@ -586,8 +565,8 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, const void *ns, const unsigned char *name) { - struct rb_node *node = parent_sd->s_dir.children.rb_node; - unsigned int hash; + struct rb_node *p = parent_sd->s_dir.name_tree.rb_node; + struct sysfs_dirent *found = NULL; if (!!sysfs_ns_type(parent_sd) != !!ns) { WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", @@ -596,21 +575,33 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, return NULL; } - hash = sysfs_name_hash(ns, name); - while (node) { - struct sysfs_dirent *sd; - int result; - - sd = to_sysfs_dirent(node); - result = sysfs_name_compare(hash, ns, name, sd); - if (result < 0) - node = node->rb_left; - else if (result > 0) - node = node->rb_right; - else - return sd; + while (p) { + int c; +#define node rb_entry(p, struct sysfs_dirent, name_node) + c = strcmp(name, node->s_name); + if (c < 0) { + p = node->name_node.rb_left; + } else if (c > 0) { + p = node->name_node.rb_right; + } else { + found = node; + p = node->name_node.rb_left; + } +#undef node } - return NULL; + + if (found) { + while (found->s_ns != ns) { + p = rb_next(&found->name_node); + if (!p) + return NULL; + found = rb_entry(p, struct sysfs_dirent, name_node); + if (strcmp(name, found->s_name)) + return NULL; + } + } + + return found; } /** @@ -813,9 +804,9 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd) pr_debug("sysfs %s: removing dir\n", dir_sd->s_name); sysfs_addrm_start(&acxt, dir_sd); - pos = rb_first(&dir_sd->s_dir.children); + pos = rb_first(&dir_sd->s_dir.inode_tree); while (pos) { - struct sysfs_dirent *sd = to_sysfs_dirent(pos); + struct sysfs_dirent *sd = rb_entry(pos, struct sysfs_dirent, inode_node); pos = rb_next(pos); if (sysfs_type(sd) != SYSFS_DIR) sysfs_remove_one(&acxt, sd); @@ -872,7 +863,6 @@ int sysfs_rename(struct sysfs_dirent *sd, dup_name = sd->s_name; sd->s_name = new_name; - sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); } /* Move to the appropriate place in the appropriate directories rbtree. */ @@ -929,36 +919,38 @@ static int sysfs_dir_release(struct inode *inode, struct file *filp) } static struct sysfs_dirent *sysfs_dir_pos(const void *ns, - struct sysfs_dirent *parent_sd, loff_t hash, struct sysfs_dirent *pos) + struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) { if (pos) { int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) && pos->s_parent == parent_sd && - hash == pos->s_hash; + ino == pos->s_ino; sysfs_put(pos); if (!valid) pos = NULL; } - if (!pos && (hash > 1) && (hash < INT_MAX)) { - struct rb_node *node = parent_sd->s_dir.children.rb_node; - while (node) { - pos = to_sysfs_dirent(node); - - if (hash < pos->s_hash) - node = node->rb_left; - else if (hash > pos->s_hash) - node = node->rb_right; - else + if (!pos && (ino > 1) && (ino < INT_MAX)) { + struct rb_node *p = parent_sd->s_dir.inode_tree.rb_node; + while (p) { +#define node rb_entry(p, struct sysfs_dirent, inode_node) + if (ino < node->s_ino) { + pos = node; + p = node->inode_node.rb_left; + } else if (ino > node->s_ino) { + p = node->inode_node.rb_right; + } else { + pos = node; break; + } +#undef node } } - /* Skip over entries in the wrong namespace */ while (pos && pos->s_ns != ns) { - struct rb_node *node = rb_next(&pos->s_rb); - if (!node) + struct rb_node *p = rb_next(&pos->inode_node); + if (!p) pos = NULL; else - pos = to_sysfs_dirent(node); + pos = rb_entry(p, struct sysfs_dirent, inode_node); } return pos; } @@ -968,11 +960,11 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns, { pos = sysfs_dir_pos(ns, parent_sd, ino, pos); if (pos) do { - struct rb_node *node = rb_next(&pos->s_rb); - if (!node) + struct rb_node *p = rb_next(&pos->inode_node); + if (!p) pos = NULL; else - pos = to_sysfs_dirent(node); + pos = rb_entry(p, struct sysfs_dirent, inode_node); } while (pos && pos->s_ns != ns); return pos; } @@ -1014,7 +1006,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) len = strlen(name); ino = pos->s_ino; type = dt_type(pos); - filp->f_pos = pos->s_hash; + filp->f_pos = ino; filp->private_data = sysfs_get(pos); mutex_unlock(&sysfs_mutex); diff --git a/trunk/fs/sysfs/inode.c b/trunk/fs/sysfs/inode.c index 4291fd1617ab..85eb81683a29 100644 --- a/trunk/fs/sysfs/inode.c +++ b/trunk/fs/sysfs/inode.c @@ -216,6 +216,9 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode) iattrs->ia_secdata, iattrs->ia_secdata_len); } + + if (sysfs_type(sd) == SYSFS_DIR) + set_nlink(inode, sd->s_dir.subdirs + 2); } int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) diff --git a/trunk/fs/sysfs/mount.c b/trunk/fs/sysfs/mount.c index 140f26a34288..e34f0d99ea4e 100644 --- a/trunk/fs/sysfs/mount.c +++ b/trunk/fs/sysfs/mount.c @@ -36,7 +36,7 @@ struct sysfs_dirent sysfs_root = { .s_name = "", .s_count = ATOMIC_INIT(1), .s_flags = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT), - .s_mode = S_IFDIR | S_IRUGO | S_IXUGO, + .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, .s_ino = 1, }; diff --git a/trunk/fs/sysfs/sysfs.h b/trunk/fs/sysfs/sysfs.h index 6289a00287db..7484a36ee678 100644 --- a/trunk/fs/sysfs/sysfs.h +++ b/trunk/fs/sysfs/sysfs.h @@ -19,8 +19,10 @@ struct sysfs_open_dirent; struct sysfs_elem_dir { struct kobject *kobj; - /* children rbtree starts here and goes through sd->s_rb */ - struct rb_root children; + unsigned long subdirs; + + struct rb_root inode_tree; + struct rb_root name_tree; }; struct sysfs_elem_symlink { @@ -60,7 +62,8 @@ struct sysfs_dirent { struct sysfs_dirent *s_parent; const char *s_name; - struct rb_node s_rb; + struct rb_node inode_node; + struct rb_node name_node; union { struct completion *completion; @@ -68,7 +71,6 @@ struct sysfs_dirent { } u; const void *s_ns; /* namespace tag */ - unsigned int s_hash; /* ns + name hash */ union { struct sysfs_elem_dir s_dir; struct sysfs_elem_symlink s_symlink; @@ -76,9 +78,9 @@ struct sysfs_dirent { struct sysfs_elem_bin_attr s_bin_attr; }; - unsigned short s_flags; + unsigned int s_flags; umode_t s_mode; - unsigned int s_ino; + ino_t s_ino; struct sysfs_inode_attrs *s_iattr; }; @@ -93,11 +95,11 @@ struct sysfs_dirent { #define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR) /* identify any namespace tag on sysfs_dirents */ -#define SYSFS_NS_TYPE_MASK 0xf00 +#define SYSFS_NS_TYPE_MASK 0xff00 #define SYSFS_NS_TYPE_SHIFT 8 #define SYSFS_FLAG_MASK ~(SYSFS_NS_TYPE_MASK|SYSFS_TYPE_MASK) -#define SYSFS_FLAG_REMOVED 0x02000 +#define SYSFS_FLAG_REMOVED 0x020000 static inline unsigned int sysfs_type(struct sysfs_dirent *sd) { diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 9d650476d5dc..8cf7e98a2c7b 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -225,7 +225,6 @@ struct acpi_processor_errata { } piix4; }; -extern void acpi_processor_load_module(struct acpi_processor *pr); extern int acpi_processor_preregister_performance(struct acpi_processor_performance __percpu *performance); diff --git a/trunk/include/linux/connector.h b/trunk/include/linux/connector.h index 76384074262d..3c9c54fd5690 100644 --- a/trunk/include/linux/connector.h +++ b/trunk/include/linux/connector.h @@ -43,7 +43,6 @@ #define CN_IDX_DRBD 0x8 #define CN_VAL_DRBD 0x1 #define CN_KVP_IDX 0x9 /* HyperV KVP */ -#define CN_KVP_VAL 0x1 /* queries from the kernel */ #define CN_NETLINK_USERS 10 /* Highest index + 1 */ diff --git a/trunk/include/linux/cpu.h b/trunk/include/linux/cpu.h index 6e53b4823d7f..1f6587590a1a 100644 --- a/trunk/include/linux/cpu.h +++ b/trunk/include/linux/cpu.h @@ -44,13 +44,6 @@ extern ssize_t arch_cpu_release(const char *, size_t); #endif struct notifier_block; -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE -extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env); -extern ssize_t arch_print_cpu_modalias(struct device *dev, - struct device_attribute *attr, - char *bufptr); -#endif - /* * CPU notifier priorities. */ diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index f62e21689fdd..b63fb393aa58 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -238,6 +238,8 @@ struct device_driver { extern int __must_check driver_register(struct device_driver *drv); extern void driver_unregister(struct device_driver *drv); +extern struct device_driver *get_driver(struct device_driver *drv); +extern void put_driver(struct device_driver *drv); extern struct device_driver *driver_find(const char *name, struct bus_type *bus); extern int driver_probe_done(void); @@ -944,14 +946,14 @@ int _dev_info(const struct device *dev, const char *fmt, ...) #define dev_info(dev, fmt, arg...) _dev_info(dev, fmt, ##arg) -#if defined(CONFIG_DYNAMIC_DEBUG) +#if defined(DEBUG) +#define dev_dbg(dev, format, arg...) \ + dev_printk(KERN_DEBUG, dev, format, ##arg) +#elif defined(CONFIG_DYNAMIC_DEBUG) #define dev_dbg(dev, format, ...) \ do { \ dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ } while (0) -#elif defined(DEBUG) -#define dev_dbg(dev, format, arg...) \ - dev_printk(KERN_DEBUG, dev, format, ##arg) #else #define dev_dbg(dev, format, arg...) \ ({ \ diff --git a/trunk/include/linux/dynamic_debug.h b/trunk/include/linux/dynamic_debug.h index 7e3c53a900d8..0564e3c39882 100644 --- a/trunk/include/linux/dynamic_debug.h +++ b/trunk/include/linux/dynamic_debug.h @@ -15,24 +15,20 @@ struct _ddebug { const char *function; const char *filename; const char *format; - unsigned int lineno:18; + unsigned int lineno:24; /* * The flags field controls the behaviour at the callsite. * The bits here are changed dynamically when the user * writes commands to /dynamic_debug/control */ -#define _DPRINTK_FLAGS_NONE 0 -#define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ +#define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ #define _DPRINTK_FLAGS_INCL_MODNAME (1<<1) #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2) #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) #define _DPRINTK_FLAGS_INCL_TID (1<<4) -#if defined DEBUG -#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT -#else #define _DPRINTK_FLAGS_DEFAULT 0 -#endif unsigned int flags:8; + char enabled; } __attribute__((aligned(8))); @@ -66,20 +62,21 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor, .format = (fmt), \ .lineno = __LINE__, \ .flags = _DPRINTK_FLAGS_DEFAULT, \ + .enabled = false, \ } #define dynamic_pr_debug(fmt, ...) \ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + if (unlikely(descriptor.enabled)) \ __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ ##__VA_ARGS__); \ } while (0) #define dynamic_dev_dbg(dev, fmt, ...) \ do { \ - DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (unlikely(descriptor.enabled)) \ __dynamic_dev_dbg(&descriptor, dev, fmt, \ ##__VA_ARGS__); \ } while (0) @@ -87,7 +84,7 @@ do { \ #define dynamic_netdev_dbg(dev, fmt, ...) \ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + if (unlikely(descriptor.enabled)) \ __dynamic_netdev_dbg(&descriptor, dev, fmt, \ ##__VA_ARGS__); \ } while (0) diff --git a/trunk/include/linux/hyperv.h b/trunk/include/linux/hyperv.h index 75aee6720c1b..62b908e0e591 100644 --- a/trunk/include/linux/hyperv.h +++ b/trunk/include/linux/hyperv.h @@ -25,147 +25,6 @@ #ifndef _HYPERV_H #define _HYPERV_H -#include - -/* - * An implementation of HyperV key value pair (KVP) functionality for Linux. - * - * - * Copyright (C) 2010, Novell, Inc. - * Author : K. Y. Srinivasan - * - */ - -/* - * Maximum value size - used for both key names and value data, and includes - * any applicable NULL terminators. - * - * Note: This limit is somewhat arbitrary, but falls easily within what is - * supported for all native guests (back to Win 2000) and what is reasonable - * for the IC KVP exchange functionality. Note that Windows Me/98/95 are - * limited to 255 character key names. - * - * MSDN recommends not storing data values larger than 2048 bytes in the - * registry. - * - * Note: This value is used in defining the KVP exchange message - this value - * cannot be modified without affecting the message size and compatibility. - */ - -/* - * bytes, including any null terminators - */ -#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) - - -/* - * Maximum key size - the registry limit for the length of an entry name - * is 256 characters, including the null terminator - */ - -#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) - -/* - * In Linux, we implement the KVP functionality in two components: - * 1) The kernel component which is packaged as part of the hv_utils driver - * is responsible for communicating with the host and responsible for - * implementing the host/guest protocol. 2) A user level daemon that is - * responsible for data gathering. - * - * Host/Guest Protocol: The host iterates over an index and expects the guest - * to assign a key name to the index and also return the value corresponding to - * the key. The host will have atmost one KVP transaction outstanding at any - * given point in time. The host side iteration stops when the guest returns - * an error. Microsoft has specified the following mapping of key names to - * host specified index: - * - * Index Key Name - * 0 FullyQualifiedDomainName - * 1 IntegrationServicesVersion - * 2 NetworkAddressIPv4 - * 3 NetworkAddressIPv6 - * 4 OSBuildNumber - * 5 OSName - * 6 OSMajorVersion - * 7 OSMinorVersion - * 8 OSVersion - * 9 ProcessorArchitecture - * - * The Windows host expects the Key Name and Key Value to be encoded in utf16. - * - * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the - * data gathering functionality in a user mode daemon. The user level daemon - * is also responsible for binding the key name to the index as well. The - * kernel and user-level daemon communicate using a connector channel. - * - * The user mode component first registers with the - * the kernel component. Subsequently, the kernel component requests, data - * for the specified keys. In response to this message the user mode component - * fills in the value corresponding to the specified key. We overload the - * sequence field in the cn_msg header to define our KVP message types. - * - * - * The kernel component simply acts as a conduit for communication between the - * Windows host and the user-level daemon. The kernel component passes up the - * index received from the Host to the user-level daemon. If the index is - * valid (supported), the corresponding key as well as its - * value (both are strings) is returned. If the index is invalid - * (not supported), a NULL key string is returned. - */ - - -/* - * Registry value types. - */ - -#define REG_SZ 1 - -enum hv_kvp_exchg_op { - KVP_OP_GET = 0, - KVP_OP_SET, - KVP_OP_DELETE, - KVP_OP_ENUMERATE, - KVP_OP_REGISTER, - KVP_OP_COUNT /* Number of operations, must be last. */ -}; - -enum hv_kvp_exchg_pool { - KVP_POOL_EXTERNAL = 0, - KVP_POOL_GUEST, - KVP_POOL_AUTO, - KVP_POOL_AUTO_EXTERNAL, - KVP_POOL_AUTO_INTERNAL, - KVP_POOL_COUNT /* Number of pools, must be last. */ -}; - -struct hv_kvp_hdr { - __u8 operation; - __u8 pool; - __u16 pad; -} __attribute__((packed)); - -struct hv_kvp_exchg_msg_value { - __u32 value_type; - __u32 key_size; - __u32 value_size; - __u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; - __u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; -} __attribute__((packed)); - -struct hv_kvp_msg_enumerate { - __u32 index; - struct hv_kvp_exchg_msg_value data; -} __attribute__((packed)); - -struct hv_kvp_msg { - struct hv_kvp_hdr kvp_hdr; - union { - struct hv_kvp_msg_enumerate kvp_enum_data; - char kvp_version[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; - } body; -} __attribute__((packed)); - -#ifdef __KERNEL__ #include #include #include @@ -1011,9 +870,4 @@ struct hyperv_service_callback { extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *, struct icmsg_negotiate *, u8 *); -int hv_kvp_init(struct hv_util_service *); -void hv_kvp_deinit(void); -void hv_kvp_onchannelcallback(void *); - -#endif /* __KERNEL__ */ #endif /* _HYPERV_H */ diff --git a/trunk/include/linux/mod_devicetable.h b/trunk/include/linux/mod_devicetable.h index fb69ad191ad7..83ac0713ed0a 100644 --- a/trunk/include/linux/mod_devicetable.h +++ b/trunk/include/linux/mod_devicetable.h @@ -560,25 +560,4 @@ struct amba_id { #endif }; -/* - * Match x86 CPUs for CPU specific drivers. - * See documentation of "x86_match_cpu" for details. - */ - -struct x86_cpu_id { - __u16 vendor; - __u16 family; - __u16 model; - __u16 feature; /* bit index */ - kernel_ulong_t driver_data; -}; - -#define X86_FEATURE_MATCH(x) \ - { X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, x } - -#define X86_VENDOR_ANY 0xffff -#define X86_FAMILY_ANY 0 -#define X86_MODEL_ANY 0 -#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ - #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index f486f635e7b5..0eac07c95255 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -2687,14 +2687,14 @@ int netdev_info(const struct net_device *dev, const char *format, ...); #define MODULE_ALIAS_NETDEV(device) \ MODULE_ALIAS("netdev-" device) -#if defined(CONFIG_DYNAMIC_DEBUG) +#if defined(DEBUG) +#define netdev_dbg(__dev, format, args...) \ + netdev_printk(KERN_DEBUG, __dev, format, ##args) +#elif defined(CONFIG_DYNAMIC_DEBUG) #define netdev_dbg(__dev, format, args...) \ do { \ dynamic_netdev_dbg(__dev, format, ##args); \ } while (0) -#elif defined(DEBUG) -#define netdev_dbg(__dev, format, args...) \ - netdev_printk(KERN_DEBUG, __dev, format, ##args) #else #define netdev_dbg(__dev, format, args...) \ ({ \ diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index d4afd703e948..a16b1df3deff 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -946,19 +946,6 @@ int __must_check __pci_register_driver(struct pci_driver *, struct module *, __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME) void pci_unregister_driver(struct pci_driver *dev); - -/** - * module_pci_driver() - Helper macro for registering a PCI driver - * @__pci_driver: pci_driver struct - * - * Helper macro for PCI drivers which do not do anything special in module - * init/exit. This eliminates a lot of boilerplate. Each module may only - * use this macro once, and calling it replaces module_init() and module_exit() - */ -#define module_pci_driver(__pci_driver) \ - module_driver(__pci_driver, pci_register_driver, \ - pci_unregister_driver) - void pci_remove_behind_bridge(struct pci_dev *dev); struct pci_driver *pci_dev_driver(const struct pci_dev *dev); int pci_add_dynid(struct pci_driver *drv, diff --git a/trunk/include/linux/printk.h b/trunk/include/linux/printk.h index f9abd9357a0c..f0e22f75143f 100644 --- a/trunk/include/linux/printk.h +++ b/trunk/include/linux/printk.h @@ -180,13 +180,13 @@ extern void dump_stack(void) __cold; #endif /* If you are writing a driver, please use dev_dbg instead */ -#if defined(CONFIG_DYNAMIC_DEBUG) +#if defined(DEBUG) +#define pr_debug(fmt, ...) \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) +#elif defined(CONFIG_DYNAMIC_DEBUG) /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */ #define pr_debug(fmt, ...) \ dynamic_pr_debug(fmt, ##__VA_ARGS__) -#elif defined(DEBUG) -#define pr_debug(fmt, ...) \ - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #else #define pr_debug(fmt, ...) \ no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) diff --git a/trunk/include/linux/sys_soc.h b/trunk/include/linux/sys_soc.h deleted file mode 100644 index 2739ccb69571..000000000000 --- a/trunk/include/linux/sys_soc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * Author: Lee Jones for ST-Ericsson. - * License terms: GNU General Public License (GPL), version 2 - */ -#ifndef __SOC_BUS_H -#define __SOC_BUS_H - -#include - -struct soc_device_attribute { - const char *machine; - const char *family; - const char *revision; - const char *soc_id; -}; - -/** - * soc_device_register - register SoC as a device - * @soc_plat_dev_attr: Attributes passed from platform to be attributed to a SoC - */ -struct soc_device *soc_device_register( - struct soc_device_attribute *soc_plat_dev_attr); - -/** - * soc_device_unregister - unregister SoC device - * @dev: SoC device to be unregistered - */ -void soc_device_unregister(struct soc_device *soc_dev); - -/** - * soc_device_to_device - helper function to fetch struct device - * @soc: Previously registered SoC device container - */ -struct device *soc_device_to_device(struct soc_device *soc); - -#endif /* __SOC_BUS_H */ diff --git a/trunk/lib/dma-debug.c b/trunk/lib/dma-debug.c index 13ef2338be41..fea790a2b176 100644 --- a/trunk/lib/dma-debug.c +++ b/trunk/lib/dma-debug.c @@ -170,7 +170,7 @@ static bool driver_filter(struct device *dev) return false; /* driver filter on but not yet initialized */ - drv = dev->driver; + drv = get_driver(dev->driver); if (!drv) return false; @@ -185,6 +185,7 @@ static bool driver_filter(struct device *dev) } read_unlock_irqrestore(&driver_name_lock, flags); + put_driver(drv); return ret; } diff --git a/trunk/lib/dynamic_debug.c b/trunk/lib/dynamic_debug.c index 310c753cf83e..dcdade39e47f 100644 --- a/trunk/lib/dynamic_debug.c +++ b/trunk/lib/dynamic_debug.c @@ -60,7 +60,6 @@ struct ddebug_iter { static DEFINE_MUTEX(ddebug_lock); static LIST_HEAD(ddebug_tables); static int verbose = 0; -module_param(verbose, int, 0644); /* Return the last part of a pathname */ static inline const char *basename(const char *path) @@ -69,24 +68,12 @@ static inline const char *basename(const char *path) return tail ? tail+1 : path; } -/* Return the path relative to source root */ -static inline const char *trim_prefix(const char *path) -{ - int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c"); - - if (strncmp(path, __FILE__, skip)) - skip = 0; /* prefix mismatch, don't skip */ - - return path + skip; -} - static struct { unsigned flag:8; char opt_char; } opt_array[] = { { _DPRINTK_FLAGS_PRINT, 'p' }, { _DPRINTK_FLAGS_INCL_MODNAME, 'm' }, { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' }, { _DPRINTK_FLAGS_INCL_LINENO, 'l' }, { _DPRINTK_FLAGS_INCL_TID, 't' }, - { _DPRINTK_FLAGS_NONE, '_' }, }; /* format a string into buf[] which describes the _ddebug's flags */ @@ -96,74 +83,58 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, char *p = buf; int i; - BUG_ON(maxlen < 6); + BUG_ON(maxlen < 4); for (i = 0; i < ARRAY_SIZE(opt_array); ++i) if (dp->flags & opt_array[i].flag) *p++ = opt_array[i].opt_char; if (p == buf) - *p++ = '_'; + *p++ = '-'; *p = '\0'; return buf; } -#define vpr_info_dq(q, msg) \ -do { \ - if (verbose) \ - /* trim last char off format print */ \ - pr_info("%s: func=\"%s\" file=\"%s\" " \ - "module=\"%s\" format=\"%.*s\" " \ - "lineno=%u-%u", \ - msg, \ - q->function ? q->function : "", \ - q->filename ? q->filename : "", \ - q->module ? q->module : "", \ - (int)(q->format ? strlen(q->format) - 1 : 0), \ - q->format ? q->format : "", \ - q->first_lineno, q->last_lineno); \ -} while (0) - /* - * Search the tables for _ddebug's which match the given `query' and - * apply the `flags' and `mask' to them. Returns number of matching - * callsites, normally the same as number of changes. If verbose, - * logs the changes. Takes ddebug_lock. + * Search the tables for _ddebug's which match the given + * `query' and apply the `flags' and `mask' to them. Tells + * the user which ddebug's were changed, or whether none + * were matched. */ -static int ddebug_change(const struct ddebug_query *query, - unsigned int flags, unsigned int mask) +static void ddebug_change(const struct ddebug_query *query, + unsigned int flags, unsigned int mask) { int i; struct ddebug_table *dt; unsigned int newflags; unsigned int nfound = 0; - char flagbuf[10]; + char flagbuf[8]; /* search for matching ddebugs */ mutex_lock(&ddebug_lock); list_for_each_entry(dt, &ddebug_tables, link) { /* match against the module name */ - if (query->module && strcmp(query->module, dt->mod_name)) + if (query->module != NULL && + strcmp(query->module, dt->mod_name)) continue; for (i = 0 ; i < dt->num_ddebugs ; i++) { struct _ddebug *dp = &dt->ddebugs[i]; /* match against the source filename */ - if (query->filename && + if (query->filename != NULL && strcmp(query->filename, dp->filename) && - strcmp(query->filename, basename(dp->filename)) && - strcmp(query->filename, trim_prefix(dp->filename))) + strcmp(query->filename, basename(dp->filename))) continue; /* match against the function */ - if (query->function && + if (query->function != NULL && strcmp(query->function, dp->function)) continue; /* match against the format */ - if (query->format && - !strstr(dp->format, query->format)) + if (query->format != NULL && + strstr(dp->format, query->format) == NULL) continue; /* match against the line number range */ @@ -180,9 +151,13 @@ static int ddebug_change(const struct ddebug_query *query, if (newflags == dp->flags) continue; dp->flags = newflags; + if (newflags) + dp->enabled = 1; + else + dp->enabled = 0; if (verbose) - pr_info("changed %s:%d [%s]%s =%s\n", - trim_prefix(dp->filename), dp->lineno, + pr_info("changed %s:%d [%s]%s %s\n", + dp->filename, dp->lineno, dt->mod_name, dp->function, ddebug_describe_flags(dp, flagbuf, sizeof(flagbuf))); @@ -192,8 +167,6 @@ static int ddebug_change(const struct ddebug_query *query, if (!nfound && verbose) pr_info("no matches for query\n"); - - return nfound; } /* @@ -213,10 +186,8 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) buf = skip_spaces(buf); if (!*buf) break; /* oh, it was trailing whitespace */ - if (*buf == '#') - break; /* token starts comment, skip rest of line */ - /* find `end' of word, whitespace separated or quoted */ + /* Run `end' over a word, either whitespace separated or quoted */ if (*buf == '"' || *buf == '\'') { int quote = *buf++; for (end = buf ; *end && *end != quote ; end++) @@ -228,8 +199,8 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) ; BUG_ON(end == buf); } + /* Here `buf' is the start of the word, `end' is one past the end */ - /* `buf' is start of word, `end' is one past its end */ if (nwords == maxwords) return -EINVAL; /* ran out of words[] before bytes */ if (*end) @@ -308,19 +279,6 @@ static char *unescape(char *str) return str; } -static int check_set(const char **dest, char *src, char *name) -{ - int rc = 0; - - if (*dest) { - rc = -EINVAL; - pr_err("match-spec:%s val:%s overridden by %s", - name, *dest, src); - } - *dest = src; - return rc; -} - /* * Parse words[] as a ddebug query specification, which is a series * of (keyword, value) pairs chosen from these possibilities: @@ -332,15 +290,11 @@ static int check_set(const char **dest, char *src, char *name) * format * line * line - // where either may be empty - * - * Only 1 of each type is allowed. - * Returns 0 on success, <0 on error. */ static int ddebug_parse_query(char *words[], int nwords, struct ddebug_query *query) { unsigned int i; - int rc; /* check we have an even number of words */ if (nwords % 2 != 0) @@ -349,43 +303,41 @@ static int ddebug_parse_query(char *words[], int nwords, for (i = 0 ; i < nwords ; i += 2) { if (!strcmp(words[i], "func")) - rc = check_set(&query->function, words[i+1], "func"); + query->function = words[i+1]; else if (!strcmp(words[i], "file")) - rc = check_set(&query->filename, words[i+1], "file"); + query->filename = words[i+1]; else if (!strcmp(words[i], "module")) - rc = check_set(&query->module, words[i+1], "module"); + query->module = words[i+1]; else if (!strcmp(words[i], "format")) - rc = check_set(&query->format, unescape(words[i+1]), - "format"); + query->format = unescape(words[i+1]); else if (!strcmp(words[i], "line")) { char *first = words[i+1]; char *last = strchr(first, '-'); - if (query->first_lineno || query->last_lineno) { - pr_err("match-spec:line given 2 times\n"); - return -EINVAL; - } if (last) *last++ = '\0'; if (parse_lineno(first, &query->first_lineno) < 0) return -EINVAL; - if (last) { + if (last != NULL) { /* range - */ - if (parse_lineno(last, &query->last_lineno) - < query->first_lineno) { - pr_err("last-line < 1st-line\n"); + if (parse_lineno(last, &query->last_lineno) < 0) return -EINVAL; - } } else { query->last_lineno = query->first_lineno; } } else { - pr_err("unknown keyword \"%s\"\n", words[i]); + if (verbose) + pr_err("unknown keyword \"%s\"\n", words[i]); return -EINVAL; } - if (rc) - return rc; } - vpr_info_dq(query, "parsed"); + + if (verbose) + pr_info("q->function=\"%s\" q->filename=\"%s\" " + "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n", + query->function, query->filename, + query->module, query->format, query->first_lineno, + query->last_lineno); + return 0; } @@ -423,6 +375,8 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, if (i < 0) return -EINVAL; } + if (flags == 0) + return -EINVAL; if (verbose) pr_info("flags=0x%x\n", flags); @@ -451,7 +405,7 @@ static int ddebug_exec_query(char *query_string) unsigned int flags = 0, mask = 0; struct ddebug_query query; #define MAXWORDS 9 - int nwords, nfound; + int nwords; char *words[MAXWORDS]; nwords = ddebug_tokenize(query_string, words, MAXWORDS); @@ -463,47 +417,8 @@ static int ddebug_exec_query(char *query_string) return -EINVAL; /* actually go and implement the change */ - nfound = ddebug_change(&query, flags, mask); - vpr_info_dq((&query), (nfound) ? "applied" : "no-match"); - - return nfound; -} - -/* handle multiple queries in query string, continue on error, return - last error or number of matching callsites. Module name is either - in param (for boot arg) or perhaps in query string. -*/ -static int ddebug_exec_queries(char *query) -{ - char *split; - int i, errs = 0, exitcode = 0, rc, nfound = 0; - - for (i = 0; query; query = split) { - split = strpbrk(query, ";\n"); - if (split) - *split++ = '\0'; - - query = skip_spaces(query); - if (!query || !*query || *query == '#') - continue; - - if (verbose) - pr_info("query %d: \"%s\"\n", i, query); - - rc = ddebug_exec_query(query); - if (rc < 0) { - errs++; - exitcode = rc; - } else - nfound += rc; - i++; - } - pr_info("processed %d queries, with %d matches, %d errs\n", - i, nfound, errs); - - if (exitcode) - return exitcode; - return nfound; + ddebug_change(&query, flags, mask); + return 0; } #define PREFIX_SIZE 64 @@ -537,8 +452,7 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf) pos += snprintf(buf + pos, remaining(pos), "%s:", desc->function); if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO) - pos += snprintf(buf + pos, remaining(pos), "%d:", - desc->lineno); + pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno); if (pos - pos_after_tid) pos += snprintf(buf + pos, remaining(pos), " "); if (pos >= PREFIX_SIZE) @@ -613,16 +527,14 @@ EXPORT_SYMBOL(__dynamic_netdev_dbg); #endif -#define DDEBUG_STRING_SIZE 1024 -static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE]; - +static __initdata char ddebug_setup_string[1024]; static __init int ddebug_setup_query(char *str) { - if (strlen(str) >= DDEBUG_STRING_SIZE) { + if (strlen(str) >= 1024) { pr_warn("ddebug boot param string too large\n"); return 0; } - strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE); + strcpy(ddebug_setup_string, str); return 1; } @@ -632,33 +544,25 @@ __setup("ddebug_query=", ddebug_setup_query); * File_ops->write method for /dynamic_debug/conrol. Gathers the * command text from userspace, parses and executes it. */ -#define USER_BUF_PAGE 4096 static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) { - char *tmpbuf; + char tmpbuf[256]; int ret; if (len == 0) return 0; - if (len > USER_BUF_PAGE - 1) { - pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE); + /* we don't check *offp -- multiple writes() are allowed */ + if (len > sizeof(tmpbuf)-1) return -E2BIG; - } - tmpbuf = kmalloc(len + 1, GFP_KERNEL); - if (!tmpbuf) - return -ENOMEM; - if (copy_from_user(tmpbuf, ubuf, len)) { - kfree(tmpbuf); + if (copy_from_user(tmpbuf, ubuf, len)) return -EFAULT; - } tmpbuf[len] = '\0'; if (verbose) pr_info("read %d bytes from userspace\n", (int)len); - ret = ddebug_exec_queries(tmpbuf); - kfree(tmpbuf); - if (ret < 0) + ret = ddebug_exec_query(tmpbuf); + if (ret) return ret; *offp += len; @@ -764,7 +668,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) { struct ddebug_iter *iter = m->private; struct _ddebug *dp = p; - char flagsbuf[10]; + char flagsbuf[8]; if (verbose) pr_info("called m=%p p=%p\n", m, p); @@ -775,10 +679,10 @@ static int ddebug_proc_show(struct seq_file *m, void *p) return 0; } - seq_printf(m, "%s:%u [%s]%s =%s \"", - trim_prefix(dp->filename), dp->lineno, - iter->table->mod_name, dp->function, - ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); + seq_printf(m, "%s:%u [%s]%s %s \"", + dp->filename, dp->lineno, + iter->table->mod_name, dp->function, + ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); seq_escape(m, dp->format, "\t\r\n\""); seq_puts(m, "\"\n"); @@ -804,11 +708,10 @@ static const struct seq_operations ddebug_proc_seqops = { }; /* - * File_ops->open method for /dynamic_debug/control. Does - * the seq_file setup dance, and also creates an iterator to walk the - * _ddebugs. Note that we create a seq_file always, even for O_WRONLY - * files where it's not needed, as doing so simplifies the ->release - * method. + * File_ops->open method for /dynamic_debug/control. Does the seq_file + * setup dance, and also creates an iterator to walk the _ddebugs. + * Note that we create a seq_file always, even for O_WRONLY files + * where it's not needed, as doing so simplifies the ->release method. */ static int ddebug_proc_open(struct inode *inode, struct file *file) { @@ -943,40 +846,33 @@ static int __init dynamic_debug_init(void) int ret = 0; int n = 0; - if (__start___verbose == __stop___verbose) { - pr_warn("_ddebug table is empty in a " - "CONFIG_DYNAMIC_DEBUG build"); - return 1; - } - iter = __start___verbose; - modname = iter->modname; - iter_start = iter; - for (; iter < __stop___verbose; iter++) { - if (strcmp(modname, iter->modname)) { - ret = ddebug_add_module(iter_start, n, modname); - if (ret) - goto out_free; - n = 0; - modname = iter->modname; - iter_start = iter; + if (__start___verbose != __stop___verbose) { + iter = __start___verbose; + modname = iter->modname; + iter_start = iter; + for (; iter < __stop___verbose; iter++) { + if (strcmp(modname, iter->modname)) { + ret = ddebug_add_module(iter_start, n, modname); + if (ret) + goto out_free; + n = 0; + modname = iter->modname; + iter_start = iter; + } + n++; } - n++; + ret = ddebug_add_module(iter_start, n, modname); } - ret = ddebug_add_module(iter_start, n, modname); - if (ret) - goto out_free; /* ddebug_query boot param got passed -> set it up */ if (ddebug_setup_string[0] != '\0') { - ret = ddebug_exec_queries(ddebug_setup_string); - if (ret < 0) + ret = ddebug_exec_query(ddebug_setup_string); + if (ret) pr_warn("Invalid ddebug boot param %s", ddebug_setup_string); else - pr_info("%d changes by ddebug_query\n", ret); - - /* keep tables even on ddebug_query parse error */ - ret = 0; + pr_info("ddebug initialized with string %s", + ddebug_setup_string); } out_free: diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index a468af059834..e8c969577768 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -1003,30 +1003,6 @@ static int do_amba_entry(const char *filename, } ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry); -/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* - * All fields are numbers. It would be nicer to use strings for vendor - * and feature, but getting those out of the build system here is too - * complicated. - */ - -static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id, - char *alias) -{ - id->feature = TO_NATIVE(id->feature); - id->family = TO_NATIVE(id->family); - id->model = TO_NATIVE(id->model); - id->vendor = TO_NATIVE(id->vendor); - - strcpy(alias, "x86cpu:"); - ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor); - ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family); - ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model); - ADD(alias, ":feature:*,", id->feature != X86_FEATURE_ANY, id->feature); - strcat(alias, ",*"); - return 1; -} -ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id, do_x86cpu_entry); - /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) { diff --git a/trunk/tools/hv/hv_kvp_daemon.c b/trunk/tools/hv/hv_kvp_daemon.c index 4ebf70380582..11224eddcdc2 100644 --- a/trunk/tools/hv/hv_kvp_daemon.c +++ b/trunk/tools/hv/hv_kvp_daemon.c @@ -34,12 +34,21 @@ #include #include #include -#include #include #include #include #include +/* + * KYS: TODO. Need to register these in the kernel. + * + * The following definitions are shared with the in-kernel component; do not + * change any of this without making the corresponding changes in + * the KVP kernel component. + */ +#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */ +#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ +#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ /* * KVP protocol: The user mode component first registers with the @@ -51,8 +60,25 @@ * We use this infrastructure for also supporting queries from user mode * application for state that may be maintained in the KVP kernel component. * + * XXXKYS: Have a shared header file between the user and kernel (TODO) */ +enum kvp_op { + KVP_REGISTER = 0, /* Register the user mode component*/ + KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/ + KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/ + KVP_USER_GET, /*User is requesting the value for the specified key*/ + KVP_USER_SET /*User is providing the value for the specified key*/ +}; + +#define HV_KVP_EXCHANGE_MAX_KEY_SIZE 512 +#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE 2048 + +struct hv_ku_msg { + __u32 kvp_index; + __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ + __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ +}; enum key_index { FullyQualifiedDomainName = 0, @@ -67,6 +93,10 @@ enum key_index { ProcessorArchitecture }; +/* + * End of shared definitions. + */ + static char kvp_send_buffer[4096]; static char kvp_recv_buffer[4096]; static struct sockaddr_nl addr; @@ -302,7 +332,7 @@ int main(void) struct pollfd pfd; struct nlmsghdr *incoming_msg; struct cn_msg *incoming_cn_msg; - struct hv_kvp_msg *hv_msg; + struct hv_ku_msg *hv_msg; char *p; char *key_value; char *key_name; @@ -340,11 +370,9 @@ int main(void) message = (struct cn_msg *)kvp_send_buffer; message->id.idx = CN_KVP_IDX; message->id.val = CN_KVP_VAL; - - hv_msg = (struct hv_kvp_msg *)message->data; - hv_msg->kvp_hdr.operation = KVP_OP_REGISTER; + message->seq = KVP_REGISTER; message->ack = 0; - message->len = sizeof(struct hv_kvp_msg); + message->len = 0; len = netlink_send(fd, message); if (len < 0) { @@ -370,15 +398,14 @@ int main(void) incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); - hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; - switch (hv_msg->kvp_hdr.operation) { - case KVP_OP_REGISTER: + switch (incoming_cn_msg->seq) { + case KVP_REGISTER: /* * Driver is registering with us; stash away the version * information. */ - p = (char *)hv_msg->body.kvp_version; + p = (char *)incoming_cn_msg->data; lic_version = malloc(strlen(p) + 1); if (lic_version) { strcpy(lic_version, p); @@ -389,15 +416,17 @@ int main(void) } continue; - default: + case KVP_KERNEL_GET: break; + default: + continue; } - hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; - key_name = (char *)hv_msg->body.kvp_enum_data.data.key; - key_value = (char *)hv_msg->body.kvp_enum_data.data.value; + hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data; + key_name = (char *)hv_msg->kvp_key; + key_value = (char *)hv_msg->kvp_value; - switch (hv_msg->body.kvp_enum_data.index) { + switch (hv_msg->kvp_index) { case FullyQualifiedDomainName: kvp_get_domain_name(key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE); @@ -457,8 +486,9 @@ int main(void) incoming_cn_msg->id.idx = CN_KVP_IDX; incoming_cn_msg->id.val = CN_KVP_VAL; + incoming_cn_msg->seq = KVP_USER_SET; incoming_cn_msg->ack = 0; - incoming_cn_msg->len = sizeof(struct hv_kvp_msg); + incoming_cn_msg->len = sizeof(struct hv_ku_msg); len = netlink_send(fd, incoming_cn_msg); if (len < 0) {