diff options
118 files changed, 1890 insertions, 484 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-bdi b/Documentation/ABI/testing/sysfs-class-bdi index 5ac1e01bbd48..5f500977b42f 100644 --- a/Documentation/ABI/testing/sysfs-class-bdi +++ b/Documentation/ABI/testing/sysfs-class-bdi | |||
| @@ -14,6 +14,10 @@ MAJOR:MINOR | |||
| 14 | non-block filesystems which provide their own BDI, such as NFS | 14 | non-block filesystems which provide their own BDI, such as NFS |
| 15 | and FUSE. | 15 | and FUSE. |
| 16 | 16 | ||
| 17 | MAJOR:MINOR-fuseblk | ||
| 18 | |||
| 19 | Value of st_dev on fuseblk filesystems. | ||
| 20 | |||
| 17 | default | 21 | default |
| 18 | 22 | ||
| 19 | The default backing dev, used for non-block device backed | 23 | The default backing dev, used for non-block device backed |
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index 77c42f40be5d..2510763295d0 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl | |||
| @@ -703,6 +703,31 @@ | |||
| 703 | </sect1> | 703 | </sect1> |
| 704 | </chapter> | 704 | </chapter> |
| 705 | 705 | ||
| 706 | <chapter id="trylock-functions"> | ||
| 707 | <title>The trylock Functions</title> | ||
| 708 | <para> | ||
| 709 | There are functions that try to acquire a lock only once and immediately | ||
| 710 | return a value telling about success or failure to acquire the lock. | ||
| 711 | They can be used if you need no access to the data protected with the lock | ||
| 712 | when some other thread is holding the lock. You should acquire the lock | ||
| 713 | later if you then need access to the data protected with the lock. | ||
| 714 | </para> | ||
| 715 | |||
| 716 | <para> | ||
| 717 | <function>spin_trylock()</function> does not spin but returns non-zero if | ||
| 718 | it acquires the spinlock on the first try or 0 if not. This function can | ||
| 719 | be used in all contexts like <function>spin_lock</function>: you must have | ||
| 720 | disabled the contexts that might interrupt you and acquire the spin lock. | ||
| 721 | </para> | ||
| 722 | |||
| 723 | <para> | ||
| 724 | <function>mutex_trylock()</function> does not suspend your task | ||
| 725 | but returns non-zero if it could lock the mutex on the first try | ||
| 726 | or 0 if not. This function cannot be safely used in hardware or software | ||
| 727 | interrupt contexts despite not sleeping. | ||
| 728 | </para> | ||
| 729 | </chapter> | ||
| 730 | |||
| 706 | <chapter id="Examples"> | 731 | <chapter id="Examples"> |
| 707 | <title>Common Examples</title> | 732 | <title>Common Examples</title> |
| 708 | <para> | 733 | <para> |
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index 6a9c55bd556b..dcec0564d040 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt | |||
| @@ -129,14 +129,6 @@ to its default value of '80' it means that between the checking | |||
| 129 | intervals the CPU needs to be on average more than 80% in use to then | 129 | intervals the CPU needs to be on average more than 80% in use to then |
| 130 | decide that the CPU frequency needs to be increased. | 130 | decide that the CPU frequency needs to be increased. |
| 131 | 131 | ||
| 132 | sampling_down_factor: this parameter controls the rate that the CPU | ||
| 133 | makes a decision on when to decrease the frequency. When set to its | ||
| 134 | default value of '5' it means that at 1/5 the sampling_rate the kernel | ||
| 135 | makes a decision to lower the frequency. Five "lower rate" decisions | ||
| 136 | have to be made in a row before the CPU frequency is actually lower. | ||
| 137 | If set to '1' then the frequency decreases as quickly as it increases, | ||
| 138 | if set to '2' it decreases at half the rate of the increase. | ||
| 139 | |||
| 140 | ignore_nice_load: this parameter takes a value of '0' or '1'. When | 132 | ignore_nice_load: this parameter takes a value of '0' or '1'. When |
| 141 | set to '0' (its default), all processes are counted towards the | 133 | set to '0' (its default), all processes are counted towards the |
| 142 | 'cpu utilisation' value. When set to '1', the processes that are | 134 | 'cpu utilisation' value. When set to '1', the processes that are |
diff --git a/Documentation/hwmon/ibmaem b/Documentation/hwmon/ibmaem new file mode 100644 index 000000000000..2fefaf582a43 --- /dev/null +++ b/Documentation/hwmon/ibmaem | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | Kernel driver ibmaem | ||
| 2 | ====================== | ||
| 3 | |||
| 4 | Supported systems: | ||
| 5 | * Any recent IBM System X server with Active Energy Manager support. | ||
| 6 | This includes the x3350, x3550, x3650, x3655, x3755, x3850 M2, | ||
| 7 | x3950 M2, and certain HS2x/LS2x/QS2x blades. The IPMI host interface | ||
| 8 | driver ("ipmi-si") needs to be loaded for this driver to do anything. | ||
| 9 | Prefix: 'ibmaem' | ||
| 10 | Datasheet: Not available | ||
| 11 | |||
| 12 | Author: Darrick J. Wong | ||
| 13 | |||
| 14 | Description | ||
| 15 | ----------- | ||
| 16 | |||
| 17 | This driver implements sensor reading support for the energy and power | ||
| 18 | meters available on various IBM System X hardware through the BMC. All | ||
| 19 | sensor banks will be exported as platform devices; this driver can talk | ||
| 20 | to both v1 and v2 interfaces. This driver is completely separate from the | ||
| 21 | older ibmpex driver. | ||
| 22 | |||
| 23 | The v1 AEM interface has a simple set of features to monitor energy use. | ||
| 24 | There is a register that displays an estimate of raw energy consumption | ||
| 25 | since the last BMC reset, and a power sensor that returns average power | ||
| 26 | use over a configurable interval. | ||
| 27 | |||
| 28 | The v2 AEM interface is a bit more sophisticated, being able to present | ||
| 29 | a wider range of energy and power use registers, the power cap as | ||
| 30 | set by the AEM software, and temperature sensors. | ||
| 31 | |||
| 32 | Special Features | ||
| 33 | ---------------- | ||
| 34 | |||
| 35 | The "power_cap" value displays the current system power cap, as set by | ||
| 36 | the Active Energy Manager software. Setting the power cap from the host | ||
| 37 | is not currently supported. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index b42dcfcbee44..0a6d2ca03cea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1240,6 +1240,20 @@ L: video4linux-list@redhat.com | |||
| 1240 | W: http://linuxtv.org | 1240 | W: http://linuxtv.org |
| 1241 | S: Maintained | 1241 | S: Maintained |
| 1242 | 1242 | ||
| 1243 | CXGB3 ETHERNET DRIVER (CXGB3) | ||
| 1244 | P: Divy Le Ray | ||
| 1245 | M: divy@chelsio.com | ||
| 1246 | L: netdev@vger.kernel.org | ||
| 1247 | W: http://www.chelsio.com | ||
| 1248 | S: Supported | ||
| 1249 | |||
| 1250 | CXGB3 IWARP RNIC DRIVER (IW_CXGB3) | ||
| 1251 | P: Steve Wise | ||
| 1252 | M: swise@chelsio.com | ||
| 1253 | L: general@lists.openfabrics.org | ||
| 1254 | W: http://www.openfabrics.org | ||
| 1255 | S: Supported | ||
| 1256 | |||
| 1243 | CYBERPRO FB DRIVER | 1257 | CYBERPRO FB DRIVER |
| 1244 | P: Russell King | 1258 | P: Russell King |
| 1245 | M: rmk@arm.linux.org.uk | 1259 | M: rmk@arm.linux.org.uk |
| @@ -4361,6 +4375,14 @@ M: gregkh@suse.de | |||
| 4361 | L: linux-kernel@vger.kernel.org | 4375 | L: linux-kernel@vger.kernel.org |
| 4362 | S: Maintained | 4376 | S: Maintained |
| 4363 | 4377 | ||
| 4378 | UTIL-LINUX-NG PACKAGE | ||
| 4379 | P: Karel Zak | ||
| 4380 | M: kzak@redhat.com | ||
| 4381 | L: util-linux-ng@vger.kernel.org | ||
| 4382 | W: http://kernel.org/~kzak/util-linux-ng/ | ||
| 4383 | T: git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git | ||
| 4384 | S: Maintained | ||
| 4385 | |||
| 4364 | VFAT/FAT/MSDOS FILESYSTEM: | 4386 | VFAT/FAT/MSDOS FILESYSTEM: |
| 4365 | P: OGAWA Hirofumi | 4387 | P: OGAWA Hirofumi |
| 4366 | M: hirofumi@mail.parknet.co.jp | 4388 | M: hirofumi@mail.parknet.co.jp |
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c index 1de121fc55f4..f44647738ee4 100644 --- a/arch/arm/mach-at91/at91x40.c +++ b/arch/arm/mach-at91/at91x40.c | |||
| @@ -16,16 +16,32 @@ | |||
| 16 | #include <asm/mach/arch.h> | 16 | #include <asm/mach/arch.h> |
| 17 | #include <asm/arch/at91x40.h> | 17 | #include <asm/arch/at91x40.h> |
| 18 | #include <asm/arch/at91_st.h> | 18 | #include <asm/arch/at91_st.h> |
| 19 | #include <asm/arch/timex.h> | ||
| 19 | #include "generic.h" | 20 | #include "generic.h" |
| 20 | 21 | ||
| 21 | /* | 22 | /* |
| 22 | * This is used in the gpio code, stub locally. | 23 | * Export the clock functions for the AT91X40. Some external code common |
| 24 | * to all AT91 family parts relys on this, like the gpio and serial support. | ||
| 23 | */ | 25 | */ |
| 24 | int clk_enable(struct clk *clk) | 26 | int clk_enable(struct clk *clk) |
| 25 | { | 27 | { |
| 26 | return 0; | 28 | return 0; |
| 27 | } | 29 | } |
| 28 | 30 | ||
| 31 | void clk_disable(struct clk *clk) | ||
| 32 | { | ||
| 33 | } | ||
| 34 | |||
| 35 | unsigned long clk_get_rate(struct clk *clk) | ||
| 36 | { | ||
| 37 | return AT91X40_MASTER_CLOCK; | ||
| 38 | } | ||
| 39 | |||
| 40 | struct clk *clk_get(struct device *dev, const char *id) | ||
| 41 | { | ||
| 42 | return NULL; | ||
| 43 | } | ||
| 44 | |||
| 29 | void __init at91x40_initialize(unsigned long main_clock) | 45 | void __init at91x40_initialize(unsigned long main_clock) |
| 30 | { | 46 | { |
| 31 | at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) | 47 | at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) |
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 92d79fb39311..62e653a3ea1a 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c | |||
| @@ -369,7 +369,8 @@ static int impd1_probe(struct lm_device *dev) | |||
| 369 | 369 | ||
| 370 | lm_set_drvdata(dev, impd1); | 370 | lm_set_drvdata(dev, impd1); |
| 371 | 371 | ||
| 372 | printk("IM-PD1 found at 0x%08lx\n", dev->resource.start); | 372 | printk("IM-PD1 found at 0x%08lx\n", |
| 373 | (unsigned long)dev->resource.start); | ||
| 373 | 374 | ||
| 374 | for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { | 375 | for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { |
| 375 | impd1->vcos[i].owner = THIS_MODULE, | 376 | impd1->vcos[i].owner = THIS_MODULE, |
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index d55fa4e9bb43..c07f497000ca 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c | |||
| @@ -405,7 +405,6 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
| 405 | addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, | 405 | addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, |
| 406 | v3_readb(V3_LB_ISTAT)); | 406 | v3_readb(V3_LB_ISTAT)); |
| 407 | printk(KERN_DEBUG "%s", buf); | 407 | printk(KERN_DEBUG "%s", buf); |
| 408 | printascii(buf); | ||
| 409 | #endif | 408 | #endif |
| 410 | 409 | ||
| 411 | v3_writeb(V3_LB_ISTAT, 0); | 410 | v3_writeb(V3_LB_ISTAT, 0); |
| @@ -447,6 +446,7 @@ static irqreturn_t v3_irq(int dummy, void *devid) | |||
| 447 | unsigned long pc = instruction_pointer(regs); | 446 | unsigned long pc = instruction_pointer(regs); |
| 448 | unsigned long instr = *(unsigned long *)pc; | 447 | unsigned long instr = *(unsigned long *)pc; |
| 449 | char buf[128]; | 448 | char buf[128]; |
| 449 | extern void printascii(const char *); | ||
| 450 | 450 | ||
| 451 | sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " | 451 | sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " |
| 452 | "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, | 452 | "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, |
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index a0b16a7e8a04..a4d20127a60e 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
| 25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
| 26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
| 27 | #include <linux/spi/tsc2102.h> | ||
| 28 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| 29 | #include <linux/apm-emulation.h> | 28 | #include <linux/apm-emulation.h> |
| 30 | 29 | ||
| @@ -315,14 +314,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery) | |||
| 315 | #define palmte_get_power_status NULL | 314 | #define palmte_get_power_status NULL |
| 316 | #endif | 315 | #endif |
| 317 | 316 | ||
| 318 | static struct tsc2102_config palmte_tsc2102_config = { | ||
| 319 | .use_internal = 0, | ||
| 320 | .monitor = TSC_BAT1 | TSC_AUX | TSC_TEMP, | ||
| 321 | .temp_at25c = { 2200, 2615 }, | ||
| 322 | .apm_report = palmte_get_power_status, | ||
| 323 | .alsa_config = &palmte_alsa_config, | ||
| 324 | }; | ||
| 325 | |||
| 326 | static struct omap_board_config_kernel palmte_config[] __initdata = { | 317 | static struct omap_board_config_kernel palmte_config[] __initdata = { |
| 327 | { OMAP_TAG_USB, &palmte_usb_config }, | 318 | { OMAP_TAG_USB, &palmte_usb_config }, |
| 328 | { OMAP_TAG_MMC, &palmte_mmc_config }, | 319 | { OMAP_TAG_MMC, &palmte_mmc_config }, |
| @@ -336,7 +327,6 @@ static struct spi_board_info palmte_spi_info[] __initdata = { | |||
| 336 | .bus_num = 2, /* uWire (officially) */ | 327 | .bus_num = 2, /* uWire (officially) */ |
| 337 | .chip_select = 0, /* As opposed to 3 */ | 328 | .chip_select = 0, /* As opposed to 3 */ |
| 338 | .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO), | 329 | .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO), |
| 339 | .platform_data = &palmte_tsc2102_config, | ||
| 340 | .max_speed_hz = 8000000, | 330 | .max_speed_hz = 8000000, |
| 341 | }, | 331 | }, |
| 342 | }; | 332 | }; |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index dace3820f1ee..e7d0fcd9b43f 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <asm/arch/pxa-regs.h> | 38 | #include <asm/arch/pxa-regs.h> |
| 39 | #include <asm/arch/pxa2xx-regs.h> | 39 | #include <asm/arch/pxa2xx-regs.h> |
| 40 | #include <asm/arch/pxa2xx-gpio.h> | 40 | #include <asm/arch/pxa2xx-gpio.h> |
| 41 | #include <asm/arch/pxa27x-udc.h> | ||
| 42 | #include <asm/arch/irda.h> | 41 | #include <asm/arch/irda.h> |
| 43 | #include <asm/arch/mmc.h> | 42 | #include <asm/arch/mmc.h> |
| 44 | #include <asm/arch/ohci.h> | 43 | #include <asm/arch/ohci.h> |
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 661a2358ac22..27f63d5d3a7b 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
| @@ -374,7 +374,7 @@ static struct resource bast_dm9k_resource[] = { | |||
| 374 | [2] = { | 374 | [2] = { |
| 375 | .start = IRQ_DM9000, | 375 | .start = IRQ_DM9000, |
| 376 | .end = IRQ_DM9000, | 376 | .end = IRQ_DM9000, |
| 377 | .flags = IORESOURCE_IRQ, | 377 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, |
| 378 | } | 378 | } |
| 379 | 379 | ||
| 380 | }; | 380 | }; |
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index c56423373ff3..4c4b5c4207c4 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c | |||
| @@ -263,7 +263,7 @@ static struct resource vr1000_dm9k0_resource[] = { | |||
| 263 | [2] = { | 263 | [2] = { |
| 264 | .start = IRQ_VR1000_DM9000A, | 264 | .start = IRQ_VR1000_DM9000A, |
| 265 | .end = IRQ_VR1000_DM9000A, | 265 | .end = IRQ_VR1000_DM9000A, |
| 266 | .flags = IORESOURCE_IRQ | 266 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | }; | 269 | }; |
| @@ -282,7 +282,7 @@ static struct resource vr1000_dm9k1_resource[] = { | |||
| 282 | [2] = { | 282 | [2] = { |
| 283 | .start = IRQ_VR1000_DM9000N, | 283 | .start = IRQ_VR1000_DM9000N, |
| 284 | .end = IRQ_VR1000_DM9000N, | 284 | .end = IRQ_VR1000_DM9000N, |
| 285 | .flags = IORESOURCE_IRQ | 285 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, |
| 286 | } | 286 | } |
| 287 | }; | 287 | }; |
| 288 | 288 | ||
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 6496eb645cee..2f772a3965c4 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
| @@ -225,26 +225,28 @@ static void __init collie_init(void) | |||
| 225 | int ret = 0; | 225 | int ret = 0; |
| 226 | 226 | ||
| 227 | /* cpu initialize */ | 227 | /* cpu initialize */ |
| 228 | GAFR = ( GPIO_SSP_TXD | \ | 228 | GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK | |
| 229 | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK | GPIO_TIC_ACK | \ | 229 | GPIO_MCP_CLK | GPIO_32_768kHz; |
| 230 | GPIO_32_768kHz ); | 230 | |
| 231 | 231 | GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | | |
| 232 | GPDR = ( GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | \ | 232 | GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | |
| 233 | GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | \ | 233 | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | |
| 234 | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | \ | 234 | COLLIE_GPIO_UCB1x00_RESET | COLLIE_GPIO_nMIC_ON | |
| 235 | GPIO_SDLC_AAF | GPIO_UART_SCLK1 | GPIO_32_768kHz ); | 235 | COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz; |
| 236 | GPLR = GPIO_GPIO18; | 236 | |
| 237 | 237 | PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | | |
| 238 | // PPC pin setting | 238 | PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | |
| 239 | PPDR = ( PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | \ | 239 | PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM; |
| 240 | PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | \ | 240 | |
| 241 | PPC_TXD1 | PPC_TXD2 | PPC_RXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM ); | 241 | PWER = COLLIE_GPIO_AC_IN | COLLIE_GPIO_CO | COLLIE_GPIO_ON_KEY | |
| 242 | 242 | COLLIE_GPIO_WAKEUP | COLLIE_GPIO_nREMOCON_INT | PWER_RTC; | |
| 243 | PSDR = ( PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4 ); | 243 | |
| 244 | 244 | PGSR = COLLIE_GPIO_nREMOCON_ON; | |
| 245 | GAFR |= GPIO_32_768kHz; | 245 | |
| 246 | GPDR |= GPIO_32_768kHz; | 246 | PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4; |
| 247 | TUCR = TUCR_32_768kHz; | 247 | |
| 248 | PCFR = PCFR_OPDE; | ||
| 249 | |||
| 248 | 250 | ||
| 249 | platform_scoop_config = &collie_pcmcia_config; | 251 | platform_scoop_config = &collie_pcmcia_config; |
| 250 | 252 | ||
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 2946c193a7d6..2db5580048d8 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/cpufreq.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| 26 | 27 | ||
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c index f197bb3a2366..2f01af5f64c4 100644 --- a/arch/arm/plat-s3c24xx/s3c244x.c +++ b/arch/arm/plat-s3c24xx/s3c244x.c | |||
| @@ -65,6 +65,7 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size) | |||
| 65 | 65 | ||
| 66 | /* rename any peripherals used differing from the s3c2410 */ | 66 | /* rename any peripherals used differing from the s3c2410 */ |
| 67 | 67 | ||
| 68 | s3c_device_sdi.name = "s3c2440-sdi"; | ||
| 68 | s3c_device_i2c.name = "s3c2440-i2c"; | 69 | s3c_device_i2c.name = "s3c2440-i2c"; |
| 69 | s3c_device_nand.name = "s3c2440-nand"; | 70 | s3c_device_nand.name = "s3c2440-nand"; |
| 70 | s3c_device_usbgadget.name = "s3c2440-usbgadget"; | 71 | s3c_device_usbgadget.name = "s3c2440-usbgadget"; |
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index b841ecfd5d5a..9af7740f32fb 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
| 28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
| 29 | #include <linux/module.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
| 31 | #include <asm/segment.h> | 32 | #include <asm/segment.h> |
| @@ -56,7 +57,9 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | |||
| 56 | */ | 57 | */ |
| 57 | static unsigned long empty_bad_page_table; | 58 | static unsigned long empty_bad_page_table; |
| 58 | static unsigned long empty_bad_page; | 59 | static unsigned long empty_bad_page; |
| 60 | |||
| 59 | unsigned long empty_zero_page; | 61 | unsigned long empty_zero_page; |
| 62 | EXPORT_SYMBOL(empty_zero_page); | ||
| 60 | 63 | ||
| 61 | /*****************************************************************************/ | 64 | /*****************************************************************************/ |
| 62 | /* | 65 | /* |
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 8e24fc1821e8..31729a9387df 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh | |||
| @@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush | |||
| 20 | _end enter_prom memcpy memset reloc_offset __secondary_hold | 20 | _end enter_prom memcpy memset reloc_offset __secondary_hold |
| 21 | __secondary_hold_acknowledge __secondary_hold_spinloop __start | 21 | __secondary_hold_acknowledge __secondary_hold_spinloop __start |
| 22 | strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 | 22 | strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 |
| 23 | reloc_got2" | 23 | reloc_got2 kernstart_addr" |
| 24 | 24 | ||
| 25 | NM="$1" | 25 | NM="$1" |
| 26 | OBJ="$2" | 26 | OBJ="$2" |
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 80d1babb230d..e0ff59f21135 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c | |||
| @@ -402,7 +402,7 @@ void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) | |||
| 402 | return; | 402 | return; |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | map_page(address, phys, flags); | 405 | map_page(address, phys, pgprot_val(flags)); |
| 406 | fixmaps++; | 406 | fixmaps++; |
| 407 | } | 407 | } |
| 408 | 408 | ||
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 5b3fb2b321ab..3a58ffabccd9 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c | |||
| @@ -317,6 +317,9 @@ static int __init ps3_mm_add_memory(void) | |||
| 317 | return result; | 317 | return result; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | lmb_add(start_addr, map.r1.size); | ||
| 321 | lmb_analyze(); | ||
| 322 | |||
| 320 | result = online_pages(start_pfn, nr_pages); | 323 | result = online_pages(start_pfn, nr_pages); |
| 321 | 324 | ||
| 322 | if (result) | 325 | if (result) |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 8619f2a3f1f6..7680001676a6 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -1331,6 +1331,9 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) | |||
| 1331 | unsigned long flags; | 1331 | unsigned long flags; |
| 1332 | u32 reg; | 1332 | u32 reg; |
| 1333 | 1333 | ||
| 1334 | if (!mpic) | ||
| 1335 | return; | ||
| 1336 | |||
| 1334 | spin_lock_irqsave(&mpic_lock, flags); | 1337 | spin_lock_irqsave(&mpic_lock, flags); |
| 1335 | if (is_ipi) { | 1338 | if (is_ipi) { |
| 1336 | reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & | 1339 | reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & |
| @@ -1346,23 +1349,6 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) | |||
| 1346 | spin_unlock_irqrestore(&mpic_lock, flags); | 1349 | spin_unlock_irqrestore(&mpic_lock, flags); |
| 1347 | } | 1350 | } |
| 1348 | 1351 | ||
| 1349 | unsigned int mpic_irq_get_priority(unsigned int irq) | ||
| 1350 | { | ||
| 1351 | unsigned int is_ipi; | ||
| 1352 | struct mpic *mpic = mpic_find(irq, &is_ipi); | ||
| 1353 | unsigned int src = mpic_irq_to_hw(irq); | ||
| 1354 | unsigned long flags; | ||
| 1355 | u32 reg; | ||
| 1356 | |||
| 1357 | spin_lock_irqsave(&mpic_lock, flags); | ||
| 1358 | if (is_ipi) | ||
| 1359 | reg = mpic_ipi_read(src = mpic->ipi_vecs[0]); | ||
| 1360 | else | ||
| 1361 | reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); | ||
| 1362 | spin_unlock_irqrestore(&mpic_lock, flags); | ||
| 1363 | return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | void mpic_setup_this_cpu(void) | 1352 | void mpic_setup_this_cpu(void) |
| 1367 | { | 1353 | { |
| 1368 | #ifdef CONFIG_SMP | 1354 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/boot/printf.c b/arch/x86/boot/printf.c index c1d00c0274c4..50e47cdbdddd 100644 --- a/arch/x86/boot/printf.c +++ b/arch/x86/boot/printf.c | |||
| @@ -56,7 +56,7 @@ static char *number(char *str, long num, int base, int size, int precision, | |||
| 56 | if (type & LEFT) | 56 | if (type & LEFT) |
| 57 | type &= ~ZEROPAD; | 57 | type &= ~ZEROPAD; |
| 58 | if (base < 2 || base > 36) | 58 | if (base < 2 || base > 36) |
| 59 | return 0; | 59 | return NULL; |
| 60 | c = (type & ZEROPAD) ? '0' : ' '; | 60 | c = (type & ZEROPAD) ? '0' : ' '; |
| 61 | sign = 0; | 61 | sign = 0; |
| 62 | if (type & SIGN) { | 62 | if (type & SIGN) { |
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c index af4a867a097c..777a7ff075de 100644 --- a/arch/x86/kernel/cpu/cpufreq/longrun.c +++ b/arch/x86/kernel/cpu/cpufreq/longrun.c | |||
| @@ -245,7 +245,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, | |||
| 245 | if ((ecx > 95) || (ecx == 0) || (eax < ebx)) | 245 | if ((ecx > 95) || (ecx == 0) || (eax < ebx)) |
| 246 | return -EIO; | 246 | return -EIO; |
| 247 | 247 | ||
| 248 | edx = (eax - ebx) / (100 - ecx); | 248 | edx = ((eax - ebx) * 100) / (100 - ecx); |
| 249 | *low_freq = edx * 1000; /* back to kHz */ | 249 | *low_freq = edx * 1000; /* back to kHz */ |
| 250 | 250 | ||
| 251 | dprintk("low frequency is %u kHz\n", *low_freq); | 251 | dprintk("low frequency is %u kHz\n", *low_freq); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 46d4034d9f37..206791eb46e3 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -1127,12 +1127,23 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1127 | * an UP version, and is deprecated by AMD. | 1127 | * an UP version, and is deprecated by AMD. |
| 1128 | */ | 1128 | */ |
| 1129 | if (num_online_cpus() != 1) { | 1129 | if (num_online_cpus() != 1) { |
| 1130 | printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); | 1130 | #ifndef CONFIG_ACPI_PROCESSOR |
| 1131 | printk(KERN_ERR PFX "ACPI Processor support is required " | ||
| 1132 | "for SMP systems but is absent. Please load the " | ||
| 1133 | "ACPI Processor module before starting this " | ||
| 1134 | "driver.\n"); | ||
| 1135 | #else | ||
| 1136 | printk(KERN_ERR PFX "Your BIOS does not provide ACPI " | ||
| 1137 | "_PSS objects in a way that Linux understands. " | ||
| 1138 | "Please report this to the Linux ACPI maintainers" | ||
| 1139 | " and complain to your BIOS vendor.\n"); | ||
| 1140 | #endif | ||
| 1131 | kfree(data); | 1141 | kfree(data); |
| 1132 | return -ENODEV; | 1142 | return -ENODEV; |
| 1133 | } | 1143 | } |
| 1134 | if (pol->cpu != 0) { | 1144 | if (pol->cpu != 0) { |
| 1135 | printk(KERN_ERR PFX "No _PSS objects for CPU other than CPU0\n"); | 1145 | printk(KERN_ERR PFX "No ACPI _PSS objects for CPU other than " |
| 1146 | "CPU0. Complain to your BIOS vendor.\n"); | ||
| 1136 | kfree(data); | 1147 | kfree(data); |
| 1137 | return -ENODEV; | 1148 | return -ENODEV; |
| 1138 | } | 1149 | } |
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index e48a3ea03117..2509809a36cf 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
| @@ -565,7 +565,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
| 565 | 565 | ||
| 566 | acpi_os_release_mutex(method_desc->method. | 566 | acpi_os_release_mutex(method_desc->method. |
| 567 | mutex->mutex.os_mutex); | 567 | mutex->mutex.os_mutex); |
| 568 | method_desc->method.mutex->mutex.thread_id = 0; | 568 | method_desc->method.mutex->mutex.thread_id = NULL; |
| 569 | } | 569 | } |
| 570 | } | 570 | } |
| 571 | 571 | ||
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index c873ab40cd0e..a8bf3d713e28 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c | |||
| @@ -326,7 +326,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) | |||
| 326 | 326 | ||
| 327 | /* Clear mutex info */ | 327 | /* Clear mutex info */ |
| 328 | 328 | ||
| 329 | obj_desc->mutex.thread_id = 0; | 329 | obj_desc->mutex.thread_id = NULL; |
| 330 | return_ACPI_STATUS(status); | 330 | return_ACPI_STATUS(status); |
| 331 | } | 331 | } |
| 332 | 332 | ||
| @@ -463,7 +463,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) | |||
| 463 | /* Mark mutex unowned */ | 463 | /* Mark mutex unowned */ |
| 464 | 464 | ||
| 465 | obj_desc->mutex.owner_thread = NULL; | 465 | obj_desc->mutex.owner_thread = NULL; |
| 466 | obj_desc->mutex.thread_id = 0; | 466 | obj_desc->mutex.thread_id = NULL; |
| 467 | 467 | ||
| 468 | /* Update Thread sync_level (Last mutex is the important one) */ | 468 | /* Update Thread sync_level (Last mutex is the important one) */ |
| 469 | 469 | ||
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index a196ef7f147f..680cdfc00b90 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
| @@ -447,6 +447,7 @@ static struct brd_device *brd_alloc(int i) | |||
| 447 | disk->fops = &brd_fops; | 447 | disk->fops = &brd_fops; |
| 448 | disk->private_data = brd; | 448 | disk->private_data = brd; |
| 449 | disk->queue = brd->brd_queue; | 449 | disk->queue = brd->brd_queue; |
| 450 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; | ||
| 450 | sprintf(disk->disk_name, "ram%d", i); | 451 | sprintf(disk->disk_name, "ram%d", i); |
| 451 | set_capacity(disk, rd_size * 2); | 452 | set_capacity(disk, rd_size * 2); |
| 452 | 453 | ||
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index ebfe038d859e..f1c8feb5510b 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 3 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
| 4 | * Ryan Arnold <ryanarn@us.ibm.com> | 4 | * Ryan Arnold <ryanarn@us.ibm.com> |
| 5 | * Colin Devilbiss <devilbis@us.ibm.com> | 5 | * Colin Devilbiss <devilbis@us.ibm.com> |
| 6 | * Stephen Rothwell <sfr@au1.ibm.com> | 6 | * Stephen Rothwell |
| 7 | * | 7 | * |
| 8 | * (C) Copyright 2000-2004 IBM Corporation | 8 | * (C) Copyright 2000-2004 IBM Corporation |
| 9 | * | 9 | * |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 5245a4a0ba74..9d0dfe6e0d63 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
| 7 | * Ryan Arnold <ryanarn@us.ibm.com> | 7 | * Ryan Arnold <ryanarn@us.ibm.com> |
| 8 | * Colin Devilbiss <devilbis@us.ibm.com> | 8 | * Colin Devilbiss <devilbis@us.ibm.com> |
| 9 | * Stephen Rothwell <sfr@au1.ibm.com> | 9 | * Stephen Rothwell |
| 10 | * | 10 | * |
| 11 | * (C) Copyright 2000-2004 IBM Corporation | 11 | * (C) Copyright 2000-2004 IBM Corporation |
| 12 | * | 12 | * |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 9a32169e88fb..af211a0ef179 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
| @@ -34,8 +34,6 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
| 34 | struct drm_minor *drm_minor = to_drm_minor(dev); | 34 | struct drm_minor *drm_minor = to_drm_minor(dev); |
| 35 | struct drm_device *drm_dev = drm_minor->dev; | 35 | struct drm_device *drm_dev = drm_minor->dev; |
| 36 | 36 | ||
| 37 | printk(KERN_ERR "%s\n", __func__); | ||
| 38 | |||
| 39 | if (drm_dev->driver->suspend) | 37 | if (drm_dev->driver->suspend) |
| 40 | return drm_dev->driver->suspend(drm_dev, state); | 38 | return drm_dev->driver->suspend(drm_dev, state); |
| 41 | 39 | ||
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile index 6bfe2543ddc2..939618f62fe1 100644 --- a/drivers/char/ip2/Makefile +++ b/drivers/char/ip2/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for the Computone IntelliPort Plus Driver | 2 | # Makefile for the Computone IntelliPort Plus Driver |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o | 5 | obj-$(CONFIG_COMPUTONE) += ip2.o |
| 6 | 6 | ||
| 7 | ip2-objs := ip2base.o | 7 | ip2-objs := ip2base.o ip2main.o |
| 8 | 8 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 70957acaa960..c12cf8fc4be0 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
| @@ -346,27 +346,6 @@ have_requested_irq( char irq ) | |||
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | /******************************************************************************/ | 348 | /******************************************************************************/ |
| 349 | /* Function: init_module() */ | ||
| 350 | /* Parameters: None */ | ||
| 351 | /* Returns: Success (0) */ | ||
| 352 | /* */ | ||
| 353 | /* Description: */ | ||
| 354 | /* This is a required entry point for an installable module. It simply calls */ | ||
| 355 | /* the driver initialisation function and returns what it returns. */ | ||
| 356 | /******************************************************************************/ | ||
| 357 | #ifdef MODULE | ||
| 358 | static int __init | ||
| 359 | ip2_init_module(void) | ||
| 360 | { | ||
| 361 | #ifdef IP2DEBUG_INIT | ||
| 362 | printk (KERN_DEBUG "Loading module ...\n" ); | ||
| 363 | #endif | ||
| 364 | return 0; | ||
| 365 | } | ||
| 366 | module_init(ip2_init_module); | ||
| 367 | #endif /* MODULE */ | ||
| 368 | |||
| 369 | /******************************************************************************/ | ||
| 370 | /* Function: cleanup_module() */ | 349 | /* Function: cleanup_module() */ |
| 371 | /* Parameters: None */ | 350 | /* Parameters: None */ |
| 372 | /* Returns: Nothing */ | 351 | /* Returns: Nothing */ |
| @@ -779,8 +758,6 @@ out: | |||
| 779 | return err; | 758 | return err; |
| 780 | } | 759 | } |
| 781 | 760 | ||
| 782 | EXPORT_SYMBOL(ip2_loadmain); | ||
| 783 | |||
| 784 | /******************************************************************************/ | 761 | /******************************************************************************/ |
| 785 | /* Function: ip2_init_board() */ | 762 | /* Function: ip2_init_board() */ |
| 786 | /* Parameters: Index of board in configuration structure */ | 763 | /* Parameters: Index of board in configuration structure */ |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 3d3e1c2b310f..65fb848e1cce 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 7 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
| 8 | * Ryan Arnold <ryanarn@us.ibm.com> | 8 | * Ryan Arnold <ryanarn@us.ibm.com> |
| 9 | * Colin Devilbiss <devilbis@us.ibm.com> | 9 | * Colin Devilbiss <devilbis@us.ibm.com> |
| 10 | * Stephen Rothwell <sfr@au1.ibm.com> | 10 | * Stephen Rothwell |
| 11 | * | 11 | * |
| 12 | * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation | 12 | * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation |
| 13 | * | 13 | * |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 58aad63831f4..c39ddaff5e8f 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
| 7 | * Ryan Arnold <ryanarn@us.ibm.com> | 7 | * Ryan Arnold <ryanarn@us.ibm.com> |
| 8 | * Colin Devilbiss <devilbis@us.ibm.com> | 8 | * Colin Devilbiss <devilbis@us.ibm.com> |
| 9 | * Stephen Rothwell <sfr@au1.ibm.com> | 9 | * Stephen Rothwell |
| 10 | * | 10 | * |
| 11 | * (C) Copyright 2000-2004 IBM Corporation | 11 | * (C) Copyright 2000-2004 IBM Corporation |
| 12 | * | 12 | * |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index ae6cd60d5c14..b64c6bc445e3 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
| @@ -2,6 +2,11 @@ | |||
| 2 | * linux/drivers/cpufreq/freq_table.c | 2 | * linux/drivers/cpufreq/freq_table.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2002 - 2003 Dominik Brodowski | 4 | * Copyright (C) 2002 - 2003 Dominik Brodowski |
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 5 | */ | 10 | */ |
| 6 | 11 | ||
| 7 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 065732ddf40c..d49361bfe670 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | 20 | ||
| 21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
| 22 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
| 23 | #include <asm/mpc85xx.h> | ||
| 24 | #include "edac_module.h" | 23 | #include "edac_module.h" |
| 25 | #include "edac_core.h" | 24 | #include "edac_core.h" |
| 26 | #include "mpc85xx_edac.h" | 25 | #include "mpc85xx_edac.h" |
| @@ -43,8 +42,6 @@ static u32 orig_pci_err_en; | |||
| 43 | static u32 orig_l2_err_disable; | 42 | static u32 orig_l2_err_disable; |
| 44 | static u32 orig_hid1; | 43 | static u32 orig_hid1; |
| 45 | 44 | ||
| 46 | static const char *mpc85xx_ctl_name = "MPC85xx"; | ||
| 47 | |||
| 48 | /************************ MC SYSFS parts ***********************************/ | 45 | /************************ MC SYSFS parts ***********************************/ |
| 49 | 46 | ||
| 50 | static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci, | 47 | static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci, |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7f138c6195ff..beaf6b3a37dc 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -127,7 +127,7 @@ int __init gpiochip_reserve(int start, int ngpio) | |||
| 127 | unsigned long flags; | 127 | unsigned long flags; |
| 128 | int i; | 128 | int i; |
| 129 | 129 | ||
| 130 | if (!gpio_is_valid(start) || !gpio_is_valid(start + ngpio)) | 130 | if (!gpio_is_valid(start) || !gpio_is_valid(start + ngpio - 1)) |
| 131 | return -EINVAL; | 131 | return -EINVAL; |
| 132 | 132 | ||
| 133 | spin_lock_irqsave(&gpio_lock, flags); | 133 | spin_lock_irqsave(&gpio_lock, flags); |
| @@ -170,7 +170,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
| 170 | unsigned id; | 170 | unsigned id; |
| 171 | int base = chip->base; | 171 | int base = chip->base; |
| 172 | 172 | ||
| 173 | if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio)) | 173 | if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1)) |
| 174 | && base >= 0) { | 174 | && base >= 0) { |
| 175 | status = -EINVAL; | 175 | status = -EINVAL; |
| 176 | goto fail; | 176 | goto fail; |
| @@ -207,7 +207,7 @@ fail: | |||
| 207 | /* failures here can mean systems won't boot... */ | 207 | /* failures here can mean systems won't boot... */ |
| 208 | if (status) | 208 | if (status) |
| 209 | pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", | 209 | pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", |
| 210 | chip->base, chip->base + chip->ngpio, | 210 | chip->base, chip->base + chip->ngpio - 1, |
| 211 | chip->label ? : "generic"); | 211 | chip->label ? : "generic"); |
| 212 | return status; | 212 | return status; |
| 213 | } | 213 | } |
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c index 7fb5b9d009d4..7f92fdd5f0e2 100644 --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/mcp23s08.c | |||
| @@ -168,7 +168,7 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
| 168 | { | 168 | { |
| 169 | struct mcp23s08 *mcp; | 169 | struct mcp23s08 *mcp; |
| 170 | char bank; | 170 | char bank; |
| 171 | unsigned t; | 171 | int t; |
| 172 | unsigned mask; | 172 | unsigned mask; |
| 173 | 173 | ||
| 174 | mcp = container_of(chip, struct mcp23s08, chip); | 174 | mcp = container_of(chip, struct mcp23s08, chip); |
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 93f916720b13..7e40e8a55edf 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
| @@ -30,6 +30,7 @@ static const struct i2c_device_id pca953x_id[] = { | |||
| 30 | { "pca9537", 4, }, | 30 | { "pca9537", 4, }, |
| 31 | { "pca9538", 8, }, | 31 | { "pca9538", 8, }, |
| 32 | { "pca9539", 16, }, | 32 | { "pca9539", 16, }, |
| 33 | { "pca9554", 8, }, | ||
| 33 | { "pca9555", 16, }, | 34 | { "pca9555", 16, }, |
| 34 | { "pca9557", 8, }, | 35 | { "pca9557", 8, }, |
| 35 | /* REVISIT several pca955x parts should work here too */ | 36 | /* REVISIT several pca955x parts should work here too */ |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4dc76bc45c9d..00ff53348491 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -330,6 +330,20 @@ config SENSORS_CORETEMP | |||
| 330 | sensor inside your CPU. Supported all are all known variants | 330 | sensor inside your CPU. Supported all are all known variants |
| 331 | of Intel Core family. | 331 | of Intel Core family. |
| 332 | 332 | ||
| 333 | config SENSORS_IBMAEM | ||
| 334 | tristate "IBM Active Energy Manager temperature/power sensors and control" | ||
| 335 | select IPMI_SI | ||
| 336 | depends on IPMI_HANDLER | ||
| 337 | help | ||
| 338 | If you say yes here you get support for the temperature and | ||
| 339 | power sensors and capping hardware in various IBM System X | ||
| 340 | servers that support Active Energy Manager. This includes | ||
| 341 | the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2, | ||
| 342 | and certain HS2x/LS2x/QS2x blades. | ||
| 343 | |||
| 344 | This driver can also be built as a module. If so, the module | ||
| 345 | will be called ibmaem. | ||
| 346 | |||
| 333 | config SENSORS_IBMPEX | 347 | config SENSORS_IBMPEX |
| 334 | tristate "IBM PowerExecutive temperature/power sensors" | 348 | tristate "IBM PowerExecutive temperature/power sensors" |
| 335 | select IPMI_SI | 349 | select IPMI_SI |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 3bdb05a5cbd7..d098677e08de 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -41,6 +41,7 @@ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | |||
| 41 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 41 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
| 42 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 42 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
| 43 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | 43 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o |
| 44 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | ||
| 44 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 45 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
| 45 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 46 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
| 46 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 47 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index bab5fd2e4dfd..88e89653daaf 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
| @@ -515,6 +515,7 @@ static struct dmi_system_id __initdata hdaps_whitelist[] = { | |||
| 515 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), | 515 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), |
| 516 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), | 516 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), |
| 517 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), | 517 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), |
| 518 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"), | ||
| 518 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), | 519 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), |
| 519 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), | 520 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), |
| 520 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), | 521 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), |
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 6ac5c6f53585..f9e2ed621f7b 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c | |||
| @@ -111,6 +111,7 @@ struct i5k_amb_data { | |||
| 111 | void __iomem *amb_mmio; | 111 | void __iomem *amb_mmio; |
| 112 | struct i5k_device_attribute *attrs; | 112 | struct i5k_device_attribute *attrs; |
| 113 | unsigned int num_attrs; | 113 | unsigned int num_attrs; |
| 114 | unsigned long chipset_id; | ||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | 117 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, |
| @@ -382,7 +383,8 @@ err: | |||
| 382 | return res; | 383 | return res; |
| 383 | } | 384 | } |
| 384 | 385 | ||
| 385 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | 386 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data, |
| 387 | unsigned long devid) | ||
| 386 | { | 388 | { |
| 387 | struct pci_dev *pcidev; | 389 | struct pci_dev *pcidev; |
| 388 | u32 val32; | 390 | u32 val32; |
| @@ -390,7 +392,7 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | |||
| 390 | 392 | ||
| 391 | /* Find AMB register memory space */ | 393 | /* Find AMB register memory space */ |
| 392 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 394 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 393 | PCI_DEVICE_ID_INTEL_5000_ERR, | 395 | devid, |
| 394 | NULL); | 396 | NULL); |
| 395 | if (!pcidev) | 397 | if (!pcidev) |
| 396 | return -ENODEV; | 398 | return -ENODEV; |
| @@ -409,6 +411,8 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | |||
| 409 | goto out; | 411 | goto out; |
| 410 | } | 412 | } |
| 411 | 413 | ||
| 414 | data->chipset_id = devid; | ||
| 415 | |||
| 412 | res = 0; | 416 | res = 0; |
| 413 | out: | 417 | out: |
| 414 | pci_dev_put(pcidev); | 418 | pci_dev_put(pcidev); |
| @@ -441,10 +445,30 @@ out: | |||
| 441 | return res; | 445 | return res; |
| 442 | } | 446 | } |
| 443 | 447 | ||
| 448 | static unsigned long i5k_channel_pci_id(struct i5k_amb_data *data, | ||
| 449 | unsigned long channel) | ||
| 450 | { | ||
| 451 | switch (data->chipset_id) { | ||
| 452 | case PCI_DEVICE_ID_INTEL_5000_ERR: | ||
| 453 | return PCI_DEVICE_ID_INTEL_5000_FBD0 + channel; | ||
| 454 | case PCI_DEVICE_ID_INTEL_5400_ERR: | ||
| 455 | return PCI_DEVICE_ID_INTEL_5400_FBD0 + channel; | ||
| 456 | default: | ||
| 457 | BUG(); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | static unsigned long chipset_ids[] = { | ||
| 462 | PCI_DEVICE_ID_INTEL_5000_ERR, | ||
| 463 | PCI_DEVICE_ID_INTEL_5400_ERR, | ||
| 464 | 0 | ||
| 465 | }; | ||
| 466 | |||
| 444 | static int __devinit i5k_amb_probe(struct platform_device *pdev) | 467 | static int __devinit i5k_amb_probe(struct platform_device *pdev) |
| 445 | { | 468 | { |
| 446 | struct i5k_amb_data *data; | 469 | struct i5k_amb_data *data; |
| 447 | struct resource *reso; | 470 | struct resource *reso; |
| 471 | int i; | ||
| 448 | int res = -ENODEV; | 472 | int res = -ENODEV; |
| 449 | 473 | ||
| 450 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 474 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
| @@ -452,19 +476,24 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev) | |||
| 452 | return -ENOMEM; | 476 | return -ENOMEM; |
| 453 | 477 | ||
| 454 | /* Figure out where the AMB registers live */ | 478 | /* Figure out where the AMB registers live */ |
| 455 | res = i5k_find_amb_registers(data); | 479 | i = 0; |
| 480 | do { | ||
| 481 | res = i5k_find_amb_registers(data, chipset_ids[i]); | ||
| 482 | i++; | ||
| 483 | } while (res && chipset_ids[i]); | ||
| 484 | |||
| 456 | if (res) | 485 | if (res) |
| 457 | goto err; | 486 | goto err; |
| 458 | 487 | ||
| 459 | /* Copy the DIMM presence map for the first two channels */ | 488 | /* Copy the DIMM presence map for the first two channels */ |
| 460 | res = i5k_channel_probe(&data->amb_present[0], | 489 | res = i5k_channel_probe(&data->amb_present[0], |
| 461 | PCI_DEVICE_ID_INTEL_5000_FBD0); | 490 | i5k_channel_pci_id(data, 0)); |
| 462 | if (res) | 491 | if (res) |
| 463 | goto err; | 492 | goto err; |
| 464 | 493 | ||
| 465 | /* Copy the DIMM presence map for the optional second two channels */ | 494 | /* Copy the DIMM presence map for the optional second two channels */ |
| 466 | i5k_channel_probe(&data->amb_present[2], | 495 | i5k_channel_probe(&data->amb_present[2], |
| 467 | PCI_DEVICE_ID_INTEL_5000_FBD1); | 496 | i5k_channel_pci_id(data, 1)); |
| 468 | 497 | ||
| 469 | /* Set up resource regions */ | 498 | /* Set up resource regions */ |
| 470 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); | 499 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c new file mode 100644 index 000000000000..5c006c9a4311 --- /dev/null +++ b/drivers/hwmon/ibmaem.c | |||
| @@ -0,0 +1,1111 @@ | |||
| 1 | /* | ||
| 2 | * A hwmon driver for the IBM Active Energy Manager temperature/power sensors | ||
| 3 | * and capping functionality. | ||
| 4 | * Copyright (C) 2008 IBM | ||
| 5 | * | ||
| 6 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/ipmi.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/hwmon.h> | ||
| 26 | #include <linux/hwmon-sysfs.h> | ||
| 27 | #include <linux/jiffies.h> | ||
| 28 | #include <linux/mutex.h> | ||
| 29 | #include <linux/kdev_t.h> | ||
| 30 | #include <linux/spinlock.h> | ||
| 31 | #include <linux/idr.h> | ||
| 32 | #include <linux/sched.h> | ||
| 33 | #include <linux/platform_device.h> | ||
| 34 | #include <linux/math64.h> | ||
| 35 | #include <linux/time.h> | ||
| 36 | |||
| 37 | #define REFRESH_INTERVAL (HZ) | ||
| 38 | #define IPMI_TIMEOUT (30 * HZ) | ||
| 39 | #define DRVNAME "aem" | ||
| 40 | |||
| 41 | #define AEM_NETFN 0x2E | ||
| 42 | |||
| 43 | #define AEM_FIND_FW_CMD 0x80 | ||
| 44 | #define AEM_ELEMENT_CMD 0x81 | ||
| 45 | #define AEM_FW_INSTANCE_CMD 0x82 | ||
| 46 | |||
| 47 | #define AEM_READ_ELEMENT_CFG 0x80 | ||
| 48 | #define AEM_READ_BUFFER 0x81 | ||
| 49 | #define AEM_READ_REGISTER 0x82 | ||
| 50 | #define AEM_WRITE_REGISTER 0x83 | ||
| 51 | #define AEM_SET_REG_MASK 0x84 | ||
| 52 | #define AEM_CLEAR_REG_MASK 0x85 | ||
| 53 | #define AEM_READ_ELEMENT_CFG2 0x86 | ||
| 54 | |||
| 55 | #define AEM_CONTROL_ELEMENT 0 | ||
| 56 | #define AEM_ENERGY_ELEMENT 1 | ||
| 57 | #define AEM_CLOCK_ELEMENT 4 | ||
| 58 | #define AEM_POWER_CAP_ELEMENT 7 | ||
| 59 | #define AEM_EXHAUST_ELEMENT 9 | ||
| 60 | #define AEM_POWER_ELEMENT 10 | ||
| 61 | |||
| 62 | #define AEM_MODULE_TYPE_ID 0x0001 | ||
| 63 | |||
| 64 | #define AEM2_NUM_ENERGY_REGS 2 | ||
| 65 | #define AEM2_NUM_PCAP_REGS 6 | ||
| 66 | #define AEM2_NUM_TEMP_REGS 2 | ||
| 67 | #define AEM2_NUM_SENSORS 14 | ||
| 68 | |||
| 69 | #define AEM1_NUM_ENERGY_REGS 1 | ||
| 70 | #define AEM1_NUM_SENSORS 3 | ||
| 71 | |||
| 72 | /* AEM 2.x has more energy registers */ | ||
| 73 | #define AEM_NUM_ENERGY_REGS AEM2_NUM_ENERGY_REGS | ||
| 74 | /* AEM 2.x needs more sensor files */ | ||
| 75 | #define AEM_NUM_SENSORS AEM2_NUM_SENSORS | ||
| 76 | |||
| 77 | #define POWER_CAP 0 | ||
| 78 | #define POWER_CAP_MAX_HOTPLUG 1 | ||
| 79 | #define POWER_CAP_MAX 2 | ||
| 80 | #define POWER_CAP_MIN_WARNING 3 | ||
| 81 | #define POWER_CAP_MIN 4 | ||
| 82 | #define POWER_AUX 5 | ||
| 83 | |||
| 84 | #define AEM_DEFAULT_POWER_INTERVAL 1000 | ||
| 85 | #define AEM_MIN_POWER_INTERVAL 200 | ||
| 86 | #define UJ_PER_MJ 1000L | ||
| 87 | |||
| 88 | static DEFINE_IDR(aem_idr); | ||
| 89 | static DEFINE_SPINLOCK(aem_idr_lock); | ||
| 90 | |||
| 91 | static struct device_driver aem_driver = { | ||
| 92 | .name = DRVNAME, | ||
| 93 | .bus = &platform_bus_type, | ||
| 94 | }; | ||
| 95 | |||
| 96 | struct aem_ipmi_data { | ||
| 97 | struct completion read_complete; | ||
| 98 | struct ipmi_addr address; | ||
| 99 | ipmi_user_t user; | ||
| 100 | int interface; | ||
| 101 | |||
| 102 | struct kernel_ipmi_msg tx_message; | ||
| 103 | long tx_msgid; | ||
| 104 | |||
| 105 | void *rx_msg_data; | ||
| 106 | unsigned short rx_msg_len; | ||
| 107 | unsigned char rx_result; | ||
| 108 | int rx_recv_type; | ||
| 109 | |||
| 110 | struct device *bmc_device; | ||
| 111 | }; | ||
| 112 | |||
| 113 | struct aem_ro_sensor_template { | ||
| 114 | char *label; | ||
| 115 | ssize_t (*show)(struct device *dev, | ||
| 116 | struct device_attribute *devattr, | ||
| 117 | char *buf); | ||
| 118 | int index; | ||
| 119 | }; | ||
| 120 | |||
| 121 | struct aem_rw_sensor_template { | ||
| 122 | char *label; | ||
| 123 | ssize_t (*show)(struct device *dev, | ||
| 124 | struct device_attribute *devattr, | ||
| 125 | char *buf); | ||
| 126 | ssize_t (*set)(struct device *dev, | ||
| 127 | struct device_attribute *devattr, | ||
| 128 | const char *buf, size_t count); | ||
| 129 | int index; | ||
| 130 | }; | ||
| 131 | |||
| 132 | struct aem_data { | ||
| 133 | struct list_head list; | ||
| 134 | |||
| 135 | struct device *hwmon_dev; | ||
| 136 | struct platform_device *pdev; | ||
| 137 | struct mutex lock; | ||
| 138 | char valid; | ||
| 139 | unsigned long last_updated; /* In jiffies */ | ||
| 140 | u8 ver_major; | ||
| 141 | u8 ver_minor; | ||
| 142 | u8 module_handle; | ||
| 143 | int id; | ||
| 144 | struct aem_ipmi_data ipmi; | ||
| 145 | |||
| 146 | /* Function to update sensors */ | ||
| 147 | void (*update)(struct aem_data *data); | ||
| 148 | |||
| 149 | /* | ||
| 150 | * AEM 1.x sensors: | ||
| 151 | * Available sensors: | ||
| 152 | * Energy meter | ||
| 153 | * Power meter | ||
| 154 | * | ||
| 155 | * AEM 2.x sensors: | ||
| 156 | * Two energy meters | ||
| 157 | * Two power meters | ||
| 158 | * Two temperature sensors | ||
| 159 | * Six power cap registers | ||
| 160 | */ | ||
| 161 | |||
| 162 | /* sysfs attrs */ | ||
| 163 | struct sensor_device_attribute sensors[AEM_NUM_SENSORS]; | ||
| 164 | |||
| 165 | /* energy use in mJ */ | ||
| 166 | u64 energy[AEM_NUM_ENERGY_REGS]; | ||
| 167 | |||
| 168 | /* power sampling interval in ms */ | ||
| 169 | unsigned long power_period[AEM_NUM_ENERGY_REGS]; | ||
| 170 | |||
| 171 | /* Everything past here is for AEM2 only */ | ||
| 172 | |||
| 173 | /* power caps in dW */ | ||
| 174 | u16 pcap[AEM2_NUM_PCAP_REGS]; | ||
| 175 | |||
| 176 | /* exhaust temperature in C */ | ||
| 177 | u8 temp[AEM2_NUM_TEMP_REGS]; | ||
| 178 | }; | ||
| 179 | |||
| 180 | /* Data structures returned by the AEM firmware */ | ||
| 181 | struct aem_iana_id { | ||
| 182 | u8 bytes[3]; | ||
| 183 | }; | ||
| 184 | static struct aem_iana_id system_x_id = { | ||
| 185 | .bytes = {0x4D, 0x4F, 0x00} | ||
| 186 | }; | ||
| 187 | |||
| 188 | /* These are used to find AEM1 instances */ | ||
| 189 | struct aem_find_firmware_req { | ||
| 190 | struct aem_iana_id id; | ||
| 191 | u8 rsvd; | ||
| 192 | u16 index; | ||
| 193 | u16 module_type_id; | ||
| 194 | } __packed; | ||
| 195 | |||
| 196 | struct aem_find_firmware_resp { | ||
| 197 | struct aem_iana_id id; | ||
| 198 | u8 num_instances; | ||
| 199 | } __packed; | ||
| 200 | |||
| 201 | /* These are used to find AEM2 instances */ | ||
| 202 | struct aem_find_instance_req { | ||
| 203 | struct aem_iana_id id; | ||
| 204 | u8 instance_number; | ||
| 205 | u16 module_type_id; | ||
| 206 | } __packed; | ||
| 207 | |||
| 208 | struct aem_find_instance_resp { | ||
| 209 | struct aem_iana_id id; | ||
| 210 | u8 num_instances; | ||
| 211 | u8 major; | ||
| 212 | u8 minor; | ||
| 213 | u8 module_handle; | ||
| 214 | u16 record_id; | ||
| 215 | } __packed; | ||
| 216 | |||
| 217 | /* These are used to query sensors */ | ||
| 218 | struct aem_read_sensor_req { | ||
| 219 | struct aem_iana_id id; | ||
| 220 | u8 module_handle; | ||
| 221 | u8 element; | ||
| 222 | u8 subcommand; | ||
| 223 | u8 reg; | ||
| 224 | u8 rx_buf_size; | ||
| 225 | } __packed; | ||
| 226 | |||
| 227 | struct aem_read_sensor_resp { | ||
| 228 | struct aem_iana_id id; | ||
| 229 | u8 bytes[0]; | ||
| 230 | } __packed; | ||
| 231 | |||
| 232 | /* Data structures to talk to the IPMI layer */ | ||
| 233 | struct aem_driver_data { | ||
| 234 | struct list_head aem_devices; | ||
| 235 | struct ipmi_smi_watcher bmc_events; | ||
| 236 | struct ipmi_user_hndl ipmi_hndlrs; | ||
| 237 | }; | ||
| 238 | |||
| 239 | static void aem_register_bmc(int iface, struct device *dev); | ||
| 240 | static void aem_bmc_gone(int iface); | ||
| 241 | static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | ||
| 242 | |||
| 243 | static void aem_remove_sensors(struct aem_data *data); | ||
| 244 | static int aem_init_aem1(struct aem_ipmi_data *probe); | ||
| 245 | static int aem_init_aem2(struct aem_ipmi_data *probe); | ||
| 246 | static int aem1_find_sensors(struct aem_data *data); | ||
| 247 | static int aem2_find_sensors(struct aem_data *data); | ||
| 248 | static void update_aem1_sensors(struct aem_data *data); | ||
| 249 | static void update_aem2_sensors(struct aem_data *data); | ||
| 250 | |||
| 251 | static struct aem_driver_data driver_data = { | ||
| 252 | .aem_devices = LIST_HEAD_INIT(driver_data.aem_devices), | ||
| 253 | .bmc_events = { | ||
| 254 | .owner = THIS_MODULE, | ||
| 255 | .new_smi = aem_register_bmc, | ||
| 256 | .smi_gone = aem_bmc_gone, | ||
| 257 | }, | ||
| 258 | .ipmi_hndlrs = { | ||
| 259 | .ipmi_recv_hndl = aem_msg_handler, | ||
| 260 | }, | ||
| 261 | }; | ||
| 262 | |||
| 263 | /* Functions to talk to the IPMI layer */ | ||
| 264 | |||
| 265 | /* Initialize IPMI address, message buffers and user data */ | ||
| 266 | static int aem_init_ipmi_data(struct aem_ipmi_data *data, int iface, | ||
| 267 | struct device *bmc) | ||
| 268 | { | ||
| 269 | int err; | ||
| 270 | |||
| 271 | init_completion(&data->read_complete); | ||
| 272 | data->bmc_device = bmc; | ||
| 273 | |||
| 274 | /* Initialize IPMI address */ | ||
| 275 | data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
| 276 | data->address.channel = IPMI_BMC_CHANNEL; | ||
| 277 | data->address.data[0] = 0; | ||
| 278 | data->interface = iface; | ||
| 279 | |||
| 280 | /* Initialize message buffers */ | ||
| 281 | data->tx_msgid = 0; | ||
| 282 | data->tx_message.netfn = AEM_NETFN; | ||
| 283 | |||
| 284 | /* Create IPMI messaging interface user */ | ||
| 285 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | ||
| 286 | data, &data->user); | ||
| 287 | if (err < 0) { | ||
| 288 | dev_err(bmc, "Unable to register user with IPMI " | ||
| 289 | "interface %d\n", data->interface); | ||
| 290 | return -EACCES; | ||
| 291 | } | ||
| 292 | |||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | /* Send an IPMI command */ | ||
| 297 | static int aem_send_message(struct aem_ipmi_data *data) | ||
| 298 | { | ||
| 299 | int err; | ||
| 300 | |||
| 301 | err = ipmi_validate_addr(&data->address, sizeof(data->address)); | ||
| 302 | if (err) | ||
| 303 | goto out; | ||
| 304 | |||
| 305 | data->tx_msgid++; | ||
| 306 | err = ipmi_request_settime(data->user, &data->address, data->tx_msgid, | ||
| 307 | &data->tx_message, data, 0, 0, 0); | ||
| 308 | if (err) | ||
| 309 | goto out1; | ||
| 310 | |||
| 311 | return 0; | ||
| 312 | out1: | ||
| 313 | dev_err(data->bmc_device, "request_settime=%x\n", err); | ||
| 314 | return err; | ||
| 315 | out: | ||
| 316 | dev_err(data->bmc_device, "validate_addr=%x\n", err); | ||
| 317 | return err; | ||
| 318 | } | ||
| 319 | |||
| 320 | /* Dispatch IPMI messages to callers */ | ||
| 321 | static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | ||
| 322 | { | ||
| 323 | unsigned short rx_len; | ||
| 324 | struct aem_ipmi_data *data = user_msg_data; | ||
| 325 | |||
| 326 | if (msg->msgid != data->tx_msgid) { | ||
| 327 | dev_err(data->bmc_device, "Mismatch between received msgid " | ||
| 328 | "(%02x) and transmitted msgid (%02x)!\n", | ||
| 329 | (int)msg->msgid, | ||
| 330 | (int)data->tx_msgid); | ||
| 331 | ipmi_free_recv_msg(msg); | ||
| 332 | return; | ||
| 333 | } | ||
| 334 | |||
| 335 | data->rx_recv_type = msg->recv_type; | ||
| 336 | if (msg->msg.data_len > 0) | ||
| 337 | data->rx_result = msg->msg.data[0]; | ||
| 338 | else | ||
| 339 | data->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; | ||
| 340 | |||
| 341 | if (msg->msg.data_len > 1) { | ||
| 342 | rx_len = msg->msg.data_len - 1; | ||
| 343 | if (data->rx_msg_len < rx_len) | ||
| 344 | rx_len = data->rx_msg_len; | ||
| 345 | data->rx_msg_len = rx_len; | ||
| 346 | memcpy(data->rx_msg_data, msg->msg.data + 1, data->rx_msg_len); | ||
| 347 | } else | ||
| 348 | data->rx_msg_len = 0; | ||
| 349 | |||
| 350 | ipmi_free_recv_msg(msg); | ||
| 351 | complete(&data->read_complete); | ||
| 352 | } | ||
| 353 | |||
| 354 | /* ID functions */ | ||
| 355 | |||
| 356 | /* Obtain an id */ | ||
| 357 | static int aem_idr_get(int *id) | ||
| 358 | { | ||
| 359 | int i, err; | ||
| 360 | |||
| 361 | again: | ||
| 362 | if (unlikely(!idr_pre_get(&aem_idr, GFP_KERNEL))) | ||
| 363 | return -ENOMEM; | ||
| 364 | |||
| 365 | spin_lock(&aem_idr_lock); | ||
| 366 | err = idr_get_new(&aem_idr, NULL, &i); | ||
| 367 | spin_unlock(&aem_idr_lock); | ||
| 368 | |||
| 369 | if (unlikely(err == -EAGAIN)) | ||
| 370 | goto again; | ||
| 371 | else if (unlikely(err)) | ||
| 372 | return err; | ||
| 373 | |||
| 374 | *id = i & MAX_ID_MASK; | ||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* Release an object ID */ | ||
| 379 | static void aem_idr_put(int id) | ||
| 380 | { | ||
| 381 | spin_lock(&aem_idr_lock); | ||
| 382 | idr_remove(&aem_idr, id); | ||
| 383 | spin_unlock(&aem_idr_lock); | ||
| 384 | } | ||
| 385 | |||
| 386 | /* Sensor support functions */ | ||
| 387 | |||
| 388 | /* Read a sensor value */ | ||
| 389 | static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | ||
| 390 | void *buf, size_t size) | ||
| 391 | { | ||
| 392 | int rs_size, res; | ||
| 393 | struct aem_read_sensor_req rs_req; | ||
| 394 | struct aem_read_sensor_resp *rs_resp; | ||
| 395 | struct aem_ipmi_data *ipmi = &data->ipmi; | ||
| 396 | |||
| 397 | /* AEM registers are 1, 2, 4 or 8 bytes */ | ||
| 398 | switch (size) { | ||
| 399 | case 1: | ||
| 400 | case 2: | ||
| 401 | case 4: | ||
| 402 | case 8: | ||
| 403 | break; | ||
| 404 | default: | ||
| 405 | return -EINVAL; | ||
| 406 | } | ||
| 407 | |||
| 408 | rs_req.id = system_x_id; | ||
| 409 | rs_req.module_handle = data->module_handle; | ||
| 410 | rs_req.element = elt; | ||
| 411 | rs_req.subcommand = AEM_READ_REGISTER; | ||
| 412 | rs_req.reg = reg; | ||
| 413 | rs_req.rx_buf_size = size; | ||
| 414 | |||
| 415 | ipmi->tx_message.cmd = AEM_ELEMENT_CMD; | ||
| 416 | ipmi->tx_message.data = (char *)&rs_req; | ||
| 417 | ipmi->tx_message.data_len = sizeof(rs_req); | ||
| 418 | |||
| 419 | rs_size = sizeof(*rs_resp) + size; | ||
| 420 | rs_resp = kzalloc(rs_size, GFP_KERNEL); | ||
| 421 | if (!rs_resp) | ||
| 422 | return -ENOMEM; | ||
| 423 | |||
| 424 | ipmi->rx_msg_data = rs_resp; | ||
| 425 | ipmi->rx_msg_len = rs_size; | ||
| 426 | |||
| 427 | aem_send_message(ipmi); | ||
| 428 | |||
| 429 | res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); | ||
| 430 | if (!res) | ||
| 431 | return -ETIMEDOUT; | ||
| 432 | |||
| 433 | if (ipmi->rx_result || ipmi->rx_msg_len != rs_size || | ||
| 434 | memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) { | ||
| 435 | kfree(rs_resp); | ||
| 436 | return -ENOENT; | ||
| 437 | } | ||
| 438 | |||
| 439 | switch (size) { | ||
| 440 | case 1: { | ||
| 441 | u8 *x = buf; | ||
| 442 | *x = rs_resp->bytes[0]; | ||
| 443 | break; | ||
| 444 | } | ||
| 445 | case 2: { | ||
| 446 | u16 *x = buf; | ||
| 447 | *x = be16_to_cpup((u16 *)rs_resp->bytes); | ||
| 448 | break; | ||
| 449 | } | ||
| 450 | case 4: { | ||
| 451 | u32 *x = buf; | ||
| 452 | *x = be32_to_cpup((u32 *)rs_resp->bytes); | ||
| 453 | break; | ||
| 454 | } | ||
| 455 | case 8: { | ||
| 456 | u64 *x = buf; | ||
| 457 | *x = be64_to_cpup((u64 *)rs_resp->bytes); | ||
| 458 | break; | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | return 0; | ||
| 463 | } | ||
| 464 | |||
| 465 | /* Update AEM energy registers */ | ||
| 466 | static void update_aem_energy(struct aem_data *data) | ||
| 467 | { | ||
| 468 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 0, &data->energy[0], 8); | ||
| 469 | if (data->ver_major < 2) | ||
| 470 | return; | ||
| 471 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 1, &data->energy[1], 8); | ||
| 472 | } | ||
| 473 | |||
| 474 | /* Update all AEM1 sensors */ | ||
| 475 | static void update_aem1_sensors(struct aem_data *data) | ||
| 476 | { | ||
| 477 | mutex_lock(&data->lock); | ||
| 478 | if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) && | ||
| 479 | data->valid) | ||
| 480 | goto out; | ||
| 481 | |||
| 482 | update_aem_energy(data); | ||
| 483 | out: | ||
| 484 | mutex_unlock(&data->lock); | ||
| 485 | } | ||
| 486 | |||
| 487 | /* Update all AEM2 sensors */ | ||
| 488 | static void update_aem2_sensors(struct aem_data *data) | ||
| 489 | { | ||
| 490 | int i; | ||
| 491 | |||
| 492 | mutex_lock(&data->lock); | ||
| 493 | if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) && | ||
| 494 | data->valid) | ||
| 495 | goto out; | ||
| 496 | |||
| 497 | update_aem_energy(data); | ||
| 498 | aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 0, &data->temp[0], 1); | ||
| 499 | aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 1, &data->temp[1], 1); | ||
| 500 | |||
| 501 | for (i = POWER_CAP; i <= POWER_AUX; i++) | ||
| 502 | aem_read_sensor(data, AEM_POWER_CAP_ELEMENT, i, | ||
| 503 | &data->pcap[i], 2); | ||
| 504 | out: | ||
| 505 | mutex_unlock(&data->lock); | ||
| 506 | } | ||
| 507 | |||
| 508 | /* Delete an AEM instance */ | ||
| 509 | static void aem_delete(struct aem_data *data) | ||
| 510 | { | ||
| 511 | list_del(&data->list); | ||
| 512 | aem_remove_sensors(data); | ||
| 513 | hwmon_device_unregister(data->hwmon_dev); | ||
| 514 | ipmi_destroy_user(data->ipmi.user); | ||
| 515 | dev_set_drvdata(&data->pdev->dev, NULL); | ||
| 516 | platform_device_unregister(data->pdev); | ||
| 517 | aem_idr_put(data->id); | ||
| 518 | kfree(data); | ||
| 519 | } | ||
| 520 | |||
| 521 | /* Probe functions for AEM1 devices */ | ||
| 522 | |||
| 523 | /* Retrieve version and module handle for an AEM1 instance */ | ||
| 524 | static int aem_find_aem1_count(struct aem_ipmi_data *data) | ||
| 525 | { | ||
| 526 | int res; | ||
| 527 | struct aem_find_firmware_req ff_req; | ||
| 528 | struct aem_find_firmware_resp ff_resp; | ||
| 529 | |||
| 530 | ff_req.id = system_x_id; | ||
| 531 | ff_req.index = 0; | ||
| 532 | ff_req.module_type_id = cpu_to_be16(AEM_MODULE_TYPE_ID); | ||
| 533 | |||
| 534 | data->tx_message.cmd = AEM_FIND_FW_CMD; | ||
| 535 | data->tx_message.data = (char *)&ff_req; | ||
| 536 | data->tx_message.data_len = sizeof(ff_req); | ||
| 537 | |||
| 538 | data->rx_msg_data = &ff_resp; | ||
| 539 | data->rx_msg_len = sizeof(ff_resp); | ||
| 540 | |||
| 541 | aem_send_message(data); | ||
| 542 | |||
| 543 | res = wait_for_completion_timeout(&data->read_complete, IPMI_TIMEOUT); | ||
| 544 | if (!res) | ||
| 545 | return -ETIMEDOUT; | ||
| 546 | |||
| 547 | if (data->rx_result || data->rx_msg_len != sizeof(ff_resp) || | ||
| 548 | memcmp(&ff_resp.id, &system_x_id, sizeof(system_x_id))) | ||
| 549 | return -ENOENT; | ||
| 550 | |||
| 551 | return ff_resp.num_instances; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* Find and initialize one AEM1 instance */ | ||
| 555 | static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | ||
| 556 | { | ||
| 557 | struct aem_data *data; | ||
| 558 | int i; | ||
| 559 | int res = -ENOMEM; | ||
| 560 | |||
| 561 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 562 | if (!data) | ||
| 563 | return res; | ||
| 564 | mutex_init(&data->lock); | ||
| 565 | |||
| 566 | /* Copy instance data */ | ||
| 567 | data->ver_major = 1; | ||
| 568 | data->ver_minor = 0; | ||
| 569 | data->module_handle = module_handle; | ||
| 570 | for (i = 0; i < AEM1_NUM_ENERGY_REGS; i++) | ||
| 571 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | ||
| 572 | |||
| 573 | /* Create sub-device for this fw instance */ | ||
| 574 | if (aem_idr_get(&data->id)) | ||
| 575 | goto id_err; | ||
| 576 | |||
| 577 | data->pdev = platform_device_alloc(DRVNAME, data->id); | ||
| 578 | if (!data->pdev) | ||
| 579 | goto dev_err; | ||
| 580 | data->pdev->dev.driver = &aem_driver; | ||
| 581 | |||
| 582 | res = platform_device_add(data->pdev); | ||
| 583 | if (res) | ||
| 584 | goto ipmi_err; | ||
| 585 | |||
| 586 | dev_set_drvdata(&data->pdev->dev, data); | ||
| 587 | |||
| 588 | /* Set up IPMI interface */ | ||
| 589 | if (aem_init_ipmi_data(&data->ipmi, probe->interface, | ||
| 590 | probe->bmc_device)) | ||
| 591 | goto ipmi_err; | ||
| 592 | |||
| 593 | /* Register with hwmon */ | ||
| 594 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | ||
| 595 | |||
| 596 | if (IS_ERR(data->hwmon_dev)) { | ||
| 597 | dev_err(&data->pdev->dev, "Unable to register hwmon " | ||
| 598 | "device for IPMI interface %d\n", | ||
| 599 | probe->interface); | ||
| 600 | goto hwmon_reg_err; | ||
| 601 | } | ||
| 602 | |||
| 603 | data->update = update_aem1_sensors; | ||
| 604 | |||
| 605 | /* Find sensors */ | ||
| 606 | if (aem1_find_sensors(data)) | ||
| 607 | goto sensor_err; | ||
| 608 | |||
| 609 | /* Add to our list of AEM devices */ | ||
| 610 | list_add_tail(&data->list, &driver_data.aem_devices); | ||
| 611 | |||
| 612 | dev_info(data->ipmi.bmc_device, "Found AEM v%d.%d at 0x%X\n", | ||
| 613 | data->ver_major, data->ver_minor, | ||
| 614 | data->module_handle); | ||
| 615 | return 0; | ||
| 616 | |||
| 617 | sensor_err: | ||
| 618 | hwmon_device_unregister(data->hwmon_dev); | ||
| 619 | hwmon_reg_err: | ||
| 620 | ipmi_destroy_user(data->ipmi.user); | ||
| 621 | ipmi_err: | ||
| 622 | dev_set_drvdata(&data->pdev->dev, NULL); | ||
| 623 | platform_device_unregister(data->pdev); | ||
| 624 | dev_err: | ||
| 625 | aem_idr_put(data->id); | ||
| 626 | id_err: | ||
| 627 | kfree(data); | ||
| 628 | |||
| 629 | return res; | ||
| 630 | } | ||
| 631 | |||
| 632 | /* Find and initialize all AEM1 instances */ | ||
| 633 | static int aem_init_aem1(struct aem_ipmi_data *probe) | ||
| 634 | { | ||
| 635 | int num, i, err; | ||
| 636 | |||
| 637 | num = aem_find_aem1_count(probe); | ||
| 638 | for (i = 0; i < num; i++) { | ||
| 639 | err = aem_init_aem1_inst(probe, i); | ||
| 640 | if (err) { | ||
| 641 | dev_err(probe->bmc_device, | ||
| 642 | "Error %d initializing AEM1 0x%X\n", | ||
| 643 | err, i); | ||
| 644 | return err; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | return 0; | ||
| 649 | } | ||
| 650 | |||
| 651 | /* Probe functions for AEM2 devices */ | ||
| 652 | |||
| 653 | /* Retrieve version and module handle for an AEM2 instance */ | ||
| 654 | static int aem_find_aem2(struct aem_ipmi_data *data, | ||
| 655 | struct aem_find_instance_resp *fi_resp, | ||
| 656 | int instance_num) | ||
| 657 | { | ||
| 658 | int res; | ||
| 659 | struct aem_find_instance_req fi_req; | ||
| 660 | |||
| 661 | fi_req.id = system_x_id; | ||
| 662 | fi_req.instance_number = instance_num; | ||
| 663 | fi_req.module_type_id = cpu_to_be16(AEM_MODULE_TYPE_ID); | ||
| 664 | |||
| 665 | data->tx_message.cmd = AEM_FW_INSTANCE_CMD; | ||
| 666 | data->tx_message.data = (char *)&fi_req; | ||
| 667 | data->tx_message.data_len = sizeof(fi_req); | ||
| 668 | |||
| 669 | data->rx_msg_data = fi_resp; | ||
| 670 | data->rx_msg_len = sizeof(*fi_resp); | ||
| 671 | |||
| 672 | aem_send_message(data); | ||
| 673 | |||
| 674 | res = wait_for_completion_timeout(&data->read_complete, IPMI_TIMEOUT); | ||
| 675 | if (!res) | ||
| 676 | return -ETIMEDOUT; | ||
| 677 | |||
| 678 | if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || | ||
| 679 | memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id))) | ||
| 680 | return -ENOENT; | ||
| 681 | |||
| 682 | return 0; | ||
| 683 | } | ||
| 684 | |||
| 685 | /* Find and initialize one AEM2 instance */ | ||
| 686 | static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | ||
| 687 | struct aem_find_instance_resp *fi_resp) | ||
| 688 | { | ||
| 689 | struct aem_data *data; | ||
| 690 | int i; | ||
| 691 | int res = -ENOMEM; | ||
| 692 | |||
| 693 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 694 | if (!data) | ||
| 695 | return res; | ||
| 696 | mutex_init(&data->lock); | ||
| 697 | |||
| 698 | /* Copy instance data */ | ||
| 699 | data->ver_major = fi_resp->major; | ||
| 700 | data->ver_minor = fi_resp->minor; | ||
| 701 | data->module_handle = fi_resp->module_handle; | ||
| 702 | for (i = 0; i < AEM2_NUM_ENERGY_REGS; i++) | ||
| 703 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | ||
| 704 | |||
| 705 | /* Create sub-device for this fw instance */ | ||
| 706 | if (aem_idr_get(&data->id)) | ||
| 707 | goto id_err; | ||
| 708 | |||
| 709 | data->pdev = platform_device_alloc(DRVNAME, data->id); | ||
| 710 | if (!data->pdev) | ||
| 711 | goto dev_err; | ||
| 712 | data->pdev->dev.driver = &aem_driver; | ||
| 713 | |||
| 714 | res = platform_device_add(data->pdev); | ||
| 715 | if (res) | ||
| 716 | goto ipmi_err; | ||
| 717 | |||
| 718 | dev_set_drvdata(&data->pdev->dev, data); | ||
| 719 | |||
| 720 | /* Set up IPMI interface */ | ||
| 721 | if (aem_init_ipmi_data(&data->ipmi, probe->interface, | ||
| 722 | probe->bmc_device)) | ||
| 723 | goto ipmi_err; | ||
| 724 | |||
| 725 | /* Register with hwmon */ | ||
| 726 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | ||
| 727 | |||
| 728 | if (IS_ERR(data->hwmon_dev)) { | ||
| 729 | dev_err(&data->pdev->dev, "Unable to register hwmon " | ||
| 730 | "device for IPMI interface %d\n", | ||
| 731 | probe->interface); | ||
| 732 | goto hwmon_reg_err; | ||
| 733 | } | ||
| 734 | |||
| 735 | data->update = update_aem2_sensors; | ||
| 736 | |||
| 737 | /* Find sensors */ | ||
| 738 | if (aem2_find_sensors(data)) | ||
| 739 | goto sensor_err; | ||
| 740 | |||
| 741 | /* Add to our list of AEM devices */ | ||
| 742 | list_add_tail(&data->list, &driver_data.aem_devices); | ||
| 743 | |||
| 744 | dev_info(data->ipmi.bmc_device, "Found AEM v%d.%d at 0x%X\n", | ||
| 745 | data->ver_major, data->ver_minor, | ||
| 746 | data->module_handle); | ||
| 747 | return 0; | ||
| 748 | |||
| 749 | sensor_err: | ||
| 750 | hwmon_device_unregister(data->hwmon_dev); | ||
| 751 | hwmon_reg_err: | ||
| 752 | ipmi_destroy_user(data->ipmi.user); | ||
| 753 | ipmi_err: | ||
| 754 | dev_set_drvdata(&data->pdev->dev, NULL); | ||
| 755 | platform_device_unregister(data->pdev); | ||
| 756 | dev_err: | ||
| 757 | aem_idr_put(data->id); | ||
| 758 | id_err: | ||
| 759 | kfree(data); | ||
| 760 | |||
| 761 | return res; | ||
| 762 | } | ||
| 763 | |||
| 764 | /* Find and initialize all AEM2 instances */ | ||
| 765 | static int aem_init_aem2(struct aem_ipmi_data *probe) | ||
| 766 | { | ||
| 767 | struct aem_find_instance_resp fi_resp; | ||
| 768 | int err; | ||
| 769 | int i = 0; | ||
| 770 | |||
| 771 | while (!aem_find_aem2(probe, &fi_resp, i)) { | ||
| 772 | if (fi_resp.major != 2) { | ||
| 773 | dev_err(probe->bmc_device, "Unknown AEM v%d; please " | ||
| 774 | "report this to the maintainer.\n", | ||
| 775 | fi_resp.major); | ||
| 776 | i++; | ||
| 777 | continue; | ||
| 778 | } | ||
| 779 | err = aem_init_aem2_inst(probe, &fi_resp); | ||
| 780 | if (err) { | ||
| 781 | dev_err(probe->bmc_device, | ||
| 782 | "Error %d initializing AEM2 0x%X\n", | ||
| 783 | err, fi_resp.module_handle); | ||
| 784 | return err; | ||
| 785 | } | ||
| 786 | i++; | ||
| 787 | } | ||
| 788 | |||
| 789 | return 0; | ||
| 790 | } | ||
| 791 | |||
| 792 | /* Probe a BMC for AEM firmware instances */ | ||
| 793 | static void aem_register_bmc(int iface, struct device *dev) | ||
| 794 | { | ||
| 795 | struct aem_ipmi_data probe; | ||
| 796 | |||
| 797 | if (aem_init_ipmi_data(&probe, iface, dev)) | ||
| 798 | return; | ||
| 799 | |||
| 800 | /* Ignore probe errors; they won't cause problems */ | ||
| 801 | aem_init_aem1(&probe); | ||
| 802 | aem_init_aem2(&probe); | ||
| 803 | |||
| 804 | ipmi_destroy_user(probe.user); | ||
| 805 | } | ||
| 806 | |||
| 807 | /* Handle BMC deletion */ | ||
| 808 | static void aem_bmc_gone(int iface) | ||
| 809 | { | ||
| 810 | struct aem_data *p1, *next1; | ||
| 811 | |||
| 812 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | ||
| 813 | if (p1->ipmi.interface == iface) | ||
| 814 | aem_delete(p1); | ||
| 815 | } | ||
| 816 | |||
| 817 | /* sysfs support functions */ | ||
| 818 | |||
| 819 | /* AEM device name */ | ||
| 820 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
| 821 | char *buf) | ||
| 822 | { | ||
| 823 | struct aem_data *data = dev_get_drvdata(dev); | ||
| 824 | |||
| 825 | return sprintf(buf, "%s%d\n", DRVNAME, data->ver_major); | ||
| 826 | } | ||
| 827 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); | ||
| 828 | |||
| 829 | /* AEM device version */ | ||
| 830 | static ssize_t show_version(struct device *dev, | ||
| 831 | struct device_attribute *devattr, | ||
| 832 | char *buf) | ||
| 833 | { | ||
| 834 | struct aem_data *data = dev_get_drvdata(dev); | ||
| 835 | |||
| 836 | return sprintf(buf, "%d.%d\n", data->ver_major, data->ver_minor); | ||
| 837 | } | ||
| 838 | static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, 0); | ||
| 839 | |||
| 840 | /* Display power use */ | ||
| 841 | static ssize_t aem_show_power(struct device *dev, | ||
| 842 | struct device_attribute *devattr, | ||
| 843 | char *buf) | ||
| 844 | { | ||
| 845 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 846 | struct aem_data *data = dev_get_drvdata(dev); | ||
| 847 | u64 before, after, delta, time; | ||
| 848 | signed long leftover; | ||
| 849 | struct timespec b, a; | ||
| 850 | |||
| 851 | mutex_lock(&data->lock); | ||
| 852 | update_aem_energy(data); | ||
| 853 | getnstimeofday(&b); | ||
| 854 | before = data->energy[attr->index]; | ||
| 855 | |||
| 856 | leftover = schedule_timeout_interruptible( | ||
| 857 | msecs_to_jiffies(data->power_period[attr->index]) | ||
| 858 | ); | ||
| 859 | if (leftover) { | ||
| 860 | mutex_unlock(&data->lock); | ||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | |||
| 864 | update_aem_energy(data); | ||
| 865 | getnstimeofday(&a); | ||
| 866 | after = data->energy[attr->index]; | ||
| 867 | mutex_unlock(&data->lock); | ||
| 868 | |||
| 869 | time = timespec_to_ns(&a) - timespec_to_ns(&b); | ||
| 870 | delta = (after - before) * UJ_PER_MJ; | ||
| 871 | |||
| 872 | return sprintf(buf, "%llu\n", | ||
| 873 | (unsigned long long)div64_u64(delta * NSEC_PER_SEC, time)); | ||
| 874 | } | ||
| 875 | |||
| 876 | /* Display energy use */ | ||
| 877 | static ssize_t aem_show_energy(struct device *dev, | ||
| 878 | struct device_attribute *devattr, | ||
| 879 | char *buf) | ||
| 880 | { | ||
| 881 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 882 | struct aem_data *a = dev_get_drvdata(dev); | ||
| 883 | a->update(a); | ||
| 884 | |||
| 885 | return sprintf(buf, "%llu\n", | ||
| 886 | (unsigned long long)a->energy[attr->index] * 1000); | ||
| 887 | } | ||
| 888 | |||
| 889 | /* Display power interval registers */ | ||
| 890 | static ssize_t aem_show_power_period(struct device *dev, | ||
| 891 | struct device_attribute *devattr, | ||
| 892 | char *buf) | ||
| 893 | { | ||
| 894 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 895 | struct aem_data *a = dev_get_drvdata(dev); | ||
| 896 | a->update(a); | ||
| 897 | |||
| 898 | return sprintf(buf, "%lu\n", a->power_period[attr->index]); | ||
| 899 | } | ||
| 900 | |||
| 901 | /* Set power interval registers */ | ||
| 902 | static ssize_t aem_set_power_period(struct device *dev, | ||
| 903 | struct device_attribute *devattr, | ||
| 904 | const char *buf, size_t count) | ||
| 905 | { | ||
| 906 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 907 | struct aem_data *a = dev_get_drvdata(dev); | ||
| 908 | unsigned long temp; | ||
| 909 | int res; | ||
| 910 | |||
| 911 | res = strict_strtoul(buf, 10, &temp); | ||
| 912 | if (res) | ||
| 913 | return res; | ||
| 914 | |||
| 915 | if (temp < AEM_MIN_POWER_INTERVAL) | ||
| 916 | return -EINVAL; | ||
| 917 | |||
| 918 | mutex_lock(&a->lock); | ||
| 919 | a->power_period[attr->index] = temp; | ||
| 920 | mutex_unlock(&a->lock); | ||
| 921 | |||
| 922 | return count; | ||
| 923 | } | ||
| 924 | |||
| 925 | /* Discover sensors on an AEM device */ | ||
| 926 | static int aem_register_sensors(struct aem_data *data, | ||
| 927 | struct aem_ro_sensor_template *ro, | ||
| 928 | struct aem_rw_sensor_template *rw) | ||
| 929 | { | ||
| 930 | struct device *dev = &data->pdev->dev; | ||
| 931 | struct sensor_device_attribute *sensors = data->sensors; | ||
| 932 | int err; | ||
| 933 | |||
| 934 | /* Set up read-only sensors */ | ||
| 935 | while (ro->label) { | ||
| 936 | sensors->dev_attr.attr.name = ro->label; | ||
| 937 | sensors->dev_attr.attr.mode = S_IRUGO; | ||
| 938 | sensors->dev_attr.show = ro->show; | ||
| 939 | sensors->index = ro->index; | ||
| 940 | |||
| 941 | err = device_create_file(dev, &sensors->dev_attr); | ||
| 942 | if (err) { | ||
| 943 | sensors->dev_attr.attr.name = NULL; | ||
| 944 | goto error; | ||
| 945 | } | ||
| 946 | sensors++; | ||
| 947 | ro++; | ||
| 948 | } | ||
| 949 | |||
| 950 | /* Set up read-write sensors */ | ||
| 951 | while (rw->label) { | ||
| 952 | sensors->dev_attr.attr.name = rw->label; | ||
| 953 | sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
| 954 | sensors->dev_attr.show = rw->show; | ||
| 955 | sensors->dev_attr.store = rw->set; | ||
| 956 | sensors->index = rw->index; | ||
| 957 | |||
| 958 | err = device_create_file(dev, &sensors->dev_attr); | ||
| 959 | if (err) { | ||
| 960 | sensors->dev_attr.attr.name = NULL; | ||
| 961 | goto error; | ||
| 962 | } | ||
| 963 | sensors++; | ||
| 964 | rw++; | ||
| 965 | } | ||
| 966 | |||
| 967 | err = device_create_file(dev, &sensor_dev_attr_name.dev_attr); | ||
| 968 | if (err) | ||
| 969 | goto error; | ||
| 970 | err = device_create_file(dev, &sensor_dev_attr_version.dev_attr); | ||
| 971 | return err; | ||
| 972 | |||
| 973 | error: | ||
| 974 | aem_remove_sensors(data); | ||
| 975 | return err; | ||
| 976 | } | ||
| 977 | |||
| 978 | /* sysfs support functions for AEM2 sensors */ | ||
| 979 | |||
| 980 | /* Display temperature use */ | ||
| 981 | static ssize_t aem2_show_temp(struct device *dev, | ||
| 982 | struct device_attribute *devattr, | ||
| 983 | char *buf) | ||
| 984 | { | ||
| 985 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 986 | struct aem_data *a = dev_get_drvdata(dev); | ||
| 987 | a->update(a); | ||
| 988 | |||
| 989 | return sprintf(buf, "%u\n", a->temp[attr->index] * 1000); | ||
| 990 | } | ||
| 991 | |||
| 992 | /* Display power-capping registers */ | ||
| 993 | static ssize_t aem2_show_pcap_value(struct device *dev, | ||
| 994 | struct device_attribute *devattr, | ||
| 995 | char *buf) | ||
| 996 | { | ||
| 997 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 998 | struct aem_data *a = dev_get_drvdata(dev); | ||
| 999 | a->update(a); | ||
| 1000 | |||
| 1001 | return sprintf(buf, "%u\n", a->pcap[attr->index] * 100000); | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | /* Remove sensors attached to an AEM device */ | ||
| 1005 | static void aem_remove_sensors(struct aem_data *data) | ||
| 1006 | { | ||
| 1007 | int i; | ||
| 1008 | |||
| 1009 | for (i = 0; i < AEM_NUM_SENSORS; i++) { | ||
| 1010 | if (!data->sensors[i].dev_attr.attr.name) | ||
| 1011 | continue; | ||
| 1012 | device_remove_file(&data->pdev->dev, | ||
| 1013 | &data->sensors[i].dev_attr); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | device_remove_file(&data->pdev->dev, | ||
| 1017 | &sensor_dev_attr_name.dev_attr); | ||
| 1018 | device_remove_file(&data->pdev->dev, | ||
| 1019 | &sensor_dev_attr_version.dev_attr); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | /* Sensor probe functions */ | ||
| 1023 | |||
| 1024 | /* Description of AEM1 sensors */ | ||
| 1025 | static struct aem_ro_sensor_template aem1_ro_sensors[] = { | ||
| 1026 | {"energy1_input", aem_show_energy, 0}, | ||
| 1027 | {"power1_average", aem_show_power, 0}, | ||
| 1028 | {NULL, NULL, 0}, | ||
| 1029 | }; | ||
| 1030 | |||
| 1031 | static struct aem_rw_sensor_template aem1_rw_sensors[] = { | ||
| 1032 | {"power1_average_interval", aem_show_power_period, aem_set_power_period, 0}, | ||
| 1033 | {NULL, NULL, NULL, 0}, | ||
| 1034 | }; | ||
| 1035 | |||
| 1036 | /* Description of AEM2 sensors */ | ||
| 1037 | static struct aem_ro_sensor_template aem2_ro_sensors[] = { | ||
| 1038 | {"energy1_input", aem_show_energy, 0}, | ||
| 1039 | {"energy2_input", aem_show_energy, 1}, | ||
| 1040 | {"power1_average", aem_show_power, 0}, | ||
| 1041 | {"power2_average", aem_show_power, 1}, | ||
| 1042 | {"temp1_input", aem2_show_temp, 0}, | ||
| 1043 | {"temp2_input", aem2_show_temp, 1}, | ||
| 1044 | |||
| 1045 | {"power4_average", aem2_show_pcap_value, POWER_CAP_MAX_HOTPLUG}, | ||
| 1046 | {"power5_average", aem2_show_pcap_value, POWER_CAP_MAX}, | ||
| 1047 | {"power6_average", aem2_show_pcap_value, POWER_CAP_MIN_WARNING}, | ||
| 1048 | {"power7_average", aem2_show_pcap_value, POWER_CAP_MIN}, | ||
| 1049 | |||
| 1050 | {"power3_average", aem2_show_pcap_value, POWER_AUX}, | ||
| 1051 | {"power_cap", aem2_show_pcap_value, POWER_CAP}, | ||
| 1052 | {NULL, NULL, 0}, | ||
| 1053 | }; | ||
| 1054 | |||
| 1055 | static struct aem_rw_sensor_template aem2_rw_sensors[] = { | ||
| 1056 | {"power1_average_interval", aem_show_power_period, aem_set_power_period, 0}, | ||
| 1057 | {"power2_average_interval", aem_show_power_period, aem_set_power_period, 1}, | ||
| 1058 | {NULL, NULL, NULL, 0}, | ||
| 1059 | }; | ||
| 1060 | |||
| 1061 | /* Set up AEM1 sensor attrs */ | ||
| 1062 | static int aem1_find_sensors(struct aem_data *data) | ||
| 1063 | { | ||
| 1064 | return aem_register_sensors(data, aem1_ro_sensors, aem1_rw_sensors); | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | /* Set up AEM2 sensor attrs */ | ||
| 1068 | static int aem2_find_sensors(struct aem_data *data) | ||
| 1069 | { | ||
| 1070 | return aem_register_sensors(data, aem2_ro_sensors, aem2_rw_sensors); | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | /* Module init/exit routines */ | ||
| 1074 | |||
| 1075 | static int __init aem_init(void) | ||
| 1076 | { | ||
| 1077 | int res; | ||
| 1078 | |||
| 1079 | res = driver_register(&aem_driver); | ||
| 1080 | if (res) { | ||
| 1081 | printk(KERN_ERR "Can't register aem driver\n"); | ||
| 1082 | return res; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | res = ipmi_smi_watcher_register(&driver_data.bmc_events); | ||
| 1086 | if (res) | ||
| 1087 | goto ipmi_reg_err; | ||
| 1088 | return 0; | ||
| 1089 | |||
| 1090 | ipmi_reg_err: | ||
| 1091 | driver_unregister(&aem_driver); | ||
| 1092 | return res; | ||
| 1093 | |||
| 1094 | } | ||
| 1095 | |||
| 1096 | static void __exit aem_exit(void) | ||
| 1097 | { | ||
| 1098 | struct aem_data *p1, *next1; | ||
| 1099 | |||
| 1100 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | ||
| 1101 | driver_unregister(&aem_driver); | ||
| 1102 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | ||
| 1103 | aem_delete(p1); | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
| 1107 | MODULE_DESCRIPTION("IBM Active Energy Manager power/temp sensor driver"); | ||
| 1108 | MODULE_LICENSE("GPL"); | ||
| 1109 | |||
| 1110 | module_init(aem_init); | ||
| 1111 | module_exit(aem_exit); | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index fbe16d5250a4..1adf2efd3cb3 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -747,7 +747,9 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
| 747 | break; | 747 | break; |
| 748 | case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED: | 748 | case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED: |
| 749 | kmem_cache_free(ib_mad_cache, mad_priv); | 749 | kmem_cache_free(ib_mad_cache, mad_priv); |
| 750 | break; | 750 | kfree(local); |
| 751 | ret = 1; | ||
| 752 | goto out; | ||
| 751 | case IB_MAD_RESULT_SUCCESS: | 753 | case IB_MAD_RESULT_SUCCESS: |
| 752 | /* Treat like an incoming receive MAD */ | 754 | /* Treat like an incoming receive MAD */ |
| 753 | port_priv = ib_get_mad_port(mad_agent_priv->agent.device, | 755 | port_priv = ib_get_mad_port(mad_agent_priv->agent.device, |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 79dbe5beae52..992613799228 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -229,7 +229,7 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 229 | struct ib_send_wr **bad_wr) | 229 | struct ib_send_wr **bad_wr) |
| 230 | { | 230 | { |
| 231 | int err = 0; | 231 | int err = 0; |
| 232 | u8 t3_wr_flit_cnt; | 232 | u8 uninitialized_var(t3_wr_flit_cnt); |
| 233 | enum t3_wr_opcode t3_wr_opcode = 0; | 233 | enum t3_wr_opcode t3_wr_opcode = 0; |
| 234 | enum t3_wr_flags t3_wr_flags; | 234 | enum t3_wr_flags t3_wr_flags; |
| 235 | struct iwch_qp *qhp; | 235 | struct iwch_qp *qhp; |
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index 3697449c1ba4..0a8c1b8091a2 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c | |||
| @@ -345,7 +345,7 @@ resched: | |||
| 345 | * state change | 345 | * state change |
| 346 | */ | 346 | */ |
| 347 | if (jiffies > dd->ipath_sdma_abort_jiffies) { | 347 | if (jiffies > dd->ipath_sdma_abort_jiffies) { |
| 348 | ipath_dbg("looping with status 0x%016llx\n", | 348 | ipath_dbg("looping with status 0x%08lx\n", |
| 349 | dd->ipath_sdma_status); | 349 | dd->ipath_sdma_status); |
| 350 | dd->ipath_sdma_abort_jiffies = jiffies + 5 * HZ; | 350 | dd->ipath_sdma_abort_jiffies = jiffies + 5 * HZ; |
| 351 | } | 351 | } |
| @@ -615,7 +615,7 @@ void ipath_restart_sdma(struct ipath_devdata *dd) | |||
| 615 | } | 615 | } |
| 616 | spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); | 616 | spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); |
| 617 | if (!needed) { | 617 | if (!needed) { |
| 618 | ipath_dbg("invalid attempt to restart SDMA, status 0x%016llx\n", | 618 | ipath_dbg("invalid attempt to restart SDMA, status 0x%08lx\n", |
| 619 | dd->ipath_sdma_status); | 619 | dd->ipath_sdma_status); |
| 620 | goto bail; | 620 | goto bail; |
| 621 | } | 621 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c index 7fd18e833907..0596ec16fcbd 100644 --- a/drivers/infiniband/hw/ipath/ipath_uc.c +++ b/drivers/infiniband/hw/ipath/ipath_uc.c | |||
| @@ -407,12 +407,11 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
| 407 | dev->n_pkt_drops++; | 407 | dev->n_pkt_drops++; |
| 408 | goto done; | 408 | goto done; |
| 409 | } | 409 | } |
| 410 | /* XXX Need to free SGEs */ | 410 | wc.opcode = IB_WC_RECV; |
| 411 | last_imm: | 411 | last_imm: |
| 412 | ipath_copy_sge(&qp->r_sge, data, tlen); | 412 | ipath_copy_sge(&qp->r_sge, data, tlen); |
| 413 | wc.wr_id = qp->r_wr_id; | 413 | wc.wr_id = qp->r_wr_id; |
| 414 | wc.status = IB_WC_SUCCESS; | 414 | wc.status = IB_WC_SUCCESS; |
| 415 | wc.opcode = IB_WC_RECV; | ||
| 416 | wc.qp = &qp->ibqp; | 415 | wc.qp = &qp->ibqp; |
| 417 | wc.src_qp = qp->remote_qpn; | 416 | wc.src_qp = qp->remote_qpn; |
| 418 | wc.slid = qp->remote_ah_attr.dlid; | 417 | wc.slid = qp->remote_ah_attr.dlid; |
| @@ -514,6 +513,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
| 514 | goto done; | 513 | goto done; |
| 515 | } | 514 | } |
| 516 | wc.byte_len = qp->r_len; | 515 | wc.byte_len = qp->r_len; |
| 516 | wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; | ||
| 517 | goto last_imm; | 517 | goto last_imm; |
| 518 | 518 | ||
| 519 | case OP(RDMA_WRITE_LAST): | 519 | case OP(RDMA_WRITE_LAST): |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 8e02ecfec188..a80df22deae8 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -333,6 +333,9 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 333 | cap->max_inline_data + sizeof (struct mlx4_wqe_inline_seg)) + | 333 | cap->max_inline_data + sizeof (struct mlx4_wqe_inline_seg)) + |
| 334 | send_wqe_overhead(type, qp->flags); | 334 | send_wqe_overhead(type, qp->flags); |
| 335 | 335 | ||
| 336 | if (s > dev->dev->caps.max_sq_desc_sz) | ||
| 337 | return -EINVAL; | ||
| 338 | |||
| 336 | /* | 339 | /* |
| 337 | * Hermon supports shrinking WQEs, such that a single work | 340 | * Hermon supports shrinking WQEs, such that a single work |
| 338 | * request can include multiple units of 1 << wqe_shift. This | 341 | * request can include multiple units of 1 << wqe_shift. This |
| @@ -372,9 +375,6 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 372 | qp->sq.wqe_shift = ilog2(roundup_pow_of_two(s)); | 375 | qp->sq.wqe_shift = ilog2(roundup_pow_of_two(s)); |
| 373 | 376 | ||
| 374 | for (;;) { | 377 | for (;;) { |
| 375 | if (1 << qp->sq.wqe_shift > dev->dev->caps.max_sq_desc_sz) | ||
| 376 | return -EINVAL; | ||
| 377 | |||
| 378 | qp->sq_max_wqes_per_wr = DIV_ROUND_UP(s, 1U << qp->sq.wqe_shift); | 378 | qp->sq_max_wqes_per_wr = DIV_ROUND_UP(s, 1U << qp->sq.wqe_shift); |
| 379 | 379 | ||
| 380 | /* | 380 | /* |
| @@ -395,7 +395,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 395 | ++qp->sq.wqe_shift; | 395 | ++qp->sq.wqe_shift; |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | qp->sq.max_gs = ((qp->sq_max_wqes_per_wr << qp->sq.wqe_shift) - | 398 | qp->sq.max_gs = (min(dev->dev->caps.max_sq_desc_sz, |
| 399 | (qp->sq_max_wqes_per_wr << qp->sq.wqe_shift)) - | ||
| 399 | send_wqe_overhead(type, qp->flags)) / | 400 | send_wqe_overhead(type, qp->flags)) / |
| 400 | sizeof (struct mlx4_wqe_data_seg); | 401 | sizeof (struct mlx4_wqe_data_seg); |
| 401 | 402 | ||
| @@ -411,7 +412,9 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 411 | 412 | ||
| 412 | cap->max_send_wr = qp->sq.max_post = | 413 | cap->max_send_wr = qp->sq.max_post = |
| 413 | (qp->sq.wqe_cnt - qp->sq_spare_wqes) / qp->sq_max_wqes_per_wr; | 414 | (qp->sq.wqe_cnt - qp->sq_spare_wqes) / qp->sq_max_wqes_per_wr; |
| 414 | cap->max_send_sge = qp->sq.max_gs; | 415 | cap->max_send_sge = min(qp->sq.max_gs, |
| 416 | min(dev->dev->caps.max_sq_sg, | ||
| 417 | dev->dev->caps.max_rq_sg)); | ||
| 415 | /* We don't support inline sends for kernel QPs (yet) */ | 418 | /* We don't support inline sends for kernel QPs (yet) */ |
| 416 | cap->max_inline_data = 0; | 419 | cap->max_inline_data = 0; |
| 417 | 420 | ||
| @@ -1457,7 +1460,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 1457 | unsigned ind; | 1460 | unsigned ind; |
| 1458 | int uninitialized_var(stamp); | 1461 | int uninitialized_var(stamp); |
| 1459 | int uninitialized_var(size); | 1462 | int uninitialized_var(size); |
| 1460 | unsigned seglen; | 1463 | unsigned uninitialized_var(seglen); |
| 1461 | int i; | 1464 | int i; |
| 1462 | 1465 | ||
| 1463 | spin_lock_irqsave(&qp->sq.lock, flags); | 1466 | spin_lock_irqsave(&qp->sq.lock, flags); |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 9ebadd6e0cfb..200cf13fc9bb 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include "mthca_cmd.h" | 45 | #include "mthca_cmd.h" |
| 46 | #include "mthca_profile.h" | 46 | #include "mthca_profile.h" |
| 47 | #include "mthca_memfree.h" | 47 | #include "mthca_memfree.h" |
| 48 | #include "mthca_wqe.h" | ||
| 48 | 49 | ||
| 49 | MODULE_AUTHOR("Roland Dreier"); | 50 | MODULE_AUTHOR("Roland Dreier"); |
| 50 | MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver"); | 51 | MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver"); |
| @@ -200,7 +201,18 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) | |||
| 200 | mdev->limits.gid_table_len = dev_lim->max_gids; | 201 | mdev->limits.gid_table_len = dev_lim->max_gids; |
| 201 | mdev->limits.pkey_table_len = dev_lim->max_pkeys; | 202 | mdev->limits.pkey_table_len = dev_lim->max_pkeys; |
| 202 | mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay; | 203 | mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay; |
| 203 | mdev->limits.max_sg = dev_lim->max_sg; | 204 | /* |
| 205 | * Need to allow for worst case send WQE overhead and check | ||
| 206 | * whether max_desc_sz imposes a lower limit than max_sg; UD | ||
| 207 | * send has the biggest overhead. | ||
| 208 | */ | ||
| 209 | mdev->limits.max_sg = min_t(int, dev_lim->max_sg, | ||
| 210 | (dev_lim->max_desc_sz - | ||
| 211 | sizeof (struct mthca_next_seg) - | ||
| 212 | (mthca_is_memfree(mdev) ? | ||
| 213 | sizeof (struct mthca_arbel_ud_seg) : | ||
| 214 | sizeof (struct mthca_tavor_ud_seg))) / | ||
| 215 | sizeof (struct mthca_data_seg)); | ||
| 204 | mdev->limits.max_wqes = dev_lim->max_qp_sz; | 216 | mdev->limits.max_wqes = dev_lim->max_qp_sz; |
| 205 | mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp; | 217 | mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp; |
| 206 | mdev->limits.reserved_qps = dev_lim->reserved_qps; | 218 | mdev->limits.reserved_qps = dev_lim->reserved_qps; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index d00a2c174aee..3f663fb852c1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
| @@ -194,7 +194,13 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
| 194 | /* Set the cached Q_Key before we attach if it's the broadcast group */ | 194 | /* Set the cached Q_Key before we attach if it's the broadcast group */ |
| 195 | if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4, | 195 | if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4, |
| 196 | sizeof (union ib_gid))) { | 196 | sizeof (union ib_gid))) { |
| 197 | spin_lock_irq(&priv->lock); | ||
| 198 | if (!priv->broadcast) { | ||
| 199 | spin_unlock_irq(&priv->lock); | ||
| 200 | return -EAGAIN; | ||
| 201 | } | ||
| 197 | priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); | 202 | priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); |
| 203 | spin_unlock_irq(&priv->lock); | ||
| 198 | priv->tx_wr.wr.ud.remote_qkey = priv->qkey; | 204 | priv->tx_wr.wr.ud.remote_qkey = priv->qkey; |
| 199 | } | 205 | } |
| 200 | 206 | ||
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index d3999a8e9f88..53f6ad1235db 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c | |||
| @@ -462,11 +462,11 @@ static int hycapi_read_proc(char *page, char **start, off_t off, | |||
| 462 | default: s = "???"; break; | 462 | default: s = "???"; break; |
| 463 | } | 463 | } |
| 464 | len += sprintf(page+len, "%-16s %s\n", "type", s); | 464 | len += sprintf(page+len, "%-16s %s\n", "type", s); |
| 465 | if ((s = cinfo->version[VER_DRIVER]) != 0) | 465 | if ((s = cinfo->version[VER_DRIVER]) != NULL) |
| 466 | len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); | 466 | len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); |
| 467 | if ((s = cinfo->version[VER_CARDTYPE]) != 0) | 467 | if ((s = cinfo->version[VER_CARDTYPE]) != NULL) |
| 468 | len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); | 468 | len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); |
| 469 | if ((s = cinfo->version[VER_SERIAL]) != 0) | 469 | if ((s = cinfo->version[VER_SERIAL]) != NULL) |
| 470 | len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); | 470 | len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); |
| 471 | 471 | ||
| 472 | len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); | 472 | len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index c14dacdacfac..b26927ce889c 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -203,17 +203,6 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page) | |||
| 203 | * bitmap file handling - read and write the bitmap file and its superblock | 203 | * bitmap file handling - read and write the bitmap file and its superblock |
| 204 | */ | 204 | */ |
| 205 | 205 | ||
| 206 | /* copy the pathname of a file to a buffer */ | ||
| 207 | char *file_path(struct file *file, char *buf, int count) | ||
| 208 | { | ||
| 209 | if (!buf) | ||
| 210 | return NULL; | ||
| 211 | |||
| 212 | buf = d_path(&file->f_path, buf, count); | ||
| 213 | |||
| 214 | return IS_ERR(buf) ? NULL : buf; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* | 206 | /* |
| 218 | * basic page I/O operations | 207 | * basic page I/O operations |
| 219 | */ | 208 | */ |
| @@ -721,11 +710,13 @@ static void bitmap_file_kick(struct bitmap *bitmap) | |||
| 721 | if (bitmap->file) { | 710 | if (bitmap->file) { |
| 722 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); | 711 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 723 | if (path) | 712 | if (path) |
| 724 | ptr = file_path(bitmap->file, path, PAGE_SIZE); | 713 | ptr = d_path(&bitmap->file->f_path, path, |
| 714 | PAGE_SIZE); | ||
| 715 | |||
| 725 | 716 | ||
| 726 | printk(KERN_ALERT | 717 | printk(KERN_ALERT |
| 727 | "%s: kicking failed bitmap file %s from array!\n", | 718 | "%s: kicking failed bitmap file %s from array!\n", |
| 728 | bmname(bitmap), ptr ? ptr : ""); | 719 | bmname(bitmap), IS_ERR(ptr) ? "" : ptr); |
| 729 | 720 | ||
| 730 | kfree(path); | 721 | kfree(path); |
| 731 | } else | 722 | } else |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 83eb78b00137..51c19f86ff99 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -74,6 +74,8 @@ static DEFINE_SPINLOCK(pers_lock); | |||
| 74 | 74 | ||
| 75 | static void md_print_devices(void); | 75 | static void md_print_devices(void); |
| 76 | 76 | ||
| 77 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | ||
| 78 | |||
| 77 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } | 79 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } |
| 78 | 80 | ||
| 79 | /* | 81 | /* |
| @@ -3013,6 +3015,36 @@ degraded_show(mddev_t *mddev, char *page) | |||
| 3013 | static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); | 3015 | static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); |
| 3014 | 3016 | ||
| 3015 | static ssize_t | 3017 | static ssize_t |
| 3018 | sync_force_parallel_show(mddev_t *mddev, char *page) | ||
| 3019 | { | ||
| 3020 | return sprintf(page, "%d\n", mddev->parallel_resync); | ||
| 3021 | } | ||
| 3022 | |||
| 3023 | static ssize_t | ||
| 3024 | sync_force_parallel_store(mddev_t *mddev, const char *buf, size_t len) | ||
| 3025 | { | ||
| 3026 | long n; | ||
| 3027 | |||
| 3028 | if (strict_strtol(buf, 10, &n)) | ||
| 3029 | return -EINVAL; | ||
| 3030 | |||
| 3031 | if (n != 0 && n != 1) | ||
| 3032 | return -EINVAL; | ||
| 3033 | |||
| 3034 | mddev->parallel_resync = n; | ||
| 3035 | |||
| 3036 | if (mddev->sync_thread) | ||
| 3037 | wake_up(&resync_wait); | ||
| 3038 | |||
| 3039 | return len; | ||
| 3040 | } | ||
| 3041 | |||
| 3042 | /* force parallel resync, even with shared block devices */ | ||
| 3043 | static struct md_sysfs_entry md_sync_force_parallel = | ||
| 3044 | __ATTR(sync_force_parallel, S_IRUGO|S_IWUSR, | ||
| 3045 | sync_force_parallel_show, sync_force_parallel_store); | ||
| 3046 | |||
| 3047 | static ssize_t | ||
| 3016 | sync_speed_show(mddev_t *mddev, char *page) | 3048 | sync_speed_show(mddev_t *mddev, char *page) |
| 3017 | { | 3049 | { |
| 3018 | unsigned long resync, dt, db; | 3050 | unsigned long resync, dt, db; |
| @@ -3187,6 +3219,7 @@ static struct attribute *md_redundancy_attrs[] = { | |||
| 3187 | &md_sync_min.attr, | 3219 | &md_sync_min.attr, |
| 3188 | &md_sync_max.attr, | 3220 | &md_sync_max.attr, |
| 3189 | &md_sync_speed.attr, | 3221 | &md_sync_speed.attr, |
| 3222 | &md_sync_force_parallel.attr, | ||
| 3190 | &md_sync_completed.attr, | 3223 | &md_sync_completed.attr, |
| 3191 | &md_max_sync.attr, | 3224 | &md_max_sync.attr, |
| 3192 | &md_suspend_lo.attr, | 3225 | &md_suspend_lo.attr, |
| @@ -3691,6 +3724,8 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
| 3691 | 3724 | ||
| 3692 | module_put(mddev->pers->owner); | 3725 | module_put(mddev->pers->owner); |
| 3693 | mddev->pers = NULL; | 3726 | mddev->pers = NULL; |
| 3727 | /* tell userspace to handle 'inactive' */ | ||
| 3728 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
| 3694 | 3729 | ||
| 3695 | set_capacity(disk, 0); | 3730 | set_capacity(disk, 0); |
| 3696 | mddev->changed = 1; | 3731 | mddev->changed = 1; |
| @@ -3987,8 +4022,8 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) | |||
| 3987 | if (!buf) | 4022 | if (!buf) |
| 3988 | goto out; | 4023 | goto out; |
| 3989 | 4024 | ||
| 3990 | ptr = file_path(mddev->bitmap->file, buf, sizeof(file->pathname)); | 4025 | ptr = d_path(&mddev->bitmap->file->f_path, buf, sizeof(file->pathname)); |
| 3991 | if (!ptr) | 4026 | if (IS_ERR(ptr)) |
| 3992 | goto out; | 4027 | goto out; |
| 3993 | 4028 | ||
| 3994 | strcpy(file->pathname, ptr); | 4029 | strcpy(file->pathname, ptr); |
| @@ -5399,7 +5434,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) | |||
| 5399 | atomic_sub(blocks, &mddev->recovery_active); | 5434 | atomic_sub(blocks, &mddev->recovery_active); |
| 5400 | wake_up(&mddev->recovery_wait); | 5435 | wake_up(&mddev->recovery_wait); |
| 5401 | if (!ok) { | 5436 | if (!ok) { |
| 5402 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 5437 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 5403 | md_wakeup_thread(mddev->thread); | 5438 | md_wakeup_thread(mddev->thread); |
| 5404 | // stop recovery, signal do_sync .... | 5439 | // stop recovery, signal do_sync .... |
| 5405 | } | 5440 | } |
| @@ -5435,8 +5470,11 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
| 5435 | md_wakeup_thread(mddev->thread); | 5470 | md_wakeup_thread(mddev->thread); |
| 5436 | } | 5471 | } |
| 5437 | spin_unlock_irq(&mddev->write_lock); | 5472 | spin_unlock_irq(&mddev->write_lock); |
| 5473 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
| 5438 | } | 5474 | } |
| 5439 | wait_event(mddev->sb_wait, mddev->flags==0); | 5475 | wait_event(mddev->sb_wait, |
| 5476 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
| 5477 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | ||
| 5440 | } | 5478 | } |
| 5441 | 5479 | ||
| 5442 | void md_write_end(mddev_t *mddev) | 5480 | void md_write_end(mddev_t *mddev) |
| @@ -5471,13 +5509,17 @@ void md_allow_write(mddev_t *mddev) | |||
| 5471 | mddev->safemode = 1; | 5509 | mddev->safemode = 1; |
| 5472 | spin_unlock_irq(&mddev->write_lock); | 5510 | spin_unlock_irq(&mddev->write_lock); |
| 5473 | md_update_sb(mddev, 0); | 5511 | md_update_sb(mddev, 0); |
| 5512 | |||
| 5513 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
| 5514 | /* wait for the dirty state to be recorded in the metadata */ | ||
| 5515 | wait_event(mddev->sb_wait, | ||
| 5516 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
| 5517 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | ||
| 5474 | } else | 5518 | } else |
| 5475 | spin_unlock_irq(&mddev->write_lock); | 5519 | spin_unlock_irq(&mddev->write_lock); |
| 5476 | } | 5520 | } |
| 5477 | EXPORT_SYMBOL_GPL(md_allow_write); | 5521 | EXPORT_SYMBOL_GPL(md_allow_write); |
| 5478 | 5522 | ||
| 5479 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | ||
| 5480 | |||
| 5481 | #define SYNC_MARKS 10 | 5523 | #define SYNC_MARKS 10 |
| 5482 | #define SYNC_MARK_STEP (3*HZ) | 5524 | #define SYNC_MARK_STEP (3*HZ) |
| 5483 | void md_do_sync(mddev_t *mddev) | 5525 | void md_do_sync(mddev_t *mddev) |
| @@ -5541,8 +5583,9 @@ void md_do_sync(mddev_t *mddev) | |||
| 5541 | for_each_mddev(mddev2, tmp) { | 5583 | for_each_mddev(mddev2, tmp) { |
| 5542 | if (mddev2 == mddev) | 5584 | if (mddev2 == mddev) |
| 5543 | continue; | 5585 | continue; |
| 5544 | if (mddev2->curr_resync && | 5586 | if (!mddev->parallel_resync |
| 5545 | match_mddev_units(mddev,mddev2)) { | 5587 | && mddev2->curr_resync |
| 5588 | && match_mddev_units(mddev, mddev2)) { | ||
| 5546 | DEFINE_WAIT(wq); | 5589 | DEFINE_WAIT(wq); |
| 5547 | if (mddev < mddev2 && mddev->curr_resync == 2) { | 5590 | if (mddev < mddev2 && mddev->curr_resync == 2) { |
| 5548 | /* arbitrarily yield */ | 5591 | /* arbitrarily yield */ |
| @@ -5647,7 +5690,7 @@ void md_do_sync(mddev_t *mddev) | |||
| 5647 | sectors = mddev->pers->sync_request(mddev, j, &skipped, | 5690 | sectors = mddev->pers->sync_request(mddev, j, &skipped, |
| 5648 | currspeed < speed_min(mddev)); | 5691 | currspeed < speed_min(mddev)); |
| 5649 | if (sectors == 0) { | 5692 | if (sectors == 0) { |
| 5650 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 5693 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 5651 | goto out; | 5694 | goto out; |
| 5652 | } | 5695 | } |
| 5653 | 5696 | ||
| @@ -5670,8 +5713,7 @@ void md_do_sync(mddev_t *mddev) | |||
| 5670 | 5713 | ||
| 5671 | last_check = io_sectors; | 5714 | last_check = io_sectors; |
| 5672 | 5715 | ||
| 5673 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) || | 5716 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) |
| 5674 | test_bit(MD_RECOVERY_ERR, &mddev->recovery)) | ||
| 5675 | break; | 5717 | break; |
| 5676 | 5718 | ||
| 5677 | repeat: | 5719 | repeat: |
| @@ -5725,8 +5767,7 @@ void md_do_sync(mddev_t *mddev) | |||
| 5725 | /* tell personality that we are finished */ | 5767 | /* tell personality that we are finished */ |
| 5726 | mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); | 5768 | mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); |
| 5727 | 5769 | ||
| 5728 | if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && | 5770 | if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && |
| 5729 | !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && | ||
| 5730 | mddev->curr_resync > 2) { | 5771 | mddev->curr_resync > 2) { |
| 5731 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | 5772 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
| 5732 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 5773 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
| @@ -5795,7 +5836,10 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 5795 | } | 5836 | } |
| 5796 | 5837 | ||
| 5797 | if (mddev->degraded) { | 5838 | if (mddev->degraded) { |
| 5798 | rdev_for_each(rdev, rtmp, mddev) | 5839 | rdev_for_each(rdev, rtmp, mddev) { |
| 5840 | if (rdev->raid_disk >= 0 && | ||
| 5841 | !test_bit(In_sync, &rdev->flags)) | ||
| 5842 | spares++; | ||
| 5799 | if (rdev->raid_disk < 0 | 5843 | if (rdev->raid_disk < 0 |
| 5800 | && !test_bit(Faulty, &rdev->flags)) { | 5844 | && !test_bit(Faulty, &rdev->flags)) { |
| 5801 | rdev->recovery_offset = 0; | 5845 | rdev->recovery_offset = 0; |
| @@ -5813,6 +5857,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 5813 | } else | 5857 | } else |
| 5814 | break; | 5858 | break; |
| 5815 | } | 5859 | } |
| 5860 | } | ||
| 5816 | } | 5861 | } |
| 5817 | return spares; | 5862 | return spares; |
| 5818 | } | 5863 | } |
| @@ -5826,7 +5871,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 5826 | * to do that as needed. | 5871 | * to do that as needed. |
| 5827 | * When it is determined that resync is needed, we set MD_RECOVERY_RUNNING in | 5872 | * When it is determined that resync is needed, we set MD_RECOVERY_RUNNING in |
| 5828 | * "->recovery" and create a thread at ->sync_thread. | 5873 | * "->recovery" and create a thread at ->sync_thread. |
| 5829 | * When the thread finishes it sets MD_RECOVERY_DONE (and might set MD_RECOVERY_ERR) | 5874 | * When the thread finishes it sets MD_RECOVERY_DONE |
| 5830 | * and wakeups up this thread which will reap the thread and finish up. | 5875 | * and wakeups up this thread which will reap the thread and finish up. |
| 5831 | * This thread also removes any faulty devices (with nr_pending == 0). | 5876 | * This thread also removes any faulty devices (with nr_pending == 0). |
| 5832 | * | 5877 | * |
| @@ -5901,8 +5946,7 @@ void md_check_recovery(mddev_t *mddev) | |||
| 5901 | /* resync has finished, collect result */ | 5946 | /* resync has finished, collect result */ |
| 5902 | md_unregister_thread(mddev->sync_thread); | 5947 | md_unregister_thread(mddev->sync_thread); |
| 5903 | mddev->sync_thread = NULL; | 5948 | mddev->sync_thread = NULL; |
| 5904 | if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && | 5949 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
| 5905 | !test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | ||
| 5906 | /* success...*/ | 5950 | /* success...*/ |
| 5907 | /* activate any spares */ | 5951 | /* activate any spares */ |
| 5908 | mddev->pers->spare_active(mddev); | 5952 | mddev->pers->spare_active(mddev); |
| @@ -5926,7 +5970,6 @@ void md_check_recovery(mddev_t *mddev) | |||
| 5926 | * might be left set | 5970 | * might be left set |
| 5927 | */ | 5971 | */ |
| 5928 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 5972 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 5929 | clear_bit(MD_RECOVERY_ERR, &mddev->recovery); | ||
| 5930 | clear_bit(MD_RECOVERY_INTR, &mddev->recovery); | 5973 | clear_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 5931 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); | 5974 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); |
| 5932 | 5975 | ||
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 4f4d1f383842..e968116e0de9 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
| @@ -327,7 +327,8 @@ static int multipath_remove_disk(mddev_t *mddev, int number) | |||
| 327 | if (rdev) { | 327 | if (rdev) { |
| 328 | if (test_bit(In_sync, &rdev->flags) || | 328 | if (test_bit(In_sync, &rdev->flags) || |
| 329 | atomic_read(&rdev->nr_pending)) { | 329 | atomic_read(&rdev->nr_pending)) { |
| 330 | printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); | 330 | printk(KERN_ERR "hot-remove-disk, slot %d is identified" |
| 331 | " but is still operational!\n", number); | ||
| 331 | err = -EBUSY; | 332 | err = -EBUSY; |
| 332 | goto abort; | 333 | goto abort; |
| 333 | } | 334 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ac409b7d83f5..c610b947218a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -773,7 +773,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
| 773 | r1bio_t *r1_bio; | 773 | r1bio_t *r1_bio; |
| 774 | struct bio *read_bio; | 774 | struct bio *read_bio; |
| 775 | int i, targets = 0, disks; | 775 | int i, targets = 0, disks; |
| 776 | struct bitmap *bitmap = mddev->bitmap; | 776 | struct bitmap *bitmap; |
| 777 | unsigned long flags; | 777 | unsigned long flags; |
| 778 | struct bio_list bl; | 778 | struct bio_list bl; |
| 779 | struct page **behind_pages = NULL; | 779 | struct page **behind_pages = NULL; |
| @@ -802,6 +802,8 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
| 802 | 802 | ||
| 803 | wait_barrier(conf); | 803 | wait_barrier(conf); |
| 804 | 804 | ||
| 805 | bitmap = mddev->bitmap; | ||
| 806 | |||
| 805 | disk_stat_inc(mddev->gendisk, ios[rw]); | 807 | disk_stat_inc(mddev->gendisk, ios[rw]); |
| 806 | disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); | 808 | disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); |
| 807 | 809 | ||
| @@ -1025,7 +1027,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1025 | /* | 1027 | /* |
| 1026 | * if recovery is running, make sure it aborts. | 1028 | * if recovery is running, make sure it aborts. |
| 1027 | */ | 1029 | */ |
| 1028 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1030 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 1029 | } else | 1031 | } else |
| 1030 | set_bit(Faulty, &rdev->flags); | 1032 | set_bit(Faulty, &rdev->flags); |
| 1031 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 1033 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
| @@ -1146,6 +1148,14 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
| 1146 | err = -EBUSY; | 1148 | err = -EBUSY; |
| 1147 | goto abort; | 1149 | goto abort; |
| 1148 | } | 1150 | } |
| 1151 | /* Only remove non-faulty devices is recovery | ||
| 1152 | * is not possible. | ||
| 1153 | */ | ||
| 1154 | if (!test_bit(Faulty, &rdev->flags) && | ||
| 1155 | mddev->degraded < conf->raid_disks) { | ||
| 1156 | err = -EBUSY; | ||
| 1157 | goto abort; | ||
| 1158 | } | ||
| 1149 | p->rdev = NULL; | 1159 | p->rdev = NULL; |
| 1150 | synchronize_rcu(); | 1160 | synchronize_rcu(); |
| 1151 | if (atomic_read(&rdev->nr_pending)) { | 1161 | if (atomic_read(&rdev->nr_pending)) { |
| @@ -1282,6 +1292,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) | |||
| 1282 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); | 1292 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); |
| 1283 | } else { | 1293 | } else { |
| 1284 | /* fixup the bio for reuse */ | 1294 | /* fixup the bio for reuse */ |
| 1295 | int size; | ||
| 1285 | sbio->bi_vcnt = vcnt; | 1296 | sbio->bi_vcnt = vcnt; |
| 1286 | sbio->bi_size = r1_bio->sectors << 9; | 1297 | sbio->bi_size = r1_bio->sectors << 9; |
| 1287 | sbio->bi_idx = 0; | 1298 | sbio->bi_idx = 0; |
| @@ -1295,10 +1306,20 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) | |||
| 1295 | sbio->bi_sector = r1_bio->sector + | 1306 | sbio->bi_sector = r1_bio->sector + |
| 1296 | conf->mirrors[i].rdev->data_offset; | 1307 | conf->mirrors[i].rdev->data_offset; |
| 1297 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1308 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; |
| 1298 | for (j = 0; j < vcnt ; j++) | 1309 | size = sbio->bi_size; |
| 1299 | memcpy(page_address(sbio->bi_io_vec[j].bv_page), | 1310 | for (j = 0; j < vcnt ; j++) { |
| 1311 | struct bio_vec *bi; | ||
| 1312 | bi = &sbio->bi_io_vec[j]; | ||
| 1313 | bi->bv_offset = 0; | ||
| 1314 | if (size > PAGE_SIZE) | ||
| 1315 | bi->bv_len = PAGE_SIZE; | ||
| 1316 | else | ||
| 1317 | bi->bv_len = size; | ||
| 1318 | size -= PAGE_SIZE; | ||
| 1319 | memcpy(page_address(bi->bv_page), | ||
| 1300 | page_address(pbio->bi_io_vec[j].bv_page), | 1320 | page_address(pbio->bi_io_vec[j].bv_page), |
| 1301 | PAGE_SIZE); | 1321 | PAGE_SIZE); |
| 1322 | } | ||
| 1302 | 1323 | ||
| 1303 | } | 1324 | } |
| 1304 | } | 1325 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8536ede1e712..1de17da34a95 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -1020,7 +1020,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1020 | /* | 1020 | /* |
| 1021 | * if recovery is running, make sure it aborts. | 1021 | * if recovery is running, make sure it aborts. |
| 1022 | */ | 1022 | */ |
| 1023 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1023 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 1024 | } | 1024 | } |
| 1025 | set_bit(Faulty, &rdev->flags); | 1025 | set_bit(Faulty, &rdev->flags); |
| 1026 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 1026 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
| @@ -1171,6 +1171,14 @@ static int raid10_remove_disk(mddev_t *mddev, int number) | |||
| 1171 | err = -EBUSY; | 1171 | err = -EBUSY; |
| 1172 | goto abort; | 1172 | goto abort; |
| 1173 | } | 1173 | } |
| 1174 | /* Only remove faulty devices in recovery | ||
| 1175 | * is not possible. | ||
| 1176 | */ | ||
| 1177 | if (!test_bit(Faulty, &rdev->flags) && | ||
| 1178 | enough(conf)) { | ||
| 1179 | err = -EBUSY; | ||
| 1180 | goto abort; | ||
| 1181 | } | ||
| 1174 | p->rdev = NULL; | 1182 | p->rdev = NULL; |
| 1175 | synchronize_rcu(); | 1183 | synchronize_rcu(); |
| 1176 | if (atomic_read(&rdev->nr_pending)) { | 1184 | if (atomic_read(&rdev->nr_pending)) { |
| @@ -1237,6 +1245,7 @@ static void end_sync_write(struct bio *bio, int error) | |||
| 1237 | 1245 | ||
| 1238 | if (!uptodate) | 1246 | if (!uptodate) |
| 1239 | md_error(mddev, conf->mirrors[d].rdev); | 1247 | md_error(mddev, conf->mirrors[d].rdev); |
| 1248 | |||
| 1240 | update_head_pos(i, r10_bio); | 1249 | update_head_pos(i, r10_bio); |
| 1241 | 1250 | ||
| 1242 | while (atomic_dec_and_test(&r10_bio->remaining)) { | 1251 | while (atomic_dec_and_test(&r10_bio->remaining)) { |
| @@ -1844,7 +1853,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1844 | if (rb2) | 1853 | if (rb2) |
| 1845 | atomic_dec(&rb2->remaining); | 1854 | atomic_dec(&rb2->remaining); |
| 1846 | r10_bio = rb2; | 1855 | r10_bio = rb2; |
| 1847 | if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery)) | 1856 | if (!test_and_set_bit(MD_RECOVERY_INTR, |
| 1857 | &mddev->recovery)) | ||
| 1848 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", | 1858 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", |
| 1849 | mdname(mddev)); | 1859 | mdname(mddev)); |
| 1850 | break; | 1860 | break; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 93fde48c0f42..425958a76b84 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -94,6 +94,8 @@ | |||
| 94 | #define __inline__ | 94 | #define __inline__ |
| 95 | #endif | 95 | #endif |
| 96 | 96 | ||
| 97 | #define printk_rl(args...) ((void) (printk_ratelimit() && printk(args))) | ||
| 98 | |||
| 97 | #if !RAID6_USE_EMPTY_ZERO_PAGE | 99 | #if !RAID6_USE_EMPTY_ZERO_PAGE |
| 98 | /* In .bss so it's zeroed */ | 100 | /* In .bss so it's zeroed */ |
| 99 | const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); | 101 | const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); |
| @@ -1143,10 +1145,12 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
| 1143 | set_bit(R5_UPTODATE, &sh->dev[i].flags); | 1145 | set_bit(R5_UPTODATE, &sh->dev[i].flags); |
| 1144 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | 1146 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { |
| 1145 | rdev = conf->disks[i].rdev; | 1147 | rdev = conf->disks[i].rdev; |
| 1146 | printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n", | 1148 | printk_rl(KERN_INFO "raid5:%s: read error corrected" |
| 1147 | mdname(conf->mddev), STRIPE_SECTORS, | 1149 | " (%lu sectors at %llu on %s)\n", |
| 1148 | (unsigned long long)(sh->sector + rdev->data_offset), | 1150 | mdname(conf->mddev), STRIPE_SECTORS, |
| 1149 | bdevname(rdev->bdev, b)); | 1151 | (unsigned long long)(sh->sector |
| 1152 | + rdev->data_offset), | ||
| 1153 | bdevname(rdev->bdev, b)); | ||
| 1150 | clear_bit(R5_ReadError, &sh->dev[i].flags); | 1154 | clear_bit(R5_ReadError, &sh->dev[i].flags); |
| 1151 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | 1155 | clear_bit(R5_ReWrite, &sh->dev[i].flags); |
| 1152 | } | 1156 | } |
| @@ -1160,16 +1164,22 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
| 1160 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); | 1164 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); |
| 1161 | atomic_inc(&rdev->read_errors); | 1165 | atomic_inc(&rdev->read_errors); |
| 1162 | if (conf->mddev->degraded) | 1166 | if (conf->mddev->degraded) |
| 1163 | printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n", | 1167 | printk_rl(KERN_WARNING |
| 1164 | mdname(conf->mddev), | 1168 | "raid5:%s: read error not correctable " |
| 1165 | (unsigned long long)(sh->sector + rdev->data_offset), | 1169 | "(sector %llu on %s).\n", |
| 1166 | bdn); | 1170 | mdname(conf->mddev), |
| 1171 | (unsigned long long)(sh->sector | ||
| 1172 | + rdev->data_offset), | ||
| 1173 | bdn); | ||
| 1167 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) | 1174 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) |
| 1168 | /* Oh, no!!! */ | 1175 | /* Oh, no!!! */ |
| 1169 | printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n", | 1176 | printk_rl(KERN_WARNING |
| 1170 | mdname(conf->mddev), | 1177 | "raid5:%s: read error NOT corrected!! " |
| 1171 | (unsigned long long)(sh->sector + rdev->data_offset), | 1178 | "(sector %llu on %s).\n", |
| 1172 | bdn); | 1179 | mdname(conf->mddev), |
| 1180 | (unsigned long long)(sh->sector | ||
| 1181 | + rdev->data_offset), | ||
| 1182 | bdn); | ||
| 1173 | else if (atomic_read(&rdev->read_errors) | 1183 | else if (atomic_read(&rdev->read_errors) |
| 1174 | > conf->max_nr_stripes) | 1184 | > conf->max_nr_stripes) |
| 1175 | printk(KERN_WARNING | 1185 | printk(KERN_WARNING |
| @@ -1258,7 +1268,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1258 | /* | 1268 | /* |
| 1259 | * if recovery was running, make sure it aborts. | 1269 | * if recovery was running, make sure it aborts. |
| 1260 | */ | 1270 | */ |
| 1261 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1271 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 1262 | } | 1272 | } |
| 1263 | set_bit(Faulty, &rdev->flags); | 1273 | set_bit(Faulty, &rdev->flags); |
| 1264 | printk (KERN_ALERT | 1274 | printk (KERN_ALERT |
| @@ -4564,6 +4574,14 @@ static int raid5_remove_disk(mddev_t *mddev, int number) | |||
| 4564 | err = -EBUSY; | 4574 | err = -EBUSY; |
| 4565 | goto abort; | 4575 | goto abort; |
| 4566 | } | 4576 | } |
| 4577 | /* Only remove non-faulty devices if recovery | ||
| 4578 | * isn't possible. | ||
| 4579 | */ | ||
| 4580 | if (!test_bit(Faulty, &rdev->flags) && | ||
| 4581 | mddev->degraded <= conf->max_degraded) { | ||
| 4582 | err = -EBUSY; | ||
| 4583 | goto abort; | ||
| 4584 | } | ||
| 4567 | p->rdev = NULL; | 4585 | p->rdev = NULL; |
| 4568 | synchronize_rcu(); | 4586 | synchronize_rcu(); |
| 4569 | if (atomic_read(&rdev->nr_pending)) { | 4587 | if (atomic_read(&rdev->nr_pending)) { |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index b31faeccb9cd..867f6fd5c2c0 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
| @@ -1278,7 +1278,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
| 1278 | error = 0; | 1278 | error = 0; |
| 1279 | /* Check for command packet errors */ | 1279 | /* Check for command packet errors */ |
| 1280 | if (full_command_packet->command.newcommand.status != 0) { | 1280 | if (full_command_packet->command.newcommand.status != 0) { |
| 1281 | if (tw_dev->srb[request_id] != 0) { | 1281 | if (tw_dev->srb[request_id] != NULL) { |
| 1282 | error = twa_fill_sense(tw_dev, request_id, 1, 1); | 1282 | error = twa_fill_sense(tw_dev, request_id, 1, 1); |
| 1283 | } else { | 1283 | } else { |
| 1284 | /* Skip ioctl error prints */ | 1284 | /* Skip ioctl error prints */ |
| @@ -1290,7 +1290,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
| 1290 | 1290 | ||
| 1291 | /* Check for correct state */ | 1291 | /* Check for correct state */ |
| 1292 | if (tw_dev->state[request_id] != TW_S_POSTED) { | 1292 | if (tw_dev->state[request_id] != TW_S_POSTED) { |
| 1293 | if (tw_dev->srb[request_id] != 0) { | 1293 | if (tw_dev->srb[request_id] != NULL) { |
| 1294 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted"); | 1294 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted"); |
| 1295 | TW_CLEAR_ALL_INTERRUPTS(tw_dev); | 1295 | TW_CLEAR_ALL_INTERRUPTS(tw_dev); |
| 1296 | goto twa_interrupt_bail; | 1296 | goto twa_interrupt_bail; |
| @@ -1298,7 +1298,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
| 1298 | } | 1298 | } |
| 1299 | 1299 | ||
| 1300 | /* Check for internal command completion */ | 1300 | /* Check for internal command completion */ |
| 1301 | if (tw_dev->srb[request_id] == 0) { | 1301 | if (tw_dev->srb[request_id] == NULL) { |
| 1302 | if (request_id != tw_dev->chrdev_request_id) { | 1302 | if (request_id != tw_dev->chrdev_request_id) { |
| 1303 | if (twa_aen_complete(tw_dev, request_id)) | 1303 | if (twa_aen_complete(tw_dev, request_id)) |
| 1304 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt"); | 1304 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt"); |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 1dca1775f4b1..0899cb61e3dd 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
| @@ -3582,7 +3582,7 @@ static int checksetup(struct aha152x_setup *setup) | |||
| 3582 | if (i == ARRAY_SIZE(ports)) | 3582 | if (i == ARRAY_SIZE(ports)) |
| 3583 | return 0; | 3583 | return 0; |
| 3584 | 3584 | ||
| 3585 | if ( request_region(setup->io_port, IO_RANGE, "aha152x")==0 ) { | 3585 | if (!request_region(setup->io_port, IO_RANGE, "aha152x")) { |
| 3586 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port); | 3586 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port); |
| 3587 | return 0; | 3587 | return 0; |
| 3588 | } | 3588 | } |
| @@ -3842,7 +3842,7 @@ static int __init aha152x_init(void) | |||
| 3842 | if ((setup_count == 1) && (setup[0].io_port == ports[i])) | 3842 | if ((setup_count == 1) && (setup[0].io_port == ports[i])) |
| 3843 | continue; | 3843 | continue; |
| 3844 | 3844 | ||
| 3845 | if ( request_region(ports[i], IO_RANGE, "aha152x")==0 ) { | 3845 | if (!request_region(ports[i], IO_RANGE, "aha152x")) { |
| 3846 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]); | 3846 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]); |
| 3847 | continue; | 3847 | continue; |
| 3848 | } | 3848 | } |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index db6de5e6afb3..7d311541c76c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
| @@ -747,7 +747,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) | |||
| 747 | dev->quhd[c] = 0; | 747 | dev->quhd[c] = 0; |
| 748 | } | 748 | } |
| 749 | workreq = dev->quereq[c][dev->quhd[c]]; | 749 | workreq = dev->quereq[c][dev->quhd[c]]; |
| 750 | if (dev->id[c][scmd_id(workreq)].curr_req == 0) { | 750 | if (dev->id[c][scmd_id(workreq)].curr_req == NULL) { |
| 751 | dev->id[c][scmd_id(workreq)].curr_req = workreq; | 751 | dev->id[c][scmd_id(workreq)].curr_req = workreq; |
| 752 | dev->last_cmd[c] = scmd_id(workreq); | 752 | dev->last_cmd[c] = scmd_id(workreq); |
| 753 | goto cmd_subp; | 753 | goto cmd_subp; |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index aaa48e0c8ed0..da876d3924be 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
| @@ -444,7 +444,7 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index) | |||
| 444 | if (!(pci_resource_flags(pcidev, index) & IORESOURCE_MEM)) { | 444 | if (!(pci_resource_flags(pcidev, index) & IORESOURCE_MEM)) { |
| 445 | printk(KERN_ERR "scsi%d: pci resource invalid\n", | 445 | printk(KERN_ERR "scsi%d: pci resource invalid\n", |
| 446 | hba->host->host_no); | 446 | hba->host->host_no); |
| 447 | return 0; | 447 | return NULL; |
| 448 | } | 448 | } |
| 449 | 449 | ||
| 450 | mem_base_phy = pci_resource_start(pcidev, index); | 450 | mem_base_phy = pci_resource_start(pcidev, index); |
| @@ -454,7 +454,7 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index) | |||
| 454 | if (!mem_base_virt) { | 454 | if (!mem_base_virt) { |
| 455 | printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n", | 455 | printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n", |
| 456 | hba->host->host_no); | 456 | hba->host->host_no); |
| 457 | return 0; | 457 | return NULL; |
| 458 | } | 458 | } |
| 459 | return mem_base_virt; | 459 | return mem_base_virt; |
| 460 | } | 460 | } |
| @@ -476,11 +476,11 @@ static void hptiop_unmap_pci_bar_itl(struct hptiop_hba *hba) | |||
| 476 | static int hptiop_map_pci_bar_mv(struct hptiop_hba *hba) | 476 | static int hptiop_map_pci_bar_mv(struct hptiop_hba *hba) |
| 477 | { | 477 | { |
| 478 | hba->u.mv.regs = hptiop_map_pci_bar(hba, 0); | 478 | hba->u.mv.regs = hptiop_map_pci_bar(hba, 0); |
| 479 | if (hba->u.mv.regs == 0) | 479 | if (hba->u.mv.regs == NULL) |
| 480 | return -1; | 480 | return -1; |
| 481 | 481 | ||
| 482 | hba->u.mv.mu = hptiop_map_pci_bar(hba, 2); | 482 | hba->u.mv.mu = hptiop_map_pci_bar(hba, 2); |
| 483 | if (hba->u.mv.mu == 0) { | 483 | if (hba->u.mv.mu == NULL) { |
| 484 | iounmap(hba->u.mv.regs); | 484 | iounmap(hba->u.mv.regs); |
| 485 | return -1; | 485 | return -1; |
| 486 | } | 486 | } |
| @@ -1210,8 +1210,8 @@ static void hptiop_remove(struct pci_dev *pcidev) | |||
| 1210 | 1210 | ||
| 1211 | static struct hptiop_adapter_ops hptiop_itl_ops = { | 1211 | static struct hptiop_adapter_ops hptiop_itl_ops = { |
| 1212 | .iop_wait_ready = iop_wait_ready_itl, | 1212 | .iop_wait_ready = iop_wait_ready_itl, |
| 1213 | .internal_memalloc = 0, | 1213 | .internal_memalloc = NULL, |
| 1214 | .internal_memfree = 0, | 1214 | .internal_memfree = NULL, |
| 1215 | .map_pci_bar = hptiop_map_pci_bar_itl, | 1215 | .map_pci_bar = hptiop_map_pci_bar_itl, |
| 1216 | .unmap_pci_bar = hptiop_unmap_pci_bar_itl, | 1216 | .unmap_pci_bar = hptiop_unmap_pci_bar_itl, |
| 1217 | .enable_intr = hptiop_enable_intr_itl, | 1217 | .enable_intr = hptiop_enable_intr_itl, |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 51e2f299dbbb..3754ab87f89a 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
| @@ -2811,7 +2811,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) | |||
| 2811 | 2811 | ||
| 2812 | /* Check for room in outstanding command list. */ | 2812 | /* Check for room in outstanding command list. */ |
| 2813 | for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && | 2813 | for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && |
| 2814 | ha->outstanding_cmds[cnt] != 0; cnt++); | 2814 | ha->outstanding_cmds[cnt] != NULL; cnt++); |
| 2815 | 2815 | ||
| 2816 | if (cnt >= MAX_OUTSTANDING_COMMANDS) { | 2816 | if (cnt >= MAX_OUTSTANDING_COMMANDS) { |
| 2817 | status = 1; | 2817 | status = 1; |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 53fa19cf2f06..788c3559522d 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
| @@ -2602,7 +2602,12 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 2602 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, | 2602 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, |
| 2603 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ | 2603 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ |
| 2604 | pbn_b2_2_115200 }, | 2604 | pbn_b2_2_115200 }, |
| 2605 | 2605 | /* | |
| 2606 | * IntaShield IS-400 | ||
| 2607 | */ | ||
| 2608 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, | ||
| 2609 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ | ||
| 2610 | pbn_b2_4_115200 }, | ||
| 2606 | /* | 2611 | /* |
| 2607 | * Perle PCI-RAS cards | 2612 | * Perle PCI-RAS cards |
| 2608 | */ | 2613 | */ |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index eab032733790..53b03c629aff 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
| @@ -2054,6 +2054,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) | |||
| 2054 | int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | 2054 | int uart_resume_port(struct uart_driver *drv, struct uart_port *port) |
| 2055 | { | 2055 | { |
| 2056 | struct uart_state *state = drv->state + port->line; | 2056 | struct uart_state *state = drv->state + port->line; |
| 2057 | struct device *tty_dev; | ||
| 2058 | struct uart_match match = {port, drv}; | ||
| 2057 | 2059 | ||
| 2058 | mutex_lock(&state->mutex); | 2060 | mutex_lock(&state->mutex); |
| 2059 | 2061 | ||
| @@ -2063,7 +2065,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | |||
| 2063 | return 0; | 2065 | return 0; |
| 2064 | } | 2066 | } |
| 2065 | 2067 | ||
| 2066 | if (!port->suspended) { | 2068 | tty_dev = device_find_child(port->dev, &match, serial_match_port); |
| 2069 | if (!port->suspended && device_may_wakeup(tty_dev)) { | ||
| 2067 | disable_irq_wake(port->irq); | 2070 | disable_irq_wake(port->irq); |
| 2068 | mutex_unlock(&state->mutex); | 2071 | mutex_unlock(&state->mutex); |
| 2069 | return 0; | 2072 | return 0; |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index b3518ca9f04e..41620c0fb046 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
| @@ -68,6 +68,7 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; | |||
| 68 | 68 | ||
| 69 | struct spidev_data { | 69 | struct spidev_data { |
| 70 | struct device dev; | 70 | struct device dev; |
| 71 | spinlock_t spi_lock; | ||
| 71 | struct spi_device *spi; | 72 | struct spi_device *spi; |
| 72 | struct list_head device_entry; | 73 | struct list_head device_entry; |
| 73 | 74 | ||
| @@ -85,12 +86,75 @@ MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message"); | |||
| 85 | 86 | ||
| 86 | /*-------------------------------------------------------------------------*/ | 87 | /*-------------------------------------------------------------------------*/ |
| 87 | 88 | ||
| 89 | /* | ||
| 90 | * We can't use the standard synchronous wrappers for file I/O; we | ||
| 91 | * need to protect against async removal of the underlying spi_device. | ||
| 92 | */ | ||
| 93 | static void spidev_complete(void *arg) | ||
| 94 | { | ||
| 95 | complete(arg); | ||
| 96 | } | ||
| 97 | |||
| 98 | static ssize_t | ||
| 99 | spidev_sync(struct spidev_data *spidev, struct spi_message *message) | ||
| 100 | { | ||
| 101 | DECLARE_COMPLETION_ONSTACK(done); | ||
| 102 | int status; | ||
| 103 | |||
| 104 | message->complete = spidev_complete; | ||
| 105 | message->context = &done; | ||
| 106 | |||
| 107 | spin_lock_irq(&spidev->spi_lock); | ||
| 108 | if (spidev->spi == NULL) | ||
| 109 | status = -ESHUTDOWN; | ||
| 110 | else | ||
| 111 | status = spi_async(spidev->spi, message); | ||
| 112 | spin_unlock_irq(&spidev->spi_lock); | ||
| 113 | |||
| 114 | if (status == 0) { | ||
| 115 | wait_for_completion(&done); | ||
| 116 | status = message->status; | ||
| 117 | if (status == 0) | ||
| 118 | status = message->actual_length; | ||
| 119 | } | ||
| 120 | return status; | ||
| 121 | } | ||
| 122 | |||
| 123 | static inline ssize_t | ||
| 124 | spidev_sync_write(struct spidev_data *spidev, size_t len) | ||
| 125 | { | ||
| 126 | struct spi_transfer t = { | ||
| 127 | .tx_buf = spidev->buffer, | ||
| 128 | .len = len, | ||
| 129 | }; | ||
| 130 | struct spi_message m; | ||
| 131 | |||
| 132 | spi_message_init(&m); | ||
| 133 | spi_message_add_tail(&t, &m); | ||
| 134 | return spidev_sync(spidev, &m); | ||
| 135 | } | ||
| 136 | |||
| 137 | static inline ssize_t | ||
| 138 | spidev_sync_read(struct spidev_data *spidev, size_t len) | ||
| 139 | { | ||
| 140 | struct spi_transfer t = { | ||
| 141 | .rx_buf = spidev->buffer, | ||
| 142 | .len = len, | ||
| 143 | }; | ||
| 144 | struct spi_message m; | ||
| 145 | |||
| 146 | spi_message_init(&m); | ||
| 147 | spi_message_add_tail(&t, &m); | ||
| 148 | return spidev_sync(spidev, &m); | ||
| 149 | } | ||
| 150 | |||
| 151 | /*-------------------------------------------------------------------------*/ | ||
| 152 | |||
| 88 | /* Read-only message with current device setup */ | 153 | /* Read-only message with current device setup */ |
| 89 | static ssize_t | 154 | static ssize_t |
| 90 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | 155 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) |
| 91 | { | 156 | { |
| 92 | struct spidev_data *spidev; | 157 | struct spidev_data *spidev; |
| 93 | struct spi_device *spi; | ||
| 94 | ssize_t status = 0; | 158 | ssize_t status = 0; |
| 95 | 159 | ||
| 96 | /* chipselect only toggles at start or end of operation */ | 160 | /* chipselect only toggles at start or end of operation */ |
| @@ -98,10 +162,9 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | |||
| 98 | return -EMSGSIZE; | 162 | return -EMSGSIZE; |
| 99 | 163 | ||
| 100 | spidev = filp->private_data; | 164 | spidev = filp->private_data; |
| 101 | spi = spidev->spi; | ||
| 102 | 165 | ||
| 103 | mutex_lock(&spidev->buf_lock); | 166 | mutex_lock(&spidev->buf_lock); |
| 104 | status = spi_read(spi, spidev->buffer, count); | 167 | status = spidev_sync_read(spidev, count); |
| 105 | if (status == 0) { | 168 | if (status == 0) { |
| 106 | unsigned long missing; | 169 | unsigned long missing; |
| 107 | 170 | ||
| @@ -122,7 +185,6 @@ spidev_write(struct file *filp, const char __user *buf, | |||
| 122 | size_t count, loff_t *f_pos) | 185 | size_t count, loff_t *f_pos) |
| 123 | { | 186 | { |
| 124 | struct spidev_data *spidev; | 187 | struct spidev_data *spidev; |
| 125 | struct spi_device *spi; | ||
| 126 | ssize_t status = 0; | 188 | ssize_t status = 0; |
| 127 | unsigned long missing; | 189 | unsigned long missing; |
| 128 | 190 | ||
| @@ -131,12 +193,11 @@ spidev_write(struct file *filp, const char __user *buf, | |||
| 131 | return -EMSGSIZE; | 193 | return -EMSGSIZE; |
| 132 | 194 | ||
| 133 | spidev = filp->private_data; | 195 | spidev = filp->private_data; |
| 134 | spi = spidev->spi; | ||
| 135 | 196 | ||
| 136 | mutex_lock(&spidev->buf_lock); | 197 | mutex_lock(&spidev->buf_lock); |
| 137 | missing = copy_from_user(spidev->buffer, buf, count); | 198 | missing = copy_from_user(spidev->buffer, buf, count); |
| 138 | if (missing == 0) { | 199 | if (missing == 0) { |
| 139 | status = spi_write(spi, spidev->buffer, count); | 200 | status = spidev_sync_write(spidev, count); |
| 140 | if (status == 0) | 201 | if (status == 0) |
| 141 | status = count; | 202 | status = count; |
| 142 | } else | 203 | } else |
| @@ -153,7 +214,6 @@ static int spidev_message(struct spidev_data *spidev, | |||
| 153 | struct spi_transfer *k_xfers; | 214 | struct spi_transfer *k_xfers; |
| 154 | struct spi_transfer *k_tmp; | 215 | struct spi_transfer *k_tmp; |
| 155 | struct spi_ioc_transfer *u_tmp; | 216 | struct spi_ioc_transfer *u_tmp; |
| 156 | struct spi_device *spi = spidev->spi; | ||
| 157 | unsigned n, total; | 217 | unsigned n, total; |
| 158 | u8 *buf; | 218 | u8 *buf; |
| 159 | int status = -EFAULT; | 219 | int status = -EFAULT; |
| @@ -215,7 +275,7 @@ static int spidev_message(struct spidev_data *spidev, | |||
| 215 | spi_message_add_tail(k_tmp, &msg); | 275 | spi_message_add_tail(k_tmp, &msg); |
| 216 | } | 276 | } |
| 217 | 277 | ||
| 218 | status = spi_sync(spi, &msg); | 278 | status = spidev_sync(spidev, &msg); |
| 219 | if (status < 0) | 279 | if (status < 0) |
| 220 | goto done; | 280 | goto done; |
| 221 | 281 | ||
| @@ -269,8 +329,16 @@ spidev_ioctl(struct inode *inode, struct file *filp, | |||
| 269 | if (err) | 329 | if (err) |
| 270 | return -EFAULT; | 330 | return -EFAULT; |
| 271 | 331 | ||
| 332 | /* guard against device removal before, or while, | ||
| 333 | * we issue this ioctl. | ||
| 334 | */ | ||
| 272 | spidev = filp->private_data; | 335 | spidev = filp->private_data; |
| 273 | spi = spidev->spi; | 336 | spin_lock_irq(&spidev->spi_lock); |
| 337 | spi = spi_dev_get(spidev->spi); | ||
| 338 | spin_unlock_irq(&spidev->spi_lock); | ||
| 339 | |||
| 340 | if (spi == NULL) | ||
| 341 | return -ESHUTDOWN; | ||
| 274 | 342 | ||
| 275 | switch (cmd) { | 343 | switch (cmd) { |
| 276 | /* read requests */ | 344 | /* read requests */ |
| @@ -356,8 +424,10 @@ spidev_ioctl(struct inode *inode, struct file *filp, | |||
| 356 | default: | 424 | default: |
| 357 | /* segmented and/or full-duplex I/O request */ | 425 | /* segmented and/or full-duplex I/O request */ |
| 358 | if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) | 426 | if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) |
| 359 | || _IOC_DIR(cmd) != _IOC_WRITE) | 427 | || _IOC_DIR(cmd) != _IOC_WRITE) { |
| 360 | return -ENOTTY; | 428 | retval = -ENOTTY; |
| 429 | break; | ||
| 430 | } | ||
| 361 | 431 | ||
| 362 | tmp = _IOC_SIZE(cmd); | 432 | tmp = _IOC_SIZE(cmd); |
| 363 | if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { | 433 | if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { |
| @@ -385,6 +455,7 @@ spidev_ioctl(struct inode *inode, struct file *filp, | |||
| 385 | kfree(ioc); | 455 | kfree(ioc); |
| 386 | break; | 456 | break; |
| 387 | } | 457 | } |
| 458 | spi_dev_put(spi); | ||
| 388 | return retval; | 459 | return retval; |
| 389 | } | 460 | } |
| 390 | 461 | ||
| @@ -488,6 +559,7 @@ static int spidev_probe(struct spi_device *spi) | |||
| 488 | 559 | ||
| 489 | /* Initialize the driver data */ | 560 | /* Initialize the driver data */ |
| 490 | spidev->spi = spi; | 561 | spidev->spi = spi; |
| 562 | spin_lock_init(&spidev->spi_lock); | ||
| 491 | mutex_init(&spidev->buf_lock); | 563 | mutex_init(&spidev->buf_lock); |
| 492 | 564 | ||
| 493 | INIT_LIST_HEAD(&spidev->device_entry); | 565 | INIT_LIST_HEAD(&spidev->device_entry); |
| @@ -526,13 +598,17 @@ static int spidev_remove(struct spi_device *spi) | |||
| 526 | { | 598 | { |
| 527 | struct spidev_data *spidev = dev_get_drvdata(&spi->dev); | 599 | struct spidev_data *spidev = dev_get_drvdata(&spi->dev); |
| 528 | 600 | ||
| 529 | mutex_lock(&device_list_lock); | 601 | /* make sure ops on existing fds can abort cleanly */ |
| 602 | spin_lock_irq(&spidev->spi_lock); | ||
| 603 | spidev->spi = NULL; | ||
| 604 | spin_unlock_irq(&spidev->spi_lock); | ||
| 530 | 605 | ||
| 606 | /* prevent new opens */ | ||
| 607 | mutex_lock(&device_list_lock); | ||
| 531 | list_del(&spidev->device_entry); | 608 | list_del(&spidev->device_entry); |
| 532 | dev_set_drvdata(&spi->dev, NULL); | 609 | dev_set_drvdata(&spi->dev, NULL); |
| 533 | clear_bit(MINOR(spidev->dev.devt), minors); | 610 | clear_bit(MINOR(spidev->dev.devt), minors); |
| 534 | device_unregister(&spidev->dev); | 611 | device_unregister(&spidev->dev); |
| 535 | |||
| 536 | mutex_unlock(&device_list_lock); | 612 | mutex_unlock(&device_list_lock); |
| 537 | 613 | ||
| 538 | return 0; | 614 | return 0; |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index e4bcf5376a99..bd4ac0bafecb 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
| @@ -3356,7 +3356,7 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *i | |||
| 3356 | 3356 | ||
| 3357 | info->fix.mmio_start = raddr; | 3357 | info->fix.mmio_start = raddr; |
| 3358 | par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); | 3358 | par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); |
| 3359 | if (par->ati_regbase == 0) | 3359 | if (par->ati_regbase == NULL) |
| 3360 | return -ENOMEM; | 3360 | return -ENOMEM; |
| 3361 | 3361 | ||
| 3362 | info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00; | 3362 | info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00; |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 72cd0d2f14ec..400e9264e456 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
| @@ -2277,8 +2277,8 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, | |||
| 2277 | do { | 2277 | do { |
| 2278 | rinfo->fb_base = ioremap (rinfo->fb_base_phys, | 2278 | rinfo->fb_base = ioremap (rinfo->fb_base_phys, |
| 2279 | rinfo->mapped_vram); | 2279 | rinfo->mapped_vram); |
| 2280 | } while ( rinfo->fb_base == 0 && | 2280 | } while (rinfo->fb_base == NULL && |
| 2281 | ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) ); | 2281 | ((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM)); |
| 2282 | 2282 | ||
| 2283 | if (rinfo->fb_base == NULL) { | 2283 | if (rinfo->fb_base == NULL) { |
| 2284 | printk (KERN_ERR "radeonfb (%s): cannot map FB\n", | 2284 | printk (KERN_ERR "radeonfb (%s): cannot map FB\n", |
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index f3107ad7e545..95883236c0cd 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h | |||
| @@ -200,7 +200,7 @@ static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, | |||
| 200 | virt->vaddr = ioremap_nocache(phys, size); | 200 | virt->vaddr = ioremap_nocache(phys, size); |
| 201 | else | 201 | else |
| 202 | virt->vaddr = ioremap(phys, size); | 202 | virt->vaddr = ioremap(phys, size); |
| 203 | return (virt->vaddr == 0); /* 0, !0... 0, error_code in future */ | 203 | return (virt->vaddr == NULL); /* 0, !0... 0, error_code in future */ |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | static inline void mga_iounmap(vaddr_t va) { | 206 | static inline void mga_iounmap(vaddr_t va) { |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3ee314beacc1..274bc93ab7d8 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
| @@ -1351,7 +1351,6 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) | |||
| 1351 | struct pxafb_info *fbi; | 1351 | struct pxafb_info *fbi; |
| 1352 | void *addr; | 1352 | void *addr; |
| 1353 | struct pxafb_mach_info *inf = dev->platform_data; | 1353 | struct pxafb_mach_info *inf = dev->platform_data; |
| 1354 | struct pxafb_mode_info *mode = inf->modes; | ||
| 1355 | 1354 | ||
| 1356 | /* Alloc the pxafb_info and pseudo_palette in one step */ | 1355 | /* Alloc the pxafb_info and pseudo_palette in one step */ |
| 1357 | fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); | 1356 | fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); |
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 13b38cbbe4cf..f0598961c6b0 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
| @@ -1,75 +1,15 @@ | |||
| 1 | /* | 1 | /* linux/drivers/video/s3c2410fb.c |
| 2 | * linux/drivers/video/s3c2410fb.c | 2 | * Copyright (c) 2004,2005 Arnaud Patard |
| 3 | * Copyright (c) Arnaud Patard, Ben Dooks | 3 | * Copyright (c) 2004-2008 Ben Dooks |
| 4 | * | ||
| 5 | * S3C2410 LCD Framebuffer Driver | ||
| 4 | * | 6 | * |
| 5 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
| 6 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
| 7 | * more details. | 9 | * more details. |
| 8 | * | 10 | * |
| 9 | * S3C2410 LCD Controller Frame Buffer Driver | 11 | * Driver based on skeletonfb.c, sa1100fb.c and others. |
| 10 | * based on skeletonfb.c, sa1100fb.c and others | 12 | */ |
| 11 | * | ||
| 12 | * ChangeLog | ||
| 13 | * 2005-04-07: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 14 | * - u32 state -> pm_message_t state | ||
| 15 | * - S3C2410_{VA,SZ}_LCD -> S3C24XX | ||
| 16 | * | ||
| 17 | * 2005-03-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 18 | * - Removed the ioctl | ||
| 19 | * - use readl/writel instead of __raw_writel/__raw_readl | ||
| 20 | * | ||
| 21 | * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 22 | * - Added the possibility to set on or off the | ||
| 23 | * debugging messages | ||
| 24 | * - Replaced 0 and 1 by on or off when reading the | ||
| 25 | * /sys files | ||
| 26 | * | ||
| 27 | * 2005-03-23: Ben Dooks <ben-linux@fluff.org> | ||
| 28 | * - added non 16bpp modes | ||
| 29 | * - updated platform information for range of x/y/bpp | ||
| 30 | * - add code to ensure palette is written correctly | ||
| 31 | * - add pixel clock divisor control | ||
| 32 | * | ||
| 33 | * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 34 | * - Removed the use of currcon as it no more exists | ||
| 35 | * - Added LCD power sysfs interface | ||
| 36 | * | ||
| 37 | * 2004-11-03: Ben Dooks <ben-linux@fluff.org> | ||
| 38 | * - minor cleanups | ||
| 39 | * - add suspend/resume support | ||
| 40 | * - s3c2410fb_setcolreg() not valid in >8bpp modes | ||
| 41 | * - removed last CONFIG_FB_S3C2410_FIXED | ||
| 42 | * - ensure lcd controller stopped before cleanup | ||
| 43 | * - added sysfs interface for backlight power | ||
| 44 | * - added mask for gpio configuration | ||
| 45 | * - ensured IRQs disabled during GPIO configuration | ||
| 46 | * - disable TPAL before enabling video | ||
| 47 | * | ||
| 48 | * 2004-09-20: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 49 | * - Suppress command line options | ||
| 50 | * | ||
| 51 | * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 52 | * - code cleanup | ||
| 53 | * | ||
| 54 | * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 55 | * - Renamed from h1940fb.c to s3c2410fb.c | ||
| 56 | * - Add support for different devices | ||
| 57 | * - Backlight support | ||
| 58 | * | ||
| 59 | * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> | ||
| 60 | * - added clock (de-)allocation code | ||
| 61 | * - added fixem fbmem option | ||
| 62 | * | ||
| 63 | * 2004-07-27: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 64 | * - code cleanup | ||
| 65 | * - added a forgotten return in h1940fb_init | ||
| 66 | * | ||
| 67 | * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at> | ||
| 68 | * - code cleanup and extended debugging | ||
| 69 | * | ||
| 70 | * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 71 | * - First version | ||
| 72 | */ | ||
| 73 | 13 | ||
| 74 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 75 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| @@ -580,6 +520,27 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
| 580 | return 0; | 520 | return 0; |
| 581 | } | 521 | } |
| 582 | 522 | ||
| 523 | /* s3c2410fb_lcd_enable | ||
| 524 | * | ||
| 525 | * shutdown the lcd controller | ||
| 526 | */ | ||
| 527 | static void s3c2410fb_lcd_enable(struct s3c2410fb_info *fbi, int enable) | ||
| 528 | { | ||
| 529 | unsigned long flags; | ||
| 530 | |||
| 531 | local_irq_save(flags); | ||
| 532 | |||
| 533 | if (enable) | ||
| 534 | fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID; | ||
| 535 | else | ||
| 536 | fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; | ||
| 537 | |||
| 538 | writel(fbi->regs.lcdcon1, fbi->io + S3C2410_LCDCON1); | ||
| 539 | |||
| 540 | local_irq_restore(flags); | ||
| 541 | } | ||
| 542 | |||
| 543 | |||
| 583 | /* | 544 | /* |
| 584 | * s3c2410fb_blank | 545 | * s3c2410fb_blank |
| 585 | * @blank_mode: the blank mode we want. | 546 | * @blank_mode: the blank mode we want. |
| @@ -589,9 +550,6 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
| 589 | * blanking succeeded, != 0 if un-/blanking failed due to e.g. a | 550 | * blanking succeeded, != 0 if un-/blanking failed due to e.g. a |
| 590 | * video mode which doesn't support it. Implements VESA suspend | 551 | * video mode which doesn't support it. Implements VESA suspend |
| 591 | * and powerdown modes on hardware that supports disabling hsync/vsync: | 552 | * and powerdown modes on hardware that supports disabling hsync/vsync: |
| 592 | * blank_mode == 2: suspend vsync | ||
| 593 | * blank_mode == 3: suspend hsync | ||
| 594 | * blank_mode == 4: powerdown | ||
| 595 | * | 553 | * |
| 596 | * Returns negative errno on error, or zero on success. | 554 | * Returns negative errno on error, or zero on success. |
| 597 | * | 555 | * |
| @@ -605,6 +563,12 @@ static int s3c2410fb_blank(int blank_mode, struct fb_info *info) | |||
| 605 | 563 | ||
| 606 | tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL; | 564 | tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL; |
| 607 | 565 | ||
| 566 | if (blank_mode == FB_BLANK_POWERDOWN) { | ||
| 567 | s3c2410fb_lcd_enable(fbi, 0); | ||
| 568 | } else { | ||
| 569 | s3c2410fb_lcd_enable(fbi, 1); | ||
| 570 | } | ||
| 571 | |||
| 608 | if (blank_mode == FB_BLANK_UNBLANK) | 572 | if (blank_mode == FB_BLANK_UNBLANK) |
| 609 | writel(0x0, tpal_reg); | 573 | writel(0x0, tpal_reg); |
| 610 | else { | 574 | else { |
| @@ -948,7 +912,10 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev, | |||
| 948 | } | 912 | } |
| 949 | 913 | ||
| 950 | /* create device files */ | 914 | /* create device files */ |
| 951 | device_create_file(&pdev->dev, &dev_attr_debug); | 915 | ret = device_create_file(&pdev->dev, &dev_attr_debug); |
| 916 | if (ret) { | ||
| 917 | printk(KERN_ERR "failed to add debug attribute\n"); | ||
| 918 | } | ||
| 952 | 919 | ||
| 953 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 920 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
| 954 | fbinfo->node, fbinfo->fix.id); | 921 | fbinfo->node, fbinfo->fix.id); |
| @@ -983,21 +950,6 @@ static int __init s3c2412fb_probe(struct platform_device *pdev) | |||
| 983 | return s3c24xxfb_probe(pdev, DRV_S3C2412); | 950 | return s3c24xxfb_probe(pdev, DRV_S3C2412); |
| 984 | } | 951 | } |
| 985 | 952 | ||
| 986 | /* s3c2410fb_stop_lcd | ||
| 987 | * | ||
| 988 | * shutdown the lcd controller | ||
| 989 | */ | ||
| 990 | static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) | ||
| 991 | { | ||
| 992 | unsigned long flags; | ||
| 993 | |||
| 994 | local_irq_save(flags); | ||
| 995 | |||
| 996 | fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; | ||
| 997 | writel(fbi->regs.lcdcon1, fbi->io + S3C2410_LCDCON1); | ||
| 998 | |||
| 999 | local_irq_restore(flags); | ||
| 1000 | } | ||
| 1001 | 953 | ||
| 1002 | /* | 954 | /* |
| 1003 | * Cleanup | 955 | * Cleanup |
| @@ -1010,7 +962,7 @@ static int s3c2410fb_remove(struct platform_device *pdev) | |||
| 1010 | 962 | ||
| 1011 | unregister_framebuffer(fbinfo); | 963 | unregister_framebuffer(fbinfo); |
| 1012 | 964 | ||
| 1013 | s3c2410fb_stop_lcd(info); | 965 | s3c2410fb_lcd_enable(info, 0); |
| 1014 | msleep(1); | 966 | msleep(1); |
| 1015 | 967 | ||
| 1016 | s3c2410fb_unmap_video_memory(fbinfo); | 968 | s3c2410fb_unmap_video_memory(fbinfo); |
| @@ -1043,7 +995,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) | |||
| 1043 | struct fb_info *fbinfo = platform_get_drvdata(dev); | 995 | struct fb_info *fbinfo = platform_get_drvdata(dev); |
| 1044 | struct s3c2410fb_info *info = fbinfo->par; | 996 | struct s3c2410fb_info *info = fbinfo->par; |
| 1045 | 997 | ||
| 1046 | s3c2410fb_stop_lcd(info); | 998 | s3c2410fb_lcd_enable(info, 0); |
| 1047 | 999 | ||
| 1048 | /* sleep before disabling the clock, we need to ensure | 1000 | /* sleep before disabling the clock, we need to ensure |
| 1049 | * the LCD DMA engine is not going to get back on the bus | 1001 | * the LCD DMA engine is not going to get back on the bus |
| @@ -1118,3 +1070,5 @@ MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, " | |||
| 1118 | "Ben Dooks <ben-linux@fluff.org>"); | 1070 | "Ben Dooks <ben-linux@fluff.org>"); |
| 1119 | MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); | 1071 | MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); |
| 1120 | MODULE_LICENSE("GPL"); | 1072 | MODULE_LICENSE("GPL"); |
| 1073 | MODULE_ALIAS("platform:s3c2410-lcd"); | ||
| 1074 | MODULE_ALIAS("platform:s3c2412-lcd"); | ||
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h index dbb73b95e2ef..9a6ba3e9d1b8 100644 --- a/drivers/video/s3c2410fb.h +++ b/drivers/video/s3c2410fb.h | |||
| @@ -1,26 +1,14 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/video/s3c2410fb.h | 2 | * linux/drivers/video/s3c2410fb.h |
| 3 | * Copyright (c) Arnaud Patard | 3 | * Copyright (c) 2004 Arnaud Patard |
| 4 | * | ||
| 5 | * S3C2410 LCD Framebuffer Driver | ||
| 4 | * | 6 | * |
| 5 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
| 6 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
| 7 | * more details. | 9 | * more details. |
| 8 | * | 10 | * |
| 9 | * S3C2410 LCD Controller Frame Buffer Driver | 11 | */ |
| 10 | * based on skeletonfb.c, sa1100fb.h | ||
| 11 | * | ||
| 12 | * ChangeLog | ||
| 13 | * | ||
| 14 | * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 15 | * - Moved dprintk to s3c2410fb.c | ||
| 16 | * | ||
| 17 | * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 18 | * - Renamed from h1940fb.h to s3c2410fb.h | ||
| 19 | * - Changed h1940 to s3c2410 | ||
| 20 | * | ||
| 21 | * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
| 22 | * - First version | ||
| 23 | */ | ||
| 24 | 12 | ||
| 25 | #ifndef __S3C2410FB_H | 13 | #ifndef __S3C2410FB_H |
| 26 | #define __S3C2410FB_H | 14 | #define __S3C2410FB_H |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 73803624c131..b9343844cd1f 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
| @@ -5787,7 +5787,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5787 | } else { | 5787 | } else { |
| 5788 | struct sis_video_info *countvideo = card_list; | 5788 | struct sis_video_info *countvideo = card_list; |
| 5789 | ivideo->cardnumber = 1; | 5789 | ivideo->cardnumber = 1; |
| 5790 | while((countvideo = countvideo->next) != 0) | 5790 | while((countvideo = countvideo->next) != NULL) |
| 5791 | ivideo->cardnumber++; | 5791 | ivideo->cardnumber++; |
| 5792 | } | 5792 | } |
| 5793 | 5793 | ||
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 742b5c656d66..15d4a768b1f6 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
| @@ -663,14 +663,14 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
| 663 | sm501fb_sync_regs(fbi); | 663 | sm501fb_sync_regs(fbi); |
| 664 | mdelay(10); | 664 | mdelay(10); |
| 665 | 665 | ||
| 666 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { | 666 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) { |
| 667 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ | 667 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ |
| 668 | writel(control, ctrl_reg); | 668 | writel(control, ctrl_reg); |
| 669 | sm501fb_sync_regs(fbi); | 669 | sm501fb_sync_regs(fbi); |
| 670 | mdelay(10); | 670 | mdelay(10); |
| 671 | } | 671 | } |
| 672 | 672 | ||
| 673 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | 673 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) { |
| 674 | control |= SM501_DC_PANEL_CONTROL_FPEN; | 674 | control |= SM501_DC_PANEL_CONTROL_FPEN; |
| 675 | writel(control, ctrl_reg); | 675 | writel(control, ctrl_reg); |
| 676 | sm501fb_sync_regs(fbi); | 676 | sm501fb_sync_regs(fbi); |
| @@ -678,14 +678,14 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
| 678 | } | 678 | } |
| 679 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { | 679 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { |
| 680 | /* disable panel power */ | 680 | /* disable panel power */ |
| 681 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | 681 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) { |
| 682 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; | 682 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; |
| 683 | writel(control, ctrl_reg); | 683 | writel(control, ctrl_reg); |
| 684 | sm501fb_sync_regs(fbi); | 684 | sm501fb_sync_regs(fbi); |
| 685 | mdelay(10); | 685 | mdelay(10); |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { | 688 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) { |
| 689 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; | 689 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; |
| 690 | writel(control, ctrl_reg); | 690 | writel(control, ctrl_reg); |
| 691 | sm501fb_sync_regs(fbi); | 691 | sm501fb_sync_regs(fbi); |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index cd62d75b2cc0..e2832bc7869a 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -1906,9 +1906,9 @@ int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, | |||
| 1906 | goto out; | 1906 | goto out; |
| 1907 | } | 1907 | } |
| 1908 | } | 1908 | } |
| 1909 | mutex_unlock(&key_tfm_list_mutex); | ||
| 1910 | (*tfm) = key_tfm->key_tfm; | 1909 | (*tfm) = key_tfm->key_tfm; |
| 1911 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; | 1910 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; |
| 1912 | out: | 1911 | out: |
| 1912 | mutex_unlock(&key_tfm_list_mutex); | ||
| 1913 | return rc; | 1913 | return rc; |
| 1914 | } | 1914 | } |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fb77e0962132..43e99513334a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
| @@ -488,7 +488,12 @@ static struct fuse_conn *new_conn(struct super_block *sb) | |||
| 488 | err = bdi_init(&fc->bdi); | 488 | err = bdi_init(&fc->bdi); |
| 489 | if (err) | 489 | if (err) |
| 490 | goto error_kfree; | 490 | goto error_kfree; |
| 491 | err = bdi_register_dev(&fc->bdi, fc->dev); | 491 | if (sb->s_bdev) { |
| 492 | err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", | ||
| 493 | MAJOR(fc->dev), MINOR(fc->dev)); | ||
| 494 | } else { | ||
| 495 | err = bdi_register_dev(&fc->bdi, fc->dev); | ||
| 496 | } | ||
| 492 | if (err) | 497 | if (err) |
| 493 | goto error_bdi_destroy; | 498 | goto error_bdi_destroy; |
| 494 | /* | 499 | /* |
diff --git a/fs/ntfs/upcase.c b/fs/ntfs/upcase.c index 9101807dc81a..e2f72ca98037 100644 --- a/fs/ntfs/upcase.c +++ b/fs/ntfs/upcase.c | |||
| @@ -77,11 +77,10 @@ ntfschar *generate_default_upcase(void) | |||
| 77 | uc[i] = cpu_to_le16(i); | 77 | uc[i] = cpu_to_le16(i); |
| 78 | for (r = 0; uc_run_table[r][0]; r++) | 78 | for (r = 0; uc_run_table[r][0]; r++) |
| 79 | for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++) | 79 | for (i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++) |
| 80 | uc[i] = cpu_to_le16(le16_to_cpu(uc[i]) + | 80 | le16_add_cpu(&uc[i], uc_run_table[r][2]); |
| 81 | uc_run_table[r][2]); | ||
| 82 | for (r = 0; uc_dup_table[r][0]; r++) | 81 | for (r = 0; uc_dup_table[r][0]; r++) |
| 83 | for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2) | 82 | for (i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2) |
| 84 | uc[i + 1] = cpu_to_le16(le16_to_cpu(uc[i + 1]) - 1); | 83 | le16_add_cpu(&uc[i + 1], -1); |
| 85 | for (r = 0; uc_word_table[r][0]; r++) | 84 | for (r = 0; uc_word_table[r][0]; r++) |
| 86 | uc[uc_word_table[r][0]] = cpu_to_le16(uc_word_table[r][1]); | 85 | uc[uc_word_table[r][0]] = cpu_to_le16(uc_word_table[r][1]); |
| 87 | return uc; | 86 | return uc; |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 6f4e8dc97da1..b08d10017911 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
| @@ -425,7 +425,8 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
| 425 | } | 425 | } |
| 426 | } | 426 | } |
| 427 | unlock_new_inode(inode); | 427 | unlock_new_inode(inode); |
| 428 | } | 428 | } else |
| 429 | module_put(de->owner); | ||
| 429 | return inode; | 430 | return inode; |
| 430 | 431 | ||
| 431 | out_ino: | 432 | out_ino: |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 74a323d2b850..32dc14cd8900 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
| @@ -139,7 +139,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off, | |||
| 139 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 139 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
| 140 | si_meminfo(&i); | 140 | si_meminfo(&i); |
| 141 | si_swapinfo(&i); | 141 | si_swapinfo(&i); |
| 142 | committed = atomic_read(&vm_committed_space); | 142 | committed = atomic_long_read(&vm_committed_space); |
| 143 | allowed = ((totalram_pages - hugetlb_total_pages()) | 143 | allowed = ((totalram_pages - hugetlb_total_pages()) |
| 144 | * sysctl_overcommit_ratio / 100) + total_swap_pages; | 144 | * sysctl_overcommit_ratio / 100) + total_swap_pages; |
| 145 | 145 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 5105015a75ad..98e0e86093b4 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -387,6 +387,8 @@ _xfs_buf_lookup_pages( | |||
| 387 | if (unlikely(page == NULL)) { | 387 | if (unlikely(page == NULL)) { |
| 388 | if (flags & XBF_READ_AHEAD) { | 388 | if (flags & XBF_READ_AHEAD) { |
| 389 | bp->b_page_count = i; | 389 | bp->b_page_count = i; |
| 390 | for (i = 0; i < bp->b_page_count; i++) | ||
| 391 | unlock_page(bp->b_pages[i]); | ||
| 390 | return -ENOMEM; | 392 | return -ENOMEM; |
| 391 | } | 393 | } |
| 392 | 394 | ||
| @@ -416,17 +418,24 @@ _xfs_buf_lookup_pages( | |||
| 416 | ASSERT(!PagePrivate(page)); | 418 | ASSERT(!PagePrivate(page)); |
| 417 | if (!PageUptodate(page)) { | 419 | if (!PageUptodate(page)) { |
| 418 | page_count--; | 420 | page_count--; |
| 419 | if (blocksize < PAGE_CACHE_SIZE && !PagePrivate(page)) { | 421 | if (blocksize >= PAGE_CACHE_SIZE) { |
| 422 | if (flags & XBF_READ) | ||
| 423 | bp->b_flags |= _XBF_PAGE_LOCKED; | ||
| 424 | } else if (!PagePrivate(page)) { | ||
| 420 | if (test_page_region(page, offset, nbytes)) | 425 | if (test_page_region(page, offset, nbytes)) |
| 421 | page_count++; | 426 | page_count++; |
| 422 | } | 427 | } |
| 423 | } | 428 | } |
| 424 | 429 | ||
| 425 | unlock_page(page); | ||
| 426 | bp->b_pages[i] = page; | 430 | bp->b_pages[i] = page; |
| 427 | offset = 0; | 431 | offset = 0; |
| 428 | } | 432 | } |
| 429 | 433 | ||
| 434 | if (!(bp->b_flags & _XBF_PAGE_LOCKED)) { | ||
| 435 | for (i = 0; i < bp->b_page_count; i++) | ||
| 436 | unlock_page(bp->b_pages[i]); | ||
| 437 | } | ||
| 438 | |||
| 430 | if (page_count == bp->b_page_count) | 439 | if (page_count == bp->b_page_count) |
| 431 | bp->b_flags |= XBF_DONE; | 440 | bp->b_flags |= XBF_DONE; |
| 432 | 441 | ||
| @@ -746,6 +755,7 @@ xfs_buf_associate_memory( | |||
| 746 | bp->b_count_desired = len; | 755 | bp->b_count_desired = len; |
| 747 | bp->b_buffer_length = buflen; | 756 | bp->b_buffer_length = buflen; |
| 748 | bp->b_flags |= XBF_MAPPED; | 757 | bp->b_flags |= XBF_MAPPED; |
| 758 | bp->b_flags &= ~_XBF_PAGE_LOCKED; | ||
| 749 | 759 | ||
| 750 | return 0; | 760 | return 0; |
| 751 | } | 761 | } |
| @@ -1093,8 +1103,10 @@ _xfs_buf_ioend( | |||
| 1093 | xfs_buf_t *bp, | 1103 | xfs_buf_t *bp, |
| 1094 | int schedule) | 1104 | int schedule) |
| 1095 | { | 1105 | { |
| 1096 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) | 1106 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { |
| 1107 | bp->b_flags &= ~_XBF_PAGE_LOCKED; | ||
| 1097 | xfs_buf_ioend(bp, schedule); | 1108 | xfs_buf_ioend(bp, schedule); |
| 1109 | } | ||
| 1098 | } | 1110 | } |
| 1099 | 1111 | ||
| 1100 | STATIC void | 1112 | STATIC void |
| @@ -1125,6 +1137,9 @@ xfs_buf_bio_end_io( | |||
| 1125 | 1137 | ||
| 1126 | if (--bvec >= bio->bi_io_vec) | 1138 | if (--bvec >= bio->bi_io_vec) |
| 1127 | prefetchw(&bvec->bv_page->flags); | 1139 | prefetchw(&bvec->bv_page->flags); |
| 1140 | |||
| 1141 | if (bp->b_flags & _XBF_PAGE_LOCKED) | ||
| 1142 | unlock_page(page); | ||
| 1128 | } while (bvec >= bio->bi_io_vec); | 1143 | } while (bvec >= bio->bi_io_vec); |
| 1129 | 1144 | ||
| 1130 | _xfs_buf_ioend(bp, 1); | 1145 | _xfs_buf_ioend(bp, 1); |
| @@ -1163,7 +1178,8 @@ _xfs_buf_ioapply( | |||
| 1163 | * filesystem block size is not smaller than the page size. | 1178 | * filesystem block size is not smaller than the page size. |
| 1164 | */ | 1179 | */ |
| 1165 | if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && | 1180 | if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && |
| 1166 | (bp->b_flags & XBF_READ) && | 1181 | ((bp->b_flags & (XBF_READ|_XBF_PAGE_LOCKED)) == |
| 1182 | (XBF_READ|_XBF_PAGE_LOCKED)) && | ||
| 1167 | (blocksize >= PAGE_CACHE_SIZE)) { | 1183 | (blocksize >= PAGE_CACHE_SIZE)) { |
| 1168 | bio = bio_alloc(GFP_NOIO, 1); | 1184 | bio = bio_alloc(GFP_NOIO, 1); |
| 1169 | 1185 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 841d7883528d..f948ec7ba9a4 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
| @@ -66,6 +66,25 @@ typedef enum { | |||
| 66 | _XBF_PAGES = (1 << 18), /* backed by refcounted pages */ | 66 | _XBF_PAGES = (1 << 18), /* backed by refcounted pages */ |
| 67 | _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ | 67 | _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ |
| 68 | _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */ | 68 | _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */ |
| 69 | |||
| 70 | /* | ||
| 71 | * Special flag for supporting metadata blocks smaller than a FSB. | ||
| 72 | * | ||
| 73 | * In this case we can have multiple xfs_buf_t on a single page and | ||
| 74 | * need to lock out concurrent xfs_buf_t readers as they only | ||
| 75 | * serialise access to the buffer. | ||
| 76 | * | ||
| 77 | * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation | ||
| 78 | * between reads of the page. Hence we can have one thread read the | ||
| 79 | * page and modify it, but then race with another thread that thinks | ||
| 80 | * the page is not up-to-date and hence reads it again. | ||
| 81 | * | ||
| 82 | * The result is that the first modifcation to the page is lost. | ||
| 83 | * This sort of AGF/AGI reading race can happen when unlinking inodes | ||
| 84 | * that require truncation and results in the AGI unlinked list | ||
| 85 | * modifications being lost. | ||
| 86 | */ | ||
| 87 | _XBF_PAGE_LOCKED = (1 << 22), | ||
| 69 | } xfs_buf_flags_t; | 88 | } xfs_buf_flags_t; |
| 70 | 89 | ||
| 71 | typedef enum { | 90 | typedef enum { |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 65e78c13d4ae..5f60363b9343 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -184,19 +184,24 @@ xfs_file_release( | |||
| 184 | return -xfs_release(XFS_I(inode)); | 184 | return -xfs_release(XFS_I(inode)); |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | /* | ||
| 188 | * We ignore the datasync flag here because a datasync is effectively | ||
| 189 | * identical to an fsync. That is, datasync implies that we need to write | ||
| 190 | * only the metadata needed to be able to access the data that is written | ||
| 191 | * if we crash after the call completes. Hence if we are writing beyond | ||
| 192 | * EOF we have to log the inode size change as well, which makes it a | ||
| 193 | * full fsync. If we don't write beyond EOF, the inode core will be | ||
| 194 | * clean in memory and so we don't need to log the inode, just like | ||
| 195 | * fsync. | ||
| 196 | */ | ||
| 187 | STATIC int | 197 | STATIC int |
| 188 | xfs_file_fsync( | 198 | xfs_file_fsync( |
| 189 | struct file *filp, | 199 | struct file *filp, |
| 190 | struct dentry *dentry, | 200 | struct dentry *dentry, |
| 191 | int datasync) | 201 | int datasync) |
| 192 | { | 202 | { |
| 193 | int flags = FSYNC_WAIT; | ||
| 194 | |||
| 195 | if (datasync) | ||
| 196 | flags |= FSYNC_DATA; | ||
| 197 | xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED); | 203 | xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED); |
| 198 | return -xfs_fsync(XFS_I(dentry->d_inode), flags, | 204 | return -xfs_fsync(XFS_I(dentry->d_inode)); |
| 199 | (xfs_off_t)0, (xfs_off_t)-1); | ||
| 200 | } | 205 | } |
| 201 | 206 | ||
| 202 | /* | 207 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 9d73cb5c0fc7..25eb2a9e8d9b 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
| @@ -230,14 +230,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) | |||
| 230 | #define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ | 230 | #define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ |
| 231 | 231 | ||
| 232 | /* | 232 | /* |
| 233 | * Flags to vop_fsync/reclaim. | ||
| 234 | */ | ||
| 235 | #define FSYNC_NOWAIT 0 /* asynchronous flush */ | ||
| 236 | #define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ | ||
| 237 | #define FSYNC_INVAL 0x2 /* flush and invalidate cached data */ | ||
| 238 | #define FSYNC_DATA 0x4 /* synchronous fsync of data only */ | ||
| 239 | |||
| 240 | /* | ||
| 241 | * Tracking vnode activity. | 233 | * Tracking vnode activity. |
| 242 | */ | 234 | */ |
| 243 | #if defined(XFS_INODE_TRACE) | 235 | #if defined(XFS_INODE_TRACE) |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index cf0bb9c1d621..e569bf5d6cf0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -2974,6 +2974,7 @@ xfs_iflush_cluster( | |||
| 2974 | xfs_mount_t *mp = ip->i_mount; | 2974 | xfs_mount_t *mp = ip->i_mount; |
| 2975 | xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino); | 2975 | xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino); |
| 2976 | unsigned long first_index, mask; | 2976 | unsigned long first_index, mask; |
| 2977 | unsigned long inodes_per_cluster; | ||
| 2977 | int ilist_size; | 2978 | int ilist_size; |
| 2978 | xfs_inode_t **ilist; | 2979 | xfs_inode_t **ilist; |
| 2979 | xfs_inode_t *iq; | 2980 | xfs_inode_t *iq; |
| @@ -2985,8 +2986,9 @@ xfs_iflush_cluster( | |||
| 2985 | ASSERT(pag->pagi_inodeok); | 2986 | ASSERT(pag->pagi_inodeok); |
| 2986 | ASSERT(pag->pag_ici_init); | 2987 | ASSERT(pag->pag_ici_init); |
| 2987 | 2988 | ||
| 2988 | ilist_size = XFS_INODE_CLUSTER_SIZE(mp) * sizeof(xfs_inode_t *); | 2989 | inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; |
| 2989 | ilist = kmem_alloc(ilist_size, KM_MAYFAIL); | 2990 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); |
| 2991 | ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS); | ||
| 2990 | if (!ilist) | 2992 | if (!ilist) |
| 2991 | return 0; | 2993 | return 0; |
| 2992 | 2994 | ||
| @@ -2995,8 +2997,7 @@ xfs_iflush_cluster( | |||
| 2995 | read_lock(&pag->pag_ici_lock); | 2997 | read_lock(&pag->pag_ici_lock); |
| 2996 | /* really need a gang lookup range call here */ | 2998 | /* really need a gang lookup range call here */ |
| 2997 | nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist, | 2999 | nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist, |
| 2998 | first_index, | 3000 | first_index, inodes_per_cluster); |
| 2999 | XFS_INODE_CLUSTER_SIZE(mp)); | ||
| 3000 | if (nr_found == 0) | 3001 | if (nr_found == 0) |
| 3001 | goto out_free; | 3002 | goto out_free; |
| 3002 | 3003 | ||
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 70702a60b4bb..e475e3717eb3 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -856,18 +856,14 @@ xfs_readlink( | |||
| 856 | /* | 856 | /* |
| 857 | * xfs_fsync | 857 | * xfs_fsync |
| 858 | * | 858 | * |
| 859 | * This is called to sync the inode and its data out to disk. | 859 | * This is called to sync the inode and its data out to disk. We need to hold |
| 860 | * We need to hold the I/O lock while flushing the data, and | 860 | * the I/O lock while flushing the data, and the inode lock while flushing the |
| 861 | * the inode lock while flushing the inode. The inode lock CANNOT | 861 | * inode. The inode lock CANNOT be held while flushing the data, so acquire |
| 862 | * be held while flushing the data, so acquire after we're done | 862 | * after we're done with that. |
| 863 | * with that. | ||
| 864 | */ | 863 | */ |
| 865 | int | 864 | int |
| 866 | xfs_fsync( | 865 | xfs_fsync( |
| 867 | xfs_inode_t *ip, | 866 | xfs_inode_t *ip) |
| 868 | int flag, | ||
| 869 | xfs_off_t start, | ||
| 870 | xfs_off_t stop) | ||
| 871 | { | 867 | { |
| 872 | xfs_trans_t *tp; | 868 | xfs_trans_t *tp; |
| 873 | int error; | 869 | int error; |
| @@ -875,103 +871,79 @@ xfs_fsync( | |||
| 875 | 871 | ||
| 876 | xfs_itrace_entry(ip); | 872 | xfs_itrace_entry(ip); |
| 877 | 873 | ||
| 878 | ASSERT(start >= 0 && stop >= -1); | ||
| 879 | |||
| 880 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 874 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
| 881 | return XFS_ERROR(EIO); | 875 | return XFS_ERROR(EIO); |
| 882 | 876 | ||
| 883 | if (flag & FSYNC_DATA) | 877 | /* capture size updates in I/O completion before writing the inode. */ |
| 884 | filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); | 878 | error = filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping); |
| 879 | if (error) | ||
| 880 | return XFS_ERROR(error); | ||
| 885 | 881 | ||
| 886 | /* | 882 | /* |
| 887 | * We always need to make sure that the required inode state | 883 | * We always need to make sure that the required inode state is safe on |
| 888 | * is safe on disk. The vnode might be clean but because | 884 | * disk. The vnode might be clean but we still might need to force the |
| 889 | * of committed transactions that haven't hit the disk yet. | 885 | * log because of committed transactions that haven't hit the disk yet. |
| 890 | * Likewise, there could be unflushed non-transactional | 886 | * Likewise, there could be unflushed non-transactional changes to the |
| 891 | * changes to the inode core that have to go to disk. | 887 | * inode core that have to go to disk and this requires us to issue |
| 888 | * a synchronous transaction to capture these changes correctly. | ||
| 892 | * | 889 | * |
| 893 | * The following code depends on one assumption: that | 890 | * This code relies on the assumption that if the update_* fields |
| 894 | * any transaction that changes an inode logs the core | 891 | * of the inode are clear and the inode is unpinned then it is clean |
| 895 | * because it has to change some field in the inode core | 892 | * and no action is required. |
| 896 | * (typically nextents or nblocks). That assumption | ||
| 897 | * implies that any transactions against an inode will | ||
| 898 | * catch any non-transactional updates. If inode-altering | ||
| 899 | * transactions exist that violate this assumption, the | ||
| 900 | * code breaks. Right now, it figures that if the involved | ||
| 901 | * update_* field is clear and the inode is unpinned, the | ||
| 902 | * inode is clean. Either it's been flushed or it's been | ||
| 903 | * committed and the commit has hit the disk unpinning the inode. | ||
| 904 | * (Note that xfs_inode_item_format() called at commit clears | ||
| 905 | * the update_* fields.) | ||
| 906 | */ | 893 | */ |
| 907 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 894 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| 908 | 895 | ||
| 909 | /* If we are flushing data then we care about update_size | 896 | if (!(ip->i_update_size || ip->i_update_core)) { |
| 910 | * being set, otherwise we care about update_core | ||
| 911 | */ | ||
| 912 | if ((flag & FSYNC_DATA) ? | ||
| 913 | (ip->i_update_size == 0) : | ||
| 914 | (ip->i_update_core == 0)) { | ||
| 915 | /* | 897 | /* |
| 916 | * Timestamps/size haven't changed since last inode | 898 | * Timestamps/size haven't changed since last inode flush or |
| 917 | * flush or inode transaction commit. That means | 899 | * inode transaction commit. That means either nothing got |
| 918 | * either nothing got written or a transaction | 900 | * written or a transaction committed which caught the updates. |
| 919 | * committed which caught the updates. If the | 901 | * If the latter happened and the transaction hasn't hit the |
| 920 | * latter happened and the transaction hasn't | 902 | * disk yet, the inode will be still be pinned. If it is, |
| 921 | * hit the disk yet, the inode will be still | 903 | * force the log. |
| 922 | * be pinned. If it is, force the log. | ||
| 923 | */ | 904 | */ |
| 924 | 905 | ||
| 925 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 906 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
| 926 | 907 | ||
| 927 | if (xfs_ipincount(ip)) { | 908 | if (xfs_ipincount(ip)) { |
| 928 | _xfs_log_force(ip->i_mount, (xfs_lsn_t)0, | 909 | error = _xfs_log_force(ip->i_mount, (xfs_lsn_t)0, |
| 929 | XFS_LOG_FORCE | | 910 | XFS_LOG_FORCE | XFS_LOG_SYNC, |
| 930 | ((flag & FSYNC_WAIT) | ||
| 931 | ? XFS_LOG_SYNC : 0), | ||
| 932 | &log_flushed); | 911 | &log_flushed); |
| 933 | } else { | 912 | } else { |
| 934 | /* | 913 | /* |
| 935 | * If the inode is not pinned and nothing | 914 | * If the inode is not pinned and nothing has changed |
| 936 | * has changed we don't need to flush the | 915 | * we don't need to flush the cache. |
| 937 | * cache. | ||
| 938 | */ | 916 | */ |
| 939 | changed = 0; | 917 | changed = 0; |
| 940 | } | 918 | } |
| 941 | error = 0; | ||
| 942 | } else { | 919 | } else { |
| 943 | /* | 920 | /* |
| 944 | * Kick off a transaction to log the inode | 921 | * Kick off a transaction to log the inode core to get the |
| 945 | * core to get the updates. Make it | 922 | * updates. The sync transaction will also force the log. |
| 946 | * sync if FSYNC_WAIT is passed in (which | ||
| 947 | * is done by everybody but specfs). The | ||
| 948 | * sync transaction will also force the log. | ||
| 949 | */ | 923 | */ |
| 950 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 924 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
| 951 | tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS); | 925 | tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS); |
| 952 | if ((error = xfs_trans_reserve(tp, 0, | 926 | error = xfs_trans_reserve(tp, 0, |
| 953 | XFS_FSYNC_TS_LOG_RES(ip->i_mount), | 927 | XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0); |
| 954 | 0, 0, 0))) { | 928 | if (error) { |
| 955 | xfs_trans_cancel(tp, 0); | 929 | xfs_trans_cancel(tp, 0); |
| 956 | return error; | 930 | return error; |
| 957 | } | 931 | } |
| 958 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 932 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 959 | 933 | ||
| 960 | /* | 934 | /* |
| 961 | * Note - it's possible that we might have pushed | 935 | * Note - it's possible that we might have pushed ourselves out |
| 962 | * ourselves out of the way during trans_reserve | 936 | * of the way during trans_reserve which would flush the inode. |
| 963 | * which would flush the inode. But there's no | 937 | * But there's no guarantee that the inode buffer has actually |
| 964 | * guarantee that the inode buffer has actually | 938 | * gone out yet (it's delwri). Plus the buffer could be pinned |
| 965 | * gone out yet (it's delwri). Plus the buffer | 939 | * anyway if it's part of an inode in another recent |
| 966 | * could be pinned anyway if it's part of an | 940 | * transaction. So we play it safe and fire off the |
| 967 | * inode in another recent transaction. So we | 941 | * transaction anyway. |
| 968 | * play it safe and fire off the transaction anyway. | ||
| 969 | */ | 942 | */ |
| 970 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 943 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
| 971 | xfs_trans_ihold(tp, ip); | 944 | xfs_trans_ihold(tp, ip); |
| 972 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 945 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
| 973 | if (flag & FSYNC_WAIT) | 946 | xfs_trans_set_sync(tp); |
| 974 | xfs_trans_set_sync(tp); | ||
| 975 | error = _xfs_trans_commit(tp, 0, &log_flushed); | 947 | error = _xfs_trans_commit(tp, 0, &log_flushed); |
| 976 | 948 | ||
| 977 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 949 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index 8abe8f186e20..57335ba4ce53 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
| @@ -18,8 +18,7 @@ int xfs_open(struct xfs_inode *ip); | |||
| 18 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, | 18 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, |
| 19 | struct cred *credp); | 19 | struct cred *credp); |
| 20 | int xfs_readlink(struct xfs_inode *ip, char *link); | 20 | int xfs_readlink(struct xfs_inode *ip, char *link); |
| 21 | int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start, | 21 | int xfs_fsync(struct xfs_inode *ip); |
| 22 | xfs_off_t stop); | ||
| 23 | int xfs_release(struct xfs_inode *ip); | 22 | int xfs_release(struct xfs_inode *ip); |
| 24 | int xfs_inactive(struct xfs_inode *ip); | 23 | int xfs_inactive(struct xfs_inode *ip); |
| 25 | int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, | 24 | int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, |
diff --git a/include/asm-arm/arch-omap/board-palmte.h b/include/asm-arm/arch-omap/board-palmte.h index cd22035a7160..6fac2c8935be 100644 --- a/include/asm-arm/arch-omap/board-palmte.h +++ b/include/asm-arm/arch-omap/board-palmte.h | |||
| @@ -14,8 +14,6 @@ | |||
| 14 | #ifndef __OMAP_BOARD_PALMTE_H | 14 | #ifndef __OMAP_BOARD_PALMTE_H |
| 15 | #define __OMAP_BOARD_PALMTE_H | 15 | #define __OMAP_BOARD_PALMTE_H |
| 16 | 16 | ||
| 17 | #include <asm/arch/gpio.h> | ||
| 18 | |||
| 19 | #define PALMTE_USBDETECT_GPIO 0 | 17 | #define PALMTE_USBDETECT_GPIO 0 |
| 20 | #define PALMTE_USB_OR_DC_GPIO 1 | 18 | #define PALMTE_USB_OR_DC_GPIO 1 |
| 21 | #define PALMTE_TSC_GPIO 4 | 19 | #define PALMTE_TSC_GPIO 4 |
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h index 57523bdb642b..12a5e4de9518 100644 --- a/include/asm-arm/arch-omap/clock.h +++ b/include/asm-arm/arch-omap/clock.h | |||
| @@ -73,6 +73,8 @@ struct clk { | |||
| 73 | #endif | 73 | #endif |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | struct cpufreq_frequency_table; | ||
| 77 | |||
| 76 | struct clk_functions { | 78 | struct clk_functions { |
| 77 | int (*clk_enable)(struct clk *clk); | 79 | int (*clk_enable)(struct clk *clk); |
| 78 | void (*clk_disable)(struct clk *clk); | 80 | void (*clk_disable)(struct clk *clk); |
| @@ -83,6 +85,9 @@ struct clk_functions { | |||
| 83 | void (*clk_allow_idle)(struct clk *clk); | 85 | void (*clk_allow_idle)(struct clk *clk); |
| 84 | void (*clk_deny_idle)(struct clk *clk); | 86 | void (*clk_deny_idle)(struct clk *clk); |
| 85 | void (*clk_disable_unused)(struct clk *clk); | 87 | void (*clk_disable_unused)(struct clk *clk); |
| 88 | #ifdef CONFIG_CPU_FREQ | ||
| 89 | void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); | ||
| 90 | #endif | ||
| 86 | }; | 91 | }; |
| 87 | 92 | ||
| 88 | extern unsigned int mpurate; | 93 | extern unsigned int mpurate; |
diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S index 74cd57221c8e..369093a45fcf 100644 --- a/include/asm-arm/arch-omap/entry-macro.S +++ b/include/asm-arm/arch-omap/entry-macro.S | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
| 9 | */ | 9 | */ |
| 10 | #include <asm/hardware.h> | 10 | #include <asm/hardware.h> |
| 11 | #include <asm/arch/io.h> | ||
| 11 | #include <asm/arch/irqs.h> | 12 | #include <asm/arch/irqs.h> |
| 12 | 13 | ||
| 13 | #if defined(CONFIG_ARCH_OMAP1) | 14 | #if defined(CONFIG_ARCH_OMAP1) |
diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h index 86621a04cd8f..5ee6a49864c3 100644 --- a/include/asm-arm/arch-omap/gpio.h +++ b/include/asm-arm/arch-omap/gpio.h | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #ifndef __ASM_ARCH_OMAP_GPIO_H | 26 | #ifndef __ASM_ARCH_OMAP_GPIO_H |
| 27 | #define __ASM_ARCH_OMAP_GPIO_H | 27 | #define __ASM_ARCH_OMAP_GPIO_H |
| 28 | 28 | ||
| 29 | #include <asm/hardware.h> | ||
| 30 | #include <asm/arch/irqs.h> | 29 | #include <asm/arch/irqs.h> |
| 31 | #include <asm/io.h> | 30 | #include <asm/io.h> |
| 32 | 31 | ||
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h index da572092e255..91d85b3417b7 100644 --- a/include/asm-arm/arch-omap/hardware.h +++ b/include/asm-arm/arch-omap/hardware.h | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <asm/types.h> | 41 | #include <asm/types.h> |
| 42 | #include <asm/arch/cpu.h> | 42 | #include <asm/arch/cpu.h> |
| 43 | #endif | 43 | #endif |
| 44 | #include <asm/arch/io.h> | ||
| 45 | #include <asm/arch/serial.h> | 44 | #include <asm/arch/serial.h> |
| 46 | 45 | ||
| 47 | /* | 46 | /* |
diff --git a/include/asm-arm/arch-sa1100/collie.h b/include/asm-arm/arch-sa1100/collie.h index 14a344aa3cc7..762eba535813 100644 --- a/include/asm-arm/arch-sa1100/collie.h +++ b/include/asm-arm/arch-sa1100/collie.h | |||
| @@ -34,9 +34,12 @@ | |||
| 34 | 34 | ||
| 35 | #define COLLIE_GPIO_ON_KEY GPIO_GPIO (0) | 35 | #define COLLIE_GPIO_ON_KEY GPIO_GPIO (0) |
| 36 | #define COLLIE_GPIO_AC_IN GPIO_GPIO (1) | 36 | #define COLLIE_GPIO_AC_IN GPIO_GPIO (1) |
| 37 | #define COLLIE_GPIO_SDIO_INT GPIO_GPIO (11) | ||
| 37 | #define COLLIE_GPIO_CF_IRQ GPIO_GPIO (14) | 38 | #define COLLIE_GPIO_CF_IRQ GPIO_GPIO (14) |
| 38 | #define COLLIE_GPIO_nREMOCON_INT GPIO_GPIO (15) | 39 | #define COLLIE_GPIO_nREMOCON_INT GPIO_GPIO (15) |
| 39 | #define COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO (16) | 40 | #define COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO (16) |
| 41 | #define COLLIE_GPIO_nMIC_ON GPIO_GPIO (17) | ||
| 42 | #define COLLIE_GPIO_nREMOCON_ON GPIO_GPIO (18) | ||
| 40 | #define COLLIE_GPIO_CO GPIO_GPIO (20) | 43 | #define COLLIE_GPIO_CO GPIO_GPIO (20) |
| 41 | #define COLLIE_GPIO_MCP_CLK GPIO_GPIO (21) | 44 | #define COLLIE_GPIO_MCP_CLK GPIO_GPIO (21) |
| 42 | #define COLLIE_GPIO_CF_CD GPIO_GPIO (22) | 45 | #define COLLIE_GPIO_CF_CD GPIO_GPIO (22) |
| @@ -49,6 +52,7 @@ | |||
| 49 | 52 | ||
| 50 | #define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0 | 53 | #define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0 |
| 51 | #define COLLIE_IRQ_GPIO_AC_IN IRQ_GPIO1 | 54 | #define COLLIE_IRQ_GPIO_AC_IN IRQ_GPIO1 |
| 55 | #define COLLIE_IRQ_GPIO_SDIO_IRQ IRQ_GPIO11 | ||
| 52 | #define COLLIE_IRQ_GPIO_CF_IRQ IRQ_GPIO14 | 56 | #define COLLIE_IRQ_GPIO_CF_IRQ IRQ_GPIO14 |
| 53 | #define COLLIE_IRQ_GPIO_nREMOCON_INT IRQ_GPIO15 | 57 | #define COLLIE_IRQ_GPIO_nREMOCON_INT IRQ_GPIO15 |
| 54 | #define COLLIE_IRQ_GPIO_CO IRQ_GPIO20 | 58 | #define COLLIE_IRQ_GPIO_CO IRQ_GPIO20 |
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h index 5c22b0112106..8e05bdb5f12f 100644 --- a/include/asm-arm/page.h +++ b/include/asm-arm/page.h | |||
| @@ -179,10 +179,10 @@ typedef unsigned long pgprot_t; | |||
| 179 | 179 | ||
| 180 | #endif /* STRICT_MM_TYPECHECKS */ | 180 | #endif /* STRICT_MM_TYPECHECKS */ |
| 181 | 181 | ||
| 182 | typedef struct page *pgtable_t; | ||
| 183 | |||
| 184 | #endif /* CONFIG_MMU */ | 182 | #endif /* CONFIG_MMU */ |
| 185 | 183 | ||
| 184 | typedef struct page *pgtable_t; | ||
| 185 | |||
| 186 | #include <asm/memory.h> | 186 | #include <asm/memory.h> |
| 187 | 187 | ||
| 188 | #endif /* !__ASSEMBLY__ */ | 188 | #endif /* !__ASSEMBLY__ */ |
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 6335de9a2bb3..514af792a598 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h | |||
| @@ -48,20 +48,6 @@ | |||
| 48 | #define CPUID_TCM 2 | 48 | #define CPUID_TCM 2 |
| 49 | #define CPUID_TLBTYPE 3 | 49 | #define CPUID_TLBTYPE 3 |
| 50 | 50 | ||
| 51 | #ifdef CONFIG_CPU_CP15 | ||
| 52 | #define read_cpuid(reg) \ | ||
| 53 | ({ \ | ||
| 54 | unsigned int __val; \ | ||
| 55 | asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \ | ||
| 56 | : "=r" (__val) \ | ||
| 57 | : \ | ||
| 58 | : "cc"); \ | ||
| 59 | __val; \ | ||
| 60 | }) | ||
| 61 | #else | ||
| 62 | #define read_cpuid(reg) (processor_id) | ||
| 63 | #endif | ||
| 64 | |||
| 65 | /* | 51 | /* |
| 66 | * This is used to ensure the compiler did actually allocate the register we | 52 | * This is used to ensure the compiler did actually allocate the register we |
| 67 | * asked it for some inline assembly sequences. Apparently we can't trust | 53 | * asked it for some inline assembly sequences. Apparently we can't trust |
| @@ -78,6 +64,21 @@ | |||
| 78 | #include <linux/stringify.h> | 64 | #include <linux/stringify.h> |
| 79 | #include <linux/irqflags.h> | 65 | #include <linux/irqflags.h> |
| 80 | 66 | ||
| 67 | #ifdef CONFIG_CPU_CP15 | ||
| 68 | #define read_cpuid(reg) \ | ||
| 69 | ({ \ | ||
| 70 | unsigned int __val; \ | ||
| 71 | asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \ | ||
| 72 | : "=r" (__val) \ | ||
| 73 | : \ | ||
| 74 | : "cc"); \ | ||
| 75 | __val; \ | ||
| 76 | }) | ||
| 77 | #else | ||
| 78 | extern unsigned int processor_id; | ||
| 79 | #define read_cpuid(reg) (processor_id) | ||
| 80 | #endif | ||
| 81 | |||
| 81 | /* | 82 | /* |
| 82 | * The CPU ID never changes at run time, so we might as well tell the | 83 | * The CPU ID never changes at run time, so we might as well tell the |
| 83 | * compiler that it's constant. Use this function to read the CPU ID | 84 | * compiler that it's constant. Use this function to read the CPU ID |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index ecf675a59d21..6be061d09da9 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
| @@ -1,8 +1,12 @@ | |||
| 1 | #ifndef _ASM_GENERIC_GPIO_H | 1 | #ifndef _ASM_GENERIC_GPIO_H |
| 2 | #define _ASM_GENERIC_GPIO_H | 2 | #define _ASM_GENERIC_GPIO_H |
| 3 | 3 | ||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 4 | #ifdef CONFIG_HAVE_GPIO_LIB | 6 | #ifdef CONFIG_HAVE_GPIO_LIB |
| 5 | 7 | ||
| 8 | #include <linux/compiler.h> | ||
| 9 | |||
| 6 | /* Platforms may implement their GPIO interface with library code, | 10 | /* Platforms may implement their GPIO interface with library code, |
| 7 | * at a small performance cost for non-inlined operations and some | 11 | * at a small performance cost for non-inlined operations and some |
| 8 | * extra memory (for code and for per-GPIO table entries). | 12 | * extra memory (for code and for per-GPIO table entries). |
| @@ -74,7 +78,7 @@ struct gpio_chip { | |||
| 74 | 78 | ||
| 75 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, | 79 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, |
| 76 | unsigned offset); | 80 | unsigned offset); |
| 77 | extern int __init __must_check gpiochip_reserve(int start, int ngpio); | 81 | extern int __must_check gpiochip_reserve(int start, int ngpio); |
| 78 | 82 | ||
| 79 | /* add/remove chips */ | 83 | /* add/remove chips */ |
| 80 | extern int gpiochip_add(struct gpio_chip *chip); | 84 | extern int gpiochip_add(struct gpio_chip *chip); |
diff --git a/include/asm-mips/gic.h b/include/asm-mips/gic.h index 01b2f92dc33d..3a492f225f00 100644 --- a/include/asm-mips/gic.h +++ b/include/asm-mips/gic.h | |||
| @@ -330,7 +330,7 @@ | |||
| 330 | 330 | ||
| 331 | #define GIC_SH_RMASK_OFS 0x0300 | 331 | #define GIC_SH_RMASK_OFS 0x0300 |
| 332 | #define GIC_CLR_INTR_MASK(intr, val) \ | 332 | #define GIC_CLR_INTR_MASK(intr, val) \ |
| 333 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32)) | 333 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32))) |
| 334 | 334 | ||
| 335 | /* Register Map for Local Section */ | 335 | /* Register Map for Local Section */ |
| 336 | #define GIC_VPE_CTL_OFS 0x0000 | 336 | #define GIC_VPE_CTL_OFS 0x0000 |
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h index 363a14ee0ae5..1b5064dac007 100644 --- a/include/asm-mips/mach-au1x00/au1000.h +++ b/include/asm-mips/mach-au1x00/au1000.h | |||
| @@ -1036,7 +1036,7 @@ enum soc_au1200_ints { | |||
| 1036 | #define USBD_INTSTAT 0xB020001C | 1036 | #define USBD_INTSTAT 0xB020001C |
| 1037 | # define USBDEV_INT_SOF (1 << 12) | 1037 | # define USBDEV_INT_SOF (1 << 12) |
| 1038 | # define USBDEV_INT_HF_BIT 6 | 1038 | # define USBDEV_INT_HF_BIT 6 |
| 1039 | # define USBDEV_INT_HF_MASK 0x3f << USBDEV_INT_HF_BIT) | 1039 | # define USBDEV_INT_HF_MASK (0x3f << USBDEV_INT_HF_BIT) |
| 1040 | # define USBDEV_INT_CMPLT_BIT 0 | 1040 | # define USBDEV_INT_CMPLT_BIT 0 |
| 1041 | # define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT) | 1041 | # define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT) |
| 1042 | #define USBD_CONFIG 0xB0200020 | 1042 | #define USBD_CONFIG 0xB0200020 |
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index 943c5a3fac8a..a4d0f876b427 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h | |||
| @@ -428,12 +428,11 @@ extern void mpic_init(struct mpic *mpic); | |||
| 428 | */ | 428 | */ |
| 429 | 429 | ||
| 430 | 430 | ||
| 431 | /* Change/Read the priority of an interrupt. Default is 8 for irqs and | 431 | /* Change the priority of an interrupt. Default is 8 for irqs and |
| 432 | * 10 for IPIs. You can call this on both IPIs and IRQ numbers, but the | 432 | * 10 for IPIs. You can call this on both IPIs and IRQ numbers, but the |
| 433 | * IPI number is then the offset'ed (linux irq number mapped to the IPI) | 433 | * IPI number is then the offset'ed (linux irq number mapped to the IPI) |
| 434 | */ | 434 | */ |
| 435 | extern void mpic_irq_set_priority(unsigned int irq, unsigned int pri); | 435 | extern void mpic_irq_set_priority(unsigned int irq, unsigned int pri); |
| 436 | extern unsigned int mpic_irq_get_priority(unsigned int irq); | ||
| 437 | 436 | ||
| 438 | /* Setup a non-boot CPU */ | 437 | /* Setup a non-boot CPU */ |
| 439 | extern void mpic_setup_this_cpu(void); | 438 | extern void mpic_setup_this_cpu(void); |
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 4987a84078ef..98be6c5762b9 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
| @@ -8,6 +8,9 @@ | |||
| 8 | 8 | ||
| 9 | #else | 9 | #else |
| 10 | 10 | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | |||
| 11 | /* | 14 | /* |
| 12 | * Some platforms don't support the GPIO programming interface. | 15 | * Some platforms don't support the GPIO programming interface. |
| 13 | * | 16 | * |
diff --git a/include/linux/mman.h b/include/linux/mman.h index 87920a0852a3..dab8892e6ff1 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h | |||
| @@ -17,14 +17,14 @@ | |||
| 17 | 17 | ||
| 18 | extern int sysctl_overcommit_memory; | 18 | extern int sysctl_overcommit_memory; |
| 19 | extern int sysctl_overcommit_ratio; | 19 | extern int sysctl_overcommit_ratio; |
| 20 | extern atomic_t vm_committed_space; | 20 | extern atomic_long_t vm_committed_space; |
| 21 | 21 | ||
| 22 | #ifdef CONFIG_SMP | 22 | #ifdef CONFIG_SMP |
| 23 | extern void vm_acct_memory(long pages); | 23 | extern void vm_acct_memory(long pages); |
| 24 | #else | 24 | #else |
| 25 | static inline void vm_acct_memory(long pages) | 25 | static inline void vm_acct_memory(long pages) |
| 26 | { | 26 | { |
| 27 | atomic_add(pages, &vm_committed_space); | 27 | atomic_long_add(pages, &vm_committed_space); |
| 28 | } | 28 | } |
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index c463cd8a15a4..443bc7cd8c62 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
| @@ -703,7 +703,7 @@ extern struct pglist_data *next_online_pgdat(struct pglist_data *pgdat); | |||
| 703 | extern struct zone *next_zone(struct zone *zone); | 703 | extern struct zone *next_zone(struct zone *zone); |
| 704 | 704 | ||
| 705 | /** | 705 | /** |
| 706 | * for_each_pgdat - helper macro to iterate over all nodes | 706 | * for_each_online_pgdat - helper macro to iterate over all online nodes |
| 707 | * @pgdat - pointer to a pg_data_t variable | 707 | * @pgdat - pointer to a pg_data_t variable |
| 708 | */ | 708 | */ |
| 709 | #define for_each_online_pgdat(pgdat) \ | 709 | #define for_each_online_pgdat(pgdat) \ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index cf6dbd759395..9b940e644179 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -1761,6 +1761,7 @@ | |||
| 1761 | 1761 | ||
| 1762 | #define PCI_VENDOR_ID_INTASHIELD 0x135a | 1762 | #define PCI_VENDOR_ID_INTASHIELD 0x135a |
| 1763 | #define PCI_DEVICE_ID_INTASHIELD_IS200 0x0d80 | 1763 | #define PCI_DEVICE_ID_INTASHIELD_IS200 0x0d80 |
| 1764 | #define PCI_DEVICE_ID_INTASHIELD_IS400 0x0dc0 | ||
| 1764 | 1765 | ||
| 1765 | #define PCI_VENDOR_ID_QUATECH 0x135C | 1766 | #define PCI_VENDOR_ID_QUATECH 0x135C |
| 1766 | #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 | 1767 | #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 |
| @@ -2383,6 +2384,9 @@ | |||
| 2383 | #define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30 | 2384 | #define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30 |
| 2384 | #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 | 2385 | #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 |
| 2385 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f | 2386 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f |
| 2387 | #define PCI_DEVICE_ID_INTEL_5400_ERR 0x4030 | ||
| 2388 | #define PCI_DEVICE_ID_INTEL_5400_FBD0 0x4035 | ||
| 2389 | #define PCI_DEVICE_ID_INTEL_5400_FBD1 0x4036 | ||
| 2386 | #define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff | 2390 | #define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff |
| 2387 | #define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031 | 2391 | #define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031 |
| 2388 | #define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032 | 2392 | #define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032 |
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index 47fbcba11850..78bfdea24a8e 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
| @@ -262,7 +262,6 @@ int bitmap_create(mddev_t *mddev); | |||
| 262 | void bitmap_flush(mddev_t *mddev); | 262 | void bitmap_flush(mddev_t *mddev); |
| 263 | void bitmap_destroy(mddev_t *mddev); | 263 | void bitmap_destroy(mddev_t *mddev); |
| 264 | 264 | ||
| 265 | char *file_path(struct file *file, char *buf, int count); | ||
| 266 | void bitmap_print_sb(struct bitmap *bitmap); | 265 | void bitmap_print_sb(struct bitmap *bitmap); |
| 267 | void bitmap_update_sb(struct bitmap *bitmap); | 266 | void bitmap_update_sb(struct bitmap *bitmap); |
| 268 | 267 | ||
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index 81a1a02d4566..b7386ae9d288 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h | |||
| @@ -72,6 +72,8 @@ | |||
| 72 | */ | 72 | */ |
| 73 | #define MD_PATCHLEVEL_VERSION 3 | 73 | #define MD_PATCHLEVEL_VERSION 3 |
| 74 | 74 | ||
| 75 | extern int mdp_major; | ||
| 76 | |||
| 75 | extern int register_md_personality (struct mdk_personality *p); | 77 | extern int register_md_personality (struct mdk_personality *p); |
| 76 | extern int unregister_md_personality (struct mdk_personality *p); | 78 | extern int unregister_md_personality (struct mdk_personality *p); |
| 77 | extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), | 79 | extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 812ffa590cff..3dea9f545c8f 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
| @@ -180,13 +180,15 @@ struct mddev_s | |||
| 180 | int sync_speed_min; | 180 | int sync_speed_min; |
| 181 | int sync_speed_max; | 181 | int sync_speed_max; |
| 182 | 182 | ||
| 183 | /* resync even though the same disks are shared among md-devices */ | ||
| 184 | int parallel_resync; | ||
| 185 | |||
| 183 | int ok_start_degraded; | 186 | int ok_start_degraded; |
| 184 | /* recovery/resync flags | 187 | /* recovery/resync flags |
| 185 | * NEEDED: we might need to start a resync/recover | 188 | * NEEDED: we might need to start a resync/recover |
| 186 | * RUNNING: a thread is running, or about to be started | 189 | * RUNNING: a thread is running, or about to be started |
| 187 | * SYNC: actually doing a resync, not a recovery | 190 | * SYNC: actually doing a resync, not a recovery |
| 188 | * ERR: and IO error was detected - abort the resync/recovery | 191 | * INTR: resync needs to be aborted for some reason |
| 189 | * INTR: someone requested a (clean) early abort. | ||
| 190 | * DONE: thread is done and is waiting to be reaped | 192 | * DONE: thread is done and is waiting to be reaped |
| 191 | * REQUEST: user-space has requested a sync (used with SYNC) | 193 | * REQUEST: user-space has requested a sync (used with SYNC) |
| 192 | * CHECK: user-space request for for check-only, no repair | 194 | * CHECK: user-space request for for check-only, no repair |
| @@ -196,7 +198,6 @@ struct mddev_s | |||
| 196 | */ | 198 | */ |
| 197 | #define MD_RECOVERY_RUNNING 0 | 199 | #define MD_RECOVERY_RUNNING 0 |
| 198 | #define MD_RECOVERY_SYNC 1 | 200 | #define MD_RECOVERY_SYNC 1 |
| 199 | #define MD_RECOVERY_ERR 2 | ||
| 200 | #define MD_RECOVERY_INTR 3 | 201 | #define MD_RECOVERY_INTR 3 |
| 201 | #define MD_RECOVERY_DONE 4 | 202 | #define MD_RECOVERY_DONE 4 |
| 202 | #define MD_RECOVERY_NEEDED 5 | 203 | #define MD_RECOVERY_NEEDED 5 |
diff --git a/include/linux/sm501.h b/include/linux/sm501.h index bca134544700..95c1c39ba445 100644 --- a/include/linux/sm501.h +++ b/include/linux/sm501.h | |||
| @@ -71,8 +71,8 @@ extern unsigned long sm501_gpio_get(struct device *dev, | |||
| 71 | #define SM501FB_FLAG_DISABLE_AT_EXIT (1<<1) | 71 | #define SM501FB_FLAG_DISABLE_AT_EXIT (1<<1) |
| 72 | #define SM501FB_FLAG_USE_HWCURSOR (1<<2) | 72 | #define SM501FB_FLAG_USE_HWCURSOR (1<<2) |
| 73 | #define SM501FB_FLAG_USE_HWACCEL (1<<3) | 73 | #define SM501FB_FLAG_USE_HWACCEL (1<<3) |
| 74 | #define SM501FB_FLAG_PANEL_USE_FPEN (1<<4) | 74 | #define SM501FB_FLAG_PANEL_NO_FPEN (1<<4) |
| 75 | #define SM501FB_FLAG_PANEL_USE_VBIASEN (1<<5) | 75 | #define SM501FB_FLAG_PANEL_NO_VBIASEN (1<<5) |
| 76 | 76 | ||
| 77 | struct sm501_platdata_fbsub { | 77 | struct sm501_platdata_fbsub { |
| 78 | struct fb_videomode *def_mode; | 78 | struct fb_videomode *def_mode; |
diff --git a/include/linux/types.h b/include/linux/types.h index 9dc2346627b4..d4a9ce6e2760 100644 --- a/include/linux/types.h +++ b/include/linux/types.h | |||
| @@ -197,8 +197,6 @@ typedef u64 resource_size_t; | |||
| 197 | typedef u32 resource_size_t; | 197 | typedef u32 resource_size_t; |
| 198 | #endif | 198 | #endif |
| 199 | 199 | ||
| 200 | #endif /* __KERNEL__ */ | ||
| 201 | |||
| 202 | struct ustat { | 200 | struct ustat { |
| 203 | __kernel_daddr_t f_tfree; | 201 | __kernel_daddr_t f_tfree; |
| 204 | __kernel_ino_t f_tinode; | 202 | __kernel_ino_t f_tinode; |
| @@ -206,4 +204,6 @@ struct ustat { | |||
| 206 | char f_fpack[6]; | 204 | char f_fpack[6]; |
| 207 | }; | 205 | }; |
| 208 | 206 | ||
| 207 | #endif /* __KERNEL__ */ | ||
| 208 | |||
| 209 | #endif /* _LINUX_TYPES_H */ | 209 | #endif /* _LINUX_TYPES_H */ |
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 7473b0c59d4d..693d24694a6c 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c | |||
| @@ -24,7 +24,6 @@ static struct { | |||
| 24 | 24 | ||
| 25 | static int md_setup_ents __initdata; | 25 | static int md_setup_ents __initdata; |
| 26 | 26 | ||
| 27 | extern int mdp_major; | ||
| 28 | /* | 27 | /* |
| 29 | * Parse the command-line parameters given our kernel, but do not | 28 | * Parse the command-line parameters given our kernel, but do not |
| 30 | * actually try to invoke the MD device now; that is handled by | 29 | * actually try to invoke the MD device now; that is handled by |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index fbc6fc8949b4..15ac0e1e4f4d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -2903,7 +2903,7 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys) | |||
| 2903 | cg = tsk->cgroups; | 2903 | cg = tsk->cgroups; |
| 2904 | parent = task_cgroup(tsk, subsys->subsys_id); | 2904 | parent = task_cgroup(tsk, subsys->subsys_id); |
| 2905 | 2905 | ||
| 2906 | snprintf(nodename, MAX_CGROUP_TYPE_NAMELEN, "node_%d", tsk->pid); | 2906 | snprintf(nodename, MAX_CGROUP_TYPE_NAMELEN, "%d", tsk->pid); |
| 2907 | 2907 | ||
| 2908 | /* Pin the hierarchy */ | 2908 | /* Pin the hierarchy */ |
| 2909 | atomic_inc(&parent->root->sb->s_active); | 2909 | atomic_inc(&parent->root->sb->s_active); |
diff --git a/kernel/exit.c b/kernel/exit.c index 1510f78a0ffa..8f6185e69b69 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -126,6 +126,12 @@ static void __exit_signal(struct task_struct *tsk) | |||
| 126 | 126 | ||
| 127 | __unhash_process(tsk); | 127 | __unhash_process(tsk); |
| 128 | 128 | ||
| 129 | /* | ||
| 130 | * Do this under ->siglock, we can race with another thread | ||
| 131 | * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals. | ||
| 132 | */ | ||
| 133 | flush_sigqueue(&tsk->pending); | ||
| 134 | |||
| 129 | tsk->signal = NULL; | 135 | tsk->signal = NULL; |
| 130 | tsk->sighand = NULL; | 136 | tsk->sighand = NULL; |
| 131 | spin_unlock(&sighand->siglock); | 137 | spin_unlock(&sighand->siglock); |
| @@ -133,7 +139,6 @@ static void __exit_signal(struct task_struct *tsk) | |||
| 133 | 139 | ||
| 134 | __cleanup_sighand(sighand); | 140 | __cleanup_sighand(sighand); |
| 135 | clear_tsk_thread_flag(tsk,TIF_SIGPENDING); | 141 | clear_tsk_thread_flag(tsk,TIF_SIGPENDING); |
| 136 | flush_sigqueue(&tsk->pending); | ||
| 137 | if (sig) { | 142 | if (sig) { |
| 138 | flush_sigqueue(&sig->shared_pending); | 143 | flush_sigqueue(&sig->shared_pending); |
| 139 | taskstats_tgid_free(sig); | 144 | taskstats_tgid_free(sig); |
diff --git a/kernel/module.c b/kernel/module.c index f5e9491ef7ac..5f80478b746d 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -1337,7 +1337,19 @@ out_unreg: | |||
| 1337 | kobject_put(&mod->mkobj.kobj); | 1337 | kobject_put(&mod->mkobj.kobj); |
| 1338 | return err; | 1338 | return err; |
| 1339 | } | 1339 | } |
| 1340 | #endif | 1340 | |
| 1341 | static void mod_sysfs_fini(struct module *mod) | ||
| 1342 | { | ||
| 1343 | kobject_put(&mod->mkobj.kobj); | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | #else /* CONFIG_SYSFS */ | ||
| 1347 | |||
| 1348 | static void mod_sysfs_fini(struct module *mod) | ||
| 1349 | { | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | #endif /* CONFIG_SYSFS */ | ||
| 1341 | 1353 | ||
| 1342 | static void mod_kobject_remove(struct module *mod) | 1354 | static void mod_kobject_remove(struct module *mod) |
| 1343 | { | 1355 | { |
| @@ -1345,7 +1357,7 @@ static void mod_kobject_remove(struct module *mod) | |||
| 1345 | module_param_sysfs_remove(mod); | 1357 | module_param_sysfs_remove(mod); |
| 1346 | kobject_put(mod->mkobj.drivers_dir); | 1358 | kobject_put(mod->mkobj.drivers_dir); |
| 1347 | kobject_put(mod->holders_dir); | 1359 | kobject_put(mod->holders_dir); |
| 1348 | kobject_put(&mod->mkobj.kobj); | 1360 | mod_sysfs_fini(mod); |
| 1349 | } | 1361 | } |
| 1350 | 1362 | ||
| 1351 | /* | 1363 | /* |
| @@ -1780,7 +1792,7 @@ static struct module *load_module(void __user *umod, | |||
| 1780 | 1792 | ||
| 1781 | /* Sanity checks against insmoding binaries or wrong arch, | 1793 | /* Sanity checks against insmoding binaries or wrong arch, |
| 1782 | weird elf version */ | 1794 | weird elf version */ |
| 1783 | if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 | 1795 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 |
| 1784 | || hdr->e_type != ET_REL | 1796 | || hdr->e_type != ET_REL |
| 1785 | || !elf_check_arch(hdr) | 1797 | || !elf_check_arch(hdr) |
| 1786 | || hdr->e_shentsize != sizeof(*sechdrs)) { | 1798 | || hdr->e_shentsize != sizeof(*sechdrs)) { |
diff --git a/kernel/signal.c b/kernel/signal.c index 72bb4f51f963..12ffea7c201d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -1242,7 +1242,8 @@ void sigqueue_free(struct sigqueue *q) | |||
| 1242 | /* | 1242 | /* |
| 1243 | * If the signal is still pending remove it from the | 1243 | * If the signal is still pending remove it from the |
| 1244 | * pending queue. We must hold ->siglock while testing | 1244 | * pending queue. We must hold ->siglock while testing |
| 1245 | * q->list to serialize with collect_signal(). | 1245 | * q->list to serialize with collect_signal() or with |
| 1246 | * __exit_signal()->flush_sigqueue(). | ||
| 1246 | */ | 1247 | */ |
| 1247 | spin_lock_irqsave(lock, flags); | 1248 | spin_lock_irqsave(lock, flags); |
| 1248 | if (!list_empty(&q->list)) | 1249 | if (!list_empty(&q->list)) |
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 0101aeef7ed7..b7350bbfb076 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c | |||
| @@ -62,8 +62,7 @@ static int stopmachine(void *cpu) | |||
| 62 | * help our sisters onto their CPUs. */ | 62 | * help our sisters onto their CPUs. */ |
| 63 | if (!prepared && !irqs_disabled) | 63 | if (!prepared && !irqs_disabled) |
| 64 | yield(); | 64 | yield(); |
| 65 | else | 65 | cpu_relax(); |
| 66 | cpu_relax(); | ||
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | /* Ack: we are exiting. */ | 68 | /* Ack: we are exiting. */ |
| @@ -106,8 +105,10 @@ static int stop_machine(void) | |||
| 106 | } | 105 | } |
| 107 | 106 | ||
| 108 | /* Wait for them all to come to life. */ | 107 | /* Wait for them all to come to life. */ |
| 109 | while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads) | 108 | while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads) { |
| 110 | yield(); | 109 | yield(); |
| 110 | cpu_relax(); | ||
| 111 | } | ||
| 111 | 112 | ||
| 112 | /* If some failed, kill them all. */ | 113 | /* If some failed, kill them all. */ |
| 113 | if (ret < 0) { | 114 | if (ret < 0) { |
diff --git a/kernel/sys.c b/kernel/sys.c index 895d2d4c9493..14e97282eb6c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1652,7 +1652,7 @@ asmlinkage long sys_umask(int mask) | |||
| 1652 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | 1652 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, |
| 1653 | unsigned long arg4, unsigned long arg5) | 1653 | unsigned long arg4, unsigned long arg5) |
| 1654 | { | 1654 | { |
| 1655 | long uninitialized_var(error); | 1655 | long error = 0; |
| 1656 | 1656 | ||
| 1657 | if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) | 1657 | if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) |
| 1658 | return error; | 1658 | return error; |
| @@ -1701,9 +1701,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
| 1701 | error = PR_TIMING_STATISTICAL; | 1701 | error = PR_TIMING_STATISTICAL; |
| 1702 | break; | 1702 | break; |
| 1703 | case PR_SET_TIMING: | 1703 | case PR_SET_TIMING: |
| 1704 | if (arg2 == PR_TIMING_STATISTICAL) | 1704 | if (arg2 != PR_TIMING_STATISTICAL) |
| 1705 | error = 0; | ||
| 1706 | else | ||
| 1707 | error = -EINVAL; | 1705 | error = -EINVAL; |
| 1708 | break; | 1706 | break; |
| 1709 | 1707 | ||
diff --git a/mm/memory.c b/mm/memory.c index fb5608a120ed..19e0ae9beecb 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -2295,8 +2295,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2295 | vmf.flags = flags; | 2295 | vmf.flags = flags; |
| 2296 | vmf.page = NULL; | 2296 | vmf.page = NULL; |
| 2297 | 2297 | ||
| 2298 | BUG_ON(vma->vm_flags & VM_PFNMAP); | ||
| 2299 | |||
| 2300 | ret = vma->vm_ops->fault(vma, &vmf); | 2298 | ret = vma->vm_ops->fault(vma, &vmf); |
| 2301 | if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) | 2299 | if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) |
| 2302 | return ret; | 2300 | return ret; |
| @@ -80,7 +80,7 @@ EXPORT_SYMBOL(vm_get_page_prot); | |||
| 80 | int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */ | 80 | int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */ |
| 81 | int sysctl_overcommit_ratio = 50; /* default is 50% */ | 81 | int sysctl_overcommit_ratio = 50; /* default is 50% */ |
| 82 | int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; | 82 | int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; |
| 83 | atomic_t vm_committed_space = ATOMIC_INIT(0); | 83 | atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0); |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| 86 | * Check that a process has enough memory to allocate a new virtual | 86 | * Check that a process has enough memory to allocate a new virtual |
| @@ -177,7 +177,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) | |||
| 177 | * cast `allowed' as a signed long because vm_committed_space | 177 | * cast `allowed' as a signed long because vm_committed_space |
| 178 | * sometimes has a negative value | 178 | * sometimes has a negative value |
| 179 | */ | 179 | */ |
| 180 | if (atomic_read(&vm_committed_space) < (long)allowed) | 180 | if (atomic_long_read(&vm_committed_space) < (long)allowed) |
| 181 | return 0; | 181 | return 0; |
| 182 | error: | 182 | error: |
| 183 | vm_unacct_memory(pages); | 183 | vm_unacct_memory(pages); |
diff --git a/mm/nommu.c b/mm/nommu.c index ef8c62cec697..dca93fcb8b7a 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -39,7 +39,7 @@ struct page *mem_map; | |||
| 39 | unsigned long max_mapnr; | 39 | unsigned long max_mapnr; |
| 40 | unsigned long num_physpages; | 40 | unsigned long num_physpages; |
| 41 | unsigned long askedalloc, realalloc; | 41 | unsigned long askedalloc, realalloc; |
| 42 | atomic_t vm_committed_space = ATOMIC_INIT(0); | 42 | atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0); |
| 43 | int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */ | 43 | int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */ |
| 44 | int sysctl_overcommit_ratio = 50; /* default is 50% */ | 44 | int sysctl_overcommit_ratio = 50; /* default is 50% */ |
| 45 | int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT; | 45 | int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT; |
| @@ -1410,7 +1410,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) | |||
| 1410 | * cast `allowed' as a signed long because vm_committed_space | 1410 | * cast `allowed' as a signed long because vm_committed_space |
| 1411 | * sometimes has a negative value | 1411 | * sometimes has a negative value |
| 1412 | */ | 1412 | */ |
| 1413 | if (atomic_read(&vm_committed_space) < (long)allowed) | 1413 | if (atomic_long_read(&vm_committed_space) < (long)allowed) |
| 1414 | return 0; | 1414 | return 0; |
| 1415 | error: | 1415 | error: |
| 1416 | vm_unacct_memory(pages); | 1416 | vm_unacct_memory(pages); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 63835579323a..8e83f02cd2d3 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1396,6 +1396,9 @@ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order, | |||
| 1396 | 1396 | ||
| 1397 | (void)first_zones_zonelist(zonelist, high_zoneidx, nodemask, | 1397 | (void)first_zones_zonelist(zonelist, high_zoneidx, nodemask, |
| 1398 | &preferred_zone); | 1398 | &preferred_zone); |
| 1399 | if (!preferred_zone) | ||
| 1400 | return NULL; | ||
| 1401 | |||
| 1399 | classzone_idx = zone_idx(preferred_zone); | 1402 | classzone_idx = zone_idx(preferred_zone); |
| 1400 | 1403 | ||
| 1401 | zonelist_scan: | 1404 | zonelist_scan: |
| @@ -2804,7 +2807,7 @@ int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) | |||
| 2804 | alloc_size = zone->wait_table_hash_nr_entries | 2807 | alloc_size = zone->wait_table_hash_nr_entries |
| 2805 | * sizeof(wait_queue_head_t); | 2808 | * sizeof(wait_queue_head_t); |
| 2806 | 2809 | ||
| 2807 | if (system_state == SYSTEM_BOOTING) { | 2810 | if (!slab_is_available()) { |
| 2808 | zone->wait_table = (wait_queue_head_t *) | 2811 | zone->wait_table = (wait_queue_head_t *) |
| 2809 | alloc_bootmem_node(pgdat, alloc_size); | 2812 | alloc_bootmem_node(pgdat, alloc_size); |
| 2810 | } else { | 2813 | } else { |
| @@ -3378,7 +3381,8 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, | |||
| 3378 | * is used by this zone for memmap. This affects the watermark | 3381 | * is used by this zone for memmap. This affects the watermark |
| 3379 | * and per-cpu initialisations | 3382 | * and per-cpu initialisations |
| 3380 | */ | 3383 | */ |
| 3381 | memmap_pages = (size * sizeof(struct page)) >> PAGE_SHIFT; | 3384 | memmap_pages = |
| 3385 | PAGE_ALIGN(size * sizeof(struct page)) >> PAGE_SHIFT; | ||
| 3382 | if (realsize >= memmap_pages) { | 3386 | if (realsize >= memmap_pages) { |
| 3383 | realsize -= memmap_pages; | 3387 | realsize -= memmap_pages; |
| 3384 | printk(KERN_DEBUG | 3388 | printk(KERN_DEBUG |
| @@ -503,7 +503,7 @@ void vm_acct_memory(long pages) | |||
| 503 | local = &__get_cpu_var(committed_space); | 503 | local = &__get_cpu_var(committed_space); |
| 504 | *local += pages; | 504 | *local += pages; |
| 505 | if (*local > ACCT_THRESHOLD || *local < -ACCT_THRESHOLD) { | 505 | if (*local > ACCT_THRESHOLD || *local < -ACCT_THRESHOLD) { |
| 506 | atomic_add(*local, &vm_committed_space); | 506 | atomic_long_add(*local, &vm_committed_space); |
| 507 | *local = 0; | 507 | *local = 0; |
| 508 | } | 508 | } |
| 509 | preempt_enable(); | 509 | preempt_enable(); |
| @@ -520,7 +520,7 @@ static int cpu_swap_callback(struct notifier_block *nfb, | |||
| 520 | 520 | ||
| 521 | committed = &per_cpu(committed_space, (long)hcpu); | 521 | committed = &per_cpu(committed_space, (long)hcpu); |
| 522 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { | 522 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { |
| 523 | atomic_add(*committed, &vm_committed_space); | 523 | atomic_long_add(*committed, &vm_committed_space); |
| 524 | *committed = 0; | 524 | *committed = 0; |
| 525 | drain_cpu_pagevecs((long)hcpu); | 525 | drain_cpu_pagevecs((long)hcpu); |
| 526 | } | 526 | } |
