diff options
154 files changed, 1559 insertions, 1061 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd2a6e8a3b7..8b61c9360999 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 2175 | reset_devices [KNL] Force drivers to reset the underlying device | 2175 | reset_devices [KNL] Force drivers to reset the underlying device |
| 2176 | during initialization. | 2176 | during initialization. |
| 2177 | 2177 | ||
| 2178 | resource_alloc_from_bottom | ||
| 2179 | Allocate new resources from the beginning of available | ||
| 2180 | space, not the end. If you need to use this, please | ||
| 2181 | report a bug. | ||
| 2182 | |||
| 2183 | resume= [SWSUSP] | 2178 | resume= [SWSUSP] |
| 2184 | Specify the partition device for software suspend | 2179 | Specify the partition device for software suspend |
| 2185 | 2180 | ||
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 489e9bacd165..41cc7b30d7dd 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
| @@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
| 379 | zero) | 379 | zero) |
| 380 | 380 | ||
| 381 | bool pm_runtime_suspended(struct device *dev); | 381 | bool pm_runtime_suspended(struct device *dev); |
| 382 | - return true if the device's runtime PM status is 'suspended', or false | 382 | - return true if the device's runtime PM status is 'suspended' and its |
| 383 | otherwise | 383 | 'power.disable_depth' field is equal to zero, or false otherwise |
| 384 | 384 | ||
| 385 | void pm_runtime_allow(struct device *dev); | 385 | void pm_runtime_allow(struct device *dev); |
| 386 | - set the power.runtime_auto flag for the device and decrease its usage | 386 | - set the power.runtime_auto flag for the device and decrease its usage |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 62d686f0b426..d13add71f72a 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
| @@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o | |||
| 65 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o | 65 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o |
| 66 | obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o | 66 | obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o |
| 67 | obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o | 67 | obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o |
| 68 | obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o | 68 | obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o |
| 69 | 69 | ||
| 70 | # AT91SAM9260/AT91SAM9G20 board-specific support | 70 | # AT91SAM9260/AT91SAM9G20 board-specific support |
| 71 | obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o | 71 | obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o |
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index bba5a560e02b..feb65787c30b 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | #include <mach/board.h> | 32 | #include <mach/board.h> |
| 33 | #include <mach/at91sam9_smc.h> | 33 | #include <mach/at91sam9_smc.h> |
| 34 | #include <mach/stamp9g20.h> | ||
| 34 | 35 | ||
| 35 | #include "sam9_smc.h" | 36 | #include "sam9_smc.h" |
| 36 | #include "generic.h" | 37 | #include "generic.h" |
| @@ -38,11 +39,7 @@ | |||
| 38 | 39 | ||
| 39 | static void __init pcontrol_g20_map_io(void) | 40 | static void __init pcontrol_g20_map_io(void) |
| 40 | { | 41 | { |
| 41 | /* Initialize processor: 18.432 MHz crystal */ | 42 | stamp9g20_map_io(); |
| 42 | at91sam9260_initialize(18432000); | ||
| 43 | |||
| 44 | /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */ | ||
| 45 | at91_register_uart(0, 0, 0); | ||
| 46 | 43 | ||
| 47 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ | 44 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ |
| 48 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | 45 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
| @@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void) | |||
| 54 | 51 | ||
| 55 | /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ | 52 | /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ |
| 56 | at91_register_uart(AT91SAM9260_ID_US4, 3, 0); | 53 | at91_register_uart(AT91SAM9260_ID_US4, 3, 0); |
| 57 | |||
| 58 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 59 | at91_set_serial_console(0); | ||
| 60 | } | 54 | } |
| 61 | 55 | ||
| 62 | 56 | ||
| @@ -66,38 +60,6 @@ static void __init init_irq(void) | |||
| 66 | } | 60 | } |
| 67 | 61 | ||
| 68 | 62 | ||
| 69 | /* | ||
| 70 | * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB | ||
| 71 | */ | ||
| 72 | static struct atmel_nand_data __initdata nand_data = { | ||
| 73 | .ale = 21, | ||
| 74 | .cle = 22, | ||
| 75 | .rdy_pin = AT91_PIN_PC13, | ||
| 76 | .enable_pin = AT91_PIN_PC14, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Bus timings; unit = 7.57ns | ||
| 81 | */ | ||
| 82 | static struct sam9_smc_config __initdata nand_smc_config = { | ||
| 83 | .ncs_read_setup = 0, | ||
| 84 | .nrd_setup = 2, | ||
| 85 | .ncs_write_setup = 0, | ||
| 86 | .nwe_setup = 2, | ||
| 87 | |||
| 88 | .ncs_read_pulse = 4, | ||
| 89 | .nrd_pulse = 4, | ||
| 90 | .ncs_write_pulse = 4, | ||
| 91 | .nwe_pulse = 4, | ||
| 92 | |||
| 93 | .read_cycle = 7, | ||
| 94 | .write_cycle = 7, | ||
| 95 | |||
| 96 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
| 97 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, | ||
| 98 | .tdf_cycles = 3, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { | 63 | static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { |
| 102 | .ncs_read_setup = 16, | 64 | .ncs_read_setup = 16, |
| 103 | .nrd_setup = 18, | 65 | .nrd_setup = 18, |
| @@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { | |||
| 138 | .tdf_cycles = 1, | 100 | .tdf_cycles = 1, |
| 139 | } }; | 101 | } }; |
| 140 | 102 | ||
| 141 | static void __init add_device_nand(void) | ||
| 142 | { | ||
| 143 | /* configure chip-select 3 (NAND) */ | ||
| 144 | sam9_smc_configure(3, &nand_smc_config); | ||
| 145 | at91_add_device_nand(&nand_data); | ||
| 146 | } | ||
| 147 | |||
| 148 | |||
| 149 | static void __init add_device_pcontrol(void) | 103 | static void __init add_device_pcontrol(void) |
| 150 | { | 104 | { |
| 151 | /* configure chip-select 4 (IO compatible to 8051 X4 ) */ | 105 | /* configure chip-select 4 (IO compatible to 8051 X4 ) */ |
| @@ -156,23 +110,6 @@ static void __init add_device_pcontrol(void) | |||
| 156 | 110 | ||
| 157 | 111 | ||
| 158 | /* | 112 | /* |
| 159 | * MCI (SD/MMC) | ||
| 160 | * det_pin, wp_pin and vcc_pin are not connected | ||
| 161 | */ | ||
| 162 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
| 163 | static struct mci_platform_data __initdata mmc_data = { | ||
| 164 | .slot[0] = { | ||
| 165 | .bus_width = 4, | ||
| 166 | }, | ||
| 167 | }; | ||
| 168 | #else | ||
| 169 | static struct at91_mmc_data __initdata mmc_data = { | ||
| 170 | .wire4 = 1, | ||
| 171 | }; | ||
| 172 | #endif | ||
| 173 | |||
| 174 | |||
| 175 | /* | ||
| 176 | * USB Host port | 113 | * USB Host port |
| 177 | */ | 114 | */ |
| 178 | static struct at91_usbh_data __initdata usbh_data = { | 115 | static struct at91_usbh_data __initdata usbh_data = { |
| @@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = { | |||
| 265 | }; | 202 | }; |
| 266 | 203 | ||
| 267 | 204 | ||
| 268 | /* | ||
| 269 | * Dallas 1-Wire DS2431 | ||
| 270 | */ | ||
| 271 | static struct w1_gpio_platform_data w1_gpio_pdata = { | ||
| 272 | .pin = AT91_PIN_PA29, | ||
| 273 | .is_open_drain = 1, | ||
| 274 | }; | ||
| 275 | |||
| 276 | static struct platform_device w1_device = { | ||
| 277 | .name = "w1-gpio", | ||
| 278 | .id = -1, | ||
| 279 | .dev.platform_data = &w1_gpio_pdata, | ||
| 280 | }; | ||
| 281 | |||
| 282 | static void add_wire1(void) | ||
| 283 | { | ||
| 284 | at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); | ||
| 285 | at91_set_multi_drive(w1_gpio_pdata.pin, 1); | ||
| 286 | platform_device_register(&w1_device); | ||
| 287 | } | ||
| 288 | |||
| 289 | |||
| 290 | static void __init pcontrol_g20_board_init(void) | 205 | static void __init pcontrol_g20_board_init(void) |
| 291 | { | 206 | { |
| 292 | at91_add_device_serial(); | 207 | stamp9g20_board_init(); |
| 293 | add_device_nand(); | ||
| 294 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
| 295 | at91_add_device_mci(0, &mmc_data); | ||
| 296 | #else | ||
| 297 | at91_add_device_mmc(0, &mmc_data); | ||
| 298 | #endif | ||
| 299 | at91_add_device_usbh(&usbh_data); | 208 | at91_add_device_usbh(&usbh_data); |
| 300 | at91_add_device_eth(&macb_data); | 209 | at91_add_device_eth(&macb_data); |
| 301 | at91_add_device_i2c(pcontrol_g20_i2c_devices, | 210 | at91_add_device_i2c(pcontrol_g20_i2c_devices, |
| 302 | ARRAY_SIZE(pcontrol_g20_i2c_devices)); | 211 | ARRAY_SIZE(pcontrol_g20_i2c_devices)); |
| 303 | add_wire1(); | ||
| 304 | add_device_pcontrol(); | 212 | add_device_pcontrol(); |
| 305 | at91_add_device_spi(pcontrol_g20_spi_devices, | 213 | at91_add_device_spi(pcontrol_g20_spi_devices, |
| 306 | ARRAY_SIZE(pcontrol_g20_spi_devices)); | 214 | ARRAY_SIZE(pcontrol_g20_spi_devices)); |
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 5206eef4a67e..f8902b118960 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include "generic.h" | 32 | #include "generic.h" |
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | static void __init portuxg20_map_io(void) | 35 | void __init stamp9g20_map_io(void) |
| 36 | { | 36 | { |
| 37 | /* Initialize processor: 18.432 MHz crystal */ | 37 | /* Initialize processor: 18.432 MHz crystal */ |
| 38 | at91sam9260_initialize(18432000); | 38 | at91sam9260_initialize(18432000); |
| @@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void) | |||
| 40 | /* DGBU on ttyS0. (Rx & Tx only) */ | 40 | /* DGBU on ttyS0. (Rx & Tx only) */ |
| 41 | at91_register_uart(0, 0, 0); | 41 | at91_register_uart(0, 0, 0); |
| 42 | 42 | ||
| 43 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 44 | at91_set_serial_console(0); | ||
| 45 | } | ||
| 46 | |||
| 47 | static void __init stamp9g20evb_map_io(void) | ||
| 48 | { | ||
| 49 | stamp9g20_map_io(); | ||
| 50 | |||
| 51 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
| 52 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | ||
| 53 | | ATMEL_UART_DTR | ATMEL_UART_DSR | ||
| 54 | | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void __init portuxg20_map_io(void) | ||
| 58 | { | ||
| 59 | stamp9g20_map_io(); | ||
| 60 | |||
| 43 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | 61 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ |
| 44 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | 62 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS |
| 45 | | ATMEL_UART_DTR | ATMEL_UART_DSR | 63 | | ATMEL_UART_DTR | ATMEL_UART_DSR |
| @@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void) | |||
| 56 | 74 | ||
| 57 | /* USART5 on ttyS6. (Rx, Tx only) */ | 75 | /* USART5 on ttyS6. (Rx, Tx only) */ |
| 58 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); | 76 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); |
| 59 | |||
| 60 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 61 | at91_set_serial_console(0); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void __init stamp9g20_map_io(void) | ||
| 65 | { | ||
| 66 | /* Initialize processor: 18.432 MHz crystal */ | ||
| 67 | at91sam9260_initialize(18432000); | ||
| 68 | |||
| 69 | /* DGBU on ttyS0. (Rx & Tx only) */ | ||
| 70 | at91_register_uart(0, 0, 0); | ||
| 71 | |||
| 72 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
| 73 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | ||
| 74 | | ATMEL_UART_DTR | ATMEL_UART_DSR | ||
| 75 | | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
| 76 | |||
| 77 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 78 | at91_set_serial_console(0); | ||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | static void __init init_irq(void) | 79 | static void __init init_irq(void) |
| @@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = { | |||
| 156 | .pullup_pin = 0, /* pull-up driven by UDC */ | 154 | .pullup_pin = 0, /* pull-up driven by UDC */ |
| 157 | }; | 155 | }; |
| 158 | 156 | ||
| 159 | static struct at91_udc_data __initdata stamp9g20_udc_data = { | 157 | static struct at91_udc_data __initdata stamp9g20evb_udc_data = { |
| 160 | .vbus_pin = AT91_PIN_PA22, | 158 | .vbus_pin = AT91_PIN_PA22, |
| 161 | .pullup_pin = 0, /* pull-up driven by UDC */ | 159 | .pullup_pin = 0, /* pull-up driven by UDC */ |
| 162 | }; | 160 | }; |
| @@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = { | |||
| 190 | } | 188 | } |
| 191 | }; | 189 | }; |
| 192 | 190 | ||
| 193 | static struct gpio_led stamp9g20_leds[] = { | 191 | static struct gpio_led stamp9g20evb_leds[] = { |
| 194 | { | 192 | { |
| 195 | .name = "D8", | 193 | .name = "D8", |
| 196 | .gpio = AT91_PIN_PB18, | 194 | .gpio = AT91_PIN_PB18, |
| @@ -250,7 +248,7 @@ void add_w1(void) | |||
| 250 | } | 248 | } |
| 251 | 249 | ||
| 252 | 250 | ||
| 253 | static void __init generic_board_init(void) | 251 | void __init stamp9g20_board_init(void) |
| 254 | { | 252 | { |
| 255 | /* Serial */ | 253 | /* Serial */ |
| 256 | at91_add_device_serial(); | 254 | at91_add_device_serial(); |
| @@ -262,34 +260,40 @@ static void __init generic_board_init(void) | |||
| 262 | #else | 260 | #else |
| 263 | at91_add_device_mmc(0, &mmc_data); | 261 | at91_add_device_mmc(0, &mmc_data); |
| 264 | #endif | 262 | #endif |
| 265 | /* USB Host */ | ||
| 266 | at91_add_device_usbh(&usbh_data); | ||
| 267 | /* Ethernet */ | ||
| 268 | at91_add_device_eth(&macb_data); | ||
| 269 | /* I2C */ | ||
| 270 | at91_add_device_i2c(NULL, 0); | ||
| 271 | /* W1 */ | 263 | /* W1 */ |
| 272 | add_w1(); | 264 | add_w1(); |
| 273 | } | 265 | } |
| 274 | 266 | ||
| 275 | static void __init portuxg20_board_init(void) | 267 | static void __init portuxg20_board_init(void) |
| 276 | { | 268 | { |
| 277 | generic_board_init(); | 269 | stamp9g20_board_init(); |
| 278 | /* SPI */ | 270 | /* USB Host */ |
| 279 | at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); | 271 | at91_add_device_usbh(&usbh_data); |
| 280 | /* USB Device */ | 272 | /* USB Device */ |
| 281 | at91_add_device_udc(&portuxg20_udc_data); | 273 | at91_add_device_udc(&portuxg20_udc_data); |
| 274 | /* Ethernet */ | ||
| 275 | at91_add_device_eth(&macb_data); | ||
| 276 | /* I2C */ | ||
| 277 | at91_add_device_i2c(NULL, 0); | ||
| 278 | /* SPI */ | ||
| 279 | at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); | ||
| 282 | /* LEDs */ | 280 | /* LEDs */ |
| 283 | at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); | 281 | at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); |
| 284 | } | 282 | } |
| 285 | 283 | ||
| 286 | static void __init stamp9g20_board_init(void) | 284 | static void __init stamp9g20evb_board_init(void) |
| 287 | { | 285 | { |
| 288 | generic_board_init(); | 286 | stamp9g20_board_init(); |
| 287 | /* USB Host */ | ||
| 288 | at91_add_device_usbh(&usbh_data); | ||
| 289 | /* USB Device */ | 289 | /* USB Device */ |
| 290 | at91_add_device_udc(&stamp9g20_udc_data); | 290 | at91_add_device_udc(&stamp9g20evb_udc_data); |
| 291 | /* Ethernet */ | ||
| 292 | at91_add_device_eth(&macb_data); | ||
| 293 | /* I2C */ | ||
| 294 | at91_add_device_i2c(NULL, 0); | ||
| 291 | /* LEDs */ | 295 | /* LEDs */ |
| 292 | at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds)); | 296 | at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds)); |
| 293 | } | 297 | } |
| 294 | 298 | ||
| 295 | MACHINE_START(PORTUXG20, "taskit PortuxG20") | 299 | MACHINE_START(PORTUXG20, "taskit PortuxG20") |
| @@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20") | |||
| 305 | /* Maintainer: taskit GmbH */ | 309 | /* Maintainer: taskit GmbH */ |
| 306 | .boot_params = AT91_SDRAM_BASE + 0x100, | 310 | .boot_params = AT91_SDRAM_BASE + 0x100, |
| 307 | .timer = &at91sam926x_timer, | 311 | .timer = &at91sam926x_timer, |
| 308 | .map_io = stamp9g20_map_io, | 312 | .map_io = stamp9g20evb_map_io, |
| 309 | .init_irq = init_irq, | 313 | .init_irq = init_irq, |
| 310 | .init_machine = stamp9g20_board_init, | 314 | .init_machine = stamp9g20evb_board_init, |
| 311 | MACHINE_END | 315 | MACHINE_END |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 7525cee3983f..9113da6845f1 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
| @@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) | |||
| 658 | /* Now set uhpck values */ | 658 | /* Now set uhpck values */ |
| 659 | uhpck.parent = &utmi_clk; | 659 | uhpck.parent = &utmi_clk; |
| 660 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | 660 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; |
| 661 | uhpck.rate_hz = utmi_clk.parent->rate_hz; | 661 | uhpck.rate_hz = utmi_clk.rate_hz; |
| 662 | uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); | 662 | uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); |
| 663 | } | 663 | } |
| 664 | 664 | ||
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h new file mode 100644 index 000000000000..6120f9c46d59 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/stamp9g20.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef __MACH_STAMP9G20_H | ||
| 2 | #define __MACH_STAMP9G20_H | ||
| 3 | |||
| 4 | void stamp9g20_map_io(void); | ||
| 5 | void stamp9g20_board_init(void); | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index fa2e5bffbb8e..6983cb4d4cae 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig | |||
| @@ -28,9 +28,16 @@ config S3C2412_DMA | |||
| 28 | 28 | ||
| 29 | config S3C2412_PM | 29 | config S3C2412_PM |
| 30 | bool | 30 | bool |
| 31 | select S3C2412_PM_SLEEP | ||
| 31 | help | 32 | help |
| 32 | Internal config node to apply S3C2412 power management | 33 | Internal config node to apply S3C2412 power management |
| 33 | 34 | ||
| 35 | config S3C2412_PM_SLEEP | ||
| 36 | bool | ||
| 37 | help | ||
| 38 | Internal config node to apply sleep for S3C2412 power management. | ||
| 39 | Can be selected by another SoCs with similar sleep procedure. | ||
| 40 | |||
| 34 | # Note, the S3C2412 IOtiming support is in plat-s3c24xx | 41 | # Note, the S3C2412 IOtiming support is in plat-s3c24xx |
| 35 | 42 | ||
| 36 | config S3C2412_CPUFREQ | 43 | config S3C2412_CPUFREQ |
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile index 530ec46cbaea..6c48a91ea39e 100644 --- a/arch/arm/mach-s3c2412/Makefile +++ b/arch/arm/mach-s3c2412/Makefile | |||
| @@ -14,7 +14,8 @@ obj-$(CONFIG_CPU_S3C2412) += irq.o | |||
| 14 | obj-$(CONFIG_CPU_S3C2412) += clock.o | 14 | obj-$(CONFIG_CPU_S3C2412) += clock.o |
| 15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o | 15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o |
| 16 | obj-$(CONFIG_S3C2412_DMA) += dma.o | 16 | obj-$(CONFIG_S3C2412_DMA) += dma.o |
| 17 | obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o | 17 | obj-$(CONFIG_S3C2412_PM) += pm.o |
| 18 | obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o | ||
| 18 | obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o | 19 | obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o |
| 19 | 20 | ||
| 20 | # Machine support | 21 | # Machine support |
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 27b3e7c9d613..df8d14974c90 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig | |||
| @@ -27,6 +27,7 @@ config S3C2416_DMA | |||
| 27 | 27 | ||
| 28 | config S3C2416_PM | 28 | config S3C2416_PM |
| 29 | bool | 29 | bool |
| 30 | select S3C2412_PM_SLEEP | ||
| 30 | help | 31 | help |
| 31 | Internal config node to apply S3C2416 power management | 32 | Internal config node to apply S3C2416 power management |
| 32 | 33 | ||
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 28677caf3613..461aa035afc0 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c | |||
| @@ -378,6 +378,12 @@ static struct max8998_regulator_data aquila_regulators[] = { | |||
| 378 | static struct max8998_platform_data aquila_max8998_pdata = { | 378 | static struct max8998_platform_data aquila_max8998_pdata = { |
| 379 | .num_regulators = ARRAY_SIZE(aquila_regulators), | 379 | .num_regulators = ARRAY_SIZE(aquila_regulators), |
| 380 | .regulators = aquila_regulators, | 380 | .regulators = aquila_regulators, |
| 381 | .buck1_set1 = S5PV210_GPH0(3), | ||
| 382 | .buck1_set2 = S5PV210_GPH0(4), | ||
| 383 | .buck2_set3 = S5PV210_GPH0(5), | ||
| 384 | .buck1_max_voltage1 = 1200000, | ||
| 385 | .buck1_max_voltage2 = 1200000, | ||
| 386 | .buck2_max_voltage = 1200000, | ||
| 381 | }; | 387 | }; |
| 382 | #endif | 388 | #endif |
| 383 | 389 | ||
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index b1dcf964a768..e22d5112fd44 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c | |||
| @@ -518,6 +518,12 @@ static struct max8998_regulator_data goni_regulators[] = { | |||
| 518 | static struct max8998_platform_data goni_max8998_pdata = { | 518 | static struct max8998_platform_data goni_max8998_pdata = { |
| 519 | .num_regulators = ARRAY_SIZE(goni_regulators), | 519 | .num_regulators = ARRAY_SIZE(goni_regulators), |
| 520 | .regulators = goni_regulators, | 520 | .regulators = goni_regulators, |
| 521 | .buck1_set1 = S5PV210_GPH0(3), | ||
| 522 | .buck1_set2 = S5PV210_GPH0(4), | ||
| 523 | .buck2_set3 = S5PV210_GPH0(5), | ||
| 524 | .buck1_max_voltage1 = 1200000, | ||
| 525 | .buck1_max_voltage2 = 1200000, | ||
| 526 | .buck2_max_voltage = 1200000, | ||
| 521 | }; | 527 | }; |
| 522 | #endif | 528 | #endif |
| 523 | 529 | ||
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 5a27b1b538f2..eb105e61c746 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig | |||
| @@ -8,7 +8,7 @@ config PLAT_S3C24XX | |||
| 8 | default y | 8 | default y |
| 9 | select NO_IOPORT | 9 | select NO_IOPORT |
| 10 | select ARCH_REQUIRE_GPIOLIB | 10 | select ARCH_REQUIRE_GPIOLIB |
| 11 | select S3C_DEVICE_NAND | 11 | select S3C_DEV_NAND |
| 12 | select S3C_GPIO_CFG_S3C24XX | 12 | select S3C_GPIO_CFG_S3C24XX |
| 13 | help | 13 | help |
| 14 | Base platform code for any Samsung S3C24XX device | 14 | Base platform code for any Samsung S3C24XX device |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 67a2fa2caa49..0a9b5b8b2a19 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -19,6 +19,8 @@ config MIPS | |||
| 19 | select GENERIC_ATOMIC64 if !64BIT | 19 | select GENERIC_ATOMIC64 if !64BIT |
| 20 | select HAVE_DMA_ATTRS | 20 | select HAVE_DMA_ATTRS |
| 21 | select HAVE_DMA_API_DEBUG | 21 | select HAVE_DMA_API_DEBUG |
| 22 | select HAVE_GENERIC_HARDIRQS | ||
| 23 | select GENERIC_IRQ_PROBE | ||
| 22 | 24 | ||
| 23 | menu "Machine selection" | 25 | menu "Machine selection" |
| 24 | 26 | ||
| @@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB | |||
| 1664 | 1666 | ||
| 1665 | endchoice | 1667 | endchoice |
| 1666 | 1668 | ||
| 1669 | config FORCE_MAX_ZONEORDER | ||
| 1670 | int "Maximum zone order" | ||
| 1671 | range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB | ||
| 1672 | default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB | ||
| 1673 | range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB | ||
| 1674 | default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB | ||
| 1675 | range 11 64 | ||
| 1676 | default "11" | ||
| 1677 | help | ||
| 1678 | The kernel memory allocator divides physically contiguous memory | ||
| 1679 | blocks into "zones", where each zone is a power of two number of | ||
| 1680 | pages. This option selects the largest power of two that the kernel | ||
| 1681 | keeps in the memory allocator. If you need to allocate very large | ||
| 1682 | blocks of physically contiguous memory, then you may need to | ||
| 1683 | increase this value. | ||
| 1684 | |||
| 1685 | This config option is actually maximum order plus one. For example, | ||
| 1686 | a value of 11 means that the largest free memory block is 2^10 pages. | ||
| 1687 | |||
| 1688 | The page size is not necessarily 4KB. Keep this in mind | ||
| 1689 | when choosing a value for this option. | ||
| 1690 | |||
| 1667 | config BOARD_SCACHE | 1691 | config BOARD_SCACHE |
| 1668 | bool | 1692 | bool |
| 1669 | 1693 | ||
| @@ -1922,20 +1946,6 @@ config CPU_R4400_WORKAROUNDS | |||
| 1922 | bool | 1946 | bool |
| 1923 | 1947 | ||
| 1924 | # | 1948 | # |
| 1925 | # Use the generic interrupt handling code in kernel/irq/: | ||
| 1926 | # | ||
| 1927 | config GENERIC_HARDIRQS | ||
| 1928 | bool | ||
| 1929 | default y | ||
| 1930 | |||
| 1931 | config GENERIC_IRQ_PROBE | ||
| 1932 | bool | ||
| 1933 | default y | ||
| 1934 | |||
| 1935 | config IRQ_PER_CPU | ||
| 1936 | bool | ||
| 1937 | |||
| 1938 | # | ||
| 1939 | # - Highmem only makes sense for the 32-bit kernel. | 1949 | # - Highmem only makes sense for the 32-bit kernel. |
| 1940 | # - The current highmem code will only work properly on physically indexed | 1950 | # - The current highmem code will only work properly on physically indexed |
| 1941 | # caches such as R3000, SB1, R7000 or those that look like they're virtually | 1951 | # caches such as R3000, SB1, R7000 or those that look like they're virtually |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 3691630931d6..9e7814db3d03 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | 27 | static void alchemy_8250_pm(struct uart_port *port, unsigned int state, |
| 28 | unsigned int old_state) | 28 | unsigned int old_state) |
| 29 | { | 29 | { |
| 30 | #ifdef CONFIG_SERIAL_8250 | ||
| 30 | switch (state) { | 31 | switch (state) { |
| 31 | case 0: | 32 | case 0: |
| 32 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { | 33 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { |
| @@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
| 49 | serial8250_do_pm(port, state, old_state); | 50 | serial8250_do_pm(port, state, old_state); |
| 50 | break; | 51 | break; |
| 51 | } | 52 | } |
| 53 | #endif | ||
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | #define PORT(_base, _irq) \ | 56 | #define PORT(_base, _irq) \ |
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c index b30df5c97ad3..baeb21385058 100644 --- a/arch/mips/alchemy/devboards/prom.c +++ b/arch/mips/alchemy/devboards/prom.c | |||
| @@ -54,10 +54,9 @@ void __init prom_init(void) | |||
| 54 | 54 | ||
| 55 | prom_init_cmdline(); | 55 | prom_init_cmdline(); |
| 56 | memsize_str = prom_getenv("memsize"); | 56 | memsize_str = prom_getenv("memsize"); |
| 57 | if (!memsize_str) | 57 | if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize)) |
| 58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; | 58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; |
| 59 | else | 59 | |
| 60 | strict_strtoul(memsize_str, 0, &memsize); | ||
| 61 | add_memory_region(0, memsize, BOOT_MEM_RAM); | 60 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
| 62 | } | 61 | } |
| 63 | 62 | ||
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index fc0e7154e8d6..2ca4ada1c291 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c | |||
| @@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock, | |||
| 239 | calculate(base_clock, frequency, &prediv, &postdiv, &mul); | 239 | calculate(base_clock, frequency, &prediv, &postdiv, &mul); |
| 240 | 240 | ||
| 241 | writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); | 241 | writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); |
| 242 | msleep(1); | 242 | mdelay(1); |
| 243 | writel(4, &clock->pll); | 243 | writel(4, &clock->pll); |
| 244 | while (readl(&clock->pll) & PLL_STATUS) | 244 | while (readl(&clock->pll) & PLL_STATUS) |
| 245 | ; | 245 | ; |
| 246 | writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); | 246 | writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); |
| 247 | msleep(75); | 247 | mdelay(75); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | static void __init tnetd7300_init_clocks(void) | 250 | static void __init tnetd7300_init_clocks(void) |
| @@ -456,7 +456,7 @@ void clk_put(struct clk *clk) | |||
| 456 | } | 456 | } |
| 457 | EXPORT_SYMBOL(clk_put); | 457 | EXPORT_SYMBOL(clk_put); |
| 458 | 458 | ||
| 459 | int __init ar7_init_clocks(void) | 459 | void __init ar7_init_clocks(void) |
| 460 | { | 460 | { |
| 461 | switch (ar7_chip_id()) { | 461 | switch (ar7_chip_id()) { |
| 462 | case AR7_CHIP_7100: | 462 | case AR7_CHIP_7100: |
| @@ -472,7 +472,4 @@ int __init ar7_init_clocks(void) | |||
| 472 | } | 472 | } |
| 473 | /* adjust vbus clock rate */ | 473 | /* adjust vbus clock rate */ |
| 474 | vbus_clk.rate = bus_clk.rate / 2; | 474 | vbus_clk.rate = bus_clk.rate / 2; |
| 475 | |||
| 476 | return 0; | ||
| 477 | } | 475 | } |
| 478 | arch_initcall(ar7_init_clocks); | ||
diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c index 5fb8a0134085..22c93213b233 100644 --- a/arch/mips/ar7/time.c +++ b/arch/mips/ar7/time.c | |||
| @@ -30,6 +30,9 @@ void __init plat_time_init(void) | |||
| 30 | { | 30 | { |
| 31 | struct clk *cpu_clk; | 31 | struct clk *cpu_clk; |
| 32 | 32 | ||
| 33 | /* Initialize ar7 clocks so the CPU clock frequency is correct */ | ||
| 34 | ar7_init_clocks(); | ||
| 35 | |||
| 33 | cpu_clk = clk_get(NULL, "cpu"); | 36 | cpu_clk = clk_get(NULL, "cpu"); |
| 34 | if (IS_ERR(cpu_clk)) { | 37 | if (IS_ERR(cpu_clk)) { |
| 35 | printk(KERN_ERR "unable to get cpu clock\n"); | 38 | printk(KERN_ERR "unable to get cpu clock\n"); |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index b1aee33efd11..c95f90bf734c 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <asm/reboot.h> | 32 | #include <asm/reboot.h> |
| 33 | #include <asm/time.h> | 33 | #include <asm/time.h> |
| 34 | #include <bcm47xx.h> | 34 | #include <bcm47xx.h> |
| 35 | #include <asm/fw/cfe/cfe_api.h> | ||
| 36 | #include <asm/mach-bcm47xx/nvram.h> | 35 | #include <asm/mach-bcm47xx/nvram.h> |
| 37 | 36 | ||
| 38 | struct ssb_bus ssb_bcm47xx; | 37 | struct ssb_bus ssb_bcm47xx; |
| @@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void) | |||
| 57 | cpu_relax(); | 56 | cpu_relax(); |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | static void str2eaddr(char *str, char *dest) | 59 | #define READ_FROM_NVRAM(_outvar, name, buf) \ |
| 61 | { | 60 | if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\ |
| 62 | int i = 0; | 61 | sprom->_outvar = simple_strtoul(buf, NULL, 0); |
| 63 | 62 | ||
| 64 | if (str == NULL) { | 63 | static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) |
| 65 | memset(dest, 0, 6); | 64 | { |
| 66 | return; | 65 | char buf[100]; |
| 66 | u32 boardflags; | ||
| 67 | |||
| 68 | memset(sprom, 0, sizeof(struct ssb_sprom)); | ||
| 69 | |||
| 70 | sprom->revision = 1; /* Fallback: Old hardware does not define this. */ | ||
| 71 | READ_FROM_NVRAM(revision, "sromrev", buf); | ||
| 72 | if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0) | ||
| 73 | nvram_parse_macaddr(buf, sprom->il0mac); | ||
| 74 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
| 75 | nvram_parse_macaddr(buf, sprom->et0mac); | ||
| 76 | if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | ||
| 77 | nvram_parse_macaddr(buf, sprom->et1mac); | ||
| 78 | READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); | ||
| 79 | READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); | ||
| 80 | READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); | ||
| 81 | READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); | ||
| 82 | READ_FROM_NVRAM(board_rev, "boardrev", buf); | ||
| 83 | READ_FROM_NVRAM(country_code, "ccode", buf); | ||
| 84 | READ_FROM_NVRAM(ant_available_a, "aa5g", buf); | ||
| 85 | READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); | ||
| 86 | READ_FROM_NVRAM(pa0b0, "pa0b0", buf); | ||
| 87 | READ_FROM_NVRAM(pa0b1, "pa0b1", buf); | ||
| 88 | READ_FROM_NVRAM(pa0b2, "pa0b2", buf); | ||
| 89 | READ_FROM_NVRAM(pa1b0, "pa1b0", buf); | ||
| 90 | READ_FROM_NVRAM(pa1b1, "pa1b1", buf); | ||
| 91 | READ_FROM_NVRAM(pa1b2, "pa1b2", buf); | ||
| 92 | READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); | ||
| 93 | READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); | ||
| 94 | READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); | ||
| 95 | READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); | ||
| 96 | READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); | ||
| 97 | READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); | ||
| 98 | READ_FROM_NVRAM(gpio0, "wl0gpio0", buf); | ||
| 99 | READ_FROM_NVRAM(gpio1, "wl0gpio1", buf); | ||
| 100 | READ_FROM_NVRAM(gpio2, "wl0gpio2", buf); | ||
| 101 | READ_FROM_NVRAM(gpio3, "wl0gpio3", buf); | ||
| 102 | READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf); | ||
| 103 | READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf); | ||
| 104 | READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf); | ||
| 105 | READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf); | ||
| 106 | READ_FROM_NVRAM(itssi_a, "pa1itssit", buf); | ||
| 107 | READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf); | ||
| 108 | READ_FROM_NVRAM(tri2g, "tri2g", buf); | ||
| 109 | READ_FROM_NVRAM(tri5gl, "tri5gl", buf); | ||
| 110 | READ_FROM_NVRAM(tri5g, "tri5g", buf); | ||
| 111 | READ_FROM_NVRAM(tri5gh, "tri5gh", buf); | ||
| 112 | READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); | ||
| 113 | READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); | ||
| 114 | READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); | ||
| 115 | READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); | ||
| 116 | READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); | ||
| 117 | READ_FROM_NVRAM(bxa2g, "bxa2g", buf); | ||
| 118 | READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); | ||
| 119 | READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); | ||
| 120 | READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); | ||
| 121 | READ_FROM_NVRAM(bxa5g, "bxa5g", buf); | ||
| 122 | READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); | ||
| 123 | READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf); | ||
| 124 | READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf); | ||
| 125 | READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf); | ||
| 126 | READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf); | ||
| 127 | |||
| 128 | if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) { | ||
| 129 | boardflags = simple_strtoul(buf, NULL, 0); | ||
| 130 | if (boardflags) { | ||
| 131 | sprom->boardflags_lo = (boardflags & 0x0000FFFFU); | ||
| 132 | sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; | ||
| 133 | } | ||
| 67 | } | 134 | } |
| 68 | 135 | if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) { | |
| 69 | for (;;) { | 136 | boardflags = simple_strtoul(buf, NULL, 0); |
| 70 | dest[i++] = (char) simple_strtoul(str, NULL, 16); | 137 | if (boardflags) { |
| 71 | str += 2; | 138 | sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); |
| 72 | if (!*str++ || i == 6) | 139 | sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; |
| 73 | break; | 140 | } |
| 74 | } | 141 | } |
| 75 | } | 142 | } |
| 76 | 143 | ||
| 77 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 144 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
| 78 | struct ssb_init_invariants *iv) | 145 | struct ssb_init_invariants *iv) |
| 79 | { | 146 | { |
| 80 | char buf[100]; | 147 | char buf[20]; |
| 81 | 148 | ||
| 82 | /* Fill boardinfo structure */ | 149 | /* Fill boardinfo structure */ |
| 83 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); | 150 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); |
| 84 | 151 | ||
| 85 | if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 || | 152 | if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) |
| 86 | nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) | 153 | iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0); |
| 87 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | 154 | else |
| 88 | if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 || | 155 | iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM; |
| 89 | nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) | 156 | if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) |
| 90 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | 157 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); |
| 91 | if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 || | 158 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) |
| 92 | nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) | ||
| 93 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); | 159 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); |
| 94 | 160 | ||
| 95 | /* Fill sprom structure */ | 161 | bcm47xx_fill_sprom(&iv->sprom); |
| 96 | memset(&(iv->sprom), 0, sizeof(struct ssb_sprom)); | ||
| 97 | iv->sprom.revision = 3; | ||
| 98 | |||
| 99 | if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 || | ||
| 100 | nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
| 101 | str2eaddr(buf, iv->sprom.et0mac); | ||
| 102 | 162 | ||
| 103 | if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 || | 163 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) |
| 104 | nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | 164 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); |
| 105 | str2eaddr(buf, iv->sprom.et1mac); | ||
| 106 | |||
| 107 | if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 || | ||
| 108 | nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) | ||
| 109 | iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0); | ||
| 110 | |||
| 111 | if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 || | ||
| 112 | nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) | ||
| 113 | iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0); | ||
| 114 | |||
| 115 | if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 || | ||
| 116 | nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0) | ||
| 117 | iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10); | ||
| 118 | |||
| 119 | if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 || | ||
| 120 | nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0) | ||
| 121 | iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10); | ||
| 122 | 165 | ||
| 123 | return 0; | 166 | return 0; |
| 124 | } | 167 | } |
| @@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, | |||
| 126 | void __init plat_mem_setup(void) | 169 | void __init plat_mem_setup(void) |
| 127 | { | 170 | { |
| 128 | int err; | 171 | int err; |
| 172 | char buf[100]; | ||
| 173 | struct ssb_mipscore *mcore; | ||
| 129 | 174 | ||
| 130 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, | 175 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, |
| 131 | bcm47xx_get_invariants); | 176 | bcm47xx_get_invariants); |
| 132 | if (err) | 177 | if (err) |
| 133 | panic("Failed to initialize SSB bus (err %d)\n", err); | 178 | panic("Failed to initialize SSB bus (err %d)\n", err); |
| 134 | 179 | ||
| 180 | mcore = &ssb_bcm47xx.mipscore; | ||
| 181 | if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { | ||
| 182 | if (strstr(buf, "console=ttyS1")) { | ||
| 183 | struct ssb_serial_port port; | ||
| 184 | |||
| 185 | printk(KERN_DEBUG "Swapping serial ports!\n"); | ||
| 186 | /* swap serial ports */ | ||
| 187 | memcpy(&port, &mcore->serial_ports[0], sizeof(port)); | ||
| 188 | memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], | ||
| 189 | sizeof(port)); | ||
| 190 | memcpy(&mcore->serial_ports[1], &port, sizeof(port)); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 135 | _machine_restart = bcm47xx_machine_restart; | 194 | _machine_restart = bcm47xx_machine_restart; |
| 136 | _machine_halt = bcm47xx_machine_halt; | 195 | _machine_halt = bcm47xx_machine_halt; |
| 137 | pm_power_off = bcm47xx_machine_halt; | 196 | pm_power_off = bcm47xx_machine_halt; |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 06d59dcbe243..86877539c6e8 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
| @@ -111,8 +111,8 @@ | |||
| 111 | * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM | 111 | * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM |
| 112 | */ | 112 | */ |
| 113 | 113 | ||
| 114 | #define PRID_IMP_BMIPS4KC 0x4000 | 114 | #define PRID_IMP_BMIPS32_REV4 0x4000 |
| 115 | #define PRID_IMP_BMIPS32 0x8000 | 115 | #define PRID_IMP_BMIPS32_REV8 0x8000 |
| 116 | #define PRID_IMP_BMIPS3300 0x9000 | 116 | #define PRID_IMP_BMIPS3300 0x9000 |
| 117 | #define PRID_IMP_BMIPS3300_ALT 0x9100 | 117 | #define PRID_IMP_BMIPS3300_ALT 0x9100 |
| 118 | #define PRID_IMP_BMIPS3300_BUG 0x0000 | 118 | #define PRID_IMP_BMIPS3300_BUG 0x0000 |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index fd1d39eb7431..455c0ac7d4ea 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
| @@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32; | |||
| 249 | 249 | ||
| 250 | #define SET_PERSONALITY(ex) \ | 250 | #define SET_PERSONALITY(ex) \ |
| 251 | do { \ | 251 | do { \ |
| 252 | set_personality(PER_LINUX); \ | 252 | if (personality(current->personality) != PER_LINUX) \ |
| 253 | set_personality(PER_LINUX); \ | ||
| 253 | \ | 254 | \ |
| 254 | current->thread.abi = &mips_abi; \ | 255 | current->thread.abi = &mips_abi; \ |
| 255 | } while (0) | 256 | } while (0) |
| @@ -296,6 +297,8 @@ do { \ | |||
| 296 | 297 | ||
| 297 | #define SET_PERSONALITY(ex) \ | 298 | #define SET_PERSONALITY(ex) \ |
| 298 | do { \ | 299 | do { \ |
| 300 | unsigned int p; \ | ||
| 301 | \ | ||
| 299 | clear_thread_flag(TIF_32BIT_REGS); \ | 302 | clear_thread_flag(TIF_32BIT_REGS); \ |
| 300 | clear_thread_flag(TIF_32BIT_ADDR); \ | 303 | clear_thread_flag(TIF_32BIT_ADDR); \ |
| 301 | \ | 304 | \ |
| @@ -304,7 +307,8 @@ do { \ | |||
| 304 | else \ | 307 | else \ |
| 305 | current->thread.abi = &mips_abi; \ | 308 | current->thread.abi = &mips_abi; \ |
| 306 | \ | 309 | \ |
| 307 | if (current->personality != PER_LINUX32) \ | 310 | p = personality(current->personality); \ |
| 311 | if (p != PER_LINUX32 && p != PER_LINUX) \ | ||
| 308 | set_personality(PER_LINUX); \ | 312 | set_personality(PER_LINUX); \ |
| 309 | } while (0) | 313 | } while (0) |
| 310 | 314 | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index c98bf514ec7d..5b017f23e243 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
| @@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val, \ | |||
| 329 | "dsrl32 %L0, %L0, 0" "\n\t" \ | 329 | "dsrl32 %L0, %L0, 0" "\n\t" \ |
| 330 | "dsll32 %M0, %M0, 0" "\n\t" \ | 330 | "dsll32 %M0, %M0, 0" "\n\t" \ |
| 331 | "or %L0, %L0, %M0" "\n\t" \ | 331 | "or %L0, %L0, %M0" "\n\t" \ |
| 332 | ".set push" "\n\t" \ | ||
| 333 | ".set noreorder" "\n\t" \ | ||
| 334 | ".set nomacro" "\n\t" \ | ||
| 332 | "sd %L0, %2" "\n\t" \ | 335 | "sd %L0, %2" "\n\t" \ |
| 336 | ".set pop" "\n\t" \ | ||
| 333 | ".set mips0" "\n" \ | 337 | ".set mips0" "\n" \ |
| 334 | : "=r" (__tmp) \ | 338 | : "=r" (__tmp) \ |
| 335 | : "0" (__val), "m" (*__mem)); \ | 339 | : "0" (__val), "R" (*__mem)); \ |
| 336 | if (irq) \ | 340 | if (irq) \ |
| 337 | local_irq_restore(__flags); \ | 341 | local_irq_restore(__flags); \ |
| 338 | } else \ | 342 | } else \ |
| @@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ | |||
| 355 | local_irq_save(__flags); \ | 359 | local_irq_save(__flags); \ |
| 356 | __asm__ __volatile__( \ | 360 | __asm__ __volatile__( \ |
| 357 | ".set mips3" "\t\t# __readq" "\n\t" \ | 361 | ".set mips3" "\t\t# __readq" "\n\t" \ |
| 362 | ".set push" "\n\t" \ | ||
| 363 | ".set noreorder" "\n\t" \ | ||
| 364 | ".set nomacro" "\n\t" \ | ||
| 358 | "ld %L0, %1" "\n\t" \ | 365 | "ld %L0, %1" "\n\t" \ |
| 366 | ".set pop" "\n\t" \ | ||
| 359 | "dsra32 %M0, %L0, 0" "\n\t" \ | 367 | "dsra32 %M0, %L0, 0" "\n\t" \ |
| 360 | "sll %L0, %L0, 0" "\n\t" \ | 368 | "sll %L0, %L0, 0" "\n\t" \ |
| 361 | ".set mips0" "\n" \ | 369 | ".set mips0" "\n" \ |
| 362 | : "=r" (__val) \ | 370 | : "=r" (__val) \ |
| 363 | : "m" (*__mem)); \ | 371 | : "R" (*__mem)); \ |
| 364 | if (irq) \ | 372 | if (irq) \ |
| 365 | local_irq_restore(__flags); \ | 373 | local_irq_restore(__flags); \ |
| 366 | } else { \ | 374 | } else { \ |
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h index 7919d76186bf..07d3fadb2443 100644 --- a/arch/mips/include/asm/mach-ar7/ar7.h +++ b/arch/mips/include/asm/mach-ar7/ar7.h | |||
| @@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit) | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | int __init ar7_gpio_init(void); | 203 | int __init ar7_gpio_init(void); |
| 204 | 204 | void __init ar7_init_clocks(void); | |
| 205 | int __init ar7_gpio_init(void); | ||
| 206 | 205 | ||
| 207 | #endif /* __AR7_H__ */ | 206 | #endif /* __AR7_H__ */ |
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index c58ebd8bc155..9759588ba3cf 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #define __NVRAM_H | 12 | #define __NVRAM_H |
| 13 | 13 | ||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/kernel.h> | ||
| 15 | 16 | ||
| 16 | struct nvram_header { | 17 | struct nvram_header { |
| 17 | u32 magic; | 18 | u32 magic; |
| @@ -36,4 +37,10 @@ struct nvram_header { | |||
| 36 | 37 | ||
| 37 | extern int nvram_getenv(char *name, char *val, size_t val_len); | 38 | extern int nvram_getenv(char *name, char *val, size_t val_len); |
| 38 | 39 | ||
| 40 | static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) | ||
| 41 | { | ||
| 42 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1], | ||
| 43 | &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]); | ||
| 44 | } | ||
| 45 | |||
| 39 | #endif | 46 | #endif |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 5742bb4d78f4..5c0a3575877c 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2009 Qi Hardware inc., | 6 | * Copyright (c) 2009 Qi Hardware inc., |
| 7 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> | 7 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> |
| 8 | * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de> | 8 | * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de> |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License version 2 or later | 11 | * it under the terms of the GNU General Public License version 2 or later |
| @@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = { | |||
| 235 | QI_LB60_GPIO_KEYIN(3), | 235 | QI_LB60_GPIO_KEYIN(3), |
| 236 | QI_LB60_GPIO_KEYIN(4), | 236 | QI_LB60_GPIO_KEYIN(4), |
| 237 | QI_LB60_GPIO_KEYIN(5), | 237 | QI_LB60_GPIO_KEYIN(5), |
| 238 | QI_LB60_GPIO_KEYIN(7), | 238 | QI_LB60_GPIO_KEYIN(6), |
| 239 | QI_LB60_GPIO_KEYIN8, | 239 | QI_LB60_GPIO_KEYIN8, |
| 240 | }; | 240 | }; |
| 241 | 241 | ||
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 95bc2b5b14f1..1cc9e544d16b 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
| @@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = { | |||
| 208 | 208 | ||
| 209 | /* PCM */ | 209 | /* PCM */ |
| 210 | struct platform_device jz4740_pcm_device = { | 210 | struct platform_device jz4740_pcm_device = { |
| 211 | .name = "jz4740-pcm", | 211 | .name = "jz4740-pcm-audio", |
| 212 | .id = -1, | 212 | .id = -1, |
| 213 | }; | 213 | }; |
| 214 | 214 | ||
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index cfeac15eb2e4..4a70407f55bb 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <asm/bootinfo.h> | 23 | #include <asm/bootinfo.h> |
| 24 | #include <asm/mach-jz4740/base.h> | 24 | #include <asm/mach-jz4740/base.h> |
| 25 | 25 | ||
| 26 | void jz4740_init_cmdline(int argc, char *argv[]) | 26 | static __init void jz4740_init_cmdline(int argc, char *argv[]) |
| 27 | { | 27 | { |
| 28 | unsigned int count = COMMAND_LINE_SIZE - 1; | 28 | unsigned int count = COMMAND_LINE_SIZE - 1; |
| 29 | int i; | 29 | int i; |
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 2f4d7a99bcc2..98c5a9737c14 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
| @@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta, | |||
| 32 | cnt = read_c0_count(); | 32 | cnt = read_c0_count(); |
| 33 | cnt += delta; | 33 | cnt += delta; |
| 34 | write_c0_compare(cnt); | 34 | write_c0_compare(cnt); |
| 35 | res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; | 35 | res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0; |
| 36 | return res; | 36 | return res; |
| 37 | } | 37 | } |
| 38 | 38 | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 71620e19827a..68dae7b6b5db 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
| 905 | { | 905 | { |
| 906 | decode_configs(c); | 906 | decode_configs(c); |
| 907 | switch (c->processor_id & 0xff00) { | 907 | switch (c->processor_id & 0xff00) { |
| 908 | case PRID_IMP_BMIPS32: | 908 | case PRID_IMP_BMIPS32_REV4: |
| 909 | case PRID_IMP_BMIPS32_REV8: | ||
| 909 | c->cputype = CPU_BMIPS32; | 910 | c->cputype = CPU_BMIPS32; |
| 910 | __cpu_name[cpu] = "Broadcom BMIPS32"; | 911 | __cpu_name[cpu] = "Broadcom BMIPS32"; |
| 911 | break; | 912 | break; |
| @@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
| 933 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 934 | __cpu_name[cpu] = "Broadcom BMIPS5000"; |
| 934 | c->options |= MIPS_CPU_ULRI; | 935 | c->options |= MIPS_CPU_ULRI; |
| 935 | break; | 936 | break; |
| 936 | case PRID_IMP_BMIPS4KC: | ||
| 937 | c->cputype = CPU_4KC; | ||
| 938 | __cpu_name[cpu] = "MIPS 4Kc"; | ||
| 939 | break; | ||
| 940 | } | 937 | } |
| 941 | } | 938 | } |
| 942 | 939 | ||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 6343b4a5b835..876a75cc376f 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
| @@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz, | |||
| 251 | 251 | ||
| 252 | SYSCALL_DEFINE1(32_personality, unsigned long, personality) | 252 | SYSCALL_DEFINE1(32_personality, unsigned long, personality) |
| 253 | { | 253 | { |
| 254 | unsigned int p = personality & 0xffffffff; | ||
| 254 | int ret; | 255 | int ret; |
| 255 | personality &= 0xffffffff; | 256 | |
| 256 | if (personality(current->personality) == PER_LINUX32 && | 257 | if (personality(current->personality) == PER_LINUX32 && |
| 257 | personality == PER_LINUX) | 258 | personality(p) == PER_LINUX) |
| 258 | personality = PER_LINUX32; | 259 | p = (p & ~PER_MASK) | PER_LINUX32; |
| 259 | ret = sys_personality(personality); | 260 | ret = sys_personality(p); |
| 260 | if (ret == PER_LINUX32) | 261 | if (ret != -1 && personality(ret) == PER_LINUX32) |
| 261 | ret = PER_LINUX; | 262 | ret = (ret & ~PER_MASK) | PER_LINUX; |
| 262 | return ret; | 263 | return ret; |
| 263 | } | 264 | } |
| 264 | 265 | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 99960940d4a4..ae167df73ddd 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
| @@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
| 142 | childregs->regs[7] = 0; /* Clear error flag */ | 142 | childregs->regs[7] = 0; /* Clear error flag */ |
| 143 | 143 | ||
| 144 | childregs->regs[2] = 0; /* Child gets zero as return value */ | 144 | childregs->regs[2] = 0; /* Child gets zero as return value */ |
| 145 | regs->regs[2] = p->pid; | ||
| 146 | 145 | ||
| 147 | if (childregs->cp0_status & ST0_CU0) { | 146 | if (childregs->cp0_status & ST0_CU0) { |
| 148 | childregs->regs[28] = (unsigned long) ti; | 147 | childregs->regs[28] = (unsigned long) ti; |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index e000b278f024..9dbe58368953 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
| @@ -100,7 +100,7 @@ void __init device_tree_init(void) | |||
| 100 | return; | 100 | return; |
| 101 | 101 | ||
| 102 | base = virt_to_phys((void *)initial_boot_params); | 102 | base = virt_to_phys((void *)initial_boot_params); |
| 103 | size = initial_boot_params->totalsize; | 103 | size = be32_to_cpu(initial_boot_params->totalsize); |
| 104 | 104 | ||
| 105 | /* Before we do anything, lets reserve the dt blob */ | 105 | /* Before we do anything, lets reserve the dt blob */ |
| 106 | reserve_mem_mach(base, size); | 106 | reserve_mem_mach(base, size); |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 43e7cdc5ded2..c0e81418ba21 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
| @@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void) | |||
| 153 | { | 153 | { |
| 154 | extern int gic_present; | 154 | extern int gic_present; |
| 155 | 155 | ||
| 156 | /* This is Malta specific: IPI,performance and timer inetrrupts */ | 156 | /* This is Malta specific: IPI,performance and timer interrupts */ |
| 157 | if (gic_present) | 157 | if (gic_present) |
| 158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | |
| 159 | STATUSF_IP6 | STATUSF_IP7); | 159 | STATUSF_IP6 | STATUSF_IP7); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 8e9fbe75894e..e97104302541 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void); | |||
| 83 | extern asmlinkage void handle_reserved(void); | 83 | extern asmlinkage void handle_reserved(void); |
| 84 | 84 | ||
| 85 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | 85 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, |
| 86 | struct mips_fpu_struct *ctx, int has_fpu); | 86 | struct mips_fpu_struct *ctx, int has_fpu, |
| 87 | void *__user *fault_addr); | ||
| 87 | 88 | ||
| 88 | void (*board_be_init)(void); | 89 | void (*board_be_init)(void); |
| 89 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); | 90 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
| @@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs) | |||
| 661 | force_sig_info(SIGFPE, &info, current); | 662 | force_sig_info(SIGFPE, &info, current); |
| 662 | } | 663 | } |
| 663 | 664 | ||
| 665 | static int process_fpemu_return(int sig, void __user *fault_addr) | ||
| 666 | { | ||
| 667 | if (sig == SIGSEGV || sig == SIGBUS) { | ||
| 668 | struct siginfo si = {0}; | ||
| 669 | si.si_addr = fault_addr; | ||
| 670 | si.si_signo = sig; | ||
| 671 | if (sig == SIGSEGV) { | ||
| 672 | if (find_vma(current->mm, (unsigned long)fault_addr)) | ||
| 673 | si.si_code = SEGV_ACCERR; | ||
| 674 | else | ||
| 675 | si.si_code = SEGV_MAPERR; | ||
| 676 | } else { | ||
| 677 | si.si_code = BUS_ADRERR; | ||
| 678 | } | ||
| 679 | force_sig_info(sig, &si, current); | ||
| 680 | return 1; | ||
| 681 | } else if (sig) { | ||
| 682 | force_sig(sig, current); | ||
| 683 | return 1; | ||
| 684 | } else { | ||
| 685 | return 0; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | |||
| 664 | /* | 689 | /* |
| 665 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX | 690 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX |
| 666 | */ | 691 | */ |
| 667 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | 692 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) |
| 668 | { | 693 | { |
| 669 | siginfo_t info; | 694 | siginfo_t info = {0}; |
| 670 | 695 | ||
| 671 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) | 696 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) |
| 672 | == NOTIFY_STOP) | 697 | == NOTIFY_STOP) |
| @@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
| 675 | 700 | ||
| 676 | if (fcr31 & FPU_CSR_UNI_X) { | 701 | if (fcr31 & FPU_CSR_UNI_X) { |
| 677 | int sig; | 702 | int sig; |
| 703 | void __user *fault_addr = NULL; | ||
| 678 | 704 | ||
| 679 | /* | 705 | /* |
| 680 | * Unimplemented operation exception. If we've got the full | 706 | * Unimplemented operation exception. If we've got the full |
| @@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
| 690 | lose_fpu(1); | 716 | lose_fpu(1); |
| 691 | 717 | ||
| 692 | /* Run the emulator */ | 718 | /* Run the emulator */ |
| 693 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1); | 719 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, |
| 720 | &fault_addr); | ||
| 694 | 721 | ||
| 695 | /* | 722 | /* |
| 696 | * We can't allow the emulated instruction to leave any of | 723 | * We can't allow the emulated instruction to leave any of |
| @@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
| 702 | own_fpu(1); /* Using the FPU again. */ | 729 | own_fpu(1); /* Using the FPU again. */ |
| 703 | 730 | ||
| 704 | /* If something went wrong, signal */ | 731 | /* If something went wrong, signal */ |
| 705 | if (sig) | 732 | process_fpemu_return(sig, fault_addr); |
| 706 | force_sig(sig, current); | ||
| 707 | 733 | ||
| 708 | return; | 734 | return; |
| 709 | } else if (fcr31 & FPU_CSR_INV_X) | 735 | } else if (fcr31 & FPU_CSR_INV_X) |
| @@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
| 996 | 1022 | ||
| 997 | if (!raw_cpu_has_fpu) { | 1023 | if (!raw_cpu_has_fpu) { |
| 998 | int sig; | 1024 | int sig; |
| 1025 | void __user *fault_addr = NULL; | ||
| 999 | sig = fpu_emulator_cop1Handler(regs, | 1026 | sig = fpu_emulator_cop1Handler(regs, |
| 1000 | ¤t->thread.fpu, 0); | 1027 | ¤t->thread.fpu, |
| 1001 | if (sig) | 1028 | 0, &fault_addr); |
| 1002 | force_sig(sig, current); | 1029 | if (!process_fpemu_return(sig, fault_addr)) |
| 1003 | else | ||
| 1004 | mt_ase_fp_affinity(); | 1030 | mt_ase_fp_affinity(); |
| 1005 | } | 1031 | } |
| 1006 | 1032 | ||
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 3eb3cde2f661..6a1fdfef8fde 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
| @@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
| 1092 | 1092 | ||
| 1093 | /* this of-course trashes what was there before... */ | 1093 | /* this of-course trashes what was there before... */ |
| 1094 | v->pbuffer = vmalloc(P_SIZE); | 1094 | v->pbuffer = vmalloc(P_SIZE); |
| 1095 | if (!v->pbuffer) { | ||
| 1096 | pr_warning("VPE loader: unable to allocate memory\n"); | ||
| 1097 | return -ENOMEM; | ||
| 1098 | } | ||
| 1095 | v->plen = P_SIZE; | 1099 | v->plen = P_SIZE; |
| 1096 | v->load_addr = NULL; | 1100 | v->load_addr = NULL; |
| 1097 | v->len = 0; | 1101 | v->len = 0; |
| @@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp) | |||
| 1149 | if (ret < 0) | 1153 | if (ret < 0) |
| 1150 | v->shared_ptr = NULL; | 1154 | v->shared_ptr = NULL; |
| 1151 | 1155 | ||
| 1152 | // cleanup any temp buffers | 1156 | vfree(v->pbuffer); |
| 1153 | if (v->pbuffer) | ||
| 1154 | vfree(v->pbuffer); | ||
| 1155 | v->plen = 0; | 1157 | v->plen = 0; |
| 1158 | |||
| 1156 | return ret; | 1159 | return ret; |
| 1157 | } | 1160 | } |
| 1158 | 1161 | ||
| @@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, | |||
| 1169 | if (v == NULL) | 1172 | if (v == NULL) |
| 1170 | return -ENODEV; | 1173 | return -ENODEV; |
| 1171 | 1174 | ||
| 1172 | if (v->pbuffer == NULL) { | ||
| 1173 | printk(KERN_ERR "VPE loader: no buffer for program\n"); | ||
| 1174 | return -ENOMEM; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | if ((count + v->len) > v->plen) { | 1175 | if ((count + v->len) > v->plen) { |
| 1178 | printk(KERN_WARNING | 1176 | printk(KERN_WARNING |
| 1179 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); | 1177 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 77dc3b20110a..606c8a9efe3b 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
| @@ -161,16 +161,16 @@ FEXPORT(__bzero) | |||
| 161 | 161 | ||
| 162 | .Lfwd_fixup: | 162 | .Lfwd_fixup: |
| 163 | PTR_L t0, TI_TASK($28) | 163 | PTR_L t0, TI_TASK($28) |
| 164 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 165 | andi a2, 0x3f | 164 | andi a2, 0x3f |
| 165 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 166 | LONG_ADDU a2, t1 | 166 | LONG_ADDU a2, t1 |
| 167 | jr ra | 167 | jr ra |
| 168 | LONG_SUBU a2, t0 | 168 | LONG_SUBU a2, t0 |
| 169 | 169 | ||
| 170 | .Lpartial_fixup: | 170 | .Lpartial_fixup: |
| 171 | PTR_L t0, TI_TASK($28) | 171 | PTR_L t0, TI_TASK($28) |
| 172 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 173 | andi a2, LONGMASK | 172 | andi a2, LONGMASK |
| 173 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 174 | LONG_ADDU a2, t1 | 174 | LONG_ADDU a2, t1 |
| 175 | jr ra | 175 | jr ra |
| 176 | LONG_SUBU a2, t0 | 176 | LONG_SUBU a2, t0 |
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index ae4cff97a56c..11b193f848f8 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c | |||
| @@ -29,9 +29,9 @@ unsigned long memsize, highmemsize; | |||
| 29 | 29 | ||
| 30 | #define parse_even_earlier(res, option, p) \ | 30 | #define parse_even_earlier(res, option, p) \ |
| 31 | do { \ | 31 | do { \ |
| 32 | int ret; \ | ||
| 32 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ | 33 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ |
| 33 | strict_strtol((char *)p + strlen(option"="), \ | 34 | ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \ |
| 34 | 10, &res); \ | ||
| 35 | } while (0) | 35 | } while (0) |
| 36 | 36 | ||
| 37 | void __init prom_init_env(void) | 37 | void __init prom_init_env(void) |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index b2ad1b0910ff..d32cb0503110 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
| @@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, | |||
| 64 | 64 | ||
| 65 | #if __mips >= 4 && __mips != 32 | 65 | #if __mips >= 4 && __mips != 32 |
| 66 | static int fpux_emu(struct pt_regs *, | 66 | static int fpux_emu(struct pt_regs *, |
| 67 | struct mips_fpu_struct *, mips_instruction); | 67 | struct mips_fpu_struct *, mips_instruction, void *__user *); |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | /* Further private data for which no space exists in mips_fpu_struct */ | 70 | /* Further private data for which no space exists in mips_fpu_struct */ |
| @@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp) | |||
| 208 | * Two instructions if the instruction is in a branch delay slot. | 208 | * Two instructions if the instruction is in a branch delay slot. |
| 209 | */ | 209 | */ |
| 210 | 210 | ||
| 211 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | 211 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 212 | void *__user *fault_addr) | ||
| 212 | { | 213 | { |
| 213 | mips_instruction ir; | 214 | mips_instruction ir; |
| 214 | unsigned long emulpc, contpc; | 215 | unsigned long emulpc, contpc; |
| 215 | unsigned int cond; | 216 | unsigned int cond; |
| 216 | 217 | ||
| 217 | if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | 218 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { |
| 218 | MIPS_FPU_EMU_INC_STATS(errors); | 219 | MIPS_FPU_EMU_INC_STATS(errors); |
| 220 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 219 | return SIGBUS; | 221 | return SIGBUS; |
| 220 | } | 222 | } |
| 223 | if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | ||
| 224 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 225 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 226 | return SIGSEGV; | ||
| 227 | } | ||
| 221 | 228 | ||
| 222 | /* XXX NEC Vr54xx bug workaround */ | 229 | /* XXX NEC Vr54xx bug workaround */ |
| 223 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) | 230 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) |
| @@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 245 | #endif | 252 | #endif |
| 246 | return SIGILL; | 253 | return SIGILL; |
| 247 | } | 254 | } |
| 248 | if (get_user(ir, (mips_instruction __user *) emulpc)) { | 255 | if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) { |
| 249 | MIPS_FPU_EMU_INC_STATS(errors); | 256 | MIPS_FPU_EMU_INC_STATS(errors); |
| 257 | *fault_addr = (mips_instruction __user *)emulpc; | ||
| 250 | return SIGBUS; | 258 | return SIGBUS; |
| 251 | } | 259 | } |
| 260 | if (__get_user(ir, (mips_instruction __user *) emulpc)) { | ||
| 261 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 262 | *fault_addr = (mips_instruction __user *)emulpc; | ||
| 263 | return SIGSEGV; | ||
| 264 | } | ||
| 252 | /* __compute_return_epc() will have updated cp0_epc */ | 265 | /* __compute_return_epc() will have updated cp0_epc */ |
| 253 | contpc = xcp->cp0_epc; | 266 | contpc = xcp->cp0_epc; |
| 254 | /* In order not to confuse ptrace() et al, tweak context */ | 267 | /* In order not to confuse ptrace() et al, tweak context */ |
| @@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 269 | u64 val; | 282 | u64 val; |
| 270 | 283 | ||
| 271 | MIPS_FPU_EMU_INC_STATS(loads); | 284 | MIPS_FPU_EMU_INC_STATS(loads); |
| 272 | if (get_user(val, va)) { | 285 | |
| 286 | if (!access_ok(VERIFY_READ, va, sizeof(u64))) { | ||
| 273 | MIPS_FPU_EMU_INC_STATS(errors); | 287 | MIPS_FPU_EMU_INC_STATS(errors); |
| 288 | *fault_addr = va; | ||
| 274 | return SIGBUS; | 289 | return SIGBUS; |
| 275 | } | 290 | } |
| 291 | if (__get_user(val, va)) { | ||
| 292 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 293 | *fault_addr = va; | ||
| 294 | return SIGSEGV; | ||
| 295 | } | ||
| 276 | DITOREG(val, MIPSInst_RT(ir)); | 296 | DITOREG(val, MIPSInst_RT(ir)); |
| 277 | break; | 297 | break; |
| 278 | } | 298 | } |
| @@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 284 | 304 | ||
| 285 | MIPS_FPU_EMU_INC_STATS(stores); | 305 | MIPS_FPU_EMU_INC_STATS(stores); |
| 286 | DIFROMREG(val, MIPSInst_RT(ir)); | 306 | DIFROMREG(val, MIPSInst_RT(ir)); |
| 287 | if (put_user(val, va)) { | 307 | if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { |
| 288 | MIPS_FPU_EMU_INC_STATS(errors); | 308 | MIPS_FPU_EMU_INC_STATS(errors); |
| 309 | *fault_addr = va; | ||
| 289 | return SIGBUS; | 310 | return SIGBUS; |
| 290 | } | 311 | } |
| 312 | if (__put_user(val, va)) { | ||
| 313 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 314 | *fault_addr = va; | ||
| 315 | return SIGSEGV; | ||
| 316 | } | ||
| 291 | break; | 317 | break; |
| 292 | } | 318 | } |
| 293 | 319 | ||
| @@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 297 | u32 val; | 323 | u32 val; |
| 298 | 324 | ||
| 299 | MIPS_FPU_EMU_INC_STATS(loads); | 325 | MIPS_FPU_EMU_INC_STATS(loads); |
| 300 | if (get_user(val, va)) { | 326 | if (!access_ok(VERIFY_READ, va, sizeof(u32))) { |
| 301 | MIPS_FPU_EMU_INC_STATS(errors); | 327 | MIPS_FPU_EMU_INC_STATS(errors); |
| 328 | *fault_addr = va; | ||
| 302 | return SIGBUS; | 329 | return SIGBUS; |
| 303 | } | 330 | } |
| 331 | if (__get_user(val, va)) { | ||
| 332 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 333 | *fault_addr = va; | ||
| 334 | return SIGSEGV; | ||
| 335 | } | ||
| 304 | SITOREG(val, MIPSInst_RT(ir)); | 336 | SITOREG(val, MIPSInst_RT(ir)); |
| 305 | break; | 337 | break; |
| 306 | } | 338 | } |
| @@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 312 | 344 | ||
| 313 | MIPS_FPU_EMU_INC_STATS(stores); | 345 | MIPS_FPU_EMU_INC_STATS(stores); |
| 314 | SIFROMREG(val, MIPSInst_RT(ir)); | 346 | SIFROMREG(val, MIPSInst_RT(ir)); |
| 315 | if (put_user(val, va)) { | 347 | if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { |
| 316 | MIPS_FPU_EMU_INC_STATS(errors); | 348 | MIPS_FPU_EMU_INC_STATS(errors); |
| 349 | *fault_addr = va; | ||
| 317 | return SIGBUS; | 350 | return SIGBUS; |
| 318 | } | 351 | } |
| 352 | if (__put_user(val, va)) { | ||
| 353 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 354 | *fault_addr = va; | ||
| 355 | return SIGSEGV; | ||
| 356 | } | ||
| 319 | break; | 357 | break; |
| 320 | } | 358 | } |
| 321 | 359 | ||
| @@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 440 | contpc = (xcp->cp0_epc + | 478 | contpc = (xcp->cp0_epc + |
| 441 | (MIPSInst_SIMM(ir) << 2)); | 479 | (MIPSInst_SIMM(ir) << 2)); |
| 442 | 480 | ||
| 443 | if (get_user(ir, | 481 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, |
| 444 | (mips_instruction __user *) xcp->cp0_epc)) { | 482 | sizeof(mips_instruction))) { |
| 445 | MIPS_FPU_EMU_INC_STATS(errors); | 483 | MIPS_FPU_EMU_INC_STATS(errors); |
| 484 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 446 | return SIGBUS; | 485 | return SIGBUS; |
| 447 | } | 486 | } |
| 487 | if (__get_user(ir, | ||
| 488 | (mips_instruction __user *) xcp->cp0_epc)) { | ||
| 489 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 490 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 491 | return SIGSEGV; | ||
| 492 | } | ||
| 448 | 493 | ||
| 449 | switch (MIPSInst_OPCODE(ir)) { | 494 | switch (MIPSInst_OPCODE(ir)) { |
| 450 | case lwc1_op: | 495 | case lwc1_op: |
| @@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 506 | 551 | ||
| 507 | #if __mips >= 4 && __mips != 32 | 552 | #if __mips >= 4 && __mips != 32 |
| 508 | case cop1x_op:{ | 553 | case cop1x_op:{ |
| 509 | int sig; | 554 | int sig = fpux_emu(xcp, ctx, ir, fault_addr); |
| 510 | 555 | if (sig) | |
| 511 | if ((sig = fpux_emu(xcp, ctx, ir))) | ||
| 512 | return sig; | 556 | return sig; |
| 513 | break; | 557 | break; |
| 514 | } | 558 | } |
| @@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); | |||
| 604 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); | 648 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); |
| 605 | 649 | ||
| 606 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 650 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 607 | mips_instruction ir) | 651 | mips_instruction ir, void *__user *fault_addr) |
| 608 | { | 652 | { |
| 609 | unsigned rcsr = 0; /* resulting csr */ | 653 | unsigned rcsr = 0; /* resulting csr */ |
| 610 | 654 | ||
| @@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 624 | xcp->regs[MIPSInst_FT(ir)]); | 668 | xcp->regs[MIPSInst_FT(ir)]); |
| 625 | 669 | ||
| 626 | MIPS_FPU_EMU_INC_STATS(loads); | 670 | MIPS_FPU_EMU_INC_STATS(loads); |
| 627 | if (get_user(val, va)) { | 671 | if (!access_ok(VERIFY_READ, va, sizeof(u32))) { |
| 628 | MIPS_FPU_EMU_INC_STATS(errors); | 672 | MIPS_FPU_EMU_INC_STATS(errors); |
| 673 | *fault_addr = va; | ||
| 629 | return SIGBUS; | 674 | return SIGBUS; |
| 630 | } | 675 | } |
| 676 | if (__get_user(val, va)) { | ||
| 677 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 678 | *fault_addr = va; | ||
| 679 | return SIGSEGV; | ||
| 680 | } | ||
| 631 | SITOREG(val, MIPSInst_FD(ir)); | 681 | SITOREG(val, MIPSInst_FD(ir)); |
| 632 | break; | 682 | break; |
| 633 | 683 | ||
| @@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 638 | MIPS_FPU_EMU_INC_STATS(stores); | 688 | MIPS_FPU_EMU_INC_STATS(stores); |
| 639 | 689 | ||
| 640 | SIFROMREG(val, MIPSInst_FS(ir)); | 690 | SIFROMREG(val, MIPSInst_FS(ir)); |
| 641 | if (put_user(val, va)) { | 691 | if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { |
| 642 | MIPS_FPU_EMU_INC_STATS(errors); | 692 | MIPS_FPU_EMU_INC_STATS(errors); |
| 693 | *fault_addr = va; | ||
| 643 | return SIGBUS; | 694 | return SIGBUS; |
| 644 | } | 695 | } |
| 696 | if (put_user(val, va)) { | ||
| 697 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 698 | *fault_addr = va; | ||
| 699 | return SIGSEGV; | ||
| 700 | } | ||
| 645 | break; | 701 | break; |
| 646 | 702 | ||
| 647 | case madd_s_op: | 703 | case madd_s_op: |
| @@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 701 | xcp->regs[MIPSInst_FT(ir)]); | 757 | xcp->regs[MIPSInst_FT(ir)]); |
| 702 | 758 | ||
| 703 | MIPS_FPU_EMU_INC_STATS(loads); | 759 | MIPS_FPU_EMU_INC_STATS(loads); |
| 704 | if (get_user(val, va)) { | 760 | if (!access_ok(VERIFY_READ, va, sizeof(u64))) { |
| 705 | MIPS_FPU_EMU_INC_STATS(errors); | 761 | MIPS_FPU_EMU_INC_STATS(errors); |
| 762 | *fault_addr = va; | ||
| 706 | return SIGBUS; | 763 | return SIGBUS; |
| 707 | } | 764 | } |
| 765 | if (__get_user(val, va)) { | ||
| 766 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 767 | *fault_addr = va; | ||
| 768 | return SIGSEGV; | ||
| 769 | } | ||
| 708 | DITOREG(val, MIPSInst_FD(ir)); | 770 | DITOREG(val, MIPSInst_FD(ir)); |
| 709 | break; | 771 | break; |
| 710 | 772 | ||
| @@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 714 | 776 | ||
| 715 | MIPS_FPU_EMU_INC_STATS(stores); | 777 | MIPS_FPU_EMU_INC_STATS(stores); |
| 716 | DIFROMREG(val, MIPSInst_FS(ir)); | 778 | DIFROMREG(val, MIPSInst_FS(ir)); |
| 717 | if (put_user(val, va)) { | 779 | if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { |
| 718 | MIPS_FPU_EMU_INC_STATS(errors); | 780 | MIPS_FPU_EMU_INC_STATS(errors); |
| 781 | *fault_addr = va; | ||
| 719 | return SIGBUS; | 782 | return SIGBUS; |
| 720 | } | 783 | } |
| 784 | if (__put_user(val, va)) { | ||
| 785 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 786 | *fault_addr = va; | ||
| 787 | return SIGSEGV; | ||
| 788 | } | ||
| 721 | break; | 789 | break; |
| 722 | 790 | ||
| 723 | case madd_d_op: | 791 | case madd_d_op: |
| @@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 1242 | } | 1310 | } |
| 1243 | 1311 | ||
| 1244 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 1312 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 1245 | int has_fpu) | 1313 | int has_fpu, void *__user *fault_addr) |
| 1246 | { | 1314 | { |
| 1247 | unsigned long oldepc, prevepc; | 1315 | unsigned long oldepc, prevepc; |
| 1248 | mips_instruction insn; | 1316 | mips_instruction insn; |
| @@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 1252 | do { | 1320 | do { |
| 1253 | prevepc = xcp->cp0_epc; | 1321 | prevepc = xcp->cp0_epc; |
| 1254 | 1322 | ||
| 1255 | if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | 1323 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { |
| 1256 | MIPS_FPU_EMU_INC_STATS(errors); | 1324 | MIPS_FPU_EMU_INC_STATS(errors); |
| 1325 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 1257 | return SIGBUS; | 1326 | return SIGBUS; |
| 1258 | } | 1327 | } |
| 1328 | if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | ||
| 1329 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 1330 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 1331 | return SIGSEGV; | ||
| 1332 | } | ||
| 1259 | if (insn == 0) | 1333 | if (insn == 0) |
| 1260 | xcp->cp0_epc += 4; /* skip nops */ | 1334 | xcp->cp0_epc += 4; /* skip nops */ |
| 1261 | else { | 1335 | else { |
| @@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 1267 | */ | 1341 | */ |
| 1268 | /* convert to ieee library modes */ | 1342 | /* convert to ieee library modes */ |
| 1269 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; | 1343 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; |
| 1270 | sig = cop1Emulate(xcp, ctx); | 1344 | sig = cop1Emulate(xcp, ctx, fault_addr); |
| 1271 | /* revert to mips rounding mode */ | 1345 | /* revert to mips rounding mode */ |
| 1272 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; | 1346 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; |
| 1273 | } | 1347 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 4fc1a0fbe007..21ea14efb837 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
| @@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask) | |||
| 288 | return plat_dma_supported(dev, mask); | 288 | return plat_dma_supported(dev, mask); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 291 | void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| 292 | enum dma_data_direction direction) | 292 | enum dma_data_direction direction) |
| 293 | { | 293 | { |
| 294 | BUG_ON(direction == DMA_NONE); | 294 | BUG_ON(direction == DMA_NONE); |
| @@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
| 298 | __dma_sync((unsigned long)vaddr, size, direction); | 298 | __dma_sync((unsigned long)vaddr, size, direction); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | EXPORT_SYMBOL(dma_cache_sync); | ||
| 302 | |||
| 301 | static struct dma_map_ops mips_default_dma_map_ops = { | 303 | static struct dma_map_ops mips_default_dma_map_ops = { |
| 302 | .alloc_coherent = mips_dma_alloc_coherent, | 304 | .alloc_coherent = mips_dma_alloc_coherent, |
| 303 | .free_coherent = mips_dma_free_coherent, | 305 | .free_coherent = mips_dma_free_coherent, |
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 505fecad4684..9cca8de00545 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c | |||
| @@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = { | |||
| 68 | */ | 68 | */ |
| 69 | static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | 69 | static inline int mips_sc_is_activated(struct cpuinfo_mips *c) |
| 70 | { | 70 | { |
| 71 | unsigned int config2 = read_c0_config2(); | ||
| 72 | unsigned int tmp; | ||
| 73 | |||
| 71 | /* Check the bypass bit (L2B) */ | 74 | /* Check the bypass bit (L2B) */ |
| 72 | switch (c->cputype) { | 75 | switch (c->cputype) { |
| 73 | case CPU_34K: | 76 | case CPU_34K: |
| @@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | |||
| 83 | c->scache.linesz = 2 << tmp; | 86 | c->scache.linesz = 2 << tmp; |
| 84 | else | 87 | else |
| 85 | return 0; | 88 | return 0; |
| 89 | return 1; | ||
| 86 | } | 90 | } |
| 87 | 91 | ||
| 88 | static inline int __init mips_sc_probe(void) | 92 | static inline int __init mips_sc_probe(void) |
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c index b7f1d9c4a8a3..434d7b1a8c6a 100644 --- a/arch/mips/pmc-sierra/yosemite/py-console.c +++ b/arch/mips/pmc-sierra/yosemite/py-console.c | |||
| @@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys) | |||
| 65 | 65 | ||
| 66 | __asm__ __volatile__ ( | 66 | __asm__ __volatile__ ( |
| 67 | " .set mips3 \n" | 67 | " .set mips3 \n" |
| 68 | " .set push \n" | ||
| 69 | " .set noreorder \n" | ||
| 70 | " .set nomacro \n" | ||
| 68 | " ld %0, %1 \n" | 71 | " ld %0, %1 \n" |
| 72 | " .set pop \n" | ||
| 69 | " lbu %0, (%0) \n" | 73 | " lbu %0, (%0) \n" |
| 70 | " .set mips0 \n" | 74 | " .set mips0 \n" |
| 71 | : "=r" (res) | 75 | : "=r" (res) |
| 72 | : "m" (vaddr)); | 76 | : "R" (vaddr)); |
| 73 | 77 | ||
| 74 | write_c0_status(sr); | 78 | write_c0_status(sr); |
| 75 | ssnop_4(); | 79 | ssnop_4(); |
| @@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c) | |||
| 89 | 93 | ||
| 90 | __asm__ __volatile__ ( | 94 | __asm__ __volatile__ ( |
| 91 | " .set mips3 \n" | 95 | " .set mips3 \n" |
| 96 | " .set push \n" | ||
| 97 | " .set noreorder \n" | ||
| 98 | " .set nomacro \n" | ||
| 92 | " ld %0, %1 \n" | 99 | " ld %0, %1 \n" |
| 100 | " .set pop \n" | ||
| 93 | " sb %2, (%0) \n" | 101 | " sb %2, (%0) \n" |
| 94 | " .set mips0 \n" | 102 | " .set mips0 \n" |
| 95 | : "=&r" (tmp) | 103 | : "=&r" (tmp) |
| 96 | : "m" (vaddr), "r" (c)); | 104 | : "R" (vaddr), "r" (c)); |
| 97 | 105 | ||
| 98 | write_c0_status(sr); | 106 | write_c0_status(sr); |
| 99 | ssnop_4(); | 107 | ssnop_4(); |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index c308989fc464..41707a245dea 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
| @@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup) | |||
| 82 | enum swarm_rtc_type { | 82 | enum swarm_rtc_type { |
| 83 | RTC_NONE, | 83 | RTC_NONE, |
| 84 | RTC_XICOR, | 84 | RTC_XICOR, |
| 85 | RTC_M4LT81 | 85 | RTC_M41T81, |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | enum swarm_rtc_type swarm_rtc_type; | 88 | enum swarm_rtc_type swarm_rtc_type; |
| @@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts) | |||
| 96 | sec = xicor_get_time(); | 96 | sec = xicor_get_time(); |
| 97 | break; | 97 | break; |
| 98 | 98 | ||
| 99 | case RTC_M4LT81: | 99 | case RTC_M41T81: |
| 100 | sec = m41t81_get_time(); | 100 | sec = m41t81_get_time(); |
| 101 | break; | 101 | break; |
| 102 | 102 | ||
| @@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec) | |||
| 115 | case RTC_XICOR: | 115 | case RTC_XICOR: |
| 116 | return xicor_set_time(sec); | 116 | return xicor_set_time(sec); |
| 117 | 117 | ||
| 118 | case RTC_M4LT81: | 118 | case RTC_M41T81: |
| 119 | return m41t81_set_time(sec); | 119 | return m41t81_set_time(sec); |
| 120 | 120 | ||
| 121 | case RTC_NONE: | 121 | case RTC_NONE: |
| @@ -141,7 +141,7 @@ void __init plat_mem_setup(void) | |||
| 141 | if (xicor_probe()) | 141 | if (xicor_probe()) |
| 142 | swarm_rtc_type = RTC_XICOR; | 142 | swarm_rtc_type = RTC_XICOR; |
| 143 | if (m41t81_probe()) | 143 | if (m41t81_probe()) |
| 144 | swarm_rtc_type = RTC_M4LT81; | 144 | swarm_rtc_type = RTC_M41T81; |
| 145 | 145 | ||
| 146 | #ifdef CONFIG_VT | 146 | #ifdef CONFIG_VT |
| 147 | screen_info = (struct screen_info) { | 147 | screen_info = (struct screen_info) { |
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c index f860a340acc9..75da468090b9 100644 --- a/arch/mn10300/kernel/time.c +++ b/arch/mn10300/kernel/time.c | |||
| @@ -40,21 +40,17 @@ unsigned long long sched_clock(void) | |||
| 40 | unsigned long long ll; | 40 | unsigned long long ll; |
| 41 | unsigned l[2]; | 41 | unsigned l[2]; |
| 42 | } tsc64, result; | 42 | } tsc64, result; |
| 43 | unsigned long tsc, tmp; | 43 | unsigned long tmp; |
| 44 | unsigned product[3]; /* 96-bit intermediate value */ | 44 | unsigned product[3]; /* 96-bit intermediate value */ |
| 45 | 45 | ||
| 46 | /* cnt32_to_63() is not safe with preemption */ | 46 | /* cnt32_to_63() is not safe with preemption */ |
| 47 | preempt_disable(); | 47 | preempt_disable(); |
| 48 | 48 | ||
| 49 | /* read the TSC value | 49 | /* expand the tsc to 64-bits. |
| 50 | */ | ||
| 51 | tsc = get_cycles(); | ||
| 52 | |||
| 53 | /* expand to 64-bits. | ||
| 54 | * - sched_clock() must be called once a minute or better or the | 50 | * - sched_clock() must be called once a minute or better or the |
| 55 | * following will go horribly wrong - see cnt32_to_63() | 51 | * following will go horribly wrong - see cnt32_to_63() |
| 56 | */ | 52 | */ |
| 57 | tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL; | 53 | tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL; |
| 58 | 54 | ||
| 59 | preempt_enable(); | 55 | preempt_enable(); |
| 60 | 56 | ||
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h index c1ee1d61d44c..81d92a45cd4b 100644 --- a/arch/tile/include/asm/signal.h +++ b/arch/tile/include/asm/signal.h | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
| 27 | struct pt_regs; | 27 | struct pt_regs; |
| 28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); | 28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); |
| 29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); | 29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); |
| 30 | void do_signal(struct pt_regs *regs); | 30 | void do_signal(struct pt_regs *regs); |
| 31 | #endif | 31 | #endif |
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 543d6a33aa26..dbb0dfc7bece 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c | |||
| @@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | |||
| 290 | return ret; | 290 | return ret; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | /* The assembly shim for this function arranges to ignore the return value. */ | ||
| 293 | long compat_sys_rt_sigreturn(struct pt_regs *regs) | 294 | long compat_sys_rt_sigreturn(struct pt_regs *regs) |
| 294 | { | 295 | { |
| 295 | struct compat_rt_sigframe __user *frame = | 296 | struct compat_rt_sigframe __user *frame = |
| 296 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); | 297 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); |
| 297 | sigset_t set; | 298 | sigset_t set; |
| 298 | long r0; | ||
| 299 | 299 | ||
| 300 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 300 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 301 | goto badframe; | 301 | goto badframe; |
| @@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs) | |||
| 308 | recalc_sigpending(); | 308 | recalc_sigpending(); |
| 309 | spin_unlock_irq(¤t->sighand->siglock); | 309 | spin_unlock_irq(¤t->sighand->siglock); |
| 310 | 310 | ||
| 311 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 311 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
| 312 | goto badframe; | 312 | goto badframe; |
| 313 | 313 | ||
| 314 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) | 314 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) |
| 315 | goto badframe; | 315 | goto badframe; |
| 316 | 316 | ||
| 317 | return r0; | 317 | return 0; |
| 318 | 318 | ||
| 319 | badframe: | 319 | badframe: |
| 320 | force_sig(SIGSEGV, current); | 320 | force_sig(SIGSEGV, current); |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index f5821626247f..5eed4a02bf62 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
| @@ -1342,8 +1342,8 @@ handle_syscall: | |||
| 1342 | lw r20, r20 | 1342 | lw r20, r20 |
| 1343 | 1343 | ||
| 1344 | /* Jump to syscall handler. */ | 1344 | /* Jump to syscall handler. */ |
| 1345 | jalr r20; .Lhandle_syscall_link: | 1345 | jalr r20 |
| 1346 | FEEDBACK_REENTER(handle_syscall) | 1346 | .Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */ |
| 1347 | 1347 | ||
| 1348 | /* | 1348 | /* |
| 1349 | * Write our r0 onto the stack so it gets restored instead | 1349 | * Write our r0 onto the stack so it gets restored instead |
| @@ -1352,6 +1352,9 @@ handle_syscall: | |||
| 1352 | PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) | 1352 | PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) |
| 1353 | sw r29, r0 | 1353 | sw r29, r0 |
| 1354 | 1354 | ||
| 1355 | .Lsyscall_sigreturn_skip: | ||
| 1356 | FEEDBACK_REENTER(handle_syscall) | ||
| 1357 | |||
| 1355 | /* Do syscall trace again, if requested. */ | 1358 | /* Do syscall trace again, if requested. */ |
| 1356 | lw r30, r31 | 1359 | lw r30, r31 |
| 1357 | andi r30, r30, _TIF_SYSCALL_TRACE | 1360 | andi r30, r30, _TIF_SYSCALL_TRACE |
| @@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr) | |||
| 1536 | }; \ | 1539 | }; \ |
| 1537 | STD_ENDPROC(_##x) | 1540 | STD_ENDPROC(_##x) |
| 1538 | 1541 | ||
| 1542 | /* | ||
| 1543 | * Special-case sigreturn to not write r0 to the stack on return. | ||
| 1544 | * This is technically more efficient, but it also avoids difficulties | ||
| 1545 | * in the 64-bit OS when handling 32-bit compat code, since we must not | ||
| 1546 | * sign-extend r0 for the sigreturn return-value case. | ||
| 1547 | */ | ||
| 1548 | #define PTREGS_SYSCALL_SIGRETURN(x, reg) \ | ||
| 1549 | STD_ENTRY(_##x); \ | ||
| 1550 | addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \ | ||
| 1551 | { \ | ||
| 1552 | PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \ | ||
| 1553 | j x \ | ||
| 1554 | }; \ | ||
| 1555 | STD_ENDPROC(_##x) | ||
| 1556 | |||
| 1539 | PTREGS_SYSCALL(sys_execve, r3) | 1557 | PTREGS_SYSCALL(sys_execve, r3) |
| 1540 | PTREGS_SYSCALL(sys_sigaltstack, r2) | 1558 | PTREGS_SYSCALL(sys_sigaltstack, r2) |
| 1541 | PTREGS_SYSCALL(sys_rt_sigreturn, r0) | 1559 | PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0) |
| 1542 | PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) | 1560 | PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) |
| 1543 | 1561 | ||
| 1544 | /* Save additional callee-saves to pt_regs, put address in r4 and jump. */ | 1562 | /* Save additional callee-saves to pt_regs, put address in r4 and jump. */ |
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 8430f45daea6..e90eb53173b0 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
| @@ -212,6 +212,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 212 | childregs->sp = sp; /* override with new user stack pointer */ | 212 | childregs->sp = sp; /* override with new user stack pointer */ |
| 213 | 213 | ||
| 214 | /* | 214 | /* |
| 215 | * If CLONE_SETTLS is set, set "tp" in the new task to "r4", | ||
| 216 | * which is passed in as arg #5 to sys_clone(). | ||
| 217 | */ | ||
| 218 | if (clone_flags & CLONE_SETTLS) | ||
| 219 | childregs->tp = regs->regs[4]; | ||
| 220 | |||
| 221 | /* | ||
| 215 | * Copy the callee-saved registers from the passed pt_regs struct | 222 | * Copy the callee-saved registers from the passed pt_regs struct |
| 216 | * into the context-switch callee-saved registers area. | 223 | * into the context-switch callee-saved registers area. |
| 217 | * This way when we start the interrupt-return sequence, the | 224 | * This way when we start the interrupt-return sequence, the |
| @@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, | |||
| 539 | return __switch_to(prev, next, next_current_ksp0(next)); | 546 | return __switch_to(prev, next, next_current_ksp0(next)); |
| 540 | } | 547 | } |
| 541 | 548 | ||
| 549 | /* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */ | ||
| 542 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | 550 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, |
| 543 | void __user *, parent_tidptr, void __user *, child_tidptr, | 551 | void __user *, parent_tidptr, void __user *, child_tidptr, |
| 544 | struct pt_regs *, regs) | 552 | struct pt_regs *, regs) |
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 757407e36696..1260321155f1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
| @@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, | |||
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | int restore_sigcontext(struct pt_regs *regs, | 54 | int restore_sigcontext(struct pt_regs *regs, |
| 55 | struct sigcontext __user *sc, long *pr0) | 55 | struct sigcontext __user *sc) |
| 56 | { | 56 | { |
| 57 | int err = 0; | 57 | int err = 0; |
| 58 | int i; | 58 | int i; |
| @@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs, | |||
| 75 | 75 | ||
| 76 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 76 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
| 77 | 77 | ||
| 78 | err |= __get_user(*pr0, &sc->gregs[0]); | ||
| 79 | return err; | 78 | return err; |
| 80 | } | 79 | } |
| 81 | 80 | ||
| 82 | /* sigreturn() returns long since it restores r0 in the interrupted code. */ | 81 | /* The assembly shim for this function arranges to ignore the return value. */ |
| 83 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | 82 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) |
| 84 | { | 83 | { |
| 85 | struct rt_sigframe __user *frame = | 84 | struct rt_sigframe __user *frame = |
| 86 | (struct rt_sigframe __user *)(regs->sp); | 85 | (struct rt_sigframe __user *)(regs->sp); |
| 87 | sigset_t set; | 86 | sigset_t set; |
| 88 | long r0; | ||
| 89 | 87 | ||
| 90 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 88 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 91 | goto badframe; | 89 | goto badframe; |
| @@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | |||
| 98 | recalc_sigpending(); | 96 | recalc_sigpending(); |
| 99 | spin_unlock_irq(¤t->sighand->siglock); | 97 | spin_unlock_irq(¤t->sighand->siglock); |
| 100 | 98 | ||
| 101 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 99 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
| 102 | goto badframe; | 100 | goto badframe; |
| 103 | 101 | ||
| 104 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) | 102 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) |
| 105 | goto badframe; | 103 | goto badframe; |
| 106 | 104 | ||
| 107 | return r0; | 105 | return 0; |
| 108 | 106 | ||
| 109 | badframe: | 107 | badframe: |
| 110 | force_sig(SIGSEGV, current); | 108 | force_sig(SIGSEGV, current); |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 23f315c9f215..325c05294fc4 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
| @@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
| 355 | if (heap > 0x3fffffffffffUL) | 355 | if (heap > 0x3fffffffffffUL) |
| 356 | error("Destination address too large"); | 356 | error("Destination address too large"); |
| 357 | #else | 357 | #else |
| 358 | if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff)) | 358 | if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) |
| 359 | error("Destination address too large"); | 359 | error("Destination address too large"); |
| 360 | #endif | 360 | #endif |
| 361 | #ifndef CONFIG_RELOCATABLE | 361 | #ifndef CONFIG_RELOCATABLE |
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 5be1542fbfaf..e99d55d74df5 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h | |||
| @@ -72,6 +72,9 @@ struct e820map { | |||
| 72 | #define BIOS_BEGIN 0x000a0000 | 72 | #define BIOS_BEGIN 0x000a0000 |
| 73 | #define BIOS_END 0x00100000 | 73 | #define BIOS_END 0x00100000 |
| 74 | 74 | ||
| 75 | #define BIOS_ROM_BASE 0xffe00000 | ||
| 76 | #define BIOS_ROM_END 0xffffffff | ||
| 77 | |||
| 75 | #ifdef __KERNEL__ | 78 | #ifdef __KERNEL__ |
| 76 | /* see comment in arch/x86/kernel/e820.c */ | 79 | /* see comment in arch/x86/kernel/e820.c */ |
| 77 | extern struct e820map e820; | 80 | extern struct e820map e820; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 9e6fe391094e..f702f82aa1eb 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -79,7 +79,7 @@ | |||
| 79 | #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) | 79 | #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) |
| 80 | #define KVM_MIN_FREE_MMU_PAGES 5 | 80 | #define KVM_MIN_FREE_MMU_PAGES 5 |
| 81 | #define KVM_REFILL_PAGES 25 | 81 | #define KVM_REFILL_PAGES 25 |
| 82 | #define KVM_MAX_CPUID_ENTRIES 40 | 82 | #define KVM_MAX_CPUID_ENTRIES 80 |
| 83 | #define KVM_NR_FIXED_MTRR_REGION 88 | 83 | #define KVM_NR_FIXED_MTRR_REGION 88 |
| 84 | #define KVM_NR_VAR_MTRR 8 | 84 | #define KVM_NR_VAR_MTRR 8 |
| 85 | 85 | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9e13763b6092..1e994754d323 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o | |||
| 45 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o | 45 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o |
| 46 | obj-y += tsc.o io_delay.o rtc.o | 46 | obj-y += tsc.o io_delay.o rtc.o |
| 47 | obj-y += pci-iommu_table.o | 47 | obj-y += pci-iommu_table.o |
| 48 | obj-y += resource.o | ||
| 48 | 49 | ||
| 49 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | 50 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o |
| 50 | obj-y += process.o | 51 | obj-y += process.o |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 3f838d537392..78218135b48e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void) | |||
| 1389 | 1389 | ||
| 1390 | setup_apic_nmi_watchdog(NULL); | 1390 | setup_apic_nmi_watchdog(NULL); |
| 1391 | apic_pm_activate(); | 1391 | apic_pm_activate(); |
| 1392 | |||
| 1393 | /* | ||
| 1394 | * Now that local APIC setup is completed for BP, configure the fault | ||
| 1395 | * handling for interrupt remapping. | ||
| 1396 | */ | ||
| 1397 | if (!smp_processor_id() && intr_remapping_enabled) | ||
| 1398 | enable_drhd_fault_handling(); | ||
| 1399 | |||
| 1392 | } | 1400 | } |
| 1393 | 1401 | ||
| 1394 | #ifdef CONFIG_X86_X2APIC | 1402 | #ifdef CONFIG_X86_X2APIC |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 7cc0a721f628..fadcd743a74f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data) | |||
| 2430 | { | 2430 | { |
| 2431 | struct irq_cfg *cfg = data->chip_data; | 2431 | struct irq_cfg *cfg = data->chip_data; |
| 2432 | int i, do_unmask_irq = 0, irq = data->irq; | 2432 | int i, do_unmask_irq = 0, irq = data->irq; |
| 2433 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 2434 | unsigned long v; | 2433 | unsigned long v; |
| 2435 | 2434 | ||
| 2436 | irq_complete_move(cfg); | 2435 | irq_complete_move(cfg); |
| 2437 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 2436 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 2438 | /* If we are moving the irq we need to mask it */ | 2437 | /* If we are moving the irq we need to mask it */ |
| 2439 | if (unlikely(desc->status & IRQ_MOVE_PENDING)) { | 2438 | if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) { |
| 2440 | do_unmask_irq = 1; | 2439 | do_unmask_irq = 1; |
| 2441 | mask_ioapic(cfg); | 2440 | mask_ioapic(cfg); |
| 2442 | } | 2441 | } |
| @@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
| 3413 | msg.data |= MSI_DATA_VECTOR(cfg->vector); | 3412 | msg.data |= MSI_DATA_VECTOR(cfg->vector); |
| 3414 | msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; | 3413 | msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; |
| 3415 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 3414 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
| 3415 | msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest); | ||
| 3416 | 3416 | ||
| 3417 | dmar_msi_write(irq, &msg); | 3417 | dmar_msi_write(irq, &msg); |
| 3418 | 3418 | ||
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index f9e4e6a54073..d8c4a6feb286 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
| @@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void) | |||
| 79 | /* need to update phys_pkg_id */ | 79 | /* need to update phys_pkg_id */ |
| 80 | apic->phys_pkg_id = apicid_phys_pkg_id; | 80 | apic->phys_pkg_id = apicid_phys_pkg_id; |
| 81 | } | 81 | } |
| 82 | |||
| 83 | /* | ||
| 84 | * Now that apic routing model is selected, configure the | ||
| 85 | * fault handling for intr remapping. | ||
| 86 | */ | ||
| 87 | if (intr_remapping_enabled) | ||
| 88 | enable_drhd_fault_handling(); | ||
| 89 | } | 82 | } |
| 90 | 83 | ||
| 91 | /* Same for both flat and physical. */ | 84 | /* Same for both flat and physical. */ |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index f0bea76f6ea5..c0dbd9ac24f0 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -60,16 +60,18 @@ | |||
| 60 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) | 60 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) |
| 61 | #endif | 61 | #endif |
| 62 | 62 | ||
| 63 | /* Number of possible pages in the lowmem region */ | ||
| 64 | LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) | ||
| 65 | |||
| 63 | /* Enough space to fit pagetables for the low memory linear map */ | 66 | /* Enough space to fit pagetables for the low memory linear map */ |
| 64 | MAPPING_BEYOND_END = \ | 67 | MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT |
| 65 | PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT | ||
| 66 | 68 | ||
| 67 | /* | 69 | /* |
| 68 | * Worst-case size of the kernel mapping we need to make: | 70 | * Worst-case size of the kernel mapping we need to make: |
| 69 | * the worst-case size of the kernel itself, plus the extra we need | 71 | * a relocatable kernel can live anywhere in lowmem, so we need to be able |
| 70 | * to map for the linear map. | 72 | * to map all of lowmem. |
| 71 | */ | 73 | */ |
| 72 | KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT | 74 | KERNEL_PAGES = LOWMEM_PAGES |
| 73 | 75 | ||
| 74 | INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm | 76 | INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm |
| 75 | RESERVE_BRK(pagetables, INIT_MAP_SIZE) | 77 | RESERVE_BRK(pagetables, INIT_MAP_SIZE) |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ae03cab4352e..4ff5968f12d2 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
| @@ -27,6 +27,9 @@ | |||
| 27 | #define HPET_DEV_FSB_CAP 0x1000 | 27 | #define HPET_DEV_FSB_CAP 0x1000 |
| 28 | #define HPET_DEV_PERI_CAP 0x2000 | 28 | #define HPET_DEV_PERI_CAP 0x2000 |
| 29 | 29 | ||
| 30 | #define HPET_MIN_CYCLES 128 | ||
| 31 | #define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1)) | ||
| 32 | |||
| 30 | #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt) | 33 | #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt) |
| 31 | 34 | ||
| 32 | /* | 35 | /* |
| @@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void) | |||
| 299 | /* Calculate the min / max delta */ | 302 | /* Calculate the min / max delta */ |
| 300 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | 303 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, |
| 301 | &hpet_clockevent); | 304 | &hpet_clockevent); |
| 302 | /* 5 usec minimum reprogramming delta. */ | 305 | /* Setup minimum reprogramming delta. */ |
| 303 | hpet_clockevent.min_delta_ns = 5000; | 306 | hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, |
| 307 | &hpet_clockevent); | ||
| 304 | 308 | ||
| 305 | /* | 309 | /* |
| 306 | * Start hpet with the boot cpu mask and make it | 310 | * Start hpet with the boot cpu mask and make it |
| @@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta, | |||
| 393 | * the wraparound into account) nor a simple count down event | 397 | * the wraparound into account) nor a simple count down event |
| 394 | * mode. Further the write to the comparator register is | 398 | * mode. Further the write to the comparator register is |
| 395 | * delayed internally up to two HPET clock cycles in certain | 399 | * delayed internally up to two HPET clock cycles in certain |
| 396 | * chipsets (ATI, ICH9,10). We worked around that by reading | 400 | * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even |
| 397 | * back the compare register, but that required another | 401 | * longer delays. We worked around that by reading back the |
| 398 | * workaround for ICH9,10 chips where the first readout after | 402 | * compare register, but that required another workaround for |
| 399 | * write can return the old stale value. We already have a | 403 | * ICH9,10 chips where the first readout after write can |
| 400 | * minimum delta of 5us enforced, but a NMI or SMI hitting | 404 | * return the old stale value. We already had a minimum |
| 405 | * programming delta of 5us enforced, but a NMI or SMI hitting | ||
| 401 | * between the counter readout and the comparator write can | 406 | * between the counter readout and the comparator write can |
| 402 | * move us behind that point easily. Now instead of reading | 407 | * move us behind that point easily. Now instead of reading |
| 403 | * the compare register back several times, we make the ETIME | 408 | * the compare register back several times, we make the ETIME |
| 404 | * decision based on the following: Return ETIME if the | 409 | * decision based on the following: Return ETIME if the |
| 405 | * counter value after the write is less than 8 HPET cycles | 410 | * counter value after the write is less than HPET_MIN_CYCLES |
| 406 | * away from the event or if the counter is already ahead of | 411 | * away from the event or if the counter is already ahead of |
| 407 | * the event. | 412 | * the event. The minimum programming delta for the generic |
| 413 | * clockevents code is set to 1.5 * HPET_MIN_CYCLES. | ||
| 408 | */ | 414 | */ |
| 409 | res = (s32)(cnt - hpet_readl(HPET_COUNTER)); | 415 | res = (s32)(cnt - hpet_readl(HPET_COUNTER)); |
| 410 | 416 | ||
| 411 | return res < 8 ? -ETIME : 0; | 417 | return res < HPET_MIN_CYCLES ? -ETIME : 0; |
| 412 | } | 418 | } |
| 413 | 419 | ||
| 414 | static void hpet_legacy_set_mode(enum clock_event_mode mode, | 420 | static void hpet_legacy_set_mode(enum clock_event_mode mode, |
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c new file mode 100644 index 000000000000..2a26819bb6a8 --- /dev/null +++ b/arch/x86/kernel/resource.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #include <linux/ioport.h> | ||
| 2 | #include <asm/e820.h> | ||
| 3 | |||
| 4 | static void resource_clip(struct resource *res, resource_size_t start, | ||
| 5 | resource_size_t end) | ||
| 6 | { | ||
| 7 | resource_size_t low = 0, high = 0; | ||
| 8 | |||
| 9 | if (res->end < start || res->start > end) | ||
| 10 | return; /* no conflict */ | ||
| 11 | |||
| 12 | if (res->start < start) | ||
| 13 | low = start - res->start; | ||
| 14 | |||
| 15 | if (res->end > end) | ||
| 16 | high = res->end - end; | ||
| 17 | |||
| 18 | /* Keep the area above or below the conflict, whichever is larger */ | ||
| 19 | if (low > high) | ||
| 20 | res->end = start - 1; | ||
| 21 | else | ||
| 22 | res->start = end + 1; | ||
| 23 | } | ||
| 24 | |||
| 25 | static void remove_e820_regions(struct resource *avail) | ||
| 26 | { | ||
| 27 | int i; | ||
| 28 | struct e820entry *entry; | ||
| 29 | |||
| 30 | for (i = 0; i < e820.nr_map; i++) { | ||
| 31 | entry = &e820.map[i]; | ||
| 32 | |||
| 33 | resource_clip(avail, entry->addr, | ||
| 34 | entry->addr + entry->size - 1); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | void arch_remove_reservations(struct resource *avail) | ||
| 39 | { | ||
| 40 | /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */ | ||
| 41 | if (avail->flags & IORESOURCE_MEM) { | ||
| 42 | if (avail->start < BIOS_END) | ||
| 43 | avail->start = BIOS_END; | ||
| 44 | resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); | ||
| 45 | |||
| 46 | remove_e820_regions(avail); | ||
| 47 | } | ||
| 48 | } | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 21c6746338af..85268f8eadf6 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -769,7 +769,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 769 | 769 | ||
| 770 | x86_init.oem.arch_setup(); | 770 | x86_init.oem.arch_setup(); |
| 771 | 771 | ||
| 772 | resource_alloc_from_bottom = 0; | ||
| 773 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; | 772 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; |
| 774 | setup_memory_map(); | 773 | setup_memory_map(); |
| 775 | parse_setup_data(); | 774 | parse_setup_data(); |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 9c253bd65e24..547128546cc3 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
| @@ -394,7 +394,8 @@ static void __init setup_xstate_init(void) | |||
| 394 | * Setup init_xstate_buf to represent the init state of | 394 | * Setup init_xstate_buf to represent the init state of |
| 395 | * all the features managed by the xsave | 395 | * all the features managed by the xsave |
| 396 | */ | 396 | */ |
| 397 | init_xstate_buf = alloc_bootmem(xstate_size); | 397 | init_xstate_buf = alloc_bootmem_align(xstate_size, |
| 398 | __alignof__(struct xsave_struct)); | ||
| 398 | init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; | 399 | init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; |
| 399 | 400 | ||
| 400 | clts(); | 401 | clts(); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1ca12298ffc7..b81a9b7c2ca4 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) | |||
| 3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | 3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) |
| 3495 | { | 3495 | { |
| 3496 | switch (func) { | 3496 | switch (func) { |
| 3497 | case 0x00000001: | ||
| 3498 | /* Mask out xsave bit as long as it is not supported by SVM */ | ||
| 3499 | entry->ecx &= ~(bit(X86_FEATURE_XSAVE)); | ||
| 3500 | break; | ||
| 3497 | case 0x80000001: | 3501 | case 0x80000001: |
| 3498 | if (nested) | 3502 | if (nested) |
| 3499 | entry->ecx |= (1 << 2); /* Set SVM bit */ | 3503 | entry->ecx |= (1 << 2); /* Set SVM bit */ |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ff21fdda0c53..81fcbe9515c5 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void) | |||
| 4227 | return PT_PDPE_LEVEL; | 4227 | return PT_PDPE_LEVEL; |
| 4228 | } | 4228 | } |
| 4229 | 4229 | ||
| 4230 | static inline u32 bit(int bitno) | ||
| 4231 | { | ||
| 4232 | return 1 << (bitno & 31); | ||
| 4233 | } | ||
| 4234 | |||
| 4235 | static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | 4230 | static void vmx_cpuid_update(struct kvm_vcpu *vcpu) |
| 4236 | { | 4231 | { |
| 4237 | struct kvm_cpuid_entry2 *best; | 4232 | struct kvm_cpuid_entry2 *best; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cdac9e592aa5..b989e1f1e5d3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
| 155 | 155 | ||
| 156 | u64 __read_mostly host_xcr0; | 156 | u64 __read_mostly host_xcr0; |
| 157 | 157 | ||
| 158 | static inline u32 bit(int bitno) | ||
| 159 | { | ||
| 160 | return 1 << (bitno & 31); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void kvm_on_user_return(struct user_return_notifier *urn) | 158 | static void kvm_on_user_return(struct user_return_notifier *urn) |
| 164 | { | 159 | { |
| 165 | unsigned slot; | 160 | unsigned slot; |
| @@ -4569,9 +4564,11 @@ static void kvm_timer_init(void) | |||
| 4569 | #ifdef CONFIG_CPU_FREQ | 4564 | #ifdef CONFIG_CPU_FREQ |
| 4570 | struct cpufreq_policy policy; | 4565 | struct cpufreq_policy policy; |
| 4571 | memset(&policy, 0, sizeof(policy)); | 4566 | memset(&policy, 0, sizeof(policy)); |
| 4572 | cpufreq_get_policy(&policy, get_cpu()); | 4567 | cpu = get_cpu(); |
| 4568 | cpufreq_get_policy(&policy, cpu); | ||
| 4573 | if (policy.cpuinfo.max_freq) | 4569 | if (policy.cpuinfo.max_freq) |
| 4574 | max_tsc_khz = policy.cpuinfo.max_freq; | 4570 | max_tsc_khz = policy.cpuinfo.max_freq; |
| 4571 | put_cpu(); | ||
| 4575 | #endif | 4572 | #endif |
| 4576 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, | 4573 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, |
| 4577 | CPUFREQ_TRANSITION_NOTIFIER); | 4574 | CPUFREQ_TRANSITION_NOTIFIER); |
| @@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
| 5522 | 5519 | ||
| 5523 | mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; | 5520 | mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; |
| 5524 | kvm_x86_ops->set_cr4(vcpu, sregs->cr4); | 5521 | kvm_x86_ops->set_cr4(vcpu, sregs->cr4); |
| 5522 | if (sregs->cr4 & X86_CR4_OSXSAVE) | ||
| 5523 | update_cpuid(vcpu); | ||
| 5525 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { | 5524 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { |
| 5526 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); | 5525 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); |
| 5527 | mmu_reset_needed = 1; | 5526 | mmu_reset_needed = 1; |
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 2cea414489f3..c600da830ce0 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
| @@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu) | |||
| 70 | return kvm_read_cr0_bits(vcpu, X86_CR0_PG); | 70 | return kvm_read_cr0_bits(vcpu, X86_CR0_PG); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static inline u32 bit(int bitno) | ||
| 74 | { | ||
| 75 | return 1 << (bitno & 31); | ||
| 76 | } | ||
| 77 | |||
| 73 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); | 78 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); |
| 74 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); | 79 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); |
| 75 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); | 80 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index c4bb261c106e..b1805b78842f 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
| @@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res, | |||
| 65 | resource_size_t size, resource_size_t align) | 65 | resource_size_t size, resource_size_t align) |
| 66 | { | 66 | { |
| 67 | struct pci_dev *dev = data; | 67 | struct pci_dev *dev = data; |
| 68 | resource_size_t start = round_down(res->end - size + 1, align); | 68 | resource_size_t start = res->start; |
| 69 | 69 | ||
| 70 | if (res->flags & IORESOURCE_IO) { | 70 | if (res->flags & IORESOURCE_IO) { |
| 71 | 71 | if (skip_isa_ioresource_align(dev)) | |
| 72 | /* | 72 | return start; |
| 73 | * If we're avoiding ISA aliases, the largest contiguous I/O | 73 | if (start & 0x300) |
| 74 | * port space is 256 bytes. Clearing bits 9 and 10 preserves | 74 | start = (start + 0x3ff) & ~0x3ff; |
| 75 | * all 256-byte and smaller alignments, so the result will | ||
| 76 | * still be correctly aligned. | ||
| 77 | */ | ||
| 78 | if (!skip_isa_ioresource_align(dev)) | ||
| 79 | start &= ~0x300; | ||
| 80 | } else if (res->flags & IORESOURCE_MEM) { | ||
| 81 | if (start < BIOS_END) | ||
| 82 | start = res->end; /* fail; no space */ | ||
| 83 | } | 75 | } |
| 84 | return start; | 76 | return start; |
| 85 | } | 77 | } |
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 4a2afa1bac51..b6552b189bcd 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile | |||
| @@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) | |||
| 25 | 25 | ||
| 26 | export CPPFLAGS_vdso.lds += -P -C | 26 | export CPPFLAGS_vdso.lds += -P -C |
| 27 | 27 | ||
| 28 | VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \ | 28 | VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ |
| 29 | -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 | 29 | -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 |
| 30 | 30 | ||
| 31 | $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so | 31 | $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so |
| @@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y) += sysenter | |||
| 69 | vdso32-images = $(vdso32.so-y:%=vdso32-%.so) | 69 | vdso32-images = $(vdso32.so-y:%=vdso32-%.so) |
| 70 | 70 | ||
| 71 | CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) | 71 | CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) |
| 72 | VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1 | 72 | VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1 |
| 73 | 73 | ||
| 74 | # This makes sure the $(obj) subdirectory exists even though vdso32/ | 74 | # This makes sure the $(obj) subdirectory exists even though vdso32/ |
| 75 | # is not a kbuild sub-make subdirectory. | 75 | # is not a kbuild sub-make subdirectory. |
diff --git a/block/blk-map.c b/block/blk-map.c index 5d5dbe47c228..e663ac2d8e68 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
| @@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, | |||
| 201 | for (i = 0; i < iov_count; i++) { | 201 | for (i = 0; i < iov_count; i++) { |
| 202 | unsigned long uaddr = (unsigned long)iov[i].iov_base; | 202 | unsigned long uaddr = (unsigned long)iov[i].iov_base; |
| 203 | 203 | ||
| 204 | if (!iov[i].iov_len) | ||
| 205 | return -EINVAL; | ||
| 206 | |||
| 204 | if (uaddr & queue_dma_alignment(q)) { | 207 | if (uaddr & queue_dma_alignment(q)) { |
| 205 | unaligned = 1; | 208 | unaligned = 1; |
| 206 | break; | 209 | break; |
| 207 | } | 210 | } |
| 208 | if (!iov[i].iov_len) | ||
| 209 | return -EINVAL; | ||
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | if (unaligned || (q->dma_pad_mask & len) || map_data) | 213 | if (unaligned || (q->dma_pad_mask & len) || map_data) |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 77b7c26df6b5..74bc4a768f32 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
| @@ -21,7 +21,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q, | |||
| 21 | return 0; | 21 | return 0; |
| 22 | 22 | ||
| 23 | fbio = bio; | 23 | fbio = bio; |
| 24 | cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 24 | cluster = blk_queue_cluster(q); |
| 25 | seg_size = 0; | 25 | seg_size = 0; |
| 26 | nr_phys_segs = 0; | 26 | nr_phys_segs = 0; |
| 27 | for_each_bio(bio) { | 27 | for_each_bio(bio) { |
| @@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments); | |||
| 87 | static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, | 87 | static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, |
| 88 | struct bio *nxt) | 88 | struct bio *nxt) |
| 89 | { | 89 | { |
| 90 | if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | 90 | if (!blk_queue_cluster(q)) |
| 91 | return 0; | 91 | return 0; |
| 92 | 92 | ||
| 93 | if (bio->bi_seg_back_size + nxt->bi_seg_front_size > | 93 | if (bio->bi_seg_back_size + nxt->bi_seg_front_size > |
| @@ -123,7 +123,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, | |||
| 123 | int nsegs, cluster; | 123 | int nsegs, cluster; |
| 124 | 124 | ||
| 125 | nsegs = 0; | 125 | nsegs = 0; |
| 126 | cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 126 | cluster = blk_queue_cluster(q); |
| 127 | 127 | ||
| 128 | /* | 128 | /* |
| 129 | * for each bio in rq | 129 | * for each bio in rq |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 701859fb9647..36c8c1f2af18 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
| @@ -126,7 +126,7 @@ void blk_set_default_limits(struct queue_limits *lim) | |||
| 126 | lim->alignment_offset = 0; | 126 | lim->alignment_offset = 0; |
| 127 | lim->io_opt = 0; | 127 | lim->io_opt = 0; |
| 128 | lim->misaligned = 0; | 128 | lim->misaligned = 0; |
| 129 | lim->no_cluster = 0; | 129 | lim->cluster = 1; |
| 130 | } | 130 | } |
| 131 | EXPORT_SYMBOL(blk_set_default_limits); | 131 | EXPORT_SYMBOL(blk_set_default_limits); |
| 132 | 132 | ||
| @@ -229,8 +229,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask) | |||
| 229 | EXPORT_SYMBOL(blk_queue_bounce_limit); | 229 | EXPORT_SYMBOL(blk_queue_bounce_limit); |
| 230 | 230 | ||
| 231 | /** | 231 | /** |
| 232 | * blk_queue_max_hw_sectors - set max sectors for a request for this queue | 232 | * blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request |
| 233 | * @q: the request queue for the device | 233 | * @limits: the queue limits |
| 234 | * @max_hw_sectors: max hardware sectors in the usual 512b unit | 234 | * @max_hw_sectors: max hardware sectors in the usual 512b unit |
| 235 | * | 235 | * |
| 236 | * Description: | 236 | * Description: |
| @@ -244,7 +244,7 @@ EXPORT_SYMBOL(blk_queue_bounce_limit); | |||
| 244 | * per-device basis in /sys/block/<device>/queue/max_sectors_kb. | 244 | * per-device basis in /sys/block/<device>/queue/max_sectors_kb. |
| 245 | * The soft limit can not exceed max_hw_sectors. | 245 | * The soft limit can not exceed max_hw_sectors. |
| 246 | **/ | 246 | **/ |
| 247 | void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors) | 247 | void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_sectors) |
| 248 | { | 248 | { |
| 249 | if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) { | 249 | if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) { |
| 250 | max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9); | 250 | max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9); |
| @@ -252,9 +252,23 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto | |||
| 252 | __func__, max_hw_sectors); | 252 | __func__, max_hw_sectors); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | q->limits.max_hw_sectors = max_hw_sectors; | 255 | limits->max_hw_sectors = max_hw_sectors; |
| 256 | q->limits.max_sectors = min_t(unsigned int, max_hw_sectors, | 256 | limits->max_sectors = min_t(unsigned int, max_hw_sectors, |
| 257 | BLK_DEF_MAX_SECTORS); | 257 | BLK_DEF_MAX_SECTORS); |
| 258 | } | ||
| 259 | EXPORT_SYMBOL(blk_limits_max_hw_sectors); | ||
| 260 | |||
| 261 | /** | ||
| 262 | * blk_queue_max_hw_sectors - set max sectors for a request for this queue | ||
| 263 | * @q: the request queue for the device | ||
| 264 | * @max_hw_sectors: max hardware sectors in the usual 512b unit | ||
| 265 | * | ||
| 266 | * Description: | ||
| 267 | * See description for blk_limits_max_hw_sectors(). | ||
| 268 | **/ | ||
| 269 | void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors) | ||
| 270 | { | ||
| 271 | blk_limits_max_hw_sectors(&q->limits, max_hw_sectors); | ||
| 258 | } | 272 | } |
| 259 | EXPORT_SYMBOL(blk_queue_max_hw_sectors); | 273 | EXPORT_SYMBOL(blk_queue_max_hw_sectors); |
| 260 | 274 | ||
| @@ -464,15 +478,6 @@ EXPORT_SYMBOL(blk_queue_io_opt); | |||
| 464 | void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) | 478 | void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) |
| 465 | { | 479 | { |
| 466 | blk_stack_limits(&t->limits, &b->limits, 0); | 480 | blk_stack_limits(&t->limits, &b->limits, 0); |
| 467 | |||
| 468 | if (!t->queue_lock) | ||
| 469 | WARN_ON_ONCE(1); | ||
| 470 | else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) { | ||
| 471 | unsigned long flags; | ||
| 472 | spin_lock_irqsave(t->queue_lock, flags); | ||
| 473 | queue_flag_clear(QUEUE_FLAG_CLUSTER, t); | ||
| 474 | spin_unlock_irqrestore(t->queue_lock, flags); | ||
| 475 | } | ||
| 476 | } | 481 | } |
| 477 | EXPORT_SYMBOL(blk_queue_stack_limits); | 482 | EXPORT_SYMBOL(blk_queue_stack_limits); |
| 478 | 483 | ||
| @@ -545,7 +550,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
| 545 | t->io_min = max(t->io_min, b->io_min); | 550 | t->io_min = max(t->io_min, b->io_min); |
| 546 | t->io_opt = lcm(t->io_opt, b->io_opt); | 551 | t->io_opt = lcm(t->io_opt, b->io_opt); |
| 547 | 552 | ||
| 548 | t->no_cluster |= b->no_cluster; | 553 | t->cluster &= b->cluster; |
| 549 | t->discard_zeroes_data &= b->discard_zeroes_data; | 554 | t->discard_zeroes_data &= b->discard_zeroes_data; |
| 550 | 555 | ||
| 551 | /* Physical block size a multiple of the logical block size? */ | 556 | /* Physical block size a multiple of the logical block size? */ |
| @@ -641,7 +646,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | |||
| 641 | sector_t offset) | 646 | sector_t offset) |
| 642 | { | 647 | { |
| 643 | struct request_queue *t = disk->queue; | 648 | struct request_queue *t = disk->queue; |
| 644 | struct request_queue *b = bdev_get_queue(bdev); | ||
| 645 | 649 | ||
| 646 | if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { | 650 | if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { |
| 647 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; | 651 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; |
| @@ -652,17 +656,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | |||
| 652 | printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n", | 656 | printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n", |
| 653 | top, bottom); | 657 | top, bottom); |
| 654 | } | 658 | } |
| 655 | |||
| 656 | if (!t->queue_lock) | ||
| 657 | WARN_ON_ONCE(1); | ||
| 658 | else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) { | ||
| 659 | unsigned long flags; | ||
| 660 | |||
| 661 | spin_lock_irqsave(t->queue_lock, flags); | ||
| 662 | if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) | ||
| 663 | queue_flag_clear(QUEUE_FLAG_CLUSTER, t); | ||
| 664 | spin_unlock_irqrestore(t->queue_lock, flags); | ||
| 665 | } | ||
| 666 | } | 659 | } |
| 667 | EXPORT_SYMBOL(disk_stack_limits); | 660 | EXPORT_SYMBOL(disk_stack_limits); |
| 668 | 661 | ||
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 013457f47fdc..41fb69150b4d 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
| @@ -119,7 +119,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char * | |||
| 119 | 119 | ||
| 120 | static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) | 120 | static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) |
| 121 | { | 121 | { |
| 122 | if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | 122 | if (blk_queue_cluster(q)) |
| 123 | return queue_var_show(queue_max_segment_size(q), (page)); | 123 | return queue_var_show(queue_max_segment_size(q), (page)); |
| 124 | 124 | ||
| 125 | return queue_var_show(PAGE_CACHE_SIZE, (page)); | 125 | return queue_var_show(PAGE_CACHE_SIZE, (page)); |
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 004be80fd894..381b09bb562b 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
| @@ -355,6 +355,12 @@ throtl_start_new_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw) | |||
| 355 | tg->slice_end[rw], jiffies); | 355 | tg->slice_end[rw], jiffies); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | static inline void throtl_set_slice_end(struct throtl_data *td, | ||
| 359 | struct throtl_grp *tg, bool rw, unsigned long jiffy_end) | ||
| 360 | { | ||
| 361 | tg->slice_end[rw] = roundup(jiffy_end, throtl_slice); | ||
| 362 | } | ||
| 363 | |||
| 358 | static inline void throtl_extend_slice(struct throtl_data *td, | 364 | static inline void throtl_extend_slice(struct throtl_data *td, |
| 359 | struct throtl_grp *tg, bool rw, unsigned long jiffy_end) | 365 | struct throtl_grp *tg, bool rw, unsigned long jiffy_end) |
| 360 | { | 366 | { |
| @@ -391,6 +397,16 @@ throtl_trim_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw) | |||
| 391 | if (throtl_slice_used(td, tg, rw)) | 397 | if (throtl_slice_used(td, tg, rw)) |
| 392 | return; | 398 | return; |
| 393 | 399 | ||
| 400 | /* | ||
| 401 | * A bio has been dispatched. Also adjust slice_end. It might happen | ||
| 402 | * that initially cgroup limit was very low resulting in high | ||
| 403 | * slice_end, but later limit was bumped up and bio was dispached | ||
| 404 | * sooner, then we need to reduce slice_end. A high bogus slice_end | ||
| 405 | * is bad because it does not allow new slice to start. | ||
| 406 | */ | ||
| 407 | |||
| 408 | throtl_set_slice_end(td, tg, rw, jiffies + throtl_slice); | ||
| 409 | |||
| 394 | time_elapsed = jiffies - tg->slice_start[rw]; | 410 | time_elapsed = jiffies - tg->slice_start[rw]; |
| 395 | 411 | ||
| 396 | nr_slices = time_elapsed / throtl_slice; | 412 | nr_slices = time_elapsed / throtl_slice; |
| @@ -709,26 +725,21 @@ static void throtl_process_limit_change(struct throtl_data *td) | |||
| 709 | struct throtl_grp *tg; | 725 | struct throtl_grp *tg; |
| 710 | struct hlist_node *pos, *n; | 726 | struct hlist_node *pos, *n; |
| 711 | 727 | ||
| 712 | /* | ||
| 713 | * Make sure atomic_inc() effects from | ||
| 714 | * throtl_update_blkio_group_read_bps(), group of functions are | ||
| 715 | * visible. | ||
| 716 | * Is this required or smp_mb__after_atomic_inc() was suffcient | ||
| 717 | * after the atomic_inc(). | ||
| 718 | */ | ||
| 719 | smp_rmb(); | ||
| 720 | if (!atomic_read(&td->limits_changed)) | 728 | if (!atomic_read(&td->limits_changed)) |
| 721 | return; | 729 | return; |
| 722 | 730 | ||
| 723 | throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed)); | 731 | throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed)); |
| 724 | 732 | ||
| 725 | hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) { | 733 | /* |
| 726 | /* | 734 | * Make sure updates from throtl_update_blkio_group_read_bps() group |
| 727 | * Do I need an smp_rmb() here to make sure tg->limits_changed | 735 | * of functions to tg->limits_changed are visible. We do not |
| 728 | * update is visible. I am relying on smp_rmb() at the | 736 | * want update td->limits_changed to be visible but update to |
| 729 | * beginning of function and not putting a new one here. | 737 | * tg->limits_changed not being visible yet on this cpu. Hence |
| 730 | */ | 738 | * the read barrier. |
| 739 | */ | ||
| 740 | smp_rmb(); | ||
| 731 | 741 | ||
| 742 | hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) { | ||
| 732 | if (throtl_tg_on_rr(tg) && tg->limits_changed) { | 743 | if (throtl_tg_on_rr(tg) && tg->limits_changed) { |
| 733 | throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu" | 744 | throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu" |
| 734 | " riops=%u wiops=%u", tg->bps[READ], | 745 | " riops=%u wiops=%u", tg->bps[READ], |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f291587d753e..233e06c29ff4 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -2834,6 +2834,8 @@ static int cciss_revalidate(struct gendisk *disk) | |||
| 2834 | InquiryData_struct *inq_buff = NULL; | 2834 | InquiryData_struct *inq_buff = NULL; |
| 2835 | 2835 | ||
| 2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { |
| 2837 | if (!h->drv[logvol]) | ||
| 2838 | continue | ||
| 2837 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, | 2839 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, |
| 2838 | sizeof(drv->LunID)) == 0) { | 2840 | sizeof(drv->LunID)) == 0) { |
| 2839 | FOUND = 1; | 2841 | FOUND = 1; |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 89d8a7cc4054..24487d4fb202 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
| @@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev) | |||
| 3627 | } | 3627 | } |
| 3628 | 3628 | ||
| 3629 | shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); | 3629 | shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); |
| 3630 | rv = drbd_recv(mdev, &header->h80.payload, shs); | ||
| 3631 | if (unlikely(rv != shs)) { | ||
| 3632 | dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); | ||
| 3633 | goto err_out; | ||
| 3634 | } | ||
| 3635 | |||
| 3636 | if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { | 3630 | if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { |
| 3637 | dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); | 3631 | dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); |
| 3638 | goto err_out; | 3632 | goto err_out; |
| 3639 | } | 3633 | } |
| 3640 | 3634 | ||
| 3635 | if (shs) { | ||
| 3636 | rv = drbd_recv(mdev, &header->h80.payload, shs); | ||
| 3637 | if (unlikely(rv != shs)) { | ||
| 3638 | dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); | ||
| 3639 | goto err_out; | ||
| 3640 | } | ||
| 3641 | } | ||
| 3642 | |||
| 3641 | rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); | 3643 | rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); |
| 3642 | 3644 | ||
| 3643 | if (unlikely(!rv)) { | 3645 | if (unlikely(!rv)) { |
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 181ea0364822..ab2bd09d54b4 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
| @@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) | |||
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | /* completion of master bio is outside of spinlock. | 341 | /* completion of master bio is outside of spinlock. |
| 342 | * If you need it irqsave, do it your self! */ | 342 | * If you need it irqsave, do it your self! |
| 343 | * Which means: don't use from bio endio callback. */ | ||
| 343 | static inline int req_mod(struct drbd_request *req, | 344 | static inline int req_mod(struct drbd_request *req, |
| 344 | enum drbd_req_event what) | 345 | enum drbd_req_event what) |
| 345 | { | 346 | { |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 47d223c2409c..34f224b018b3 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
| @@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error) | |||
| 193 | */ | 193 | */ |
| 194 | void drbd_endio_pri(struct bio *bio, int error) | 194 | void drbd_endio_pri(struct bio *bio, int error) |
| 195 | { | 195 | { |
| 196 | unsigned long flags; | ||
| 196 | struct drbd_request *req = bio->bi_private; | 197 | struct drbd_request *req = bio->bi_private; |
| 197 | struct drbd_conf *mdev = req->mdev; | 198 | struct drbd_conf *mdev = req->mdev; |
| 199 | struct bio_and_error m; | ||
| 198 | enum drbd_req_event what; | 200 | enum drbd_req_event what; |
| 199 | int uptodate = bio_flagged(bio, BIO_UPTODATE); | 201 | int uptodate = bio_flagged(bio, BIO_UPTODATE); |
| 200 | 202 | ||
| @@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error) | |||
| 220 | bio_put(req->private_bio); | 222 | bio_put(req->private_bio); |
| 221 | req->private_bio = ERR_PTR(error); | 223 | req->private_bio = ERR_PTR(error); |
| 222 | 224 | ||
| 223 | req_mod(req, what); | 225 | /* not req_mod(), we need irqsave here! */ |
| 226 | spin_lock_irqsave(&mdev->req_lock, flags); | ||
| 227 | __req_mod(req, what, &m); | ||
| 228 | spin_unlock_irqrestore(&mdev->req_lock, flags); | ||
| 229 | |||
| 230 | if (m.bio) | ||
| 231 | complete_master_bio(mdev, &m); | ||
| 224 | } | 232 | } |
| 225 | 233 | ||
| 226 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | 234 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index d68d3aa1814b..f975d24890fa 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
| @@ -283,16 +283,21 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, | |||
| 283 | } while (delay); | 283 | } while (delay); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | 286 | static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) |
| 287 | { | 287 | { |
| 288 | unsigned long flags; | ||
| 289 | |||
| 290 | if (delta > p->max_match_value) | 288 | if (delta > p->max_match_value) |
| 291 | dev_warn(&p->pdev->dev, "delta out of range\n"); | 289 | dev_warn(&p->pdev->dev, "delta out of range\n"); |
| 292 | 290 | ||
| 293 | spin_lock_irqsave(&p->lock, flags); | ||
| 294 | p->next_match_value = delta; | 291 | p->next_match_value = delta; |
| 295 | sh_cmt_clock_event_program_verify(p, 0); | 292 | sh_cmt_clock_event_program_verify(p, 0); |
| 293 | } | ||
| 294 | |||
| 295 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | ||
| 296 | { | ||
| 297 | unsigned long flags; | ||
| 298 | |||
| 299 | spin_lock_irqsave(&p->lock, flags); | ||
| 300 | __sh_cmt_set_next(p, delta); | ||
| 296 | spin_unlock_irqrestore(&p->lock, flags); | 301 | spin_unlock_irqrestore(&p->lock, flags); |
| 297 | } | 302 | } |
| 298 | 303 | ||
| @@ -359,7 +364,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) | |||
| 359 | 364 | ||
| 360 | /* setup timeout if no clockevent */ | 365 | /* setup timeout if no clockevent */ |
| 361 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) | 366 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) |
| 362 | sh_cmt_set_next(p, p->max_match_value); | 367 | __sh_cmt_set_next(p, p->max_match_value); |
| 363 | out: | 368 | out: |
| 364 | spin_unlock_irqrestore(&p->lock, flags); | 369 | spin_unlock_irqrestore(&p->lock, flags); |
| 365 | 370 | ||
| @@ -381,7 +386,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) | |||
| 381 | 386 | ||
| 382 | /* adjust the timeout to maximum if only clocksource left */ | 387 | /* adjust the timeout to maximum if only clocksource left */ |
| 383 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) | 388 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) |
| 384 | sh_cmt_set_next(p, p->max_match_value); | 389 | __sh_cmt_set_next(p, p->max_match_value); |
| 385 | 390 | ||
| 386 | spin_unlock_irqrestore(&p->lock, flags); | 391 | spin_unlock_irqrestore(&p->lock, flags); |
| 387 | } | 392 | } |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 90267f8d64ee..4d705cea0f8c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
| @@ -517,9 +517,8 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
| 517 | */ | 517 | */ |
| 518 | 518 | ||
| 519 | if (q->merge_bvec_fn && !ti->type->merge) | 519 | if (q->merge_bvec_fn && !ti->type->merge) |
| 520 | limits->max_sectors = | 520 | blk_limits_max_hw_sectors(limits, |
| 521 | min_not_zero(limits->max_sectors, | 521 | (unsigned int) (PAGE_SIZE >> 9)); |
| 522 | (unsigned int) (PAGE_SIZE >> 9)); | ||
| 523 | return 0; | 522 | return 0; |
| 524 | } | 523 | } |
| 525 | EXPORT_SYMBOL_GPL(dm_set_device_limits); | 524 | EXPORT_SYMBOL_GPL(dm_set_device_limits); |
| @@ -1131,11 +1130,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
| 1131 | */ | 1130 | */ |
| 1132 | q->limits = *limits; | 1131 | q->limits = *limits; |
| 1133 | 1132 | ||
| 1134 | if (limits->no_cluster) | ||
| 1135 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); | ||
| 1136 | else | ||
| 1137 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q); | ||
| 1138 | |||
| 1139 | if (!dm_table_supports_discards(t)) | 1133 | if (!dm_table_supports_discards(t)) |
| 1140 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | 1134 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); |
| 1141 | else | 1135 | else |
diff --git a/drivers/md/md.c b/drivers/md/md.c index e71c5fa527f5..175c424f201f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -4295,9 +4295,6 @@ static int md_alloc(dev_t dev, char *name) | |||
| 4295 | goto abort; | 4295 | goto abort; |
| 4296 | mddev->queue->queuedata = mddev; | 4296 | mddev->queue->queuedata = mddev; |
| 4297 | 4297 | ||
| 4298 | /* Can be unlocked because the queue is new: no concurrency */ | ||
| 4299 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue); | ||
| 4300 | |||
| 4301 | blk_queue_make_request(mddev->queue, md_make_request); | 4298 | blk_queue_make_request(mddev->queue, md_make_request); |
| 4302 | 4299 | ||
| 4303 | disk = alloc_disk(1 << shift); | 4300 | disk = alloc_disk(1 << shift); |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 5bf4985daede..05e832f61c3e 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
| @@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 361 | 361 | ||
| 362 | static const struct v4l2_file_operations rtrack_fops = { | 362 | static const struct v4l2_file_operations rtrack_fops = { |
| 363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
| 365 | }; | 365 | }; |
| 366 | 366 | ||
| 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { |
| @@ -412,13 +412,6 @@ static int __init rtrack_init(void) | |||
| 412 | rt->vdev.release = video_device_release_empty; | 412 | rt->vdev.release = video_device_release_empty; |
| 413 | video_set_drvdata(&rt->vdev, rt); | 413 | video_set_drvdata(&rt->vdev, rt); |
| 414 | 414 | ||
| 415 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 416 | v4l2_device_unregister(&rt->v4l2_dev); | ||
| 417 | release_region(rt->io, 2); | ||
| 418 | return -EINVAL; | ||
| 419 | } | ||
| 420 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
| 421 | |||
| 422 | /* Set up the I/O locking */ | 415 | /* Set up the I/O locking */ |
| 423 | 416 | ||
| 424 | mutex_init(&rt->lock); | 417 | mutex_init(&rt->lock); |
| @@ -430,6 +423,13 @@ static int __init rtrack_init(void) | |||
| 430 | sleep_delay(2000000); /* make sure it's totally down */ | 423 | sleep_delay(2000000); /* make sure it's totally down */ |
| 431 | outb(0xc0, rt->io); /* steady volume, mute card */ | 424 | outb(0xc0, rt->io); /* steady volume, mute card */ |
| 432 | 425 | ||
| 426 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 427 | v4l2_device_unregister(&rt->v4l2_dev); | ||
| 428 | release_region(rt->io, 2); | ||
| 429 | return -EINVAL; | ||
| 430 | } | ||
| 431 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
| 432 | |||
| 433 | return 0; | 433 | return 0; |
| 434 | } | 434 | } |
| 435 | 435 | ||
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index c22311393624..dd8a6ab0d437 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
| @@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 324 | 324 | ||
| 325 | static const struct v4l2_file_operations aztech_fops = { | 325 | static const struct v4l2_file_operations aztech_fops = { |
| 326 | .owner = THIS_MODULE, | 326 | .owner = THIS_MODULE, |
| 327 | .ioctl = video_ioctl2, | 327 | .unlocked_ioctl = video_ioctl2, |
| 328 | }; | 328 | }; |
| 329 | 329 | ||
| 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { | 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { |
| @@ -375,6 +375,8 @@ static int __init aztech_init(void) | |||
| 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; | 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; |
| 376 | az->vdev.release = video_device_release_empty; | 376 | az->vdev.release = video_device_release_empty; |
| 377 | video_set_drvdata(&az->vdev, az); | 377 | video_set_drvdata(&az->vdev, az); |
| 378 | /* mute card - prevents noisy bootups */ | ||
| 379 | outb(0, az->io); | ||
| 378 | 380 | ||
| 379 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 381 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 380 | v4l2_device_unregister(v4l2_dev); | 382 | v4l2_device_unregister(v4l2_dev); |
| @@ -383,8 +385,6 @@ static int __init aztech_init(void) | |||
| 383 | } | 385 | } |
| 384 | 386 | ||
| 385 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); | 387 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); |
| 386 | /* mute card - prevents noisy bootups */ | ||
| 387 | outb(0, az->io); | ||
| 388 | return 0; | 388 | return 0; |
| 389 | } | 389 | } |
| 390 | 390 | ||
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index b701ea6e7c73..bc9ad0897c55 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
| @@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
| 328 | unsigned char readbuf[RDS_BUFFER]; | 328 | unsigned char readbuf[RDS_BUFFER]; |
| 329 | int i = 0; | 329 | int i = 0; |
| 330 | 330 | ||
| 331 | mutex_lock(&dev->lock); | ||
| 331 | if (dev->rdsstat == 0) { | 332 | if (dev->rdsstat == 0) { |
| 332 | mutex_lock(&dev->lock); | ||
| 333 | dev->rdsstat = 1; | 333 | dev->rdsstat = 1; |
| 334 | outb(0x80, dev->io); /* Select RDS fifo */ | 334 | outb(0x80, dev->io); /* Select RDS fifo */ |
| 335 | mutex_unlock(&dev->lock); | ||
| 336 | init_timer(&dev->readtimer); | 335 | init_timer(&dev->readtimer); |
| 337 | dev->readtimer.function = cadet_handler; | 336 | dev->readtimer.function = cadet_handler; |
| 338 | dev->readtimer.data = (unsigned long)dev; | 337 | dev->readtimer.data = (unsigned long)dev; |
| @@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
| 340 | add_timer(&dev->readtimer); | 339 | add_timer(&dev->readtimer); |
| 341 | } | 340 | } |
| 342 | if (dev->rdsin == dev->rdsout) { | 341 | if (dev->rdsin == dev->rdsout) { |
| 342 | mutex_unlock(&dev->lock); | ||
| 343 | if (file->f_flags & O_NONBLOCK) | 343 | if (file->f_flags & O_NONBLOCK) |
| 344 | return -EWOULDBLOCK; | 344 | return -EWOULDBLOCK; |
| 345 | interruptible_sleep_on(&dev->read_queue); | 345 | interruptible_sleep_on(&dev->read_queue); |
| 346 | mutex_lock(&dev->lock); | ||
| 346 | } | 347 | } |
| 347 | while (i < count && dev->rdsin != dev->rdsout) | 348 | while (i < count && dev->rdsin != dev->rdsout) |
| 348 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; | 349 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; |
| 350 | mutex_unlock(&dev->lock); | ||
| 349 | 351 | ||
| 350 | if (copy_to_user(data, readbuf, i)) | 352 | if (copy_to_user(data, readbuf, i)) |
| 351 | return -EFAULT; | 353 | return -EFAULT; |
| @@ -525,9 +527,11 @@ static int cadet_open(struct file *file) | |||
| 525 | { | 527 | { |
| 526 | struct cadet *dev = video_drvdata(file); | 528 | struct cadet *dev = video_drvdata(file); |
| 527 | 529 | ||
| 530 | mutex_lock(&dev->lock); | ||
| 528 | dev->users++; | 531 | dev->users++; |
| 529 | if (1 == dev->users) | 532 | if (1 == dev->users) |
| 530 | init_waitqueue_head(&dev->read_queue); | 533 | init_waitqueue_head(&dev->read_queue); |
| 534 | mutex_unlock(&dev->lock); | ||
| 531 | return 0; | 535 | return 0; |
| 532 | } | 536 | } |
| 533 | 537 | ||
| @@ -535,11 +539,13 @@ static int cadet_release(struct file *file) | |||
| 535 | { | 539 | { |
| 536 | struct cadet *dev = video_drvdata(file); | 540 | struct cadet *dev = video_drvdata(file); |
| 537 | 541 | ||
| 542 | mutex_lock(&dev->lock); | ||
| 538 | dev->users--; | 543 | dev->users--; |
| 539 | if (0 == dev->users) { | 544 | if (0 == dev->users) { |
| 540 | del_timer_sync(&dev->readtimer); | 545 | del_timer_sync(&dev->readtimer); |
| 541 | dev->rdsstat = 0; | 546 | dev->rdsstat = 0; |
| 542 | } | 547 | } |
| 548 | mutex_unlock(&dev->lock); | ||
| 543 | return 0; | 549 | return 0; |
| 544 | } | 550 | } |
| 545 | 551 | ||
| @@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = { | |||
| 559 | .open = cadet_open, | 565 | .open = cadet_open, |
| 560 | .release = cadet_release, | 566 | .release = cadet_release, |
| 561 | .read = cadet_read, | 567 | .read = cadet_read, |
| 562 | .ioctl = video_ioctl2, | 568 | .unlocked_ioctl = video_ioctl2, |
| 563 | .poll = cadet_poll, | 569 | .poll = cadet_poll, |
| 564 | }; | 570 | }; |
| 565 | 571 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 79039674a0e0..28fa85ba2087 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
| @@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id); | |||
| 361 | 361 | ||
| 362 | static const struct v4l2_file_operations gemtek_pci_fops = { | 362 | static const struct v4l2_file_operations gemtek_pci_fops = { |
| 363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
| 365 | }; | 365 | }; |
| 366 | 366 | ||
| 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { |
| @@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev | |||
| 422 | card->vdev.release = video_device_release_empty; | 422 | card->vdev.release = video_device_release_empty; |
| 423 | video_set_drvdata(&card->vdev, card); | 423 | video_set_drvdata(&card->vdev, card); |
| 424 | 424 | ||
| 425 | gemtek_pci_mute(card); | ||
| 426 | |||
| 425 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) | 427 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) |
| 426 | goto err_video; | 428 | goto err_video; |
| 427 | 429 | ||
| 428 | gemtek_pci_mute(card); | ||
| 429 | |||
| 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", | 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", |
| 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); | 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); |
| 432 | 432 | ||
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 73985f641f07..259936422e49 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
| @@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt) | |||
| 378 | 378 | ||
| 379 | static const struct v4l2_file_operations gemtek_fops = { | 379 | static const struct v4l2_file_operations gemtek_fops = { |
| 380 | .owner = THIS_MODULE, | 380 | .owner = THIS_MODULE, |
| 381 | .ioctl = video_ioctl2, | 381 | .unlocked_ioctl = video_ioctl2, |
| 382 | }; | 382 | }; |
| 383 | 383 | ||
| 384 | static int vidioc_querycap(struct file *file, void *priv, | 384 | static int vidioc_querycap(struct file *file, void *priv, |
| @@ -577,12 +577,6 @@ static int __init gemtek_init(void) | |||
| 577 | gt->vdev.release = video_device_release_empty; | 577 | gt->vdev.release = video_device_release_empty; |
| 578 | video_set_drvdata(>->vdev, gt); | 578 | video_set_drvdata(>->vdev, gt); |
| 579 | 579 | ||
| 580 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 581 | v4l2_device_unregister(v4l2_dev); | ||
| 582 | release_region(gt->io, 1); | ||
| 583 | return -EBUSY; | ||
| 584 | } | ||
| 585 | |||
| 586 | /* Set defaults */ | 580 | /* Set defaults */ |
| 587 | gt->lastfreq = GEMTEK_LOWFREQ; | 581 | gt->lastfreq = GEMTEK_LOWFREQ; |
| 588 | gt->bu2614data = 0; | 582 | gt->bu2614data = 0; |
| @@ -590,6 +584,12 @@ static int __init gemtek_init(void) | |||
| 590 | if (initmute) | 584 | if (initmute) |
| 591 | gemtek_mute(gt); | 585 | gemtek_mute(gt); |
| 592 | 586 | ||
| 587 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 588 | v4l2_device_unregister(v4l2_dev); | ||
| 589 | release_region(gt->io, 1); | ||
| 590 | return -EBUSY; | ||
| 591 | } | ||
| 592 | |||
| 593 | return 0; | 593 | return 0; |
| 594 | } | 594 | } |
| 595 | 595 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 08f1051979ca..6af61bfeb178 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
| @@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 299 | 299 | ||
| 300 | static const struct v4l2_file_operations maestro_fops = { | 300 | static const struct v4l2_file_operations maestro_fops = { |
| 301 | .owner = THIS_MODULE, | 301 | .owner = THIS_MODULE, |
| 302 | .ioctl = video_ioctl2, | 302 | .unlocked_ioctl = video_ioctl2, |
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { | 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { |
| @@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev, | |||
| 383 | dev->vdev.release = video_device_release_empty; | 383 | dev->vdev.release = video_device_release_empty; |
| 384 | video_set_drvdata(&dev->vdev, dev); | 384 | video_set_drvdata(&dev->vdev, dev); |
| 385 | 385 | ||
| 386 | if (!radio_power_on(dev)) { | ||
| 387 | retval = -EIO; | ||
| 388 | goto errfr1; | ||
| 389 | } | ||
| 390 | |||
| 386 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); | 391 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); |
| 387 | if (retval) { | 392 | if (retval) { |
| 388 | v4l2_err(v4l2_dev, "can't register video device!\n"); | 393 | v4l2_err(v4l2_dev, "can't register video device!\n"); |
| 389 | goto errfr1; | 394 | goto errfr1; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| 392 | if (!radio_power_on(dev)) { | ||
| 393 | retval = -EIO; | ||
| 394 | goto errunr; | ||
| 395 | } | ||
| 396 | |||
| 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); | 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); |
| 398 | 398 | ||
| 399 | return 0; | 399 | return 0; |
| 400 | errunr: | ||
| 401 | video_unregister_device(&dev->vdev); | ||
| 402 | errfr1: | 400 | errfr1: |
| 403 | v4l2_device_unregister(v4l2_dev); | 401 | v4l2_device_unregister(v4l2_dev); |
| 404 | errfr: | 402 | errfr: |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 255d40df4b46..6459a220b0dd 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
| @@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 346 | 346 | ||
| 347 | static const struct v4l2_file_operations maxiradio_fops = { | 347 | static const struct v4l2_file_operations maxiradio_fops = { |
| 348 | .owner = THIS_MODULE, | 348 | .owner = THIS_MODULE, |
| 349 | .ioctl = video_ioctl2, | 349 | .unlocked_ioctl = video_ioctl2, |
| 350 | }; | 350 | }; |
| 351 | 351 | ||
| 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { | 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c index 4ff885445fd4..3fb76e3834c9 100644 --- a/drivers/media/radio/radio-miropcm20.c +++ b/drivers/media/radio/radio-miropcm20.c | |||
| @@ -33,6 +33,7 @@ struct pcm20 { | |||
| 33 | unsigned long freq; | 33 | unsigned long freq; |
| 34 | int muted; | 34 | int muted; |
| 35 | struct snd_miro_aci *aci; | 35 | struct snd_miro_aci *aci; |
| 36 | struct mutex lock; | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | static struct pcm20 pcm20_card = { | 39 | static struct pcm20 pcm20_card = { |
| @@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq) | |||
| 72 | 73 | ||
| 73 | static const struct v4l2_file_operations pcm20_fops = { | 74 | static const struct v4l2_file_operations pcm20_fops = { |
| 74 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
| 75 | .ioctl = video_ioctl2, | 76 | .unlocked_ioctl = video_ioctl2, |
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | static int vidioc_querycap(struct file *file, void *priv, | 79 | static int vidioc_querycap(struct file *file, void *priv, |
| @@ -229,7 +230,7 @@ static int __init pcm20_init(void) | |||
| 229 | return -ENODEV; | 230 | return -ENODEV; |
| 230 | } | 231 | } |
| 231 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); | 232 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); |
| 232 | 233 | mutex_init(&dev->lock); | |
| 233 | 234 | ||
| 234 | res = v4l2_device_register(NULL, v4l2_dev); | 235 | res = v4l2_device_register(NULL, v4l2_dev); |
| 235 | if (res < 0) { | 236 | if (res < 0) { |
| @@ -242,6 +243,7 @@ static int __init pcm20_init(void) | |||
| 242 | dev->vdev.fops = &pcm20_fops; | 243 | dev->vdev.fops = &pcm20_fops; |
| 243 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; | 244 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; |
| 244 | dev->vdev.release = video_device_release_empty; | 245 | dev->vdev.release = video_device_release_empty; |
| 246 | dev->vdev.lock = &dev->lock; | ||
| 245 | video_set_drvdata(&dev->vdev, dev); | 247 | video_set_drvdata(&dev->vdev, dev); |
| 246 | 248 | ||
| 247 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) | 249 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index a79296aac9a9..8d6ea591bd18 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
| @@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 266 | 266 | ||
| 267 | static const struct v4l2_file_operations rtrack2_fops = { | 267 | static const struct v4l2_file_operations rtrack2_fops = { |
| 268 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
| 269 | .ioctl = video_ioctl2, | 269 | .unlocked_ioctl = video_ioctl2, |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { | 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { |
| @@ -315,6 +315,10 @@ static int __init rtrack2_init(void) | |||
| 315 | dev->vdev.release = video_device_release_empty; | 315 | dev->vdev.release = video_device_release_empty; |
| 316 | video_set_drvdata(&dev->vdev, dev); | 316 | video_set_drvdata(&dev->vdev, dev); |
| 317 | 317 | ||
| 318 | /* mute card - prevents noisy bootups */ | ||
| 319 | outb(1, dev->io); | ||
| 320 | dev->muted = 1; | ||
| 321 | |||
| 318 | mutex_init(&dev->lock); | 322 | mutex_init(&dev->lock); |
| 319 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 323 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 320 | v4l2_device_unregister(v4l2_dev); | 324 | v4l2_device_unregister(v4l2_dev); |
| @@ -324,10 +328,6 @@ static int __init rtrack2_init(void) | |||
| 324 | 328 | ||
| 325 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); | 329 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); |
| 326 | 330 | ||
| 327 | /* mute card - prevents noisy bootups */ | ||
| 328 | outb(1, dev->io); | ||
| 329 | dev->muted = 1; | ||
| 330 | |||
| 331 | return 0; | 331 | return 0; |
| 332 | } | 332 | } |
| 333 | 333 | ||
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 985359d18aa5..b5a5f89e238a 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
| @@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 260 | 260 | ||
| 261 | static const struct v4l2_file_operations fmi_fops = { | 261 | static const struct v4l2_file_operations fmi_fops = { |
| 262 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
| 263 | .ioctl = video_ioctl2, | 263 | .unlocked_ioctl = video_ioctl2, |
| 264 | }; | 264 | }; |
| 265 | 265 | ||
| 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { | 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { |
| @@ -382,6 +382,9 @@ static int __init fmi_init(void) | |||
| 382 | 382 | ||
| 383 | mutex_init(&fmi->lock); | 383 | mutex_init(&fmi->lock); |
| 384 | 384 | ||
| 385 | /* mute card - prevents noisy bootups */ | ||
| 386 | fmi_mute(fmi); | ||
| 387 | |||
| 385 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 388 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 386 | v4l2_device_unregister(v4l2_dev); | 389 | v4l2_device_unregister(v4l2_dev); |
| 387 | release_region(fmi->io, 2); | 390 | release_region(fmi->io, 2); |
| @@ -391,8 +394,6 @@ static int __init fmi_init(void) | |||
| 391 | } | 394 | } |
| 392 | 395 | ||
| 393 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); | 396 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); |
| 394 | /* mute card - prevents noisy bootups */ | ||
| 395 | fmi_mute(fmi); | ||
| 396 | return 0; | 397 | return 0; |
| 397 | } | 398 | } |
| 398 | 399 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52c7bbb32b8b..dc3f04c52d5e 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
| @@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 376 | 376 | ||
| 377 | static const struct v4l2_file_operations fmr2_fops = { | 377 | static const struct v4l2_file_operations fmr2_fops = { |
| 378 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
| 379 | .ioctl = video_ioctl2, | 379 | .unlocked_ioctl = video_ioctl2, |
| 380 | }; | 380 | }; |
| 381 | 381 | ||
| 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { | 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { |
| @@ -424,6 +424,10 @@ static int __init fmr2_init(void) | |||
| 424 | fmr2->vdev.release = video_device_release_empty; | 424 | fmr2->vdev.release = video_device_release_empty; |
| 425 | video_set_drvdata(&fmr2->vdev, fmr2); | 425 | video_set_drvdata(&fmr2->vdev, fmr2); |
| 426 | 426 | ||
| 427 | /* mute card - prevents noisy bootups */ | ||
| 428 | fmr2_mute(fmr2->io); | ||
| 429 | fmr2_product_info(fmr2); | ||
| 430 | |||
| 427 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 431 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 428 | v4l2_device_unregister(v4l2_dev); | 432 | v4l2_device_unregister(v4l2_dev); |
| 429 | release_region(fmr2->io, 2); | 433 | release_region(fmr2->io, 2); |
| @@ -431,11 +435,6 @@ static int __init fmr2_init(void) | |||
| 431 | } | 435 | } |
| 432 | 436 | ||
| 433 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); | 437 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); |
| 434 | /* mute card - prevents noisy bootups */ | ||
| 435 | mutex_lock(&fmr2->lock); | ||
| 436 | fmr2_mute(fmr2->io); | ||
| 437 | fmr2_product_info(fmr2); | ||
| 438 | mutex_unlock(&fmr2->lock); | ||
| 439 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); | 438 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); |
| 440 | return 0; | 439 | return 0; |
| 441 | } | 440 | } |
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 03829e6818bd..726d367ad8d0 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c | |||
| @@ -53,7 +53,8 @@ struct radio_si4713_device { | |||
| 53 | /* radio_si4713_fops - file operations interface */ | 53 | /* radio_si4713_fops - file operations interface */ |
| 54 | static const struct v4l2_file_operations radio_si4713_fops = { | 54 | static const struct v4l2_file_operations radio_si4713_fops = { |
| 55 | .owner = THIS_MODULE, | 55 | .owner = THIS_MODULE, |
| 56 | .ioctl = video_ioctl2, | 56 | /* Note: locking is done at the subdev level in the i2c driver. */ |
| 57 | .unlocked_ioctl = video_ioctl2, | ||
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| 59 | /* Video4Linux Interface */ | 60 | /* Video4Linux Interface */ |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 789d2ec66e19..0e71d816c725 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c | |||
| @@ -142,7 +142,6 @@ struct tea5764_device { | |||
| 142 | struct video_device *videodev; | 142 | struct video_device *videodev; |
| 143 | struct tea5764_regs regs; | 143 | struct tea5764_regs regs; |
| 144 | struct mutex mutex; | 144 | struct mutex mutex; |
| 145 | int users; | ||
| 146 | }; | 145 | }; |
| 147 | 146 | ||
| 148 | /* I2C code related */ | 147 | /* I2C code related */ |
| @@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 458 | return 0; | 457 | return 0; |
| 459 | } | 458 | } |
| 460 | 459 | ||
| 461 | static int tea5764_open(struct file *file) | ||
| 462 | { | ||
| 463 | /* Currently we support only one device */ | ||
| 464 | struct tea5764_device *radio = video_drvdata(file); | ||
| 465 | |||
| 466 | mutex_lock(&radio->mutex); | ||
| 467 | /* Only exclusive access */ | ||
| 468 | if (radio->users) { | ||
| 469 | mutex_unlock(&radio->mutex); | ||
| 470 | return -EBUSY; | ||
| 471 | } | ||
| 472 | radio->users++; | ||
| 473 | mutex_unlock(&radio->mutex); | ||
| 474 | file->private_data = radio; | ||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | static int tea5764_close(struct file *file) | ||
| 479 | { | ||
| 480 | struct tea5764_device *radio = video_drvdata(file); | ||
| 481 | |||
| 482 | if (!radio) | ||
| 483 | return -ENODEV; | ||
| 484 | mutex_lock(&radio->mutex); | ||
| 485 | radio->users--; | ||
| 486 | mutex_unlock(&radio->mutex); | ||
| 487 | return 0; | ||
| 488 | } | ||
| 489 | |||
| 490 | /* File system interface */ | 460 | /* File system interface */ |
| 491 | static const struct v4l2_file_operations tea5764_fops = { | 461 | static const struct v4l2_file_operations tea5764_fops = { |
| 492 | .owner = THIS_MODULE, | 462 | .owner = THIS_MODULE, |
| 493 | .open = tea5764_open, | 463 | .unlocked_ioctl = video_ioctl2, |
| 494 | .release = tea5764_close, | ||
| 495 | .ioctl = video_ioctl2, | ||
| 496 | }; | 464 | }; |
| 497 | 465 | ||
| 498 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { | 466 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { |
| @@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 527 | int ret; | 495 | int ret; |
| 528 | 496 | ||
| 529 | PDEBUG("probe"); | 497 | PDEBUG("probe"); |
| 530 | radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); | 498 | radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL); |
| 531 | if (!radio) | 499 | if (!radio) |
| 532 | return -ENOMEM; | 500 | return -ENOMEM; |
| 533 | 501 | ||
| @@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 555 | 523 | ||
| 556 | i2c_set_clientdata(client, radio); | 524 | i2c_set_clientdata(client, radio); |
| 557 | video_set_drvdata(radio->videodev, radio); | 525 | video_set_drvdata(radio->videodev, radio); |
| 558 | 526 | radio->videodev->lock = &radio->mutex; | |
| 559 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 560 | if (ret < 0) { | ||
| 561 | PWARN("Could not register video device!"); | ||
| 562 | goto errrel; | ||
| 563 | } | ||
| 564 | 527 | ||
| 565 | /* initialize and power off the chip */ | 528 | /* initialize and power off the chip */ |
| 566 | tea5764_i2c_read(radio); | 529 | tea5764_i2c_read(radio); |
| @@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 568 | tea5764_mute(radio, 1); | 531 | tea5764_mute(radio, 1); |
| 569 | tea5764_power_down(radio); | 532 | tea5764_power_down(radio); |
| 570 | 533 | ||
| 534 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 535 | if (ret < 0) { | ||
| 536 | PWARN("Could not register video device!"); | ||
| 537 | goto errrel; | ||
| 538 | } | ||
| 539 | |||
| 571 | PINFO("registered."); | 540 | PINFO("registered."); |
| 572 | return 0; | 541 | return 0; |
| 573 | errrel: | 542 | errrel: |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index fc1c860fd438..a32663917059 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
| @@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 338 | 338 | ||
| 339 | static const struct v4l2_file_operations terratec_fops = { | 339 | static const struct v4l2_file_operations terratec_fops = { |
| 340 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
| 341 | .ioctl = video_ioctl2, | 341 | .unlocked_ioctl = video_ioctl2, |
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { | 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { |
| @@ -389,6 +389,9 @@ static int __init terratec_init(void) | |||
| 389 | 389 | ||
| 390 | mutex_init(&tt->lock); | 390 | mutex_init(&tt->lock); |
| 391 | 391 | ||
| 392 | /* mute card - prevents noisy bootups */ | ||
| 393 | tt_write_vol(tt, 0); | ||
| 394 | |||
| 392 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 395 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 393 | v4l2_device_unregister(&tt->v4l2_dev); | 396 | v4l2_device_unregister(&tt->v4l2_dev); |
| 394 | release_region(tt->io, 2); | 397 | release_region(tt->io, 2); |
| @@ -396,9 +399,6 @@ static int __init terratec_init(void) | |||
| 396 | } | 399 | } |
| 397 | 400 | ||
| 398 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); | 401 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); |
| 399 | |||
| 400 | /* mute card - prevents noisy bootups */ | ||
| 401 | tt_write_vol(tt, 0); | ||
| 402 | return 0; | 402 | return 0; |
| 403 | } | 403 | } |
| 404 | 404 | ||
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index b8bb3ef47df5..a185610b376b 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c | |||
| @@ -34,6 +34,7 @@ struct timbradio { | |||
| 34 | struct v4l2_subdev *sd_dsp; | 34 | struct v4l2_subdev *sd_dsp; |
| 35 | struct video_device video_dev; | 35 | struct video_device video_dev; |
| 36 | struct v4l2_device v4l2_dev; | 36 | struct v4l2_device v4l2_dev; |
| 37 | struct mutex lock; | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | 40 | ||
| @@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = { | |||
| 142 | 143 | ||
| 143 | static const struct v4l2_file_operations timbradio_fops = { | 144 | static const struct v4l2_file_operations timbradio_fops = { |
| 144 | .owner = THIS_MODULE, | 145 | .owner = THIS_MODULE, |
| 145 | .ioctl = video_ioctl2, | 146 | .unlocked_ioctl = video_ioctl2, |
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | static int __devinit timbradio_probe(struct platform_device *pdev) | 149 | static int __devinit timbradio_probe(struct platform_device *pdev) |
| @@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
| 164 | } | 165 | } |
| 165 | 166 | ||
| 166 | tr->pdata = *pdata; | 167 | tr->pdata = *pdata; |
| 168 | mutex_init(&tr->lock); | ||
| 167 | 169 | ||
| 168 | strlcpy(tr->video_dev.name, "Timberdale Radio", | 170 | strlcpy(tr->video_dev.name, "Timberdale Radio", |
| 169 | sizeof(tr->video_dev.name)); | 171 | sizeof(tr->video_dev.name)); |
| @@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
| 171 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; | 173 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; |
| 172 | tr->video_dev.release = video_device_release_empty; | 174 | tr->video_dev.release = video_device_release_empty; |
| 173 | tr->video_dev.minor = -1; | 175 | tr->video_dev.minor = -1; |
| 176 | tr->video_dev.lock = &tr->lock; | ||
| 174 | 177 | ||
| 175 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); | 178 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); |
| 176 | err = v4l2_device_register(NULL, &tr->v4l2_dev); | 179 | err = v4l2_device_register(NULL, &tr->v4l2_dev); |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 9d6dcf8af5b0..22fa9cc28abe 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
| @@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 344 | 344 | ||
| 345 | static const struct v4l2_file_operations trust_fops = { | 345 | static const struct v4l2_file_operations trust_fops = { |
| 346 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
| 347 | .ioctl = video_ioctl2, | 347 | .unlocked_ioctl = video_ioctl2, |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { | 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { |
| @@ -396,14 +396,6 @@ static int __init trust_init(void) | |||
| 396 | tr->vdev.release = video_device_release_empty; | 396 | tr->vdev.release = video_device_release_empty; |
| 397 | video_set_drvdata(&tr->vdev, tr); | 397 | video_set_drvdata(&tr->vdev, tr); |
| 398 | 398 | ||
| 399 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 400 | v4l2_device_unregister(v4l2_dev); | ||
| 401 | release_region(tr->io, 2); | ||
| 402 | return -EINVAL; | ||
| 403 | } | ||
| 404 | |||
| 405 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
| 406 | |||
| 407 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ | 399 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ |
| 408 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ | 400 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ |
| 409 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ | 401 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ |
| @@ -418,6 +410,14 @@ static int __init trust_init(void) | |||
| 418 | /* mute card - prevents noisy bootups */ | 410 | /* mute card - prevents noisy bootups */ |
| 419 | tr_setmute(tr, 1); | 411 | tr_setmute(tr, 1); |
| 420 | 412 | ||
| 413 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 414 | v4l2_device_unregister(v4l2_dev); | ||
| 415 | release_region(tr->io, 2); | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 418 | |||
| 419 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
| 420 | |||
| 421 | return 0; | 421 | return 0; |
| 422 | } | 422 | } |
| 423 | 423 | ||
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index b1f630527dc1..8dbbf08f2207 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
| @@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv) | |||
| 317 | 317 | ||
| 318 | static const struct v4l2_file_operations typhoon_fops = { | 318 | static const struct v4l2_file_operations typhoon_fops = { |
| 319 | .owner = THIS_MODULE, | 319 | .owner = THIS_MODULE, |
| 320 | .ioctl = video_ioctl2, | 320 | .unlocked_ioctl = video_ioctl2, |
| 321 | }; | 321 | }; |
| 322 | 322 | ||
| 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { | 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { |
| @@ -344,18 +344,18 @@ static int __init typhoon_init(void) | |||
| 344 | 344 | ||
| 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); | 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); |
| 346 | dev->io = io; | 346 | dev->io = io; |
| 347 | dev->curfreq = dev->mutefreq = mutefreq; | ||
| 348 | 347 | ||
| 349 | if (dev->io == -1) { | 348 | if (dev->io == -1) { |
| 350 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); | 349 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); |
| 351 | return -EINVAL; | 350 | return -EINVAL; |
| 352 | } | 351 | } |
| 353 | 352 | ||
| 354 | if (dev->mutefreq < 87000 || dev->mutefreq > 108500) { | 353 | if (mutefreq < 87000 || mutefreq > 108500) { |
| 355 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); | 354 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); |
| 356 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); | 355 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); |
| 357 | return -EINVAL; | 356 | return -EINVAL; |
| 358 | } | 357 | } |
| 358 | dev->curfreq = dev->mutefreq = mutefreq << 4; | ||
| 359 | 359 | ||
| 360 | mutex_init(&dev->lock); | 360 | mutex_init(&dev->lock); |
| 361 | if (!request_region(dev->io, 8, "typhoon")) { | 361 | if (!request_region(dev->io, 8, "typhoon")) { |
| @@ -378,17 +378,17 @@ static int __init typhoon_init(void) | |||
| 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; | 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; |
| 379 | dev->vdev.release = video_device_release_empty; | 379 | dev->vdev.release = video_device_release_empty; |
| 380 | video_set_drvdata(&dev->vdev, dev); | 380 | video_set_drvdata(&dev->vdev, dev); |
| 381 | |||
| 382 | /* mute card - prevents noisy bootups */ | ||
| 383 | typhoon_mute(dev); | ||
| 384 | |||
| 381 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 385 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 382 | v4l2_device_unregister(&dev->v4l2_dev); | 386 | v4l2_device_unregister(&dev->v4l2_dev); |
| 383 | release_region(dev->io, 8); | 387 | release_region(dev->io, 8); |
| 384 | return -EINVAL; | 388 | return -EINVAL; |
| 385 | } | 389 | } |
| 386 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); | 390 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); |
| 387 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq); | 391 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq); |
| 388 | dev->mutefreq <<= 4; | ||
| 389 | |||
| 390 | /* mute card - prevents noisy bootups */ | ||
| 391 | typhoon_mute(dev); | ||
| 392 | 392 | ||
| 393 | return 0; | 393 | return 0; |
| 394 | } | 394 | } |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index f31eab99c943..af99c5bd88c1 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
| @@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 377 | static const struct v4l2_file_operations zoltrix_fops = | 377 | static const struct v4l2_file_operations zoltrix_fops = |
| 378 | { | 378 | { |
| 379 | .owner = THIS_MODULE, | 379 | .owner = THIS_MODULE, |
| 380 | .ioctl = video_ioctl2, | 380 | .unlocked_ioctl = video_ioctl2, |
| 381 | }; | 381 | }; |
| 382 | 382 | ||
| 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { | 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { |
| @@ -424,20 +424,6 @@ static int __init zoltrix_init(void) | |||
| 424 | return res; | 424 | return res; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
| 428 | zol->vdev.v4l2_dev = v4l2_dev; | ||
| 429 | zol->vdev.fops = &zoltrix_fops; | ||
| 430 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
| 431 | zol->vdev.release = video_device_release_empty; | ||
| 432 | video_set_drvdata(&zol->vdev, zol); | ||
| 433 | |||
| 434 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 435 | v4l2_device_unregister(v4l2_dev); | ||
| 436 | release_region(zol->io, 2); | ||
| 437 | return -EINVAL; | ||
| 438 | } | ||
| 439 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
| 440 | |||
| 441 | mutex_init(&zol->lock); | 427 | mutex_init(&zol->lock); |
| 442 | 428 | ||
| 443 | /* mute card - prevents noisy bootups */ | 429 | /* mute card - prevents noisy bootups */ |
| @@ -452,6 +438,20 @@ static int __init zoltrix_init(void) | |||
| 452 | zol->curvol = 0; | 438 | zol->curvol = 0; |
| 453 | zol->stereo = 1; | 439 | zol->stereo = 1; |
| 454 | 440 | ||
| 441 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
| 442 | zol->vdev.v4l2_dev = v4l2_dev; | ||
| 443 | zol->vdev.fops = &zoltrix_fops; | ||
| 444 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
| 445 | zol->vdev.release = video_device_release_empty; | ||
| 446 | video_set_drvdata(&zol->vdev, zol); | ||
| 447 | |||
| 448 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 449 | v4l2_device_unregister(v4l2_dev); | ||
| 450 | release_region(zol->io, 2); | ||
| 451 | return -EINVAL; | ||
| 452 | } | ||
| 453 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
| 454 | |||
| 455 | return 0; | 455 | return 0; |
| 456 | } | 456 | } |
| 457 | 457 | ||
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 31e7a123d19a..f989f2820d88 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
| @@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar) | |||
| 712 | static const struct v4l2_file_operations ar_fops = { | 712 | static const struct v4l2_file_operations ar_fops = { |
| 713 | .owner = THIS_MODULE, | 713 | .owner = THIS_MODULE, |
| 714 | .read = ar_read, | 714 | .read = ar_read, |
| 715 | .ioctl = video_ioctl2, | 715 | .unlocked_ioctl = video_ioctl2, |
| 716 | }; | 716 | }; |
| 717 | 717 | ||
| 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { | 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { |
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 935e0c9a9674..c1193506131c 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
| @@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 860 | 860 | ||
| 861 | static const struct v4l2_file_operations qcam_fops = { | 861 | static const struct v4l2_file_operations qcam_fops = { |
| 862 | .owner = THIS_MODULE, | 862 | .owner = THIS_MODULE, |
| 863 | .ioctl = video_ioctl2, | 863 | .unlocked_ioctl = video_ioctl2, |
| 864 | .read = qcam_read, | 864 | .read = qcam_read, |
| 865 | }; | 865 | }; |
| 866 | 866 | ||
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 6e4b19698c13..24fc00965a12 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
| @@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 718 | 718 | ||
| 719 | static const struct v4l2_file_operations qcam_fops = { | 719 | static const struct v4l2_file_operations qcam_fops = { |
| 720 | .owner = THIS_MODULE, | 720 | .owner = THIS_MODULE, |
| 721 | .ioctl = video_ioctl2, | 721 | .unlocked_ioctl = video_ioctl2, |
| 722 | .read = qcam_read, | 722 | .read = qcam_read, |
| 723 | }; | 723 | }; |
| 724 | 724 | ||
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 260c666ce931..0dfff50891e4 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
| @@ -1775,7 +1775,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = { | |||
| 1775 | .read = cafe_v4l_read, | 1775 | .read = cafe_v4l_read, |
| 1776 | .poll = cafe_v4l_poll, | 1776 | .poll = cafe_v4l_poll, |
| 1777 | .mmap = cafe_v4l_mmap, | 1777 | .mmap = cafe_v4l_mmap, |
| 1778 | .ioctl = video_ioctl2, | 1778 | .unlocked_ioctl = video_ioctl2, |
| 1779 | }; | 1779 | }; |
| 1780 | 1780 | ||
| 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { |
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c index 8f55692db36d..82d195be9197 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.c +++ b/drivers/media/video/cx18/cx18-alsa-pcm.c | |||
| @@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) | |||
| 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, | 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, |
| 219 | unsigned int cmd, void *arg) | 219 | unsigned int cmd, void *arg) |
| 220 | { | 220 | { |
| 221 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 221 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
| 222 | int ret; | ||
| 223 | |||
| 224 | snd_cx18_lock(cxsc); | ||
| 225 | ret = snd_pcm_lib_ioctl(substream, cmd, arg); | ||
| 226 | snd_cx18_unlock(cxsc); | ||
| 227 | return ret; | ||
| 222 | } | 228 | } |
| 223 | 229 | ||
| 224 | 230 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 9045f1ece0eb..ab461e27d9dd 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
| @@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = { | |||
| 41 | .read = cx18_v4l2_read, | 41 | .read = cx18_v4l2_read, |
| 42 | .open = cx18_v4l2_open, | 42 | .open = cx18_v4l2_open, |
| 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ | 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ |
| 44 | .ioctl = cx18_v4l2_ioctl, | 44 | .unlocked_ioctl = cx18_v4l2_ioctl, |
| 45 | .release = cx18_v4l2_close, | 45 | .release = cx18_v4l2_close, |
| 46 | .poll = cx18_v4l2_enc_poll, | 46 | .poll = cx18_v4l2_enc_poll, |
| 47 | }; | 47 | }; |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index a5cfc76b40b7..bb164099ea2c 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
| @@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = { | |||
| 2530 | .owner = THIS_MODULE, | 2530 | .owner = THIS_MODULE, |
| 2531 | .open = et61x251_open, | 2531 | .open = et61x251_open, |
| 2532 | .release = et61x251_release, | 2532 | .release = et61x251_release, |
| 2533 | .ioctl = et61x251_ioctl, | 2533 | .unlocked_ioctl = et61x251_ioctl, |
| 2534 | .read = et61x251_read, | 2534 | .read = et61x251_read, |
| 2535 | .poll = et61x251_poll, | 2535 | .poll = et61x251_poll, |
| 2536 | .mmap = et61x251_mmap, | 2536 | .mmap = et61x251_mmap, |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 2be23bccd3c8..48d2c2419c13 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
| @@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = { | |||
| 1659 | .open = meye_open, | 1659 | .open = meye_open, |
| 1660 | .release = meye_release, | 1660 | .release = meye_release, |
| 1661 | .mmap = meye_mmap, | 1661 | .mmap = meye_mmap, |
| 1662 | .ioctl = video_ioctl2, | 1662 | .unlocked_ioctl = video_ioctl2, |
| 1663 | .poll = meye_poll, | 1663 | .poll = meye_poll, |
| 1664 | }; | 1664 | }; |
| 1665 | 1665 | ||
| @@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1831 | msleep(1); | 1831 | msleep(1); |
| 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); | 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); |
| 1833 | 1833 | ||
| 1834 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
| 1835 | video_nr) < 0) { | ||
| 1836 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
| 1837 | goto outvideoreg; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | mutex_init(&meye.lock); | 1834 | mutex_init(&meye.lock); |
| 1841 | init_waitqueue_head(&meye.proc_list); | 1835 | init_waitqueue_head(&meye.proc_list); |
| 1842 | meye.brightness = 32 << 10; | 1836 | meye.brightness = 32 << 10; |
| @@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1858 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); | 1852 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); |
| 1859 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); | 1853 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); |
| 1860 | 1854 | ||
| 1855 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
| 1856 | video_nr) < 0) { | ||
| 1857 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
| 1858 | goto outvideoreg; | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", | 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", |
| 1862 | MEYE_DRIVER_VERSION); | 1862 | MEYE_DRIVER_VERSION); |
| 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", | 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 7129b50757db..7551907f8c28 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
| @@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
| 932 | 932 | ||
| 933 | static const struct v4l2_file_operations pms_fops = { | 933 | static const struct v4l2_file_operations pms_fops = { |
| 934 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
| 935 | .ioctl = video_ioctl2, | 935 | .unlocked_ioctl = video_ioctl2, |
| 936 | .read = pms_read, | 936 | .read = pms_read, |
| 937 | }; | 937 | }; |
| 938 | 938 | ||
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 4e5a8cf76ded..07cf0c6c7c1f 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
| @@ -75,6 +75,7 @@ struct sh_vou_device { | |||
| 75 | int pix_idx; | 75 | int pix_idx; |
| 76 | struct videobuf_buffer *active; | 76 | struct videobuf_buffer *active; |
| 77 | enum sh_vou_status status; | 77 | enum sh_vou_status status; |
| 78 | struct mutex fop_lock; | ||
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | struct sh_vou_file { | 81 | struct sh_vou_file { |
| @@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
| 235 | vb->state = VIDEOBUF_NEEDS_INIT; | 236 | vb->state = VIDEOBUF_NEEDS_INIT; |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | /* Locking: caller holds vq->vb_lock mutex */ | 239 | /* Locking: caller holds fop_lock mutex */ |
| 239 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | 240 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, |
| 240 | unsigned int *size) | 241 | unsigned int *size) |
| 241 | { | 242 | { |
| @@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
| 257 | return 0; | 258 | return 0; |
| 258 | } | 259 | } |
| 259 | 260 | ||
| 260 | /* Locking: caller holds vq->vb_lock mutex */ | 261 | /* Locking: caller holds fop_lock mutex */ |
| 261 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, | 262 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, |
| 262 | struct videobuf_buffer *vb, | 263 | struct videobuf_buffer *vb, |
| 263 | enum v4l2_field field) | 264 | enum v4l2_field field) |
| @@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq, | |||
| 306 | return 0; | 307 | return 0; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | /* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */ | 310 | /* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */ |
| 310 | static void sh_vou_buf_queue(struct videobuf_queue *vq, | 311 | static void sh_vou_buf_queue(struct videobuf_queue *vq, |
| 311 | struct videobuf_buffer *vb) | 312 | struct videobuf_buffer *vb) |
| 312 | { | 313 | { |
| @@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file) | |||
| 1190 | V4L2_BUF_TYPE_VIDEO_OUTPUT, | 1191 | V4L2_BUF_TYPE_VIDEO_OUTPUT, |
| 1191 | V4L2_FIELD_NONE, | 1192 | V4L2_FIELD_NONE, |
| 1192 | sizeof(struct videobuf_buffer), vdev, | 1193 | sizeof(struct videobuf_buffer), vdev, |
| 1193 | NULL); | 1194 | &vou_dev->fop_lock); |
| 1194 | 1195 | ||
| 1195 | return 0; | 1196 | return 0; |
| 1196 | } | 1197 | } |
| @@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = { | |||
| 1292 | .owner = THIS_MODULE, | 1293 | .owner = THIS_MODULE, |
| 1293 | .open = sh_vou_open, | 1294 | .open = sh_vou_open, |
| 1294 | .release = sh_vou_release, | 1295 | .release = sh_vou_release, |
| 1295 | .ioctl = video_ioctl2, | 1296 | .unlocked_ioctl = video_ioctl2, |
| 1296 | .mmap = sh_vou_mmap, | 1297 | .mmap = sh_vou_mmap, |
| 1297 | .poll = sh_vou_poll, | 1298 | .poll = sh_vou_poll, |
| 1298 | }; | 1299 | }; |
| @@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
| 1331 | 1332 | ||
| 1332 | INIT_LIST_HEAD(&vou_dev->queue); | 1333 | INIT_LIST_HEAD(&vou_dev->queue); |
| 1333 | spin_lock_init(&vou_dev->lock); | 1334 | spin_lock_init(&vou_dev->lock); |
| 1335 | mutex_init(&vou_dev->fop_lock); | ||
| 1334 | atomic_set(&vou_dev->use_count, 0); | 1336 | atomic_set(&vou_dev->use_count, 0); |
| 1335 | vou_dev->pdata = vou_pdata; | 1337 | vou_dev->pdata = vou_pdata; |
| 1336 | vou_dev->status = SH_VOU_IDLE; | 1338 | vou_dev->status = SH_VOU_IDLE; |
| @@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
| 1388 | vdev->tvnorms |= V4L2_STD_PAL; | 1390 | vdev->tvnorms |= V4L2_STD_PAL; |
| 1389 | vdev->v4l2_dev = &vou_dev->v4l2_dev; | 1391 | vdev->v4l2_dev = &vou_dev->v4l2_dev; |
| 1390 | vdev->release = video_device_release; | 1392 | vdev->release = video_device_release; |
| 1393 | vdev->lock = &vou_dev->fop_lock; | ||
| 1391 | 1394 | ||
| 1392 | vou_dev->vdev = vdev; | 1395 | vou_dev->vdev = vdev; |
| 1393 | video_set_drvdata(vdev, vou_dev); | 1396 | video_set_drvdata(vdev, vou_dev); |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 28e19daadec9..f49fbfb7dc13 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
| @@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = { | |||
| 3238 | .owner = THIS_MODULE, | 3238 | .owner = THIS_MODULE, |
| 3239 | .open = sn9c102_open, | 3239 | .open = sn9c102_open, |
| 3240 | .release = sn9c102_release, | 3240 | .release = sn9c102_release, |
| 3241 | .ioctl = sn9c102_ioctl, | 3241 | .unlocked_ioctl = sn9c102_ioctl, |
| 3242 | .read = sn9c102_read, | 3242 | .read = sn9c102_read, |
| 3243 | .poll = sn9c102_poll, | 3243 | .poll = sn9c102_poll, |
| 3244 | .mmap = sn9c102_mmap, | 3244 | .mmap = sn9c102_mmap, |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index f169f7736677..59f8a9ad3796 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
| @@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
| 785 | } | 785 | } |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | 788 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, |
| 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) | 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) |
| 790 | { | 790 | { |
| 791 | struct uvc_control *ctrl = NULL; | 791 | struct uvc_control *ctrl = NULL; |
| @@ -944,6 +944,52 @@ done: | |||
| 944 | return ret; | 944 | return ret; |
| 945 | } | 945 | } |
| 946 | 946 | ||
| 947 | /* | ||
| 948 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
| 949 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
| 950 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
| 951 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
| 952 | * otherwise translated. The approach we take here is to use a translation | ||
| 953 | * table for the controls that can be mapped directly, and handle the others | ||
| 954 | * manually. | ||
| 955 | */ | ||
| 956 | int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
| 957 | struct v4l2_querymenu *query_menu) | ||
| 958 | { | ||
| 959 | struct uvc_menu_info *menu_info; | ||
| 960 | struct uvc_control_mapping *mapping; | ||
| 961 | struct uvc_control *ctrl; | ||
| 962 | u32 index = query_menu->index; | ||
| 963 | u32 id = query_menu->id; | ||
| 964 | int ret; | ||
| 965 | |||
| 966 | memset(query_menu, 0, sizeof(*query_menu)); | ||
| 967 | query_menu->id = id; | ||
| 968 | query_menu->index = index; | ||
| 969 | |||
| 970 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
| 971 | if (ret < 0) | ||
| 972 | return -ERESTARTSYS; | ||
| 973 | |||
| 974 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
| 975 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { | ||
| 976 | ret = -EINVAL; | ||
| 977 | goto done; | ||
| 978 | } | ||
| 979 | |||
| 980 | if (query_menu->index >= mapping->menu_count) { | ||
| 981 | ret = -EINVAL; | ||
| 982 | goto done; | ||
| 983 | } | ||
| 984 | |||
| 985 | menu_info = &mapping->menu_info[query_menu->index]; | ||
| 986 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
| 987 | |||
| 988 | done: | ||
| 989 | mutex_unlock(&chain->ctrl_mutex); | ||
| 990 | return ret; | ||
| 991 | } | ||
| 992 | |||
| 947 | 993 | ||
| 948 | /* -------------------------------------------------------------------------- | 994 | /* -------------------------------------------------------------------------- |
| 949 | * Control transactions | 995 | * Control transactions |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index ed6d5449741c..f14581bd707f 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
| @@ -90,6 +90,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* | 92 | /* |
| 93 | * Free the video buffers. | ||
| 94 | * | ||
| 95 | * This function must be called with the queue lock held. | ||
| 96 | */ | ||
| 97 | static int __uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 98 | { | ||
| 99 | unsigned int i; | ||
| 100 | |||
| 101 | for (i = 0; i < queue->count; ++i) { | ||
| 102 | if (queue->buffer[i].vma_use_count != 0) | ||
| 103 | return -EBUSY; | ||
| 104 | } | ||
| 105 | |||
| 106 | if (queue->count) { | ||
| 107 | vfree(queue->mem); | ||
| 108 | queue->count = 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 115 | { | ||
| 116 | int ret; | ||
| 117 | |||
| 118 | mutex_lock(&queue->mutex); | ||
| 119 | ret = __uvc_free_buffers(queue); | ||
| 120 | mutex_unlock(&queue->mutex); | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | /* | ||
| 93 | * Allocate the video buffers. | 126 | * Allocate the video buffers. |
| 94 | * | 127 | * |
| 95 | * Pages are reserved to make sure they will not be swapped, as they will be | 128 | * Pages are reserved to make sure they will not be swapped, as they will be |
| @@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | |||
| 110 | 143 | ||
| 111 | mutex_lock(&queue->mutex); | 144 | mutex_lock(&queue->mutex); |
| 112 | 145 | ||
| 113 | if ((ret = uvc_free_buffers(queue)) < 0) | 146 | if ((ret = __uvc_free_buffers(queue)) < 0) |
| 114 | goto done; | 147 | goto done; |
| 115 | 148 | ||
| 116 | /* Bail out if no buffers should be allocated. */ | 149 | /* Bail out if no buffers should be allocated. */ |
| @@ -152,28 +185,6 @@ done: | |||
| 152 | } | 185 | } |
| 153 | 186 | ||
| 154 | /* | 187 | /* |
| 155 | * Free the video buffers. | ||
| 156 | * | ||
| 157 | * This function must be called with the queue lock held. | ||
| 158 | */ | ||
| 159 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 160 | { | ||
| 161 | unsigned int i; | ||
| 162 | |||
| 163 | for (i = 0; i < queue->count; ++i) { | ||
| 164 | if (queue->buffer[i].vma_use_count != 0) | ||
| 165 | return -EBUSY; | ||
| 166 | } | ||
| 167 | |||
| 168 | if (queue->count) { | ||
| 169 | vfree(queue->mem); | ||
| 170 | queue->count = 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | /* | ||
| 177 | * Check if buffers have been allocated. | 188 | * Check if buffers have been allocated. |
| 178 | */ | 189 | */ |
| 179 | int uvc_queue_allocated(struct uvc_video_queue *queue) | 190 | int uvc_queue_allocated(struct uvc_video_queue *queue) |
| @@ -369,6 +380,82 @@ done: | |||
| 369 | } | 380 | } |
| 370 | 381 | ||
| 371 | /* | 382 | /* |
| 383 | * VMA operations. | ||
| 384 | */ | ||
| 385 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
| 386 | { | ||
| 387 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 388 | buffer->vma_use_count++; | ||
| 389 | } | ||
| 390 | |||
| 391 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
| 392 | { | ||
| 393 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 394 | buffer->vma_use_count--; | ||
| 395 | } | ||
| 396 | |||
| 397 | static const struct vm_operations_struct uvc_vm_ops = { | ||
| 398 | .open = uvc_vm_open, | ||
| 399 | .close = uvc_vm_close, | ||
| 400 | }; | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Memory-map a video buffer. | ||
| 404 | * | ||
| 405 | * This function implements video buffers memory mapping and is intended to be | ||
| 406 | * used by the device mmap handler. | ||
| 407 | */ | ||
| 408 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | ||
| 409 | { | ||
| 410 | struct uvc_buffer *uninitialized_var(buffer); | ||
| 411 | struct page *page; | ||
| 412 | unsigned long addr, start, size; | ||
| 413 | unsigned int i; | ||
| 414 | int ret = 0; | ||
| 415 | |||
| 416 | start = vma->vm_start; | ||
| 417 | size = vma->vm_end - vma->vm_start; | ||
| 418 | |||
| 419 | mutex_lock(&queue->mutex); | ||
| 420 | |||
| 421 | for (i = 0; i < queue->count; ++i) { | ||
| 422 | buffer = &queue->buffer[i]; | ||
| 423 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (i == queue->count || size != queue->buf_size) { | ||
| 428 | ret = -EINVAL; | ||
| 429 | goto done; | ||
| 430 | } | ||
| 431 | |||
| 432 | /* | ||
| 433 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
| 434 | * device. It also prevents the region from being core dumped. | ||
| 435 | */ | ||
| 436 | vma->vm_flags |= VM_IO; | ||
| 437 | |||
| 438 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
| 439 | while (size > 0) { | ||
| 440 | page = vmalloc_to_page((void *)addr); | ||
| 441 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
| 442 | goto done; | ||
| 443 | |||
| 444 | start += PAGE_SIZE; | ||
| 445 | addr += PAGE_SIZE; | ||
| 446 | size -= PAGE_SIZE; | ||
| 447 | } | ||
| 448 | |||
| 449 | vma->vm_ops = &uvc_vm_ops; | ||
| 450 | vma->vm_private_data = buffer; | ||
| 451 | uvc_vm_open(vma); | ||
| 452 | |||
| 453 | done: | ||
| 454 | mutex_unlock(&queue->mutex); | ||
| 455 | return ret; | ||
| 456 | } | ||
| 457 | |||
| 458 | /* | ||
| 372 | * Poll the video queue. | 459 | * Poll the video queue. |
| 373 | * | 460 | * |
| 374 | * This function implements video queue polling and is intended to be used by | 461 | * This function implements video queue polling and is intended to be used by |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 6d15de9b5204..8cf61e8a634f 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
| @@ -101,40 +101,6 @@ done: | |||
| 101 | */ | 101 | */ |
| 102 | 102 | ||
| 103 | /* | 103 | /* |
| 104 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
| 105 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
| 106 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
| 107 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
| 108 | * otherwise translated. The approach we take here is to use a translation | ||
| 109 | * table for the controls that can be mapped directly, and handle the others | ||
| 110 | * manually. | ||
| 111 | */ | ||
| 112 | static int uvc_v4l2_query_menu(struct uvc_video_chain *chain, | ||
| 113 | struct v4l2_querymenu *query_menu) | ||
| 114 | { | ||
| 115 | struct uvc_menu_info *menu_info; | ||
| 116 | struct uvc_control_mapping *mapping; | ||
| 117 | struct uvc_control *ctrl; | ||
| 118 | u32 index = query_menu->index; | ||
| 119 | u32 id = query_menu->id; | ||
| 120 | |||
| 121 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
| 122 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) | ||
| 123 | return -EINVAL; | ||
| 124 | |||
| 125 | if (query_menu->index >= mapping->menu_count) | ||
| 126 | return -EINVAL; | ||
| 127 | |||
| 128 | memset(query_menu, 0, sizeof(*query_menu)); | ||
| 129 | query_menu->id = id; | ||
| 130 | query_menu->index = index; | ||
| 131 | |||
| 132 | menu_info = &mapping->menu_info[query_menu->index]; | ||
| 133 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Find the frame interval closest to the requested frame interval for the | 104 | * Find the frame interval closest to the requested frame interval for the |
| 139 | * given frame format and size. This should be done by the device as part of | 105 | * given frame format and size. This should be done by the device as part of |
| 140 | * the Video Probe and Commit negotiation, but some hardware don't implement | 106 | * the Video Probe and Commit negotiation, but some hardware don't implement |
| @@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
| 260 | * developers test their webcams with the Linux driver as well as with | 226 | * developers test their webcams with the Linux driver as well as with |
| 261 | * the Windows driver). | 227 | * the Windows driver). |
| 262 | */ | 228 | */ |
| 229 | mutex_lock(&stream->mutex); | ||
| 263 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) | 230 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) |
| 264 | probe->dwMaxVideoFrameSize = | 231 | probe->dwMaxVideoFrameSize = |
| 265 | stream->ctrl.dwMaxVideoFrameSize; | 232 | stream->ctrl.dwMaxVideoFrameSize; |
| 266 | 233 | ||
| 267 | /* Probe the device. */ | 234 | /* Probe the device. */ |
| 268 | ret = uvc_probe_video(stream, probe); | 235 | ret = uvc_probe_video(stream, probe); |
| 236 | mutex_unlock(&stream->mutex); | ||
| 269 | if (ret < 0) | 237 | if (ret < 0) |
| 270 | goto done; | 238 | goto done; |
| 271 | 239 | ||
| @@ -289,14 +257,21 @@ done: | |||
| 289 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, | 257 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, |
| 290 | struct v4l2_format *fmt) | 258 | struct v4l2_format *fmt) |
| 291 | { | 259 | { |
| 292 | struct uvc_format *format = stream->cur_format; | 260 | struct uvc_format *format; |
| 293 | struct uvc_frame *frame = stream->cur_frame; | 261 | struct uvc_frame *frame; |
| 262 | int ret = 0; | ||
| 294 | 263 | ||
| 295 | if (fmt->type != stream->type) | 264 | if (fmt->type != stream->type) |
| 296 | return -EINVAL; | 265 | return -EINVAL; |
| 297 | 266 | ||
| 298 | if (format == NULL || frame == NULL) | 267 | mutex_lock(&stream->mutex); |
| 299 | return -EINVAL; | 268 | format = stream->cur_format; |
| 269 | frame = stream->cur_frame; | ||
| 270 | |||
| 271 | if (format == NULL || frame == NULL) { | ||
| 272 | ret = -EINVAL; | ||
| 273 | goto done; | ||
| 274 | } | ||
| 300 | 275 | ||
| 301 | fmt->fmt.pix.pixelformat = format->fcc; | 276 | fmt->fmt.pix.pixelformat = format->fcc; |
| 302 | fmt->fmt.pix.width = frame->wWidth; | 277 | fmt->fmt.pix.width = frame->wWidth; |
| @@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream, | |||
| 307 | fmt->fmt.pix.colorspace = format->colorspace; | 282 | fmt->fmt.pix.colorspace = format->colorspace; |
| 308 | fmt->fmt.pix.priv = 0; | 283 | fmt->fmt.pix.priv = 0; |
| 309 | 284 | ||
| 310 | return 0; | 285 | done: |
| 286 | mutex_unlock(&stream->mutex); | ||
| 287 | return ret; | ||
| 311 | } | 288 | } |
| 312 | 289 | ||
| 313 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, | 290 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, |
| @@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, | |||
| 321 | if (fmt->type != stream->type) | 298 | if (fmt->type != stream->type) |
| 322 | return -EINVAL; | 299 | return -EINVAL; |
| 323 | 300 | ||
| 324 | if (uvc_queue_allocated(&stream->queue)) | ||
| 325 | return -EBUSY; | ||
| 326 | |||
| 327 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); | 301 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); |
| 328 | if (ret < 0) | 302 | if (ret < 0) |
| 329 | return ret; | 303 | return ret; |
| 330 | 304 | ||
| 305 | mutex_lock(&stream->mutex); | ||
| 306 | |||
| 307 | if (uvc_queue_allocated(&stream->queue)) { | ||
| 308 | ret = -EBUSY; | ||
| 309 | goto done; | ||
| 310 | } | ||
| 311 | |||
| 331 | memcpy(&stream->ctrl, &probe, sizeof probe); | 312 | memcpy(&stream->ctrl, &probe, sizeof probe); |
| 332 | stream->cur_format = format; | 313 | stream->cur_format = format; |
| 333 | stream->cur_frame = frame; | 314 | stream->cur_frame = frame; |
| 334 | 315 | ||
| 335 | return 0; | 316 | done: |
| 317 | mutex_unlock(&stream->mutex); | ||
| 318 | return ret; | ||
| 336 | } | 319 | } |
| 337 | 320 | ||
| 338 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | 321 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, |
| @@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
| 343 | if (parm->type != stream->type) | 326 | if (parm->type != stream->type) |
| 344 | return -EINVAL; | 327 | return -EINVAL; |
| 345 | 328 | ||
| 329 | mutex_lock(&stream->mutex); | ||
| 346 | numerator = stream->ctrl.dwFrameInterval; | 330 | numerator = stream->ctrl.dwFrameInterval; |
| 331 | mutex_unlock(&stream->mutex); | ||
| 332 | |||
| 347 | denominator = 10000000; | 333 | denominator = 10000000; |
| 348 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 334 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
| 349 | 335 | ||
| @@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
| 370 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | 356 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, |
| 371 | struct v4l2_streamparm *parm) | 357 | struct v4l2_streamparm *parm) |
| 372 | { | 358 | { |
| 373 | struct uvc_frame *frame = stream->cur_frame; | ||
| 374 | struct uvc_streaming_control probe; | 359 | struct uvc_streaming_control probe; |
| 375 | struct v4l2_fract timeperframe; | 360 | struct v4l2_fract timeperframe; |
| 376 | uint32_t interval; | 361 | uint32_t interval; |
| @@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
| 379 | if (parm->type != stream->type) | 364 | if (parm->type != stream->type) |
| 380 | return -EINVAL; | 365 | return -EINVAL; |
| 381 | 366 | ||
| 382 | if (uvc_queue_streaming(&stream->queue)) | ||
| 383 | return -EBUSY; | ||
| 384 | |||
| 385 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 367 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 386 | timeperframe = parm->parm.capture.timeperframe; | 368 | timeperframe = parm->parm.capture.timeperframe; |
| 387 | else | 369 | else |
| 388 | timeperframe = parm->parm.output.timeperframe; | 370 | timeperframe = parm->parm.output.timeperframe; |
| 389 | 371 | ||
| 390 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
| 391 | interval = uvc_fraction_to_interval(timeperframe.numerator, | 372 | interval = uvc_fraction_to_interval(timeperframe.numerator, |
| 392 | timeperframe.denominator); | 373 | timeperframe.denominator); |
| 393 | |||
| 394 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", | 374 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", |
| 395 | timeperframe.numerator, timeperframe.denominator, interval); | 375 | timeperframe.numerator, timeperframe.denominator, interval); |
| 396 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); | 376 | |
| 377 | mutex_lock(&stream->mutex); | ||
| 378 | |||
| 379 | if (uvc_queue_streaming(&stream->queue)) { | ||
| 380 | mutex_unlock(&stream->mutex); | ||
| 381 | return -EBUSY; | ||
| 382 | } | ||
| 383 | |||
| 384 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
| 385 | probe.dwFrameInterval = | ||
| 386 | uvc_try_frame_interval(stream->cur_frame, interval); | ||
| 397 | 387 | ||
| 398 | /* Probe the device with the new settings. */ | 388 | /* Probe the device with the new settings. */ |
| 399 | ret = uvc_probe_video(stream, &probe); | 389 | ret = uvc_probe_video(stream, &probe); |
| 400 | if (ret < 0) | 390 | if (ret < 0) { |
| 391 | mutex_unlock(&stream->mutex); | ||
| 401 | return ret; | 392 | return ret; |
| 393 | } | ||
| 402 | 394 | ||
| 403 | memcpy(&stream->ctrl, &probe, sizeof probe); | 395 | memcpy(&stream->ctrl, &probe, sizeof probe); |
| 396 | mutex_unlock(&stream->mutex); | ||
| 404 | 397 | ||
| 405 | /* Return the actual frame period. */ | 398 | /* Return the actual frame period. */ |
| 406 | timeperframe.numerator = probe.dwFrameInterval; | 399 | timeperframe.numerator = probe.dwFrameInterval; |
| @@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file) | |||
| 528 | if (uvc_has_privileges(handle)) { | 521 | if (uvc_has_privileges(handle)) { |
| 529 | uvc_video_enable(stream, 0); | 522 | uvc_video_enable(stream, 0); |
| 530 | 523 | ||
| 531 | mutex_lock(&stream->queue.mutex); | ||
| 532 | if (uvc_free_buffers(&stream->queue) < 0) | 524 | if (uvc_free_buffers(&stream->queue) < 0) |
| 533 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | 525 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " |
| 534 | "free buffers.\n"); | 526 | "free buffers.\n"); |
| 535 | mutex_unlock(&stream->queue.mutex); | ||
| 536 | } | 527 | } |
| 537 | 528 | ||
| 538 | /* Release the file handle. */ | 529 | /* Release the file handle. */ |
| @@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 624 | } | 615 | } |
| 625 | 616 | ||
| 626 | case VIDIOC_QUERYMENU: | 617 | case VIDIOC_QUERYMENU: |
| 627 | return uvc_v4l2_query_menu(chain, arg); | 618 | return uvc_query_v4l2_menu(chain, arg); |
| 628 | 619 | ||
| 629 | case VIDIOC_G_EXT_CTRLS: | 620 | case VIDIOC_G_EXT_CTRLS: |
| 630 | { | 621 | { |
| @@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 905 | case VIDIOC_CROPCAP: | 896 | case VIDIOC_CROPCAP: |
| 906 | { | 897 | { |
| 907 | struct v4l2_cropcap *ccap = arg; | 898 | struct v4l2_cropcap *ccap = arg; |
| 908 | struct uvc_frame *frame = stream->cur_frame; | ||
| 909 | 899 | ||
| 910 | if (ccap->type != stream->type) | 900 | if (ccap->type != stream->type) |
| 911 | return -EINVAL; | 901 | return -EINVAL; |
| 912 | 902 | ||
| 913 | ccap->bounds.left = 0; | 903 | ccap->bounds.left = 0; |
| 914 | ccap->bounds.top = 0; | 904 | ccap->bounds.top = 0; |
| 915 | ccap->bounds.width = frame->wWidth; | 905 | |
| 916 | ccap->bounds.height = frame->wHeight; | 906 | mutex_lock(&stream->mutex); |
| 907 | ccap->bounds.width = stream->cur_frame->wWidth; | ||
| 908 | ccap->bounds.height = stream->cur_frame->wHeight; | ||
| 909 | mutex_unlock(&stream->mutex); | ||
| 917 | 910 | ||
| 918 | ccap->defrect = ccap->bounds; | 911 | ccap->defrect = ccap->bounds; |
| 919 | 912 | ||
| @@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 930 | case VIDIOC_REQBUFS: | 923 | case VIDIOC_REQBUFS: |
| 931 | { | 924 | { |
| 932 | struct v4l2_requestbuffers *rb = arg; | 925 | struct v4l2_requestbuffers *rb = arg; |
| 933 | unsigned int bufsize = | ||
| 934 | stream->ctrl.dwMaxVideoFrameSize; | ||
| 935 | 926 | ||
| 936 | if (rb->type != stream->type || | 927 | if (rb->type != stream->type || |
| 937 | rb->memory != V4L2_MEMORY_MMAP) | 928 | rb->memory != V4L2_MEMORY_MMAP) |
| @@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 940 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 931 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
| 941 | return ret; | 932 | return ret; |
| 942 | 933 | ||
| 943 | ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize); | 934 | mutex_lock(&stream->mutex); |
| 935 | ret = uvc_alloc_buffers(&stream->queue, rb->count, | ||
| 936 | stream->ctrl.dwMaxVideoFrameSize); | ||
| 937 | mutex_unlock(&stream->mutex); | ||
| 944 | if (ret < 0) | 938 | if (ret < 0) |
| 945 | return ret; | 939 | return ret; |
| 946 | 940 | ||
| @@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 988 | if (!uvc_has_privileges(handle)) | 982 | if (!uvc_has_privileges(handle)) |
| 989 | return -EBUSY; | 983 | return -EBUSY; |
| 990 | 984 | ||
| 985 | mutex_lock(&stream->mutex); | ||
| 991 | ret = uvc_video_enable(stream, 1); | 986 | ret = uvc_video_enable(stream, 1); |
| 987 | mutex_unlock(&stream->mutex); | ||
| 992 | if (ret < 0) | 988 | if (ret < 0) |
| 993 | return ret; | 989 | return ret; |
| 994 | break; | 990 | break; |
| @@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data, | |||
| 1068 | return -EINVAL; | 1064 | return -EINVAL; |
| 1069 | } | 1065 | } |
| 1070 | 1066 | ||
| 1071 | /* | ||
| 1072 | * VMA operations. | ||
| 1073 | */ | ||
| 1074 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
| 1075 | { | ||
| 1076 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 1077 | buffer->vma_use_count++; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
| 1081 | { | ||
| 1082 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 1083 | buffer->vma_use_count--; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | static const struct vm_operations_struct uvc_vm_ops = { | ||
| 1087 | .open = uvc_vm_open, | ||
| 1088 | .close = uvc_vm_close, | ||
| 1089 | }; | ||
| 1090 | |||
| 1091 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 1067 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
| 1092 | { | 1068 | { |
| 1093 | struct uvc_fh *handle = file->private_data; | 1069 | struct uvc_fh *handle = file->private_data; |
| 1094 | struct uvc_streaming *stream = handle->stream; | 1070 | struct uvc_streaming *stream = handle->stream; |
| 1095 | struct uvc_video_queue *queue = &stream->queue; | ||
| 1096 | struct uvc_buffer *uninitialized_var(buffer); | ||
| 1097 | struct page *page; | ||
| 1098 | unsigned long addr, start, size; | ||
| 1099 | unsigned int i; | ||
| 1100 | int ret = 0; | ||
| 1101 | 1071 | ||
| 1102 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); | 1072 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); |
| 1103 | 1073 | ||
| 1104 | start = vma->vm_start; | 1074 | return uvc_queue_mmap(&stream->queue, vma); |
| 1105 | size = vma->vm_end - vma->vm_start; | ||
| 1106 | |||
| 1107 | mutex_lock(&queue->mutex); | ||
| 1108 | |||
| 1109 | for (i = 0; i < queue->count; ++i) { | ||
| 1110 | buffer = &queue->buffer[i]; | ||
| 1111 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
| 1112 | break; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | if (i == queue->count || size != queue->buf_size) { | ||
| 1116 | ret = -EINVAL; | ||
| 1117 | goto done; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | /* | ||
| 1121 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
| 1122 | * device. It also prevents the region from being core dumped. | ||
| 1123 | */ | ||
| 1124 | vma->vm_flags |= VM_IO; | ||
| 1125 | |||
| 1126 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
| 1127 | while (size > 0) { | ||
| 1128 | page = vmalloc_to_page((void *)addr); | ||
| 1129 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
| 1130 | goto done; | ||
| 1131 | |||
| 1132 | start += PAGE_SIZE; | ||
| 1133 | addr += PAGE_SIZE; | ||
| 1134 | size -= PAGE_SIZE; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | vma->vm_ops = &uvc_vm_ops; | ||
| 1138 | vma->vm_private_data = buffer; | ||
| 1139 | uvc_vm_open(vma); | ||
| 1140 | |||
| 1141 | done: | ||
| 1142 | mutex_unlock(&queue->mutex); | ||
| 1143 | return ret; | ||
| 1144 | } | 1075 | } |
| 1145 | 1076 | ||
| 1146 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | 1077 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) |
| @@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = { | |||
| 1157 | .owner = THIS_MODULE, | 1088 | .owner = THIS_MODULE, |
| 1158 | .open = uvc_v4l2_open, | 1089 | .open = uvc_v4l2_open, |
| 1159 | .release = uvc_v4l2_release, | 1090 | .release = uvc_v4l2_release, |
| 1160 | .ioctl = uvc_v4l2_ioctl, | 1091 | .unlocked_ioctl = uvc_v4l2_ioctl, |
| 1161 | .read = uvc_v4l2_read, | 1092 | .read = uvc_v4l2_read, |
| 1162 | .mmap = uvc_v4l2_mmap, | 1093 | .mmap = uvc_v4l2_mmap, |
| 1163 | .poll = uvc_v4l2_poll, | 1094 | .poll = uvc_v4l2_poll, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 5555f0102838..5673d673504b 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
| @@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
| 293 | unsigned int i; | 293 | unsigned int i; |
| 294 | int ret; | 294 | int ret; |
| 295 | 295 | ||
| 296 | mutex_lock(&stream->mutex); | ||
| 297 | |||
| 298 | /* Perform probing. The device should adjust the requested values | 296 | /* Perform probing. The device should adjust the requested values |
| 299 | * according to its capabilities. However, some devices, namely the | 297 | * according to its capabilities. However, some devices, namely the |
| 300 | * first generation UVC Logitech webcams, don't implement the Video | 298 | * first generation UVC Logitech webcams, don't implement the Video |
| @@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
| 346 | } | 344 | } |
| 347 | 345 | ||
| 348 | done: | 346 | done: |
| 349 | mutex_unlock(&stream->mutex); | ||
| 350 | return ret; | 347 | return ret; |
| 351 | } | 348 | } |
| 352 | 349 | ||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index d97cf6d6a4f9..45f01e7e13d2 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
| @@ -436,7 +436,9 @@ struct uvc_streaming { | |||
| 436 | struct uvc_streaming_control ctrl; | 436 | struct uvc_streaming_control ctrl; |
| 437 | struct uvc_format *cur_format; | 437 | struct uvc_format *cur_format; |
| 438 | struct uvc_frame *cur_frame; | 438 | struct uvc_frame *cur_frame; |
| 439 | 439 | /* Protect access to ctrl, cur_format, cur_frame and hardware video | |
| 440 | * probe control. | ||
| 441 | */ | ||
| 440 | struct mutex mutex; | 442 | struct mutex mutex; |
| 441 | 443 | ||
| 442 | unsigned int frozen : 1; | 444 | unsigned int frozen : 1; |
| @@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); | |||
| 574 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); | 576 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); |
| 575 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | 577 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, |
| 576 | struct uvc_buffer *buf); | 578 | struct uvc_buffer *buf); |
| 579 | extern int uvc_queue_mmap(struct uvc_video_queue *queue, | ||
| 580 | struct vm_area_struct *vma); | ||
| 577 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, | 581 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, |
| 578 | struct file *file, poll_table *wait); | 582 | struct file *file, poll_table *wait); |
| 579 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 583 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); |
| @@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev); | |||
| 606 | extern int uvc_status_resume(struct uvc_device *dev); | 610 | extern int uvc_status_resume(struct uvc_device *dev); |
| 607 | 611 | ||
| 608 | /* Controls */ | 612 | /* Controls */ |
| 609 | extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | ||
| 610 | __u32 v4l2_id, struct uvc_control_mapping **mapping); | ||
| 611 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 613 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
| 612 | struct v4l2_queryctrl *v4l2_ctrl); | 614 | struct v4l2_queryctrl *v4l2_ctrl); |
| 615 | extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
| 616 | struct v4l2_querymenu *query_menu); | ||
| 613 | 617 | ||
| 614 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | 618 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
| 615 | const struct uvc_control_mapping *mapping); | 619 | const struct uvc_control_mapping *mapping); |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 03f7f4670e9b..359e23290a7e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
| @@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
| 186 | size_t sz, loff_t *off) | 186 | size_t sz, loff_t *off) |
| 187 | { | 187 | { |
| 188 | struct video_device *vdev = video_devdata(filp); | 188 | struct video_device *vdev = video_devdata(filp); |
| 189 | int ret = -EIO; | 189 | int ret = -ENODEV; |
| 190 | 190 | ||
| 191 | if (!vdev->fops->read) | 191 | if (!vdev->fops->read) |
| 192 | return -EINVAL; | 192 | return -EINVAL; |
| 193 | if (vdev->lock) | 193 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 194 | mutex_lock(vdev->lock); | 194 | return -ERESTARTSYS; |
| 195 | if (video_is_registered(vdev)) | 195 | if (video_is_registered(vdev)) |
| 196 | ret = vdev->fops->read(filp, buf, sz, off); | 196 | ret = vdev->fops->read(filp, buf, sz, off); |
| 197 | if (vdev->lock) | 197 | if (vdev->lock) |
| @@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 203 | size_t sz, loff_t *off) | 203 | size_t sz, loff_t *off) |
| 204 | { | 204 | { |
| 205 | struct video_device *vdev = video_devdata(filp); | 205 | struct video_device *vdev = video_devdata(filp); |
| 206 | int ret = -EIO; | 206 | int ret = -ENODEV; |
| 207 | 207 | ||
| 208 | if (!vdev->fops->write) | 208 | if (!vdev->fops->write) |
| 209 | return -EINVAL; | 209 | return -EINVAL; |
| 210 | if (vdev->lock) | 210 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 211 | mutex_lock(vdev->lock); | 211 | return -ERESTARTSYS; |
| 212 | if (video_is_registered(vdev)) | 212 | if (video_is_registered(vdev)) |
| 213 | ret = vdev->fops->write(filp, buf, sz, off); | 213 | ret = vdev->fops->write(filp, buf, sz, off); |
| 214 | if (vdev->lock) | 214 | if (vdev->lock) |
| @@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) |
| 220 | { | 220 | { |
| 221 | struct video_device *vdev = video_devdata(filp); | 221 | struct video_device *vdev = video_devdata(filp); |
| 222 | int ret = DEFAULT_POLLMASK; | 222 | int ret = POLLERR | POLLHUP; |
| 223 | 223 | ||
| 224 | if (!vdev->fops->poll) | 224 | if (!vdev->fops->poll) |
| 225 | return ret; | 225 | return DEFAULT_POLLMASK; |
| 226 | if (vdev->lock) | 226 | if (vdev->lock) |
| 227 | mutex_lock(vdev->lock); | 227 | mutex_lock(vdev->lock); |
| 228 | if (video_is_registered(vdev)) | 228 | if (video_is_registered(vdev)) |
| @@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 238 | int ret = -ENODEV; | 238 | int ret = -ENODEV; |
| 239 | 239 | ||
| 240 | if (vdev->fops->unlocked_ioctl) { | 240 | if (vdev->fops->unlocked_ioctl) { |
| 241 | if (vdev->lock) | 241 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 242 | mutex_lock(vdev->lock); | 242 | return -ERESTARTSYS; |
| 243 | if (video_is_registered(vdev)) | 243 | if (video_is_registered(vdev)) |
| 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
| 245 | if (vdev->lock) | 245 | if (vdev->lock) |
| 246 | mutex_unlock(vdev->lock); | 246 | mutex_unlock(vdev->lock); |
| 247 | } else if (vdev->fops->ioctl) { | 247 | } else if (vdev->fops->ioctl) { |
| 248 | /* TODO: convert all drivers to unlocked_ioctl */ | 248 | /* This code path is a replacement for the BKL. It is a major |
| 249 | * hack but it will have to do for those drivers that are not | ||
| 250 | * yet converted to use unlocked_ioctl. | ||
| 251 | * | ||
| 252 | * There are two options: if the driver implements struct | ||
| 253 | * v4l2_device, then the lock defined there is used to | ||
| 254 | * serialize the ioctls. Otherwise the v4l2 core lock defined | ||
| 255 | * below is used. This lock is really bad since it serializes | ||
| 256 | * completely independent devices. | ||
| 257 | * | ||
| 258 | * Both variants suffer from the same problem: if the driver | ||
| 259 | * sleeps, then it blocks all ioctls since the lock is still | ||
| 260 | * held. This is very common for VIDIOC_DQBUF since that | ||
| 261 | * normally waits for a frame to arrive. As a result any other | ||
| 262 | * ioctl calls will proceed very, very slowly since each call | ||
| 263 | * will have to wait for the VIDIOC_QBUF to finish. Things that | ||
| 264 | * should take 0.01s may now take 10-20 seconds. | ||
| 265 | * | ||
| 266 | * The workaround is to *not* take the lock for VIDIOC_DQBUF. | ||
| 267 | * This actually works OK for videobuf-based drivers, since | ||
| 268 | * videobuf will take its own internal lock. | ||
| 269 | */ | ||
| 249 | static DEFINE_MUTEX(v4l2_ioctl_mutex); | 270 | static DEFINE_MUTEX(v4l2_ioctl_mutex); |
| 271 | struct mutex *m = vdev->v4l2_dev ? | ||
| 272 | &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex; | ||
| 250 | 273 | ||
| 251 | mutex_lock(&v4l2_ioctl_mutex); | 274 | if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) |
| 275 | return -ERESTARTSYS; | ||
| 252 | if (video_is_registered(vdev)) | 276 | if (video_is_registered(vdev)) |
| 253 | ret = vdev->fops->ioctl(filp, cmd, arg); | 277 | ret = vdev->fops->ioctl(filp, cmd, arg); |
| 254 | mutex_unlock(&v4l2_ioctl_mutex); | 278 | if (cmd != VIDIOC_DQBUF) |
| 279 | mutex_unlock(m); | ||
| 255 | } else | 280 | } else |
| 256 | ret = -ENOTTY; | 281 | ret = -ENOTTY; |
| 257 | 282 | ||
| @@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
| 265 | 290 | ||
| 266 | if (!vdev->fops->mmap) | 291 | if (!vdev->fops->mmap) |
| 267 | return ret; | 292 | return ret; |
| 268 | if (vdev->lock) | 293 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 269 | mutex_lock(vdev->lock); | 294 | return -ERESTARTSYS; |
| 270 | if (video_is_registered(vdev)) | 295 | if (video_is_registered(vdev)) |
| 271 | ret = vdev->fops->mmap(filp, vm); | 296 | ret = vdev->fops->mmap(filp, vm); |
| 272 | if (vdev->lock) | 297 | if (vdev->lock) |
| @@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 284 | mutex_lock(&videodev_lock); | 309 | mutex_lock(&videodev_lock); |
| 285 | vdev = video_devdata(filp); | 310 | vdev = video_devdata(filp); |
| 286 | /* return ENODEV if the video device has already been removed. */ | 311 | /* return ENODEV if the video device has already been removed. */ |
| 287 | if (vdev == NULL) { | 312 | if (vdev == NULL || !video_is_registered(vdev)) { |
| 288 | mutex_unlock(&videodev_lock); | 313 | mutex_unlock(&videodev_lock); |
| 289 | return -ENODEV; | 314 | return -ENODEV; |
| 290 | } | 315 | } |
| @@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 292 | video_get(vdev); | 317 | video_get(vdev); |
| 293 | mutex_unlock(&videodev_lock); | 318 | mutex_unlock(&videodev_lock); |
| 294 | if (vdev->fops->open) { | 319 | if (vdev->fops->open) { |
| 295 | if (vdev->lock) | 320 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { |
| 296 | mutex_lock(vdev->lock); | 321 | ret = -ERESTARTSYS; |
| 322 | goto err; | ||
| 323 | } | ||
| 297 | if (video_is_registered(vdev)) | 324 | if (video_is_registered(vdev)) |
| 298 | ret = vdev->fops->open(filp); | 325 | ret = vdev->fops->open(filp); |
| 299 | else | 326 | else |
| @@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 302 | mutex_unlock(vdev->lock); | 329 | mutex_unlock(vdev->lock); |
| 303 | } | 330 | } |
| 304 | 331 | ||
| 332 | err: | ||
| 305 | /* decrease the refcount in case of an error */ | 333 | /* decrease the refcount in case of an error */ |
| 306 | if (ret) | 334 | if (ret) |
| 307 | video_put(vdev); | 335 | video_put(vdev); |
| @@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev) | |||
| 596 | if (!vdev || !video_is_registered(vdev)) | 624 | if (!vdev || !video_is_registered(vdev)) |
| 597 | return; | 625 | return; |
| 598 | 626 | ||
| 627 | mutex_lock(&videodev_lock); | ||
| 628 | /* This must be in a critical section to prevent a race with v4l2_open. | ||
| 629 | * Once this bit has been cleared video_get may never be called again. | ||
| 630 | */ | ||
| 599 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); | 631 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); |
| 632 | mutex_unlock(&videodev_lock); | ||
| 600 | device_unregister(&vdev->dev); | 633 | device_unregister(&vdev->dev); |
| 601 | } | 634 | } |
| 602 | EXPORT_SYMBOL(video_unregister_device); | 635 | EXPORT_SYMBOL(video_unregister_device); |
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 0b08f96b74a5..7fe6f92af480 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
| @@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
| 35 | 35 | ||
| 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); | 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); |
| 37 | spin_lock_init(&v4l2_dev->lock); | 37 | spin_lock_init(&v4l2_dev->lock); |
| 38 | mutex_init(&v4l2_dev->ioctl_lock); | ||
| 38 | v4l2_dev->dev = dev; | 39 | v4l2_dev->dev = dev; |
| 39 | if (dev == NULL) { | 40 | if (dev == NULL) { |
| 40 | /* If dev == NULL, then name must be filled in by the caller */ | 41 | /* If dev == NULL, then name must be filled in by the caller */ |
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 635420d8d84a..019ee206cbee 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
| @@ -815,7 +815,7 @@ out: | |||
| 815 | 815 | ||
| 816 | static const struct v4l2_file_operations w9966_fops = { | 816 | static const struct v4l2_file_operations w9966_fops = { |
| 817 | .owner = THIS_MODULE, | 817 | .owner = THIS_MODULE, |
| 818 | .ioctl = video_ioctl2, | 818 | .unlocked_ioctl = video_ioctl2, |
| 819 | .read = w9966_v4l_read, | 819 | .read = w9966_v4l_read, |
| 820 | }; | 820 | }; |
| 821 | 821 | ||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 003170ea2e39..69546e9213dd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static bool pci_bus_resource_better(struct resource *res1, bool pos1, | ||
| 68 | struct resource *res2, bool pos2) | ||
| 69 | { | ||
| 70 | /* If exactly one is positive decode, always prefer that one */ | ||
| 71 | if (pos1 != pos2) | ||
| 72 | return pos1 ? true : false; | ||
| 73 | |||
| 74 | /* Prefer the one that contains the highest address */ | ||
| 75 | if (res1->end != res2->end) | ||
| 76 | return (res1->end > res2->end) ? true : false; | ||
| 77 | |||
| 78 | /* Otherwise, prefer the one with highest "center of gravity" */ | ||
| 79 | if (res1->start != res2->start) | ||
| 80 | return (res1->start > res2->start) ? true : false; | ||
| 81 | |||
| 82 | /* Otherwise, choose one arbitrarily (but consistently) */ | ||
| 83 | return (res1 > res2) ? true : false; | ||
| 84 | } | ||
| 85 | |||
| 86 | static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res) | ||
| 87 | { | ||
| 88 | struct pci_bus_resource *bus_res; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * This relies on the fact that pci_bus.resource[] refers to P2P or | ||
| 92 | * CardBus bridge base/limit registers, which are always positively | ||
| 93 | * decoded. The pci_bus.resources list contains host bridge or | ||
| 94 | * subtractively decoded resources. | ||
| 95 | */ | ||
| 96 | list_for_each_entry(bus_res, &bus->resources, list) { | ||
| 97 | if (bus_res->res == res) | ||
| 98 | return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ? | ||
| 99 | false : true; | ||
| 100 | } | ||
| 101 | return true; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Find the next-best bus resource after the cursor "res". If the cursor is | ||
| 106 | * NULL, return the best resource. "Best" means that we prefer positive | ||
| 107 | * decode regions over subtractive decode, then those at higher addresses. | ||
| 108 | */ | ||
| 109 | static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, | ||
| 110 | unsigned int type, | ||
| 111 | struct resource *res) | ||
| 112 | { | ||
| 113 | bool res_pos, r_pos, prev_pos = false; | ||
| 114 | struct resource *r, *prev = NULL; | ||
| 115 | int i; | ||
| 116 | |||
| 117 | res_pos = pci_bus_resource_positive(bus, res); | ||
| 118 | pci_bus_for_each_resource(bus, r, i) { | ||
| 119 | if (!r) | ||
| 120 | continue; | ||
| 121 | |||
| 122 | if ((r->flags & IORESOURCE_TYPE_BITS) != type) | ||
| 123 | continue; | ||
| 124 | |||
| 125 | r_pos = pci_bus_resource_positive(bus, r); | ||
| 126 | if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) { | ||
| 127 | if (!prev || pci_bus_resource_better(r, r_pos, | ||
| 128 | prev, prev_pos)) { | ||
| 129 | prev = r; | ||
| 130 | prev_pos = r_pos; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | return prev; | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | 67 | /** |
| 139 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 68 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
| 140 | * @bus: PCI bus | 69 | * @bus: PCI bus |
| @@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 160 | resource_size_t), | 89 | resource_size_t), |
| 161 | void *alignf_data) | 90 | void *alignf_data) |
| 162 | { | 91 | { |
| 163 | int ret = -ENOMEM; | 92 | int i, ret = -ENOMEM; |
| 164 | struct resource *r; | 93 | struct resource *r; |
| 165 | resource_size_t max = -1; | 94 | resource_size_t max = -1; |
| 166 | unsigned int type = res->flags & IORESOURCE_TYPE_BITS; | ||
| 167 | 95 | ||
| 168 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 96 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
| 169 | 97 | ||
| @@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 171 | if (!(res->flags & IORESOURCE_MEM_64)) | 99 | if (!(res->flags & IORESOURCE_MEM_64)) |
| 172 | max = PCIBIOS_MAX_MEM_32; | 100 | max = PCIBIOS_MAX_MEM_32; |
| 173 | 101 | ||
| 174 | /* Look for space at highest addresses first */ | 102 | pci_bus_for_each_resource(bus, r, i) { |
| 175 | r = pci_bus_find_resource_prev(bus, type, NULL); | 103 | if (!r) |
| 176 | for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { | 104 | continue; |
| 105 | |||
| 177 | /* type_mask must match */ | 106 | /* type_mask must match */ |
| 178 | if ((res->flags ^ r->flags) & type_mask) | 107 | if ((res->flags ^ r->flags) & type_mask) |
| 179 | continue; | 108 | continue; |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 0157708d474d..09933eb9126b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
| @@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void) | |||
| 1417 | (unsigned long long)drhd->reg_base_addr, ret); | 1417 | (unsigned long long)drhd->reg_base_addr, ret); |
| 1418 | return -1; | 1418 | return -1; |
| 1419 | } | 1419 | } |
| 1420 | |||
| 1421 | /* | ||
| 1422 | * Clear any previous faults. | ||
| 1423 | */ | ||
| 1424 | dmar_fault(iommu->irq, iommu); | ||
| 1420 | } | 1425 | } |
| 1421 | 1426 | ||
| 1422 | return 0; | 1427 | return 0; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6f9350cabbd5..53a786fd0d40 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev) | |||
| 2329 | { | 2329 | { |
| 2330 | u32 cfg; | 2330 | u32 cfg; |
| 2331 | 2331 | ||
| 2332 | if (!pci_find_capability(dev, PCI_CAP_ID_HT)) | ||
| 2333 | return; | ||
| 2334 | |||
| 2332 | pci_read_config_dword(dev, 0x74, &cfg); | 2335 | pci_read_config_dword(dev, 0x74, &cfg); |
| 2333 | 2336 | ||
| 2334 | if (cfg & ((1 << 2) | (1 << 15))) { | 2337 | if (cfg & ((1 << 2) | (1 << 15))) { |
| @@ -2764,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m | |||
| 2764 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2767 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
| 2765 | #endif /*CONFIG_MMC_RICOH_MMC*/ | 2768 | #endif /*CONFIG_MMC_RICOH_MMC*/ |
| 2766 | 2769 | ||
| 2770 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) | ||
| 2771 | #define VTUNCERRMSK_REG 0x1ac | ||
| 2772 | #define VTD_MSK_SPEC_ERRORS (1 << 31) | ||
| 2773 | /* | ||
| 2774 | * This is a quirk for masking vt-d spec defined errors to platform error | ||
| 2775 | * handling logic. With out this, platforms using Intel 7500, 5500 chipsets | ||
| 2776 | * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based | ||
| 2777 | * on the RAS config settings of the platform) when a vt-d fault happens. | ||
| 2778 | * The resulting SMI caused the system to hang. | ||
| 2779 | * | ||
| 2780 | * VT-d spec related errors are already handled by the VT-d OS code, so no | ||
| 2781 | * need to report the same error through other channels. | ||
| 2782 | */ | ||
| 2783 | static void vtd_mask_spec_errors(struct pci_dev *dev) | ||
| 2784 | { | ||
| 2785 | u32 word; | ||
| 2786 | |||
| 2787 | pci_read_config_dword(dev, VTUNCERRMSK_REG, &word); | ||
| 2788 | pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS); | ||
| 2789 | } | ||
| 2790 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors); | ||
| 2791 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | ||
| 2792 | #endif | ||
| 2767 | 2793 | ||
| 2768 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2794 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
| 2769 | struct pci_fixup *end) | 2795 | struct pci_fixup *end) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 5b6bbaea59fe..4a3842212c50 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -1637,9 +1637,8 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, | |||
| 1637 | 1637 | ||
| 1638 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); | 1638 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); |
| 1639 | 1639 | ||
| 1640 | /* New queue, no concurrency on queue_flags */ | ||
| 1641 | if (!shost->use_clustering) | 1640 | if (!shost->use_clustering) |
| 1642 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); | 1641 | q->limits.cluster = 0; |
| 1643 | 1642 | ||
| 1644 | /* | 1643 | /* |
| 1645 | * set a reasonable default alignment on word boundaries: the | 1644 | * set a reasonable default alignment on word boundaries: the |
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index 455c6055325d..083c8fe53e24 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config FB_OMAP | 1 | config FB_OMAP |
| 2 | tristate "OMAP frame buffer support (EXPERIMENTAL)" | 2 | tristate "OMAP frame buffer support (EXPERIMENTAL)" |
| 3 | depends on FB && ARCH_OMAP && (OMAP2_DSS = "n") | 3 | depends on FB && (OMAP2_DSS = "n") |
| 4 | 4 | depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3 | |
| 5 | select FB_CFB_FILLRECT | 5 | select FB_CFB_FILLRECT |
| 6 | select FB_CFB_COPYAREA | 6 | select FB_CFB_COPYAREA |
| 7 | select FB_CFB_IMAGEBLIT | 7 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c index 2fd7e5271be9..9441e2eb3dee 100644 --- a/drivers/video/omap2/vram.c +++ b/drivers/video/omap2/vram.c | |||
| @@ -551,7 +551,7 @@ void __init omap_vram_reserve_sdram_memblock(void) | |||
| 551 | if (!size) | 551 | if (!size) |
| 552 | return; | 552 | return; |
| 553 | 553 | ||
| 554 | size = PAGE_ALIGN(size); | 554 | size = ALIGN(size, SZ_2M); |
| 555 | 555 | ||
| 556 | if (paddr) { | 556 | if (paddr) { |
| 557 | if (paddr & ~PAGE_MASK) { | 557 | if (paddr & ~PAGE_MASK) { |
| @@ -576,7 +576,7 @@ void __init omap_vram_reserve_sdram_memblock(void) | |||
| 576 | return; | 576 | return; |
| 577 | } | 577 | } |
| 578 | } else { | 578 | } else { |
| 579 | paddr = memblock_alloc(size, PAGE_SIZE); | 579 | paddr = memblock_alloc(size, SZ_2M); |
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | memblock_free(paddr, size); | 582 | memblock_free(paddr, size); |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 6f0444473594..659f532d26a0 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -166,7 +166,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | |||
| 166 | static struct dentry *btrfs_get_parent(struct dentry *child) | 166 | static struct dentry *btrfs_get_parent(struct dentry *child) |
| 167 | { | 167 | { |
| 168 | struct inode *dir = child->d_inode; | 168 | struct inode *dir = child->d_inode; |
| 169 | static struct dentry *dentry; | 169 | struct dentry *dentry; |
| 170 | struct btrfs_root *root = BTRFS_I(dir)->root; | 170 | struct btrfs_root *root = BTRFS_I(dir)->root; |
| 171 | struct btrfs_path *path; | 171 | struct btrfs_path *path; |
| 172 | struct extent_buffer *leaf; | 172 | struct extent_buffer *leaf; |
diff --git a/fs/namei.c b/fs/namei.c index 5362af9b7372..4ff7ca530533 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1748,6 +1748,9 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
| 1748 | if (!(open_flag & O_CREAT)) | 1748 | if (!(open_flag & O_CREAT)) |
| 1749 | mode = 0; | 1749 | mode = 0; |
| 1750 | 1750 | ||
| 1751 | /* Must never be set by userspace */ | ||
| 1752 | open_flag &= ~FMODE_NONOTIFY; | ||
| 1753 | |||
| 1751 | /* | 1754 | /* |
| 1752 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only | 1755 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only |
| 1753 | * check for O_DSYNC if the need any syncing at all we enforce it's | 1756 | * check for O_DSYNC if the need any syncing at all we enforce it's |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b04f88eed09e..f35794b97e8e 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
| @@ -92,7 +92,11 @@ static int fanotify_get_response_from_access(struct fsnotify_group *group, | |||
| 92 | 92 | ||
| 93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
| 94 | 94 | ||
| 95 | wait_event(group->fanotify_data.access_waitq, event->response); | 95 | wait_event(group->fanotify_data.access_waitq, event->response || |
| 96 | atomic_read(&group->fanotify_data.bypass_perm)); | ||
| 97 | |||
| 98 | if (!event->response) /* bypass_perm set */ | ||
| 99 | return 0; | ||
| 96 | 100 | ||
| 97 | /* userspace responded, convert to something usable */ | 101 | /* userspace responded, convert to something usable */ |
| 98 | spin_lock(&event->lock); | 102 | spin_lock(&event->lock); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 063224812b7e..8b61220cffc5 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
| @@ -106,20 +106,29 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) | |||
| 106 | return client_fd; | 106 | return client_fd; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static ssize_t fill_event_metadata(struct fsnotify_group *group, | 109 | static int fill_event_metadata(struct fsnotify_group *group, |
| 110 | struct fanotify_event_metadata *metadata, | 110 | struct fanotify_event_metadata *metadata, |
| 111 | struct fsnotify_event *event) | 111 | struct fsnotify_event *event) |
| 112 | { | 112 | { |
| 113 | int ret = 0; | ||
| 114 | |||
| 113 | pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, | 115 | pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, |
| 114 | group, metadata, event); | 116 | group, metadata, event); |
| 115 | 117 | ||
| 116 | metadata->event_len = FAN_EVENT_METADATA_LEN; | 118 | metadata->event_len = FAN_EVENT_METADATA_LEN; |
| 119 | metadata->metadata_len = FAN_EVENT_METADATA_LEN; | ||
| 117 | metadata->vers = FANOTIFY_METADATA_VERSION; | 120 | metadata->vers = FANOTIFY_METADATA_VERSION; |
| 118 | metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; | 121 | metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; |
| 119 | metadata->pid = pid_vnr(event->tgid); | 122 | metadata->pid = pid_vnr(event->tgid); |
| 120 | metadata->fd = create_fd(group, event); | 123 | if (unlikely(event->mask & FAN_Q_OVERFLOW)) |
| 124 | metadata->fd = FAN_NOFD; | ||
| 125 | else { | ||
| 126 | metadata->fd = create_fd(group, event); | ||
| 127 | if (metadata->fd < 0) | ||
| 128 | ret = metadata->fd; | ||
| 129 | } | ||
| 121 | 130 | ||
| 122 | return metadata->fd; | 131 | return ret; |
| 123 | } | 132 | } |
| 124 | 133 | ||
| 125 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 134 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
| @@ -200,7 +209,7 @@ static int prepare_for_access_response(struct fsnotify_group *group, | |||
| 200 | 209 | ||
| 201 | mutex_lock(&group->fanotify_data.access_mutex); | 210 | mutex_lock(&group->fanotify_data.access_mutex); |
| 202 | 211 | ||
| 203 | if (group->fanotify_data.bypass_perm) { | 212 | if (atomic_read(&group->fanotify_data.bypass_perm)) { |
| 204 | mutex_unlock(&group->fanotify_data.access_mutex); | 213 | mutex_unlock(&group->fanotify_data.access_mutex); |
| 205 | kmem_cache_free(fanotify_response_event_cache, re); | 214 | kmem_cache_free(fanotify_response_event_cache, re); |
| 206 | event->response = FAN_ALLOW; | 215 | event->response = FAN_ALLOW; |
| @@ -257,24 +266,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, | |||
| 257 | 266 | ||
| 258 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 267 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
| 259 | 268 | ||
| 260 | fd = fill_event_metadata(group, &fanotify_event_metadata, event); | 269 | ret = fill_event_metadata(group, &fanotify_event_metadata, event); |
| 261 | if (fd < 0) | 270 | if (ret < 0) |
| 262 | return fd; | 271 | goto out; |
| 263 | 272 | ||
| 273 | fd = fanotify_event_metadata.fd; | ||
| 264 | ret = prepare_for_access_response(group, event, fd); | 274 | ret = prepare_for_access_response(group, event, fd); |
| 265 | if (ret) | 275 | if (ret) |
| 266 | goto out_close_fd; | 276 | goto out_close_fd; |
| 267 | 277 | ||
| 268 | ret = -EFAULT; | 278 | ret = -EFAULT; |
| 269 | if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN)) | 279 | if (copy_to_user(buf, &fanotify_event_metadata, |
| 280 | fanotify_event_metadata.event_len)) | ||
| 270 | goto out_kill_access_response; | 281 | goto out_kill_access_response; |
| 271 | 282 | ||
| 272 | return FAN_EVENT_METADATA_LEN; | 283 | return fanotify_event_metadata.event_len; |
| 273 | 284 | ||
| 274 | out_kill_access_response: | 285 | out_kill_access_response: |
| 275 | remove_access_response(group, event, fd); | 286 | remove_access_response(group, event, fd); |
| 276 | out_close_fd: | 287 | out_close_fd: |
| 277 | sys_close(fd); | 288 | if (fd != FAN_NOFD) |
| 289 | sys_close(fd); | ||
| 290 | out: | ||
| 291 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | ||
| 292 | if (event->mask & FAN_ALL_PERM_EVENTS) { | ||
| 293 | event->response = FAN_DENY; | ||
| 294 | wake_up(&group->fanotify_data.access_waitq); | ||
| 295 | } | ||
| 296 | #endif | ||
| 278 | return ret; | 297 | return ret; |
| 279 | } | 298 | } |
| 280 | 299 | ||
| @@ -382,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
| 382 | 401 | ||
| 383 | mutex_lock(&group->fanotify_data.access_mutex); | 402 | mutex_lock(&group->fanotify_data.access_mutex); |
| 384 | 403 | ||
| 385 | group->fanotify_data.bypass_perm = true; | 404 | atomic_inc(&group->fanotify_data.bypass_perm); |
| 386 | 405 | ||
| 387 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { | 406 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { |
| 388 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, | 407 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, |
| @@ -586,11 +605,10 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
| 586 | { | 605 | { |
| 587 | struct fsnotify_mark *fsn_mark; | 606 | struct fsnotify_mark *fsn_mark; |
| 588 | __u32 added; | 607 | __u32 added; |
| 608 | int ret = 0; | ||
| 589 | 609 | ||
| 590 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); | 610 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); |
| 591 | if (!fsn_mark) { | 611 | if (!fsn_mark) { |
| 592 | int ret; | ||
| 593 | |||
| 594 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) | 612 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) |
| 595 | return -ENOSPC; | 613 | return -ENOSPC; |
| 596 | 614 | ||
| @@ -600,17 +618,16 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
| 600 | 618 | ||
| 601 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 619 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
| 602 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); | 620 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); |
| 603 | if (ret) { | 621 | if (ret) |
| 604 | fanotify_free_mark(fsn_mark); | 622 | goto err; |
| 605 | return ret; | ||
| 606 | } | ||
| 607 | } | 623 | } |
| 608 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | 624 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); |
| 609 | fsnotify_put_mark(fsn_mark); | 625 | |
| 610 | if (added & ~mnt->mnt_fsnotify_mask) | 626 | if (added & ~mnt->mnt_fsnotify_mask) |
| 611 | fsnotify_recalc_vfsmount_mask(mnt); | 627 | fsnotify_recalc_vfsmount_mask(mnt); |
| 612 | 628 | err: | |
| 613 | return 0; | 629 | fsnotify_put_mark(fsn_mark); |
| 630 | return ret; | ||
| 614 | } | 631 | } |
| 615 | 632 | ||
| 616 | static int fanotify_add_inode_mark(struct fsnotify_group *group, | 633 | static int fanotify_add_inode_mark(struct fsnotify_group *group, |
| @@ -619,6 +636,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 619 | { | 636 | { |
| 620 | struct fsnotify_mark *fsn_mark; | 637 | struct fsnotify_mark *fsn_mark; |
| 621 | __u32 added; | 638 | __u32 added; |
| 639 | int ret = 0; | ||
| 622 | 640 | ||
| 623 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); | 641 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); |
| 624 | 642 | ||
| @@ -634,8 +652,6 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 634 | 652 | ||
| 635 | fsn_mark = fsnotify_find_inode_mark(group, inode); | 653 | fsn_mark = fsnotify_find_inode_mark(group, inode); |
| 636 | if (!fsn_mark) { | 654 | if (!fsn_mark) { |
| 637 | int ret; | ||
| 638 | |||
| 639 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) | 655 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) |
| 640 | return -ENOSPC; | 656 | return -ENOSPC; |
| 641 | 657 | ||
| @@ -645,16 +661,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 645 | 661 | ||
| 646 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 662 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
| 647 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); | 663 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); |
| 648 | if (ret) { | 664 | if (ret) |
| 649 | fanotify_free_mark(fsn_mark); | 665 | goto err; |
| 650 | return ret; | ||
| 651 | } | ||
| 652 | } | 666 | } |
| 653 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | 667 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); |
| 654 | fsnotify_put_mark(fsn_mark); | 668 | |
| 655 | if (added & ~inode->i_fsnotify_mask) | 669 | if (added & ~inode->i_fsnotify_mask) |
| 656 | fsnotify_recalc_inode_mask(inode); | 670 | fsnotify_recalc_inode_mask(inode); |
| 657 | return 0; | 671 | err: |
| 672 | fsnotify_put_mark(fsn_mark); | ||
| 673 | return ret; | ||
| 658 | } | 674 | } |
| 659 | 675 | ||
| 660 | /* fanotify syscalls */ | 676 | /* fanotify syscalls */ |
| @@ -687,8 +703,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
| 687 | 703 | ||
| 688 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ | 704 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ |
| 689 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); | 705 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); |
| 690 | if (IS_ERR(group)) | 706 | if (IS_ERR(group)) { |
| 707 | free_uid(user); | ||
| 691 | return PTR_ERR(group); | 708 | return PTR_ERR(group); |
| 709 | } | ||
| 692 | 710 | ||
| 693 | group->fanotify_data.user = user; | 711 | group->fanotify_data.user = user; |
| 694 | atomic_inc(&user->fanotify_listeners); | 712 | atomic_inc(&user->fanotify_listeners); |
| @@ -698,6 +716,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
| 698 | mutex_init(&group->fanotify_data.access_mutex); | 716 | mutex_init(&group->fanotify_data.access_mutex); |
| 699 | init_waitqueue_head(&group->fanotify_data.access_waitq); | 717 | init_waitqueue_head(&group->fanotify_data.access_waitq); |
| 700 | INIT_LIST_HEAD(&group->fanotify_data.access_list); | 718 | INIT_LIST_HEAD(&group->fanotify_data.access_list); |
| 719 | atomic_set(&group->fanotify_data.bypass_perm, 0); | ||
| 701 | #endif | 720 | #endif |
| 702 | switch (flags & FAN_ALL_CLASS_BITS) { | 721 | switch (flags & FAN_ALL_CLASS_BITS) { |
| 703 | case FAN_CLASS_NOTIF: | 722 | case FAN_CLASS_NOTIF: |
| @@ -764,8 +783,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
| 764 | if (flags & ~FAN_ALL_MARK_FLAGS) | 783 | if (flags & ~FAN_ALL_MARK_FLAGS) |
| 765 | return -EINVAL; | 784 | return -EINVAL; |
| 766 | switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { | 785 | switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { |
| 767 | case FAN_MARK_ADD: | 786 | case FAN_MARK_ADD: /* fallthrough */ |
| 768 | case FAN_MARK_REMOVE: | 787 | case FAN_MARK_REMOVE: |
| 788 | if (!mask) | ||
| 789 | return -EINVAL; | ||
| 769 | case FAN_MARK_FLUSH: | 790 | case FAN_MARK_FLUSH: |
| 770 | break; | 791 | break; |
| 771 | default: | 792 | default: |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 444c305a468c..4cd5d5d78f9f 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
| @@ -752,6 +752,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags) | |||
| 752 | if (ret >= 0) | 752 | if (ret >= 0) |
| 753 | return ret; | 753 | return ret; |
| 754 | 754 | ||
| 755 | fsnotify_put_group(group); | ||
| 755 | atomic_dec(&user->inotify_devs); | 756 | atomic_dec(&user->inotify_devs); |
| 756 | out_free_uid: | 757 | out_free_uid: |
| 757 | free_uid(user); | 758 | free_uid(user); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aae86fd10c4f..36ab42c9bb99 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -250,7 +250,7 @@ struct queue_limits { | |||
| 250 | 250 | ||
| 251 | unsigned char misaligned; | 251 | unsigned char misaligned; |
| 252 | unsigned char discard_misaligned; | 252 | unsigned char discard_misaligned; |
| 253 | unsigned char no_cluster; | 253 | unsigned char cluster; |
| 254 | signed char discard_zeroes_data; | 254 | signed char discard_zeroes_data; |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| @@ -380,7 +380,6 @@ struct request_queue | |||
| 380 | #endif | 380 | #endif |
| 381 | }; | 381 | }; |
| 382 | 382 | ||
| 383 | #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ | ||
| 384 | #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ | 383 | #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ |
| 385 | #define QUEUE_FLAG_STOPPED 2 /* queue is stopped */ | 384 | #define QUEUE_FLAG_STOPPED 2 /* queue is stopped */ |
| 386 | #define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ | 385 | #define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ |
| @@ -403,7 +402,6 @@ struct request_queue | |||
| 403 | #define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */ | 402 | #define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */ |
| 404 | 403 | ||
| 405 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 404 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
| 406 | (1 << QUEUE_FLAG_CLUSTER) | \ | ||
| 407 | (1 << QUEUE_FLAG_STACKABLE) | \ | 405 | (1 << QUEUE_FLAG_STACKABLE) | \ |
| 408 | (1 << QUEUE_FLAG_SAME_COMP) | \ | 406 | (1 << QUEUE_FLAG_SAME_COMP) | \ |
| 409 | (1 << QUEUE_FLAG_ADD_RANDOM)) | 407 | (1 << QUEUE_FLAG_ADD_RANDOM)) |
| @@ -510,6 +508,11 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) | |||
| 510 | 508 | ||
| 511 | #define rq_data_dir(rq) ((rq)->cmd_flags & 1) | 509 | #define rq_data_dir(rq) ((rq)->cmd_flags & 1) |
| 512 | 510 | ||
| 511 | static inline unsigned int blk_queue_cluster(struct request_queue *q) | ||
| 512 | { | ||
| 513 | return q->limits.cluster; | ||
| 514 | } | ||
| 515 | |||
| 513 | /* | 516 | /* |
| 514 | * We regard a request as sync, if either a read or a sync write | 517 | * We regard a request as sync, if either a read or a sync write |
| 515 | */ | 518 | */ |
| @@ -805,6 +808,7 @@ extern struct request_queue *blk_init_allocated_queue(struct request_queue *, | |||
| 805 | extern void blk_cleanup_queue(struct request_queue *); | 808 | extern void blk_cleanup_queue(struct request_queue *); |
| 806 | extern void blk_queue_make_request(struct request_queue *, make_request_fn *); | 809 | extern void blk_queue_make_request(struct request_queue *, make_request_fn *); |
| 807 | extern void blk_queue_bounce_limit(struct request_queue *, u64); | 810 | extern void blk_queue_bounce_limit(struct request_queue *, u64); |
| 811 | extern void blk_limits_max_hw_sectors(struct queue_limits *, unsigned int); | ||
| 808 | extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); | 812 | extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); |
| 809 | extern void blk_queue_max_segments(struct request_queue *, unsigned short); | 813 | extern void blk_queue_max_segments(struct request_queue *, unsigned short); |
| 810 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); | 814 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); |
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 266ab9291232..499dfe982a0e 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
| @@ -105,6 +105,8 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, | |||
| 105 | 105 | ||
| 106 | #define alloc_bootmem(x) \ | 106 | #define alloc_bootmem(x) \ |
| 107 | __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) | 107 | __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) |
| 108 | #define alloc_bootmem_align(x, align) \ | ||
| 109 | __alloc_bootmem(x, align, __pa(MAX_DMA_ADDRESS)) | ||
| 108 | #define alloc_bootmem_nopanic(x) \ | 110 | #define alloc_bootmem_nopanic(x) \ |
| 109 | __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) | 111 | __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) |
| 110 | #define alloc_bootmem_pages(x) \ | 112 | #define alloc_bootmem_pages(x) \ |
diff --git a/include/linux/cnt32_to_63.h b/include/linux/cnt32_to_63.h index 7605fdd1eb65..e3d8bf26e5eb 100644 --- a/include/linux/cnt32_to_63.h +++ b/include/linux/cnt32_to_63.h | |||
| @@ -61,13 +61,31 @@ union cnt32_to_63 { | |||
| 61 | * | 61 | * |
| 62 | * 2) this code must not be preempted for a duration longer than the | 62 | * 2) this code must not be preempted for a duration longer than the |
| 63 | * 32-bit counter half period minus the longest period between two | 63 | * 32-bit counter half period minus the longest period between two |
| 64 | * calls to this code. | 64 | * calls to this code; |
| 65 | * | 65 | * |
| 66 | * Those requirements ensure proper update to the state bit in memory. | 66 | * Those requirements ensure proper update to the state bit in memory. |
| 67 | * This is usually not a problem in practice, but if it is then a kernel | 67 | * This is usually not a problem in practice, but if it is then a kernel |
| 68 | * timer should be scheduled to manage for this code to be executed often | 68 | * timer should be scheduled to manage for this code to be executed often |
| 69 | * enough. | 69 | * enough. |
| 70 | * | 70 | * |
| 71 | * And finally: | ||
| 72 | * | ||
| 73 | * 3) the cnt_lo argument must be seen as a globally incrementing value, | ||
| 74 | * meaning that it should be a direct reference to the counter data which | ||
| 75 | * can be evaluated according to a specific ordering within the macro, | ||
| 76 | * and not the result of a previous evaluation stored in a variable. | ||
| 77 | * | ||
| 78 | * For example, this is wrong: | ||
| 79 | * | ||
| 80 | * u32 partial = get_hw_count(); | ||
| 81 | * u64 full = cnt32_to_63(partial); | ||
| 82 | * return full; | ||
| 83 | * | ||
| 84 | * This is fine: | ||
| 85 | * | ||
| 86 | * u64 full = cnt32_to_63(get_hw_count()); | ||
| 87 | * return full; | ||
| 88 | * | ||
| 71 | * Note that the top bit (bit 63) in the returned value should be considered | 89 | * Note that the top bit (bit 63) in the returned value should be considered |
| 72 | * as garbage. It is not cleared here because callers are likely to use a | 90 | * as garbage. It is not cleared here because callers are likely to use a |
| 73 | * multiplier on the returned value which can get rid of the top bit | 91 | * multiplier on the returned value which can get rid of the top bit |
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 0f0121467fc4..6c6133f76e16 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h | |||
| @@ -83,11 +83,13 @@ | |||
| 83 | FAN_ALL_PERM_EVENTS |\ | 83 | FAN_ALL_PERM_EVENTS |\ |
| 84 | FAN_Q_OVERFLOW) | 84 | FAN_Q_OVERFLOW) |
| 85 | 85 | ||
| 86 | #define FANOTIFY_METADATA_VERSION 2 | 86 | #define FANOTIFY_METADATA_VERSION 3 |
| 87 | 87 | ||
| 88 | struct fanotify_event_metadata { | 88 | struct fanotify_event_metadata { |
| 89 | __u32 event_len; | 89 | __u32 event_len; |
| 90 | __u32 vers; | 90 | __u8 vers; |
| 91 | __u8 reserved; | ||
| 92 | __u16 metadata_len; | ||
| 91 | __aligned_u64 mask; | 93 | __aligned_u64 mask; |
| 92 | __s32 fd; | 94 | __s32 fd; |
| 93 | __s32 pid; | 95 | __s32 pid; |
| @@ -96,11 +98,13 @@ struct fanotify_event_metadata { | |||
| 96 | struct fanotify_response { | 98 | struct fanotify_response { |
| 97 | __s32 fd; | 99 | __s32 fd; |
| 98 | __u32 response; | 100 | __u32 response; |
| 99 | } __attribute__ ((packed)); | 101 | }; |
| 100 | 102 | ||
| 101 | /* Legit userspace responses to a _PERM event */ | 103 | /* Legit userspace responses to a _PERM event */ |
| 102 | #define FAN_ALLOW 0x01 | 104 | #define FAN_ALLOW 0x01 |
| 103 | #define FAN_DENY 0x02 | 105 | #define FAN_DENY 0x02 |
| 106 | /* No fd set in event */ | ||
| 107 | #define FAN_NOFD -1 | ||
| 104 | 108 | ||
| 105 | /* Helper functions to deal with fanotify_event_metadata buffers */ | 109 | /* Helper functions to deal with fanotify_event_metadata buffers */ |
| 106 | #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) | 110 | #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 5c185fa27089..b10bcdeaef76 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
| @@ -235,9 +235,6 @@ static inline void fsnotify_open(struct file *file) | |||
| 235 | if (S_ISDIR(inode->i_mode)) | 235 | if (S_ISDIR(inode->i_mode)) |
| 236 | mask |= FS_ISDIR; | 236 | mask |= FS_ISDIR; |
| 237 | 237 | ||
| 238 | /* FMODE_NONOTIFY must never be set from user */ | ||
| 239 | file->f_mode &= ~FMODE_NONOTIFY; | ||
| 240 | |||
| 241 | fsnotify_parent(path, NULL, mask); | 238 | fsnotify_parent(path, NULL, mask); |
| 242 | fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); | 239 | fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); |
| 243 | } | 240 | } |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 0a68f924f06f..7380763595d3 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -166,7 +166,7 @@ struct fsnotify_group { | |||
| 166 | struct mutex access_mutex; | 166 | struct mutex access_mutex; |
| 167 | struct list_head access_list; | 167 | struct list_head access_list; |
| 168 | wait_queue_head_t access_waitq; | 168 | wait_queue_head_t access_waitq; |
| 169 | bool bypass_perm; /* protected by access_mutex */ | 169 | atomic_t bypass_perm; |
| 170 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | 170 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ |
| 171 | int f_flags; | 171 | int f_flags; |
| 172 | unsigned int max_marks; | 172 | unsigned int max_marks; |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index d377ea815d45..e9bb22cba764 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
| @@ -112,7 +112,6 @@ struct resource_list { | |||
| 112 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ | 112 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ |
| 113 | extern struct resource ioport_resource; | 113 | extern struct resource ioport_resource; |
| 114 | extern struct resource iomem_resource; | 114 | extern struct resource iomem_resource; |
| 115 | extern int resource_alloc_from_bottom; | ||
| 116 | 115 | ||
| 117 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); | 116 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); |
| 118 | extern int request_resource(struct resource *root, struct resource *new); | 117 | extern int request_resource(struct resource *root, struct resource *new); |
| @@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root, | |||
| 124 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); | 123 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); |
| 125 | extern int insert_resource(struct resource *parent, struct resource *new); | 124 | extern int insert_resource(struct resource *parent, struct resource *new); |
| 126 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); | 125 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); |
| 126 | extern void arch_remove_reservations(struct resource *avail); | ||
| 127 | extern int allocate_resource(struct resource *root, struct resource *new, | 127 | extern int allocate_resource(struct resource *root, struct resource *new, |
| 128 | resource_size_t size, resource_size_t min, | 128 | resource_size_t size, resource_size_t min, |
| 129 | resource_size_t max, resource_size_t align, | 129 | resource_size_t max, resource_size_t align, |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index de2c41758e29..4f1279e105ee 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -887,6 +887,7 @@ struct perf_cpu_context { | |||
| 887 | int exclusive; | 887 | int exclusive; |
| 888 | struct list_head rotation_list; | 888 | struct list_head rotation_list; |
| 889 | int jiffies_interval; | 889 | int jiffies_interval; |
| 890 | struct pmu *active_pmu; | ||
| 890 | }; | 891 | }; |
| 891 | 892 | ||
| 892 | struct perf_output_handle { | 893 | struct perf_output_handle { |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 3ec2358f8692..d19f1cca7f74 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
| @@ -77,7 +77,8 @@ static inline void device_set_run_wake(struct device *dev, bool enable) | |||
| 77 | 77 | ||
| 78 | static inline bool pm_runtime_suspended(struct device *dev) | 78 | static inline bool pm_runtime_suspended(struct device *dev) |
| 79 | { | 79 | { |
| 80 | return dev->power.runtime_status == RPM_SUSPENDED; | 80 | return dev->power.runtime_status == RPM_SUSPENDED |
| 81 | && !dev->power.disable_depth; | ||
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | static inline void pm_runtime_mark_last_busy(struct device *dev) | 84 | static inline void pm_runtime_mark_last_busy(struct device *dev) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c79e921a68b..223874538b33 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -143,7 +143,7 @@ extern unsigned long nr_iowait_cpu(int cpu); | |||
| 143 | extern unsigned long this_cpu_load(void); | 143 | extern unsigned long this_cpu_load(void); |
| 144 | 144 | ||
| 145 | 145 | ||
| 146 | extern void calc_global_load(void); | 146 | extern void calc_global_load(unsigned long ticks); |
| 147 | 147 | ||
| 148 | extern unsigned long get_parent_ip(unsigned long addr); | 148 | extern unsigned long get_parent_ip(unsigned long addr); |
| 149 | 149 | ||
diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h index 942e38736901..eba52a100533 100644 --- a/include/linux/ssb/ssb_driver_gige.h +++ b/include/linux/ssb/ssb_driver_gige.h | |||
| @@ -96,16 +96,21 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev) | |||
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | extern char * nvram_get(const char *name); | 99 | #ifdef CONFIG_BCM47XX |
| 100 | #include <asm/mach-bcm47xx/nvram.h> | ||
| 100 | /* Get the device MAC address */ | 101 | /* Get the device MAC address */ |
| 101 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | 102 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) |
| 102 | { | 103 | { |
| 103 | #ifdef CONFIG_BCM47XX | 104 | char buf[20]; |
| 104 | char *res = nvram_get("et0macaddr"); | 105 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0) |
| 105 | if (res) | 106 | return; |
| 106 | memcpy(macaddr, res, 6); | 107 | nvram_parse_macaddr(buf, macaddr); |
| 107 | #endif | ||
| 108 | } | 108 | } |
| 109 | #else | ||
| 110 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | ||
| 111 | { | ||
| 112 | } | ||
| 113 | #endif | ||
| 109 | 114 | ||
| 110 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, | 115 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, |
| 111 | struct pci_dev *pdev); | 116 | struct pci_dev *pdev); |
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 6648036b728d..b16f307d471a 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h | |||
| @@ -51,6 +51,8 @@ struct v4l2_device { | |||
| 51 | unsigned int notification, void *arg); | 51 | unsigned int notification, void *arg); |
| 52 | /* The control handler. May be NULL. */ | 52 | /* The control handler. May be NULL. */ |
| 53 | struct v4l2_ctrl_handler *ctrl_handler; | 53 | struct v4l2_ctrl_handler *ctrl_handler; |
| 54 | /* BKL replacement mutex. Temporary solution only. */ | ||
| 55 | struct mutex ioctl_lock; | ||
| 54 | }; | 56 | }; |
| 55 | 57 | ||
| 56 | /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. | 58 | /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. |
diff --git a/kernel/fork.c b/kernel/fork.c index 3b159c5991b7..5447dc7defa9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -273,6 +273,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
| 273 | 273 | ||
| 274 | setup_thread_stack(tsk, orig); | 274 | setup_thread_stack(tsk, orig); |
| 275 | clear_user_return_notifier(tsk); | 275 | clear_user_return_notifier(tsk); |
| 276 | clear_tsk_need_resched(tsk); | ||
| 276 | stackend = end_of_stack(tsk); | 277 | stackend = end_of_stack(tsk); |
| 277 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | 278 | *stackend = STACK_END_MAGIC; /* for overflow detection */ |
| 278 | 279 | ||
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index eac7e3364335..2870feee81dd 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -3824,6 +3824,8 @@ static void perf_event_task_event(struct perf_task_event *task_event) | |||
| 3824 | rcu_read_lock(); | 3824 | rcu_read_lock(); |
| 3825 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 3825 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
| 3826 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 3826 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
| 3827 | if (cpuctx->active_pmu != pmu) | ||
| 3828 | goto next; | ||
| 3827 | perf_event_task_ctx(&cpuctx->ctx, task_event); | 3829 | perf_event_task_ctx(&cpuctx->ctx, task_event); |
| 3828 | 3830 | ||
| 3829 | ctx = task_event->task_ctx; | 3831 | ctx = task_event->task_ctx; |
| @@ -3959,6 +3961,8 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) | |||
| 3959 | rcu_read_lock(); | 3961 | rcu_read_lock(); |
| 3960 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 3962 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
| 3961 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 3963 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
| 3964 | if (cpuctx->active_pmu != pmu) | ||
| 3965 | goto next; | ||
| 3962 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); | 3966 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); |
| 3963 | 3967 | ||
| 3964 | ctxn = pmu->task_ctx_nr; | 3968 | ctxn = pmu->task_ctx_nr; |
| @@ -4144,6 +4148,8 @@ got_name: | |||
| 4144 | rcu_read_lock(); | 4148 | rcu_read_lock(); |
| 4145 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 4149 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
| 4146 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 4150 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
| 4151 | if (cpuctx->active_pmu != pmu) | ||
| 4152 | goto next; | ||
| 4147 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, | 4153 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, |
| 4148 | vma->vm_flags & VM_EXEC); | 4154 | vma->vm_flags & VM_EXEC); |
| 4149 | 4155 | ||
| @@ -4713,7 +4719,7 @@ static int perf_swevent_init(struct perf_event *event) | |||
| 4713 | break; | 4719 | break; |
| 4714 | } | 4720 | } |
| 4715 | 4721 | ||
| 4716 | if (event_id > PERF_COUNT_SW_MAX) | 4722 | if (event_id >= PERF_COUNT_SW_MAX) |
| 4717 | return -ENOENT; | 4723 | return -ENOENT; |
| 4718 | 4724 | ||
| 4719 | if (!event->parent) { | 4725 | if (!event->parent) { |
| @@ -5145,20 +5151,36 @@ static void *find_pmu_context(int ctxn) | |||
| 5145 | return NULL; | 5151 | return NULL; |
| 5146 | } | 5152 | } |
| 5147 | 5153 | ||
| 5148 | static void free_pmu_context(void * __percpu cpu_context) | 5154 | static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu) |
| 5149 | { | 5155 | { |
| 5150 | struct pmu *pmu; | 5156 | int cpu; |
| 5157 | |||
| 5158 | for_each_possible_cpu(cpu) { | ||
| 5159 | struct perf_cpu_context *cpuctx; | ||
| 5160 | |||
| 5161 | cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); | ||
| 5162 | |||
| 5163 | if (cpuctx->active_pmu == old_pmu) | ||
| 5164 | cpuctx->active_pmu = pmu; | ||
| 5165 | } | ||
| 5166 | } | ||
| 5167 | |||
| 5168 | static void free_pmu_context(struct pmu *pmu) | ||
| 5169 | { | ||
| 5170 | struct pmu *i; | ||
| 5151 | 5171 | ||
| 5152 | mutex_lock(&pmus_lock); | 5172 | mutex_lock(&pmus_lock); |
| 5153 | /* | 5173 | /* |
| 5154 | * Like a real lame refcount. | 5174 | * Like a real lame refcount. |
| 5155 | */ | 5175 | */ |
| 5156 | list_for_each_entry(pmu, &pmus, entry) { | 5176 | list_for_each_entry(i, &pmus, entry) { |
| 5157 | if (pmu->pmu_cpu_context == cpu_context) | 5177 | if (i->pmu_cpu_context == pmu->pmu_cpu_context) { |
| 5178 | update_pmu_context(i, pmu); | ||
| 5158 | goto out; | 5179 | goto out; |
| 5180 | } | ||
| 5159 | } | 5181 | } |
| 5160 | 5182 | ||
| 5161 | free_percpu(cpu_context); | 5183 | free_percpu(pmu->pmu_cpu_context); |
| 5162 | out: | 5184 | out: |
| 5163 | mutex_unlock(&pmus_lock); | 5185 | mutex_unlock(&pmus_lock); |
| 5164 | } | 5186 | } |
| @@ -5190,6 +5212,7 @@ int perf_pmu_register(struct pmu *pmu) | |||
| 5190 | cpuctx->ctx.pmu = pmu; | 5212 | cpuctx->ctx.pmu = pmu; |
| 5191 | cpuctx->jiffies_interval = 1; | 5213 | cpuctx->jiffies_interval = 1; |
| 5192 | INIT_LIST_HEAD(&cpuctx->rotation_list); | 5214 | INIT_LIST_HEAD(&cpuctx->rotation_list); |
| 5215 | cpuctx->active_pmu = pmu; | ||
| 5193 | } | 5216 | } |
| 5194 | 5217 | ||
| 5195 | got_cpu_context: | 5218 | got_cpu_context: |
| @@ -5241,7 +5264,7 @@ void perf_pmu_unregister(struct pmu *pmu) | |||
| 5241 | synchronize_rcu(); | 5264 | synchronize_rcu(); |
| 5242 | 5265 | ||
| 5243 | free_percpu(pmu->pmu_disable_count); | 5266 | free_percpu(pmu->pmu_disable_count); |
| 5244 | free_pmu_context(pmu->pmu_cpu_context); | 5267 | free_pmu_context(pmu); |
| 5245 | } | 5268 | } |
| 5246 | 5269 | ||
| 5247 | struct pmu *perf_init_event(struct perf_event *event) | 5270 | struct pmu *perf_init_event(struct perf_event *event) |
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index baf667bb2794..8c7e4832b9be 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #include "power.h" | 31 | #include "power.h" |
| 32 | 32 | ||
| 33 | #define HIBERNATE_SIG "LINHIB0001" | 33 | #define HIBERNATE_SIG "S1SUSPEND" |
| 34 | 34 | ||
| 35 | /* | 35 | /* |
| 36 | * The swap map is a data structure used for keeping track of each page | 36 | * The swap map is a data structure used for keeping track of each page |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 1b2ea31e6bd8..c36c3b9e8a84 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
| @@ -137,7 +137,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
| 137 | free_all_swap_pages(data->swap); | 137 | free_all_swap_pages(data->swap); |
| 138 | if (data->frozen) | 138 | if (data->frozen) |
| 139 | thaw_processes(); | 139 | thaw_processes(); |
| 140 | pm_notifier_call_chain(data->mode == O_WRONLY ? | 140 | pm_notifier_call_chain(data->mode == O_RDONLY ? |
| 141 | PM_POST_HIBERNATION : PM_POST_RESTORE); | 141 | PM_POST_HIBERNATION : PM_POST_RESTORE); |
| 142 | atomic_inc(&snapshot_device_available); | 142 | atomic_inc(&snapshot_device_available); |
| 143 | 143 | ||
diff --git a/kernel/resource.c b/kernel/resource.c index 9fad33efd0db..798e2fae2a06 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
| @@ -40,23 +40,6 @@ EXPORT_SYMBOL(iomem_resource); | |||
| 40 | 40 | ||
| 41 | static DEFINE_RWLOCK(resource_lock); | 41 | static DEFINE_RWLOCK(resource_lock); |
| 42 | 42 | ||
| 43 | /* | ||
| 44 | * By default, we allocate free space bottom-up. The architecture can request | ||
| 45 | * top-down by clearing this flag. The user can override the architecture's | ||
| 46 | * choice with the "resource_alloc_from_bottom" kernel boot option, but that | ||
| 47 | * should only be a debugging tool. | ||
| 48 | */ | ||
| 49 | int resource_alloc_from_bottom = 1; | ||
| 50 | |||
| 51 | static __init int setup_alloc_from_bottom(char *s) | ||
| 52 | { | ||
| 53 | printk(KERN_INFO | ||
| 54 | "resource: allocating from bottom-up; please report a bug\n"); | ||
| 55 | resource_alloc_from_bottom = 1; | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | early_param("resource_alloc_from_bottom", setup_alloc_from_bottom); | ||
| 59 | |||
| 60 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) | 43 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) |
| 61 | { | 44 | { |
| 62 | struct resource *p = v; | 45 | struct resource *p = v; |
| @@ -374,6 +357,10 @@ int __weak page_is_ram(unsigned long pfn) | |||
| 374 | return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; | 357 | return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; |
| 375 | } | 358 | } |
| 376 | 359 | ||
| 360 | void __weak arch_remove_reservations(struct resource *avail) | ||
| 361 | { | ||
| 362 | } | ||
| 363 | |||
| 377 | static resource_size_t simple_align_resource(void *data, | 364 | static resource_size_t simple_align_resource(void *data, |
| 378 | const struct resource *avail, | 365 | const struct resource *avail, |
| 379 | resource_size_t size, | 366 | resource_size_t size, |
| @@ -397,74 +384,7 @@ static bool resource_contains(struct resource *res1, struct resource *res2) | |||
| 397 | } | 384 | } |
| 398 | 385 | ||
| 399 | /* | 386 | /* |
| 400 | * Find the resource before "child" in the sibling list of "root" children. | ||
| 401 | */ | ||
| 402 | static struct resource *find_sibling_prev(struct resource *root, struct resource *child) | ||
| 403 | { | ||
| 404 | struct resource *this; | ||
| 405 | |||
| 406 | for (this = root->child; this; this = this->sibling) | ||
| 407 | if (this->sibling == child) | ||
| 408 | return this; | ||
| 409 | |||
| 410 | return NULL; | ||
| 411 | } | ||
| 412 | |||
| 413 | /* | ||
| 414 | * Find empty slot in the resource tree given range and alignment. | 387 | * Find empty slot in the resource tree given range and alignment. |
| 415 | * This version allocates from the end of the root resource first. | ||
| 416 | */ | ||
| 417 | static int find_resource_from_top(struct resource *root, struct resource *new, | ||
| 418 | resource_size_t size, resource_size_t min, | ||
| 419 | resource_size_t max, resource_size_t align, | ||
| 420 | resource_size_t (*alignf)(void *, | ||
| 421 | const struct resource *, | ||
| 422 | resource_size_t, | ||
| 423 | resource_size_t), | ||
| 424 | void *alignf_data) | ||
| 425 | { | ||
| 426 | struct resource *this; | ||
| 427 | struct resource tmp, avail, alloc; | ||
| 428 | |||
| 429 | tmp.start = root->end; | ||
| 430 | tmp.end = root->end; | ||
| 431 | |||
| 432 | this = find_sibling_prev(root, NULL); | ||
| 433 | for (;;) { | ||
| 434 | if (this) { | ||
| 435 | if (this->end < root->end) | ||
| 436 | tmp.start = this->end + 1; | ||
| 437 | } else | ||
| 438 | tmp.start = root->start; | ||
| 439 | |||
| 440 | resource_clip(&tmp, min, max); | ||
| 441 | |||
| 442 | /* Check for overflow after ALIGN() */ | ||
| 443 | avail = *new; | ||
| 444 | avail.start = ALIGN(tmp.start, align); | ||
| 445 | avail.end = tmp.end; | ||
| 446 | if (avail.start >= tmp.start) { | ||
| 447 | alloc.start = alignf(alignf_data, &avail, size, align); | ||
| 448 | alloc.end = alloc.start + size - 1; | ||
| 449 | if (resource_contains(&avail, &alloc)) { | ||
| 450 | new->start = alloc.start; | ||
| 451 | new->end = alloc.end; | ||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | } | ||
| 455 | |||
| 456 | if (!this || this->start == root->start) | ||
| 457 | break; | ||
| 458 | |||
| 459 | tmp.end = this->start - 1; | ||
| 460 | this = find_sibling_prev(root, this); | ||
| 461 | } | ||
| 462 | return -EBUSY; | ||
| 463 | } | ||
| 464 | |||
| 465 | /* | ||
| 466 | * Find empty slot in the resource tree given range and alignment. | ||
| 467 | * This version allocates from the beginning of the root resource first. | ||
| 468 | */ | 388 | */ |
| 469 | static int find_resource(struct resource *root, struct resource *new, | 389 | static int find_resource(struct resource *root, struct resource *new, |
| 470 | resource_size_t size, resource_size_t min, | 390 | resource_size_t size, resource_size_t min, |
| @@ -478,23 +398,24 @@ static int find_resource(struct resource *root, struct resource *new, | |||
| 478 | struct resource *this = root->child; | 398 | struct resource *this = root->child; |
| 479 | struct resource tmp = *new, avail, alloc; | 399 | struct resource tmp = *new, avail, alloc; |
| 480 | 400 | ||
| 401 | tmp.flags = new->flags; | ||
| 481 | tmp.start = root->start; | 402 | tmp.start = root->start; |
| 482 | /* | 403 | /* |
| 483 | * Skip past an allocated resource that starts at 0, since the | 404 | * Skip past an allocated resource that starts at 0, since the assignment |
| 484 | * assignment of this->start - 1 to tmp->end below would cause an | 405 | * of this->start - 1 to tmp->end below would cause an underflow. |
| 485 | * underflow. | ||
| 486 | */ | 406 | */ |
| 487 | if (this && this->start == 0) { | 407 | if (this && this->start == 0) { |
| 488 | tmp.start = this->end + 1; | 408 | tmp.start = this->end + 1; |
| 489 | this = this->sibling; | 409 | this = this->sibling; |
| 490 | } | 410 | } |
| 491 | for (;;) { | 411 | for(;;) { |
| 492 | if (this) | 412 | if (this) |
| 493 | tmp.end = this->start - 1; | 413 | tmp.end = this->start - 1; |
| 494 | else | 414 | else |
| 495 | tmp.end = root->end; | 415 | tmp.end = root->end; |
| 496 | 416 | ||
| 497 | resource_clip(&tmp, min, max); | 417 | resource_clip(&tmp, min, max); |
| 418 | arch_remove_reservations(&tmp); | ||
| 498 | 419 | ||
| 499 | /* Check for overflow after ALIGN() */ | 420 | /* Check for overflow after ALIGN() */ |
| 500 | avail = *new; | 421 | avail = *new; |
| @@ -509,10 +430,8 @@ static int find_resource(struct resource *root, struct resource *new, | |||
| 509 | return 0; | 430 | return 0; |
| 510 | } | 431 | } |
| 511 | } | 432 | } |
| 512 | |||
| 513 | if (!this) | 433 | if (!this) |
| 514 | break; | 434 | break; |
| 515 | |||
| 516 | tmp.start = this->end + 1; | 435 | tmp.start = this->end + 1; |
| 517 | this = this->sibling; | 436 | this = this->sibling; |
| 518 | } | 437 | } |
| @@ -545,10 +464,7 @@ int allocate_resource(struct resource *root, struct resource *new, | |||
| 545 | alignf = simple_align_resource; | 464 | alignf = simple_align_resource; |
| 546 | 465 | ||
| 547 | write_lock(&resource_lock); | 466 | write_lock(&resource_lock); |
| 548 | if (resource_alloc_from_bottom) | 467 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); |
| 549 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); | ||
| 550 | else | ||
| 551 | err = find_resource_from_top(root, new, size, min, max, align, alignf, alignf_data); | ||
| 552 | if (err >= 0 && __request_resource(root, new)) | 468 | if (err >= 0 && __request_resource(root, new)) |
| 553 | err = -EBUSY; | 469 | err = -EBUSY; |
| 554 | write_unlock(&resource_lock); | 470 | write_unlock(&resource_lock); |
diff --git a/kernel/sched.c b/kernel/sched.c index dc91a4d09ac3..297d1a0eedb0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -636,22 +636,18 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
| 636 | 636 | ||
| 637 | #endif /* CONFIG_CGROUP_SCHED */ | 637 | #endif /* CONFIG_CGROUP_SCHED */ |
| 638 | 638 | ||
| 639 | static u64 irq_time_cpu(int cpu); | 639 | static void update_rq_clock_task(struct rq *rq, s64 delta); |
| 640 | static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time); | ||
| 641 | 640 | ||
| 642 | inline void update_rq_clock(struct rq *rq) | 641 | static void update_rq_clock(struct rq *rq) |
| 643 | { | 642 | { |
| 644 | if (!rq->skip_clock_update) { | 643 | s64 delta; |
| 645 | int cpu = cpu_of(rq); | ||
| 646 | u64 irq_time; | ||
| 647 | 644 | ||
| 648 | rq->clock = sched_clock_cpu(cpu); | 645 | if (rq->skip_clock_update) |
| 649 | irq_time = irq_time_cpu(cpu); | 646 | return; |
| 650 | if (rq->clock - irq_time > rq->clock_task) | ||
| 651 | rq->clock_task = rq->clock - irq_time; | ||
| 652 | 647 | ||
| 653 | sched_irq_time_avg_update(rq, irq_time); | 648 | delta = sched_clock_cpu(cpu_of(rq)) - rq->clock; |
| 654 | } | 649 | rq->clock += delta; |
| 650 | update_rq_clock_task(rq, delta); | ||
| 655 | } | 651 | } |
| 656 | 652 | ||
| 657 | /* | 653 | /* |
| @@ -1924,10 +1920,9 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int flags) | |||
| 1924 | * They are read and saved off onto struct rq in update_rq_clock(). | 1920 | * They are read and saved off onto struct rq in update_rq_clock(). |
| 1925 | * This may result in other CPU reading this CPU's irq time and can | 1921 | * This may result in other CPU reading this CPU's irq time and can |
| 1926 | * race with irq/account_system_vtime on this CPU. We would either get old | 1922 | * race with irq/account_system_vtime on this CPU. We would either get old |
| 1927 | * or new value (or semi updated value on 32 bit) with a side effect of | 1923 | * or new value with a side effect of accounting a slice of irq time to wrong |
| 1928 | * accounting a slice of irq time to wrong task when irq is in progress | 1924 | * task when irq is in progress while we read rq->clock. That is a worthy |
| 1929 | * while we read rq->clock. That is a worthy compromise in place of having | 1925 | * compromise in place of having locks on each irq in account_system_time. |
| 1930 | * locks on each irq in account_system_time. | ||
| 1931 | */ | 1926 | */ |
| 1932 | static DEFINE_PER_CPU(u64, cpu_hardirq_time); | 1927 | static DEFINE_PER_CPU(u64, cpu_hardirq_time); |
| 1933 | static DEFINE_PER_CPU(u64, cpu_softirq_time); | 1928 | static DEFINE_PER_CPU(u64, cpu_softirq_time); |
| @@ -1945,19 +1940,58 @@ void disable_sched_clock_irqtime(void) | |||
| 1945 | sched_clock_irqtime = 0; | 1940 | sched_clock_irqtime = 0; |
| 1946 | } | 1941 | } |
| 1947 | 1942 | ||
| 1948 | static u64 irq_time_cpu(int cpu) | 1943 | #ifndef CONFIG_64BIT |
| 1944 | static DEFINE_PER_CPU(seqcount_t, irq_time_seq); | ||
| 1945 | |||
| 1946 | static inline void irq_time_write_begin(void) | ||
| 1949 | { | 1947 | { |
| 1950 | if (!sched_clock_irqtime) | 1948 | __this_cpu_inc(irq_time_seq.sequence); |
| 1951 | return 0; | 1949 | smp_wmb(); |
| 1950 | } | ||
| 1951 | |||
| 1952 | static inline void irq_time_write_end(void) | ||
| 1953 | { | ||
| 1954 | smp_wmb(); | ||
| 1955 | __this_cpu_inc(irq_time_seq.sequence); | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | static inline u64 irq_time_read(int cpu) | ||
| 1959 | { | ||
| 1960 | u64 irq_time; | ||
| 1961 | unsigned seq; | ||
| 1952 | 1962 | ||
| 1963 | do { | ||
| 1964 | seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu)); | ||
| 1965 | irq_time = per_cpu(cpu_softirq_time, cpu) + | ||
| 1966 | per_cpu(cpu_hardirq_time, cpu); | ||
| 1967 | } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq)); | ||
| 1968 | |||
| 1969 | return irq_time; | ||
| 1970 | } | ||
| 1971 | #else /* CONFIG_64BIT */ | ||
| 1972 | static inline void irq_time_write_begin(void) | ||
| 1973 | { | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | static inline void irq_time_write_end(void) | ||
| 1977 | { | ||
| 1978 | } | ||
| 1979 | |||
| 1980 | static inline u64 irq_time_read(int cpu) | ||
| 1981 | { | ||
| 1953 | return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); | 1982 | return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); |
| 1954 | } | 1983 | } |
| 1984 | #endif /* CONFIG_64BIT */ | ||
| 1955 | 1985 | ||
| 1986 | /* | ||
| 1987 | * Called before incrementing preempt_count on {soft,}irq_enter | ||
| 1988 | * and before decrementing preempt_count on {soft,}irq_exit. | ||
| 1989 | */ | ||
| 1956 | void account_system_vtime(struct task_struct *curr) | 1990 | void account_system_vtime(struct task_struct *curr) |
| 1957 | { | 1991 | { |
| 1958 | unsigned long flags; | 1992 | unsigned long flags; |
| 1993 | s64 delta; | ||
| 1959 | int cpu; | 1994 | int cpu; |
| 1960 | u64 now, delta; | ||
| 1961 | 1995 | ||
| 1962 | if (!sched_clock_irqtime) | 1996 | if (!sched_clock_irqtime) |
| 1963 | return; | 1997 | return; |
| @@ -1965,9 +1999,10 @@ void account_system_vtime(struct task_struct *curr) | |||
| 1965 | local_irq_save(flags); | 1999 | local_irq_save(flags); |
| 1966 | 2000 | ||
| 1967 | cpu = smp_processor_id(); | 2001 | cpu = smp_processor_id(); |
| 1968 | now = sched_clock_cpu(cpu); | 2002 | delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time); |
| 1969 | delta = now - per_cpu(irq_start_time, cpu); | 2003 | __this_cpu_add(irq_start_time, delta); |
| 1970 | per_cpu(irq_start_time, cpu) = now; | 2004 | |
| 2005 | irq_time_write_begin(); | ||
| 1971 | /* | 2006 | /* |
| 1972 | * We do not account for softirq time from ksoftirqd here. | 2007 | * We do not account for softirq time from ksoftirqd here. |
| 1973 | * We want to continue accounting softirq time to ksoftirqd thread | 2008 | * We want to continue accounting softirq time to ksoftirqd thread |
| @@ -1975,33 +2010,55 @@ void account_system_vtime(struct task_struct *curr) | |||
| 1975 | * that do not consume any time, but still wants to run. | 2010 | * that do not consume any time, but still wants to run. |
| 1976 | */ | 2011 | */ |
| 1977 | if (hardirq_count()) | 2012 | if (hardirq_count()) |
| 1978 | per_cpu(cpu_hardirq_time, cpu) += delta; | 2013 | __this_cpu_add(cpu_hardirq_time, delta); |
| 1979 | else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD)) | 2014 | else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD)) |
| 1980 | per_cpu(cpu_softirq_time, cpu) += delta; | 2015 | __this_cpu_add(cpu_softirq_time, delta); |
| 1981 | 2016 | ||
| 2017 | irq_time_write_end(); | ||
| 1982 | local_irq_restore(flags); | 2018 | local_irq_restore(flags); |
| 1983 | } | 2019 | } |
| 1984 | EXPORT_SYMBOL_GPL(account_system_vtime); | 2020 | EXPORT_SYMBOL_GPL(account_system_vtime); |
| 1985 | 2021 | ||
| 1986 | static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) | 2022 | static void update_rq_clock_task(struct rq *rq, s64 delta) |
| 1987 | { | 2023 | { |
| 1988 | if (sched_clock_irqtime && sched_feat(NONIRQ_POWER)) { | 2024 | s64 irq_delta; |
| 1989 | u64 delta_irq = curr_irq_time - rq->prev_irq_time; | 2025 | |
| 1990 | rq->prev_irq_time = curr_irq_time; | 2026 | irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time; |
| 1991 | sched_rt_avg_update(rq, delta_irq); | 2027 | |
| 1992 | } | 2028 | /* |
| 2029 | * Since irq_time is only updated on {soft,}irq_exit, we might run into | ||
| 2030 | * this case when a previous update_rq_clock() happened inside a | ||
| 2031 | * {soft,}irq region. | ||
| 2032 | * | ||
| 2033 | * When this happens, we stop ->clock_task and only update the | ||
| 2034 | * prev_irq_time stamp to account for the part that fit, so that a next | ||
| 2035 | * update will consume the rest. This ensures ->clock_task is | ||
| 2036 | * monotonic. | ||
| 2037 | * | ||
| 2038 | * It does however cause some slight miss-attribution of {soft,}irq | ||
| 2039 | * time, a more accurate solution would be to update the irq_time using | ||
| 2040 | * the current rq->clock timestamp, except that would require using | ||
| 2041 | * atomic ops. | ||
| 2042 | */ | ||
| 2043 | if (irq_delta > delta) | ||
| 2044 | irq_delta = delta; | ||
| 2045 | |||
| 2046 | rq->prev_irq_time += irq_delta; | ||
| 2047 | delta -= irq_delta; | ||
| 2048 | rq->clock_task += delta; | ||
| 2049 | |||
| 2050 | if (irq_delta && sched_feat(NONIRQ_POWER)) | ||
| 2051 | sched_rt_avg_update(rq, irq_delta); | ||
| 1993 | } | 2052 | } |
| 1994 | 2053 | ||
| 1995 | #else | 2054 | #else /* CONFIG_IRQ_TIME_ACCOUNTING */ |
| 1996 | 2055 | ||
| 1997 | static u64 irq_time_cpu(int cpu) | 2056 | static void update_rq_clock_task(struct rq *rq, s64 delta) |
| 1998 | { | 2057 | { |
| 1999 | return 0; | 2058 | rq->clock_task += delta; |
| 2000 | } | 2059 | } |
| 2001 | 2060 | ||
| 2002 | static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) { } | 2061 | #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ |
| 2003 | |||
| 2004 | #endif | ||
| 2005 | 2062 | ||
| 2006 | #include "sched_idletask.c" | 2063 | #include "sched_idletask.c" |
| 2007 | #include "sched_fair.c" | 2064 | #include "sched_fair.c" |
| @@ -2129,7 +2186,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) | |||
| 2129 | * A queue event has occurred, and we're going to schedule. In | 2186 | * A queue event has occurred, and we're going to schedule. In |
| 2130 | * this case, we can save a useless back to back clock update. | 2187 | * this case, we can save a useless back to back clock update. |
| 2131 | */ | 2188 | */ |
| 2132 | if (test_tsk_need_resched(rq->curr)) | 2189 | if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr)) |
| 2133 | rq->skip_clock_update = 1; | 2190 | rq->skip_clock_update = 1; |
| 2134 | } | 2191 | } |
| 2135 | 2192 | ||
| @@ -3119,6 +3176,15 @@ static long calc_load_fold_active(struct rq *this_rq) | |||
| 3119 | return delta; | 3176 | return delta; |
| 3120 | } | 3177 | } |
| 3121 | 3178 | ||
| 3179 | static unsigned long | ||
| 3180 | calc_load(unsigned long load, unsigned long exp, unsigned long active) | ||
| 3181 | { | ||
| 3182 | load *= exp; | ||
| 3183 | load += active * (FIXED_1 - exp); | ||
| 3184 | load += 1UL << (FSHIFT - 1); | ||
| 3185 | return load >> FSHIFT; | ||
| 3186 | } | ||
| 3187 | |||
| 3122 | #ifdef CONFIG_NO_HZ | 3188 | #ifdef CONFIG_NO_HZ |
| 3123 | /* | 3189 | /* |
| 3124 | * For NO_HZ we delay the active fold to the next LOAD_FREQ update. | 3190 | * For NO_HZ we delay the active fold to the next LOAD_FREQ update. |
| @@ -3148,6 +3214,128 @@ static long calc_load_fold_idle(void) | |||
| 3148 | 3214 | ||
| 3149 | return delta; | 3215 | return delta; |
| 3150 | } | 3216 | } |
| 3217 | |||
| 3218 | /** | ||
| 3219 | * fixed_power_int - compute: x^n, in O(log n) time | ||
| 3220 | * | ||
| 3221 | * @x: base of the power | ||
| 3222 | * @frac_bits: fractional bits of @x | ||
| 3223 | * @n: power to raise @x to. | ||
| 3224 | * | ||
| 3225 | * By exploiting the relation between the definition of the natural power | ||
| 3226 | * function: x^n := x*x*...*x (x multiplied by itself for n times), and | ||
| 3227 | * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i, | ||
| 3228 | * (where: n_i \elem {0, 1}, the binary vector representing n), | ||
| 3229 | * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is | ||
| 3230 | * of course trivially computable in O(log_2 n), the length of our binary | ||
| 3231 | * vector. | ||
| 3232 | */ | ||
| 3233 | static unsigned long | ||
| 3234 | fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n) | ||
| 3235 | { | ||
| 3236 | unsigned long result = 1UL << frac_bits; | ||
| 3237 | |||
| 3238 | if (n) for (;;) { | ||
| 3239 | if (n & 1) { | ||
| 3240 | result *= x; | ||
| 3241 | result += 1UL << (frac_bits - 1); | ||
| 3242 | result >>= frac_bits; | ||
| 3243 | } | ||
| 3244 | n >>= 1; | ||
| 3245 | if (!n) | ||
| 3246 | break; | ||
| 3247 | x *= x; | ||
| 3248 | x += 1UL << (frac_bits - 1); | ||
| 3249 | x >>= frac_bits; | ||
| 3250 | } | ||
| 3251 | |||
| 3252 | return result; | ||
| 3253 | } | ||
| 3254 | |||
| 3255 | /* | ||
| 3256 | * a1 = a0 * e + a * (1 - e) | ||
| 3257 | * | ||
| 3258 | * a2 = a1 * e + a * (1 - e) | ||
| 3259 | * = (a0 * e + a * (1 - e)) * e + a * (1 - e) | ||
| 3260 | * = a0 * e^2 + a * (1 - e) * (1 + e) | ||
| 3261 | * | ||
| 3262 | * a3 = a2 * e + a * (1 - e) | ||
| 3263 | * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e) | ||
| 3264 | * = a0 * e^3 + a * (1 - e) * (1 + e + e^2) | ||
| 3265 | * | ||
| 3266 | * ... | ||
| 3267 | * | ||
| 3268 | * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1] | ||
| 3269 | * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e) | ||
| 3270 | * = a0 * e^n + a * (1 - e^n) | ||
| 3271 | * | ||
| 3272 | * [1] application of the geometric series: | ||
| 3273 | * | ||
| 3274 | * n 1 - x^(n+1) | ||
| 3275 | * S_n := \Sum x^i = ------------- | ||
| 3276 | * i=0 1 - x | ||
| 3277 | */ | ||
| 3278 | static unsigned long | ||
| 3279 | calc_load_n(unsigned long load, unsigned long exp, | ||
| 3280 | unsigned long active, unsigned int n) | ||
| 3281 | { | ||
| 3282 | |||
| 3283 | return calc_load(load, fixed_power_int(exp, FSHIFT, n), active); | ||
| 3284 | } | ||
| 3285 | |||
| 3286 | /* | ||
| 3287 | * NO_HZ can leave us missing all per-cpu ticks calling | ||
| 3288 | * calc_load_account_active(), but since an idle CPU folds its delta into | ||
| 3289 | * calc_load_tasks_idle per calc_load_account_idle(), all we need to do is fold | ||
| 3290 | * in the pending idle delta if our idle period crossed a load cycle boundary. | ||
| 3291 | * | ||
| 3292 | * Once we've updated the global active value, we need to apply the exponential | ||
| 3293 | * weights adjusted to the number of cycles missed. | ||
| 3294 | */ | ||
| 3295 | static void calc_global_nohz(unsigned long ticks) | ||
| 3296 | { | ||
| 3297 | long delta, active, n; | ||
| 3298 | |||
| 3299 | if (time_before(jiffies, calc_load_update)) | ||
| 3300 | return; | ||
| 3301 | |||
| 3302 | /* | ||
| 3303 | * If we crossed a calc_load_update boundary, make sure to fold | ||
| 3304 | * any pending idle changes, the respective CPUs might have | ||
| 3305 | * missed the tick driven calc_load_account_active() update | ||
| 3306 | * due to NO_HZ. | ||
| 3307 | */ | ||
| 3308 | delta = calc_load_fold_idle(); | ||
| 3309 | if (delta) | ||
| 3310 | atomic_long_add(delta, &calc_load_tasks); | ||
| 3311 | |||
| 3312 | /* | ||
| 3313 | * If we were idle for multiple load cycles, apply them. | ||
| 3314 | */ | ||
| 3315 | if (ticks >= LOAD_FREQ) { | ||
| 3316 | n = ticks / LOAD_FREQ; | ||
| 3317 | |||
| 3318 | active = atomic_long_read(&calc_load_tasks); | ||
| 3319 | active = active > 0 ? active * FIXED_1 : 0; | ||
| 3320 | |||
| 3321 | avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n); | ||
| 3322 | avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n); | ||
| 3323 | avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n); | ||
| 3324 | |||
| 3325 | calc_load_update += n * LOAD_FREQ; | ||
| 3326 | } | ||
| 3327 | |||
| 3328 | /* | ||
| 3329 | * Its possible the remainder of the above division also crosses | ||
| 3330 | * a LOAD_FREQ period, the regular check in calc_global_load() | ||
| 3331 | * which comes after this will take care of that. | ||
| 3332 | * | ||
| 3333 | * Consider us being 11 ticks before a cycle completion, and us | ||
| 3334 | * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will | ||
| 3335 | * age us 4 cycles, and the test in calc_global_load() will | ||
| 3336 | * pick up the final one. | ||
| 3337 | */ | ||
| 3338 | } | ||
| 3151 | #else | 3339 | #else |
| 3152 | static void calc_load_account_idle(struct rq *this_rq) | 3340 | static void calc_load_account_idle(struct rq *this_rq) |
| 3153 | { | 3341 | { |
| @@ -3157,6 +3345,10 @@ static inline long calc_load_fold_idle(void) | |||
| 3157 | { | 3345 | { |
| 3158 | return 0; | 3346 | return 0; |
| 3159 | } | 3347 | } |
| 3348 | |||
| 3349 | static void calc_global_nohz(unsigned long ticks) | ||
| 3350 | { | ||
| 3351 | } | ||
| 3160 | #endif | 3352 | #endif |
| 3161 | 3353 | ||
| 3162 | /** | 3354 | /** |
| @@ -3174,24 +3366,17 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift) | |||
| 3174 | loads[2] = (avenrun[2] + offset) << shift; | 3366 | loads[2] = (avenrun[2] + offset) << shift; |
| 3175 | } | 3367 | } |
| 3176 | 3368 | ||
| 3177 | static unsigned long | ||
| 3178 | calc_load(unsigned long load, unsigned long exp, unsigned long active) | ||
| 3179 | { | ||
| 3180 | load *= exp; | ||
| 3181 | load += active * (FIXED_1 - exp); | ||
| 3182 | return load >> FSHIFT; | ||
| 3183 | } | ||
| 3184 | |||
| 3185 | /* | 3369 | /* |
| 3186 | * calc_load - update the avenrun load estimates 10 ticks after the | 3370 | * calc_load - update the avenrun load estimates 10 ticks after the |
| 3187 | * CPUs have updated calc_load_tasks. | 3371 | * CPUs have updated calc_load_tasks. |
| 3188 | */ | 3372 | */ |
| 3189 | void calc_global_load(void) | 3373 | void calc_global_load(unsigned long ticks) |
| 3190 | { | 3374 | { |
| 3191 | unsigned long upd = calc_load_update + 10; | ||
| 3192 | long active; | 3375 | long active; |
| 3193 | 3376 | ||
| 3194 | if (time_before(jiffies, upd)) | 3377 | calc_global_nohz(ticks); |
| 3378 | |||
| 3379 | if (time_before(jiffies, calc_load_update + 10)) | ||
| 3195 | return; | 3380 | return; |
| 3196 | 3381 | ||
| 3197 | active = atomic_long_read(&calc_load_tasks); | 3382 | active = atomic_long_read(&calc_load_tasks); |
| @@ -3845,7 +4030,6 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev) | |||
| 3845 | { | 4030 | { |
| 3846 | if (prev->se.on_rq) | 4031 | if (prev->se.on_rq) |
| 3847 | update_rq_clock(rq); | 4032 | update_rq_clock(rq); |
| 3848 | rq->skip_clock_update = 0; | ||
| 3849 | prev->sched_class->put_prev_task(rq, prev); | 4033 | prev->sched_class->put_prev_task(rq, prev); |
| 3850 | } | 4034 | } |
| 3851 | 4035 | ||
| @@ -3903,7 +4087,6 @@ need_resched_nonpreemptible: | |||
| 3903 | hrtick_clear(rq); | 4087 | hrtick_clear(rq); |
| 3904 | 4088 | ||
| 3905 | raw_spin_lock_irq(&rq->lock); | 4089 | raw_spin_lock_irq(&rq->lock); |
| 3906 | clear_tsk_need_resched(prev); | ||
| 3907 | 4090 | ||
| 3908 | switch_count = &prev->nivcsw; | 4091 | switch_count = &prev->nivcsw; |
| 3909 | if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { | 4092 | if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { |
| @@ -3935,6 +4118,8 @@ need_resched_nonpreemptible: | |||
| 3935 | 4118 | ||
| 3936 | put_prev_task(rq, prev); | 4119 | put_prev_task(rq, prev); |
| 3937 | next = pick_next_task(rq); | 4120 | next = pick_next_task(rq); |
| 4121 | clear_tsk_need_resched(prev); | ||
| 4122 | rq->skip_clock_update = 0; | ||
| 3938 | 4123 | ||
| 3939 | if (likely(prev != next)) { | 4124 | if (likely(prev != next)) { |
| 3940 | sched_info_switch(prev, next); | 4125 | sched_info_switch(prev, next); |
diff --git a/kernel/timer.c b/kernel/timer.c index 68a9ae7679b7..353b9227c2ec 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -1252,6 +1252,12 @@ unsigned long get_next_timer_interrupt(unsigned long now) | |||
| 1252 | struct tvec_base *base = __get_cpu_var(tvec_bases); | 1252 | struct tvec_base *base = __get_cpu_var(tvec_bases); |
| 1253 | unsigned long expires; | 1253 | unsigned long expires; |
| 1254 | 1254 | ||
| 1255 | /* | ||
| 1256 | * Pretend that there is no timer pending if the cpu is offline. | ||
| 1257 | * Possible pending timers will be migrated later to an active cpu. | ||
| 1258 | */ | ||
| 1259 | if (cpu_is_offline(smp_processor_id())) | ||
| 1260 | return now + NEXT_TIMER_MAX_DELTA; | ||
| 1255 | spin_lock(&base->lock); | 1261 | spin_lock(&base->lock); |
| 1256 | if (time_before_eq(base->next_timer, base->timer_jiffies)) | 1262 | if (time_before_eq(base->next_timer, base->timer_jiffies)) |
| 1257 | base->next_timer = __next_timer_interrupt(base); | 1263 | base->next_timer = __next_timer_interrupt(base); |
| @@ -1319,7 +1325,7 @@ void do_timer(unsigned long ticks) | |||
| 1319 | { | 1325 | { |
| 1320 | jiffies_64 += ticks; | 1326 | jiffies_64 += ticks; |
| 1321 | update_wall_time(); | 1327 | update_wall_time(); |
| 1322 | calc_global_load(); | 1328 | calc_global_load(ticks); |
| 1323 | } | 1329 | } |
| 1324 | 1330 | ||
| 1325 | #ifdef __ARCH_WANT_SYS_ALARM | 1331 | #ifdef __ARCH_WANT_SYS_ALARM |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c380612273bf..f8cf959bad45 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -2338,11 +2338,19 @@ tracing_write_stub(struct file *filp, const char __user *ubuf, | |||
| 2338 | return count; | 2338 | return count; |
| 2339 | } | 2339 | } |
| 2340 | 2340 | ||
| 2341 | static loff_t tracing_seek(struct file *file, loff_t offset, int origin) | ||
| 2342 | { | ||
| 2343 | if (file->f_mode & FMODE_READ) | ||
| 2344 | return seq_lseek(file, offset, origin); | ||
| 2345 | else | ||
| 2346 | return 0; | ||
| 2347 | } | ||
| 2348 | |||
| 2341 | static const struct file_operations tracing_fops = { | 2349 | static const struct file_operations tracing_fops = { |
| 2342 | .open = tracing_open, | 2350 | .open = tracing_open, |
| 2343 | .read = seq_read, | 2351 | .read = seq_read, |
| 2344 | .write = tracing_write_stub, | 2352 | .write = tracing_write_stub, |
| 2345 | .llseek = seq_lseek, | 2353 | .llseek = tracing_seek, |
| 2346 | .release = tracing_release, | 2354 | .release = tracing_release, |
| 2347 | }; | 2355 | }; |
| 2348 | 2356 | ||
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 58e933a20544..39667174971d 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
| @@ -119,7 +119,7 @@ static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM; | |||
| 119 | 119 | ||
| 120 | static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) | 120 | static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) |
| 121 | { | 121 | { |
| 122 | rp->r_info = ELF_R_INFO(sym, type); | 122 | rp->r_info = _w(ELF_R_INFO(sym, type)); |
| 123 | } | 123 | } |
| 124 | static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; | 124 | static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; |
| 125 | 125 | ||
diff --git a/scripts/tags.sh b/scripts/tags.sh index 8509bb512935..bbbe584d4494 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
| @@ -125,7 +125,9 @@ exuberant() | |||
| 125 | -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ | 125 | -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ |
| 126 | --extra=+f --c-kinds=-px \ | 126 | --extra=+f --c-kinds=-px \ |
| 127 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ | 127 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ |
| 128 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' | 128 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ |
| 129 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ | ||
| 130 | --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' | ||
| 129 | 131 | ||
| 130 | all_kconfigs | xargs $1 -a \ | 132 | all_kconfigs | xargs $1 -a \ |
| 131 | --langdef=kconfig --language-force=kconfig \ | 133 | --langdef=kconfig --language-force=kconfig \ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2d7d7de8498a..427da45d7906 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -10830,7 +10830,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
| 10830 | { | 10830 | { |
| 10831 | struct alc_spec *spec = codec->spec; | 10831 | struct alc_spec *spec = codec->spec; |
| 10832 | struct auto_pin_cfg *cfg = &spec->autocfg; | 10832 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 10833 | int i, err; | 10833 | int i, err, type; |
| 10834 | int type_idx = 0; | ||
| 10834 | hda_nid_t nid; | 10835 | hda_nid_t nid; |
| 10835 | 10836 | ||
| 10836 | for (i = 0; i < cfg->num_inputs; i++) { | 10837 | for (i = 0; i < cfg->num_inputs; i++) { |
| @@ -10839,9 +10840,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
| 10839 | nid = cfg->inputs[i].pin; | 10840 | nid = cfg->inputs[i].pin; |
| 10840 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { | 10841 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { |
| 10841 | char label[32]; | 10842 | char label[32]; |
| 10843 | type = cfg->inputs[i].type; | ||
| 10844 | if (i > 0 && type == cfg->inputs[i - 1].type) | ||
| 10845 | type_idx++; | ||
| 10846 | else | ||
| 10847 | type_idx = 0; | ||
| 10842 | snprintf(label, sizeof(label), "%s Boost", | 10848 | snprintf(label, sizeof(label), "%s Boost", |
| 10843 | hda_get_autocfg_input_label(codec, cfg, i)); | 10849 | hda_get_autocfg_input_label(codec, cfg, i)); |
| 10844 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, | 10850 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, |
| 10851 | type_idx, | ||
| 10845 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10852 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
| 10846 | if (err < 0) | 10853 | if (err < 0) |
| 10847 | return err; | 10854 | return err; |
| @@ -14800,6 +14807,8 @@ static int alc269_resume(struct hda_codec *codec) | |||
| 14800 | enum { | 14807 | enum { |
| 14801 | ALC269_FIXUP_SONY_VAIO, | 14808 | ALC269_FIXUP_SONY_VAIO, |
| 14802 | ALC269_FIXUP_DELL_M101Z, | 14809 | ALC269_FIXUP_DELL_M101Z, |
| 14810 | ALC269_FIXUP_LENOVO_EDGE14, | ||
| 14811 | ALC269_FIXUP_ASUS_G73JW, | ||
| 14803 | }; | 14812 | }; |
| 14804 | 14813 | ||
| 14805 | static const struct alc_fixup alc269_fixups[] = { | 14814 | static const struct alc_fixup alc269_fixups[] = { |
| @@ -14817,11 +14826,22 @@ static const struct alc_fixup alc269_fixups[] = { | |||
| 14817 | {} | 14826 | {} |
| 14818 | } | 14827 | } |
| 14819 | }, | 14828 | }, |
| 14829 | [ALC269_FIXUP_LENOVO_EDGE14] = { | ||
| 14830 | .sku = ALC_FIXUP_SKU_IGNORE, | ||
| 14831 | }, | ||
| 14832 | [ALC269_FIXUP_ASUS_G73JW] = { | ||
| 14833 | .pins = (const struct alc_pincfg[]) { | ||
| 14834 | { 0x17, 0x99130111 }, /* subwoofer */ | ||
| 14835 | { } | ||
| 14836 | } | ||
| 14837 | }, | ||
| 14820 | }; | 14838 | }; |
| 14821 | 14839 | ||
| 14822 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14840 | static struct snd_pci_quirk alc269_fixup_tbl[] = { |
| 14823 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14841 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
| 14824 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 14842 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
| 14843 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14), | ||
| 14844 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | ||
| 14825 | {} | 14845 | {} |
| 14826 | }; | 14846 | }; |
| 14827 | 14847 | ||
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 879dff2714dd..8725d4e75431 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
| @@ -161,7 +161,7 @@ | |||
| 161 | static const u16 wm8580_reg[] = { | 161 | static const u16 wm8580_reg[] = { |
| 162 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ | 162 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ |
| 163 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ | 163 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ |
| 164 | 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/ | 164 | 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/ |
| 165 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ | 165 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ |
| 166 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ | 166 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ |
| 167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ | 167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index fca60a0b57b8..9001cc48ba13 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
| @@ -818,7 +818,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, | |||
| 818 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 818 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 819 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 819 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
| 820 | 820 | ||
| 821 | return wm8904->deemph; | 821 | ucontrol->value.enumerated.item[0] = wm8904->deemph; |
| 822 | return 0; | ||
| 822 | } | 823 | } |
| 823 | 824 | ||
| 824 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, | 825 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index f89ad6c9a80b..9cbab8e1de01 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
| @@ -380,7 +380,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, | |||
| 380 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 380 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 381 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 381 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
| 382 | 382 | ||
| 383 | return wm8955->deemph; | 383 | ucontrol->value.enumerated.item[0] = wm8955->deemph; |
| 384 | return 0; | ||
| 384 | } | 385 | } |
| 385 | 386 | ||
| 386 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, | 387 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8d5efb333c33..21986c42272f 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
| @@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, | |||
| 138 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 138 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 139 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 139 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
| 140 | 140 | ||
| 141 | return wm8960->deemph; | 141 | ucontrol->value.enumerated.item[0] = wm8960->deemph; |
| 142 | return 0; | ||
| 142 | } | 143 | } |
| 143 | 144 | ||
| 144 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, | 145 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 75ed6491222d..c721502833bc 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
| 944 | case SND_SOC_DAPM_STREAM_RESUME: | 944 | case SND_SOC_DAPM_STREAM_RESUME: |
| 945 | sys_power = 1; | 945 | sys_power = 1; |
| 946 | break; | 946 | break; |
| 947 | case SND_SOC_DAPM_STREAM_STOP: | ||
| 948 | sys_power = !!codec->active; | ||
| 949 | break; | ||
| 947 | case SND_SOC_DAPM_STREAM_SUSPEND: | 950 | case SND_SOC_DAPM_STREAM_SUSPEND: |
| 948 | sys_power = 0; | 951 | sys_power = 0; |
| 949 | break; | 952 | break; |
