diff options
138 files changed, 3247 insertions, 1328 deletions
diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index 5147be5e13cd..b58b84b50fa2 100644 --- a/Documentation/filesystems/vfat.txt +++ b/Documentation/filesystems/vfat.txt | |||
| @@ -132,6 +132,11 @@ rodir -- FAT has the ATTR_RO (read-only) attribute. On Windows, | |||
| 132 | If you want to use ATTR_RO as read-only flag even for | 132 | If you want to use ATTR_RO as read-only flag even for |
| 133 | the directory, set this option. | 133 | the directory, set this option. |
| 134 | 134 | ||
| 135 | errors=panic|continue|remount-ro | ||
| 136 | -- specify FAT behavior on critical errors: panic, continue | ||
| 137 | without doing anything or remount the partition in | ||
| 138 | read-only mode (default behavior). | ||
| 139 | |||
| 135 | <bool>: 0,1,yes,no,true,false | 140 | <bool>: 0,1,yes,no,true,false |
| 136 | 141 | ||
| 137 | TODO | 142 | TODO |
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg index a8321267b5b6..bee4c30bc1e2 100644 --- a/Documentation/hwmon/f71882fg +++ b/Documentation/hwmon/f71882fg | |||
| @@ -2,14 +2,18 @@ Kernel driver f71882fg | |||
| 2 | ====================== | 2 | ====================== |
| 3 | 3 | ||
| 4 | Supported chips: | 4 | Supported chips: |
| 5 | * Fintek F71882FG and F71883FG | 5 | * Fintek F71858FG |
| 6 | Prefix: 'f71882fg' | 6 | Prefix: 'f71858fg' |
| 7 | Addresses scanned: none, address read from Super I/O config space | 7 | Addresses scanned: none, address read from Super I/O config space |
| 8 | Datasheet: Available from the Fintek website | 8 | Datasheet: Available from the Fintek website |
| 9 | * Fintek F71862FG and F71863FG | 9 | * Fintek F71862FG and F71863FG |
| 10 | Prefix: 'f71862fg' | 10 | Prefix: 'f71862fg' |
| 11 | Addresses scanned: none, address read from Super I/O config space | 11 | Addresses scanned: none, address read from Super I/O config space |
| 12 | Datasheet: Available from the Fintek website | 12 | Datasheet: Available from the Fintek website |
| 13 | * Fintek F71882FG and F71883FG | ||
| 14 | Prefix: 'f71882fg' | ||
| 15 | Addresses scanned: none, address read from Super I/O config space | ||
| 16 | Datasheet: Available from the Fintek website | ||
| 13 | * Fintek F8000 | 17 | * Fintek F8000 |
| 14 | Prefix: 'f8000' | 18 | Prefix: 'f8000' |
| 15 | Addresses scanned: none, address read from Super I/O config space | 19 | Addresses scanned: none, address read from Super I/O config space |
| @@ -66,13 +70,13 @@ printed when loading the driver. | |||
| 66 | 70 | ||
| 67 | Three different fan control modes are supported; the mode number is written | 71 | Three different fan control modes are supported; the mode number is written |
| 68 | to the pwm#_enable file. Note that not all modes are supported on all | 72 | to the pwm#_enable file. Note that not all modes are supported on all |
| 69 | chips, and some modes may only be available in RPM / PWM mode on the F8000. | 73 | chips, and some modes may only be available in RPM / PWM mode. |
| 70 | Writing an unsupported mode will result in an invalid parameter error. | 74 | Writing an unsupported mode will result in an invalid parameter error. |
| 71 | 75 | ||
| 72 | * 1: Manual mode | 76 | * 1: Manual mode |
| 73 | You ask for a specific PWM duty cycle / DC voltage or a specific % of | 77 | You ask for a specific PWM duty cycle / DC voltage or a specific % of |
| 74 | fan#_full_speed by writing to the pwm# file. This mode is only | 78 | fan#_full_speed by writing to the pwm# file. This mode is only |
| 75 | available on the F8000 if the fan channel is in RPM mode. | 79 | available on the F71858FG / F8000 if the fan channel is in RPM mode. |
| 76 | 80 | ||
| 77 | * 2: Normal auto mode | 81 | * 2: Normal auto mode |
| 78 | You can define a number of temperature/fan speed trip points, which % the | 82 | You can define a number of temperature/fan speed trip points, which % the |
diff --git a/Documentation/hwmon/ibmaem b/Documentation/hwmon/ibmaem index e98bdfea3467..1e0d59e000b4 100644 --- a/Documentation/hwmon/ibmaem +++ b/Documentation/hwmon/ibmaem | |||
| @@ -7,7 +7,7 @@ henceforth as AEM. | |||
| 7 | Supported systems: | 7 | Supported systems: |
| 8 | * Any recent IBM System X server with AEM support. | 8 | * Any recent IBM System X server with AEM support. |
| 9 | This includes the x3350, x3550, x3650, x3655, x3755, x3850 M2, | 9 | This includes the x3350, x3550, x3650, x3655, x3755, x3850 M2, |
| 10 | x3950 M2, and certain HS2x/LS2x/QS2x blades. The IPMI host interface | 10 | x3950 M2, and certain HC10/HS2x/LS2x/QS2x blades. The IPMI host interface |
| 11 | driver ("ipmi-si") needs to be loaded for this driver to do anything. | 11 | driver ("ipmi-si") needs to be loaded for this driver to do anything. |
| 12 | Prefix: 'ibmaem' | 12 | Prefix: 'ibmaem' |
| 13 | Datasheet: Not available | 13 | Datasheet: Not available |
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index 004ee161721e..dcbd502c8792 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
| @@ -70,6 +70,7 @@ are interpreted as 0! For more on how written strings are interpreted see the | |||
| 70 | [0-*] denotes any positive number starting from 0 | 70 | [0-*] denotes any positive number starting from 0 |
| 71 | [1-*] denotes any positive number starting from 1 | 71 | [1-*] denotes any positive number starting from 1 |
| 72 | RO read only value | 72 | RO read only value |
| 73 | WO write only value | ||
| 73 | RW read/write value | 74 | RW read/write value |
| 74 | 75 | ||
| 75 | Read/write values may be read-only for some chips, depending on the | 76 | Read/write values may be read-only for some chips, depending on the |
| @@ -295,6 +296,24 @@ temp[1-*]_label Suggested temperature channel label. | |||
| 295 | user-space. | 296 | user-space. |
| 296 | RO | 297 | RO |
| 297 | 298 | ||
| 299 | temp[1-*]_lowest | ||
| 300 | Historical minimum temperature | ||
| 301 | Unit: millidegree Celsius | ||
| 302 | RO | ||
| 303 | |||
| 304 | temp[1-*]_highest | ||
| 305 | Historical maximum temperature | ||
| 306 | Unit: millidegree Celsius | ||
| 307 | RO | ||
| 308 | |||
| 309 | temp[1-*]_reset_history | ||
| 310 | Reset temp_lowest and temp_highest | ||
| 311 | WO | ||
| 312 | |||
| 313 | temp_reset_history | ||
| 314 | Reset temp_lowest and temp_highest for all sensors | ||
| 315 | WO | ||
| 316 | |||
| 298 | Some chips measure temperature using external thermistors and an ADC, and | 317 | Some chips measure temperature using external thermistors and an ADC, and |
| 299 | report the temperature measurement as a voltage. Converting this voltage | 318 | report the temperature measurement as a voltage. Converting this voltage |
| 300 | back to a temperature (or the other way around for limits) requires | 319 | back to a temperature (or the other way around for limits) requires |
diff --git a/Documentation/hwmon/tmp401 b/Documentation/hwmon/tmp401 new file mode 100644 index 000000000000..9fc447249212 --- /dev/null +++ b/Documentation/hwmon/tmp401 | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | Kernel driver tmp401 | ||
| 2 | ==================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * Texas Instruments TMP401 | ||
| 6 | Prefix: 'tmp401' | ||
| 7 | Addresses scanned: I2C 0x4c | ||
| 8 | Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp401.html | ||
| 9 | * Texas Instruments TMP411 | ||
| 10 | Prefix: 'tmp411' | ||
| 11 | Addresses scanned: I2C 0x4c | ||
| 12 | Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp411.html | ||
| 13 | |||
| 14 | Authors: | ||
| 15 | Hans de Goede <hdegoede@redhat.com> | ||
| 16 | Andre Prendel <andre.prendel@gmx.de> | ||
| 17 | |||
| 18 | Description | ||
| 19 | ----------- | ||
| 20 | |||
| 21 | This driver implements support for Texas Instruments TMP401 and | ||
| 22 | TMP411 chips. These chips implements one remote and one local | ||
| 23 | temperature sensor. Temperature is measured in degrees | ||
| 24 | Celsius. Resolution of the remote sensor is 0.0625 degree. Local | ||
| 25 | sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not | ||
| 26 | supported by the driver so far, so using the default resolution of 0.5 | ||
| 27 | degree). | ||
| 28 | |||
| 29 | The driver provides the common sysfs-interface for temperatures (see | ||
| 30 | /Documentation/hwmon/sysfs-interface under Temperatures). | ||
| 31 | |||
| 32 | The TMP411 chip is compatible with TMP401. It provides some additional | ||
| 33 | features. | ||
| 34 | |||
| 35 | * Minimum and Maximum temperature measured since power-on, chip-reset | ||
| 36 | |||
| 37 | Exported via sysfs attributes tempX_lowest and tempX_highest. | ||
| 38 | |||
| 39 | * Reset of historical minimum/maximum temperature measurements | ||
| 40 | |||
| 41 | Exported via sysfs attribute temp_reset_history. Writing 1 to this | ||
| 42 | file triggers a reset. | ||
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index b6eb59384bb3..02b74899edaf 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf | |||
| @@ -12,6 +12,10 @@ Supported chips: | |||
| 12 | Addresses scanned: ISA address retrieved from Super I/O registers | 12 | Addresses scanned: ISA address retrieved from Super I/O registers |
| 13 | Datasheet: | 13 | Datasheet: |
| 14 | http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf | 14 | http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf |
| 15 | * Winbond W83627DHG-P | ||
| 16 | Prefix: 'w83627dhg' | ||
| 17 | Addresses scanned: ISA address retrieved from Super I/O registers | ||
| 18 | Datasheet: not available | ||
| 15 | * Winbond W83667HG | 19 | * Winbond W83667HG |
| 16 | Prefix: 'w83667hg' | 20 | Prefix: 'w83667hg' |
| 17 | Addresses scanned: ISA address retrieved from Super I/O registers | 21 | Addresses scanned: ISA address retrieved from Super I/O registers |
| @@ -28,8 +32,8 @@ Description | |||
| 28 | ----------- | 32 | ----------- |
| 29 | 33 | ||
| 30 | This driver implements support for the Winbond W83627EHF, W83627EHG, | 34 | This driver implements support for the Winbond W83627EHF, W83627EHG, |
| 31 | W83627DHG and W83667HG super I/O chips. We will refer to them collectively | 35 | W83627DHG, W83627DHG-P and W83667HG super I/O chips. We will refer to them |
| 32 | as Winbond chips. | 36 | collectively as Winbond chips. |
| 33 | 37 | ||
| 34 | The chips implement three temperature sensors, five fan rotation | 38 | The chips implement three temperature sensors, five fan rotation |
| 35 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), one | 39 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), one |
| @@ -135,3 +139,6 @@ done in the driver for all register addresses. | |||
| 135 | The DHG also supports PECI, where the DHG queries Intel CPU temperatures, and | 139 | The DHG also supports PECI, where the DHG queries Intel CPU temperatures, and |
| 136 | the ICH8 southbridge gets that data via PECI from the DHG, so that the | 140 | the ICH8 southbridge gets that data via PECI from the DHG, so that the |
| 137 | southbridge drives the fans. And the DHG supports SST, a one-wire serial bus. | 141 | southbridge drives the fans. And the DHG supports SST, a one-wire serial bus. |
| 142 | |||
| 143 | The DHG-P has an additional automatic fan speed control mode named Smart Fan | ||
| 144 | (TM) III+. This mode is not yet supported by the driver. | ||
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index 22efedf60c87..2e758b0e9456 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro | |||
| @@ -19,6 +19,9 @@ Supported adapters: | |||
| 19 | * VIA Technologies, Inc. VX800/VX820 | 19 | * VIA Technologies, Inc. VX800/VX820 |
| 20 | Datasheet: available on http://linux.via.com.tw | 20 | Datasheet: available on http://linux.via.com.tw |
| 21 | 21 | ||
| 22 | * VIA Technologies, Inc. VX855/VX875 | ||
| 23 | Datasheet: Availability unknown | ||
| 24 | |||
| 22 | Authors: | 25 | Authors: |
| 23 | Kyösti Mälkki <kmalkki@cc.hut.fi>, | 26 | Kyösti Mälkki <kmalkki@cc.hut.fi>, |
| 24 | Mark D. Studebaker <mdsxyz123@yahoo.com>, | 27 | Mark D. Studebaker <mdsxyz123@yahoo.com>, |
| @@ -53,6 +56,7 @@ Your lspci -n listing must show one of these : | |||
| 53 | device 1106:3287 (VT8251) | 56 | device 1106:3287 (VT8251) |
| 54 | device 1106:8324 (CX700) | 57 | device 1106:8324 (CX700) |
| 55 | device 1106:8353 (VX800/VX820) | 58 | device 1106:8353 (VX800/VX820) |
| 59 | device 1106:8409 (VX855/VX875) | ||
| 56 | 60 | ||
| 57 | If none of these show up, you should look in the BIOS for settings like | 61 | If none of these show up, you should look in the BIOS for settings like |
| 58 | enable ACPI / SMBus or even USB. | 62 | enable ACPI / SMBus or even USB. |
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 783da855a2e3..d6d35b2e5fe8 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig | |||
| @@ -963,7 +963,7 @@ CONFIG_EEPROM_LEGACY=y | |||
| 963 | CONFIG_SENSORS_PCF8574=y | 963 | CONFIG_SENSORS_PCF8574=y |
| 964 | # CONFIG_PCF8575 is not set | 964 | # CONFIG_PCF8575 is not set |
| 965 | CONFIG_SENSORS_PCF8591=y | 965 | CONFIG_SENSORS_PCF8591=y |
| 966 | CONFIG_SENSORS_MAX6875=y | 966 | CONFIG_EEPROM_MAX6875=y |
| 967 | # CONFIG_SENSORS_TSL2550 is not set | 967 | # CONFIG_SENSORS_TSL2550 is not set |
| 968 | CONFIG_I2C_DEBUG_CORE=y | 968 | CONFIG_I2C_DEBUG_CORE=y |
| 969 | CONFIG_I2C_DEBUG_ALGO=y | 969 | CONFIG_I2C_DEBUG_ALGO=y |
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 8426d3b9501c..fadb351d249b 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig | |||
| @@ -1849,7 +1849,7 @@ CONFIG_EEPROM_LEGACY=m | |||
| 1849 | CONFIG_SENSORS_PCF8574=m | 1849 | CONFIG_SENSORS_PCF8574=m |
| 1850 | CONFIG_SENSORS_PCA9539=m | 1850 | CONFIG_SENSORS_PCA9539=m |
| 1851 | CONFIG_SENSORS_PCF8591=m | 1851 | CONFIG_SENSORS_PCF8591=m |
| 1852 | CONFIG_SENSORS_MAX6875=m | 1852 | CONFIG_EEPROM_MAX6875=m |
| 1853 | # CONFIG_SENSORS_TSL2550 is not set | 1853 | # CONFIG_SENSORS_TSL2550 is not set |
| 1854 | # CONFIG_I2C_DEBUG_CORE is not set | 1854 | # CONFIG_I2C_DEBUG_CORE is not set |
| 1855 | # CONFIG_I2C_DEBUG_ALGO is not set | 1855 | # CONFIG_I2C_DEBUG_ALGO is not set |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 93a61898b259..9fb344d5a86a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -93,10 +93,6 @@ config GENERIC_HWEIGHT | |||
| 93 | bool | 93 | bool |
| 94 | default y | 94 | default y |
| 95 | 95 | ||
| 96 | config GENERIC_CALIBRATE_DELAY | ||
| 97 | bool | ||
| 98 | default y | ||
| 99 | |||
| 100 | config GENERIC_FIND_NEXT_BIT | 96 | config GENERIC_FIND_NEXT_BIT |
| 101 | bool | 97 | bool |
| 102 | default y | 98 | default y |
| @@ -129,6 +125,7 @@ config PPC | |||
| 129 | select USE_GENERIC_SMP_HELPERS if SMP | 125 | select USE_GENERIC_SMP_HELPERS if SMP |
| 130 | select HAVE_OPROFILE | 126 | select HAVE_OPROFILE |
| 131 | select HAVE_SYSCALL_WRAPPERS if PPC64 | 127 | select HAVE_SYSCALL_WRAPPERS if PPC64 |
| 128 | select GENERIC_ATOMIC64 if PPC32 | ||
| 132 | 129 | ||
| 133 | config EARLY_PRINTK | 130 | config EARLY_PRINTK |
| 134 | bool | 131 | bool |
diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh index 51b2387bdba0..98312d169c85 100644 --- a/arch/powerpc/boot/install.sh +++ b/arch/powerpc/boot/install.sh | |||
| @@ -18,6 +18,9 @@ | |||
| 18 | # $5 and more - kernel boot files; zImage*, uImage, cuImage.*, etc. | 18 | # $5 and more - kernel boot files; zImage*, uImage, cuImage.*, etc. |
| 19 | # | 19 | # |
| 20 | 20 | ||
| 21 | # Bail with error code if anything goes wrong | ||
| 22 | set -e | ||
| 23 | |||
| 21 | # User may have a custom install script | 24 | # User may have a custom install script |
| 22 | 25 | ||
| 23 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 26 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi |
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 7d044dfd9236..12dc7c409616 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig | |||
| @@ -1808,7 +1808,7 @@ CONFIG_PCF8575=m | |||
| 1808 | CONFIG_SENSORS_PCA9539=m | 1808 | CONFIG_SENSORS_PCA9539=m |
| 1809 | CONFIG_SENSORS_PCF8591=m | 1809 | CONFIG_SENSORS_PCF8591=m |
| 1810 | # CONFIG_TPS65010 is not set | 1810 | # CONFIG_TPS65010 is not set |
| 1811 | CONFIG_SENSORS_MAX6875=m | 1811 | CONFIG_EEPROM_MAX6875=m |
| 1812 | CONFIG_SENSORS_TSL2550=m | 1812 | CONFIG_SENSORS_TSL2550=m |
| 1813 | CONFIG_MCU_MPC8349EMITX=m | 1813 | CONFIG_MCU_MPC8349EMITX=m |
| 1814 | # CONFIG_I2C_DEBUG_CORE is not set | 1814 | # CONFIG_I2C_DEBUG_CORE is not set |
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index b7d2d07b6f96..4012483b1899 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h | |||
| @@ -470,6 +470,9 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) | |||
| 470 | 470 | ||
| 471 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 471 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 472 | 472 | ||
| 473 | #else /* __powerpc64__ */ | ||
| 474 | #include <asm-generic/atomic64.h> | ||
| 475 | |||
| 473 | #endif /* __powerpc64__ */ | 476 | #endif /* __powerpc64__ */ |
| 474 | 477 | ||
| 475 | #include <asm-generic/atomic-long.h> | 478 | #include <asm-generic/atomic-long.h> |
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 53512374e1c9..b7f8f4a87cc0 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h | |||
| @@ -80,7 +80,7 @@ static inline void local_irq_disable(void) | |||
| 80 | __asm__ __volatile__("wrteei 0": : :"memory"); | 80 | __asm__ __volatile__("wrteei 0": : :"memory"); |
| 81 | #else | 81 | #else |
| 82 | unsigned long msr; | 82 | unsigned long msr; |
| 83 | __asm__ __volatile__("": : :"memory"); | 83 | |
| 84 | msr = mfmsr(); | 84 | msr = mfmsr(); |
| 85 | SET_MSR_EE(msr & ~MSR_EE); | 85 | SET_MSR_EE(msr & ~MSR_EE); |
| 86 | #endif | 86 | #endif |
| @@ -92,7 +92,7 @@ static inline void local_irq_enable(void) | |||
| 92 | __asm__ __volatile__("wrteei 1": : :"memory"); | 92 | __asm__ __volatile__("wrteei 1": : :"memory"); |
| 93 | #else | 93 | #else |
| 94 | unsigned long msr; | 94 | unsigned long msr; |
| 95 | __asm__ __volatile__("": : :"memory"); | 95 | |
| 96 | msr = mfmsr(); | 96 | msr = mfmsr(); |
| 97 | SET_MSR_EE(msr | MSR_EE); | 97 | SET_MSR_EE(msr | MSR_EE); |
| 98 | #endif | 98 | #endif |
| @@ -108,7 +108,6 @@ static inline void local_irq_save_ptr(unsigned long *flags) | |||
| 108 | #else | 108 | #else |
| 109 | SET_MSR_EE(msr & ~MSR_EE); | 109 | SET_MSR_EE(msr & ~MSR_EE); |
| 110 | #endif | 110 | #endif |
| 111 | __asm__ __volatile__("": : :"memory"); | ||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | #define local_save_flags(flags) ((flags) = mfmsr()) | 113 | #define local_save_flags(flags) ((flags) = mfmsr()) |
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 7464c0daddd1..7ead7c16fb7c 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h | |||
| @@ -35,6 +35,16 @@ | |||
| 35 | #define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1)) | 35 | #define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1)) |
| 36 | #define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE) | 36 | #define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE) |
| 37 | 37 | ||
| 38 | /* Cell page table entries */ | ||
| 39 | #define CBE_IOPTE_PP_W 0x8000000000000000ul /* protection: write */ | ||
| 40 | #define CBE_IOPTE_PP_R 0x4000000000000000ul /* protection: read */ | ||
| 41 | #define CBE_IOPTE_M 0x2000000000000000ul /* coherency required */ | ||
| 42 | #define CBE_IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */ | ||
| 43 | #define CBE_IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */ | ||
| 44 | #define CBE_IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */ | ||
| 45 | #define CBE_IOPTE_H 0x0000000000000800ul /* cache hint */ | ||
| 46 | #define CBE_IOPTE_IOID_Mask 0x00000000000007fful /* ioid */ | ||
| 47 | |||
| 38 | /* Boot time flags */ | 48 | /* Boot time flags */ |
| 39 | extern int iommu_is_off; | 49 | extern int iommu_is_off; |
| 40 | extern int iommu_force_on; | 50 | extern int iommu_force_on; |
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index cdb6fd814de8..7f065e178ec4 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h | |||
| @@ -53,6 +53,13 @@ enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void); | |||
| 53 | extern u64 ps3_os_area_get_rtc_diff(void); | 53 | extern u64 ps3_os_area_get_rtc_diff(void); |
| 54 | extern void ps3_os_area_set_rtc_diff(u64 rtc_diff); | 54 | extern void ps3_os_area_set_rtc_diff(u64 rtc_diff); |
| 55 | 55 | ||
| 56 | struct ps3_os_area_flash_ops { | ||
| 57 | ssize_t (*read)(void *buf, size_t count, loff_t pos); | ||
| 58 | ssize_t (*write)(const void *buf, size_t count, loff_t pos); | ||
| 59 | }; | ||
| 60 | |||
| 61 | extern void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops); | ||
| 62 | |||
| 56 | /* dma routines */ | 63 | /* dma routines */ |
| 57 | 64 | ||
| 58 | enum ps3_dma_page_size { | 65 | enum ps3_dma_page_size { |
| @@ -418,15 +425,15 @@ static inline struct ps3_system_bus_driver * | |||
| 418 | * @data: Data to set | 425 | * @data: Data to set |
| 419 | */ | 426 | */ |
| 420 | 427 | ||
| 421 | static inline void ps3_system_bus_set_driver_data( | 428 | static inline void ps3_system_bus_set_drvdata( |
| 422 | struct ps3_system_bus_device *dev, void *data) | 429 | struct ps3_system_bus_device *dev, void *data) |
| 423 | { | 430 | { |
| 424 | dev->core.driver_data = data; | 431 | dev_set_drvdata(&dev->core, data); |
| 425 | } | 432 | } |
| 426 | static inline void *ps3_system_bus_get_driver_data( | 433 | static inline void *ps3_system_bus_get_drvdata( |
| 427 | struct ps3_system_bus_device *dev) | 434 | struct ps3_system_bus_device *dev) |
| 428 | { | 435 | { |
| 429 | return dev->core.driver_data; | 436 | return dev_get_drvdata(&dev->core); |
| 430 | } | 437 | } |
| 431 | 438 | ||
| 432 | /* These two need global scope for get_dma_ops(). */ | 439 | /* These two need global scope for get_dma_ops(). */ |
| @@ -520,7 +527,4 @@ void ps3_sync_irq(int node); | |||
| 520 | u32 ps3_get_hw_thread_id(int cpu); | 527 | u32 ps3_get_hw_thread_id(int cpu); |
| 521 | u64 ps3_get_spe_id(void *arg); | 528 | u64 ps3_get_spe_id(void *arg); |
| 522 | 529 | ||
| 523 | /* mutex synchronizing GPU accesses and video mode changes */ | ||
| 524 | extern struct mutex ps3_gpu_mutex; | ||
| 525 | |||
| 526 | #endif | 530 | #endif |
diff --git a/arch/powerpc/include/asm/ps3gpu.h b/arch/powerpc/include/asm/ps3gpu.h new file mode 100644 index 000000000000..b2b89591907c --- /dev/null +++ b/arch/powerpc/include/asm/ps3gpu.h | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * PS3 GPU declarations. | ||
| 3 | * | ||
| 4 | * Copyright 2009 Sony Corporation | ||
| 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 as published by | ||
| 8 | * the Free Software Foundation; version 2 of the License. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. | ||
| 17 | * If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef _ASM_POWERPC_PS3GPU_H | ||
| 21 | #define _ASM_POWERPC_PS3GPU_H | ||
| 22 | |||
| 23 | #include <linux/mutex.h> | ||
| 24 | |||
| 25 | #include <asm/lv1call.h> | ||
| 26 | |||
| 27 | |||
| 28 | #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101 | ||
| 29 | #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102 | ||
| 30 | |||
| 31 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600 | ||
| 32 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 | ||
| 33 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602 | ||
| 34 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_CLOSE 0x603 | ||
| 35 | |||
| 36 | #define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32) | ||
| 37 | |||
| 38 | #define L1GPU_DISPLAY_SYNC_HSYNC 1 | ||
| 39 | #define L1GPU_DISPLAY_SYNC_VSYNC 2 | ||
| 40 | |||
| 41 | |||
| 42 | /* mutex synchronizing GPU accesses and video mode changes */ | ||
| 43 | extern struct mutex ps3_gpu_mutex; | ||
| 44 | |||
| 45 | |||
| 46 | static inline int lv1_gpu_display_sync(u64 context_handle, u64 head, | ||
| 47 | u64 ddr_offset) | ||
| 48 | { | ||
| 49 | return lv1_gpu_context_attribute(context_handle, | ||
| 50 | L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, | ||
| 51 | head, ddr_offset, 0, 0); | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline int lv1_gpu_display_flip(u64 context_handle, u64 head, | ||
| 55 | u64 ddr_offset) | ||
| 56 | { | ||
| 57 | return lv1_gpu_context_attribute(context_handle, | ||
| 58 | L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, | ||
| 59 | head, ddr_offset, 0, 0); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline int lv1_gpu_fb_setup(u64 context_handle, u64 xdr_lpar, | ||
| 63 | u64 xdr_size, u64 ioif_offset) | ||
| 64 | { | ||
| 65 | return lv1_gpu_context_attribute(context_handle, | ||
| 66 | L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, | ||
| 67 | xdr_lpar, xdr_size, ioif_offset, 0); | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline int lv1_gpu_fb_blit(u64 context_handle, u64 ddr_offset, | ||
| 71 | u64 ioif_offset, u64 sync_width, u64 pitch) | ||
| 72 | { | ||
| 73 | return lv1_gpu_context_attribute(context_handle, | ||
| 74 | L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, | ||
| 75 | ddr_offset, ioif_offset, sync_width, | ||
| 76 | pitch); | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline int lv1_gpu_fb_close(u64 context_handle) | ||
| 80 | { | ||
| 81 | return lv1_gpu_context_attribute(context_handle, | ||
| 82 | L1GPU_CONTEXT_ATTRIBUTE_FB_CLOSE, 0, | ||
| 83 | 0, 0, 0); | ||
| 84 | } | ||
| 85 | |||
| 86 | #endif /* _ASM_POWERPC_PS3GPU_H */ | ||
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index fb359b0a6937..a3c28e46947c 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
| @@ -745,11 +745,11 @@ | |||
| 745 | asm volatile("mfmsr %0" : "=r" (rval)); rval;}) | 745 | asm volatile("mfmsr %0" : "=r" (rval)); rval;}) |
| 746 | #ifdef CONFIG_PPC64 | 746 | #ifdef CONFIG_PPC64 |
| 747 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ | 747 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ |
| 748 | : : "r" (v)) | 748 | : : "r" (v) : "memory") |
| 749 | #define mtmsrd(v) __mtmsrd((v), 0) | 749 | #define mtmsrd(v) __mtmsrd((v), 0) |
| 750 | #define mtmsr(v) mtmsrd(v) | 750 | #define mtmsr(v) mtmsrd(v) |
| 751 | #else | 751 | #else |
| 752 | #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) | 752 | #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v) : "memory") |
| 753 | #endif | 753 | #endif |
| 754 | 754 | ||
| 755 | #define mfspr(rn) ({unsigned long rval; \ | 755 | #define mfspr(rn) ({unsigned long rval; \ |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index a0b92de51c7e..370600ca2765 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
| @@ -325,3 +325,4 @@ SYSCALL(inotify_init1) | |||
| 325 | SYSCALL_SPU(perf_counter_open) | 325 | SYSCALL_SPU(perf_counter_open) |
| 326 | COMPAT_SYS_SPU(preadv) | 326 | COMPAT_SYS_SPU(preadv) |
| 327 | COMPAT_SYS_SPU(pwritev) | 327 | COMPAT_SYS_SPU(pwritev) |
| 328 | COMPAT_SYS(rt_tgsigqueueinfo) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 4badac2d11d1..cef080bfc607 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
| @@ -344,10 +344,11 @@ | |||
| 344 | #define __NR_perf_counter_open 319 | 344 | #define __NR_perf_counter_open 319 |
| 345 | #define __NR_preadv 320 | 345 | #define __NR_preadv 320 |
| 346 | #define __NR_pwritev 321 | 346 | #define __NR_pwritev 321 |
| 347 | #define __NR_rt_tgsigqueueinfo 322 | ||
| 347 | 348 | ||
| 348 | #ifdef __KERNEL__ | 349 | #ifdef __KERNEL__ |
| 349 | 350 | ||
| 350 | #define __NR_syscalls 322 | 351 | #define __NR_syscalls 323 |
| 351 | 352 | ||
| 352 | #define __NR__exit __NR_exit | 353 | #define __NR__exit __NR_exit |
| 353 | #define NR_syscalls __NR_syscalls | 354 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index a7def5f90cad..612b0c4dc26d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -125,6 +125,7 @@ PHONY += systbl_chk | |||
| 125 | systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i | 125 | systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i |
| 126 | $(call cmd,systbl_chk) | 126 | $(call cmd,systbl_chk) |
| 127 | 127 | ||
| 128 | ifeq ($(CONFIG_PPC_OF_BOOT_TRAMPOLINE),y) | ||
| 128 | $(obj)/built-in.o: prom_init_check | 129 | $(obj)/built-in.o: prom_init_check |
| 129 | 130 | ||
| 130 | quiet_cmd_prom_init_check = CALL $< | 131 | quiet_cmd_prom_init_check = CALL $< |
| @@ -133,5 +134,6 @@ quiet_cmd_prom_init_check = CALL $< | |||
| 133 | PHONY += prom_init_check | 134 | PHONY += prom_init_check |
| 134 | prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o | 135 | prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o |
| 135 | $(call cmd,prom_init_check) | 136 | $(call cmd,prom_init_check) |
| 137 | endif | ||
| 136 | 138 | ||
| 137 | clean-files := vmlinux.lds | 139 | clean-files := vmlinux.lds |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index f46548e66045..1f6816003ebe 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -424,8 +424,8 @@ void __init setup_system(void) | |||
| 424 | printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); | 424 | printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); |
| 425 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 425 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
| 426 | if (PHYSICAL_START > 0) | 426 | if (PHYSICAL_START > 0) |
| 427 | printk("physical_start = 0x%lx\n", | 427 | printk("physical_start = 0x%llx\n", |
| 428 | PHYSICAL_START); | 428 | (unsigned long long)PHYSICAL_START); |
| 429 | printk("-----------------------------------------------------\n"); | 429 | printk("-----------------------------------------------------\n"); |
| 430 | 430 | ||
| 431 | DBG(" <- setup_system()\n"); | 431 | DBG(" <- setup_system()\n"); |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index bee1443da763..15391c2ab013 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #include <linux/jiffies.h> | 52 | #include <linux/jiffies.h> |
| 53 | #include <linux/posix-timers.h> | 53 | #include <linux/posix-timers.h> |
| 54 | #include <linux/irq.h> | 54 | #include <linux/irq.h> |
| 55 | #include <linux/delay.h> | ||
| 55 | 56 | ||
| 56 | #include <asm/io.h> | 57 | #include <asm/io.h> |
| 57 | #include <asm/processor.h> | 58 | #include <asm/processor.h> |
| @@ -1143,6 +1144,15 @@ void div128_by_32(u64 dividend_high, u64 dividend_low, | |||
| 1143 | 1144 | ||
| 1144 | } | 1145 | } |
| 1145 | 1146 | ||
| 1147 | /* We don't need to calibrate delay, we use the CPU timebase for that */ | ||
| 1148 | void calibrate_delay(void) | ||
| 1149 | { | ||
| 1150 | /* Some generic code (such as spinlock debug) use loops_per_jiffy | ||
| 1151 | * as the number of __delay(1) in a jiffy, so make it so | ||
| 1152 | */ | ||
| 1153 | loops_per_jiffy = tb_ticks_per_jiffy; | ||
| 1154 | } | ||
| 1155 | |||
| 1146 | static int __init rtc_init(void) | 1156 | static int __init rtc_init(void) |
| 1147 | { | 1157 | { |
| 1148 | struct platform_device *pdev; | 1158 | struct platform_device *pdev; |
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 0ce45c2b42f8..c71498dbf211 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c | |||
| @@ -329,7 +329,7 @@ static struct irq_host_ops msic_host_ops = { | |||
| 329 | 329 | ||
| 330 | static int axon_msi_shutdown(struct of_device *device) | 330 | static int axon_msi_shutdown(struct of_device *device) |
| 331 | { | 331 | { |
| 332 | struct axon_msic *msic = device->dev.platform_data; | 332 | struct axon_msic *msic = dev_get_drvdata(&device->dev); |
| 333 | u32 tmp; | 333 | u32 tmp; |
| 334 | 334 | ||
| 335 | pr_debug("axon_msi: disabling %s\n", | 335 | pr_debug("axon_msi: disabling %s\n", |
| @@ -416,7 +416,7 @@ static int axon_msi_probe(struct of_device *device, | |||
| 416 | msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG) | 416 | msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG) |
| 417 | & MSIC_FIFO_SIZE_MASK; | 417 | & MSIC_FIFO_SIZE_MASK; |
| 418 | 418 | ||
| 419 | device->dev.platform_data = msic; | 419 | dev_set_drvdata(&device->dev, msic); |
| 420 | 420 | ||
| 421 | ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; | 421 | ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; |
| 422 | ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; | 422 | ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index bed4690de394..5b34fc211f35 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
| @@ -100,16 +100,6 @@ | |||
| 100 | #define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */ | 100 | #define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */ |
| 101 | #define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */ | 101 | #define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */ |
| 102 | 102 | ||
| 103 | /* Page table entries */ | ||
| 104 | #define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ | ||
| 105 | #define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ | ||
| 106 | #define IOPTE_M 0x2000000000000000ul /* coherency required */ | ||
| 107 | #define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */ | ||
| 108 | #define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */ | ||
| 109 | #define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */ | ||
| 110 | #define IOPTE_H 0x0000000000000800ul /* cache hint */ | ||
| 111 | #define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */ | ||
| 112 | |||
| 113 | 103 | ||
| 114 | /* IOMMU sizing */ | 104 | /* IOMMU sizing */ |
| 115 | #define IO_SEGMENT_SHIFT 28 | 105 | #define IO_SEGMENT_SHIFT 28 |
| @@ -193,19 +183,21 @@ static int tce_build_cell(struct iommu_table *tbl, long index, long npages, | |||
| 193 | */ | 183 | */ |
| 194 | const unsigned long prot = 0xc48; | 184 | const unsigned long prot = 0xc48; |
| 195 | base_pte = | 185 | base_pte = |
| 196 | ((prot << (52 + 4 * direction)) & (IOPTE_PP_W | IOPTE_PP_R)) | 186 | ((prot << (52 + 4 * direction)) & |
| 197 | | IOPTE_M | IOPTE_SO_RW | (window->ioid & IOPTE_IOID_Mask); | 187 | (CBE_IOPTE_PP_W | CBE_IOPTE_PP_R)) | |
| 188 | CBE_IOPTE_M | CBE_IOPTE_SO_RW | | ||
| 189 | (window->ioid & CBE_IOPTE_IOID_Mask); | ||
| 198 | #else | 190 | #else |
| 199 | base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | | 191 | base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M | |
| 200 | (window->ioid & IOPTE_IOID_Mask); | 192 | CBE_IOPTE_SO_RW | (window->ioid & CBE_IOPTE_IOID_Mask); |
| 201 | #endif | 193 | #endif |
| 202 | if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))) | 194 | if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))) |
| 203 | base_pte &= ~IOPTE_SO_RW; | 195 | base_pte &= ~CBE_IOPTE_SO_RW; |
| 204 | 196 | ||
| 205 | io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); | 197 | io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); |
| 206 | 198 | ||
| 207 | for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) | 199 | for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) |
| 208 | io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); | 200 | io_pte[i] = base_pte | (__pa(uaddr) & CBE_IOPTE_RPN_Mask); |
| 209 | 201 | ||
| 210 | mb(); | 202 | mb(); |
| 211 | 203 | ||
| @@ -231,8 +223,9 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages) | |||
| 231 | #else | 223 | #else |
| 232 | /* spider bridge does PCI reads after freeing - insert a mapping | 224 | /* spider bridge does PCI reads after freeing - insert a mapping |
| 233 | * to a scratch page instead of an invalid entry */ | 225 | * to a scratch page instead of an invalid entry */ |
| 234 | pte = IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | __pa(window->iommu->pad_page) | 226 | pte = CBE_IOPTE_PP_R | CBE_IOPTE_M | CBE_IOPTE_SO_RW | |
| 235 | | (window->ioid & IOPTE_IOID_Mask); | 227 | __pa(window->iommu->pad_page) | |
| 228 | (window->ioid & CBE_IOPTE_IOID_Mask); | ||
| 236 | #endif | 229 | #endif |
| 237 | 230 | ||
| 238 | io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); | 231 | io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); |
| @@ -1001,7 +994,7 @@ static void insert_16M_pte(unsigned long addr, unsigned long *ptab, | |||
| 1001 | pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", | 994 | pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", |
| 1002 | addr, ptab, segment, offset); | 995 | addr, ptab, segment, offset); |
| 1003 | 996 | ||
| 1004 | ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask); | 997 | ptab[offset] = base_pte | (__pa(addr) & CBE_IOPTE_RPN_Mask); |
| 1005 | } | 998 | } |
| 1006 | 999 | ||
| 1007 | static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, | 1000 | static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, |
| @@ -1016,14 +1009,14 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, | |||
| 1016 | 1009 | ||
| 1017 | pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); | 1010 | pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); |
| 1018 | 1011 | ||
| 1019 | base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | 1012 | base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M | |
| 1020 | | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask); | 1013 | (cell_iommu_get_ioid(np) & CBE_IOPTE_IOID_Mask); |
| 1021 | 1014 | ||
| 1022 | if (iommu_fixed_is_weak) | 1015 | if (iommu_fixed_is_weak) |
| 1023 | pr_info("IOMMU: Using weak ordering for fixed mapping\n"); | 1016 | pr_info("IOMMU: Using weak ordering for fixed mapping\n"); |
| 1024 | else { | 1017 | else { |
| 1025 | pr_info("IOMMU: Using strong ordering for fixed mapping\n"); | 1018 | pr_info("IOMMU: Using strong ordering for fixed mapping\n"); |
| 1026 | base_pte |= IOPTE_SO_RW; | 1019 | base_pte |= CBE_IOPTE_SO_RW; |
| 1027 | } | 1020 | } |
| 1028 | 1021 | ||
| 1029 | for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) { | 1022 | for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) { |
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index 4543c4bc3a56..c5a87a72057b 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c | |||
| @@ -204,7 +204,8 @@ static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name, | |||
| 204 | dt_prop(dt, name, &data, sizeof(u32)); | 204 | dt_prop(dt, name, &data, sizeof(u32)); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name, | 207 | static void __init __maybe_unused dt_prop_u64(struct iseries_flat_dt *dt, |
| 208 | const char *name, | ||
| 208 | u64 data) | 209 | u64 data) |
| 209 | { | 210 | { |
| 210 | dt_prop(dt, name, &data, sizeof(u64)); | 211 | dt_prop(dt, name, &data, sizeof(u64)); |
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 3689c2413d24..fef4d5150517 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c | |||
| @@ -267,7 +267,8 @@ static struct pending_event *new_pending_event(void) | |||
| 267 | return ev; | 267 | return ev; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | static int signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd) | 270 | static int __maybe_unused |
| 271 | signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd) | ||
| 271 | { | 272 | { |
| 272 | struct pending_event *ev = new_pending_event(); | 273 | struct pending_event *ev = new_pending_event(); |
| 273 | int rc; | 274 | int rc; |
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 9a2b6d948610..846eb8b57fd1 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/lmb.h> | 24 | #include <linux/lmb.h> |
| 25 | 25 | ||
| 26 | #include <asm/firmware.h> | 26 | #include <asm/firmware.h> |
| 27 | #include <asm/iommu.h> | ||
| 27 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
| 28 | #include <asm/udbg.h> | 29 | #include <asm/udbg.h> |
| 29 | #include <asm/lv1call.h> | 30 | #include <asm/lv1call.h> |
| @@ -605,9 +606,8 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, | |||
| 605 | r->ioid, | 606 | r->ioid, |
| 606 | iopte_flag); | 607 | iopte_flag); |
| 607 | if (result) { | 608 | if (result) { |
| 608 | printk(KERN_WARNING "%s:%d: lv1_map_device_dma_region " | 609 | pr_warning("%s:%d: lv1_put_iopte failed: %s\n", |
| 609 | "failed: %s\n", __func__, __LINE__, | 610 | __func__, __LINE__, ps3_result(result)); |
| 610 | ps3_result(result)); | ||
| 611 | goto fail_map; | 611 | goto fail_map; |
| 612 | } | 612 | } |
| 613 | DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__, | 613 | DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__, |
| @@ -1001,7 +1001,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r) | |||
| 1001 | if (len > r->len) | 1001 | if (len > r->len) |
| 1002 | len = r->len; | 1002 | len = r->len; |
| 1003 | result = dma_sb_map_area(r, virt_addr, len, &tmp, | 1003 | result = dma_sb_map_area(r, virt_addr, len, &tmp, |
| 1004 | IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); | 1004 | CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_SO_RW | |
| 1005 | CBE_IOPTE_M); | ||
| 1005 | BUG_ON(result); | 1006 | BUG_ON(result); |
| 1006 | } | 1007 | } |
| 1007 | 1008 | ||
| @@ -1014,7 +1015,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r) | |||
| 1014 | else | 1015 | else |
| 1015 | len -= map.rm.size - r->offset; | 1016 | len -= map.rm.size - r->offset; |
| 1016 | result = dma_sb_map_area(r, virt_addr, len, &tmp, | 1017 | result = dma_sb_map_area(r, virt_addr, len, &tmp, |
| 1017 | IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); | 1018 | CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_SO_RW | |
| 1019 | CBE_IOPTE_M); | ||
| 1018 | BUG_ON(result); | 1020 | BUG_ON(result); |
| 1019 | } | 1021 | } |
| 1020 | 1022 | ||
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index cf1cd0f8c18f..d6487a9c8019 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c | |||
| @@ -226,6 +226,44 @@ static struct property property_av_multi_out = { | |||
| 226 | .value = &saved_params.av_multi_out, | 226 | .value = &saved_params.av_multi_out, |
| 227 | }; | 227 | }; |
| 228 | 228 | ||
| 229 | |||
| 230 | static DEFINE_MUTEX(os_area_flash_mutex); | ||
| 231 | |||
| 232 | static const struct ps3_os_area_flash_ops *os_area_flash_ops; | ||
| 233 | |||
| 234 | void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops) | ||
| 235 | { | ||
| 236 | mutex_lock(&os_area_flash_mutex); | ||
| 237 | os_area_flash_ops = ops; | ||
| 238 | mutex_unlock(&os_area_flash_mutex); | ||
| 239 | } | ||
| 240 | EXPORT_SYMBOL_GPL(ps3_os_area_flash_register); | ||
| 241 | |||
| 242 | static ssize_t os_area_flash_read(void *buf, size_t count, loff_t pos) | ||
| 243 | { | ||
| 244 | ssize_t res = -ENODEV; | ||
| 245 | |||
| 246 | mutex_lock(&os_area_flash_mutex); | ||
| 247 | if (os_area_flash_ops) | ||
| 248 | res = os_area_flash_ops->read(buf, count, pos); | ||
| 249 | mutex_unlock(&os_area_flash_mutex); | ||
| 250 | |||
| 251 | return res; | ||
| 252 | } | ||
| 253 | |||
| 254 | static ssize_t os_area_flash_write(const void *buf, size_t count, loff_t pos) | ||
| 255 | { | ||
| 256 | ssize_t res = -ENODEV; | ||
| 257 | |||
| 258 | mutex_lock(&os_area_flash_mutex); | ||
| 259 | if (os_area_flash_ops) | ||
| 260 | res = os_area_flash_ops->write(buf, count, pos); | ||
| 261 | mutex_unlock(&os_area_flash_mutex); | ||
| 262 | |||
| 263 | return res; | ||
| 264 | } | ||
| 265 | |||
| 266 | |||
| 229 | /** | 267 | /** |
| 230 | * os_area_set_property - Add or overwrite a saved_params value to the device tree. | 268 | * os_area_set_property - Add or overwrite a saved_params value to the device tree. |
| 231 | * | 269 | * |
| @@ -352,12 +390,12 @@ static int db_verify(const struct os_area_db *db) | |||
| 352 | if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM, | 390 | if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM, |
| 353 | sizeof(db->magic_num))) { | 391 | sizeof(db->magic_num))) { |
| 354 | pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); | 392 | pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); |
| 355 | return -1; | 393 | return -EINVAL; |
| 356 | } | 394 | } |
| 357 | 395 | ||
| 358 | if (db->version != 1) { | 396 | if (db->version != 1) { |
| 359 | pr_debug("%s:%d version failed\n", __func__, __LINE__); | 397 | pr_debug("%s:%d version failed\n", __func__, __LINE__); |
| 360 | return -1; | 398 | return -EINVAL; |
| 361 | } | 399 | } |
| 362 | 400 | ||
| 363 | return 0; | 401 | return 0; |
| @@ -578,59 +616,48 @@ static void os_area_db_init(struct os_area_db *db) | |||
| 578 | * | 616 | * |
| 579 | */ | 617 | */ |
| 580 | 618 | ||
| 581 | static void __maybe_unused update_flash_db(void) | 619 | static int update_flash_db(void) |
| 582 | { | 620 | { |
| 583 | int result; | 621 | const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE; |
| 584 | int file; | 622 | struct os_area_header *header; |
| 585 | off_t offset; | ||
| 586 | ssize_t count; | 623 | ssize_t count; |
| 587 | static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE; | 624 | int error; |
| 588 | const struct os_area_header *header; | 625 | loff_t pos; |
| 589 | struct os_area_db* db; | 626 | struct os_area_db* db; |
| 590 | 627 | ||
| 591 | /* Read in header and db from flash. */ | 628 | /* Read in header and db from flash. */ |
| 592 | 629 | ||
| 593 | file = sys_open("/dev/ps3flash", O_RDWR, 0); | ||
| 594 | |||
| 595 | if (file < 0) { | ||
| 596 | pr_debug("%s:%d sys_open failed\n", __func__, __LINE__); | ||
| 597 | goto fail_open; | ||
| 598 | } | ||
| 599 | |||
| 600 | header = kmalloc(buf_len, GFP_KERNEL); | 630 | header = kmalloc(buf_len, GFP_KERNEL); |
| 601 | |||
| 602 | if (!header) { | 631 | if (!header) { |
| 603 | pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__); | 632 | pr_debug("%s: kmalloc failed\n", __func__); |
| 604 | goto fail_malloc; | 633 | return -ENOMEM; |
| 605 | } | 634 | } |
| 606 | 635 | ||
| 607 | offset = sys_lseek(file, 0, SEEK_SET); | 636 | count = os_area_flash_read(header, buf_len, 0); |
| 608 | 637 | if (count < 0) { | |
| 609 | if (offset != 0) { | 638 | pr_debug("%s: os_area_flash_read failed %zd\n", __func__, |
| 610 | pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__); | 639 | count); |
| 611 | goto fail_header_seek; | 640 | error = count; |
| 641 | goto fail; | ||
| 612 | } | 642 | } |
| 613 | 643 | ||
| 614 | count = sys_read(file, (char __user *)header, buf_len); | 644 | pos = header->db_area_offset * OS_AREA_SEGMENT_SIZE; |
| 615 | 645 | if (count < OS_AREA_SEGMENT_SIZE || verify_header(header) || | |
| 616 | result = count < OS_AREA_SEGMENT_SIZE || verify_header(header) | 646 | count < pos) { |
| 617 | || count < header->db_area_offset * OS_AREA_SEGMENT_SIZE; | 647 | pr_debug("%s: verify_header failed\n", __func__); |
| 618 | |||
| 619 | if (result) { | ||
| 620 | pr_debug("%s:%d verify_header failed\n", __func__, __LINE__); | ||
| 621 | dump_header(header); | 648 | dump_header(header); |
| 622 | goto fail_header; | 649 | error = -EINVAL; |
| 650 | goto fail; | ||
| 623 | } | 651 | } |
| 624 | 652 | ||
| 625 | /* Now got a good db offset and some maybe good db data. */ | 653 | /* Now got a good db offset and some maybe good db data. */ |
| 626 | 654 | ||
| 627 | db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE; | 655 | db = (void *)header + pos; |
| 628 | 656 | ||
| 629 | result = db_verify(db); | 657 | error = db_verify(db); |
| 630 | 658 | if (error) { | |
| 631 | if (result) { | 659 | pr_notice("%s: Verify of flash database failed, formatting.\n", |
| 632 | printk(KERN_NOTICE "%s:%d: Verify of flash database failed, " | 660 | __func__); |
| 633 | "formatting.\n", __func__, __LINE__); | ||
| 634 | dump_db(db); | 661 | dump_db(db); |
| 635 | os_area_db_init(db); | 662 | os_area_db_init(db); |
| 636 | } | 663 | } |
| @@ -639,29 +666,16 @@ static void __maybe_unused update_flash_db(void) | |||
| 639 | 666 | ||
| 640 | db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff); | 667 | db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff); |
| 641 | 668 | ||
| 642 | offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE, | 669 | count = os_area_flash_write(db, sizeof(struct os_area_db), pos); |
| 643 | SEEK_SET); | ||
| 644 | |||
| 645 | if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) { | ||
| 646 | pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__); | ||
| 647 | goto fail_db_seek; | ||
| 648 | } | ||
| 649 | |||
| 650 | count = sys_write(file, (const char __user *)db, | ||
| 651 | sizeof(struct os_area_db)); | ||
| 652 | |||
| 653 | if (count < sizeof(struct os_area_db)) { | 670 | if (count < sizeof(struct os_area_db)) { |
| 654 | pr_debug("%s:%d sys_write failed\n", __func__, __LINE__); | 671 | pr_debug("%s: os_area_flash_write failed %zd\n", __func__, |
| 672 | count); | ||
| 673 | error = count < 0 ? count : -EIO; | ||
| 655 | } | 674 | } |
| 656 | 675 | ||
| 657 | fail_db_seek: | 676 | fail: |
| 658 | fail_header: | ||
| 659 | fail_header_seek: | ||
| 660 | kfree(header); | 677 | kfree(header); |
| 661 | fail_malloc: | 678 | return error; |
| 662 | sys_close(file); | ||
| 663 | fail_open: | ||
| 664 | return; | ||
| 665 | } | 679 | } |
| 666 | 680 | ||
| 667 | /** | 681 | /** |
| @@ -674,11 +688,11 @@ fail_open: | |||
| 674 | static void os_area_queue_work_handler(struct work_struct *work) | 688 | static void os_area_queue_work_handler(struct work_struct *work) |
| 675 | { | 689 | { |
| 676 | struct device_node *node; | 690 | struct device_node *node; |
| 691 | int error; | ||
| 677 | 692 | ||
| 678 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | 693 | pr_debug(" -> %s:%d\n", __func__, __LINE__); |
| 679 | 694 | ||
| 680 | node = of_find_node_by_path("/"); | 695 | node = of_find_node_by_path("/"); |
| 681 | |||
| 682 | if (node) { | 696 | if (node) { |
| 683 | os_area_set_property(node, &property_rtc_diff); | 697 | os_area_set_property(node, &property_rtc_diff); |
| 684 | of_node_put(node); | 698 | of_node_put(node); |
| @@ -686,12 +700,10 @@ static void os_area_queue_work_handler(struct work_struct *work) | |||
| 686 | pr_debug("%s:%d of_find_node_by_path failed\n", | 700 | pr_debug("%s:%d of_find_node_by_path failed\n", |
| 687 | __func__, __LINE__); | 701 | __func__, __LINE__); |
| 688 | 702 | ||
| 689 | #if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) | 703 | error = update_flash_db(); |
| 690 | update_flash_db(); | 704 | if (error) |
| 691 | #else | 705 | pr_warning("%s: Could not update FLASH ROM\n", __func__); |
| 692 | printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n", | 706 | |
| 693 | __func__, __LINE__); | ||
| 694 | #endif | ||
| 695 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 707 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
| 696 | } | 708 | } |
| 697 | 709 | ||
| @@ -808,7 +820,7 @@ u64 ps3_os_area_get_rtc_diff(void) | |||
| 808 | { | 820 | { |
| 809 | return saved_params.rtc_diff; | 821 | return saved_params.rtc_diff; |
| 810 | } | 822 | } |
| 811 | EXPORT_SYMBOL(ps3_os_area_get_rtc_diff); | 823 | EXPORT_SYMBOL_GPL(ps3_os_area_get_rtc_diff); |
| 812 | 824 | ||
| 813 | /** | 825 | /** |
| 814 | * ps3_os_area_set_rtc_diff - Set the rtc diff value. | 826 | * ps3_os_area_set_rtc_diff - Set the rtc diff value. |
| @@ -824,7 +836,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_diff) | |||
| 824 | os_area_queue_work(); | 836 | os_area_queue_work(); |
| 825 | } | 837 | } |
| 826 | } | 838 | } |
| 827 | EXPORT_SYMBOL(ps3_os_area_set_rtc_diff); | 839 | EXPORT_SYMBOL_GPL(ps3_os_area_set_rtc_diff); |
| 828 | 840 | ||
| 829 | /** | 841 | /** |
| 830 | * ps3_os_area_get_av_multi_out - Returns the default video mode. | 842 | * ps3_os_area_get_av_multi_out - Returns the default video mode. |
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 136aa0637d9c..9a196a88eda7 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h | |||
| @@ -232,14 +232,4 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index, | |||
| 232 | int ps3_repository_read_vuart_av_port(unsigned int *port); | 232 | int ps3_repository_read_vuart_av_port(unsigned int *port); |
| 233 | int ps3_repository_read_vuart_sysmgr_port(unsigned int *port); | 233 | int ps3_repository_read_vuart_sysmgr_port(unsigned int *port); |
| 234 | 234 | ||
| 235 | /* Page table entries */ | ||
| 236 | #define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ | ||
| 237 | #define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ | ||
| 238 | #define IOPTE_M 0x2000000000000000ul /* coherency required */ | ||
| 239 | #define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */ | ||
| 240 | #define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */ | ||
| 241 | #define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */ | ||
| 242 | #define IOPTE_H 0x0000000000000800ul /* cache hint */ | ||
| 243 | #define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */ | ||
| 244 | |||
| 245 | #endif | 235 | #endif |
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 1a7b5ae0c83e..149bea2ce583 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <asm/udbg.h> | 32 | #include <asm/udbg.h> |
| 33 | #include <asm/prom.h> | 33 | #include <asm/prom.h> |
| 34 | #include <asm/lv1call.h> | 34 | #include <asm/lv1call.h> |
| 35 | #include <asm/ps3gpu.h> | ||
| 35 | 36 | ||
| 36 | #include "platform.h" | 37 | #include "platform.h" |
| 37 | 38 | ||
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 9a73d0238639..9fead0faf38b 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <asm/udbg.h> | 27 | #include <asm/udbg.h> |
| 28 | #include <asm/lv1call.h> | 28 | #include <asm/lv1call.h> |
| 29 | #include <asm/firmware.h> | 29 | #include <asm/firmware.h> |
| 30 | #include <asm/iommu.h> | ||
| 30 | 31 | ||
| 31 | #include "platform.h" | 32 | #include "platform.h" |
| 32 | 33 | ||
| @@ -531,7 +532,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size, | |||
| 531 | } | 532 | } |
| 532 | 533 | ||
| 533 | result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle, | 534 | result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle, |
| 534 | IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); | 535 | CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | |
| 536 | CBE_IOPTE_SO_RW | CBE_IOPTE_M); | ||
| 535 | 537 | ||
| 536 | if (result) { | 538 | if (result) { |
| 537 | pr_debug("%s:%d: ps3_dma_map failed (%d)\n", | 539 | pr_debug("%s:%d: ps3_dma_map failed (%d)\n", |
| @@ -575,7 +577,8 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page, | |||
| 575 | 577 | ||
| 576 | result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, | 578 | result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, |
| 577 | &bus_addr, | 579 | &bus_addr, |
| 578 | IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M); | 580 | CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | |
| 581 | CBE_IOPTE_SO_RW | CBE_IOPTE_M); | ||
| 579 | 582 | ||
| 580 | if (result) { | 583 | if (result) { |
| 581 | pr_debug("%s:%d: ps3_dma_map failed (%d)\n", | 584 | pr_debug("%s:%d: ps3_dma_map failed (%d)\n", |
| @@ -596,16 +599,16 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, | |||
| 596 | u64 iopte_flag; | 599 | u64 iopte_flag; |
| 597 | void *ptr = page_address(page) + offset; | 600 | void *ptr = page_address(page) + offset; |
| 598 | 601 | ||
| 599 | iopte_flag = IOPTE_M; | 602 | iopte_flag = CBE_IOPTE_M; |
| 600 | switch (direction) { | 603 | switch (direction) { |
| 601 | case DMA_BIDIRECTIONAL: | 604 | case DMA_BIDIRECTIONAL: |
| 602 | iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW; | 605 | iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW; |
| 603 | break; | 606 | break; |
| 604 | case DMA_TO_DEVICE: | 607 | case DMA_TO_DEVICE: |
| 605 | iopte_flag |= IOPTE_PP_R | IOPTE_SO_R; | 608 | iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R; |
| 606 | break; | 609 | break; |
| 607 | case DMA_FROM_DEVICE: | 610 | case DMA_FROM_DEVICE: |
| 608 | iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW; | 611 | iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW; |
| 609 | break; | 612 | break; |
| 610 | default: | 613 | default: |
| 611 | /* not happned */ | 614 | /* not happned */ |
diff --git a/block/blk-core.c b/block/blk-core.c index f6452f692501..b06cf5c2a829 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/swap.h> | 26 | #include <linux/swap.h> |
| 27 | #include <linux/writeback.h> | 27 | #include <linux/writeback.h> |
| 28 | #include <linux/task_io_accounting_ops.h> | 28 | #include <linux/task_io_accounting_ops.h> |
| 29 | #include <linux/blktrace_api.h> | ||
| 30 | #include <linux/fault-inject.h> | 29 | #include <linux/fault-inject.h> |
| 31 | 30 | ||
| 32 | #define CREATE_TRACE_POINTS | 31 | #define CREATE_TRACE_POINTS |
| @@ -498,6 +497,11 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) | |||
| 498 | 497 | ||
| 499 | q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug; | 498 | q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug; |
| 500 | q->backing_dev_info.unplug_io_data = q; | 499 | q->backing_dev_info.unplug_io_data = q; |
| 500 | q->backing_dev_info.ra_pages = | ||
| 501 | (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | ||
| 502 | q->backing_dev_info.state = 0; | ||
| 503 | q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY; | ||
| 504 | |||
| 501 | err = bdi_init(&q->backing_dev_info); | 505 | err = bdi_init(&q->backing_dev_info); |
| 502 | if (err) { | 506 | if (err) { |
| 503 | kmem_cache_free(blk_requestq_cachep, q); | 507 | kmem_cache_free(blk_requestq_cachep, q); |
diff --git a/block/blk-settings.c b/block/blk-settings.c index d71cedc09c4e..7541ea4bf9fe 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
| @@ -96,6 +96,31 @@ void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn) | |||
| 96 | EXPORT_SYMBOL_GPL(blk_queue_lld_busy); | 96 | EXPORT_SYMBOL_GPL(blk_queue_lld_busy); |
| 97 | 97 | ||
| 98 | /** | 98 | /** |
| 99 | * blk_set_default_limits - reset limits to default values | ||
| 100 | * @limits: the queue_limits structure to reset | ||
| 101 | * | ||
| 102 | * Description: | ||
| 103 | * Returns a queue_limit struct to its default state. Can be used by | ||
| 104 | * stacking drivers like DM that stage table swaps and reuse an | ||
| 105 | * existing device queue. | ||
| 106 | */ | ||
| 107 | void blk_set_default_limits(struct queue_limits *lim) | ||
| 108 | { | ||
| 109 | lim->max_phys_segments = MAX_PHYS_SEGMENTS; | ||
| 110 | lim->max_hw_segments = MAX_HW_SEGMENTS; | ||
| 111 | lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; | ||
| 112 | lim->max_segment_size = MAX_SEGMENT_SIZE; | ||
| 113 | lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS; | ||
| 114 | lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; | ||
| 115 | lim->bounce_pfn = BLK_BOUNCE_ANY; | ||
| 116 | lim->alignment_offset = 0; | ||
| 117 | lim->io_opt = 0; | ||
| 118 | lim->misaligned = 0; | ||
| 119 | lim->no_cluster = 0; | ||
| 120 | } | ||
| 121 | EXPORT_SYMBOL(blk_set_default_limits); | ||
| 122 | |||
| 123 | /** | ||
| 99 | * blk_queue_make_request - define an alternate make_request function for a device | 124 | * blk_queue_make_request - define an alternate make_request function for a device |
| 100 | * @q: the request queue for the device to be affected | 125 | * @q: the request queue for the device to be affected |
| 101 | * @mfn: the alternate make_request function | 126 | * @mfn: the alternate make_request function |
| @@ -123,18 +148,8 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) | |||
| 123 | * set defaults | 148 | * set defaults |
| 124 | */ | 149 | */ |
| 125 | q->nr_requests = BLKDEV_MAX_RQ; | 150 | q->nr_requests = BLKDEV_MAX_RQ; |
| 126 | blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); | ||
| 127 | blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); | ||
| 128 | blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK); | ||
| 129 | blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE); | ||
| 130 | 151 | ||
| 131 | q->make_request_fn = mfn; | 152 | q->make_request_fn = mfn; |
| 132 | q->backing_dev_info.ra_pages = | ||
| 133 | (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | ||
| 134 | q->backing_dev_info.state = 0; | ||
| 135 | q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY; | ||
| 136 | blk_queue_max_sectors(q, SAFE_MAX_SECTORS); | ||
| 137 | blk_queue_logical_block_size(q, 512); | ||
| 138 | blk_queue_dma_alignment(q, 511); | 153 | blk_queue_dma_alignment(q, 511); |
| 139 | blk_queue_congestion_threshold(q); | 154 | blk_queue_congestion_threshold(q); |
| 140 | q->nr_batching = BLK_BATCH_REQ; | 155 | q->nr_batching = BLK_BATCH_REQ; |
| @@ -147,6 +162,8 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) | |||
| 147 | q->unplug_timer.function = blk_unplug_timeout; | 162 | q->unplug_timer.function = blk_unplug_timeout; |
| 148 | q->unplug_timer.data = (unsigned long)q; | 163 | q->unplug_timer.data = (unsigned long)q; |
| 149 | 164 | ||
| 165 | blk_set_default_limits(&q->limits); | ||
| 166 | |||
| 150 | /* | 167 | /* |
| 151 | * by default assume old behaviour and bounce for any highmem page | 168 | * by default assume old behaviour and bounce for any highmem page |
| 152 | */ | 169 | */ |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index ef2f72d42434..833ec18eaa63 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -122,7 +122,6 @@ struct cfq_data { | |||
| 122 | struct cfq_queue *async_idle_cfqq; | 122 | struct cfq_queue *async_idle_cfqq; |
| 123 | 123 | ||
| 124 | sector_t last_position; | 124 | sector_t last_position; |
| 125 | unsigned long last_end_request; | ||
| 126 | 125 | ||
| 127 | /* | 126 | /* |
| 128 | * tunables, see top of file | 127 | * tunables, see top of file |
| @@ -1253,7 +1252,7 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd) | |||
| 1253 | 1252 | ||
| 1254 | BUG_ON(cfqd->busy_queues); | 1253 | BUG_ON(cfqd->busy_queues); |
| 1255 | 1254 | ||
| 1256 | cfq_log(cfqd, "forced_dispatch=%d\n", dispatched); | 1255 | cfq_log(cfqd, "forced_dispatch=%d", dispatched); |
| 1257 | return dispatched; | 1256 | return dispatched; |
| 1258 | } | 1257 | } |
| 1259 | 1258 | ||
| @@ -2164,9 +2163,6 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
| 2164 | if (cfq_cfqq_sync(cfqq)) | 2163 | if (cfq_cfqq_sync(cfqq)) |
| 2165 | cfqd->sync_flight--; | 2164 | cfqd->sync_flight--; |
| 2166 | 2165 | ||
| 2167 | if (!cfq_class_idle(cfqq)) | ||
| 2168 | cfqd->last_end_request = now; | ||
| 2169 | |||
| 2170 | if (sync) | 2166 | if (sync) |
| 2171 | RQ_CIC(rq)->last_end_request = now; | 2167 | RQ_CIC(rq)->last_end_request = now; |
| 2172 | 2168 | ||
| @@ -2479,7 +2475,6 @@ static void *cfq_init_queue(struct request_queue *q) | |||
| 2479 | 2475 | ||
| 2480 | INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); | 2476 | INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); |
| 2481 | 2477 | ||
| 2482 | cfqd->last_end_request = jiffies; | ||
| 2483 | cfqd->cfq_quantum = cfq_quantum; | 2478 | cfqd->cfq_quantum = cfq_quantum; |
| 2484 | cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; | 2479 | cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; |
| 2485 | cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1]; | 2480 | cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1]; |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 07e20135f01b..0bba148a2c61 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
| @@ -139,7 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void); | |||
| 139 | acpi_status | 139 | acpi_status |
| 140 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | 140 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, |
| 141 | u32 function, | 141 | u32 function, |
| 142 | acpi_physical_address address, | 142 | u32 region_offset, |
| 143 | u32 bit_width, acpi_integer * value); | 143 | u32 bit_width, acpi_integer * value); |
| 144 | 144 | ||
| 145 | acpi_status | 145 | acpi_status |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 16e5210ae936..3d87362d17ed 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
| @@ -362,9 +362,6 @@ extern u8 acpi_gbl_method_executing; | |||
| 362 | extern u8 acpi_gbl_abort_method; | 362 | extern u8 acpi_gbl_abort_method; |
| 363 | extern u8 acpi_gbl_db_terminate_threads; | 363 | extern u8 acpi_gbl_db_terminate_threads; |
| 364 | 364 | ||
| 365 | ACPI_EXTERN int optind; | ||
| 366 | ACPI_EXTERN char *optarg; | ||
| 367 | |||
| 368 | ACPI_EXTERN u8 acpi_gbl_db_opt_tables; | 365 | ACPI_EXTERN u8 acpi_gbl_db_opt_tables; |
| 369 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; | 366 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; |
| 370 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; | 367 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2ec394a328e9..ee986edfa0da 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
| @@ -205,6 +205,7 @@ struct acpi_namespace_node { | |||
| 205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ | 205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ |
| 206 | #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ | 206 | #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ |
| 207 | #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ | 207 | #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ |
| 208 | #define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */ | ||
| 208 | 209 | ||
| 209 | #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ | 210 | #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ |
| 210 | #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ | 211 | #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ |
| @@ -788,11 +789,14 @@ struct acpi_bit_register_info { | |||
| 788 | /* For control registers, both ignored and reserved bits must be preserved */ | 789 | /* For control registers, both ignored and reserved bits must be preserved */ |
| 789 | 790 | ||
| 790 | /* | 791 | /* |
| 791 | * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) | 792 | * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the |
| 792 | * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly | 793 | * ACPI specification to be a "preserved" bit - "OSPM always preserves this |
| 793 | * as a BIOS workaround on some machines. | 794 | * bit position", section 4.7.3.2.1. However, on some machines the OS must |
| 795 | * write a one to this bit after resume for the machine to work properly. | ||
| 796 | * To enable this, we no longer attempt to preserve this bit. No machines | ||
| 797 | * are known to fail if the bit is not preserved. (May 2009) | ||
| 794 | */ | 798 | */ |
| 795 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ | 799 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bit 9 */ |
| 796 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ | 800 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ |
| 797 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ | 801 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ |
| 798 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) | 802 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 46cb5b46d280..94cdc2b8cb93 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
| @@ -99,10 +99,19 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
| 99 | acpi_walk_callback user_function, | 99 | acpi_walk_callback user_function, |
| 100 | void *context, void **return_value); | 100 | void *context, void **return_value); |
| 101 | 101 | ||
| 102 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | 102 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
| 103 | *parent, struct acpi_namespace_node | 103 | *parent, |
| 104 | struct acpi_namespace_node | ||
| 104 | *child); | 105 | *child); |
| 105 | 106 | ||
| 107 | struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | ||
| 108 | struct | ||
| 109 | acpi_namespace_node | ||
| 110 | *parent, | ||
| 111 | struct | ||
| 112 | acpi_namespace_node | ||
| 113 | *child); | ||
| 114 | |||
| 106 | /* | 115 | /* |
| 107 | * nsparse - table parsing | 116 | * nsparse - table parsing |
| 108 | */ | 117 | */ |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index ff851c5df698..067f967eb389 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
| @@ -483,7 +483,7 @@ typedef enum { | |||
| 483 | 483 | ||
| 484 | #define AML_METHOD_ARG_COUNT 0x07 | 484 | #define AML_METHOD_ARG_COUNT 0x07 |
| 485 | #define AML_METHOD_SERIALIZED 0x08 | 485 | #define AML_METHOD_SERIALIZED 0x08 |
| 486 | #define AML_METHOD_SYNCH_LEVEL 0xF0 | 486 | #define AML_METHOD_SYNC_LEVEL 0xF0 |
| 487 | 487 | ||
| 488 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ | 488 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ |
| 489 | 489 | ||
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index dab3f48f0b42..02e6caad4a76 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
| @@ -734,7 +734,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
| 734 | 734 | ||
| 735 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ | 735 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ |
| 736 | 736 | ||
| 737 | obj_desc->reference.value = opcode - AML_LOCAL_OP; | 737 | obj_desc->reference.value = |
| 738 | ((u32)opcode) - AML_LOCAL_OP; | ||
| 738 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; | 739 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; |
| 739 | 740 | ||
| 740 | #ifndef ACPI_NO_METHOD_EXECUTION | 741 | #ifndef ACPI_NO_METHOD_EXECUTION |
| @@ -754,7 +755,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
| 754 | 755 | ||
| 755 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ | 756 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ |
| 756 | 757 | ||
| 757 | obj_desc->reference.value = opcode - AML_ARG_OP; | 758 | obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP; |
| 758 | obj_desc->reference.class = ACPI_REFCLASS_ARG; | 759 | obj_desc->reference.class = ACPI_REFCLASS_ARG; |
| 759 | 760 | ||
| 760 | #ifndef ACPI_NO_METHOD_EXECUTION | 761 | #ifndef ACPI_NO_METHOD_EXECUTION |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index b4c87b5053e6..584d766e6f12 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
| @@ -1386,14 +1386,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
| 1386 | 1386 | ||
| 1387 | case AML_BREAK_POINT_OP: | 1387 | case AML_BREAK_POINT_OP: |
| 1388 | 1388 | ||
| 1389 | /* Call up to the OS service layer to handle this */ | 1389 | /* |
| 1390 | 1390 | * Set the single-step flag. This will cause the debugger (if present) | |
| 1391 | status = | 1391 | * to break to the console within the AML debugger at the start of the |
| 1392 | acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | 1392 | * next AML instruction. |
| 1393 | "Executed AML Breakpoint opcode"); | 1393 | */ |
| 1394 | ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE); | ||
| 1395 | ACPI_DEBUGGER_EXEC(acpi_os_printf | ||
| 1396 | ("**break** Executed AML BreakPoint opcode\n")); | ||
| 1394 | 1397 | ||
| 1395 | /* If and when it returns, all done. */ | 1398 | /* Call to the OSL in case OS wants a piece of the action */ |
| 1396 | 1399 | ||
| 1400 | status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | ||
| 1401 | "Executed AML Breakpoint opcode"); | ||
| 1397 | break; | 1402 | break; |
| 1398 | 1403 | ||
| 1399 | case AML_BREAK_OP: | 1404 | case AML_BREAK_OP: |
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 40f92bf7dce5..e46c821cf572 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c | |||
| @@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object, | |||
| 102 | /* Return object of the top element and clean that top element result stack */ | 102 | /* Return object of the top element and clean that top element result stack */ |
| 103 | 103 | ||
| 104 | walk_state->result_count--; | 104 | walk_state->result_count--; |
| 105 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 105 | index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; |
| 106 | 106 | ||
| 107 | *object = state->results.obj_desc[index]; | 107 | *object = state->results.obj_desc[index]; |
| 108 | if (!*object) { | 108 | if (!*object) { |
| @@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
| 186 | 186 | ||
| 187 | /* Assign the address of object to the top free element of result stack */ | 187 | /* Assign the address of object to the top free element of result stack */ |
| 188 | 188 | ||
| 189 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 189 | index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; |
| 190 | state->results.obj_desc[index] = object; | 190 | state->results.obj_desc[index] = object; |
| 191 | walk_state->result_count++; | 191 | walk_state->result_count++; |
| 192 | 192 | ||
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 538d63264555..98c7f9c62653 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
| @@ -275,7 +275,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
| 275 | * | 275 | * |
| 276 | * PARAMETERS: region_obj - Internal region object | 276 | * PARAMETERS: region_obj - Internal region object |
| 277 | * Function - Read or Write operation | 277 | * Function - Read or Write operation |
| 278 | * Address - Where in the space to read or write | 278 | * region_offset - Where in the region to read or write |
| 279 | * bit_width - Field width in bits (8, 16, 32, or 64) | 279 | * bit_width - Field width in bits (8, 16, 32, or 64) |
| 280 | * Value - Pointer to in or out value, must be | 280 | * Value - Pointer to in or out value, must be |
| 281 | * full 64-bit acpi_integer | 281 | * full 64-bit acpi_integer |
| @@ -290,7 +290,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
| 290 | acpi_status | 290 | acpi_status |
| 291 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | 291 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, |
| 292 | u32 function, | 292 | u32 function, |
| 293 | acpi_physical_address address, | 293 | u32 region_offset, |
| 294 | u32 bit_width, acpi_integer * value) | 294 | u32 bit_width, acpi_integer * value) |
| 295 | { | 295 | { |
| 296 | acpi_status status; | 296 | acpi_status status; |
| @@ -396,7 +396,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
| 396 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | 396 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, |
| 397 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", | 397 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", |
| 398 | ®ion_obj->region.handler->address_space, handler, | 398 | ®ion_obj->region.handler->address_space, handler, |
| 399 | ACPI_FORMAT_NATIVE_UINT(address), | 399 | ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + |
| 400 | region_offset), | ||
| 400 | acpi_ut_get_region_name(region_obj->region. | 401 | acpi_ut_get_region_name(region_obj->region. |
| 401 | space_id))); | 402 | space_id))); |
| 402 | 403 | ||
| @@ -412,8 +413,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
| 412 | 413 | ||
| 413 | /* Call the handler */ | 414 | /* Call the handler */ |
| 414 | 415 | ||
| 415 | status = handler(function, address, bit_width, value, | 416 | status = handler(function, |
| 416 | handler_desc->address_space.context, | 417 | (region_obj->region.address + region_offset), |
| 418 | bit_width, value, handler_desc->address_space.context, | ||
| 417 | region_obj2->extra.region_context); | 419 | region_obj2->extra.region_context); |
| 418 | 420 | ||
| 419 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d0a080747ec3..4721f58fe42c 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | ACPI_MODULE_NAME("evxfevnt") | 51 | ACPI_MODULE_NAME("evxfevnt") |
| 52 | 52 | ||
| 53 | /* Local prototypes */ | 53 | /* Local prototypes */ |
| 54 | acpi_status | 54 | static acpi_status |
| 55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
| 56 | struct acpi_gpe_block_info *gpe_block, void *context); | 56 | struct acpi_gpe_block_info *gpe_block, void *context); |
| 57 | 57 | ||
| @@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | |||
| 785 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | 785 | * block device. NULL if the GPE is one of the FADT-defined GPEs. |
| 786 | * | 786 | * |
| 787 | ******************************************************************************/ | 787 | ******************************************************************************/ |
| 788 | acpi_status | 788 | static acpi_status |
| 789 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 789 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
| 790 | struct acpi_gpe_block_info *gpe_block, void *context) | 790 | struct acpi_gpe_block_info *gpe_block, void *context) |
| 791 | { | 791 | { |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 3deb20a126b2..277fd609611a 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
| 48 | #include "actables.h" | 48 | #include "actables.h" |
| 49 | #include "acdispat.h" | 49 | #include "acdispat.h" |
| 50 | #include "acevents.h" | ||
| 50 | 51 | ||
| 51 | #define _COMPONENT ACPI_EXECUTER | 52 | #define _COMPONENT ACPI_EXECUTER |
| 52 | ACPI_MODULE_NAME("exconfig") | 53 | ACPI_MODULE_NAME("exconfig") |
| @@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index, | |||
| 57 | struct acpi_namespace_node *parent_node, | 58 | struct acpi_namespace_node *parent_node, |
| 58 | union acpi_operand_object **ddb_handle); | 59 | union acpi_operand_object **ddb_handle); |
| 59 | 60 | ||
| 61 | static acpi_status | ||
| 62 | acpi_ex_region_read(union acpi_operand_object *obj_desc, | ||
| 63 | u32 length, u8 *buffer); | ||
| 64 | |||
| 60 | /******************************************************************************* | 65 | /******************************************************************************* |
| 61 | * | 66 | * |
| 62 | * FUNCTION: acpi_ex_add_table | 67 | * FUNCTION: acpi_ex_add_table |
| @@ -91,6 +96,7 @@ acpi_ex_add_table(u32 table_index, | |||
| 91 | 96 | ||
| 92 | /* Init the table handle */ | 97 | /* Init the table handle */ |
| 93 | 98 | ||
| 99 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | ||
| 94 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; | 100 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; |
| 95 | *ddb_handle = obj_desc; | 101 | *ddb_handle = obj_desc; |
| 96 | 102 | ||
| @@ -229,6 +235,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
| 229 | walk_state); | 235 | walk_state); |
| 230 | if (ACPI_FAILURE(status)) { | 236 | if (ACPI_FAILURE(status)) { |
| 231 | (void)acpi_ex_unload_table(ddb_handle); | 237 | (void)acpi_ex_unload_table(ddb_handle); |
| 238 | |||
| 239 | acpi_ut_remove_reference(ddb_handle); | ||
| 232 | return_ACPI_STATUS(status); | 240 | return_ACPI_STATUS(status); |
| 233 | } | 241 | } |
| 234 | } | 242 | } |
| @@ -254,6 +262,47 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
| 254 | 262 | ||
| 255 | /******************************************************************************* | 263 | /******************************************************************************* |
| 256 | * | 264 | * |
| 265 | * FUNCTION: acpi_ex_region_read | ||
| 266 | * | ||
| 267 | * PARAMETERS: obj_desc - Region descriptor | ||
| 268 | * Length - Number of bytes to read | ||
| 269 | * Buffer - Pointer to where to put the data | ||
| 270 | * | ||
| 271 | * RETURN: Status | ||
| 272 | * | ||
| 273 | * DESCRIPTION: Read data from an operation region. The read starts from the | ||
| 274 | * beginning of the region. | ||
| 275 | * | ||
| 276 | ******************************************************************************/ | ||
| 277 | |||
| 278 | static acpi_status | ||
| 279 | acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) | ||
| 280 | { | ||
| 281 | acpi_status status; | ||
| 282 | acpi_integer value; | ||
| 283 | u32 region_offset = 0; | ||
| 284 | u32 i; | ||
| 285 | |||
| 286 | /* Bytewise reads */ | ||
| 287 | |||
| 288 | for (i = 0; i < length; i++) { | ||
| 289 | status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, | ||
| 290 | region_offset, 8, | ||
| 291 | &value); | ||
| 292 | if (ACPI_FAILURE(status)) { | ||
| 293 | return status; | ||
| 294 | } | ||
| 295 | |||
| 296 | *buffer = (u8)value; | ||
| 297 | buffer++; | ||
| 298 | region_offset++; | ||
| 299 | } | ||
| 300 | |||
| 301 | return AE_OK; | ||
| 302 | } | ||
| 303 | |||
| 304 | /******************************************************************************* | ||
| 305 | * | ||
| 257 | * FUNCTION: acpi_ex_load_op | 306 | * FUNCTION: acpi_ex_load_op |
| 258 | * | 307 | * |
| 259 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be | 308 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be |
| @@ -314,18 +363,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
| 314 | } | 363 | } |
| 315 | } | 364 | } |
| 316 | 365 | ||
| 317 | /* | 366 | /* Get the table header first so we can get the table length */ |
| 318 | * Map the table header and get the actual table length. The region | 367 | |
| 319 | * length is not guaranteed to be the same as the table length. | 368 | table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); |
| 320 | */ | ||
| 321 | table = acpi_os_map_memory(obj_desc->region.address, | ||
| 322 | sizeof(struct acpi_table_header)); | ||
| 323 | if (!table) { | 369 | if (!table) { |
| 324 | return_ACPI_STATUS(AE_NO_MEMORY); | 370 | return_ACPI_STATUS(AE_NO_MEMORY); |
| 325 | } | 371 | } |
| 326 | 372 | ||
| 373 | status = | ||
| 374 | acpi_ex_region_read(obj_desc, | ||
| 375 | sizeof(struct acpi_table_header), | ||
| 376 | ACPI_CAST_PTR(u8, table)); | ||
| 327 | length = table->length; | 377 | length = table->length; |
| 328 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | 378 | ACPI_FREE(table); |
| 379 | |||
| 380 | if (ACPI_FAILURE(status)) { | ||
| 381 | return_ACPI_STATUS(status); | ||
| 382 | } | ||
| 329 | 383 | ||
| 330 | /* Must have at least an ACPI table header */ | 384 | /* Must have at least an ACPI table header */ |
| 331 | 385 | ||
| @@ -334,10 +388,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
| 334 | } | 388 | } |
| 335 | 389 | ||
| 336 | /* | 390 | /* |
| 337 | * The memory region is not guaranteed to remain stable and we must | 391 | * The original implementation simply mapped the table, with no copy. |
| 338 | * copy the table to a local buffer. For example, the memory region | 392 | * However, the memory region is not guaranteed to remain stable and |
| 339 | * is corrupted after suspend on some machines. Dynamically loaded | 393 | * we must copy the table to a local buffer. For example, the memory |
| 340 | * tables are usually small, so this overhead is minimal. | 394 | * region is corrupted after suspend on some machines. Dynamically |
| 395 | * loaded tables are usually small, so this overhead is minimal. | ||
| 396 | * | ||
| 397 | * The latest implementation (5/2009) does not use a mapping at all. | ||
| 398 | * We use the low-level operation region interface to read the table | ||
| 399 | * instead of the obvious optimization of using a direct mapping. | ||
| 400 | * This maintains a consistent use of operation regions across the | ||
| 401 | * entire subsystem. This is important if additional processing must | ||
| 402 | * be performed in the (possibly user-installed) operation region | ||
| 403 | * handler. For example, acpi_exec and ASLTS depend on this. | ||
| 341 | */ | 404 | */ |
| 342 | 405 | ||
| 343 | /* Allocate a buffer for the table */ | 406 | /* Allocate a buffer for the table */ |
| @@ -347,17 +410,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
| 347 | return_ACPI_STATUS(AE_NO_MEMORY); | 410 | return_ACPI_STATUS(AE_NO_MEMORY); |
| 348 | } | 411 | } |
| 349 | 412 | ||
| 350 | /* Map the entire table and copy it */ | 413 | /* Read the entire table */ |
| 351 | 414 | ||
| 352 | table = acpi_os_map_memory(obj_desc->region.address, length); | 415 | status = acpi_ex_region_read(obj_desc, length, |
| 353 | if (!table) { | 416 | ACPI_CAST_PTR(u8, |
| 417 | table_desc.pointer)); | ||
| 418 | if (ACPI_FAILURE(status)) { | ||
| 354 | ACPI_FREE(table_desc.pointer); | 419 | ACPI_FREE(table_desc.pointer); |
| 355 | return_ACPI_STATUS(AE_NO_MEMORY); | 420 | return_ACPI_STATUS(status); |
| 356 | } | 421 | } |
| 357 | 422 | ||
| 358 | ACPI_MEMCPY(table_desc.pointer, table, length); | ||
| 359 | acpi_os_unmap_memory(table, length); | ||
| 360 | |||
| 361 | table_desc.address = obj_desc->region.address; | 423 | table_desc.address = obj_desc->region.address; |
| 362 | break; | 424 | break; |
| 363 | 425 | ||
| @@ -454,6 +516,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
| 454 | return_ACPI_STATUS(status); | 516 | return_ACPI_STATUS(status); |
| 455 | } | 517 | } |
| 456 | 518 | ||
| 519 | /* Remove the reference by added by acpi_ex_store above */ | ||
| 520 | |||
| 521 | acpi_ut_remove_reference(ddb_handle); | ||
| 522 | |||
| 457 | /* Invoke table handler if present */ | 523 | /* Invoke table handler if present */ |
| 458 | 524 | ||
| 459 | if (acpi_gbl_table_handler) { | 525 | if (acpi_gbl_table_handler) { |
| @@ -495,13 +561,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
| 495 | 561 | ||
| 496 | /* | 562 | /* |
| 497 | * Validate the handle | 563 | * Validate the handle |
| 498 | * Although the handle is partially validated in acpi_ex_reconfiguration(), | 564 | * Although the handle is partially validated in acpi_ex_reconfiguration() |
| 499 | * when it calls acpi_ex_resolve_operands(), the handle is more completely | 565 | * when it calls acpi_ex_resolve_operands(), the handle is more completely |
| 500 | * validated here. | 566 | * validated here. |
| 567 | * | ||
| 568 | * Handle must be a valid operand object of type reference. Also, the | ||
| 569 | * ddb_handle must still be marked valid (table has not been previously | ||
| 570 | * unloaded) | ||
| 501 | */ | 571 | */ |
| 502 | if ((!ddb_handle) || | 572 | if ((!ddb_handle) || |
| 503 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || | 573 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || |
| 504 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { | 574 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) || |
| 575 | (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) { | ||
| 505 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 576 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 506 | } | 577 | } |
| 507 | 578 | ||
| @@ -509,6 +580,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
| 509 | 580 | ||
| 510 | table_index = table_desc->reference.value; | 581 | table_index = table_desc->reference.value; |
| 511 | 582 | ||
| 583 | /* Ensure the table is still loaded */ | ||
| 584 | |||
| 585 | if (!acpi_tb_is_table_loaded(table_index)) { | ||
| 586 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
| 587 | } | ||
| 588 | |||
| 512 | /* Invoke table handler if present */ | 589 | /* Invoke table handler if present */ |
| 513 | 590 | ||
| 514 | if (acpi_gbl_table_handler) { | 591 | if (acpi_gbl_table_handler) { |
| @@ -530,8 +607,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
| 530 | (void)acpi_tb_release_owner_id(table_index); | 607 | (void)acpi_tb_release_owner_id(table_index); |
| 531 | acpi_tb_set_table_loaded_flag(table_index, FALSE); | 608 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
| 532 | 609 | ||
| 533 | /* Table unloaded, remove a reference to the ddb_handle object */ | 610 | /* |
| 534 | 611 | * Invalidate the handle. We do this because the handle may be stored | |
| 535 | acpi_ut_remove_reference(ddb_handle); | 612 | * in a named object and may not be actually deleted until much later. |
| 613 | */ | ||
| 614 | ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; | ||
| 536 | return_ACPI_STATUS(AE_OK); | 615 | return_ACPI_STATUS(AE_OK); |
| 537 | } | 616 | } |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index a57ad2564ab0..02b25d233d99 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
| @@ -502,7 +502,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
| 502 | * ACPI 2.0: sync_level = sync_level in method declaration | 502 | * ACPI 2.0: sync_level = sync_level in method declaration |
| 503 | */ | 503 | */ |
| 504 | obj_desc->method.sync_level = (u8) | 504 | obj_desc->method.sync_level = (u8) |
| 505 | ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4); | 505 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | /* Attach the new object to the method Node */ | 508 | /* Attach the new object to the method Node */ |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 89d141fdae0b..ec524614e708 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
| @@ -120,9 +120,11 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { | |||
| 120 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} | 120 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} |
| 121 | }; | 121 | }; |
| 122 | 122 | ||
| 123 | static struct acpi_exdump_info acpi_ex_dump_method[8] = { | 123 | static struct acpi_exdump_info acpi_ex_dump_method[9] = { |
| 124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, | 124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, |
| 125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"}, | 125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, |
| 126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), | ||
| 127 | "Parameter Count"}, | ||
| 126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, | 128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, |
| 127 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, | 129 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, |
| 128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, | 130 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 99cee61e655d..d4075b821021 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
| @@ -222,7 +222,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
| 222 | { | 222 | { |
| 223 | acpi_status status; | 223 | acpi_status status; |
| 224 | union acpi_operand_object *rgn_desc; | 224 | union acpi_operand_object *rgn_desc; |
| 225 | acpi_physical_address address; | 225 | u32 region_offset; |
| 226 | 226 | ||
| 227 | ACPI_FUNCTION_TRACE(ex_access_region); | 227 | ACPI_FUNCTION_TRACE(ex_access_region); |
| 228 | 228 | ||
| @@ -243,7 +243,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
| 243 | * 3) The current offset into the field | 243 | * 3) The current offset into the field |
| 244 | */ | 244 | */ |
| 245 | rgn_desc = obj_desc->common_field.region_obj; | 245 | rgn_desc = obj_desc->common_field.region_obj; |
| 246 | address = rgn_desc->region.address + | 246 | region_offset = |
| 247 | obj_desc->common_field.base_byte_offset + field_datum_byte_offset; | 247 | obj_desc->common_field.base_byte_offset + field_datum_byte_offset; |
| 248 | 248 | ||
| 249 | if ((function & ACPI_IO_MASK) == ACPI_READ) { | 249 | if ((function & ACPI_IO_MASK) == ACPI_READ) { |
| @@ -260,16 +260,18 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
| 260 | obj_desc->common_field.access_byte_width, | 260 | obj_desc->common_field.access_byte_width, |
| 261 | obj_desc->common_field.base_byte_offset, | 261 | obj_desc->common_field.base_byte_offset, |
| 262 | field_datum_byte_offset, ACPI_CAST_PTR(void, | 262 | field_datum_byte_offset, ACPI_CAST_PTR(void, |
| 263 | address))); | 263 | (rgn_desc-> |
| 264 | region. | ||
| 265 | address + | ||
| 266 | region_offset)))); | ||
| 264 | 267 | ||
| 265 | /* Invoke the appropriate address_space/op_region handler */ | 268 | /* Invoke the appropriate address_space/op_region handler */ |
| 266 | 269 | ||
| 267 | status = acpi_ev_address_space_dispatch(rgn_desc, function, | 270 | status = |
| 268 | address, | 271 | acpi_ev_address_space_dispatch(rgn_desc, function, region_offset, |
| 269 | ACPI_MUL_8(obj_desc-> | 272 | ACPI_MUL_8(obj_desc->common_field. |
| 270 | common_field. | 273 | access_byte_width), |
| 271 | access_byte_width), | 274 | value); |
| 272 | value); | ||
| 273 | 275 | ||
| 274 | if (ACPI_FAILURE(status)) { | 276 | if (ACPI_FAILURE(status)) { |
| 275 | if (status == AE_NOT_IMPLEMENTED) { | 277 | if (status == AE_NOT_IMPLEMENTED) { |
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index d301c1f363ef..2f0114202b05 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
| @@ -83,6 +83,15 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) | |||
| 83 | 83 | ||
| 84 | if (obj_desc->mutex.prev) { | 84 | if (obj_desc->mutex.prev) { |
| 85 | (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; | 85 | (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; |
| 86 | |||
| 87 | /* | ||
| 88 | * Migrate the previous sync level associated with this mutex to the | ||
| 89 | * previous mutex on the list so that it may be preserved. This handles | ||
| 90 | * the case where several mutexes have been acquired at the same level, | ||
| 91 | * but are not released in opposite order. | ||
| 92 | */ | ||
| 93 | (obj_desc->mutex.prev)->mutex.original_sync_level = | ||
| 94 | obj_desc->mutex.original_sync_level; | ||
| 86 | } else { | 95 | } else { |
| 87 | thread->acquired_mutex_list = obj_desc->mutex.next; | 96 | thread->acquired_mutex_list = obj_desc->mutex.next; |
| 88 | } | 97 | } |
| @@ -349,6 +358,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
| 349 | struct acpi_walk_state *walk_state) | 358 | struct acpi_walk_state *walk_state) |
| 350 | { | 359 | { |
| 351 | acpi_status status = AE_OK; | 360 | acpi_status status = AE_OK; |
| 361 | u8 previous_sync_level; | ||
| 352 | 362 | ||
| 353 | ACPI_FUNCTION_TRACE(ex_release_mutex); | 363 | ACPI_FUNCTION_TRACE(ex_release_mutex); |
| 354 | 364 | ||
| @@ -373,11 +383,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
| 373 | walk_state->thread->thread_id) | 383 | walk_state->thread->thread_id) |
| 374 | && (obj_desc != acpi_gbl_global_lock_mutex)) { | 384 | && (obj_desc != acpi_gbl_global_lock_mutex)) { |
| 375 | ACPI_ERROR((AE_INFO, | 385 | ACPI_ERROR((AE_INFO, |
| 376 | "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", | 386 | "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", |
| 377 | (unsigned long)walk_state->thread->thread_id, | 387 | ACPI_CAST_PTR(void, walk_state->thread->thread_id), |
| 378 | acpi_ut_get_node_name(obj_desc->mutex.node), | 388 | acpi_ut_get_node_name(obj_desc->mutex.node), |
| 379 | (unsigned long)obj_desc->mutex.owner_thread-> | 389 | ACPI_CAST_PTR(void, |
| 380 | thread_id)); | 390 | obj_desc->mutex.owner_thread-> |
| 391 | thread_id))); | ||
| 381 | return_ACPI_STATUS(AE_AML_NOT_OWNER); | 392 | return_ACPI_STATUS(AE_AML_NOT_OWNER); |
| 382 | } | 393 | } |
| 383 | 394 | ||
| @@ -391,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
| 391 | } | 402 | } |
| 392 | 403 | ||
| 393 | /* | 404 | /* |
| 394 | * The sync level of the mutex must be less than or equal to the current | 405 | * The sync level of the mutex must be equal to the current sync level. In |
| 395 | * sync level | 406 | * other words, the current level means that at least one mutex at that |
| 407 | * level is currently being held. Attempting to release a mutex of a | ||
| 408 | * different level can only mean that the mutex ordering rule is being | ||
| 409 | * violated. This behavior is clarified in ACPI 4.0 specification. | ||
| 396 | */ | 410 | */ |
| 397 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { | 411 | if (obj_desc->mutex.sync_level != |
| 412 | walk_state->thread->current_sync_level) { | ||
| 398 | ACPI_ERROR((AE_INFO, | 413 | ACPI_ERROR((AE_INFO, |
| 399 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", | 414 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", |
| 400 | acpi_ut_get_node_name(obj_desc->mutex.node), | 415 | acpi_ut_get_node_name(obj_desc->mutex.node), |
| @@ -403,14 +418,24 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
| 403 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); | 418 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); |
| 404 | } | 419 | } |
| 405 | 420 | ||
| 421 | /* | ||
| 422 | * Get the previous sync_level from the head of the acquired mutex list. | ||
| 423 | * This handles the case where several mutexes at the same level have been | ||
| 424 | * acquired, but are not released in reverse order. | ||
| 425 | */ | ||
| 426 | previous_sync_level = | ||
| 427 | walk_state->thread->acquired_mutex_list->mutex.original_sync_level; | ||
| 428 | |||
| 406 | status = acpi_ex_release_mutex_object(obj_desc); | 429 | status = acpi_ex_release_mutex_object(obj_desc); |
| 430 | if (ACPI_FAILURE(status)) { | ||
| 431 | return_ACPI_STATUS(status); | ||
| 432 | } | ||
| 407 | 433 | ||
| 408 | if (obj_desc->mutex.acquisition_depth == 0) { | 434 | if (obj_desc->mutex.acquisition_depth == 0) { |
| 409 | 435 | ||
| 410 | /* Restore the original sync_level */ | 436 | /* Restore the previous sync_level */ |
| 411 | 437 | ||
| 412 | walk_state->thread->current_sync_level = | 438 | walk_state->thread->current_sync_level = previous_sync_level; |
| 413 | obj_desc->mutex.original_sync_level; | ||
| 414 | } | 439 | } |
| 415 | return_ACPI_STATUS(status); | 440 | return_ACPI_STATUS(status); |
| 416 | } | 441 | } |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 90d606196c99..6efd07a4f779 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
| @@ -193,10 +193,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
| 193 | 193 | ||
| 194 | case ACPI_REFCLASS_TABLE: | 194 | case ACPI_REFCLASS_TABLE: |
| 195 | 195 | ||
| 196 | /* Case for ddb_handle */ | ||
| 197 | |||
| 196 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | 198 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
| 197 | "Table Index 0x%X\n", | 199 | "Table Index 0x%X\n", |
| 198 | source_desc->reference.value)); | 200 | source_desc->reference.value)); |
| 199 | break; | 201 | return; |
| 200 | 202 | ||
| 201 | default: | 203 | default: |
| 202 | break; | 204 | break; |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 7b2fb602b5cb..23d5505cb1f7 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
| @@ -81,9 +81,9 @@ acpi_status acpi_hw_clear_acpi_status(void) | |||
| 81 | 81 | ||
| 82 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); | 82 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); |
| 83 | 83 | ||
| 84 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n", | 84 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", |
| 85 | ACPI_BITMASK_ALL_FIXED_STATUS, | 85 | ACPI_BITMASK_ALL_FIXED_STATUS, |
| 86 | acpi_gbl_xpm1a_status.address)); | 86 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); |
| 87 | 87 | ||
| 88 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 88 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
| 89 | 89 | ||
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index aceb93111967..efc971ab7d65 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
| @@ -334,9 +334,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
| 334 | 334 | ||
| 335 | /* Get the next node in this scope (NULL if none) */ | 335 | /* Get the next node in this scope (NULL if none) */ |
| 336 | 336 | ||
| 337 | child_node = | 337 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
| 338 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
| 339 | child_node); | ||
| 340 | if (child_node) { | 338 | if (child_node) { |
| 341 | 339 | ||
| 342 | /* Found a child node - detach any attached object */ | 340 | /* Found a child node - detach any attached object */ |
| @@ -345,8 +343,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
| 345 | 343 | ||
| 346 | /* Check if this node has any children */ | 344 | /* Check if this node has any children */ |
| 347 | 345 | ||
| 348 | if (acpi_ns_get_next_node | 346 | if (child_node->child) { |
| 349 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
| 350 | /* | 347 | /* |
| 351 | * There is at least one child of this node, | 348 | * There is at least one child of this node, |
| 352 | * visit the node | 349 | * visit the node |
| @@ -432,9 +429,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
| 432 | * Get the next child of this parent node. When child_node is NULL, | 429 | * Get the next child of this parent node. When child_node is NULL, |
| 433 | * the first child of the parent is returned | 430 | * the first child of the parent is returned |
| 434 | */ | 431 | */ |
| 435 | child_node = | 432 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
| 436 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
| 437 | child_node); | ||
| 438 | 433 | ||
| 439 | if (deletion_node) { | 434 | if (deletion_node) { |
| 440 | acpi_ns_delete_children(deletion_node); | 435 | acpi_ns_delete_children(deletion_node); |
| @@ -452,8 +447,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
| 452 | 447 | ||
| 453 | /* Check if this node has any children */ | 448 | /* Check if this node has any children */ |
| 454 | 449 | ||
| 455 | if (acpi_ns_get_next_node | 450 | if (child_node->child) { |
| 456 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
| 457 | /* | 451 | /* |
| 458 | * There is at least one child of this node, | 452 | * There is at least one child of this node, |
| 459 | * visit the node | 453 | * visit the node |
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index ae3dc10a7e81..af8e6bcee07e 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c | |||
| @@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | |||
| 149 | 149 | ||
| 150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); | 150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); |
| 151 | if (!name_buffer) { | 151 | if (!name_buffer) { |
| 152 | ACPI_ERROR((AE_INFO, "Allocation failure")); | 152 | ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size)); |
| 153 | return_PTR(NULL); | 153 | return_PTR(NULL); |
| 154 | } | 154 | } |
| 155 | 155 | ||
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 3eb20bfda9d8..60f3af08d28c 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
| @@ -213,6 +213,15 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
| 213 | return_VOID; | 213 | return_VOID; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | if (node->flags & ANOBJ_ALLOCATED_BUFFER) { | ||
| 217 | |||
| 218 | /* Free the dynamic aml buffer */ | ||
| 219 | |||
| 220 | if (obj_desc->common.type == ACPI_TYPE_METHOD) { | ||
| 221 | ACPI_FREE(obj_desc->method.aml_start); | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 216 | /* Clear the entry in all cases */ | 225 | /* Clear the entry in all cases */ |
| 217 | 226 | ||
| 218 | node->object = NULL; | 227 | node->object = NULL; |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d9e8cbc6e679..7f8e066b12a3 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
| @@ -144,7 +144,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
| 144 | 144 | ||
| 145 | pathname = acpi_ns_get_external_pathname(node); | 145 | pathname = acpi_ns_get_external_pathname(node); |
| 146 | if (!pathname) { | 146 | if (!pathname) { |
| 147 | pathname = ACPI_CAST_PTR(char, predefined->info.name); | 147 | return AE_OK; /* Could not get pathname, ignore */ |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | /* | 150 | /* |
| @@ -230,10 +230,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | exit: | 232 | exit: |
| 233 | if (pathname != predefined->info.name) { | 233 | ACPI_FREE(pathname); |
| 234 | ACPI_FREE(pathname); | ||
| 235 | } | ||
| 236 | |||
| 237 | return (status); | 234 | return (status); |
| 238 | } | 235 | } |
| 239 | 236 | ||
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index f9b4f51bf8f2..7e865639a928 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
| @@ -45,6 +45,10 @@ | |||
| 45 | #include "accommon.h" | 45 | #include "accommon.h" |
| 46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
| 47 | 47 | ||
| 48 | #ifdef ACPI_ASL_COMPILER | ||
| 49 | #include "amlcode.h" | ||
| 50 | #endif | ||
| 51 | |||
| 48 | #define _COMPONENT ACPI_NAMESPACE | 52 | #define _COMPONENT ACPI_NAMESPACE |
| 49 | ACPI_MODULE_NAME("nssearch") | 53 | ACPI_MODULE_NAME("nssearch") |
| 50 | 54 | ||
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 83e3aa6d4b9b..35539df5c75d 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
| @@ -52,8 +52,7 @@ ACPI_MODULE_NAME("nswalk") | |||
| 52 | * | 52 | * |
| 53 | * FUNCTION: acpi_ns_get_next_node | 53 | * FUNCTION: acpi_ns_get_next_node |
| 54 | * | 54 | * |
| 55 | * PARAMETERS: Type - Type of node to be searched for | 55 | * PARAMETERS: parent_node - Parent node whose children we are |
| 56 | * parent_node - Parent node whose children we are | ||
| 57 | * getting | 56 | * getting |
| 58 | * child_node - Previous child that was found. | 57 | * child_node - Previous child that was found. |
| 59 | * The NEXT child will be returned | 58 | * The NEXT child will be returned |
| @@ -66,27 +65,68 @@ ACPI_MODULE_NAME("nswalk") | |||
| 66 | * within Scope is returned. | 65 | * within Scope is returned. |
| 67 | * | 66 | * |
| 68 | ******************************************************************************/ | 67 | ******************************************************************************/ |
| 69 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | 68 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
| 70 | *parent_node, struct acpi_namespace_node | 69 | *parent_node, |
| 70 | struct acpi_namespace_node | ||
| 71 | *child_node) | 71 | *child_node) |
| 72 | { | 72 | { |
| 73 | struct acpi_namespace_node *next_node = NULL; | ||
| 74 | |||
| 75 | ACPI_FUNCTION_ENTRY(); | 73 | ACPI_FUNCTION_ENTRY(); |
| 76 | 74 | ||
| 77 | if (!child_node) { | 75 | if (!child_node) { |
| 78 | 76 | ||
| 79 | /* It's really the parent's _scope_ that we want */ | 77 | /* It's really the parent's _scope_ that we want */ |
| 80 | 78 | ||
| 81 | next_node = parent_node->child; | 79 | return parent_node->child; |
| 82 | } | 80 | } |
| 83 | 81 | ||
| 84 | else { | 82 | /* |
| 85 | /* Start search at the NEXT node */ | 83 | * Get the next node. |
| 86 | 84 | * | |
| 87 | next_node = acpi_ns_get_next_valid_node(child_node); | 85 | * If we are at the end of this peer list, return NULL |
| 86 | */ | ||
| 87 | if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
| 88 | return NULL; | ||
| 88 | } | 89 | } |
| 89 | 90 | ||
| 91 | /* Otherwise just return the next peer */ | ||
| 92 | |||
| 93 | return child_node->peer; | ||
| 94 | } | ||
| 95 | |||
| 96 | /******************************************************************************* | ||
| 97 | * | ||
| 98 | * FUNCTION: acpi_ns_get_next_node_typed | ||
| 99 | * | ||
| 100 | * PARAMETERS: Type - Type of node to be searched for | ||
| 101 | * parent_node - Parent node whose children we are | ||
| 102 | * getting | ||
| 103 | * child_node - Previous child that was found. | ||
| 104 | * The NEXT child will be returned | ||
| 105 | * | ||
| 106 | * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if | ||
| 107 | * none is found. | ||
| 108 | * | ||
| 109 | * DESCRIPTION: Return the next peer node within the namespace. If Handle | ||
| 110 | * is valid, Scope is ignored. Otherwise, the first node | ||
| 111 | * within Scope is returned. | ||
| 112 | * | ||
| 113 | ******************************************************************************/ | ||
| 114 | |||
| 115 | struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | ||
| 116 | struct | ||
| 117 | acpi_namespace_node | ||
| 118 | *parent_node, | ||
| 119 | struct | ||
| 120 | acpi_namespace_node | ||
| 121 | *child_node) | ||
| 122 | { | ||
| 123 | struct acpi_namespace_node *next_node = NULL; | ||
| 124 | |||
| 125 | ACPI_FUNCTION_ENTRY(); | ||
| 126 | |||
| 127 | next_node = acpi_ns_get_next_node(parent_node, child_node); | ||
| 128 | |||
| 129 | |||
| 90 | /* If any type is OK, we are done */ | 130 | /* If any type is OK, we are done */ |
| 91 | 131 | ||
| 92 | if (type == ACPI_TYPE_ANY) { | 132 | if (type == ACPI_TYPE_ANY) { |
| @@ -186,9 +226,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
| 186 | /* Get the next node in this scope. Null if not found */ | 226 | /* Get the next node in this scope. Null if not found */ |
| 187 | 227 | ||
| 188 | status = AE_OK; | 228 | status = AE_OK; |
| 189 | child_node = | 229 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
| 190 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
| 191 | child_node); | ||
| 192 | if (child_node) { | 230 | if (child_node) { |
| 193 | 231 | ||
| 194 | /* Found next child, get the type if we are not searching for ANY */ | 232 | /* Found next child, get the type if we are not searching for ANY */ |
| @@ -269,8 +307,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
| 269 | * function has specified that the maximum depth has been reached. | 307 | * function has specified that the maximum depth has been reached. |
| 270 | */ | 308 | */ |
| 271 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { | 309 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { |
| 272 | if (acpi_ns_get_next_node | 310 | if (child_node->child) { |
| 273 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
| 274 | 311 | ||
| 275 | /* There is at least one child of this node, visit it */ | 312 | /* There is at least one child of this node, visit it */ |
| 276 | 313 | ||
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 9589fea24997..f23593d6add4 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
| @@ -45,6 +45,8 @@ | |||
| 45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
| 46 | #include "accommon.h" | 46 | #include "accommon.h" |
| 47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
| 48 | #include "acparser.h" | ||
| 49 | #include "amlcode.h" | ||
| 48 | 50 | ||
| 49 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
| 50 | ACPI_MODULE_NAME("nsxfname") | 52 | ACPI_MODULE_NAME("nsxfname") |
| @@ -358,3 +360,151 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
| 358 | } | 360 | } |
| 359 | 361 | ||
| 360 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) | 362 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) |
| 363 | |||
| 364 | /****************************************************************************** | ||
| 365 | * | ||
| 366 | * FUNCTION: acpi_install_method | ||
| 367 | * | ||
| 368 | * PARAMETERS: Buffer - An ACPI table containing one control method | ||
| 369 | * | ||
| 370 | * RETURN: Status | ||
| 371 | * | ||
| 372 | * DESCRIPTION: Install a control method into the namespace. If the method | ||
| 373 | * name already exists in the namespace, it is overwritten. The | ||
| 374 | * input buffer must contain a valid DSDT or SSDT containing a | ||
| 375 | * single control method. | ||
| 376 | * | ||
| 377 | ******************************************************************************/ | ||
| 378 | acpi_status acpi_install_method(u8 *buffer) | ||
| 379 | { | ||
| 380 | struct acpi_table_header *table = | ||
| 381 | ACPI_CAST_PTR(struct acpi_table_header, buffer); | ||
| 382 | u8 *aml_buffer; | ||
| 383 | u8 *aml_start; | ||
| 384 | char *path; | ||
| 385 | struct acpi_namespace_node *node; | ||
| 386 | union acpi_operand_object *method_obj; | ||
| 387 | struct acpi_parse_state parser_state; | ||
| 388 | u32 aml_length; | ||
| 389 | u16 opcode; | ||
| 390 | u8 method_flags; | ||
| 391 | acpi_status status; | ||
| 392 | |||
| 393 | /* Parameter validation */ | ||
| 394 | |||
| 395 | if (!buffer) { | ||
| 396 | return AE_BAD_PARAMETER; | ||
| 397 | } | ||
| 398 | |||
| 399 | /* Table must be a DSDT or SSDT */ | ||
| 400 | |||
| 401 | if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) && | ||
| 402 | !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { | ||
| 403 | return AE_BAD_HEADER; | ||
| 404 | } | ||
| 405 | |||
| 406 | /* First AML opcode in the table must be a control method */ | ||
| 407 | |||
| 408 | parser_state.aml = buffer + sizeof(struct acpi_table_header); | ||
| 409 | opcode = acpi_ps_peek_opcode(&parser_state); | ||
| 410 | if (opcode != AML_METHOD_OP) { | ||
| 411 | return AE_BAD_PARAMETER; | ||
| 412 | } | ||
| 413 | |||
| 414 | /* Extract method information from the raw AML */ | ||
| 415 | |||
| 416 | parser_state.aml += acpi_ps_get_opcode_size(opcode); | ||
| 417 | parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state); | ||
| 418 | path = acpi_ps_get_next_namestring(&parser_state); | ||
| 419 | method_flags = *parser_state.aml++; | ||
| 420 | aml_start = parser_state.aml; | ||
| 421 | aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start); | ||
| 422 | |||
| 423 | /* | ||
| 424 | * Allocate resources up-front. We don't want to have to delete a new | ||
| 425 | * node from the namespace if we cannot allocate memory. | ||
| 426 | */ | ||
| 427 | aml_buffer = ACPI_ALLOCATE(aml_length); | ||
| 428 | if (!aml_buffer) { | ||
| 429 | return AE_NO_MEMORY; | ||
| 430 | } | ||
| 431 | |||
| 432 | method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | ||
| 433 | if (!method_obj) { | ||
| 434 | ACPI_FREE(aml_buffer); | ||
| 435 | return AE_NO_MEMORY; | ||
| 436 | } | ||
| 437 | |||
| 438 | /* Lock namespace for acpi_ns_lookup, we may be creating a new node */ | ||
| 439 | |||
| 440 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
| 441 | if (ACPI_FAILURE(status)) { | ||
| 442 | goto error_exit; | ||
| 443 | } | ||
| 444 | |||
| 445 | /* The lookup either returns an existing node or creates a new one */ | ||
| 446 | |||
| 447 | status = | ||
| 448 | acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, | ||
| 449 | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, | ||
| 450 | NULL, &node); | ||
| 451 | |||
| 452 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
| 453 | |||
| 454 | if (ACPI_FAILURE(status)) { /* ns_lookup */ | ||
| 455 | if (status != AE_ALREADY_EXISTS) { | ||
| 456 | goto error_exit; | ||
| 457 | } | ||
| 458 | |||
| 459 | /* Node existed previously, make sure it is a method node */ | ||
| 460 | |||
| 461 | if (node->type != ACPI_TYPE_METHOD) { | ||
| 462 | status = AE_TYPE; | ||
| 463 | goto error_exit; | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | /* Copy the method AML to the local buffer */ | ||
| 468 | |||
| 469 | ACPI_MEMCPY(aml_buffer, aml_start, aml_length); | ||
| 470 | |||
| 471 | /* Initialize the method object with the new method's information */ | ||
| 472 | |||
| 473 | method_obj->method.aml_start = aml_buffer; | ||
| 474 | method_obj->method.aml_length = aml_length; | ||
| 475 | |||
| 476 | method_obj->method.param_count = (u8) | ||
| 477 | (method_flags & AML_METHOD_ARG_COUNT); | ||
| 478 | |||
| 479 | method_obj->method.method_flags = (u8) | ||
| 480 | (method_flags & ~AML_METHOD_ARG_COUNT); | ||
| 481 | |||
| 482 | if (method_flags & AML_METHOD_SERIALIZED) { | ||
| 483 | method_obj->method.sync_level = (u8) | ||
| 484 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); | ||
| 485 | } | ||
| 486 | |||
| 487 | /* | ||
| 488 | * Now that it is complete, we can attach the new method object to | ||
| 489 | * the method Node (detaches/deletes any existing object) | ||
| 490 | */ | ||
| 491 | status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD); | ||
| 492 | |||
| 493 | /* | ||
| 494 | * Flag indicates AML buffer is dynamic, must be deleted later. | ||
| 495 | * Must be set only after attach above. | ||
| 496 | */ | ||
| 497 | node->flags |= ANOBJ_ALLOCATED_BUFFER; | ||
| 498 | |||
| 499 | /* Remove local reference to the method object */ | ||
| 500 | |||
| 501 | acpi_ut_remove_reference(method_obj); | ||
| 502 | return status; | ||
| 503 | |||
| 504 | error_exit: | ||
| 505 | |||
| 506 | ACPI_FREE(aml_buffer); | ||
| 507 | ACPI_FREE(method_obj); | ||
| 508 | return status; | ||
| 509 | } | ||
| 510 | ACPI_EXPORT_SYMBOL(acpi_install_method) | ||
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 1c7efc15225f..4071bad4458e 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
| @@ -162,6 +162,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type) | |||
| 162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | 162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) |
| 163 | { | 163 | { |
| 164 | struct acpi_namespace_node *node; | 164 | struct acpi_namespace_node *node; |
| 165 | struct acpi_namespace_node *parent_node; | ||
| 165 | acpi_status status; | 166 | acpi_status status; |
| 166 | 167 | ||
| 167 | if (!ret_handle) { | 168 | if (!ret_handle) { |
| @@ -189,12 +190,12 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | |||
| 189 | 190 | ||
| 190 | /* Get the parent entry */ | 191 | /* Get the parent entry */ |
| 191 | 192 | ||
| 192 | *ret_handle = | 193 | parent_node = acpi_ns_get_parent_node(node); |
| 193 | acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node)); | 194 | *ret_handle = acpi_ns_convert_entry_to_handle(parent_node); |
| 194 | 195 | ||
| 195 | /* Return exception if parent is null */ | 196 | /* Return exception if parent is null */ |
| 196 | 197 | ||
| 197 | if (!acpi_ns_get_parent_node(node)) { | 198 | if (!parent_node) { |
| 198 | status = AE_NULL_ENTRY; | 199 | status = AE_NULL_ENTRY; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| @@ -268,7 +269,7 @@ acpi_get_next_object(acpi_object_type type, | |||
| 268 | 269 | ||
| 269 | /* Internal function does the real work */ | 270 | /* Internal function does the real work */ |
| 270 | 271 | ||
| 271 | node = acpi_ns_get_next_node(type, parent_node, child_node); | 272 | node = acpi_ns_get_next_node_typed(type, parent_node, child_node); |
| 272 | if (!node) { | 273 | if (!node) { |
| 273 | status = AE_NOT_FOUND; | 274 | status = AE_NOT_FOUND; |
| 274 | goto unlock_and_exit; | 275 | goto unlock_and_exit; |
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 88b5a2c4814d..3c4dcc3d1069 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
| @@ -547,7 +547,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
| 547 | 547 | ||
| 548 | if (!package_element || | 548 | if (!package_element || |
| 549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { | 549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { |
| 550 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); | 550 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
| 551 | } | 551 | } |
| 552 | 552 | ||
| 553 | /* | 553 | /* |
| @@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
| 593 | } else { | 593 | } else { |
| 594 | temp_size_needed += | 594 | temp_size_needed += |
| 595 | acpi_ns_get_pathname_length((*sub_object_list)->reference.node); | 595 | acpi_ns_get_pathname_length((*sub_object_list)->reference.node); |
| 596 | if (!temp_size_needed) { | ||
| 597 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| 598 | } | ||
| 599 | } | 596 | } |
| 600 | } else { | 597 | } else { |
| 601 | /* | 598 | /* |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 69a2aa5b5d83..395212bcd19b 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
| @@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource, | |||
| 338 | switch (resource->type) { | 338 | switch (resource->type) { |
| 339 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 339 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
| 340 | 340 | ||
| 341 | address16 = (struct acpi_resource_address16 *)&resource->data; | 341 | address16 = |
| 342 | ACPI_CAST_PTR(struct acpi_resource_address16, | ||
| 343 | &resource->data); | ||
| 342 | ACPI_COPY_ADDRESS(out, address16); | 344 | ACPI_COPY_ADDRESS(out, address16); |
| 343 | break; | 345 | break; |
| 344 | 346 | ||
| 345 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 347 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
| 346 | 348 | ||
| 347 | address32 = (struct acpi_resource_address32 *)&resource->data; | 349 | address32 = |
| 350 | ACPI_CAST_PTR(struct acpi_resource_address32, | ||
| 351 | &resource->data); | ||
| 348 | ACPI_COPY_ADDRESS(out, address32); | 352 | ACPI_COPY_ADDRESS(out, address32); |
| 349 | break; | 353 | break; |
| 350 | 354 | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 71e655d14cb0..82b02dcb942e 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
| @@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
| 284 | if (length > sizeof(struct acpi_table_fadt)) { | 284 | if (length > sizeof(struct acpi_table_fadt)) { |
| 285 | ACPI_WARNING((AE_INFO, | 285 | ACPI_WARNING((AE_INFO, |
| 286 | "FADT (revision %u) is longer than ACPI 2.0 version, " | 286 | "FADT (revision %u) is longer than ACPI 2.0 version, " |
| 287 | "truncating length 0x%X to 0x%zX", | 287 | "truncating length 0x%X to 0x%X", |
| 288 | table->revision, (unsigned)length, | 288 | table->revision, length, |
| 289 | sizeof(struct acpi_table_fadt))); | 289 | (u32)sizeof(struct acpi_table_fadt))); |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | /* Clear the entire local FADT */ | 292 | /* Clear the entire local FADT */ |
| @@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void) | |||
| 441 | &acpi_gbl_FADT, | 441 | &acpi_gbl_FADT, |
| 442 | fadt_info_table | 442 | fadt_info_table |
| 443 | [i].length), | 443 | [i].length), |
| 444 | address32); | 444 | (u64) address32); |
| 445 | } | 445 | } |
| 446 | } | 446 | } |
| 447 | } | 447 | } |
| @@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void) | |||
| 469 | static void acpi_tb_validate_fadt(void) | 469 | static void acpi_tb_validate_fadt(void) |
| 470 | { | 470 | { |
| 471 | char *name; | 471 | char *name; |
| 472 | u32 *address32; | ||
| 473 | struct acpi_generic_address *address64; | 472 | struct acpi_generic_address *address64; |
| 474 | u8 length; | 473 | u8 length; |
| 475 | u32 i; | 474 | u32 i; |
| @@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void) | |||
| 505 | 504 | ||
| 506 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 505 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
| 507 | /* | 506 | /* |
| 508 | * Generate pointers to the 32-bit and 64-bit addresses, get the | 507 | * Generate pointer to the 64-bit address, get the register |
| 509 | * register length (width), and the register name | 508 | * length (width) and the register name |
| 510 | */ | 509 | */ |
| 511 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, | 510 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, |
| 512 | &acpi_gbl_FADT, | 511 | &acpi_gbl_FADT, |
| 513 | fadt_info_table[i].address64); | 512 | fadt_info_table[i].address64); |
| 514 | address32 = | ||
| 515 | ACPI_ADD_PTR(u32, &acpi_gbl_FADT, | ||
| 516 | fadt_info_table[i].address32); | ||
| 517 | length = | 513 | length = |
| 518 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, | 514 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, |
| 519 | fadt_info_table[i].length); | 515 | fadt_info_table[i].length); |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index f865d5a096de..63e82329a9e8 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
| @@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | |||
| 472 | * lock may block, and also since the execution of a namespace walk | 472 | * lock may block, and also since the execution of a namespace walk |
| 473 | * must be allowed to use the interpreter. | 473 | * must be allowed to use the interpreter. |
| 474 | */ | 474 | */ |
| 475 | acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 475 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
| 476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); |
| 477 | 477 | ||
| 478 | acpi_ns_delete_namespace_by_owner(owner_id); | 478 | acpi_ns_delete_namespace_by_owner(owner_id); |
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 919624f123d5..0f0c64bf8ac9 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
| @@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
| 676 | { | 676 | { |
| 677 | u16 reference_count; | 677 | u16 reference_count; |
| 678 | union acpi_operand_object *next_object; | 678 | union acpi_operand_object *next_object; |
| 679 | acpi_status status; | ||
| 679 | 680 | ||
| 680 | /* Save fields from destination that we don't want to overwrite */ | 681 | /* Save fields from destination that we don't want to overwrite */ |
| 681 | 682 | ||
| @@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
| 768 | } | 769 | } |
| 769 | break; | 770 | break; |
| 770 | 771 | ||
| 772 | /* | ||
| 773 | * For Mutex and Event objects, we cannot simply copy the underlying | ||
| 774 | * OS object. We must create a new one. | ||
| 775 | */ | ||
| 776 | case ACPI_TYPE_MUTEX: | ||
| 777 | |||
| 778 | status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex); | ||
| 779 | if (ACPI_FAILURE(status)) { | ||
| 780 | return status; | ||
| 781 | } | ||
| 782 | break; | ||
| 783 | |||
| 784 | case ACPI_TYPE_EVENT: | ||
| 785 | |||
| 786 | status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, | ||
| 787 | &dest_desc->event. | ||
| 788 | os_semaphore); | ||
| 789 | if (ACPI_FAILURE(status)) { | ||
| 790 | return status; | ||
| 791 | } | ||
| 792 | break; | ||
| 793 | |||
| 771 | default: | 794 | default: |
| 772 | /* Nothing to do for other simple objects */ | 795 | /* Nothing to do for other simple objects */ |
| 773 | break; | 796 | break; |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 38821f53042c..527d729f6815 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
| @@ -179,9 +179,9 @@ acpi_debug_print(u32 requested_debug_level, | |||
| 179 | if (thread_id != acpi_gbl_prev_thread_id) { | 179 | if (thread_id != acpi_gbl_prev_thread_id) { |
| 180 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 180 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
| 181 | acpi_os_printf | 181 | acpi_os_printf |
| 182 | ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", | 182 | ("\n**** Context Switch from TID %p to TID %p ****\n\n", |
| 183 | (unsigned long)acpi_gbl_prev_thread_id, | 183 | ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), |
| 184 | (unsigned long)thread_id); | 184 | ACPI_CAST_PTR(void, thread_id)); |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | acpi_gbl_prev_thread_id = thread_id; | 187 | acpi_gbl_prev_thread_id = thread_id; |
| @@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level, | |||
| 194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); | 194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); |
| 195 | 195 | ||
| 196 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 196 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
| 197 | acpi_os_printf("[%04lX] ", (unsigned long)thread_id); | 197 | acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | acpi_os_printf("[%02ld] %-22.22s: ", | 200 | acpi_os_printf("[%02ld] %-22.22s: ", |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index a5ee23bc4f55..bc1710315088 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
| @@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
| 75 | union acpi_operand_object *handler_desc; | 75 | union acpi_operand_object *handler_desc; |
| 76 | union acpi_operand_object *second_desc; | 76 | union acpi_operand_object *second_desc; |
| 77 | union acpi_operand_object *next_desc; | 77 | union acpi_operand_object *next_desc; |
| 78 | union acpi_operand_object **last_obj_ptr; | ||
| 78 | 79 | ||
| 79 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); | 80 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); |
| 80 | 81 | ||
| @@ -223,6 +224,26 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
| 223 | */ | 224 | */ |
| 224 | handler_desc = object->region.handler; | 225 | handler_desc = object->region.handler; |
| 225 | if (handler_desc) { | 226 | if (handler_desc) { |
| 227 | next_desc = | ||
| 228 | handler_desc->address_space.region_list; | ||
| 229 | last_obj_ptr = | ||
| 230 | &handler_desc->address_space.region_list; | ||
| 231 | |||
| 232 | /* Remove the region object from the handler's list */ | ||
| 233 | |||
| 234 | while (next_desc) { | ||
| 235 | if (next_desc == object) { | ||
| 236 | *last_obj_ptr = | ||
| 237 | next_desc->region.next; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | |||
| 241 | /* Walk the linked list of handler */ | ||
| 242 | |||
| 243 | last_obj_ptr = &next_desc->region.next; | ||
| 244 | next_desc = next_desc->region.next; | ||
| 245 | } | ||
| 246 | |||
| 226 | if (handler_desc->address_space.handler_flags & | 247 | if (handler_desc->address_space.handler_flags & |
| 227 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { | 248 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { |
| 228 | 249 | ||
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 1c9e250caefb..fbe782348b0b 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
| @@ -1033,11 +1033,12 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) | |||
| 1033 | { | 1033 | { |
| 1034 | va_list args; | 1034 | va_list args; |
| 1035 | 1035 | ||
| 1036 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | 1036 | acpi_os_printf("ACPI Error: "); |
| 1037 | 1037 | ||
| 1038 | va_start(args, format); | 1038 | va_start(args, format); |
| 1039 | acpi_os_vprintf(format, args); | 1039 | acpi_os_vprintf(format, args); |
| 1040 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1040 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, |
| 1041 | line_number); | ||
| 1041 | va_end(args); | 1042 | va_end(args); |
| 1042 | } | 1043 | } |
| 1043 | 1044 | ||
| @@ -1047,12 +1048,12 @@ acpi_exception(const char *module_name, | |||
| 1047 | { | 1048 | { |
| 1048 | va_list args; | 1049 | va_list args; |
| 1049 | 1050 | ||
| 1050 | acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, | 1051 | acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); |
| 1051 | line_number, acpi_format_exception(status)); | ||
| 1052 | 1052 | ||
| 1053 | va_start(args, format); | 1053 | va_start(args, format); |
| 1054 | acpi_os_vprintf(format, args); | 1054 | acpi_os_vprintf(format, args); |
| 1055 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1055 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, |
| 1056 | line_number); | ||
| 1056 | va_end(args); | 1057 | va_end(args); |
| 1057 | } | 1058 | } |
| 1058 | 1059 | ||
| @@ -1061,11 +1062,12 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | |||
| 1061 | { | 1062 | { |
| 1062 | va_list args; | 1063 | va_list args; |
| 1063 | 1064 | ||
| 1064 | acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); | 1065 | acpi_os_printf("ACPI Warning: "); |
| 1065 | 1066 | ||
| 1066 | va_start(args, format); | 1067 | va_start(args, format); |
| 1067 | acpi_os_vprintf(format, args); | 1068 | acpi_os_vprintf(format, args); |
| 1068 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1069 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, |
| 1070 | line_number); | ||
| 1069 | va_end(args); | 1071 | va_end(args); |
| 1070 | } | 1072 | } |
| 1071 | 1073 | ||
| @@ -1074,10 +1076,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...) | |||
| 1074 | { | 1076 | { |
| 1075 | va_list args; | 1077 | va_list args; |
| 1076 | 1078 | ||
| 1077 | /* | ||
| 1078 | * Removed module_name, line_number, and acpica version, not needed | ||
| 1079 | * for info output | ||
| 1080 | */ | ||
| 1081 | acpi_os_printf("ACPI: "); | 1079 | acpi_os_printf("ACPI: "); |
| 1082 | 1080 | ||
| 1083 | va_start(args, format); | 1081 | va_start(args, format); |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 26c93a748e64..80bb65154117 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
| @@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
| 230 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { | 230 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { |
| 231 | if (i == mutex_id) { | 231 | if (i == mutex_id) { |
| 232 | ACPI_ERROR((AE_INFO, | 232 | ACPI_ERROR((AE_INFO, |
| 233 | "Mutex [%s] already acquired by this thread [%X]", | 233 | "Mutex [%s] already acquired by this thread [%p]", |
| 234 | acpi_ut_get_mutex_name | 234 | acpi_ut_get_mutex_name |
| 235 | (mutex_id), | 235 | (mutex_id), |
| 236 | this_thread_id)); | 236 | ACPI_CAST_PTR(void, |
| 237 | this_thread_id))); | ||
| 237 | 238 | ||
| 238 | return (AE_ALREADY_ACQUIRED); | 239 | return (AE_ALREADY_ACQUIRED); |
| 239 | } | 240 | } |
| 240 | 241 | ||
| 241 | ACPI_ERROR((AE_INFO, | 242 | ACPI_ERROR((AE_INFO, |
| 242 | "Invalid acquire order: Thread %X owns [%s], wants [%s]", | 243 | "Invalid acquire order: Thread %p owns [%s], wants [%s]", |
| 243 | this_thread_id, | 244 | ACPI_CAST_PTR(void, this_thread_id), |
| 244 | acpi_ut_get_mutex_name(i), | 245 | acpi_ut_get_mutex_name(i), |
| 245 | acpi_ut_get_mutex_name(mutex_id))); | 246 | acpi_ut_get_mutex_name(mutex_id))); |
| 246 | 247 | ||
| @@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
| 251 | #endif | 252 | #endif |
| 252 | 253 | ||
| 253 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 254 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
| 254 | "Thread %lX attempting to acquire Mutex [%s]\n", | 255 | "Thread %p attempting to acquire Mutex [%s]\n", |
| 255 | (unsigned long)this_thread_id, | 256 | ACPI_CAST_PTR(void, this_thread_id), |
| 256 | acpi_ut_get_mutex_name(mutex_id))); | 257 | acpi_ut_get_mutex_name(mutex_id))); |
| 257 | 258 | ||
| 258 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, | 259 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, |
| 259 | ACPI_WAIT_FOREVER); | 260 | ACPI_WAIT_FOREVER); |
| 260 | if (ACPI_SUCCESS(status)) { | 261 | if (ACPI_SUCCESS(status)) { |
| 261 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 262 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
| 262 | "Thread %lX acquired Mutex [%s]\n", | 263 | "Thread %p acquired Mutex [%s]\n", |
| 263 | (unsigned long)this_thread_id, | 264 | ACPI_CAST_PTR(void, this_thread_id), |
| 264 | acpi_ut_get_mutex_name(mutex_id))); | 265 | acpi_ut_get_mutex_name(mutex_id))); |
| 265 | 266 | ||
| 266 | acpi_gbl_mutex_info[mutex_id].use_count++; | 267 | acpi_gbl_mutex_info[mutex_id].use_count++; |
| 267 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; | 268 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; |
| 268 | } else { | 269 | } else { |
| 269 | ACPI_EXCEPTION((AE_INFO, status, | 270 | ACPI_EXCEPTION((AE_INFO, status, |
| 270 | "Thread %lX could not acquire Mutex [%X]", | 271 | "Thread %p could not acquire Mutex [%X]", |
| 271 | (unsigned long)this_thread_id, mutex_id)); | 272 | ACPI_CAST_PTR(void, this_thread_id), mutex_id)); |
| 272 | } | 273 | } |
| 273 | 274 | ||
| 274 | return (status); | 275 | return (status); |
| @@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | |||
| 293 | ACPI_FUNCTION_NAME(ut_release_mutex); | 294 | ACPI_FUNCTION_NAME(ut_release_mutex); |
| 294 | 295 | ||
| 295 | this_thread_id = acpi_os_get_thread_id(); | 296 | this_thread_id = acpi_os_get_thread_id(); |
| 296 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 297 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", |
| 297 | "Thread %lX releasing Mutex [%s]\n", | 298 | ACPI_CAST_PTR(void, this_thread_id), |
| 298 | (unsigned long)this_thread_id, | ||
| 299 | acpi_ut_get_mutex_name(mutex_id))); | 299 | acpi_ut_get_mutex_name(mutex_id))); |
| 300 | 300 | ||
| 301 | if (mutex_id > ACPI_MAX_MUTEX) { | 301 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b22cec97ea19..c7a527c08a09 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <linux/hdreg.h> | 38 | #include <linux/hdreg.h> |
| 39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
| 40 | #include <linux/compat.h> | 40 | #include <linux/compat.h> |
| 41 | #include <linux/blktrace_api.h> | ||
| 42 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
| 43 | #include <asm/io.h> | 42 | #include <asm/io.h> |
| 44 | 43 | ||
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 60de5a01e71e..f703f5478246 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c | |||
| @@ -22,13 +22,12 @@ | |||
| 22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
| 25 | #include <linux/mg_disk.h> | ||
| 25 | 26 | ||
| 26 | #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) | 27 | #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) |
| 27 | 28 | ||
| 28 | /* name for block device */ | 29 | /* name for block device */ |
| 29 | #define MG_DISK_NAME "mgd" | 30 | #define MG_DISK_NAME "mgd" |
| 30 | /* name for platform device */ | ||
| 31 | #define MG_DEV_NAME "mg_disk" | ||
| 32 | 31 | ||
| 33 | #define MG_DISK_MAJ 0 | 32 | #define MG_DISK_MAJ 0 |
| 34 | #define MG_DISK_MAX_PART 16 | 33 | #define MG_DISK_MAX_PART 16 |
| @@ -103,33 +102,8 @@ | |||
| 103 | #define MG_TMAX_SWRST_TO_RDY 500 | 102 | #define MG_TMAX_SWRST_TO_RDY 500 |
| 104 | #define MG_TMAX_RSTOUT 3000 | 103 | #define MG_TMAX_RSTOUT 3000 |
| 105 | 104 | ||
| 106 | /* device attribution */ | ||
| 107 | /* use mflash as boot device */ | ||
| 108 | #define MG_BOOT_DEV (1 << 0) | ||
| 109 | /* use mflash as storage device */ | ||
| 110 | #define MG_STORAGE_DEV (1 << 1) | ||
| 111 | /* same as MG_STORAGE_DEV, but bootloader already done reset sequence */ | ||
| 112 | #define MG_STORAGE_DEV_SKIP_RST (1 << 2) | ||
| 113 | |||
| 114 | #define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST) | 105 | #define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST) |
| 115 | 106 | ||
| 116 | /* names of GPIO resource */ | ||
| 117 | #define MG_RST_PIN "mg_rst" | ||
| 118 | /* except MG_BOOT_DEV, reset-out pin should be assigned */ | ||
| 119 | #define MG_RSTOUT_PIN "mg_rstout" | ||
| 120 | |||
| 121 | /* private driver data */ | ||
| 122 | struct mg_drv_data { | ||
| 123 | /* disk resource */ | ||
| 124 | u32 use_polling; | ||
| 125 | |||
| 126 | /* device attribution */ | ||
| 127 | u32 dev_attr; | ||
| 128 | |||
| 129 | /* internally used */ | ||
| 130 | struct mg_host *host; | ||
| 131 | }; | ||
| 132 | |||
| 133 | /* main structure for mflash driver */ | 107 | /* main structure for mflash driver */ |
| 134 | struct mg_host { | 108 | struct mg_host { |
| 135 | struct device *dev; | 109 | struct device *dev; |
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index aaeeb544228a..34cbb7f3efa8 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c | |||
| @@ -120,7 +120,7 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, | |||
| 120 | static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, | 120 | static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, |
| 121 | struct request *req) | 121 | struct request *req) |
| 122 | { | 122 | { |
| 123 | struct ps3disk_private *priv = dev->sbd.core.driver_data; | 123 | struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 124 | int write = rq_data_dir(req), res; | 124 | int write = rq_data_dir(req), res; |
| 125 | const char *op = write ? "write" : "read"; | 125 | const char *op = write ? "write" : "read"; |
| 126 | u64 start_sector, sectors; | 126 | u64 start_sector, sectors; |
| @@ -168,7 +168,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, | |||
| 168 | static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, | 168 | static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, |
| 169 | struct request *req) | 169 | struct request *req) |
| 170 | { | 170 | { |
| 171 | struct ps3disk_private *priv = dev->sbd.core.driver_data; | 171 | struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 172 | u64 res; | 172 | u64 res; |
| 173 | 173 | ||
| 174 | dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__); | 174 | dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__); |
| @@ -213,7 +213,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev, | |||
| 213 | static void ps3disk_request(struct request_queue *q) | 213 | static void ps3disk_request(struct request_queue *q) |
| 214 | { | 214 | { |
| 215 | struct ps3_storage_device *dev = q->queuedata; | 215 | struct ps3_storage_device *dev = q->queuedata; |
| 216 | struct ps3disk_private *priv = dev->sbd.core.driver_data; | 216 | struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 217 | 217 | ||
| 218 | if (priv->req) { | 218 | if (priv->req) { |
| 219 | dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__); | 219 | dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__); |
| @@ -245,7 +245,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) | |||
| 245 | return IRQ_HANDLED; | 245 | return IRQ_HANDLED; |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | priv = dev->sbd.core.driver_data; | 248 | priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 249 | req = priv->req; | 249 | req = priv->req; |
| 250 | if (!req) { | 250 | if (!req) { |
| 251 | dev_dbg(&dev->sbd.core, | 251 | dev_dbg(&dev->sbd.core, |
| @@ -364,7 +364,7 @@ static void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs, | |||
| 364 | 364 | ||
| 365 | static int ps3disk_identify(struct ps3_storage_device *dev) | 365 | static int ps3disk_identify(struct ps3_storage_device *dev) |
| 366 | { | 366 | { |
| 367 | struct ps3disk_private *priv = dev->sbd.core.driver_data; | 367 | struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 368 | struct lv1_ata_cmnd_block ata_cmnd; | 368 | struct lv1_ata_cmnd_block ata_cmnd; |
| 369 | u16 *id = dev->bounce_buf; | 369 | u16 *id = dev->bounce_buf; |
| 370 | u64 res; | 370 | u64 res; |
| @@ -445,7 +445,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) | |||
| 445 | goto fail; | 445 | goto fail; |
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | dev->sbd.core.driver_data = priv; | 448 | ps3_system_bus_set_drvdata(_dev, priv); |
| 449 | spin_lock_init(&priv->lock); | 449 | spin_lock_init(&priv->lock); |
| 450 | 450 | ||
| 451 | dev->bounce_size = BOUNCE_SIZE; | 451 | dev->bounce_size = BOUNCE_SIZE; |
| @@ -523,7 +523,7 @@ fail_free_bounce: | |||
| 523 | kfree(dev->bounce_buf); | 523 | kfree(dev->bounce_buf); |
| 524 | fail_free_priv: | 524 | fail_free_priv: |
| 525 | kfree(priv); | 525 | kfree(priv); |
| 526 | dev->sbd.core.driver_data = NULL; | 526 | ps3_system_bus_set_drvdata(_dev, NULL); |
| 527 | fail: | 527 | fail: |
| 528 | mutex_lock(&ps3disk_mask_mutex); | 528 | mutex_lock(&ps3disk_mask_mutex); |
| 529 | __clear_bit(devidx, &ps3disk_mask); | 529 | __clear_bit(devidx, &ps3disk_mask); |
| @@ -534,7 +534,7 @@ fail: | |||
| 534 | static int ps3disk_remove(struct ps3_system_bus_device *_dev) | 534 | static int ps3disk_remove(struct ps3_system_bus_device *_dev) |
| 535 | { | 535 | { |
| 536 | struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); | 536 | struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); |
| 537 | struct ps3disk_private *priv = dev->sbd.core.driver_data; | 537 | struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 538 | 538 | ||
| 539 | mutex_lock(&ps3disk_mask_mutex); | 539 | mutex_lock(&ps3disk_mask_mutex); |
| 540 | __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS, | 540 | __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS, |
| @@ -548,7 +548,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev) | |||
| 548 | ps3stor_teardown(dev); | 548 | ps3stor_teardown(dev); |
| 549 | kfree(dev->bounce_buf); | 549 | kfree(dev->bounce_buf); |
| 550 | kfree(priv); | 550 | kfree(priv); |
| 551 | dev->sbd.core.driver_data = NULL; | 551 | ps3_system_bus_set_drvdata(_dev, NULL); |
| 552 | return 0; | 552 | return 0; |
| 553 | } | 553 | } |
| 554 | 554 | ||
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 8eddef373a91..095f97e60665 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c | |||
| @@ -14,8 +14,10 @@ | |||
| 14 | #include <linux/seq_file.h> | 14 | #include <linux/seq_file.h> |
| 15 | 15 | ||
| 16 | #include <asm/firmware.h> | 16 | #include <asm/firmware.h> |
| 17 | #include <asm/iommu.h> | ||
| 17 | #include <asm/lv1call.h> | 18 | #include <asm/lv1call.h> |
| 18 | #include <asm/ps3.h> | 19 | #include <asm/ps3.h> |
| 20 | #include <asm/ps3gpu.h> | ||
| 19 | 21 | ||
| 20 | 22 | ||
| 21 | #define DEVICE_NAME "ps3vram" | 23 | #define DEVICE_NAME "ps3vram" |
| @@ -45,8 +47,6 @@ | |||
| 45 | #define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c | 47 | #define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c |
| 46 | #define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 | 48 | #define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 |
| 47 | 49 | ||
| 48 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 | ||
| 49 | |||
| 50 | #define CACHE_PAGE_PRESENT 1 | 50 | #define CACHE_PAGE_PRESENT 1 |
| 51 | #define CACHE_PAGE_DIRTY 2 | 51 | #define CACHE_PAGE_DIRTY 2 |
| 52 | 52 | ||
| @@ -72,8 +72,7 @@ struct ps3vram_priv { | |||
| 72 | u64 memory_handle; | 72 | u64 memory_handle; |
| 73 | u64 context_handle; | 73 | u64 context_handle; |
| 74 | u32 *ctrl; | 74 | u32 *ctrl; |
| 75 | u32 *reports; | 75 | void *reports; |
| 76 | u8 __iomem *ddr_base; | ||
| 77 | u8 *xdr_buf; | 76 | u8 *xdr_buf; |
| 78 | 77 | ||
| 79 | u32 *fifo_base; | 78 | u32 *fifo_base; |
| @@ -81,8 +80,8 @@ struct ps3vram_priv { | |||
| 81 | 80 | ||
| 82 | struct ps3vram_cache cache; | 81 | struct ps3vram_cache cache; |
| 83 | 82 | ||
| 84 | /* Used to serialize cache/DMA operations */ | 83 | spinlock_t lock; /* protecting list of bios */ |
| 85 | struct mutex lock; | 84 | struct bio_list list; |
| 86 | }; | 85 | }; |
| 87 | 86 | ||
| 88 | 87 | ||
| @@ -103,15 +102,15 @@ static char *size = "256M"; | |||
| 103 | module_param(size, charp, 0); | 102 | module_param(size, charp, 0); |
| 104 | MODULE_PARM_DESC(size, "memory size"); | 103 | MODULE_PARM_DESC(size, "memory size"); |
| 105 | 104 | ||
| 106 | static u32 *ps3vram_get_notifier(u32 *reports, int notifier) | 105 | static u32 *ps3vram_get_notifier(void *reports, int notifier) |
| 107 | { | 106 | { |
| 108 | return (void *)reports + DMA_NOTIFIER_OFFSET_BASE + | 107 | return reports + DMA_NOTIFIER_OFFSET_BASE + |
| 109 | DMA_NOTIFIER_SIZE * notifier; | 108 | DMA_NOTIFIER_SIZE * notifier; |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) | 111 | static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) |
| 113 | { | 112 | { |
| 114 | struct ps3vram_priv *priv = dev->core.driver_data; | 113 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 115 | u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); | 114 | u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); |
| 116 | int i; | 115 | int i; |
| 117 | 116 | ||
| @@ -122,7 +121,7 @@ static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) | |||
| 122 | static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, | 121 | static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, |
| 123 | unsigned int timeout_ms) | 122 | unsigned int timeout_ms) |
| 124 | { | 123 | { |
| 125 | struct ps3vram_priv *priv = dev->core.driver_data; | 124 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 126 | u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); | 125 | u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); |
| 127 | unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); | 126 | unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); |
| 128 | 127 | ||
| @@ -137,7 +136,7 @@ static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, | |||
| 137 | 136 | ||
| 138 | static void ps3vram_init_ring(struct ps3_system_bus_device *dev) | 137 | static void ps3vram_init_ring(struct ps3_system_bus_device *dev) |
| 139 | { | 138 | { |
| 140 | struct ps3vram_priv *priv = dev->core.driver_data; | 139 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 141 | 140 | ||
| 142 | priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; | 141 | priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; |
| 143 | priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; | 142 | priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; |
| @@ -146,7 +145,7 @@ static void ps3vram_init_ring(struct ps3_system_bus_device *dev) | |||
| 146 | static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, | 145 | static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, |
| 147 | unsigned int timeout_ms) | 146 | unsigned int timeout_ms) |
| 148 | { | 147 | { |
| 149 | struct ps3vram_priv *priv = dev->core.driver_data; | 148 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 150 | unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); | 149 | unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); |
| 151 | 150 | ||
| 152 | do { | 151 | do { |
| @@ -175,7 +174,7 @@ static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag, | |||
| 175 | 174 | ||
| 176 | static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) | 175 | static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) |
| 177 | { | 176 | { |
| 178 | struct ps3vram_priv *priv = dev->core.driver_data; | 177 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 179 | int status; | 178 | int status; |
| 180 | 179 | ||
| 181 | ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); | 180 | ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); |
| @@ -183,20 +182,17 @@ static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) | |||
| 183 | priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; | 182 | priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; |
| 184 | 183 | ||
| 185 | /* asking the HV for a blit will kick the FIFO */ | 184 | /* asking the HV for a blit will kick the FIFO */ |
| 186 | status = lv1_gpu_context_attribute(priv->context_handle, | 185 | status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0); |
| 187 | L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, | ||
| 188 | 0, 0, 0); | ||
| 189 | if (status) | 186 | if (status) |
| 190 | dev_err(&dev->core, | 187 | dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n", |
| 191 | "%s: lv1_gpu_context_attribute failed %d\n", __func__, | 188 | __func__, status); |
| 192 | status); | ||
| 193 | 189 | ||
| 194 | priv->fifo_ptr = priv->fifo_base; | 190 | priv->fifo_ptr = priv->fifo_base; |
| 195 | } | 191 | } |
| 196 | 192 | ||
| 197 | static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) | 193 | static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) |
| 198 | { | 194 | { |
| 199 | struct ps3vram_priv *priv = dev->core.driver_data; | 195 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 200 | int status; | 196 | int status; |
| 201 | 197 | ||
| 202 | mutex_lock(&ps3_gpu_mutex); | 198 | mutex_lock(&ps3_gpu_mutex); |
| @@ -205,13 +201,10 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) | |||
| 205 | (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); | 201 | (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); |
| 206 | 202 | ||
| 207 | /* asking the HV for a blit will kick the FIFO */ | 203 | /* asking the HV for a blit will kick the FIFO */ |
| 208 | status = lv1_gpu_context_attribute(priv->context_handle, | 204 | status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0); |
| 209 | L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, | ||
| 210 | 0, 0, 0); | ||
| 211 | if (status) | 205 | if (status) |
| 212 | dev_err(&dev->core, | 206 | dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n", |
| 213 | "%s: lv1_gpu_context_attribute failed %d\n", __func__, | 207 | __func__, status); |
| 214 | status); | ||
| 215 | 208 | ||
| 216 | if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > | 209 | if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > |
| 217 | FIFO_SIZE - 1024) { | 210 | FIFO_SIZE - 1024) { |
| @@ -225,7 +218,7 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) | |||
| 225 | 218 | ||
| 226 | static void ps3vram_bind(struct ps3_system_bus_device *dev) | 219 | static void ps3vram_bind(struct ps3_system_bus_device *dev) |
| 227 | { | 220 | { |
| 228 | struct ps3vram_priv *priv = dev->core.driver_data; | 221 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 229 | 222 | ||
| 230 | ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); | 223 | ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); |
| 231 | ps3vram_out_ring(priv, 0x31337303); | 224 | ps3vram_out_ring(priv, 0x31337303); |
| @@ -248,7 +241,7 @@ static int ps3vram_upload(struct ps3_system_bus_device *dev, | |||
| 248 | unsigned int src_offset, unsigned int dst_offset, | 241 | unsigned int src_offset, unsigned int dst_offset, |
| 249 | int len, int count) | 242 | int len, int count) |
| 250 | { | 243 | { |
| 251 | struct ps3vram_priv *priv = dev->core.driver_data; | 244 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 252 | 245 | ||
| 253 | ps3vram_begin_ring(priv, UPLOAD_SUBCH, | 246 | ps3vram_begin_ring(priv, UPLOAD_SUBCH, |
| 254 | NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); | 247 | NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); |
| @@ -280,7 +273,7 @@ static int ps3vram_download(struct ps3_system_bus_device *dev, | |||
| 280 | unsigned int src_offset, unsigned int dst_offset, | 273 | unsigned int src_offset, unsigned int dst_offset, |
| 281 | int len, int count) | 274 | int len, int count) |
| 282 | { | 275 | { |
| 283 | struct ps3vram_priv *priv = dev->core.driver_data; | 276 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 284 | 277 | ||
| 285 | ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, | 278 | ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, |
| 286 | NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); | 279 | NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); |
| @@ -310,7 +303,7 @@ static int ps3vram_download(struct ps3_system_bus_device *dev, | |||
| 310 | 303 | ||
| 311 | static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) | 304 | static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) |
| 312 | { | 305 | { |
| 313 | struct ps3vram_priv *priv = dev->core.driver_data; | 306 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 314 | struct ps3vram_cache *cache = &priv->cache; | 307 | struct ps3vram_cache *cache = &priv->cache; |
| 315 | 308 | ||
| 316 | if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) | 309 | if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) |
| @@ -332,7 +325,7 @@ static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) | |||
| 332 | static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, | 325 | static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, |
| 333 | unsigned int address) | 326 | unsigned int address) |
| 334 | { | 327 | { |
| 335 | struct ps3vram_priv *priv = dev->core.driver_data; | 328 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 336 | struct ps3vram_cache *cache = &priv->cache; | 329 | struct ps3vram_cache *cache = &priv->cache; |
| 337 | 330 | ||
| 338 | dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); | 331 | dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); |
| @@ -352,7 +345,7 @@ static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, | |||
| 352 | 345 | ||
| 353 | static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) | 346 | static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) |
| 354 | { | 347 | { |
| 355 | struct ps3vram_priv *priv = dev->core.driver_data; | 348 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 356 | struct ps3vram_cache *cache = &priv->cache; | 349 | struct ps3vram_cache *cache = &priv->cache; |
| 357 | int i; | 350 | int i; |
| 358 | 351 | ||
| @@ -366,7 +359,7 @@ static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) | |||
| 366 | static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, | 359 | static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, |
| 367 | loff_t address) | 360 | loff_t address) |
| 368 | { | 361 | { |
| 369 | struct ps3vram_priv *priv = dev->core.driver_data; | 362 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 370 | struct ps3vram_cache *cache = &priv->cache; | 363 | struct ps3vram_cache *cache = &priv->cache; |
| 371 | unsigned int base; | 364 | unsigned int base; |
| 372 | unsigned int offset; | 365 | unsigned int offset; |
| @@ -400,7 +393,7 @@ static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, | |||
| 400 | 393 | ||
| 401 | static int ps3vram_cache_init(struct ps3_system_bus_device *dev) | 394 | static int ps3vram_cache_init(struct ps3_system_bus_device *dev) |
| 402 | { | 395 | { |
| 403 | struct ps3vram_priv *priv = dev->core.driver_data; | 396 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 404 | 397 | ||
| 405 | priv->cache.page_count = CACHE_PAGE_COUNT; | 398 | priv->cache.page_count = CACHE_PAGE_COUNT; |
| 406 | priv->cache.page_size = CACHE_PAGE_SIZE; | 399 | priv->cache.page_size = CACHE_PAGE_SIZE; |
| @@ -419,7 +412,7 @@ static int ps3vram_cache_init(struct ps3_system_bus_device *dev) | |||
| 419 | 412 | ||
| 420 | static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) | 413 | static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) |
| 421 | { | 414 | { |
| 422 | struct ps3vram_priv *priv = dev->core.driver_data; | 415 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 423 | 416 | ||
| 424 | ps3vram_cache_flush(dev); | 417 | ps3vram_cache_flush(dev); |
| 425 | kfree(priv->cache.tags); | 418 | kfree(priv->cache.tags); |
| @@ -428,7 +421,7 @@ static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) | |||
| 428 | static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, | 421 | static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, |
| 429 | size_t len, size_t *retlen, u_char *buf) | 422 | size_t len, size_t *retlen, u_char *buf) |
| 430 | { | 423 | { |
| 431 | struct ps3vram_priv *priv = dev->core.driver_data; | 424 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 432 | unsigned int cached, count; | 425 | unsigned int cached, count; |
| 433 | 426 | ||
| 434 | dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, | 427 | dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, |
| @@ -449,8 +442,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, | |||
| 449 | offset = (unsigned int) (from & (priv->cache.page_size - 1)); | 442 | offset = (unsigned int) (from & (priv->cache.page_size - 1)); |
| 450 | avail = priv->cache.page_size - offset; | 443 | avail = priv->cache.page_size - offset; |
| 451 | 444 | ||
| 452 | mutex_lock(&priv->lock); | ||
| 453 | |||
| 454 | entry = ps3vram_cache_match(dev, from); | 445 | entry = ps3vram_cache_match(dev, from); |
| 455 | cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; | 446 | cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; |
| 456 | 447 | ||
| @@ -462,8 +453,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, | |||
| 462 | avail = count; | 453 | avail = count; |
| 463 | memcpy(buf, priv->xdr_buf + cached, avail); | 454 | memcpy(buf, priv->xdr_buf + cached, avail); |
| 464 | 455 | ||
| 465 | mutex_unlock(&priv->lock); | ||
| 466 | |||
| 467 | buf += avail; | 456 | buf += avail; |
| 468 | count -= avail; | 457 | count -= avail; |
| 469 | from += avail; | 458 | from += avail; |
| @@ -476,7 +465,7 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, | |||
| 476 | static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, | 465 | static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, |
| 477 | size_t len, size_t *retlen, const u_char *buf) | 466 | size_t len, size_t *retlen, const u_char *buf) |
| 478 | { | 467 | { |
| 479 | struct ps3vram_priv *priv = dev->core.driver_data; | 468 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 480 | unsigned int cached, count; | 469 | unsigned int cached, count; |
| 481 | 470 | ||
| 482 | if (to >= priv->size) | 471 | if (to >= priv->size) |
| @@ -494,8 +483,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, | |||
| 494 | offset = (unsigned int) (to & (priv->cache.page_size - 1)); | 483 | offset = (unsigned int) (to & (priv->cache.page_size - 1)); |
| 495 | avail = priv->cache.page_size - offset; | 484 | avail = priv->cache.page_size - offset; |
| 496 | 485 | ||
| 497 | mutex_lock(&priv->lock); | ||
| 498 | |||
| 499 | entry = ps3vram_cache_match(dev, to); | 486 | entry = ps3vram_cache_match(dev, to); |
| 500 | cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; | 487 | cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; |
| 501 | 488 | ||
| @@ -509,8 +496,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, | |||
| 509 | 496 | ||
| 510 | priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; | 497 | priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; |
| 511 | 498 | ||
| 512 | mutex_unlock(&priv->lock); | ||
| 513 | |||
| 514 | buf += avail; | 499 | buf += avail; |
| 515 | count -= avail; | 500 | count -= avail; |
| 516 | to += avail; | 501 | to += avail; |
| @@ -543,28 +528,26 @@ static const struct file_operations ps3vram_proc_fops = { | |||
| 543 | 528 | ||
| 544 | static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) | 529 | static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) |
| 545 | { | 530 | { |
| 546 | struct ps3vram_priv *priv = dev->core.driver_data; | 531 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 547 | struct proc_dir_entry *pde; | 532 | struct proc_dir_entry *pde; |
| 548 | 533 | ||
| 549 | pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops); | 534 | pde = proc_create_data(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops, |
| 550 | if (!pde) { | 535 | priv); |
| 536 | if (!pde) | ||
| 551 | dev_warn(&dev->core, "failed to create /proc entry\n"); | 537 | dev_warn(&dev->core, "failed to create /proc entry\n"); |
| 552 | return; | ||
| 553 | } | ||
| 554 | pde->data = priv; | ||
| 555 | } | 538 | } |
| 556 | 539 | ||
| 557 | static int ps3vram_make_request(struct request_queue *q, struct bio *bio) | 540 | static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev, |
| 541 | struct bio *bio) | ||
| 558 | { | 542 | { |
| 559 | struct ps3_system_bus_device *dev = q->queuedata; | 543 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 560 | int write = bio_data_dir(bio) == WRITE; | 544 | int write = bio_data_dir(bio) == WRITE; |
| 561 | const char *op = write ? "write" : "read"; | 545 | const char *op = write ? "write" : "read"; |
| 562 | loff_t offset = bio->bi_sector << 9; | 546 | loff_t offset = bio->bi_sector << 9; |
| 563 | int error = 0; | 547 | int error = 0; |
| 564 | struct bio_vec *bvec; | 548 | struct bio_vec *bvec; |
| 565 | unsigned int i; | 549 | unsigned int i; |
| 566 | 550 | struct bio *next; | |
| 567 | dev_dbg(&dev->core, "%s\n", __func__); | ||
| 568 | 551 | ||
| 569 | bio_for_each_segment(bvec, bio, i) { | 552 | bio_for_each_segment(bvec, bio, i) { |
| 570 | /* PS3 is ppc64, so we don't handle highmem */ | 553 | /* PS3 is ppc64, so we don't handle highmem */ |
| @@ -585,6 +568,7 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio) | |||
| 585 | 568 | ||
| 586 | if (retlen != len) { | 569 | if (retlen != len) { |
| 587 | dev_err(&dev->core, "Short %s\n", op); | 570 | dev_err(&dev->core, "Short %s\n", op); |
| 571 | error = -EIO; | ||
| 588 | goto out; | 572 | goto out; |
| 589 | } | 573 | } |
| 590 | 574 | ||
| @@ -594,7 +578,35 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio) | |||
| 594 | dev_dbg(&dev->core, "%s completed\n", op); | 578 | dev_dbg(&dev->core, "%s completed\n", op); |
| 595 | 579 | ||
| 596 | out: | 580 | out: |
| 581 | spin_lock_irq(&priv->lock); | ||
| 582 | bio_list_pop(&priv->list); | ||
| 583 | next = bio_list_peek(&priv->list); | ||
| 584 | spin_unlock_irq(&priv->lock); | ||
| 585 | |||
| 597 | bio_endio(bio, error); | 586 | bio_endio(bio, error); |
| 587 | return next; | ||
| 588 | } | ||
| 589 | |||
| 590 | static int ps3vram_make_request(struct request_queue *q, struct bio *bio) | ||
| 591 | { | ||
| 592 | struct ps3_system_bus_device *dev = q->queuedata; | ||
| 593 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); | ||
| 594 | int busy; | ||
| 595 | |||
| 596 | dev_dbg(&dev->core, "%s\n", __func__); | ||
| 597 | |||
| 598 | spin_lock_irq(&priv->lock); | ||
| 599 | busy = !bio_list_empty(&priv->list); | ||
| 600 | bio_list_add(&priv->list, bio); | ||
| 601 | spin_unlock_irq(&priv->lock); | ||
| 602 | |||
| 603 | if (busy) | ||
| 604 | return 0; | ||
| 605 | |||
| 606 | do { | ||
| 607 | bio = ps3vram_do_bio(dev, bio); | ||
| 608 | } while (bio); | ||
| 609 | |||
| 598 | return 0; | 610 | return 0; |
| 599 | } | 611 | } |
| 600 | 612 | ||
| @@ -604,8 +616,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) | |||
| 604 | int error, status; | 616 | int error, status; |
| 605 | struct request_queue *queue; | 617 | struct request_queue *queue; |
| 606 | struct gendisk *gendisk; | 618 | struct gendisk *gendisk; |
| 607 | u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size, | 619 | u64 ddr_size, ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, |
| 608 | reports_size; | 620 | reports_size, xdr_lpar; |
| 609 | char *rest; | 621 | char *rest; |
| 610 | 622 | ||
| 611 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 623 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| @@ -614,10 +626,9 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) | |||
| 614 | goto fail; | 626 | goto fail; |
| 615 | } | 627 | } |
| 616 | 628 | ||
| 617 | mutex_init(&priv->lock); | 629 | spin_lock_init(&priv->lock); |
| 618 | dev->core.driver_data = priv; | 630 | bio_list_init(&priv->list); |
| 619 | 631 | ps3_system_bus_set_drvdata(dev, priv); | |
| 620 | priv = dev->core.driver_data; | ||
| 621 | 632 | ||
| 622 | /* Allocate XDR buffer (1MiB aligned) */ | 633 | /* Allocate XDR buffer (1MiB aligned) */ |
| 623 | priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, | 634 | priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, |
| @@ -636,7 +647,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) | |||
| 636 | if (ps3_open_hv_device(dev)) { | 647 | if (ps3_open_hv_device(dev)) { |
| 637 | dev_err(&dev->core, "ps3_open_hv_device failed\n"); | 648 | dev_err(&dev->core, "ps3_open_hv_device failed\n"); |
| 638 | error = -EAGAIN; | 649 | error = -EAGAIN; |
| 639 | goto out_close_gpu; | 650 | goto out_free_xdr_buf; |
| 640 | } | 651 | } |
| 641 | 652 | ||
| 642 | /* Request memory */ | 653 | /* Request memory */ |
| @@ -660,7 +671,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) | |||
| 660 | dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", | 671 | dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", |
| 661 | status); | 672 | status); |
| 662 | error = -ENOMEM; | 673 | error = -ENOMEM; |
| 663 | goto out_free_xdr_buf; | 674 | goto out_close_gpu; |
| 664 | } | 675 | } |
| 665 | 676 | ||
| 666 | /* Request context */ | 677 | /* Request context */ |
| @@ -676,9 +687,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) | |||
| 676 | } | 687 | } |
| 677 | 688 | ||
| 678 | /* Map XDR buffer to RSX */ | 689 | /* Map XDR buffer to RSX */ |
| 690 | xdr_lpar = ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)); | ||
| 679 | status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, | 691 | status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, |
| 680 | ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), | 692 | xdr_lpar, XDR_BUF_SIZE, |
| 681 | XDR_BUF_SIZE, 0); | 693 | CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | |
| 694 | CBE_IOPTE_M); | ||
| 682 | if (status) { | 695 | if (status) { |
| 683 | dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", | 696 | dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", |
| 684 | status); | 697 | status); |
| @@ -686,19 +699,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) | |||
| 686 | goto out_free_context; | 699 | goto out_free_context; |
| 687 | } | 700 | } |
| 688 | 701 | ||
| 689 | priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); | ||
| 690 | |||
| 691 | if (!priv->ddr_base) { | ||
| 692 | dev_err(&dev->core, "ioremap DDR failed\n"); | ||
| 693 | error = -ENOMEM; | ||
| 694 | goto out_free_context; | ||
| 695 | } | ||
| 696 | |||
| 697 | priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); | 702 | priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); |
| 698 | if (!priv->ctrl) { | 703 | if (!priv->ctrl) { |
| 699 | dev_err(&dev->core, "ioremap CTRL failed\n"); | 704 | dev_err(&dev->core, "ioremap CTRL failed\n"); |
| 700 | error = -ENOMEM; | 705 | error = -ENOMEM; |
| 701 | goto out_unmap_vram; | 706 | goto out_unmap_context; |
| 702 | } | 707 | } |
| 703 | 708 | ||
| 704 | priv->reports = ioremap(reports_lpar, reports_size); | 709 | priv->reports = ioremap(reports_lpar, reports_size); |
| @@ -775,8 +780,9 @@ out_unmap_reports: | |||
| 775 | iounmap(priv->reports); | 780 | iounmap(priv->reports); |
| 776 | out_unmap_ctrl: | 781 | out_unmap_ctrl: |
| 777 | iounmap(priv->ctrl); | 782 | iounmap(priv->ctrl); |
| 778 | out_unmap_vram: | 783 | out_unmap_context: |
| 779 | iounmap(priv->ddr_base); | 784 | lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, xdr_lpar, |
| 785 | XDR_BUF_SIZE, CBE_IOPTE_M); | ||
| 780 | out_free_context: | 786 | out_free_context: |
| 781 | lv1_gpu_context_free(priv->context_handle); | 787 | lv1_gpu_context_free(priv->context_handle); |
| 782 | out_free_memory: | 788 | out_free_memory: |
| @@ -787,14 +793,14 @@ out_free_xdr_buf: | |||
| 787 | free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); | 793 | free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); |
| 788 | fail_free_priv: | 794 | fail_free_priv: |
| 789 | kfree(priv); | 795 | kfree(priv); |
| 790 | dev->core.driver_data = NULL; | 796 | ps3_system_bus_set_drvdata(dev, NULL); |
| 791 | fail: | 797 | fail: |
| 792 | return error; | 798 | return error; |
| 793 | } | 799 | } |
| 794 | 800 | ||
| 795 | static int ps3vram_remove(struct ps3_system_bus_device *dev) | 801 | static int ps3vram_remove(struct ps3_system_bus_device *dev) |
| 796 | { | 802 | { |
| 797 | struct ps3vram_priv *priv = dev->core.driver_data; | 803 | struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); |
| 798 | 804 | ||
| 799 | del_gendisk(priv->gendisk); | 805 | del_gendisk(priv->gendisk); |
| 800 | put_disk(priv->gendisk); | 806 | put_disk(priv->gendisk); |
| @@ -803,13 +809,15 @@ static int ps3vram_remove(struct ps3_system_bus_device *dev) | |||
| 803 | ps3vram_cache_cleanup(dev); | 809 | ps3vram_cache_cleanup(dev); |
| 804 | iounmap(priv->reports); | 810 | iounmap(priv->reports); |
| 805 | iounmap(priv->ctrl); | 811 | iounmap(priv->ctrl); |
| 806 | iounmap(priv->ddr_base); | 812 | lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, |
| 813 | ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), | ||
| 814 | XDR_BUF_SIZE, CBE_IOPTE_M); | ||
| 807 | lv1_gpu_context_free(priv->context_handle); | 815 | lv1_gpu_context_free(priv->context_handle); |
| 808 | lv1_gpu_memory_free(priv->memory_handle); | 816 | lv1_gpu_memory_free(priv->memory_handle); |
| 809 | ps3_close_hv_device(dev); | 817 | ps3_close_hv_device(dev); |
| 810 | free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); | 818 | free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); |
| 811 | kfree(priv); | 819 | kfree(priv); |
| 812 | dev->core.driver_data = NULL; | 820 | ps3_system_bus_set_drvdata(dev, NULL); |
| 813 | return 0; | 821 | return 0; |
| 814 | } | 822 | } |
| 815 | 823 | ||
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index afbe45676d71..f424d394a286 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c | |||
| @@ -33,48 +33,64 @@ | |||
| 33 | 33 | ||
| 34 | struct ps3flash_private { | 34 | struct ps3flash_private { |
| 35 | struct mutex mutex; /* Bounce buffer mutex */ | 35 | struct mutex mutex; /* Bounce buffer mutex */ |
| 36 | u64 chunk_sectors; | ||
| 37 | int tag; /* Start sector of buffer, -1 if invalid */ | ||
| 38 | bool dirty; | ||
| 36 | }; | 39 | }; |
| 37 | 40 | ||
| 38 | static struct ps3_storage_device *ps3flash_dev; | 41 | static struct ps3_storage_device *ps3flash_dev; |
| 39 | 42 | ||
| 40 | static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, | 43 | static int ps3flash_read_write_sectors(struct ps3_storage_device *dev, |
| 41 | u64 lpar, u64 start_sector, | 44 | u64 start_sector, int write) |
| 42 | u64 sectors, int write) | ||
| 43 | { | 45 | { |
| 44 | u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, | 46 | struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 47 | u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, | ||
| 48 | start_sector, priv->chunk_sectors, | ||
| 45 | write); | 49 | write); |
| 46 | if (res) { | 50 | if (res) { |
| 47 | dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, | 51 | dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, |
| 48 | __LINE__, write ? "write" : "read", res); | 52 | __LINE__, write ? "write" : "read", res); |
| 49 | return -EIO; | 53 | return -EIO; |
| 50 | } | 54 | } |
| 51 | return sectors; | 55 | return 0; |
| 52 | } | 56 | } |
| 53 | 57 | ||
| 54 | static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, | 58 | static int ps3flash_writeback(struct ps3_storage_device *dev) |
| 55 | u64 start_sector, u64 sectors, | ||
| 56 | unsigned int sector_offset) | ||
| 57 | { | 59 | { |
| 58 | u64 max_sectors, lpar; | 60 | struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 61 | int res; | ||
| 59 | 62 | ||
| 60 | max_sectors = dev->bounce_size / dev->blk_size; | 63 | if (!priv->dirty || priv->tag < 0) |
| 61 | if (sectors > max_sectors) { | 64 | return 0; |
| 62 | dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %llu\n", | ||
| 63 | __func__, __LINE__, max_sectors); | ||
| 64 | sectors = max_sectors; | ||
| 65 | } | ||
| 66 | 65 | ||
| 67 | lpar = dev->bounce_lpar + sector_offset * dev->blk_size; | 66 | res = ps3flash_read_write_sectors(dev, priv->tag, 1); |
| 68 | return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, | 67 | if (res) |
| 69 | 0); | 68 | return res; |
| 69 | |||
| 70 | priv->dirty = false; | ||
| 71 | return 0; | ||
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev, | 74 | static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector) |
| 73 | u64 start_sector) | ||
| 74 | { | 75 | { |
| 75 | u64 sectors = dev->bounce_size / dev->blk_size; | 76 | struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 76 | return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector, | 77 | int res; |
| 77 | sectors, 1); | 78 | |
| 79 | if (start_sector == priv->tag) | ||
| 80 | return 0; | ||
| 81 | |||
| 82 | res = ps3flash_writeback(dev); | ||
| 83 | if (res) | ||
| 84 | return res; | ||
| 85 | |||
| 86 | priv->tag = -1; | ||
| 87 | |||
| 88 | res = ps3flash_read_write_sectors(dev, start_sector, 0); | ||
| 89 | if (res) | ||
| 90 | return res; | ||
| 91 | |||
| 92 | priv->tag = start_sector; | ||
| 93 | return 0; | ||
| 78 | } | 94 | } |
| 79 | 95 | ||
| 80 | static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) | 96 | static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) |
| @@ -104,18 +120,19 @@ out: | |||
| 104 | return res; | 120 | return res; |
| 105 | } | 121 | } |
| 106 | 122 | ||
| 107 | static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, | 123 | static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, |
| 108 | loff_t *pos) | 124 | size_t count, loff_t *pos) |
| 109 | { | 125 | { |
| 110 | struct ps3_storage_device *dev = ps3flash_dev; | 126 | struct ps3_storage_device *dev = ps3flash_dev; |
| 111 | struct ps3flash_private *priv = dev->sbd.core.driver_data; | 127 | struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 112 | u64 size, start_sector, end_sector, offset; | 128 | u64 size, sector, offset; |
| 113 | ssize_t sectors_read; | 129 | int res; |
| 114 | size_t remaining, n; | 130 | size_t remaining, n; |
| 131 | const void *src; | ||
| 115 | 132 | ||
| 116 | dev_dbg(&dev->sbd.core, | 133 | dev_dbg(&dev->sbd.core, |
| 117 | "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n", | 134 | "%s:%u: Reading %zu bytes at position %lld to U0x%p/K0x%p\n", |
| 118 | __func__, __LINE__, count, *pos, buf); | 135 | __func__, __LINE__, count, *pos, userbuf, kernelbuf); |
| 119 | 136 | ||
| 120 | size = dev->regions[dev->region_idx].size*dev->blk_size; | 137 | size = dev->regions[dev->region_idx].size*dev->blk_size; |
| 121 | if (*pos >= size || !count) | 138 | if (*pos >= size || !count) |
| @@ -128,61 +145,63 @@ static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, | |||
| 128 | count = size - *pos; | 145 | count = size - *pos; |
| 129 | } | 146 | } |
| 130 | 147 | ||
| 131 | start_sector = *pos / dev->blk_size; | 148 | sector = *pos / dev->bounce_size * priv->chunk_sectors; |
| 132 | offset = *pos % dev->blk_size; | 149 | offset = *pos % dev->bounce_size; |
| 133 | end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size); | ||
| 134 | 150 | ||
| 135 | remaining = count; | 151 | remaining = count; |
| 136 | do { | 152 | do { |
| 153 | n = min_t(u64, remaining, dev->bounce_size - offset); | ||
| 154 | src = dev->bounce_buf + offset; | ||
| 155 | |||
| 137 | mutex_lock(&priv->mutex); | 156 | mutex_lock(&priv->mutex); |
| 138 | 157 | ||
| 139 | sectors_read = ps3flash_read_sectors(dev, start_sector, | 158 | res = ps3flash_fetch(dev, sector); |
| 140 | end_sector-start_sector, | 159 | if (res) |
| 141 | 0); | ||
| 142 | if (sectors_read < 0) { | ||
| 143 | mutex_unlock(&priv->mutex); | ||
| 144 | goto fail; | 160 | goto fail; |
| 145 | } | ||
| 146 | 161 | ||
| 147 | n = min_t(u64, remaining, sectors_read*dev->blk_size-offset); | ||
| 148 | dev_dbg(&dev->sbd.core, | 162 | dev_dbg(&dev->sbd.core, |
| 149 | "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", | 163 | "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n", |
| 150 | __func__, __LINE__, n, dev->bounce_buf+offset, buf); | 164 | __func__, __LINE__, n, src, userbuf, kernelbuf); |
| 151 | if (copy_to_user(buf, dev->bounce_buf+offset, n)) { | 165 | if (userbuf) { |
| 152 | mutex_unlock(&priv->mutex); | 166 | if (copy_to_user(userbuf, src, n)) { |
| 153 | sectors_read = -EFAULT; | 167 | res = -EFAULT; |
| 154 | goto fail; | 168 | goto fail; |
| 169 | } | ||
| 170 | userbuf += n; | ||
| 171 | } | ||
| 172 | if (kernelbuf) { | ||
| 173 | memcpy(kernelbuf, src, n); | ||
| 174 | kernelbuf += n; | ||
| 155 | } | 175 | } |
| 156 | 176 | ||
| 157 | mutex_unlock(&priv->mutex); | 177 | mutex_unlock(&priv->mutex); |
| 158 | 178 | ||
| 159 | *pos += n; | 179 | *pos += n; |
| 160 | buf += n; | ||
| 161 | remaining -= n; | 180 | remaining -= n; |
| 162 | start_sector += sectors_read; | 181 | sector += priv->chunk_sectors; |
| 163 | offset = 0; | 182 | offset = 0; |
| 164 | } while (remaining > 0); | 183 | } while (remaining > 0); |
| 165 | 184 | ||
| 166 | return count; | 185 | return count; |
| 167 | 186 | ||
| 168 | fail: | 187 | fail: |
| 169 | return sectors_read; | 188 | mutex_unlock(&priv->mutex); |
| 189 | return res; | ||
| 170 | } | 190 | } |
| 171 | 191 | ||
| 172 | static ssize_t ps3flash_write(struct file *file, const char __user *buf, | 192 | static ssize_t ps3flash_write(const char __user *userbuf, |
| 173 | size_t count, loff_t *pos) | 193 | const void *kernelbuf, size_t count, loff_t *pos) |
| 174 | { | 194 | { |
| 175 | struct ps3_storage_device *dev = ps3flash_dev; | 195 | struct ps3_storage_device *dev = ps3flash_dev; |
| 176 | struct ps3flash_private *priv = dev->sbd.core.driver_data; | 196 | struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); |
| 177 | u64 size, chunk_sectors, start_write_sector, end_write_sector, | 197 | u64 size, sector, offset; |
| 178 | end_read_sector, start_read_sector, head, tail, offset; | 198 | int res = 0; |
| 179 | ssize_t res; | ||
| 180 | size_t remaining, n; | 199 | size_t remaining, n; |
| 181 | unsigned int sec_off; | 200 | void *dst; |
| 182 | 201 | ||
| 183 | dev_dbg(&dev->sbd.core, | 202 | dev_dbg(&dev->sbd.core, |
| 184 | "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n", | 203 | "%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n", |
| 185 | __func__, __LINE__, count, *pos, buf); | 204 | __func__, __LINE__, count, *pos, userbuf, kernelbuf); |
| 186 | 205 | ||
| 187 | size = dev->regions[dev->region_idx].size*dev->blk_size; | 206 | size = dev->regions[dev->region_idx].size*dev->blk_size; |
| 188 | if (*pos >= size || !count) | 207 | if (*pos >= size || !count) |
| @@ -195,89 +214,46 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf, | |||
| 195 | count = size - *pos; | 214 | count = size - *pos; |
| 196 | } | 215 | } |
| 197 | 216 | ||
| 198 | chunk_sectors = dev->bounce_size / dev->blk_size; | 217 | sector = *pos / dev->bounce_size * priv->chunk_sectors; |
| 199 | |||
| 200 | start_write_sector = *pos / dev->bounce_size * chunk_sectors; | ||
| 201 | offset = *pos % dev->bounce_size; | 218 | offset = *pos % dev->bounce_size; |
| 202 | end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) * | ||
| 203 | chunk_sectors; | ||
| 204 | |||
| 205 | end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size); | ||
| 206 | start_read_sector = (*pos + count) / dev->blk_size; | ||
| 207 | |||
| 208 | /* | ||
| 209 | * As we have to write in 256 KiB chunks, while we can read in blk_size | ||
| 210 | * (usually 512 bytes) chunks, we perform the following steps: | ||
| 211 | * 1. Read from start_write_sector to end_read_sector ("head") | ||
| 212 | * 2. Read from start_read_sector to end_write_sector ("tail") | ||
| 213 | * 3. Copy data to buffer | ||
| 214 | * 4. Write from start_write_sector to end_write_sector | ||
| 215 | * All of this is complicated by using only one 256 KiB bounce buffer. | ||
| 216 | */ | ||
| 217 | |||
| 218 | head = end_read_sector - start_write_sector; | ||
| 219 | tail = end_write_sector - start_read_sector; | ||
| 220 | 219 | ||
| 221 | remaining = count; | 220 | remaining = count; |
| 222 | do { | 221 | do { |
| 222 | n = min_t(u64, remaining, dev->bounce_size - offset); | ||
| 223 | dst = dev->bounce_buf + offset; | ||
| 224 | |||
| 223 | mutex_lock(&priv->mutex); | 225 | mutex_lock(&priv->mutex); |
| 224 | 226 | ||
| 225 | if (end_read_sector >= start_read_sector) { | 227 | if (n != dev->bounce_size) |
| 226 | /* Merge head and tail */ | 228 | res = ps3flash_fetch(dev, sector); |
| 227 | dev_dbg(&dev->sbd.core, | 229 | else if (sector != priv->tag) |
| 228 | "Merged head and tail: %llu sectors at %llu\n", | 230 | res = ps3flash_writeback(dev); |
| 229 | chunk_sectors, start_write_sector); | 231 | if (res) |
| 230 | res = ps3flash_read_sectors(dev, start_write_sector, | 232 | goto fail; |
| 231 | chunk_sectors, 0); | 233 | |
| 232 | if (res < 0) | 234 | dev_dbg(&dev->sbd.core, |
| 235 | "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n", | ||
| 236 | __func__, __LINE__, n, userbuf, kernelbuf, dst); | ||
| 237 | if (userbuf) { | ||
| 238 | if (copy_from_user(dst, userbuf, n)) { | ||
| 239 | res = -EFAULT; | ||
| 233 | goto fail; | 240 | goto fail; |
| 234 | } else { | ||
| 235 | if (head) { | ||
| 236 | /* Read head */ | ||
| 237 | dev_dbg(&dev->sbd.core, | ||
| 238 | "head: %llu sectors at %llu\n", head, | ||
| 239 | start_write_sector); | ||
| 240 | res = ps3flash_read_sectors(dev, | ||
| 241 | start_write_sector, | ||
| 242 | head, 0); | ||
| 243 | if (res < 0) | ||
| 244 | goto fail; | ||
| 245 | } | ||
| 246 | if (start_read_sector < | ||
| 247 | start_write_sector+chunk_sectors) { | ||
| 248 | /* Read tail */ | ||
| 249 | dev_dbg(&dev->sbd.core, | ||
| 250 | "tail: %llu sectors at %llu\n", tail, | ||
| 251 | start_read_sector); | ||
| 252 | sec_off = start_read_sector-start_write_sector; | ||
| 253 | res = ps3flash_read_sectors(dev, | ||
| 254 | start_read_sector, | ||
| 255 | tail, sec_off); | ||
| 256 | if (res < 0) | ||
| 257 | goto fail; | ||
| 258 | } | 241 | } |
| 242 | userbuf += n; | ||
| 259 | } | 243 | } |
| 260 | 244 | if (kernelbuf) { | |
| 261 | n = min_t(u64, remaining, dev->bounce_size-offset); | 245 | memcpy(dst, kernelbuf, n); |
| 262 | dev_dbg(&dev->sbd.core, | 246 | kernelbuf += n; |
| 263 | "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n", | ||
| 264 | __func__, __LINE__, n, buf, dev->bounce_buf+offset); | ||
| 265 | if (copy_from_user(dev->bounce_buf+offset, buf, n)) { | ||
| 266 | res = -EFAULT; | ||
| 267 | goto fail; | ||
| 268 | } | 247 | } |
| 269 | 248 | ||
| 270 | res = ps3flash_write_chunk(dev, start_write_sector); | 249 | priv->tag = sector; |
| 271 | if (res < 0) | 250 | priv->dirty = true; |
| 272 | goto fail; | ||
| 273 | 251 | ||
| 274 | mutex_unlock(&priv->mutex); | 252 | mutex_unlock(&priv->mutex); |
| 275 | 253 | ||
| 276 | *pos += n; | 254 | *pos += n; |
| 277 | buf += n; | ||
| 278 | remaining -= n; | 255 | remaining -= n; |
| 279 | start_write_sector += chunk_sectors; | 256 | sector += priv->chunk_sectors; |
| 280 | head = 0; | ||
| 281 | offset = 0; | 257 | offset = 0; |
| 282 | } while (remaining > 0); | 258 | } while (remaining > 0); |
| 283 | 259 | ||
| @@ -288,6 +264,51 @@ fail: | |||
| 288 | return res; | 264 | return res; |
| 289 | } | 265 | } |
| 290 | 266 | ||
| 267 | static ssize_t ps3flash_user_read(struct file *file, char __user *buf, | ||
| 268 | size_t count, loff_t *pos) | ||
| 269 | { | ||
| 270 | return ps3flash_read(buf, NULL, count, pos); | ||
| 271 | } | ||
| 272 | |||
| 273 | static ssize_t ps3flash_user_write(struct file *file, const char __user *buf, | ||
| 274 | size_t count, loff_t *pos) | ||
| 275 | { | ||
| 276 | return ps3flash_write(buf, NULL, count, pos); | ||
| 277 | } | ||
| 278 | |||
| 279 | static ssize_t ps3flash_kernel_read(void *buf, size_t count, loff_t pos) | ||
| 280 | { | ||
| 281 | return ps3flash_read(NULL, buf, count, &pos); | ||
| 282 | } | ||
| 283 | |||
| 284 | static ssize_t ps3flash_kernel_write(const void *buf, size_t count, | ||
| 285 | loff_t pos) | ||
| 286 | { | ||
| 287 | ssize_t res; | ||
| 288 | int wb; | ||
| 289 | |||
| 290 | res = ps3flash_write(NULL, buf, count, &pos); | ||
| 291 | if (res < 0) | ||
| 292 | return res; | ||
| 293 | |||
| 294 | /* Make kernel writes synchronous */ | ||
| 295 | wb = ps3flash_writeback(ps3flash_dev); | ||
| 296 | if (wb) | ||
| 297 | return wb; | ||
| 298 | |||
| 299 | return res; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int ps3flash_flush(struct file *file, fl_owner_t id) | ||
| 303 | { | ||
| 304 | return ps3flash_writeback(ps3flash_dev); | ||
| 305 | } | ||
| 306 | |||
| 307 | static int ps3flash_fsync(struct file *file, struct dentry *dentry, | ||
| 308 | int datasync) | ||
| 309 | { | ||
| 310 | return ps3flash_writeback(ps3flash_dev); | ||
| 311 | } | ||
| 291 | 312 | ||
| 292 | static irqreturn_t ps3flash_interrupt(int irq, void *data) | 313 | static irqreturn_t ps3flash_interrupt(int irq, void *data) |
| 293 | { | 314 | { |
| @@ -312,12 +333,18 @@ static irqreturn_t ps3flash_interrupt(int irq, void *data) | |||
| 312 | return IRQ_HANDLED; | 333 | return IRQ_HANDLED; |
| 313 | } | 334 | } |
| 314 | 335 | ||
| 315 | |||
| 316 | static const struct file_operations ps3flash_fops = { | 336 | static const struct file_operations ps3flash_fops = { |
| 317 | .owner = THIS_MODULE, | 337 | .owner = THIS_MODULE, |
| 318 | .llseek = ps3flash_llseek, | 338 | .llseek = ps3flash_llseek, |
| 319 | .read = ps3flash_read, | 339 | .read = ps3flash_user_read, |
| 320 | .write = ps3flash_write, | 340 | .write = ps3flash_user_write, |
| 341 | .flush = ps3flash_flush, | ||
| 342 | .fsync = ps3flash_fsync, | ||
| 343 | }; | ||
| 344 | |||
| 345 | static const struct ps3_os_area_flash_ops ps3flash_kernel_ops = { | ||
| 346 | .read = ps3flash_kernel_read, | ||
| 347 | .write = ps3flash_kernel_write, | ||
| 321 | }; | 348 | }; |
| 322 | 349 | ||
| 323 | static struct miscdevice ps3flash_misc = { | 350 | static struct miscdevice ps3flash_misc = { |
| @@ -366,11 +393,13 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) | |||
| 366 | goto fail; | 393 | goto fail; |
| 367 | } | 394 | } |
| 368 | 395 | ||
| 369 | dev->sbd.core.driver_data = priv; | 396 | ps3_system_bus_set_drvdata(&dev->sbd, priv); |
| 370 | mutex_init(&priv->mutex); | 397 | mutex_init(&priv->mutex); |
| 398 | priv->tag = -1; | ||
| 371 | 399 | ||
| 372 | dev->bounce_size = ps3flash_bounce_buffer.size; | 400 | dev->bounce_size = ps3flash_bounce_buffer.size; |
| 373 | dev->bounce_buf = ps3flash_bounce_buffer.address; | 401 | dev->bounce_buf = ps3flash_bounce_buffer.address; |
| 402 | priv->chunk_sectors = dev->bounce_size / dev->blk_size; | ||
| 374 | 403 | ||
| 375 | error = ps3stor_setup(dev, ps3flash_interrupt); | 404 | error = ps3stor_setup(dev, ps3flash_interrupt); |
| 376 | if (error) | 405 | if (error) |
| @@ -386,13 +415,15 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) | |||
| 386 | 415 | ||
| 387 | dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", | 416 | dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", |
| 388 | __func__, __LINE__, ps3flash_misc.minor); | 417 | __func__, __LINE__, ps3flash_misc.minor); |
| 418 | |||
| 419 | ps3_os_area_flash_register(&ps3flash_kernel_ops); | ||
| 389 | return 0; | 420 | return 0; |
| 390 | 421 | ||
| 391 | fail_teardown: | 422 | fail_teardown: |
| 392 | ps3stor_teardown(dev); | 423 | ps3stor_teardown(dev); |
| 393 | fail_free_priv: | 424 | fail_free_priv: |
| 394 | kfree(priv); | 425 | kfree(priv); |
| 395 | dev->sbd.core.driver_data = NULL; | 426 | ps3_system_bus_set_drvdata(&dev->sbd, NULL); |
| 396 | fail: | 427 | fail: |
| 397 | ps3flash_dev = NULL; | 428 | ps3flash_dev = NULL; |
| 398 | return error; | 429 | return error; |
| @@ -402,10 +433,11 @@ static int ps3flash_remove(struct ps3_system_bus_device *_dev) | |||
| 402 | { | 433 | { |
| 403 | struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); | 434 | struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); |
| 404 | 435 | ||
| 436 | ps3_os_area_flash_register(NULL); | ||
| 405 | misc_deregister(&ps3flash_misc); | 437 | misc_deregister(&ps3flash_misc); |
| 406 | ps3stor_teardown(dev); | 438 | ps3stor_teardown(dev); |
| 407 | kfree(dev->sbd.core.driver_data); | 439 | kfree(ps3_system_bus_get_drvdata(&dev->sbd)); |
| 408 | dev->sbd.core.driver_data = NULL; | 440 | ps3_system_bus_set_drvdata(&dev->sbd, NULL); |
| 409 | ps3flash_dev = NULL; | 441 | ps3flash_dev = NULL; |
| 410 | return 0; | 442 | return 0; |
| 411 | } | 443 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 5acd29e6e043..3910ce112a95 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
| @@ -104,7 +104,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, | |||
| 104 | struct tty_struct *to = tty->link; | 104 | struct tty_struct *to = tty->link; |
| 105 | int c; | 105 | int c; |
| 106 | 106 | ||
| 107 | if (!to || tty->stopped) | 107 | if (!to || !to->ldisc || tty->stopped) |
| 108 | return 0; | 108 | return 0; |
| 109 | 109 | ||
| 110 | c = to->receive_room; | 110 | c = to->receive_room; |
| @@ -148,7 +148,7 @@ static int pty_chars_in_buffer(struct tty_struct *tty) | |||
| 148 | int count; | 148 | int count; |
| 149 | 149 | ||
| 150 | /* We should get the line discipline lock for "tty->link" */ | 150 | /* We should get the line discipline lock for "tty->link" */ |
| 151 | if (!to || !to->ldisc->ops->chars_in_buffer) | 151 | if (!to || !to->ldisc || !to->ldisc->ops->chars_in_buffer) |
| 152 | return 0; | 152 | return 0; |
| 153 | 153 | ||
| 154 | /* The ldisc must report 0 if no characters available to be read */ | 154 | /* The ldisc must report 0 if no characters available to be read */ |
| @@ -183,7 +183,7 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
| 183 | struct tty_struct *to = tty->link; | 183 | struct tty_struct *to = tty->link; |
| 184 | unsigned long flags; | 184 | unsigned long flags; |
| 185 | 185 | ||
| 186 | if (!to) | 186 | if (!to || !to->ldisc) |
| 187 | return; | 187 | return; |
| 188 | 188 | ||
| 189 | if (to->ldisc->ops->flush_buffer) | 189 | if (to->ldisc->ops->flush_buffer) |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 39c8f86dedd4..94b3e06d73ec 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
| @@ -148,8 +148,10 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc) | |||
| 148 | } | 148 | } |
| 149 | } | 149 | } |
| 150 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 150 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
| 151 | if (err) | 151 | if (err) { |
| 152 | kfree(ld); | ||
| 152 | return ERR_PTR(err); | 153 | return ERR_PTR(err); |
| 154 | } | ||
| 153 | return ld; | 155 | return ld; |
| 154 | } | 156 | } |
| 155 | 157 | ||
| @@ -262,7 +264,7 @@ const struct file_operations tty_ldiscs_proc_fops = { | |||
| 262 | * @ld: line discipline | 264 | * @ld: line discipline |
| 263 | * | 265 | * |
| 264 | * Install an instance of a line discipline into a tty structure. The | 266 | * Install an instance of a line discipline into a tty structure. The |
| 265 | * ldisc must have a reference count above zero to ensure it remains/ | 267 | * ldisc must have a reference count above zero to ensure it remains. |
| 266 | * The tty instance refcount starts at zero. | 268 | * The tty instance refcount starts at zero. |
| 267 | * | 269 | * |
| 268 | * Locking: | 270 | * Locking: |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index d73f5f473e38..f8090e137fef 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -306,11 +306,11 @@ config SENSORS_F71805F | |||
| 306 | will be called f71805f. | 306 | will be called f71805f. |
| 307 | 307 | ||
| 308 | config SENSORS_F71882FG | 308 | config SENSORS_F71882FG |
| 309 | tristate "Fintek F71862FG, F71882FG and F8000" | 309 | tristate "Fintek F71858FG, F71862FG, F71882FG and F8000" |
| 310 | depends on EXPERIMENTAL | 310 | depends on EXPERIMENTAL |
| 311 | help | 311 | help |
| 312 | If you say yes here you get support for hardware monitoring | 312 | If you say yes here you get support for hardware monitoring |
| 313 | features of the Fintek F71882FG/F71883FG, F71862FG/71863FG | 313 | features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG |
| 314 | and F8000 Super-I/O chips. | 314 | and F8000 Super-I/O chips. |
| 315 | 315 | ||
| 316 | This driver can also be built as a module. If so, the module | 316 | This driver can also be built as a module. If so, the module |
| @@ -418,7 +418,7 @@ config SENSORS_IBMAEM | |||
| 418 | power sensors and capping hardware in various IBM System X | 418 | power sensors and capping hardware in various IBM System X |
| 419 | servers that support Active Energy Manager. This includes | 419 | servers that support Active Energy Manager. This includes |
| 420 | the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2, | 420 | the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2, |
| 421 | and certain HS2x/LS2x/QS2x blades. | 421 | and certain HC10/HS2x/LS2x/QS2x blades. |
| 422 | 422 | ||
| 423 | This driver can also be built as a module. If so, the module | 423 | This driver can also be built as a module. If so, the module |
| 424 | will be called ibmaem. | 424 | will be called ibmaem. |
| @@ -787,6 +787,16 @@ config SENSORS_THMC50 | |||
| 787 | This driver can also be built as a module. If so, the module | 787 | This driver can also be built as a module. If so, the module |
| 788 | will be called thmc50. | 788 | will be called thmc50. |
| 789 | 789 | ||
| 790 | config SENSORS_TMP401 | ||
| 791 | tristate "Texas Instruments TMP401 and compatibles" | ||
| 792 | depends on I2C && EXPERIMENTAL | ||
| 793 | help | ||
| 794 | If you say yes here you get support for Texas Instruments TMP401 and | ||
| 795 | TMP411 temperature sensor chips. | ||
| 796 | |||
| 797 | This driver can also be built as a module. If so, the module | ||
| 798 | will be called tmp401. | ||
| 799 | |||
| 790 | config SENSORS_VIA686A | 800 | config SENSORS_VIA686A |
| 791 | tristate "VIA686A" | 801 | tristate "VIA686A" |
| 792 | depends on PCI | 802 | depends on PCI |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 0ae26984ba45..b793dce6bed5 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -82,6 +82,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | |||
| 82 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | 82 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o |
| 83 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o | 83 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o |
| 84 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o | 84 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o |
| 85 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o | ||
| 85 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o | 86 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o |
| 86 | obj-$(CONFIG_SENSORS_VT1211) += vt1211.o | 87 | obj-$(CONFIG_SENSORS_VT1211) += vt1211.o |
| 87 | obj-$(CONFIG_SENSORS_VT8231) += vt8231.o | 88 | obj-$(CONFIG_SENSORS_VT8231) += vt8231.o |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 5f81ddf71508..4146105f1a57 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * | 2 | * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * |
| 3 | * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> * | 3 | * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> * |
| 4 | * * | 4 | * * |
| 5 | * This program is free software; you can redistribute it and/or modify * | 5 | * This program is free software; you can redistribute it and/or modify * |
| 6 | * it under the terms of the GNU General Public License as published by * | 6 | * it under the terms of the GNU General Public License as published by * |
| @@ -32,6 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | #define DRVNAME "f71882fg" | 33 | #define DRVNAME "f71882fg" |
| 34 | 34 | ||
| 35 | #define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */ | ||
| 35 | #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ | 36 | #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ |
| 36 | #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ | 37 | #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ |
| 37 | #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ | 38 | #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ |
| @@ -44,6 +45,7 @@ | |||
| 44 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 45 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
| 45 | 46 | ||
| 46 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ | 47 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ |
| 48 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ | ||
| 47 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ | 49 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ |
| 48 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | 50 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ |
| 49 | #define SIO_F8000_ID 0x0581 /* Chipset ID */ | 51 | #define SIO_F8000_ID 0x0581 /* Chipset ID */ |
| @@ -70,6 +72,7 @@ | |||
| 70 | #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr)) | 72 | #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr)) |
| 71 | #define F71882FG_REG_TEMP_STATUS 0x62 | 73 | #define F71882FG_REG_TEMP_STATUS 0x62 |
| 72 | #define F71882FG_REG_TEMP_BEEP 0x63 | 74 | #define F71882FG_REG_TEMP_BEEP 0x63 |
| 75 | #define F71882FG_REG_TEMP_CONFIG 0x69 | ||
| 73 | #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr)) | 76 | #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr)) |
| 74 | #define F71882FG_REG_TEMP_TYPE 0x6B | 77 | #define F71882FG_REG_TEMP_TYPE 0x6B |
| 75 | #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F | 78 | #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F |
| @@ -92,9 +95,10 @@ static unsigned short force_id; | |||
| 92 | module_param(force_id, ushort, 0); | 95 | module_param(force_id, ushort, 0); |
| 93 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 96 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
| 94 | 97 | ||
| 95 | enum chips { f71862fg, f71882fg, f8000 }; | 98 | enum chips { f71858fg, f71862fg, f71882fg, f8000 }; |
| 96 | 99 | ||
| 97 | static const char *f71882fg_names[] = { | 100 | static const char *f71882fg_names[] = { |
| 101 | "f71858fg", | ||
| 98 | "f71862fg", | 102 | "f71862fg", |
| 99 | "f71882fg", | 103 | "f71882fg", |
| 100 | "f8000", | 104 | "f8000", |
| @@ -119,6 +123,7 @@ struct f71882fg_data { | |||
| 119 | struct device *hwmon_dev; | 123 | struct device *hwmon_dev; |
| 120 | 124 | ||
| 121 | struct mutex update_lock; | 125 | struct mutex update_lock; |
| 126 | int temp_start; /* temp numbering start (0 or 1) */ | ||
| 122 | char valid; /* !=0 if following fields are valid */ | 127 | char valid; /* !=0 if following fields are valid */ |
| 123 | unsigned long last_updated; /* In jiffies */ | 128 | unsigned long last_updated; /* In jiffies */ |
| 124 | unsigned long last_limits; /* In jiffies */ | 129 | unsigned long last_limits; /* In jiffies */ |
| @@ -136,7 +141,7 @@ struct f71882fg_data { | |||
| 136 | /* Note: all models have only 3 temperature channels, but on some | 141 | /* Note: all models have only 3 temperature channels, but on some |
| 137 | they are addressed as 0-2 and on others as 1-3, so for coding | 142 | they are addressed as 0-2 and on others as 1-3, so for coding |
| 138 | convenience we reserve space for 4 channels */ | 143 | convenience we reserve space for 4 channels */ |
| 139 | u8 temp[4]; | 144 | u16 temp[4]; |
| 140 | u8 temp_ovt[4]; | 145 | u8 temp_ovt[4]; |
| 141 | u8 temp_high[4]; | 146 | u8 temp_high[4]; |
| 142 | u8 temp_hyst[2]; /* 2 hysts stored per reg */ | 147 | u8 temp_hyst[2]; /* 2 hysts stored per reg */ |
| @@ -144,6 +149,7 @@ struct f71882fg_data { | |||
| 144 | u8 temp_status; | 149 | u8 temp_status; |
| 145 | u8 temp_beep; | 150 | u8 temp_beep; |
| 146 | u8 temp_diode_open; | 151 | u8 temp_diode_open; |
| 152 | u8 temp_config; | ||
| 147 | u8 pwm[4]; | 153 | u8 pwm[4]; |
| 148 | u8 pwm_enable; | 154 | u8 pwm_enable; |
| 149 | u8 pwm_auto_point_hyst[2]; | 155 | u8 pwm_auto_point_hyst[2]; |
| @@ -247,11 +253,55 @@ static struct platform_driver f71882fg_driver = { | |||
| 247 | .name = DRVNAME, | 253 | .name = DRVNAME, |
| 248 | }, | 254 | }, |
| 249 | .probe = f71882fg_probe, | 255 | .probe = f71882fg_probe, |
| 250 | .remove = __devexit_p(f71882fg_remove), | 256 | .remove = f71882fg_remove, |
| 251 | }; | 257 | }; |
| 252 | 258 | ||
| 253 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 259 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
| 254 | 260 | ||
| 261 | /* Temp and in attr for the f71858fg */ | ||
| 262 | static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { | ||
| 263 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
| 264 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
| 265 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
| 266 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), | ||
| 267 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
| 268 | store_temp_max, 0, 0), | ||
| 269 | SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
| 270 | store_temp_max_hyst, 0, 0), | ||
| 271 | SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0), | ||
| 272 | SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
| 273 | store_temp_crit, 0, 0), | ||
| 274 | SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, | ||
| 275 | 0, 0), | ||
| 276 | SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), | ||
| 277 | SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0), | ||
| 278 | SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), | ||
| 279 | SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
| 280 | store_temp_max, 0, 1), | ||
| 281 | SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
| 282 | store_temp_max_hyst, 0, 1), | ||
| 283 | SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), | ||
| 284 | SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
| 285 | store_temp_crit, 0, 1), | ||
| 286 | SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, | ||
| 287 | 0, 1), | ||
| 288 | SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), | ||
| 289 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), | ||
| 290 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), | ||
| 291 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), | ||
| 292 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, | ||
| 293 | store_temp_max, 0, 2), | ||
| 294 | SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, | ||
| 295 | store_temp_max_hyst, 0, 2), | ||
| 296 | SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2), | ||
| 297 | SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, | ||
| 298 | store_temp_crit, 0, 2), | ||
| 299 | SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, | ||
| 300 | 0, 2), | ||
| 301 | SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), | ||
| 302 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | ||
| 303 | }; | ||
| 304 | |||
| 255 | /* Temp and in attr common to both the f71862fg and f71882fg */ | 305 | /* Temp and in attr common to both the f71862fg and f71882fg */ |
| 256 | static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { | 306 | static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { |
| 257 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | 307 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), |
| @@ -344,6 +394,7 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { | |||
| 344 | SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, | 394 | SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, |
| 345 | store_temp_max, 0, 0), | 395 | store_temp_max, 0, 0), |
| 346 | SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), | 396 | SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), |
| 397 | SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0), | ||
| 347 | SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), | 398 | SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), |
| 348 | SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit, | 399 | SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit, |
| 349 | store_temp_crit, 0, 1), | 400 | store_temp_crit, 0, 1), |
| @@ -351,12 +402,14 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { | |||
| 351 | store_temp_max, 0, 1), | 402 | store_temp_max, 0, 1), |
| 352 | SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), | 403 | SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), |
| 353 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), | 404 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), |
| 405 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), | ||
| 354 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), | 406 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), |
| 355 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, | 407 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, |
| 356 | store_temp_crit, 0, 2), | 408 | store_temp_crit, 0, 2), |
| 357 | SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, | 409 | SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, |
| 358 | store_temp_max, 0, 2), | 410 | store_temp_max, 0, 2), |
| 359 | SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), | 411 | SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), |
| 412 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | ||
| 360 | }; | 413 | }; |
| 361 | 414 | ||
| 362 | /* Fan / PWM attr common to all models */ | 415 | /* Fan / PWM attr common to all models */ |
| @@ -395,6 +448,9 @@ static struct sensor_device_attribute_2 fxxxx_fan_attr[] = { | |||
| 395 | show_pwm_auto_point_channel, | 448 | show_pwm_auto_point_channel, |
| 396 | store_pwm_auto_point_channel, 0, 1), | 449 | store_pwm_auto_point_channel, 0, 1), |
| 397 | 450 | ||
| 451 | SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), | ||
| 452 | SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
| 453 | store_pwm_enable, 0, 2), | ||
| 398 | SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, | 454 | SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, |
| 399 | show_pwm_interpolate, store_pwm_interpolate, 0, 2), | 455 | show_pwm_interpolate, store_pwm_interpolate, 0, 2), |
| 400 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, | 456 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, |
| @@ -450,9 +506,6 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = { | |||
| 450 | SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, | 506 | SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, |
| 451 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), | 507 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), |
| 452 | 508 | ||
| 453 | SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), | ||
| 454 | SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
| 455 | store_pwm_enable, 0, 2), | ||
| 456 | SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, | 509 | SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, |
| 457 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, | 510 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, |
| 458 | 1, 2), | 511 | 1, 2), |
| @@ -473,22 +526,8 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = { | |||
| 473 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), | 526 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), |
| 474 | }; | 527 | }; |
| 475 | 528 | ||
| 476 | /* Fan / PWM attr for the f71882fg */ | 529 | /* Fan / PWM attr common to both the f71882fg and f71858fg */ |
| 477 | static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { | 530 | static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = { |
| 478 | SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 479 | store_fan_beep, 0, 0), | ||
| 480 | SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 481 | store_fan_beep, 0, 1), | ||
| 482 | SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 483 | store_fan_beep, 0, 2), | ||
| 484 | SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), | ||
| 485 | SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR, | ||
| 486 | show_fan_full_speed, | ||
| 487 | store_fan_full_speed, 0, 3), | ||
| 488 | SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 489 | store_fan_beep, 0, 3), | ||
| 490 | SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3), | ||
| 491 | |||
| 492 | SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, | 531 | SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, |
| 493 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, | 532 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, |
| 494 | 0, 0), | 533 | 0, 0), |
| @@ -565,9 +604,6 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { | |||
| 565 | SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, | 604 | SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, |
| 566 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), | 605 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), |
| 567 | 606 | ||
| 568 | SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), | ||
| 569 | SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
| 570 | store_pwm_enable, 0, 2), | ||
| 571 | SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, | 607 | SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, |
| 572 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, | 608 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, |
| 573 | 0, 2), | 609 | 0, 2), |
| @@ -605,6 +641,24 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { | |||
| 605 | show_pwm_auto_point_temp_hyst, NULL, 2, 2), | 641 | show_pwm_auto_point_temp_hyst, NULL, 2, 2), |
| 606 | SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, | 642 | SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, |
| 607 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), | 643 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), |
| 644 | }; | ||
| 645 | |||
| 646 | /* Fan / PWM attr found on the f71882fg but not on the f71858fg */ | ||
| 647 | static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { | ||
| 648 | SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 649 | store_fan_beep, 0, 0), | ||
| 650 | SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 651 | store_fan_beep, 0, 1), | ||
| 652 | SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 653 | store_fan_beep, 0, 2), | ||
| 654 | |||
| 655 | SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), | ||
| 656 | SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR, | ||
| 657 | show_fan_full_speed, | ||
| 658 | store_fan_full_speed, 0, 3), | ||
| 659 | SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, | ||
| 660 | store_fan_beep, 0, 3), | ||
| 661 | SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3), | ||
| 608 | 662 | ||
| 609 | SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3), | 663 | SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3), |
| 610 | SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | 664 | SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable, |
| @@ -659,8 +713,6 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { | |||
| 659 | static struct sensor_device_attribute_2 f8000_fan_attr[] = { | 713 | static struct sensor_device_attribute_2 f8000_fan_attr[] = { |
| 660 | SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), | 714 | SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), |
| 661 | 715 | ||
| 662 | SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2), | ||
| 663 | |||
| 664 | SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR, | 716 | SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR, |
| 665 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, | 717 | show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, |
| 666 | 0, 2), | 718 | 0, 2), |
| @@ -857,13 +909,20 @@ static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) | |||
| 857 | outb(val & 255, data->addr + DATA_REG_OFFSET); | 909 | outb(val & 255, data->addr + DATA_REG_OFFSET); |
| 858 | } | 910 | } |
| 859 | 911 | ||
| 912 | static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) | ||
| 913 | { | ||
| 914 | if (data->type == f71858fg) | ||
| 915 | return f71882fg_read16(data, F71882FG_REG_TEMP(nr)); | ||
| 916 | else | ||
| 917 | return f71882fg_read8(data, F71882FG_REG_TEMP(nr)); | ||
| 918 | } | ||
| 919 | |||
| 860 | static struct f71882fg_data *f71882fg_update_device(struct device *dev) | 920 | static struct f71882fg_data *f71882fg_update_device(struct device *dev) |
| 861 | { | 921 | { |
| 862 | struct f71882fg_data *data = dev_get_drvdata(dev); | 922 | struct f71882fg_data *data = dev_get_drvdata(dev); |
| 863 | int nr, reg = 0, reg2; | 923 | int nr, reg = 0, reg2; |
| 864 | int nr_fans = (data->type == f71882fg) ? 4 : 3; | 924 | int nr_fans = (data->type == f71882fg) ? 4 : 3; |
| 865 | int nr_ins = (data->type == f8000) ? 3 : 9; | 925 | int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9; |
| 866 | int temp_start = (data->type == f8000) ? 0 : 1; | ||
| 867 | 926 | ||
| 868 | mutex_lock(&data->update_lock); | 927 | mutex_lock(&data->update_lock); |
| 869 | 928 | ||
| @@ -878,7 +937,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
| 878 | } | 937 | } |
| 879 | 938 | ||
| 880 | /* Get High & boundary temps*/ | 939 | /* Get High & boundary temps*/ |
| 881 | for (nr = temp_start; nr < 3 + temp_start; nr++) { | 940 | for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) { |
| 882 | data->temp_ovt[nr] = f71882fg_read8(data, | 941 | data->temp_ovt[nr] = f71882fg_read8(data, |
| 883 | F71882FG_REG_TEMP_OVT(nr)); | 942 | F71882FG_REG_TEMP_OVT(nr)); |
| 884 | data->temp_high[nr] = f71882fg_read8(data, | 943 | data->temp_high[nr] = f71882fg_read8(data, |
| @@ -886,14 +945,17 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
| 886 | } | 945 | } |
| 887 | 946 | ||
| 888 | if (data->type != f8000) { | 947 | if (data->type != f8000) { |
| 889 | data->fan_beep = f71882fg_read8(data, | ||
| 890 | F71882FG_REG_FAN_BEEP); | ||
| 891 | data->temp_beep = f71882fg_read8(data, | ||
| 892 | F71882FG_REG_TEMP_BEEP); | ||
| 893 | data->temp_hyst[0] = f71882fg_read8(data, | 948 | data->temp_hyst[0] = f71882fg_read8(data, |
| 894 | F71882FG_REG_TEMP_HYST(0)); | 949 | F71882FG_REG_TEMP_HYST(0)); |
| 895 | data->temp_hyst[1] = f71882fg_read8(data, | 950 | data->temp_hyst[1] = f71882fg_read8(data, |
| 896 | F71882FG_REG_TEMP_HYST(1)); | 951 | F71882FG_REG_TEMP_HYST(1)); |
| 952 | } | ||
| 953 | |||
| 954 | if (data->type == f71862fg || data->type == f71882fg) { | ||
| 955 | data->fan_beep = f71882fg_read8(data, | ||
| 956 | F71882FG_REG_FAN_BEEP); | ||
| 957 | data->temp_beep = f71882fg_read8(data, | ||
| 958 | F71882FG_REG_TEMP_BEEP); | ||
| 897 | /* Have to hardcode type, because temp1 is special */ | 959 | /* Have to hardcode type, because temp1 is special */ |
| 898 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); | 960 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); |
| 899 | data->temp_type[2] = (reg & 0x04) ? 2 : 4; | 961 | data->temp_type[2] = (reg & 0x04) ? 2 : 4; |
| @@ -904,10 +966,10 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
| 904 | data->temp_type[1] = 6 /* PECI */; | 966 | data->temp_type[1] = 6 /* PECI */; |
| 905 | else if ((reg2 & 0x03) == 0x02) | 967 | else if ((reg2 & 0x03) == 0x02) |
| 906 | data->temp_type[1] = 5 /* AMDSI */; | 968 | data->temp_type[1] = 5 /* AMDSI */; |
| 907 | else if (data->type != f8000) | 969 | else if (data->type == f71862fg || data->type == f71882fg) |
| 908 | data->temp_type[1] = (reg & 0x02) ? 2 : 4; | 970 | data->temp_type[1] = (reg & 0x02) ? 2 : 4; |
| 909 | else | 971 | else |
| 910 | data->temp_type[1] = 2; /* F8000 only supports BJT */ | 972 | data->temp_type[1] = 2; /* Only supports BJT */ |
| 911 | 973 | ||
| 912 | data->pwm_enable = f71882fg_read8(data, | 974 | data->pwm_enable = f71882fg_read8(data, |
| 913 | F71882FG_REG_PWM_ENABLE); | 975 | F71882FG_REG_PWM_ENABLE); |
| @@ -963,9 +1025,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
| 963 | F71882FG_REG_TEMP_STATUS); | 1025 | F71882FG_REG_TEMP_STATUS); |
| 964 | data->temp_diode_open = f71882fg_read8(data, | 1026 | data->temp_diode_open = f71882fg_read8(data, |
| 965 | F71882FG_REG_TEMP_DIODE_OPEN); | 1027 | F71882FG_REG_TEMP_DIODE_OPEN); |
| 966 | for (nr = temp_start; nr < 3 + temp_start; nr++) | 1028 | for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) |
| 967 | data->temp[nr] = f71882fg_read8(data, | 1029 | data->temp[nr] = f71882fg_read_temp(data, nr); |
| 968 | F71882FG_REG_TEMP(nr)); | ||
| 969 | 1030 | ||
| 970 | data->fan_status = f71882fg_read8(data, | 1031 | data->fan_status = f71882fg_read8(data, |
| 971 | F71882FG_REG_FAN_STATUS); | 1032 | F71882FG_REG_FAN_STATUS); |
| @@ -1168,8 +1229,24 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | |||
| 1168 | { | 1229 | { |
| 1169 | struct f71882fg_data *data = f71882fg_update_device(dev); | 1230 | struct f71882fg_data *data = f71882fg_update_device(dev); |
| 1170 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1231 | int nr = to_sensor_dev_attr_2(devattr)->index; |
| 1232 | int sign, temp; | ||
| 1233 | |||
| 1234 | if (data->type == f71858fg) { | ||
| 1235 | /* TEMP_TABLE_SEL 1 or 3 ? */ | ||
| 1236 | if (data->temp_config & 1) { | ||
| 1237 | sign = data->temp[nr] & 0x0001; | ||
| 1238 | temp = (data->temp[nr] >> 5) & 0x7ff; | ||
| 1239 | } else { | ||
| 1240 | sign = data->temp[nr] & 0x8000; | ||
| 1241 | temp = (data->temp[nr] >> 5) & 0x3ff; | ||
| 1242 | } | ||
| 1243 | temp *= 125; | ||
| 1244 | if (sign) | ||
| 1245 | temp -= 128000; | ||
| 1246 | } else | ||
| 1247 | temp = data->temp[nr] * 1000; | ||
| 1171 | 1248 | ||
| 1172 | return sprintf(buf, "%d\n", data->temp[nr] * 1000); | 1249 | return sprintf(buf, "%d\n", temp); |
| 1173 | } | 1250 | } |
| 1174 | 1251 | ||
| 1175 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | 1252 | static ssize_t show_temp_max(struct device *dev, struct device_attribute |
| @@ -1440,6 +1517,10 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute | |||
| 1440 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1517 | int nr = to_sensor_dev_attr_2(devattr)->index; |
| 1441 | long val = simple_strtol(buf, NULL, 10); | 1518 | long val = simple_strtol(buf, NULL, 10); |
| 1442 | 1519 | ||
| 1520 | /* Special case for F8000 pwm channel 3 which only does auto mode */ | ||
| 1521 | if (data->type == f8000 && nr == 2 && val != 2) | ||
| 1522 | return -EINVAL; | ||
| 1523 | |||
| 1443 | mutex_lock(&data->update_lock); | 1524 | mutex_lock(&data->update_lock); |
| 1444 | data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); | 1525 | data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); |
| 1445 | /* Special case for F8000 auto PWM mode / Thermostat mode */ | 1526 | /* Special case for F8000 auto PWM mode / Thermostat mode */ |
| @@ -1458,6 +1539,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute | |||
| 1458 | } else { | 1539 | } else { |
| 1459 | switch (val) { | 1540 | switch (val) { |
| 1460 | case 1: | 1541 | case 1: |
| 1542 | /* The f71858fg does not support manual RPM mode */ | ||
| 1543 | if (data->type == f71858fg && | ||
| 1544 | ((data->pwm_enable >> (2 * nr)) & 1)) { | ||
| 1545 | count = -EINVAL; | ||
| 1546 | goto leave; | ||
| 1547 | } | ||
| 1461 | data->pwm_enable |= 2 << (2 * nr); | 1548 | data->pwm_enable |= 2 << (2 * nr); |
| 1462 | break; /* Manual */ | 1549 | break; /* Manual */ |
| 1463 | case 2: | 1550 | case 2: |
| @@ -1616,9 +1703,9 @@ static ssize_t show_pwm_auto_point_channel(struct device *dev, | |||
| 1616 | int result; | 1703 | int result; |
| 1617 | struct f71882fg_data *data = f71882fg_update_device(dev); | 1704 | struct f71882fg_data *data = f71882fg_update_device(dev); |
| 1618 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1705 | int nr = to_sensor_dev_attr_2(devattr)->index; |
| 1619 | int temp_start = (data->type == f8000) ? 0 : 1; | ||
| 1620 | 1706 | ||
| 1621 | result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start); | 1707 | result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - |
| 1708 | data->temp_start); | ||
| 1622 | 1709 | ||
| 1623 | return sprintf(buf, "%d\n", result); | 1710 | return sprintf(buf, "%d\n", result); |
| 1624 | } | 1711 | } |
| @@ -1629,7 +1716,6 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, | |||
| 1629 | { | 1716 | { |
| 1630 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1717 | struct f71882fg_data *data = dev_get_drvdata(dev); |
| 1631 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1718 | int nr = to_sensor_dev_attr_2(devattr)->index; |
| 1632 | int temp_start = (data->type == f8000) ? 0 : 1; | ||
| 1633 | long val = simple_strtol(buf, NULL, 10); | 1719 | long val = simple_strtol(buf, NULL, 10); |
| 1634 | 1720 | ||
| 1635 | switch (val) { | 1721 | switch (val) { |
| @@ -1645,7 +1731,7 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, | |||
| 1645 | default: | 1731 | default: |
| 1646 | return -EINVAL; | 1732 | return -EINVAL; |
| 1647 | } | 1733 | } |
| 1648 | val += temp_start; | 1734 | val += data->temp_start; |
| 1649 | mutex_lock(&data->update_lock); | 1735 | mutex_lock(&data->update_lock); |
| 1650 | data->pwm_auto_point_mapping[nr] = | 1736 | data->pwm_auto_point_mapping[nr] = |
| 1651 | f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); | 1737 | f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); |
| @@ -1721,6 +1807,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
| 1721 | 1807 | ||
| 1722 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | 1808 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; |
| 1723 | data->type = sio_data->type; | 1809 | data->type = sio_data->type; |
| 1810 | data->temp_start = | ||
| 1811 | (data->type == f71858fg || data->type == f8000) ? 0 : 1; | ||
| 1724 | mutex_init(&data->update_lock); | 1812 | mutex_init(&data->update_lock); |
| 1725 | platform_set_drvdata(pdev, data); | 1813 | platform_set_drvdata(pdev, data); |
| 1726 | 1814 | ||
| @@ -1736,19 +1824,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
| 1736 | goto exit_free; | 1824 | goto exit_free; |
| 1737 | } | 1825 | } |
| 1738 | 1826 | ||
| 1739 | data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); | ||
| 1740 | /* If it is a 71862 and the fan / pwm part is enabled sanity check | ||
| 1741 | the pwm settings */ | ||
| 1742 | if (data->type == f71862fg && (start_reg & 0x02)) { | ||
| 1743 | if ((data->pwm_enable & 0x15) != 0x15) { | ||
| 1744 | dev_err(&pdev->dev, | ||
| 1745 | "Invalid (reserved) pwm settings: 0x%02x\n", | ||
| 1746 | (unsigned int)data->pwm_enable); | ||
| 1747 | err = -ENODEV; | ||
| 1748 | goto exit_free; | ||
| 1749 | } | ||
| 1750 | } | ||
| 1751 | |||
| 1752 | /* Register sysfs interface files */ | 1827 | /* Register sysfs interface files */ |
| 1753 | err = device_create_file(&pdev->dev, &dev_attr_name); | 1828 | err = device_create_file(&pdev->dev, &dev_attr_name); |
| 1754 | if (err) | 1829 | if (err) |
| @@ -1756,6 +1831,20 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
| 1756 | 1831 | ||
| 1757 | if (start_reg & 0x01) { | 1832 | if (start_reg & 0x01) { |
| 1758 | switch (data->type) { | 1833 | switch (data->type) { |
| 1834 | case f71858fg: | ||
| 1835 | data->temp_config = | ||
| 1836 | f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG); | ||
| 1837 | if (data->temp_config & 0x10) | ||
| 1838 | /* The f71858fg temperature alarms behave as | ||
| 1839 | the f8000 alarms in this mode */ | ||
| 1840 | err = f71882fg_create_sysfs_files(pdev, | ||
| 1841 | f8000_in_temp_attr, | ||
| 1842 | ARRAY_SIZE(f8000_in_temp_attr)); | ||
| 1843 | else | ||
| 1844 | err = f71882fg_create_sysfs_files(pdev, | ||
| 1845 | f71858fg_in_temp_attr, | ||
| 1846 | ARRAY_SIZE(f71858fg_in_temp_attr)); | ||
| 1847 | break; | ||
| 1759 | case f71882fg: | 1848 | case f71882fg: |
| 1760 | err = f71882fg_create_sysfs_files(pdev, | 1849 | err = f71882fg_create_sysfs_files(pdev, |
| 1761 | f71882fg_in_temp_attr, | 1850 | f71882fg_in_temp_attr, |
| @@ -1779,6 +1868,35 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
| 1779 | } | 1868 | } |
| 1780 | 1869 | ||
| 1781 | if (start_reg & 0x02) { | 1870 | if (start_reg & 0x02) { |
| 1871 | data->pwm_enable = | ||
| 1872 | f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); | ||
| 1873 | |||
| 1874 | /* Sanity check the pwm settings */ | ||
| 1875 | switch (data->type) { | ||
| 1876 | case f71858fg: | ||
| 1877 | err = 0; | ||
| 1878 | for (i = 0; i < nr_fans; i++) | ||
| 1879 | if (((data->pwm_enable >> (i * 2)) & 3) == 3) | ||
| 1880 | err = 1; | ||
| 1881 | break; | ||
| 1882 | case f71862fg: | ||
| 1883 | err = (data->pwm_enable & 0x15) != 0x15; | ||
| 1884 | break; | ||
| 1885 | case f71882fg: | ||
| 1886 | err = 0; | ||
| 1887 | break; | ||
| 1888 | case f8000: | ||
| 1889 | err = data->pwm_enable & 0x20; | ||
| 1890 | break; | ||
| 1891 | } | ||
| 1892 | if (err) { | ||
| 1893 | dev_err(&pdev->dev, | ||
| 1894 | "Invalid (reserved) pwm settings: 0x%02x\n", | ||
| 1895 | (unsigned int)data->pwm_enable); | ||
| 1896 | err = -ENODEV; | ||
| 1897 | goto exit_unregister_sysfs; | ||
| 1898 | } | ||
| 1899 | |||
| 1782 | err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr, | 1900 | err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr, |
| 1783 | ARRAY_SIZE(fxxxx_fan_attr)); | 1901 | ARRAY_SIZE(fxxxx_fan_attr)); |
| 1784 | if (err) | 1902 | if (err) |
| @@ -1794,6 +1912,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
| 1794 | err = f71882fg_create_sysfs_files(pdev, | 1912 | err = f71882fg_create_sysfs_files(pdev, |
| 1795 | f71882fg_fan_attr, | 1913 | f71882fg_fan_attr, |
| 1796 | ARRAY_SIZE(f71882fg_fan_attr)); | 1914 | ARRAY_SIZE(f71882fg_fan_attr)); |
| 1915 | if (err) | ||
| 1916 | goto exit_unregister_sysfs; | ||
| 1917 | /* fall through! */ | ||
| 1918 | case f71858fg: | ||
| 1919 | err = f71882fg_create_sysfs_files(pdev, | ||
| 1920 | f71882fg_f71858fg_fan_attr, | ||
| 1921 | ARRAY_SIZE(f71882fg_f71858fg_fan_attr)); | ||
| 1797 | break; | 1922 | break; |
| 1798 | case f8000: | 1923 | case f8000: |
| 1799 | err = f71882fg_create_sysfs_files(pdev, | 1924 | err = f71882fg_create_sysfs_files(pdev, |
| @@ -1878,6 +2003,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
| 1878 | 2003 | ||
| 1879 | devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); | 2004 | devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); |
| 1880 | switch (devid) { | 2005 | switch (devid) { |
| 2006 | case SIO_F71858_ID: | ||
| 2007 | sio_data->type = f71858fg; | ||
| 2008 | break; | ||
| 1881 | case SIO_F71862_ID: | 2009 | case SIO_F71862_ID: |
| 1882 | sio_data->type = f71862fg; | 2010 | sio_data->type = f71862fg; |
| 1883 | break; | 2011 | break; |
| @@ -1892,7 +2020,11 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
| 1892 | goto exit; | 2020 | goto exit; |
| 1893 | } | 2021 | } |
| 1894 | 2022 | ||
| 1895 | superio_select(sioaddr, SIO_F71882FG_LD_HWM); | 2023 | if (sio_data->type == f71858fg) |
| 2024 | superio_select(sioaddr, SIO_F71858FG_LD_HWM); | ||
| 2025 | else | ||
| 2026 | superio_select(sioaddr, SIO_F71882FG_LD_HWM); | ||
| 2027 | |||
| 1896 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | 2028 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { |
| 1897 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | 2029 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); |
| 1898 | goto exit; | 2030 | goto exit; |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index e15c3e7b07e9..29ea6753f3bb 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/hwmon.h> | 18 | #include <linux/hwmon.h> |
| 19 | #include <linux/gfp.h> | 19 | #include <linux/gfp.h> |
| 20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
| 21 | #include <linux/pci.h> | ||
| 21 | 22 | ||
| 22 | #define HWMON_ID_PREFIX "hwmon" | 23 | #define HWMON_ID_PREFIX "hwmon" |
| 23 | #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" | 24 | #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" |
| @@ -86,8 +87,36 @@ void hwmon_device_unregister(struct device *dev) | |||
| 86 | "hwmon_device_unregister() failed: bad class ID!\n"); | 87 | "hwmon_device_unregister() failed: bad class ID!\n"); |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 90 | static void __init hwmon_pci_quirks(void) | ||
| 91 | { | ||
| 92 | #if defined CONFIG_X86 && defined CONFIG_PCI | ||
| 93 | struct pci_dev *sb; | ||
| 94 | u16 base; | ||
| 95 | u8 enable; | ||
| 96 | |||
| 97 | /* Open access to 0x295-0x296 on MSI MS-7031 */ | ||
| 98 | sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL); | ||
| 99 | if (sb && | ||
| 100 | (sb->subsystem_vendor == 0x1462 && /* MSI */ | ||
| 101 | sb->subsystem_device == 0x0031)) { /* MS-7031 */ | ||
| 102 | |||
| 103 | pci_read_config_byte(sb, 0x48, &enable); | ||
| 104 | pci_read_config_word(sb, 0x64, &base); | ||
| 105 | |||
| 106 | if (base == 0 && !(enable & BIT(2))) { | ||
| 107 | dev_info(&sb->dev, | ||
| 108 | "Opening wide generic port at 0x295\n"); | ||
| 109 | pci_write_config_word(sb, 0x64, 0x295); | ||
| 110 | pci_write_config_byte(sb, 0x48, enable | BIT(2)); | ||
| 111 | } | ||
| 112 | } | ||
| 113 | #endif | ||
| 114 | } | ||
| 115 | |||
| 89 | static int __init hwmon_init(void) | 116 | static int __init hwmon_init(void) |
| 90 | { | 117 | { |
| 118 | hwmon_pci_quirks(); | ||
| 119 | |||
| 91 | hwmon_class = class_create(THIS_MODULE, "hwmon"); | 120 | hwmon_class = class_create(THIS_MODULE, "hwmon"); |
| 92 | if (IS_ERR(hwmon_class)) { | 121 | if (IS_ERR(hwmon_class)) { |
| 93 | printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); | 122 | printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index fe74609a7feb..405d3fb5d76f 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
| @@ -1127,3 +1127,4 @@ MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*"); | |||
| 1127 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*"); | 1127 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*"); |
| 1128 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*"); | 1128 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*"); |
| 1129 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*"); | 1129 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*"); |
| 1130 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMBladeHC10-*"); | ||
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index f27af6a9da41..86142a858238 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | * also work with the MAX6651. It does not distinguish max6650 and max6651 | 12 | * also work with the MAX6651. It does not distinguish max6650 and max6651 |
| 13 | * chips. | 13 | * chips. |
| 14 | * | 14 | * |
| 15 | * Tha datasheet was last seen at: | 15 | * The datasheet was last seen at: |
| 16 | * | 16 | * |
| 17 | * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf | 17 | * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf |
| 18 | * | 18 | * |
| @@ -98,6 +98,16 @@ I2C_CLIENT_INSMOD_1(max6650); | |||
| 98 | #define MAX6650_CFG_MODE_OPEN_LOOP 0x30 | 98 | #define MAX6650_CFG_MODE_OPEN_LOOP 0x30 |
| 99 | #define MAX6650_COUNT_MASK 0x03 | 99 | #define MAX6650_COUNT_MASK 0x03 |
| 100 | 100 | ||
| 101 | /* | ||
| 102 | * Alarm status register bits | ||
| 103 | */ | ||
| 104 | |||
| 105 | #define MAX6650_ALRM_MAX 0x01 | ||
| 106 | #define MAX6650_ALRM_MIN 0x02 | ||
| 107 | #define MAX6650_ALRM_TACH 0x04 | ||
| 108 | #define MAX6650_ALRM_GPIO1 0x08 | ||
| 109 | #define MAX6650_ALRM_GPIO2 0x10 | ||
| 110 | |||
| 101 | /* Minimum and maximum values of the FAN-RPM */ | 111 | /* Minimum and maximum values of the FAN-RPM */ |
| 102 | #define FAN_RPM_MIN 240 | 112 | #define FAN_RPM_MIN 240 |
| 103 | #define FAN_RPM_MAX 30000 | 113 | #define FAN_RPM_MAX 30000 |
| @@ -151,6 +161,7 @@ struct max6650_data | |||
| 151 | u8 tach[4]; | 161 | u8 tach[4]; |
| 152 | u8 count; | 162 | u8 count; |
| 153 | u8 dac; | 163 | u8 dac; |
| 164 | u8 alarm; | ||
| 154 | }; | 165 | }; |
| 155 | 166 | ||
| 156 | static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, | 167 | static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, |
| @@ -418,6 +429,33 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, | |||
| 418 | return count; | 429 | return count; |
| 419 | } | 430 | } |
| 420 | 431 | ||
| 432 | /* | ||
| 433 | * Get alarm stati: | ||
| 434 | * Possible values: | ||
| 435 | * 0 = no alarm | ||
| 436 | * 1 = alarm | ||
| 437 | */ | ||
| 438 | |||
| 439 | static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr, | ||
| 440 | char *buf) | ||
| 441 | { | ||
| 442 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 443 | struct max6650_data *data = max6650_update_device(dev); | ||
| 444 | struct i2c_client *client = to_i2c_client(dev); | ||
| 445 | int alarm = 0; | ||
| 446 | |||
| 447 | if (data->alarm & attr->index) { | ||
| 448 | mutex_lock(&data->update_lock); | ||
| 449 | alarm = 1; | ||
| 450 | data->alarm &= ~attr->index; | ||
| 451 | data->alarm |= i2c_smbus_read_byte_data(client, | ||
| 452 | MAX6650_REG_ALARM); | ||
| 453 | mutex_unlock(&data->update_lock); | ||
| 454 | } | ||
| 455 | |||
| 456 | return sprintf(buf, "%d\n", alarm); | ||
| 457 | } | ||
| 458 | |||
| 421 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); | 459 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); |
| 422 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); | 460 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); |
| 423 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); | 461 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); |
| @@ -426,7 +464,41 @@ static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target); | |||
| 426 | static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); | 464 | static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); |
| 427 | static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); | 465 | static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); |
| 428 | static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); | 466 | static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); |
| 467 | static SENSOR_DEVICE_ATTR(fan1_max_alarm, S_IRUGO, get_alarm, NULL, | ||
| 468 | MAX6650_ALRM_MAX); | ||
| 469 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, get_alarm, NULL, | ||
| 470 | MAX6650_ALRM_MIN); | ||
| 471 | static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_alarm, NULL, | ||
| 472 | MAX6650_ALRM_TACH); | ||
| 473 | static SENSOR_DEVICE_ATTR(gpio1_alarm, S_IRUGO, get_alarm, NULL, | ||
| 474 | MAX6650_ALRM_GPIO1); | ||
| 475 | static SENSOR_DEVICE_ATTR(gpio2_alarm, S_IRUGO, get_alarm, NULL, | ||
| 476 | MAX6650_ALRM_GPIO2); | ||
| 477 | |||
| 478 | static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a, | ||
| 479 | int n) | ||
| 480 | { | ||
| 481 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 482 | struct i2c_client *client = to_i2c_client(dev); | ||
| 483 | u8 alarm_en = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN); | ||
| 484 | struct device_attribute *devattr; | ||
| 429 | 485 | ||
| 486 | /* | ||
| 487 | * Hide the alarms that have not been enabled by the firmware | ||
| 488 | */ | ||
| 489 | |||
| 490 | devattr = container_of(a, struct device_attribute, attr); | ||
| 491 | if (devattr == &sensor_dev_attr_fan1_max_alarm.dev_attr | ||
| 492 | || devattr == &sensor_dev_attr_fan1_min_alarm.dev_attr | ||
| 493 | || devattr == &sensor_dev_attr_fan1_fault.dev_attr | ||
| 494 | || devattr == &sensor_dev_attr_gpio1_alarm.dev_attr | ||
| 495 | || devattr == &sensor_dev_attr_gpio2_alarm.dev_attr) { | ||
| 496 | if (!(alarm_en & to_sensor_dev_attr(devattr)->index)) | ||
| 497 | return 0; | ||
| 498 | } | ||
| 499 | |||
| 500 | return a->mode; | ||
| 501 | } | ||
| 430 | 502 | ||
| 431 | static struct attribute *max6650_attrs[] = { | 503 | static struct attribute *max6650_attrs[] = { |
| 432 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 504 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
| @@ -437,11 +509,17 @@ static struct attribute *max6650_attrs[] = { | |||
| 437 | &dev_attr_fan1_div.attr, | 509 | &dev_attr_fan1_div.attr, |
| 438 | &dev_attr_pwm1_enable.attr, | 510 | &dev_attr_pwm1_enable.attr, |
| 439 | &dev_attr_pwm1.attr, | 511 | &dev_attr_pwm1.attr, |
| 512 | &sensor_dev_attr_fan1_max_alarm.dev_attr.attr, | ||
| 513 | &sensor_dev_attr_fan1_min_alarm.dev_attr.attr, | ||
| 514 | &sensor_dev_attr_fan1_fault.dev_attr.attr, | ||
| 515 | &sensor_dev_attr_gpio1_alarm.dev_attr.attr, | ||
| 516 | &sensor_dev_attr_gpio2_alarm.dev_attr.attr, | ||
| 440 | NULL | 517 | NULL |
| 441 | }; | 518 | }; |
| 442 | 519 | ||
| 443 | static struct attribute_group max6650_attr_grp = { | 520 | static struct attribute_group max6650_attr_grp = { |
| 444 | .attrs = max6650_attrs, | 521 | .attrs = max6650_attrs, |
| 522 | .is_visible = max6650_attrs_visible, | ||
| 445 | }; | 523 | }; |
| 446 | 524 | ||
| 447 | /* | 525 | /* |
| @@ -659,6 +737,12 @@ static struct max6650_data *max6650_update_device(struct device *dev) | |||
| 659 | MAX6650_REG_COUNT); | 737 | MAX6650_REG_COUNT); |
| 660 | data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); | 738 | data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); |
| 661 | 739 | ||
| 740 | /* Alarms are cleared on read in case the condition that | ||
| 741 | * caused the alarm is removed. Keep the value latched here | ||
| 742 | * for providing the register through different alarm files. */ | ||
| 743 | data->alarm |= i2c_smbus_read_byte_data(client, | ||
| 744 | MAX6650_REG_ALARM); | ||
| 745 | |||
| 662 | data->last_updated = jiffies; | 746 | data->last_updated = jiffies; |
| 663 | data->valid = 1; | 747 | data->valid = 1; |
| 664 | } | 748 | } |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 6cbdc2fea734..56cd6004da36 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
| @@ -627,35 +627,35 @@ static struct platform_driver sht_drivers[] = { | |||
| 627 | .owner = THIS_MODULE, | 627 | .owner = THIS_MODULE, |
| 628 | }, | 628 | }, |
| 629 | .probe = sht15_probe, | 629 | .probe = sht15_probe, |
| 630 | .remove = sht15_remove, | 630 | .remove = __devexit_p(sht15_remove), |
| 631 | }, { | 631 | }, { |
| 632 | .driver = { | 632 | .driver = { |
| 633 | .name = "sht11", | 633 | .name = "sht11", |
| 634 | .owner = THIS_MODULE, | 634 | .owner = THIS_MODULE, |
| 635 | }, | 635 | }, |
| 636 | .probe = sht15_probe, | 636 | .probe = sht15_probe, |
| 637 | .remove = sht15_remove, | 637 | .remove = __devexit_p(sht15_remove), |
| 638 | }, { | 638 | }, { |
| 639 | .driver = { | 639 | .driver = { |
| 640 | .name = "sht15", | 640 | .name = "sht15", |
| 641 | .owner = THIS_MODULE, | 641 | .owner = THIS_MODULE, |
| 642 | }, | 642 | }, |
| 643 | .probe = sht15_probe, | 643 | .probe = sht15_probe, |
| 644 | .remove = sht15_remove, | 644 | .remove = __devexit_p(sht15_remove), |
| 645 | }, { | 645 | }, { |
| 646 | .driver = { | 646 | .driver = { |
| 647 | .name = "sht71", | 647 | .name = "sht71", |
| 648 | .owner = THIS_MODULE, | 648 | .owner = THIS_MODULE, |
| 649 | }, | 649 | }, |
| 650 | .probe = sht15_probe, | 650 | .probe = sht15_probe, |
| 651 | .remove = sht15_remove, | 651 | .remove = __devexit_p(sht15_remove), |
| 652 | }, { | 652 | }, { |
| 653 | .driver = { | 653 | .driver = { |
| 654 | .name = "sht75", | 654 | .name = "sht75", |
| 655 | .owner = THIS_MODULE, | 655 | .owner = THIS_MODULE, |
| 656 | }, | 656 | }, |
| 657 | .probe = sht15_probe, | 657 | .probe = sht15_probe, |
| 658 | .remove = sht15_remove, | 658 | .remove = __devexit_p(sht15_remove), |
| 659 | }, | 659 | }, |
| 660 | }; | 660 | }; |
| 661 | 661 | ||
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c new file mode 100644 index 000000000000..7b34f2cd08bb --- /dev/null +++ b/drivers/hwmon/tmp401.c | |||
| @@ -0,0 +1,690 @@ | |||
| 1 | /* tmp401.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com> | ||
| 4 | * Preliminary tmp411 support by: | ||
| 5 | * Gabriel Konat, Sander Leget, Wouter Willems | ||
| 6 | * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> | ||
| 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC. | ||
| 25 | * | ||
| 26 | * Note this IC is in some aspect similar to the LM90, but it has quite a | ||
| 27 | * few differences too, for example the local temp has a higher resolution | ||
| 28 | * and thus has 16 bits registers for its value and limit instead of 8 bits. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include <linux/module.h> | ||
| 32 | #include <linux/init.h> | ||
| 33 | #include <linux/slab.h> | ||
| 34 | #include <linux/jiffies.h> | ||
| 35 | #include <linux/i2c.h> | ||
| 36 | #include <linux/hwmon.h> | ||
| 37 | #include <linux/hwmon-sysfs.h> | ||
| 38 | #include <linux/err.h> | ||
| 39 | #include <linux/mutex.h> | ||
| 40 | #include <linux/sysfs.h> | ||
| 41 | |||
| 42 | /* Addresses to scan */ | ||
| 43 | static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; | ||
| 44 | |||
| 45 | /* Insmod parameters */ | ||
| 46 | I2C_CLIENT_INSMOD_2(tmp401, tmp411); | ||
| 47 | |||
| 48 | /* | ||
| 49 | * The TMP401 registers, note some registers have different addresses for | ||
| 50 | * reading and writing | ||
| 51 | */ | ||
| 52 | #define TMP401_STATUS 0x02 | ||
| 53 | #define TMP401_CONFIG_READ 0x03 | ||
| 54 | #define TMP401_CONFIG_WRITE 0x09 | ||
| 55 | #define TMP401_CONVERSION_RATE_READ 0x04 | ||
| 56 | #define TMP401_CONVERSION_RATE_WRITE 0x0A | ||
| 57 | #define TMP401_TEMP_CRIT_HYST 0x21 | ||
| 58 | #define TMP401_CONSECUTIVE_ALERT 0x22 | ||
| 59 | #define TMP401_MANUFACTURER_ID_REG 0xFE | ||
| 60 | #define TMP401_DEVICE_ID_REG 0xFF | ||
| 61 | #define TMP411_N_FACTOR_REG 0x18 | ||
| 62 | |||
| 63 | static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 }; | ||
| 64 | static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 }; | ||
| 65 | static const u8 TMP401_TEMP_LOW_LIMIT_MSB_READ[2] = { 0x06, 0x08 }; | ||
| 66 | static const u8 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[2] = { 0x0C, 0x0E }; | ||
| 67 | static const u8 TMP401_TEMP_LOW_LIMIT_LSB[2] = { 0x17, 0x14 }; | ||
| 68 | static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_READ[2] = { 0x05, 0x07 }; | ||
| 69 | static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[2] = { 0x0B, 0x0D }; | ||
| 70 | static const u8 TMP401_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 }; | ||
| 71 | /* These are called the THERM limit / hysteresis / mask in the datasheet */ | ||
| 72 | static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 }; | ||
| 73 | |||
| 74 | static const u8 TMP411_TEMP_LOWEST_MSB[2] = { 0x30, 0x34 }; | ||
| 75 | static const u8 TMP411_TEMP_LOWEST_LSB[2] = { 0x31, 0x35 }; | ||
| 76 | static const u8 TMP411_TEMP_HIGHEST_MSB[2] = { 0x32, 0x36 }; | ||
| 77 | static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; | ||
| 78 | |||
| 79 | /* Flags */ | ||
| 80 | #define TMP401_CONFIG_RANGE 0x04 | ||
| 81 | #define TMP401_CONFIG_SHUTDOWN 0x40 | ||
| 82 | #define TMP401_STATUS_LOCAL_CRIT 0x01 | ||
| 83 | #define TMP401_STATUS_REMOTE_CRIT 0x02 | ||
| 84 | #define TMP401_STATUS_REMOTE_OPEN 0x04 | ||
| 85 | #define TMP401_STATUS_REMOTE_LOW 0x08 | ||
| 86 | #define TMP401_STATUS_REMOTE_HIGH 0x10 | ||
| 87 | #define TMP401_STATUS_LOCAL_LOW 0x20 | ||
| 88 | #define TMP401_STATUS_LOCAL_HIGH 0x40 | ||
| 89 | |||
| 90 | /* Manufacturer / Device ID's */ | ||
| 91 | #define TMP401_MANUFACTURER_ID 0x55 | ||
| 92 | #define TMP401_DEVICE_ID 0x11 | ||
| 93 | #define TMP411_DEVICE_ID 0x12 | ||
| 94 | |||
| 95 | /* | ||
| 96 | * Functions declarations | ||
| 97 | */ | ||
| 98 | |||
| 99 | static int tmp401_probe(struct i2c_client *client, | ||
| 100 | const struct i2c_device_id *id); | ||
| 101 | static int tmp401_detect(struct i2c_client *client, int kind, | ||
| 102 | struct i2c_board_info *info); | ||
| 103 | static int tmp401_remove(struct i2c_client *client); | ||
| 104 | static struct tmp401_data *tmp401_update_device(struct device *dev); | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Driver data (common to all clients) | ||
| 108 | */ | ||
| 109 | |||
| 110 | static const struct i2c_device_id tmp401_id[] = { | ||
| 111 | { "tmp401", tmp401 }, | ||
| 112 | { "tmp411", tmp411 }, | ||
| 113 | { } | ||
| 114 | }; | ||
| 115 | MODULE_DEVICE_TABLE(i2c, tmp401_id); | ||
| 116 | |||
| 117 | static struct i2c_driver tmp401_driver = { | ||
| 118 | .class = I2C_CLASS_HWMON, | ||
| 119 | .driver = { | ||
| 120 | .name = "tmp401", | ||
| 121 | }, | ||
| 122 | .probe = tmp401_probe, | ||
| 123 | .remove = tmp401_remove, | ||
| 124 | .id_table = tmp401_id, | ||
| 125 | .detect = tmp401_detect, | ||
| 126 | .address_data = &addr_data, | ||
| 127 | }; | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Client data (each client gets its own) | ||
| 131 | */ | ||
| 132 | |||
| 133 | struct tmp401_data { | ||
| 134 | struct device *hwmon_dev; | ||
| 135 | struct mutex update_lock; | ||
| 136 | char valid; /* zero until following fields are valid */ | ||
| 137 | unsigned long last_updated; /* in jiffies */ | ||
| 138 | int kind; | ||
| 139 | |||
| 140 | /* register values */ | ||
| 141 | u8 status; | ||
| 142 | u8 config; | ||
| 143 | u16 temp[2]; | ||
| 144 | u16 temp_low[2]; | ||
| 145 | u16 temp_high[2]; | ||
| 146 | u8 temp_crit[2]; | ||
| 147 | u8 temp_crit_hyst; | ||
| 148 | u16 temp_lowest[2]; | ||
| 149 | u16 temp_highest[2]; | ||
| 150 | }; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * Sysfs attr show / store functions | ||
| 154 | */ | ||
| 155 | |||
| 156 | static int tmp401_register_to_temp(u16 reg, u8 config) | ||
| 157 | { | ||
| 158 | int temp = reg; | ||
| 159 | |||
| 160 | if (config & TMP401_CONFIG_RANGE) | ||
| 161 | temp -= 64 * 256; | ||
| 162 | |||
| 163 | return (temp * 625 + 80) / 160; | ||
| 164 | } | ||
| 165 | |||
| 166 | static u16 tmp401_temp_to_register(long temp, u8 config) | ||
| 167 | { | ||
| 168 | if (config & TMP401_CONFIG_RANGE) { | ||
| 169 | temp = SENSORS_LIMIT(temp, -64000, 191000); | ||
| 170 | temp += 64000; | ||
| 171 | } else | ||
| 172 | temp = SENSORS_LIMIT(temp, 0, 127000); | ||
| 173 | |||
| 174 | return (temp * 160 + 312) / 625; | ||
| 175 | } | ||
| 176 | |||
| 177 | static int tmp401_crit_register_to_temp(u8 reg, u8 config) | ||
| 178 | { | ||
| 179 | int temp = reg; | ||
| 180 | |||
| 181 | if (config & TMP401_CONFIG_RANGE) | ||
| 182 | temp -= 64; | ||
| 183 | |||
| 184 | return temp * 1000; | ||
| 185 | } | ||
| 186 | |||
| 187 | static u8 tmp401_crit_temp_to_register(long temp, u8 config) | ||
| 188 | { | ||
| 189 | if (config & TMP401_CONFIG_RANGE) { | ||
| 190 | temp = SENSORS_LIMIT(temp, -64000, 191000); | ||
| 191 | temp += 64000; | ||
| 192 | } else | ||
| 193 | temp = SENSORS_LIMIT(temp, 0, 127000); | ||
| 194 | |||
| 195 | return (temp + 500) / 1000; | ||
| 196 | } | ||
| 197 | |||
| 198 | static ssize_t show_temp_value(struct device *dev, | ||
| 199 | struct device_attribute *devattr, char *buf) | ||
| 200 | { | ||
| 201 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 202 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 203 | |||
| 204 | return sprintf(buf, "%d\n", | ||
| 205 | tmp401_register_to_temp(data->temp[index], data->config)); | ||
| 206 | } | ||
| 207 | |||
| 208 | static ssize_t show_temp_min(struct device *dev, | ||
| 209 | struct device_attribute *devattr, char *buf) | ||
| 210 | { | ||
| 211 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 212 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 213 | |||
| 214 | return sprintf(buf, "%d\n", | ||
| 215 | tmp401_register_to_temp(data->temp_low[index], data->config)); | ||
| 216 | } | ||
| 217 | |||
| 218 | static ssize_t show_temp_max(struct device *dev, | ||
| 219 | struct device_attribute *devattr, char *buf) | ||
| 220 | { | ||
| 221 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 222 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 223 | |||
| 224 | return sprintf(buf, "%d\n", | ||
| 225 | tmp401_register_to_temp(data->temp_high[index], data->config)); | ||
| 226 | } | ||
| 227 | |||
| 228 | static ssize_t show_temp_crit(struct device *dev, | ||
| 229 | struct device_attribute *devattr, char *buf) | ||
| 230 | { | ||
| 231 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 232 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 233 | |||
| 234 | return sprintf(buf, "%d\n", | ||
| 235 | tmp401_crit_register_to_temp(data->temp_crit[index], | ||
| 236 | data->config)); | ||
| 237 | } | ||
| 238 | |||
| 239 | static ssize_t show_temp_crit_hyst(struct device *dev, | ||
| 240 | struct device_attribute *devattr, char *buf) | ||
| 241 | { | ||
| 242 | int temp, index = to_sensor_dev_attr(devattr)->index; | ||
| 243 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 244 | |||
| 245 | mutex_lock(&data->update_lock); | ||
| 246 | temp = tmp401_crit_register_to_temp(data->temp_crit[index], | ||
| 247 | data->config); | ||
| 248 | temp -= data->temp_crit_hyst * 1000; | ||
| 249 | mutex_unlock(&data->update_lock); | ||
| 250 | |||
| 251 | return sprintf(buf, "%d\n", temp); | ||
| 252 | } | ||
| 253 | |||
| 254 | static ssize_t show_temp_lowest(struct device *dev, | ||
| 255 | struct device_attribute *devattr, char *buf) | ||
| 256 | { | ||
| 257 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 258 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 259 | |||
| 260 | return sprintf(buf, "%d\n", | ||
| 261 | tmp401_register_to_temp(data->temp_lowest[index], | ||
| 262 | data->config)); | ||
| 263 | } | ||
| 264 | |||
| 265 | static ssize_t show_temp_highest(struct device *dev, | ||
| 266 | struct device_attribute *devattr, char *buf) | ||
| 267 | { | ||
| 268 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 269 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 270 | |||
| 271 | return sprintf(buf, "%d\n", | ||
| 272 | tmp401_register_to_temp(data->temp_highest[index], | ||
| 273 | data->config)); | ||
| 274 | } | ||
| 275 | |||
| 276 | static ssize_t show_status(struct device *dev, | ||
| 277 | struct device_attribute *devattr, char *buf) | ||
| 278 | { | ||
| 279 | int mask = to_sensor_dev_attr(devattr)->index; | ||
| 280 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 281 | |||
| 282 | if (data->status & mask) | ||
| 283 | return sprintf(buf, "1\n"); | ||
| 284 | else | ||
| 285 | return sprintf(buf, "0\n"); | ||
| 286 | } | ||
| 287 | |||
| 288 | static ssize_t store_temp_min(struct device *dev, struct device_attribute | ||
| 289 | *devattr, const char *buf, size_t count) | ||
| 290 | { | ||
| 291 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 292 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 293 | long val; | ||
| 294 | u16 reg; | ||
| 295 | |||
| 296 | if (strict_strtol(buf, 10, &val)) | ||
| 297 | return -EINVAL; | ||
| 298 | |||
| 299 | reg = tmp401_temp_to_register(val, data->config); | ||
| 300 | |||
| 301 | mutex_lock(&data->update_lock); | ||
| 302 | |||
| 303 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 304 | TMP401_TEMP_LOW_LIMIT_MSB_WRITE[index], reg >> 8); | ||
| 305 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 306 | TMP401_TEMP_LOW_LIMIT_LSB[index], reg & 0xFF); | ||
| 307 | |||
| 308 | data->temp_low[index] = reg; | ||
| 309 | |||
| 310 | mutex_unlock(&data->update_lock); | ||
| 311 | |||
| 312 | return count; | ||
| 313 | } | ||
| 314 | |||
| 315 | static ssize_t store_temp_max(struct device *dev, struct device_attribute | ||
| 316 | *devattr, const char *buf, size_t count) | ||
| 317 | { | ||
| 318 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 319 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 320 | long val; | ||
| 321 | u16 reg; | ||
| 322 | |||
| 323 | if (strict_strtol(buf, 10, &val)) | ||
| 324 | return -EINVAL; | ||
| 325 | |||
| 326 | reg = tmp401_temp_to_register(val, data->config); | ||
| 327 | |||
| 328 | mutex_lock(&data->update_lock); | ||
| 329 | |||
| 330 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 331 | TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[index], reg >> 8); | ||
| 332 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 333 | TMP401_TEMP_HIGH_LIMIT_LSB[index], reg & 0xFF); | ||
| 334 | |||
| 335 | data->temp_high[index] = reg; | ||
| 336 | |||
| 337 | mutex_unlock(&data->update_lock); | ||
| 338 | |||
| 339 | return count; | ||
| 340 | } | ||
| 341 | |||
| 342 | static ssize_t store_temp_crit(struct device *dev, struct device_attribute | ||
| 343 | *devattr, const char *buf, size_t count) | ||
| 344 | { | ||
| 345 | int index = to_sensor_dev_attr(devattr)->index; | ||
| 346 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 347 | long val; | ||
| 348 | u8 reg; | ||
| 349 | |||
| 350 | if (strict_strtol(buf, 10, &val)) | ||
| 351 | return -EINVAL; | ||
| 352 | |||
| 353 | reg = tmp401_crit_temp_to_register(val, data->config); | ||
| 354 | |||
| 355 | mutex_lock(&data->update_lock); | ||
| 356 | |||
| 357 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 358 | TMP401_TEMP_CRIT_LIMIT[index], reg); | ||
| 359 | |||
| 360 | data->temp_crit[index] = reg; | ||
| 361 | |||
| 362 | mutex_unlock(&data->update_lock); | ||
| 363 | |||
| 364 | return count; | ||
| 365 | } | ||
| 366 | |||
| 367 | static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute | ||
| 368 | *devattr, const char *buf, size_t count) | ||
| 369 | { | ||
| 370 | int temp, index = to_sensor_dev_attr(devattr)->index; | ||
| 371 | struct tmp401_data *data = tmp401_update_device(dev); | ||
| 372 | long val; | ||
| 373 | u8 reg; | ||
| 374 | |||
| 375 | if (strict_strtol(buf, 10, &val)) | ||
| 376 | return -EINVAL; | ||
| 377 | |||
| 378 | if (data->config & TMP401_CONFIG_RANGE) | ||
| 379 | val = SENSORS_LIMIT(val, -64000, 191000); | ||
| 380 | else | ||
| 381 | val = SENSORS_LIMIT(val, 0, 127000); | ||
| 382 | |||
| 383 | mutex_lock(&data->update_lock); | ||
| 384 | temp = tmp401_crit_register_to_temp(data->temp_crit[index], | ||
| 385 | data->config); | ||
| 386 | val = SENSORS_LIMIT(val, temp - 255000, temp); | ||
| 387 | reg = ((temp - val) + 500) / 1000; | ||
| 388 | |||
| 389 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 390 | TMP401_TEMP_CRIT_HYST, reg); | ||
| 391 | |||
| 392 | data->temp_crit_hyst = reg; | ||
| 393 | |||
| 394 | mutex_unlock(&data->update_lock); | ||
| 395 | |||
| 396 | return count; | ||
| 397 | } | ||
| 398 | |||
| 399 | /* | ||
| 400 | * Resets the historical measurements of minimum and maximum temperatures. | ||
| 401 | * This is done by writing any value to any of the minimum/maximum registers | ||
| 402 | * (0x30-0x37). | ||
| 403 | */ | ||
| 404 | static ssize_t reset_temp_history(struct device *dev, | ||
| 405 | struct device_attribute *devattr, const char *buf, size_t count) | ||
| 406 | { | ||
| 407 | long val; | ||
| 408 | |||
| 409 | if (strict_strtol(buf, 10, &val)) | ||
| 410 | return -EINVAL; | ||
| 411 | |||
| 412 | if (val != 1) { | ||
| 413 | dev_err(dev, "temp_reset_history value %ld not" | ||
| 414 | " supported. Use 1 to reset the history!\n", val); | ||
| 415 | return -EINVAL; | ||
| 416 | } | ||
| 417 | i2c_smbus_write_byte_data(to_i2c_client(dev), | ||
| 418 | TMP411_TEMP_LOWEST_MSB[0], val); | ||
| 419 | |||
| 420 | return count; | ||
| 421 | } | ||
| 422 | |||
| 423 | static struct sensor_device_attribute tmp401_attr[] = { | ||
| 424 | SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0), | ||
| 425 | SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0), | ||
| 426 | SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0), | ||
| 427 | SENSOR_ATTR(temp1_crit, 0644, show_temp_crit, store_temp_crit, 0), | ||
| 428 | SENSOR_ATTR(temp1_crit_hyst, 0644, show_temp_crit_hyst, | ||
| 429 | store_temp_crit_hyst, 0), | ||
| 430 | SENSOR_ATTR(temp1_min_alarm, 0444, show_status, NULL, | ||
| 431 | TMP401_STATUS_LOCAL_LOW), | ||
| 432 | SENSOR_ATTR(temp1_max_alarm, 0444, show_status, NULL, | ||
| 433 | TMP401_STATUS_LOCAL_HIGH), | ||
| 434 | SENSOR_ATTR(temp1_crit_alarm, 0444, show_status, NULL, | ||
| 435 | TMP401_STATUS_LOCAL_CRIT), | ||
| 436 | SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1), | ||
| 437 | SENSOR_ATTR(temp2_min, 0644, show_temp_min, store_temp_min, 1), | ||
| 438 | SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1), | ||
| 439 | SENSOR_ATTR(temp2_crit, 0644, show_temp_crit, store_temp_crit, 1), | ||
| 440 | SENSOR_ATTR(temp2_crit_hyst, 0444, show_temp_crit_hyst, NULL, 1), | ||
| 441 | SENSOR_ATTR(temp2_fault, 0444, show_status, NULL, | ||
| 442 | TMP401_STATUS_REMOTE_OPEN), | ||
| 443 | SENSOR_ATTR(temp2_min_alarm, 0444, show_status, NULL, | ||
| 444 | TMP401_STATUS_REMOTE_LOW), | ||
| 445 | SENSOR_ATTR(temp2_max_alarm, 0444, show_status, NULL, | ||
| 446 | TMP401_STATUS_REMOTE_HIGH), | ||
| 447 | SENSOR_ATTR(temp2_crit_alarm, 0444, show_status, NULL, | ||
| 448 | TMP401_STATUS_REMOTE_CRIT), | ||
| 449 | }; | ||
| 450 | |||
| 451 | /* | ||
| 452 | * Additional features of the TMP411 chip. | ||
| 453 | * The TMP411 stores the minimum and maximum | ||
| 454 | * temperature measured since power-on, chip-reset, or | ||
| 455 | * minimum and maximum register reset for both the local | ||
| 456 | * and remote channels. | ||
| 457 | */ | ||
| 458 | static struct sensor_device_attribute tmp411_attr[] = { | ||
| 459 | SENSOR_ATTR(temp1_highest, 0444, show_temp_highest, NULL, 0), | ||
| 460 | SENSOR_ATTR(temp1_lowest, 0444, show_temp_lowest, NULL, 0), | ||
| 461 | SENSOR_ATTR(temp2_highest, 0444, show_temp_highest, NULL, 1), | ||
| 462 | SENSOR_ATTR(temp2_lowest, 0444, show_temp_lowest, NULL, 1), | ||
| 463 | SENSOR_ATTR(temp_reset_history, 0200, NULL, reset_temp_history, 0), | ||
| 464 | }; | ||
| 465 | |||
| 466 | /* | ||
| 467 | * Begin non sysfs callback code (aka Real code) | ||
| 468 | */ | ||
| 469 | |||
| 470 | static void tmp401_init_client(struct i2c_client *client) | ||
| 471 | { | ||
| 472 | int config, config_orig; | ||
| 473 | |||
| 474 | /* Set the conversion rate to 2 Hz */ | ||
| 475 | i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); | ||
| 476 | |||
| 477 | /* Start conversions (disable shutdown if necessary) */ | ||
| 478 | config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); | ||
| 479 | if (config < 0) { | ||
| 480 | dev_warn(&client->dev, "Initialization failed!\n"); | ||
| 481 | return; | ||
| 482 | } | ||
| 483 | |||
| 484 | config_orig = config; | ||
| 485 | config &= ~TMP401_CONFIG_SHUTDOWN; | ||
| 486 | |||
| 487 | if (config != config_orig) | ||
| 488 | i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config); | ||
| 489 | } | ||
| 490 | |||
| 491 | static int tmp401_detect(struct i2c_client *client, int kind, | ||
| 492 | struct i2c_board_info *info) | ||
| 493 | { | ||
| 494 | struct i2c_adapter *adapter = client->adapter; | ||
| 495 | |||
| 496 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 497 | return -ENODEV; | ||
| 498 | |||
| 499 | /* Detect and identify the chip */ | ||
| 500 | if (kind <= 0) { | ||
| 501 | u8 reg; | ||
| 502 | |||
| 503 | reg = i2c_smbus_read_byte_data(client, | ||
| 504 | TMP401_MANUFACTURER_ID_REG); | ||
| 505 | if (reg != TMP401_MANUFACTURER_ID) | ||
| 506 | return -ENODEV; | ||
| 507 | |||
| 508 | reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG); | ||
| 509 | |||
| 510 | switch (reg) { | ||
| 511 | case TMP401_DEVICE_ID: | ||
| 512 | kind = tmp401; | ||
| 513 | break; | ||
| 514 | case TMP411_DEVICE_ID: | ||
| 515 | kind = tmp411; | ||
| 516 | break; | ||
| 517 | default: | ||
| 518 | return -ENODEV; | ||
| 519 | } | ||
| 520 | |||
| 521 | reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); | ||
| 522 | if (reg & 0x1b) | ||
| 523 | return -ENODEV; | ||
| 524 | |||
| 525 | reg = i2c_smbus_read_byte_data(client, | ||
| 526 | TMP401_CONVERSION_RATE_READ); | ||
| 527 | /* Datasheet says: 0x1-0x6 */ | ||
| 528 | if (reg > 15) | ||
| 529 | return -ENODEV; | ||
| 530 | } | ||
| 531 | strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE); | ||
| 532 | |||
| 533 | return 0; | ||
| 534 | } | ||
| 535 | |||
| 536 | static int tmp401_probe(struct i2c_client *client, | ||
| 537 | const struct i2c_device_id *id) | ||
| 538 | { | ||
| 539 | int i, err = 0; | ||
| 540 | struct tmp401_data *data; | ||
| 541 | const char *names[] = { "TMP401", "TMP411" }; | ||
| 542 | |||
| 543 | data = kzalloc(sizeof(struct tmp401_data), GFP_KERNEL); | ||
| 544 | if (!data) | ||
| 545 | return -ENOMEM; | ||
| 546 | |||
| 547 | i2c_set_clientdata(client, data); | ||
| 548 | mutex_init(&data->update_lock); | ||
| 549 | data->kind = id->driver_data; | ||
| 550 | |||
| 551 | /* Initialize the TMP401 chip */ | ||
| 552 | tmp401_init_client(client); | ||
| 553 | |||
| 554 | /* Register sysfs hooks */ | ||
| 555 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) { | ||
| 556 | err = device_create_file(&client->dev, | ||
| 557 | &tmp401_attr[i].dev_attr); | ||
| 558 | if (err) | ||
| 559 | goto exit_remove; | ||
| 560 | } | ||
| 561 | |||
| 562 | /* Register aditional tmp411 sysfs hooks */ | ||
| 563 | if (data->kind == tmp411) { | ||
| 564 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) { | ||
| 565 | err = device_create_file(&client->dev, | ||
| 566 | &tmp411_attr[i].dev_attr); | ||
| 567 | if (err) | ||
| 568 | goto exit_remove; | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 572 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
| 573 | if (IS_ERR(data->hwmon_dev)) { | ||
| 574 | err = PTR_ERR(data->hwmon_dev); | ||
| 575 | data->hwmon_dev = NULL; | ||
| 576 | goto exit_remove; | ||
| 577 | } | ||
| 578 | |||
| 579 | dev_info(&client->dev, "Detected TI %s chip\n", | ||
| 580 | names[data->kind - 1]); | ||
| 581 | |||
| 582 | return 0; | ||
| 583 | |||
| 584 | exit_remove: | ||
| 585 | tmp401_remove(client); /* will also free data for us */ | ||
| 586 | return err; | ||
| 587 | } | ||
| 588 | |||
| 589 | static int tmp401_remove(struct i2c_client *client) | ||
| 590 | { | ||
| 591 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
| 592 | int i; | ||
| 593 | |||
| 594 | if (data->hwmon_dev) | ||
| 595 | hwmon_device_unregister(data->hwmon_dev); | ||
| 596 | |||
| 597 | for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) | ||
| 598 | device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); | ||
| 599 | |||
| 600 | if (data->kind == tmp411) { | ||
| 601 | for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) | ||
| 602 | device_remove_file(&client->dev, | ||
| 603 | &tmp411_attr[i].dev_attr); | ||
| 604 | } | ||
| 605 | |||
| 606 | kfree(data); | ||
| 607 | return 0; | ||
| 608 | } | ||
| 609 | |||
| 610 | static struct tmp401_data *tmp401_update_device_reg16( | ||
| 611 | struct i2c_client *client, struct tmp401_data *data) | ||
| 612 | { | ||
| 613 | int i; | ||
| 614 | |||
| 615 | for (i = 0; i < 2; i++) { | ||
| 616 | /* | ||
| 617 | * High byte must be read first immediately followed | ||
| 618 | * by the low byte | ||
| 619 | */ | ||
| 620 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
| 621 | TMP401_TEMP_MSB[i]) << 8; | ||
| 622 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
| 623 | TMP401_TEMP_LSB[i]); | ||
| 624 | data->temp_low[i] = i2c_smbus_read_byte_data(client, | ||
| 625 | TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; | ||
| 626 | data->temp_low[i] |= i2c_smbus_read_byte_data(client, | ||
| 627 | TMP401_TEMP_LOW_LIMIT_LSB[i]); | ||
| 628 | data->temp_high[i] = i2c_smbus_read_byte_data(client, | ||
| 629 | TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; | ||
| 630 | data->temp_high[i] |= i2c_smbus_read_byte_data(client, | ||
| 631 | TMP401_TEMP_HIGH_LIMIT_LSB[i]); | ||
| 632 | data->temp_crit[i] = i2c_smbus_read_byte_data(client, | ||
| 633 | TMP401_TEMP_CRIT_LIMIT[i]); | ||
| 634 | |||
| 635 | if (data->kind == tmp411) { | ||
| 636 | data->temp_lowest[i] = i2c_smbus_read_byte_data(client, | ||
| 637 | TMP411_TEMP_LOWEST_MSB[i]) << 8; | ||
| 638 | data->temp_lowest[i] |= i2c_smbus_read_byte_data( | ||
| 639 | client, TMP411_TEMP_LOWEST_LSB[i]); | ||
| 640 | |||
| 641 | data->temp_highest[i] = i2c_smbus_read_byte_data( | ||
| 642 | client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; | ||
| 643 | data->temp_highest[i] |= i2c_smbus_read_byte_data( | ||
| 644 | client, TMP411_TEMP_HIGHEST_LSB[i]); | ||
| 645 | } | ||
| 646 | } | ||
| 647 | return data; | ||
| 648 | } | ||
| 649 | |||
| 650 | static struct tmp401_data *tmp401_update_device(struct device *dev) | ||
| 651 | { | ||
| 652 | struct i2c_client *client = to_i2c_client(dev); | ||
| 653 | struct tmp401_data *data = i2c_get_clientdata(client); | ||
| 654 | |||
| 655 | mutex_lock(&data->update_lock); | ||
| 656 | |||
| 657 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
| 658 | data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); | ||
| 659 | data->config = i2c_smbus_read_byte_data(client, | ||
| 660 | TMP401_CONFIG_READ); | ||
| 661 | tmp401_update_device_reg16(client, data); | ||
| 662 | |||
| 663 | data->temp_crit_hyst = i2c_smbus_read_byte_data(client, | ||
| 664 | TMP401_TEMP_CRIT_HYST); | ||
| 665 | |||
| 666 | data->last_updated = jiffies; | ||
| 667 | data->valid = 1; | ||
| 668 | } | ||
| 669 | |||
| 670 | mutex_unlock(&data->update_lock); | ||
| 671 | |||
| 672 | return data; | ||
| 673 | } | ||
| 674 | |||
| 675 | static int __init tmp401_init(void) | ||
| 676 | { | ||
| 677 | return i2c_add_driver(&tmp401_driver); | ||
| 678 | } | ||
| 679 | |||
| 680 | static void __exit tmp401_exit(void) | ||
| 681 | { | ||
| 682 | i2c_del_driver(&tmp401_driver); | ||
| 683 | } | ||
| 684 | |||
| 685 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
| 686 | MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver"); | ||
| 687 | MODULE_LICENSE("GPL"); | ||
| 688 | |||
| 689 | module_init(tmp401_init); | ||
| 690 | module_exit(tmp401_exit); | ||
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index e64b42058b21..0e9746913d2b 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 | 36 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 |
| 37 | 0x8860 0xa1 | 37 | 0x8860 0xa1 |
| 38 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | 38 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 |
| 39 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 | ||
| 39 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 | 40 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 |
| 40 | */ | 41 | */ |
| 41 | 42 | ||
| @@ -53,12 +54,13 @@ | |||
| 53 | #include <asm/io.h> | 54 | #include <asm/io.h> |
| 54 | #include "lm75.h" | 55 | #include "lm75.h" |
| 55 | 56 | ||
| 56 | enum kinds { w83627ehf, w83627dhg, w83667hg }; | 57 | enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg }; |
| 57 | 58 | ||
| 58 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ | 59 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
| 59 | static const char * w83627ehf_device_names[] = { | 60 | static const char * w83627ehf_device_names[] = { |
| 60 | "w83627ehf", | 61 | "w83627ehf", |
| 61 | "w83627dhg", | 62 | "w83627dhg", |
| 63 | "w83627dhg", | ||
| 62 | "w83667hg", | 64 | "w83667hg", |
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| @@ -86,6 +88,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); | |||
| 86 | #define SIO_W83627EHF_ID 0x8850 | 88 | #define SIO_W83627EHF_ID 0x8850 |
| 87 | #define SIO_W83627EHG_ID 0x8860 | 89 | #define SIO_W83627EHG_ID 0x8860 |
| 88 | #define SIO_W83627DHG_ID 0xa020 | 90 | #define SIO_W83627DHG_ID 0xa020 |
| 91 | #define SIO_W83627DHG_P_ID 0xb070 | ||
| 89 | #define SIO_W83667HG_ID 0xa510 | 92 | #define SIO_W83667HG_ID 0xa510 |
| 90 | #define SIO_ID_MASK 0xFFF0 | 93 | #define SIO_ID_MASK 0xFFF0 |
| 91 | 94 | ||
| @@ -1517,6 +1520,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
| 1517 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; | 1520 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; |
| 1518 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | 1521 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; |
| 1519 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | 1522 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; |
| 1523 | static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P"; | ||
| 1520 | static const char __initdata sio_name_W83667HG[] = "W83667HG"; | 1524 | static const char __initdata sio_name_W83667HG[] = "W83667HG"; |
| 1521 | 1525 | ||
| 1522 | u16 val; | 1526 | u16 val; |
| @@ -1542,6 +1546,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
| 1542 | sio_data->kind = w83627dhg; | 1546 | sio_data->kind = w83627dhg; |
| 1543 | sio_name = sio_name_W83627DHG; | 1547 | sio_name = sio_name_W83627DHG; |
| 1544 | break; | 1548 | break; |
| 1549 | case SIO_W83627DHG_P_ID: | ||
| 1550 | sio_data->kind = w83627dhg_p; | ||
| 1551 | sio_name = sio_name_W83627DHG_P; | ||
| 1552 | break; | ||
| 1545 | case SIO_W83667HG_ID: | 1553 | case SIO_W83667HG_ID: |
| 1546 | sio_data->kind = w83667hg; | 1554 | sio_data->kind = w83667hg; |
| 1547 | sio_name = sio_name_W83667HG; | 1555 | sio_name = sio_name_W83667HG; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c8460fa9cfac..0d04d3ebfc2d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -211,7 +211,7 @@ config I2C_VIA | |||
| 211 | will be called i2c-via. | 211 | will be called i2c-via. |
| 212 | 212 | ||
| 213 | config I2C_VIAPRO | 213 | config I2C_VIAPRO |
| 214 | tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820" | 214 | tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx" |
| 215 | depends on PCI | 215 | depends on PCI |
| 216 | help | 216 | help |
| 217 | If you say yes to this option, support will be included for the VIA | 217 | If you say yes to this option, support will be included for the VIA |
| @@ -225,8 +225,8 @@ config I2C_VIAPRO | |||
| 225 | VT8237R/A/S | 225 | VT8237R/A/S |
| 226 | VT8251 | 226 | VT8251 |
| 227 | CX700 | 227 | CX700 |
| 228 | VX800 | 228 | VX800/VX820 |
| 229 | VX820 | 229 | VX855/VX875 |
| 230 | 230 | ||
| 231 | This driver can also be built as a module. If so, the module | 231 | This driver can also be built as a module. If so, the module |
| 232 | will be called i2c-viapro. | 232 | will be called i2c-viapro. |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 02e6f724b05f..54d810a4d00f 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | VT8251 0x3287 yes | 37 | VT8251 0x3287 yes |
| 38 | CX700 0x8324 yes | 38 | CX700 0x8324 yes |
| 39 | VX800/VX820 0x8353 yes | 39 | VX800/VX820 0x8353 yes |
| 40 | VX855/VX875 0x8409 yes | ||
| 40 | 41 | ||
| 41 | Note: we assume there can only be one device, with one SMBus interface. | 42 | Note: we assume there can only be one device, with one SMBus interface. |
| 42 | */ | 43 | */ |
| @@ -404,6 +405,7 @@ found: | |||
| 404 | switch (pdev->device) { | 405 | switch (pdev->device) { |
| 405 | case PCI_DEVICE_ID_VIA_CX700: | 406 | case PCI_DEVICE_ID_VIA_CX700: |
| 406 | case PCI_DEVICE_ID_VIA_VX800: | 407 | case PCI_DEVICE_ID_VIA_VX800: |
| 408 | case PCI_DEVICE_ID_VIA_VX855: | ||
| 407 | case PCI_DEVICE_ID_VIA_8251: | 409 | case PCI_DEVICE_ID_VIA_8251: |
| 408 | case PCI_DEVICE_ID_VIA_8237: | 410 | case PCI_DEVICE_ID_VIA_8237: |
| 409 | case PCI_DEVICE_ID_VIA_8237A: | 411 | case PCI_DEVICE_ID_VIA_8237A: |
| @@ -469,6 +471,8 @@ static struct pci_device_id vt596_ids[] = { | |||
| 469 | .driver_data = SMBBA3 }, | 471 | .driver_data = SMBBA3 }, |
| 470 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800), | 472 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800), |
| 471 | .driver_data = SMBBA3 }, | 473 | .driver_data = SMBBA3 }, |
| 474 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855), | ||
| 475 | .driver_data = SMBBA3 }, | ||
| 472 | { 0, } | 476 | { 0, } |
| 473 | }; | 477 | }; |
| 474 | 478 | ||
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c index 1a474acc0ddd..7663d57833a0 100644 --- a/drivers/i2c/busses/i2c-voodoo3.c +++ b/drivers/i2c/busses/i2c-voodoo3.c | |||
| @@ -163,7 +163,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = { | |||
| 163 | 163 | ||
| 164 | static struct i2c_adapter voodoo3_i2c_adapter = { | 164 | static struct i2c_adapter voodoo3_i2c_adapter = { |
| 165 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
| 166 | .class = I2C_CLASS_TV_ANALOG, | ||
| 167 | .name = "I2C Voodoo3/Banshee adapter", | 166 | .name = "I2C Voodoo3/Banshee adapter", |
| 168 | .algo_data = &voo_i2c_bit_data, | 167 | .algo_data = &voo_i2c_bit_data, |
| 169 | }; | 168 | }; |
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 8f8c81eb0aee..02d746c9c474 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig | |||
| @@ -64,21 +64,6 @@ config SENSORS_PCA9539 | |||
| 64 | This driver is deprecated and will be dropped soon. Use | 64 | This driver is deprecated and will be dropped soon. Use |
| 65 | drivers/gpio/pca953x.c instead. | 65 | drivers/gpio/pca953x.c instead. |
| 66 | 66 | ||
| 67 | config SENSORS_MAX6875 | ||
| 68 | tristate "Maxim MAX6875 Power supply supervisor" | ||
| 69 | depends on EXPERIMENTAL | ||
| 70 | help | ||
| 71 | If you say yes here you get support for the Maxim MAX6875 | ||
| 72 | EEPROM-programmable, quad power-supply sequencer/supervisor. | ||
| 73 | |||
| 74 | This provides an interface to program the EEPROM and reset the chip. | ||
| 75 | |||
| 76 | This driver also supports the Maxim MAX6874 hex power-supply | ||
| 77 | sequencer/supervisor if found at a compatible address. | ||
| 78 | |||
| 79 | This driver can also be built as a module. If so, the module | ||
| 80 | will be called max6875. | ||
| 81 | |||
| 82 | config SENSORS_TSL2550 | 67 | config SENSORS_TSL2550 |
| 83 | tristate "Taos TSL2550 ambient light sensor" | 68 | tristate "Taos TSL2550 ambient light sensor" |
| 84 | depends on EXPERIMENTAL | 69 | depends on EXPERIMENTAL |
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 55a376037183..f4680d16ee34 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | # | 11 | # |
| 12 | 12 | ||
| 13 | obj-$(CONFIG_DS1682) += ds1682.o | 13 | obj-$(CONFIG_DS1682) += ds1682.o |
| 14 | obj-$(CONFIG_SENSORS_MAX6875) += max6875.o | ||
| 15 | obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o | 14 | obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o |
| 16 | obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o | 15 | obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o |
| 17 | obj-$(CONFIG_PCF8575) += pcf8575.o | 16 | obj-$(CONFIG_PCF8575) += pcf8575.o |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 85e2e919d1cd..5ed622ee65c3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 32 | #include <linux/platform_device.h> | ||
| 33 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 34 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
| 35 | #include <linux/hardirq.h> | 34 | #include <linux/hardirq.h> |
| @@ -451,16 +450,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
| 451 | 450 | ||
| 452 | mutex_lock(&core_lock); | 451 | mutex_lock(&core_lock); |
| 453 | 452 | ||
| 454 | /* Add the adapter to the driver core. | ||
| 455 | * If the parent pointer is not set up, | ||
| 456 | * we add this adapter to the host bus. | ||
| 457 | */ | ||
| 458 | if (adap->dev.parent == NULL) { | ||
| 459 | adap->dev.parent = &platform_bus; | ||
| 460 | pr_debug("I2C adapter driver [%s] forgot to specify " | ||
| 461 | "physical device\n", adap->name); | ||
| 462 | } | ||
| 463 | |||
| 464 | /* Set default timeout to 1 second if not already set */ | 453 | /* Set default timeout to 1 second if not already set */ |
| 465 | if (adap->timeout == 0) | 454 | if (adap->timeout == 0) |
| 466 | adap->timeout = HZ; | 455 | adap->timeout = HZ; |
| @@ -1022,7 +1011,8 @@ module_exit(i2c_exit); | |||
| 1022 | */ | 1011 | */ |
| 1023 | int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | 1012 | int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) |
| 1024 | { | 1013 | { |
| 1025 | int ret; | 1014 | unsigned long orig_jiffies; |
| 1015 | int ret, try; | ||
| 1026 | 1016 | ||
| 1027 | /* REVISIT the fault reporting model here is weak: | 1017 | /* REVISIT the fault reporting model here is weak: |
| 1028 | * | 1018 | * |
| @@ -1060,7 +1050,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
| 1060 | mutex_lock_nested(&adap->bus_lock, adap->level); | 1050 | mutex_lock_nested(&adap->bus_lock, adap->level); |
| 1061 | } | 1051 | } |
| 1062 | 1052 | ||
| 1063 | ret = adap->algo->master_xfer(adap,msgs,num); | 1053 | /* Retry automatically on arbitration loss */ |
| 1054 | orig_jiffies = jiffies; | ||
| 1055 | for (ret = 0, try = 0; try <= adap->retries; try++) { | ||
| 1056 | ret = adap->algo->master_xfer(adap, msgs, num); | ||
| 1057 | if (ret != -EAGAIN) | ||
| 1058 | break; | ||
| 1059 | if (time_after(jiffies, orig_jiffies + adap->timeout)) | ||
| 1060 | break; | ||
| 1061 | } | ||
| 1064 | mutex_unlock(&adap->bus_lock); | 1062 | mutex_unlock(&adap->bus_lock); |
| 1065 | 1063 | ||
| 1066 | return ret; | 1064 | return ret; |
| @@ -1509,7 +1507,7 @@ struct i2c_adapter* i2c_get_adapter(int id) | |||
| 1509 | struct i2c_adapter *adapter; | 1507 | struct i2c_adapter *adapter; |
| 1510 | 1508 | ||
| 1511 | mutex_lock(&core_lock); | 1509 | mutex_lock(&core_lock); |
| 1512 | adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); | 1510 | adapter = idr_find(&i2c_adapter_idr, id); |
| 1513 | if (adapter && !try_module_get(adapter->owner)) | 1511 | if (adapter && !try_module_get(adapter->owner)) |
| 1514 | adapter = NULL; | 1512 | adapter = NULL; |
| 1515 | 1513 | ||
| @@ -1995,14 +1993,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
| 1995 | char read_write, u8 command, int protocol, | 1993 | char read_write, u8 command, int protocol, |
| 1996 | union i2c_smbus_data *data) | 1994 | union i2c_smbus_data *data) |
| 1997 | { | 1995 | { |
| 1996 | unsigned long orig_jiffies; | ||
| 1997 | int try; | ||
| 1998 | s32 res; | 1998 | s32 res; |
| 1999 | 1999 | ||
| 2000 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | 2000 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; |
| 2001 | 2001 | ||
| 2002 | if (adapter->algo->smbus_xfer) { | 2002 | if (adapter->algo->smbus_xfer) { |
| 2003 | mutex_lock(&adapter->bus_lock); | 2003 | mutex_lock(&adapter->bus_lock); |
| 2004 | res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, | 2004 | |
| 2005 | command, protocol, data); | 2005 | /* Retry automatically on arbitration loss */ |
| 2006 | orig_jiffies = jiffies; | ||
| 2007 | for (res = 0, try = 0; try <= adapter->retries; try++) { | ||
| 2008 | res = adapter->algo->smbus_xfer(adapter, addr, flags, | ||
| 2009 | read_write, command, | ||
| 2010 | protocol, data); | ||
| 2011 | if (res != -EAGAIN) | ||
| 2012 | break; | ||
| 2013 | if (time_after(jiffies, | ||
| 2014 | orig_jiffies + adapter->timeout)) | ||
| 2015 | break; | ||
| 2016 | } | ||
| 2006 | mutex_unlock(&adapter->bus_lock); | 2017 | mutex_unlock(&adapter->bus_lock); |
| 2007 | } else | 2018 | } else |
| 2008 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, | 2019 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, |
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 0ddf9044948a..fde377c60cca 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
| @@ -72,7 +72,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations " | |||
| 72 | "(default 0)"); | 72 | "(default 0)"); |
| 73 | 73 | ||
| 74 | struct thermostat { | 74 | struct thermostat { |
| 75 | struct i2c_client clt; | 75 | struct i2c_client *clt; |
| 76 | u8 temps[3]; | 76 | u8 temps[3]; |
| 77 | u8 cached_temp[3]; | 77 | u8 cached_temp[3]; |
| 78 | u8 initial_limits[3]; | 78 | u8 initial_limits[3]; |
| @@ -87,9 +87,6 @@ static struct of_device * of_dev; | |||
| 87 | static struct thermostat* thermostat; | 87 | static struct thermostat* thermostat; |
| 88 | static struct task_struct *thread_therm = NULL; | 88 | static struct task_struct *thread_therm = NULL; |
| 89 | 89 | ||
| 90 | static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | ||
| 91 | int busno); | ||
| 92 | |||
| 93 | static void write_both_fan_speed(struct thermostat *th, int speed); | 90 | static void write_both_fan_speed(struct thermostat *th, int speed); |
| 94 | static void write_fan_speed(struct thermostat *th, int speed, int fan); | 91 | static void write_fan_speed(struct thermostat *th, int speed, int fan); |
| 95 | 92 | ||
| @@ -101,7 +98,7 @@ write_reg(struct thermostat* th, int reg, u8 data) | |||
| 101 | 98 | ||
| 102 | tmp[0] = reg; | 99 | tmp[0] = reg; |
| 103 | tmp[1] = data; | 100 | tmp[1] = data; |
| 104 | rc = i2c_master_send(&th->clt, (const char *)tmp, 2); | 101 | rc = i2c_master_send(th->clt, (const char *)tmp, 2); |
| 105 | if (rc < 0) | 102 | if (rc < 0) |
| 106 | return rc; | 103 | return rc; |
| 107 | if (rc != 2) | 104 | if (rc != 2) |
| @@ -116,12 +113,12 @@ read_reg(struct thermostat* th, int reg) | |||
| 116 | int rc; | 113 | int rc; |
| 117 | 114 | ||
| 118 | reg_addr = (u8)reg; | 115 | reg_addr = (u8)reg; |
| 119 | rc = i2c_master_send(&th->clt, ®_addr, 1); | 116 | rc = i2c_master_send(th->clt, ®_addr, 1); |
| 120 | if (rc < 0) | 117 | if (rc < 0) |
| 121 | return rc; | 118 | return rc; |
| 122 | if (rc != 1) | 119 | if (rc != 1) |
| 123 | return -ENODEV; | 120 | return -ENODEV; |
| 124 | rc = i2c_master_recv(&th->clt, (char *)&data, 1); | 121 | rc = i2c_master_recv(th->clt, (char *)&data, 1); |
| 125 | if (rc < 0) | 122 | if (rc < 0) |
| 126 | return rc; | 123 | return rc; |
| 127 | return data; | 124 | return data; |
| @@ -131,26 +128,36 @@ static int | |||
| 131 | attach_thermostat(struct i2c_adapter *adapter) | 128 | attach_thermostat(struct i2c_adapter *adapter) |
| 132 | { | 129 | { |
| 133 | unsigned long bus_no; | 130 | unsigned long bus_no; |
| 131 | struct i2c_board_info info; | ||
| 132 | struct i2c_client *client; | ||
| 134 | 133 | ||
| 135 | if (strncmp(adapter->name, "uni-n", 5)) | 134 | if (strncmp(adapter->name, "uni-n", 5)) |
| 136 | return -ENODEV; | 135 | return -ENODEV; |
| 137 | bus_no = simple_strtoul(adapter->name + 6, NULL, 10); | 136 | bus_no = simple_strtoul(adapter->name + 6, NULL, 10); |
| 138 | if (bus_no != therm_bus) | 137 | if (bus_no != therm_bus) |
| 139 | return -ENODEV; | 138 | return -ENODEV; |
| 140 | return attach_one_thermostat(adapter, therm_address, bus_no); | 139 | |
| 140 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 141 | strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE); | ||
| 142 | info.addr = therm_address; | ||
| 143 | client = i2c_new_device(adapter, &info); | ||
| 144 | if (!client) | ||
| 145 | return -ENODEV; | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Let i2c-core delete that device on driver removal. | ||
| 149 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
| 150 | */ | ||
| 151 | list_add_tail(&client->detected, &client->driver->clients); | ||
| 152 | return 0; | ||
| 141 | } | 153 | } |
| 142 | 154 | ||
| 143 | static int | 155 | static int |
| 144 | detach_thermostat(struct i2c_adapter *adapter) | 156 | remove_thermostat(struct i2c_client *client) |
| 145 | { | 157 | { |
| 146 | struct thermostat* th; | 158 | struct thermostat *th = i2c_get_clientdata(client); |
| 147 | int i; | 159 | int i; |
| 148 | 160 | ||
| 149 | if (thermostat == NULL) | ||
| 150 | return 0; | ||
| 151 | |||
| 152 | th = thermostat; | ||
| 153 | |||
| 154 | if (thread_therm != NULL) { | 161 | if (thread_therm != NULL) { |
| 155 | kthread_stop(thread_therm); | 162 | kthread_stop(thread_therm); |
| 156 | } | 163 | } |
| @@ -166,8 +173,6 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
| 166 | 173 | ||
| 167 | write_both_fan_speed(th, -1); | 174 | write_both_fan_speed(th, -1); |
| 168 | 175 | ||
| 169 | i2c_detach_client(&th->clt); | ||
| 170 | |||
| 171 | thermostat = NULL; | 176 | thermostat = NULL; |
| 172 | 177 | ||
| 173 | kfree(th); | 178 | kfree(th); |
| @@ -175,14 +180,6 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
| 175 | return 0; | 180 | return 0; |
| 176 | } | 181 | } |
| 177 | 182 | ||
| 178 | static struct i2c_driver thermostat_driver = { | ||
| 179 | .driver = { | ||
| 180 | .name = "therm_adt746x", | ||
| 181 | }, | ||
| 182 | .attach_adapter = attach_thermostat, | ||
| 183 | .detach_adapter = detach_thermostat, | ||
| 184 | }; | ||
| 185 | |||
| 186 | static int read_fan_speed(struct thermostat *th, u8 addr) | 183 | static int read_fan_speed(struct thermostat *th, u8 addr) |
| 187 | { | 184 | { |
| 188 | u8 tmp[2]; | 185 | u8 tmp[2]; |
| @@ -371,8 +368,8 @@ static void set_limit(struct thermostat *th, int i) | |||
| 371 | th->limits[i] = default_limits_local[i] + limit_adjust; | 368 | th->limits[i] = default_limits_local[i] + limit_adjust; |
| 372 | } | 369 | } |
| 373 | 370 | ||
| 374 | static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | 371 | static int probe_thermostat(struct i2c_client *client, |
| 375 | int busno) | 372 | const struct i2c_device_id *id) |
| 376 | { | 373 | { |
| 377 | struct thermostat* th; | 374 | struct thermostat* th; |
| 378 | int rc; | 375 | int rc; |
| @@ -385,16 +382,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
| 385 | if (!th) | 382 | if (!th) |
| 386 | return -ENOMEM; | 383 | return -ENOMEM; |
| 387 | 384 | ||
| 388 | th->clt.addr = addr; | 385 | i2c_set_clientdata(client, th); |
| 389 | th->clt.adapter = adapter; | 386 | th->clt = client; |
| 390 | th->clt.driver = &thermostat_driver; | ||
| 391 | strcpy(th->clt.name, "thermostat"); | ||
| 392 | 387 | ||
| 393 | rc = read_reg(th, 0); | 388 | rc = read_reg(th, 0); |
| 394 | if (rc < 0) { | 389 | if (rc < 0) { |
| 395 | printk(KERN_ERR "adt746x: Thermostat failed to read config " | 390 | dev_err(&client->dev, "Thermostat failed to read config!\n"); |
| 396 | "from bus %d !\n", | ||
| 397 | busno); | ||
| 398 | kfree(th); | 391 | kfree(th); |
| 399 | return -ENODEV; | 392 | return -ENODEV; |
| 400 | } | 393 | } |
| @@ -423,14 +416,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
| 423 | 416 | ||
| 424 | thermostat = th; | 417 | thermostat = th; |
| 425 | 418 | ||
| 426 | if (i2c_attach_client(&th->clt)) { | ||
| 427 | printk(KERN_INFO "adt746x: Thermostat failed to attach " | ||
| 428 | "client !\n"); | ||
| 429 | thermostat = NULL; | ||
| 430 | kfree(th); | ||
| 431 | return -ENODEV; | ||
| 432 | } | ||
| 433 | |||
| 434 | /* be sure to really write fan speed the first time */ | 419 | /* be sure to really write fan speed the first time */ |
| 435 | th->last_speed[0] = -2; | 420 | th->last_speed[0] = -2; |
| 436 | th->last_speed[1] = -2; | 421 | th->last_speed[1] = -2; |
| @@ -456,6 +441,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
| 456 | return 0; | 441 | return 0; |
| 457 | } | 442 | } |
| 458 | 443 | ||
| 444 | static const struct i2c_device_id therm_adt746x_id[] = { | ||
| 445 | { "therm_adt746x", 0 }, | ||
| 446 | { } | ||
| 447 | }; | ||
| 448 | |||
| 449 | static struct i2c_driver thermostat_driver = { | ||
| 450 | .driver = { | ||
| 451 | .name = "therm_adt746x", | ||
| 452 | }, | ||
| 453 | .attach_adapter = attach_thermostat, | ||
| 454 | .probe = probe_thermostat, | ||
| 455 | .remove = remove_thermostat, | ||
| 456 | .id_table = therm_adt746x_id, | ||
| 457 | }; | ||
| 458 | |||
| 459 | /* | 459 | /* |
| 460 | * Now, unfortunately, sysfs doesn't give us a nice void * we could | 460 | * Now, unfortunately, sysfs doesn't give us a nice void * we could |
| 461 | * pass around to the attribute functions, so we don't really have | 461 | * pass around to the attribute functions, so we don't really have |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 817607e2af6a..a028598af2d3 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
| @@ -287,22 +287,6 @@ struct fcu_fan_table fcu_fans[] = { | |||
| 287 | }; | 287 | }; |
| 288 | 288 | ||
| 289 | /* | 289 | /* |
| 290 | * i2c_driver structure to attach to the host i2c controller | ||
| 291 | */ | ||
| 292 | |||
| 293 | static int therm_pm72_attach(struct i2c_adapter *adapter); | ||
| 294 | static int therm_pm72_detach(struct i2c_adapter *adapter); | ||
| 295 | |||
| 296 | static struct i2c_driver therm_pm72_driver = | ||
| 297 | { | ||
| 298 | .driver = { | ||
| 299 | .name = "therm_pm72", | ||
| 300 | }, | ||
| 301 | .attach_adapter = therm_pm72_attach, | ||
| 302 | .detach_adapter = therm_pm72_detach, | ||
| 303 | }; | ||
| 304 | |||
| 305 | /* | ||
| 306 | * Utility function to create an i2c_client structure and | 290 | * Utility function to create an i2c_client structure and |
| 307 | * attach it to one of u3 adapters | 291 | * attach it to one of u3 adapters |
| 308 | */ | 292 | */ |
| @@ -310,6 +294,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) | |||
| 310 | { | 294 | { |
| 311 | struct i2c_client *clt; | 295 | struct i2c_client *clt; |
| 312 | struct i2c_adapter *adap; | 296 | struct i2c_adapter *adap; |
| 297 | struct i2c_board_info info; | ||
| 313 | 298 | ||
| 314 | if (id & 0x200) | 299 | if (id & 0x200) |
| 315 | adap = k2; | 300 | adap = k2; |
| @@ -320,31 +305,21 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) | |||
| 320 | if (adap == NULL) | 305 | if (adap == NULL) |
| 321 | return NULL; | 306 | return NULL; |
| 322 | 307 | ||
| 323 | clt = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 308 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 324 | if (clt == NULL) | 309 | info.addr = (id >> 1) & 0x7f; |
| 325 | return NULL; | 310 | strlcpy(info.type, "therm_pm72", I2C_NAME_SIZE); |
| 326 | 311 | clt = i2c_new_device(adap, &info); | |
| 327 | clt->addr = (id >> 1) & 0x7f; | 312 | if (!clt) { |
| 328 | clt->adapter = adap; | ||
| 329 | clt->driver = &therm_pm72_driver; | ||
| 330 | strncpy(clt->name, name, I2C_NAME_SIZE-1); | ||
| 331 | |||
| 332 | if (i2c_attach_client(clt)) { | ||
| 333 | printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id); | 313 | printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id); |
| 334 | kfree(clt); | ||
| 335 | return NULL; | 314 | return NULL; |
| 336 | } | 315 | } |
| 337 | return clt; | ||
| 338 | } | ||
| 339 | 316 | ||
| 340 | /* | 317 | /* |
| 341 | * Utility function to get rid of the i2c_client structure | 318 | * Let i2c-core delete that device on driver removal. |
| 342 | * (will also detach from the adapter hopepfully) | 319 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 343 | */ | 320 | */ |
| 344 | static void detach_i2c_chip(struct i2c_client *clt) | 321 | list_add_tail(&clt->detected, &clt->driver->clients); |
| 345 | { | 322 | return clt; |
| 346 | i2c_detach_client(clt); | ||
| 347 | kfree(clt); | ||
| 348 | } | 323 | } |
| 349 | 324 | ||
| 350 | /* | 325 | /* |
| @@ -1203,8 +1178,6 @@ static int init_cpu_state(struct cpu_pid_state *state, int index) | |||
| 1203 | 1178 | ||
| 1204 | return 0; | 1179 | return 0; |
| 1205 | fail: | 1180 | fail: |
| 1206 | if (state->monitor) | ||
| 1207 | detach_i2c_chip(state->monitor); | ||
| 1208 | state->monitor = NULL; | 1181 | state->monitor = NULL; |
| 1209 | 1182 | ||
| 1210 | return -ENODEV; | 1183 | return -ENODEV; |
| @@ -1232,7 +1205,6 @@ static void dispose_cpu_state(struct cpu_pid_state *state) | |||
| 1232 | device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); | 1205 | device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); |
| 1233 | } | 1206 | } |
| 1234 | 1207 | ||
| 1235 | detach_i2c_chip(state->monitor); | ||
| 1236 | state->monitor = NULL; | 1208 | state->monitor = NULL; |
| 1237 | } | 1209 | } |
| 1238 | 1210 | ||
| @@ -1407,7 +1379,6 @@ static void dispose_backside_state(struct backside_pid_state *state) | |||
| 1407 | device_remove_file(&of_dev->dev, &dev_attr_backside_temperature); | 1379 | device_remove_file(&of_dev->dev, &dev_attr_backside_temperature); |
| 1408 | device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm); | 1380 | device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm); |
| 1409 | 1381 | ||
| 1410 | detach_i2c_chip(state->monitor); | ||
| 1411 | state->monitor = NULL; | 1382 | state->monitor = NULL; |
| 1412 | } | 1383 | } |
| 1413 | 1384 | ||
| @@ -1532,7 +1503,6 @@ static void dispose_drives_state(struct drives_pid_state *state) | |||
| 1532 | device_remove_file(&of_dev->dev, &dev_attr_drives_temperature); | 1503 | device_remove_file(&of_dev->dev, &dev_attr_drives_temperature); |
| 1533 | device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm); | 1504 | device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm); |
| 1534 | 1505 | ||
| 1535 | detach_i2c_chip(state->monitor); | ||
| 1536 | state->monitor = NULL; | 1506 | state->monitor = NULL; |
| 1537 | } | 1507 | } |
| 1538 | 1508 | ||
| @@ -1654,7 +1624,6 @@ static void dispose_dimms_state(struct dimm_pid_state *state) | |||
| 1654 | 1624 | ||
| 1655 | device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature); | 1625 | device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature); |
| 1656 | 1626 | ||
| 1657 | detach_i2c_chip(state->monitor); | ||
| 1658 | state->monitor = NULL; | 1627 | state->monitor = NULL; |
| 1659 | } | 1628 | } |
| 1660 | 1629 | ||
| @@ -1779,7 +1748,6 @@ static void dispose_slots_state(struct slots_pid_state *state) | |||
| 1779 | device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); | 1748 | device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); |
| 1780 | device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); | 1749 | device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); |
| 1781 | 1750 | ||
| 1782 | detach_i2c_chip(state->monitor); | ||
| 1783 | state->monitor = NULL; | 1751 | state->monitor = NULL; |
| 1784 | } | 1752 | } |
| 1785 | 1753 | ||
| @@ -2008,8 +1976,6 @@ static int attach_fcu(void) | |||
| 2008 | */ | 1976 | */ |
| 2009 | static void detach_fcu(void) | 1977 | static void detach_fcu(void) |
| 2010 | { | 1978 | { |
| 2011 | if (fcu) | ||
| 2012 | detach_i2c_chip(fcu); | ||
| 2013 | fcu = NULL; | 1979 | fcu = NULL; |
| 2014 | } | 1980 | } |
| 2015 | 1981 | ||
| @@ -2060,12 +2026,21 @@ static int therm_pm72_attach(struct i2c_adapter *adapter) | |||
| 2060 | return 0; | 2026 | return 0; |
| 2061 | } | 2027 | } |
| 2062 | 2028 | ||
| 2029 | static int therm_pm72_probe(struct i2c_client *client, | ||
| 2030 | const struct i2c_device_id *id) | ||
| 2031 | { | ||
| 2032 | /* Always succeed, the real work was done in therm_pm72_attach() */ | ||
| 2033 | return 0; | ||
| 2034 | } | ||
| 2035 | |||
| 2063 | /* | 2036 | /* |
| 2064 | * Called on every adapter when the driver or the i2c controller | 2037 | * Called when any of the devices which participates into thermal management |
| 2065 | * is going away. | 2038 | * is going away. |
| 2066 | */ | 2039 | */ |
| 2067 | static int therm_pm72_detach(struct i2c_adapter *adapter) | 2040 | static int therm_pm72_remove(struct i2c_client *client) |
| 2068 | { | 2041 | { |
| 2042 | struct i2c_adapter *adapter = client->adapter; | ||
| 2043 | |||
| 2069 | mutex_lock(&driver_lock); | 2044 | mutex_lock(&driver_lock); |
| 2070 | 2045 | ||
| 2071 | if (state != state_detached) | 2046 | if (state != state_detached) |
| @@ -2096,6 +2071,30 @@ static int therm_pm72_detach(struct i2c_adapter *adapter) | |||
| 2096 | return 0; | 2071 | return 0; |
| 2097 | } | 2072 | } |
| 2098 | 2073 | ||
| 2074 | /* | ||
| 2075 | * i2c_driver structure to attach to the host i2c controller | ||
| 2076 | */ | ||
| 2077 | |||
| 2078 | static const struct i2c_device_id therm_pm72_id[] = { | ||
| 2079 | /* | ||
| 2080 | * Fake device name, thermal management is done by several | ||
| 2081 | * chips but we don't need to differentiate between them at | ||
| 2082 | * this point. | ||
| 2083 | */ | ||
| 2084 | { "therm_pm72", 0 }, | ||
| 2085 | { } | ||
| 2086 | }; | ||
| 2087 | |||
| 2088 | static struct i2c_driver therm_pm72_driver = { | ||
| 2089 | .driver = { | ||
| 2090 | .name = "therm_pm72", | ||
| 2091 | }, | ||
| 2092 | .attach_adapter = therm_pm72_attach, | ||
| 2093 | .probe = therm_pm72_probe, | ||
| 2094 | .remove = therm_pm72_remove, | ||
| 2095 | .id_table = therm_pm72_id, | ||
| 2096 | }; | ||
| 2097 | |||
| 2099 | static int fan_check_loc_match(const char *loc, int fan) | 2098 | static int fan_check_loc_match(const char *loc, int fan) |
| 2100 | { | 2099 | { |
| 2101 | char tmp[64]; | 2100 | char tmp[64]; |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 3da0a02efd76..40023313a760 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
| @@ -48,16 +48,6 @@ | |||
| 48 | 48 | ||
| 49 | #define LOG_TEMP 0 /* continously log temperature */ | 49 | #define LOG_TEMP 0 /* continously log temperature */ |
| 50 | 50 | ||
| 51 | static int do_probe( struct i2c_adapter *adapter, int addr, int kind); | ||
| 52 | |||
| 53 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ | ||
| 54 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, | ||
| 55 | 0x4c, 0x4d, 0x4e, 0x4f, | ||
| 56 | 0x2c, 0x2d, 0x2e, 0x2f, | ||
| 57 | I2C_CLIENT_END }; | ||
| 58 | |||
| 59 | I2C_CLIENT_INSMOD; | ||
| 60 | |||
| 61 | static struct { | 51 | static struct { |
| 62 | volatile int running; | 52 | volatile int running; |
| 63 | struct task_struct *poll_task; | 53 | struct task_struct *poll_task; |
| @@ -315,53 +305,54 @@ static int control_loop(void *dummy) | |||
| 315 | static int | 305 | static int |
| 316 | do_attach( struct i2c_adapter *adapter ) | 306 | do_attach( struct i2c_adapter *adapter ) |
| 317 | { | 307 | { |
| 318 | int ret = 0; | 308 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ |
| 309 | static const unsigned short scan_ds1775[] = { | ||
| 310 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, | ||
| 311 | I2C_CLIENT_END | ||
| 312 | }; | ||
| 313 | static const unsigned short scan_adm1030[] = { | ||
| 314 | 0x2c, 0x2d, 0x2e, 0x2f, | ||
| 315 | I2C_CLIENT_END | ||
| 316 | }; | ||
| 319 | 317 | ||
| 320 | if( strncmp(adapter->name, "uni-n", 5) ) | 318 | if( strncmp(adapter->name, "uni-n", 5) ) |
| 321 | return 0; | 319 | return 0; |
| 322 | 320 | ||
| 323 | if( !x.running ) { | 321 | if( !x.running ) { |
| 324 | ret = i2c_probe( adapter, &addr_data, &do_probe ); | 322 | struct i2c_board_info info; |
| 323 | |||
| 324 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 325 | strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); | ||
| 326 | i2c_new_probed_device(adapter, &info, scan_ds1775); | ||
| 327 | |||
| 328 | strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); | ||
| 329 | i2c_new_probed_device(adapter, &info, scan_adm1030); | ||
| 330 | |||
| 325 | if( x.thermostat && x.fan ) { | 331 | if( x.thermostat && x.fan ) { |
| 326 | x.running = 1; | 332 | x.running = 1; |
| 327 | x.poll_task = kthread_run(control_loop, NULL, "g4fand"); | 333 | x.poll_task = kthread_run(control_loop, NULL, "g4fand"); |
| 328 | } | 334 | } |
| 329 | } | 335 | } |
| 330 | return ret; | 336 | return 0; |
| 331 | } | 337 | } |
| 332 | 338 | ||
| 333 | static int | 339 | static int |
| 334 | do_detach( struct i2c_client *client ) | 340 | do_remove(struct i2c_client *client) |
| 335 | { | 341 | { |
| 336 | int err; | 342 | if (x.running) { |
| 337 | 343 | x.running = 0; | |
| 338 | if( (err=i2c_detach_client(client)) ) | 344 | kthread_stop(x.poll_task); |
| 339 | printk(KERN_ERR "failed to detach thermostat client\n"); | 345 | x.poll_task = NULL; |
| 340 | else { | ||
| 341 | if( x.running ) { | ||
| 342 | x.running = 0; | ||
| 343 | kthread_stop(x.poll_task); | ||
| 344 | x.poll_task = NULL; | ||
| 345 | } | ||
| 346 | if( client == x.thermostat ) | ||
| 347 | x.thermostat = NULL; | ||
| 348 | else if( client == x.fan ) | ||
| 349 | x.fan = NULL; | ||
| 350 | else { | ||
| 351 | printk(KERN_ERR "g4fan: bad client\n"); | ||
| 352 | } | ||
| 353 | kfree( client ); | ||
| 354 | } | 346 | } |
| 355 | return err; | 347 | if (client == x.thermostat) |
| 356 | } | 348 | x.thermostat = NULL; |
| 349 | else if (client == x.fan) | ||
| 350 | x.fan = NULL; | ||
| 351 | else | ||
| 352 | printk(KERN_ERR "g4fan: bad client\n"); | ||
| 357 | 353 | ||
| 358 | static struct i2c_driver g4fan_driver = { | 354 | return 0; |
| 359 | .driver = { | 355 | } |
| 360 | .name = "therm_windtunnel", | ||
| 361 | }, | ||
| 362 | .attach_adapter = do_attach, | ||
| 363 | .detach_client = do_detach, | ||
| 364 | }; | ||
| 365 | 356 | ||
| 366 | static int | 357 | static int |
| 367 | attach_fan( struct i2c_client *cl ) | 358 | attach_fan( struct i2c_client *cl ) |
| @@ -374,13 +365,8 @@ attach_fan( struct i2c_client *cl ) | |||
| 374 | goto out; | 365 | goto out; |
| 375 | printk("ADM1030 fan controller [@%02x]\n", cl->addr ); | 366 | printk("ADM1030 fan controller [@%02x]\n", cl->addr ); |
| 376 | 367 | ||
| 377 | strlcpy( cl->name, "ADM1030 fan controller", sizeof(cl->name) ); | 368 | x.fan = cl; |
| 378 | |||
| 379 | if( !i2c_attach_client(cl) ) | ||
| 380 | x.fan = cl; | ||
| 381 | out: | 369 | out: |
| 382 | if( cl != x.fan ) | ||
| 383 | kfree( cl ); | ||
| 384 | return 0; | 370 | return 0; |
| 385 | } | 371 | } |
| 386 | 372 | ||
| @@ -412,39 +398,47 @@ attach_thermostat( struct i2c_client *cl ) | |||
| 412 | x.temp = temp; | 398 | x.temp = temp; |
| 413 | x.overheat_temp = os_temp; | 399 | x.overheat_temp = os_temp; |
| 414 | x.overheat_hyst = hyst_temp; | 400 | x.overheat_hyst = hyst_temp; |
| 415 | 401 | x.thermostat = cl; | |
| 416 | strlcpy( cl->name, "DS1775 thermostat", sizeof(cl->name) ); | ||
| 417 | |||
| 418 | if( !i2c_attach_client(cl) ) | ||
| 419 | x.thermostat = cl; | ||
| 420 | out: | 402 | out: |
| 421 | if( cl != x.thermostat ) | ||
| 422 | kfree( cl ); | ||
| 423 | return 0; | 403 | return 0; |
| 424 | } | 404 | } |
| 425 | 405 | ||
| 406 | enum chip { ds1775, adm1030 }; | ||
| 407 | |||
| 408 | static const struct i2c_device_id therm_windtunnel_id[] = { | ||
| 409 | { "therm_ds1775", ds1775 }, | ||
| 410 | { "therm_adm1030", adm1030 }, | ||
| 411 | { } | ||
| 412 | }; | ||
| 413 | |||
| 426 | static int | 414 | static int |
| 427 | do_probe( struct i2c_adapter *adapter, int addr, int kind ) | 415 | do_probe(struct i2c_client *cl, const struct i2c_device_id *id) |
| 428 | { | 416 | { |
| 429 | struct i2c_client *cl; | 417 | struct i2c_adapter *adapter = cl->adapter; |
| 430 | 418 | ||
| 431 | if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA | 419 | if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA |
| 432 | | I2C_FUNC_SMBUS_WRITE_BYTE) ) | 420 | | I2C_FUNC_SMBUS_WRITE_BYTE) ) |
| 433 | return 0; | 421 | return 0; |
| 434 | 422 | ||
| 435 | if( !(cl=kzalloc(sizeof(*cl), GFP_KERNEL)) ) | 423 | switch (id->driver_data) { |
| 436 | return -ENOMEM; | 424 | case adm1030: |
| 437 | |||
| 438 | cl->addr = addr; | ||
| 439 | cl->adapter = adapter; | ||
| 440 | cl->driver = &g4fan_driver; | ||
| 441 | cl->flags = 0; | ||
| 442 | |||
| 443 | if( addr < 0x48 ) | ||
| 444 | return attach_fan( cl ); | 425 | return attach_fan( cl ); |
| 445 | return attach_thermostat( cl ); | 426 | case ds1775: |
| 427 | return attach_thermostat(cl); | ||
| 428 | } | ||
| 429 | return 0; | ||
| 446 | } | 430 | } |
| 447 | 431 | ||
| 432 | static struct i2c_driver g4fan_driver = { | ||
| 433 | .driver = { | ||
| 434 | .name = "therm_windtunnel", | ||
| 435 | }, | ||
| 436 | .attach_adapter = do_attach, | ||
| 437 | .probe = do_probe, | ||
| 438 | .remove = do_remove, | ||
| 439 | .id_table = therm_windtunnel_id, | ||
| 440 | }; | ||
| 441 | |||
| 448 | 442 | ||
| 449 | /************************************************************************/ | 443 | /************************************************************************/ |
| 450 | /* initialization / cleanup */ | 444 | /* initialization / cleanup */ |
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index b92b959fe16e..529886c7a826 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
| @@ -37,34 +37,22 @@ | |||
| 37 | struct wf_lm75_sensor { | 37 | struct wf_lm75_sensor { |
| 38 | int ds1775 : 1; | 38 | int ds1775 : 1; |
| 39 | int inited : 1; | 39 | int inited : 1; |
| 40 | struct i2c_client i2c; | 40 | struct i2c_client *i2c; |
| 41 | struct wf_sensor sens; | 41 | struct wf_sensor sens; |
| 42 | }; | 42 | }; |
| 43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) | 43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) |
| 44 | #define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c) | ||
| 45 | |||
| 46 | static int wf_lm75_attach(struct i2c_adapter *adapter); | ||
| 47 | static int wf_lm75_detach(struct i2c_client *client); | ||
| 48 | |||
| 49 | static struct i2c_driver wf_lm75_driver = { | ||
| 50 | .driver = { | ||
| 51 | .name = "wf_lm75", | ||
| 52 | }, | ||
| 53 | .attach_adapter = wf_lm75_attach, | ||
| 54 | .detach_client = wf_lm75_detach, | ||
| 55 | }; | ||
| 56 | 44 | ||
| 57 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | 45 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) |
| 58 | { | 46 | { |
| 59 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 47 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
| 60 | s32 data; | 48 | s32 data; |
| 61 | 49 | ||
| 62 | if (lm->i2c.adapter == NULL) | 50 | if (lm->i2c == NULL) |
| 63 | return -ENODEV; | 51 | return -ENODEV; |
| 64 | 52 | ||
| 65 | /* Init chip if necessary */ | 53 | /* Init chip if necessary */ |
| 66 | if (!lm->inited) { | 54 | if (!lm->inited) { |
| 67 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1); | 55 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1); |
| 68 | 56 | ||
| 69 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", | 57 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", |
| 70 | sr->name, cfg); | 58 | sr->name, cfg); |
| @@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | |||
| 73 | * the firmware for now | 61 | * the firmware for now |
| 74 | */ | 62 | */ |
| 75 | cfg_new = cfg & ~0x01; | 63 | cfg_new = cfg & ~0x01; |
| 76 | i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new); | 64 | i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new); |
| 77 | lm->inited = 1; | 65 | lm->inited = 1; |
| 78 | 66 | ||
| 79 | /* If we just powered it up, let's wait 200 ms */ | 67 | /* If we just powered it up, let's wait 200 ms */ |
| @@ -81,7 +69,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | |||
| 81 | } | 69 | } |
| 82 | 70 | ||
| 83 | /* Read temperature register */ | 71 | /* Read temperature register */ |
| 84 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0)); | 72 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0)); |
| 85 | data <<= 8; | 73 | data <<= 8; |
| 86 | *value = data; | 74 | *value = data; |
| 87 | 75 | ||
| @@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr) | |||
| 92 | { | 80 | { |
| 93 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 81 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
| 94 | 82 | ||
| 95 | /* check if client is registered and detach from i2c */ | ||
| 96 | if (lm->i2c.adapter) { | ||
| 97 | i2c_detach_client(&lm->i2c); | ||
| 98 | lm->i2c.adapter = NULL; | ||
| 99 | } | ||
| 100 | |||
| 101 | kfree(lm); | 83 | kfree(lm); |
| 102 | } | 84 | } |
| 103 | 85 | ||
| @@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = { | |||
| 107 | .owner = THIS_MODULE, | 89 | .owner = THIS_MODULE, |
| 108 | }; | 90 | }; |
| 109 | 91 | ||
| 110 | static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, | 92 | static int wf_lm75_probe(struct i2c_client *client, |
| 111 | u8 addr, int ds1775, | 93 | const struct i2c_device_id *id) |
| 112 | const char *loc) | ||
| 113 | { | 94 | { |
| 114 | struct wf_lm75_sensor *lm; | 95 | struct wf_lm75_sensor *lm; |
| 115 | int rc; | 96 | int rc; |
| 116 | 97 | ||
| 117 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | ||
| 118 | ds1775 ? "ds1775" : "lm75", addr); | ||
| 119 | |||
| 120 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); | 98 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); |
| 121 | if (lm == NULL) | 99 | if (lm == NULL) |
| 122 | return NULL; | 100 | return -ENODEV; |
| 101 | |||
| 102 | lm->inited = 0; | ||
| 103 | lm->ds1775 = id->driver_data; | ||
| 104 | lm->i2c = client; | ||
| 105 | lm->sens.name = client->dev.platform_data; | ||
| 106 | lm->sens.ops = &wf_lm75_ops; | ||
| 107 | i2c_set_clientdata(client, lm); | ||
| 108 | |||
| 109 | rc = wf_register_sensor(&lm->sens); | ||
| 110 | if (rc) { | ||
| 111 | i2c_set_clientdata(client, NULL); | ||
| 112 | kfree(lm); | ||
| 113 | } | ||
| 114 | |||
| 115 | return rc; | ||
| 116 | } | ||
| 117 | |||
| 118 | static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | ||
| 119 | u8 addr, int ds1775, | ||
| 120 | const char *loc) | ||
| 121 | { | ||
| 122 | struct i2c_board_info info; | ||
| 123 | struct i2c_client *client; | ||
| 124 | char *name; | ||
| 125 | |||
| 126 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | ||
| 127 | ds1775 ? "ds1775" : "lm75", addr); | ||
| 123 | 128 | ||
| 124 | /* Usual rant about sensor names not beeing very consistent in | 129 | /* Usual rant about sensor names not beeing very consistent in |
| 125 | * the device-tree, oh well ... | 130 | * the device-tree, oh well ... |
| 126 | * Add more entries below as you deal with more setups | 131 | * Add more entries below as you deal with more setups |
| 127 | */ | 132 | */ |
| 128 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) | 133 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) |
| 129 | lm->sens.name = "hd-temp"; | 134 | name = "hd-temp"; |
| 130 | else if (!strcmp(loc, "Incoming Air Temp")) | 135 | else if (!strcmp(loc, "Incoming Air Temp")) |
| 131 | lm->sens.name = "incoming-air-temp"; | 136 | name = "incoming-air-temp"; |
| 132 | else if (!strcmp(loc, "ODD Temp")) | 137 | else if (!strcmp(loc, "ODD Temp")) |
| 133 | lm->sens.name = "optical-drive-temp"; | 138 | name = "optical-drive-temp"; |
| 134 | else if (!strcmp(loc, "HD Temp")) | 139 | else if (!strcmp(loc, "HD Temp")) |
| 135 | lm->sens.name = "hard-drive-temp"; | 140 | name = "hard-drive-temp"; |
| 136 | else | 141 | else |
| 137 | goto fail; | 142 | goto fail; |
| 138 | 143 | ||
| 139 | lm->inited = 0; | 144 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 140 | lm->sens.ops = &wf_lm75_ops; | 145 | info.addr = (addr >> 1) & 0x7f; |
| 141 | lm->ds1775 = ds1775; | 146 | info.platform_data = name; |
| 142 | lm->i2c.addr = (addr >> 1) & 0x7f; | 147 | strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE); |
| 143 | lm->i2c.adapter = adapter; | ||
| 144 | lm->i2c.driver = &wf_lm75_driver; | ||
| 145 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); | ||
| 146 | |||
| 147 | rc = i2c_attach_client(&lm->i2c); | ||
| 148 | if (rc) { | ||
| 149 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c," | ||
| 150 | " err %d\n", ds1775 ? "ds1775" : "lm75", | ||
| 151 | lm->i2c.name, rc); | ||
| 152 | goto fail; | ||
| 153 | } | ||
| 154 | 148 | ||
| 155 | if (wf_register_sensor(&lm->sens)) { | 149 | client = i2c_new_device(adapter, &info); |
| 156 | i2c_detach_client(&lm->i2c); | 150 | if (client == NULL) { |
| 151 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", | ||
| 152 | ds1775 ? "ds1775" : "lm75", name); | ||
| 157 | goto fail; | 153 | goto fail; |
| 158 | } | 154 | } |
| 159 | 155 | ||
| 160 | return lm; | 156 | /* |
| 157 | * Let i2c-core delete that device on driver removal. | ||
| 158 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
| 159 | */ | ||
| 160 | list_add_tail(&client->detected, &client->driver->clients); | ||
| 161 | return client; | ||
| 161 | fail: | 162 | fail: |
| 162 | kfree(lm); | ||
| 163 | return NULL; | 163 | return NULL; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| @@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) | |||
| 202 | return 0; | 202 | return 0; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | static int wf_lm75_detach(struct i2c_client *client) | 205 | static int wf_lm75_remove(struct i2c_client *client) |
| 206 | { | 206 | { |
| 207 | struct wf_lm75_sensor *lm = i2c_to_lm75(client); | 207 | struct wf_lm75_sensor *lm = i2c_get_clientdata(client); |
| 208 | 208 | ||
| 209 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); | 209 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); |
| 210 | 210 | ||
| 211 | /* Mark client detached */ | 211 | /* Mark client detached */ |
| 212 | lm->i2c.adapter = NULL; | 212 | lm->i2c = NULL; |
| 213 | 213 | ||
| 214 | /* release sensor */ | 214 | /* release sensor */ |
| 215 | wf_unregister_sensor(&lm->sens); | 215 | wf_unregister_sensor(&lm->sens); |
| 216 | 216 | ||
| 217 | i2c_set_clientdata(client, NULL); | ||
| 217 | return 0; | 218 | return 0; |
| 218 | } | 219 | } |
| 219 | 220 | ||
| 221 | static const struct i2c_device_id wf_lm75_id[] = { | ||
| 222 | { "wf_lm75", 0 }, | ||
| 223 | { "wf_ds1775", 1 }, | ||
| 224 | { } | ||
| 225 | }; | ||
| 226 | |||
| 227 | static struct i2c_driver wf_lm75_driver = { | ||
| 228 | .driver = { | ||
| 229 | .name = "wf_lm75", | ||
| 230 | }, | ||
| 231 | .attach_adapter = wf_lm75_attach, | ||
| 232 | .probe = wf_lm75_probe, | ||
| 233 | .remove = wf_lm75_remove, | ||
| 234 | .id_table = wf_lm75_id, | ||
| 235 | }; | ||
| 236 | |||
| 220 | static int __init wf_lm75_sensor_init(void) | 237 | static int __init wf_lm75_sensor_init(void) |
| 221 | { | 238 | { |
| 222 | /* Don't register on old machines that use therm_pm72 for now */ | 239 | /* Don't register on old machines that use therm_pm72 for now */ |
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index e207a90d6b27..e2a55ecda2b2 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c | |||
| @@ -26,34 +26,22 @@ | |||
| 26 | #define MAX6690_EXTERNAL_TEMP 1 | 26 | #define MAX6690_EXTERNAL_TEMP 1 |
| 27 | 27 | ||
| 28 | struct wf_6690_sensor { | 28 | struct wf_6690_sensor { |
| 29 | struct i2c_client i2c; | 29 | struct i2c_client *i2c; |
| 30 | struct wf_sensor sens; | 30 | struct wf_sensor sens; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) | 33 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) |
| 34 | #define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) | ||
| 35 | |||
| 36 | static int wf_max6690_attach(struct i2c_adapter *adapter); | ||
| 37 | static int wf_max6690_detach(struct i2c_client *client); | ||
| 38 | |||
| 39 | static struct i2c_driver wf_max6690_driver = { | ||
| 40 | .driver = { | ||
| 41 | .name = "wf_max6690", | ||
| 42 | }, | ||
| 43 | .attach_adapter = wf_max6690_attach, | ||
| 44 | .detach_client = wf_max6690_detach, | ||
| 45 | }; | ||
| 46 | 34 | ||
| 47 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) | 35 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) |
| 48 | { | 36 | { |
| 49 | struct wf_6690_sensor *max = wf_to_6690(sr); | 37 | struct wf_6690_sensor *max = wf_to_6690(sr); |
| 50 | s32 data; | 38 | s32 data; |
| 51 | 39 | ||
| 52 | if (max->i2c.adapter == NULL) | 40 | if (max->i2c == NULL) |
| 53 | return -ENODEV; | 41 | return -ENODEV; |
| 54 | 42 | ||
| 55 | /* chip gets initialized by firmware */ | 43 | /* chip gets initialized by firmware */ |
| 56 | data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); | 44 | data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP); |
| 57 | if (data < 0) | 45 | if (data < 0) |
| 58 | return data; | 46 | return data; |
| 59 | *value = data << 16; | 47 | *value = data << 16; |
| @@ -64,10 +52,6 @@ static void wf_max6690_release(struct wf_sensor *sr) | |||
| 64 | { | 52 | { |
| 65 | struct wf_6690_sensor *max = wf_to_6690(sr); | 53 | struct wf_6690_sensor *max = wf_to_6690(sr); |
| 66 | 54 | ||
| 67 | if (max->i2c.adapter) { | ||
| 68 | i2c_detach_client(&max->i2c); | ||
| 69 | max->i2c.adapter = NULL; | ||
| 70 | } | ||
| 71 | kfree(max); | 55 | kfree(max); |
| 72 | } | 56 | } |
| 73 | 57 | ||
| @@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = { | |||
| 77 | .owner = THIS_MODULE, | 61 | .owner = THIS_MODULE, |
| 78 | }; | 62 | }; |
| 79 | 63 | ||
| 80 | static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr, | 64 | static int wf_max6690_probe(struct i2c_client *client, |
| 81 | const char *loc) | 65 | const struct i2c_device_id *id) |
| 82 | { | 66 | { |
| 83 | struct wf_6690_sensor *max; | 67 | struct wf_6690_sensor *max; |
| 84 | char *name; | 68 | int rc; |
| 85 | 69 | ||
| 86 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); | 70 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); |
| 87 | if (max == NULL) { | 71 | if (max == NULL) { |
| 88 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " | 72 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: " |
| 89 | "no memory\n", loc); | 73 | "no memory\n"); |
| 90 | return; | 74 | return -ENOMEM; |
| 75 | } | ||
| 76 | |||
| 77 | max->i2c = client; | ||
| 78 | max->sens.name = client->dev.platform_data; | ||
| 79 | max->sens.ops = &wf_max6690_ops; | ||
| 80 | i2c_set_clientdata(client, max); | ||
| 81 | |||
| 82 | rc = wf_register_sensor(&max->sens); | ||
| 83 | if (rc) { | ||
| 84 | i2c_set_clientdata(client, NULL); | ||
| 85 | kfree(max); | ||
| 91 | } | 86 | } |
| 92 | 87 | ||
| 88 | return rc; | ||
| 89 | } | ||
| 90 | |||
| 91 | static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, | ||
| 92 | u8 addr, const char *loc) | ||
| 93 | { | ||
| 94 | struct i2c_board_info info; | ||
| 95 | struct i2c_client *client; | ||
| 96 | char *name; | ||
| 97 | |||
| 93 | if (!strcmp(loc, "BACKSIDE")) | 98 | if (!strcmp(loc, "BACKSIDE")) |
| 94 | name = "backside-temp"; | 99 | name = "backside-temp"; |
| 95 | else if (!strcmp(loc, "NB Ambient")) | 100 | else if (!strcmp(loc, "NB Ambient")) |
| @@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr, | |||
| 99 | else | 104 | else |
| 100 | goto fail; | 105 | goto fail; |
| 101 | 106 | ||
| 102 | max->sens.ops = &wf_max6690_ops; | 107 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 103 | max->sens.name = name; | 108 | info.addr = addr >> 1; |
| 104 | max->i2c.addr = addr >> 1; | 109 | info.platform_data = name; |
| 105 | max->i2c.adapter = adapter; | 110 | strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE); |
| 106 | max->i2c.driver = &wf_max6690_driver; | ||
| 107 | strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); | ||
| 108 | 111 | ||
| 109 | if (i2c_attach_client(&max->i2c)) { | 112 | client = i2c_new_device(adapter, &info); |
| 113 | if (client == NULL) { | ||
| 110 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); | 114 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); |
| 111 | goto fail; | 115 | goto fail; |
| 112 | } | 116 | } |
| 113 | 117 | ||
| 114 | if (wf_register_sensor(&max->sens)) { | 118 | /* |
| 115 | i2c_detach_client(&max->i2c); | 119 | * Let i2c-core delete that device on driver removal. |
| 116 | goto fail; | 120 | * This is safe because i2c-core holds the core_lock mutex for us. |
| 117 | } | 121 | */ |
| 118 | 122 | list_add_tail(&client->detected, &client->driver->clients); | |
| 119 | return; | 123 | return client; |
| 120 | 124 | ||
| 121 | fail: | 125 | fail: |
| 122 | kfree(max); | 126 | return NULL; |
| 123 | } | 127 | } |
| 124 | 128 | ||
| 125 | static int wf_max6690_attach(struct i2c_adapter *adapter) | 129 | static int wf_max6690_attach(struct i2c_adapter *adapter) |
| @@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter) | |||
| 154 | return 0; | 158 | return 0; |
| 155 | } | 159 | } |
| 156 | 160 | ||
| 157 | static int wf_max6690_detach(struct i2c_client *client) | 161 | static int wf_max6690_remove(struct i2c_client *client) |
| 158 | { | 162 | { |
| 159 | struct wf_6690_sensor *max = i2c_to_6690(client); | 163 | struct wf_6690_sensor *max = i2c_get_clientdata(client); |
| 160 | 164 | ||
| 161 | max->i2c.adapter = NULL; | 165 | max->i2c = NULL; |
| 162 | wf_unregister_sensor(&max->sens); | 166 | wf_unregister_sensor(&max->sens); |
| 163 | 167 | ||
| 164 | return 0; | 168 | return 0; |
| 165 | } | 169 | } |
| 166 | 170 | ||
| 171 | static const struct i2c_device_id wf_max6690_id[] = { | ||
| 172 | { "wf_max6690", 0 }, | ||
| 173 | { } | ||
| 174 | }; | ||
| 175 | |||
| 176 | static struct i2c_driver wf_max6690_driver = { | ||
| 177 | .driver = { | ||
| 178 | .name = "wf_max6690", | ||
| 179 | }, | ||
| 180 | .attach_adapter = wf_max6690_attach, | ||
| 181 | .probe = wf_max6690_probe, | ||
| 182 | .remove = wf_max6690_remove, | ||
| 183 | .id_table = wf_max6690_id, | ||
| 184 | }; | ||
| 185 | |||
| 167 | static int __init wf_max6690_sensor_init(void) | 186 | static int __init wf_max6690_sensor_init(void) |
| 168 | { | 187 | { |
| 169 | /* Don't register on old machines that use therm_pm72 for now */ | 188 | /* Don't register on old machines that use therm_pm72 for now */ |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 7847e981ac33..5da729e58f99 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
| @@ -39,7 +39,7 @@ struct wf_sat { | |||
| 39 | struct mutex mutex; | 39 | struct mutex mutex; |
| 40 | unsigned long last_read; /* jiffies when cache last updated */ | 40 | unsigned long last_read; /* jiffies when cache last updated */ |
| 41 | u8 cache[16]; | 41 | u8 cache[16]; |
| 42 | struct i2c_client i2c; | 42 | struct i2c_client *i2c; |
| 43 | struct device_node *node; | 43 | struct device_node *node; |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| @@ -54,18 +54,6 @@ struct wf_sat_sensor { | |||
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) | 56 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) |
| 57 | #define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) | ||
| 58 | |||
| 59 | static int wf_sat_attach(struct i2c_adapter *adapter); | ||
| 60 | static int wf_sat_detach(struct i2c_client *client); | ||
| 61 | |||
| 62 | static struct i2c_driver wf_sat_driver = { | ||
| 63 | .driver = { | ||
| 64 | .name = "wf_smu_sat", | ||
| 65 | }, | ||
| 66 | .attach_adapter = wf_sat_attach, | ||
| 67 | .detach_client = wf_sat_detach, | ||
| 68 | }; | ||
| 69 | 57 | ||
| 70 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | 58 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, |
| 71 | unsigned int *size) | 59 | unsigned int *size) |
| @@ -81,13 +69,13 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | |||
| 81 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) | 69 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) |
| 82 | return NULL; | 70 | return NULL; |
| 83 | 71 | ||
| 84 | err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); | 72 | err = i2c_smbus_write_word_data(sat->i2c, 8, id << 8); |
| 85 | if (err) { | 73 | if (err) { |
| 86 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); | 74 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); |
| 87 | return NULL; | 75 | return NULL; |
| 88 | } | 76 | } |
| 89 | 77 | ||
| 90 | err = i2c_smbus_read_word_data(&sat->i2c, 9); | 78 | err = i2c_smbus_read_word_data(sat->i2c, 9); |
| 91 | if (err < 0) { | 79 | if (err < 0) { |
| 92 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); | 80 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); |
| 93 | return NULL; | 81 | return NULL; |
| @@ -105,7 +93,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | |||
| 105 | return NULL; | 93 | return NULL; |
| 106 | 94 | ||
| 107 | for (i = 0; i < len; i += 4) { | 95 | for (i = 0; i < len; i += 4) { |
| 108 | err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data); | 96 | err = i2c_smbus_read_i2c_block_data(sat->i2c, 0xa, 4, data); |
| 109 | if (err < 0) { | 97 | if (err < 0) { |
| 110 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", | 98 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", |
| 111 | err); | 99 | err); |
| @@ -138,7 +126,7 @@ static int wf_sat_read_cache(struct wf_sat *sat) | |||
| 138 | { | 126 | { |
| 139 | int err; | 127 | int err; |
| 140 | 128 | ||
| 141 | err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache); | 129 | err = i2c_smbus_read_i2c_block_data(sat->i2c, 0x3f, 16, sat->cache); |
| 142 | if (err < 0) | 130 | if (err < 0) |
| 143 | return err; | 131 | return err; |
| 144 | sat->last_read = jiffies; | 132 | sat->last_read = jiffies; |
| @@ -161,7 +149,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value) | |||
| 161 | int i, err; | 149 | int i, err; |
| 162 | s32 val; | 150 | s32 val; |
| 163 | 151 | ||
| 164 | if (sat->i2c.adapter == NULL) | 152 | if (sat->i2c == NULL) |
| 165 | return -ENODEV; | 153 | return -ENODEV; |
| 166 | 154 | ||
| 167 | mutex_lock(&sat->mutex); | 155 | mutex_lock(&sat->mutex); |
| @@ -193,10 +181,6 @@ static void wf_sat_release(struct wf_sensor *sr) | |||
| 193 | struct wf_sat *sat = sens->sat; | 181 | struct wf_sat *sat = sens->sat; |
| 194 | 182 | ||
| 195 | if (atomic_dec_and_test(&sat->refcnt)) { | 183 | if (atomic_dec_and_test(&sat->refcnt)) { |
| 196 | if (sat->i2c.adapter) { | ||
| 197 | i2c_detach_client(&sat->i2c); | ||
| 198 | sat->i2c.adapter = NULL; | ||
| 199 | } | ||
| 200 | if (sat->nr >= 0) | 184 | if (sat->nr >= 0) |
| 201 | sats[sat->nr] = NULL; | 185 | sats[sat->nr] = NULL; |
| 202 | kfree(sat); | 186 | kfree(sat); |
| @@ -212,38 +196,58 @@ static struct wf_sensor_ops wf_sat_ops = { | |||
| 212 | 196 | ||
| 213 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | 197 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) |
| 214 | { | 198 | { |
| 199 | struct i2c_board_info info; | ||
| 200 | struct i2c_client *client; | ||
| 201 | const u32 *reg; | ||
| 202 | u8 addr; | ||
| 203 | |||
| 204 | reg = of_get_property(dev, "reg", NULL); | ||
| 205 | if (reg == NULL) | ||
| 206 | return; | ||
| 207 | addr = *reg; | ||
| 208 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
| 209 | |||
| 210 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 211 | info.addr = (addr >> 1) & 0x7f; | ||
| 212 | info.platform_data = dev; | ||
| 213 | strlcpy(info.type, "wf_sat", I2C_NAME_SIZE); | ||
| 214 | |||
| 215 | client = i2c_new_device(adapter, &info); | ||
| 216 | if (client == NULL) { | ||
| 217 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
| 218 | return; | ||
| 219 | } | ||
| 220 | |||
| 221 | /* | ||
| 222 | * Let i2c-core delete that device on driver removal. | ||
| 223 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
| 224 | */ | ||
| 225 | list_add_tail(&client->detected, &client->driver->clients); | ||
| 226 | } | ||
| 227 | |||
| 228 | static int wf_sat_probe(struct i2c_client *client, | ||
| 229 | const struct i2c_device_id *id) | ||
| 230 | { | ||
| 231 | struct device_node *dev = client->dev.platform_data; | ||
| 215 | struct wf_sat *sat; | 232 | struct wf_sat *sat; |
| 216 | struct wf_sat_sensor *sens; | 233 | struct wf_sat_sensor *sens; |
| 217 | const u32 *reg; | 234 | const u32 *reg; |
| 218 | const char *loc, *type; | 235 | const char *loc, *type; |
| 219 | u8 addr, chip, core; | 236 | u8 chip, core; |
| 220 | struct device_node *child; | 237 | struct device_node *child; |
| 221 | int shift, cpu, index; | 238 | int shift, cpu, index; |
| 222 | char *name; | 239 | char *name; |
| 223 | int vsens[2], isens[2]; | 240 | int vsens[2], isens[2]; |
| 224 | 241 | ||
| 225 | reg = of_get_property(dev, "reg", NULL); | ||
| 226 | if (reg == NULL) | ||
| 227 | return; | ||
| 228 | addr = *reg; | ||
| 229 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
| 230 | |||
| 231 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); | 242 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); |
| 232 | if (sat == NULL) | 243 | if (sat == NULL) |
| 233 | return; | 244 | return -ENOMEM; |
| 234 | sat->nr = -1; | 245 | sat->nr = -1; |
| 235 | sat->node = of_node_get(dev); | 246 | sat->node = of_node_get(dev); |
| 236 | atomic_set(&sat->refcnt, 0); | 247 | atomic_set(&sat->refcnt, 0); |
| 237 | mutex_init(&sat->mutex); | 248 | mutex_init(&sat->mutex); |
| 238 | sat->i2c.addr = (addr >> 1) & 0x7f; | 249 | sat->i2c = client; |
| 239 | sat->i2c.adapter = adapter; | 250 | i2c_set_clientdata(client, sat); |
| 240 | sat->i2c.driver = &wf_sat_driver; | ||
| 241 | strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); | ||
| 242 | |||
| 243 | if (i2c_attach_client(&sat->i2c)) { | ||
| 244 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
| 245 | goto fail; | ||
| 246 | } | ||
| 247 | 251 | ||
| 248 | vsens[0] = vsens[1] = -1; | 252 | vsens[0] = vsens[1] = -1; |
| 249 | isens[0] = isens[1] = -1; | 253 | isens[0] = isens[1] = -1; |
| @@ -344,10 +348,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | |||
| 344 | if (sat->nr >= 0) | 348 | if (sat->nr >= 0) |
| 345 | sats[sat->nr] = sat; | 349 | sats[sat->nr] = sat; |
| 346 | 350 | ||
| 347 | return; | 351 | return 0; |
| 348 | |||
| 349 | fail: | ||
| 350 | kfree(sat); | ||
| 351 | } | 352 | } |
| 352 | 353 | ||
| 353 | static int wf_sat_attach(struct i2c_adapter *adapter) | 354 | static int wf_sat_attach(struct i2c_adapter *adapter) |
| @@ -366,16 +367,32 @@ static int wf_sat_attach(struct i2c_adapter *adapter) | |||
| 366 | return 0; | 367 | return 0; |
| 367 | } | 368 | } |
| 368 | 369 | ||
| 369 | static int wf_sat_detach(struct i2c_client *client) | 370 | static int wf_sat_remove(struct i2c_client *client) |
| 370 | { | 371 | { |
| 371 | struct wf_sat *sat = i2c_to_sat(client); | 372 | struct wf_sat *sat = i2c_get_clientdata(client); |
| 372 | 373 | ||
| 373 | /* XXX TODO */ | 374 | /* XXX TODO */ |
| 374 | 375 | ||
| 375 | sat->i2c.adapter = NULL; | 376 | sat->i2c = NULL; |
| 377 | i2c_set_clientdata(client, NULL); | ||
| 376 | return 0; | 378 | return 0; |
| 377 | } | 379 | } |
| 378 | 380 | ||
| 381 | static const struct i2c_device_id wf_sat_id[] = { | ||
| 382 | { "wf_sat", 0 }, | ||
| 383 | { } | ||
| 384 | }; | ||
| 385 | |||
| 386 | static struct i2c_driver wf_sat_driver = { | ||
| 387 | .driver = { | ||
| 388 | .name = "wf_smu_sat", | ||
| 389 | }, | ||
| 390 | .attach_adapter = wf_sat_attach, | ||
| 391 | .probe = wf_sat_probe, | ||
| 392 | .remove = wf_sat_remove, | ||
| 393 | .id_table = wf_sat_id, | ||
| 394 | }; | ||
| 395 | |||
| 379 | static int __init sat_sensors_init(void) | 396 | static int __init sat_sensors_init(void) |
| 380 | { | 397 | { |
| 381 | return i2c_add_driver(&wf_sat_driver); | 398 | return i2c_add_driver(&wf_sat_driver); |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3fd8b1e65483..48db308fae67 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/idr.h> | 20 | #include <linux/idr.h> |
| 21 | #include <linux/hdreg.h> | 21 | #include <linux/hdreg.h> |
| 22 | #include <linux/blktrace_api.h> | ||
| 23 | 22 | ||
| 24 | #include <trace/events/block.h> | 23 | #include <trace/events/block.h> |
| 25 | 24 | ||
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index 89fec052f3b4..9118613af321 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig | |||
| @@ -48,6 +48,20 @@ config EEPROM_LEGACY | |||
| 48 | This driver can also be built as a module. If so, the module | 48 | This driver can also be built as a module. If so, the module |
| 49 | will be called eeprom. | 49 | will be called eeprom. |
| 50 | 50 | ||
| 51 | config EEPROM_MAX6875 | ||
| 52 | tristate "Maxim MAX6874/5 power supply supervisor" | ||
| 53 | depends on I2C && EXPERIMENTAL | ||
| 54 | help | ||
| 55 | If you say yes here you get read-only support for the user EEPROM of | ||
| 56 | the Maxim MAX6874/5 EEPROM-programmable, quad power-supply | ||
| 57 | sequencer/supervisor. | ||
| 58 | |||
| 59 | All other features of this chip should be accessed via i2c-dev. | ||
| 60 | |||
| 61 | This driver can also be built as a module. If so, the module | ||
| 62 | will be called max6875. | ||
| 63 | |||
| 64 | |||
| 51 | config EEPROM_93CX6 | 65 | config EEPROM_93CX6 |
| 52 | tristate "EEPROM 93CX6 support" | 66 | tristate "EEPROM 93CX6 support" |
| 53 | help | 67 | help |
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile index 539dd8f88128..df3d68ffa9d1 100644 --- a/drivers/misc/eeprom/Makefile +++ b/drivers/misc/eeprom/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | obj-$(CONFIG_EEPROM_AT24) += at24.o | 1 | obj-$(CONFIG_EEPROM_AT24) += at24.o |
| 2 | obj-$(CONFIG_EEPROM_AT25) += at25.o | 2 | obj-$(CONFIG_EEPROM_AT25) += at25.o |
| 3 | obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o | 3 | obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o |
| 4 | obj-$(CONFIG_EEPROM_MAX6875) += max6875.o | ||
| 4 | obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o | 5 | obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o |
diff --git a/drivers/i2c/chips/max6875.c b/drivers/misc/eeprom/max6875.c index 033d9d81ec8a..3c0c58eed347 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/misc/eeprom/max6875.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> | 4 | Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> |
| 5 | 5 | ||
| 6 | Based on i2c/chips/eeprom.c | 6 | Based on eeprom.c |
| 7 | 7 | ||
| 8 | The MAX6875 has a bank of registers and two banks of EEPROM. | 8 | The MAX6875 has a bank of registers and two banks of EEPROM. |
| 9 | Address ranges are defined as follows: | 9 | Address ranges are defined as follows: |
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 30900b30d532..2b38f39924a6 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
| @@ -1648,7 +1648,7 @@ static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev) | |||
| 1648 | result = -ENOMEM; | 1648 | result = -ENOMEM; |
| 1649 | goto fail_alloc_card; | 1649 | goto fail_alloc_card; |
| 1650 | } | 1650 | } |
| 1651 | ps3_system_bus_set_driver_data(dev, card); | 1651 | ps3_system_bus_set_drvdata(dev, card); |
| 1652 | card->dev = dev; | 1652 | card->dev = dev; |
| 1653 | 1653 | ||
| 1654 | /* get internal vlan info */ | 1654 | /* get internal vlan info */ |
| @@ -1749,7 +1749,7 @@ fail_alloc_irq: | |||
| 1749 | bus_id(card), | 1749 | bus_id(card), |
| 1750 | 0, 0); | 1750 | 0, 0); |
| 1751 | fail_status_indicator: | 1751 | fail_status_indicator: |
| 1752 | ps3_system_bus_set_driver_data(dev, NULL); | 1752 | ps3_system_bus_set_drvdata(dev, NULL); |
| 1753 | kfree(netdev_card(netdev)->unalign); | 1753 | kfree(netdev_card(netdev)->unalign); |
| 1754 | free_netdev(netdev); | 1754 | free_netdev(netdev); |
| 1755 | fail_alloc_card: | 1755 | fail_alloc_card: |
| @@ -1766,7 +1766,7 @@ fail_open: | |||
| 1766 | 1766 | ||
| 1767 | static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) | 1767 | static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) |
| 1768 | { | 1768 | { |
| 1769 | struct gelic_card *card = ps3_system_bus_get_driver_data(dev); | 1769 | struct gelic_card *card = ps3_system_bus_get_drvdata(dev); |
| 1770 | struct net_device *netdev0; | 1770 | struct net_device *netdev0; |
| 1771 | pr_debug("%s: called\n", __func__); | 1771 | pr_debug("%s: called\n", __func__); |
| 1772 | 1772 | ||
| @@ -1803,7 +1803,7 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) | |||
| 1803 | kfree(netdev_card(netdev0)->unalign); | 1803 | kfree(netdev_card(netdev0)->unalign); |
| 1804 | free_netdev(netdev0); | 1804 | free_netdev(netdev0); |
| 1805 | 1805 | ||
| 1806 | ps3_system_bus_set_driver_data(dev, NULL); | 1806 | ps3_system_bus_set_drvdata(dev, NULL); |
| 1807 | 1807 | ||
| 1808 | ps3_dma_region_free(dev->d_region); | 1808 | ps3_dma_region_free(dev->d_region); |
| 1809 | 1809 | ||
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c index f17513dd9d4b..88cb74088611 100644 --- a/drivers/ps3/ps3-sys-manager.c +++ b/drivers/ps3/ps3-sys-manager.c | |||
| @@ -706,7 +706,7 @@ static void ps3_sys_manager_work(struct ps3_system_bus_device *dev) | |||
| 706 | ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN); | 706 | ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN); |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev) | 709 | static int __devinit ps3_sys_manager_probe(struct ps3_system_bus_device *dev) |
| 710 | { | 710 | { |
| 711 | int result; | 711 | int result; |
| 712 | struct ps3_sys_manager_ops ops; | 712 | struct ps3_sys_manager_ops ops; |
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 235e87fcb49f..e82d8c9c6cda 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c | |||
| @@ -80,12 +80,12 @@ static const struct avset_video_mode { | |||
| 80 | { 0, }, /* auto */ | 80 | { 0, }, /* auto */ |
| 81 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480}, | 81 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480}, |
| 82 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480}, | 82 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480}, |
| 83 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720}, | 83 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_W, 1280, 720}, |
| 84 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080}, | 84 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080}, |
| 85 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080}, | 85 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080}, |
| 86 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576}, | 86 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576}, |
| 87 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576}, | 87 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576}, |
| 88 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720}, | 88 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_W, 1280, 720}, |
| 89 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080}, | 89 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080}, |
| 90 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080}, | 90 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080}, |
| 91 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768}, | 91 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768}, |
| @@ -937,7 +937,7 @@ int ps3av_audio_mute(int mute) | |||
| 937 | 937 | ||
| 938 | EXPORT_SYMBOL_GPL(ps3av_audio_mute); | 938 | EXPORT_SYMBOL_GPL(ps3av_audio_mute); |
| 939 | 939 | ||
| 940 | static int ps3av_probe(struct ps3_system_bus_device *dev) | 940 | static int __devinit ps3av_probe(struct ps3_system_bus_device *dev) |
| 941 | { | 941 | { |
| 942 | int res; | 942 | int res; |
| 943 | int id; | 943 | int id; |
| @@ -1048,7 +1048,7 @@ static struct ps3_vuart_port_driver ps3av_driver = { | |||
| 1048 | .shutdown = ps3av_shutdown, | 1048 | .shutdown = ps3av_shutdown, |
| 1049 | }; | 1049 | }; |
| 1050 | 1050 | ||
| 1051 | static int ps3av_module_init(void) | 1051 | static int __init ps3av_module_init(void) |
| 1052 | { | 1052 | { |
| 1053 | int error; | 1053 | int error; |
| 1054 | 1054 | ||
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c index 716596e8e5b0..f555fedd5073 100644 --- a/drivers/ps3/ps3av_cmd.c +++ b/drivers/ps3/ps3av_cmd.c | |||
| @@ -21,9 +21,10 @@ | |||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | |||
| 24 | #include <asm/ps3av.h> | 25 | #include <asm/ps3av.h> |
| 25 | #include <asm/ps3fb.h> | ||
| 26 | #include <asm/ps3.h> | 26 | #include <asm/ps3.h> |
| 27 | #include <asm/ps3gpu.h> | ||
| 27 | 28 | ||
| 28 | #include "vuart.h" | 29 | #include "vuart.h" |
| 29 | 30 | ||
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 1ba9f9a8c308..bb870b8f81bc 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
| @@ -162,7 +162,7 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev) | |||
| 162 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | 162 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, |
| 163 | (unsigned long)virq); | 163 | (unsigned long)virq); |
| 164 | 164 | ||
| 165 | ps3_system_bus_set_driver_data(dev, hcd); | 165 | ps3_system_bus_set_drvdata(dev, hcd); |
| 166 | 166 | ||
| 167 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | 167 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); |
| 168 | 168 | ||
| @@ -195,8 +195,7 @@ fail_start: | |||
| 195 | static int ps3_ehci_remove(struct ps3_system_bus_device *dev) | 195 | static int ps3_ehci_remove(struct ps3_system_bus_device *dev) |
| 196 | { | 196 | { |
| 197 | unsigned int tmp; | 197 | unsigned int tmp; |
| 198 | struct usb_hcd *hcd = | 198 | struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev); |
| 199 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
| 200 | 199 | ||
| 201 | BUG_ON(!hcd); | 200 | BUG_ON(!hcd); |
| 202 | 201 | ||
| @@ -208,7 +207,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev) | |||
| 208 | ehci_shutdown(hcd); | 207 | ehci_shutdown(hcd); |
| 209 | usb_remove_hcd(hcd); | 208 | usb_remove_hcd(hcd); |
| 210 | 209 | ||
| 211 | ps3_system_bus_set_driver_data(dev, NULL); | 210 | ps3_system_bus_set_drvdata(dev, NULL); |
| 212 | 211 | ||
| 213 | BUG_ON(!hcd->regs); | 212 | BUG_ON(!hcd->regs); |
| 214 | iounmap(hcd->regs); | 213 | iounmap(hcd->regs); |
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 3d1910317328..1d56259c5db1 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c | |||
| @@ -162,7 +162,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev) | |||
| 162 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | 162 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, |
| 163 | (unsigned long)virq); | 163 | (unsigned long)virq); |
| 164 | 164 | ||
| 165 | ps3_system_bus_set_driver_data(dev, hcd); | 165 | ps3_system_bus_set_drvdata(dev, hcd); |
| 166 | 166 | ||
| 167 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | 167 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); |
| 168 | 168 | ||
| @@ -195,8 +195,7 @@ fail_start: | |||
| 195 | static int ps3_ohci_remove(struct ps3_system_bus_device *dev) | 195 | static int ps3_ohci_remove(struct ps3_system_bus_device *dev) |
| 196 | { | 196 | { |
| 197 | unsigned int tmp; | 197 | unsigned int tmp; |
| 198 | struct usb_hcd *hcd = | 198 | struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev); |
| 199 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
| 200 | 199 | ||
| 201 | BUG_ON(!hcd); | 200 | BUG_ON(!hcd); |
| 202 | 201 | ||
| @@ -208,7 +207,7 @@ static int ps3_ohci_remove(struct ps3_system_bus_device *dev) | |||
| 208 | ohci_shutdown(hcd); | 207 | ohci_shutdown(hcd); |
| 209 | usb_remove_hcd(hcd); | 208 | usb_remove_hcd(hcd); |
| 210 | 209 | ||
| 211 | ps3_system_bus_set_driver_data(dev, NULL); | 210 | ps3_system_bus_set_drvdata(dev, NULL); |
| 212 | 211 | ||
| 213 | BUG_ON(!hcd->regs); | 212 | BUG_ON(!hcd->regs); |
| 214 | iounmap(hcd->regs); | 213 | iounmap(hcd->regs); |
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index e00c1dff55de..c0af638fe702 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c | |||
| @@ -32,25 +32,16 @@ | |||
| 32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
| 33 | 33 | ||
| 34 | #include <asm/abs_addr.h> | 34 | #include <asm/abs_addr.h> |
| 35 | #include <asm/iommu.h> | ||
| 35 | #include <asm/lv1call.h> | 36 | #include <asm/lv1call.h> |
| 36 | #include <asm/ps3av.h> | 37 | #include <asm/ps3av.h> |
| 37 | #include <asm/ps3fb.h> | 38 | #include <asm/ps3fb.h> |
| 38 | #include <asm/ps3.h> | 39 | #include <asm/ps3.h> |
| 40 | #include <asm/ps3gpu.h> | ||
| 39 | 41 | ||
| 40 | 42 | ||
| 41 | #define DEVICE_NAME "ps3fb" | 43 | #define DEVICE_NAME "ps3fb" |
| 42 | 44 | ||
| 43 | #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101 | ||
| 44 | #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102 | ||
| 45 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600 | ||
| 46 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 | ||
| 47 | #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602 | ||
| 48 | |||
| 49 | #define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32) | ||
| 50 | |||
| 51 | #define L1GPU_DISPLAY_SYNC_HSYNC 1 | ||
| 52 | #define L1GPU_DISPLAY_SYNC_VSYNC 2 | ||
| 53 | |||
| 54 | #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024) | 45 | #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024) |
| 55 | #define GPU_FB_START (64 * 1024) | 46 | #define GPU_FB_START (64 * 1024) |
| 56 | #define GPU_IOIF (0x0d000000UL) | 47 | #define GPU_IOIF (0x0d000000UL) |
| @@ -462,33 +453,27 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset, | |||
| 462 | src_offset += GPU_FB_START; | 453 | src_offset += GPU_FB_START; |
| 463 | 454 | ||
| 464 | mutex_lock(&ps3_gpu_mutex); | 455 | mutex_lock(&ps3_gpu_mutex); |
| 465 | status = lv1_gpu_context_attribute(ps3fb.context_handle, | 456 | status = lv1_gpu_fb_blit(ps3fb.context_handle, dst_offset, |
| 466 | L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, | 457 | GPU_IOIF + src_offset, |
| 467 | dst_offset, GPU_IOIF + src_offset, | 458 | L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | |
| 468 | L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | | 459 | (width << 16) | height, |
| 469 | (width << 16) | height, | 460 | line_length); |
| 470 | line_length); | ||
| 471 | mutex_unlock(&ps3_gpu_mutex); | 461 | mutex_unlock(&ps3_gpu_mutex); |
| 472 | 462 | ||
| 473 | if (status) | 463 | if (status) |
| 474 | dev_err(dev, | 464 | dev_err(dev, "%s: lv1_gpu_fb_blit failed: %d\n", __func__, |
| 475 | "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", | 465 | status); |
| 476 | __func__, status); | ||
| 477 | #ifdef HEAD_A | 466 | #ifdef HEAD_A |
| 478 | status = lv1_gpu_context_attribute(ps3fb.context_handle, | 467 | status = lv1_gpu_display_flip(ps3fb.context_handle, 0, frame_offset); |
| 479 | L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, | ||
| 480 | 0, frame_offset, 0, 0); | ||
| 481 | if (status) | 468 | if (status) |
| 482 | dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", | 469 | dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__, |
| 483 | __func__, status); | 470 | status); |
| 484 | #endif | 471 | #endif |
| 485 | #ifdef HEAD_B | 472 | #ifdef HEAD_B |
| 486 | status = lv1_gpu_context_attribute(ps3fb.context_handle, | 473 | status = lv1_gpu_display_flip(ps3fb.context_handle, 1, frame_offset); |
| 487 | L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, | ||
| 488 | 1, frame_offset, 0, 0); | ||
| 489 | if (status) | 474 | if (status) |
| 490 | dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", | 475 | dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__, |
| 491 | __func__, status); | 476 | status); |
| 492 | #endif | 477 | #endif |
| 493 | } | 478 | } |
| 494 | 479 | ||
| @@ -956,73 +941,6 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr) | |||
| 956 | } | 941 | } |
| 957 | 942 | ||
| 958 | 943 | ||
| 959 | static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, | ||
| 960 | struct device *dev) | ||
| 961 | { | ||
| 962 | int error; | ||
| 963 | |||
| 964 | dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver); | ||
| 965 | dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet); | ||
| 966 | dev_dbg(dev, | ||
| 967 | "version_gpu: %x memory_size: %x ch: %x core_freq: %d " | ||
| 968 | "mem_freq:%d\n", | ||
| 969 | dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel, | ||
| 970 | dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000); | ||
| 971 | |||
| 972 | if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) { | ||
| 973 | dev_err(dev, "%s: version_driver err:%x\n", __func__, | ||
| 974 | dinfo->version_driver); | ||
| 975 | return -EINVAL; | ||
| 976 | } | ||
| 977 | |||
| 978 | error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, | ||
| 979 | &ps3fb.irq_no); | ||
| 980 | if (error) { | ||
| 981 | dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error); | ||
| 982 | return error; | ||
| 983 | } | ||
| 984 | |||
| 985 | error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, | ||
| 986 | DEVICE_NAME, dev); | ||
| 987 | if (error) { | ||
| 988 | dev_err(dev, "%s: request_irq failed %d\n", __func__, error); | ||
| 989 | ps3_irq_plug_destroy(ps3fb.irq_no); | ||
| 990 | return error; | ||
| 991 | } | ||
| 992 | |||
| 993 | dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) | | ||
| 994 | (1 << GPU_INTR_STATUS_FLIP_1); | ||
| 995 | return 0; | ||
| 996 | } | ||
| 997 | |||
| 998 | static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev) | ||
| 999 | { | ||
| 1000 | int status; | ||
| 1001 | |||
| 1002 | status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, | ||
| 1003 | xdr_lpar, ps3fb_videomemory.size, 0); | ||
| 1004 | if (status) { | ||
| 1005 | dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n", | ||
| 1006 | __func__, status); | ||
| 1007 | return -ENXIO; | ||
| 1008 | } | ||
| 1009 | dev_dbg(dev, "video:%p ioif:%lx lpar:%llx size:%lx\n", | ||
| 1010 | ps3fb_videomemory.address, GPU_IOIF, xdr_lpar, | ||
| 1011 | ps3fb_videomemory.size); | ||
| 1012 | |||
| 1013 | status = lv1_gpu_context_attribute(ps3fb.context_handle, | ||
| 1014 | L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, | ||
| 1015 | xdr_lpar, GPU_CMD_BUF_SIZE, | ||
| 1016 | GPU_IOIF, 0); | ||
| 1017 | if (status) { | ||
| 1018 | dev_err(dev, | ||
| 1019 | "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", | ||
| 1020 | __func__, status); | ||
| 1021 | return -ENXIO; | ||
| 1022 | } | ||
| 1023 | return 0; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | static struct fb_ops ps3fb_ops = { | 944 | static struct fb_ops ps3fb_ops = { |
| 1027 | .fb_open = ps3fb_open, | 945 | .fb_open = ps3fb_open, |
| 1028 | .fb_release = ps3fb_release, | 946 | .fb_release = ps3fb_release, |
| @@ -1048,49 +966,18 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = { | |||
| 1048 | .accel = FB_ACCEL_NONE, | 966 | .accel = FB_ACCEL_NONE, |
| 1049 | }; | 967 | }; |
| 1050 | 968 | ||
| 1051 | static int ps3fb_set_sync(struct device *dev) | ||
| 1052 | { | ||
| 1053 | int status; | ||
| 1054 | |||
| 1055 | #ifdef HEAD_A | ||
| 1056 | status = lv1_gpu_context_attribute(0x0, | ||
| 1057 | L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, | ||
| 1058 | 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); | ||
| 1059 | if (status) { | ||
| 1060 | dev_err(dev, | ||
| 1061 | "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: " | ||
| 1062 | "%d\n", | ||
| 1063 | __func__, status); | ||
| 1064 | return -1; | ||
| 1065 | } | ||
| 1066 | #endif | ||
| 1067 | #ifdef HEAD_B | ||
| 1068 | status = lv1_gpu_context_attribute(0x0, | ||
| 1069 | L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, | ||
| 1070 | 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); | ||
| 1071 | |||
| 1072 | if (status) { | ||
| 1073 | dev_err(dev, | ||
| 1074 | "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: " | ||
| 1075 | "%d\n", | ||
| 1076 | __func__, status); | ||
| 1077 | return -1; | ||
| 1078 | } | ||
| 1079 | #endif | ||
| 1080 | return 0; | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | 969 | static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) |
| 1084 | { | 970 | { |
| 1085 | struct fb_info *info; | 971 | struct fb_info *info; |
| 1086 | struct ps3fb_par *par; | 972 | struct ps3fb_par *par; |
| 1087 | int retval = -ENOMEM; | 973 | int retval; |
| 1088 | u64 ddr_lpar = 0; | 974 | u64 ddr_lpar = 0; |
| 1089 | u64 lpar_dma_control = 0; | 975 | u64 lpar_dma_control = 0; |
| 1090 | u64 lpar_driver_info = 0; | 976 | u64 lpar_driver_info = 0; |
| 1091 | u64 lpar_reports = 0; | 977 | u64 lpar_reports = 0; |
| 1092 | u64 lpar_reports_size = 0; | 978 | u64 lpar_reports_size = 0; |
| 1093 | u64 xdr_lpar; | 979 | u64 xdr_lpar; |
| 980 | struct gpu_driver_info *dinfo; | ||
| 1094 | void *fb_start; | 981 | void *fb_start; |
| 1095 | int status; | 982 | int status; |
| 1096 | struct task_struct *task; | 983 | struct task_struct *task; |
| @@ -1101,8 +988,8 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
| 1101 | return -ENOMEM; | 988 | return -ENOMEM; |
| 1102 | } | 989 | } |
| 1103 | 990 | ||
| 1104 | status = ps3_open_hv_device(dev); | 991 | retval = ps3_open_hv_device(dev); |
| 1105 | if (status) { | 992 | if (retval) { |
| 1106 | dev_err(&dev->core, "%s: ps3_open_hv_device failed\n", | 993 | dev_err(&dev->core, "%s: ps3_open_hv_device failed\n", |
| 1107 | __func__); | 994 | __func__); |
| 1108 | goto err; | 995 | goto err; |
| @@ -1116,7 +1003,24 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
| 1116 | atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ | 1003 | atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ |
| 1117 | init_waitqueue_head(&ps3fb.wait_vsync); | 1004 | init_waitqueue_head(&ps3fb.wait_vsync); |
| 1118 | 1005 | ||
| 1119 | ps3fb_set_sync(&dev->core); | 1006 | #ifdef HEAD_A |
| 1007 | status = lv1_gpu_display_sync(0x0, 0, L1GPU_DISPLAY_SYNC_VSYNC); | ||
| 1008 | if (status) { | ||
| 1009 | dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n", | ||
| 1010 | __func__, status); | ||
| 1011 | retval = -ENODEV; | ||
| 1012 | goto err_close_device; | ||
| 1013 | } | ||
| 1014 | #endif | ||
| 1015 | #ifdef HEAD_B | ||
| 1016 | status = lv1_gpu_display_sync(0x0, 1, L1GPU_DISPLAY_SYNC_VSYNC); | ||
| 1017 | if (status) { | ||
| 1018 | dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n", | ||
| 1019 | __func__, status); | ||
| 1020 | retval = -ENODEV; | ||
| 1021 | goto err_close_device; | ||
| 1022 | } | ||
| 1023 | #endif | ||
| 1120 | 1024 | ||
| 1121 | max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF; | 1025 | max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF; |
| 1122 | if (ps3fb_videomemory.size > max_ps3fb_size) { | 1026 | if (ps3fb_videomemory.size > max_ps3fb_size) { |
| @@ -1131,7 +1035,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
| 1131 | if (status) { | 1035 | if (status) { |
| 1132 | dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n", | 1036 | dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n", |
| 1133 | __func__, status); | 1037 | __func__, status); |
| 1134 | goto err; | 1038 | goto err_close_device; |
| 1135 | } | 1039 | } |
| 1136 | dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar); | 1040 | dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar); |
| 1137 | 1041 | ||
| @@ -1141,33 +1045,85 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
| 1141 | &lpar_reports, &lpar_reports_size); | 1045 | &lpar_reports, &lpar_reports_size); |
| 1142 | if (status) { | 1046 | if (status) { |
| 1143 | dev_err(&dev->core, | 1047 | dev_err(&dev->core, |
| 1144 | "%s: lv1_gpu_context_attribute failed: %d\n", __func__, | 1048 | "%s: lv1_gpu_context_allocate failed: %d\n", __func__, |
| 1145 | status); | 1049 | status); |
| 1146 | goto err_gpu_memory_free; | 1050 | goto err_gpu_memory_free; |
| 1147 | } | 1051 | } |
| 1148 | 1052 | ||
| 1149 | /* vsync interrupt */ | 1053 | /* vsync interrupt */ |
| 1150 | ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); | 1054 | dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); |
| 1151 | if (!ps3fb.dinfo) { | 1055 | if (!dinfo) { |
| 1152 | dev_err(&dev->core, "%s: ioremap failed\n", __func__); | 1056 | dev_err(&dev->core, "%s: ioremap failed\n", __func__); |
| 1153 | goto err_gpu_context_free; | 1057 | goto err_gpu_context_free; |
| 1154 | } | 1058 | } |
| 1155 | 1059 | ||
| 1156 | retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core); | 1060 | ps3fb.dinfo = dinfo; |
| 1157 | if (retval) | 1061 | dev_dbg(&dev->core, "version_driver:%x\n", dinfo->version_driver); |
| 1062 | dev_dbg(&dev->core, "irq outlet:%x\n", dinfo->irq.irq_outlet); | ||
| 1063 | dev_dbg(&dev->core, "version_gpu: %x memory_size: %x ch: %x " | ||
| 1064 | "core_freq: %d mem_freq:%d\n", dinfo->version_gpu, | ||
| 1065 | dinfo->memory_size, dinfo->hardware_channel, | ||
| 1066 | dinfo->nvcore_frequency/1000000, | ||
| 1067 | dinfo->memory_frequency/1000000); | ||
| 1068 | |||
| 1069 | if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) { | ||
| 1070 | dev_err(&dev->core, "%s: version_driver err:%x\n", __func__, | ||
| 1071 | dinfo->version_driver); | ||
| 1072 | retval = -EINVAL; | ||
| 1073 | goto err_iounmap_dinfo; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | retval = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, | ||
| 1077 | &ps3fb.irq_no); | ||
| 1078 | if (retval) { | ||
| 1079 | dev_err(&dev->core, "%s: ps3_alloc_irq failed %d\n", __func__, | ||
| 1080 | retval); | ||
| 1158 | goto err_iounmap_dinfo; | 1081 | goto err_iounmap_dinfo; |
| 1082 | } | ||
| 1083 | |||
| 1084 | retval = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, | ||
| 1085 | IRQF_DISABLED, DEVICE_NAME, &dev->core); | ||
| 1086 | if (retval) { | ||
| 1087 | dev_err(&dev->core, "%s: request_irq failed %d\n", __func__, | ||
| 1088 | retval); | ||
| 1089 | goto err_destroy_plug; | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) | | ||
| 1093 | (1 << GPU_INTR_STATUS_FLIP_1); | ||
| 1159 | 1094 | ||
| 1160 | /* Clear memory to prevent kernel info leakage into userspace */ | 1095 | /* Clear memory to prevent kernel info leakage into userspace */ |
| 1161 | memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size); | 1096 | memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size); |
| 1162 | 1097 | ||
| 1163 | xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); | 1098 | xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); |
| 1164 | retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); | 1099 | |
| 1165 | if (retval) | 1100 | status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, |
| 1101 | xdr_lpar, ps3fb_videomemory.size, | ||
| 1102 | CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | | ||
| 1103 | CBE_IOPTE_M); | ||
| 1104 | if (status) { | ||
| 1105 | dev_err(&dev->core, "%s: lv1_gpu_context_iomap failed: %d\n", | ||
| 1106 | __func__, status); | ||
| 1107 | retval = -ENXIO; | ||
| 1166 | goto err_free_irq; | 1108 | goto err_free_irq; |
| 1109 | } | ||
| 1110 | |||
| 1111 | dev_dbg(&dev->core, "video:%p ioif:%lx lpar:%llx size:%lx\n", | ||
| 1112 | ps3fb_videomemory.address, GPU_IOIF, xdr_lpar, | ||
| 1113 | ps3fb_videomemory.size); | ||
| 1114 | |||
| 1115 | status = lv1_gpu_fb_setup(ps3fb.context_handle, xdr_lpar, | ||
| 1116 | GPU_CMD_BUF_SIZE, GPU_IOIF); | ||
| 1117 | if (status) { | ||
| 1118 | dev_err(&dev->core, "%s: lv1_gpu_fb_setup failed: %d\n", | ||
| 1119 | __func__, status); | ||
| 1120 | retval = -ENXIO; | ||
| 1121 | goto err_context_unmap; | ||
| 1122 | } | ||
| 1167 | 1123 | ||
| 1168 | info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core); | 1124 | info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core); |
| 1169 | if (!info) | 1125 | if (!info) |
| 1170 | goto err_free_irq; | 1126 | goto err_context_fb_close; |
| 1171 | 1127 | ||
| 1172 | par = info->par; | 1128 | par = info->par; |
| 1173 | par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ | 1129 | par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ |
| @@ -1210,7 +1166,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
| 1210 | if (retval < 0) | 1166 | if (retval < 0) |
| 1211 | goto err_fb_dealloc; | 1167 | goto err_fb_dealloc; |
| 1212 | 1168 | ||
| 1213 | dev->core.driver_data = info; | 1169 | ps3_system_bus_set_drvdata(dev, info); |
| 1214 | 1170 | ||
| 1215 | dev_info(info->device, "%s %s, using %u KiB of video memory\n", | 1171 | dev_info(info->device, "%s %s, using %u KiB of video memory\n", |
| 1216 | dev_driver_string(info->dev), dev_name(info->dev), | 1172 | dev_driver_string(info->dev), dev_name(info->dev), |
| @@ -1232,8 +1188,14 @@ err_fb_dealloc: | |||
| 1232 | fb_dealloc_cmap(&info->cmap); | 1188 | fb_dealloc_cmap(&info->cmap); |
| 1233 | err_framebuffer_release: | 1189 | err_framebuffer_release: |
| 1234 | framebuffer_release(info); | 1190 | framebuffer_release(info); |
| 1191 | err_context_fb_close: | ||
| 1192 | lv1_gpu_fb_close(ps3fb.context_handle); | ||
| 1193 | err_context_unmap: | ||
| 1194 | lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar, | ||
| 1195 | ps3fb_videomemory.size, CBE_IOPTE_M); | ||
| 1235 | err_free_irq: | 1196 | err_free_irq: |
| 1236 | free_irq(ps3fb.irq_no, &dev->core); | 1197 | free_irq(ps3fb.irq_no, &dev->core); |
| 1198 | err_destroy_plug: | ||
| 1237 | ps3_irq_plug_destroy(ps3fb.irq_no); | 1199 | ps3_irq_plug_destroy(ps3fb.irq_no); |
| 1238 | err_iounmap_dinfo: | 1200 | err_iounmap_dinfo: |
| 1239 | iounmap((u8 __force __iomem *)ps3fb.dinfo); | 1201 | iounmap((u8 __force __iomem *)ps3fb.dinfo); |
| @@ -1241,14 +1203,16 @@ err_gpu_context_free: | |||
| 1241 | lv1_gpu_context_free(ps3fb.context_handle); | 1203 | lv1_gpu_context_free(ps3fb.context_handle); |
| 1242 | err_gpu_memory_free: | 1204 | err_gpu_memory_free: |
| 1243 | lv1_gpu_memory_free(ps3fb.memory_handle); | 1205 | lv1_gpu_memory_free(ps3fb.memory_handle); |
| 1206 | err_close_device: | ||
| 1207 | ps3_close_hv_device(dev); | ||
| 1244 | err: | 1208 | err: |
| 1245 | return retval; | 1209 | return retval; |
| 1246 | } | 1210 | } |
| 1247 | 1211 | ||
| 1248 | static int ps3fb_shutdown(struct ps3_system_bus_device *dev) | 1212 | static int ps3fb_shutdown(struct ps3_system_bus_device *dev) |
| 1249 | { | 1213 | { |
| 1250 | int status; | 1214 | struct fb_info *info = ps3_system_bus_get_drvdata(dev); |
| 1251 | struct fb_info *info = dev->core.driver_data; | 1215 | u64 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); |
| 1252 | 1216 | ||
| 1253 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); | 1217 | dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); |
| 1254 | 1218 | ||
| @@ -1268,20 +1232,14 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) | |||
| 1268 | unregister_framebuffer(info); | 1232 | unregister_framebuffer(info); |
| 1269 | fb_dealloc_cmap(&info->cmap); | 1233 | fb_dealloc_cmap(&info->cmap); |
| 1270 | framebuffer_release(info); | 1234 | framebuffer_release(info); |
| 1271 | info = dev->core.driver_data = NULL; | 1235 | ps3_system_bus_set_drvdata(dev, NULL); |
| 1272 | } | 1236 | } |
| 1273 | iounmap((u8 __force __iomem *)ps3fb.dinfo); | 1237 | iounmap((u8 __force __iomem *)ps3fb.dinfo); |
| 1274 | 1238 | lv1_gpu_fb_close(ps3fb.context_handle); | |
| 1275 | status = lv1_gpu_context_free(ps3fb.context_handle); | 1239 | lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar, |
| 1276 | if (status) | 1240 | ps3fb_videomemory.size, CBE_IOPTE_M); |
| 1277 | dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n", | 1241 | lv1_gpu_context_free(ps3fb.context_handle); |
| 1278 | status); | 1242 | lv1_gpu_memory_free(ps3fb.memory_handle); |
| 1279 | |||
| 1280 | status = lv1_gpu_memory_free(ps3fb.memory_handle); | ||
| 1281 | if (status) | ||
| 1282 | dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n", | ||
| 1283 | status); | ||
| 1284 | |||
| 1285 | ps3_close_hv_device(dev); | 1243 | ps3_close_hv_device(dev); |
| 1286 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); | 1244 | dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); |
| 1287 | 1245 | ||
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 89f231dc443f..ff43c8885028 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
| @@ -1315,7 +1315,6 @@ static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan, | |||
| 1315 | 1315 | ||
| 1316 | strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name)); | 1316 | strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name)); |
| 1317 | chan->adapter.owner = THIS_MODULE; | 1317 | chan->adapter.owner = THIS_MODULE; |
| 1318 | chan->adapter.class = I2C_CLASS_TV_ANALOG; | ||
| 1319 | chan->adapter.algo_data = &chan->algo; | 1318 | chan->adapter.algo_data = &chan->algo; |
| 1320 | chan->adapter.dev.parent = dev; | 1319 | chan->adapter.dev.parent = dev; |
| 1321 | chan->algo.setsda = tdfxfb_i2c_setsda; | 1320 | chan->algo.setsda = tdfxfb_i2c_setsda; |
| @@ -25,7 +25,6 @@ | |||
| 25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 26 | #include <linux/mempool.h> | 26 | #include <linux/mempool.h> |
| 27 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
| 28 | #include <linux/blktrace_api.h> | ||
| 29 | #include <scsi/sg.h> /* for struct sg_iovec */ | 28 | #include <scsi/sg.h> /* for struct sg_iovec */ |
| 30 | 29 | ||
| 31 | #include <trace/events/block.h> | 30 | #include <trace/events/block.h> |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0d50d49d990a..d28d29c95f7c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | static struct extent_io_ops btree_extent_io_ops; | 42 | static struct extent_io_ops btree_extent_io_ops; |
| 43 | static void end_workqueue_fn(struct btrfs_work *work); | 43 | static void end_workqueue_fn(struct btrfs_work *work); |
| 44 | 44 | ||
| 45 | static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); | ||
| 46 | |||
| 45 | /* | 47 | /* |
| 46 | * end_io_wq structs are used to do processing in task context when an IO is | 48 | * end_io_wq structs are used to do processing in task context when an IO is |
| 47 | * complete. This is used during reads to verify checksums, and it is used | 49 | * complete. This is used during reads to verify checksums, and it is used |
| @@ -1342,12 +1344,25 @@ static void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | |||
| 1342 | free_extent_map(em); | 1344 | free_extent_map(em); |
| 1343 | } | 1345 | } |
| 1344 | 1346 | ||
| 1347 | /* | ||
| 1348 | * If this fails, caller must call bdi_destroy() to get rid of the | ||
| 1349 | * bdi again. | ||
| 1350 | */ | ||
| 1345 | static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) | 1351 | static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) |
| 1346 | { | 1352 | { |
| 1347 | bdi_init(bdi); | 1353 | int err; |
| 1354 | |||
| 1355 | bdi->capabilities = BDI_CAP_MAP_COPY; | ||
| 1356 | err = bdi_init(bdi); | ||
| 1357 | if (err) | ||
| 1358 | return err; | ||
| 1359 | |||
| 1360 | err = bdi_register(bdi, NULL, "btrfs-%d", | ||
| 1361 | atomic_inc_return(&btrfs_bdi_num)); | ||
| 1362 | if (err) | ||
| 1363 | return err; | ||
| 1364 | |||
| 1348 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 1365 | bdi->ra_pages = default_backing_dev_info.ra_pages; |
| 1349 | bdi->state = 0; | ||
| 1350 | bdi->capabilities = default_backing_dev_info.capabilities; | ||
| 1351 | bdi->unplug_io_fn = btrfs_unplug_io_fn; | 1366 | bdi->unplug_io_fn = btrfs_unplug_io_fn; |
| 1352 | bdi->unplug_io_data = info; | 1367 | bdi->unplug_io_data = info; |
| 1353 | bdi->congested_fn = btrfs_congested_fn; | 1368 | bdi->congested_fn = btrfs_congested_fn; |
| @@ -1569,7 +1584,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1569 | fs_info->sb = sb; | 1584 | fs_info->sb = sb; |
| 1570 | fs_info->max_extent = (u64)-1; | 1585 | fs_info->max_extent = (u64)-1; |
| 1571 | fs_info->max_inline = 8192 * 1024; | 1586 | fs_info->max_inline = 8192 * 1024; |
| 1572 | setup_bdi(fs_info, &fs_info->bdi); | 1587 | if (setup_bdi(fs_info, &fs_info->bdi)) |
| 1588 | goto fail_bdi; | ||
| 1573 | fs_info->btree_inode = new_inode(sb); | 1589 | fs_info->btree_inode = new_inode(sb); |
| 1574 | fs_info->btree_inode->i_ino = 1; | 1590 | fs_info->btree_inode->i_ino = 1; |
| 1575 | fs_info->btree_inode->i_nlink = 1; | 1591 | fs_info->btree_inode->i_nlink = 1; |
| @@ -1946,8 +1962,8 @@ fail_iput: | |||
| 1946 | 1962 | ||
| 1947 | btrfs_close_devices(fs_info->fs_devices); | 1963 | btrfs_close_devices(fs_info->fs_devices); |
| 1948 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 1964 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
| 1965 | fail_bdi: | ||
| 1949 | bdi_destroy(&fs_info->bdi); | 1966 | bdi_destroy(&fs_info->bdi); |
| 1950 | |||
| 1951 | fail: | 1967 | fail: |
| 1952 | kfree(extent_root); | 1968 | kfree(extent_root); |
| 1953 | kfree(tree_root); | 1969 | kfree(tree_root); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 2e177d7f4bb9..4e83457ea253 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -543,13 +543,13 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
| 543 | btrfs_free_log(trans, root); | 543 | btrfs_free_log(trans, root); |
| 544 | btrfs_update_reloc_root(trans, root); | 544 | btrfs_update_reloc_root(trans, root); |
| 545 | 545 | ||
| 546 | if (root->commit_root == root->node) | 546 | if (root->commit_root != root->node) { |
| 547 | continue; | 547 | free_extent_buffer(root->commit_root); |
| 548 | 548 | root->commit_root = btrfs_root_node(root); | |
| 549 | free_extent_buffer(root->commit_root); | 549 | btrfs_set_root_node(&root->root_item, |
| 550 | root->commit_root = btrfs_root_node(root); | 550 | root->node); |
| 551 | } | ||
| 551 | 552 | ||
| 552 | btrfs_set_root_node(&root->root_item, root->node); | ||
| 553 | err = btrfs_update_root(trans, fs_info->tree_root, | 553 | err = btrfs_update_root(trans, fs_info->tree_root, |
| 554 | &root->root_key, | 554 | &root->root_key, |
| 555 | &root->root_item); | 555 | &root->root_item); |
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index b42602298087..923990e4f16e 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c | |||
| @@ -241,7 +241,7 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) | |||
| 241 | while (*fclus < cluster) { | 241 | while (*fclus < cluster) { |
| 242 | /* prevent the infinite loop of cluster chain */ | 242 | /* prevent the infinite loop of cluster chain */ |
| 243 | if (*fclus > limit) { | 243 | if (*fclus > limit) { |
| 244 | fat_fs_panic(sb, "%s: detected the cluster chain loop" | 244 | fat_fs_error(sb, "%s: detected the cluster chain loop" |
| 245 | " (i_pos %lld)", __func__, | 245 | " (i_pos %lld)", __func__, |
| 246 | MSDOS_I(inode)->i_pos); | 246 | MSDOS_I(inode)->i_pos); |
| 247 | nr = -EIO; | 247 | nr = -EIO; |
| @@ -252,7 +252,7 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) | |||
| 252 | if (nr < 0) | 252 | if (nr < 0) |
| 253 | goto out; | 253 | goto out; |
| 254 | else if (nr == FAT_ENT_FREE) { | 254 | else if (nr == FAT_ENT_FREE) { |
| 255 | fat_fs_panic(sb, "%s: invalid cluster chain" | 255 | fat_fs_error(sb, "%s: invalid cluster chain" |
| 256 | " (i_pos %lld)", __func__, | 256 | " (i_pos %lld)", __func__, |
| 257 | MSDOS_I(inode)->i_pos); | 257 | MSDOS_I(inode)->i_pos); |
| 258 | nr = -EIO; | 258 | nr = -EIO; |
| @@ -285,7 +285,7 @@ static int fat_bmap_cluster(struct inode *inode, int cluster) | |||
| 285 | if (ret < 0) | 285 | if (ret < 0) |
| 286 | return ret; | 286 | return ret; |
| 287 | else if (ret == FAT_ENT_EOF) { | 287 | else if (ret == FAT_ENT_EOF) { |
| 288 | fat_fs_panic(sb, "%s: request beyond EOF (i_pos %lld)", | 288 | fat_fs_error(sb, "%s: request beyond EOF (i_pos %lld)", |
| 289 | __func__, MSDOS_I(inode)->i_pos); | 289 | __func__, MSDOS_I(inode)->i_pos); |
| 290 | return -EIO; | 290 | return -EIO; |
| 291 | } | 291 | } |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index f3500294eec5..3b8e71b412fd 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
| @@ -1334,7 +1334,7 @@ found: | |||
| 1334 | goto error_remove; | 1334 | goto error_remove; |
| 1335 | } | 1335 | } |
| 1336 | if (dir->i_size & (sbi->cluster_size - 1)) { | 1336 | if (dir->i_size & (sbi->cluster_size - 1)) { |
| 1337 | fat_fs_panic(sb, "Odd directory size"); | 1337 | fat_fs_error(sb, "Odd directory size"); |
| 1338 | dir->i_size = (dir->i_size + sbi->cluster_size - 1) | 1338 | dir->i_size = (dir->i_size + sbi->cluster_size - 1) |
| 1339 | & ~((loff_t)sbi->cluster_size - 1); | 1339 | & ~((loff_t)sbi->cluster_size - 1); |
| 1340 | } | 1340 | } |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index e4d88527b5dd..adb0e72a176d 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
| @@ -17,6 +17,10 @@ | |||
| 17 | #define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */ | 17 | #define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */ |
| 18 | #define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */ | 18 | #define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */ |
| 19 | 19 | ||
| 20 | #define FAT_ERRORS_CONT 1 /* ignore error and continue */ | ||
| 21 | #define FAT_ERRORS_PANIC 2 /* panic on error */ | ||
| 22 | #define FAT_ERRORS_RO 3 /* remount r/o on error */ | ||
| 23 | |||
| 20 | struct fat_mount_options { | 24 | struct fat_mount_options { |
| 21 | uid_t fs_uid; | 25 | uid_t fs_uid; |
| 22 | gid_t fs_gid; | 26 | gid_t fs_gid; |
| @@ -26,6 +30,7 @@ struct fat_mount_options { | |||
| 26 | char *iocharset; /* Charset used for filename input/display */ | 30 | char *iocharset; /* Charset used for filename input/display */ |
| 27 | unsigned short shortname; /* flags for shortname display/create rule */ | 31 | unsigned short shortname; /* flags for shortname display/create rule */ |
| 28 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ | 32 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ |
| 33 | unsigned char errors; /* On error: continue, panic, remount-ro */ | ||
| 29 | unsigned short allow_utime;/* permission for setting the [am]time */ | 34 | unsigned short allow_utime;/* permission for setting the [am]time */ |
| 30 | unsigned quiet:1, /* set = fake successful chmods and chowns */ | 35 | unsigned quiet:1, /* set = fake successful chmods and chowns */ |
| 31 | showexec:1, /* set = only set x bit for com/exe/bat */ | 36 | showexec:1, /* set = only set x bit for com/exe/bat */ |
| @@ -316,7 +321,7 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
| 316 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, | 321 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, |
| 317 | struct inode *i2); | 322 | struct inode *i2); |
| 318 | /* fat/misc.c */ | 323 | /* fat/misc.c */ |
| 319 | extern void fat_fs_panic(struct super_block *s, const char *fmt, ...) | 324 | extern void fat_fs_error(struct super_block *s, const char *fmt, ...) |
| 320 | __attribute__ ((format (printf, 2, 3))) __cold; | 325 | __attribute__ ((format (printf, 2, 3))) __cold; |
| 321 | extern void fat_clusters_flush(struct super_block *sb); | 326 | extern void fat_clusters_flush(struct super_block *sb); |
| 322 | extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); | 327 | extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); |
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 618f5305c2e4..a81037721a6f 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c | |||
| @@ -348,7 +348,7 @@ int fat_ent_read(struct inode *inode, struct fat_entry *fatent, int entry) | |||
| 348 | 348 | ||
| 349 | if (entry < FAT_START_ENT || sbi->max_cluster <= entry) { | 349 | if (entry < FAT_START_ENT || sbi->max_cluster <= entry) { |
| 350 | fatent_brelse(fatent); | 350 | fatent_brelse(fatent); |
| 351 | fat_fs_panic(sb, "invalid access to FAT (entry 0x%08x)", entry); | 351 | fat_fs_error(sb, "invalid access to FAT (entry 0x%08x)", entry); |
| 352 | return -EIO; | 352 | return -EIO; |
| 353 | } | 353 | } |
| 354 | 354 | ||
| @@ -560,7 +560,7 @@ int fat_free_clusters(struct inode *inode, int cluster) | |||
| 560 | err = cluster; | 560 | err = cluster; |
| 561 | goto error; | 561 | goto error; |
| 562 | } else if (cluster == FAT_ENT_FREE) { | 562 | } else if (cluster == FAT_ENT_FREE) { |
| 563 | fat_fs_panic(sb, "%s: deleting FAT entry beyond EOF", | 563 | fat_fs_error(sb, "%s: deleting FAT entry beyond EOF", |
| 564 | __func__); | 564 | __func__); |
| 565 | err = -EIO; | 565 | err = -EIO; |
| 566 | goto error; | 566 | goto error; |
diff --git a/fs/fat/file.c b/fs/fat/file.c index e955a56b4e5e..b28ea646ff60 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
| @@ -18,106 +18,112 @@ | |||
| 18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
| 19 | #include "fat.h" | 19 | #include "fat.h" |
| 20 | 20 | ||
| 21 | int fat_generic_ioctl(struct inode *inode, struct file *filp, | 21 | static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr) |
| 22 | unsigned int cmd, unsigned long arg) | ||
| 23 | { | 22 | { |
| 23 | u32 attr; | ||
| 24 | |||
| 25 | mutex_lock(&inode->i_mutex); | ||
| 26 | attr = fat_make_attrs(inode); | ||
| 27 | mutex_unlock(&inode->i_mutex); | ||
| 28 | |||
| 29 | return put_user(attr, user_attr); | ||
| 30 | } | ||
| 31 | |||
| 32 | static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) | ||
| 33 | { | ||
| 34 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 24 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | 35 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
| 25 | u32 __user *user_attr = (u32 __user *)arg; | 36 | int is_dir = S_ISDIR(inode->i_mode); |
| 37 | u32 attr, oldattr; | ||
| 38 | struct iattr ia; | ||
| 39 | int err; | ||
| 26 | 40 | ||
| 27 | switch (cmd) { | 41 | err = get_user(attr, user_attr); |
| 28 | case FAT_IOCTL_GET_ATTRIBUTES: | 42 | if (err) |
| 29 | { | 43 | goto out; |
| 30 | u32 attr; | ||
| 31 | 44 | ||
| 32 | mutex_lock(&inode->i_mutex); | 45 | mutex_lock(&inode->i_mutex); |
| 33 | attr = fat_make_attrs(inode); | 46 | err = mnt_want_write(file->f_path.mnt); |
| 34 | mutex_unlock(&inode->i_mutex); | 47 | if (err) |
| 48 | goto out_unlock_inode; | ||
| 35 | 49 | ||
| 36 | return put_user(attr, user_attr); | 50 | /* |
| 51 | * ATTR_VOLUME and ATTR_DIR cannot be changed; this also | ||
| 52 | * prevents the user from turning us into a VFAT | ||
| 53 | * longname entry. Also, we obviously can't set | ||
| 54 | * any of the NTFS attributes in the high 24 bits. | ||
| 55 | */ | ||
| 56 | attr &= 0xff & ~(ATTR_VOLUME | ATTR_DIR); | ||
| 57 | /* Merge in ATTR_VOLUME and ATTR_DIR */ | ||
| 58 | attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) | | ||
| 59 | (is_dir ? ATTR_DIR : 0); | ||
| 60 | oldattr = fat_make_attrs(inode); | ||
| 61 | |||
| 62 | /* Equivalent to a chmod() */ | ||
| 63 | ia.ia_valid = ATTR_MODE | ATTR_CTIME; | ||
| 64 | ia.ia_ctime = current_fs_time(inode->i_sb); | ||
| 65 | if (is_dir) | ||
| 66 | ia.ia_mode = fat_make_mode(sbi, attr, S_IRWXUGO); | ||
| 67 | else { | ||
| 68 | ia.ia_mode = fat_make_mode(sbi, attr, | ||
| 69 | S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO)); | ||
| 37 | } | 70 | } |
| 38 | case FAT_IOCTL_SET_ATTRIBUTES: | ||
| 39 | { | ||
| 40 | u32 attr, oldattr; | ||
| 41 | int err, is_dir = S_ISDIR(inode->i_mode); | ||
| 42 | struct iattr ia; | ||
| 43 | 71 | ||
| 44 | err = get_user(attr, user_attr); | 72 | /* The root directory has no attributes */ |
| 45 | if (err) | 73 | if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { |
| 46 | return err; | 74 | err = -EINVAL; |
| 75 | goto out_drop_write; | ||
| 76 | } | ||
| 47 | 77 | ||
| 48 | mutex_lock(&inode->i_mutex); | 78 | if (sbi->options.sys_immutable && |
| 49 | 79 | ((attr | oldattr) & ATTR_SYS) && | |
| 50 | err = mnt_want_write(filp->f_path.mnt); | 80 | !capable(CAP_LINUX_IMMUTABLE)) { |
| 51 | if (err) | 81 | err = -EPERM; |
| 52 | goto up_no_drop_write; | 82 | goto out_drop_write; |
| 53 | 83 | } | |
| 54 | /* | ||
| 55 | * ATTR_VOLUME and ATTR_DIR cannot be changed; this also | ||
| 56 | * prevents the user from turning us into a VFAT | ||
| 57 | * longname entry. Also, we obviously can't set | ||
| 58 | * any of the NTFS attributes in the high 24 bits. | ||
| 59 | */ | ||
| 60 | attr &= 0xff & ~(ATTR_VOLUME | ATTR_DIR); | ||
| 61 | /* Merge in ATTR_VOLUME and ATTR_DIR */ | ||
| 62 | attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) | | ||
| 63 | (is_dir ? ATTR_DIR : 0); | ||
| 64 | oldattr = fat_make_attrs(inode); | ||
| 65 | |||
| 66 | /* Equivalent to a chmod() */ | ||
| 67 | ia.ia_valid = ATTR_MODE | ATTR_CTIME; | ||
| 68 | ia.ia_ctime = current_fs_time(inode->i_sb); | ||
| 69 | if (is_dir) | ||
| 70 | ia.ia_mode = fat_make_mode(sbi, attr, S_IRWXUGO); | ||
| 71 | else { | ||
| 72 | ia.ia_mode = fat_make_mode(sbi, attr, | ||
| 73 | S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO)); | ||
| 74 | } | ||
| 75 | 84 | ||
| 76 | /* The root directory has no attributes */ | 85 | /* |
| 77 | if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { | 86 | * The security check is questionable... We single |
| 78 | err = -EINVAL; | 87 | * out the RO attribute for checking by the security |
| 79 | goto up; | 88 | * module, just because it maps to a file mode. |
| 80 | } | 89 | */ |
| 90 | err = security_inode_setattr(file->f_path.dentry, &ia); | ||
| 91 | if (err) | ||
| 92 | goto out_drop_write; | ||
| 81 | 93 | ||
| 82 | if (sbi->options.sys_immutable) { | 94 | /* This MUST be done before doing anything irreversible... */ |
| 83 | if ((attr | oldattr) & ATTR_SYS) { | 95 | err = fat_setattr(file->f_path.dentry, &ia); |
| 84 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 96 | if (err) |
| 85 | err = -EPERM; | 97 | goto out_drop_write; |
| 86 | goto up; | 98 | |
| 87 | } | 99 | fsnotify_change(file->f_path.dentry, ia.ia_valid); |
| 88 | } | 100 | if (sbi->options.sys_immutable) { |
| 89 | } | 101 | if (attr & ATTR_SYS) |
| 102 | inode->i_flags |= S_IMMUTABLE; | ||
| 103 | else | ||
| 104 | inode->i_flags &= S_IMMUTABLE; | ||
| 105 | } | ||
| 90 | 106 | ||
| 91 | /* | 107 | fat_save_attrs(inode, attr); |
| 92 | * The security check is questionable... We single | 108 | mark_inode_dirty(inode); |
| 93 | * out the RO attribute for checking by the security | 109 | out_drop_write: |
| 94 | * module, just because it maps to a file mode. | 110 | mnt_drop_write(file->f_path.mnt); |
| 95 | */ | 111 | out_unlock_inode: |
| 96 | err = security_inode_setattr(filp->f_path.dentry, &ia); | 112 | mutex_unlock(&inode->i_mutex); |
| 97 | if (err) | 113 | out: |
| 98 | goto up; | 114 | return err; |
| 99 | 115 | } | |
| 100 | /* This MUST be done before doing anything irreversible... */ | ||
| 101 | err = fat_setattr(filp->f_path.dentry, &ia); | ||
| 102 | if (err) | ||
| 103 | goto up; | ||
| 104 | |||
| 105 | fsnotify_change(filp->f_path.dentry, ia.ia_valid); | ||
| 106 | if (sbi->options.sys_immutable) { | ||
| 107 | if (attr & ATTR_SYS) | ||
| 108 | inode->i_flags |= S_IMMUTABLE; | ||
| 109 | else | ||
| 110 | inode->i_flags &= S_IMMUTABLE; | ||
| 111 | } | ||
| 112 | 116 | ||
| 113 | fat_save_attrs(inode, attr); | 117 | int fat_generic_ioctl(struct inode *inode, struct file *filp, |
| 114 | mark_inode_dirty(inode); | 118 | unsigned int cmd, unsigned long arg) |
| 115 | up: | 119 | { |
| 116 | mnt_drop_write(filp->f_path.mnt); | 120 | u32 __user *user_attr = (u32 __user *)arg; |
| 117 | up_no_drop_write: | 121 | |
| 118 | mutex_unlock(&inode->i_mutex); | 122 | switch (cmd) { |
| 119 | return err; | 123 | case FAT_IOCTL_GET_ATTRIBUTES: |
| 120 | } | 124 | return fat_ioctl_get_attributes(inode, user_attr); |
| 125 | case FAT_IOCTL_SET_ATTRIBUTES: | ||
| 126 | return fat_ioctl_set_attributes(filp, user_attr); | ||
| 121 | default: | 127 | default: |
| 122 | return -ENOTTY; /* Inappropriate ioctl for device */ | 128 | return -ENOTTY; /* Inappropriate ioctl for device */ |
| 123 | } | 129 | } |
| @@ -225,7 +231,7 @@ static int fat_free(struct inode *inode, int skip) | |||
| 225 | fatent_brelse(&fatent); | 231 | fatent_brelse(&fatent); |
| 226 | return 0; | 232 | return 0; |
| 227 | } else if (ret == FAT_ENT_FREE) { | 233 | } else if (ret == FAT_ENT_FREE) { |
| 228 | fat_fs_panic(sb, | 234 | fat_fs_error(sb, |
| 229 | "%s: invalid cluster chain (i_pos %lld)", | 235 | "%s: invalid cluster chain (i_pos %lld)", |
| 230 | __func__, MSDOS_I(inode)->i_pos); | 236 | __func__, MSDOS_I(inode)->i_pos); |
| 231 | ret = -EIO; | 237 | ret = -EIO; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 51a5ecf9000a..304b411cb8bc 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
| @@ -76,7 +76,7 @@ static inline int __fat_get_block(struct inode *inode, sector_t iblock, | |||
| 76 | return 0; | 76 | return 0; |
| 77 | 77 | ||
| 78 | if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) { | 78 | if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) { |
| 79 | fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)", | 79 | fat_fs_error(sb, "corrupted file size (i_pos %lld, %lld)", |
| 80 | MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private); | 80 | MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private); |
| 81 | return -EIO; | 81 | return -EIO; |
| 82 | } | 82 | } |
| @@ -856,6 +856,12 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
| 856 | seq_puts(m, ",flush"); | 856 | seq_puts(m, ",flush"); |
| 857 | if (opts->tz_utc) | 857 | if (opts->tz_utc) |
| 858 | seq_puts(m, ",tz=UTC"); | 858 | seq_puts(m, ",tz=UTC"); |
| 859 | if (opts->errors == FAT_ERRORS_CONT) | ||
| 860 | seq_puts(m, ",errors=continue"); | ||
| 861 | else if (opts->errors == FAT_ERRORS_PANIC) | ||
| 862 | seq_puts(m, ",errors=panic"); | ||
| 863 | else | ||
| 864 | seq_puts(m, ",errors=remount-ro"); | ||
| 859 | 865 | ||
| 860 | return 0; | 866 | return 0; |
| 861 | } | 867 | } |
| @@ -868,7 +874,8 @@ enum { | |||
| 868 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, | 874 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, |
| 869 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 875 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, |
| 870 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 876 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
| 871 | Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err, | 877 | Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, |
| 878 | Opt_err_panic, Opt_err_ro, Opt_err, | ||
| 872 | }; | 879 | }; |
| 873 | 880 | ||
| 874 | static const match_table_t fat_tokens = { | 881 | static const match_table_t fat_tokens = { |
| @@ -891,6 +898,11 @@ static const match_table_t fat_tokens = { | |||
| 891 | {Opt_showexec, "showexec"}, | 898 | {Opt_showexec, "showexec"}, |
| 892 | {Opt_debug, "debug"}, | 899 | {Opt_debug, "debug"}, |
| 893 | {Opt_immutable, "sys_immutable"}, | 900 | {Opt_immutable, "sys_immutable"}, |
| 901 | {Opt_flush, "flush"}, | ||
| 902 | {Opt_tz_utc, "tz=UTC"}, | ||
| 903 | {Opt_err_cont, "errors=continue"}, | ||
| 904 | {Opt_err_panic, "errors=panic"}, | ||
| 905 | {Opt_err_ro, "errors=remount-ro"}, | ||
| 894 | {Opt_obsolate, "conv=binary"}, | 906 | {Opt_obsolate, "conv=binary"}, |
| 895 | {Opt_obsolate, "conv=text"}, | 907 | {Opt_obsolate, "conv=text"}, |
| 896 | {Opt_obsolate, "conv=auto"}, | 908 | {Opt_obsolate, "conv=auto"}, |
| @@ -902,8 +914,6 @@ static const match_table_t fat_tokens = { | |||
| 902 | {Opt_obsolate, "cvf_format=%20s"}, | 914 | {Opt_obsolate, "cvf_format=%20s"}, |
| 903 | {Opt_obsolate, "cvf_options=%100s"}, | 915 | {Opt_obsolate, "cvf_options=%100s"}, |
| 904 | {Opt_obsolate, "posix"}, | 916 | {Opt_obsolate, "posix"}, |
| 905 | {Opt_flush, "flush"}, | ||
| 906 | {Opt_tz_utc, "tz=UTC"}, | ||
| 907 | {Opt_err, NULL}, | 917 | {Opt_err, NULL}, |
| 908 | }; | 918 | }; |
| 909 | static const match_table_t msdos_tokens = { | 919 | static const match_table_t msdos_tokens = { |
| @@ -973,6 +983,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
| 973 | opts->numtail = 1; | 983 | opts->numtail = 1; |
| 974 | opts->usefree = opts->nocase = 0; | 984 | opts->usefree = opts->nocase = 0; |
| 975 | opts->tz_utc = 0; | 985 | opts->tz_utc = 0; |
| 986 | opts->errors = FAT_ERRORS_RO; | ||
| 976 | *debug = 0; | 987 | *debug = 0; |
| 977 | 988 | ||
| 978 | if (!options) | 989 | if (!options) |
| @@ -1065,6 +1076,15 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
| 1065 | case Opt_tz_utc: | 1076 | case Opt_tz_utc: |
| 1066 | opts->tz_utc = 1; | 1077 | opts->tz_utc = 1; |
| 1067 | break; | 1078 | break; |
| 1079 | case Opt_err_cont: | ||
| 1080 | opts->errors = FAT_ERRORS_CONT; | ||
| 1081 | break; | ||
| 1082 | case Opt_err_panic: | ||
| 1083 | opts->errors = FAT_ERRORS_PANIC; | ||
| 1084 | break; | ||
| 1085 | case Opt_err_ro: | ||
| 1086 | opts->errors = FAT_ERRORS_RO; | ||
| 1087 | break; | ||
| 1068 | 1088 | ||
| 1069 | /* msdos specific */ | 1089 | /* msdos specific */ |
| 1070 | case Opt_dots: | 1090 | case Opt_dots: |
diff --git a/fs/fat/misc.c b/fs/fat/misc.c index ac39ebcc1496..a6c20473dfd7 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c | |||
| @@ -12,14 +12,19 @@ | |||
| 12 | #include "fat.h" | 12 | #include "fat.h" |
| 13 | 13 | ||
| 14 | /* | 14 | /* |
| 15 | * fat_fs_panic reports a severe file system problem and sets the file system | 15 | * fat_fs_error reports a file system problem that might indicate fa data |
| 16 | * read-only. The file system can be made writable again by remounting it. | 16 | * corruption/inconsistency. Depending on 'errors' mount option the |
| 17 | * panic() is called, or error message is printed FAT and nothing is done, | ||
| 18 | * or filesystem is remounted read-only (default behavior). | ||
| 19 | * In case the file system is remounted read-only, it can be made writable | ||
| 20 | * again by remounting it. | ||
| 17 | */ | 21 | */ |
| 18 | void fat_fs_panic(struct super_block *s, const char *fmt, ...) | 22 | void fat_fs_error(struct super_block *s, const char *fmt, ...) |
| 19 | { | 23 | { |
| 24 | struct fat_mount_options *opts = &MSDOS_SB(s)->options; | ||
| 20 | va_list args; | 25 | va_list args; |
| 21 | 26 | ||
| 22 | printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n", s->s_id); | 27 | printk(KERN_ERR "FAT: Filesystem error (dev %s)\n", s->s_id); |
| 23 | 28 | ||
| 24 | printk(KERN_ERR " "); | 29 | printk(KERN_ERR " "); |
| 25 | va_start(args, fmt); | 30 | va_start(args, fmt); |
| @@ -27,13 +32,14 @@ void fat_fs_panic(struct super_block *s, const char *fmt, ...) | |||
| 27 | va_end(args); | 32 | va_end(args); |
| 28 | printk("\n"); | 33 | printk("\n"); |
| 29 | 34 | ||
| 30 | if (!(s->s_flags & MS_RDONLY)) { | 35 | if (opts->errors == FAT_ERRORS_PANIC) |
| 36 | panic(" FAT fs panic from previous error\n"); | ||
| 37 | else if (opts->errors == FAT_ERRORS_RO && !(s->s_flags & MS_RDONLY)) { | ||
| 31 | s->s_flags |= MS_RDONLY; | 38 | s->s_flags |= MS_RDONLY; |
| 32 | printk(KERN_ERR " File system has been set read-only\n"); | 39 | printk(KERN_ERR " File system has been set read-only\n"); |
| 33 | } | 40 | } |
| 34 | } | 41 | } |
| 35 | 42 | EXPORT_SYMBOL_GPL(fat_fs_error); | |
| 36 | EXPORT_SYMBOL_GPL(fat_fs_panic); | ||
| 37 | 43 | ||
| 38 | /* Flushes the number of free clusters on FAT32 */ | 44 | /* Flushes the number of free clusters on FAT32 */ |
| 39 | /* XXX: Need to write one per FSINFO block. Currently only writes 1 */ | 45 | /* XXX: Need to write one per FSINFO block. Currently only writes 1 */ |
| @@ -124,7 +130,7 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster) | |||
| 124 | mark_inode_dirty(inode); | 130 | mark_inode_dirty(inode); |
| 125 | } | 131 | } |
| 126 | if (new_fclus != (inode->i_blocks >> (sbi->cluster_bits - 9))) { | 132 | if (new_fclus != (inode->i_blocks >> (sbi->cluster_bits - 9))) { |
| 127 | fat_fs_panic(sb, "clusters badly computed (%d != %llu)", | 133 | fat_fs_error(sb, "clusters badly computed (%d != %llu)", |
| 128 | new_fclus, | 134 | new_fclus, |
| 129 | (llu)(inode->i_blocks >> (sbi->cluster_bits - 9))); | 135 | (llu)(inode->i_blocks >> (sbi->cluster_bits - 9))); |
| 130 | fat_cache_inval_inode(inode); | 136 | fat_cache_inval_inode(inode); |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 20f522861355..82f88733b681 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
| @@ -608,7 +608,7 @@ error_inode: | |||
| 608 | sinfo.bh = NULL; | 608 | sinfo.bh = NULL; |
| 609 | } | 609 | } |
| 610 | if (corrupt < 0) { | 610 | if (corrupt < 0) { |
| 611 | fat_fs_panic(new_dir->i_sb, | 611 | fat_fs_error(new_dir->i_sb, |
| 612 | "%s: Filesystem corrupted (i_pos %lld)", | 612 | "%s: Filesystem corrupted (i_pos %lld)", |
| 613 | __func__, sinfo.i_pos); | 613 | __func__, sinfo.i_pos); |
| 614 | } | 614 | } |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index b50ecbe97f83..8d6fdcfd41df 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
| @@ -1030,7 +1030,7 @@ error_inode: | |||
| 1030 | sinfo.bh = NULL; | 1030 | sinfo.bh = NULL; |
| 1031 | } | 1031 | } |
| 1032 | if (corrupt < 0) { | 1032 | if (corrupt < 0) { |
| 1033 | fat_fs_panic(new_dir->i_sb, | 1033 | fat_fs_error(new_dir->i_sb, |
| 1034 | "%s: Filesystem corrupted (i_pos %lld)", | 1034 | "%s: Filesystem corrupted (i_pos %lld)", |
| 1035 | __func__, sinfo.i_pos); | 1035 | __func__, sinfo.i_pos); |
| 1036 | } | 1036 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 3589eab02a2f..3260b73abe29 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -1937,6 +1937,9 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1937 | err = bdi_init(&c->bdi); | 1937 | err = bdi_init(&c->bdi); |
| 1938 | if (err) | 1938 | if (err) |
| 1939 | goto out_close; | 1939 | goto out_close; |
| 1940 | err = bdi_register(&c->bdi, NULL, "ubifs"); | ||
| 1941 | if (err) | ||
| 1942 | goto out_bdi; | ||
| 1940 | 1943 | ||
| 1941 | err = ubifs_parse_options(c, data, 0); | 1944 | err = ubifs_parse_options(c, data, 0); |
| 1942 | if (err) | 1945 | if (err) |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 4db89e98535d..82ec6a3c0500 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
| @@ -47,7 +47,7 @@ | |||
| 47 | 47 | ||
| 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
| 49 | 49 | ||
| 50 | #define ACPI_CA_VERSION 0x20090320 | 50 | #define ACPI_CA_VERSION 0x20090521 |
| 51 | 51 | ||
| 52 | #include "actypes.h" | 52 | #include "actypes.h" |
| 53 | #include "actbl.h" | 53 | #include "actbl.h" |
| @@ -201,6 +201,8 @@ acpi_evaluate_object_typed(acpi_handle object, | |||
| 201 | acpi_status | 201 | acpi_status |
| 202 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer); | 202 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer); |
| 203 | 203 | ||
| 204 | acpi_status acpi_install_method(u8 *buffer); | ||
| 205 | |||
| 204 | acpi_status | 206 | acpi_status |
| 205 | acpi_get_next_object(acpi_object_type type, | 207 | acpi_get_next_object(acpi_object_type type, |
| 206 | acpi_handle parent, | 208 | acpi_handle parent, |
| @@ -375,7 +377,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); | |||
| 375 | acpi_status acpi_leave_sleep_state(u8 sleep_state); | 377 | acpi_status acpi_leave_sleep_state(u8 sleep_state); |
| 376 | 378 | ||
| 377 | /* | 379 | /* |
| 378 | * Debug output | 380 | * Error/Warning output |
| 379 | */ | 381 | */ |
| 380 | void ACPI_INTERNAL_VAR_XFACE | 382 | void ACPI_INTERNAL_VAR_XFACE |
| 381 | acpi_error(const char *module_name, | 383 | acpi_error(const char *module_name, |
| @@ -394,6 +396,9 @@ void ACPI_INTERNAL_VAR_XFACE | |||
| 394 | acpi_info(const char *module_name, | 396 | acpi_info(const char *module_name, |
| 395 | u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); | 397 | u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); |
| 396 | 398 | ||
| 399 | /* | ||
| 400 | * Debug output | ||
| 401 | */ | ||
| 397 | #ifdef ACPI_DEBUG_OUTPUT | 402 | #ifdef ACPI_DEBUG_OUTPUT |
| 398 | 403 | ||
| 399 | void ACPI_INTERNAL_VAR_XFACE | 404 | void ACPI_INTERNAL_VAR_XFACE |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index f555d927f7c0..37ba576d06e8 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
| @@ -429,20 +429,12 @@ typedef unsigned long long acpi_integer; | |||
| 429 | 429 | ||
| 430 | /* Data manipulation */ | 430 | /* Data manipulation */ |
| 431 | 431 | ||
| 432 | #define ACPI_LOWORD(l) ((u16)(u32)(l)) | 432 | #define ACPI_LOBYTE(integer) ((u8) (u16)(integer)) |
| 433 | #define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) | 433 | #define ACPI_HIBYTE(integer) ((u8) (((u16)(integer)) >> 8)) |
| 434 | #define ACPI_LOBYTE(l) ((u8)(u16)(l)) | 434 | #define ACPI_LOWORD(integer) ((u16) (u32)(integer)) |
| 435 | #define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) | 435 | #define ACPI_HIWORD(integer) ((u16)(((u32)(integer)) >> 16)) |
| 436 | 436 | #define ACPI_LODWORD(integer64) ((u32) (u64)(integer64)) | |
| 437 | /* Full 64-bit integer must be available on both 32-bit and 64-bit platforms */ | 437 | #define ACPI_HIDWORD(integer64) ((u32)(((u64)(integer64)) >> 32)) |
| 438 | |||
| 439 | struct acpi_integer_overlay { | ||
| 440 | u32 lo_dword; | ||
| 441 | u32 hi_dword; | ||
| 442 | }; | ||
| 443 | |||
| 444 | #define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword) | ||
| 445 | #define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword) | ||
| 446 | 438 | ||
| 447 | #define ACPI_SET_BIT(target,bit) ((target) |= (bit)) | 439 | #define ACPI_SET_BIT(target,bit) ((target) |= (bit)) |
| 448 | #define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) | 440 | #define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit)) |
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 8e2cdc57b197..935c5d7fc86e 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h | |||
| @@ -62,4 +62,8 @@ | |||
| 62 | */ | 62 | */ |
| 63 | #define ACPI_UNUSED_VAR __attribute__ ((unused)) | 63 | #define ACPI_UNUSED_VAR __attribute__ ((unused)) |
| 64 | 64 | ||
| 65 | #ifdef _ANSI | ||
| 66 | #define inline | ||
| 67 | #endif | ||
| 68 | |||
| 65 | #endif /* __ACGCC_H__ */ | 69 | #endif /* __ACGCC_H__ */ |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 6d49b2a498c4..fcb8e4b159b1 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Name: aclinux.h - OS specific defines, etc. | 3 | * Name: aclinux.h - OS specific defines, etc. for Linux |
| 4 | * | 4 | * |
| 5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Copyright (C) 2000 - 2008, Intel Corp. | 8 | * Copyright (C) 2000 - 2009, Intel Corp. |
| 9 | * All rights reserved. | 9 | * All rights reserved. |
| 10 | * | 10 | * |
| 11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
| @@ -44,10 +44,13 @@ | |||
| 44 | #ifndef __ACLINUX_H__ | 44 | #ifndef __ACLINUX_H__ |
| 45 | #define __ACLINUX_H__ | 45 | #define __ACLINUX_H__ |
| 46 | 46 | ||
| 47 | /* Common (in-kernel/user-space) ACPICA configuration */ | ||
| 48 | |||
| 47 | #define ACPI_USE_SYSTEM_CLIBRARY | 49 | #define ACPI_USE_SYSTEM_CLIBRARY |
| 48 | #define ACPI_USE_DO_WHILE_0 | 50 | #define ACPI_USE_DO_WHILE_0 |
| 49 | #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE | 51 | #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE |
| 50 | 52 | ||
| 53 | |||
| 51 | #ifdef __KERNEL__ | 54 | #ifdef __KERNEL__ |
| 52 | 55 | ||
| 53 | #include <linux/string.h> | 56 | #include <linux/string.h> |
| @@ -63,15 +66,18 @@ | |||
| 63 | #include <linux/spinlock_types.h> | 66 | #include <linux/spinlock_types.h> |
| 64 | #include <asm/current.h> | 67 | #include <asm/current.h> |
| 65 | 68 | ||
| 66 | /* Host-dependent types and defines */ | 69 | /* Host-dependent types and defines for in-kernel ACPICA */ |
| 67 | 70 | ||
| 68 | #define ACPI_MACHINE_WIDTH BITS_PER_LONG | 71 | #define ACPI_MACHINE_WIDTH BITS_PER_LONG |
| 69 | #define acpi_cache_t struct kmem_cache | ||
| 70 | #define acpi_spinlock spinlock_t * | ||
| 71 | #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); | 72 | #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); |
| 72 | #define strtoul simple_strtoul | 73 | #define strtoul simple_strtoul |
| 73 | 74 | ||
| 74 | #else /* !__KERNEL__ */ | 75 | #define acpi_cache_t struct kmem_cache |
| 76 | #define acpi_spinlock spinlock_t * | ||
| 77 | #define acpi_cpu_flags unsigned long | ||
| 78 | #define acpi_thread_id struct task_struct * | ||
| 79 | |||
| 80 | #else /* !__KERNEL__ */ | ||
| 75 | 81 | ||
| 76 | #include <stdarg.h> | 82 | #include <stdarg.h> |
| 77 | #include <string.h> | 83 | #include <string.h> |
| @@ -79,6 +85,11 @@ | |||
| 79 | #include <ctype.h> | 85 | #include <ctype.h> |
| 80 | #include <unistd.h> | 86 | #include <unistd.h> |
| 81 | 87 | ||
| 88 | /* Host-dependent types and defines for user-space ACPICA */ | ||
| 89 | |||
| 90 | #define ACPI_FLUSH_CPU_CACHE() | ||
| 91 | #define acpi_thread_id pthread_t | ||
| 92 | |||
| 82 | #if defined(__ia64__) || defined(__x86_64__) | 93 | #if defined(__ia64__) || defined(__x86_64__) |
| 83 | #define ACPI_MACHINE_WIDTH 64 | 94 | #define ACPI_MACHINE_WIDTH 64 |
| 84 | #define COMPILER_DEPENDENT_INT64 long | 95 | #define COMPILER_DEPENDENT_INT64 long |
| @@ -94,17 +105,17 @@ | |||
| 94 | #define __cdecl | 105 | #define __cdecl |
| 95 | #endif | 106 | #endif |
| 96 | 107 | ||
| 97 | #define ACPI_FLUSH_CPU_CACHE() | 108 | #endif /* __KERNEL__ */ |
| 98 | #endif /* __KERNEL__ */ | ||
| 99 | 109 | ||
| 100 | /* Linux uses GCC */ | 110 | /* Linux uses GCC */ |
| 101 | 111 | ||
| 102 | #include "acgcc.h" | 112 | #include "acgcc.h" |
| 103 | 113 | ||
| 104 | #define acpi_cpu_flags unsigned long | ||
| 105 | |||
| 106 | #define acpi_thread_id struct task_struct * | ||
| 107 | 114 | ||
| 115 | #ifdef __KERNEL__ | ||
| 116 | /* | ||
| 117 | * Overrides for in-kernel ACPICA | ||
| 118 | */ | ||
| 108 | static inline acpi_thread_id acpi_os_get_thread_id(void) | 119 | static inline acpi_thread_id acpi_os_get_thread_id(void) |
| 109 | { | 120 | { |
| 110 | return current; | 121 | return current; |
| @@ -119,30 +130,32 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) | |||
| 119 | #include <acpi/actypes.h> | 130 | #include <acpi/actypes.h> |
| 120 | static inline void *acpi_os_allocate(acpi_size size) | 131 | static inline void *acpi_os_allocate(acpi_size size) |
| 121 | { | 132 | { |
| 122 | return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | 133 | return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); |
| 123 | } | 134 | } |
| 135 | |||
| 124 | static inline void *acpi_os_allocate_zeroed(acpi_size size) | 136 | static inline void *acpi_os_allocate_zeroed(acpi_size size) |
| 125 | { | 137 | { |
| 126 | return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | 138 | return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); |
| 127 | } | 139 | } |
| 128 | 140 | ||
| 129 | static inline void *acpi_os_acquire_object(acpi_cache_t * cache) | 141 | static inline void *acpi_os_acquire_object(acpi_cache_t * cache) |
| 130 | { | 142 | { |
| 131 | return kmem_cache_zalloc(cache, | 143 | return kmem_cache_zalloc(cache, |
| 132 | irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | 144 | irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); |
| 133 | } | 145 | } |
| 134 | 146 | ||
| 135 | #define ACPI_ALLOCATE(a) acpi_os_allocate(a) | 147 | #define ACPI_ALLOCATE(a) acpi_os_allocate(a) |
| 136 | #define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) | 148 | #define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) |
| 137 | #define ACPI_FREE(a) kfree(a) | 149 | #define ACPI_FREE(a) kfree(a) |
| 138 | 150 | ||
| 139 | /* | 151 | /* Used within ACPICA to show where it is safe to preempt execution */ |
| 140 | * We need to show where it is safe to preempt execution of ACPICA | 152 | |
| 141 | */ | 153 | #define ACPI_PREEMPTION_POINT() \ |
| 142 | #define ACPI_PREEMPTION_POINT() \ | 154 | do { \ |
| 143 | do { \ | 155 | if (!irqs_disabled()) \ |
| 144 | if (!irqs_disabled()) \ | 156 | cond_resched(); \ |
| 145 | cond_resched(); \ | ||
| 146 | } while (0) | 157 | } while (0) |
| 147 | 158 | ||
| 148 | #endif /* __ACLINUX_H__ */ | 159 | #endif /* __KERNEL__ */ |
| 160 | |||
| 161 | #endif /* __ACLINUX_H__ */ | ||
diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h new file mode 100644 index 000000000000..b18ce4f9ee3d --- /dev/null +++ b/include/asm-generic/atomic64.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* | ||
| 2 | * Generic implementation of 64-bit atomics using spinlocks, | ||
| 3 | * useful on processors that don't have 64-bit atomic instructions. | ||
| 4 | * | ||
| 5 | * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | #ifndef _ASM_GENERIC_ATOMIC64_H | ||
| 13 | #define _ASM_GENERIC_ATOMIC64_H | ||
| 14 | |||
| 15 | typedef struct { | ||
| 16 | long long counter; | ||
| 17 | } atomic64_t; | ||
| 18 | |||
| 19 | #define ATOMIC64_INIT(i) { (i) } | ||
| 20 | |||
| 21 | extern long long atomic64_read(const atomic64_t *v); | ||
| 22 | extern void atomic64_set(atomic64_t *v, long long i); | ||
| 23 | extern void atomic64_add(long long a, atomic64_t *v); | ||
| 24 | extern long long atomic64_add_return(long long a, atomic64_t *v); | ||
| 25 | extern void atomic64_sub(long long a, atomic64_t *v); | ||
| 26 | extern long long atomic64_sub_return(long long a, atomic64_t *v); | ||
| 27 | extern long long atomic64_dec_if_positive(atomic64_t *v); | ||
| 28 | extern long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n); | ||
| 29 | extern long long atomic64_xchg(atomic64_t *v, long long new); | ||
| 30 | extern int atomic64_add_unless(atomic64_t *v, long long a, long long u); | ||
| 31 | |||
| 32 | #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) | ||
| 33 | #define atomic64_inc(v) atomic64_add(1LL, (v)) | ||
| 34 | #define atomic64_inc_return(v) atomic64_add_return(1LL, (v)) | ||
| 35 | #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) | ||
| 36 | #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) | ||
| 37 | #define atomic64_dec(v) atomic64_sub(1LL, (v)) | ||
| 38 | #define atomic64_dec_return(v) atomic64_sub_return(1LL, (v)) | ||
| 39 | #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) | ||
| 40 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL) | ||
| 41 | |||
| 42 | #endif /* _ASM_GENERIC_ATOMIC64_H */ | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index 12737be58601..2a04eb54c0dd 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
| @@ -590,6 +590,11 @@ static inline void bio_list_merge_head(struct bio_list *bl, | |||
| 590 | bl->head = bl2->head; | 590 | bl->head = bl2->head; |
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | static inline struct bio *bio_list_peek(struct bio_list *bl) | ||
| 594 | { | ||
| 595 | return bl->head; | ||
| 596 | } | ||
| 597 | |||
| 593 | static inline struct bio *bio_list_pop(struct bio_list *bl) | 598 | static inline struct bio *bio_list_pop(struct bio_list *bl) |
| 594 | { | 599 | { |
| 595 | struct bio *bio = bl->head; | 600 | struct bio *bio = bl->head; |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0b1a6cae9de1..8963d9149b5f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -926,6 +926,7 @@ extern void blk_queue_alignment_offset(struct request_queue *q, | |||
| 926 | unsigned int alignment); | 926 | unsigned int alignment); |
| 927 | extern void blk_queue_io_min(struct request_queue *q, unsigned int min); | 927 | extern void blk_queue_io_min(struct request_queue *q, unsigned int min); |
| 928 | extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); | 928 | extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); |
| 929 | extern void blk_set_default_limits(struct queue_limits *lim); | ||
| 929 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | 930 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, |
| 930 | sector_t offset); | 931 | sector_t offset); |
| 931 | extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | 932 | extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 883cd44ff765..1b2e1747df1a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -97,12 +97,14 @@ extern const char linux_proc_banner[]; | |||
| 97 | #define KERN_INFO "<6>" /* informational */ | 97 | #define KERN_INFO "<6>" /* informational */ |
| 98 | #define KERN_DEBUG "<7>" /* debug-level messages */ | 98 | #define KERN_DEBUG "<7>" /* debug-level messages */ |
| 99 | 99 | ||
| 100 | /* Use the default kernel loglevel */ | ||
| 101 | #define KERN_DEFAULT "<d>" | ||
| 100 | /* | 102 | /* |
| 101 | * Annotation for a "continued" line of log printout (only done after a | 103 | * Annotation for a "continued" line of log printout (only done after a |
| 102 | * line that had no enclosing \n). Only to be used by core/arch code | 104 | * line that had no enclosing \n). Only to be used by core/arch code |
| 103 | * during early bootup (a continued line is not SMP-safe otherwise). | 105 | * during early bootup (a continued line is not SMP-safe otherwise). |
| 104 | */ | 106 | */ |
| 105 | #define KERN_CONT "" | 107 | #define KERN_CONT "<c>" |
| 106 | 108 | ||
| 107 | extern int console_printk[]; | 109 | extern int console_printk[]; |
| 108 | 110 | ||
diff --git a/include/linux/mg_disk.h b/include/linux/mg_disk.h new file mode 100644 index 000000000000..e11f4d9f1c2e --- /dev/null +++ b/include/linux/mg_disk.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* | ||
| 2 | * include/linux/mg_disk.c | ||
| 3 | * | ||
| 4 | * Private data for mflash platform driver | ||
| 5 | * | ||
| 6 | * (c) 2008 mGine Co.,LTD | ||
| 7 | * (c) 2008 unsik Kim <donari75@gmail.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __MG_DISK_H__ | ||
| 15 | #define __MG_DISK_H__ | ||
| 16 | |||
| 17 | /* name for platform device */ | ||
| 18 | #define MG_DEV_NAME "mg_disk" | ||
| 19 | |||
| 20 | /* names of GPIO resource */ | ||
| 21 | #define MG_RST_PIN "mg_rst" | ||
| 22 | /* except MG_BOOT_DEV, reset-out pin should be assigned */ | ||
| 23 | #define MG_RSTOUT_PIN "mg_rstout" | ||
| 24 | |||
| 25 | /* device attribution */ | ||
| 26 | /* use mflash as boot device */ | ||
| 27 | #define MG_BOOT_DEV (1 << 0) | ||
| 28 | /* use mflash as storage device */ | ||
| 29 | #define MG_STORAGE_DEV (1 << 1) | ||
| 30 | /* same as MG_STORAGE_DEV, but bootloader already done reset sequence */ | ||
| 31 | #define MG_STORAGE_DEV_SKIP_RST (1 << 2) | ||
| 32 | |||
| 33 | /* private driver data */ | ||
| 34 | struct mg_drv_data { | ||
| 35 | /* disk resource */ | ||
| 36 | u32 use_polling; | ||
| 37 | |||
| 38 | /* device attribution */ | ||
| 39 | u32 dev_attr; | ||
| 40 | |||
| 41 | /* internally used */ | ||
| 42 | void *host; | ||
| 43 | }; | ||
| 44 | |||
| 45 | #endif | ||
diff --git a/kernel/module.c b/kernel/module.c index e4ab36ce7672..215aaab09e91 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -2899,7 +2899,7 @@ void print_modules(void) | |||
| 2899 | struct module *mod; | 2899 | struct module *mod; |
| 2900 | char buf[8]; | 2900 | char buf[8]; |
| 2901 | 2901 | ||
| 2902 | printk("Modules linked in:"); | 2902 | printk(KERN_DEFAULT "Modules linked in:"); |
| 2903 | /* Most callers should already have preempt disabled, but make sure */ | 2903 | /* Most callers should already have preempt disabled, but make sure */ |
| 2904 | preempt_disable(); | 2904 | preempt_disable(); |
| 2905 | list_for_each_entry_rcu(mod, &modules, list) | 2905 | list_for_each_entry_rcu(mod, &modules, list) |
diff --git a/kernel/printk.c b/kernel/printk.c index 5052b5497c67..b4d97b54c1ec 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -687,20 +687,35 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
| 687 | sizeof(printk_buf) - printed_len, fmt, args); | 687 | sizeof(printk_buf) - printed_len, fmt, args); |
| 688 | 688 | ||
| 689 | 689 | ||
| 690 | p = printk_buf; | ||
| 691 | |||
| 692 | /* Do we have a loglevel in the string? */ | ||
| 693 | if (p[0] == '<') { | ||
| 694 | unsigned char c = p[1]; | ||
| 695 | if (c && p[2] == '>') { | ||
| 696 | switch (c) { | ||
| 697 | case '0' ... '7': /* loglevel */ | ||
| 698 | current_log_level = c - '0'; | ||
| 699 | /* Fallthrough - make sure we're on a new line */ | ||
| 700 | case 'd': /* KERN_DEFAULT */ | ||
| 701 | if (!new_text_line) { | ||
| 702 | emit_log_char('\n'); | ||
| 703 | new_text_line = 1; | ||
| 704 | } | ||
| 705 | /* Fallthrough - skip the loglevel */ | ||
| 706 | case 'c': /* KERN_CONT */ | ||
| 707 | p += 3; | ||
| 708 | break; | ||
| 709 | } | ||
| 710 | } | ||
| 711 | } | ||
| 712 | |||
| 690 | /* | 713 | /* |
| 691 | * Copy the output into log_buf. If the caller didn't provide | 714 | * Copy the output into log_buf. If the caller didn't provide |
| 692 | * appropriate log level tags, we insert them here | 715 | * appropriate log level tags, we insert them here |
| 693 | */ | 716 | */ |
| 694 | for (p = printk_buf; *p; p++) { | 717 | for ( ; *p; p++) { |
| 695 | if (new_text_line) { | 718 | if (new_text_line) { |
| 696 | /* If a token, set current_log_level and skip over */ | ||
| 697 | if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' && | ||
| 698 | p[2] == '>') { | ||
| 699 | current_log_level = p[1] - '0'; | ||
| 700 | p += 3; | ||
| 701 | printed_len -= 3; | ||
| 702 | } | ||
| 703 | |||
| 704 | /* Always output the token */ | 719 | /* Always output the token */ |
| 705 | emit_log_char('<'); | 720 | emit_log_char('<'); |
| 706 | emit_log_char(current_log_level + '0'); | 721 | emit_log_char(current_log_level + '0'); |
diff --git a/lib/Kconfig b/lib/Kconfig index 9960be04cbbe..bb1326d3839c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
| @@ -194,4 +194,10 @@ config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | |||
| 194 | config NLATTR | 194 | config NLATTR |
| 195 | bool | 195 | bool |
| 196 | 196 | ||
| 197 | # | ||
| 198 | # Generic 64-bit atomic support is selected if needed | ||
| 199 | # | ||
| 200 | config GENERIC_ATOMIC64 | ||
| 201 | bool | ||
| 202 | |||
| 197 | endmenu | 203 | endmenu |
diff --git a/lib/Makefile b/lib/Makefile index 34c5c0e6222e..8e9bcf9d3261 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -95,6 +95,8 @@ obj-$(CONFIG_DMA_API_DEBUG) += dma-debug.o | |||
| 95 | 95 | ||
| 96 | obj-$(CONFIG_GENERIC_CSUM) += checksum.o | 96 | obj-$(CONFIG_GENERIC_CSUM) += checksum.o |
| 97 | 97 | ||
| 98 | obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o | ||
| 99 | |||
| 98 | hostprogs-y := gen_crc32table | 100 | hostprogs-y := gen_crc32table |
| 99 | clean-files := crc32table.h | 101 | clean-files := crc32table.h |
| 100 | 102 | ||
diff --git a/lib/atomic64.c b/lib/atomic64.c new file mode 100644 index 000000000000..c5e725562416 --- /dev/null +++ b/lib/atomic64.c | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | * Generic implementation of 64-bit atomics using spinlocks, | ||
| 3 | * useful on processors that don't have 64-bit atomic instructions. | ||
| 4 | * | ||
| 5 | * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | */ | ||
| 12 | #include <linux/types.h> | ||
| 13 | #include <linux/cache.h> | ||
| 14 | #include <linux/spinlock.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <asm/atomic.h> | ||
| 17 | |||
| 18 | /* | ||
| 19 | * We use a hashed array of spinlocks to provide exclusive access | ||
| 20 | * to each atomic64_t variable. Since this is expected to used on | ||
| 21 | * systems with small numbers of CPUs (<= 4 or so), we use a | ||
| 22 | * relatively small array of 16 spinlocks to avoid wasting too much | ||
| 23 | * memory on the spinlock array. | ||
| 24 | */ | ||
| 25 | #define NR_LOCKS 16 | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Ensure each lock is in a separate cacheline. | ||
| 29 | */ | ||
| 30 | static union { | ||
| 31 | spinlock_t lock; | ||
| 32 | char pad[L1_CACHE_BYTES]; | ||
| 33 | } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp; | ||
| 34 | |||
| 35 | static inline spinlock_t *lock_addr(const atomic64_t *v) | ||
| 36 | { | ||
| 37 | unsigned long addr = (unsigned long) v; | ||
| 38 | |||
| 39 | addr >>= L1_CACHE_SHIFT; | ||
| 40 | addr ^= (addr >> 8) ^ (addr >> 16); | ||
| 41 | return &atomic64_lock[addr & (NR_LOCKS - 1)].lock; | ||
| 42 | } | ||
| 43 | |||
| 44 | long long atomic64_read(const atomic64_t *v) | ||
| 45 | { | ||
| 46 | unsigned long flags; | ||
| 47 | spinlock_t *lock = lock_addr(v); | ||
| 48 | long long val; | ||
| 49 | |||
| 50 | spin_lock_irqsave(lock, flags); | ||
| 51 | val = v->counter; | ||
| 52 | spin_unlock_irqrestore(lock, flags); | ||
| 53 | return val; | ||
| 54 | } | ||
| 55 | |||
| 56 | void atomic64_set(atomic64_t *v, long long i) | ||
| 57 | { | ||
| 58 | unsigned long flags; | ||
| 59 | spinlock_t *lock = lock_addr(v); | ||
| 60 | |||
| 61 | spin_lock_irqsave(lock, flags); | ||
| 62 | v->counter = i; | ||
| 63 | spin_unlock_irqrestore(lock, flags); | ||
| 64 | } | ||
| 65 | |||
| 66 | void atomic64_add(long long a, atomic64_t *v) | ||
| 67 | { | ||
| 68 | unsigned long flags; | ||
| 69 | spinlock_t *lock = lock_addr(v); | ||
| 70 | |||
| 71 | spin_lock_irqsave(lock, flags); | ||
| 72 | v->counter += a; | ||
| 73 | spin_unlock_irqrestore(lock, flags); | ||
| 74 | } | ||
| 75 | |||
| 76 | long long atomic64_add_return(long long a, atomic64_t *v) | ||
| 77 | { | ||
| 78 | unsigned long flags; | ||
| 79 | spinlock_t *lock = lock_addr(v); | ||
| 80 | long long val; | ||
| 81 | |||
| 82 | spin_lock_irqsave(lock, flags); | ||
| 83 | val = v->counter += a; | ||
| 84 | spin_unlock_irqrestore(lock, flags); | ||
| 85 | return val; | ||
| 86 | } | ||
| 87 | |||
| 88 | void atomic64_sub(long long a, atomic64_t *v) | ||
| 89 | { | ||
| 90 | unsigned long flags; | ||
| 91 | spinlock_t *lock = lock_addr(v); | ||
| 92 | |||
| 93 | spin_lock_irqsave(lock, flags); | ||
| 94 | v->counter -= a; | ||
| 95 | spin_unlock_irqrestore(lock, flags); | ||
| 96 | } | ||
| 97 | |||
| 98 | long long atomic64_sub_return(long long a, atomic64_t *v) | ||
| 99 | { | ||
| 100 | unsigned long flags; | ||
| 101 | spinlock_t *lock = lock_addr(v); | ||
| 102 | long long val; | ||
| 103 | |||
| 104 | spin_lock_irqsave(lock, flags); | ||
| 105 | val = v->counter -= a; | ||
| 106 | spin_unlock_irqrestore(lock, flags); | ||
| 107 | return val; | ||
| 108 | } | ||
| 109 | |||
| 110 | long long atomic64_dec_if_positive(atomic64_t *v) | ||
| 111 | { | ||
| 112 | unsigned long flags; | ||
| 113 | spinlock_t *lock = lock_addr(v); | ||
| 114 | long long val; | ||
| 115 | |||
| 116 | spin_lock_irqsave(lock, flags); | ||
| 117 | val = v->counter - 1; | ||
| 118 | if (val >= 0) | ||
| 119 | v->counter = val; | ||
| 120 | spin_unlock_irqrestore(lock, flags); | ||
| 121 | return val; | ||
| 122 | } | ||
| 123 | |||
| 124 | long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n) | ||
| 125 | { | ||
| 126 | unsigned long flags; | ||
| 127 | spinlock_t *lock = lock_addr(v); | ||
| 128 | long long val; | ||
| 129 | |||
| 130 | spin_lock_irqsave(lock, flags); | ||
| 131 | val = v->counter; | ||
| 132 | if (val == o) | ||
| 133 | v->counter = n; | ||
| 134 | spin_unlock_irqrestore(lock, flags); | ||
| 135 | return val; | ||
| 136 | } | ||
| 137 | |||
| 138 | long long atomic64_xchg(atomic64_t *v, long long new) | ||
| 139 | { | ||
| 140 | unsigned long flags; | ||
| 141 | spinlock_t *lock = lock_addr(v); | ||
| 142 | long long val; | ||
| 143 | |||
| 144 | spin_lock_irqsave(lock, flags); | ||
| 145 | val = v->counter; | ||
| 146 | v->counter = new; | ||
| 147 | spin_unlock_irqrestore(lock, flags); | ||
| 148 | return val; | ||
| 149 | } | ||
| 150 | |||
| 151 | int atomic64_add_unless(atomic64_t *v, long long a, long long u) | ||
| 152 | { | ||
| 153 | unsigned long flags; | ||
| 154 | spinlock_t *lock = lock_addr(v); | ||
| 155 | int ret = 1; | ||
| 156 | |||
| 157 | spin_lock_irqsave(lock, flags); | ||
| 158 | if (v->counter != u) { | ||
| 159 | v->counter += a; | ||
| 160 | ret = 0; | ||
| 161 | } | ||
| 162 | spin_unlock_irqrestore(lock, flags); | ||
| 163 | return ret; | ||
| 164 | } | ||
| 165 | |||
| 166 | static int init_atomic64_lock(void) | ||
| 167 | { | ||
| 168 | int i; | ||
| 169 | |||
| 170 | for (i = 0; i < NR_LOCKS; ++i) | ||
| 171 | spin_lock_init(&atomic64_lock[i].lock); | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | pure_initcall(init_atomic64_lock); | ||
diff --git a/mm/bounce.c b/mm/bounce.c index 4ebe3ea83795..a2b76a588e34 100644 --- a/mm/bounce.c +++ b/mm/bounce.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/hash.h> | 14 | #include <linux/hash.h> |
| 15 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
| 16 | #include <linux/blktrace_api.h> | ||
| 17 | #include <asm/tlbflush.h> | 16 | #include <asm/tlbflush.h> |
| 18 | 17 | ||
| 19 | #include <trace/events/block.h> | 18 | #include <trace/events/block.h> |
diff --git a/mm/highmem.c b/mm/highmem.c index 68eb1d9b63fa..25878cc49daa 100644 --- a/mm/highmem.c +++ b/mm/highmem.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/hash.h> | 27 | #include <linux/hash.h> |
| 28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
| 29 | #include <linux/blktrace_api.h> | ||
| 30 | #include <asm/tlbflush.h> | 29 | #include <asm/tlbflush.h> |
| 31 | 30 | ||
| 32 | /* | 31 | /* |
