diff options
Diffstat (limited to 'drivers')
605 files changed, 14685 insertions, 5881 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f4f632917509..b0243fd55ac0 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -312,9 +312,13 @@ config ACPI_DEBUG | |||
| 312 | bool "Debug Statements" | 312 | bool "Debug Statements" |
| 313 | default n | 313 | default n |
| 314 | help | 314 | help |
| 315 | The ACPI driver can optionally report errors with a great deal | 315 | The ACPI subsystem can produce debug output. Saying Y enables this |
| 316 | of verbosity. Saying Y enables these statements. This will increase | 316 | output and increases the kernel size by around 50K. |
| 317 | your kernel size by around 50K. | 317 | |
| 318 | Use the acpi.debug_layer and acpi.debug_level kernel command-line | ||
| 319 | parameters documented in Documentation/acpi/debug.txt and | ||
| 320 | Documentation/kernel-parameters.txt to control the type and | ||
| 321 | amount of debug output. | ||
| 318 | 322 | ||
| 319 | config ACPI_DEBUG_FUNC_TRACE | 323 | config ACPI_DEBUG_FUNC_TRACE |
| 320 | bool "Additionally enable ACPI function tracing" | 324 | bool "Additionally enable ACPI function tracing" |
| @@ -324,14 +328,6 @@ config ACPI_DEBUG_FUNC_TRACE | |||
| 324 | ACPI Debug Statements slow down ACPI processing. Function trace | 328 | ACPI Debug Statements slow down ACPI processing. Function trace |
| 325 | is about half of the penalty and is rarely useful. | 329 | is about half of the penalty and is rarely useful. |
| 326 | 330 | ||
| 327 | config ACPI_EC | ||
| 328 | bool | ||
| 329 | default y | ||
| 330 | help | ||
| 331 | This driver is required on some systems for the proper operation of | ||
| 332 | the battery and thermal drivers. If you are compiling for a | ||
| 333 | mobile system, say Y. | ||
| 334 | |||
| 335 | config ACPI_PCI_SLOT | 331 | config ACPI_PCI_SLOT |
| 336 | tristate "PCI slot detection driver" | 332 | tristate "PCI slot detection driver" |
| 337 | default n | 333 | default n |
| @@ -341,10 +337,6 @@ config ACPI_PCI_SLOT | |||
| 341 | help you correlate PCI bus addresses with the physical geography | 337 | help you correlate PCI bus addresses with the physical geography |
| 342 | of your slots. If you are unsure, say N. | 338 | of your slots. If you are unsure, say N. |
| 343 | 339 | ||
| 344 | config ACPI_POWER | ||
| 345 | bool | ||
| 346 | default y | ||
| 347 | |||
| 348 | config ACPI_SYSTEM | 340 | config ACPI_SYSTEM |
| 349 | bool | 341 | bool |
| 350 | default y | 342 | default y |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d91c027ece8f..3c0c93300f12 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
| @@ -39,19 +39,23 @@ obj-y += sleep/ | |||
| 39 | obj-y += bus.o glue.o | 39 | obj-y += bus.o glue.o |
| 40 | obj-y += scan.o | 40 | obj-y += scan.o |
| 41 | # Keep EC driver first. Initialization of others depend on it. | 41 | # Keep EC driver first. Initialization of others depend on it. |
| 42 | obj-$(CONFIG_ACPI_EC) += ec.o | 42 | obj-y += ec.o |
| 43 | obj-$(CONFIG_ACPI_AC) += ac.o | 43 | obj-$(CONFIG_ACPI_AC) += ac.o |
| 44 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | 44 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
| 45 | obj-$(CONFIG_ACPI_BUTTON) += button.o | 45 | obj-$(CONFIG_ACPI_BUTTON) += button.o |
| 46 | obj-$(CONFIG_ACPI_FAN) += fan.o | 46 | obj-$(CONFIG_ACPI_FAN) += fan.o |
| 47 | obj-$(CONFIG_ACPI_DOCK) += dock.o | 47 | obj-$(CONFIG_ACPI_DOCK) += dock.o |
| 48 | obj-$(CONFIG_ACPI_VIDEO) += video.o | 48 | obj-$(CONFIG_ACPI_VIDEO) += video.o |
| 49 | ifdef CONFIG_ACPI_VIDEO | ||
| 50 | obj-y += video_detect.o | ||
| 51 | endif | ||
| 52 | |||
| 49 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 53 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
| 50 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o | 54 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o |
| 51 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o | 55 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o |
| 52 | obj-$(CONFIG_ACPI_CONTAINER) += container.o | 56 | obj-$(CONFIG_ACPI_CONTAINER) += container.o |
| 53 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o | 57 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o |
| 54 | obj-$(CONFIG_ACPI_POWER) += power.o | 58 | obj-y += power.o |
| 55 | obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o | 59 | obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o |
| 56 | obj-$(CONFIG_ACPI_DEBUG) += debug.o | 60 | obj-$(CONFIG_ACPI_DEBUG) += debug.o |
| 57 | obj-$(CONFIG_ACPI_NUMA) += numa.o | 61 | obj-$(CONFIG_ACPI_NUMA) += numa.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d72a1b6c8a94..9b917dac7732 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <acpi/acpi_bus.h> | 37 | #include <acpi/acpi_bus.h> |
| 38 | #include <acpi/acpi_drivers.h> | 38 | #include <acpi/acpi_drivers.h> |
| 39 | 39 | ||
| 40 | #define ACPI_AC_COMPONENT 0x00020000 | ||
| 41 | #define ACPI_AC_CLASS "ac_adapter" | 40 | #define ACPI_AC_CLASS "ac_adapter" |
| 42 | #define ACPI_AC_DEVICE_NAME "AC Adapter" | 41 | #define ACPI_AC_DEVICE_NAME "AC Adapter" |
| 43 | #define ACPI_AC_FILE_STATE "state" | 42 | #define ACPI_AC_FILE_STATE "state" |
| @@ -242,7 +241,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) | |||
| 242 | acpi_ac_get_state(ac); | 241 | acpi_ac_get_state(ac); |
| 243 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); | 242 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); |
| 244 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 243 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 245 | device->dev.bus_id, event, | 244 | dev_name(&device->dev), event, |
| 246 | (u32) ac->state); | 245 | (u32) ac->state); |
| 247 | #ifdef CONFIG_ACPI_SYSFS_POWER | 246 | #ifdef CONFIG_ACPI_SYSFS_POWER |
| 248 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 247 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 71d21c51c45f..63a17b55b39b 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/memory_hotplug.h> | 32 | #include <linux/memory_hotplug.h> |
| 33 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
| 34 | 34 | ||
| 35 | #define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL | ||
| 36 | #define ACPI_MEMORY_DEVICE_CLASS "memory" | 35 | #define ACPI_MEMORY_DEVICE_CLASS "memory" |
| 37 | #define ACPI_MEMORY_DEVICE_HID "PNP0C80" | 36 | #define ACPI_MEMORY_DEVICE_HID "PNP0C80" |
| 38 | #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" | 37 | #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2133e89ad9a..1423b0c0cd2e 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -46,7 +46,6 @@ | |||
| 46 | 46 | ||
| 47 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF | 47 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
| 48 | 48 | ||
| 49 | #define ACPI_BATTERY_COMPONENT 0x00040000 | ||
| 50 | #define ACPI_BATTERY_CLASS "battery" | 49 | #define ACPI_BATTERY_CLASS "battery" |
| 51 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 50 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
| 52 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 | 51 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 |
| @@ -782,7 +781,7 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
| 782 | acpi_bus_generate_proc_event(device, event, | 781 | acpi_bus_generate_proc_event(device, event, |
| 783 | acpi_battery_present(battery)); | 782 | acpi_battery_present(battery)); |
| 784 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 783 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 785 | device->dev.bus_id, event, | 784 | dev_name(&device->dev), event, |
| 786 | acpi_battery_present(battery)); | 785 | acpi_battery_present(battery)); |
| 787 | #ifdef CONFIG_ACPI_SYSFS_POWER | 786 | #ifdef CONFIG_ACPI_SYSFS_POWER |
| 788 | /* acpi_batter_update could remove power_supply object */ | 787 | /* acpi_batter_update could remove power_supply object */ |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index ea92bac42c53..09c69806c1fc 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
| @@ -176,16 +176,6 @@ static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) | |||
| 176 | acpi_dmi_osi_linux(1, d); /* enable */ | 176 | acpi_dmi_osi_linux(1, d); /* enable */ |
| 177 | return 0; | 177 | return 0; |
| 178 | } | 178 | } |
| 179 | static int __init dmi_disable_osi_linux(const struct dmi_system_id *d) | ||
| 180 | { | ||
| 181 | acpi_dmi_osi_linux(0, d); /* disable */ | ||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d) | ||
| 185 | { | ||
| 186 | acpi_dmi_osi_linux(-1, d); /* unknown */ | ||
| 187 | return 0; | ||
| 188 | } | ||
| 189 | static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | 179 | static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) |
| 190 | { | 180 | { |
| 191 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 181 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
| @@ -193,295 +183,21 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | |||
| 193 | return 0; | 183 | return 0; |
| 194 | } | 184 | } |
| 195 | 185 | ||
| 196 | /* | ||
| 197 | * Most BIOS that invoke OSI(Linux) do nothing with it. | ||
| 198 | * But some cause Linux to break. | ||
| 199 | * Only a couple use it to make Linux run better. | ||
| 200 | * | ||
| 201 | * Thus, Linux should continue to disable OSI(Linux) by default, | ||
| 202 | * should continue to discourage BIOS writers from using it, and | ||
| 203 | * should whitelist the few existing systems that require it. | ||
| 204 | * | ||
| 205 | * If it appears clear a vendor isn't using OSI(Linux) | ||
| 206 | * for anything constructive, blacklist them by name to disable | ||
| 207 | * unnecessary dmesg warnings on all of their products. | ||
| 208 | */ | ||
| 209 | |||
| 210 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | 186 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { |
| 211 | /* | ||
| 212 | * Disable OSI(Linux) warnings on all "Acer, inc." | ||
| 213 | * | ||
| 214 | * _OSI(Linux) disables the latest Windows BIOS code: | ||
| 215 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"), | ||
| 216 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"), | ||
| 217 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), | ||
| 218 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"), | ||
| 219 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"), | ||
| 220 | * _OSI(Linux) effect unknown: | ||
| 221 | * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"), | ||
| 222 | */ | ||
| 223 | /* | ||
| 224 | * note that dmi_check_system() uses strstr() | ||
| 225 | * to match sub-strings rather than !strcmp(), | ||
| 226 | * so "Acer" below matches "Acer, inc." above. | ||
| 227 | */ | ||
| 228 | /* | ||
| 229 | * Disable OSI(Linux) warnings on all "Acer" | ||
| 230 | * | ||
| 231 | * _OSI(Linux) effect unknown: | ||
| 232 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), | ||
| 233 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"), | ||
| 234 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"), | ||
| 235 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"), | ||
| 236 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"), | ||
| 237 | * | ||
| 238 | * _OSI(Linux) is a NOP: | ||
| 239 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), | ||
| 240 | * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), | ||
| 241 | */ | ||
| 242 | { | ||
| 243 | .callback = dmi_disable_osi_linux, | ||
| 244 | .ident = "Acer", | ||
| 245 | .matches = { | ||
| 246 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 247 | }, | ||
| 248 | }, | ||
| 249 | /* | ||
| 250 | * Disable OSI(Linux) warnings on all "Apple Computer, Inc." | ||
| 251 | * Disable OSI(Linux) warnings on all "Apple Inc." | ||
| 252 | * | ||
| 253 | * _OSI(Linux) confirmed to be a NOP: | ||
| 254 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
| 255 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), | ||
| 256 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), | ||
| 257 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"), | ||
| 258 | * _OSI(Linux) effect unknown: | ||
| 259 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"), | ||
| 260 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), | ||
| 261 | */ | ||
| 262 | { | ||
| 263 | .callback = dmi_disable_osi_linux, | ||
| 264 | .ident = "Apple", | ||
| 265 | .matches = { | ||
| 266 | DMI_MATCH(DMI_SYS_VENDOR, "Apple"), | ||
| 267 | }, | ||
| 268 | }, | ||
| 269 | /* | ||
| 270 | * Disable OSI(Linux) warnings on all "BenQ" | ||
| 271 | * | ||
| 272 | * _OSI(Linux) confirmed to be a NOP: | ||
| 273 | * DMI_MATCH(DMI_PRODUCT_NAME, "Joybook S31"), | ||
| 274 | */ | ||
| 275 | { | ||
| 276 | .callback = dmi_disable_osi_linux, | ||
| 277 | .ident = "BenQ", | ||
| 278 | .matches = { | ||
| 279 | DMI_MATCH(DMI_SYS_VENDOR, "BenQ"), | ||
| 280 | }, | ||
| 281 | }, | ||
| 282 | /* | ||
| 283 | * Disable OSI(Linux) warnings on all "Clevo Co." | ||
| 284 | * | ||
| 285 | * _OSI(Linux) confirmed to be a NOP: | ||
| 286 | * DMI_MATCH(DMI_PRODUCT_NAME, "M570RU"), | ||
| 287 | */ | ||
| 288 | { | ||
| 289 | .callback = dmi_disable_osi_linux, | ||
| 290 | .ident = "Clevo", | ||
| 291 | .matches = { | ||
| 292 | DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."), | ||
| 293 | }, | ||
| 294 | }, | ||
| 295 | /* | ||
| 296 | * Disable OSI(Linux) warnings on all "COMPAL" | ||
| 297 | * | ||
| 298 | * _OSI(Linux) confirmed to be a NOP: | ||
| 299 | * DMI_MATCH(DMI_BOARD_NAME, "HEL8X"), | ||
| 300 | * _OSI(Linux) unknown effect: | ||
| 301 | * DMI_MATCH(DMI_BOARD_NAME, "IFL91"), | ||
| 302 | */ | ||
| 303 | { | ||
| 304 | .callback = dmi_disable_osi_linux, | ||
| 305 | .ident = "Compal", | ||
| 306 | .matches = { | ||
| 307 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
| 308 | }, | ||
| 309 | }, | ||
| 310 | { /* OSI(Linux) touches USB, unknown side-effect */ | ||
| 311 | .callback = dmi_disable_osi_linux, | ||
| 312 | .ident = "Dell Dimension 5150", | ||
| 313 | .matches = { | ||
| 314 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 315 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM051"), | ||
| 316 | }, | ||
| 317 | }, | ||
| 318 | { /* OSI(Linux) is a NOP */ | ||
| 319 | .callback = dmi_disable_osi_linux, | ||
| 320 | .ident = "Dell i1501", | ||
| 321 | .matches = { | ||
| 322 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 323 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"), | ||
| 324 | }, | ||
| 325 | }, | ||
| 326 | { /* OSI(Linux) effect unknown */ | ||
| 327 | .callback = dmi_unknown_osi_linux, | ||
| 328 | .ident = "Dell Latitude D830", | ||
| 329 | .matches = { | ||
| 330 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 331 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"), | ||
| 332 | }, | ||
| 333 | }, | ||
| 334 | { /* OSI(Linux) effect unknown */ | ||
| 335 | .callback = dmi_unknown_osi_linux, | ||
| 336 | .ident = "Dell OptiPlex GX620", | ||
| 337 | .matches = { | ||
| 338 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 339 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"), | ||
| 340 | }, | ||
| 341 | }, | ||
| 342 | { /* OSI(Linux) causes some USB initialization to not run */ | ||
| 343 | .callback = dmi_unknown_osi_linux, | ||
| 344 | .ident = "Dell OptiPlex 755", | ||
| 345 | .matches = { | ||
| 346 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 347 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 755"), | ||
| 348 | }, | ||
| 349 | }, | ||
| 350 | { /* OSI(Linux) effect unknown */ | ||
| 351 | .callback = dmi_unknown_osi_linux, | ||
| 352 | .ident = "Dell PE 1900", | ||
| 353 | .matches = { | ||
| 354 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 355 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"), | ||
| 356 | }, | ||
| 357 | }, | ||
| 358 | { /* OSI(Linux) is a NOP */ | ||
| 359 | .callback = dmi_unknown_osi_linux, | ||
| 360 | .ident = "Dell PE 1950", | ||
| 361 | .matches = { | ||
| 362 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 363 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), | ||
| 364 | }, | ||
| 365 | }, | ||
| 366 | { /* OSI(Linux) is a NOP */ | ||
| 367 | .callback = dmi_disable_osi_linux, | ||
| 368 | .ident = "Dell PE R200", | ||
| 369 | .matches = { | ||
| 370 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 371 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R200"), | ||
| 372 | }, | ||
| 373 | }, | ||
| 374 | { /* OSI(Linux) touches USB */ | ||
| 375 | .callback = dmi_disable_osi_linux, | ||
| 376 | .ident = "Dell PR 390", | ||
| 377 | .matches = { | ||
| 378 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 379 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"), | ||
| 380 | }, | ||
| 381 | }, | ||
| 382 | { /* OSI(Linux) touches USB */ | ||
| 383 | .callback = dmi_unknown_osi_linux, | ||
| 384 | .ident = "Dell PR 390", | ||
| 385 | .matches = { | ||
| 386 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 387 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 690"), | ||
| 388 | }, | ||
| 389 | }, | ||
| 390 | { /* OSI(Linux) unknown - ASL looks benign, but may effect dock/SMM */ | ||
| 391 | .callback = dmi_unknown_osi_linux, | ||
| 392 | .ident = "Dell PR M4300", | ||
| 393 | .matches = { | ||
| 394 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 395 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision M4300"), | ||
| 396 | }, | ||
| 397 | }, | ||
| 398 | { /* OSI(Linux) is a NOP */ | ||
| 399 | .callback = dmi_disable_osi_linux, | ||
| 400 | .ident = "Dell Vostro 1000", | ||
| 401 | .matches = { | ||
| 402 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 403 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1000"), | ||
| 404 | }, | ||
| 405 | }, | ||
| 406 | { /* OSI(Linux) effect unknown */ | ||
| 407 | .callback = dmi_unknown_osi_linux, | ||
| 408 | .ident = "Dell PE SC440", | ||
| 409 | .matches = { | ||
| 410 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 411 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"), | ||
| 412 | }, | ||
| 413 | }, | ||
| 414 | { /* OSI(Linux) effect unknown */ | ||
| 415 | .callback = dmi_unknown_osi_linux, | ||
| 416 | .ident = "Dialogue Flybook V5", | ||
| 417 | .matches = { | ||
| 418 | DMI_MATCH(DMI_SYS_VENDOR, "Dialogue Technology Corporation"), | ||
| 419 | DMI_MATCH(DMI_PRODUCT_NAME, "Flybook V5"), | ||
| 420 | }, | ||
| 421 | }, | ||
| 422 | /* | ||
| 423 | * Disable OSI(Linux) warnings on all "FUJITSU SIEMENS" | ||
| 424 | * | ||
| 425 | * _OSI(Linux) disables latest Windows BIOS code: | ||
| 426 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2510"), | ||
| 427 | * _OSI(Linux) confirmed to be a NOP: | ||
| 428 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"), | ||
| 429 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"), | ||
| 430 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"), | ||
| 431 | * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | ||
| 432 | * _OSI(Linux) unknown effect: | ||
| 433 | * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"), | ||
| 434 | * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"), | ||
| 435 | */ | ||
| 436 | { | ||
| 437 | .callback = dmi_disable_osi_linux, | ||
| 438 | .ident = "Fujitsu Siemens", | ||
| 439 | .matches = { | ||
| 440 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
| 441 | }, | ||
| 442 | }, | ||
| 443 | { | 187 | { |
| 444 | .callback = dmi_disable_osi_vista, | 188 | .callback = dmi_disable_osi_vista, |
| 445 | .ident = "Fujitsu Siemens", | 189 | .ident = "Fujitsu Siemens", |
| 446 | .matches = { | 190 | .matches = { |
| 447 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 191 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
| 448 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | 192 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), |
| 449 | }, | 193 | }, |
| 450 | }, | 194 | }, |
| 195 | |||
| 451 | /* | 196 | /* |
| 452 | * Disable OSI(Linux) warnings on all "Hewlett-Packard" | 197 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
| 453 | * | 198 | * Linux ignores it, except for the machines enumerated below. |
| 454 | * _OSI(Linux) confirmed to be a NOP: | ||
| 455 | * .ident = "HP Pavilion tx 1000" | ||
| 456 | * DMI_MATCH(DMI_BOARD_NAME, "30BF"), | ||
| 457 | * .ident = "HP Pavilion dv2000" | ||
| 458 | * DMI_MATCH(DMI_BOARD_NAME, "30B5"), | ||
| 459 | * .ident = "HP Pavilion dv5000", | ||
| 460 | * DMI_MATCH(DMI_BOARD_NAME, "30A7"), | ||
| 461 | * .ident = "HP Pavilion dv6300 30BC", | ||
| 462 | * DMI_MATCH(DMI_BOARD_NAME, "30BC"), | ||
| 463 | * .ident = "HP Pavilion dv6000", | ||
| 464 | * DMI_MATCH(DMI_BOARD_NAME, "30B7"), | ||
| 465 | * DMI_MATCH(DMI_BOARD_NAME, "30B8"), | ||
| 466 | * .ident = "HP Pavilion dv9000", | ||
| 467 | * DMI_MATCH(DMI_BOARD_NAME, "30B9"), | ||
| 468 | * .ident = "HP Pavilion dv9500", | ||
| 469 | * DMI_MATCH(DMI_BOARD_NAME, "30CB"), | ||
| 470 | * .ident = "HP/Compaq Presario C500", | ||
| 471 | * DMI_MATCH(DMI_BOARD_NAME, "30C6"), | ||
| 472 | * .ident = "HP/Compaq Presario F500", | ||
| 473 | * DMI_MATCH(DMI_BOARD_NAME, "30D3"), | ||
| 474 | * _OSI(Linux) unknown effect: | ||
| 475 | * .ident = "HP Pavilion dv6500", | ||
| 476 | * DMI_MATCH(DMI_BOARD_NAME, "30D0"), | ||
| 477 | */ | 199 | */ |
| 478 | { | 200 | |
| 479 | .callback = dmi_disable_osi_linux, | ||
| 480 | .ident = "Hewlett-Packard", | ||
| 481 | .matches = { | ||
| 482 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 483 | }, | ||
| 484 | }, | ||
| 485 | /* | 201 | /* |
| 486 | * Lenovo has a mix of systems OSI(Linux) situations | 202 | * Lenovo has a mix of systems OSI(Linux) situations |
| 487 | * and thus we can not wildcard the vendor. | 203 | * and thus we can not wildcard the vendor. |
| @@ -519,113 +235,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
| 519 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), | 235 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), |
| 520 | }, | 236 | }, |
| 521 | }, | 237 | }, |
| 522 | { | ||
| 523 | .callback = dmi_disable_osi_linux, | ||
| 524 | .ident = "Lenovo 3000 V100", | ||
| 525 | .matches = { | ||
| 526 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 527 | DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), | ||
| 528 | }, | ||
| 529 | }, | ||
| 530 | { | ||
| 531 | .callback = dmi_disable_osi_linux, | ||
| 532 | .ident = "Lenovo 3000 N100", | ||
| 533 | .matches = { | ||
| 534 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 535 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | ||
| 536 | }, | ||
| 537 | }, | ||
| 538 | /* | ||
| 539 | * Disable OSI(Linux) warnings on all "LG Electronics" | ||
| 540 | * | ||
| 541 | * _OSI(Linux) confirmed to be a NOP: | ||
| 542 | * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"), | ||
| 543 | * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"), | ||
| 544 | * | ||
| 545 | * unknown: | ||
| 546 | * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"), | ||
| 547 | * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"), | ||
| 548 | */ | ||
| 549 | { | ||
| 550 | .callback = dmi_disable_osi_linux, | ||
| 551 | .ident = "LG", | ||
| 552 | .matches = { | ||
| 553 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | ||
| 554 | }, | ||
| 555 | }, | ||
| 556 | /* NEC - OSI(Linux) effect unknown */ | ||
| 557 | { | ||
| 558 | .callback = dmi_unknown_osi_linux, | ||
| 559 | .ident = "NEC VERSA M360", | ||
| 560 | .matches = { | ||
| 561 | DMI_MATCH(DMI_SYS_VENDOR, "NEC Computers SAS"), | ||
| 562 | DMI_MATCH(DMI_PRODUCT_NAME, "NEC VERSA M360"), | ||
| 563 | }, | ||
| 564 | }, | ||
| 565 | /* Panasonic */ | ||
| 566 | { | ||
| 567 | .callback = dmi_unknown_osi_linux, | ||
| 568 | .ident = "Panasonic", | ||
| 569 | .matches = { | ||
| 570 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
| 571 | /* Toughbook CF-52 */ | ||
| 572 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-52CCABVBG"), | ||
| 573 | }, | ||
| 574 | }, | ||
| 575 | /* | ||
| 576 | * Disable OSI(Linux) warnings on all "Samsung Electronics" | ||
| 577 | * | ||
| 578 | * OSI(Linux) disables PNP0C32 and other BIOS code for Windows: | ||
| 579 | * DMI_MATCH(DMI_PRODUCT_NAME, "R40P/R41P"), | ||
| 580 | * DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"), | ||
| 581 | */ | ||
| 582 | { | ||
| 583 | .callback = dmi_disable_osi_linux, | ||
| 584 | .ident = "Samsung", | ||
| 585 | .matches = { | ||
| 586 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
| 587 | }, | ||
| 588 | }, | ||
| 589 | /* | ||
| 590 | * Disable OSI(Linux) warnings on all "Sony Corporation" | ||
| 591 | * | ||
| 592 | * _OSI(Linux) is a NOP: | ||
| 593 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NR11S_S"), | ||
| 594 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"), | ||
| 595 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"), | ||
| 596 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"), | ||
| 597 | * _OSI(Linux) unknown effect: | ||
| 598 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"), | ||
| 599 | */ | ||
| 600 | { | ||
| 601 | .callback = dmi_disable_osi_linux, | ||
| 602 | .ident = "Sony", | ||
| 603 | .matches = { | ||
| 604 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
| 605 | }, | ||
| 606 | }, | ||
| 607 | /* | ||
| 608 | * Disable OSI(Linux) warnings on all "TOSHIBA" | ||
| 609 | * | ||
| 610 | * _OSI(Linux) breaks sound (bugzilla 7787): | ||
| 611 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"), | ||
| 612 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P105"), | ||
| 613 | * _OSI(Linux) is a NOP: | ||
| 614 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"), | ||
| 615 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A210"), | ||
| 616 | * _OSI(Linux) unknown effect: | ||
| 617 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A135"), | ||
| 618 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A200"), | ||
| 619 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P205"), | ||
| 620 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U305"), | ||
| 621 | */ | ||
| 622 | { | ||
| 623 | .callback = dmi_disable_osi_linux, | ||
| 624 | .ident = "Toshiba", | ||
| 625 | .matches = { | ||
| 626 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 627 | }, | ||
| 628 | }, | ||
| 629 | {} | 238 | {} |
| 630 | }; | 239 | }; |
| 631 | 240 | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c797c6473f31..7edf6d913c13 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -688,6 +688,14 @@ void __init acpi_early_init(void) | |||
| 688 | if (acpi_disabled) | 688 | if (acpi_disabled) |
| 689 | return; | 689 | return; |
| 690 | 690 | ||
| 691 | /* | ||
| 692 | * ACPI CA initializes acpi_dbg_level to non-zero, which means | ||
| 693 | * we get debug output merely by turning on CONFIG_ACPI_DEBUG. | ||
| 694 | * Turn it off so we don't get output unless the user specifies | ||
| 695 | * acpi.debug_level. | ||
| 696 | */ | ||
| 697 | acpi_dbg_level = 0; | ||
| 698 | |||
| 691 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); | 699 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); |
| 692 | 700 | ||
| 693 | /* enable workarounds, unless strict ACPI spec. compliance */ | 701 | /* enable workarounds, unless strict ACPI spec. compliance */ |
| @@ -774,7 +782,7 @@ static int __init acpi_bus_init(void) | |||
| 774 | "Unable to initialize ACPI OS objects\n"); | 782 | "Unable to initialize ACPI OS objects\n"); |
| 775 | goto error1; | 783 | goto error1; |
| 776 | } | 784 | } |
| 777 | #ifdef CONFIG_ACPI_EC | 785 | |
| 778 | /* | 786 | /* |
| 779 | * ACPI 2.0 requires the EC driver to be loaded and work before | 787 | * ACPI 2.0 requires the EC driver to be loaded and work before |
| 780 | * the EC device is found in the namespace (i.e. before acpi_initialize_objects() | 788 | * the EC device is found in the namespace (i.e. before acpi_initialize_objects() |
| @@ -785,7 +793,6 @@ static int __init acpi_bus_init(void) | |||
| 785 | */ | 793 | */ |
| 786 | status = acpi_ec_ecdt_probe(); | 794 | status = acpi_ec_ecdt_probe(); |
| 787 | /* Ignore result. Not having an ECDT is not fatal. */ | 795 | /* Ignore result. Not having an ECDT is not fatal. */ |
| 788 | #endif | ||
| 789 | 796 | ||
| 790 | status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); | 797 | status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); |
| 791 | if (ACPI_FAILURE(status)) { | 798 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index cb046c3fc3f2..171fd914f435 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
| 34 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
| 35 | 35 | ||
| 36 | #define ACPI_BUTTON_COMPONENT 0x00080000 | ||
| 37 | #define ACPI_BUTTON_CLASS "button" | 36 | #define ACPI_BUTTON_CLASS "button" |
| 38 | #define ACPI_BUTTON_FILE_INFO "info" | 37 | #define ACPI_BUTTON_FILE_INFO "info" |
| 39 | #define ACPI_BUTTON_FILE_STATE "state" | 38 | #define ACPI_BUTTON_FILE_STATE "state" |
| @@ -479,7 +478,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
| 479 | device->wakeup.gpe_number, | 478 | device->wakeup.gpe_number, |
| 480 | ACPI_GPE_TYPE_WAKE_RUN); | 479 | ACPI_GPE_TYPE_WAKE_RUN); |
| 481 | acpi_enable_gpe(device->wakeup.gpe_device, | 480 | acpi_enable_gpe(device->wakeup.gpe_device, |
| 482 | device->wakeup.gpe_number, ACPI_NOT_ISR); | 481 | device->wakeup.gpe_number); |
| 483 | device->wakeup.state.enabled = 1; | 482 | device->wakeup.state.enabled = 1; |
| 484 | } | 483 | } |
| 485 | 484 | ||
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 4441e84b28a9..307963bd1043 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | ACPI_MODULE_NAME("cm_sbs"); | 34 | ACPI_MODULE_NAME("cm_sbs"); |
| 35 | #define ACPI_AC_CLASS "ac_adapter" | 35 | #define ACPI_AC_CLASS "ac_adapter" |
| 36 | #define ACPI_BATTERY_CLASS "battery" | 36 | #define ACPI_BATTERY_CLASS "battery" |
| 37 | #define ACPI_SBS_COMPONENT 0x00080000 | ||
| 38 | #define _COMPONENT ACPI_SBS_COMPONENT | 37 | #define _COMPONENT ACPI_SBS_COMPONENT |
| 39 | static struct proc_dir_entry *acpi_ac_dir; | 38 | static struct proc_dir_entry *acpi_ac_dir; |
| 40 | static struct proc_dir_entry *acpi_battery_dir; | 39 | static struct proc_dir_entry *acpi_battery_dir; |
| @@ -105,9 +104,3 @@ void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | |||
| 105 | return; | 104 | return; |
| 106 | } | 105 | } |
| 107 | EXPORT_SYMBOL(acpi_unlock_battery_dir); | 106 | EXPORT_SYMBOL(acpi_unlock_battery_dir); |
| 108 | |||
| 109 | static int __init acpi_cm_sbs_init(void) | ||
| 110 | { | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | subsys_initcall(acpi_cm_sbs_init); | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 134818b265a9..17020c12623c 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #define INSTALL_NOTIFY_HANDLER 1 | 41 | #define INSTALL_NOTIFY_HANDLER 1 |
| 42 | #define UNINSTALL_NOTIFY_HANDLER 2 | 42 | #define UNINSTALL_NOTIFY_HANDLER 2 |
| 43 | 43 | ||
| 44 | #define ACPI_CONTAINER_COMPONENT 0x01000000 | ||
| 45 | #define _COMPONENT ACPI_CONTAINER_COMPONENT | 44 | #define _COMPONENT ACPI_CONTAINER_COMPONENT |
| 46 | ACPI_MODULE_NAME("container"); | 45 | ACPI_MODULE_NAME("container"); |
| 47 | 46 | ||
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index abf36b4b1d1d..c48396892008 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
| @@ -44,6 +44,21 @@ static const struct acpi_dlayer acpi_debug_layers[] = { | |||
| 44 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), | 44 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), |
| 45 | ACPI_DEBUG_INIT(ACPI_COMPILER), | 45 | ACPI_DEBUG_INIT(ACPI_COMPILER), |
| 46 | ACPI_DEBUG_INIT(ACPI_TOOLS), | 46 | ACPI_DEBUG_INIT(ACPI_TOOLS), |
| 47 | |||
| 48 | ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), | ||
| 49 | ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), | ||
| 50 | ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), | ||
| 51 | ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), | ||
| 52 | ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), | ||
| 53 | ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), | ||
| 54 | ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), | ||
| 55 | ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), | ||
| 56 | ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), | ||
| 57 | ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), | ||
| 58 | ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), | ||
| 59 | ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), | ||
| 60 | ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), | ||
| 61 | ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), | ||
| 47 | }; | 62 | }; |
| 48 | 63 | ||
| 49 | static const struct acpi_dlevel acpi_debug_levels[] = { | 64 | static const struct acpi_dlevel acpi_debug_levels[] = { |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ef42316f89f5..30f3ef236ecb 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -70,7 +70,7 @@ enum ec_command { | |||
| 70 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 70 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
| 71 | #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ | 71 | #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ |
| 72 | 72 | ||
| 73 | #define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts | 73 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
| 74 | per one transaction */ | 74 | per one transaction */ |
| 75 | 75 | ||
| 76 | enum { | 76 | enum { |
| @@ -100,8 +100,11 @@ struct transaction { | |||
| 100 | u8 *rdata; | 100 | u8 *rdata; |
| 101 | unsigned short irq_count; | 101 | unsigned short irq_count; |
| 102 | u8 command; | 102 | u8 command; |
| 103 | u8 wi; | ||
| 104 | u8 ri; | ||
| 103 | u8 wlen; | 105 | u8 wlen; |
| 104 | u8 rlen; | 106 | u8 rlen; |
| 107 | bool done; | ||
| 105 | }; | 108 | }; |
| 106 | 109 | ||
| 107 | static struct acpi_ec { | 110 | static struct acpi_ec { |
| @@ -178,34 +181,46 @@ static int ec_transaction_done(struct acpi_ec *ec) | |||
| 178 | unsigned long flags; | 181 | unsigned long flags; |
| 179 | int ret = 0; | 182 | int ret = 0; |
| 180 | spin_lock_irqsave(&ec->curr_lock, flags); | 183 | spin_lock_irqsave(&ec->curr_lock, flags); |
| 181 | if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen)) | 184 | if (!ec->curr || ec->curr->done) |
| 182 | ret = 1; | 185 | ret = 1; |
| 183 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 186 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
| 184 | return ret; | 187 | return ret; |
| 185 | } | 188 | } |
| 186 | 189 | ||
| 190 | static void start_transaction(struct acpi_ec *ec) | ||
| 191 | { | ||
| 192 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; | ||
| 193 | ec->curr->done = false; | ||
| 194 | acpi_ec_write_cmd(ec, ec->curr->command); | ||
| 195 | } | ||
| 196 | |||
| 187 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 197 | static void gpe_transaction(struct acpi_ec *ec, u8 status) |
| 188 | { | 198 | { |
| 189 | unsigned long flags; | 199 | unsigned long flags; |
| 190 | spin_lock_irqsave(&ec->curr_lock, flags); | 200 | spin_lock_irqsave(&ec->curr_lock, flags); |
| 191 | if (!ec->curr) | 201 | if (!ec->curr) |
| 192 | goto unlock; | 202 | goto unlock; |
| 193 | if (ec->curr->wlen > 0) { | 203 | if (ec->curr->wlen > ec->curr->wi) { |
| 194 | if ((status & ACPI_EC_FLAG_IBF) == 0) { | 204 | if ((status & ACPI_EC_FLAG_IBF) == 0) |
| 195 | acpi_ec_write_data(ec, *(ec->curr->wdata++)); | 205 | acpi_ec_write_data(ec, |
| 196 | --ec->curr->wlen; | 206 | ec->curr->wdata[ec->curr->wi++]); |
| 197 | } else | 207 | else |
| 198 | /* false interrupt, state didn't change */ | 208 | goto err; |
| 199 | ++ec->curr->irq_count; | 209 | } else if (ec->curr->rlen > ec->curr->ri) { |
| 200 | |||
| 201 | } else if (ec->curr->rlen > 0) { | ||
| 202 | if ((status & ACPI_EC_FLAG_OBF) == 1) { | 210 | if ((status & ACPI_EC_FLAG_OBF) == 1) { |
| 203 | *(ec->curr->rdata++) = acpi_ec_read_data(ec); | 211 | ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); |
| 204 | --ec->curr->rlen; | 212 | if (ec->curr->rlen == ec->curr->ri) |
| 213 | ec->curr->done = true; | ||
| 205 | } else | 214 | } else |
| 206 | /* false interrupt, state didn't change */ | 215 | goto err; |
| 207 | ++ec->curr->irq_count; | 216 | } else if (ec->curr->wlen == ec->curr->wi && |
| 208 | } | 217 | (status & ACPI_EC_FLAG_IBF) == 0) |
| 218 | ec->curr->done = true; | ||
| 219 | goto unlock; | ||
| 220 | err: | ||
| 221 | /* false interrupt, state didn't change */ | ||
| 222 | if (in_interrupt()) | ||
| 223 | ++ec->curr->irq_count; | ||
| 209 | unlock: | 224 | unlock: |
| 210 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 225 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
| 211 | } | 226 | } |
| @@ -215,6 +230,15 @@ static int acpi_ec_wait(struct acpi_ec *ec) | |||
| 215 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | 230 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), |
| 216 | msecs_to_jiffies(ACPI_EC_DELAY))) | 231 | msecs_to_jiffies(ACPI_EC_DELAY))) |
| 217 | return 0; | 232 | return 0; |
| 233 | /* try restart command if we get any false interrupts */ | ||
| 234 | if (ec->curr->irq_count && | ||
| 235 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
| 236 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
| 237 | start_transaction(ec); | ||
| 238 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
| 239 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
| 240 | return 0; | ||
| 241 | } | ||
| 218 | /* missing GPEs, switch back to poll mode */ | 242 | /* missing GPEs, switch back to poll mode */ |
| 219 | if (printk_ratelimit()) | 243 | if (printk_ratelimit()) |
| 220 | pr_info(PREFIX "missing confirmations, " | 244 | pr_info(PREFIX "missing confirmations, " |
| @@ -239,10 +263,10 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
| 239 | static int ec_poll(struct acpi_ec *ec) | 263 | static int ec_poll(struct acpi_ec *ec) |
| 240 | { | 264 | { |
| 241 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 265 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
| 242 | msleep(1); | 266 | udelay(ACPI_EC_UDELAY); |
| 243 | while (time_before(jiffies, delay)) { | 267 | while (time_before(jiffies, delay)) { |
| 244 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 268 | gpe_transaction(ec, acpi_ec_read_status(ec)); |
| 245 | msleep(1); | 269 | udelay(ACPI_EC_UDELAY); |
| 246 | if (ec_transaction_done(ec)) | 270 | if (ec_transaction_done(ec)) |
| 247 | return 0; | 271 | return 0; |
| 248 | } | 272 | } |
| @@ -259,14 +283,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
| 259 | /* disable GPE during transaction if storm is detected */ | 283 | /* disable GPE during transaction if storm is detected */ |
| 260 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 284 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
| 261 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 285 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
| 262 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 286 | acpi_disable_gpe(NULL, ec->gpe); |
| 263 | } | 287 | } |
| 264 | /* start transaction */ | 288 | /* start transaction */ |
| 265 | spin_lock_irqsave(&ec->curr_lock, tmp); | 289 | spin_lock_irqsave(&ec->curr_lock, tmp); |
| 266 | /* following two actions should be kept atomic */ | 290 | /* following two actions should be kept atomic */ |
| 267 | t->irq_count = 0; | ||
| 268 | ec->curr = t; | 291 | ec->curr = t; |
| 269 | acpi_ec_write_cmd(ec, ec->curr->command); | 292 | start_transaction(ec); |
| 270 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 293 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
| 271 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 294 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
| 272 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 295 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
| @@ -283,10 +306,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
| 283 | /* check if we received SCI during transaction */ | 306 | /* check if we received SCI during transaction */ |
| 284 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 307 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
| 285 | /* it is safe to enable GPE outside of transaction */ | 308 | /* it is safe to enable GPE outside of transaction */ |
| 286 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 309 | acpi_enable_gpe(NULL, ec->gpe); |
| 287 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 310 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && |
| 288 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | 311 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
| 289 | pr_debug(PREFIX "GPE storm detected\n"); | 312 | pr_info(PREFIX "GPE storm detected, " |
| 313 | "transactions will use polling mode\n"); | ||
| 290 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 314 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
| 291 | } | 315 | } |
| 292 | return ret; | 316 | return ret; |
| @@ -558,17 +582,26 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
| 558 | pr_debug(PREFIX "~~~> interrupt\n"); | 582 | pr_debug(PREFIX "~~~> interrupt\n"); |
| 559 | status = acpi_ec_read_status(ec); | 583 | status = acpi_ec_read_status(ec); |
| 560 | 584 | ||
| 561 | gpe_transaction(ec, status); | 585 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { |
| 562 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) | 586 | gpe_transaction(ec, status); |
| 563 | wake_up(&ec->wait); | 587 | if (ec_transaction_done(ec) && |
| 588 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
| 589 | wake_up(&ec->wait); | ||
| 590 | } | ||
| 564 | 591 | ||
| 565 | ec_check_sci(ec, status); | 592 | ec_check_sci(ec, status); |
| 566 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 593 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && |
| 567 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | 594 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { |
| 568 | /* this is non-query, must be confirmation */ | 595 | /* this is non-query, must be confirmation */ |
| 569 | if (printk_ratelimit()) | 596 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
| 570 | pr_info(PREFIX "non-query interrupt received," | 597 | if (printk_ratelimit()) |
| 598 | pr_info(PREFIX "non-query interrupt received," | ||
| 599 | " switching to interrupt mode\n"); | ||
| 600 | } else { | ||
| 601 | /* hush, STORM switches the mode every transaction */ | ||
| 602 | pr_debug(PREFIX "non-query interrupt received," | ||
| 571 | " switching to interrupt mode\n"); | 603 | " switching to interrupt mode\n"); |
| 604 | } | ||
| 572 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 605 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
| 573 | } | 606 | } |
| 574 | return ACPI_INTERRUPT_HANDLED; | 607 | return ACPI_INTERRUPT_HANDLED; |
| @@ -736,7 +769,7 @@ static acpi_status | |||
| 736 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | 769 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) |
| 737 | { | 770 | { |
| 738 | acpi_status status; | 771 | acpi_status status; |
| 739 | unsigned long long tmp; | 772 | unsigned long long tmp = 0; |
| 740 | 773 | ||
| 741 | struct acpi_ec *ec = context; | 774 | struct acpi_ec *ec = context; |
| 742 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 775 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
| @@ -751,6 +784,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
| 751 | return status; | 784 | return status; |
| 752 | ec->gpe = tmp; | 785 | ec->gpe = tmp; |
| 753 | /* Use the global lock for all EC transactions? */ | 786 | /* Use the global lock for all EC transactions? */ |
| 787 | tmp = 0; | ||
| 754 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); | 788 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); |
| 755 | ec->global_lock = tmp; | 789 | ec->global_lock = tmp; |
| 756 | ec->handle = handle; | 790 | ec->handle = handle; |
| @@ -868,7 +902,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
| 868 | if (ACPI_FAILURE(status)) | 902 | if (ACPI_FAILURE(status)) |
| 869 | return -ENODEV; | 903 | return -ENODEV; |
| 870 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 904 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); |
| 871 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 905 | acpi_enable_gpe(NULL, ec->gpe); |
| 872 | status = acpi_install_address_space_handler(ec->handle, | 906 | status = acpi_install_address_space_handler(ec->handle, |
| 873 | ACPI_ADR_SPACE_EC, | 907 | ACPI_ADR_SPACE_EC, |
| 874 | &acpi_ec_space_handler, | 908 | &acpi_ec_space_handler, |
| @@ -1007,7 +1041,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
| 1007 | /* Stop using GPE */ | 1041 | /* Stop using GPE */ |
| 1008 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | 1042 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); |
| 1009 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 1043 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
| 1010 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 1044 | acpi_disable_gpe(NULL, ec->gpe); |
| 1011 | return 0; | 1045 | return 0; |
| 1012 | } | 1046 | } |
| 1013 | 1047 | ||
| @@ -1016,7 +1050,7 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
| 1016 | struct acpi_ec *ec = acpi_driver_data(device); | 1050 | struct acpi_ec *ec = acpi_driver_data(device); |
| 1017 | /* Enable use of GPE back */ | 1051 | /* Enable use of GPE back */ |
| 1018 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | 1052 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); |
| 1019 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 1053 | acpi_enable_gpe(NULL, ec->gpe); |
| 1020 | return 0; | 1054 | return 0; |
| 1021 | } | 1055 | } |
| 1022 | 1056 | ||
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index c5e53aae86f7..f45c74fe745e 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
| @@ -289,8 +289,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
| 289 | */ | 289 | */ |
| 290 | status = acpi_hw_low_disable_gpe(gpe_event_info); | 290 | status = acpi_hw_low_disable_gpe(gpe_event_info); |
| 291 | return_ACPI_STATUS(status); | 291 | return_ACPI_STATUS(status); |
| 292 | |||
| 293 | return_ACPI_STATUS(AE_OK); | ||
| 294 | } | 292 | } |
| 295 | 293 | ||
| 296 | /******************************************************************************* | 294 | /******************************************************************************* |
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 73bfd6bf962f..41554f736b68 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c | |||
| @@ -248,21 +248,15 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) | |||
| 248 | * DESCRIPTION: Enable an ACPI event (general purpose) | 248 | * DESCRIPTION: Enable an ACPI event (general purpose) |
| 249 | * | 249 | * |
| 250 | ******************************************************************************/ | 250 | ******************************************************************************/ |
| 251 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | 251 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) |
| 252 | { | 252 | { |
| 253 | acpi_status status = AE_OK; | 253 | acpi_status status = AE_OK; |
| 254 | acpi_cpu_flags flags; | ||
| 254 | struct acpi_gpe_event_info *gpe_event_info; | 255 | struct acpi_gpe_event_info *gpe_event_info; |
| 255 | 256 | ||
| 256 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | 257 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); |
| 257 | 258 | ||
| 258 | /* Use semaphore lock if not executing at interrupt level */ | 259 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
| 259 | |||
| 260 | if (flags & ACPI_NOT_ISR) { | ||
| 261 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
| 262 | if (ACPI_FAILURE(status)) { | ||
| 263 | return_ACPI_STATUS(status); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | 260 | ||
| 267 | /* Ensure that we have a valid GPE number */ | 261 | /* Ensure that we have a valid GPE number */ |
| 268 | 262 | ||
| @@ -277,9 +271,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | |||
| 277 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); | 271 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); |
| 278 | 272 | ||
| 279 | unlock_and_exit: | 273 | unlock_and_exit: |
| 280 | if (flags & ACPI_NOT_ISR) { | 274 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 281 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
| 282 | } | ||
| 283 | return_ACPI_STATUS(status); | 275 | return_ACPI_STATUS(status); |
| 284 | } | 276 | } |
| 285 | 277 | ||
| @@ -299,22 +291,15 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
| 299 | * DESCRIPTION: Disable an ACPI event (general purpose) | 291 | * DESCRIPTION: Disable an ACPI event (general purpose) |
| 300 | * | 292 | * |
| 301 | ******************************************************************************/ | 293 | ******************************************************************************/ |
| 302 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | 294 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) |
| 303 | { | 295 | { |
| 304 | acpi_status status = AE_OK; | 296 | acpi_status status = AE_OK; |
| 297 | acpi_cpu_flags flags; | ||
| 305 | struct acpi_gpe_event_info *gpe_event_info; | 298 | struct acpi_gpe_event_info *gpe_event_info; |
| 306 | 299 | ||
| 307 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | 300 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); |
| 308 | 301 | ||
| 309 | /* Use semaphore lock if not executing at interrupt level */ | 302 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
| 310 | |||
| 311 | if (flags & ACPI_NOT_ISR) { | ||
| 312 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
| 313 | if (ACPI_FAILURE(status)) { | ||
| 314 | return_ACPI_STATUS(status); | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | /* Ensure that we have a valid GPE number */ | 303 | /* Ensure that we have a valid GPE number */ |
| 319 | 304 | ||
| 320 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 305 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
| @@ -325,10 +310,8 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | |||
| 325 | 310 | ||
| 326 | status = acpi_ev_disable_gpe(gpe_event_info); | 311 | status = acpi_ev_disable_gpe(gpe_event_info); |
| 327 | 312 | ||
| 328 | unlock_and_exit: | 313 | unlock_and_exit: |
| 329 | if (flags & ACPI_NOT_ISR) { | 314 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 330 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
| 331 | } | ||
| 332 | return_ACPI_STATUS(status); | 315 | return_ACPI_STATUS(status); |
| 333 | } | 316 | } |
| 334 | 317 | ||
| @@ -521,6 +504,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
| 521 | if (value) | 504 | if (value) |
| 522 | *event_status |= ACPI_EVENT_FLAG_SET; | 505 | *event_status |= ACPI_EVENT_FLAG_SET; |
| 523 | 506 | ||
| 507 | if (acpi_gbl_fixed_event_handlers[event].handler) | ||
| 508 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
| 509 | |||
| 524 | return_ACPI_STATUS(status); | 510 | return_ACPI_STATUS(status); |
| 525 | } | 511 | } |
| 526 | 512 | ||
| @@ -571,6 +557,9 @@ acpi_get_gpe_status(acpi_handle gpe_device, | |||
| 571 | 557 | ||
| 572 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); | 558 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); |
| 573 | 559 | ||
| 560 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
| 561 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
| 562 | |||
| 574 | unlock_and_exit: | 563 | unlock_and_exit: |
| 575 | if (flags & ACPI_NOT_ISR) { | 564 | if (flags & ACPI_NOT_ISR) { |
| 576 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 565 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 60d54d1f6b19..eaaee1660bdf 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
| 35 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
| 36 | 36 | ||
| 37 | #define ACPI_FAN_COMPONENT 0x00200000 | ||
| 38 | #define ACPI_FAN_CLASS "fan" | 37 | #define ACPI_FAN_CLASS "fan" |
| 39 | #define ACPI_FAN_FILE_STATE "state" | 38 | #define ACPI_FAN_FILE_STATE "state" |
| 40 | 39 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 24649ada08df..adec3d15810a 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
| @@ -140,6 +140,46 @@ struct device *acpi_get_physical_device(acpi_handle handle) | |||
| 140 | 140 | ||
| 141 | EXPORT_SYMBOL(acpi_get_physical_device); | 141 | EXPORT_SYMBOL(acpi_get_physical_device); |
| 142 | 142 | ||
| 143 | /* ToDo: When a PCI bridge is found, return the PCI device behind the bridge | ||
| 144 | * This should work in general, but did not on a Lenovo T61 for the | ||
| 145 | * graphics card. But this must be fixed when the PCI device is | ||
| 146 | * bound and the kernel device struct is attached to the acpi device | ||
| 147 | * Note: A success call will increase reference count by one | ||
| 148 | * Do call put_device(dev) on the returned device then | ||
| 149 | */ | ||
| 150 | struct device *acpi_get_physical_pci_device(acpi_handle handle) | ||
| 151 | { | ||
| 152 | struct device *dev; | ||
| 153 | long long device_id; | ||
| 154 | acpi_status status; | ||
| 155 | |||
| 156 | status = | ||
| 157 | acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); | ||
| 158 | |||
| 159 | if (ACPI_FAILURE(status)) | ||
| 160 | return NULL; | ||
| 161 | |||
| 162 | /* We need to attempt to determine whether the _ADR refers to a | ||
| 163 | PCI device or not. There's no terribly good way to do this, | ||
| 164 | so the best we can hope for is to assume that there'll never | ||
| 165 | be a device in the host bridge */ | ||
| 166 | if (device_id >= 0x10000) { | ||
| 167 | /* It looks like a PCI device. Does it exist? */ | ||
| 168 | dev = acpi_get_physical_device(handle); | ||
| 169 | } else { | ||
| 170 | /* It doesn't look like a PCI device. Does its parent | ||
| 171 | exist? */ | ||
| 172 | acpi_handle phandle; | ||
| 173 | if (acpi_get_parent(handle, &phandle)) | ||
| 174 | return NULL; | ||
| 175 | dev = acpi_get_physical_device(phandle); | ||
| 176 | } | ||
| 177 | if (!dev) | ||
| 178 | return NULL; | ||
| 179 | return dev; | ||
| 180 | } | ||
| 181 | EXPORT_SYMBOL(acpi_get_physical_pci_device); | ||
| 182 | |||
| 143 | static int acpi_bind_one(struct device *dev, acpi_handle handle) | 183 | static int acpi_bind_one(struct device *dev, acpi_handle handle) |
| 144 | { | 184 | { |
| 145 | struct acpi_device *acpi_dev; | 185 | struct acpi_device *acpi_dev; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4be252145cb4..c8111424dcb8 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
| 36 | #include <linux/kmod.h> | 36 | #include <linux/kmod.h> |
| 37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
| 38 | #include <linux/dmi.h> | ||
| 39 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
| 40 | #include <linux/nmi.h> | 39 | #include <linux/nmi.h> |
| 41 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
| @@ -97,54 +96,44 @@ static DEFINE_SPINLOCK(acpi_res_lock); | |||
| 97 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | 96 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; |
| 98 | 97 | ||
| 99 | /* | 98 | /* |
| 100 | * "Ode to _OSI(Linux)" | 99 | * The story of _OSI(Linux) |
| 101 | * | 100 | * |
| 102 | * osi_linux -- Control response to BIOS _OSI(Linux) query. | 101 | * From pre-history through Linux-2.6.22, |
| 102 | * Linux responded TRUE upon a BIOS OSI(Linux) query. | ||
| 103 | * | 103 | * |
| 104 | * As Linux evolves, the features that it supports change. | 104 | * Unfortunately, reference BIOS writers got wind of this |
| 105 | * So an OSI string such as "Linux" is not specific enough | 105 | * and put OSI(Linux) in their example code, quickly exposing |
| 106 | * to be useful across multiple versions of Linux. It | 106 | * this string as ill-conceived and opening the door to |
| 107 | * doesn't identify any particular feature, interface, | 107 | * an un-bounded number of BIOS incompatibilities. |
| 108 | * or even any particular version of Linux... | ||
| 109 | * | 108 | * |
| 110 | * Unfortunately, Linux-2.6.22 and earlier responded "yes" | 109 | * For example, OSI(Linux) was used on resume to re-POST a |
| 111 | * to a BIOS _OSI(Linux) query. When | 110 | * video card on one system, because Linux at that time |
| 112 | * a reference mobile BIOS started using it, its use | 111 | * could not do a speedy restore in its native driver. |
| 113 | * started to spread to many vendor platforms. | 112 | * But then upon gaining quick native restore capability, |
| 114 | * As it is not supportable, we need to halt that spread. | 113 | * Linux has no way to tell the BIOS to skip the time-consuming |
| 114 | * POST -- putting Linux at a permanent performance disadvantage. | ||
| 115 | * On another system, the BIOS writer used OSI(Linux) | ||
| 116 | * to infer native OS support for IPMI! On other systems, | ||
| 117 | * OSI(Linux) simply got in the way of Linux claiming to | ||
| 118 | * be compatible with other operating systems, exposing | ||
| 119 | * BIOS issues such as skipped device initialization. | ||
| 115 | * | 120 | * |
| 116 | * Today, most BIOS references to _OSI(Linux) are noise -- | 121 | * So "Linux" turned out to be a really poor chose of |
| 117 | * they have no functional effect and are just dead code | 122 | * OSI string, and from Linux-2.6.23 onward we respond FALSE. |
| 118 | * carried over from the reference BIOS. | ||
| 119 | * | ||
| 120 | * The next most common case is that _OSI(Linux) harms Linux, | ||
| 121 | * usually by causing the BIOS to follow paths that are | ||
| 122 | * not tested during Windows validation. | ||
| 123 | * | ||
| 124 | * Finally, there is a short list of platforms | ||
| 125 | * where OSI(Linux) benefits Linux. | ||
| 126 | * | ||
| 127 | * In Linux-2.6.23, OSI(Linux) is first disabled by default. | ||
| 128 | * DMI is used to disable the dmesg warning about OSI(Linux) | ||
| 129 | * on platforms where it is known to have no effect. | ||
| 130 | * But a dmesg warning remains for systems where | ||
| 131 | * we do not know if OSI(Linux) is good or bad for the system. | ||
| 132 | * DMI is also used to enable OSI(Linux) for the machines | ||
| 133 | * that are known to need it. | ||
| 134 | * | 123 | * |
| 135 | * BIOS writers should NOT query _OSI(Linux) on future systems. | 124 | * BIOS writers should NOT query _OSI(Linux) on future systems. |
| 136 | * It will be ignored by default, and to get Linux to | 125 | * Linux will complain on the console when it sees it, and return FALSE. |
| 137 | * not ignore it will require a kernel source update to | 126 | * To get Linux to return TRUE for your system will require |
| 138 | * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation. | 127 | * a kernel source update to add a DMI entry, |
| 128 | * or boot with "acpi_osi=Linux" | ||
| 139 | */ | 129 | */ |
| 140 | #define OSI_LINUX_ENABLE 0 | ||
| 141 | 130 | ||
| 142 | static struct osi_linux { | 131 | static struct osi_linux { |
| 143 | unsigned int enable:1; | 132 | unsigned int enable:1; |
| 144 | unsigned int dmi:1; | 133 | unsigned int dmi:1; |
| 145 | unsigned int cmdline:1; | 134 | unsigned int cmdline:1; |
| 146 | unsigned int known:1; | 135 | unsigned int known:1; |
| 147 | } osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0}; | 136 | } osi_linux = { 0, 0, 0, 0}; |
| 148 | 137 | ||
| 149 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 138 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
| 150 | unsigned int length, char *desc) | 139 | unsigned int length, char *desc) |
| @@ -1296,34 +1285,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
| 1296 | return (AE_OK); | 1285 | return (AE_OK); |
| 1297 | } | 1286 | } |
| 1298 | 1287 | ||
| 1299 | /** | ||
| 1300 | * acpi_dmi_dump - dump DMI slots needed for blacklist entry | ||
| 1301 | * | ||
| 1302 | * Returns 0 on success | ||
| 1303 | */ | ||
| 1304 | static int acpi_dmi_dump(void) | ||
| 1305 | { | ||
| 1306 | |||
| 1307 | if (!dmi_available) | ||
| 1308 | return -1; | ||
| 1309 | |||
| 1310 | printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n", | ||
| 1311 | dmi_get_system_info(DMI_SYS_VENDOR)); | ||
| 1312 | printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n", | ||
| 1313 | dmi_get_system_info(DMI_PRODUCT_NAME)); | ||
| 1314 | printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n", | ||
| 1315 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
| 1316 | printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n", | ||
| 1317 | dmi_get_system_info(DMI_BOARD_NAME)); | ||
| 1318 | printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n", | ||
| 1319 | dmi_get_system_info(DMI_BIOS_VENDOR)); | ||
| 1320 | printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n", | ||
| 1321 | dmi_get_system_info(DMI_BIOS_DATE)); | ||
| 1322 | |||
| 1323 | return 0; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | |||
| 1327 | /****************************************************************************** | 1288 | /****************************************************************************** |
| 1328 | * | 1289 | * |
| 1329 | * FUNCTION: acpi_os_validate_interface | 1290 | * FUNCTION: acpi_os_validate_interface |
| @@ -1350,21 +1311,6 @@ acpi_os_validate_interface (char *interface) | |||
| 1350 | osi_linux.cmdline ? " via cmdline" : | 1311 | osi_linux.cmdline ? " via cmdline" : |
| 1351 | osi_linux.dmi ? " via DMI" : ""); | 1312 | osi_linux.dmi ? " via DMI" : ""); |
| 1352 | 1313 | ||
| 1353 | if (!osi_linux.dmi) { | ||
| 1354 | if (acpi_dmi_dump()) | ||
| 1355 | printk(KERN_NOTICE PREFIX | ||
| 1356 | "[please extract dmidecode output]\n"); | ||
| 1357 | printk(KERN_NOTICE PREFIX | ||
| 1358 | "Please send DMI info above to " | ||
| 1359 | "linux-acpi@vger.kernel.org\n"); | ||
| 1360 | } | ||
| 1361 | if (!osi_linux.known && !osi_linux.cmdline) { | ||
| 1362 | printk(KERN_NOTICE PREFIX | ||
| 1363 | "If \"acpi_osi=%sLinux\" works better, " | ||
| 1364 | "please notify linux-acpi@vger.kernel.org\n", | ||
| 1365 | osi_linux.enable ? "!" : ""); | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | if (osi_linux.enable) | 1314 | if (osi_linux.enable) |
| 1369 | return AE_OK; | 1315 | return AE_OK; |
| 1370 | } | 1316 | } |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index fcfdef7b4fdd..e52ad91ce2dc 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
| @@ -531,7 +531,7 @@ int __init acpi_irq_penalty_init(void) | |||
| 531 | return 0; | 531 | return 0; |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | static int acpi_irq_balance; /* 0: static, 1: balance */ | 534 | static int acpi_irq_balance = -1; /* 0: static, 1: balance */ |
| 535 | 535 | ||
| 536 | static int acpi_pci_link_allocate(struct acpi_pci_link *link) | 536 | static int acpi_pci_link_allocate(struct acpi_pci_link *link) |
| 537 | { | 537 | { |
| @@ -950,10 +950,17 @@ device_initcall(irqrouter_init_sysfs); | |||
| 950 | 950 | ||
| 951 | static int __init acpi_pci_link_init(void) | 951 | static int __init acpi_pci_link_init(void) |
| 952 | { | 952 | { |
| 953 | |||
| 954 | if (acpi_noirq) | 953 | if (acpi_noirq) |
| 955 | return 0; | 954 | return 0; |
| 956 | 955 | ||
| 956 | if (acpi_irq_balance == -1) { | ||
| 957 | /* no command line switch: enable balancing in IOAPIC mode */ | ||
| 958 | if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) | ||
| 959 | acpi_irq_balance = 1; | ||
| 960 | else | ||
| 961 | acpi_irq_balance = 0; | ||
| 962 | } | ||
| 963 | |||
| 957 | acpi_link.count = 0; | 964 | acpi_link.count = 0; |
| 958 | INIT_LIST_HEAD(&acpi_link.entries); | 965 | INIT_LIST_HEAD(&acpi_link.entries); |
| 959 | 966 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1b8f67d21d53..642554b1b60c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -376,15 +376,9 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
| 376 | 376 | ||
| 377 | static int __init acpi_pci_root_init(void) | 377 | static int __init acpi_pci_root_init(void) |
| 378 | { | 378 | { |
| 379 | |||
| 380 | if (acpi_pci_disabled) | 379 | if (acpi_pci_disabled) |
| 381 | return 0; | 380 | return 0; |
| 382 | 381 | ||
| 383 | /* DEBUG: | ||
| 384 | acpi_dbg_layer = ACPI_PCI_COMPONENT; | ||
| 385 | acpi_dbg_level = 0xFFFFFFFF; | ||
| 386 | */ | ||
| 387 | |||
| 388 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) | 382 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) |
| 389 | return -ENODEV; | 383 | return -ENODEV; |
| 390 | 384 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index a1718e56103b..bb7d50dd2818 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
| @@ -44,9 +44,8 @@ | |||
| 44 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
| 45 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
| 46 | 46 | ||
| 47 | #define _COMPONENT ACPI_POWER_COMPONENT | 47 | #define _COMPONENT ACPI_POWER_COMPONENT |
| 48 | ACPI_MODULE_NAME("power"); | 48 | ACPI_MODULE_NAME("power"); |
| 49 | #define ACPI_POWER_COMPONENT 0x00800000 | ||
| 50 | #define ACPI_POWER_CLASS "power_resource" | 49 | #define ACPI_POWER_CLASS "power_resource" |
| 51 | #define ACPI_POWER_DEVICE_NAME "Power Resource" | 50 | #define ACPI_POWER_DEVICE_NAME "Power Resource" |
| 52 | #define ACPI_POWER_FILE_INFO "info" | 51 | #define ACPI_POWER_FILE_INFO "info" |
| @@ -153,7 +152,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state) | |||
| 153 | ACPI_POWER_RESOURCE_STATE_OFF; | 152 | ACPI_POWER_RESOURCE_STATE_OFF; |
| 154 | 153 | ||
| 155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", | 154 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", |
| 156 | acpi_ut_get_node_name(handle), state ? "on" : "off")); | 155 | acpi_ut_get_node_name(handle), |
| 156 | *state ? "on" : "off")); | ||
| 157 | 157 | ||
| 158 | return 0; | 158 | return 0; |
| 159 | } | 159 | } |
| @@ -516,11 +516,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
| 516 | cl = &device->power.states[device->power.state].resources; | 516 | cl = &device->power.states[device->power.state].resources; |
| 517 | tl = &device->power.states[state].resources; | 517 | tl = &device->power.states[state].resources; |
| 518 | 518 | ||
| 519 | if (!cl->count && !tl->count) { | ||
| 520 | result = -ENODEV; | ||
| 521 | goto end; | ||
| 522 | } | ||
| 523 | |||
| 524 | /* TBD: Resources must be ordered. */ | 519 | /* TBD: Resources must be ordered. */ |
| 525 | 520 | ||
| 526 | /* | 521 | /* |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 24a362f8034c..34948362f41d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -59,7 +59,6 @@ | |||
| 59 | #include <acpi/acpi_drivers.h> | 59 | #include <acpi/acpi_drivers.h> |
| 60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
| 61 | 61 | ||
| 62 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
| 63 | #define ACPI_PROCESSOR_CLASS "processor" | 62 | #define ACPI_PROCESSOR_CLASS "processor" |
| 64 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | 63 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" |
| 65 | #define ACPI_PROCESSOR_FILE_INFO "info" | 64 | #define ACPI_PROCESSOR_FILE_INFO "info" |
| @@ -89,6 +88,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr); | |||
| 89 | 88 | ||
| 90 | 89 | ||
| 91 | static const struct acpi_device_id processor_device_ids[] = { | 90 | static const struct acpi_device_id processor_device_ids[] = { |
| 91 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | ||
| 92 | {ACPI_PROCESSOR_HID, 0}, | 92 | {ACPI_PROCESSOR_HID, 0}, |
| 93 | {"", 0}, | 93 | {"", 0}, |
| 94 | }; | 94 | }; |
| @@ -409,7 +409,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
| 409 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 409 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
| 410 | 410 | ||
| 411 | #ifndef CONFIG_SMP | 411 | #ifndef CONFIG_SMP |
| 412 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} | 412 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } |
| 413 | #else | 413 | #else |
| 414 | 414 | ||
| 415 | static struct acpi_table_madt *madt; | 415 | static struct acpi_table_madt *madt; |
| @@ -428,27 +428,35 @@ static int map_lapic_id(struct acpi_subtable_header *entry, | |||
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | static int map_lsapic_id(struct acpi_subtable_header *entry, | 430 | static int map_lsapic_id(struct acpi_subtable_header *entry, |
| 431 | u32 acpi_id, int *apic_id) | 431 | int device_declaration, u32 acpi_id, int *apic_id) |
| 432 | { | 432 | { |
| 433 | struct acpi_madt_local_sapic *lsapic = | 433 | struct acpi_madt_local_sapic *lsapic = |
| 434 | (struct acpi_madt_local_sapic *)entry; | 434 | (struct acpi_madt_local_sapic *)entry; |
| 435 | u32 tmp = (lsapic->id << 8) | lsapic->eid; | ||
| 436 | |||
| 435 | /* Only check enabled APICs*/ | 437 | /* Only check enabled APICs*/ |
| 436 | if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { | 438 | if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) |
| 437 | /* First check against id */ | 439 | return 0; |
| 438 | if (lsapic->processor_id == acpi_id) { | 440 | |
| 439 | *apic_id = (lsapic->id << 8) | lsapic->eid; | 441 | /* Device statement declaration type */ |
| 440 | return 1; | 442 | if (device_declaration) { |
| 441 | /* Check against optional uid */ | 443 | if (entry->length < 16) |
| 442 | } else if (entry->length >= 16 && | 444 | printk(KERN_ERR PREFIX |
| 443 | lsapic->uid == acpi_id) { | 445 | "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", |
| 444 | *apic_id = lsapic->uid; | 446 | tmp); |
| 445 | return 1; | 447 | else if (lsapic->uid == acpi_id) |
| 446 | } | 448 | goto found; |
| 447 | } | 449 | /* Processor statement declaration type */ |
| 450 | } else if (lsapic->processor_id == acpi_id) | ||
| 451 | goto found; | ||
| 452 | |||
| 448 | return 0; | 453 | return 0; |
| 454 | found: | ||
| 455 | *apic_id = tmp; | ||
| 456 | return 1; | ||
| 449 | } | 457 | } |
| 450 | 458 | ||
| 451 | static int map_madt_entry(u32 acpi_id) | 459 | static int map_madt_entry(int type, u32 acpi_id) |
| 452 | { | 460 | { |
| 453 | unsigned long madt_end, entry; | 461 | unsigned long madt_end, entry; |
| 454 | int apic_id = -1; | 462 | int apic_id = -1; |
| @@ -469,7 +477,7 @@ static int map_madt_entry(u32 acpi_id) | |||
| 469 | if (map_lapic_id(header, acpi_id, &apic_id)) | 477 | if (map_lapic_id(header, acpi_id, &apic_id)) |
| 470 | break; | 478 | break; |
| 471 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 479 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
| 472 | if (map_lsapic_id(header, acpi_id, &apic_id)) | 480 | if (map_lsapic_id(header, type, acpi_id, &apic_id)) |
| 473 | break; | 481 | break; |
| 474 | } | 482 | } |
| 475 | entry += header->length; | 483 | entry += header->length; |
| @@ -477,7 +485,7 @@ static int map_madt_entry(u32 acpi_id) | |||
| 477 | return apic_id; | 485 | return apic_id; |
| 478 | } | 486 | } |
| 479 | 487 | ||
| 480 | static int map_mat_entry(acpi_handle handle, u32 acpi_id) | 488 | static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) |
| 481 | { | 489 | { |
| 482 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 490 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 483 | union acpi_object *obj; | 491 | union acpi_object *obj; |
| @@ -500,7 +508,7 @@ static int map_mat_entry(acpi_handle handle, u32 acpi_id) | |||
| 500 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | 508 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { |
| 501 | map_lapic_id(header, acpi_id, &apic_id); | 509 | map_lapic_id(header, acpi_id, &apic_id); |
| 502 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 510 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
| 503 | map_lsapic_id(header, acpi_id, &apic_id); | 511 | map_lsapic_id(header, type, acpi_id, &apic_id); |
| 504 | } | 512 | } |
| 505 | 513 | ||
| 506 | exit: | 514 | exit: |
| @@ -509,14 +517,14 @@ exit: | |||
| 509 | return apic_id; | 517 | return apic_id; |
| 510 | } | 518 | } |
| 511 | 519 | ||
| 512 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) | 520 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) |
| 513 | { | 521 | { |
| 514 | int i; | 522 | int i; |
| 515 | int apic_id = -1; | 523 | int apic_id = -1; |
| 516 | 524 | ||
| 517 | apic_id = map_mat_entry(handle, acpi_id); | 525 | apic_id = map_mat_entry(handle, type, acpi_id); |
| 518 | if (apic_id == -1) | 526 | if (apic_id == -1) |
| 519 | apic_id = map_madt_entry(acpi_id); | 527 | apic_id = map_madt_entry(type, acpi_id); |
| 520 | if (apic_id == -1) | 528 | if (apic_id == -1) |
| 521 | return apic_id; | 529 | return apic_id; |
| 522 | 530 | ||
| @@ -532,15 +540,16 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) | |||
| 532 | Driver Interface | 540 | Driver Interface |
| 533 | -------------------------------------------------------------------------- */ | 541 | -------------------------------------------------------------------------- */ |
| 534 | 542 | ||
| 535 | static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | 543 | static int acpi_processor_get_info(struct acpi_device *device) |
| 536 | { | 544 | { |
| 537 | acpi_status status = 0; | 545 | acpi_status status = 0; |
| 538 | union acpi_object object = { 0 }; | 546 | union acpi_object object = { 0 }; |
| 539 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 547 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
| 540 | int cpu_index; | 548 | struct acpi_processor *pr; |
| 549 | int cpu_index, device_declaration = 0; | ||
| 541 | static int cpu0_initialized; | 550 | static int cpu0_initialized; |
| 542 | 551 | ||
| 543 | 552 | pr = acpi_driver_data(device); | |
| 544 | if (!pr) | 553 | if (!pr) |
| 545 | return -EINVAL; | 554 | return -EINVAL; |
| 546 | 555 | ||
| @@ -561,22 +570,23 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
| 561 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 570 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 562 | "No bus mastering arbitration control\n")); | 571 | "No bus mastering arbitration control\n")); |
| 563 | 572 | ||
| 564 | /* Check if it is a Device with HID and UID */ | 573 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { |
| 565 | if (has_uid) { | 574 | /* |
| 575 | * Declared with "Device" statement; match _UID. | ||
| 576 | * Note that we don't handle string _UIDs yet. | ||
| 577 | */ | ||
| 566 | unsigned long long value; | 578 | unsigned long long value; |
| 567 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | 579 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
| 568 | NULL, &value); | 580 | NULL, &value); |
| 569 | if (ACPI_FAILURE(status)) { | 581 | if (ACPI_FAILURE(status)) { |
| 570 | printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); | 582 | printk(KERN_ERR PREFIX |
| 583 | "Evaluating processor _UID [%#x]\n", status); | ||
| 571 | return -ENODEV; | 584 | return -ENODEV; |
| 572 | } | 585 | } |
| 586 | device_declaration = 1; | ||
| 573 | pr->acpi_id = value; | 587 | pr->acpi_id = value; |
| 574 | } else { | 588 | } else { |
| 575 | /* | 589 | /* Declared with "Processor" statement; match ProcessorID */ |
| 576 | * Evalute the processor object. Note that it is common on SMP to | ||
| 577 | * have the first (boot) processor with a valid PBLK address while | ||
| 578 | * all others have a NULL address. | ||
| 579 | */ | ||
| 580 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | 590 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); |
| 581 | if (ACPI_FAILURE(status)) { | 591 | if (ACPI_FAILURE(status)) { |
| 582 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | 592 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); |
| @@ -584,12 +594,13 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
| 584 | } | 594 | } |
| 585 | 595 | ||
| 586 | /* | 596 | /* |
| 587 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | 597 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. |
| 588 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c | 598 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in |
| 589 | */ | 599 | * arch/xxx/acpi.c |
| 600 | */ | ||
| 590 | pr->acpi_id = object.processor.proc_id; | 601 | pr->acpi_id = object.processor.proc_id; |
| 591 | } | 602 | } |
| 592 | cpu_index = get_cpu_id(pr->handle, pr->acpi_id); | 603 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); |
| 593 | 604 | ||
| 594 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 605 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ |
| 595 | if (!cpu0_initialized && (cpu_index == -1) && | 606 | if (!cpu0_initialized && (cpu_index == -1) && |
| @@ -661,7 +672,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
| 661 | 672 | ||
| 662 | pr = acpi_driver_data(device); | 673 | pr = acpi_driver_data(device); |
| 663 | 674 | ||
| 664 | result = acpi_processor_get_info(pr, device->flags.unique_id); | 675 | result = acpi_processor_get_info(device); |
| 665 | if (result) { | 676 | if (result) { |
| 666 | /* Processor is physically not present */ | 677 | /* Processor is physically not present */ |
| 667 | return 0; | 678 | return 0; |
| @@ -761,20 +772,20 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | |||
| 761 | acpi_bus_generate_proc_event(device, event, | 772 | acpi_bus_generate_proc_event(device, event, |
| 762 | pr->performance_platform_limit); | 773 | pr->performance_platform_limit); |
| 763 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 774 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 764 | device->dev.bus_id, event, | 775 | dev_name(&device->dev), event, |
| 765 | pr->performance_platform_limit); | 776 | pr->performance_platform_limit); |
| 766 | break; | 777 | break; |
| 767 | case ACPI_PROCESSOR_NOTIFY_POWER: | 778 | case ACPI_PROCESSOR_NOTIFY_POWER: |
| 768 | acpi_processor_cst_has_changed(pr); | 779 | acpi_processor_cst_has_changed(pr); |
| 769 | acpi_bus_generate_proc_event(device, event, 0); | 780 | acpi_bus_generate_proc_event(device, event, 0); |
| 770 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 781 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 771 | device->dev.bus_id, event, 0); | 782 | dev_name(&device->dev), event, 0); |
| 772 | break; | 783 | break; |
| 773 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: | 784 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: |
| 774 | acpi_processor_tstate_has_changed(pr); | 785 | acpi_processor_tstate_has_changed(pr); |
| 775 | acpi_bus_generate_proc_event(device, event, 0); | 786 | acpi_bus_generate_proc_event(device, event, 0); |
| 776 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 787 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 777 | device->dev.bus_id, event, 0); | 788 | dev_name(&device->dev), event, 0); |
| 778 | default: | 789 | default: |
| 779 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 790 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 780 | "Unsupported event [0x%x]\n", event)); | 791 | "Unsupported event [0x%x]\n", event)); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 81b40ed5379e..5f8d746a9b81 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -59,7 +59,6 @@ | |||
| 59 | #include <acpi/processor.h> | 59 | #include <acpi/processor.h> |
| 60 | #include <asm/processor.h> | 60 | #include <asm/processor.h> |
| 61 | 61 | ||
| 62 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
| 63 | #define ACPI_PROCESSOR_CLASS "processor" | 62 | #define ACPI_PROCESSOR_CLASS "processor" |
| 64 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 63 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
| 65 | ACPI_MODULE_NAME("processor_idle"); | 64 | ACPI_MODULE_NAME("processor_idle"); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index dbcf260ea93f..0d7b772bef50 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -44,9 +44,9 @@ | |||
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #include <acpi/acpi_bus.h> | 46 | #include <acpi/acpi_bus.h> |
| 47 | #include <acpi/acpi_drivers.h> | ||
| 47 | #include <acpi/processor.h> | 48 | #include <acpi/processor.h> |
| 48 | 49 | ||
| 49 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
| 50 | #define ACPI_PROCESSOR_CLASS "processor" | 50 | #define ACPI_PROCESSOR_CLASS "processor" |
| 51 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" | 51 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" |
| 52 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 52 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ef34b18f95ca..b1eb376fae45 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | #include <acpi/processor.h> | 40 | #include <acpi/processor.h> |
| 41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
| 42 | 42 | ||
| 43 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
| 44 | #define ACPI_PROCESSOR_CLASS "processor" | 43 | #define ACPI_PROCESSOR_CLASS "processor" |
| 45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
| 46 | ACPI_MODULE_NAME("processor_thermal"); | 45 | ACPI_MODULE_NAME("processor_thermal"); |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 3da2df93d924..a0c38c94a8a0 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
| @@ -38,9 +38,9 @@ | |||
| 38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
| 39 | 39 | ||
| 40 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
| 41 | #include <acpi/acpi_drivers.h> | ||
| 41 | #include <acpi/processor.h> | 42 | #include <acpi/processor.h> |
| 42 | 43 | ||
| 43 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
| 44 | #define ACPI_PROCESSOR_CLASS "processor" | 44 | #define ACPI_PROCESSOR_CLASS "processor" |
| 45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
| 46 | ACPI_MODULE_NAME("processor_throttling"); | 46 | ACPI_MODULE_NAME("processor_throttling"); |
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index 755baf2ca70a..a6b662c00b67 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c | |||
| @@ -15,28 +15,9 @@ void acpi_reboot(void) | |||
| 15 | 15 | ||
| 16 | rr = &acpi_gbl_FADT.reset_register; | 16 | rr = &acpi_gbl_FADT.reset_register; |
| 17 | 17 | ||
| 18 | /* | 18 | /* Is the reset register supported? */ |
| 19 | * Is the ACPI reset register supported? | 19 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || |
| 20 | * | 20 | rr->bit_width != 8 || rr->bit_offset != 0) |
| 21 | * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates | ||
| 22 | * whether the ACPI reset mechanism is supported. | ||
| 23 | * | ||
| 24 | * However, some boxes have this bit clear, yet a valid | ||
| 25 | * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only | ||
| 26 | * mechanism that works for them after S3. | ||
| 27 | * | ||
| 28 | * This suggests that other operating systems may not be checking | ||
| 29 | * the RESET_REG_SUP bit, and are using other means to decide | ||
| 30 | * whether to use the ACPI reboot mechanism or not. | ||
| 31 | * | ||
| 32 | * So when acpi reboot is requested, | ||
| 33 | * only the reset_register is checked. If the following | ||
| 34 | * conditions are met, it indicates that the reset register is supported. | ||
| 35 | * a. reset_register is not zero | ||
| 36 | * b. the access width is eight | ||
| 37 | * c. the bit_offset is zero | ||
| 38 | */ | ||
| 39 | if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0) | ||
| 40 | return; | 21 | return; |
| 41 | 22 | ||
| 42 | reset_value = acpi_gbl_FADT.reset_value; | 23 | reset_value = acpi_gbl_FADT.reset_value; |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a9dda8e0f9f9..39b7233c3485 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -109,8 +109,7 @@ static int acpi_bus_hot_remove_device(void *context) | |||
| 109 | return 0; | 109 | return 0; |
| 110 | 110 | ||
| 111 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 111 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 112 | "Hot-removing device %s...\n", device->dev.bus_id)); | 112 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
| 113 | |||
| 114 | 113 | ||
| 115 | if (acpi_bus_trim(device, 1)) { | 114 | if (acpi_bus_trim(device, 1)) { |
| 116 | printk(KERN_ERR PREFIX | 115 | printk(KERN_ERR PREFIX |
| @@ -460,7 +459,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
| 460 | acpi_device_bus_id->instance_no = 0; | 459 | acpi_device_bus_id->instance_no = 0; |
| 461 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); | 460 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
| 462 | } | 461 | } |
| 463 | sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); | 462 | dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
| 464 | 463 | ||
| 465 | if (device->parent) { | 464 | if (device->parent) { |
| 466 | list_add_tail(&device->node, &device->parent->children); | 465 | list_add_tail(&device->node, &device->parent->children); |
| @@ -484,7 +483,8 @@ static int acpi_device_register(struct acpi_device *device, | |||
| 484 | 483 | ||
| 485 | result = acpi_device_setup_files(device); | 484 | result = acpi_device_setup_files(device); |
| 486 | if(result) | 485 | if(result) |
| 487 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id); | 486 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", |
| 487 | dev_name(&device->dev)); | ||
| 488 | 488 | ||
| 489 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; | 489 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
| 490 | return 0; | 490 | return 0; |
| @@ -751,16 +751,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
| 751 | if (!acpi_match_device_ids(device, button_device_ids)) | 751 | if (!acpi_match_device_ids(device, button_device_ids)) |
| 752 | device->wakeup.flags.run_wake = 1; | 752 | device->wakeup.flags.run_wake = 1; |
| 753 | 753 | ||
| 754 | /* | ||
| 755 | * Don't set Power button GPE as run_wake | ||
| 756 | * if Fixed Power button is used | ||
| 757 | */ | ||
| 758 | if (!strcmp(device->pnp.hardware_id, "PNP0C0C") && | ||
| 759 | !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { | ||
| 760 | device->wakeup.flags.run_wake = 0; | ||
| 761 | device->wakeup.flags.valid = 0; | ||
| 762 | } | ||
| 763 | |||
| 764 | end: | 754 | end: |
| 765 | if (ACPI_FAILURE(status)) | 755 | if (ACPI_FAILURE(status)) |
| 766 | device->flags.wake_capable = 0; | 756 | device->flags.wake_capable = 0; |
| @@ -919,36 +909,6 @@ static void acpi_device_get_busid(struct acpi_device *device, | |||
| 919 | } | 909 | } |
| 920 | } | 910 | } |
| 921 | 911 | ||
| 922 | static int | ||
| 923 | acpi_video_bus_match(struct acpi_device *device) | ||
| 924 | { | ||
| 925 | acpi_handle h_dummy; | ||
| 926 | |||
| 927 | if (!device) | ||
| 928 | return -EINVAL; | ||
| 929 | |||
| 930 | /* Since there is no HID, CID for ACPI Video drivers, we have | ||
| 931 | * to check well known required nodes for each feature we support. | ||
| 932 | */ | ||
| 933 | |||
| 934 | /* Does this device able to support video switching ? */ | ||
| 935 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && | ||
| 936 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
| 937 | return 0; | ||
| 938 | |||
| 939 | /* Does this device able to retrieve a video ROM ? */ | ||
| 940 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | ||
| 941 | return 0; | ||
| 942 | |||
| 943 | /* Does this device able to configure which video head to be POSTed ? */ | ||
| 944 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && | ||
| 945 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && | ||
| 946 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) | ||
| 947 | return 0; | ||
| 948 | |||
| 949 | return -ENODEV; | ||
| 950 | } | ||
| 951 | |||
| 952 | /* | 912 | /* |
| 953 | * acpi_bay_match - see if a device is an ejectable driver bay | 913 | * acpi_bay_match - see if a device is an ejectable driver bay |
| 954 | * | 914 | * |
| @@ -1031,7 +991,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
| 1031 | will get autoloaded and the device might still match | 991 | will get autoloaded and the device might still match |
| 1032 | against another driver. | 992 | against another driver. |
| 1033 | */ | 993 | */ |
| 1034 | if (ACPI_SUCCESS(acpi_video_bus_match(device))) | 994 | if (acpi_is_video_device(device)) |
| 1035 | cid_add = ACPI_VIDEO_HID; | 995 | cid_add = ACPI_VIDEO_HID; |
| 1036 | else if (ACPI_SUCCESS(acpi_bay_match(device))) | 996 | else if (ACPI_SUCCESS(acpi_bay_match(device))) |
| 1037 | cid_add = ACPI_BAY_HID; | 997 | cid_add = ACPI_BAY_HID; |
| @@ -1043,7 +1003,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
| 1043 | hid = ACPI_POWER_HID; | 1003 | hid = ACPI_POWER_HID; |
| 1044 | break; | 1004 | break; |
| 1045 | case ACPI_BUS_TYPE_PROCESSOR: | 1005 | case ACPI_BUS_TYPE_PROCESSOR: |
| 1046 | hid = ACPI_PROCESSOR_HID; | 1006 | hid = ACPI_PROCESSOR_OBJECT_HID; |
| 1047 | break; | 1007 | break; |
| 1048 | case ACPI_BUS_TYPE_SYSTEM: | 1008 | case ACPI_BUS_TYPE_SYSTEM: |
| 1049 | hid = ACPI_SYSTEM_HID; | 1009 | hid = ACPI_SYSTEM_HID; |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 80c0868d0480..28a691cc625e 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
| @@ -90,6 +90,18 @@ void __init acpi_old_suspend_ordering(void) | |||
| 90 | old_suspend_ordering = true; | 90 | old_suspend_ordering = true; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* | ||
| 94 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
| 95 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
| 96 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
| 97 | * on such systems during resume. Unfortunately that doesn't help in | ||
| 98 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
| 99 | * resume, although the specification states very clearly that this flag is | ||
| 100 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
| 101 | * cases. | ||
| 102 | */ | ||
| 103 | static bool set_sci_en_on_resume; | ||
| 104 | |||
| 93 | /** | 105 | /** |
| 94 | * acpi_pm_disable_gpes - Disable the GPEs. | 106 | * acpi_pm_disable_gpes - Disable the GPEs. |
| 95 | */ | 107 | */ |
| @@ -235,7 +247,11 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 235 | } | 247 | } |
| 236 | 248 | ||
| 237 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ | 249 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ |
| 238 | acpi_enable(); | 250 | if (set_sci_en_on_resume) |
| 251 | acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); | ||
| 252 | else | ||
| 253 | acpi_enable(); | ||
| 254 | |||
| 239 | /* Reprogram control registers and execute _BFS */ | 255 | /* Reprogram control registers and execute _BFS */ |
| 240 | acpi_leave_sleep_state_prep(acpi_state); | 256 | acpi_leave_sleep_state_prep(acpi_state); |
| 241 | 257 | ||
| @@ -323,6 +339,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
| 323 | return 0; | 339 | return 0; |
| 324 | } | 340 | } |
| 325 | 341 | ||
| 342 | static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) | ||
| 343 | { | ||
| 344 | set_sci_en_on_resume = true; | ||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 326 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 348 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
| 327 | { | 349 | { |
| 328 | .callback = init_old_suspend_ordering, | 350 | .callback = init_old_suspend_ordering, |
| @@ -340,6 +362,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
| 340 | DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), | 362 | DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), |
| 341 | }, | 363 | }, |
| 342 | }, | 364 | }, |
| 365 | { | ||
| 366 | .callback = init_set_sci_en_on_resume, | ||
| 367 | .ident = "Apple MacBook 1,1", | ||
| 368 | .matches = { | ||
| 369 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
| 370 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
| 371 | }, | ||
| 372 | }, | ||
| 373 | { | ||
| 374 | .callback = init_set_sci_en_on_resume, | ||
| 375 | .ident = "Apple MacMini 1,1", | ||
| 376 | .matches = { | ||
| 377 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
| 378 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), | ||
| 379 | }, | ||
| 380 | }, | ||
| 343 | {}, | 381 | {}, |
| 344 | }; | 382 | }; |
| 345 | #endif /* CONFIG_SUSPEND */ | 383 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 631ee2ee2ca0..4dbc2271acf5 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
| @@ -367,7 +367,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
| 367 | if (ldev) | 367 | if (ldev) |
| 368 | seq_printf(seq, "%s:%s", | 368 | seq_printf(seq, "%s:%s", |
| 369 | ldev->bus ? ldev->bus->name : "no-bus", | 369 | ldev->bus ? ldev->bus->name : "no-bus", |
| 370 | ldev->bus_id); | 370 | dev_name(ldev)); |
| 371 | seq_printf(seq, "\n"); | 371 | seq_printf(seq, "\n"); |
| 372 | put_device(ldev); | 372 | put_device(ldev); |
| 373 | 373 | ||
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index 38655eb132dc..dea4c23df764 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c | |||
| @@ -88,7 +88,7 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
| 88 | spin_unlock(&acpi_device_lock); | 88 | spin_unlock(&acpi_device_lock); |
| 89 | if (!dev->wakeup.flags.run_wake) | 89 | if (!dev->wakeup.flags.run_wake) |
| 90 | acpi_enable_gpe(dev->wakeup.gpe_device, | 90 | acpi_enable_gpe(dev->wakeup.gpe_device, |
| 91 | dev->wakeup.gpe_number, ACPI_ISR); | 91 | dev->wakeup.gpe_number); |
| 92 | spin_lock(&acpi_device_lock); | 92 | spin_lock(&acpi_device_lock); |
| 93 | } | 93 | } |
| 94 | spin_unlock(&acpi_device_lock); | 94 | spin_unlock(&acpi_device_lock); |
| @@ -122,7 +122,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
| 122 | ACPI_GPE_TYPE_WAKE_RUN); | 122 | ACPI_GPE_TYPE_WAKE_RUN); |
| 123 | /* Re-enable it, since set_gpe_type will disable it */ | 123 | /* Re-enable it, since set_gpe_type will disable it */ |
| 124 | acpi_enable_gpe(dev->wakeup.gpe_device, | 124 | acpi_enable_gpe(dev->wakeup.gpe_device, |
| 125 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 125 | dev->wakeup.gpe_number); |
| 126 | spin_lock(&acpi_device_lock); | 126 | spin_lock(&acpi_device_lock); |
| 127 | } | 127 | } |
| 128 | continue; | 128 | continue; |
| @@ -133,7 +133,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
| 133 | /* Never disable run-wake GPE */ | 133 | /* Never disable run-wake GPE */ |
| 134 | if (!dev->wakeup.flags.run_wake) { | 134 | if (!dev->wakeup.flags.run_wake) { |
| 135 | acpi_disable_gpe(dev->wakeup.gpe_device, | 135 | acpi_disable_gpe(dev->wakeup.gpe_device, |
| 136 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 136 | dev->wakeup.gpe_number); |
| 137 | acpi_clear_gpe(dev->wakeup.gpe_device, | 137 | acpi_clear_gpe(dev->wakeup.gpe_device, |
| 138 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 138 | dev->wakeup.gpe_number, ACPI_NOT_ISR); |
| 139 | } | 139 | } |
| @@ -162,7 +162,7 @@ static int __init acpi_wakeup_device_init(void) | |||
| 162 | dev->wakeup.gpe_number, | 162 | dev->wakeup.gpe_number, |
| 163 | ACPI_GPE_TYPE_WAKE_RUN); | 163 | ACPI_GPE_TYPE_WAKE_RUN); |
| 164 | acpi_enable_gpe(dev->wakeup.gpe_device, | 164 | acpi_enable_gpe(dev->wakeup.gpe_device, |
| 165 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 165 | dev->wakeup.gpe_number); |
| 166 | dev->wakeup.state.enabled = 1; | 166 | dev->wakeup.state.enabled = 1; |
| 167 | spin_lock(&acpi_device_lock); | 167 | spin_lock(&acpi_device_lock); |
| 168 | } | 168 | } |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 1d74171b7940..6e4107f82403 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
| @@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct kobject *kobj, | |||
| 78 | container_of(bin_attr, struct acpi_table_attr, attr); | 78 | container_of(bin_attr, struct acpi_table_attr, attr); |
| 79 | struct acpi_table_header *table_header = NULL; | 79 | struct acpi_table_header *table_header = NULL; |
| 80 | acpi_status status; | 80 | acpi_status status; |
| 81 | char name[ACPI_NAME_SIZE]; | ||
| 82 | |||
| 83 | if (strncmp(table_attr->name, "NULL", 4)) | ||
| 84 | memcpy(name, table_attr->name, ACPI_NAME_SIZE); | ||
| 85 | else | ||
| 86 | memcpy(name, "\0\0\0\0", 4); | ||
| 81 | 87 | ||
| 82 | status = | 88 | status = |
| 83 | acpi_get_table(table_attr->name, table_attr->instance, | 89 | acpi_get_table(name, table_attr->instance, |
| 84 | &table_header); | 90 | &table_header); |
| 85 | if (ACPI_FAILURE(status)) | 91 | if (ACPI_FAILURE(status)) |
| 86 | return -ENODEV; | 92 | return -ENODEV; |
| @@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
| 95 | struct acpi_table_header *header = NULL; | 101 | struct acpi_table_header *header = NULL; |
| 96 | struct acpi_table_attr *attr = NULL; | 102 | struct acpi_table_attr *attr = NULL; |
| 97 | 103 | ||
| 98 | memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE); | 104 | if (table_header->signature[0] != '\0') |
| 105 | memcpy(table_attr->name, table_header->signature, | ||
| 106 | ACPI_NAME_SIZE); | ||
| 107 | else | ||
| 108 | memcpy(table_attr->name, "NULL", 4); | ||
| 99 | 109 | ||
| 100 | list_for_each_entry(attr, &acpi_table_attr_list, node) { | 110 | list_for_each_entry(attr, &acpi_table_attr_list, node) { |
| 101 | if (!memcmp(table_header->signature, attr->name, | 111 | if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE)) |
| 102 | ACPI_NAME_SIZE)) | ||
| 103 | if (table_attr->instance < attr->instance) | 112 | if (table_attr->instance < attr->instance) |
| 104 | table_attr->instance = attr->instance; | 113 | table_attr->instance = attr->instance; |
| 105 | } | 114 | } |
| 106 | table_attr->instance++; | 115 | table_attr->instance++; |
| 107 | 116 | ||
| 108 | if (table_attr->instance > 1 || (table_attr->instance == 1 && | 117 | if (table_attr->instance > 1 || (table_attr->instance == 1 && |
| 109 | !acpi_get_table(table_header-> | 118 | !acpi_get_table |
| 110 | signature, 2, | 119 | (table_header->signature, 2, &header))) |
| 111 | &header))) | 120 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", |
| 112 | sprintf(table_attr->name + 4, "%d", table_attr->instance); | 121 | table_attr->instance); |
| 113 | 122 | ||
| 114 | table_attr->attr.size = 0; | 123 | table_attr->attr.size = 0; |
| 115 | table_attr->attr.read = acpi_table_show; | 124 | table_attr->attr.read = acpi_table_show; |
| @@ -167,7 +176,6 @@ static int acpi_system_sysfs_init(void) | |||
| 167 | #define COUNT_ERROR 2 /* other */ | 176 | #define COUNT_ERROR 2 /* other */ |
| 168 | #define NUM_COUNTERS_EXTRA 3 | 177 | #define NUM_COUNTERS_EXTRA 3 |
| 169 | 178 | ||
| 170 | #define ACPI_EVENT_VALID 0x01 | ||
| 171 | struct event_counter { | 179 | struct event_counter { |
| 172 | u32 count; | 180 | u32 count; |
| 173 | u32 flags; | 181 | u32 flags; |
| @@ -312,12 +320,6 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) | |||
| 312 | } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) | 320 | } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) |
| 313 | result = acpi_get_event_status(index - num_gpes, status); | 321 | result = acpi_get_event_status(index - num_gpes, status); |
| 314 | 322 | ||
| 315 | /* | ||
| 316 | * sleep/power button GPE/Fixed Event is enabled after acpi_system_init, | ||
| 317 | * check the status at runtime and mark it as valid once it's enabled | ||
| 318 | */ | ||
| 319 | if (!result && (*status & ACPI_EVENT_FLAG_ENABLED)) | ||
| 320 | all_counters[index].flags |= ACPI_EVENT_VALID; | ||
| 321 | end: | 323 | end: |
| 322 | return result; | 324 | return result; |
| 323 | } | 325 | } |
| @@ -346,12 +348,14 @@ static ssize_t counter_show(struct kobject *kobj, | |||
| 346 | if (result) | 348 | if (result) |
| 347 | goto end; | 349 | goto end; |
| 348 | 350 | ||
| 349 | if (!(all_counters[index].flags & ACPI_EVENT_VALID)) | 351 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) |
| 350 | size += sprintf(buf + size, " invalid"); | 352 | size += sprintf(buf + size, " invalid"); |
| 351 | else if (status & ACPI_EVENT_FLAG_ENABLED) | 353 | else if (status & ACPI_EVENT_FLAG_ENABLED) |
| 352 | size += sprintf(buf + size, " enable"); | 354 | size += sprintf(buf + size, " enabled"); |
| 355 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) | ||
| 356 | size += sprintf(buf + size, " wake_enabled"); | ||
| 353 | else | 357 | else |
| 354 | size += sprintf(buf + size, " disable"); | 358 | size += sprintf(buf + size, " disabled"); |
| 355 | 359 | ||
| 356 | end: | 360 | end: |
| 357 | size += sprintf(buf + size, "\n"); | 361 | size += sprintf(buf + size, "\n"); |
| @@ -385,7 +389,7 @@ static ssize_t counter_set(struct kobject *kobj, | |||
| 385 | if (result) | 389 | if (result) |
| 386 | goto end; | 390 | goto end; |
| 387 | 391 | ||
| 388 | if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { | 392 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) { |
| 389 | printk(KERN_WARNING PREFIX | 393 | printk(KERN_WARNING PREFIX |
| 390 | "Can not change Invalid GPE/Fixed Event status\n"); | 394 | "Can not change Invalid GPE/Fixed Event status\n"); |
| 391 | return -EINVAL; | 395 | return -EINVAL; |
| @@ -394,10 +398,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
| 394 | if (index < num_gpes) { | 398 | if (index < num_gpes) { |
| 395 | if (!strcmp(buf, "disable\n") && | 399 | if (!strcmp(buf, "disable\n") && |
| 396 | (status & ACPI_EVENT_FLAG_ENABLED)) | 400 | (status & ACPI_EVENT_FLAG_ENABLED)) |
| 397 | result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR); | 401 | result = acpi_disable_gpe(handle, index); |
| 398 | else if (!strcmp(buf, "enable\n") && | 402 | else if (!strcmp(buf, "enable\n") && |
| 399 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 403 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
| 400 | result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR); | 404 | result = acpi_enable_gpe(handle, index); |
| 401 | else if (!strcmp(buf, "clear\n") && | 405 | else if (!strcmp(buf, "clear\n") && |
| 402 | (status & ACPI_EVENT_FLAG_SET)) | 406 | (status & ACPI_EVENT_FLAG_SET)) |
| 403 | result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); | 407 | result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); |
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 2c7885e7ffba..2817158fb6a1 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
| @@ -304,7 +304,7 @@ static void acpi_tb_convert_fadt(void) | |||
| 304 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at | 304 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at |
| 305 | * offset 45, 55, 95, and the word located at offset 109, 110. | 305 | * offset 45, 55, 95, and the word located at offset 109, 110. |
| 306 | */ | 306 | */ |
| 307 | if (acpi_gbl_FADT.header.revision < 3) { | 307 | if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) { |
| 308 | acpi_gbl_FADT.preferred_profile = 0; | 308 | acpi_gbl_FADT.preferred_profile = 0; |
| 309 | acpi_gbl_FADT.pstate_control = 0; | 309 | acpi_gbl_FADT.pstate_control = 0; |
| 310 | acpi_gbl_FADT.cst_control = 0; | 310 | acpi_gbl_FADT.cst_control = 0; |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index ad6cae938f0b..073ff09218a9 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
| @@ -47,7 +47,6 @@ | |||
| 47 | #include <acpi/acpi_bus.h> | 47 | #include <acpi/acpi_bus.h> |
| 48 | #include <acpi/acpi_drivers.h> | 48 | #include <acpi/acpi_drivers.h> |
| 49 | 49 | ||
| 50 | #define ACPI_THERMAL_COMPONENT 0x04000000 | ||
| 51 | #define ACPI_THERMAL_CLASS "thermal_zone" | 50 | #define ACPI_THERMAL_CLASS "thermal_zone" |
| 52 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" | 51 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" |
| 53 | #define ACPI_THERMAL_FILE_STATE "state" | 52 | #define ACPI_THERMAL_FILE_STATE "state" |
| @@ -576,7 +575,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) | |||
| 576 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, | 575 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, |
| 577 | tz->trips.critical.flags.enabled); | 576 | tz->trips.critical.flags.enabled); |
| 578 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | 577 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, |
| 579 | tz->device->dev.bus_id, | 578 | dev_name(&tz->device->dev), |
| 580 | ACPI_THERMAL_NOTIFY_CRITICAL, | 579 | ACPI_THERMAL_NOTIFY_CRITICAL, |
| 581 | tz->trips.critical.flags.enabled); | 580 | tz->trips.critical.flags.enabled); |
| 582 | 581 | ||
| @@ -605,7 +604,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) | |||
| 605 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, | 604 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, |
| 606 | tz->trips.hot.flags.enabled); | 605 | tz->trips.hot.flags.enabled); |
| 607 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | 606 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, |
| 608 | tz->device->dev.bus_id, | 607 | dev_name(&tz->device->dev), |
| 609 | ACPI_THERMAL_NOTIFY_HOT, | 608 | ACPI_THERMAL_NOTIFY_HOT, |
| 610 | tz->trips.hot.flags.enabled); | 609 | tz->trips.hot.flags.enabled); |
| 611 | 610 | ||
| @@ -1592,14 +1591,14 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) | |||
| 1592 | acpi_thermal_check(tz); | 1591 | acpi_thermal_check(tz); |
| 1593 | acpi_bus_generate_proc_event(device, event, 0); | 1592 | acpi_bus_generate_proc_event(device, event, 0); |
| 1594 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1593 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 1595 | device->dev.bus_id, event, 0); | 1594 | dev_name(&device->dev), event, 0); |
| 1596 | break; | 1595 | break; |
| 1597 | case ACPI_THERMAL_NOTIFY_DEVICES: | 1596 | case ACPI_THERMAL_NOTIFY_DEVICES: |
| 1598 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); | 1597 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); |
| 1599 | acpi_thermal_check(tz); | 1598 | acpi_thermal_check(tz); |
| 1600 | acpi_bus_generate_proc_event(device, event, 0); | 1599 | acpi_bus_generate_proc_event(device, event, 0); |
| 1601 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1600 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 1602 | device->dev.bus_id, event, 0); | 1601 | dev_name(&device->dev), event, 0); |
| 1603 | break; | 1602 | break; |
| 1604 | default: | 1603 | default: |
| 1605 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1604 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 66aac06f2ac5..25f531d892de 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c | |||
| @@ -848,8 +848,6 @@ static int __init toshiba_acpi_init(void) | |||
| 848 | ret = input_register_polled_device(toshiba_acpi.poll_dev); | 848 | ret = input_register_polled_device(toshiba_acpi.poll_dev); |
| 849 | if (ret) { | 849 | if (ret) { |
| 850 | printk(MY_ERR "unable to register kill-switch input device\n"); | 850 | printk(MY_ERR "unable to register kill-switch input device\n"); |
| 851 | rfkill_free(toshiba_acpi.rfk_dev); | ||
| 852 | toshiba_acpi.rfk_dev = NULL; | ||
| 853 | toshiba_acpi_exit(); | 851 | toshiba_acpi_exit(); |
| 854 | return ret; | 852 | return ret; |
| 855 | } | 853 | } |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index e827be36ee8d..f844941089bb 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
| @@ -259,34 +259,26 @@ acpi_evaluate_integer(acpi_handle handle, | |||
| 259 | struct acpi_object_list *arguments, unsigned long long *data) | 259 | struct acpi_object_list *arguments, unsigned long long *data) |
| 260 | { | 260 | { |
| 261 | acpi_status status = AE_OK; | 261 | acpi_status status = AE_OK; |
| 262 | union acpi_object *element; | 262 | union acpi_object element; |
| 263 | struct acpi_buffer buffer = { 0, NULL }; | 263 | struct acpi_buffer buffer = { 0, NULL }; |
| 264 | 264 | ||
| 265 | |||
| 266 | if (!data) | 265 | if (!data) |
| 267 | return AE_BAD_PARAMETER; | 266 | return AE_BAD_PARAMETER; |
| 268 | 267 | ||
| 269 | element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); | ||
| 270 | if (!element) | ||
| 271 | return AE_NO_MEMORY; | ||
| 272 | |||
| 273 | buffer.length = sizeof(union acpi_object); | 268 | buffer.length = sizeof(union acpi_object); |
| 274 | buffer.pointer = element; | 269 | buffer.pointer = &element; |
| 275 | status = acpi_evaluate_object(handle, pathname, arguments, &buffer); | 270 | status = acpi_evaluate_object(handle, pathname, arguments, &buffer); |
| 276 | if (ACPI_FAILURE(status)) { | 271 | if (ACPI_FAILURE(status)) { |
| 277 | acpi_util_eval_error(handle, pathname, status); | 272 | acpi_util_eval_error(handle, pathname, status); |
| 278 | kfree(element); | ||
| 279 | return status; | 273 | return status; |
| 280 | } | 274 | } |
| 281 | 275 | ||
| 282 | if (element->type != ACPI_TYPE_INTEGER) { | 276 | if (element.type != ACPI_TYPE_INTEGER) { |
| 283 | acpi_util_eval_error(handle, pathname, AE_BAD_DATA); | 277 | acpi_util_eval_error(handle, pathname, AE_BAD_DATA); |
| 284 | kfree(element); | ||
| 285 | return AE_BAD_DATA; | 278 | return AE_BAD_DATA; |
| 286 | } | 279 | } |
| 287 | 280 | ||
| 288 | *data = element->integer.value; | 281 | *data = element.integer.value; |
| 289 | kfree(element); | ||
| 290 | 282 | ||
| 291 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); | 283 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); |
| 292 | 284 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a29b0ccac65a..baa441929720 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
| 42 | #include <acpi/acpi_drivers.h> | 42 | #include <acpi/acpi_drivers.h> |
| 43 | 43 | ||
| 44 | #define ACPI_VIDEO_COMPONENT 0x08000000 | ||
| 45 | #define ACPI_VIDEO_CLASS "video" | 44 | #define ACPI_VIDEO_CLASS "video" |
| 46 | #define ACPI_VIDEO_BUS_NAME "Video Bus" | 45 | #define ACPI_VIDEO_BUS_NAME "Video Bus" |
| 47 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" | 46 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" |
| @@ -739,7 +738,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
| 739 | device->cap._DSS = 1; | 738 | device->cap._DSS = 1; |
| 740 | } | 739 | } |
| 741 | 740 | ||
| 742 | max_level = acpi_video_init_brightness(device); | 741 | if (acpi_video_backlight_support()) |
| 742 | max_level = acpi_video_init_brightness(device); | ||
| 743 | 743 | ||
| 744 | if (device->cap._BCL && device->cap._BCM && max_level > 0) { | 744 | if (device->cap._BCL && device->cap._BCM && max_level > 0) { |
| 745 | int result; | 745 | int result; |
| @@ -785,18 +785,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
| 785 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 785 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
| 786 | 786 | ||
| 787 | } | 787 | } |
| 788 | if (device->cap._DCS && device->cap._DSS){ | 788 | |
| 789 | static int count = 0; | 789 | if (acpi_video_display_switch_support()) { |
| 790 | char *name; | 790 | |
| 791 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 791 | if (device->cap._DCS && device->cap._DSS) { |
| 792 | if (!name) | 792 | static int count; |
| 793 | return; | 793 | char *name; |
| 794 | sprintf(name, "acpi_video%d", count++); | 794 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); |
| 795 | device->output_dev = video_output_register(name, | 795 | if (!name) |
| 796 | NULL, device, &acpi_output_properties); | 796 | return; |
| 797 | kfree(name); | 797 | sprintf(name, "acpi_video%d", count++); |
| 798 | device->output_dev = video_output_register(name, | ||
| 799 | NULL, device, &acpi_output_properties); | ||
| 800 | kfree(name); | ||
| 801 | } | ||
| 798 | } | 802 | } |
| 799 | return; | ||
| 800 | } | 803 | } |
| 801 | 804 | ||
| 802 | /* | 805 | /* |
| @@ -842,11 +845,16 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
| 842 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 845 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
| 843 | { | 846 | { |
| 844 | acpi_status status = -ENOENT; | 847 | acpi_status status = -ENOENT; |
| 845 | 848 | struct device *dev; | |
| 846 | 849 | ||
| 847 | if (!video) | 850 | if (!video) |
| 848 | return -EINVAL; | 851 | return -EINVAL; |
| 849 | 852 | ||
| 853 | dev = acpi_get_physical_pci_device(video->device->handle); | ||
| 854 | if (!dev) | ||
| 855 | return -ENODEV; | ||
| 856 | put_device(dev); | ||
| 857 | |||
| 850 | /* Since there is no HID, CID and so on for VGA driver, we have | 858 | /* Since there is no HID, CID and so on for VGA driver, we have |
| 851 | * to check well known required nodes. | 859 | * to check well known required nodes. |
| 852 | */ | 860 | */ |
| @@ -2094,12 +2102,6 @@ static int __init acpi_video_init(void) | |||
| 2094 | { | 2102 | { |
| 2095 | int result = 0; | 2103 | int result = 0; |
| 2096 | 2104 | ||
| 2097 | |||
| 2098 | /* | ||
| 2099 | acpi_dbg_level = 0xFFFFFFFF; | ||
| 2100 | acpi_dbg_layer = 0x08000000; | ||
| 2101 | */ | ||
| 2102 | |||
| 2103 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2105 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
| 2104 | if (!acpi_video_dir) | 2106 | if (!acpi_video_dir) |
| 2105 | return -ENODEV; | 2107 | return -ENODEV; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c new file mode 100644 index 000000000000..f022eb6f5637 --- /dev/null +++ b/drivers/acpi/video_detect.c | |||
| @@ -0,0 +1,267 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008 SuSE Linux Products GmbH | ||
| 3 | * Thomas Renninger <trenn@suse.de> | ||
| 4 | * | ||
| 5 | * May be copied or modified under the terms of the GNU General Public License | ||
| 6 | * | ||
| 7 | * video_detect.c: | ||
| 8 | * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c | ||
| 9 | * There a Linux specific (Spec does not provide a HID for video devices) is | ||
| 10 | * assinged | ||
| 11 | * | ||
| 12 | * After PCI devices are glued with ACPI devices | ||
| 13 | * acpi_get_physical_pci_device() can be called to identify ACPI graphics | ||
| 14 | * devices for which a real graphics card is plugged in | ||
| 15 | * | ||
| 16 | * Now acpi_video_get_capabilities() can be called to check which | ||
| 17 | * capabilities the graphics cards plugged in support. The check for general | ||
| 18 | * video capabilities will be triggered by the first caller of | ||
| 19 | * acpi_video_get_capabilities(NULL); which will happen when the first | ||
| 20 | * backlight (or display output) switching supporting driver calls: | ||
| 21 | * acpi_video_backlight_support(); | ||
| 22 | * | ||
| 23 | * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) | ||
| 24 | * are available, video.ko should be used to handle the device. | ||
| 25 | * | ||
| 26 | * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, | ||
| 27 | * sony_acpi,... can take care about backlight brightness and display output | ||
| 28 | * switching. | ||
| 29 | * | ||
| 30 | * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) | ||
| 31 | * this file will not be compiled, acpi_video_get_capabilities() and | ||
| 32 | * acpi_video_backlight_support() will always return 0 and vendor specific | ||
| 33 | * drivers always can handle backlight. | ||
| 34 | * | ||
| 35 | */ | ||
| 36 | |||
| 37 | #include <linux/acpi.h> | ||
| 38 | #include <linux/dmi.h> | ||
| 39 | |||
| 40 | ACPI_MODULE_NAME("video"); | ||
| 41 | #define _COMPONENT ACPI_VIDEO_COMPONENT | ||
| 42 | |||
| 43 | static long acpi_video_support; | ||
| 44 | static bool acpi_video_caps_checked; | ||
| 45 | |||
| 46 | static acpi_status | ||
| 47 | acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | ||
| 48 | void **retyurn_value) | ||
| 49 | { | ||
| 50 | long *cap = context; | ||
| 51 | acpi_handle h_dummy; | ||
| 52 | |||
| 53 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) && | ||
| 54 | ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) { | ||
| 55 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " | ||
| 56 | "support\n")); | ||
| 57 | *cap |= ACPI_VIDEO_BACKLIGHT; | ||
| 58 | /* We have backlight support, no need to scan further */ | ||
| 59 | return AE_CTRL_TERMINATE; | ||
| 60 | } | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | /* Returns true if the device is a video device which can be handled by | ||
| 65 | * video.ko. | ||
| 66 | * The device will get a Linux specific CID added in scan.c to | ||
| 67 | * identify the device as an ACPI graphics device | ||
| 68 | * Be aware that the graphics device may not be physically present | ||
| 69 | * Use acpi_video_get_capabilities() to detect general ACPI video | ||
| 70 | * capabilities of present cards | ||
| 71 | */ | ||
| 72 | long acpi_is_video_device(struct acpi_device *device) | ||
| 73 | { | ||
| 74 | acpi_handle h_dummy; | ||
| 75 | long video_caps = 0; | ||
| 76 | |||
| 77 | if (!device) | ||
| 78 | return 0; | ||
| 79 | |||
| 80 | /* Does this device able to support video switching ? */ | ||
| 81 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && | ||
| 82 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
| 83 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; | ||
| 84 | |||
| 85 | /* Does this device able to retrieve a video ROM ? */ | ||
| 86 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | ||
| 87 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; | ||
| 88 | |||
| 89 | /* Does this device able to configure which video head to be POSTed ? */ | ||
| 90 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && | ||
| 91 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && | ||
| 92 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) | ||
| 93 | video_caps |= ACPI_VIDEO_DEVICE_POSTING; | ||
| 94 | |||
| 95 | /* Only check for backlight functionality if one of the above hit. */ | ||
| 96 | if (video_caps) | ||
| 97 | acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle, | ||
| 98 | ACPI_UINT32_MAX, acpi_backlight_cap_match, | ||
| 99 | &video_caps, NULL); | ||
| 100 | |||
| 101 | return video_caps; | ||
| 102 | } | ||
| 103 | EXPORT_SYMBOL(acpi_is_video_device); | ||
| 104 | |||
| 105 | static acpi_status | ||
| 106 | find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
| 107 | { | ||
| 108 | long *cap = context; | ||
| 109 | struct device *dev; | ||
| 110 | struct acpi_device *acpi_dev; | ||
| 111 | |||
| 112 | const struct acpi_device_id video_ids[] = { | ||
| 113 | {ACPI_VIDEO_HID, 0}, | ||
| 114 | {"", 0}, | ||
| 115 | }; | ||
| 116 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
| 117 | return AE_OK; | ||
| 118 | |||
| 119 | if (!acpi_match_device_ids(acpi_dev, video_ids)) { | ||
| 120 | dev = acpi_get_physical_pci_device(handle); | ||
| 121 | if (!dev) | ||
| 122 | return AE_OK; | ||
| 123 | put_device(dev); | ||
| 124 | *cap |= acpi_is_video_device(acpi_dev); | ||
| 125 | } | ||
| 126 | return AE_OK; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Returns the video capabilities of a specific ACPI graphics device | ||
| 131 | * | ||
| 132 | * if NULL is passed as argument all ACPI devices are enumerated and | ||
| 133 | * all graphics capabilities of physically present devices are | ||
| 134 | * summerized and returned. This is cached and done only once. | ||
| 135 | */ | ||
| 136 | long acpi_video_get_capabilities(acpi_handle graphics_handle) | ||
| 137 | { | ||
| 138 | long caps = 0; | ||
| 139 | struct acpi_device *tmp_dev; | ||
| 140 | acpi_status status; | ||
| 141 | |||
| 142 | if (acpi_video_caps_checked && graphics_handle == NULL) | ||
| 143 | return acpi_video_support; | ||
| 144 | |||
| 145 | if (!graphics_handle) { | ||
| 146 | /* Only do the global walk through all graphics devices once */ | ||
| 147 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
| 148 | ACPI_UINT32_MAX, find_video, | ||
| 149 | &caps, NULL); | ||
| 150 | /* There might be boot param flags set already... */ | ||
| 151 | acpi_video_support |= caps; | ||
| 152 | acpi_video_caps_checked = 1; | ||
| 153 | /* Add blacklists here. Be careful to use the right *DMI* bits | ||
| 154 | * to still be able to override logic via boot params, e.g.: | ||
| 155 | * | ||
| 156 | * if (dmi_name_in_vendors("XY")) { | ||
| 157 | * acpi_video_support |= | ||
| 158 | * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR; | ||
| 159 | * acpi_video_support |= | ||
| 160 | * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | ||
| 161 | *} | ||
| 162 | */ | ||
| 163 | } else { | ||
| 164 | status = acpi_bus_get_device(graphics_handle, &tmp_dev); | ||
| 165 | if (ACPI_FAILURE(status)) { | ||
| 166 | ACPI_EXCEPTION((AE_INFO, status, "Invalid device")); | ||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle, | ||
| 170 | ACPI_UINT32_MAX, find_video, | ||
| 171 | &caps, NULL); | ||
| 172 | } | ||
| 173 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n", | ||
| 174 | graphics_handle ? caps : acpi_video_support, | ||
| 175 | graphics_handle ? "on device " : "in general", | ||
| 176 | graphics_handle ? acpi_device_bid(tmp_dev) : "")); | ||
| 177 | return caps; | ||
| 178 | } | ||
| 179 | EXPORT_SYMBOL(acpi_video_get_capabilities); | ||
| 180 | |||
| 181 | /* Returns true if video.ko can do backlight switching */ | ||
| 182 | int acpi_video_backlight_support(void) | ||
| 183 | { | ||
| 184 | /* | ||
| 185 | * We must check whether the ACPI graphics device is physically plugged | ||
| 186 | * in. Therefore this must be called after binding PCI and ACPI devices | ||
| 187 | */ | ||
| 188 | if (!acpi_video_caps_checked) | ||
| 189 | acpi_video_get_capabilities(NULL); | ||
| 190 | |||
| 191 | /* First check for boot param -> highest prio */ | ||
| 192 | if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR) | ||
| 193 | return 0; | ||
| 194 | else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO) | ||
| 195 | return 1; | ||
| 196 | |||
| 197 | /* Then check for DMI blacklist -> second highest prio */ | ||
| 198 | if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR) | ||
| 199 | return 0; | ||
| 200 | else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO) | ||
| 201 | return 1; | ||
| 202 | |||
| 203 | /* Then go the default way */ | ||
| 204 | return acpi_video_support & ACPI_VIDEO_BACKLIGHT; | ||
| 205 | } | ||
| 206 | EXPORT_SYMBOL(acpi_video_backlight_support); | ||
| 207 | |||
| 208 | /* | ||
| 209 | * Returns true if video.ko can do display output switching. | ||
| 210 | * This does not work well/at all with binary graphics drivers | ||
| 211 | * which disable system io ranges and do it on their own. | ||
| 212 | */ | ||
| 213 | int acpi_video_display_switch_support(void) | ||
| 214 | { | ||
| 215 | if (!acpi_video_caps_checked) | ||
| 216 | acpi_video_get_capabilities(NULL); | ||
| 217 | |||
| 218 | if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR) | ||
| 219 | return 0; | ||
| 220 | else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO) | ||
| 221 | return 1; | ||
| 222 | |||
| 223 | if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR) | ||
| 224 | return 0; | ||
| 225 | else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO) | ||
| 226 | return 1; | ||
| 227 | |||
| 228 | return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING; | ||
| 229 | } | ||
| 230 | EXPORT_SYMBOL(acpi_video_display_switch_support); | ||
| 231 | |||
| 232 | /* | ||
| 233 | * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video | ||
| 234 | * To force that backlight or display output switching is processed by vendor | ||
| 235 | * specific acpi drivers or video.ko driver. | ||
| 236 | */ | ||
| 237 | int __init acpi_backlight(char *str) | ||
| 238 | { | ||
| 239 | if (str == NULL || *str == '\0') | ||
| 240 | return 1; | ||
| 241 | else { | ||
| 242 | if (!strcmp("vendor", str)) | ||
| 243 | acpi_video_support |= | ||
| 244 | ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; | ||
| 245 | if (!strcmp("video", str)) | ||
| 246 | acpi_video_support |= | ||
| 247 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | ||
| 248 | } | ||
| 249 | return 1; | ||
| 250 | } | ||
| 251 | __setup("acpi_backlight=", acpi_backlight); | ||
| 252 | |||
| 253 | int __init acpi_display_output(char *str) | ||
| 254 | { | ||
| 255 | if (str == NULL || *str == '\0') | ||
| 256 | return 1; | ||
| 257 | else { | ||
| 258 | if (!strcmp("vendor", str)) | ||
| 259 | acpi_video_support |= | ||
| 260 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR; | ||
| 261 | if (!strcmp("video", str)) | ||
| 262 | acpi_video_support |= | ||
| 263 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | ||
| 264 | } | ||
| 265 | return 1; | ||
| 266 | } | ||
| 267 | __setup("acpi_display_output=", acpi_display_output); | ||
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index 47cd7baf9b1b..8a8b377712c9 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c | |||
| @@ -660,7 +660,7 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data) | |||
| 660 | wblock->handler(event, wblock->handler_data); | 660 | wblock->handler(event, wblock->handler_data); |
| 661 | 661 | ||
| 662 | acpi_bus_generate_netlink_event( | 662 | acpi_bus_generate_netlink_event( |
| 663 | device->pnp.device_class, device->dev.bus_id, | 663 | device->pnp.device_class, dev_name(&device->dev), |
| 664 | event, 0); | 664 | event, 0); |
| 665 | break; | 665 | break; |
| 666 | } | 666 | } |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 78fbec8ceda0..421b7c71e72d 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -153,7 +153,7 @@ config SATA_PROMISE | |||
| 153 | If unsure, say N. | 153 | If unsure, say N. |
| 154 | 154 | ||
| 155 | config SATA_SX4 | 155 | config SATA_SX4 |
| 156 | tristate "Promise SATA SX4 support" | 156 | tristate "Promise SATA SX4 support (Experimental)" |
| 157 | depends on PCI && EXPERIMENTAL | 157 | depends on PCI && EXPERIMENTAL |
| 158 | help | 158 | help |
| 159 | This option enables support for Promise Serial ATA SX4. | 159 | This option enables support for Promise Serial ATA SX4. |
| @@ -219,8 +219,8 @@ config PATA_ACPI | |||
| 219 | otherwise unsupported hardware. | 219 | otherwise unsupported hardware. |
| 220 | 220 | ||
| 221 | config PATA_ALI | 221 | config PATA_ALI |
| 222 | tristate "ALi PATA support (Experimental)" | 222 | tristate "ALi PATA support" |
| 223 | depends on PCI && EXPERIMENTAL | 223 | depends on PCI |
| 224 | help | 224 | help |
| 225 | This option enables support for the ALi ATA interfaces | 225 | This option enables support for the ALi ATA interfaces |
| 226 | found on the many ALi chipsets. | 226 | found on the many ALi chipsets. |
| @@ -263,7 +263,7 @@ config PATA_ATIIXP | |||
| 263 | If unsure, say N. | 263 | If unsure, say N. |
| 264 | 264 | ||
| 265 | config PATA_CMD640_PCI | 265 | config PATA_CMD640_PCI |
| 266 | tristate "CMD640 PCI PATA support (Very Experimental)" | 266 | tristate "CMD640 PCI PATA support (Experimental)" |
| 267 | depends on PCI && EXPERIMENTAL | 267 | depends on PCI && EXPERIMENTAL |
| 268 | help | 268 | help |
| 269 | This option enables support for the CMD640 PCI IDE | 269 | This option enables support for the CMD640 PCI IDE |
| @@ -291,8 +291,8 @@ config PATA_CS5520 | |||
| 291 | If unsure, say N. | 291 | If unsure, say N. |
| 292 | 292 | ||
| 293 | config PATA_CS5530 | 293 | config PATA_CS5530 |
| 294 | tristate "CS5530 PATA support (Experimental)" | 294 | tristate "CS5530 PATA support" |
| 295 | depends on PCI && EXPERIMENTAL | 295 | depends on PCI |
| 296 | help | 296 | help |
| 297 | This option enables support for the Cyrix/NatSemi/AMD CS5530 | 297 | This option enables support for the Cyrix/NatSemi/AMD CS5530 |
| 298 | companion chip used with the MediaGX/Geode processor family. | 298 | companion chip used with the MediaGX/Geode processor family. |
| @@ -309,8 +309,8 @@ config PATA_CS5535 | |||
| 309 | If unsure, say N. | 309 | If unsure, say N. |
| 310 | 310 | ||
| 311 | config PATA_CS5536 | 311 | config PATA_CS5536 |
| 312 | tristate "CS5536 PATA support (Experimental)" | 312 | tristate "CS5536 PATA support" |
| 313 | depends on PCI && X86 && !X86_64 && EXPERIMENTAL | 313 | depends on PCI && X86 && !X86_64 |
| 314 | help | 314 | help |
| 315 | This option enables support for the AMD CS5536 | 315 | This option enables support for the AMD CS5536 |
| 316 | companion chip used with the Geode LX processor family. | 316 | companion chip used with the Geode LX processor family. |
| @@ -363,7 +363,7 @@ config PATA_HPT37X | |||
| 363 | If unsure, say N. | 363 | If unsure, say N. |
| 364 | 364 | ||
| 365 | config PATA_HPT3X2N | 365 | config PATA_HPT3X2N |
| 366 | tristate "HPT 372N/302N PATA support (Very Experimental)" | 366 | tristate "HPT 372N/302N PATA support (Experimental)" |
| 367 | depends on PCI && EXPERIMENTAL | 367 | depends on PCI && EXPERIMENTAL |
| 368 | help | 368 | help |
| 369 | This option enables support for the N variant HPT PATA | 369 | This option enables support for the N variant HPT PATA |
| @@ -389,8 +389,8 @@ config PATA_HPT3X3_DMA | |||
| 389 | problems with DMA on this chipset. | 389 | problems with DMA on this chipset. |
| 390 | 390 | ||
| 391 | config PATA_ISAPNP | 391 | config PATA_ISAPNP |
| 392 | tristate "ISA Plug and Play PATA support (Experimental)" | 392 | tristate "ISA Plug and Play PATA support" |
| 393 | depends on EXPERIMENTAL && ISAPNP | 393 | depends on ISAPNP |
| 394 | help | 394 | help |
| 395 | This option enables support for ISA plug & play ATA | 395 | This option enables support for ISA plug & play ATA |
| 396 | controllers such as those found on old soundcards. | 396 | controllers such as those found on old soundcards. |
| @@ -498,8 +498,8 @@ config PATA_NINJA32 | |||
| 498 | If unsure, say N. | 498 | If unsure, say N. |
| 499 | 499 | ||
| 500 | config PATA_NS87410 | 500 | config PATA_NS87410 |
| 501 | tristate "Nat Semi NS87410 PATA support (Experimental)" | 501 | tristate "Nat Semi NS87410 PATA support" |
| 502 | depends on PCI && EXPERIMENTAL | 502 | depends on PCI |
| 503 | help | 503 | help |
| 504 | This option enables support for the National Semiconductor | 504 | This option enables support for the National Semiconductor |
| 505 | NS87410 PCI-IDE controller. | 505 | NS87410 PCI-IDE controller. |
| @@ -507,8 +507,8 @@ config PATA_NS87410 | |||
| 507 | If unsure, say N. | 507 | If unsure, say N. |
| 508 | 508 | ||
| 509 | config PATA_NS87415 | 509 | config PATA_NS87415 |
| 510 | tristate "Nat Semi NS87415 PATA support (Experimental)" | 510 | tristate "Nat Semi NS87415 PATA support" |
| 511 | depends on PCI && EXPERIMENTAL | 511 | depends on PCI |
| 512 | help | 512 | help |
| 513 | This option enables support for the National Semiconductor | 513 | This option enables support for the National Semiconductor |
| 514 | NS87415 PCI-IDE controller. | 514 | NS87415 PCI-IDE controller. |
| @@ -544,8 +544,8 @@ config PATA_PCMCIA | |||
| 544 | If unsure, say N. | 544 | If unsure, say N. |
| 545 | 545 | ||
| 546 | config PATA_PDC_OLD | 546 | config PATA_PDC_OLD |
| 547 | tristate "Older Promise PATA controller support (Experimental)" | 547 | tristate "Older Promise PATA controller support" |
| 548 | depends on PCI && EXPERIMENTAL | 548 | depends on PCI |
| 549 | help | 549 | help |
| 550 | This option enables support for the Promise 20246, 20262, 20263, | 550 | This option enables support for the Promise 20246, 20262, 20263, |
| 551 | 20265 and 20267 adapters. | 551 | 20265 and 20267 adapters. |
| @@ -559,7 +559,7 @@ config PATA_QDI | |||
| 559 | Support for QDI 6500 and 6580 PATA controllers on VESA local bus. | 559 | Support for QDI 6500 and 6580 PATA controllers on VESA local bus. |
| 560 | 560 | ||
| 561 | config PATA_RADISYS | 561 | config PATA_RADISYS |
| 562 | tristate "RADISYS 82600 PATA support (Very Experimental)" | 562 | tristate "RADISYS 82600 PATA support (Experimental)" |
| 563 | depends on PCI && EXPERIMENTAL | 563 | depends on PCI && EXPERIMENTAL |
| 564 | help | 564 | help |
| 565 | This option enables support for the RADISYS 82600 | 565 | This option enables support for the RADISYS 82600 |
| @@ -586,8 +586,8 @@ config PATA_RZ1000 | |||
| 586 | If unsure, say N. | 586 | If unsure, say N. |
| 587 | 587 | ||
| 588 | config PATA_SC1200 | 588 | config PATA_SC1200 |
| 589 | tristate "SC1200 PATA support (Very Experimental)" | 589 | tristate "SC1200 PATA support" |
| 590 | depends on PCI && EXPERIMENTAL | 590 | depends on PCI |
| 591 | help | 591 | help |
| 592 | This option enables support for the NatSemi/AMD SC1200 SoC | 592 | This option enables support for the NatSemi/AMD SC1200 SoC |
| 593 | companion chip used with the Geode processor family. | 593 | companion chip used with the Geode processor family. |
| @@ -620,8 +620,8 @@ config PATA_SIL680 | |||
| 620 | If unsure, say N. | 620 | If unsure, say N. |
| 621 | 621 | ||
| 622 | config PATA_SIS | 622 | config PATA_SIS |
| 623 | tristate "SiS PATA support (Experimental)" | 623 | tristate "SiS PATA support" |
| 624 | depends on PCI && EXPERIMENTAL | 624 | depends on PCI |
| 625 | help | 625 | help |
| 626 | This option enables support for SiS PATA controllers | 626 | This option enables support for SiS PATA controllers |
| 627 | 627 | ||
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 52dc2d8b8f22..c11936e13dd3 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
| @@ -738,7 +738,6 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
| 738 | * do_pata_set_dmamode - Initialize host controller PATA PIO timings | 738 | * do_pata_set_dmamode - Initialize host controller PATA PIO timings |
| 739 | * @ap: Port whose timings we are configuring | 739 | * @ap: Port whose timings we are configuring |
| 740 | * @adev: Drive in question | 740 | * @adev: Drive in question |
| 741 | * @udma: udma mode, 0 - 6 | ||
| 742 | * @isich: set if the chip is an ICH device | 741 | * @isich: set if the chip is an ICH device |
| 743 | * | 742 | * |
| 744 | * Set UDMA mode for device, in host controller PCI config space. | 743 | * Set UDMA mode for device, in host controller PCI config space. |
| @@ -1067,6 +1066,28 @@ static int piix_broken_suspend(void) | |||
| 1067 | if (dmi_find_device(DMI_DEV_TYPE_OEM_STRING, oemstrs[i], NULL)) | 1066 | if (dmi_find_device(DMI_DEV_TYPE_OEM_STRING, oemstrs[i], NULL)) |
| 1068 | return 1; | 1067 | return 1; |
| 1069 | 1068 | ||
| 1069 | /* TECRA M4 sometimes forgets its identify and reports bogus | ||
| 1070 | * DMI information. As the bogus information is a bit | ||
| 1071 | * generic, match as many entries as possible. This manual | ||
| 1072 | * matching is necessary because dmi_system_id.matches is | ||
| 1073 | * limited to four entries. | ||
| 1074 | */ | ||
| 1075 | if (dmi_get_system_info(DMI_SYS_VENDOR) && | ||
| 1076 | dmi_get_system_info(DMI_PRODUCT_NAME) && | ||
| 1077 | dmi_get_system_info(DMI_PRODUCT_VERSION) && | ||
| 1078 | dmi_get_system_info(DMI_PRODUCT_SERIAL) && | ||
| 1079 | dmi_get_system_info(DMI_BOARD_VENDOR) && | ||
| 1080 | dmi_get_system_info(DMI_BOARD_NAME) && | ||
| 1081 | dmi_get_system_info(DMI_BOARD_VERSION) && | ||
| 1082 | !strcmp(dmi_get_system_info(DMI_SYS_VENDOR), "TOSHIBA") && | ||
| 1083 | !strcmp(dmi_get_system_info(DMI_PRODUCT_NAME), "000000") && | ||
| 1084 | !strcmp(dmi_get_system_info(DMI_PRODUCT_VERSION), "000000") && | ||
| 1085 | !strcmp(dmi_get_system_info(DMI_PRODUCT_SERIAL), "000000") && | ||
| 1086 | !strcmp(dmi_get_system_info(DMI_BOARD_VENDOR), "TOSHIBA") && | ||
| 1087 | !strcmp(dmi_get_system_info(DMI_BOARD_NAME), "Portable PC") && | ||
| 1088 | !strcmp(dmi_get_system_info(DMI_BOARD_VERSION), "Version A0")) | ||
| 1089 | return 1; | ||
| 1090 | |||
| 1070 | return 0; | 1091 | return 0; |
| 1071 | } | 1092 | } |
| 1072 | 1093 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2ff633c119e2..5e2eb740df46 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -612,7 +612,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) | |||
| 612 | if (tf->flags & ATA_TFLAG_LBA48) { | 612 | if (tf->flags & ATA_TFLAG_LBA48) { |
| 613 | block |= (u64)tf->hob_lbah << 40; | 613 | block |= (u64)tf->hob_lbah << 40; |
| 614 | block |= (u64)tf->hob_lbam << 32; | 614 | block |= (u64)tf->hob_lbam << 32; |
| 615 | block |= tf->hob_lbal << 24; | 615 | block |= (u64)tf->hob_lbal << 24; |
| 616 | } else | 616 | } else |
| 617 | block |= (tf->device & 0xf) << 24; | 617 | block |= (tf->device & 0xf) << 24; |
| 618 | 618 | ||
| @@ -1268,7 +1268,7 @@ u64 ata_tf_to_lba48(const struct ata_taskfile *tf) | |||
| 1268 | 1268 | ||
| 1269 | sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40; | 1269 | sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40; |
| 1270 | sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32; | 1270 | sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32; |
| 1271 | sectors |= (tf->hob_lbal & 0xff) << 24; | 1271 | sectors |= ((u64)(tf->hob_lbal & 0xff)) << 24; |
| 1272 | sectors |= (tf->lbah & 0xff) << 16; | 1272 | sectors |= (tf->lbah & 0xff) << 16; |
| 1273 | sectors |= (tf->lbam & 0xff) << 8; | 1273 | sectors |= (tf->lbam & 0xff) << 8; |
| 1274 | sectors |= (tf->lbal & 0xff); | 1274 | sectors |= (tf->lbal & 0xff); |
| @@ -1602,7 +1602,6 @@ unsigned long ata_id_xfermask(const u16 *id) | |||
| 1602 | /** | 1602 | /** |
| 1603 | * ata_pio_queue_task - Queue port_task | 1603 | * ata_pio_queue_task - Queue port_task |
| 1604 | * @ap: The ata_port to queue port_task for | 1604 | * @ap: The ata_port to queue port_task for |
| 1605 | * @fn: workqueue function to be scheduled | ||
| 1606 | * @data: data for @fn to use | 1605 | * @data: data for @fn to use |
| 1607 | * @delay: delay time in msecs for workqueue function | 1606 | * @delay: delay time in msecs for workqueue function |
| 1608 | * | 1607 | * |
| @@ -1713,6 +1712,8 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, | |||
| 1713 | else | 1712 | else |
| 1714 | tag = 0; | 1713 | tag = 0; |
| 1715 | 1714 | ||
| 1715 | if (test_and_set_bit(tag, &ap->qc_allocated)) | ||
| 1716 | BUG(); | ||
| 1716 | qc = __ata_qc_from_tag(ap, tag); | 1717 | qc = __ata_qc_from_tag(ap, tag); |
| 1717 | 1718 | ||
| 1718 | qc->tag = tag; | 1719 | qc->tag = tag; |
| @@ -2159,6 +2160,10 @@ retry: | |||
| 2159 | static inline u8 ata_dev_knobble(struct ata_device *dev) | 2160 | static inline u8 ata_dev_knobble(struct ata_device *dev) |
| 2160 | { | 2161 | { |
| 2161 | struct ata_port *ap = dev->link->ap; | 2162 | struct ata_port *ap = dev->link->ap; |
| 2163 | |||
| 2164 | if (ata_dev_blacklisted(dev) & ATA_HORKAGE_BRIDGE_OK) | ||
| 2165 | return 0; | ||
| 2166 | |||
| 2162 | return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); | 2167 | return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); |
| 2163 | } | 2168 | } |
| 2164 | 2169 | ||
| @@ -2487,6 +2492,13 @@ int ata_dev_configure(struct ata_device *dev) | |||
| 2487 | } | 2492 | } |
| 2488 | } | 2493 | } |
| 2489 | 2494 | ||
| 2495 | if ((dev->horkage & ATA_HORKAGE_FIRMWARE_WARN) && print_info) { | ||
| 2496 | ata_dev_printk(dev, KERN_WARNING, "WARNING: device requires " | ||
| 2497 | "firmware update to be fully functional.\n"); | ||
| 2498 | ata_dev_printk(dev, KERN_WARNING, " contact the vendor " | ||
| 2499 | "or visit http://ata.wiki.kernel.org.\n"); | ||
| 2500 | } | ||
| 2501 | |||
| 2490 | return 0; | 2502 | return 0; |
| 2491 | 2503 | ||
| 2492 | err_out_nosup: | 2504 | err_out_nosup: |
| @@ -4021,6 +4033,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4021 | 4033 | ||
| 4022 | /* Weird ATAPI devices */ | 4034 | /* Weird ATAPI devices */ |
| 4023 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, | 4035 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, |
| 4036 | { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA }, | ||
| 4024 | 4037 | ||
| 4025 | /* Devices we expect to fail diagnostics */ | 4038 | /* Devices we expect to fail diagnostics */ |
| 4026 | 4039 | ||
| @@ -4036,6 +4049,20 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4036 | { "ST380817AS", "3.42", ATA_HORKAGE_NONCQ }, | 4049 | { "ST380817AS", "3.42", ATA_HORKAGE_NONCQ }, |
| 4037 | { "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ }, | 4050 | { "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ }, |
| 4038 | 4051 | ||
| 4052 | /* Seagate NCQ + FLUSH CACHE firmware bug */ | ||
| 4053 | { "ST31500341AS", "9JU138", ATA_HORKAGE_NONCQ | | ||
| 4054 | ATA_HORKAGE_FIRMWARE_WARN }, | ||
| 4055 | { "ST31000333AS", "9FZ136", ATA_HORKAGE_NONCQ | | ||
| 4056 | ATA_HORKAGE_FIRMWARE_WARN }, | ||
| 4057 | { "ST3640623AS", "9FZ164", ATA_HORKAGE_NONCQ | | ||
| 4058 | ATA_HORKAGE_FIRMWARE_WARN }, | ||
| 4059 | { "ST3640323AS", "9FZ134", ATA_HORKAGE_NONCQ | | ||
| 4060 | ATA_HORKAGE_FIRMWARE_WARN }, | ||
| 4061 | { "ST3320813AS", "9FZ182", ATA_HORKAGE_NONCQ | | ||
| 4062 | ATA_HORKAGE_FIRMWARE_WARN }, | ||
| 4063 | { "ST3320613AS", "9FZ162", ATA_HORKAGE_NONCQ | | ||
| 4064 | ATA_HORKAGE_FIRMWARE_WARN }, | ||
| 4065 | |||
| 4039 | /* Blacklist entries taken from Silicon Image 3124/3132 | 4066 | /* Blacklist entries taken from Silicon Image 3124/3132 |
| 4040 | Windows driver .inf file - also several Linux problem reports */ | 4067 | Windows driver .inf file - also several Linux problem reports */ |
| 4041 | { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, | 4068 | { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, |
| @@ -4063,6 +4090,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4063 | { "TSSTcorp CDDVDW SH-S202N", "SB00", ATA_HORKAGE_IVB, }, | 4090 | { "TSSTcorp CDDVDW SH-S202N", "SB00", ATA_HORKAGE_IVB, }, |
| 4064 | { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, }, | 4091 | { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, }, |
| 4065 | 4092 | ||
| 4093 | /* Devices that do not need bridging limits applied */ | ||
| 4094 | { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, | ||
| 4095 | |||
| 4066 | /* End Marker */ | 4096 | /* End Marker */ |
| 4067 | { } | 4097 | { } |
| 4068 | }; | 4098 | }; |
| @@ -4438,7 +4468,8 @@ int atapi_check_dma(struct ata_queued_cmd *qc) | |||
| 4438 | /* Don't allow DMA if it isn't multiple of 16 bytes. Quite a | 4468 | /* Don't allow DMA if it isn't multiple of 16 bytes. Quite a |
| 4439 | * few ATAPI devices choke on such DMA requests. | 4469 | * few ATAPI devices choke on such DMA requests. |
| 4440 | */ | 4470 | */ |
| 4441 | if (unlikely(qc->nbytes & 15)) | 4471 | if (!(qc->dev->horkage & ATA_HORKAGE_ATAPI_MOD16_DMA) && |
| 4472 | unlikely(qc->nbytes & 15)) | ||
| 4442 | return 1; | 4473 | return 1; |
| 4443 | 4474 | ||
| 4444 | if (ap->ops->check_atapi_dma) | 4475 | if (ap->ops->check_atapi_dma) |
| @@ -4555,6 +4586,37 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
| 4555 | } | 4586 | } |
| 4556 | 4587 | ||
| 4557 | /** | 4588 | /** |
| 4589 | * ata_qc_new - Request an available ATA command, for queueing | ||
| 4590 | * @ap: Port associated with device @dev | ||
| 4591 | * @dev: Device from whom we request an available command structure | ||
| 4592 | * | ||
| 4593 | * LOCKING: | ||
| 4594 | * None. | ||
| 4595 | */ | ||
| 4596 | |||
| 4597 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | ||
| 4598 | { | ||
| 4599 | struct ata_queued_cmd *qc = NULL; | ||
| 4600 | unsigned int i; | ||
| 4601 | |||
| 4602 | /* no command while frozen */ | ||
| 4603 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | ||
| 4604 | return NULL; | ||
| 4605 | |||
| 4606 | /* the last tag is reserved for internal command. */ | ||
| 4607 | for (i = 0; i < ATA_MAX_QUEUE - 1; i++) | ||
| 4608 | if (!test_and_set_bit(i, &ap->qc_allocated)) { | ||
| 4609 | qc = __ata_qc_from_tag(ap, i); | ||
| 4610 | break; | ||
| 4611 | } | ||
| 4612 | |||
| 4613 | if (qc) | ||
| 4614 | qc->tag = i; | ||
| 4615 | |||
| 4616 | return qc; | ||
| 4617 | } | ||
| 4618 | |||
| 4619 | /** | ||
| 4558 | * ata_qc_new_init - Request an available ATA command, and initialize it | 4620 | * ata_qc_new_init - Request an available ATA command, and initialize it |
| 4559 | * @dev: Device from whom we request an available command structure | 4621 | * @dev: Device from whom we request an available command structure |
| 4560 | * @tag: command tag | 4622 | * @tag: command tag |
| @@ -4563,20 +4625,16 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
| 4563 | * None. | 4625 | * None. |
| 4564 | */ | 4626 | */ |
| 4565 | 4627 | ||
| 4566 | struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) | 4628 | struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev) |
| 4567 | { | 4629 | { |
| 4568 | struct ata_port *ap = dev->link->ap; | 4630 | struct ata_port *ap = dev->link->ap; |
| 4569 | struct ata_queued_cmd *qc; | 4631 | struct ata_queued_cmd *qc; |
| 4570 | 4632 | ||
| 4571 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | 4633 | qc = ata_qc_new(ap); |
| 4572 | return NULL; | ||
| 4573 | |||
| 4574 | qc = __ata_qc_from_tag(ap, tag); | ||
| 4575 | if (qc) { | 4634 | if (qc) { |
| 4576 | qc->scsicmd = NULL; | 4635 | qc->scsicmd = NULL; |
| 4577 | qc->ap = ap; | 4636 | qc->ap = ap; |
| 4578 | qc->dev = dev; | 4637 | qc->dev = dev; |
| 4579 | qc->tag = tag; | ||
| 4580 | 4638 | ||
| 4581 | ata_qc_reinit(qc); | 4639 | ata_qc_reinit(qc); |
| 4582 | } | 4640 | } |
| @@ -4584,6 +4642,31 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) | |||
| 4584 | return qc; | 4642 | return qc; |
| 4585 | } | 4643 | } |
| 4586 | 4644 | ||
| 4645 | /** | ||
| 4646 | * ata_qc_free - free unused ata_queued_cmd | ||
| 4647 | * @qc: Command to complete | ||
| 4648 | * | ||
| 4649 | * Designed to free unused ata_queued_cmd object | ||
| 4650 | * in case something prevents using it. | ||
| 4651 | * | ||
| 4652 | * LOCKING: | ||
| 4653 | * spin_lock_irqsave(host lock) | ||
| 4654 | */ | ||
| 4655 | void ata_qc_free(struct ata_queued_cmd *qc) | ||
| 4656 | { | ||
| 4657 | struct ata_port *ap = qc->ap; | ||
| 4658 | unsigned int tag; | ||
| 4659 | |||
| 4660 | WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ | ||
| 4661 | |||
| 4662 | qc->flags = 0; | ||
| 4663 | tag = qc->tag; | ||
| 4664 | if (likely(ata_tag_valid(tag))) { | ||
| 4665 | qc->tag = ATA_TAG_POISON; | ||
| 4666 | clear_bit(tag, &ap->qc_allocated); | ||
| 4667 | } | ||
| 4668 | } | ||
| 4669 | |||
| 4587 | void __ata_qc_complete(struct ata_queued_cmd *qc) | 4670 | void __ata_qc_complete(struct ata_queued_cmd *qc) |
| 4588 | { | 4671 | { |
| 4589 | struct ata_port *ap = qc->ap; | 4672 | struct ata_port *ap = qc->ap; |
| @@ -4648,7 +4731,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) | |||
| 4648 | /** | 4731 | /** |
| 4649 | * ata_qc_complete - Complete an active ATA command | 4732 | * ata_qc_complete - Complete an active ATA command |
| 4650 | * @qc: Command to complete | 4733 | * @qc: Command to complete |
| 4651 | * @err_mask: ATA Status register contents | ||
| 4652 | * | 4734 | * |
| 4653 | * Indicate to the mid and upper layers that an ATA | 4735 | * Indicate to the mid and upper layers that an ATA |
| 4654 | * command has completed, with either an ok or not-ok status. | 4736 | * command has completed, with either an ok or not-ok status. |
| @@ -5929,7 +6011,7 @@ static void ata_port_detach(struct ata_port *ap) | |||
| 5929 | * to us. Restore SControl and disable all existing devices. | 6011 | * to us. Restore SControl and disable all existing devices. |
| 5930 | */ | 6012 | */ |
| 5931 | __ata_port_for_each_link(link, ap) { | 6013 | __ata_port_for_each_link(link, ap) { |
| 5932 | sata_scr_write(link, SCR_CONTROL, link->saved_scontrol); | 6014 | sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0); |
| 5933 | ata_link_for_each_dev(dev, link) | 6015 | ata_link_for_each_dev(dev, link) |
| 5934 | ata_dev_disable(dev); | 6016 | ata_dev_disable(dev); |
| 5935 | } | 6017 | } |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 8077bdf5d30d..32da9a93ce44 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -610,9 +610,6 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
| 610 | if (ata_ncq_enabled(dev)) | 610 | if (ata_ncq_enabled(dev)) |
| 611 | ehc->saved_ncq_enabled |= 1 << devno; | 611 | ehc->saved_ncq_enabled |= 1 << devno; |
| 612 | } | 612 | } |
| 613 | |||
| 614 | /* set last reset timestamp to some time in the past */ | ||
| 615 | ehc->last_reset = jiffies - 60 * HZ; | ||
| 616 | } | 613 | } |
| 617 | 614 | ||
| 618 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; | 615 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; |
| @@ -2281,17 +2278,21 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2281 | if (link->flags & ATA_LFLAG_NO_SRST) | 2278 | if (link->flags & ATA_LFLAG_NO_SRST) |
| 2282 | softreset = NULL; | 2279 | softreset = NULL; |
| 2283 | 2280 | ||
| 2284 | now = jiffies; | 2281 | /* make sure each reset attemp is at least COOL_DOWN apart */ |
| 2285 | deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); | 2282 | if (ehc->i.flags & ATA_EHI_DID_RESET) { |
| 2286 | if (time_before(now, deadline)) | 2283 | now = jiffies; |
| 2287 | schedule_timeout_uninterruptible(deadline - now); | 2284 | WARN_ON(time_after(ehc->last_reset, now)); |
| 2285 | deadline = ata_deadline(ehc->last_reset, | ||
| 2286 | ATA_EH_RESET_COOL_DOWN); | ||
| 2287 | if (time_before(now, deadline)) | ||
| 2288 | schedule_timeout_uninterruptible(deadline - now); | ||
| 2289 | } | ||
| 2288 | 2290 | ||
| 2289 | spin_lock_irqsave(ap->lock, flags); | 2291 | spin_lock_irqsave(ap->lock, flags); |
| 2290 | ap->pflags |= ATA_PFLAG_RESETTING; | 2292 | ap->pflags |= ATA_PFLAG_RESETTING; |
| 2291 | spin_unlock_irqrestore(ap->lock, flags); | 2293 | spin_unlock_irqrestore(ap->lock, flags); |
| 2292 | 2294 | ||
| 2293 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2295 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
| 2294 | ehc->last_reset = jiffies; | ||
| 2295 | 2296 | ||
| 2296 | ata_link_for_each_dev(dev, link) { | 2297 | ata_link_for_each_dev(dev, link) { |
| 2297 | /* If we issue an SRST then an ATA drive (not ATAPI) | 2298 | /* If we issue an SRST then an ATA drive (not ATAPI) |
| @@ -2379,7 +2380,6 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2379 | /* | 2380 | /* |
| 2380 | * Perform reset | 2381 | * Perform reset |
| 2381 | */ | 2382 | */ |
| 2382 | ehc->last_reset = jiffies; | ||
| 2383 | if (ata_is_host_link(link)) | 2383 | if (ata_is_host_link(link)) |
| 2384 | ata_eh_freeze_port(ap); | 2384 | ata_eh_freeze_port(ap); |
| 2385 | 2385 | ||
| @@ -2391,6 +2391,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2391 | reset == softreset ? "soft" : "hard"); | 2391 | reset == softreset ? "soft" : "hard"); |
| 2392 | 2392 | ||
| 2393 | /* mark that this EH session started with reset */ | 2393 | /* mark that this EH session started with reset */ |
| 2394 | ehc->last_reset = jiffies; | ||
| 2394 | if (reset == hardreset) | 2395 | if (reset == hardreset) |
| 2395 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; | 2396 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; |
| 2396 | else | 2397 | else |
| @@ -2535,7 +2536,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2535 | ata_eh_done(link, NULL, ATA_EH_RESET); | 2536 | ata_eh_done(link, NULL, ATA_EH_RESET); |
| 2536 | if (slave) | 2537 | if (slave) |
| 2537 | ata_eh_done(slave, NULL, ATA_EH_RESET); | 2538 | ata_eh_done(slave, NULL, ATA_EH_RESET); |
| 2538 | ehc->last_reset = jiffies; | 2539 | ehc->last_reset = jiffies; /* update to completion time */ |
| 2539 | ehc->i.action |= ATA_EH_REVALIDATE; | 2540 | ehc->i.action |= ATA_EH_REVALIDATE; |
| 2540 | 2541 | ||
| 2541 | rc = 0; | 2542 | rc = 0; |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index bbb30d882f05..47c7afcb36f2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -190,7 +190,7 @@ static ssize_t ata_scsi_park_show(struct device *device, | |||
| 190 | struct ata_port *ap; | 190 | struct ata_port *ap; |
| 191 | struct ata_link *link; | 191 | struct ata_link *link; |
| 192 | struct ata_device *dev; | 192 | struct ata_device *dev; |
| 193 | unsigned long flags; | 193 | unsigned long flags, now; |
| 194 | unsigned int uninitialized_var(msecs); | 194 | unsigned int uninitialized_var(msecs); |
| 195 | int rc = 0; | 195 | int rc = 0; |
| 196 | 196 | ||
| @@ -208,10 +208,11 @@ static ssize_t ata_scsi_park_show(struct device *device, | |||
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | link = dev->link; | 210 | link = dev->link; |
| 211 | now = jiffies; | ||
| 211 | if (ap->pflags & ATA_PFLAG_EH_IN_PROGRESS && | 212 | if (ap->pflags & ATA_PFLAG_EH_IN_PROGRESS && |
| 212 | link->eh_context.unloaded_mask & (1 << dev->devno) && | 213 | link->eh_context.unloaded_mask & (1 << dev->devno) && |
| 213 | time_after(dev->unpark_deadline, jiffies)) | 214 | time_after(dev->unpark_deadline, now)) |
| 214 | msecs = jiffies_to_msecs(dev->unpark_deadline - jiffies); | 215 | msecs = jiffies_to_msecs(dev->unpark_deadline - now); |
| 215 | else | 216 | else |
| 216 | msecs = 0; | 217 | msecs = 0; |
| 217 | 218 | ||
| @@ -708,11 +709,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, | |||
| 708 | { | 709 | { |
| 709 | struct ata_queued_cmd *qc; | 710 | struct ata_queued_cmd *qc; |
| 710 | 711 | ||
| 711 | if (cmd->request->tag != -1) | 712 | qc = ata_qc_new_init(dev); |
| 712 | qc = ata_qc_new_init(dev, cmd->request->tag); | ||
| 713 | else | ||
| 714 | qc = ata_qc_new_init(dev, 0); | ||
| 715 | |||
| 716 | if (qc) { | 713 | if (qc) { |
| 717 | qc->scsicmd = cmd; | 714 | qc->scsicmd = cmd; |
| 718 | qc->scsidone = done; | 715 | qc->scsidone = done; |
| @@ -1107,17 +1104,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, | |||
| 1107 | 1104 | ||
| 1108 | depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); | 1105 | depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); |
| 1109 | depth = min(ATA_MAX_QUEUE - 1, depth); | 1106 | depth = min(ATA_MAX_QUEUE - 1, depth); |
| 1110 | 1107 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); | |
| 1111 | /* | ||
| 1112 | * If this device is behind a port multiplier, we have | ||
| 1113 | * to share the tag map between all devices on that PMP. | ||
| 1114 | * Set up the shared tag map here and we get automatic. | ||
| 1115 | */ | ||
| 1116 | if (dev->link->ap->pmp_link) | ||
| 1117 | scsi_init_shared_tag_map(sdev->host, ATA_MAX_QUEUE - 1); | ||
| 1118 | |||
| 1119 | scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); | ||
| 1120 | scsi_activate_tcq(sdev, depth); | ||
| 1121 | } | 1108 | } |
| 1122 | 1109 | ||
| 1123 | return 0; | 1110 | return 0; |
| @@ -1957,11 +1944,6 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) | |||
| 1957 | hdr[1] |= (1 << 7); | 1944 | hdr[1] |= (1 << 7); |
| 1958 | 1945 | ||
| 1959 | memcpy(rbuf, hdr, sizeof(hdr)); | 1946 | memcpy(rbuf, hdr, sizeof(hdr)); |
| 1960 | |||
| 1961 | /* if ncq, set tags supported */ | ||
| 1962 | if (ata_id_has_ncq(args->id)) | ||
| 1963 | rbuf[7] |= (1 << 1); | ||
| 1964 | |||
| 1965 | memcpy(&rbuf[8], "ATA ", 8); | 1947 | memcpy(&rbuf[8], "ATA ", 8); |
| 1966 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); | 1948 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); |
| 1967 | ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4); | 1949 | ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 4b4739486327..9033d164c4ec 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
| @@ -1227,10 +1227,19 @@ fsm_start: | |||
| 1227 | /* ATA PIO protocol */ | 1227 | /* ATA PIO protocol */ |
| 1228 | if (unlikely((status & ATA_DRQ) == 0)) { | 1228 | if (unlikely((status & ATA_DRQ) == 0)) { |
| 1229 | /* handle BSY=0, DRQ=0 as error */ | 1229 | /* handle BSY=0, DRQ=0 as error */ |
| 1230 | if (likely(status & (ATA_ERR | ATA_DF))) | 1230 | if (likely(status & (ATA_ERR | ATA_DF))) { |
| 1231 | /* device stops HSM for abort/error */ | 1231 | /* device stops HSM for abort/error */ |
| 1232 | qc->err_mask |= AC_ERR_DEV; | 1232 | qc->err_mask |= AC_ERR_DEV; |
| 1233 | else { | 1233 | |
| 1234 | /* If diagnostic failed and this is | ||
| 1235 | * IDENTIFY, it's likely a phantom | ||
| 1236 | * device. Mark hint. | ||
| 1237 | */ | ||
| 1238 | if (qc->dev->horkage & | ||
| 1239 | ATA_HORKAGE_DIAGNOSTIC) | ||
| 1240 | qc->err_mask |= | ||
| 1241 | AC_ERR_NODEV_HINT; | ||
| 1242 | } else { | ||
| 1234 | /* HSM violation. Let EH handle this. | 1243 | /* HSM violation. Let EH handle this. |
| 1235 | * Phantom devices also trigger this | 1244 | * Phantom devices also trigger this |
| 1236 | * condition. Mark hint. | 1245 | * condition. Mark hint. |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index d3831d39bdaa..fe2839e58774 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
| @@ -74,7 +74,7 @@ extern struct ata_link *ata_dev_phys_link(struct ata_device *dev); | |||
| 74 | extern void ata_force_cbl(struct ata_port *ap); | 74 | extern void ata_force_cbl(struct ata_port *ap); |
| 75 | extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); | 75 | extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); |
| 76 | extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); | 76 | extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); |
| 77 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); | 77 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); |
| 78 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, | 78 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, |
| 79 | u64 block, u32 n_block, unsigned int tf_flags, | 79 | u64 block, u32 n_block, unsigned int tf_flags, |
| 80 | unsigned int tag); | 80 | unsigned int tag); |
| @@ -103,6 +103,7 @@ extern int ata_dev_configure(struct ata_device *dev); | |||
| 103 | extern int sata_down_spd_limit(struct ata_link *link); | 103 | extern int sata_down_spd_limit(struct ata_link *link); |
| 104 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); | 104 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); |
| 105 | extern void ata_sg_clean(struct ata_queued_cmd *qc); | 105 | extern void ata_sg_clean(struct ata_queued_cmd *qc); |
| 106 | extern void ata_qc_free(struct ata_queued_cmd *qc); | ||
| 106 | extern void ata_qc_issue(struct ata_queued_cmd *qc); | 107 | extern void ata_qc_issue(struct ata_queued_cmd *qc); |
| 107 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); | 108 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); |
| 108 | extern int atapi_check_dma(struct ata_queued_cmd *qc); | 109 | extern int atapi_check_dma(struct ata_queued_cmd *qc); |
| @@ -118,22 +119,6 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host); | |||
| 118 | extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); | 119 | extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); |
| 119 | extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); | 120 | extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); |
| 120 | 121 | ||
| 121 | /** | ||
| 122 | * ata_qc_free - free unused ata_queued_cmd | ||
| 123 | * @qc: Command to complete | ||
| 124 | * | ||
| 125 | * Designed to free unused ata_queued_cmd object | ||
| 126 | * in case something prevents using it. | ||
| 127 | * | ||
| 128 | * LOCKING: | ||
| 129 | * spin_lock_irqsave(host lock) | ||
| 130 | */ | ||
| 131 | static inline void ata_qc_free(struct ata_queued_cmd *qc) | ||
| 132 | { | ||
| 133 | qc->flags = 0; | ||
| 134 | qc->tag = ATA_TAG_POISON; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* libata-acpi.c */ | 122 | /* libata-acpi.c */ |
| 138 | #ifdef CONFIG_ATA_ACPI | 123 | #ifdef CONFIG_ATA_ACPI |
| 139 | extern void ata_acpi_associate_sata_port(struct ata_port *ap); | 124 | extern void ata_acpi_associate_sata_port(struct ata_port *ap); |
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 1b2d4a0f5f74..8b236af84c2e 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c | |||
| @@ -72,7 +72,6 @@ | |||
| 72 | /** | 72 | /** |
| 73 | * cs5535_cable_detect - detect cable type | 73 | * cs5535_cable_detect - detect cable type |
| 74 | * @ap: Port to detect on | 74 | * @ap: Port to detect on |
| 75 | * @deadline: deadline jiffies for the operation | ||
| 76 | * | 75 | * |
| 77 | * Perform cable detection for ATA66 capable cable. Return a libata | 76 | * Perform cable detection for ATA66 capable cable. Return a libata |
| 78 | * cable type. | 77 | * cable type. |
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 73f8332cb679..afed92976198 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c | |||
| @@ -110,7 +110,6 @@ static inline int cs5536_write(struct pci_dev *pdev, int reg, int val) | |||
| 110 | /** | 110 | /** |
| 111 | * cs5536_cable_detect - detect cable type | 111 | * cs5536_cable_detect - detect cable type |
| 112 | * @ap: Port to detect on | 112 | * @ap: Port to detect on |
| 113 | * @deadline: deadline jiffies for the operation | ||
| 114 | * | 113 | * |
| 115 | * Perform cable detection for ATA66 capable cable. Return a libata | 114 | * Perform cable detection for ATA66 capable cable. Return a libata |
| 116 | * cable type. | 115 | * cable type. |
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index f2b83eabc7c7..a098ba8eaab6 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
| @@ -382,10 +382,10 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 382 | /* PCI clocking determines the ATA timing values to use */ | 382 | /* PCI clocking determines the ATA timing values to use */ |
| 383 | /* info_hpt366 is safe against re-entry so we can scribble on it */ | 383 | /* info_hpt366 is safe against re-entry so we can scribble on it */ |
| 384 | switch((reg1 & 0x700) >> 8) { | 384 | switch((reg1 & 0x700) >> 8) { |
| 385 | case 5: | 385 | case 9: |
| 386 | hpriv = &hpt366_40; | 386 | hpriv = &hpt366_40; |
| 387 | break; | 387 | break; |
| 388 | case 9: | 388 | case 5: |
| 389 | hpriv = &hpt366_25; | 389 | hpriv = &hpt366_25; |
| 390 | break; | 390 | break; |
| 391 | default: | 391 | default: |
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 4e466eae8b46..4dd9a3b031e4 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | #include <linux/libata.h> | 44 | #include <linux/libata.h> |
| 45 | 45 | ||
| 46 | #define DRV_NAME "pata_ninja32" | 46 | #define DRV_NAME "pata_ninja32" |
| 47 | #define DRV_VERSION "0.1.1" | 47 | #define DRV_VERSION "0.1.3" |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| @@ -130,7 +130,8 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 130 | return rc; | 130 | return rc; |
| 131 | pci_set_master(dev); | 131 | pci_set_master(dev); |
| 132 | 132 | ||
| 133 | /* Set up the register mappings */ | 133 | /* Set up the register mappings. We use the I/O mapping as only the |
| 134 | older chips also have MMIO on BAR 1 */ | ||
| 134 | base = host->iomap[0]; | 135 | base = host->iomap[0]; |
| 135 | if (!base) | 136 | if (!base) |
| 136 | return -ENOMEM; | 137 | return -ENOMEM; |
| @@ -167,8 +168,12 @@ static int ninja32_reinit_one(struct pci_dev *pdev) | |||
| 167 | #endif | 168 | #endif |
| 168 | 169 | ||
| 169 | static const struct pci_device_id ninja32[] = { | 170 | static const struct pci_device_id ninja32[] = { |
| 171 | { 0x10FC, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
| 172 | { 0x1145, 0x8008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
| 173 | { 0x1145, 0xf008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
| 170 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 174 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
| 171 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 175 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
| 176 | { 0x1145, 0xf02C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
| 172 | { }, | 177 | { }, |
| 173 | }; | 178 | }; |
| 174 | 179 | ||
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 271cb64d429e..64b2e2281ee7 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
| @@ -416,6 +416,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { | |||
| 416 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 416 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
| 417 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 417 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
| 418 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | 418 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), |
| 419 | PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506), | ||
| 419 | PCMCIA_DEVICE_NULL, | 420 | PCMCIA_DEVICE_NULL, |
| 420 | }; | 421 | }; |
| 421 | 422 | ||
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index f8b3ffc8ae9e..c2e6fb9f2ef9 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c | |||
| @@ -39,9 +39,11 @@ | |||
| 39 | #define RB500_CF_MAXPORTS 1 | 39 | #define RB500_CF_MAXPORTS 1 |
| 40 | #define RB500_CF_IO_DELAY 400 | 40 | #define RB500_CF_IO_DELAY 400 |
| 41 | 41 | ||
| 42 | #define RB500_CF_REG_CMD 0x0800 | 42 | #define RB500_CF_REG_BASE 0x0800 |
| 43 | #define RB500_CF_REG_ERR 0x080D | ||
| 43 | #define RB500_CF_REG_CTRL 0x080E | 44 | #define RB500_CF_REG_CTRL 0x080E |
| 44 | #define RB500_CF_REG_DATA 0x0C00 | 45 | /* 32bit buffered data register offset */ |
| 46 | #define RB500_CF_REG_DBUF32 0x0C00 | ||
| 45 | 47 | ||
| 46 | struct rb532_cf_info { | 48 | struct rb532_cf_info { |
| 47 | void __iomem *iobase; | 49 | void __iomem *iobase; |
| @@ -72,11 +74,12 @@ static void rb532_pata_exec_command(struct ata_port *ap, | |||
| 72 | rb532_pata_finish_io(ap); | 74 | rb532_pata_finish_io(ap); |
| 73 | } | 75 | } |
| 74 | 76 | ||
| 75 | static void rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, | 77 | static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, |
| 76 | unsigned int buflen, int write_data) | 78 | unsigned int buflen, int write_data) |
| 77 | { | 79 | { |
| 78 | struct ata_port *ap = adev->link->ap; | 80 | struct ata_port *ap = adev->link->ap; |
| 79 | void __iomem *ioaddr = ap->ioaddr.data_addr; | 81 | void __iomem *ioaddr = ap->ioaddr.data_addr; |
| 82 | int retlen = buflen; | ||
| 80 | 83 | ||
| 81 | if (write_data) { | 84 | if (write_data) { |
| 82 | for (; buflen > 0; buflen--, buf++) | 85 | for (; buflen > 0; buflen--, buf++) |
| @@ -87,6 +90,7 @@ static void rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | rb532_pata_finish_io(adev->link->ap); | 92 | rb532_pata_finish_io(adev->link->ap); |
| 93 | return retlen; | ||
| 90 | } | 94 | } |
| 91 | 95 | ||
| 92 | static void rb532_pata_freeze(struct ata_port *ap) | 96 | static void rb532_pata_freeze(struct ata_port *ap) |
| @@ -146,13 +150,14 @@ static void rb532_pata_setup_ports(struct ata_host *ah) | |||
| 146 | ap->pio_mask = 0x1f; /* PIO4 */ | 150 | ap->pio_mask = 0x1f; /* PIO4 */ |
| 147 | ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; | 151 | ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; |
| 148 | 152 | ||
| 149 | ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_CMD; | 153 | ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE; |
| 150 | ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; | 154 | ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; |
| 151 | ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL; | 155 | ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL; |
| 152 | 156 | ||
| 153 | ata_sff_std_ports(&ap->ioaddr); | 157 | ata_sff_std_ports(&ap->ioaddr); |
| 154 | 158 | ||
| 155 | ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DATA; | 159 | ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DBUF32; |
| 160 | ap->ioaddr.error_addr = info->iobase + RB500_CF_REG_ERR; | ||
| 156 | } | 161 | } |
| 157 | 162 | ||
| 158 | static __devinit int rb532_pata_driver_probe(struct platform_device *pdev) | 163 | static __devinit int rb532_pata_driver_probe(struct platform_device *pdev) |
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index c8cc027789fe..6aeeeeb34124 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c | |||
| @@ -83,7 +83,7 @@ static struct ata_port_operations sch_pata_ops = { | |||
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static struct ata_port_info sch_port_info = { | 85 | static struct ata_port_info sch_port_info = { |
| 86 | .flags = 0, | 86 | .flags = ATA_FLAG_SLAVE_POSS, |
| 87 | .pio_mask = ATA_PIO4, /* pio0-4 */ | 87 | .pio_mask = ATA_PIO4, /* pio0-4 */ |
| 88 | .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ | 88 | .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ |
| 89 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 89 | .udma_mask = ATA_UDMA5, /* udma0-5 */ |
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index d34236611752..e4be55e047f6 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c | |||
| @@ -56,7 +56,6 @@ static const struct sis_laptop sis_laptop[] = { | |||
| 56 | { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ | 56 | { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ |
| 57 | { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ | 57 | { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ |
| 58 | { 0x5513, 0x1071, 0x8640 }, /* EasyNote K5305 */ | 58 | { 0x5513, 0x1071, 0x8640 }, /* EasyNote K5305 */ |
| 59 | { 0x5513, 0x1039, 0x5513 }, /* Targa Visionary 1000 */ | ||
| 60 | /* end marker */ | 59 | /* end marker */ |
| 61 | { 0, } | 60 | { 0, } |
| 62 | }; | 61 | }; |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index fae3841de0d8..6f1460614325 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
| @@ -307,10 +307,10 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); | |||
| 307 | 307 | ||
| 308 | static void nv_nf2_freeze(struct ata_port *ap); | 308 | static void nv_nf2_freeze(struct ata_port *ap); |
| 309 | static void nv_nf2_thaw(struct ata_port *ap); | 309 | static void nv_nf2_thaw(struct ata_port *ap); |
| 310 | static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class, | ||
| 311 | unsigned long deadline); | ||
| 310 | static void nv_ck804_freeze(struct ata_port *ap); | 312 | static void nv_ck804_freeze(struct ata_port *ap); |
| 311 | static void nv_ck804_thaw(struct ata_port *ap); | 313 | static void nv_ck804_thaw(struct ata_port *ap); |
| 312 | static int nv_hardreset(struct ata_link *link, unsigned int *class, | ||
| 313 | unsigned long deadline); | ||
| 314 | static int nv_adma_slave_config(struct scsi_device *sdev); | 314 | static int nv_adma_slave_config(struct scsi_device *sdev); |
| 315 | static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); | 315 | static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); |
| 316 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc); | 316 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc); |
| @@ -405,17 +405,8 @@ static struct scsi_host_template nv_swncq_sht = { | |||
| 405 | .slave_configure = nv_swncq_slave_config, | 405 | .slave_configure = nv_swncq_slave_config, |
| 406 | }; | 406 | }; |
| 407 | 407 | ||
| 408 | /* OSDL bz3352 reports that some nv controllers can't determine device | ||
| 409 | * signature reliably and nv_hardreset is implemented to work around | ||
| 410 | * the problem. This was reported on nf3 and it's unclear whether any | ||
| 411 | * other controllers are affected. However, the workaround has been | ||
| 412 | * applied to all variants and there isn't much to gain by trying to | ||
| 413 | * find out exactly which ones are affected at this point especially | ||
| 414 | * because NV has moved over to ahci for newer controllers. | ||
| 415 | */ | ||
| 416 | static struct ata_port_operations nv_common_ops = { | 408 | static struct ata_port_operations nv_common_ops = { |
| 417 | .inherits = &ata_bmdma_port_ops, | 409 | .inherits = &ata_bmdma_port_ops, |
| 418 | .hardreset = nv_hardreset, | ||
| 419 | .scr_read = nv_scr_read, | 410 | .scr_read = nv_scr_read, |
| 420 | .scr_write = nv_scr_write, | 411 | .scr_write = nv_scr_write, |
| 421 | }; | 412 | }; |
| @@ -429,12 +420,22 @@ static struct ata_port_operations nv_generic_ops = { | |||
| 429 | .hardreset = ATA_OP_NULL, | 420 | .hardreset = ATA_OP_NULL, |
| 430 | }; | 421 | }; |
| 431 | 422 | ||
| 423 | /* OSDL bz3352 reports that nf2/3 controllers can't determine device | ||
| 424 | * signature reliably. Also, the following thread reports detection | ||
| 425 | * failure on cold boot with the standard debouncing timing. | ||
| 426 | * | ||
| 427 | * http://thread.gmane.org/gmane.linux.ide/34098 | ||
| 428 | * | ||
| 429 | * Debounce with hotplug timing and request follow-up SRST. | ||
| 430 | */ | ||
| 432 | static struct ata_port_operations nv_nf2_ops = { | 431 | static struct ata_port_operations nv_nf2_ops = { |
| 433 | .inherits = &nv_common_ops, | 432 | .inherits = &nv_common_ops, |
| 434 | .freeze = nv_nf2_freeze, | 433 | .freeze = nv_nf2_freeze, |
| 435 | .thaw = nv_nf2_thaw, | 434 | .thaw = nv_nf2_thaw, |
| 435 | .hardreset = nv_nf2_hardreset, | ||
| 436 | }; | 436 | }; |
| 437 | 437 | ||
| 438 | /* CK804 finally gets hardreset right */ | ||
| 438 | static struct ata_port_operations nv_ck804_ops = { | 439 | static struct ata_port_operations nv_ck804_ops = { |
| 439 | .inherits = &nv_common_ops, | 440 | .inherits = &nv_common_ops, |
| 440 | .freeze = nv_ck804_freeze, | 441 | .freeze = nv_ck804_freeze, |
| @@ -443,7 +444,7 @@ static struct ata_port_operations nv_ck804_ops = { | |||
| 443 | }; | 444 | }; |
| 444 | 445 | ||
| 445 | static struct ata_port_operations nv_adma_ops = { | 446 | static struct ata_port_operations nv_adma_ops = { |
| 446 | .inherits = &nv_common_ops, | 447 | .inherits = &nv_ck804_ops, |
| 447 | 448 | ||
| 448 | .check_atapi_dma = nv_adma_check_atapi_dma, | 449 | .check_atapi_dma = nv_adma_check_atapi_dma, |
| 449 | .sff_tf_read = nv_adma_tf_read, | 450 | .sff_tf_read = nv_adma_tf_read, |
| @@ -467,7 +468,7 @@ static struct ata_port_operations nv_adma_ops = { | |||
| 467 | }; | 468 | }; |
| 468 | 469 | ||
| 469 | static struct ata_port_operations nv_swncq_ops = { | 470 | static struct ata_port_operations nv_swncq_ops = { |
| 470 | .inherits = &nv_common_ops, | 471 | .inherits = &nv_generic_ops, |
| 471 | 472 | ||
| 472 | .qc_defer = ata_std_qc_defer, | 473 | .qc_defer = ata_std_qc_defer, |
| 473 | .qc_prep = nv_swncq_qc_prep, | 474 | .qc_prep = nv_swncq_qc_prep, |
| @@ -1553,6 +1554,17 @@ static void nv_nf2_thaw(struct ata_port *ap) | |||
| 1553 | iowrite8(mask, scr_addr + NV_INT_ENABLE); | 1554 | iowrite8(mask, scr_addr + NV_INT_ENABLE); |
| 1554 | } | 1555 | } |
| 1555 | 1556 | ||
| 1557 | static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class, | ||
| 1558 | unsigned long deadline) | ||
| 1559 | { | ||
| 1560 | bool online; | ||
| 1561 | int rc; | ||
| 1562 | |||
| 1563 | rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, | ||
| 1564 | &online, NULL); | ||
| 1565 | return online ? -EAGAIN : rc; | ||
| 1566 | } | ||
| 1567 | |||
| 1556 | static void nv_ck804_freeze(struct ata_port *ap) | 1568 | static void nv_ck804_freeze(struct ata_port *ap) |
| 1557 | { | 1569 | { |
| 1558 | void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; | 1570 | void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; |
| @@ -1605,21 +1617,6 @@ static void nv_mcp55_thaw(struct ata_port *ap) | |||
| 1605 | ata_sff_thaw(ap); | 1617 | ata_sff_thaw(ap); |
| 1606 | } | 1618 | } |
| 1607 | 1619 | ||
| 1608 | static int nv_hardreset(struct ata_link *link, unsigned int *class, | ||
| 1609 | unsigned long deadline) | ||
| 1610 | { | ||
| 1611 | int rc; | ||
| 1612 | |||
| 1613 | /* SATA hardreset fails to retrieve proper device signature on | ||
| 1614 | * some controllers. Request follow up SRST. For more info, | ||
| 1615 | * see http://bugzilla.kernel.org/show_bug.cgi?id=3352 | ||
| 1616 | */ | ||
| 1617 | rc = sata_sff_hardreset(link, class, deadline); | ||
| 1618 | if (rc) | ||
| 1619 | return rc; | ||
| 1620 | return -EAGAIN; | ||
| 1621 | } | ||
| 1622 | |||
| 1623 | static void nv_adma_error_handler(struct ata_port *ap) | 1620 | static void nv_adma_error_handler(struct ata_port *ap) |
| 1624 | { | 1621 | { |
| 1625 | struct nv_adma_port_priv *pp = ap->private_data; | 1622 | struct nv_adma_port_priv *pp = ap->private_data; |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 750d8cdc00cd..ba9a2570a742 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
| @@ -153,6 +153,10 @@ static void pdc_freeze(struct ata_port *ap); | |||
| 153 | static void pdc_sata_freeze(struct ata_port *ap); | 153 | static void pdc_sata_freeze(struct ata_port *ap); |
| 154 | static void pdc_thaw(struct ata_port *ap); | 154 | static void pdc_thaw(struct ata_port *ap); |
| 155 | static void pdc_sata_thaw(struct ata_port *ap); | 155 | static void pdc_sata_thaw(struct ata_port *ap); |
| 156 | static int pdc_pata_softreset(struct ata_link *link, unsigned int *class, | ||
| 157 | unsigned long deadline); | ||
| 158 | static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, | ||
| 159 | unsigned long deadline); | ||
| 156 | static void pdc_error_handler(struct ata_port *ap); | 160 | static void pdc_error_handler(struct ata_port *ap); |
| 157 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); | 161 | static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); |
| 158 | static int pdc_pata_cable_detect(struct ata_port *ap); | 162 | static int pdc_pata_cable_detect(struct ata_port *ap); |
| @@ -186,6 +190,7 @@ static struct ata_port_operations pdc_sata_ops = { | |||
| 186 | .scr_read = pdc_sata_scr_read, | 190 | .scr_read = pdc_sata_scr_read, |
| 187 | .scr_write = pdc_sata_scr_write, | 191 | .scr_write = pdc_sata_scr_write, |
| 188 | .port_start = pdc_sata_port_start, | 192 | .port_start = pdc_sata_port_start, |
| 193 | .hardreset = pdc_sata_hardreset, | ||
| 189 | }; | 194 | }; |
| 190 | 195 | ||
| 191 | /* First-generation chips need a more restrictive ->check_atapi_dma op */ | 196 | /* First-generation chips need a more restrictive ->check_atapi_dma op */ |
| @@ -200,6 +205,7 @@ static struct ata_port_operations pdc_pata_ops = { | |||
| 200 | .freeze = pdc_freeze, | 205 | .freeze = pdc_freeze, |
| 201 | .thaw = pdc_thaw, | 206 | .thaw = pdc_thaw, |
| 202 | .port_start = pdc_common_port_start, | 207 | .port_start = pdc_common_port_start, |
| 208 | .softreset = pdc_pata_softreset, | ||
| 203 | }; | 209 | }; |
| 204 | 210 | ||
| 205 | static const struct ata_port_info pdc_port_info[] = { | 211 | static const struct ata_port_info pdc_port_info[] = { |
| @@ -693,6 +699,20 @@ static void pdc_sata_thaw(struct ata_port *ap) | |||
| 693 | readl(host_mmio + hotplug_offset); /* flush */ | 699 | readl(host_mmio + hotplug_offset); /* flush */ |
| 694 | } | 700 | } |
| 695 | 701 | ||
| 702 | static int pdc_pata_softreset(struct ata_link *link, unsigned int *class, | ||
| 703 | unsigned long deadline) | ||
| 704 | { | ||
| 705 | pdc_reset_port(link->ap); | ||
| 706 | return ata_sff_softreset(link, class, deadline); | ||
| 707 | } | ||
| 708 | |||
| 709 | static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, | ||
| 710 | unsigned long deadline) | ||
| 711 | { | ||
| 712 | pdc_reset_port(link->ap); | ||
| 713 | return sata_sff_hardreset(link, class, deadline); | ||
| 714 | } | ||
| 715 | |||
| 696 | static void pdc_error_handler(struct ata_port *ap) | 716 | static void pdc_error_handler(struct ata_port *ap) |
| 697 | { | 717 | { |
| 698 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | 718 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 5b72e734300a..c18935f0bda2 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
| @@ -44,11 +44,16 @@ | |||
| 44 | #include <linux/libata.h> | 44 | #include <linux/libata.h> |
| 45 | 45 | ||
| 46 | #define DRV_NAME "sata_via" | 46 | #define DRV_NAME "sata_via" |
| 47 | #define DRV_VERSION "2.3" | 47 | #define DRV_VERSION "2.4" |
| 48 | 48 | ||
| 49 | /* | ||
| 50 | * vt8251 is different from other sata controllers of VIA. It has two | ||
| 51 | * channels, each channel has both Master and Slave slot. | ||
| 52 | */ | ||
| 49 | enum board_ids_enum { | 53 | enum board_ids_enum { |
| 50 | vt6420, | 54 | vt6420, |
| 51 | vt6421, | 55 | vt6421, |
| 56 | vt8251, | ||
| 52 | }; | 57 | }; |
| 53 | 58 | ||
| 54 | enum { | 59 | enum { |
| @@ -70,6 +75,8 @@ enum { | |||
| 70 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 75 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
| 71 | static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 76 | static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
| 72 | static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); | 77 | static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
| 78 | static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val); | ||
| 79 | static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val); | ||
| 73 | static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); | 80 | static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); |
| 74 | static void svia_noop_freeze(struct ata_port *ap); | 81 | static void svia_noop_freeze(struct ata_port *ap); |
| 75 | static int vt6420_prereset(struct ata_link *link, unsigned long deadline); | 82 | static int vt6420_prereset(struct ata_link *link, unsigned long deadline); |
| @@ -79,12 +86,12 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); | |||
| 79 | 86 | ||
| 80 | static const struct pci_device_id svia_pci_tbl[] = { | 87 | static const struct pci_device_id svia_pci_tbl[] = { |
| 81 | { PCI_VDEVICE(VIA, 0x5337), vt6420 }, | 88 | { PCI_VDEVICE(VIA, 0x5337), vt6420 }, |
| 82 | { PCI_VDEVICE(VIA, 0x0591), vt6420 }, | 89 | { PCI_VDEVICE(VIA, 0x0591), vt6420 }, /* 2 sata chnls (Master) */ |
| 83 | { PCI_VDEVICE(VIA, 0x3149), vt6420 }, | 90 | { PCI_VDEVICE(VIA, 0x3149), vt6420 }, /* 2 sata chnls (Master) */ |
| 84 | { PCI_VDEVICE(VIA, 0x3249), vt6421 }, | 91 | { PCI_VDEVICE(VIA, 0x3249), vt6421 }, /* 2 sata chnls, 1 pata chnl */ |
| 85 | { PCI_VDEVICE(VIA, 0x5287), vt6420 }, | ||
| 86 | { PCI_VDEVICE(VIA, 0x5372), vt6420 }, | 92 | { PCI_VDEVICE(VIA, 0x5372), vt6420 }, |
| 87 | { PCI_VDEVICE(VIA, 0x7372), vt6420 }, | 93 | { PCI_VDEVICE(VIA, 0x7372), vt6420 }, |
| 94 | { PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */ | ||
| 88 | 95 | ||
| 89 | { } /* terminate list */ | 96 | { } /* terminate list */ |
| 90 | }; | 97 | }; |
| @@ -128,6 +135,13 @@ static struct ata_port_operations vt6421_sata_ops = { | |||
| 128 | .scr_write = svia_scr_write, | 135 | .scr_write = svia_scr_write, |
| 129 | }; | 136 | }; |
| 130 | 137 | ||
| 138 | static struct ata_port_operations vt8251_ops = { | ||
| 139 | .inherits = &svia_base_ops, | ||
| 140 | .hardreset = sata_std_hardreset, | ||
| 141 | .scr_read = vt8251_scr_read, | ||
| 142 | .scr_write = vt8251_scr_write, | ||
| 143 | }; | ||
| 144 | |||
| 131 | static const struct ata_port_info vt6420_port_info = { | 145 | static const struct ata_port_info vt6420_port_info = { |
| 132 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 146 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, |
| 133 | .pio_mask = 0x1f, | 147 | .pio_mask = 0x1f, |
| @@ -152,6 +166,15 @@ static struct ata_port_info vt6421_pport_info = { | |||
| 152 | .port_ops = &vt6421_pata_ops, | 166 | .port_ops = &vt6421_pata_ops, |
| 153 | }; | 167 | }; |
| 154 | 168 | ||
| 169 | static struct ata_port_info vt8251_port_info = { | ||
| 170 | .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS | | ||
| 171 | ATA_FLAG_NO_LEGACY, | ||
| 172 | .pio_mask = 0x1f, | ||
| 173 | .mwdma_mask = 0x07, | ||
| 174 | .udma_mask = ATA_UDMA6, | ||
| 175 | .port_ops = &vt8251_ops, | ||
| 176 | }; | ||
| 177 | |||
| 155 | MODULE_AUTHOR("Jeff Garzik"); | 178 | MODULE_AUTHOR("Jeff Garzik"); |
| 156 | MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers"); | 179 | MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers"); |
| 157 | MODULE_LICENSE("GPL"); | 180 | MODULE_LICENSE("GPL"); |
| @@ -174,6 +197,83 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) | |||
| 174 | return 0; | 197 | return 0; |
| 175 | } | 198 | } |
| 176 | 199 | ||
| 200 | static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val) | ||
| 201 | { | ||
| 202 | static const u8 ipm_tbl[] = { 1, 2, 6, 0 }; | ||
| 203 | struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); | ||
| 204 | int slot = 2 * link->ap->port_no + link->pmp; | ||
| 205 | u32 v = 0; | ||
| 206 | u8 raw; | ||
| 207 | |||
| 208 | switch (scr) { | ||
| 209 | case SCR_STATUS: | ||
| 210 | pci_read_config_byte(pdev, 0xA0 + slot, &raw); | ||
| 211 | |||
| 212 | /* read the DET field, bit0 and 1 of the config byte */ | ||
| 213 | v |= raw & 0x03; | ||
| 214 | |||
| 215 | /* read the SPD field, bit4 of the configure byte */ | ||
| 216 | if (raw & (1 << 4)) | ||
| 217 | v |= 0x02 << 4; | ||
| 218 | else | ||
| 219 | v |= 0x01 << 4; | ||
| 220 | |||
| 221 | /* read the IPM field, bit2 and 3 of the config byte */ | ||
| 222 | v |= ipm_tbl[(raw >> 2) & 0x3]; | ||
| 223 | break; | ||
| 224 | |||
| 225 | case SCR_ERROR: | ||
| 226 | /* devices other than 5287 uses 0xA8 as base */ | ||
| 227 | WARN_ON(pdev->device != 0x5287); | ||
| 228 | pci_read_config_dword(pdev, 0xB0 + slot * 4, &v); | ||
| 229 | break; | ||
| 230 | |||
| 231 | case SCR_CONTROL: | ||
| 232 | pci_read_config_byte(pdev, 0xA4 + slot, &raw); | ||
| 233 | |||
| 234 | /* read the DET field, bit0 and bit1 */ | ||
| 235 | v |= ((raw & 0x02) << 1) | (raw & 0x01); | ||
| 236 | |||
| 237 | /* read the IPM field, bit2 and bit3 */ | ||
| 238 | v |= ((raw >> 2) & 0x03) << 8; | ||
| 239 | break; | ||
| 240 | |||
| 241 | default: | ||
| 242 | return -EINVAL; | ||
| 243 | } | ||
| 244 | |||
| 245 | *val = v; | ||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val) | ||
| 250 | { | ||
| 251 | struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); | ||
| 252 | int slot = 2 * link->ap->port_no + link->pmp; | ||
| 253 | u32 v = 0; | ||
| 254 | |||
| 255 | switch (scr) { | ||
| 256 | case SCR_ERROR: | ||
| 257 | /* devices other than 5287 uses 0xA8 as base */ | ||
| 258 | WARN_ON(pdev->device != 0x5287); | ||
| 259 | pci_write_config_dword(pdev, 0xB0 + slot * 4, val); | ||
| 260 | return 0; | ||
| 261 | |||
| 262 | case SCR_CONTROL: | ||
| 263 | /* set the DET field */ | ||
| 264 | v |= ((val & 0x4) >> 1) | (val & 0x1); | ||
| 265 | |||
| 266 | /* set the IPM field */ | ||
| 267 | v |= ((val >> 8) & 0x3) << 2; | ||
| 268 | |||
| 269 | pci_write_config_byte(pdev, 0xA4 + slot, v); | ||
| 270 | return 0; | ||
| 271 | |||
| 272 | default: | ||
| 273 | return -EINVAL; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 177 | /** | 277 | /** |
| 178 | * svia_tf_load - send taskfile registers to host controller | 278 | * svia_tf_load - send taskfile registers to host controller |
| 179 | * @ap: Port to which output is sent | 279 | * @ap: Port to which output is sent |
| @@ -396,6 +496,30 @@ static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) | |||
| 396 | return 0; | 496 | return 0; |
| 397 | } | 497 | } |
| 398 | 498 | ||
| 499 | static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) | ||
| 500 | { | ||
| 501 | const struct ata_port_info *ppi[] = { &vt8251_port_info, NULL }; | ||
| 502 | struct ata_host *host; | ||
| 503 | int i, rc; | ||
| 504 | |||
| 505 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | ||
| 506 | if (rc) | ||
| 507 | return rc; | ||
| 508 | *r_host = host; | ||
| 509 | |||
| 510 | rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); | ||
| 511 | if (rc) { | ||
| 512 | dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n"); | ||
| 513 | return rc; | ||
| 514 | } | ||
| 515 | |||
| 516 | /* 8251 hosts four sata ports as M/S of the two channels */ | ||
| 517 | for (i = 0; i < host->n_ports; i++) | ||
| 518 | ata_slave_link_init(host->ports[i]); | ||
| 519 | |||
| 520 | return 0; | ||
| 521 | } | ||
| 522 | |||
| 399 | static void svia_configure(struct pci_dev *pdev) | 523 | static void svia_configure(struct pci_dev *pdev) |
| 400 | { | 524 | { |
| 401 | u8 tmp8; | 525 | u8 tmp8; |
| @@ -451,10 +575,10 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 451 | if (rc) | 575 | if (rc) |
| 452 | return rc; | 576 | return rc; |
| 453 | 577 | ||
| 454 | if (board_id == vt6420) | 578 | if (board_id == vt6421) |
| 455 | bar_sizes = &svia_bar_sizes[0]; | ||
| 456 | else | ||
| 457 | bar_sizes = &vt6421_bar_sizes[0]; | 579 | bar_sizes = &vt6421_bar_sizes[0]; |
| 580 | else | ||
| 581 | bar_sizes = &svia_bar_sizes[0]; | ||
| 458 | 582 | ||
| 459 | for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) | 583 | for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) |
| 460 | if ((pci_resource_start(pdev, i) == 0) || | 584 | if ((pci_resource_start(pdev, i) == 0) || |
| @@ -467,10 +591,19 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 467 | return -ENODEV; | 591 | return -ENODEV; |
| 468 | } | 592 | } |
| 469 | 593 | ||
| 470 | if (board_id == vt6420) | 594 | switch (board_id) { |
| 595 | case vt6420: | ||
| 471 | rc = vt6420_prepare_host(pdev, &host); | 596 | rc = vt6420_prepare_host(pdev, &host); |
| 472 | else | 597 | break; |
| 598 | case vt6421: | ||
| 473 | rc = vt6421_prepare_host(pdev, &host); | 599 | rc = vt6421_prepare_host(pdev, &host); |
| 600 | break; | ||
| 601 | case vt8251: | ||
| 602 | rc = vt8251_prepare_host(pdev, &host); | ||
| 603 | break; | ||
| 604 | default: | ||
| 605 | rc = -EINVAL; | ||
| 606 | } | ||
| 474 | if (rc) | 607 | if (rc) |
| 475 | return rc; | 608 | return rc; |
| 476 | 609 | ||
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 615412364e99..6b969f8c684f 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c | |||
| @@ -2705,7 +2705,7 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
| 2705 | 2705 | ||
| 2706 | /* XXX DEV_LABEL is a guess */ | 2706 | /* XXX DEV_LABEL is a guess */ |
| 2707 | if (!request_region(iobase, HRZ_IO_EXTENT, DEV_LABEL)) { | 2707 | if (!request_region(iobase, HRZ_IO_EXTENT, DEV_LABEL)) { |
| 2708 | return -EINVAL; | 2708 | err = -EINVAL; |
| 2709 | goto out_disable; | 2709 | goto out_disable; |
| 2710 | } | 2710 | } |
| 2711 | 2711 | ||
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 61ad8d639ba3..0344a8a8321d 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
| @@ -21,7 +21,8 @@ config BLK_DEV_FD | |||
| 21 | ---help--- | 21 | ---help--- |
| 22 | If you want to use the floppy disk drive(s) of your PC under Linux, | 22 | If you want to use the floppy disk drive(s) of your PC under Linux, |
| 23 | say Y. Information about this driver, especially important for IBM | 23 | say Y. Information about this driver, especially important for IBM |
| 24 | Thinkpad users, is contained in <file:Documentation/floppy.txt>. | 24 | Thinkpad users, is contained in |
| 25 | <file:Documentation/blockdev/floppy.txt>. | ||
| 25 | That file also contains the location of the Floppy driver FAQ as | 26 | That file also contains the location of the Floppy driver FAQ as |
| 26 | well as location of the fdutils package used to configure additional | 27 | well as location of the fdutils package used to configure additional |
| 27 | parameters of the driver at run time. | 28 | parameters of the driver at run time. |
| @@ -76,7 +77,7 @@ config PARIDE | |||
| 76 | your computer's parallel port. Most of them are actually IDE devices | 77 | your computer's parallel port. Most of them are actually IDE devices |
| 77 | using a parallel port IDE adapter. This option enables the PARIDE | 78 | using a parallel port IDE adapter. This option enables the PARIDE |
| 78 | subsystem which contains drivers for many of these external drives. | 79 | subsystem which contains drivers for many of these external drives. |
| 79 | Read <file:Documentation/paride.txt> for more information. | 80 | Read <file:Documentation/blockdev/paride.txt> for more information. |
| 80 | 81 | ||
| 81 | If you have said Y to the "Parallel-port support" configuration | 82 | If you have said Y to the "Parallel-port support" configuration |
| 82 | option, you may share a single port between your printer and other | 83 | option, you may share a single port between your printer and other |
| @@ -114,9 +115,9 @@ config BLK_CPQ_DA | |||
| 114 | help | 115 | help |
| 115 | This is the driver for Compaq Smart Array controllers. Everyone | 116 | This is the driver for Compaq Smart Array controllers. Everyone |
| 116 | using these boards should say Y here. See the file | 117 | using these boards should say Y here. See the file |
| 117 | <file:Documentation/cpqarray.txt> for the current list of boards | 118 | <file:Documentation/blockdev/cpqarray.txt> for the current list of |
| 118 | supported by this driver, and for further information on the use of | 119 | boards supported by this driver, and for further information on the |
| 119 | this driver. | 120 | use of this driver. |
| 120 | 121 | ||
| 121 | config BLK_CPQ_CISS_DA | 122 | config BLK_CPQ_CISS_DA |
| 122 | tristate "Compaq Smart Array 5xxx support" | 123 | tristate "Compaq Smart Array 5xxx support" |
| @@ -124,7 +125,7 @@ config BLK_CPQ_CISS_DA | |||
| 124 | help | 125 | help |
| 125 | This is the driver for Compaq Smart Array 5xxx controllers. | 126 | This is the driver for Compaq Smart Array 5xxx controllers. |
| 126 | Everyone using these boards should say Y here. | 127 | Everyone using these boards should say Y here. |
| 127 | See <file:Documentation/cciss.txt> for the current list of | 128 | See <file:Documentation/blockdev/cciss.txt> for the current list of |
| 128 | boards supported by this driver, and for further information | 129 | boards supported by this driver, and for further information |
| 129 | on the use of this driver. | 130 | on the use of this driver. |
| 130 | 131 | ||
| @@ -135,7 +136,7 @@ config CISS_SCSI_TAPE | |||
| 135 | help | 136 | help |
| 136 | When enabled (Y), this option allows SCSI tape drives and SCSI medium | 137 | When enabled (Y), this option allows SCSI tape drives and SCSI medium |
| 137 | changers (tape robots) to be accessed via a Compaq 5xxx array | 138 | changers (tape robots) to be accessed via a Compaq 5xxx array |
| 138 | controller. (See <file:Documentation/cciss.txt> for more details.) | 139 | controller. (See <file:Documentation/blockdev/cciss.txt> for more details.) |
| 139 | 140 | ||
| 140 | "SCSI support" and "SCSI tape support" must also be enabled for this | 141 | "SCSI support" and "SCSI tape support" must also be enabled for this |
| 141 | option to work. | 142 | option to work. |
| @@ -149,8 +150,8 @@ config BLK_DEV_DAC960 | |||
| 149 | help | 150 | help |
| 150 | This driver adds support for the Mylex DAC960, AcceleRAID, and | 151 | This driver adds support for the Mylex DAC960, AcceleRAID, and |
| 151 | eXtremeRAID PCI RAID controllers. See the file | 152 | eXtremeRAID PCI RAID controllers. See the file |
| 152 | <file:Documentation/README.DAC960> for further information about | 153 | <file:Documentation/blockdev/README.DAC960> for further information |
| 153 | this driver. | 154 | about this driver. |
| 154 | 155 | ||
| 155 | To compile this driver as a module, choose M here: the | 156 | To compile this driver as a module, choose M here: the |
| 156 | module will be called DAC960. | 157 | module will be called DAC960. |
| @@ -278,9 +279,9 @@ config BLK_DEV_NBD | |||
| 278 | userland (making server and client physically the same computer, | 279 | userland (making server and client physically the same computer, |
| 279 | communicating using the loopback network device). | 280 | communicating using the loopback network device). |
| 280 | 281 | ||
| 281 | Read <file:Documentation/nbd.txt> for more information, especially | 282 | Read <file:Documentation/blockdev/nbd.txt> for more information, |
| 282 | about where to find the server code, which runs in user space and | 283 | especially about where to find the server code, which runs in user |
| 283 | does not need special kernel support. | 284 | space and does not need special kernel support. |
| 284 | 285 | ||
| 285 | Note that this has nothing to do with the network file systems NFS | 286 | Note that this has nothing to do with the network file systems NFS |
| 286 | or Coda; you can say N here even if you intend to use NFS or Coda. | 287 | or Coda; you can say N here even if you intend to use NFS or Coda. |
| @@ -321,8 +322,8 @@ config BLK_DEV_RAM | |||
| 321 | store a copy of a minimal root file system off of a floppy into RAM | 322 | store a copy of a minimal root file system off of a floppy into RAM |
| 322 | during the initial install of Linux. | 323 | during the initial install of Linux. |
| 323 | 324 | ||
| 324 | Note that the kernel command line option "ramdisk=XX" is now | 325 | Note that the kernel command line option "ramdisk=XX" is now obsolete. |
| 325 | obsolete. For details, read <file:Documentation/ramdisk.txt>. | 326 | For details, read <file:Documentation/blockdev/ramdisk.txt>. |
| 326 | 327 | ||
| 327 | To compile this driver as a module, choose M here: the | 328 | To compile this driver as a module, choose M here: the |
| 328 | module will be called rd. | 329 | module will be called rd. |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 4023885353e0..9364dc554257 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -96,6 +96,8 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
| 96 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, | 96 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, |
| 97 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, | 97 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, |
| 98 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | 98 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, |
| 99 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, | ||
| 100 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, | ||
| 99 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 101 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| 100 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 102 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
| 101 | {0,} | 103 | {0,} |
| @@ -133,6 +135,8 @@ static struct board_type products[] = { | |||
| 133 | {0x3245103C, "Smart Array P410i", &SA5_access}, | 135 | {0x3245103C, "Smart Array P410i", &SA5_access}, |
| 134 | {0x3247103C, "Smart Array P411", &SA5_access}, | 136 | {0x3247103C, "Smart Array P411", &SA5_access}, |
| 135 | {0x3249103C, "Smart Array P812", &SA5_access}, | 137 | {0x3249103C, "Smart Array P812", &SA5_access}, |
| 138 | {0x324A103C, "Smart Array P712m", &SA5_access}, | ||
| 139 | {0x324B103C, "Smart Array P711m", &SA5_access}, | ||
| 136 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, | 140 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, |
| 137 | }; | 141 | }; |
| 138 | 142 | ||
| @@ -1366,6 +1370,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
| 1366 | disk->first_minor = drv_index << NWD_SHIFT; | 1370 | disk->first_minor = drv_index << NWD_SHIFT; |
| 1367 | disk->fops = &cciss_fops; | 1371 | disk->fops = &cciss_fops; |
| 1368 | disk->private_data = &h->drv[drv_index]; | 1372 | disk->private_data = &h->drv[drv_index]; |
| 1373 | disk->driverfs_dev = &h->pdev->dev; | ||
| 1369 | 1374 | ||
| 1370 | /* Set up queue information */ | 1375 | /* Set up queue information */ |
| 1371 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | 1376 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); |
| @@ -2842,7 +2847,7 @@ static void do_cciss_request(struct request_queue *q) | |||
| 2842 | h->maxSG = seg; | 2847 | h->maxSG = seg; |
| 2843 | 2848 | ||
| 2844 | #ifdef CCISS_DEBUG | 2849 | #ifdef CCISS_DEBUG |
| 2845 | printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n", | 2850 | printk(KERN_DEBUG "cciss: Submitting %lu sectors in %d segments\n", |
| 2846 | creq->nr_sectors, seg); | 2851 | creq->nr_sectors, seg); |
| 2847 | #endif /* CCISS_DEBUG */ | 2852 | #endif /* CCISS_DEBUG */ |
| 2848 | 2853 | ||
| @@ -3192,7 +3197,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3192 | 3197 | ||
| 3193 | c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */ | 3198 | c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */ |
| 3194 | #ifdef CCISS_DEBUG | 3199 | #ifdef CCISS_DEBUG |
| 3195 | printk("address 0 = %x\n", c->paddr); | 3200 | printk("address 0 = %lx\n", c->paddr); |
| 3196 | #endif /* CCISS_DEBUG */ | 3201 | #endif /* CCISS_DEBUG */ |
| 3197 | c->vaddr = remap_pci_mem(c->paddr, 0x250); | 3202 | c->vaddr = remap_pci_mem(c->paddr, 0x250); |
| 3198 | 3203 | ||
| @@ -3219,7 +3224,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3219 | #endif /* CCISS_DEBUG */ | 3224 | #endif /* CCISS_DEBUG */ |
| 3220 | cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); | 3225 | cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); |
| 3221 | #ifdef CCISS_DEBUG | 3226 | #ifdef CCISS_DEBUG |
| 3222 | printk("cfg base address index = %x\n", cfg_base_addr_index); | 3227 | printk("cfg base address index = %llx\n", |
| 3228 | (unsigned long long)cfg_base_addr_index); | ||
| 3223 | #endif /* CCISS_DEBUG */ | 3229 | #endif /* CCISS_DEBUG */ |
| 3224 | if (cfg_base_addr_index == -1) { | 3230 | if (cfg_base_addr_index == -1) { |
| 3225 | printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); | 3231 | printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); |
| @@ -3229,7 +3235,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3229 | 3235 | ||
| 3230 | cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); | 3236 | cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); |
| 3231 | #ifdef CCISS_DEBUG | 3237 | #ifdef CCISS_DEBUG |
| 3232 | printk("cfg offset = %x\n", cfg_offset); | 3238 | printk("cfg offset = %llx\n", (unsigned long long)cfg_offset); |
| 3233 | #endif /* CCISS_DEBUG */ | 3239 | #endif /* CCISS_DEBUG */ |
| 3234 | c->cfgtable = remap_pci_mem(pci_resource_start(pdev, | 3240 | c->cfgtable = remap_pci_mem(pci_resource_start(pdev, |
| 3235 | cfg_base_addr_index) + | 3241 | cfg_base_addr_index) + |
| @@ -3404,7 +3410,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3404 | int i; | 3410 | int i; |
| 3405 | int j = 0; | 3411 | int j = 0; |
| 3406 | int rc; | 3412 | int rc; |
| 3407 | int dac; | 3413 | int dac, return_code; |
| 3414 | InquiryData_struct *inq_buff = NULL; | ||
| 3408 | 3415 | ||
| 3409 | i = alloc_cciss_hba(); | 3416 | i = alloc_cciss_hba(); |
| 3410 | if (i < 0) | 3417 | if (i < 0) |
| @@ -3510,6 +3517,25 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3510 | /* Turn the interrupts on so we can service requests */ | 3517 | /* Turn the interrupts on so we can service requests */ |
| 3511 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); | 3518 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); |
| 3512 | 3519 | ||
| 3520 | /* Get the firmware version */ | ||
| 3521 | inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
| 3522 | if (inq_buff == NULL) { | ||
| 3523 | printk(KERN_ERR "cciss: out of memory\n"); | ||
| 3524 | goto clean4; | ||
| 3525 | } | ||
| 3526 | |||
| 3527 | return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff, | ||
| 3528 | sizeof(InquiryData_struct), 0, 0 , 0, TYPE_CMD); | ||
| 3529 | if (return_code == IO_OK) { | ||
| 3530 | hba[i]->firm_ver[0] = inq_buff->data_byte[32]; | ||
| 3531 | hba[i]->firm_ver[1] = inq_buff->data_byte[33]; | ||
| 3532 | hba[i]->firm_ver[2] = inq_buff->data_byte[34]; | ||
| 3533 | hba[i]->firm_ver[3] = inq_buff->data_byte[35]; | ||
| 3534 | } else { /* send command failed */ | ||
| 3535 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
| 3536 | " version of controller\n"); | ||
| 3537 | } | ||
| 3538 | |||
| 3513 | cciss_procinit(i); | 3539 | cciss_procinit(i); |
| 3514 | 3540 | ||
| 3515 | hba[i]->cciss_max_sectors = 2048; | 3541 | hba[i]->cciss_max_sectors = 2048; |
| @@ -3520,6 +3546,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3520 | return 1; | 3546 | return 1; |
| 3521 | 3547 | ||
| 3522 | clean4: | 3548 | clean4: |
| 3549 | kfree(inq_buff); | ||
| 3523 | #ifdef CONFIG_CISS_SCSI_TAPE | 3550 | #ifdef CONFIG_CISS_SCSI_TAPE |
| 3524 | kfree(hba[i]->scsi_rejects.complete); | 3551 | kfree(hba[i]->scsi_rejects.complete); |
| 3525 | #endif | 3552 | #endif |
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 47d233c6d0b3..5d39df14ed90 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
| @@ -567,7 +567,12 @@ static int __init cpqarray_init(void) | |||
| 567 | num_cntlrs_reg++; | 567 | num_cntlrs_reg++; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | return(num_cntlrs_reg); | 570 | if (num_cntlrs_reg) |
| 571 | return 0; | ||
| 572 | else { | ||
| 573 | pci_unregister_driver(&cpqarray_pci_driver); | ||
| 574 | return -ENODEV; | ||
| 575 | } | ||
| 571 | } | 576 | } |
| 572 | 577 | ||
| 573 | /* Function to find the first free pointer into our hba[] array */ | 578 | /* Function to find the first free pointer into our hba[] array */ |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 14db747a636e..cf29cc4e6ab7 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
| @@ -4124,7 +4124,7 @@ static int __init floppy_setup(char *str) | |||
| 4124 | printk("\n"); | 4124 | printk("\n"); |
| 4125 | } else | 4125 | } else |
| 4126 | DPRINT("botched floppy option\n"); | 4126 | DPRINT("botched floppy option\n"); |
| 4127 | DPRINT("Read Documentation/floppy.txt\n"); | 4127 | DPRINT("Read Documentation/blockdev/floppy.txt\n"); |
| 4128 | return 0; | 4128 | return 0; |
| 4129 | } | 4129 | } |
| 4130 | 4130 | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index f20bf359b84f..dc7a8c352da2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
| @@ -302,7 +302,7 @@ static struct kobj_type kobj_pkt_type_wqueue = { | |||
| 302 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) | 302 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) |
| 303 | { | 303 | { |
| 304 | if (class_pktcdvd) { | 304 | if (class_pktcdvd) { |
| 305 | pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, NULL, | 305 | pd->dev = device_create(class_pktcdvd, NULL, MKDEV(0, 0), NULL, |
| 306 | "%s", pd->name); | 306 | "%s", pd->name); |
| 307 | if (IS_ERR(pd->dev)) | 307 | if (IS_ERR(pd->dev)) |
| 308 | pd->dev = NULL; | 308 | pd->dev = NULL; |
| @@ -2790,7 +2790,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
| 2790 | return 0; | 2790 | return 0; |
| 2791 | 2791 | ||
| 2792 | out_mem: | 2792 | out_mem: |
| 2793 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | 2793 | blkdev_put(bdev, FMODE_READ | FMODE_NDELAY); |
| 2794 | /* This is safe: open() is still holding a reference. */ | 2794 | /* This is safe: open() is still holding a reference. */ |
| 2795 | module_put(THIS_MODULE); | 2795 | module_put(THIS_MODULE); |
| 2796 | return ret; | 2796 | return ret; |
| @@ -2975,7 +2975,7 @@ static int pkt_remove_dev(dev_t pkt_dev) | |||
| 2975 | pkt_debugfs_dev_remove(pd); | 2975 | pkt_debugfs_dev_remove(pd); |
| 2976 | pkt_sysfs_dev_remove(pd); | 2976 | pkt_sysfs_dev_remove(pd); |
| 2977 | 2977 | ||
| 2978 | blkdev_put(pd->bdev, FMODE_READ|FMODE_WRITE); | 2978 | blkdev_put(pd->bdev, FMODE_READ | FMODE_NDELAY); |
| 2979 | 2979 | ||
| 2980 | remove_proc_entry(pd->name, pkt_proc); | 2980 | remove_proc_entry(pd->name, pkt_proc); |
| 2981 | DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name); | 2981 | DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name); |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index fccac18d3111..048d71d244d7 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
| @@ -1546,8 +1546,6 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) | |||
| 1546 | 1546 | ||
| 1547 | /* | 1547 | /* |
| 1548 | * Reset management | 1548 | * Reset management |
| 1549 | * XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing. | ||
| 1550 | * XXX Make usb_sync_reset asynchronous. | ||
| 1551 | */ | 1549 | */ |
| 1552 | 1550 | ||
| 1553 | static void ub_reset_enter(struct ub_dev *sc, int try) | 1551 | static void ub_reset_enter(struct ub_dev *sc, int try) |
| @@ -1633,6 +1631,22 @@ static void ub_reset_task(struct work_struct *work) | |||
| 1633 | } | 1631 | } |
| 1634 | 1632 | ||
| 1635 | /* | 1633 | /* |
| 1634 | * XXX Reset brackets are too much hassle to implement, so just stub them | ||
| 1635 | * in order to prevent forced unbinding (which deadlocks solid when our | ||
| 1636 | * ->disconnect method waits for the reset to complete and this kills keventd). | ||
| 1637 | * | ||
| 1638 | * XXX Tell Alan to move usb_unlock_device inside of usb_reset_device, | ||
| 1639 | * or else the post_reset is invoked, and restats I/O on a locked device. | ||
| 1640 | */ | ||
| 1641 | static int ub_pre_reset(struct usb_interface *iface) { | ||
| 1642 | return 0; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static int ub_post_reset(struct usb_interface *iface) { | ||
| 1646 | return 0; | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | /* | ||
| 1636 | * This is called from a process context. | 1650 | * This is called from a process context. |
| 1637 | */ | 1651 | */ |
| 1638 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) | 1652 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) |
| @@ -2446,6 +2460,8 @@ static struct usb_driver ub_driver = { | |||
| 2446 | .probe = ub_probe, | 2460 | .probe = ub_probe, |
| 2447 | .disconnect = ub_disconnect, | 2461 | .disconnect = ub_disconnect, |
| 2448 | .id_table = ub_usb_ids, | 2462 | .id_table = ub_usb_ids, |
| 2463 | .pre_reset = ub_pre_reset, | ||
| 2464 | .post_reset = ub_post_reset, | ||
| 2449 | }; | 2465 | }; |
| 2450 | 2466 | ||
| 2451 | static int __init ub_init(void) | 2467 | static int __init ub_init(void) |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index b220c686089d..2d19f0cc47f2 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
| @@ -338,12 +338,18 @@ wait: | |||
| 338 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) | 338 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) |
| 339 | { | 339 | { |
| 340 | struct request_queue *rq; | 340 | struct request_queue *rq; |
| 341 | elevator_t *old_e; | ||
| 341 | 342 | ||
| 342 | rq = blk_init_queue(do_blkif_request, &blkif_io_lock); | 343 | rq = blk_init_queue(do_blkif_request, &blkif_io_lock); |
| 343 | if (rq == NULL) | 344 | if (rq == NULL) |
| 344 | return -1; | 345 | return -1; |
| 345 | 346 | ||
| 346 | elevator_init(rq, "noop"); | 347 | old_e = rq->elevator; |
| 348 | if (IS_ERR_VALUE(elevator_init(rq, "noop"))) | ||
| 349 | printk(KERN_WARNING | ||
| 350 | "blkfront: Switch elevator failed, use default\n"); | ||
| 351 | else | ||
| 352 | elevator_exit(old_e); | ||
| 347 | 353 | ||
| 348 | /* Hard sector size and max sectors impersonate the equiv. hardware. */ | 354 | /* Hard sector size and max sectors impersonate the equiv. hardware. */ |
| 349 | blk_queue_hardsect_size(rq, sector_size); | 355 | blk_queue_hardsect_size(rq, sector_size); |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index ecab9e67d47a..29e1dfafb7c6 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
| @@ -194,7 +194,7 @@ struct ace_device { | |||
| 194 | int in_irq; | 194 | int in_irq; |
| 195 | 195 | ||
| 196 | /* Details of hardware device */ | 196 | /* Details of hardware device */ |
| 197 | unsigned long physaddr; | 197 | resource_size_t physaddr; |
| 198 | void __iomem *baseaddr; | 198 | void __iomem *baseaddr; |
| 199 | int irq; | 199 | int irq; |
| 200 | int bus_width; /* 0 := 8 bit; 1 := 16 bit */ | 200 | int bus_width; /* 0 := 8 bit; 1 := 16 bit */ |
| @@ -628,8 +628,8 @@ static void ace_fsm_dostate(struct ace_device *ace) | |||
| 628 | 628 | ||
| 629 | /* Okay, it's a data request, set it up for transfer */ | 629 | /* Okay, it's a data request, set it up for transfer */ |
| 630 | dev_dbg(ace->dev, | 630 | dev_dbg(ace->dev, |
| 631 | "request: sec=%lx hcnt=%lx, ccnt=%x, dir=%i\n", | 631 | "request: sec=%llx hcnt=%lx, ccnt=%x, dir=%i\n", |
| 632 | req->sector, req->hard_nr_sectors, | 632 | (unsigned long long) req->sector, req->hard_nr_sectors, |
| 633 | req->current_nr_sectors, rq_data_dir(req)); | 633 | req->current_nr_sectors, rq_data_dir(req)); |
| 634 | 634 | ||
| 635 | ace->req = req; | 635 | ace->req = req; |
| @@ -935,7 +935,8 @@ static int __devinit ace_setup(struct ace_device *ace) | |||
| 935 | int rc; | 935 | int rc; |
| 936 | 936 | ||
| 937 | dev_dbg(ace->dev, "ace_setup(ace=0x%p)\n", ace); | 937 | dev_dbg(ace->dev, "ace_setup(ace=0x%p)\n", ace); |
| 938 | dev_dbg(ace->dev, "physaddr=0x%lx irq=%i\n", ace->physaddr, ace->irq); | 938 | dev_dbg(ace->dev, "physaddr=0x%llx irq=%i\n", |
| 939 | (unsigned long long)ace->physaddr, ace->irq); | ||
| 939 | 940 | ||
| 940 | spin_lock_init(&ace->lock); | 941 | spin_lock_init(&ace->lock); |
| 941 | init_completion(&ace->id_completion); | 942 | init_completion(&ace->id_completion); |
| @@ -1017,8 +1018,8 @@ static int __devinit ace_setup(struct ace_device *ace) | |||
| 1017 | /* Print the identification */ | 1018 | /* Print the identification */ |
| 1018 | dev_info(ace->dev, "Xilinx SystemACE revision %i.%i.%i\n", | 1019 | dev_info(ace->dev, "Xilinx SystemACE revision %i.%i.%i\n", |
| 1019 | (version >> 12) & 0xf, (version >> 8) & 0x0f, version & 0xff); | 1020 | (version >> 12) & 0xf, (version >> 8) & 0x0f, version & 0xff); |
| 1020 | dev_dbg(ace->dev, "physaddr 0x%lx, mapped to 0x%p, irq=%i\n", | 1021 | dev_dbg(ace->dev, "physaddr 0x%llx, mapped to 0x%p, irq=%i\n", |
| 1021 | ace->physaddr, ace->baseaddr, ace->irq); | 1022 | (unsigned long long) ace->physaddr, ace->baseaddr, ace->irq); |
| 1022 | 1023 | ||
| 1023 | ace->media_change = 1; | 1024 | ace->media_change = 1; |
| 1024 | ace_revalidate_disk(ace->gd); | 1025 | ace_revalidate_disk(ace->gd); |
| @@ -1035,8 +1036,8 @@ err_alloc_disk: | |||
| 1035 | err_blk_initq: | 1036 | err_blk_initq: |
| 1036 | iounmap(ace->baseaddr); | 1037 | iounmap(ace->baseaddr); |
| 1037 | err_ioremap: | 1038 | err_ioremap: |
| 1038 | dev_info(ace->dev, "xsysace: error initializing device at 0x%lx\n", | 1039 | dev_info(ace->dev, "xsysace: error initializing device at 0x%llx\n", |
| 1039 | ace->physaddr); | 1040 | (unsigned long long) ace->physaddr); |
| 1040 | return -ENOMEM; | 1041 | return -ENOMEM; |
| 1041 | } | 1042 | } |
| 1042 | 1043 | ||
| @@ -1059,7 +1060,7 @@ static void __devexit ace_teardown(struct ace_device *ace) | |||
| 1059 | } | 1060 | } |
| 1060 | 1061 | ||
| 1061 | static int __devinit | 1062 | static int __devinit |
| 1062 | ace_alloc(struct device *dev, int id, unsigned long physaddr, | 1063 | ace_alloc(struct device *dev, int id, resource_size_t physaddr, |
| 1063 | int irq, int bus_width) | 1064 | int irq, int bus_width) |
| 1064 | { | 1065 | { |
| 1065 | struct ace_device *ace; | 1066 | struct ace_device *ace; |
| @@ -1119,7 +1120,7 @@ static void __devexit ace_free(struct device *dev) | |||
| 1119 | 1120 | ||
| 1120 | static int __devinit ace_probe(struct platform_device *dev) | 1121 | static int __devinit ace_probe(struct platform_device *dev) |
| 1121 | { | 1122 | { |
| 1122 | unsigned long physaddr = 0; | 1123 | resource_size_t physaddr = 0; |
| 1123 | int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */ | 1124 | int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */ |
| 1124 | int id = dev->id; | 1125 | int id = dev->id; |
| 1125 | int irq = NO_IRQ; | 1126 | int irq = NO_IRQ; |
| @@ -1165,7 +1166,7 @@ static int __devinit | |||
| 1165 | ace_of_probe(struct of_device *op, const struct of_device_id *match) | 1166 | ace_of_probe(struct of_device *op, const struct of_device_id *match) |
| 1166 | { | 1167 | { |
| 1167 | struct resource res; | 1168 | struct resource res; |
| 1168 | unsigned long physaddr; | 1169 | resource_size_t physaddr; |
| 1169 | const u32 *id; | 1170 | const u32 *id; |
| 1170 | int irq, bus_width, rc; | 1171 | int irq, bus_width, rc; |
| 1171 | 1172 | ||
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 32f3a8ed8d3d..b936d8ce2728 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c | |||
| @@ -443,8 +443,8 @@ static void bpa10x_destruct(struct hci_dev *hdev) | |||
| 443 | 443 | ||
| 444 | BT_DBG("%s", hdev->name); | 444 | BT_DBG("%s", hdev->name); |
| 445 | 445 | ||
| 446 | kfree(data->rx_skb[0]); | 446 | kfree_skb(data->rx_skb[0]); |
| 447 | kfree(data->rx_skb[1]); | 447 | kfree_skb(data->rx_skb[1]); |
| 448 | kfree(data); | 448 | kfree(data); |
| 449 | } | 449 | } |
| 450 | 450 | ||
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 9aaa86b232b1..2eecb779437b 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c | |||
| @@ -495,9 +495,10 @@ static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode) | |||
| 495 | return cdrom_open(gd.cd_info, bdev, mode); | 495 | return cdrom_open(gd.cd_info, bdev, mode); |
| 496 | } | 496 | } |
| 497 | 497 | ||
| 498 | static int gdrom_bdops_release(struct block_device *bdev, fmode_t mode) | 498 | static int gdrom_bdops_release(struct gendisk *disk, fmode_t mode) |
| 499 | { | 499 | { |
| 500 | return cdrom_release(gd.cd_info, mode); | 500 | cdrom_release(gd.cd_info, mode); |
| 501 | return 0; | ||
| 501 | } | 502 | } |
| 502 | 503 | ||
| 503 | static int gdrom_bdops_mediachanged(struct gendisk *disk) | 504 | static int gdrom_bdops_mediachanged(struct gendisk *disk) |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 43b35d0369d6..43d6ba83a191 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -124,7 +124,7 @@ config COMPUTONE | |||
| 124 | which give you many serial ports. You would need something like this | 124 | which give you many serial ports. You would need something like this |
| 125 | to connect more than two modems to your Linux box, for instance in | 125 | to connect more than two modems to your Linux box, for instance in |
| 126 | order to become a dial-in server. If you have a card like that, say | 126 | order to become a dial-in server. If you have a card like that, say |
| 127 | Y here and read <file:Documentation/computone.txt>. | 127 | Y here and read <file:Documentation/serial/computone.txt>. |
| 128 | 128 | ||
| 129 | To compile this driver as module, choose M here: the | 129 | To compile this driver as module, choose M here: the |
| 130 | module will be called ip2. | 130 | module will be called ip2. |
| @@ -136,7 +136,7 @@ config ROCKETPORT | |||
| 136 | This driver supports Comtrol RocketPort and RocketModem PCI boards. | 136 | This driver supports Comtrol RocketPort and RocketModem PCI boards. |
| 137 | These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or | 137 | These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or |
| 138 | modems. For information about the RocketPort/RocketModem boards | 138 | modems. For information about the RocketPort/RocketModem boards |
| 139 | and this driver read <file:Documentation/rocket.txt>. | 139 | and this driver read <file:Documentation/serial/rocket.txt>. |
| 140 | 140 | ||
| 141 | To compile this driver as a module, choose M here: the | 141 | To compile this driver as a module, choose M here: the |
| 142 | module will be called rocket. | 142 | module will be called rocket. |
| @@ -154,7 +154,7 @@ config CYCLADES | |||
| 154 | your Linux box, for instance in order to become a dial-in server. | 154 | your Linux box, for instance in order to become a dial-in server. |
| 155 | 155 | ||
| 156 | For information about the Cyclades-Z card, read | 156 | For information about the Cyclades-Z card, read |
| 157 | <file:Documentation/README.cycladesZ>. | 157 | <file:Documentation/serial/README.cycladesZ>. |
| 158 | 158 | ||
| 159 | To compile this driver as a module, choose M here: the | 159 | To compile this driver as a module, choose M here: the |
| 160 | module will be called cyclades. | 160 | module will be called cyclades. |
| @@ -183,7 +183,7 @@ config DIGIEPCA | |||
| 183 | box, for instance in order to become a dial-in server. This driver | 183 | box, for instance in order to become a dial-in server. This driver |
| 184 | supports the original PC (ISA) boards as well as PCI, and EISA. If | 184 | supports the original PC (ISA) boards as well as PCI, and EISA. If |
| 185 | you have a card like this, say Y here and read the file | 185 | you have a card like this, say Y here and read the file |
| 186 | <file:Documentation/digiepca.txt>. | 186 | <file:Documentation/serial/digiepca.txt>. |
| 187 | 187 | ||
| 188 | To compile this driver as a module, choose M here: the | 188 | To compile this driver as a module, choose M here: the |
| 189 | module will be called epca. | 189 | module will be called epca. |
| @@ -289,7 +289,7 @@ config RISCOM8 | |||
| 289 | which gives you many serial ports. You would need something like | 289 | which gives you many serial ports. You would need something like |
| 290 | this to connect more than two modems to your Linux box, for instance | 290 | this to connect more than two modems to your Linux box, for instance |
| 291 | in order to become a dial-in server. If you have a card like that, | 291 | in order to become a dial-in server. If you have a card like that, |
| 292 | say Y here and read the file <file:Documentation/riscom8.txt>. | 292 | say Y here and read the file <file:Documentation/serial/riscom8.txt>. |
| 293 | 293 | ||
| 294 | Also it's possible to say M here and compile this driver as kernel | 294 | Also it's possible to say M here and compile this driver as kernel |
| 295 | loadable module; the module will be called riscom8. | 295 | loadable module; the module will be called riscom8. |
| @@ -304,8 +304,8 @@ config SPECIALIX | |||
| 304 | your Linux box, for instance in order to become a dial-in server. | 304 | your Linux box, for instance in order to become a dial-in server. |
| 305 | 305 | ||
| 306 | If you have a card like that, say Y here and read the file | 306 | If you have a card like that, say Y here and read the file |
| 307 | <file:Documentation/specialix.txt>. Also it's possible to say M here | 307 | <file:Documentation/serial/specialix.txt>. Also it's possible to say |
| 308 | and compile this driver as kernel loadable module which will be | 308 | M here and compile this driver as kernel loadable module which will be |
| 309 | called specialix. | 309 | called specialix. |
| 310 | 310 | ||
| 311 | config SX | 311 | config SX |
| @@ -313,7 +313,7 @@ config SX | |||
| 313 | depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) | 313 | depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) |
| 314 | help | 314 | help |
| 315 | This is a driver for the SX and SI multiport serial cards. | 315 | This is a driver for the SX and SI multiport serial cards. |
| 316 | Please read the file <file:Documentation/sx.txt> for details. | 316 | Please read the file <file:Documentation/serial/sx.txt> for details. |
| 317 | 317 | ||
| 318 | This driver can only be built as a module ( = code which can be | 318 | This driver can only be built as a module ( = code which can be |
| 319 | inserted in and removed from the running kernel whenever you want). | 319 | inserted in and removed from the running kernel whenever you want). |
| @@ -344,8 +344,8 @@ config STALDRV | |||
| 344 | like this to connect more than two modems to your Linux box, for | 344 | like this to connect more than two modems to your Linux box, for |
| 345 | instance in order to become a dial-in server. If you say Y here, | 345 | instance in order to become a dial-in server. If you say Y here, |
| 346 | you will be asked for your specific card model in the next | 346 | you will be asked for your specific card model in the next |
| 347 | questions. Make sure to read <file:Documentation/stallion.txt> in | 347 | questions. Make sure to read <file:Documentation/serial/stallion.txt> |
| 348 | this case. If you have never heard about all this, it's safe to | 348 | in this case. If you have never heard about all this, it's safe to |
| 349 | say N. | 349 | say N. |
| 350 | 350 | ||
| 351 | config STALLION | 351 | config STALLION |
| @@ -354,7 +354,7 @@ config STALLION | |||
| 354 | help | 354 | help |
| 355 | If you have an EasyIO or EasyConnection 8/32 multiport Stallion | 355 | If you have an EasyIO or EasyConnection 8/32 multiport Stallion |
| 356 | card, then this is for you; say Y. Make sure to read | 356 | card, then this is for you; say Y. Make sure to read |
| 357 | <file:Documentation/stallion.txt>. | 357 | <file:Documentation/serial/stallion.txt>. |
| 358 | 358 | ||
| 359 | To compile this driver as a module, choose M here: the | 359 | To compile this driver as a module, choose M here: the |
| 360 | module will be called stallion. | 360 | module will be called stallion. |
| @@ -365,7 +365,7 @@ config ISTALLION | |||
| 365 | help | 365 | help |
| 366 | If you have an EasyConnection 8/64, ONboard, Brumby or Stallion | 366 | If you have an EasyConnection 8/64, ONboard, Brumby or Stallion |
| 367 | serial multiport card, say Y here. Make sure to read | 367 | serial multiport card, say Y here. Make sure to read |
| 368 | <file:Documentation/stallion.txt>. | 368 | <file:Documentation/serial/stallion.txt>. |
| 369 | 369 | ||
| 370 | To compile this driver as a module, choose M here: the | 370 | To compile this driver as a module, choose M here: the |
| 371 | module will be called istallion. | 371 | module will be called istallion. |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 0f004b65ec03..03f95ec08f59 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | static int uninorth_rev; | 27 | static int uninorth_rev; |
| 28 | static int is_u3; | 28 | static int is_u3; |
| 29 | 29 | ||
| 30 | static char __devinitdata *aperture = NULL; | 30 | static char *aperture = NULL; |
| 31 | 31 | ||
| 32 | static int uninorth_fetch_size(void) | 32 | static int uninorth_fetch_size(void) |
| 33 | { | 33 | { |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 408f5f92cb4e..53fdc7ff3870 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
| @@ -427,9 +427,6 @@ static int hpet_release(struct inode *inode, struct file *file) | |||
| 427 | if (irq) | 427 | if (irq) |
| 428 | free_irq(irq, devp); | 428 | free_irq(irq, devp); |
| 429 | 429 | ||
| 430 | if (file->f_flags & FASYNC) | ||
| 431 | hpet_fasync(-1, file, 0); | ||
| 432 | |||
| 433 | file->private_data = NULL; | 430 | file->private_data = NULL; |
| 434 | return 0; | 431 | return 0; |
| 435 | } | 432 | } |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 1d7b429f7ffa..41fc11dc921c 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
| @@ -162,8 +162,6 @@ static int ipmi_release(struct inode *inode, struct file *file) | |||
| 162 | if (rv) | 162 | if (rv) |
| 163 | return rv; | 163 | return rv; |
| 164 | 164 | ||
| 165 | ipmi_fasync (-1, file, 0); | ||
| 166 | |||
| 167 | /* FIXME - free the messages in the list. */ | 165 | /* FIXME - free the messages in the list. */ |
| 168 | kfree(priv); | 166 | kfree(priv); |
| 169 | 167 | ||
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 8a59aaa21be5..7a88dfd4427b 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
| @@ -422,9 +422,11 @@ struct ipmi_smi { | |||
| 422 | /** | 422 | /** |
| 423 | * The driver model view of the IPMI messaging driver. | 423 | * The driver model view of the IPMI messaging driver. |
| 424 | */ | 424 | */ |
| 425 | static struct device_driver ipmidriver = { | 425 | static struct platform_driver ipmidriver = { |
| 426 | .name = "ipmi", | 426 | .driver = { |
| 427 | .bus = &platform_bus_type | 427 | .name = "ipmi", |
| 428 | .bus = &platform_bus_type | ||
| 429 | } | ||
| 428 | }; | 430 | }; |
| 429 | static DEFINE_MUTEX(ipmidriver_mutex); | 431 | static DEFINE_MUTEX(ipmidriver_mutex); |
| 430 | 432 | ||
| @@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
| 2384 | * representing the interfaced BMC already | 2386 | * representing the interfaced BMC already |
| 2385 | */ | 2387 | */ |
| 2386 | if (bmc->guid_set) | 2388 | if (bmc->guid_set) |
| 2387 | old_bmc = ipmi_find_bmc_guid(&ipmidriver, bmc->guid); | 2389 | old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid); |
| 2388 | else | 2390 | else |
| 2389 | old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver, | 2391 | old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, |
| 2390 | bmc->id.product_id, | 2392 | bmc->id.product_id, |
| 2391 | bmc->id.device_id); | 2393 | bmc->id.device_id); |
| 2392 | 2394 | ||
| @@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
| 2416 | snprintf(name, sizeof(name), | 2418 | snprintf(name, sizeof(name), |
| 2417 | "ipmi_bmc.%4.4x", bmc->id.product_id); | 2419 | "ipmi_bmc.%4.4x", bmc->id.product_id); |
| 2418 | 2420 | ||
| 2419 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver, | 2421 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, |
| 2420 | bmc->id.product_id, | 2422 | bmc->id.product_id, |
| 2421 | bmc->id.device_id)) { | 2423 | bmc->id.device_id)) { |
| 2422 | if (!warn_printed) { | 2424 | if (!warn_printed) { |
| @@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
| 2446 | " Unable to allocate platform device\n"); | 2448 | " Unable to allocate platform device\n"); |
| 2447 | return -ENOMEM; | 2449 | return -ENOMEM; |
| 2448 | } | 2450 | } |
| 2449 | bmc->dev->dev.driver = &ipmidriver; | 2451 | bmc->dev->dev.driver = &ipmidriver.driver; |
| 2450 | dev_set_drvdata(&bmc->dev->dev, bmc); | 2452 | dev_set_drvdata(&bmc->dev->dev, bmc); |
| 2451 | kref_init(&bmc->refcount); | 2453 | kref_init(&bmc->refcount); |
| 2452 | 2454 | ||
| @@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void) | |||
| 4247 | if (initialized) | 4249 | if (initialized) |
| 4248 | return 0; | 4250 | return 0; |
| 4249 | 4251 | ||
| 4250 | rv = driver_register(&ipmidriver); | 4252 | rv = driver_register(&ipmidriver.driver); |
| 4251 | if (rv) { | 4253 | if (rv) { |
| 4252 | printk(KERN_ERR PFX "Could not register IPMI driver\n"); | 4254 | printk(KERN_ERR PFX "Could not register IPMI driver\n"); |
| 4253 | return rv; | 4255 | return rv; |
| @@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void) | |||
| 4308 | remove_proc_entry(proc_ipmi_root->name, NULL); | 4310 | remove_proc_entry(proc_ipmi_root->name, NULL); |
| 4309 | #endif /* CONFIG_PROC_FS */ | 4311 | #endif /* CONFIG_PROC_FS */ |
| 4310 | 4312 | ||
| 4311 | driver_unregister(&ipmidriver); | 4313 | driver_unregister(&ipmidriver.driver); |
| 4312 | 4314 | ||
| 4313 | initialized = 0; | 4315 | initialized = 0; |
| 4314 | 4316 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 3123bf57ad91..3000135f2ead 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" }; | |||
| 114 | 114 | ||
| 115 | #define DEVICE_NAME "ipmi_si" | 115 | #define DEVICE_NAME "ipmi_si" |
| 116 | 116 | ||
| 117 | static struct device_driver ipmi_driver = { | 117 | static struct platform_driver ipmi_driver = { |
| 118 | .name = DEVICE_NAME, | 118 | .driver = { |
| 119 | .bus = &platform_bus_type | 119 | .name = DEVICE_NAME, |
| 120 | .bus = &platform_bus_type | ||
| 121 | } | ||
| 120 | }; | 122 | }; |
| 121 | 123 | ||
| 122 | 124 | ||
| @@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
| 2868 | goto out_err; | 2870 | goto out_err; |
| 2869 | } | 2871 | } |
| 2870 | new_smi->dev = &new_smi->pdev->dev; | 2872 | new_smi->dev = &new_smi->pdev->dev; |
| 2871 | new_smi->dev->driver = &ipmi_driver; | 2873 | new_smi->dev->driver = &ipmi_driver.driver; |
| 2872 | 2874 | ||
| 2873 | rv = platform_device_add(new_smi->pdev); | 2875 | rv = platform_device_add(new_smi->pdev); |
| 2874 | if (rv) { | 2876 | if (rv) { |
| @@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void) | |||
| 2983 | initialized = 1; | 2985 | initialized = 1; |
| 2984 | 2986 | ||
| 2985 | /* Register the device drivers. */ | 2987 | /* Register the device drivers. */ |
| 2986 | rv = driver_register(&ipmi_driver); | 2988 | rv = driver_register(&ipmi_driver.driver); |
| 2987 | if (rv) { | 2989 | if (rv) { |
| 2988 | printk(KERN_ERR | 2990 | printk(KERN_ERR |
| 2989 | "init_ipmi_si: Unable to register driver: %d\n", | 2991 | "init_ipmi_si: Unable to register driver: %d\n", |
| @@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void) | |||
| 3052 | #ifdef CONFIG_PPC_OF | 3054 | #ifdef CONFIG_PPC_OF |
| 3053 | of_unregister_platform_driver(&ipmi_of_platform_driver); | 3055 | of_unregister_platform_driver(&ipmi_of_platform_driver); |
| 3054 | #endif | 3056 | #endif |
| 3055 | driver_unregister(&ipmi_driver); | 3057 | driver_unregister(&ipmi_driver.driver); |
| 3056 | printk(KERN_WARNING | 3058 | printk(KERN_WARNING |
| 3057 | "ipmi_si: Unable to find any System Interface(s)\n"); | 3059 | "ipmi_si: Unable to find any System Interface(s)\n"); |
| 3058 | return -ENODEV; | 3060 | return -ENODEV; |
| @@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void) | |||
| 3151 | cleanup_one_si(e); | 3153 | cleanup_one_si(e); |
| 3152 | mutex_unlock(&smi_infos_lock); | 3154 | mutex_unlock(&smi_infos_lock); |
| 3153 | 3155 | ||
| 3154 | driver_unregister(&ipmi_driver); | 3156 | driver_unregister(&ipmi_driver.driver); |
| 3155 | } | 3157 | } |
| 3156 | module_exit(cleanup_ipmi_si); | 3158 | module_exit(cleanup_ipmi_si); |
| 3157 | 3159 | ||
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 235fab0bdf79..a4d57e31f713 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
| @@ -870,7 +870,6 @@ static int ipmi_close(struct inode *ino, struct file *filep) | |||
| 870 | clear_bit(0, &ipmi_wdog_open); | 870 | clear_bit(0, &ipmi_wdog_open); |
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | ipmi_fasync(-1, filep, 0); | ||
| 874 | expect_close = 0; | 873 | expect_close = 0; |
| 875 | 874 | ||
| 876 | return 0; | 875 | return 0; |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 7d30ee1d3fca..04e4549299ba 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
| @@ -7,12 +7,14 @@ | |||
| 7 | * Original driver code supplied by Multi-Tech | 7 | * Original driver code supplied by Multi-Tech |
| 8 | * | 8 | * |
| 9 | * Changes | 9 | * Changes |
| 10 | * 1/9/98 alan@redhat.com Merge to 2.0.x kernel tree | 10 | * 1/9/98 alan@lxorguk.ukuu.org.uk |
| 11 | * Merge to 2.0.x kernel tree | ||
| 11 | * Obtain and use official major/minors | 12 | * Obtain and use official major/minors |
| 12 | * Loader switched to a misc device | 13 | * Loader switched to a misc device |
| 13 | * (fixed range check bug as a side effect) | 14 | * (fixed range check bug as a side effect) |
| 14 | * Printk clean up | 15 | * Printk clean up |
| 15 | * 9/12/98 alan@redhat.com Rough port to 2.1.x | 16 | * 9/12/98 alan@lxorguk.ukuu.org.uk |
| 17 | * Rough port to 2.1.x | ||
| 16 | * | 18 | * |
| 17 | * 10/6/99 sameer Merged the ISA and PCI drivers to | 19 | * 10/6/99 sameer Merged the ISA and PCI drivers to |
| 18 | * a new unified driver. | 20 | * a new unified driver. |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 44e5d60f517e..4b10770fa937 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
| @@ -3739,7 +3739,7 @@ static int stli_getbrdnr(void) | |||
| 3739 | * do is go probing around in the usual places hoping we can find it. | 3739 | * do is go probing around in the usual places hoping we can find it. |
| 3740 | */ | 3740 | */ |
| 3741 | 3741 | ||
| 3742 | static int stli_findeisabrds(void) | 3742 | static int __init stli_findeisabrds(void) |
| 3743 | { | 3743 | { |
| 3744 | struct stlibrd *brdp; | 3744 | struct stlibrd *brdp; |
| 3745 | unsigned int iobase, eid, i; | 3745 | unsigned int iobase, eid, i; |
| @@ -3935,7 +3935,7 @@ static struct stlibrd *stli_allocbrd(void) | |||
| 3935 | * can find. | 3935 | * can find. |
| 3936 | */ | 3936 | */ |
| 3937 | 3937 | ||
| 3938 | static int stli_initbrds(void) | 3938 | static int __init stli_initbrds(void) |
| 3939 | { | 3939 | { |
| 3940 | struct stlibrd *brdp, *nxtbrdp; | 3940 | struct stlibrd *brdp, *nxtbrdp; |
| 3941 | struct stlconf conf; | 3941 | struct stlconf conf; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 8beef50f95a0..047766915411 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
| @@ -14,7 +14,8 @@ | |||
| 14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
| 15 | * | 15 | * |
| 16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox | 16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox |
| 17 | * <alan@redhat.com>. The original 1.8 code is available on www.moxa.com. | 17 | * <alan@lxorguk.ukuu.org.uk>. The original 1.8 code is available on |
| 18 | * www.moxa.com. | ||
| 18 | * - Fixed x86_64 cleanness | 19 | * - Fixed x86_64 cleanness |
| 19 | */ | 20 | */ |
| 20 | 21 | ||
diff --git a/drivers/char/random.c b/drivers/char/random.c index 705a839f1796..675076f5fca8 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -1139,18 +1139,12 @@ static int random_fasync(int fd, struct file *filp, int on) | |||
| 1139 | return fasync_helper(fd, filp, on, &fasync); | 1139 | return fasync_helper(fd, filp, on, &fasync); |
| 1140 | } | 1140 | } |
| 1141 | 1141 | ||
| 1142 | static int random_release(struct inode *inode, struct file *filp) | ||
| 1143 | { | ||
| 1144 | return fasync_helper(-1, filp, 0, &fasync); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | const struct file_operations random_fops = { | 1142 | const struct file_operations random_fops = { |
| 1148 | .read = random_read, | 1143 | .read = random_read, |
| 1149 | .write = random_write, | 1144 | .write = random_write, |
| 1150 | .poll = random_poll, | 1145 | .poll = random_poll, |
| 1151 | .unlocked_ioctl = random_ioctl, | 1146 | .unlocked_ioctl = random_ioctl, |
| 1152 | .fasync = random_fasync, | 1147 | .fasync = random_fasync, |
| 1153 | .release = random_release, | ||
| 1154 | }; | 1148 | }; |
| 1155 | 1149 | ||
| 1156 | const struct file_operations urandom_fops = { | 1150 | const struct file_operations urandom_fops = { |
| @@ -1158,7 +1152,6 @@ const struct file_operations urandom_fops = { | |||
| 1158 | .write = random_write, | 1152 | .write = random_write, |
| 1159 | .unlocked_ioctl = random_ioctl, | 1153 | .unlocked_ioctl = random_ioctl, |
| 1160 | .fasync = random_fasync, | 1154 | .fasync = random_fasync, |
| 1161 | .release = random_release, | ||
| 1162 | }; | 1155 | }; |
| 1163 | 1156 | ||
| 1164 | /*************************************************************** | 1157 | /*************************************************************** |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 32dc89720d58..20d6efb6324e 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
| @@ -788,8 +788,6 @@ static int rtc_release(struct inode *inode, struct file *file) | |||
| 788 | } | 788 | } |
| 789 | spin_unlock_irq(&rtc_lock); | 789 | spin_unlock_irq(&rtc_lock); |
| 790 | 790 | ||
| 791 | if (file->f_flags & FASYNC) | ||
| 792 | rtc_fasync(-1, file, 0); | ||
| 793 | no_irq: | 791 | no_irq: |
| 794 | #endif | 792 | #endif |
| 795 | 793 | ||
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 3b23270eaa65..a8f15e6be594 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
| @@ -418,7 +418,7 @@ static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id) | |||
| 418 | TTY_OVERRUN); | 418 | TTY_OVERRUN); |
| 419 | /* | 419 | /* |
| 420 | If the flip buffer itself is | 420 | If the flip buffer itself is |
| 421 | overflowing, we still loose | 421 | overflowing, we still lose |
| 422 | the next incoming character. | 422 | the next incoming character. |
| 423 | */ | 423 | */ |
| 424 | if (tty_buffer_request_room(tty, 1) != | 424 | if (tty_buffer_request_room(tty, 1) != |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 85e0eb76eeab..f4374437a033 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
| @@ -523,7 +523,7 @@ static int acpi_driver_registered; | |||
| 523 | 523 | ||
| 524 | static int sonypi_ec_write(u8 addr, u8 value) | 524 | static int sonypi_ec_write(u8 addr, u8 value) |
| 525 | { | 525 | { |
| 526 | #ifdef CONFIG_ACPI_EC | 526 | #ifdef CONFIG_ACPI |
| 527 | if (SONYPI_ACPI_ACTIVE) | 527 | if (SONYPI_ACPI_ACTIVE) |
| 528 | return ec_write(addr, value); | 528 | return ec_write(addr, value); |
| 529 | #endif | 529 | #endif |
| @@ -539,7 +539,7 @@ static int sonypi_ec_write(u8 addr, u8 value) | |||
| 539 | 539 | ||
| 540 | static int sonypi_ec_read(u8 addr, u8 *value) | 540 | static int sonypi_ec_read(u8 addr, u8 *value) |
| 541 | { | 541 | { |
| 542 | #ifdef CONFIG_ACPI_EC | 542 | #ifdef CONFIG_ACPI |
| 543 | if (SONYPI_ACPI_ACTIVE) | 543 | if (SONYPI_ACPI_ACTIVE) |
| 544 | return ec_read(addr, value); | 544 | return ec_read(addr, value); |
| 545 | #endif | 545 | #endif |
| @@ -898,7 +898,6 @@ static int sonypi_misc_fasync(int fd, struct file *filp, int on) | |||
| 898 | 898 | ||
| 899 | static int sonypi_misc_release(struct inode *inode, struct file *file) | 899 | static int sonypi_misc_release(struct inode *inode, struct file *file) |
| 900 | { | 900 | { |
| 901 | sonypi_misc_fasync(-1, file, 0); | ||
| 902 | mutex_lock(&sonypi_device.lock); | 901 | mutex_lock(&sonypi_device.lock); |
| 903 | sonypi_device.open_count--; | 902 | sonypi_device.open_count--; |
| 904 | mutex_unlock(&sonypi_device.lock); | 903 | mutex_unlock(&sonypi_device.lock); |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 242fd46fda22..a16b94f12eb2 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
| @@ -72,7 +72,7 @@ | |||
| 72 | /* | 72 | /* |
| 73 | * There is a bunch of documentation about the card, jumpers, config | 73 | * There is a bunch of documentation about the card, jumpers, config |
| 74 | * settings, restrictions, cables, device names and numbers in | 74 | * settings, restrictions, cables, device names and numbers in |
| 75 | * Documentation/specialix.txt | 75 | * Documentation/serial/specialix.txt |
| 76 | */ | 76 | */ |
| 77 | 77 | ||
| 78 | #include <linux/module.h> | 78 | #include <linux/module.h> |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 59f472143f08..1412a8d1e58d 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -1795,12 +1795,15 @@ retry_open: | |||
| 1795 | } | 1795 | } |
| 1796 | #endif | 1796 | #endif |
| 1797 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | 1797 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { |
| 1798 | driver = tty_driver_kref_get(console_device(&index)); | 1798 | struct tty_driver *console_driver = console_device(&index); |
| 1799 | if (driver) { | 1799 | if (console_driver) { |
| 1800 | /* Don't let /dev/console block */ | 1800 | driver = tty_driver_kref_get(console_driver); |
| 1801 | filp->f_flags |= O_NONBLOCK; | 1801 | if (driver) { |
| 1802 | noctty = 1; | 1802 | /* Don't let /dev/console block */ |
| 1803 | goto got_driver; | 1803 | filp->f_flags |= O_NONBLOCK; |
| 1804 | noctty = 1; | ||
| 1805 | goto got_driver; | ||
| 1806 | } | ||
| 1804 | } | 1807 | } |
| 1805 | mutex_unlock(&tty_mutex); | 1808 | mutex_unlock(&tty_mutex); |
| 1806 | return -ENODEV; | 1809 | return -ENODEV; |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index d8f83e26e4a4..a5af6072e2b3 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
| @@ -1644,7 +1644,10 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
| 1644 | vc->vc_tab_stop[1] = | 1644 | vc->vc_tab_stop[1] = |
| 1645 | vc->vc_tab_stop[2] = | 1645 | vc->vc_tab_stop[2] = |
| 1646 | vc->vc_tab_stop[3] = | 1646 | vc->vc_tab_stop[3] = |
| 1647 | vc->vc_tab_stop[4] = 0x01010101; | 1647 | vc->vc_tab_stop[4] = |
| 1648 | vc->vc_tab_stop[5] = | ||
| 1649 | vc->vc_tab_stop[6] = | ||
| 1650 | vc->vc_tab_stop[7] = 0x01010101; | ||
| 1648 | 1651 | ||
| 1649 | vc->vc_bell_pitch = DEFAULT_BELL_PITCH; | 1652 | vc->vc_bell_pitch = DEFAULT_BELL_PITCH; |
| 1650 | vc->vc_bell_duration = DEFAULT_BELL_DURATION; | 1653 | vc->vc_bell_duration = DEFAULT_BELL_DURATION; |
| @@ -1935,7 +1938,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
| 1935 | vc->vc_tab_stop[1] = | 1938 | vc->vc_tab_stop[1] = |
| 1936 | vc->vc_tab_stop[2] = | 1939 | vc->vc_tab_stop[2] = |
| 1937 | vc->vc_tab_stop[3] = | 1940 | vc->vc_tab_stop[3] = |
| 1938 | vc->vc_tab_stop[4] = 0; | 1941 | vc->vc_tab_stop[4] = |
| 1942 | vc->vc_tab_stop[5] = | ||
| 1943 | vc->vc_tab_stop[6] = | ||
| 1944 | vc->vc_tab_stop[7] = 0; | ||
| 1939 | } | 1945 | } |
| 1940 | return; | 1946 | return; |
| 1941 | case 'm': | 1947 | case 'm': |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index ed132fe55d3d..d16131949097 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
| @@ -626,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, | |||
| 626 | if (!request_mem_region(drvdata->mem_start, | 626 | if (!request_mem_region(drvdata->mem_start, |
| 627 | drvdata->mem_size, DRIVER_NAME)) { | 627 | drvdata->mem_size, DRIVER_NAME)) { |
| 628 | dev_err(dev, "Couldn't lock memory region at %Lx\n", | 628 | dev_err(dev, "Couldn't lock memory region at %Lx\n", |
| 629 | regs_res->start); | 629 | (unsigned long long) regs_res->start); |
| 630 | retval = -EBUSY; | 630 | retval = -EBUSY; |
| 631 | goto failed1; | 631 | goto failed1; |
| 632 | } | 632 | } |
| @@ -645,9 +645,10 @@ static int __devinit hwicap_setup(struct device *dev, int id, | |||
| 645 | mutex_init(&drvdata->sem); | 645 | mutex_init(&drvdata->sem); |
| 646 | drvdata->is_open = 0; | 646 | drvdata->is_open = 0; |
| 647 | 647 | ||
| 648 | dev_info(dev, "ioremap %lx to %p with size %Lx\n", | 648 | dev_info(dev, "ioremap %llx to %p with size %llx\n", |
| 649 | (unsigned long int)drvdata->mem_start, | 649 | (unsigned long long) drvdata->mem_start, |
| 650 | drvdata->base_address, drvdata->mem_size); | 650 | drvdata->base_address, |
| 651 | (unsigned long long) drvdata->mem_size); | ||
| 651 | 652 | ||
| 652 | cdev_init(&drvdata->cdev, &hwicap_fops); | 653 | cdev_init(&drvdata->cdev, &hwicap_fops); |
| 653 | drvdata->cdev.owner = THIS_MODULE; | 654 | drvdata->cdev.owner = THIS_MODULE; |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 5bed73329ef8..8504a2108557 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
| @@ -65,12 +65,14 @@ static void cpuidle_idle_call(void) | |||
| 65 | return; | 65 | return; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | #if 0 | ||
| 69 | /* shows regressions, re-enable for 2.6.29 */ | ||
| 68 | /* | 70 | /* |
| 69 | * run any timers that can be run now, at this point | 71 | * run any timers that can be run now, at this point |
| 70 | * before calculating the idle duration etc. | 72 | * before calculating the idle duration etc. |
| 71 | */ | 73 | */ |
| 72 | hrtimer_peek_ahead_timers(); | 74 | hrtimer_peek_ahead_timers(); |
| 73 | 75 | #endif | |
| 74 | /* ask the governor for the next state */ | 76 | /* ask the governor for the next state */ |
| 75 | next_state = cpuidle_curr_governor->select(dev); | 77 | next_state = cpuidle_curr_governor->select(dev); |
| 76 | if (need_resched()) | 78 | if (need_resched()) |
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index b6ad3ac5916e..24607669a52b 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
| @@ -1357,7 +1357,7 @@ static int hw_supports(struct device *dev, __be32 desc_hdr_template) | |||
| 1357 | return ret; | 1357 | return ret; |
| 1358 | } | 1358 | } |
| 1359 | 1359 | ||
| 1360 | static int __devexit talitos_remove(struct of_device *ofdev) | 1360 | static int talitos_remove(struct of_device *ofdev) |
| 1361 | { | 1361 | { |
| 1362 | struct device *dev = &ofdev->dev; | 1362 | struct device *dev = &ofdev->dev; |
| 1363 | struct talitos_private *priv = dev_get_drvdata(dev); | 1363 | struct talitos_private *priv = dev_get_drvdata(dev); |
| @@ -1622,7 +1622,7 @@ static struct of_platform_driver talitos_driver = { | |||
| 1622 | .name = "talitos", | 1622 | .name = "talitos", |
| 1623 | .match_table = talitos_match, | 1623 | .match_table = talitos_match, |
| 1624 | .probe = talitos_probe, | 1624 | .probe = talitos_probe, |
| 1625 | .remove = __devexit_p(talitos_remove), | 1625 | .remove = talitos_remove, |
| 1626 | }; | 1626 | }; |
| 1627 | 1627 | ||
| 1628 | static int __init talitos_init(void) | 1628 | static int __init talitos_init(void) |
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index ec249d2db633..d883e1b8bb8c 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c | |||
| @@ -270,6 +270,6 @@ static void __exit dca_exit(void) | |||
| 270 | dca_sysfs_exit(); | 270 | dca_sysfs_exit(); |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | module_init(dca_init); | 273 | subsys_initcall(dca_init); |
| 274 | module_exit(dca_exit); | 274 | module_exit(dca_exit); |
| 275 | 275 | ||
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index dc003a3a787d..5317e08221ec 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
| @@ -399,8 +399,8 @@ int dma_async_device_register(struct dma_device *device) | |||
| 399 | chan->chan_id = chancnt++; | 399 | chan->chan_id = chancnt++; |
| 400 | chan->dev.class = &dma_devclass; | 400 | chan->dev.class = &dma_devclass; |
| 401 | chan->dev.parent = device->dev; | 401 | chan->dev.parent = device->dev; |
| 402 | snprintf(chan->dev.bus_id, BUS_ID_SIZE, "dma%dchan%d", | 402 | dev_set_name(&chan->dev, "dma%dchan%d", |
| 403 | device->dev_id, chan->chan_id); | 403 | device->dev_id, chan->chan_id); |
| 404 | 404 | ||
| 405 | rc = device_register(&chan->dev); | 405 | rc = device_register(&chan->dev); |
| 406 | if (rc) { | 406 | if (rc) { |
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index d1e381e35a9e..ed9636bfb54a 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
| @@ -20,11 +20,11 @@ static unsigned int test_buf_size = 16384; | |||
| 20 | module_param(test_buf_size, uint, S_IRUGO); | 20 | module_param(test_buf_size, uint, S_IRUGO); |
| 21 | MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); | 21 | MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); |
| 22 | 22 | ||
| 23 | static char test_channel[BUS_ID_SIZE]; | 23 | static char test_channel[20]; |
| 24 | module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); | 24 | module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); |
| 25 | MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); | 25 | MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); |
| 26 | 26 | ||
| 27 | static char test_device[BUS_ID_SIZE]; | 27 | static char test_device[20]; |
| 28 | module_param_string(device, test_device, sizeof(test_device), S_IRUGO); | 28 | module_param_string(device, test_device, sizeof(test_device), S_IRUGO); |
| 29 | MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); | 29 | MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); |
| 30 | 30 | ||
| @@ -80,14 +80,14 @@ static bool dmatest_match_channel(struct dma_chan *chan) | |||
| 80 | { | 80 | { |
| 81 | if (test_channel[0] == '\0') | 81 | if (test_channel[0] == '\0') |
| 82 | return true; | 82 | return true; |
| 83 | return strcmp(chan->dev.bus_id, test_channel) == 0; | 83 | return strcmp(dev_name(&chan->dev), test_channel) == 0; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static bool dmatest_match_device(struct dma_device *device) | 86 | static bool dmatest_match_device(struct dma_device *device) |
| 87 | { | 87 | { |
| 88 | if (test_device[0] == '\0') | 88 | if (test_device[0] == '\0') |
| 89 | return true; | 89 | return true; |
| 90 | return strcmp(device->dev->bus_id, test_device) == 0; | 90 | return strcmp(dev_name(device->dev), test_device) == 0; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static unsigned long dmatest_random(void) | 93 | static unsigned long dmatest_random(void) |
| @@ -332,7 +332,7 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
| 332 | 332 | ||
| 333 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); | 333 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); |
| 334 | if (!dtc) { | 334 | if (!dtc) { |
| 335 | pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id); | 335 | pr_warning("dmatest: No memory for %s\n", dev_name(&chan->dev)); |
| 336 | return DMA_NAK; | 336 | return DMA_NAK; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| @@ -343,16 +343,16 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
| 343 | thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL); | 343 | thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL); |
| 344 | if (!thread) { | 344 | if (!thread) { |
| 345 | pr_warning("dmatest: No memory for %s-test%u\n", | 345 | pr_warning("dmatest: No memory for %s-test%u\n", |
| 346 | chan->dev.bus_id, i); | 346 | dev_name(&chan->dev), i); |
| 347 | break; | 347 | break; |
| 348 | } | 348 | } |
| 349 | thread->chan = dtc->chan; | 349 | thread->chan = dtc->chan; |
| 350 | smp_wmb(); | 350 | smp_wmb(); |
| 351 | thread->task = kthread_run(dmatest_func, thread, "%s-test%u", | 351 | thread->task = kthread_run(dmatest_func, thread, "%s-test%u", |
| 352 | chan->dev.bus_id, i); | 352 | dev_name(&chan->dev), i); |
| 353 | if (IS_ERR(thread->task)) { | 353 | if (IS_ERR(thread->task)) { |
| 354 | pr_warning("dmatest: Failed to run thread %s-test%u\n", | 354 | pr_warning("dmatest: Failed to run thread %s-test%u\n", |
| 355 | chan->dev.bus_id, i); | 355 | dev_name(&chan->dev), i); |
| 356 | kfree(thread); | 356 | kfree(thread); |
| 357 | break; | 357 | break; |
| 358 | } | 358 | } |
| @@ -362,7 +362,7 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
| 362 | list_add_tail(&thread->node, &dtc->threads); | 362 | list_add_tail(&thread->node, &dtc->threads); |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | pr_info("dmatest: Started %u threads using %s\n", i, chan->dev.bus_id); | 365 | pr_info("dmatest: Started %u threads using %s\n", i, dev_name(&chan->dev)); |
| 366 | 366 | ||
| 367 | list_add_tail(&dtc->node, &dmatest_channels); | 367 | list_add_tail(&dtc->node, &dmatest_channels); |
| 368 | nr_channels++; | 368 | nr_channels++; |
| @@ -379,7 +379,7 @@ static enum dma_state_client dmatest_remove_channel(struct dma_chan *chan) | |||
| 379 | list_del(&dtc->node); | 379 | list_del(&dtc->node); |
| 380 | dmatest_cleanup_channel(dtc); | 380 | dmatest_cleanup_channel(dtc); |
| 381 | pr_debug("dmatest: lost channel %s\n", | 381 | pr_debug("dmatest: lost channel %s\n", |
| 382 | chan->dev.bus_id); | 382 | dev_name(&chan->dev)); |
| 383 | return DMA_ACK; | 383 | return DMA_ACK; |
| 384 | } | 384 | } |
| 385 | } | 385 | } |
| @@ -418,7 +418,7 @@ dmatest_event(struct dma_client *client, struct dma_chan *chan, | |||
| 418 | 418 | ||
| 419 | default: | 419 | default: |
| 420 | pr_info("dmatest: Unhandled event %u (%s)\n", | 420 | pr_info("dmatest: Unhandled event %u (%s)\n", |
| 421 | state, chan->dev.bus_id); | 421 | state, dev_name(&chan->dev)); |
| 422 | break; | 422 | break; |
| 423 | } | 423 | } |
| 424 | 424 | ||
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index b0438c4f0c30..ecd743f7cc61 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c | |||
| @@ -525,7 +525,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) | |||
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | 527 | hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; |
| 528 | if (new->async_tx.callback) { | 528 | if (first->async_tx.callback) { |
| 529 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; | 529 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; |
| 530 | if (first != new) { | 530 | if (first != new) { |
| 531 | /* move callback into to last desc */ | 531 | /* move callback into to last desc */ |
| @@ -617,7 +617,7 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx) | |||
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | 619 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS; |
| 620 | if (new->async_tx.callback) { | 620 | if (first->async_tx.callback) { |
| 621 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; | 621 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; |
| 622 | if (first != new) { | 622 | if (first != new) { |
| 623 | /* move callback into to last desc */ | 623 | /* move callback into to last desc */ |
| @@ -807,6 +807,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
| 807 | struct ioat_desc_sw *desc, *_desc; | 807 | struct ioat_desc_sw *desc, *_desc; |
| 808 | int in_use_descs = 0; | 808 | int in_use_descs = 0; |
| 809 | 809 | ||
| 810 | /* Before freeing channel resources first check | ||
| 811 | * if they have been previously allocated for this channel. | ||
| 812 | */ | ||
| 813 | if (ioat_chan->desccount == 0) | ||
| 814 | return; | ||
| 815 | |||
| 810 | tasklet_disable(&ioat_chan->cleanup_task); | 816 | tasklet_disable(&ioat_chan->cleanup_task); |
| 811 | ioat_dma_memcpy_cleanup(ioat_chan); | 817 | ioat_dma_memcpy_cleanup(ioat_chan); |
| 812 | 818 | ||
| @@ -869,6 +875,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
| 869 | ioat_chan->last_completion = ioat_chan->completion_addr = 0; | 875 | ioat_chan->last_completion = ioat_chan->completion_addr = 0; |
| 870 | ioat_chan->pending = 0; | 876 | ioat_chan->pending = 0; |
| 871 | ioat_chan->dmacount = 0; | 877 | ioat_chan->dmacount = 0; |
| 878 | ioat_chan->desccount = 0; | ||
| 872 | ioat_chan->watchdog_completion = 0; | 879 | ioat_chan->watchdog_completion = 0; |
| 873 | ioat_chan->last_compl_desc_addr_hw = 0; | 880 | ioat_chan->last_compl_desc_addr_hw = 0; |
| 874 | ioat_chan->watchdog_tcp_cookie = | 881 | ioat_chan->watchdog_tcp_cookie = |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 71fba82462cb..c7a9306d951d 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
| @@ -411,6 +411,7 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
| 411 | int slot_cnt; | 411 | int slot_cnt; |
| 412 | int slots_per_op; | 412 | int slots_per_op; |
| 413 | dma_cookie_t cookie; | 413 | dma_cookie_t cookie; |
| 414 | dma_addr_t next_dma; | ||
| 414 | 415 | ||
| 415 | grp_start = sw_desc->group_head; | 416 | grp_start = sw_desc->group_head; |
| 416 | slot_cnt = grp_start->slot_cnt; | 417 | slot_cnt = grp_start->slot_cnt; |
| @@ -425,12 +426,12 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
| 425 | &old_chain_tail->chain_node); | 426 | &old_chain_tail->chain_node); |
| 426 | 427 | ||
| 427 | /* fix up the hardware chain */ | 428 | /* fix up the hardware chain */ |
| 428 | iop_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys); | 429 | next_dma = grp_start->async_tx.phys; |
| 430 | iop_desc_set_next_desc(old_chain_tail, next_dma); | ||
| 431 | BUG_ON(iop_desc_get_next_desc(old_chain_tail) != next_dma); /* flush */ | ||
| 429 | 432 | ||
| 430 | /* 1/ don't add pre-chained descriptors | 433 | /* check for pre-chained descriptors */ |
| 431 | * 2/ dummy read to flush next_desc write | 434 | iop_paranoia(iop_desc_get_next_desc(sw_desc)); |
| 432 | */ | ||
| 433 | BUG_ON(iop_desc_get_next_desc(sw_desc)); | ||
| 434 | 435 | ||
| 435 | /* increment the pending count by the number of slots | 436 | /* increment the pending count by the number of slots |
| 436 | * memcpy operations have a 1:1 (slot:operation) relation | 437 | * memcpy operations have a 1:1 (slot:operation) relation |
diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c index e763d723e4cf..9f6fe46a9b87 100644 --- a/drivers/dma/iovlock.c +++ b/drivers/dma/iovlock.c | |||
| @@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
| 55 | int nr_iovecs = 0; | 55 | int nr_iovecs = 0; |
| 56 | int iovec_len_used = 0; | 56 | int iovec_len_used = 0; |
| 57 | int iovec_pages_used = 0; | 57 | int iovec_pages_used = 0; |
| 58 | long err; | ||
| 59 | 58 | ||
| 60 | /* don't pin down non-user-based iovecs */ | 59 | /* don't pin down non-user-based iovecs */ |
| 61 | if (segment_eq(get_fs(), KERNEL_DS)) | 60 | if (segment_eq(get_fs(), KERNEL_DS)) |
| @@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
| 72 | local_list = kmalloc(sizeof(*local_list) | 71 | local_list = kmalloc(sizeof(*local_list) |
| 73 | + (nr_iovecs * sizeof (struct dma_page_list)) | 72 | + (nr_iovecs * sizeof (struct dma_page_list)) |
| 74 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); | 73 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); |
| 75 | if (!local_list) { | 74 | if (!local_list) |
| 76 | err = -ENOMEM; | ||
| 77 | goto out; | 75 | goto out; |
| 78 | } | ||
| 79 | 76 | ||
| 80 | /* list of pages starts right after the page list array */ | 77 | /* list of pages starts right after the page list array */ |
| 81 | pages = (struct page **) &local_list->page_list[nr_iovecs]; | 78 | pages = (struct page **) &local_list->page_list[nr_iovecs]; |
| 82 | 79 | ||
| 80 | local_list->nr_iovecs = 0; | ||
| 81 | |||
| 83 | for (i = 0; i < nr_iovecs; i++) { | 82 | for (i = 0; i < nr_iovecs; i++) { |
| 84 | struct dma_page_list *page_list = &local_list->page_list[i]; | 83 | struct dma_page_list *page_list = &local_list->page_list[i]; |
| 85 | 84 | ||
| 86 | len -= iov[i].iov_len; | 85 | len -= iov[i].iov_len; |
| 87 | 86 | ||
| 88 | if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) { | 87 | if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) |
| 89 | err = -EFAULT; | ||
| 90 | goto unpin; | 88 | goto unpin; |
| 91 | } | ||
| 92 | 89 | ||
| 93 | page_list->nr_pages = num_pages_spanned(&iov[i]); | 90 | page_list->nr_pages = num_pages_spanned(&iov[i]); |
| 94 | page_list->base_address = iov[i].iov_base; | 91 | page_list->base_address = iov[i].iov_base; |
| @@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
| 109 | NULL); | 106 | NULL); |
| 110 | up_read(¤t->mm->mmap_sem); | 107 | up_read(¤t->mm->mmap_sem); |
| 111 | 108 | ||
| 112 | if (ret != page_list->nr_pages) { | 109 | if (ret != page_list->nr_pages) |
| 113 | err = -ENOMEM; | ||
| 114 | goto unpin; | 110 | goto unpin; |
| 115 | } | ||
| 116 | 111 | ||
| 117 | local_list->nr_iovecs = i + 1; | 112 | local_list->nr_iovecs = i + 1; |
| 118 | } | 113 | } |
| @@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
| 122 | unpin: | 117 | unpin: |
| 123 | dma_unpin_iovec_pages(local_list); | 118 | dma_unpin_iovec_pages(local_list); |
| 124 | out: | 119 | out: |
| 125 | return ERR_PTR(err); | 120 | return NULL; |
| 126 | } | 121 | } |
| 127 | 122 | ||
| 128 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) | 123 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) |
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index f0d9b415db50..d335086f4a26 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c | |||
| @@ -1381,6 +1381,7 @@ static int i5000_probe1(struct pci_dev *pdev, int dev_idx) | |||
| 1381 | if (mci == NULL) | 1381 | if (mci == NULL) |
| 1382 | return -ENOMEM; | 1382 | return -ENOMEM; |
| 1383 | 1383 | ||
| 1384 | kobject_get(&mci->edac_mci_kobj); | ||
| 1384 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); | 1385 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); |
| 1385 | 1386 | ||
| 1386 | mci->dev = &pdev->dev; /* record ptr to the generic device */ | 1387 | mci->dev = &pdev->dev; /* record ptr to the generic device */ |
| @@ -1453,6 +1454,7 @@ fail1: | |||
| 1453 | i5000_put_devices(mci); | 1454 | i5000_put_devices(mci); |
| 1454 | 1455 | ||
| 1455 | fail0: | 1456 | fail0: |
| 1457 | kobject_put(&mci->edac_mci_kobj); | ||
| 1456 | edac_mc_free(mci); | 1458 | edac_mc_free(mci); |
| 1457 | return -ENODEV; | 1459 | return -ENODEV; |
| 1458 | } | 1460 | } |
| @@ -1498,7 +1500,7 @@ static void __devexit i5000_remove_one(struct pci_dev *pdev) | |||
| 1498 | 1500 | ||
| 1499 | /* retrieve references to resources, and free those resources */ | 1501 | /* retrieve references to resources, and free those resources */ |
| 1500 | i5000_put_devices(mci); | 1502 | i5000_put_devices(mci); |
| 1501 | 1503 | kobject_put(&mci->edac_mci_kobj); | |
| 1502 | edac_mc_free(mci); | 1504 | edac_mc_free(mci); |
| 1503 | } | 1505 | } |
| 1504 | 1506 | ||
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index e43bdc43a1bf..ebb037b78758 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
| @@ -182,8 +182,6 @@ static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has | |||
| 182 | * already registered driver | 182 | * already registered driver |
| 183 | */ | 183 | */ |
| 184 | 184 | ||
| 185 | static int i82875p_registered = 1; | ||
| 186 | |||
| 187 | static struct edac_pci_ctl_info *i82875p_pci; | 185 | static struct edac_pci_ctl_info *i82875p_pci; |
| 188 | 186 | ||
| 189 | static void i82875p_get_error_info(struct mem_ctl_info *mci, | 187 | static void i82875p_get_error_info(struct mem_ctl_info *mci, |
| @@ -295,6 +293,7 @@ static int i82875p_setup_overfl_dev(struct pci_dev *pdev, | |||
| 295 | "%s(): pci_bus_add_device() Failed\n", | 293 | "%s(): pci_bus_add_device() Failed\n", |
| 296 | __func__); | 294 | __func__); |
| 297 | } | 295 | } |
| 296 | pci_bus_assign_resources(dev->bus); | ||
| 298 | } | 297 | } |
| 299 | 298 | ||
| 300 | *ovrfl_pdev = dev; | 299 | *ovrfl_pdev = dev; |
| @@ -409,6 +408,9 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) | |||
| 409 | goto fail0; | 408 | goto fail0; |
| 410 | } | 409 | } |
| 411 | 410 | ||
| 411 | /* Keeps mci available after edac_mc_del_mc() till edac_mc_free() */ | ||
| 412 | kobject_get(&mci->edac_mci_kobj); | ||
| 413 | |||
| 412 | debugf3("%s(): init mci\n", __func__); | 414 | debugf3("%s(): init mci\n", __func__); |
| 413 | mci->dev = &pdev->dev; | 415 | mci->dev = &pdev->dev; |
| 414 | mci->mtype_cap = MEM_FLAG_DDR; | 416 | mci->mtype_cap = MEM_FLAG_DDR; |
| @@ -451,6 +453,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) | |||
| 451 | return 0; | 453 | return 0; |
| 452 | 454 | ||
| 453 | fail1: | 455 | fail1: |
| 456 | kobject_put(&mci->edac_mci_kobj); | ||
| 454 | edac_mc_free(mci); | 457 | edac_mc_free(mci); |
| 455 | 458 | ||
| 456 | fail0: | 459 | fail0: |
| @@ -578,12 +581,11 @@ static void __exit i82875p_exit(void) | |||
| 578 | { | 581 | { |
| 579 | debugf3("%s()\n", __func__); | 582 | debugf3("%s()\n", __func__); |
| 580 | 583 | ||
| 584 | i82875p_remove_one(mci_pdev); | ||
| 585 | pci_dev_put(mci_pdev); | ||
| 586 | |||
| 581 | pci_unregister_driver(&i82875p_driver); | 587 | pci_unregister_driver(&i82875p_driver); |
| 582 | 588 | ||
| 583 | if (!i82875p_registered) { | ||
| 584 | i82875p_remove_one(mci_pdev); | ||
| 585 | pci_dev_put(mci_pdev); | ||
| 586 | } | ||
| 587 | } | 589 | } |
| 588 | 590 | ||
| 589 | module_init(i82875p_init); | 591 | module_init(i82875p_init); |
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 3fccdd484100..6b9be42c7b98 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
| @@ -587,8 +587,7 @@ static void create_units(struct fw_device *device) | |||
| 587 | unit->device.bus = &fw_bus_type; | 587 | unit->device.bus = &fw_bus_type; |
| 588 | unit->device.type = &fw_unit_type; | 588 | unit->device.type = &fw_unit_type; |
| 589 | unit->device.parent = &device->device; | 589 | unit->device.parent = &device->device; |
| 590 | snprintf(unit->device.bus_id, sizeof(unit->device.bus_id), | 590 | dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++); |
| 591 | "%s.%d", device->device.bus_id, i++); | ||
| 592 | 591 | ||
| 593 | init_fw_attribute_group(&unit->device, | 592 | init_fw_attribute_group(&unit->device, |
| 594 | fw_unit_attributes, | 593 | fw_unit_attributes, |
| @@ -711,8 +710,7 @@ static void fw_device_init(struct work_struct *work) | |||
| 711 | device->device.type = &fw_device_type; | 710 | device->device.type = &fw_device_type; |
| 712 | device->device.parent = device->card->device; | 711 | device->device.parent = device->card->device; |
| 713 | device->device.devt = MKDEV(fw_cdev_major, minor); | 712 | device->device.devt = MKDEV(fw_cdev_major, minor); |
| 714 | snprintf(device->device.bus_id, sizeof(device->device.bus_id), | 713 | dev_set_name(&device->device, "fw%d", minor); |
| 715 | "fw%d", minor); | ||
| 716 | 714 | ||
| 717 | init_fw_attribute_group(&device->device, | 715 | init_fw_attribute_group(&device->device, |
| 718 | fw_device_attributes, | 716 | fw_device_attributes, |
| @@ -741,13 +739,13 @@ static void fw_device_init(struct work_struct *work) | |||
| 741 | if (device->config_rom_retries) | 739 | if (device->config_rom_retries) |
| 742 | fw_notify("created device %s: GUID %08x%08x, S%d00, " | 740 | fw_notify("created device %s: GUID %08x%08x, S%d00, " |
| 743 | "%d config ROM retries\n", | 741 | "%d config ROM retries\n", |
| 744 | device->device.bus_id, | 742 | dev_name(&device->device), |
| 745 | device->config_rom[3], device->config_rom[4], | 743 | device->config_rom[3], device->config_rom[4], |
| 746 | 1 << device->max_speed, | 744 | 1 << device->max_speed, |
| 747 | device->config_rom_retries); | 745 | device->config_rom_retries); |
| 748 | else | 746 | else |
| 749 | fw_notify("created device %s: GUID %08x%08x, S%d00\n", | 747 | fw_notify("created device %s: GUID %08x%08x, S%d00\n", |
| 750 | device->device.bus_id, | 748 | dev_name(&device->device), |
| 751 | device->config_rom[3], device->config_rom[4], | 749 | device->config_rom[3], device->config_rom[4], |
| 752 | 1 << device->max_speed); | 750 | 1 << device->max_speed); |
| 753 | device->config_rom_retries = 0; | 751 | device->config_rom_retries = 0; |
| @@ -883,12 +881,12 @@ static void fw_device_refresh(struct work_struct *work) | |||
| 883 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) | 881 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) |
| 884 | goto gone; | 882 | goto gone; |
| 885 | 883 | ||
| 886 | fw_notify("refreshed device %s\n", device->device.bus_id); | 884 | fw_notify("refreshed device %s\n", dev_name(&device->device)); |
| 887 | device->config_rom_retries = 0; | 885 | device->config_rom_retries = 0; |
| 888 | goto out; | 886 | goto out; |
| 889 | 887 | ||
| 890 | give_up: | 888 | give_up: |
| 891 | fw_notify("giving up on refresh of device %s\n", device->device.bus_id); | 889 | fw_notify("giving up on refresh of device %s\n", dev_name(&device->device)); |
| 892 | gone: | 890 | gone: |
| 893 | atomic_set(&device->state, FW_DEVICE_SHUTDOWN); | 891 | atomic_set(&device->state, FW_DEVICE_SHUTDOWN); |
| 894 | fw_device_shutdown(work); | 892 | fw_device_shutdown(work); |
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 8e16bfbdcb3d..ab9c01e462ef 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
| @@ -974,6 +974,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) | |||
| 974 | packet->ack = RCODE_SEND_ERROR; | 974 | packet->ack = RCODE_SEND_ERROR; |
| 975 | return -1; | 975 | return -1; |
| 976 | } | 976 | } |
| 977 | packet->payload_bus = payload_bus; | ||
| 977 | 978 | ||
| 978 | d[2].req_count = cpu_to_le16(packet->payload_length); | 979 | d[2].req_count = cpu_to_le16(packet->payload_length); |
| 979 | d[2].data_address = cpu_to_le32(payload_bus); | 980 | d[2].data_address = cpu_to_le32(payload_bus); |
| @@ -1025,7 +1026,6 @@ static int handle_at_packet(struct context *context, | |||
| 1025 | struct driver_data *driver_data; | 1026 | struct driver_data *driver_data; |
| 1026 | struct fw_packet *packet; | 1027 | struct fw_packet *packet; |
| 1027 | struct fw_ohci *ohci = context->ohci; | 1028 | struct fw_ohci *ohci = context->ohci; |
| 1028 | dma_addr_t payload_bus; | ||
| 1029 | int evt; | 1029 | int evt; |
| 1030 | 1030 | ||
| 1031 | if (last->transfer_status == 0) | 1031 | if (last->transfer_status == 0) |
| @@ -1038,9 +1038,8 @@ static int handle_at_packet(struct context *context, | |||
| 1038 | /* This packet was cancelled, just continue. */ | 1038 | /* This packet was cancelled, just continue. */ |
| 1039 | return 1; | 1039 | return 1; |
| 1040 | 1040 | ||
| 1041 | payload_bus = le32_to_cpu(last->data_address); | 1041 | if (packet->payload_bus) |
| 1042 | if (payload_bus != 0) | 1042 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
| 1043 | dma_unmap_single(ohci->card.device, payload_bus, | ||
| 1044 | packet->payload_length, DMA_TO_DEVICE); | 1043 | packet->payload_length, DMA_TO_DEVICE); |
| 1045 | 1044 | ||
| 1046 | evt = le16_to_cpu(last->transfer_status) & 0x1f; | 1045 | evt = le16_to_cpu(last->transfer_status) & 0x1f; |
| @@ -1697,6 +1696,10 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) | |||
| 1697 | if (packet->ack != 0) | 1696 | if (packet->ack != 0) |
| 1698 | goto out; | 1697 | goto out; |
| 1699 | 1698 | ||
| 1699 | if (packet->payload_bus) | ||
| 1700 | dma_unmap_single(ohci->card.device, packet->payload_bus, | ||
| 1701 | packet->payload_length, DMA_TO_DEVICE); | ||
| 1702 | |||
| 1700 | log_ar_at_event('T', packet->speed, packet->header, 0x20); | 1703 | log_ar_at_event('T', packet->speed, packet->header, 0x20); |
| 1701 | driver_data->packet = NULL; | 1704 | driver_data->packet = NULL; |
| 1702 | packet->ack = RCODE_CANCELLED; | 1705 | packet->ack = RCODE_CANCELLED; |
| @@ -2468,7 +2471,7 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
| 2468 | goto fail_self_id; | 2471 | goto fail_self_id; |
| 2469 | 2472 | ||
| 2470 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2473 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
| 2471 | dev->dev.bus_id, version >> 16, version & 0xff); | 2474 | dev_name(&dev->dev), version >> 16, version & 0xff); |
| 2472 | return 0; | 2475 | return 0; |
| 2473 | 2476 | ||
| 2474 | fail_self_id: | 2477 | fail_self_id: |
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index d334cac5e1fc..e54403ee59e7 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
| @@ -372,6 +372,11 @@ static const struct { | |||
| 372 | }, | 372 | }, |
| 373 | /* iPod mini */ { | 373 | /* iPod mini */ { |
| 374 | .firmware_revision = 0x0a2700, | 374 | .firmware_revision = 0x0a2700, |
| 375 | .model = 0x000022, | ||
| 376 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | ||
| 377 | }, | ||
| 378 | /* iPod mini */ { | ||
| 379 | .firmware_revision = 0x0a2700, | ||
| 375 | .model = 0x000023, | 380 | .model = 0x000023, |
| 376 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | 381 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, |
| 377 | }, | 382 | }, |
| @@ -1135,7 +1140,7 @@ static int sbp2_probe(struct device *dev) | |||
| 1135 | tgt->unit = unit; | 1140 | tgt->unit = unit; |
| 1136 | kref_init(&tgt->kref); | 1141 | kref_init(&tgt->kref); |
| 1137 | INIT_LIST_HEAD(&tgt->lu_list); | 1142 | INIT_LIST_HEAD(&tgt->lu_list); |
| 1138 | tgt->bus_id = unit->device.bus_id; | 1143 | tgt->bus_id = dev_name(&unit->device); |
| 1139 | tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; | 1144 | tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; |
| 1140 | 1145 | ||
| 1141 | if (fw_device_enable_phys_dma(device) < 0) | 1146 | if (fw_device_enable_phys_dma(device) < 0) |
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 022ac4fabb67..2884f876397b 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c | |||
| @@ -207,6 +207,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, | |||
| 207 | packet->speed = speed; | 207 | packet->speed = speed; |
| 208 | packet->generation = generation; | 208 | packet->generation = generation; |
| 209 | packet->ack = 0; | 209 | packet->ack = 0; |
| 210 | packet->payload_bus = 0; | ||
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | /** | 213 | /** |
| @@ -581,6 +582,8 @@ fw_fill_response(struct fw_packet *response, u32 *request_header, | |||
| 581 | BUG(); | 582 | BUG(); |
| 582 | return; | 583 | return; |
| 583 | } | 584 | } |
| 585 | |||
| 586 | response->payload_bus = 0; | ||
| 584 | } | 587 | } |
| 585 | EXPORT_SYMBOL(fw_fill_response); | 588 | EXPORT_SYMBOL(fw_fill_response); |
| 586 | 589 | ||
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index aed7dbb17cda..839466f0a795 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
| 28 | #include <linux/spinlock_types.h> | 28 | #include <linux/spinlock_types.h> |
| 29 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
| 30 | #include <linux/types.h> | ||
| 30 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
| 31 | 32 | ||
| 32 | #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) | 33 | #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) |
| @@ -153,6 +154,7 @@ struct fw_packet { | |||
| 153 | size_t header_length; | 154 | size_t header_length; |
| 154 | void *payload; | 155 | void *payload; |
| 155 | size_t payload_length; | 156 | size_t payload_length; |
| 157 | dma_addr_t payload_bus; | ||
| 156 | u32 timestamp; | 158 | u32 timestamp; |
| 157 | 159 | ||
| 158 | /* | 160 | /* |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 3e526b6d00cb..8daf4793ac32 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
| @@ -81,9 +81,9 @@ static void dmi_table(u8 *buf, int len, int num, | |||
| 81 | const struct dmi_header *dm = (const struct dmi_header *)data; | 81 | const struct dmi_header *dm = (const struct dmi_header *)data; |
| 82 | 82 | ||
| 83 | /* | 83 | /* |
| 84 | * We want to know the total length (formated area and strings) | 84 | * We want to know the total length (formatted area and |
| 85 | * before decoding to make sure we won't run off the table in | 85 | * strings) before decoding to make sure we won't run off the |
| 86 | * dmi_decode or dmi_string | 86 | * table in dmi_decode or dmi_string |
| 87 | */ | 87 | */ |
| 88 | data += dm->length; | 88 | data += dm->length; |
| 89 | while ((data - buf < len - 1) && (data[0] || data[1])) | 89 | while ((data - buf < len - 1) && (data[0] || data[1])) |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7f2ee27fe76b..48f49d93d249 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -65,6 +65,14 @@ config GPIO_SYSFS | |||
| 65 | 65 | ||
| 66 | # put expanders in the right section, in alphabetical order | 66 | # put expanders in the right section, in alphabetical order |
| 67 | 67 | ||
| 68 | comment "Memory mapped GPIO expanders:" | ||
| 69 | |||
| 70 | config GPIO_XILINX | ||
| 71 | bool "Xilinx GPIO support" | ||
| 72 | depends on PPC_OF | ||
| 73 | help | ||
| 74 | Say yes here to support the Xilinx FPGA GPIO device | ||
| 75 | |||
| 68 | comment "I2C GPIO expanders:" | 76 | comment "I2C GPIO expanders:" |
| 69 | 77 | ||
| 70 | config GPIO_MAX732X | 78 | config GPIO_MAX732X |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 6aafdeb9ad03..49ac64e515e6 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
| @@ -10,4 +10,5 @@ obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o | |||
| 10 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o | 10 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o |
| 11 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | 11 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o |
| 12 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o | 12 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o |
| 13 | obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o | ||
| 13 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o | 14 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index faa1cc66e9cf..82020abc329e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -1134,7 +1134,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
| 1134 | continue; | 1134 | continue; |
| 1135 | 1135 | ||
| 1136 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); | 1136 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); |
| 1137 | seq_printf(s, " gpio-%-3d (%-12s) %s %s", | 1137 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", |
| 1138 | gpio, gdesc->label, | 1138 | gpio, gdesc->label, |
| 1139 | is_out ? "out" : "in ", | 1139 | is_out ? "out" : "in ", |
| 1140 | chip->get | 1140 | chip->get |
diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c new file mode 100644 index 000000000000..3c1177abebd3 --- /dev/null +++ b/drivers/gpio/xilinx_gpio.c | |||
| @@ -0,0 +1,235 @@ | |||
| 1 | /* | ||
| 2 | * Xilinx gpio driver | ||
| 3 | * | ||
| 4 | * Copyright 2008 Xilinx, Inc. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 | ||
| 8 | * as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * You should have received a copy of the GNU General Public License | ||
| 11 | * along with this program; if not, write to the Free Software | ||
| 12 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/of_device.h> | ||
| 18 | #include <linux/of_platform.h> | ||
| 19 | #include <linux/of_gpio.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/gpio.h> | ||
| 22 | |||
| 23 | /* Register Offset Definitions */ | ||
| 24 | #define XGPIO_DATA_OFFSET (0x0) /* Data register */ | ||
| 25 | #define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ | ||
| 26 | |||
| 27 | struct xgpio_instance { | ||
| 28 | struct of_mm_gpio_chip mmchip; | ||
| 29 | u32 gpio_state; /* GPIO state shadow register */ | ||
| 30 | u32 gpio_dir; /* GPIO direction shadow register */ | ||
| 31 | spinlock_t gpio_lock; /* Lock used for synchronization */ | ||
| 32 | }; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * xgpio_get - Read the specified signal of the GPIO device. | ||
| 36 | * @gc: Pointer to gpio_chip device structure. | ||
| 37 | * @gpio: GPIO signal number. | ||
| 38 | * | ||
| 39 | * This function reads the specified signal of the GPIO device. It returns 0 if | ||
| 40 | * the signal clear, 1 if signal is set or negative value on error. | ||
| 41 | */ | ||
| 42 | static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
| 43 | { | ||
| 44 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 45 | |||
| 46 | return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1; | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * xgpio_set - Write the specified signal of the GPIO device. | ||
| 51 | * @gc: Pointer to gpio_chip device structure. | ||
| 52 | * @gpio: GPIO signal number. | ||
| 53 | * @val: Value to be written to specified signal. | ||
| 54 | * | ||
| 55 | * This function writes the specified value in to the specified signal of the | ||
| 56 | * GPIO device. | ||
| 57 | */ | ||
| 58 | static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
| 59 | { | ||
| 60 | unsigned long flags; | ||
| 61 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 62 | struct xgpio_instance *chip = | ||
| 63 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
| 64 | |||
| 65 | spin_lock_irqsave(&chip->gpio_lock, flags); | ||
| 66 | |||
| 67 | /* Write to GPIO signal and set its direction to output */ | ||
| 68 | if (val) | ||
| 69 | chip->gpio_state |= 1 << gpio; | ||
| 70 | else | ||
| 71 | chip->gpio_state &= ~(1 << gpio); | ||
| 72 | out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); | ||
| 73 | |||
| 74 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * xgpio_dir_in - Set the direction of the specified GPIO signal as input. | ||
| 79 | * @gc: Pointer to gpio_chip device structure. | ||
| 80 | * @gpio: GPIO signal number. | ||
| 81 | * | ||
| 82 | * This function sets the direction of specified GPIO signal as input. | ||
| 83 | * It returns 0 if direction of GPIO signals is set as input otherwise it | ||
| 84 | * returns negative error value. | ||
| 85 | */ | ||
| 86 | static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
| 87 | { | ||
| 88 | unsigned long flags; | ||
| 89 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 90 | struct xgpio_instance *chip = | ||
| 91 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
| 92 | |||
| 93 | spin_lock_irqsave(&chip->gpio_lock, flags); | ||
| 94 | |||
| 95 | /* Set the GPIO bit in shadow register and set direction as input */ | ||
| 96 | chip->gpio_dir |= (1 << gpio); | ||
| 97 | out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | ||
| 98 | |||
| 99 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * xgpio_dir_out - Set the direction of the specified GPIO signal as output. | ||
| 106 | * @gc: Pointer to gpio_chip device structure. | ||
| 107 | * @gpio: GPIO signal number. | ||
| 108 | * @val: Value to be written to specified signal. | ||
| 109 | * | ||
| 110 | * This function sets the direction of specified GPIO signal as output. If all | ||
| 111 | * GPIO signals of GPIO chip is configured as input then it returns | ||
| 112 | * error otherwise it returns 0. | ||
| 113 | */ | ||
| 114 | static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
| 115 | { | ||
| 116 | unsigned long flags; | ||
| 117 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
| 118 | struct xgpio_instance *chip = | ||
| 119 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
| 120 | |||
| 121 | spin_lock_irqsave(&chip->gpio_lock, flags); | ||
| 122 | |||
| 123 | /* Write state of GPIO signal */ | ||
| 124 | if (val) | ||
| 125 | chip->gpio_state |= 1 << gpio; | ||
| 126 | else | ||
| 127 | chip->gpio_state &= ~(1 << gpio); | ||
| 128 | out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); | ||
| 129 | |||
| 130 | /* Clear the GPIO bit in shadow register and set direction as output */ | ||
| 131 | chip->gpio_dir &= (~(1 << gpio)); | ||
| 132 | out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | ||
| 133 | |||
| 134 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * xgpio_save_regs - Set initial values of GPIO pins | ||
| 141 | * @mm_gc: pointer to memory mapped GPIO chip structure | ||
| 142 | */ | ||
| 143 | static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) | ||
| 144 | { | ||
| 145 | struct xgpio_instance *chip = | ||
| 146 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
| 147 | |||
| 148 | out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); | ||
| 149 | out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | ||
| 150 | } | ||
| 151 | |||
| 152 | /** | ||
| 153 | * xgpio_of_probe - Probe method for the GPIO device. | ||
| 154 | * @np: pointer to device tree node | ||
| 155 | * | ||
| 156 | * This function probes the GPIO device in the device tree. It initializes the | ||
| 157 | * driver data structure. It returns 0, if the driver is bound to the GPIO | ||
| 158 | * device, or a negative value if there is an error. | ||
| 159 | */ | ||
| 160 | static int __devinit xgpio_of_probe(struct device_node *np) | ||
| 161 | { | ||
| 162 | struct xgpio_instance *chip; | ||
| 163 | struct of_gpio_chip *ofchip; | ||
| 164 | int status = 0; | ||
| 165 | const u32 *tree_info; | ||
| 166 | |||
| 167 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
| 168 | if (!chip) | ||
| 169 | return -ENOMEM; | ||
| 170 | ofchip = &chip->mmchip.of_gc; | ||
| 171 | |||
| 172 | /* Update GPIO state shadow register with default value */ | ||
| 173 | tree_info = of_get_property(np, "xlnx,dout-default", NULL); | ||
| 174 | if (tree_info) | ||
| 175 | chip->gpio_state = *tree_info; | ||
| 176 | |||
| 177 | /* Update GPIO direction shadow register with default value */ | ||
| 178 | chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */ | ||
| 179 | tree_info = of_get_property(np, "xlnx,tri-default", NULL); | ||
| 180 | if (tree_info) | ||
| 181 | chip->gpio_dir = *tree_info; | ||
| 182 | |||
| 183 | /* Check device node and parent device node for device width */ | ||
| 184 | ofchip->gc.ngpio = 32; /* By default assume full GPIO controller */ | ||
| 185 | tree_info = of_get_property(np, "xlnx,gpio-width", NULL); | ||
| 186 | if (!tree_info) | ||
| 187 | tree_info = of_get_property(np->parent, | ||
| 188 | "xlnx,gpio-width", NULL); | ||
| 189 | if (tree_info) | ||
| 190 | ofchip->gc.ngpio = *tree_info; | ||
| 191 | |||
| 192 | spin_lock_init(&chip->gpio_lock); | ||
| 193 | |||
| 194 | ofchip->gpio_cells = 2; | ||
| 195 | ofchip->gc.direction_input = xgpio_dir_in; | ||
| 196 | ofchip->gc.direction_output = xgpio_dir_out; | ||
| 197 | ofchip->gc.get = xgpio_get; | ||
| 198 | ofchip->gc.set = xgpio_set; | ||
| 199 | |||
| 200 | chip->mmchip.save_regs = xgpio_save_regs; | ||
| 201 | |||
| 202 | /* Call the OF gpio helper to setup and register the GPIO device */ | ||
| 203 | status = of_mm_gpiochip_add(np, &chip->mmchip); | ||
| 204 | if (status) { | ||
| 205 | kfree(chip); | ||
| 206 | pr_err("%s: error in probe function with status %d\n", | ||
| 207 | np->full_name, status); | ||
| 208 | return status; | ||
| 209 | } | ||
| 210 | pr_info("XGpio: %s: registered\n", np->full_name); | ||
| 211 | return 0; | ||
| 212 | } | ||
| 213 | |||
| 214 | static struct of_device_id xgpio_of_match[] __devinitdata = { | ||
| 215 | { .compatible = "xlnx,xps-gpio-1.00.a", }, | ||
| 216 | { /* end of list */ }, | ||
| 217 | }; | ||
| 218 | |||
| 219 | static int __init xgpio_init(void) | ||
| 220 | { | ||
| 221 | struct device_node *np; | ||
| 222 | |||
| 223 | for_each_matching_node(np, xgpio_of_match) | ||
| 224 | xgpio_of_probe(np); | ||
| 225 | |||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | |||
| 229 | /* Make sure we get initialized before anyone else tries to use us */ | ||
| 230 | subsys_initcall(xgpio_init); | ||
| 231 | /* No exit call at the moment as we cannot unregister of GPIO chips */ | ||
| 232 | |||
| 233 | MODULE_AUTHOR("Xilinx, Inc."); | ||
| 234 | MODULE_DESCRIPTION("Xilinx GPIO driver"); | ||
| 235 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 96f416afc3f6..996097acb5e7 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -266,11 +266,19 @@ int drm_init(struct drm_driver *driver) | |||
| 266 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { | 266 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { |
| 267 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; | 267 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; |
| 268 | 268 | ||
| 269 | /* Loop around setting up a DRM device for each PCI device | ||
| 270 | * matching our ID and device class. If we had the internal | ||
| 271 | * function that pci_get_subsys and pci_get_class used, we'd | ||
| 272 | * be able to just pass pid in instead of doing a two-stage | ||
| 273 | * thing. | ||
| 274 | */ | ||
| 269 | pdev = NULL; | 275 | pdev = NULL; |
| 270 | /* pass back in pdev to account for multiple identical cards */ | ||
| 271 | while ((pdev = | 276 | while ((pdev = |
| 272 | pci_get_subsys(pid->vendor, pid->device, pid->subvendor, | 277 | pci_get_subsys(pid->vendor, pid->device, pid->subvendor, |
| 273 | pid->subdevice, pdev)) != NULL) { | 278 | pid->subdevice, pdev)) != NULL) { |
| 279 | if ((pdev->class & pid->class_mask) != pid->class) | ||
| 280 | continue; | ||
| 281 | |||
| 274 | /* stealth mode requires a manual probe */ | 282 | /* stealth mode requires a manual probe */ |
| 275 | pci_dev_get(pdev); | 283 | pci_dev_get(pdev); |
| 276 | drm_get_dev(pdev, pid, driver); | 284 | drm_get_dev(pdev, pid, driver); |
| @@ -297,6 +305,8 @@ static void drm_cleanup(struct drm_device * dev) | |||
| 297 | return; | 305 | return; |
| 298 | } | 306 | } |
| 299 | 307 | ||
| 308 | drm_vblank_cleanup(dev); | ||
| 309 | |||
| 300 | drm_lastclose(dev); | 310 | drm_lastclose(dev); |
| 301 | 311 | ||
| 302 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && | 312 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 0d46627663b1..78eeed5caaff 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -406,8 +406,6 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 406 | if (dev->driver->driver_features & DRIVER_GEM) | 406 | if (dev->driver->driver_features & DRIVER_GEM) |
| 407 | drm_gem_release(dev, file_priv); | 407 | drm_gem_release(dev, file_priv); |
| 408 | 408 | ||
| 409 | drm_fasync(-1, filp, 0); | ||
| 410 | |||
| 411 | mutex_lock(&dev->ctxlist_mutex); | 409 | mutex_lock(&dev->ctxlist_mutex); |
| 412 | if (!list_empty(&dev->ctxlist)) { | 410 | if (!list_empty(&dev->ctxlist)) { |
| 413 | struct drm_ctx_list *pos, *n; | 411 | struct drm_ctx_list *pos, *n; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 212a94f715b2..1e787f894b3c 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -94,7 +94,7 @@ static void vblank_disable_fn(unsigned long arg) | |||
| 94 | } | 94 | } |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static void drm_vblank_cleanup(struct drm_device *dev) | 97 | void drm_vblank_cleanup(struct drm_device *dev) |
| 98 | { | 98 | { |
| 99 | /* Bail if the driver didn't call drm_vblank_init() */ | 99 | /* Bail if the driver didn't call drm_vblank_init() */ |
| 100 | if (dev->num_crtcs == 0) | 100 | if (dev->num_crtcs == 0) |
| @@ -278,10 +278,6 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
| 278 | 278 | ||
| 279 | free_irq(dev->pdev->irq, dev); | 279 | free_irq(dev->pdev->irq, dev); |
| 280 | 280 | ||
| 281 | drm_vblank_cleanup(dev); | ||
| 282 | |||
| 283 | dev->locked_tasklet_func = NULL; | ||
| 284 | |||
| 285 | return 0; | 281 | return 0; |
| 286 | } | 282 | } |
| 287 | EXPORT_SYMBOL(drm_irq_uninstall); | 283 | EXPORT_SYMBOL(drm_irq_uninstall); |
| @@ -699,81 +695,3 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
| 699 | drm_vbl_send_signals(dev, crtc); | 695 | drm_vbl_send_signals(dev, crtc); |
| 700 | } | 696 | } |
| 701 | EXPORT_SYMBOL(drm_handle_vblank); | 697 | EXPORT_SYMBOL(drm_handle_vblank); |
| 702 | |||
| 703 | /** | ||
| 704 | * Tasklet wrapper function. | ||
| 705 | * | ||
| 706 | * \param data DRM device in disguise. | ||
| 707 | * | ||
| 708 | * Attempts to grab the HW lock and calls the driver callback on success. On | ||
| 709 | * failure, leave the lock marked as contended so the callback can be called | ||
| 710 | * from drm_unlock(). | ||
| 711 | */ | ||
| 712 | static void drm_locked_tasklet_func(unsigned long data) | ||
| 713 | { | ||
| 714 | struct drm_device *dev = (struct drm_device *)data; | ||
| 715 | unsigned long irqflags; | ||
| 716 | void (*tasklet_func)(struct drm_device *); | ||
| 717 | |||
| 718 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 719 | tasklet_func = dev->locked_tasklet_func; | ||
| 720 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 721 | |||
| 722 | if (!tasklet_func || | ||
| 723 | !drm_lock_take(&dev->lock, | ||
| 724 | DRM_KERNEL_CONTEXT)) { | ||
| 725 | return; | ||
| 726 | } | ||
| 727 | |||
| 728 | dev->lock.lock_time = jiffies; | ||
| 729 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
| 730 | |||
| 731 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 732 | tasklet_func = dev->locked_tasklet_func; | ||
| 733 | dev->locked_tasklet_func = NULL; | ||
| 734 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 735 | |||
| 736 | if (tasklet_func != NULL) | ||
| 737 | tasklet_func(dev); | ||
| 738 | |||
| 739 | drm_lock_free(&dev->lock, | ||
| 740 | DRM_KERNEL_CONTEXT); | ||
| 741 | } | ||
| 742 | |||
| 743 | /** | ||
| 744 | * Schedule a tasklet to call back a driver hook with the HW lock held. | ||
| 745 | * | ||
| 746 | * \param dev DRM device. | ||
| 747 | * \param func Driver callback. | ||
| 748 | * | ||
| 749 | * This is intended for triggering actions that require the HW lock from an | ||
| 750 | * interrupt handler. The lock will be grabbed ASAP after the interrupt handler | ||
| 751 | * completes. Note that the callback may be called from interrupt or process | ||
| 752 | * context, it must not make any assumptions about this. Also, the HW lock will | ||
| 753 | * be held with the kernel context or any client context. | ||
| 754 | */ | ||
| 755 | void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device *)) | ||
| 756 | { | ||
| 757 | unsigned long irqflags; | ||
| 758 | static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0); | ||
| 759 | |||
| 760 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) || | ||
| 761 | test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state)) | ||
| 762 | return; | ||
| 763 | |||
| 764 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 765 | |||
| 766 | if (dev->locked_tasklet_func) { | ||
| 767 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 768 | return; | ||
| 769 | } | ||
| 770 | |||
| 771 | dev->locked_tasklet_func = func; | ||
| 772 | |||
| 773 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 774 | |||
| 775 | drm_tasklet.data = (unsigned long)dev; | ||
| 776 | |||
| 777 | tasklet_hi_schedule(&drm_tasklet); | ||
| 778 | } | ||
| 779 | EXPORT_SYMBOL(drm_locked_tasklet); | ||
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 888159e03d26..1cfa72031f8f 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
| @@ -154,8 +154,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
| 154 | int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | 154 | int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) |
| 155 | { | 155 | { |
| 156 | struct drm_lock *lock = data; | 156 | struct drm_lock *lock = data; |
| 157 | unsigned long irqflags; | ||
| 158 | void (*tasklet_func)(struct drm_device *); | ||
| 159 | 157 | ||
| 160 | if (lock->context == DRM_KERNEL_CONTEXT) { | 158 | if (lock->context == DRM_KERNEL_CONTEXT) { |
| 161 | DRM_ERROR("Process %d using kernel context %d\n", | 159 | DRM_ERROR("Process %d using kernel context %d\n", |
| @@ -163,13 +161,6 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
| 163 | return -EINVAL; | 161 | return -EINVAL; |
| 164 | } | 162 | } |
| 165 | 163 | ||
| 166 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 167 | tasklet_func = dev->locked_tasklet_func; | ||
| 168 | dev->locked_tasklet_func = NULL; | ||
| 169 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 170 | if (tasklet_func != NULL) | ||
| 171 | tasklet_func(dev); | ||
| 172 | |||
| 173 | atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); | 164 | atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); |
| 174 | 165 | ||
| 175 | /* kernel_context_switch isn't used by any of the x86 drm | 166 | /* kernel_context_switch isn't used by any of the x86 drm |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 141e33004a76..66c96ec66672 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
| @@ -92,7 +92,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
| 92 | 92 | ||
| 93 | spin_lock_init(&dev->count_lock); | 93 | spin_lock_init(&dev->count_lock); |
| 94 | spin_lock_init(&dev->drw_lock); | 94 | spin_lock_init(&dev->drw_lock); |
| 95 | spin_lock_init(&dev->tasklet_lock); | ||
| 96 | spin_lock_init(&dev->lock.spinlock); | 95 | spin_lock_init(&dev->lock.spinlock); |
| 97 | init_timer(&dev->timer); | 96 | init_timer(&dev->timer); |
| 98 | mutex_init(&dev->struct_mutex); | 97 | mutex_init(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 5ba78e4fd2b5..d8fb5d8ee7ea 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
| @@ -3,13 +3,14 @@ | |||
| 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
| 4 | 4 | ||
| 5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
| 6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \ | 6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ |
| 7 | i915_suspend.o \ | 7 | i915_suspend.o \ |
| 8 | i915_gem.o \ | 8 | i915_gem.o \ |
| 9 | i915_gem_debug.o \ | 9 | i915_gem_debug.o \ |
| 10 | i915_gem_proc.o \ | 10 | i915_gem_proc.o \ |
| 11 | i915_gem_tiling.o | 11 | i915_gem_tiling.o |
| 12 | 12 | ||
| 13 | i915-$(CONFIG_ACPI) += i915_opregion.o | ||
| 13 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 14 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
| 14 | 15 | ||
| 15 | obj-$(CONFIG_DRM_I915) += i915.o | 16 | obj-$(CONFIG_DRM_I915) += i915.o |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 01de536e0211..553dd4bc3075 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -154,6 +154,9 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
| 154 | if (I915_NEED_GFX_HWS(dev)) | 154 | if (I915_NEED_GFX_HWS(dev)) |
| 155 | i915_free_hws(dev); | 155 | i915_free_hws(dev); |
| 156 | 156 | ||
| 157 | dev_priv->sarea = NULL; | ||
| 158 | dev_priv->sarea_priv = NULL; | ||
| 159 | |||
| 157 | return 0; | 160 | return 0; |
| 158 | } | 161 | } |
| 159 | 162 | ||
| @@ -442,7 +445,7 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
| 442 | 445 | ||
| 443 | BEGIN_LP_RING(4); | 446 | BEGIN_LP_RING(4); |
| 444 | OUT_RING(MI_STORE_DWORD_INDEX); | 447 | OUT_RING(MI_STORE_DWORD_INDEX); |
| 445 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); | 448 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
| 446 | OUT_RING(dev_priv->counter); | 449 | OUT_RING(dev_priv->counter); |
| 447 | OUT_RING(0); | 450 | OUT_RING(0); |
| 448 | ADVANCE_LP_RING(); | 451 | ADVANCE_LP_RING(); |
| @@ -573,7 +576,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
| 573 | 576 | ||
| 574 | BEGIN_LP_RING(4); | 577 | BEGIN_LP_RING(4); |
| 575 | OUT_RING(MI_STORE_DWORD_INDEX); | 578 | OUT_RING(MI_STORE_DWORD_INDEX); |
| 576 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); | 579 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
| 577 | OUT_RING(dev_priv->counter); | 580 | OUT_RING(dev_priv->counter); |
| 578 | OUT_RING(0); | 581 | OUT_RING(0); |
| 579 | ADVANCE_LP_RING(); | 582 | ADVANCE_LP_RING(); |
| @@ -608,7 +611,6 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
| 608 | struct drm_file *file_priv) | 611 | struct drm_file *file_priv) |
| 609 | { | 612 | { |
| 610 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 613 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 611 | u32 *hw_status = dev_priv->hw_status_page; | ||
| 612 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 614 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
| 613 | dev_priv->sarea_priv; | 615 | dev_priv->sarea_priv; |
| 614 | drm_i915_batchbuffer_t *batch = data; | 616 | drm_i915_batchbuffer_t *batch = data; |
| @@ -634,7 +636,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
| 634 | mutex_unlock(&dev->struct_mutex); | 636 | mutex_unlock(&dev->struct_mutex); |
| 635 | 637 | ||
| 636 | if (sarea_priv) | 638 | if (sarea_priv) |
| 637 | sarea_priv->last_dispatch = (int)hw_status[5]; | 639 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
| 638 | return ret; | 640 | return ret; |
| 639 | } | 641 | } |
| 640 | 642 | ||
| @@ -642,7 +644,6 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 642 | struct drm_file *file_priv) | 644 | struct drm_file *file_priv) |
| 643 | { | 645 | { |
| 644 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 646 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 645 | u32 *hw_status = dev_priv->hw_status_page; | ||
| 646 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 647 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
| 647 | dev_priv->sarea_priv; | 648 | dev_priv->sarea_priv; |
| 648 | drm_i915_cmdbuffer_t *cmdbuf = data; | 649 | drm_i915_cmdbuffer_t *cmdbuf = data; |
| @@ -670,7 +671,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 670 | } | 671 | } |
| 671 | 672 | ||
| 672 | if (sarea_priv) | 673 | if (sarea_priv) |
| 673 | sarea_priv->last_dispatch = (int)hw_status[5]; | 674 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
| 674 | return 0; | 675 | return 0; |
| 675 | } | 676 | } |
| 676 | 677 | ||
| @@ -846,16 +847,23 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 846 | * and the registers being closely associated. | 847 | * and the registers being closely associated. |
| 847 | * | 848 | * |
| 848 | * According to chipset errata, on the 965GM, MSI interrupts may | 849 | * According to chipset errata, on the 965GM, MSI interrupts may |
| 849 | * be lost or delayed | 850 | * be lost or delayed, but we use them anyways to avoid |
| 851 | * stuck interrupts on some machines. | ||
| 850 | */ | 852 | */ |
| 851 | if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev)) | 853 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
| 852 | if (pci_enable_msi(dev->pdev)) | 854 | pci_enable_msi(dev->pdev); |
| 853 | DRM_ERROR("failed to enable MSI\n"); | ||
| 854 | 855 | ||
| 855 | intel_opregion_init(dev); | 856 | intel_opregion_init(dev); |
| 856 | 857 | ||
| 857 | spin_lock_init(&dev_priv->user_irq_lock); | 858 | spin_lock_init(&dev_priv->user_irq_lock); |
| 858 | 859 | ||
| 860 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | ||
| 861 | |||
| 862 | if (ret) { | ||
| 863 | (void) i915_driver_unload(dev); | ||
| 864 | return ret; | ||
| 865 | } | ||
| 866 | |||
| 859 | return ret; | 867 | return ret; |
| 860 | } | 868 | } |
| 861 | 869 | ||
| @@ -960,6 +968,7 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
| 960 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), | 968 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), |
| 961 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), | 969 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), |
| 962 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), | 970 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), |
| 971 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), | ||
| 963 | }; | 972 | }; |
| 964 | 973 | ||
| 965 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 974 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f20ffe17df71..adc972cc6bfc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #define _I915_DRV_H_ | 31 | #define _I915_DRV_H_ |
| 32 | 32 | ||
| 33 | #include "i915_reg.h" | 33 | #include "i915_reg.h" |
| 34 | #include <linux/io-mapping.h> | ||
| 34 | 35 | ||
| 35 | /* General customization: | 36 | /* General customization: |
| 36 | */ | 37 | */ |
| @@ -46,6 +47,8 @@ enum pipe { | |||
| 46 | PIPE_B, | 47 | PIPE_B, |
| 47 | }; | 48 | }; |
| 48 | 49 | ||
| 50 | #define I915_NUM_PIPE 2 | ||
| 51 | |||
| 49 | /* Interface history: | 52 | /* Interface history: |
| 50 | * | 53 | * |
| 51 | * 1.1: Original. | 54 | * 1.1: Original. |
| @@ -87,13 +90,6 @@ struct mem_block { | |||
| 87 | struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ | 90 | struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ |
| 88 | }; | 91 | }; |
| 89 | 92 | ||
| 90 | typedef struct _drm_i915_vbl_swap { | ||
| 91 | struct list_head head; | ||
| 92 | drm_drawable_t drw_id; | ||
| 93 | unsigned int pipe; | ||
| 94 | unsigned int sequence; | ||
| 95 | } drm_i915_vbl_swap_t; | ||
| 96 | |||
| 97 | struct opregion_header; | 93 | struct opregion_header; |
| 98 | struct opregion_acpi; | 94 | struct opregion_acpi; |
| 99 | struct opregion_swsci; | 95 | struct opregion_swsci; |
| @@ -138,6 +134,7 @@ typedef struct drm_i915_private { | |||
| 138 | int user_irq_refcount; | 134 | int user_irq_refcount; |
| 139 | /** Cached value of IMR to avoid reads in updating the bitfield */ | 135 | /** Cached value of IMR to avoid reads in updating the bitfield */ |
| 140 | u32 irq_mask_reg; | 136 | u32 irq_mask_reg; |
| 137 | u32 pipestat[2]; | ||
| 141 | 138 | ||
| 142 | int tex_lru_log_granularity; | 139 | int tex_lru_log_granularity; |
| 143 | int allow_batchbuffer; | 140 | int allow_batchbuffer; |
| @@ -145,10 +142,6 @@ typedef struct drm_i915_private { | |||
| 145 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 142 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
| 146 | int vblank_pipe; | 143 | int vblank_pipe; |
| 147 | 144 | ||
| 148 | spinlock_t swaps_lock; | ||
| 149 | drm_i915_vbl_swap_t vbl_swaps; | ||
| 150 | unsigned int swaps_pending; | ||
| 151 | |||
| 152 | struct intel_opregion opregion; | 145 | struct intel_opregion opregion; |
| 153 | 146 | ||
| 154 | /* Register state */ | 147 | /* Register state */ |
| @@ -156,6 +149,8 @@ typedef struct drm_i915_private { | |||
| 156 | u32 saveDSPACNTR; | 149 | u32 saveDSPACNTR; |
| 157 | u32 saveDSPBCNTR; | 150 | u32 saveDSPBCNTR; |
| 158 | u32 saveDSPARB; | 151 | u32 saveDSPARB; |
| 152 | u32 saveRENDERSTANDBY; | ||
| 153 | u32 saveHWS; | ||
| 159 | u32 savePIPEACONF; | 154 | u32 savePIPEACONF; |
| 160 | u32 savePIPEBCONF; | 155 | u32 savePIPEBCONF; |
| 161 | u32 savePIPEASRC; | 156 | u32 savePIPEASRC; |
| @@ -240,16 +235,19 @@ typedef struct drm_i915_private { | |||
| 240 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ | 235 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ |
| 241 | u8 saveCR[37]; | 236 | u8 saveCR[37]; |
| 242 | 237 | ||
| 243 | /** Work task for vblank-related ring access */ | ||
| 244 | struct work_struct vblank_work; | ||
| 245 | |||
| 246 | struct { | 238 | struct { |
| 247 | struct drm_mm gtt_space; | 239 | struct drm_mm gtt_space; |
| 248 | 240 | ||
| 241 | struct io_mapping *gtt_mapping; | ||
| 242 | |||
| 249 | /** | 243 | /** |
| 250 | * List of objects currently involved in rendering from the | 244 | * List of objects currently involved in rendering from the |
| 251 | * ringbuffer. | 245 | * ringbuffer. |
| 252 | * | 246 | * |
| 247 | * Includes buffers having the contents of their GPU caches | ||
| 248 | * flushed, not necessarily primitives. last_rendering_seqno | ||
| 249 | * represents when the rendering involved will be completed. | ||
| 250 | * | ||
| 253 | * A reference is held on the buffer while on this list. | 251 | * A reference is held on the buffer while on this list. |
| 254 | */ | 252 | */ |
| 255 | struct list_head active_list; | 253 | struct list_head active_list; |
| @@ -259,6 +257,8 @@ typedef struct drm_i915_private { | |||
| 259 | * still have a write_domain which needs to be flushed before | 257 | * still have a write_domain which needs to be flushed before |
| 260 | * unbinding. | 258 | * unbinding. |
| 261 | * | 259 | * |
| 260 | * last_rendering_seqno is 0 while an object is in this list. | ||
| 261 | * | ||
| 262 | * A reference is held on the buffer while on this list. | 262 | * A reference is held on the buffer while on this list. |
| 263 | */ | 263 | */ |
| 264 | struct list_head flushing_list; | 264 | struct list_head flushing_list; |
| @@ -267,6 +267,8 @@ typedef struct drm_i915_private { | |||
| 267 | * LRU list of objects which are not in the ringbuffer and | 267 | * LRU list of objects which are not in the ringbuffer and |
| 268 | * are ready to unbind, but are still in the GTT. | 268 | * are ready to unbind, but are still in the GTT. |
| 269 | * | 269 | * |
| 270 | * last_rendering_seqno is 0 while an object is in this list. | ||
| 271 | * | ||
| 270 | * A reference is not held on the buffer while on this list, | 272 | * A reference is not held on the buffer while on this list, |
| 271 | * as merely being GTT-bound shouldn't prevent its being | 273 | * as merely being GTT-bound shouldn't prevent its being |
| 272 | * freed, and we'll pull it off the list in the free path. | 274 | * freed, and we'll pull it off the list in the free path. |
| @@ -377,8 +379,8 @@ struct drm_i915_gem_object { | |||
| 377 | uint32_t agp_type; | 379 | uint32_t agp_type; |
| 378 | 380 | ||
| 379 | /** | 381 | /** |
| 380 | * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when | 382 | * If present, while GEM_DOMAIN_CPU is in the read domain this array |
| 381 | * GEM_DOMAIN_CPU is not in the object's read domain. | 383 | * flags which individual pages are valid. |
| 382 | */ | 384 | */ |
| 383 | uint8_t *page_cpu_valid; | 385 | uint8_t *page_cpu_valid; |
| 384 | }; | 386 | }; |
| @@ -400,9 +402,6 @@ struct drm_i915_gem_request { | |||
| 400 | /** Time at which this request was emitted, in jiffies. */ | 402 | /** Time at which this request was emitted, in jiffies. */ |
| 401 | unsigned long emitted_jiffies; | 403 | unsigned long emitted_jiffies; |
| 402 | 404 | ||
| 403 | /** Cache domains that were flushed at the start of the request. */ | ||
| 404 | uint32_t flush_domains; | ||
| 405 | |||
| 406 | struct list_head list; | 405 | struct list_head list; |
| 407 | }; | 406 | }; |
| 408 | 407 | ||
| @@ -441,7 +440,6 @@ extern int i915_irq_wait(struct drm_device *dev, void *data, | |||
| 441 | void i915_user_irq_get(struct drm_device *dev); | 440 | void i915_user_irq_get(struct drm_device *dev); |
| 442 | void i915_user_irq_put(struct drm_device *dev); | 441 | void i915_user_irq_put(struct drm_device *dev); |
| 443 | 442 | ||
| 444 | extern void i915_vblank_work_handler(struct work_struct *work); | ||
| 445 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 443 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
| 446 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | 444 | extern void i915_driver_irq_preinstall(struct drm_device * dev); |
| 447 | extern int i915_driver_irq_postinstall(struct drm_device *dev); | 445 | extern int i915_driver_irq_postinstall(struct drm_device *dev); |
| @@ -457,6 +455,13 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data, | |||
| 457 | struct drm_file *file_priv); | 455 | struct drm_file *file_priv); |
| 458 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); | 456 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); |
| 459 | 457 | ||
| 458 | void | ||
| 459 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | ||
| 460 | |||
| 461 | void | ||
| 462 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | ||
| 463 | |||
| 464 | |||
| 460 | /* i915_mem.c */ | 465 | /* i915_mem.c */ |
| 461 | extern int i915_mem_alloc(struct drm_device *dev, void *data, | 466 | extern int i915_mem_alloc(struct drm_device *dev, void *data, |
| 462 | struct drm_file *file_priv); | 467 | struct drm_file *file_priv); |
| @@ -502,6 +507,8 @@ int i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 502 | struct drm_file *file_priv); | 507 | struct drm_file *file_priv); |
| 503 | int i915_gem_get_tiling(struct drm_device *dev, void *data, | 508 | int i915_gem_get_tiling(struct drm_device *dev, void *data, |
| 504 | struct drm_file *file_priv); | 509 | struct drm_file *file_priv); |
| 510 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | ||
| 511 | struct drm_file *file_priv); | ||
| 505 | void i915_gem_load(struct drm_device *dev); | 512 | void i915_gem_load(struct drm_device *dev); |
| 506 | int i915_gem_proc_init(struct drm_minor *minor); | 513 | int i915_gem_proc_init(struct drm_minor *minor); |
| 507 | void i915_gem_proc_cleanup(struct drm_minor *minor); | 514 | void i915_gem_proc_cleanup(struct drm_minor *minor); |
| @@ -539,11 +546,18 @@ extern int i915_restore_state(struct drm_device *dev); | |||
| 539 | extern int i915_save_state(struct drm_device *dev); | 546 | extern int i915_save_state(struct drm_device *dev); |
| 540 | extern int i915_restore_state(struct drm_device *dev); | 547 | extern int i915_restore_state(struct drm_device *dev); |
| 541 | 548 | ||
| 549 | #ifdef CONFIG_ACPI | ||
| 542 | /* i915_opregion.c */ | 550 | /* i915_opregion.c */ |
| 543 | extern int intel_opregion_init(struct drm_device *dev); | 551 | extern int intel_opregion_init(struct drm_device *dev); |
| 544 | extern void intel_opregion_free(struct drm_device *dev); | 552 | extern void intel_opregion_free(struct drm_device *dev); |
| 545 | extern void opregion_asle_intr(struct drm_device *dev); | 553 | extern void opregion_asle_intr(struct drm_device *dev); |
| 546 | extern void opregion_enable_asle(struct drm_device *dev); | 554 | extern void opregion_enable_asle(struct drm_device *dev); |
| 555 | #else | ||
| 556 | static inline int intel_opregion_init(struct drm_device *dev) { return 0; } | ||
| 557 | static inline void intel_opregion_free(struct drm_device *dev) { return; } | ||
| 558 | static inline void opregion_asle_intr(struct drm_device *dev) { return; } | ||
| 559 | static inline void opregion_enable_asle(struct drm_device *dev) { return; } | ||
| 560 | #endif | ||
| 547 | 561 | ||
| 548 | /** | 562 | /** |
| 549 | * Lock test for when it's just for synchronization of ring access. | 563 | * Lock test for when it's just for synchronization of ring access. |
| @@ -610,8 +624,9 @@ extern void opregion_enable_asle(struct drm_device *dev); | |||
| 610 | * The area from dword 0x20 to 0x3ff is available for driver usage. | 624 | * The area from dword 0x20 to 0x3ff is available for driver usage. |
| 611 | */ | 625 | */ |
| 612 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) | 626 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) |
| 613 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5) | 627 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) |
| 614 | #define I915_GEM_HWS_INDEX 0x20 | 628 | #define I915_GEM_HWS_INDEX 0x20 |
| 629 | #define I915_BREADCRUMB_INDEX 0x21 | ||
| 615 | 630 | ||
| 616 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | 631 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); |
| 617 | 632 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 17ae330ff269..ad672d854828 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -31,21 +31,23 @@ | |||
| 31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
| 32 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
| 33 | 33 | ||
| 34 | static int | 34 | #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) |
| 35 | i915_gem_object_set_domain(struct drm_gem_object *obj, | 35 | |
| 36 | uint32_t read_domains, | 36 | static void |
| 37 | uint32_t write_domain); | 37 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, |
| 38 | static int | 38 | uint32_t read_domains, |
| 39 | i915_gem_object_set_domain_range(struct drm_gem_object *obj, | 39 | uint32_t write_domain); |
| 40 | uint64_t offset, | 40 | static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
| 41 | uint64_t size, | 41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
| 42 | uint32_t read_domains, | 42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
| 43 | uint32_t write_domain); | 43 | static int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
| 44 | static int | 44 | int write); |
| 45 | i915_gem_set_domain(struct drm_gem_object *obj, | 45 | static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, |
| 46 | struct drm_file *file_priv, | 46 | int write); |
| 47 | uint32_t read_domains, | 47 | static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, |
| 48 | uint32_t write_domain); | 48 | uint64_t offset, |
| 49 | uint64_t size); | ||
| 50 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); | ||
| 49 | static int i915_gem_object_get_page_list(struct drm_gem_object *obj); | 51 | static int i915_gem_object_get_page_list(struct drm_gem_object *obj); |
| 50 | static void i915_gem_object_free_page_list(struct drm_gem_object *obj); | 52 | static void i915_gem_object_free_page_list(struct drm_gem_object *obj); |
| 51 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | 53 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); |
| @@ -79,6 +81,22 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data, | |||
| 79 | return 0; | 81 | return 0; |
| 80 | } | 82 | } |
| 81 | 83 | ||
| 84 | int | ||
| 85 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | ||
| 86 | struct drm_file *file_priv) | ||
| 87 | { | ||
| 88 | struct drm_i915_gem_get_aperture *args = data; | ||
| 89 | |||
| 90 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
| 91 | return -ENODEV; | ||
| 92 | |||
| 93 | args->aper_size = dev->gtt_total; | ||
| 94 | args->aper_available_size = (args->aper_size - | ||
| 95 | atomic_read(&dev->pin_memory)); | ||
| 96 | |||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 82 | 100 | ||
| 83 | /** | 101 | /** |
| 84 | * Creates a new mm object and returns a handle to it. | 102 | * Creates a new mm object and returns a handle to it. |
| @@ -144,8 +162,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 144 | 162 | ||
| 145 | mutex_lock(&dev->struct_mutex); | 163 | mutex_lock(&dev->struct_mutex); |
| 146 | 164 | ||
| 147 | ret = i915_gem_object_set_domain_range(obj, args->offset, args->size, | 165 | ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset, |
| 148 | I915_GEM_DOMAIN_CPU, 0); | 166 | args->size); |
| 149 | if (ret != 0) { | 167 | if (ret != 0) { |
| 150 | drm_gem_object_unreference(obj); | 168 | drm_gem_object_unreference(obj); |
| 151 | mutex_unlock(&dev->struct_mutex); | 169 | mutex_unlock(&dev->struct_mutex); |
| @@ -171,35 +189,50 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 171 | return 0; | 189 | return 0; |
| 172 | } | 190 | } |
| 173 | 191 | ||
| 174 | /* | 192 | /* This is the fast write path which cannot handle |
| 175 | * Try to write quickly with an atomic kmap. Return true on success. | 193 | * page faults in the source data |
| 176 | * | ||
| 177 | * If this fails (which includes a partial write), we'll redo the whole | ||
| 178 | * thing with the slow version. | ||
| 179 | * | ||
| 180 | * This is a workaround for the low performance of iounmap (approximate | ||
| 181 | * 10% cpu cost on normal 3D workloads). kmap_atomic on HIGHMEM kernels | ||
| 182 | * happens to let us map card memory without taking IPIs. When the vmap | ||
| 183 | * rework lands we should be able to dump this hack. | ||
| 184 | */ | 194 | */ |
| 185 | static inline int fast_user_write(unsigned long pfn, char __user *user_data, | 195 | |
| 186 | int l, int o) | 196 | static inline int |
| 197 | fast_user_write(struct io_mapping *mapping, | ||
| 198 | loff_t page_base, int page_offset, | ||
| 199 | char __user *user_data, | ||
| 200 | int length) | ||
| 187 | { | 201 | { |
| 188 | #ifdef CONFIG_HIGHMEM | ||
| 189 | unsigned long unwritten; | ||
| 190 | char *vaddr_atomic; | 202 | char *vaddr_atomic; |
| 203 | unsigned long unwritten; | ||
| 191 | 204 | ||
| 192 | vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); | 205 | vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); |
| 193 | #if WATCH_PWRITE | 206 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, |
| 194 | DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", | 207 | user_data, length); |
| 195 | i, o, l, pfn, vaddr_atomic); | 208 | io_mapping_unmap_atomic(vaddr_atomic); |
| 196 | #endif | 209 | if (unwritten) |
| 197 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, user_data, l); | 210 | return -EFAULT; |
| 198 | kunmap_atomic(vaddr_atomic, KM_USER0); | 211 | return 0; |
| 199 | return !unwritten; | 212 | } |
| 200 | #else | 213 | |
| 214 | /* Here's the write path which can sleep for | ||
| 215 | * page faults | ||
| 216 | */ | ||
| 217 | |||
| 218 | static inline int | ||
| 219 | slow_user_write(struct io_mapping *mapping, | ||
| 220 | loff_t page_base, int page_offset, | ||
| 221 | char __user *user_data, | ||
| 222 | int length) | ||
| 223 | { | ||
| 224 | char __iomem *vaddr; | ||
| 225 | unsigned long unwritten; | ||
| 226 | |||
| 227 | vaddr = io_mapping_map_wc(mapping, page_base); | ||
| 228 | if (vaddr == NULL) | ||
| 229 | return -EFAULT; | ||
| 230 | unwritten = __copy_from_user(vaddr + page_offset, | ||
| 231 | user_data, length); | ||
| 232 | io_mapping_unmap(vaddr); | ||
| 233 | if (unwritten) | ||
| 234 | return -EFAULT; | ||
| 201 | return 0; | 235 | return 0; |
| 202 | #endif | ||
| 203 | } | 236 | } |
| 204 | 237 | ||
| 205 | static int | 238 | static int |
| @@ -208,10 +241,12 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
| 208 | struct drm_file *file_priv) | 241 | struct drm_file *file_priv) |
| 209 | { | 242 | { |
| 210 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 243 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
| 244 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 211 | ssize_t remain; | 245 | ssize_t remain; |
| 212 | loff_t offset; | 246 | loff_t offset, page_base; |
| 213 | char __user *user_data; | 247 | char __user *user_data; |
| 214 | int ret = 0; | 248 | int page_offset, page_length; |
| 249 | int ret; | ||
| 215 | 250 | ||
| 216 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 251 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
| 217 | remain = args->size; | 252 | remain = args->size; |
| @@ -225,8 +260,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
| 225 | mutex_unlock(&dev->struct_mutex); | 260 | mutex_unlock(&dev->struct_mutex); |
| 226 | return ret; | 261 | return ret; |
| 227 | } | 262 | } |
| 228 | ret = i915_gem_set_domain(obj, file_priv, | 263 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); |
| 229 | I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); | ||
| 230 | if (ret) | 264 | if (ret) |
| 231 | goto fail; | 265 | goto fail; |
| 232 | 266 | ||
| @@ -235,57 +269,37 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
| 235 | obj_priv->dirty = 1; | 269 | obj_priv->dirty = 1; |
| 236 | 270 | ||
| 237 | while (remain > 0) { | 271 | while (remain > 0) { |
| 238 | unsigned long pfn; | ||
| 239 | int i, o, l; | ||
| 240 | |||
| 241 | /* Operation in this page | 272 | /* Operation in this page |
| 242 | * | 273 | * |
| 243 | * i = page number | 274 | * page_base = page offset within aperture |
| 244 | * o = offset within page | 275 | * page_offset = offset within page |
| 245 | * l = bytes to copy | 276 | * page_length = bytes to copy for this page |
| 246 | */ | 277 | */ |
| 247 | i = offset >> PAGE_SHIFT; | 278 | page_base = (offset & ~(PAGE_SIZE-1)); |
| 248 | o = offset & (PAGE_SIZE-1); | 279 | page_offset = offset & (PAGE_SIZE-1); |
| 249 | l = remain; | 280 | page_length = remain; |
| 250 | if ((o + l) > PAGE_SIZE) | 281 | if ((page_offset + remain) > PAGE_SIZE) |
| 251 | l = PAGE_SIZE - o; | 282 | page_length = PAGE_SIZE - page_offset; |
| 252 | 283 | ||
| 253 | pfn = (dev->agp->base >> PAGE_SHIFT) + i; | 284 | ret = fast_user_write (dev_priv->mm.gtt_mapping, page_base, |
| 254 | 285 | page_offset, user_data, page_length); | |
| 255 | if (!fast_user_write(pfn, user_data, l, o)) { | 286 | |
| 256 | unsigned long unwritten; | 287 | /* If we get a fault while copying data, then (presumably) our |
| 257 | char __iomem *vaddr; | 288 | * source page isn't available. In this case, use the |
| 258 | 289 | * non-atomic function | |
| 259 | vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE); | 290 | */ |
| 260 | #if WATCH_PWRITE | 291 | if (ret) { |
| 261 | DRM_INFO("pwrite slow i %d o %d l %d " | 292 | ret = slow_user_write (dev_priv->mm.gtt_mapping, |
| 262 | "pfn %ld vaddr %p\n", | 293 | page_base, page_offset, |
| 263 | i, o, l, pfn, vaddr); | 294 | user_data, page_length); |
| 264 | #endif | 295 | if (ret) |
| 265 | if (vaddr == NULL) { | ||
| 266 | ret = -EFAULT; | ||
| 267 | goto fail; | ||
| 268 | } | ||
| 269 | unwritten = __copy_from_user(vaddr + o, user_data, l); | ||
| 270 | #if WATCH_PWRITE | ||
| 271 | DRM_INFO("unwritten %ld\n", unwritten); | ||
| 272 | #endif | ||
| 273 | iounmap(vaddr); | ||
| 274 | if (unwritten) { | ||
| 275 | ret = -EFAULT; | ||
| 276 | goto fail; | 296 | goto fail; |
| 277 | } | ||
| 278 | } | 297 | } |
| 279 | 298 | ||
| 280 | remain -= l; | 299 | remain -= page_length; |
| 281 | user_data += l; | 300 | user_data += page_length; |
| 282 | offset += l; | 301 | offset += page_length; |
| 283 | } | 302 | } |
| 284 | #if WATCH_PWRITE && 1 | ||
| 285 | i915_gem_clflush_object(obj); | ||
| 286 | i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0); | ||
| 287 | i915_gem_clflush_object(obj); | ||
| 288 | #endif | ||
| 289 | 303 | ||
| 290 | fail: | 304 | fail: |
| 291 | i915_gem_object_unpin(obj); | 305 | i915_gem_object_unpin(obj); |
| @@ -305,8 +319,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
| 305 | 319 | ||
| 306 | mutex_lock(&dev->struct_mutex); | 320 | mutex_lock(&dev->struct_mutex); |
| 307 | 321 | ||
| 308 | ret = i915_gem_set_domain(obj, file_priv, | 322 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); |
| 309 | I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); | ||
| 310 | if (ret) { | 323 | if (ret) { |
| 311 | mutex_unlock(&dev->struct_mutex); | 324 | mutex_unlock(&dev->struct_mutex); |
| 312 | return ret; | 325 | return ret; |
| @@ -382,7 +395,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 382 | } | 395 | } |
| 383 | 396 | ||
| 384 | /** | 397 | /** |
| 385 | * Called when user space prepares to use an object | 398 | * Called when user space prepares to use an object with the CPU, either |
| 399 | * through the mmap ioctl's mapping or a GTT mapping. | ||
| 386 | */ | 400 | */ |
| 387 | int | 401 | int |
| 388 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | 402 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, |
| @@ -390,11 +404,26 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 390 | { | 404 | { |
| 391 | struct drm_i915_gem_set_domain *args = data; | 405 | struct drm_i915_gem_set_domain *args = data; |
| 392 | struct drm_gem_object *obj; | 406 | struct drm_gem_object *obj; |
| 407 | uint32_t read_domains = args->read_domains; | ||
| 408 | uint32_t write_domain = args->write_domain; | ||
| 393 | int ret; | 409 | int ret; |
| 394 | 410 | ||
| 395 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 411 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
| 396 | return -ENODEV; | 412 | return -ENODEV; |
| 397 | 413 | ||
| 414 | /* Only handle setting domains to types used by the CPU. */ | ||
| 415 | if (write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | ||
| 416 | return -EINVAL; | ||
| 417 | |||
| 418 | if (read_domains & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | ||
| 419 | return -EINVAL; | ||
| 420 | |||
| 421 | /* Having something in the write domain implies it's in the read | ||
| 422 | * domain, and only that read domain. Enforce that in the request. | ||
| 423 | */ | ||
| 424 | if (write_domain != 0 && read_domains != write_domain) | ||
| 425 | return -EINVAL; | ||
| 426 | |||
| 398 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 427 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
| 399 | if (obj == NULL) | 428 | if (obj == NULL) |
| 400 | return -EBADF; | 429 | return -EBADF; |
| @@ -402,10 +431,21 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 402 | mutex_lock(&dev->struct_mutex); | 431 | mutex_lock(&dev->struct_mutex); |
| 403 | #if WATCH_BUF | 432 | #if WATCH_BUF |
| 404 | DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", | 433 | DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", |
| 405 | obj, obj->size, args->read_domains, args->write_domain); | 434 | obj, obj->size, read_domains, write_domain); |
| 406 | #endif | 435 | #endif |
| 407 | ret = i915_gem_set_domain(obj, file_priv, | 436 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
| 408 | args->read_domains, args->write_domain); | 437 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
| 438 | |||
| 439 | /* Silently promote "you're not bound, there was nothing to do" | ||
| 440 | * to success, since the client was just asking us to | ||
| 441 | * make sure everything was done. | ||
| 442 | */ | ||
| 443 | if (ret == -EINVAL) | ||
| 444 | ret = 0; | ||
| 445 | } else { | ||
| 446 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | ||
| 447 | } | ||
| 448 | |||
| 409 | drm_gem_object_unreference(obj); | 449 | drm_gem_object_unreference(obj); |
| 410 | mutex_unlock(&dev->struct_mutex); | 450 | mutex_unlock(&dev->struct_mutex); |
| 411 | return ret; | 451 | return ret; |
| @@ -440,10 +480,9 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
| 440 | obj_priv = obj->driver_private; | 480 | obj_priv = obj->driver_private; |
| 441 | 481 | ||
| 442 | /* Pinned buffers may be scanout, so flush the cache */ | 482 | /* Pinned buffers may be scanout, so flush the cache */ |
| 443 | if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) { | 483 | if (obj_priv->pin_count) |
| 444 | i915_gem_clflush_object(obj); | 484 | i915_gem_object_flush_cpu_write_domain(obj); |
| 445 | drm_agp_chipset_flush(dev); | 485 | |
| 446 | } | ||
| 447 | drm_gem_object_unreference(obj); | 486 | drm_gem_object_unreference(obj); |
| 448 | mutex_unlock(&dev->struct_mutex); | 487 | mutex_unlock(&dev->struct_mutex); |
| 449 | return ret; | 488 | return ret; |
| @@ -517,7 +556,7 @@ i915_gem_object_free_page_list(struct drm_gem_object *obj) | |||
| 517 | } | 556 | } |
| 518 | 557 | ||
| 519 | static void | 558 | static void |
| 520 | i915_gem_object_move_to_active(struct drm_gem_object *obj) | 559 | i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) |
| 521 | { | 560 | { |
| 522 | struct drm_device *dev = obj->dev; | 561 | struct drm_device *dev = obj->dev; |
| 523 | drm_i915_private_t *dev_priv = dev->dev_private; | 562 | drm_i915_private_t *dev_priv = dev->dev_private; |
| @@ -531,8 +570,20 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj) | |||
| 531 | /* Move from whatever list we were on to the tail of execution. */ | 570 | /* Move from whatever list we were on to the tail of execution. */ |
| 532 | list_move_tail(&obj_priv->list, | 571 | list_move_tail(&obj_priv->list, |
| 533 | &dev_priv->mm.active_list); | 572 | &dev_priv->mm.active_list); |
| 573 | obj_priv->last_rendering_seqno = seqno; | ||
| 534 | } | 574 | } |
| 535 | 575 | ||
| 576 | static void | ||
| 577 | i915_gem_object_move_to_flushing(struct drm_gem_object *obj) | ||
| 578 | { | ||
| 579 | struct drm_device *dev = obj->dev; | ||
| 580 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 581 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 582 | |||
| 583 | BUG_ON(!obj_priv->active); | ||
| 584 | list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list); | ||
| 585 | obj_priv->last_rendering_seqno = 0; | ||
| 586 | } | ||
| 536 | 587 | ||
| 537 | static void | 588 | static void |
| 538 | i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | 589 | i915_gem_object_move_to_inactive(struct drm_gem_object *obj) |
| @@ -547,6 +598,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | |||
| 547 | else | 598 | else |
| 548 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | 599 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); |
| 549 | 600 | ||
| 601 | obj_priv->last_rendering_seqno = 0; | ||
| 550 | if (obj_priv->active) { | 602 | if (obj_priv->active) { |
| 551 | obj_priv->active = 0; | 603 | obj_priv->active = 0; |
| 552 | drm_gem_object_unreference(obj); | 604 | drm_gem_object_unreference(obj); |
| @@ -595,10 +647,28 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains) | |||
| 595 | 647 | ||
| 596 | request->seqno = seqno; | 648 | request->seqno = seqno; |
| 597 | request->emitted_jiffies = jiffies; | 649 | request->emitted_jiffies = jiffies; |
| 598 | request->flush_domains = flush_domains; | ||
| 599 | was_empty = list_empty(&dev_priv->mm.request_list); | 650 | was_empty = list_empty(&dev_priv->mm.request_list); |
| 600 | list_add_tail(&request->list, &dev_priv->mm.request_list); | 651 | list_add_tail(&request->list, &dev_priv->mm.request_list); |
| 601 | 652 | ||
| 653 | /* Associate any objects on the flushing list matching the write | ||
| 654 | * domain we're flushing with our flush. | ||
| 655 | */ | ||
| 656 | if (flush_domains != 0) { | ||
| 657 | struct drm_i915_gem_object *obj_priv, *next; | ||
| 658 | |||
| 659 | list_for_each_entry_safe(obj_priv, next, | ||
| 660 | &dev_priv->mm.flushing_list, list) { | ||
| 661 | struct drm_gem_object *obj = obj_priv->obj; | ||
| 662 | |||
| 663 | if ((obj->write_domain & flush_domains) == | ||
| 664 | obj->write_domain) { | ||
| 665 | obj->write_domain = 0; | ||
| 666 | i915_gem_object_move_to_active(obj, seqno); | ||
| 667 | } | ||
| 668 | } | ||
| 669 | |||
| 670 | } | ||
| 671 | |||
| 602 | if (was_empty && !dev_priv->mm.suspended) | 672 | if (was_empty && !dev_priv->mm.suspended) |
| 603 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | 673 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); |
| 604 | return seqno; | 674 | return seqno; |
| @@ -661,30 +731,10 @@ i915_gem_retire_request(struct drm_device *dev, | |||
| 661 | __func__, request->seqno, obj); | 731 | __func__, request->seqno, obj); |
| 662 | #endif | 732 | #endif |
| 663 | 733 | ||
| 664 | if (obj->write_domain != 0) { | 734 | if (obj->write_domain != 0) |
| 665 | list_move_tail(&obj_priv->list, | 735 | i915_gem_object_move_to_flushing(obj); |
| 666 | &dev_priv->mm.flushing_list); | 736 | else |
| 667 | } else { | ||
| 668 | i915_gem_object_move_to_inactive(obj); | 737 | i915_gem_object_move_to_inactive(obj); |
| 669 | } | ||
| 670 | } | ||
| 671 | |||
| 672 | if (request->flush_domains != 0) { | ||
| 673 | struct drm_i915_gem_object *obj_priv, *next; | ||
| 674 | |||
| 675 | /* Clear the write domain and activity from any buffers | ||
| 676 | * that are just waiting for a flush matching the one retired. | ||
| 677 | */ | ||
| 678 | list_for_each_entry_safe(obj_priv, next, | ||
| 679 | &dev_priv->mm.flushing_list, list) { | ||
| 680 | struct drm_gem_object *obj = obj_priv->obj; | ||
| 681 | |||
| 682 | if (obj->write_domain & request->flush_domains) { | ||
| 683 | obj->write_domain = 0; | ||
| 684 | i915_gem_object_move_to_inactive(obj); | ||
| 685 | } | ||
| 686 | } | ||
| 687 | |||
| 688 | } | 738 | } |
| 689 | } | 739 | } |
| 690 | 740 | ||
| @@ -877,25 +927,10 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj) | |||
| 877 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 927 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
| 878 | int ret; | 928 | int ret; |
| 879 | 929 | ||
| 880 | /* If there are writes queued to the buffer, flush and | 930 | /* This function only exists to support waiting for existing rendering, |
| 881 | * create a new seqno to wait for. | 931 | * not for emitting required flushes. |
| 882 | */ | 932 | */ |
| 883 | if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { | 933 | BUG_ON((obj->write_domain & I915_GEM_GPU_DOMAINS) != 0); |
| 884 | uint32_t write_domain = obj->write_domain; | ||
| 885 | #if WATCH_BUF | ||
| 886 | DRM_INFO("%s: flushing object %p from write domain %08x\n", | ||
| 887 | __func__, obj, write_domain); | ||
| 888 | #endif | ||
| 889 | i915_gem_flush(dev, 0, write_domain); | ||
| 890 | |||
| 891 | i915_gem_object_move_to_active(obj); | ||
| 892 | obj_priv->last_rendering_seqno = i915_add_request(dev, | ||
| 893 | write_domain); | ||
| 894 | BUG_ON(obj_priv->last_rendering_seqno == 0); | ||
| 895 | #if WATCH_LRU | ||
| 896 | DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj); | ||
| 897 | #endif | ||
| 898 | } | ||
| 899 | 934 | ||
| 900 | /* If there is rendering queued on the buffer being evicted, wait for | 935 | /* If there is rendering queued on the buffer being evicted, wait for |
| 901 | * it. | 936 | * it. |
| @@ -935,24 +970,16 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
| 935 | return -EINVAL; | 970 | return -EINVAL; |
| 936 | } | 971 | } |
| 937 | 972 | ||
| 938 | /* Wait for any rendering to complete | ||
| 939 | */ | ||
| 940 | ret = i915_gem_object_wait_rendering(obj); | ||
| 941 | if (ret) { | ||
| 942 | DRM_ERROR("wait_rendering failed: %d\n", ret); | ||
| 943 | return ret; | ||
| 944 | } | ||
| 945 | |||
| 946 | /* Move the object to the CPU domain to ensure that | 973 | /* Move the object to the CPU domain to ensure that |
| 947 | * any possible CPU writes while it's not in the GTT | 974 | * any possible CPU writes while it's not in the GTT |
| 948 | * are flushed when we go to remap it. This will | 975 | * are flushed when we go to remap it. This will |
| 949 | * also ensure that all pending GPU writes are finished | 976 | * also ensure that all pending GPU writes are finished |
| 950 | * before we unbind. | 977 | * before we unbind. |
| 951 | */ | 978 | */ |
| 952 | ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU, | 979 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); |
| 953 | I915_GEM_DOMAIN_CPU); | ||
| 954 | if (ret) { | 980 | if (ret) { |
| 955 | DRM_ERROR("set_domain failed: %d\n", ret); | 981 | if (ret != -ERESTARTSYS) |
| 982 | DRM_ERROR("set_domain failed: %d\n", ret); | ||
| 956 | return ret; | 983 | return ret; |
| 957 | } | 984 | } |
| 958 | 985 | ||
| @@ -1068,6 +1095,21 @@ i915_gem_evict_something(struct drm_device *dev) | |||
| 1068 | } | 1095 | } |
| 1069 | 1096 | ||
| 1070 | static int | 1097 | static int |
| 1098 | i915_gem_evict_everything(struct drm_device *dev) | ||
| 1099 | { | ||
| 1100 | int ret; | ||
| 1101 | |||
| 1102 | for (;;) { | ||
| 1103 | ret = i915_gem_evict_something(dev); | ||
| 1104 | if (ret != 0) | ||
| 1105 | break; | ||
| 1106 | } | ||
| 1107 | if (ret == -ENOMEM) | ||
| 1108 | return 0; | ||
| 1109 | return ret; | ||
| 1110 | } | ||
| 1111 | |||
| 1112 | static int | ||
| 1071 | i915_gem_object_get_page_list(struct drm_gem_object *obj) | 1113 | i915_gem_object_get_page_list(struct drm_gem_object *obj) |
| 1072 | { | 1114 | { |
| 1073 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1115 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
| @@ -1153,7 +1195,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 1153 | 1195 | ||
| 1154 | ret = i915_gem_evict_something(dev); | 1196 | ret = i915_gem_evict_something(dev); |
| 1155 | if (ret != 0) { | 1197 | if (ret != 0) { |
| 1156 | DRM_ERROR("Failed to evict a buffer %d\n", ret); | 1198 | if (ret != -ERESTARTSYS) |
| 1199 | DRM_ERROR("Failed to evict a buffer %d\n", ret); | ||
| 1157 | return ret; | 1200 | return ret; |
| 1158 | } | 1201 | } |
| 1159 | goto search_free; | 1202 | goto search_free; |
| @@ -1213,6 +1256,143 @@ i915_gem_clflush_object(struct drm_gem_object *obj) | |||
| 1213 | drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE); | 1256 | drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE); |
| 1214 | } | 1257 | } |
| 1215 | 1258 | ||
| 1259 | /** Flushes any GPU write domain for the object if it's dirty. */ | ||
| 1260 | static void | ||
| 1261 | i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | ||
| 1262 | { | ||
| 1263 | struct drm_device *dev = obj->dev; | ||
| 1264 | uint32_t seqno; | ||
| 1265 | |||
| 1266 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) | ||
| 1267 | return; | ||
| 1268 | |||
| 1269 | /* Queue the GPU write cache flushing we need. */ | ||
| 1270 | i915_gem_flush(dev, 0, obj->write_domain); | ||
| 1271 | seqno = i915_add_request(dev, obj->write_domain); | ||
| 1272 | obj->write_domain = 0; | ||
| 1273 | i915_gem_object_move_to_active(obj, seqno); | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | /** Flushes the GTT write domain for the object if it's dirty. */ | ||
| 1277 | static void | ||
| 1278 | i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) | ||
| 1279 | { | ||
| 1280 | if (obj->write_domain != I915_GEM_DOMAIN_GTT) | ||
| 1281 | return; | ||
| 1282 | |||
| 1283 | /* No actual flushing is required for the GTT write domain. Writes | ||
| 1284 | * to it immediately go to main memory as far as we know, so there's | ||
| 1285 | * no chipset flush. It also doesn't land in render cache. | ||
| 1286 | */ | ||
| 1287 | obj->write_domain = 0; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | /** Flushes the CPU write domain for the object if it's dirty. */ | ||
| 1291 | static void | ||
| 1292 | i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) | ||
| 1293 | { | ||
| 1294 | struct drm_device *dev = obj->dev; | ||
| 1295 | |||
| 1296 | if (obj->write_domain != I915_GEM_DOMAIN_CPU) | ||
| 1297 | return; | ||
| 1298 | |||
| 1299 | i915_gem_clflush_object(obj); | ||
| 1300 | drm_agp_chipset_flush(dev); | ||
| 1301 | obj->write_domain = 0; | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | /** | ||
| 1305 | * Moves a single object to the GTT read, and possibly write domain. | ||
| 1306 | * | ||
| 1307 | * This function returns when the move is complete, including waiting on | ||
| 1308 | * flushes to occur. | ||
| 1309 | */ | ||
| 1310 | static int | ||
| 1311 | i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | ||
| 1312 | { | ||
| 1313 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 1314 | int ret; | ||
| 1315 | |||
| 1316 | /* Not valid to be called on unbound objects. */ | ||
| 1317 | if (obj_priv->gtt_space == NULL) | ||
| 1318 | return -EINVAL; | ||
| 1319 | |||
| 1320 | i915_gem_object_flush_gpu_write_domain(obj); | ||
| 1321 | /* Wait on any GPU rendering and flushing to occur. */ | ||
| 1322 | ret = i915_gem_object_wait_rendering(obj); | ||
| 1323 | if (ret != 0) | ||
| 1324 | return ret; | ||
| 1325 | |||
| 1326 | /* If we're writing through the GTT domain, then CPU and GPU caches | ||
| 1327 | * will need to be invalidated at next use. | ||
| 1328 | */ | ||
| 1329 | if (write) | ||
| 1330 | obj->read_domains &= I915_GEM_DOMAIN_GTT; | ||
| 1331 | |||
| 1332 | i915_gem_object_flush_cpu_write_domain(obj); | ||
| 1333 | |||
| 1334 | /* It should now be out of any other write domains, and we can update | ||
| 1335 | * the domain values for our changes. | ||
| 1336 | */ | ||
| 1337 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | ||
| 1338 | obj->read_domains |= I915_GEM_DOMAIN_GTT; | ||
| 1339 | if (write) { | ||
| 1340 | obj->write_domain = I915_GEM_DOMAIN_GTT; | ||
| 1341 | obj_priv->dirty = 1; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | return 0; | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | /** | ||
| 1348 | * Moves a single object to the CPU read, and possibly write domain. | ||
| 1349 | * | ||
| 1350 | * This function returns when the move is complete, including waiting on | ||
| 1351 | * flushes to occur. | ||
| 1352 | */ | ||
| 1353 | static int | ||
| 1354 | i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | ||
| 1355 | { | ||
| 1356 | struct drm_device *dev = obj->dev; | ||
| 1357 | int ret; | ||
| 1358 | |||
| 1359 | i915_gem_object_flush_gpu_write_domain(obj); | ||
| 1360 | /* Wait on any GPU rendering and flushing to occur. */ | ||
| 1361 | ret = i915_gem_object_wait_rendering(obj); | ||
| 1362 | if (ret != 0) | ||
| 1363 | return ret; | ||
| 1364 | |||
| 1365 | i915_gem_object_flush_gtt_write_domain(obj); | ||
| 1366 | |||
| 1367 | /* If we have a partially-valid cache of the object in the CPU, | ||
| 1368 | * finish invalidating it and free the per-page flags. | ||
| 1369 | */ | ||
| 1370 | i915_gem_object_set_to_full_cpu_read_domain(obj); | ||
| 1371 | |||
| 1372 | /* Flush the CPU cache if it's still invalid. */ | ||
| 1373 | if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { | ||
| 1374 | i915_gem_clflush_object(obj); | ||
| 1375 | drm_agp_chipset_flush(dev); | ||
| 1376 | |||
| 1377 | obj->read_domains |= I915_GEM_DOMAIN_CPU; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | /* It should now be out of any other write domains, and we can update | ||
| 1381 | * the domain values for our changes. | ||
| 1382 | */ | ||
| 1383 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); | ||
| 1384 | |||
| 1385 | /* If we're writing through the CPU, then the GPU read domains will | ||
| 1386 | * need to be invalidated at next use. | ||
| 1387 | */ | ||
| 1388 | if (write) { | ||
| 1389 | obj->read_domains &= I915_GEM_DOMAIN_CPU; | ||
| 1390 | obj->write_domain = I915_GEM_DOMAIN_CPU; | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | return 0; | ||
| 1394 | } | ||
| 1395 | |||
| 1216 | /* | 1396 | /* |
| 1217 | * Set the next domain for the specified object. This | 1397 | * Set the next domain for the specified object. This |
| 1218 | * may not actually perform the necessary flushing/invaliding though, | 1398 | * may not actually perform the necessary flushing/invaliding though, |
| @@ -1324,16 +1504,18 @@ i915_gem_clflush_object(struct drm_gem_object *obj) | |||
| 1324 | * MI_FLUSH | 1504 | * MI_FLUSH |
| 1325 | * drm_agp_chipset_flush | 1505 | * drm_agp_chipset_flush |
| 1326 | */ | 1506 | */ |
| 1327 | static int | 1507 | static void |
| 1328 | i915_gem_object_set_domain(struct drm_gem_object *obj, | 1508 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, |
| 1329 | uint32_t read_domains, | 1509 | uint32_t read_domains, |
| 1330 | uint32_t write_domain) | 1510 | uint32_t write_domain) |
| 1331 | { | 1511 | { |
| 1332 | struct drm_device *dev = obj->dev; | 1512 | struct drm_device *dev = obj->dev; |
| 1333 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1513 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
| 1334 | uint32_t invalidate_domains = 0; | 1514 | uint32_t invalidate_domains = 0; |
| 1335 | uint32_t flush_domains = 0; | 1515 | uint32_t flush_domains = 0; |
| 1336 | int ret; | 1516 | |
| 1517 | BUG_ON(read_domains & I915_GEM_DOMAIN_CPU); | ||
| 1518 | BUG_ON(write_domain == I915_GEM_DOMAIN_CPU); | ||
| 1337 | 1519 | ||
| 1338 | #if WATCH_BUF | 1520 | #if WATCH_BUF |
| 1339 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", | 1521 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", |
| @@ -1370,34 +1552,11 @@ i915_gem_object_set_domain(struct drm_gem_object *obj, | |||
| 1370 | DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", | 1552 | DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", |
| 1371 | __func__, flush_domains, invalidate_domains); | 1553 | __func__, flush_domains, invalidate_domains); |
| 1372 | #endif | 1554 | #endif |
| 1373 | /* | ||
| 1374 | * If we're invaliding the CPU cache and flushing a GPU cache, | ||
| 1375 | * then pause for rendering so that the GPU caches will be | ||
| 1376 | * flushed before the cpu cache is invalidated | ||
| 1377 | */ | ||
| 1378 | if ((invalidate_domains & I915_GEM_DOMAIN_CPU) && | ||
| 1379 | (flush_domains & ~(I915_GEM_DOMAIN_CPU | | ||
| 1380 | I915_GEM_DOMAIN_GTT))) { | ||
| 1381 | ret = i915_gem_object_wait_rendering(obj); | ||
| 1382 | if (ret) | ||
| 1383 | return ret; | ||
| 1384 | } | ||
| 1385 | i915_gem_clflush_object(obj); | 1555 | i915_gem_clflush_object(obj); |
| 1386 | } | 1556 | } |
| 1387 | 1557 | ||
| 1388 | if ((write_domain | flush_domains) != 0) | 1558 | if ((write_domain | flush_domains) != 0) |
| 1389 | obj->write_domain = write_domain; | 1559 | obj->write_domain = write_domain; |
| 1390 | |||
| 1391 | /* If we're invalidating the CPU domain, clear the per-page CPU | ||
| 1392 | * domain list as well. | ||
| 1393 | */ | ||
| 1394 | if (obj_priv->page_cpu_valid != NULL && | ||
| 1395 | (write_domain != 0 || | ||
| 1396 | read_domains & I915_GEM_DOMAIN_CPU)) { | ||
| 1397 | drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, | ||
| 1398 | DRM_MEM_DRIVER); | ||
| 1399 | obj_priv->page_cpu_valid = NULL; | ||
| 1400 | } | ||
| 1401 | obj->read_domains = read_domains; | 1560 | obj->read_domains = read_domains; |
| 1402 | 1561 | ||
| 1403 | dev->invalidate_domains |= invalidate_domains; | 1562 | dev->invalidate_domains |= invalidate_domains; |
| @@ -1408,49 +1567,94 @@ i915_gem_object_set_domain(struct drm_gem_object *obj, | |||
| 1408 | obj->read_domains, obj->write_domain, | 1567 | obj->read_domains, obj->write_domain, |
| 1409 | dev->invalidate_domains, dev->flush_domains); | 1568 | dev->invalidate_domains, dev->flush_domains); |
| 1410 | #endif | 1569 | #endif |
| 1411 | return 0; | ||
| 1412 | } | 1570 | } |
| 1413 | 1571 | ||
| 1414 | /** | 1572 | /** |
| 1415 | * Set the read/write domain on a range of the object. | 1573 | * Moves the object from a partially CPU read to a full one. |
| 1416 | * | 1574 | * |
| 1417 | * Currently only implemented for CPU reads, otherwise drops to normal | 1575 | * Note that this only resolves i915_gem_object_set_cpu_read_domain_range(), |
| 1418 | * i915_gem_object_set_domain(). | 1576 | * and doesn't handle transitioning from !(read_domains & I915_GEM_DOMAIN_CPU). |
| 1419 | */ | 1577 | */ |
| 1420 | static int | 1578 | static void |
| 1421 | i915_gem_object_set_domain_range(struct drm_gem_object *obj, | 1579 | i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) |
| 1422 | uint64_t offset, | ||
| 1423 | uint64_t size, | ||
| 1424 | uint32_t read_domains, | ||
| 1425 | uint32_t write_domain) | ||
| 1426 | { | 1580 | { |
| 1581 | struct drm_device *dev = obj->dev; | ||
| 1427 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1582 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
| 1428 | int ret, i; | ||
| 1429 | 1583 | ||
| 1430 | if (obj->read_domains & I915_GEM_DOMAIN_CPU) | 1584 | if (!obj_priv->page_cpu_valid) |
| 1431 | return 0; | 1585 | return; |
| 1432 | 1586 | ||
| 1433 | if (read_domains != I915_GEM_DOMAIN_CPU || | 1587 | /* If we're partially in the CPU read domain, finish moving it in. |
| 1434 | write_domain != 0) | 1588 | */ |
| 1435 | return i915_gem_object_set_domain(obj, | 1589 | if (obj->read_domains & I915_GEM_DOMAIN_CPU) { |
| 1436 | read_domains, write_domain); | 1590 | int i; |
| 1437 | 1591 | ||
| 1438 | /* Wait on any GPU rendering to the object to be flushed. */ | 1592 | for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) { |
| 1439 | if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) { | 1593 | if (obj_priv->page_cpu_valid[i]) |
| 1440 | ret = i915_gem_object_wait_rendering(obj); | 1594 | continue; |
| 1441 | if (ret) | 1595 | drm_clflush_pages(obj_priv->page_list + i, 1); |
| 1442 | return ret; | 1596 | } |
| 1597 | drm_agp_chipset_flush(dev); | ||
| 1443 | } | 1598 | } |
| 1444 | 1599 | ||
| 1600 | /* Free the page_cpu_valid mappings which are now stale, whether | ||
| 1601 | * or not we've got I915_GEM_DOMAIN_CPU. | ||
| 1602 | */ | ||
| 1603 | drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, | ||
| 1604 | DRM_MEM_DRIVER); | ||
| 1605 | obj_priv->page_cpu_valid = NULL; | ||
| 1606 | } | ||
| 1607 | |||
| 1608 | /** | ||
| 1609 | * Set the CPU read domain on a range of the object. | ||
| 1610 | * | ||
| 1611 | * The object ends up with I915_GEM_DOMAIN_CPU in its read flags although it's | ||
| 1612 | * not entirely valid. The page_cpu_valid member of the object flags which | ||
| 1613 | * pages have been flushed, and will be respected by | ||
| 1614 | * i915_gem_object_set_to_cpu_domain() if it's called on to get a valid mapping | ||
| 1615 | * of the whole object. | ||
| 1616 | * | ||
| 1617 | * This function returns when the move is complete, including waiting on | ||
| 1618 | * flushes to occur. | ||
| 1619 | */ | ||
| 1620 | static int | ||
| 1621 | i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | ||
| 1622 | uint64_t offset, uint64_t size) | ||
| 1623 | { | ||
| 1624 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 1625 | int i, ret; | ||
| 1626 | |||
| 1627 | if (offset == 0 && size == obj->size) | ||
| 1628 | return i915_gem_object_set_to_cpu_domain(obj, 0); | ||
| 1629 | |||
| 1630 | i915_gem_object_flush_gpu_write_domain(obj); | ||
| 1631 | /* Wait on any GPU rendering and flushing to occur. */ | ||
| 1632 | ret = i915_gem_object_wait_rendering(obj); | ||
| 1633 | if (ret != 0) | ||
| 1634 | return ret; | ||
| 1635 | i915_gem_object_flush_gtt_write_domain(obj); | ||
| 1636 | |||
| 1637 | /* If we're already fully in the CPU read domain, we're done. */ | ||
| 1638 | if (obj_priv->page_cpu_valid == NULL && | ||
| 1639 | (obj->read_domains & I915_GEM_DOMAIN_CPU) != 0) | ||
| 1640 | return 0; | ||
| 1641 | |||
| 1642 | /* Otherwise, create/clear the per-page CPU read domain flag if we're | ||
| 1643 | * newly adding I915_GEM_DOMAIN_CPU | ||
| 1644 | */ | ||
| 1445 | if (obj_priv->page_cpu_valid == NULL) { | 1645 | if (obj_priv->page_cpu_valid == NULL) { |
| 1446 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, | 1646 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, |
| 1447 | DRM_MEM_DRIVER); | 1647 | DRM_MEM_DRIVER); |
| 1448 | } | 1648 | if (obj_priv->page_cpu_valid == NULL) |
| 1649 | return -ENOMEM; | ||
| 1650 | } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) | ||
| 1651 | memset(obj_priv->page_cpu_valid, 0, obj->size / PAGE_SIZE); | ||
| 1449 | 1652 | ||
| 1450 | /* Flush the cache on any pages that are still invalid from the CPU's | 1653 | /* Flush the cache on any pages that are still invalid from the CPU's |
| 1451 | * perspective. | 1654 | * perspective. |
| 1452 | */ | 1655 | */ |
| 1453 | for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) { | 1656 | for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; |
| 1657 | i++) { | ||
| 1454 | if (obj_priv->page_cpu_valid[i]) | 1658 | if (obj_priv->page_cpu_valid[i]) |
| 1455 | continue; | 1659 | continue; |
| 1456 | 1660 | ||
| @@ -1459,39 +1663,14 @@ i915_gem_object_set_domain_range(struct drm_gem_object *obj, | |||
| 1459 | obj_priv->page_cpu_valid[i] = 1; | 1663 | obj_priv->page_cpu_valid[i] = 1; |
| 1460 | } | 1664 | } |
| 1461 | 1665 | ||
| 1462 | return 0; | 1666 | /* It should now be out of any other write domains, and we can update |
| 1463 | } | 1667 | * the domain values for our changes. |
| 1464 | |||
| 1465 | /** | ||
| 1466 | * Once all of the objects have been set in the proper domain, | ||
| 1467 | * perform the necessary flush and invalidate operations. | ||
| 1468 | * | ||
| 1469 | * Returns the write domains flushed, for use in flush tracking. | ||
| 1470 | */ | ||
| 1471 | static uint32_t | ||
| 1472 | i915_gem_dev_set_domain(struct drm_device *dev) | ||
| 1473 | { | ||
| 1474 | uint32_t flush_domains = dev->flush_domains; | ||
| 1475 | |||
| 1476 | /* | ||
| 1477 | * Now that all the buffers are synced to the proper domains, | ||
| 1478 | * flush and invalidate the collected domains | ||
| 1479 | */ | 1668 | */ |
| 1480 | if (dev->invalidate_domains | dev->flush_domains) { | 1669 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); |
| 1481 | #if WATCH_EXEC | ||
| 1482 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
| 1483 | __func__, | ||
| 1484 | dev->invalidate_domains, | ||
| 1485 | dev->flush_domains); | ||
| 1486 | #endif | ||
| 1487 | i915_gem_flush(dev, | ||
| 1488 | dev->invalidate_domains, | ||
| 1489 | dev->flush_domains); | ||
| 1490 | dev->invalidate_domains = 0; | ||
| 1491 | dev->flush_domains = 0; | ||
| 1492 | } | ||
| 1493 | 1670 | ||
| 1494 | return flush_domains; | 1671 | obj->read_domains |= I915_GEM_DOMAIN_CPU; |
| 1672 | |||
| 1673 | return 0; | ||
| 1495 | } | 1674 | } |
| 1496 | 1675 | ||
| 1497 | /** | 1676 | /** |
| @@ -1503,12 +1682,12 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
| 1503 | struct drm_i915_gem_exec_object *entry) | 1682 | struct drm_i915_gem_exec_object *entry) |
| 1504 | { | 1683 | { |
| 1505 | struct drm_device *dev = obj->dev; | 1684 | struct drm_device *dev = obj->dev; |
| 1685 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 1506 | struct drm_i915_gem_relocation_entry reloc; | 1686 | struct drm_i915_gem_relocation_entry reloc; |
| 1507 | struct drm_i915_gem_relocation_entry __user *relocs; | 1687 | struct drm_i915_gem_relocation_entry __user *relocs; |
| 1508 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1688 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
| 1509 | int i, ret; | 1689 | int i, ret; |
| 1510 | uint32_t last_reloc_offset = -1; | 1690 | void __iomem *reloc_page; |
| 1511 | void __iomem *reloc_page = NULL; | ||
| 1512 | 1691 | ||
| 1513 | /* Choose the GTT offset for our buffer and put it there. */ | 1692 | /* Choose the GTT offset for our buffer and put it there. */ |
| 1514 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); | 1693 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); |
| @@ -1572,6 +1751,18 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
| 1572 | return -EINVAL; | 1751 | return -EINVAL; |
| 1573 | } | 1752 | } |
| 1574 | 1753 | ||
| 1754 | if (reloc.write_domain & I915_GEM_DOMAIN_CPU || | ||
| 1755 | reloc.read_domains & I915_GEM_DOMAIN_CPU) { | ||
| 1756 | DRM_ERROR("reloc with read/write CPU domains: " | ||
| 1757 | "obj %p target %d offset %d " | ||
| 1758 | "read %08x write %08x", | ||
| 1759 | obj, reloc.target_handle, | ||
| 1760 | (int) reloc.offset, | ||
| 1761 | reloc.read_domains, | ||
| 1762 | reloc.write_domain); | ||
| 1763 | return -EINVAL; | ||
| 1764 | } | ||
| 1765 | |||
| 1575 | if (reloc.write_domain && target_obj->pending_write_domain && | 1766 | if (reloc.write_domain && target_obj->pending_write_domain && |
| 1576 | reloc.write_domain != target_obj->pending_write_domain) { | 1767 | reloc.write_domain != target_obj->pending_write_domain) { |
| 1577 | DRM_ERROR("Write domain conflict: " | 1768 | DRM_ERROR("Write domain conflict: " |
| @@ -1612,45 +1803,22 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
| 1612 | continue; | 1803 | continue; |
| 1613 | } | 1804 | } |
| 1614 | 1805 | ||
| 1615 | /* Now that we're going to actually write some data in, | 1806 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); |
| 1616 | * make sure that any rendering using this buffer's contents | 1807 | if (ret != 0) { |
| 1617 | * is completed. | 1808 | drm_gem_object_unreference(target_obj); |
| 1618 | */ | 1809 | i915_gem_object_unpin(obj); |
| 1619 | i915_gem_object_wait_rendering(obj); | 1810 | return -EINVAL; |
| 1620 | |||
| 1621 | /* As we're writing through the gtt, flush | ||
| 1622 | * any CPU writes before we write the relocations | ||
| 1623 | */ | ||
| 1624 | if (obj->write_domain & I915_GEM_DOMAIN_CPU) { | ||
| 1625 | i915_gem_clflush_object(obj); | ||
| 1626 | drm_agp_chipset_flush(dev); | ||
| 1627 | obj->write_domain = 0; | ||
| 1628 | } | 1811 | } |
| 1629 | 1812 | ||
| 1630 | /* Map the page containing the relocation we're going to | 1813 | /* Map the page containing the relocation we're going to |
| 1631 | * perform. | 1814 | * perform. |
| 1632 | */ | 1815 | */ |
| 1633 | reloc_offset = obj_priv->gtt_offset + reloc.offset; | 1816 | reloc_offset = obj_priv->gtt_offset + reloc.offset; |
| 1634 | if (reloc_page == NULL || | 1817 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
| 1635 | (last_reloc_offset & ~(PAGE_SIZE - 1)) != | 1818 | (reloc_offset & |
| 1636 | (reloc_offset & ~(PAGE_SIZE - 1))) { | 1819 | ~(PAGE_SIZE - 1))); |
| 1637 | if (reloc_page != NULL) | ||
| 1638 | iounmap(reloc_page); | ||
| 1639 | |||
| 1640 | reloc_page = ioremap_wc(dev->agp->base + | ||
| 1641 | (reloc_offset & | ||
| 1642 | ~(PAGE_SIZE - 1)), | ||
| 1643 | PAGE_SIZE); | ||
| 1644 | last_reloc_offset = reloc_offset; | ||
| 1645 | if (reloc_page == NULL) { | ||
| 1646 | drm_gem_object_unreference(target_obj); | ||
| 1647 | i915_gem_object_unpin(obj); | ||
| 1648 | return -ENOMEM; | ||
| 1649 | } | ||
| 1650 | } | ||
| 1651 | |||
| 1652 | reloc_entry = (uint32_t __iomem *)(reloc_page + | 1820 | reloc_entry = (uint32_t __iomem *)(reloc_page + |
| 1653 | (reloc_offset & (PAGE_SIZE - 1))); | 1821 | (reloc_offset & (PAGE_SIZE - 1))); |
| 1654 | reloc_val = target_obj_priv->gtt_offset + reloc.delta; | 1822 | reloc_val = target_obj_priv->gtt_offset + reloc.delta; |
| 1655 | 1823 | ||
| 1656 | #if WATCH_BUF | 1824 | #if WATCH_BUF |
| @@ -1659,6 +1827,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
| 1659 | readl(reloc_entry), reloc_val); | 1827 | readl(reloc_entry), reloc_val); |
| 1660 | #endif | 1828 | #endif |
| 1661 | writel(reloc_val, reloc_entry); | 1829 | writel(reloc_val, reloc_entry); |
| 1830 | io_mapping_unmap_atomic(reloc_page); | ||
| 1662 | 1831 | ||
| 1663 | /* Write the updated presumed offset for this entry back out | 1832 | /* Write the updated presumed offset for this entry back out |
| 1664 | * to the user. | 1833 | * to the user. |
| @@ -1674,9 +1843,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
| 1674 | drm_gem_object_unreference(target_obj); | 1843 | drm_gem_object_unreference(target_obj); |
| 1675 | } | 1844 | } |
| 1676 | 1845 | ||
| 1677 | if (reloc_page != NULL) | ||
| 1678 | iounmap(reloc_page); | ||
| 1679 | |||
| 1680 | #if WATCH_BUF | 1846 | #if WATCH_BUF |
| 1681 | if (0) | 1847 | if (0) |
| 1682 | i915_gem_dump_object(obj, 128, __func__, ~0); | 1848 | i915_gem_dump_object(obj, 128, __func__, ~0); |
| @@ -1783,6 +1949,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 1783 | int ret, i, pinned = 0; | 1949 | int ret, i, pinned = 0; |
| 1784 | uint64_t exec_offset; | 1950 | uint64_t exec_offset; |
| 1785 | uint32_t seqno, flush_domains; | 1951 | uint32_t seqno, flush_domains; |
| 1952 | int pin_tries; | ||
| 1786 | 1953 | ||
| 1787 | #if WATCH_EXEC | 1954 | #if WATCH_EXEC |
| 1788 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | 1955 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", |
| @@ -1831,14 +1998,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 1831 | return -EBUSY; | 1998 | return -EBUSY; |
| 1832 | } | 1999 | } |
| 1833 | 2000 | ||
| 1834 | /* Zero the gloabl flush/invalidate flags. These | 2001 | /* Look up object handles */ |
| 1835 | * will be modified as each object is bound to the | ||
| 1836 | * gtt | ||
| 1837 | */ | ||
| 1838 | dev->invalidate_domains = 0; | ||
| 1839 | dev->flush_domains = 0; | ||
| 1840 | |||
| 1841 | /* Look up object handles and perform the relocations */ | ||
| 1842 | for (i = 0; i < args->buffer_count; i++) { | 2002 | for (i = 0; i < args->buffer_count; i++) { |
| 1843 | object_list[i] = drm_gem_object_lookup(dev, file_priv, | 2003 | object_list[i] = drm_gem_object_lookup(dev, file_priv, |
| 1844 | exec_list[i].handle); | 2004 | exec_list[i].handle); |
| @@ -1848,17 +2008,39 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 1848 | ret = -EBADF; | 2008 | ret = -EBADF; |
| 1849 | goto err; | 2009 | goto err; |
| 1850 | } | 2010 | } |
| 2011 | } | ||
| 1851 | 2012 | ||
| 1852 | object_list[i]->pending_read_domains = 0; | 2013 | /* Pin and relocate */ |
| 1853 | object_list[i]->pending_write_domain = 0; | 2014 | for (pin_tries = 0; ; pin_tries++) { |
| 1854 | ret = i915_gem_object_pin_and_relocate(object_list[i], | 2015 | ret = 0; |
| 1855 | file_priv, | 2016 | for (i = 0; i < args->buffer_count; i++) { |
| 1856 | &exec_list[i]); | 2017 | object_list[i]->pending_read_domains = 0; |
| 1857 | if (ret) { | 2018 | object_list[i]->pending_write_domain = 0; |
| 1858 | DRM_ERROR("object bind and relocate failed %d\n", ret); | 2019 | ret = i915_gem_object_pin_and_relocate(object_list[i], |
| 2020 | file_priv, | ||
| 2021 | &exec_list[i]); | ||
| 2022 | if (ret) | ||
| 2023 | break; | ||
| 2024 | pinned = i + 1; | ||
| 2025 | } | ||
| 2026 | /* success */ | ||
| 2027 | if (ret == 0) | ||
| 2028 | break; | ||
| 2029 | |||
| 2030 | /* error other than GTT full, or we've already tried again */ | ||
| 2031 | if (ret != -ENOMEM || pin_tries >= 1) { | ||
| 2032 | DRM_ERROR("Failed to pin buffers %d\n", ret); | ||
| 1859 | goto err; | 2033 | goto err; |
| 1860 | } | 2034 | } |
| 1861 | pinned = i + 1; | 2035 | |
| 2036 | /* unpin all of our buffers */ | ||
| 2037 | for (i = 0; i < pinned; i++) | ||
| 2038 | i915_gem_object_unpin(object_list[i]); | ||
| 2039 | |||
| 2040 | /* evict everyone we can from the aperture */ | ||
| 2041 | ret = i915_gem_evict_everything(dev); | ||
| 2042 | if (ret) | ||
| 2043 | goto err; | ||
| 1862 | } | 2044 | } |
| 1863 | 2045 | ||
| 1864 | /* Set the pending read domains for the batch buffer to COMMAND */ | 2046 | /* Set the pending read domains for the batch buffer to COMMAND */ |
| @@ -1868,32 +2050,37 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 1868 | 2050 | ||
| 1869 | i915_verify_inactive(dev, __FILE__, __LINE__); | 2051 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| 1870 | 2052 | ||
| 2053 | /* Zero the global flush/invalidate flags. These | ||
| 2054 | * will be modified as new domains are computed | ||
| 2055 | * for each object | ||
| 2056 | */ | ||
| 2057 | dev->invalidate_domains = 0; | ||
| 2058 | dev->flush_domains = 0; | ||
| 2059 | |||
| 1871 | for (i = 0; i < args->buffer_count; i++) { | 2060 | for (i = 0; i < args->buffer_count; i++) { |
| 1872 | struct drm_gem_object *obj = object_list[i]; | 2061 | struct drm_gem_object *obj = object_list[i]; |
| 1873 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 1874 | |||
| 1875 | if (obj_priv->gtt_space == NULL) { | ||
| 1876 | /* We evicted the buffer in the process of validating | ||
| 1877 | * our set of buffers in. We could try to recover by | ||
| 1878 | * kicking them everything out and trying again from | ||
| 1879 | * the start. | ||
| 1880 | */ | ||
| 1881 | ret = -ENOMEM; | ||
| 1882 | goto err; | ||
| 1883 | } | ||
| 1884 | 2062 | ||
| 1885 | /* make sure all previous memory operations have passed */ | 2063 | /* Compute new gpu domains and update invalidate/flush */ |
| 1886 | ret = i915_gem_object_set_domain(obj, | 2064 | i915_gem_object_set_to_gpu_domain(obj, |
| 1887 | obj->pending_read_domains, | 2065 | obj->pending_read_domains, |
| 1888 | obj->pending_write_domain); | 2066 | obj->pending_write_domain); |
| 1889 | if (ret) | ||
| 1890 | goto err; | ||
| 1891 | } | 2067 | } |
| 1892 | 2068 | ||
| 1893 | i915_verify_inactive(dev, __FILE__, __LINE__); | 2069 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| 1894 | 2070 | ||
| 1895 | /* Flush/invalidate caches and chipset buffer */ | 2071 | if (dev->invalidate_domains | dev->flush_domains) { |
| 1896 | flush_domains = i915_gem_dev_set_domain(dev); | 2072 | #if WATCH_EXEC |
| 2073 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
| 2074 | __func__, | ||
| 2075 | dev->invalidate_domains, | ||
| 2076 | dev->flush_domains); | ||
| 2077 | #endif | ||
| 2078 | i915_gem_flush(dev, | ||
| 2079 | dev->invalidate_domains, | ||
| 2080 | dev->flush_domains); | ||
| 2081 | if (dev->flush_domains) | ||
| 2082 | (void)i915_add_request(dev, dev->flush_domains); | ||
| 2083 | } | ||
| 1897 | 2084 | ||
| 1898 | i915_verify_inactive(dev, __FILE__, __LINE__); | 2085 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| 1899 | 2086 | ||
| @@ -1913,8 +2100,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 1913 | ~0); | 2100 | ~0); |
| 1914 | #endif | 2101 | #endif |
| 1915 | 2102 | ||
| 1916 | (void)i915_add_request(dev, flush_domains); | ||
| 1917 | |||
| 1918 | /* Exec the batchbuffer */ | 2103 | /* Exec the batchbuffer */ |
| 1919 | ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset); | 2104 | ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset); |
| 1920 | if (ret) { | 2105 | if (ret) { |
| @@ -1942,10 +2127,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 1942 | i915_file_priv->mm.last_gem_seqno = seqno; | 2127 | i915_file_priv->mm.last_gem_seqno = seqno; |
| 1943 | for (i = 0; i < args->buffer_count; i++) { | 2128 | for (i = 0; i < args->buffer_count; i++) { |
| 1944 | struct drm_gem_object *obj = object_list[i]; | 2129 | struct drm_gem_object *obj = object_list[i]; |
| 1945 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 1946 | 2130 | ||
| 1947 | i915_gem_object_move_to_active(obj); | 2131 | i915_gem_object_move_to_active(obj, seqno); |
| 1948 | obj_priv->last_rendering_seqno = seqno; | ||
| 1949 | #if WATCH_LRU | 2132 | #if WATCH_LRU |
| 1950 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); | 2133 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); |
| 1951 | #endif | 2134 | #endif |
| @@ -2076,11 +2259,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, | |||
| 2076 | /* XXX - flush the CPU caches for pinned objects | 2259 | /* XXX - flush the CPU caches for pinned objects |
| 2077 | * as the X server doesn't manage domains yet | 2260 | * as the X server doesn't manage domains yet |
| 2078 | */ | 2261 | */ |
| 2079 | if (obj->write_domain & I915_GEM_DOMAIN_CPU) { | 2262 | i915_gem_object_flush_cpu_write_domain(obj); |
| 2080 | i915_gem_clflush_object(obj); | ||
| 2081 | drm_agp_chipset_flush(dev); | ||
| 2082 | obj->write_domain = 0; | ||
| 2083 | } | ||
| 2084 | args->offset = obj_priv->gtt_offset; | 2263 | args->offset = obj_priv->gtt_offset; |
| 2085 | drm_gem_object_unreference(obj); | 2264 | drm_gem_object_unreference(obj); |
| 2086 | mutex_unlock(&dev->struct_mutex); | 2265 | mutex_unlock(&dev->struct_mutex); |
| @@ -2182,29 +2361,6 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
| 2182 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); | 2361 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); |
| 2183 | } | 2362 | } |
| 2184 | 2363 | ||
| 2185 | static int | ||
| 2186 | i915_gem_set_domain(struct drm_gem_object *obj, | ||
| 2187 | struct drm_file *file_priv, | ||
| 2188 | uint32_t read_domains, | ||
| 2189 | uint32_t write_domain) | ||
| 2190 | { | ||
| 2191 | struct drm_device *dev = obj->dev; | ||
| 2192 | int ret; | ||
| 2193 | uint32_t flush_domains; | ||
| 2194 | |||
| 2195 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
| 2196 | |||
| 2197 | ret = i915_gem_object_set_domain(obj, read_domains, write_domain); | ||
| 2198 | if (ret) | ||
| 2199 | return ret; | ||
| 2200 | flush_domains = i915_gem_dev_set_domain(obj->dev); | ||
| 2201 | |||
| 2202 | if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) | ||
| 2203 | (void) i915_add_request(dev, flush_domains); | ||
| 2204 | |||
| 2205 | return 0; | ||
| 2206 | } | ||
| 2207 | |||
| 2208 | /** Unbinds all objects that are on the given buffer list. */ | 2364 | /** Unbinds all objects that are on the given buffer list. */ |
| 2209 | static int | 2365 | static int |
| 2210 | i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) | 2366 | i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) |
| @@ -2299,29 +2455,52 @@ i915_gem_idle(struct drm_device *dev) | |||
| 2299 | 2455 | ||
| 2300 | i915_gem_retire_requests(dev); | 2456 | i915_gem_retire_requests(dev); |
| 2301 | 2457 | ||
| 2302 | /* Active and flushing should now be empty as we've | 2458 | if (!dev_priv->mm.wedged) { |
| 2303 | * waited for a sequence higher than any pending execbuffer | 2459 | /* Active and flushing should now be empty as we've |
| 2304 | */ | 2460 | * waited for a sequence higher than any pending execbuffer |
| 2305 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 2461 | */ |
| 2306 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 2462 | WARN_ON(!list_empty(&dev_priv->mm.active_list)); |
| 2463 | WARN_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
| 2464 | /* Request should now be empty as we've also waited | ||
| 2465 | * for the last request in the list | ||
| 2466 | */ | ||
| 2467 | WARN_ON(!list_empty(&dev_priv->mm.request_list)); | ||
| 2468 | } | ||
| 2307 | 2469 | ||
| 2308 | /* Request should now be empty as we've also waited | 2470 | /* Empty the active and flushing lists to inactive. If there's |
| 2309 | * for the last request in the list | 2471 | * anything left at this point, it means that we're wedged and |
| 2472 | * nothing good's going to happen by leaving them there. So strip | ||
| 2473 | * the GPU domains and just stuff them onto inactive. | ||
| 2310 | */ | 2474 | */ |
| 2311 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | 2475 | while (!list_empty(&dev_priv->mm.active_list)) { |
| 2476 | struct drm_i915_gem_object *obj_priv; | ||
| 2477 | |||
| 2478 | obj_priv = list_first_entry(&dev_priv->mm.active_list, | ||
| 2479 | struct drm_i915_gem_object, | ||
| 2480 | list); | ||
| 2481 | obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; | ||
| 2482 | i915_gem_object_move_to_inactive(obj_priv->obj); | ||
| 2483 | } | ||
| 2484 | |||
| 2485 | while (!list_empty(&dev_priv->mm.flushing_list)) { | ||
| 2486 | struct drm_i915_gem_object *obj_priv; | ||
| 2312 | 2487 | ||
| 2313 | /* Move all buffers out of the GTT. */ | 2488 | obj_priv = list_first_entry(&dev_priv->mm.flushing_list, |
| 2489 | struct drm_i915_gem_object, | ||
| 2490 | list); | ||
| 2491 | obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; | ||
| 2492 | i915_gem_object_move_to_inactive(obj_priv->obj); | ||
| 2493 | } | ||
| 2494 | |||
| 2495 | |||
| 2496 | /* Move all inactive buffers out of the GTT. */ | ||
| 2314 | ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); | 2497 | ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); |
| 2498 | WARN_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
| 2315 | if (ret) { | 2499 | if (ret) { |
| 2316 | mutex_unlock(&dev->struct_mutex); | 2500 | mutex_unlock(&dev->struct_mutex); |
| 2317 | return ret; | 2501 | return ret; |
| 2318 | } | 2502 | } |
| 2319 | 2503 | ||
| 2320 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | ||
| 2321 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
| 2322 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
| 2323 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | ||
| 2324 | |||
| 2325 | i915_gem_cleanup_ringbuffer(dev); | 2504 | i915_gem_cleanup_ringbuffer(dev); |
| 2326 | mutex_unlock(&dev->struct_mutex); | 2505 | mutex_unlock(&dev->struct_mutex); |
| 2327 | 2506 | ||
| @@ -2518,6 +2697,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
| 2518 | if (ret != 0) | 2697 | if (ret != 0) |
| 2519 | return ret; | 2698 | return ret; |
| 2520 | 2699 | ||
| 2700 | dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, | ||
| 2701 | dev->agp->agp_info.aper_size | ||
| 2702 | * 1024 * 1024); | ||
| 2703 | |||
| 2521 | mutex_lock(&dev->struct_mutex); | 2704 | mutex_lock(&dev->struct_mutex); |
| 2522 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 2705 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); |
| 2523 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 2706 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
| @@ -2535,11 +2718,13 @@ int | |||
| 2535 | i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, | 2718 | i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, |
| 2536 | struct drm_file *file_priv) | 2719 | struct drm_file *file_priv) |
| 2537 | { | 2720 | { |
| 2721 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2538 | int ret; | 2722 | int ret; |
| 2539 | 2723 | ||
| 2540 | ret = i915_gem_idle(dev); | 2724 | ret = i915_gem_idle(dev); |
| 2541 | drm_irq_uninstall(dev); | 2725 | drm_irq_uninstall(dev); |
| 2542 | 2726 | ||
| 2727 | io_mapping_free(dev_priv->mm.gtt_mapping); | ||
| 2543 | return ret; | 2728 | return ret; |
| 2544 | } | 2729 | } |
| 2545 | 2730 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c index 93de15b4c9a7..e8d5abe1250e 100644 --- a/drivers/gpu/drm/i915/i915_gem_proc.c +++ b/drivers/gpu/drm/i915/i915_gem_proc.c | |||
| @@ -166,10 +166,9 @@ static int i915_gem_request_info(char *buf, char **start, off_t offset, | |||
| 166 | list_for_each_entry(gem_request, &dev_priv->mm.request_list, | 166 | list_for_each_entry(gem_request, &dev_priv->mm.request_list, |
| 167 | list) | 167 | list) |
| 168 | { | 168 | { |
| 169 | DRM_PROC_PRINT(" %d @ %d %08x\n", | 169 | DRM_PROC_PRINT(" %d @ %d\n", |
| 170 | gem_request->seqno, | 170 | gem_request->seqno, |
| 171 | (int) (jiffies - gem_request->emitted_jiffies), | 171 | (int) (jiffies - gem_request->emitted_jiffies)); |
| 172 | gem_request->flush_domains); | ||
| 173 | } | 172 | } |
| 174 | if (len > request + offset) | 173 | if (len > request + offset) |
| 175 | return request; | 174 | return request; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index e8b85ac4ca04..a8cb69469c64 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -119,9 +119,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
| 119 | dcc & DCC_CHANNEL_XOR_DISABLE) { | 119 | dcc & DCC_CHANNEL_XOR_DISABLE) { |
| 120 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | 120 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; |
| 121 | swizzle_y = I915_BIT_6_SWIZZLE_9; | 121 | swizzle_y = I915_BIT_6_SWIZZLE_9; |
| 122 | } else if (IS_I965GM(dev) || IS_GM45(dev)) { | 122 | } else if ((IS_I965GM(dev) || IS_GM45(dev)) && |
| 123 | /* GM965 only does bit 11-based channel | 123 | (dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { |
| 124 | * randomization | 124 | /* GM965/GM45 does either bit 11 or bit 17 |
| 125 | * swizzling. | ||
| 125 | */ | 126 | */ |
| 126 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; | 127 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; |
| 127 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; | 128 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26f48932a51e..69b9a42da95e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -33,11 +33,23 @@ | |||
| 33 | 33 | ||
| 34 | #define MAX_NOPID ((u32)~0) | 34 | #define MAX_NOPID ((u32)~0) |
| 35 | 35 | ||
| 36 | /** These are the interrupts used by the driver */ | 36 | /** |
| 37 | #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ | 37 | * Interrupts that are always left unmasked. |
| 38 | I915_ASLE_INTERRUPT | \ | 38 | * |
| 39 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | 39 | * Since pipe events are edge-triggered from the PIPESTAT register to IIR, |
| 40 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | 40 | * we leave them always unmasked in IMR and then control enabling them through |
| 41 | * PIPESTAT alone. | ||
| 42 | */ | ||
| 43 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ | ||
| 44 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | ||
| 45 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | ||
| 46 | |||
| 47 | /** Interrupts that we mask and unmask at runtime. */ | ||
| 48 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | ||
| 49 | |||
| 50 | /** These are all of the interrupts used by the driver */ | ||
| 51 | #define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \ | ||
| 52 | I915_INTERRUPT_ENABLE_VAR) | ||
| 41 | 53 | ||
| 42 | void | 54 | void |
| 43 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | 55 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) |
| @@ -59,6 +71,41 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | |||
| 59 | } | 71 | } |
| 60 | } | 72 | } |
| 61 | 73 | ||
| 74 | static inline u32 | ||
| 75 | i915_pipestat(int pipe) | ||
| 76 | { | ||
| 77 | if (pipe == 0) | ||
| 78 | return PIPEASTAT; | ||
| 79 | if (pipe == 1) | ||
| 80 | return PIPEBSTAT; | ||
| 81 | BUG(); | ||
| 82 | } | ||
| 83 | |||
| 84 | void | ||
| 85 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) | ||
| 86 | { | ||
| 87 | if ((dev_priv->pipestat[pipe] & mask) != mask) { | ||
| 88 | u32 reg = i915_pipestat(pipe); | ||
| 89 | |||
| 90 | dev_priv->pipestat[pipe] |= mask; | ||
| 91 | /* Enable the interrupt, clear any pending status */ | ||
| 92 | I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16)); | ||
| 93 | (void) I915_READ(reg); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | void | ||
| 98 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) | ||
| 99 | { | ||
| 100 | if ((dev_priv->pipestat[pipe] & mask) != 0) { | ||
| 101 | u32 reg = i915_pipestat(pipe); | ||
| 102 | |||
| 103 | dev_priv->pipestat[pipe] &= ~mask; | ||
| 104 | I915_WRITE(reg, dev_priv->pipestat[pipe]); | ||
| 105 | (void) I915_READ(reg); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 62 | /** | 109 | /** |
| 63 | * i915_pipe_enabled - check if a pipe is enabled | 110 | * i915_pipe_enabled - check if a pipe is enabled |
| 64 | * @dev: DRM device | 111 | * @dev: DRM device |
| @@ -80,211 +127,6 @@ i915_pipe_enabled(struct drm_device *dev, int pipe) | |||
| 80 | return 0; | 127 | return 0; |
| 81 | } | 128 | } |
| 82 | 129 | ||
| 83 | /** | ||
| 84 | * Emit blits for scheduled buffer swaps. | ||
| 85 | * | ||
| 86 | * This function will be called with the HW lock held. | ||
| 87 | * Because this function must grab the ring mutex (dev->struct_mutex), | ||
| 88 | * it can no longer run at soft irq time. We'll fix this when we do | ||
| 89 | * the DRI2 swap buffer work. | ||
| 90 | */ | ||
| 91 | static void i915_vblank_tasklet(struct drm_device *dev) | ||
| 92 | { | ||
| 93 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
| 94 | unsigned long irqflags; | ||
| 95 | struct list_head *list, *tmp, hits, *hit; | ||
| 96 | int nhits, nrects, slice[2], upper[2], lower[2], i; | ||
| 97 | unsigned counter[2]; | ||
| 98 | struct drm_drawable_info *drw; | ||
| 99 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | ||
| 100 | u32 cpp = dev_priv->cpp; | ||
| 101 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | | ||
| 102 | XY_SRC_COPY_BLT_WRITE_ALPHA | | ||
| 103 | XY_SRC_COPY_BLT_WRITE_RGB) | ||
| 104 | : XY_SRC_COPY_BLT_CMD; | ||
| 105 | u32 src_pitch = sarea_priv->pitch * cpp; | ||
| 106 | u32 dst_pitch = sarea_priv->pitch * cpp; | ||
| 107 | u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); | ||
| 108 | RING_LOCALS; | ||
| 109 | |||
| 110 | mutex_lock(&dev->struct_mutex); | ||
| 111 | |||
| 112 | if (IS_I965G(dev) && sarea_priv->front_tiled) { | ||
| 113 | cmd |= XY_SRC_COPY_BLT_DST_TILED; | ||
| 114 | dst_pitch >>= 2; | ||
| 115 | } | ||
| 116 | if (IS_I965G(dev) && sarea_priv->back_tiled) { | ||
| 117 | cmd |= XY_SRC_COPY_BLT_SRC_TILED; | ||
| 118 | src_pitch >>= 2; | ||
| 119 | } | ||
| 120 | |||
| 121 | counter[0] = drm_vblank_count(dev, 0); | ||
| 122 | counter[1] = drm_vblank_count(dev, 1); | ||
| 123 | |||
| 124 | DRM_DEBUG("\n"); | ||
| 125 | |||
| 126 | INIT_LIST_HEAD(&hits); | ||
| 127 | |||
| 128 | nhits = nrects = 0; | ||
| 129 | |||
| 130 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | ||
| 131 | |||
| 132 | /* Find buffer swaps scheduled for this vertical blank */ | ||
| 133 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { | ||
| 134 | drm_i915_vbl_swap_t *vbl_swap = | ||
| 135 | list_entry(list, drm_i915_vbl_swap_t, head); | ||
| 136 | int pipe = vbl_swap->pipe; | ||
| 137 | |||
| 138 | if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) | ||
| 139 | continue; | ||
| 140 | |||
| 141 | list_del(list); | ||
| 142 | dev_priv->swaps_pending--; | ||
| 143 | drm_vblank_put(dev, pipe); | ||
| 144 | |||
| 145 | spin_unlock(&dev_priv->swaps_lock); | ||
| 146 | spin_lock(&dev->drw_lock); | ||
| 147 | |||
| 148 | drw = drm_get_drawable_info(dev, vbl_swap->drw_id); | ||
| 149 | |||
| 150 | list_for_each(hit, &hits) { | ||
| 151 | drm_i915_vbl_swap_t *swap_cmp = | ||
| 152 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
| 153 | struct drm_drawable_info *drw_cmp = | ||
| 154 | drm_get_drawable_info(dev, swap_cmp->drw_id); | ||
| 155 | |||
| 156 | /* Make sure both drawables are still | ||
| 157 | * around and have some rectangles before | ||
| 158 | * we look inside to order them for the | ||
| 159 | * blts below. | ||
| 160 | */ | ||
| 161 | if (drw_cmp && drw_cmp->num_rects > 0 && | ||
| 162 | drw && drw->num_rects > 0 && | ||
| 163 | drw_cmp->rects[0].y1 > drw->rects[0].y1) { | ||
| 164 | list_add_tail(list, hit); | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | spin_unlock(&dev->drw_lock); | ||
| 170 | |||
| 171 | /* List of hits was empty, or we reached the end of it */ | ||
| 172 | if (hit == &hits) | ||
| 173 | list_add_tail(list, hits.prev); | ||
| 174 | |||
| 175 | nhits++; | ||
| 176 | |||
| 177 | spin_lock(&dev_priv->swaps_lock); | ||
| 178 | } | ||
| 179 | |||
| 180 | if (nhits == 0) { | ||
| 181 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
| 182 | mutex_unlock(&dev->struct_mutex); | ||
| 183 | return; | ||
| 184 | } | ||
| 185 | |||
| 186 | spin_unlock(&dev_priv->swaps_lock); | ||
| 187 | |||
| 188 | i915_kernel_lost_context(dev); | ||
| 189 | |||
| 190 | if (IS_I965G(dev)) { | ||
| 191 | BEGIN_LP_RING(4); | ||
| 192 | |||
| 193 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | ||
| 194 | OUT_RING(0); | ||
| 195 | OUT_RING(((sarea_priv->width - 1) & 0xffff) | ((sarea_priv->height - 1) << 16)); | ||
| 196 | OUT_RING(0); | ||
| 197 | ADVANCE_LP_RING(); | ||
| 198 | } else { | ||
| 199 | BEGIN_LP_RING(6); | ||
| 200 | |||
| 201 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
| 202 | OUT_RING(0); | ||
| 203 | OUT_RING(0); | ||
| 204 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
| 205 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
| 206 | OUT_RING(0); | ||
| 207 | |||
| 208 | ADVANCE_LP_RING(); | ||
| 209 | } | ||
| 210 | |||
| 211 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | ||
| 212 | |||
| 213 | upper[0] = upper[1] = 0; | ||
| 214 | slice[0] = max(sarea_priv->pipeA_h / nhits, 1); | ||
| 215 | slice[1] = max(sarea_priv->pipeB_h / nhits, 1); | ||
| 216 | lower[0] = sarea_priv->pipeA_y + slice[0]; | ||
| 217 | lower[1] = sarea_priv->pipeB_y + slice[0]; | ||
| 218 | |||
| 219 | spin_lock(&dev->drw_lock); | ||
| 220 | |||
| 221 | /* Emit blits for buffer swaps, partitioning both outputs into as many | ||
| 222 | * slices as there are buffer swaps scheduled in order to avoid tearing | ||
| 223 | * (based on the assumption that a single buffer swap would always | ||
| 224 | * complete before scanout starts). | ||
| 225 | */ | ||
| 226 | for (i = 0; i++ < nhits; | ||
| 227 | upper[0] = lower[0], lower[0] += slice[0], | ||
| 228 | upper[1] = lower[1], lower[1] += slice[1]) { | ||
| 229 | if (i == nhits) | ||
| 230 | lower[0] = lower[1] = sarea_priv->height; | ||
| 231 | |||
| 232 | list_for_each(hit, &hits) { | ||
| 233 | drm_i915_vbl_swap_t *swap_hit = | ||
| 234 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
| 235 | struct drm_clip_rect *rect; | ||
| 236 | int num_rects, pipe; | ||
| 237 | unsigned short top, bottom; | ||
| 238 | |||
| 239 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); | ||
| 240 | |||
| 241 | /* The drawable may have been destroyed since | ||
| 242 | * the vblank swap was queued | ||
| 243 | */ | ||
| 244 | if (!drw) | ||
| 245 | continue; | ||
| 246 | |||
| 247 | rect = drw->rects; | ||
| 248 | pipe = swap_hit->pipe; | ||
| 249 | top = upper[pipe]; | ||
| 250 | bottom = lower[pipe]; | ||
| 251 | |||
| 252 | for (num_rects = drw->num_rects; num_rects--; rect++) { | ||
| 253 | int y1 = max(rect->y1, top); | ||
| 254 | int y2 = min(rect->y2, bottom); | ||
| 255 | |||
| 256 | if (y1 >= y2) | ||
| 257 | continue; | ||
| 258 | |||
| 259 | BEGIN_LP_RING(8); | ||
| 260 | |||
| 261 | OUT_RING(cmd); | ||
| 262 | OUT_RING(ropcpp | dst_pitch); | ||
| 263 | OUT_RING((y1 << 16) | rect->x1); | ||
| 264 | OUT_RING((y2 << 16) | rect->x2); | ||
| 265 | OUT_RING(sarea_priv->front_offset); | ||
| 266 | OUT_RING((y1 << 16) | rect->x1); | ||
| 267 | OUT_RING(src_pitch); | ||
| 268 | OUT_RING(sarea_priv->back_offset); | ||
| 269 | |||
| 270 | ADVANCE_LP_RING(); | ||
| 271 | } | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
| 276 | mutex_unlock(&dev->struct_mutex); | ||
| 277 | |||
| 278 | list_for_each_safe(hit, tmp, &hits) { | ||
| 279 | drm_i915_vbl_swap_t *swap_hit = | ||
| 280 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
| 281 | |||
| 282 | list_del(hit); | ||
| 283 | |||
| 284 | drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER); | ||
| 285 | } | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Called from drm generic code, passed a 'crtc', which | 130 | /* Called from drm generic code, passed a 'crtc', which |
| 289 | * we use as a pipe index | 131 | * we use as a pipe index |
| 290 | */ | 132 | */ |
| @@ -322,121 +164,106 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
| 322 | return count; | 164 | return count; |
| 323 | } | 165 | } |
| 324 | 166 | ||
| 325 | void | ||
| 326 | i915_vblank_work_handler(struct work_struct *work) | ||
| 327 | { | ||
| 328 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
| 329 | vblank_work); | ||
| 330 | struct drm_device *dev = dev_priv->dev; | ||
| 331 | unsigned long irqflags; | ||
| 332 | |||
| 333 | if (dev->lock.hw_lock == NULL) { | ||
| 334 | i915_vblank_tasklet(dev); | ||
| 335 | return; | ||
| 336 | } | ||
| 337 | |||
| 338 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 339 | dev->locked_tasklet_func = i915_vblank_tasklet; | ||
| 340 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 341 | |||
| 342 | /* Try to get the lock now, if this fails, the lock | ||
| 343 | * holder will execute the tasklet during unlock | ||
| 344 | */ | ||
| 345 | if (!drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT)) | ||
| 346 | return; | ||
| 347 | |||
| 348 | dev->lock.lock_time = jiffies; | ||
| 349 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
| 350 | |||
| 351 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
| 352 | dev->locked_tasklet_func = NULL; | ||
| 353 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
| 354 | |||
| 355 | i915_vblank_tasklet(dev); | ||
| 356 | drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT); | ||
| 357 | } | ||
| 358 | |||
| 359 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 167 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
| 360 | { | 168 | { |
| 361 | struct drm_device *dev = (struct drm_device *) arg; | 169 | struct drm_device *dev = (struct drm_device *) arg; |
| 362 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 170 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 363 | u32 iir; | 171 | u32 iir, new_iir; |
| 364 | u32 pipea_stats, pipeb_stats; | 172 | u32 pipea_stats, pipeb_stats; |
| 173 | u32 vblank_status; | ||
| 174 | u32 vblank_enable; | ||
| 365 | int vblank = 0; | 175 | int vblank = 0; |
| 176 | unsigned long irqflags; | ||
| 177 | int irq_received; | ||
| 178 | int ret = IRQ_NONE; | ||
| 366 | 179 | ||
| 367 | atomic_inc(&dev_priv->irq_received); | 180 | atomic_inc(&dev_priv->irq_received); |
| 368 | 181 | ||
| 369 | if (dev->pdev->msi_enabled) | ||
| 370 | I915_WRITE(IMR, ~0); | ||
| 371 | iir = I915_READ(IIR); | 182 | iir = I915_READ(IIR); |
| 372 | 183 | ||
| 373 | if (iir == 0) { | 184 | if (IS_I965G(dev)) { |
| 374 | if (dev->pdev->msi_enabled) { | 185 | vblank_status = I915_START_VBLANK_INTERRUPT_STATUS; |
| 375 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | 186 | vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE; |
| 376 | (void) I915_READ(IMR); | 187 | } else { |
| 377 | } | 188 | vblank_status = I915_VBLANK_INTERRUPT_STATUS; |
| 378 | return IRQ_NONE; | 189 | vblank_enable = I915_VBLANK_INTERRUPT_ENABLE; |
| 379 | } | 190 | } |
| 380 | 191 | ||
| 381 | /* | 192 | for (;;) { |
| 382 | * Clear the PIPE(A|B)STAT regs before the IIR otherwise | 193 | irq_received = iir != 0; |
| 383 | * we may get extra interrupts. | 194 | |
| 384 | */ | 195 | /* Can't rely on pipestat interrupt bit in iir as it might |
| 385 | if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { | 196 | * have been cleared after the pipestat interrupt was received. |
| 197 | * It doesn't set the bit in iir again, but it still produces | ||
| 198 | * interrupts (for non-MSI). | ||
| 199 | */ | ||
| 200 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | ||
| 386 | pipea_stats = I915_READ(PIPEASTAT); | 201 | pipea_stats = I915_READ(PIPEASTAT); |
| 387 | if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)) | 202 | pipeb_stats = I915_READ(PIPEBSTAT); |
| 388 | pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | | 203 | /* |
| 389 | PIPE_VBLANK_INTERRUPT_ENABLE); | 204 | * Clear the PIPE(A|B)STAT regs before the IIR |
| 390 | else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| | 205 | */ |
| 391 | PIPE_VBLANK_INTERRUPT_STATUS)) { | 206 | if (pipea_stats & 0x8000ffff) { |
| 207 | I915_WRITE(PIPEASTAT, pipea_stats); | ||
| 208 | irq_received = 1; | ||
| 209 | } | ||
| 210 | |||
| 211 | if (pipeb_stats & 0x8000ffff) { | ||
| 212 | I915_WRITE(PIPEBSTAT, pipeb_stats); | ||
| 213 | irq_received = 1; | ||
| 214 | } | ||
| 215 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | ||
| 216 | |||
| 217 | if (!irq_received) | ||
| 218 | break; | ||
| 219 | |||
| 220 | ret = IRQ_HANDLED; | ||
| 221 | |||
| 222 | I915_WRITE(IIR, iir); | ||
| 223 | new_iir = I915_READ(IIR); /* Flush posted writes */ | ||
| 224 | |||
| 225 | if (dev_priv->sarea_priv) | ||
| 226 | dev_priv->sarea_priv->last_dispatch = | ||
| 227 | READ_BREADCRUMB(dev_priv); | ||
| 228 | |||
| 229 | if (iir & I915_USER_INTERRUPT) { | ||
| 230 | dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); | ||
| 231 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
| 232 | } | ||
| 233 | |||
| 234 | if (pipea_stats & vblank_status) { | ||
| 392 | vblank++; | 235 | vblank++; |
| 393 | drm_handle_vblank(dev, 0); | 236 | drm_handle_vblank(dev, 0); |
| 394 | } | 237 | } |
| 395 | 238 | ||
| 396 | I915_WRITE(PIPEASTAT, pipea_stats); | 239 | if (pipeb_stats & vblank_status) { |
| 397 | } | ||
| 398 | if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { | ||
| 399 | pipeb_stats = I915_READ(PIPEBSTAT); | ||
| 400 | /* Ack the event */ | ||
| 401 | I915_WRITE(PIPEBSTAT, pipeb_stats); | ||
| 402 | |||
| 403 | /* The vblank interrupt gets enabled even if we didn't ask for | ||
| 404 | it, so make sure it's shut down again */ | ||
| 405 | if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)) | ||
| 406 | pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | | ||
| 407 | PIPE_VBLANK_INTERRUPT_ENABLE); | ||
| 408 | else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| | ||
| 409 | PIPE_VBLANK_INTERRUPT_STATUS)) { | ||
| 410 | vblank++; | 240 | vblank++; |
| 411 | drm_handle_vblank(dev, 1); | 241 | drm_handle_vblank(dev, 1); |
| 412 | } | 242 | } |
| 413 | 243 | ||
| 414 | if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) | 244 | if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || |
| 245 | (iir & I915_ASLE_INTERRUPT)) | ||
| 415 | opregion_asle_intr(dev); | 246 | opregion_asle_intr(dev); |
| 416 | I915_WRITE(PIPEBSTAT, pipeb_stats); | ||
| 417 | } | ||
| 418 | |||
| 419 | I915_WRITE(IIR, iir); | ||
| 420 | if (dev->pdev->msi_enabled) | ||
| 421 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
| 422 | (void) I915_READ(IIR); /* Flush posted writes */ | ||
| 423 | |||
| 424 | if (dev_priv->sarea_priv) | ||
| 425 | dev_priv->sarea_priv->last_dispatch = | ||
| 426 | READ_BREADCRUMB(dev_priv); | ||
| 427 | 247 | ||
| 428 | if (iir & I915_USER_INTERRUPT) { | 248 | /* With MSI, interrupts are only generated when iir |
| 429 | dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); | 249 | * transitions from zero to nonzero. If another bit got |
| 430 | DRM_WAKEUP(&dev_priv->irq_queue); | 250 | * set while we were handling the existing iir bits, then |
| 251 | * we would never get another interrupt. | ||
| 252 | * | ||
| 253 | * This is fine on non-MSI as well, as if we hit this path | ||
| 254 | * we avoid exiting the interrupt handler only to generate | ||
| 255 | * another one. | ||
| 256 | * | ||
| 257 | * Note that for MSI this could cause a stray interrupt report | ||
| 258 | * if an interrupt landed in the time between writing IIR and | ||
| 259 | * the posting read. This should be rare enough to never | ||
| 260 | * trigger the 99% of 100,000 interrupts test for disabling | ||
| 261 | * stray interrupts. | ||
| 262 | */ | ||
| 263 | iir = new_iir; | ||
| 431 | } | 264 | } |
| 432 | 265 | ||
| 433 | if (iir & I915_ASLE_INTERRUPT) | 266 | return ret; |
| 434 | opregion_asle_intr(dev); | ||
| 435 | |||
| 436 | if (vblank && dev_priv->swaps_pending > 0) | ||
| 437 | schedule_work(&dev_priv->vblank_work); | ||
| 438 | |||
| 439 | return IRQ_HANDLED; | ||
| 440 | } | 267 | } |
| 441 | 268 | ||
| 442 | static int i915_emit_irq(struct drm_device * dev) | 269 | static int i915_emit_irq(struct drm_device * dev) |
| @@ -454,12 +281,10 @@ static int i915_emit_irq(struct drm_device * dev) | |||
| 454 | if (dev_priv->sarea_priv) | 281 | if (dev_priv->sarea_priv) |
| 455 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; | 282 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; |
| 456 | 283 | ||
| 457 | BEGIN_LP_RING(6); | 284 | BEGIN_LP_RING(4); |
| 458 | OUT_RING(MI_STORE_DWORD_INDEX); | 285 | OUT_RING(MI_STORE_DWORD_INDEX); |
| 459 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); | 286 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
| 460 | OUT_RING(dev_priv->counter); | 287 | OUT_RING(dev_priv->counter); |
| 461 | OUT_RING(0); | ||
| 462 | OUT_RING(0); | ||
| 463 | OUT_RING(MI_USER_INTERRUPT); | 288 | OUT_RING(MI_USER_INTERRUPT); |
| 464 | ADVANCE_LP_RING(); | 289 | ADVANCE_LP_RING(); |
| 465 | 290 | ||
| @@ -574,48 +399,16 @@ int i915_irq_wait(struct drm_device *dev, void *data, | |||
| 574 | int i915_enable_vblank(struct drm_device *dev, int pipe) | 399 | int i915_enable_vblank(struct drm_device *dev, int pipe) |
| 575 | { | 400 | { |
| 576 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 401 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 577 | u32 pipestat_reg = 0; | ||
| 578 | u32 pipestat; | ||
| 579 | u32 interrupt = 0; | ||
| 580 | unsigned long irqflags; | 402 | unsigned long irqflags; |
| 581 | 403 | ||
| 582 | switch (pipe) { | ||
| 583 | case 0: | ||
| 584 | pipestat_reg = PIPEASTAT; | ||
| 585 | interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
| 586 | break; | ||
| 587 | case 1: | ||
| 588 | pipestat_reg = PIPEBSTAT; | ||
| 589 | interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
| 590 | break; | ||
| 591 | default: | ||
| 592 | DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", | ||
| 593 | pipe); | ||
| 594 | return 0; | ||
| 595 | } | ||
| 596 | |||
| 597 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 404 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
| 598 | /* Enabling vblank events in IMR comes before PIPESTAT write, or | ||
| 599 | * there's a race where the PIPESTAT vblank bit gets set to 1, so | ||
| 600 | * the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in | ||
| 601 | * ISR flashes to 1, but the IIR bit doesn't get set to 1 because | ||
| 602 | * IMR masks it. It doesn't ever get set after we clear the masking | ||
| 603 | * in IMR because the ISR bit is edge, not level-triggered, on the | ||
| 604 | * OR of PIPESTAT bits. | ||
| 605 | */ | ||
| 606 | i915_enable_irq(dev_priv, interrupt); | ||
| 607 | pipestat = I915_READ(pipestat_reg); | ||
| 608 | if (IS_I965G(dev)) | 405 | if (IS_I965G(dev)) |
| 609 | pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; | 406 | i915_enable_pipestat(dev_priv, pipe, |
| 407 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | ||
| 610 | else | 408 | else |
| 611 | pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; | 409 | i915_enable_pipestat(dev_priv, pipe, |
| 612 | /* Clear any stale interrupt status */ | 410 | PIPE_VBLANK_INTERRUPT_ENABLE); |
| 613 | pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | | ||
| 614 | PIPE_VBLANK_INTERRUPT_STATUS); | ||
| 615 | I915_WRITE(pipestat_reg, pipestat); | ||
| 616 | (void) I915_READ(pipestat_reg); /* Posting read */ | ||
| 617 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 411 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); |
| 618 | |||
| 619 | return 0; | 412 | return 0; |
| 620 | } | 413 | } |
| 621 | 414 | ||
| @@ -625,37 +418,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
| 625 | void i915_disable_vblank(struct drm_device *dev, int pipe) | 418 | void i915_disable_vblank(struct drm_device *dev, int pipe) |
| 626 | { | 419 | { |
| 627 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 420 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 628 | u32 pipestat_reg = 0; | ||
| 629 | u32 pipestat; | ||
| 630 | u32 interrupt = 0; | ||
| 631 | unsigned long irqflags; | 421 | unsigned long irqflags; |
| 632 | 422 | ||
| 633 | switch (pipe) { | ||
| 634 | case 0: | ||
| 635 | pipestat_reg = PIPEASTAT; | ||
| 636 | interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
| 637 | break; | ||
| 638 | case 1: | ||
| 639 | pipestat_reg = PIPEBSTAT; | ||
| 640 | interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
| 641 | break; | ||
| 642 | default: | ||
| 643 | DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", | ||
| 644 | pipe); | ||
| 645 | return; | ||
| 646 | break; | ||
| 647 | } | ||
| 648 | |||
| 649 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 423 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
| 650 | i915_disable_irq(dev_priv, interrupt); | 424 | i915_disable_pipestat(dev_priv, pipe, |
| 651 | pipestat = I915_READ(pipestat_reg); | 425 | PIPE_VBLANK_INTERRUPT_ENABLE | |
| 652 | pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | | 426 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
| 653 | PIPE_VBLANK_INTERRUPT_ENABLE); | ||
| 654 | /* Clear any stale interrupt status */ | ||
| 655 | pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | | ||
| 656 | PIPE_VBLANK_INTERRUPT_STATUS); | ||
| 657 | I915_WRITE(pipestat_reg, pipestat); | ||
| 658 | (void) I915_READ(pipestat_reg); /* Posting read */ | ||
| 659 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 427 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); |
| 660 | } | 428 | } |
| 661 | 429 | ||
| @@ -696,123 +464,21 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
| 696 | int i915_vblank_swap(struct drm_device *dev, void *data, | 464 | int i915_vblank_swap(struct drm_device *dev, void *data, |
| 697 | struct drm_file *file_priv) | 465 | struct drm_file *file_priv) |
| 698 | { | 466 | { |
| 699 | drm_i915_private_t *dev_priv = dev->dev_private; | 467 | /* The delayed swap mechanism was fundamentally racy, and has been |
| 700 | drm_i915_vblank_swap_t *swap = data; | 468 | * removed. The model was that the client requested a delayed flip/swap |
| 701 | drm_i915_vbl_swap_t *vbl_swap, *vbl_old; | 469 | * from the kernel, then waited for vblank before continuing to perform |
| 702 | unsigned int pipe, seqtype, curseq; | 470 | * rendering. The problem was that the kernel might wake the client |
| 703 | unsigned long irqflags; | 471 | * up before it dispatched the vblank swap (since the lock has to be |
| 704 | struct list_head *list; | 472 | * held while touching the ringbuffer), in which case the client would |
| 705 | int ret; | 473 | * clear and start the next frame before the swap occurred, and |
| 706 | 474 | * flicker would occur in addition to likely missing the vblank. | |
| 707 | if (!dev_priv || !dev_priv->sarea_priv) { | 475 | * |
| 708 | DRM_ERROR("%s called with no initialization\n", __func__); | 476 | * In the absence of this ioctl, userland falls back to a correct path |
| 709 | return -EINVAL; | 477 | * of waiting for a vblank, then dispatching the swap on its own. |
| 710 | } | 478 | * Context switching to userland and back is plenty fast enough for |
| 711 | 479 | * meeting the requirements of vblank swapping. | |
| 712 | if (dev_priv->sarea_priv->rotation) { | ||
| 713 | DRM_DEBUG("Rotation not supported\n"); | ||
| 714 | return -EINVAL; | ||
| 715 | } | ||
| 716 | |||
| 717 | if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | | ||
| 718 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { | ||
| 719 | DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); | ||
| 720 | return -EINVAL; | ||
| 721 | } | ||
| 722 | |||
| 723 | pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; | ||
| 724 | |||
| 725 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); | ||
| 726 | |||
| 727 | if (!(dev_priv->vblank_pipe & (1 << pipe))) { | ||
| 728 | DRM_ERROR("Invalid pipe %d\n", pipe); | ||
| 729 | return -EINVAL; | ||
| 730 | } | ||
| 731 | |||
| 732 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
| 733 | |||
| 734 | if (!drm_get_drawable_info(dev, swap->drawable)) { | ||
| 735 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
| 736 | DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); | ||
| 737 | return -EINVAL; | ||
| 738 | } | ||
| 739 | |||
| 740 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
| 741 | |||
| 742 | /* | ||
| 743 | * We take the ref here and put it when the swap actually completes | ||
| 744 | * in the tasklet. | ||
| 745 | */ | 480 | */ |
| 746 | ret = drm_vblank_get(dev, pipe); | 481 | return -EINVAL; |
| 747 | if (ret) | ||
| 748 | return ret; | ||
| 749 | curseq = drm_vblank_count(dev, pipe); | ||
| 750 | |||
| 751 | if (seqtype == _DRM_VBLANK_RELATIVE) | ||
| 752 | swap->sequence += curseq; | ||
| 753 | |||
| 754 | if ((curseq - swap->sequence) <= (1<<23)) { | ||
| 755 | if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) { | ||
| 756 | swap->sequence = curseq + 1; | ||
| 757 | } else { | ||
| 758 | DRM_DEBUG("Missed target sequence\n"); | ||
| 759 | drm_vblank_put(dev, pipe); | ||
| 760 | return -EINVAL; | ||
| 761 | } | ||
| 762 | } | ||
| 763 | |||
| 764 | vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
| 765 | |||
| 766 | if (!vbl_swap) { | ||
| 767 | DRM_ERROR("Failed to allocate memory to queue swap\n"); | ||
| 768 | drm_vblank_put(dev, pipe); | ||
| 769 | return -ENOMEM; | ||
| 770 | } | ||
| 771 | |||
| 772 | vbl_swap->drw_id = swap->drawable; | ||
| 773 | vbl_swap->pipe = pipe; | ||
| 774 | vbl_swap->sequence = swap->sequence; | ||
| 775 | |||
| 776 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | ||
| 777 | |||
| 778 | list_for_each(list, &dev_priv->vbl_swaps.head) { | ||
| 779 | vbl_old = list_entry(list, drm_i915_vbl_swap_t, head); | ||
| 780 | |||
| 781 | if (vbl_old->drw_id == swap->drawable && | ||
| 782 | vbl_old->pipe == pipe && | ||
| 783 | vbl_old->sequence == swap->sequence) { | ||
| 784 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
| 785 | drm_vblank_put(dev, pipe); | ||
| 786 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
| 787 | DRM_DEBUG("Already scheduled\n"); | ||
| 788 | return 0; | ||
| 789 | } | ||
| 790 | } | ||
| 791 | |||
| 792 | if (dev_priv->swaps_pending >= 10) { | ||
| 793 | DRM_DEBUG("Too many swaps queued\n"); | ||
| 794 | DRM_DEBUG(" pipe 0: %d pipe 1: %d\n", | ||
| 795 | drm_vblank_count(dev, 0), | ||
| 796 | drm_vblank_count(dev, 1)); | ||
| 797 | |||
| 798 | list_for_each(list, &dev_priv->vbl_swaps.head) { | ||
| 799 | vbl_old = list_entry(list, drm_i915_vbl_swap_t, head); | ||
| 800 | DRM_DEBUG("\tdrw %x pipe %d seq %x\n", | ||
| 801 | vbl_old->drw_id, vbl_old->pipe, | ||
| 802 | vbl_old->sequence); | ||
| 803 | } | ||
| 804 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
| 805 | drm_vblank_put(dev, pipe); | ||
| 806 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
| 807 | return -EBUSY; | ||
| 808 | } | ||
| 809 | |||
| 810 | list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head); | ||
| 811 | dev_priv->swaps_pending++; | ||
| 812 | |||
| 813 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
| 814 | |||
| 815 | return 0; | ||
| 816 | } | 482 | } |
| 817 | 483 | ||
| 818 | /* drm_dma.h hooks | 484 | /* drm_dma.h hooks |
| @@ -822,37 +488,35 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
| 822 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 488 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 823 | 489 | ||
| 824 | I915_WRITE(HWSTAM, 0xeffe); | 490 | I915_WRITE(HWSTAM, 0xeffe); |
| 491 | I915_WRITE(PIPEASTAT, 0); | ||
| 492 | I915_WRITE(PIPEBSTAT, 0); | ||
| 825 | I915_WRITE(IMR, 0xffffffff); | 493 | I915_WRITE(IMR, 0xffffffff); |
| 826 | I915_WRITE(IER, 0x0); | 494 | I915_WRITE(IER, 0x0); |
| 495 | (void) I915_READ(IER); | ||
| 827 | } | 496 | } |
| 828 | 497 | ||
| 829 | int i915_driver_irq_postinstall(struct drm_device *dev) | 498 | int i915_driver_irq_postinstall(struct drm_device *dev) |
| 830 | { | 499 | { |
| 831 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 500 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 832 | int ret, num_pipes = 2; | ||
| 833 | |||
| 834 | spin_lock_init(&dev_priv->swaps_lock); | ||
| 835 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); | ||
| 836 | INIT_WORK(&dev_priv->vblank_work, i915_vblank_work_handler); | ||
| 837 | dev_priv->swaps_pending = 0; | ||
| 838 | |||
| 839 | /* Set initial unmasked IRQs to just the selected vblank pipes. */ | ||
| 840 | dev_priv->irq_mask_reg = ~0; | ||
| 841 | |||
| 842 | ret = drm_vblank_init(dev, num_pipes); | ||
| 843 | if (ret) | ||
| 844 | return ret; | ||
| 845 | 501 | ||
| 846 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; | 502 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; |
| 847 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; | ||
| 848 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
| 849 | 503 | ||
| 850 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 504 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
| 851 | 505 | ||
| 852 | dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK; | 506 | /* Unmask the interrupts that we always want on. */ |
| 507 | dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX; | ||
| 508 | |||
| 509 | dev_priv->pipestat[0] = 0; | ||
| 510 | dev_priv->pipestat[1] = 0; | ||
| 511 | |||
| 512 | /* Disable pipe interrupt enables, clear pending pipe status */ | ||
| 513 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | ||
| 514 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | ||
| 515 | /* Clear pending interrupt status */ | ||
| 516 | I915_WRITE(IIR, I915_READ(IIR)); | ||
| 853 | 517 | ||
| 854 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
| 855 | I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); | 518 | I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); |
| 519 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | ||
| 856 | (void) I915_READ(IER); | 520 | (void) I915_READ(IER); |
| 857 | 521 | ||
| 858 | opregion_enable_asle(dev); | 522 | opregion_enable_asle(dev); |
| @@ -864,7 +528,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
| 864 | void i915_driver_irq_uninstall(struct drm_device * dev) | 528 | void i915_driver_irq_uninstall(struct drm_device * dev) |
| 865 | { | 529 | { |
| 866 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 530 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 867 | u32 temp; | ||
| 868 | 531 | ||
| 869 | if (!dev_priv) | 532 | if (!dev_priv) |
| 870 | return; | 533 | return; |
| @@ -872,13 +535,12 @@ void i915_driver_irq_uninstall(struct drm_device * dev) | |||
| 872 | dev_priv->vblank_pipe = 0; | 535 | dev_priv->vblank_pipe = 0; |
| 873 | 536 | ||
| 874 | I915_WRITE(HWSTAM, 0xffffffff); | 537 | I915_WRITE(HWSTAM, 0xffffffff); |
| 538 | I915_WRITE(PIPEASTAT, 0); | ||
| 539 | I915_WRITE(PIPEBSTAT, 0); | ||
| 875 | I915_WRITE(IMR, 0xffffffff); | 540 | I915_WRITE(IMR, 0xffffffff); |
| 876 | I915_WRITE(IER, 0x0); | 541 | I915_WRITE(IER, 0x0); |
| 877 | 542 | ||
| 878 | temp = I915_READ(PIPEASTAT); | 543 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); |
| 879 | I915_WRITE(PIPEASTAT, temp); | 544 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); |
| 880 | temp = I915_READ(PIPEBSTAT); | 545 | I915_WRITE(IIR, I915_READ(IIR)); |
| 881 | I915_WRITE(PIPEBSTAT, temp); | ||
| 882 | temp = I915_READ(IIR); | ||
| 883 | I915_WRITE(IIR, temp); | ||
| 884 | } | 546 | } |
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 1787a0c7e3ab..13ae731a33db 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
| @@ -235,17 +235,15 @@ void opregion_enable_asle(struct drm_device *dev) | |||
| 235 | struct opregion_asle *asle = dev_priv->opregion.asle; | 235 | struct opregion_asle *asle = dev_priv->opregion.asle; |
| 236 | 236 | ||
| 237 | if (asle) { | 237 | if (asle) { |
| 238 | u32 pipeb_stats = I915_READ(PIPEBSTAT); | ||
| 239 | if (IS_MOBILE(dev)) { | 238 | if (IS_MOBILE(dev)) { |
| 240 | /* Many devices trigger events with a write to the | 239 | unsigned long irqflags; |
| 241 | legacy backlight controller, so we need to ensure | 240 | |
| 242 | that it's able to generate interrupts */ | 241 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
| 243 | I915_WRITE(PIPEBSTAT, pipeb_stats |= | 242 | i915_enable_pipestat(dev_priv, 1, |
| 244 | I915_LEGACY_BLC_EVENT_ENABLE); | 243 | I915_LEGACY_BLC_EVENT_ENABLE); |
| 245 | i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT | | 244 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, |
| 246 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); | 245 | irqflags); |
| 247 | } else | 246 | } |
| 248 | i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT); | ||
| 249 | 247 | ||
| 250 | asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | | 248 | asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | |
| 251 | ASLE_PFMB_EN; | 249 | ASLE_PFMB_EN; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5c2d9f206d05..9d24aaeb8a45 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -522,11 +522,15 @@ | |||
| 522 | #define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) | 522 | #define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) |
| 523 | #define DCC_ADDRESSING_MODE_MASK (3 << 0) | 523 | #define DCC_ADDRESSING_MODE_MASK (3 << 0) |
| 524 | #define DCC_CHANNEL_XOR_DISABLE (1 << 10) | 524 | #define DCC_CHANNEL_XOR_DISABLE (1 << 10) |
| 525 | #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) | ||
| 525 | 526 | ||
| 526 | /** 965 MCH register controlling DRAM channel configuration */ | 527 | /** 965 MCH register controlling DRAM channel configuration */ |
| 527 | #define C0DRB3 0x10206 | 528 | #define C0DRB3 0x10206 |
| 528 | #define C1DRB3 0x10606 | 529 | #define C1DRB3 0x10606 |
| 529 | 530 | ||
| 531 | /** GM965 GM45 render standby register */ | ||
| 532 | #define MCHBAR_RENDER_STANDBY 0x111B8 | ||
| 533 | |||
| 530 | /* | 534 | /* |
| 531 | * Overlay regs | 535 | * Overlay regs |
| 532 | */ | 536 | */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 603fe742ccd4..5d84027ee8f3 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
| @@ -240,6 +240,13 @@ int i915_save_state(struct drm_device *dev) | |||
| 240 | 240 | ||
| 241 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 241 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
| 242 | 242 | ||
| 243 | /* Render Standby */ | ||
| 244 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
| 245 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
| 246 | |||
| 247 | /* Hardware status page */ | ||
| 248 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
| 249 | |||
| 243 | /* Display arbitration control */ | 250 | /* Display arbitration control */ |
| 244 | dev_priv->saveDSPARB = I915_READ(DSPARB); | 251 | dev_priv->saveDSPARB = I915_READ(DSPARB); |
| 245 | 252 | ||
| @@ -365,6 +372,14 @@ int i915_restore_state(struct drm_device *dev) | |||
| 365 | 372 | ||
| 366 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 373 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
| 367 | 374 | ||
| 375 | /* Render Standby */ | ||
| 376 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
| 377 | I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); | ||
| 378 | |||
| 379 | /* Hardware status page */ | ||
| 380 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | ||
| 381 | |||
| 382 | /* Display arbitration */ | ||
| 368 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); | 383 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); |
| 369 | 384 | ||
| 370 | /* Pipe & plane A info */ | 385 | /* Pipe & plane A info */ |
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index c1d12dbfa8d8..b49c5ff29585 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c | |||
| @@ -396,6 +396,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) | |||
| 396 | int mga_driver_load(struct drm_device * dev, unsigned long flags) | 396 | int mga_driver_load(struct drm_device * dev, unsigned long flags) |
| 397 | { | 397 | { |
| 398 | drm_mga_private_t *dev_priv; | 398 | drm_mga_private_t *dev_priv; |
| 399 | int ret; | ||
| 399 | 400 | ||
| 400 | dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); | 401 | dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); |
| 401 | if (!dev_priv) | 402 | if (!dev_priv) |
| @@ -415,6 +416,13 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags) | |||
| 415 | dev->types[7] = _DRM_STAT_PRIMARY; | 416 | dev->types[7] = _DRM_STAT_PRIMARY; |
| 416 | dev->types[8] = _DRM_STAT_SECONDARY; | 417 | dev->types[8] = _DRM_STAT_SECONDARY; |
| 417 | 418 | ||
| 419 | ret = drm_vblank_init(dev, 1); | ||
| 420 | |||
| 421 | if (ret) { | ||
| 422 | (void) mga_driver_unload(dev); | ||
| 423 | return ret; | ||
| 424 | } | ||
| 425 | |||
| 418 | return 0; | 426 | return 0; |
| 419 | } | 427 | } |
| 420 | 428 | ||
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c index bab42f41188b..daa6041a483a 100644 --- a/drivers/gpu/drm/mga/mga_irq.c +++ b/drivers/gpu/drm/mga/mga_irq.c | |||
| @@ -152,11 +152,6 @@ void mga_driver_irq_preinstall(struct drm_device * dev) | |||
| 152 | int mga_driver_irq_postinstall(struct drm_device *dev) | 152 | int mga_driver_irq_postinstall(struct drm_device *dev) |
| 153 | { | 153 | { |
| 154 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 154 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
| 155 | int ret; | ||
| 156 | |||
| 157 | ret = drm_vblank_init(dev, 1); | ||
| 158 | if (ret) | ||
| 159 | return ret; | ||
| 160 | 155 | ||
| 161 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); | 156 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); |
| 162 | 157 | ||
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 3265d53ba91f..601f4c0e5da5 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
| @@ -45,6 +45,7 @@ static struct drm_driver driver = { | |||
| 45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
| 46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
| 47 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), | 47 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), |
| 48 | .load = r128_driver_load, | ||
| 48 | .preclose = r128_driver_preclose, | 49 | .preclose = r128_driver_preclose, |
| 49 | .lastclose = r128_driver_lastclose, | 50 | .lastclose = r128_driver_lastclose, |
| 50 | .get_vblank_counter = r128_get_vblank_counter, | 51 | .get_vblank_counter = r128_get_vblank_counter, |
| @@ -84,6 +85,11 @@ static struct drm_driver driver = { | |||
| 84 | .patchlevel = DRIVER_PATCHLEVEL, | 85 | .patchlevel = DRIVER_PATCHLEVEL, |
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| 88 | int r128_driver_load(struct drm_device * dev, unsigned long flags) | ||
| 89 | { | ||
| 90 | return drm_vblank_init(dev, 1); | ||
| 91 | } | ||
| 92 | |||
| 87 | static int __init r128_init(void) | 93 | static int __init r128_init(void) |
| 88 | { | 94 | { |
| 89 | driver.num_ioctls = r128_max_ioctl; | 95 | driver.num_ioctls = r128_max_ioctl; |
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h index 5898b274279d..797a26c42dab 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h | |||
| @@ -159,6 +159,7 @@ extern void r128_driver_irq_preinstall(struct drm_device * dev); | |||
| 159 | extern int r128_driver_irq_postinstall(struct drm_device *dev); | 159 | extern int r128_driver_irq_postinstall(struct drm_device *dev); |
| 160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); | 160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); |
| 161 | extern void r128_driver_lastclose(struct drm_device * dev); | 161 | extern void r128_driver_lastclose(struct drm_device * dev); |
| 162 | extern int r128_driver_load(struct drm_device * dev, unsigned long flags); | ||
| 162 | extern void r128_driver_preclose(struct drm_device * dev, | 163 | extern void r128_driver_preclose(struct drm_device * dev, |
| 163 | struct drm_file *file_priv); | 164 | struct drm_file *file_priv); |
| 164 | 165 | ||
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index d7349012a680..69810fb8ac49 100644 --- a/drivers/gpu/drm/r128/r128_irq.c +++ b/drivers/gpu/drm/r128/r128_irq.c | |||
| @@ -102,7 +102,7 @@ void r128_driver_irq_preinstall(struct drm_device * dev) | |||
| 102 | 102 | ||
| 103 | int r128_driver_irq_postinstall(struct drm_device *dev) | 103 | int r128_driver_irq_postinstall(struct drm_device *dev) |
| 104 | { | 104 | { |
| 105 | return drm_vblank_init(dev, 1); | 105 | return 0; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | void r128_driver_irq_uninstall(struct drm_device * dev) | 108 | void r128_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 59a2132a8f57..dcebb4bee7aa 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
| @@ -653,15 +653,16 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
| 653 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); | 653 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); |
| 654 | 654 | ||
| 655 | /* Turn on bus mastering */ | 655 | /* Turn on bus mastering */ |
| 656 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || | 656 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
| 657 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | ||
| 658 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | 657 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { |
| 659 | /* rs400, rs690/rs740 */ | 658 | /* rs600/rs690/rs740 */ |
| 660 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS; | 659 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; |
| 661 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | 660 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); |
| 662 | } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || | 661 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || |
| 663 | ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) { | 662 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || |
| 664 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ | 663 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || |
| 664 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { | ||
| 665 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ | ||
| 665 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | 666 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
| 666 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | 667 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); |
| 667 | } /* PCIE cards appears to not need this */ | 668 | } /* PCIE cards appears to not need this */ |
| @@ -1750,6 +1751,18 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1750 | else | 1751 | else |
| 1751 | dev_priv->flags |= RADEON_IS_PCI; | 1752 | dev_priv->flags |= RADEON_IS_PCI; |
| 1752 | 1753 | ||
| 1754 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | ||
| 1755 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | ||
| 1756 | _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); | ||
| 1757 | if (ret != 0) | ||
| 1758 | return ret; | ||
| 1759 | |||
| 1760 | ret = drm_vblank_init(dev, 2); | ||
| 1761 | if (ret) { | ||
| 1762 | radeon_driver_unload(dev); | ||
| 1763 | return ret; | ||
| 1764 | } | ||
| 1765 | |||
| 1753 | DRM_DEBUG("%s card detected\n", | 1766 | DRM_DEBUG("%s card detected\n", |
| 1754 | ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); | 1767 | ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); |
| 1755 | return ret; | 1768 | return ret; |
| @@ -1766,12 +1779,6 @@ int radeon_driver_firstopen(struct drm_device *dev) | |||
| 1766 | 1779 | ||
| 1767 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | 1780 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; |
| 1768 | 1781 | ||
| 1769 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | ||
| 1770 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | ||
| 1771 | _DRM_READ_ONLY, &dev_priv->mmio); | ||
| 1772 | if (ret != 0) | ||
| 1773 | return ret; | ||
| 1774 | |||
| 1775 | dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); | 1782 | dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); |
| 1776 | ret = drm_addmap(dev, dev_priv->fb_aper_offset, | 1783 | ret = drm_addmap(dev, dev_priv->fb_aper_offset, |
| 1777 | drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, | 1784 | drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, |
| @@ -1787,6 +1794,9 @@ int radeon_driver_unload(struct drm_device *dev) | |||
| 1787 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1794 | drm_radeon_private_t *dev_priv = dev->dev_private; |
| 1788 | 1795 | ||
| 1789 | DRM_DEBUG("\n"); | 1796 | DRM_DEBUG("\n"); |
| 1797 | |||
| 1798 | drm_rmmap(dev, dev_priv->mmio); | ||
| 1799 | |||
| 1790 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 1800 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); |
| 1791 | 1801 | ||
| 1792 | dev->dev_private = NULL; | 1802 | dev->dev_private = NULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 4dbb813910c3..3bbb871b25d5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
| @@ -287,7 +287,6 @@ typedef struct drm_radeon_private { | |||
| 287 | unsigned long gart_textures_offset; | 287 | unsigned long gart_textures_offset; |
| 288 | 288 | ||
| 289 | drm_local_map_t *sarea; | 289 | drm_local_map_t *sarea; |
| 290 | drm_local_map_t *mmio; | ||
| 291 | drm_local_map_t *cp_ring; | 290 | drm_local_map_t *cp_ring; |
| 292 | drm_local_map_t *ring_rptr; | 291 | drm_local_map_t *ring_rptr; |
| 293 | drm_local_map_t *gart_textures; | 292 | drm_local_map_t *gart_textures; |
| @@ -300,7 +299,6 @@ typedef struct drm_radeon_private { | |||
| 300 | atomic_t swi_emitted; | 299 | atomic_t swi_emitted; |
| 301 | int vblank_crtc; | 300 | int vblank_crtc; |
| 302 | uint32_t irq_enable_reg; | 301 | uint32_t irq_enable_reg; |
| 303 | int irq_enabled; | ||
| 304 | uint32_t r500_disp_irq_reg; | 302 | uint32_t r500_disp_irq_reg; |
| 305 | 303 | ||
| 306 | struct radeon_surface surfaces[RADEON_MAX_SURFACES]; | 304 | struct radeon_surface surfaces[RADEON_MAX_SURFACES]; |
| @@ -318,6 +316,7 @@ typedef struct drm_radeon_private { | |||
| 318 | 316 | ||
| 319 | int num_gb_pipes; | 317 | int num_gb_pipes; |
| 320 | int track_flush; | 318 | int track_flush; |
| 319 | drm_local_map_t *mmio; | ||
| 321 | } drm_radeon_private_t; | 320 | } drm_radeon_private_t; |
| 322 | 321 | ||
| 323 | typedef struct drm_radeon_buf_priv { | 322 | typedef struct drm_radeon_buf_priv { |
| @@ -447,12 +446,12 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, | |||
| 447 | * handling, not bus mastering itself. | 446 | * handling, not bus mastering itself. |
| 448 | */ | 447 | */ |
| 449 | #define RADEON_BUS_CNTL 0x0030 | 448 | #define RADEON_BUS_CNTL 0x0030 |
| 450 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */ | 449 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ |
| 451 | # define RADEON_BUS_MASTER_DIS (1 << 6) | 450 | # define RADEON_BUS_MASTER_DIS (1 << 6) |
| 452 | /* rs400, rs690/rs740 */ | 451 | /* rs600/rs690/rs740 */ |
| 453 | # define RS400_BUS_MASTER_DIS (1 << 14) | 452 | # define RS600_BUS_MASTER_DIS (1 << 14) |
| 454 | # define RS400_MSI_REARM (1 << 20) | 453 | # define RS600_MSI_REARM (1 << 20) |
| 455 | /* see RS480_MSI_REARM in AIC_CNTL for rs480 */ | 454 | /* see RS400_MSI_REARM in AIC_CNTL for rs480 */ |
| 456 | 455 | ||
| 457 | #define RADEON_BUS_CNTL1 0x0034 | 456 | #define RADEON_BUS_CNTL1 0x0034 |
| 458 | # define RADEON_PMI_BM_DIS (1 << 2) | 457 | # define RADEON_PMI_BM_DIS (1 << 2) |
| @@ -937,7 +936,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, | |||
| 937 | 936 | ||
| 938 | #define RADEON_AIC_CNTL 0x01d0 | 937 | #define RADEON_AIC_CNTL 0x01d0 |
| 939 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) | 938 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) |
| 940 | # define RS480_MSI_REARM (1 << 3) | 939 | # define RS400_MSI_REARM (1 << 3) |
| 941 | #define RADEON_AIC_STAT 0x01d4 | 940 | #define RADEON_AIC_STAT 0x01d4 |
| 942 | #define RADEON_AIC_PT_BASE 0x01d8 | 941 | #define RADEON_AIC_PT_BASE 0x01d8 |
| 943 | #define RADEON_AIC_LO_ADDR 0x01dc | 942 | #define RADEON_AIC_LO_ADDR 0x01dc |
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index 5079f7054a2f..99be11418ac2 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c | |||
| @@ -44,7 +44,8 @@ void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) | |||
| 44 | else | 44 | else |
| 45 | dev_priv->irq_enable_reg &= ~mask; | 45 | dev_priv->irq_enable_reg &= ~mask; |
| 46 | 46 | ||
| 47 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | 47 | if (!dev->irq_enabled) |
| 48 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) | 51 | static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) |
| @@ -56,7 +57,8 @@ static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) | |||
| 56 | else | 57 | else |
| 57 | dev_priv->r500_disp_irq_reg &= ~mask; | 58 | dev_priv->r500_disp_irq_reg &= ~mask; |
| 58 | 59 | ||
| 59 | RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); | 60 | if (!dev->irq_enabled) |
| 61 | RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); | ||
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | int radeon_enable_vblank(struct drm_device *dev, int crtc) | 64 | int radeon_enable_vblank(struct drm_device *dev, int crtc) |
| @@ -337,15 +339,10 @@ int radeon_driver_irq_postinstall(struct drm_device *dev) | |||
| 337 | { | 339 | { |
| 338 | drm_radeon_private_t *dev_priv = | 340 | drm_radeon_private_t *dev_priv = |
| 339 | (drm_radeon_private_t *) dev->dev_private; | 341 | (drm_radeon_private_t *) dev->dev_private; |
| 340 | int ret; | ||
| 341 | 342 | ||
| 342 | atomic_set(&dev_priv->swi_emitted, 0); | 343 | atomic_set(&dev_priv->swi_emitted, 0); |
| 343 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); | 344 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); |
| 344 | 345 | ||
| 345 | ret = drm_vblank_init(dev, 2); | ||
| 346 | if (ret) | ||
| 347 | return ret; | ||
| 348 | |||
| 349 | dev->max_vblank_count = 0x001fffff; | 346 | dev->max_vblank_count = 0x001fffff; |
| 350 | 347 | ||
| 351 | radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); | 348 | radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); |
| @@ -360,8 +357,6 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) | |||
| 360 | if (!dev_priv) | 357 | if (!dev_priv) |
| 361 | return; | 358 | return; |
| 362 | 359 | ||
| 363 | dev_priv->irq_enabled = 0; | ||
| 364 | |||
| 365 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) | 360 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) |
| 366 | RADEON_WRITE(R500_DxMODE_INT_MASK, 0); | 361 | RADEON_WRITE(R500_DxMODE_INT_MASK, 0); |
| 367 | /* Disable *all* interrupts */ | 362 | /* Disable *all* interrupts */ |
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 665d319b927b..c248c1d37268 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c | |||
| @@ -314,7 +314,6 @@ int via_driver_irq_postinstall(struct drm_device *dev) | |||
| 314 | if (!dev_priv) | 314 | if (!dev_priv) |
| 315 | return -EINVAL; | 315 | return -EINVAL; |
| 316 | 316 | ||
| 317 | drm_vblank_init(dev, 1); | ||
| 318 | status = VIA_READ(VIA_REG_INTERRUPT); | 317 | status = VIA_READ(VIA_REG_INTERRUPT); |
| 319 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | 318 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL |
| 320 | | dev_priv->irq_enable_mask); | 319 | | dev_priv->irq_enable_mask); |
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index a967556be014..2c4f0b485792 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c | |||
| @@ -107,8 +107,17 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 107 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); | 107 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); |
| 108 | if (ret) { | 108 | if (ret) { |
| 109 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 109 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); |
| 110 | return ret; | ||
| 110 | } | 111 | } |
| 111 | return ret; | 112 | |
| 113 | ret = drm_vblank_init(dev, 1); | ||
| 114 | if (ret) { | ||
| 115 | drm_sman_takedown(&dev_priv->sman); | ||
| 116 | drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | return 0; | ||
| 112 | } | 121 | } |
| 113 | 122 | ||
| 114 | int via_driver_unload(struct drm_device *dev) | 123 | int via_driver_unload(struct drm_device *dev) |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index c6ab4ba60c52..aa28aed0e46c 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
| @@ -55,10 +55,11 @@ struct apple_key_translation { | |||
| 55 | 55 | ||
| 56 | static struct apple_key_translation apple_fn_keys[] = { | 56 | static struct apple_key_translation apple_fn_keys[] = { |
| 57 | { KEY_BACKSPACE, KEY_DELETE }, | 57 | { KEY_BACKSPACE, KEY_DELETE }, |
| 58 | { KEY_ENTER, KEY_INSERT }, | ||
| 58 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | 59 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
| 59 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | 60 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
| 60 | { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ | 61 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
| 61 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ | 62 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
| 62 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, | 63 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
| 63 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, | 64 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
| 64 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, | 65 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
| @@ -399,12 +400,12 @@ static const struct hid_device_id apple_devices[] = { | |||
| 399 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), | 400 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), |
| 400 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 401 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
| 401 | APPLE_RDESC_JIS }, | 402 | APPLE_RDESC_JIS }, |
| 402 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), | 403 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), |
| 403 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 404 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 404 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), | 405 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), |
| 405 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 406 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
| 406 | APPLE_ISO_KEYBOARD }, | 407 | APPLE_ISO_KEYBOARD }, |
| 407 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), | 408 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
| 408 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 409 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 409 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 410 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
| 410 | .driver_data = APPLE_HAS_FN }, | 411 | .driver_data = APPLE_HAS_FN }, |
| @@ -418,6 +419,12 @@ static const struct hid_device_id apple_devices[] = { | |||
| 418 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 419 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
| 419 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), | 420 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), |
| 420 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 421 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
| 422 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), | ||
| 423 | .driver_data = APPLE_HAS_FN }, | ||
| 424 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), | ||
| 425 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | ||
| 426 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | ||
| 427 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | ||
| 421 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), | 428 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), |
| 422 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 429 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 423 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), | 430 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1903e7515650..40df3e1b4bd1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1241,18 +1241,20 @@ static const struct hid_device_id hid_blacklist[] = { | |||
| 1241 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, | 1241 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, |
| 1242 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, | 1242 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, |
| 1243 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, | 1243 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, |
| 1244 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, | 1244 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, |
| 1245 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, | 1245 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, |
| 1246 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, | 1246 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, |
| 1247 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, | 1247 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, |
| 1248 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, | 1248 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, |
| 1249 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, | 1249 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, |
| 1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
| 1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
| 1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
| 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | ||
| 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | ||
| 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | ||
| 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1256 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1257 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | ||
| 1256 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1258 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
| 1257 | { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, | 1259 | { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, |
| 1258 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1260 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
| @@ -1264,6 +1266,9 @@ static const struct hid_device_id hid_blacklist[] = { | |||
| 1264 | { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) }, | 1266 | { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) }, |
| 1265 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
| 1266 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, | 1268 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, |
| 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | ||
| 1270 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | ||
| 1271 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | ||
| 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1272 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
| 1268 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1273 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
| 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1274 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
| @@ -1408,6 +1413,7 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 1408 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, | 1413 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, |
| 1409 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, | 1414 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, |
| 1410 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, | 1415 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, |
| 1416 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | ||
| 1411 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, | 1417 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, |
| 1412 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, | 1418 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, |
| 1413 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, | 1419 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, |
| @@ -1417,7 +1423,6 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 1417 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, | 1423 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, |
| 1418 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, | 1424 | { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, |
| 1419 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, | 1425 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
| 1420 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | ||
| 1421 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, | 1426 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, |
| 1422 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, | 1427 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, |
| 1423 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, | 1428 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, |
| @@ -1433,7 +1438,6 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 1433 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, | 1438 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, |
| 1434 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, | 1439 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, |
| 1435 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, | 1440 | { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, |
| 1436 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | ||
| 1437 | { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, | 1441 | { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, |
| 1438 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, | 1442 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, |
| 1439 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, | 1443 | { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, |
| @@ -1485,6 +1489,7 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 1485 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, | 1489 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, |
| 1486 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, | 1490 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, |
| 1487 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, | 1491 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, |
| 1492 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | ||
| 1488 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, | 1493 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, |
| 1489 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, | 1494 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, |
| 1490 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, | 1495 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, |
| @@ -1729,7 +1734,7 @@ static int __init hid_init(void) | |||
| 1729 | goto err_bus; | 1734 | goto err_bus; |
| 1730 | 1735 | ||
| 1731 | #ifdef CONFIG_HID_COMPAT | 1736 | #ifdef CONFIG_HID_COMPAT |
| 1732 | hid_compat_wq = create_workqueue("hid_compat"); | 1737 | hid_compat_wq = create_singlethread_workqueue("hid_compat"); |
| 1733 | if (!hid_compat_wq) { | 1738 | if (!hid_compat_wq) { |
| 1734 | hidraw_exit(); | 1739 | hidraw_exit(); |
| 1735 | goto err; | 1740 | goto err; |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5cc404291736..39289699c32f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -82,6 +82,9 @@ | |||
| 82 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | 82 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 |
| 83 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | 83 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 |
| 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 |
| 85 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | ||
| 86 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | ||
| 87 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | ||
| 85 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 88 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
| 86 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 89 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
| 87 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 | 90 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 |
| @@ -160,6 +163,7 @@ | |||
| 160 | 163 | ||
| 161 | #define USB_VENDOR_ID_GAMERON 0x0810 | 164 | #define USB_VENDOR_ID_GAMERON 0x0810 |
| 162 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 | 165 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 |
| 166 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 | ||
| 163 | 167 | ||
| 164 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc | 168 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc |
| 165 | 169 | ||
| @@ -253,6 +257,9 @@ | |||
| 253 | #define USB_VENDOR_ID_KBGEAR 0x084e | 257 | #define USB_VENDOR_ID_KBGEAR 0x084e |
| 254 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 258 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
| 255 | 259 | ||
| 260 | #define USB_VENDOR_ID_KWORLD 0x1b80 | ||
| 261 | #define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 | ||
| 262 | |||
| 256 | #define USB_VENDOR_ID_LABTEC 0x1020 | 263 | #define USB_VENDOR_ID_LABTEC 0x1020 |
| 257 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 | 264 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 |
| 258 | 265 | ||
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index acd815586182..46941f979b9d 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c | |||
| @@ -178,6 +178,8 @@ err: | |||
| 178 | static const struct hid_device_id pl_devices[] = { | 178 | static const struct hid_device_id pl_devices[] = { |
| 179 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR), | 179 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR), |
| 180 | .driver_data = 1 }, /* Twin USB Joystick */ | 180 | .driver_data = 1 }, /* Twin USB Joystick */ |
| 181 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), | ||
| 182 | .driver_data = 1 }, /* Twin USB Joystick */ | ||
| 181 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */ | 183 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */ |
| 182 | { } | 184 | { } |
| 183 | }; | 185 | }; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 894d52e05bf9..7685ae6808c4 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -38,7 +38,7 @@ static int hidraw_major; | |||
| 38 | static struct cdev hidraw_cdev; | 38 | static struct cdev hidraw_cdev; |
| 39 | static struct class *hidraw_class; | 39 | static struct class *hidraw_class; |
| 40 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; | 40 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; |
| 41 | static DEFINE_SPINLOCK(minors_lock); | 41 | static DEFINE_MUTEX(minors_lock); |
| 42 | 42 | ||
| 43 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 43 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 44 | { | 44 | { |
| @@ -159,13 +159,13 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
| 159 | struct hidraw_list *list; | 159 | struct hidraw_list *list; |
| 160 | int err = 0; | 160 | int err = 0; |
| 161 | 161 | ||
| 162 | lock_kernel(); | ||
| 163 | if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { | 162 | if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { |
| 164 | err = -ENOMEM; | 163 | err = -ENOMEM; |
| 165 | goto out; | 164 | goto out; |
| 166 | } | 165 | } |
| 167 | 166 | ||
| 168 | spin_lock(&minors_lock); | 167 | lock_kernel(); |
| 168 | mutex_lock(&minors_lock); | ||
| 169 | if (!hidraw_table[minor]) { | 169 | if (!hidraw_table[minor]) { |
| 170 | printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", | 170 | printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", |
| 171 | minor); | 171 | minor); |
| @@ -180,13 +180,16 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
| 180 | file->private_data = list; | 180 | file->private_data = list; |
| 181 | 181 | ||
| 182 | dev = hidraw_table[minor]; | 182 | dev = hidraw_table[minor]; |
| 183 | if (!dev->open++) | 183 | if (!dev->open++) { |
| 184 | dev->hid->ll_driver->open(dev->hid); | 184 | err = dev->hid->ll_driver->open(dev->hid); |
| 185 | if (err < 0) | ||
| 186 | dev->open--; | ||
| 187 | } | ||
| 185 | 188 | ||
| 186 | out_unlock: | 189 | out_unlock: |
| 187 | spin_unlock(&minors_lock); | 190 | mutex_unlock(&minors_lock); |
| 188 | out: | ||
| 189 | unlock_kernel(); | 191 | unlock_kernel(); |
| 192 | out: | ||
| 190 | return err; | 193 | return err; |
| 191 | 194 | ||
| 192 | } | 195 | } |
| @@ -310,7 +313,7 @@ int hidraw_connect(struct hid_device *hid) | |||
| 310 | 313 | ||
| 311 | result = -EINVAL; | 314 | result = -EINVAL; |
| 312 | 315 | ||
| 313 | spin_lock(&minors_lock); | 316 | mutex_lock(&minors_lock); |
| 314 | 317 | ||
| 315 | for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) { | 318 | for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) { |
| 316 | if (hidraw_table[minor]) | 319 | if (hidraw_table[minor]) |
| @@ -320,9 +323,8 @@ int hidraw_connect(struct hid_device *hid) | |||
| 320 | break; | 323 | break; |
| 321 | } | 324 | } |
| 322 | 325 | ||
| 323 | spin_unlock(&minors_lock); | ||
| 324 | |||
| 325 | if (result) { | 326 | if (result) { |
| 327 | mutex_unlock(&minors_lock); | ||
| 326 | kfree(dev); | 328 | kfree(dev); |
| 327 | goto out; | 329 | goto out; |
| 328 | } | 330 | } |
| @@ -331,14 +333,14 @@ int hidraw_connect(struct hid_device *hid) | |||
| 331 | NULL, "%s%d", "hidraw", minor); | 333 | NULL, "%s%d", "hidraw", minor); |
| 332 | 334 | ||
| 333 | if (IS_ERR(dev->dev)) { | 335 | if (IS_ERR(dev->dev)) { |
| 334 | spin_lock(&minors_lock); | ||
| 335 | hidraw_table[minor] = NULL; | 336 | hidraw_table[minor] = NULL; |
| 336 | spin_unlock(&minors_lock); | 337 | mutex_unlock(&minors_lock); |
| 337 | result = PTR_ERR(dev->dev); | 338 | result = PTR_ERR(dev->dev); |
| 338 | kfree(dev); | 339 | kfree(dev); |
| 339 | goto out; | 340 | goto out; |
| 340 | } | 341 | } |
| 341 | 342 | ||
| 343 | mutex_unlock(&minors_lock); | ||
| 342 | init_waitqueue_head(&dev->wait); | 344 | init_waitqueue_head(&dev->wait); |
| 343 | INIT_LIST_HEAD(&dev->list); | 345 | INIT_LIST_HEAD(&dev->list); |
| 344 | 346 | ||
| @@ -360,9 +362,9 @@ void hidraw_disconnect(struct hid_device *hid) | |||
| 360 | 362 | ||
| 361 | hidraw->exist = 0; | 363 | hidraw->exist = 0; |
| 362 | 364 | ||
| 363 | spin_lock(&minors_lock); | 365 | mutex_lock(&minors_lock); |
| 364 | hidraw_table[hidraw->minor] = NULL; | 366 | hidraw_table[hidraw->minor] = NULL; |
| 365 | spin_unlock(&minors_lock); | 367 | mutex_unlock(&minors_lock); |
| 366 | 368 | ||
| 367 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | 369 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); |
| 368 | 370 | ||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 18e5ddd722cd..606369ea24ca 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
| @@ -781,6 +781,8 @@ static int usbhid_start(struct hid_device *hid) | |||
| 781 | unsigned int n, insize = 0; | 781 | unsigned int n, insize = 0; |
| 782 | int ret; | 782 | int ret; |
| 783 | 783 | ||
| 784 | clear_bit(HID_DISCONNECTED, &usbhid->iofl); | ||
| 785 | |||
| 784 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; | 786 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; |
| 785 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); | 787 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); |
| 786 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); | 788 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); |
| @@ -794,7 +796,6 @@ static int usbhid_start(struct hid_device *hid) | |||
| 794 | if (insize > HID_MAX_BUFFER_SIZE) | 796 | if (insize > HID_MAX_BUFFER_SIZE) |
| 795 | insize = HID_MAX_BUFFER_SIZE; | 797 | insize = HID_MAX_BUFFER_SIZE; |
| 796 | 798 | ||
| 797 | mutex_lock(&usbhid->setup); | ||
| 798 | if (hid_alloc_buffers(dev, hid)) { | 799 | if (hid_alloc_buffers(dev, hid)) { |
| 799 | ret = -ENOMEM; | 800 | ret = -ENOMEM; |
| 800 | goto fail; | 801 | goto fail; |
| @@ -847,12 +848,6 @@ static int usbhid_start(struct hid_device *hid) | |||
| 847 | } | 848 | } |
| 848 | } | 849 | } |
| 849 | 850 | ||
| 850 | if (!usbhid->urbin) { | ||
| 851 | err_hid("couldn't find an input interrupt endpoint"); | ||
| 852 | ret = -ENODEV; | ||
| 853 | goto fail; | ||
| 854 | } | ||
| 855 | |||
| 856 | init_waitqueue_head(&usbhid->wait); | 851 | init_waitqueue_head(&usbhid->wait); |
| 857 | INIT_WORK(&usbhid->reset_work, hid_reset); | 852 | INIT_WORK(&usbhid->reset_work, hid_reset); |
| 858 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 853 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
| @@ -880,7 +875,6 @@ static int usbhid_start(struct hid_device *hid) | |||
| 880 | hid_dump_device(hid); | 875 | hid_dump_device(hid); |
| 881 | 876 | ||
| 882 | set_bit(HID_STARTED, &usbhid->iofl); | 877 | set_bit(HID_STARTED, &usbhid->iofl); |
| 883 | mutex_unlock(&usbhid->setup); | ||
| 884 | 878 | ||
| 885 | return 0; | 879 | return 0; |
| 886 | 880 | ||
| @@ -888,8 +882,10 @@ fail: | |||
| 888 | usb_free_urb(usbhid->urbin); | 882 | usb_free_urb(usbhid->urbin); |
| 889 | usb_free_urb(usbhid->urbout); | 883 | usb_free_urb(usbhid->urbout); |
| 890 | usb_free_urb(usbhid->urbctrl); | 884 | usb_free_urb(usbhid->urbctrl); |
| 885 | usbhid->urbin = NULL; | ||
| 886 | usbhid->urbout = NULL; | ||
| 887 | usbhid->urbctrl = NULL; | ||
| 891 | hid_free_buffers(dev, hid); | 888 | hid_free_buffers(dev, hid); |
| 892 | mutex_unlock(&usbhid->setup); | ||
| 893 | return ret; | 889 | return ret; |
| 894 | } | 890 | } |
| 895 | 891 | ||
| @@ -900,7 +896,6 @@ static void usbhid_stop(struct hid_device *hid) | |||
| 900 | if (WARN_ON(!usbhid)) | 896 | if (WARN_ON(!usbhid)) |
| 901 | return; | 897 | return; |
| 902 | 898 | ||
| 903 | mutex_lock(&usbhid->setup); | ||
| 904 | clear_bit(HID_STARTED, &usbhid->iofl); | 899 | clear_bit(HID_STARTED, &usbhid->iofl); |
| 905 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 900 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ |
| 906 | set_bit(HID_DISCONNECTED, &usbhid->iofl); | 901 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
| @@ -924,9 +919,11 @@ static void usbhid_stop(struct hid_device *hid) | |||
| 924 | usb_free_urb(usbhid->urbin); | 919 | usb_free_urb(usbhid->urbin); |
| 925 | usb_free_urb(usbhid->urbctrl); | 920 | usb_free_urb(usbhid->urbctrl); |
| 926 | usb_free_urb(usbhid->urbout); | 921 | usb_free_urb(usbhid->urbout); |
| 922 | usbhid->urbin = NULL; /* don't mess up next start */ | ||
| 923 | usbhid->urbctrl = NULL; | ||
| 924 | usbhid->urbout = NULL; | ||
| 927 | 925 | ||
| 928 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 926 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
| 929 | mutex_unlock(&usbhid->setup); | ||
| 930 | } | 927 | } |
| 931 | 928 | ||
| 932 | static struct hid_ll_driver usb_hid_driver = { | 929 | static struct hid_ll_driver usb_hid_driver = { |
| @@ -940,15 +937,26 @@ static struct hid_ll_driver usb_hid_driver = { | |||
| 940 | 937 | ||
| 941 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 938 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| 942 | { | 939 | { |
| 940 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
| 943 | struct usb_device *dev = interface_to_usbdev(intf); | 941 | struct usb_device *dev = interface_to_usbdev(intf); |
| 944 | struct usbhid_device *usbhid; | 942 | struct usbhid_device *usbhid; |
| 945 | struct hid_device *hid; | 943 | struct hid_device *hid; |
| 944 | unsigned int n, has_in = 0; | ||
| 946 | size_t len; | 945 | size_t len; |
| 947 | int ret; | 946 | int ret; |
| 948 | 947 | ||
| 949 | dbg_hid("HID probe called for ifnum %d\n", | 948 | dbg_hid("HID probe called for ifnum %d\n", |
| 950 | intf->altsetting->desc.bInterfaceNumber); | 949 | intf->altsetting->desc.bInterfaceNumber); |
| 951 | 950 | ||
| 951 | for (n = 0; n < interface->desc.bNumEndpoints; n++) | ||
| 952 | if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) | ||
| 953 | has_in++; | ||
| 954 | if (!has_in) { | ||
| 955 | dev_err(&intf->dev, "couldn't find an input interrupt " | ||
| 956 | "endpoint\n"); | ||
| 957 | return -ENODEV; | ||
| 958 | } | ||
| 959 | |||
| 952 | hid = hid_allocate_device(); | 960 | hid = hid_allocate_device(); |
| 953 | if (IS_ERR(hid)) | 961 | if (IS_ERR(hid)) |
| 954 | return PTR_ERR(hid); | 962 | return PTR_ERR(hid); |
| @@ -1003,7 +1011,6 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1003 | 1011 | ||
| 1004 | hid->driver_data = usbhid; | 1012 | hid->driver_data = usbhid; |
| 1005 | usbhid->hid = hid; | 1013 | usbhid->hid = hid; |
| 1006 | mutex_init(&usbhid->setup); /* needed on suspend/resume */ | ||
| 1007 | 1014 | ||
| 1008 | ret = hid_add_device(hid); | 1015 | ret = hid_add_device(hid); |
| 1009 | if (ret) { | 1016 | if (ret) { |
| @@ -1038,18 +1045,14 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 1038 | struct hid_device *hid = usb_get_intfdata (intf); | 1045 | struct hid_device *hid = usb_get_intfdata (intf); |
| 1039 | struct usbhid_device *usbhid = hid->driver_data; | 1046 | struct usbhid_device *usbhid = hid->driver_data; |
| 1040 | 1047 | ||
| 1041 | mutex_lock(&usbhid->setup); | 1048 | if (!test_bit(HID_STARTED, &usbhid->iofl)) |
| 1042 | if (!test_bit(HID_STARTED, &usbhid->iofl)) { | ||
| 1043 | mutex_unlock(&usbhid->setup); | ||
| 1044 | return 0; | 1049 | return 0; |
| 1045 | } | ||
| 1046 | 1050 | ||
| 1047 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 1051 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ |
| 1048 | set_bit(HID_SUSPENDED, &usbhid->iofl); | 1052 | set_bit(HID_SUSPENDED, &usbhid->iofl); |
| 1049 | spin_unlock_irq(&usbhid->inlock); | 1053 | spin_unlock_irq(&usbhid->inlock); |
| 1050 | del_timer_sync(&usbhid->io_retry); | 1054 | del_timer_sync(&usbhid->io_retry); |
| 1051 | usb_kill_urb(usbhid->urbin); | 1055 | usb_kill_urb(usbhid->urbin); |
| 1052 | mutex_unlock(&usbhid->setup); | ||
| 1053 | dev_dbg(&intf->dev, "suspend\n"); | 1056 | dev_dbg(&intf->dev, "suspend\n"); |
| 1054 | return 0; | 1057 | return 0; |
| 1055 | } | 1058 | } |
| @@ -1060,16 +1063,12 @@ static int hid_resume(struct usb_interface *intf) | |||
| 1060 | struct usbhid_device *usbhid = hid->driver_data; | 1063 | struct usbhid_device *usbhid = hid->driver_data; |
| 1061 | int status; | 1064 | int status; |
| 1062 | 1065 | ||
| 1063 | mutex_lock(&usbhid->setup); | 1066 | if (!test_bit(HID_STARTED, &usbhid->iofl)) |
| 1064 | if (!test_bit(HID_STARTED, &usbhid->iofl)) { | ||
| 1065 | mutex_unlock(&usbhid->setup); | ||
| 1066 | return 0; | 1067 | return 0; |
| 1067 | } | ||
| 1068 | 1068 | ||
| 1069 | clear_bit(HID_SUSPENDED, &usbhid->iofl); | 1069 | clear_bit(HID_SUSPENDED, &usbhid->iofl); |
| 1070 | usbhid->retry_delay = 0; | 1070 | usbhid->retry_delay = 0; |
| 1071 | status = hid_start_in(hid); | 1071 | status = hid_start_in(hid); |
| 1072 | mutex_unlock(&usbhid->setup); | ||
| 1073 | dev_dbg(&intf->dev, "resume status %d\n", status); | 1072 | dev_dbg(&intf->dev, "resume status %d\n", status); |
| 1074 | return status; | 1073 | return status; |
| 1075 | } | 1074 | } |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 3ac320785fc5..83e851a5ed30 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
| @@ -242,8 +242,6 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
| 242 | struct hiddev_list *list = file->private_data; | 242 | struct hiddev_list *list = file->private_data; |
| 243 | unsigned long flags; | 243 | unsigned long flags; |
| 244 | 244 | ||
| 245 | hiddev_fasync(-1, file, 0); | ||
| 246 | |||
| 247 | spin_lock_irqsave(&list->hiddev->list_lock, flags); | 245 | spin_lock_irqsave(&list->hiddev->list_lock, flags); |
| 248 | list_del(&list->node); | 246 | list_del(&list->node); |
| 249 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); | 247 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 55973ff54008..332abcdf9956 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
| @@ -74,7 +74,6 @@ struct usbhid_device { | |||
| 74 | dma_addr_t outbuf_dma; /* Output buffer dma */ | 74 | dma_addr_t outbuf_dma; /* Output buffer dma */ |
| 75 | spinlock_t outlock; /* Output fifo spinlock */ | 75 | spinlock_t outlock; /* Output fifo spinlock */ |
| 76 | 76 | ||
| 77 | struct mutex setup; | ||
| 78 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ | 77 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ |
| 79 | struct timer_list io_retry; /* Retry timer */ | 78 | struct timer_list io_retry; /* Retry timer */ |
| 80 | unsigned long stop_retry; /* Time to give up, in jiffies */ | 79 | unsigned long stop_retry; /* Time to give up, in jiffies */ |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6de1e0ffd391..c709e821f04b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -159,6 +159,16 @@ config SENSORS_ADM9240 | |||
| 159 | This driver can also be built as a module. If so, the module | 159 | This driver can also be built as a module. If so, the module |
| 160 | will be called adm9240. | 160 | will be called adm9240. |
| 161 | 161 | ||
| 162 | config SENSORS_ADT7462 | ||
| 163 | tristate "Analog Devices ADT7462" | ||
| 164 | depends on I2C && EXPERIMENTAL | ||
| 165 | help | ||
| 166 | If you say yes here you get support for the Analog Devices | ||
| 167 | ADT7462 temperature monitoring chips. | ||
| 168 | |||
| 169 | This driver can also be built as a module. If so, the module | ||
| 170 | will be called adt7462. | ||
| 171 | |||
| 162 | config SENSORS_ADT7470 | 172 | config SENSORS_ADT7470 |
| 163 | tristate "Analog Devices ADT7470" | 173 | tristate "Analog Devices ADT7470" |
| 164 | depends on I2C && EXPERIMENTAL | 174 | depends on I2C && EXPERIMENTAL |
| @@ -825,6 +835,25 @@ config SENSORS_HDAPS | |||
| 825 | Say Y here if you have an applicable laptop and want to experience | 835 | Say Y here if you have an applicable laptop and want to experience |
| 826 | the awesome power of hdaps. | 836 | the awesome power of hdaps. |
| 827 | 837 | ||
| 838 | config SENSORS_LIS3LV02D | ||
| 839 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" | ||
| 840 | depends on ACPI && INPUT | ||
| 841 | default n | ||
| 842 | help | ||
| 843 | This driver provides support for the LIS3LV02Dx accelerometer. In | ||
| 844 | particular, it can be found in a number of HP laptops, which have the | ||
| 845 | "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such | ||
| 846 | systems the driver should load automatically (via ACPI). The | ||
| 847 | accelerometer might also be found in other systems, connected via SPI | ||
| 848 | or I2C. The accelerometer data is readable via | ||
| 849 | /sys/devices/platform/lis3lv02d. | ||
| 850 | |||
| 851 | This driver also provides an absolute input class device, allowing | ||
| 852 | the laptop to act as a pinball machine-esque joystick. | ||
| 853 | |||
| 854 | This driver can also be built as a module. If so, the module | ||
| 855 | will be called lis3lv02d. | ||
| 856 | |||
| 828 | config SENSORS_APPLESMC | 857 | config SENSORS_APPLESMC |
| 829 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" | 858 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" |
| 830 | depends on INPUT && X86 | 859 | depends on INPUT && X86 |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 042d5a78622e..58fc5be5355d 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -25,6 +25,7 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o | |||
| 25 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | 25 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o |
| 26 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 26 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
| 27 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o | 27 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o |
| 28 | obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o | ||
| 28 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o | 29 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o |
| 29 | obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o | 30 | obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o |
| 30 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | 31 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o |
| @@ -48,6 +49,7 @@ obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | |||
| 48 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 49 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
| 49 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 50 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
| 50 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 51 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
| 52 | obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o | ||
| 51 | obj-$(CONFIG_SENSORS_LM63) += lm63.o | 53 | obj-$(CONFIG_SENSORS_LM63) += lm63.o |
| 52 | obj-$(CONFIG_SENSORS_LM70) += lm70.o | 54 | obj-$(CONFIG_SENSORS_LM70) += lm70.o |
| 53 | obj-$(CONFIG_SENSORS_LM75) += lm75.o | 55 | obj-$(CONFIG_SENSORS_LM75) += lm75.o |
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c new file mode 100644 index 000000000000..66107b4dc12a --- /dev/null +++ b/drivers/hwmon/adt7462.c | |||
| @@ -0,0 +1,2002 @@ | |||
| 1 | /* | ||
| 2 | * A hwmon driver for the Analog Devices ADT7462 | ||
| 3 | * Copyright (C) 2008 IBM | ||
| 4 | * | ||
| 5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/jiffies.h> | ||
| 24 | #include <linux/i2c.h> | ||
| 25 | #include <linux/hwmon.h> | ||
| 26 | #include <linux/hwmon-sysfs.h> | ||
| 27 | #include <linux/err.h> | ||
| 28 | #include <linux/mutex.h> | ||
| 29 | #include <linux/delay.h> | ||
| 30 | #include <linux/log2.h> | ||
| 31 | |||
| 32 | /* Addresses to scan */ | ||
| 33 | static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; | ||
| 34 | |||
| 35 | /* Insmod parameters */ | ||
| 36 | I2C_CLIENT_INSMOD_1(adt7462); | ||
| 37 | |||
| 38 | /* ADT7462 registers */ | ||
| 39 | #define ADT7462_REG_DEVICE 0x3D | ||
| 40 | #define ADT7462_REG_VENDOR 0x3E | ||
| 41 | #define ADT7462_REG_REVISION 0x3F | ||
| 42 | |||
| 43 | #define ADT7462_REG_MIN_TEMP_BASE_ADDR 0x44 | ||
| 44 | #define ADT7462_REG_MIN_TEMP_MAX_ADDR 0x47 | ||
| 45 | #define ADT7462_REG_MAX_TEMP_BASE_ADDR 0x48 | ||
| 46 | #define ADT7462_REG_MAX_TEMP_MAX_ADDR 0x4B | ||
| 47 | #define ADT7462_REG_TEMP_BASE_ADDR 0x88 | ||
| 48 | #define ADT7462_REG_TEMP_MAX_ADDR 0x8F | ||
| 49 | |||
| 50 | #define ADT7462_REG_FAN_BASE_ADDR 0x98 | ||
| 51 | #define ADT7462_REG_FAN_MAX_ADDR 0x9F | ||
| 52 | #define ADT7462_REG_FAN2_BASE_ADDR 0xA2 | ||
| 53 | #define ADT7462_REG_FAN2_MAX_ADDR 0xA9 | ||
| 54 | #define ADT7462_REG_FAN_ENABLE 0x07 | ||
| 55 | #define ADT7462_REG_FAN_MIN_BASE_ADDR 0x78 | ||
| 56 | #define ADT7462_REG_FAN_MIN_MAX_ADDR 0x7F | ||
| 57 | |||
| 58 | #define ADT7462_REG_CFG2 0x02 | ||
| 59 | #define ADT7462_FSPD_MASK 0x20 | ||
| 60 | |||
| 61 | #define ADT7462_REG_PWM_BASE_ADDR 0xAA | ||
| 62 | #define ADT7462_REG_PWM_MAX_ADDR 0xAD | ||
| 63 | #define ADT7462_REG_PWM_MIN_BASE_ADDR 0x28 | ||
| 64 | #define ADT7462_REG_PWM_MIN_MAX_ADDR 0x2B | ||
| 65 | #define ADT7462_REG_PWM_MAX 0x2C | ||
| 66 | #define ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR 0x5C | ||
| 67 | #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR 0x5F | ||
| 68 | #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR 0x60 | ||
| 69 | #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR 0x63 | ||
| 70 | #define ADT7462_PWM_HYST_MASK 0x0F | ||
| 71 | #define ADT7462_PWM_RANGE_MASK 0xF0 | ||
| 72 | #define ADT7462_PWM_RANGE_SHIFT 4 | ||
| 73 | #define ADT7462_REG_PWM_CFG_BASE_ADDR 0x21 | ||
| 74 | #define ADT7462_REG_PWM_CFG_MAX_ADDR 0x24 | ||
| 75 | #define ADT7462_PWM_CHANNEL_MASK 0xE0 | ||
| 76 | #define ADT7462_PWM_CHANNEL_SHIFT 5 | ||
| 77 | |||
| 78 | #define ADT7462_REG_PIN_CFG_BASE_ADDR 0x10 | ||
| 79 | #define ADT7462_REG_PIN_CFG_MAX_ADDR 0x13 | ||
| 80 | #define ADT7462_PIN7_INPUT 0x01 /* cfg0 */ | ||
| 81 | #define ADT7462_DIODE3_INPUT 0x20 | ||
| 82 | #define ADT7462_DIODE1_INPUT 0x40 | ||
| 83 | #define ADT7462_VID_INPUT 0x80 | ||
| 84 | #define ADT7462_PIN22_INPUT 0x04 /* cfg1 */ | ||
| 85 | #define ADT7462_PIN21_INPUT 0x08 | ||
| 86 | #define ADT7462_PIN19_INPUT 0x10 | ||
| 87 | #define ADT7462_PIN15_INPUT 0x20 | ||
| 88 | #define ADT7462_PIN13_INPUT 0x40 | ||
| 89 | #define ADT7462_PIN8_INPUT 0x80 | ||
| 90 | #define ADT7462_PIN23_MASK 0x03 | ||
| 91 | #define ADT7462_PIN23_SHIFT 0 | ||
| 92 | #define ADT7462_PIN26_MASK 0x0C /* cfg2 */ | ||
| 93 | #define ADT7462_PIN26_SHIFT 2 | ||
| 94 | #define ADT7462_PIN25_MASK 0x30 | ||
| 95 | #define ADT7462_PIN25_SHIFT 4 | ||
| 96 | #define ADT7462_PIN24_MASK 0xC0 | ||
| 97 | #define ADT7462_PIN24_SHIFT 6 | ||
| 98 | #define ADT7462_PIN26_VOLT_INPUT 0x08 | ||
| 99 | #define ADT7462_PIN25_VOLT_INPUT 0x20 | ||
| 100 | #define ADT7462_PIN28_SHIFT 6 /* cfg3 */ | ||
| 101 | #define ADT7462_PIN28_VOLT 0x5 | ||
| 102 | |||
| 103 | #define ADT7462_REG_ALARM1 0xB8 | ||
| 104 | #define ADT7462_LT_ALARM 0x02 | ||
| 105 | #define ADT7462_R1T_ALARM 0x04 | ||
| 106 | #define ADT7462_R2T_ALARM 0x08 | ||
| 107 | #define ADT7462_R3T_ALARM 0x10 | ||
| 108 | #define ADT7462_REG_ALARM2 0xBB | ||
| 109 | #define ADT7462_V0_ALARM 0x01 | ||
| 110 | #define ADT7462_V1_ALARM 0x02 | ||
| 111 | #define ADT7462_V2_ALARM 0x04 | ||
| 112 | #define ADT7462_V3_ALARM 0x08 | ||
| 113 | #define ADT7462_V4_ALARM 0x10 | ||
| 114 | #define ADT7462_V5_ALARM 0x20 | ||
| 115 | #define ADT7462_V6_ALARM 0x40 | ||
| 116 | #define ADT7462_V7_ALARM 0x80 | ||
| 117 | #define ADT7462_REG_ALARM3 0xBC | ||
| 118 | #define ADT7462_V8_ALARM 0x08 | ||
| 119 | #define ADT7462_V9_ALARM 0x10 | ||
| 120 | #define ADT7462_V10_ALARM 0x20 | ||
| 121 | #define ADT7462_V11_ALARM 0x40 | ||
| 122 | #define ADT7462_V12_ALARM 0x80 | ||
| 123 | #define ADT7462_REG_ALARM4 0xBD | ||
| 124 | #define ADT7462_F0_ALARM 0x01 | ||
| 125 | #define ADT7462_F1_ALARM 0x02 | ||
| 126 | #define ADT7462_F2_ALARM 0x04 | ||
| 127 | #define ADT7462_F3_ALARM 0x08 | ||
| 128 | #define ADT7462_F4_ALARM 0x10 | ||
| 129 | #define ADT7462_F5_ALARM 0x20 | ||
| 130 | #define ADT7462_F6_ALARM 0x40 | ||
| 131 | #define ADT7462_F7_ALARM 0x80 | ||
| 132 | #define ADT7462_ALARM1 0x0000 | ||
| 133 | #define ADT7462_ALARM2 0x0100 | ||
| 134 | #define ADT7462_ALARM3 0x0200 | ||
| 135 | #define ADT7462_ALARM4 0x0300 | ||
| 136 | #define ADT7462_ALARM_REG_SHIFT 8 | ||
| 137 | #define ADT7462_ALARM_FLAG_MASK 0x0F | ||
| 138 | |||
| 139 | #define ADT7462_TEMP_COUNT 4 | ||
| 140 | #define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + (x * 2)) | ||
| 141 | #define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) | ||
| 142 | #define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) | ||
| 143 | #define TEMP_FRAC_OFFSET 6 | ||
| 144 | |||
| 145 | #define ADT7462_FAN_COUNT 8 | ||
| 146 | #define ADT7462_REG_FAN_MIN(x) (ADT7462_REG_FAN_MIN_BASE_ADDR + (x)) | ||
| 147 | |||
| 148 | #define ADT7462_PWM_COUNT 4 | ||
| 149 | #define ADT7462_REG_PWM(x) (ADT7462_REG_PWM_BASE_ADDR + (x)) | ||
| 150 | #define ADT7462_REG_PWM_MIN(x) (ADT7462_REG_PWM_MIN_BASE_ADDR + (x)) | ||
| 151 | #define ADT7462_REG_PWM_TMIN(x) \ | ||
| 152 | (ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) | ||
| 153 | #define ADT7462_REG_PWM_TRANGE(x) \ | ||
| 154 | (ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR + (x)) | ||
| 155 | |||
| 156 | #define ADT7462_PIN_CFG_REG_COUNT 4 | ||
| 157 | #define ADT7462_REG_PIN_CFG(x) (ADT7462_REG_PIN_CFG_BASE_ADDR + (x)) | ||
| 158 | #define ADT7462_REG_PWM_CFG(x) (ADT7462_REG_PWM_CFG_BASE_ADDR + (x)) | ||
| 159 | |||
| 160 | #define ADT7462_ALARM_REG_COUNT 4 | ||
| 161 | |||
| 162 | /* | ||
| 163 | * The chip can measure 13 different voltage sources: | ||
| 164 | * | ||
| 165 | * 1. +12V1 (pin 7) | ||
| 166 | * 2. Vccp1/+2.5V/+1.8V/+1.5V (pin 23) | ||
| 167 | * 3. +12V3 (pin 22) | ||
| 168 | * 4. +5V (pin 21) | ||
| 169 | * 5. +1.25V/+0.9V (pin 19) | ||
| 170 | * 6. +2.5V/+1.8V (pin 15) | ||
| 171 | * 7. +3.3v (pin 13) | ||
| 172 | * 8. +12V2 (pin 8) | ||
| 173 | * 9. Vbatt/FSB_Vtt (pin 26) | ||
| 174 | * A. +3.3V/+1.2V1 (pin 25) | ||
| 175 | * B. Vccp2/+2.5V/+1.8V/+1.5V (pin 24) | ||
| 176 | * C. +1.5V ICH (only if BOTH pin 28/29 are set to +1.5V) | ||
| 177 | * D. +1.5V 3GPIO (only if BOTH pin 28/29 are set to +1.5V) | ||
| 178 | * | ||
| 179 | * Each of these 13 has a factor to convert raw to voltage. Even better, | ||
| 180 | * the pins can be connected to other sensors (tach/gpio/hot/etc), which | ||
| 181 | * makes the bookkeeping tricky. | ||
| 182 | * | ||
| 183 | * Some, but not all, of these voltages have low/high limits. | ||
| 184 | */ | ||
| 185 | #define ADT7462_VOLT_COUNT 12 | ||
| 186 | |||
| 187 | #define ADT7462_VENDOR 0x41 | ||
| 188 | #define ADT7462_DEVICE 0x62 | ||
| 189 | /* datasheet only mentions a revision 4 */ | ||
| 190 | #define ADT7462_REVISION 0x04 | ||
| 191 | |||
| 192 | /* How often do we reread sensors values? (In jiffies) */ | ||
| 193 | #define SENSOR_REFRESH_INTERVAL (2 * HZ) | ||
| 194 | |||
| 195 | /* How often do we reread sensor limit values? (In jiffies) */ | ||
| 196 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | ||
| 197 | |||
| 198 | /* datasheet says to divide this number by the fan reading to get fan rpm */ | ||
| 199 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | ||
| 200 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM | ||
| 201 | #define FAN_PERIOD_INVALID 65535 | ||
| 202 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | ||
| 203 | |||
| 204 | #define MASK_AND_SHIFT(value, prefix) \ | ||
| 205 | (((value) & prefix##_MASK) >> prefix##_SHIFT) | ||
| 206 | |||
| 207 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
| 208 | |||
| 209 | struct adt7462_data { | ||
| 210 | struct device *hwmon_dev; | ||
| 211 | struct attribute_group attrs; | ||
| 212 | struct mutex lock; | ||
| 213 | char sensors_valid; | ||
| 214 | char limits_valid; | ||
| 215 | unsigned long sensors_last_updated; /* In jiffies */ | ||
| 216 | unsigned long limits_last_updated; /* In jiffies */ | ||
| 217 | |||
| 218 | u8 temp[ADT7462_TEMP_COUNT]; | ||
| 219 | /* bits 6-7 are quarter pieces of temp */ | ||
| 220 | u8 temp_frac[ADT7462_TEMP_COUNT]; | ||
| 221 | u8 temp_min[ADT7462_TEMP_COUNT]; | ||
| 222 | u8 temp_max[ADT7462_TEMP_COUNT]; | ||
| 223 | u16 fan[ADT7462_FAN_COUNT]; | ||
| 224 | u8 fan_enabled; | ||
| 225 | u8 fan_min[ADT7462_FAN_COUNT]; | ||
| 226 | u8 cfg2; | ||
| 227 | u8 pwm[ADT7462_PWM_COUNT]; | ||
| 228 | u8 pin_cfg[ADT7462_PIN_CFG_REG_COUNT]; | ||
| 229 | u8 voltages[ADT7462_VOLT_COUNT]; | ||
| 230 | u8 volt_max[ADT7462_VOLT_COUNT]; | ||
| 231 | u8 volt_min[ADT7462_VOLT_COUNT]; | ||
| 232 | u8 pwm_min[ADT7462_PWM_COUNT]; | ||
| 233 | u8 pwm_tmin[ADT7462_PWM_COUNT]; | ||
| 234 | u8 pwm_trange[ADT7462_PWM_COUNT]; | ||
| 235 | u8 pwm_max; /* only one per chip */ | ||
| 236 | u8 pwm_cfg[ADT7462_PWM_COUNT]; | ||
| 237 | u8 alarms[ADT7462_ALARM_REG_COUNT]; | ||
| 238 | }; | ||
| 239 | |||
| 240 | static int adt7462_probe(struct i2c_client *client, | ||
| 241 | const struct i2c_device_id *id); | ||
| 242 | static int adt7462_detect(struct i2c_client *client, int kind, | ||
| 243 | struct i2c_board_info *info); | ||
| 244 | static int adt7462_remove(struct i2c_client *client); | ||
| 245 | |||
| 246 | static const struct i2c_device_id adt7462_id[] = { | ||
| 247 | { "adt7462", adt7462 }, | ||
| 248 | { } | ||
| 249 | }; | ||
| 250 | MODULE_DEVICE_TABLE(i2c, adt7462_id); | ||
| 251 | |||
| 252 | static struct i2c_driver adt7462_driver = { | ||
| 253 | .class = I2C_CLASS_HWMON, | ||
| 254 | .driver = { | ||
| 255 | .name = "adt7462", | ||
| 256 | }, | ||
| 257 | .probe = adt7462_probe, | ||
| 258 | .remove = adt7462_remove, | ||
| 259 | .id_table = adt7462_id, | ||
| 260 | .detect = adt7462_detect, | ||
| 261 | .address_data = &addr_data, | ||
| 262 | }; | ||
| 263 | |||
| 264 | /* | ||
| 265 | * 16-bit registers on the ADT7462 are low-byte first. The data sheet says | ||
| 266 | * that the low byte must be read before the high byte. | ||
| 267 | */ | ||
| 268 | static inline int adt7462_read_word_data(struct i2c_client *client, u8 reg) | ||
| 269 | { | ||
| 270 | u16 foo; | ||
| 271 | foo = i2c_smbus_read_byte_data(client, reg); | ||
| 272 | foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); | ||
| 273 | return foo; | ||
| 274 | } | ||
| 275 | |||
| 276 | /* For some reason these registers are not contiguous. */ | ||
| 277 | static int ADT7462_REG_FAN(int fan) | ||
| 278 | { | ||
| 279 | if (fan < 4) | ||
| 280 | return ADT7462_REG_FAN_BASE_ADDR + (2 * fan); | ||
| 281 | return ADT7462_REG_FAN2_BASE_ADDR + (2 * (fan - 4)); | ||
| 282 | } | ||
| 283 | |||
| 284 | /* Voltage registers are scattered everywhere */ | ||
| 285 | static int ADT7462_REG_VOLT_MAX(struct adt7462_data *data, int which) | ||
| 286 | { | ||
| 287 | switch (which) { | ||
| 288 | case 0: | ||
| 289 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
| 290 | return 0x7C; | ||
| 291 | break; | ||
| 292 | case 1: | ||
| 293 | return 0x69; | ||
| 294 | case 2: | ||
| 295 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
| 296 | return 0x7F; | ||
| 297 | break; | ||
| 298 | case 3: | ||
| 299 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
| 300 | return 0x7E; | ||
| 301 | break; | ||
| 302 | case 4: | ||
| 303 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | ||
| 304 | return 0x4B; | ||
| 305 | break; | ||
| 306 | case 5: | ||
| 307 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | ||
| 308 | return 0x49; | ||
| 309 | break; | ||
| 310 | case 6: | ||
| 311 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
| 312 | return 0x68; | ||
| 313 | break; | ||
| 314 | case 7: | ||
| 315 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
| 316 | return 0x7D; | ||
| 317 | break; | ||
| 318 | case 8: | ||
| 319 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | ||
| 320 | return 0x6C; | ||
| 321 | break; | ||
| 322 | case 9: | ||
| 323 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | ||
| 324 | return 0x6B; | ||
| 325 | break; | ||
| 326 | case 10: | ||
| 327 | return 0x6A; | ||
| 328 | case 11: | ||
| 329 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 330 | ADT7462_PIN28_VOLT && | ||
| 331 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 332 | return 0x50; | ||
| 333 | break; | ||
| 334 | case 12: | ||
| 335 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 336 | ADT7462_PIN28_VOLT && | ||
| 337 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 338 | return 0x4C; | ||
| 339 | break; | ||
| 340 | } | ||
| 341 | return -ENODEV; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int ADT7462_REG_VOLT_MIN(struct adt7462_data *data, int which) | ||
| 345 | { | ||
| 346 | switch (which) { | ||
| 347 | case 0: | ||
| 348 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
| 349 | return 0x6D; | ||
| 350 | break; | ||
| 351 | case 1: | ||
| 352 | return 0x72; | ||
| 353 | case 2: | ||
| 354 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
| 355 | return 0x6F; | ||
| 356 | break; | ||
| 357 | case 3: | ||
| 358 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
| 359 | return 0x71; | ||
| 360 | break; | ||
| 361 | case 4: | ||
| 362 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | ||
| 363 | return 0x47; | ||
| 364 | break; | ||
| 365 | case 5: | ||
| 366 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | ||
| 367 | return 0x45; | ||
| 368 | break; | ||
| 369 | case 6: | ||
| 370 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
| 371 | return 0x70; | ||
| 372 | break; | ||
| 373 | case 7: | ||
| 374 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
| 375 | return 0x6E; | ||
| 376 | break; | ||
| 377 | case 8: | ||
| 378 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | ||
| 379 | return 0x75; | ||
| 380 | break; | ||
| 381 | case 9: | ||
| 382 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | ||
| 383 | return 0x74; | ||
| 384 | break; | ||
| 385 | case 10: | ||
| 386 | return 0x73; | ||
| 387 | case 11: | ||
| 388 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 389 | ADT7462_PIN28_VOLT && | ||
| 390 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 391 | return 0x76; | ||
| 392 | break; | ||
| 393 | case 12: | ||
| 394 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 395 | ADT7462_PIN28_VOLT && | ||
| 396 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 397 | return 0x77; | ||
| 398 | break; | ||
| 399 | } | ||
| 400 | return -ENODEV; | ||
| 401 | } | ||
| 402 | |||
| 403 | static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) | ||
| 404 | { | ||
| 405 | switch (which) { | ||
| 406 | case 0: | ||
| 407 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
| 408 | return 0xA3; | ||
| 409 | break; | ||
| 410 | case 1: | ||
| 411 | return 0x90; | ||
| 412 | case 2: | ||
| 413 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
| 414 | return 0xA9; | ||
| 415 | break; | ||
| 416 | case 3: | ||
| 417 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
| 418 | return 0xA7; | ||
| 419 | break; | ||
| 420 | case 4: | ||
| 421 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | ||
| 422 | return 0x8F; | ||
| 423 | break; | ||
| 424 | case 5: | ||
| 425 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | ||
| 426 | return 0x8B; | ||
| 427 | break; | ||
| 428 | case 6: | ||
| 429 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
| 430 | return 0x96; | ||
| 431 | break; | ||
| 432 | case 7: | ||
| 433 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
| 434 | return 0xA5; | ||
| 435 | break; | ||
| 436 | case 8: | ||
| 437 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | ||
| 438 | return 0x93; | ||
| 439 | break; | ||
| 440 | case 9: | ||
| 441 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | ||
| 442 | return 0x92; | ||
| 443 | break; | ||
| 444 | case 10: | ||
| 445 | return 0x91; | ||
| 446 | case 11: | ||
| 447 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 448 | ADT7462_PIN28_VOLT && | ||
| 449 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 450 | return 0x94; | ||
| 451 | break; | ||
| 452 | case 12: | ||
| 453 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 454 | ADT7462_PIN28_VOLT && | ||
| 455 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 456 | return 0x95; | ||
| 457 | break; | ||
| 458 | } | ||
| 459 | return -ENODEV; | ||
| 460 | } | ||
| 461 | |||
| 462 | /* Provide labels for sysfs */ | ||
| 463 | static const char *voltage_label(struct adt7462_data *data, int which) | ||
| 464 | { | ||
| 465 | switch (which) { | ||
| 466 | case 0: | ||
| 467 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
| 468 | return "+12V1"; | ||
| 469 | break; | ||
| 470 | case 1: | ||
| 471 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { | ||
| 472 | case 0: | ||
| 473 | return "Vccp1"; | ||
| 474 | case 1: | ||
| 475 | return "+2.5V"; | ||
| 476 | case 2: | ||
| 477 | return "+1.8V"; | ||
| 478 | case 3: | ||
| 479 | return "+1.5V"; | ||
| 480 | } | ||
| 481 | case 2: | ||
| 482 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
| 483 | return "+12V3"; | ||
| 484 | break; | ||
| 485 | case 3: | ||
| 486 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
| 487 | return "+5V"; | ||
| 488 | break; | ||
| 489 | case 4: | ||
| 490 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { | ||
| 491 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | ||
| 492 | return "+0.9V"; | ||
| 493 | return "+1.25V"; | ||
| 494 | } | ||
| 495 | break; | ||
| 496 | case 5: | ||
| 497 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { | ||
| 498 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | ||
| 499 | return "+1.8V"; | ||
| 500 | return "+2.5V"; | ||
| 501 | } | ||
| 502 | break; | ||
| 503 | case 6: | ||
| 504 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
| 505 | return "+3.3V"; | ||
| 506 | break; | ||
| 507 | case 7: | ||
| 508 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
| 509 | return "+12V2"; | ||
| 510 | break; | ||
| 511 | case 8: | ||
| 512 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { | ||
| 513 | case 0: | ||
| 514 | return "Vbatt"; | ||
| 515 | case 1: | ||
| 516 | return "FSB_Vtt"; | ||
| 517 | } | ||
| 518 | break; | ||
| 519 | case 9: | ||
| 520 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { | ||
| 521 | case 0: | ||
| 522 | return "+3.3V"; | ||
| 523 | case 1: | ||
| 524 | return "+1.2V1"; | ||
| 525 | } | ||
| 526 | break; | ||
| 527 | case 10: | ||
| 528 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { | ||
| 529 | case 0: | ||
| 530 | return "Vccp2"; | ||
| 531 | case 1: | ||
| 532 | return "+2.5V"; | ||
| 533 | case 2: | ||
| 534 | return "+1.8V"; | ||
| 535 | case 3: | ||
| 536 | return "+1.5"; | ||
| 537 | } | ||
| 538 | case 11: | ||
| 539 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 540 | ADT7462_PIN28_VOLT && | ||
| 541 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 542 | return "+1.5V ICH"; | ||
| 543 | break; | ||
| 544 | case 12: | ||
| 545 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 546 | ADT7462_PIN28_VOLT && | ||
| 547 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 548 | return "+1.5V 3GPIO"; | ||
| 549 | break; | ||
| 550 | } | ||
| 551 | return "N/A"; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* Multipliers are actually in uV, not mV. */ | ||
| 555 | static int voltage_multiplier(struct adt7462_data *data, int which) | ||
| 556 | { | ||
| 557 | switch (which) { | ||
| 558 | case 0: | ||
| 559 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
| 560 | return 62500; | ||
| 561 | break; | ||
| 562 | case 1: | ||
| 563 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { | ||
| 564 | case 0: | ||
| 565 | if (data->pin_cfg[0] & ADT7462_VID_INPUT) | ||
| 566 | return 12500; | ||
| 567 | return 6250; | ||
| 568 | case 1: | ||
| 569 | return 13000; | ||
| 570 | case 2: | ||
| 571 | return 9400; | ||
| 572 | case 3: | ||
| 573 | return 7800; | ||
| 574 | } | ||
| 575 | case 2: | ||
| 576 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
| 577 | return 62500; | ||
| 578 | break; | ||
| 579 | case 3: | ||
| 580 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
| 581 | return 26000; | ||
| 582 | break; | ||
| 583 | case 4: | ||
| 584 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { | ||
| 585 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | ||
| 586 | return 4690; | ||
| 587 | return 6500; | ||
| 588 | } | ||
| 589 | break; | ||
| 590 | case 5: | ||
| 591 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { | ||
| 592 | if (data->pin_cfg[1] & ADT7462_PIN15_INPUT) | ||
| 593 | return 9400; | ||
| 594 | return 13000; | ||
| 595 | } | ||
| 596 | break; | ||
| 597 | case 6: | ||
| 598 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
| 599 | return 17200; | ||
| 600 | break; | ||
| 601 | case 7: | ||
| 602 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
| 603 | return 62500; | ||
| 604 | break; | ||
| 605 | case 8: | ||
| 606 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { | ||
| 607 | case 0: | ||
| 608 | return 15600; | ||
| 609 | case 1: | ||
| 610 | return 6250; | ||
| 611 | } | ||
| 612 | break; | ||
| 613 | case 9: | ||
| 614 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { | ||
| 615 | case 0: | ||
| 616 | return 17200; | ||
| 617 | case 1: | ||
| 618 | return 6250; | ||
| 619 | } | ||
| 620 | break; | ||
| 621 | case 10: | ||
| 622 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { | ||
| 623 | case 0: | ||
| 624 | return 6250; | ||
| 625 | case 1: | ||
| 626 | return 13000; | ||
| 627 | case 2: | ||
| 628 | return 9400; | ||
| 629 | case 3: | ||
| 630 | return 7800; | ||
| 631 | } | ||
| 632 | case 11: | ||
| 633 | case 12: | ||
| 634 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
| 635 | ADT7462_PIN28_VOLT && | ||
| 636 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
| 637 | return 7800; | ||
| 638 | } | ||
| 639 | return 0; | ||
| 640 | } | ||
| 641 | |||
| 642 | static int temp_enabled(struct adt7462_data *data, int which) | ||
| 643 | { | ||
| 644 | switch (which) { | ||
| 645 | case 0: | ||
| 646 | case 2: | ||
| 647 | return 1; | ||
| 648 | case 1: | ||
| 649 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) | ||
| 650 | return 1; | ||
| 651 | break; | ||
| 652 | case 3: | ||
| 653 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) | ||
| 654 | return 1; | ||
| 655 | break; | ||
| 656 | } | ||
| 657 | return 0; | ||
| 658 | } | ||
| 659 | |||
| 660 | static const char *temp_label(struct adt7462_data *data, int which) | ||
| 661 | { | ||
| 662 | switch (which) { | ||
| 663 | case 0: | ||
| 664 | return "local"; | ||
| 665 | case 1: | ||
| 666 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) | ||
| 667 | return "remote1"; | ||
| 668 | break; | ||
| 669 | case 2: | ||
| 670 | return "remote2"; | ||
| 671 | case 3: | ||
| 672 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) | ||
| 673 | return "remote3"; | ||
| 674 | break; | ||
| 675 | } | ||
| 676 | return "N/A"; | ||
| 677 | } | ||
| 678 | |||
| 679 | /* Map Trange register values to mC */ | ||
| 680 | #define NUM_TRANGE_VALUES 16 | ||
| 681 | static const int trange_values[NUM_TRANGE_VALUES] = { | ||
| 682 | 2000, | ||
| 683 | 2500, | ||
| 684 | 3300, | ||
| 685 | 4000, | ||
| 686 | 5000, | ||
| 687 | 6700, | ||
| 688 | 8000, | ||
| 689 | 10000, | ||
| 690 | 13300, | ||
| 691 | 16000, | ||
| 692 | 20000, | ||
| 693 | 26700, | ||
| 694 | 32000, | ||
| 695 | 40000, | ||
| 696 | 53300, | ||
| 697 | 80000 | ||
| 698 | }; | ||
| 699 | |||
| 700 | static int find_trange_value(int trange) | ||
| 701 | { | ||
| 702 | int i; | ||
| 703 | |||
| 704 | for (i = 0; i < NUM_TRANGE_VALUES; i++) | ||
| 705 | if (trange_values[i] == trange) | ||
| 706 | return i; | ||
| 707 | |||
| 708 | return -ENODEV; | ||
| 709 | } | ||
| 710 | |||
| 711 | static struct adt7462_data *adt7462_update_device(struct device *dev) | ||
| 712 | { | ||
| 713 | struct i2c_client *client = to_i2c_client(dev); | ||
| 714 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 715 | unsigned long local_jiffies = jiffies; | ||
| 716 | int i; | ||
| 717 | |||
| 718 | mutex_lock(&data->lock); | ||
| 719 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
| 720 | SENSOR_REFRESH_INTERVAL) | ||
| 721 | && data->sensors_valid) | ||
| 722 | goto no_sensor_update; | ||
| 723 | |||
| 724 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { | ||
| 725 | /* | ||
| 726 | * Reading the fractional register locks the integral | ||
| 727 | * register until both have been read. | ||
| 728 | */ | ||
| 729 | data->temp_frac[i] = i2c_smbus_read_byte_data(client, | ||
| 730 | ADT7462_TEMP_REG(i)); | ||
| 731 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
| 732 | ADT7462_TEMP_REG(i) + 1); | ||
| 733 | } | ||
| 734 | |||
| 735 | for (i = 0; i < ADT7462_FAN_COUNT; i++) | ||
| 736 | data->fan[i] = adt7462_read_word_data(client, | ||
| 737 | ADT7462_REG_FAN(i)); | ||
| 738 | |||
| 739 | data->fan_enabled = i2c_smbus_read_byte_data(client, | ||
| 740 | ADT7462_REG_FAN_ENABLE); | ||
| 741 | |||
| 742 | for (i = 0; i < ADT7462_PWM_COUNT; i++) | ||
| 743 | data->pwm[i] = i2c_smbus_read_byte_data(client, | ||
| 744 | ADT7462_REG_PWM(i)); | ||
| 745 | |||
| 746 | for (i = 0; i < ADT7462_PIN_CFG_REG_COUNT; i++) | ||
| 747 | data->pin_cfg[i] = i2c_smbus_read_byte_data(client, | ||
| 748 | ADT7462_REG_PIN_CFG(i)); | ||
| 749 | |||
| 750 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { | ||
| 751 | int reg = ADT7462_REG_VOLT(data, i); | ||
| 752 | if (!reg) | ||
| 753 | data->voltages[i] = 0; | ||
| 754 | else | ||
| 755 | data->voltages[i] = i2c_smbus_read_byte_data(client, | ||
| 756 | reg); | ||
| 757 | } | ||
| 758 | |||
| 759 | data->alarms[0] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM1); | ||
| 760 | data->alarms[1] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM2); | ||
| 761 | data->alarms[2] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM3); | ||
| 762 | data->alarms[3] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM4); | ||
| 763 | |||
| 764 | data->sensors_last_updated = local_jiffies; | ||
| 765 | data->sensors_valid = 1; | ||
| 766 | |||
| 767 | no_sensor_update: | ||
| 768 | if (time_before(local_jiffies, data->limits_last_updated + | ||
| 769 | LIMIT_REFRESH_INTERVAL) | ||
| 770 | && data->limits_valid) | ||
| 771 | goto out; | ||
| 772 | |||
| 773 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { | ||
| 774 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | ||
| 775 | ADT7462_TEMP_MIN_REG(i)); | ||
| 776 | data->temp_max[i] = i2c_smbus_read_byte_data(client, | ||
| 777 | ADT7462_TEMP_MAX_REG(i)); | ||
| 778 | } | ||
| 779 | |||
| 780 | for (i = 0; i < ADT7462_FAN_COUNT; i++) | ||
| 781 | data->fan_min[i] = i2c_smbus_read_byte_data(client, | ||
| 782 | ADT7462_REG_FAN_MIN(i)); | ||
| 783 | |||
| 784 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { | ||
| 785 | int reg = ADT7462_REG_VOLT_MAX(data, i); | ||
| 786 | data->volt_max[i] = | ||
| 787 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); | ||
| 788 | |||
| 789 | reg = ADT7462_REG_VOLT_MIN(data, i); | ||
| 790 | data->volt_min[i] = | ||
| 791 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); | ||
| 792 | } | ||
| 793 | |||
| 794 | for (i = 0; i < ADT7462_PWM_COUNT; i++) { | ||
| 795 | data->pwm_min[i] = i2c_smbus_read_byte_data(client, | ||
| 796 | ADT7462_REG_PWM_MIN(i)); | ||
| 797 | data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, | ||
| 798 | ADT7462_REG_PWM_TMIN(i)); | ||
| 799 | data->pwm_trange[i] = i2c_smbus_read_byte_data(client, | ||
| 800 | ADT7462_REG_PWM_TRANGE(i)); | ||
| 801 | data->pwm_cfg[i] = i2c_smbus_read_byte_data(client, | ||
| 802 | ADT7462_REG_PWM_CFG(i)); | ||
| 803 | } | ||
| 804 | |||
| 805 | data->pwm_max = i2c_smbus_read_byte_data(client, ADT7462_REG_PWM_MAX); | ||
| 806 | |||
| 807 | data->cfg2 = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); | ||
| 808 | |||
| 809 | data->limits_last_updated = local_jiffies; | ||
| 810 | data->limits_valid = 1; | ||
| 811 | |||
| 812 | out: | ||
| 813 | mutex_unlock(&data->lock); | ||
| 814 | return data; | ||
| 815 | } | ||
| 816 | |||
| 817 | static ssize_t show_temp_min(struct device *dev, | ||
| 818 | struct device_attribute *devattr, | ||
| 819 | char *buf) | ||
| 820 | { | ||
| 821 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 822 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 823 | |||
| 824 | if (!temp_enabled(data, attr->index)) | ||
| 825 | return sprintf(buf, "0\n"); | ||
| 826 | |||
| 827 | return sprintf(buf, "%d\n", 1000 * (data->temp_min[attr->index] - 64)); | ||
| 828 | } | ||
| 829 | |||
| 830 | static ssize_t set_temp_min(struct device *dev, | ||
| 831 | struct device_attribute *devattr, | ||
| 832 | const char *buf, | ||
| 833 | size_t count) | ||
| 834 | { | ||
| 835 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 836 | struct i2c_client *client = to_i2c_client(dev); | ||
| 837 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 838 | long temp; | ||
| 839 | |||
| 840 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | ||
| 841 | return -EINVAL; | ||
| 842 | |||
| 843 | temp = ROUND_DIV(temp, 1000) + 64; | ||
| 844 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 845 | |||
| 846 | mutex_lock(&data->lock); | ||
| 847 | data->temp_min[attr->index] = temp; | ||
| 848 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MIN_REG(attr->index), | ||
| 849 | temp); | ||
| 850 | mutex_unlock(&data->lock); | ||
| 851 | |||
| 852 | return count; | ||
| 853 | } | ||
| 854 | |||
| 855 | static ssize_t show_temp_max(struct device *dev, | ||
| 856 | struct device_attribute *devattr, | ||
| 857 | char *buf) | ||
| 858 | { | ||
| 859 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 860 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 861 | |||
| 862 | if (!temp_enabled(data, attr->index)) | ||
| 863 | return sprintf(buf, "0\n"); | ||
| 864 | |||
| 865 | return sprintf(buf, "%d\n", 1000 * (data->temp_max[attr->index] - 64)); | ||
| 866 | } | ||
| 867 | |||
| 868 | static ssize_t set_temp_max(struct device *dev, | ||
| 869 | struct device_attribute *devattr, | ||
| 870 | const char *buf, | ||
| 871 | size_t count) | ||
| 872 | { | ||
| 873 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 874 | struct i2c_client *client = to_i2c_client(dev); | ||
| 875 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 876 | long temp; | ||
| 877 | |||
| 878 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | ||
| 879 | return -EINVAL; | ||
| 880 | |||
| 881 | temp = ROUND_DIV(temp, 1000) + 64; | ||
| 882 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 883 | |||
| 884 | mutex_lock(&data->lock); | ||
| 885 | data->temp_max[attr->index] = temp; | ||
| 886 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MAX_REG(attr->index), | ||
| 887 | temp); | ||
| 888 | mutex_unlock(&data->lock); | ||
| 889 | |||
| 890 | return count; | ||
| 891 | } | ||
| 892 | |||
| 893 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
| 894 | char *buf) | ||
| 895 | { | ||
| 896 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 897 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 898 | u8 frac = data->temp_frac[attr->index] >> TEMP_FRAC_OFFSET; | ||
| 899 | |||
| 900 | if (!temp_enabled(data, attr->index)) | ||
| 901 | return sprintf(buf, "0\n"); | ||
| 902 | |||
| 903 | return sprintf(buf, "%d\n", 1000 * (data->temp[attr->index] - 64) + | ||
| 904 | 250 * frac); | ||
| 905 | } | ||
| 906 | |||
| 907 | static ssize_t show_temp_label(struct device *dev, | ||
| 908 | struct device_attribute *devattr, | ||
| 909 | char *buf) | ||
| 910 | { | ||
| 911 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 912 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 913 | |||
| 914 | return sprintf(buf, "%s\n", temp_label(data, attr->index)); | ||
| 915 | } | ||
| 916 | |||
| 917 | static ssize_t show_volt_max(struct device *dev, | ||
| 918 | struct device_attribute *devattr, | ||
| 919 | char *buf) | ||
| 920 | { | ||
| 921 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 922 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 923 | int x = voltage_multiplier(data, attr->index); | ||
| 924 | |||
| 925 | x *= data->volt_max[attr->index]; | ||
| 926 | x /= 1000; /* convert from uV to mV */ | ||
| 927 | |||
| 928 | return sprintf(buf, "%d\n", x); | ||
| 929 | } | ||
| 930 | |||
| 931 | static ssize_t set_volt_max(struct device *dev, | ||
| 932 | struct device_attribute *devattr, | ||
| 933 | const char *buf, | ||
| 934 | size_t count) | ||
| 935 | { | ||
| 936 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 937 | struct i2c_client *client = to_i2c_client(dev); | ||
| 938 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 939 | int x = voltage_multiplier(data, attr->index); | ||
| 940 | long temp; | ||
| 941 | |||
| 942 | if (strict_strtol(buf, 10, &temp) || !x) | ||
| 943 | return -EINVAL; | ||
| 944 | |||
| 945 | temp *= 1000; /* convert mV to uV */ | ||
| 946 | temp = ROUND_DIV(temp, x); | ||
| 947 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 948 | |||
| 949 | mutex_lock(&data->lock); | ||
| 950 | data->volt_max[attr->index] = temp; | ||
| 951 | i2c_smbus_write_byte_data(client, | ||
| 952 | ADT7462_REG_VOLT_MAX(data, attr->index), | ||
| 953 | temp); | ||
| 954 | mutex_unlock(&data->lock); | ||
| 955 | |||
| 956 | return count; | ||
| 957 | } | ||
| 958 | |||
| 959 | static ssize_t show_volt_min(struct device *dev, | ||
| 960 | struct device_attribute *devattr, | ||
| 961 | char *buf) | ||
| 962 | { | ||
| 963 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 964 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 965 | int x = voltage_multiplier(data, attr->index); | ||
| 966 | |||
| 967 | x *= data->volt_min[attr->index]; | ||
| 968 | x /= 1000; /* convert from uV to mV */ | ||
| 969 | |||
| 970 | return sprintf(buf, "%d\n", x); | ||
| 971 | } | ||
| 972 | |||
| 973 | static ssize_t set_volt_min(struct device *dev, | ||
| 974 | struct device_attribute *devattr, | ||
| 975 | const char *buf, | ||
| 976 | size_t count) | ||
| 977 | { | ||
| 978 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 979 | struct i2c_client *client = to_i2c_client(dev); | ||
| 980 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 981 | int x = voltage_multiplier(data, attr->index); | ||
| 982 | long temp; | ||
| 983 | |||
| 984 | if (strict_strtol(buf, 10, &temp) || !x) | ||
| 985 | return -EINVAL; | ||
| 986 | |||
| 987 | temp *= 1000; /* convert mV to uV */ | ||
| 988 | temp = ROUND_DIV(temp, x); | ||
| 989 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 990 | |||
| 991 | mutex_lock(&data->lock); | ||
| 992 | data->volt_min[attr->index] = temp; | ||
| 993 | i2c_smbus_write_byte_data(client, | ||
| 994 | ADT7462_REG_VOLT_MIN(data, attr->index), | ||
| 995 | temp); | ||
| 996 | mutex_unlock(&data->lock); | ||
| 997 | |||
| 998 | return count; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | static ssize_t show_voltage(struct device *dev, | ||
| 1002 | struct device_attribute *devattr, | ||
| 1003 | char *buf) | ||
| 1004 | { | ||
| 1005 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1006 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1007 | int x = voltage_multiplier(data, attr->index); | ||
| 1008 | |||
| 1009 | x *= data->voltages[attr->index]; | ||
| 1010 | x /= 1000; /* convert from uV to mV */ | ||
| 1011 | |||
| 1012 | return sprintf(buf, "%d\n", x); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | static ssize_t show_voltage_label(struct device *dev, | ||
| 1016 | struct device_attribute *devattr, | ||
| 1017 | char *buf) | ||
| 1018 | { | ||
| 1019 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1020 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1021 | |||
| 1022 | return sprintf(buf, "%s\n", voltage_label(data, attr->index)); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | static ssize_t show_alarm(struct device *dev, | ||
| 1026 | struct device_attribute *devattr, | ||
| 1027 | char *buf) | ||
| 1028 | { | ||
| 1029 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1030 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1031 | int reg = attr->index >> ADT7462_ALARM_REG_SHIFT; | ||
| 1032 | int mask = attr->index & ADT7462_ALARM_FLAG_MASK; | ||
| 1033 | |||
| 1034 | if (data->alarms[reg] & mask) | ||
| 1035 | return sprintf(buf, "1\n"); | ||
| 1036 | else | ||
| 1037 | return sprintf(buf, "0\n"); | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | static int fan_enabled(struct adt7462_data *data, int fan) | ||
| 1041 | { | ||
| 1042 | return data->fan_enabled & (1 << fan); | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | static ssize_t show_fan_min(struct device *dev, | ||
| 1046 | struct device_attribute *devattr, | ||
| 1047 | char *buf) | ||
| 1048 | { | ||
| 1049 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1050 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1051 | u16 temp; | ||
| 1052 | |||
| 1053 | /* Only the MSB of the min fan period is stored... */ | ||
| 1054 | temp = data->fan_min[attr->index]; | ||
| 1055 | temp <<= 8; | ||
| 1056 | |||
| 1057 | if (!fan_enabled(data, attr->index) || | ||
| 1058 | !FAN_DATA_VALID(temp)) | ||
| 1059 | return sprintf(buf, "0\n"); | ||
| 1060 | |||
| 1061 | return sprintf(buf, "%d\n", FAN_PERIOD_TO_RPM(temp)); | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | static ssize_t set_fan_min(struct device *dev, | ||
| 1065 | struct device_attribute *devattr, | ||
| 1066 | const char *buf, size_t count) | ||
| 1067 | { | ||
| 1068 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1069 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1070 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1071 | long temp; | ||
| 1072 | |||
| 1073 | if (strict_strtol(buf, 10, &temp) || !temp || | ||
| 1074 | !fan_enabled(data, attr->index)) | ||
| 1075 | return -EINVAL; | ||
| 1076 | |||
| 1077 | temp = FAN_RPM_TO_PERIOD(temp); | ||
| 1078 | temp >>= 8; | ||
| 1079 | temp = SENSORS_LIMIT(temp, 1, 255); | ||
| 1080 | |||
| 1081 | mutex_lock(&data->lock); | ||
| 1082 | data->fan_min[attr->index] = temp; | ||
| 1083 | i2c_smbus_write_byte_data(client, ADT7462_REG_FAN_MIN(attr->index), | ||
| 1084 | temp); | ||
| 1085 | mutex_unlock(&data->lock); | ||
| 1086 | |||
| 1087 | return count; | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
| 1091 | char *buf) | ||
| 1092 | { | ||
| 1093 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1094 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1095 | |||
| 1096 | if (!fan_enabled(data, attr->index) || | ||
| 1097 | !FAN_DATA_VALID(data->fan[attr->index])) | ||
| 1098 | return sprintf(buf, "0\n"); | ||
| 1099 | |||
| 1100 | return sprintf(buf, "%d\n", | ||
| 1101 | FAN_PERIOD_TO_RPM(data->fan[attr->index])); | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | static ssize_t show_force_pwm_max(struct device *dev, | ||
| 1105 | struct device_attribute *devattr, | ||
| 1106 | char *buf) | ||
| 1107 | { | ||
| 1108 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1109 | return sprintf(buf, "%d\n", (data->cfg2 & ADT7462_FSPD_MASK ? 1 : 0)); | ||
| 1110 | } | ||
| 1111 | |||
| 1112 | static ssize_t set_force_pwm_max(struct device *dev, | ||
| 1113 | struct device_attribute *devattr, | ||
| 1114 | const char *buf, | ||
| 1115 | size_t count) | ||
| 1116 | { | ||
| 1117 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1118 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1119 | long temp; | ||
| 1120 | u8 reg; | ||
| 1121 | |||
| 1122 | if (strict_strtol(buf, 10, &temp)) | ||
| 1123 | return -EINVAL; | ||
| 1124 | |||
| 1125 | mutex_lock(&data->lock); | ||
| 1126 | reg = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); | ||
| 1127 | if (temp) | ||
| 1128 | reg |= ADT7462_FSPD_MASK; | ||
| 1129 | else | ||
| 1130 | reg &= ~ADT7462_FSPD_MASK; | ||
| 1131 | data->cfg2 = reg; | ||
| 1132 | i2c_smbus_write_byte_data(client, ADT7462_REG_CFG2, reg); | ||
| 1133 | mutex_unlock(&data->lock); | ||
| 1134 | |||
| 1135 | return count; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, | ||
| 1139 | char *buf) | ||
| 1140 | { | ||
| 1141 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1142 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1143 | return sprintf(buf, "%d\n", data->pwm[attr->index]); | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | ||
| 1147 | const char *buf, size_t count) | ||
| 1148 | { | ||
| 1149 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1150 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1151 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1152 | long temp; | ||
| 1153 | |||
| 1154 | if (strict_strtol(buf, 10, &temp)) | ||
| 1155 | return -EINVAL; | ||
| 1156 | |||
| 1157 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 1158 | |||
| 1159 | mutex_lock(&data->lock); | ||
| 1160 | data->pwm[attr->index] = temp; | ||
| 1161 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM(attr->index), temp); | ||
| 1162 | mutex_unlock(&data->lock); | ||
| 1163 | |||
| 1164 | return count; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | static ssize_t show_pwm_max(struct device *dev, | ||
| 1168 | struct device_attribute *devattr, | ||
| 1169 | char *buf) | ||
| 1170 | { | ||
| 1171 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1172 | return sprintf(buf, "%d\n", data->pwm_max); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | static ssize_t set_pwm_max(struct device *dev, | ||
| 1176 | struct device_attribute *devattr, | ||
| 1177 | const char *buf, | ||
| 1178 | size_t count) | ||
| 1179 | { | ||
| 1180 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1181 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1182 | long temp; | ||
| 1183 | |||
| 1184 | if (strict_strtol(buf, 10, &temp)) | ||
| 1185 | return -EINVAL; | ||
| 1186 | |||
| 1187 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 1188 | |||
| 1189 | mutex_lock(&data->lock); | ||
| 1190 | data->pwm_max = temp; | ||
| 1191 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MAX, temp); | ||
| 1192 | mutex_unlock(&data->lock); | ||
| 1193 | |||
| 1194 | return count; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | static ssize_t show_pwm_min(struct device *dev, | ||
| 1198 | struct device_attribute *devattr, | ||
| 1199 | char *buf) | ||
| 1200 | { | ||
| 1201 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1202 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1203 | return sprintf(buf, "%d\n", data->pwm_min[attr->index]); | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | static ssize_t set_pwm_min(struct device *dev, | ||
| 1207 | struct device_attribute *devattr, | ||
| 1208 | const char *buf, | ||
| 1209 | size_t count) | ||
| 1210 | { | ||
| 1211 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1212 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1213 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1214 | long temp; | ||
| 1215 | |||
| 1216 | if (strict_strtol(buf, 10, &temp)) | ||
| 1217 | return -EINVAL; | ||
| 1218 | |||
| 1219 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 1220 | |||
| 1221 | mutex_lock(&data->lock); | ||
| 1222 | data->pwm_min[attr->index] = temp; | ||
| 1223 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MIN(attr->index), | ||
| 1224 | temp); | ||
| 1225 | mutex_unlock(&data->lock); | ||
| 1226 | |||
| 1227 | return count; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | static ssize_t show_pwm_hyst(struct device *dev, | ||
| 1231 | struct device_attribute *devattr, | ||
| 1232 | char *buf) | ||
| 1233 | { | ||
| 1234 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1235 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1236 | return sprintf(buf, "%d\n", 1000 * | ||
| 1237 | (data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK)); | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | static ssize_t set_pwm_hyst(struct device *dev, | ||
| 1241 | struct device_attribute *devattr, | ||
| 1242 | const char *buf, | ||
| 1243 | size_t count) | ||
| 1244 | { | ||
| 1245 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1246 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1247 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1248 | long temp; | ||
| 1249 | |||
| 1250 | if (strict_strtol(buf, 10, &temp)) | ||
| 1251 | return -EINVAL; | ||
| 1252 | |||
| 1253 | temp = ROUND_DIV(temp, 1000); | ||
| 1254 | temp = SENSORS_LIMIT(temp, 0, 15); | ||
| 1255 | |||
| 1256 | /* package things up */ | ||
| 1257 | temp &= ADT7462_PWM_HYST_MASK; | ||
| 1258 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_RANGE_MASK; | ||
| 1259 | |||
| 1260 | mutex_lock(&data->lock); | ||
| 1261 | data->pwm_trange[attr->index] = temp; | ||
| 1262 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), | ||
| 1263 | temp); | ||
| 1264 | mutex_unlock(&data->lock); | ||
| 1265 | |||
| 1266 | return count; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | static ssize_t show_pwm_tmax(struct device *dev, | ||
| 1270 | struct device_attribute *devattr, | ||
| 1271 | char *buf) | ||
| 1272 | { | ||
| 1273 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1274 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1275 | |||
| 1276 | /* tmax = tmin + trange */ | ||
| 1277 | int trange = trange_values[data->pwm_trange[attr->index] >> | ||
| 1278 | ADT7462_PWM_RANGE_SHIFT]; | ||
| 1279 | int tmin = (data->pwm_tmin[attr->index] - 64) * 1000; | ||
| 1280 | |||
| 1281 | return sprintf(buf, "%d\n", tmin + trange); | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | static ssize_t set_pwm_tmax(struct device *dev, | ||
| 1285 | struct device_attribute *devattr, | ||
| 1286 | const char *buf, | ||
| 1287 | size_t count) | ||
| 1288 | { | ||
| 1289 | int temp; | ||
| 1290 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1291 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1292 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1293 | int tmin, trange_value; | ||
| 1294 | long trange; | ||
| 1295 | |||
| 1296 | if (strict_strtol(buf, 10, &trange)) | ||
| 1297 | return -EINVAL; | ||
| 1298 | |||
| 1299 | /* trange = tmax - tmin */ | ||
| 1300 | tmin = (data->pwm_tmin[attr->index] - 64) * 1000; | ||
| 1301 | trange_value = find_trange_value(trange - tmin); | ||
| 1302 | |||
| 1303 | if (trange_value < 0) | ||
| 1304 | return -EINVAL; | ||
| 1305 | |||
| 1306 | temp = trange_value << ADT7462_PWM_RANGE_SHIFT; | ||
| 1307 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK; | ||
| 1308 | |||
| 1309 | mutex_lock(&data->lock); | ||
| 1310 | data->pwm_trange[attr->index] = temp; | ||
| 1311 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), | ||
| 1312 | temp); | ||
| 1313 | mutex_unlock(&data->lock); | ||
| 1314 | |||
| 1315 | return count; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | static ssize_t show_pwm_tmin(struct device *dev, | ||
| 1319 | struct device_attribute *devattr, | ||
| 1320 | char *buf) | ||
| 1321 | { | ||
| 1322 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1323 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1324 | return sprintf(buf, "%d\n", 1000 * (data->pwm_tmin[attr->index] - 64)); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | static ssize_t set_pwm_tmin(struct device *dev, | ||
| 1328 | struct device_attribute *devattr, | ||
| 1329 | const char *buf, | ||
| 1330 | size_t count) | ||
| 1331 | { | ||
| 1332 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1333 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1334 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1335 | long temp; | ||
| 1336 | |||
| 1337 | if (strict_strtol(buf, 10, &temp)) | ||
| 1338 | return -EINVAL; | ||
| 1339 | |||
| 1340 | temp = ROUND_DIV(temp, 1000) + 64; | ||
| 1341 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 1342 | |||
| 1343 | mutex_lock(&data->lock); | ||
| 1344 | data->pwm_tmin[attr->index] = temp; | ||
| 1345 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TMIN(attr->index), | ||
| 1346 | temp); | ||
| 1347 | mutex_unlock(&data->lock); | ||
| 1348 | |||
| 1349 | return count; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | static ssize_t show_pwm_auto(struct device *dev, | ||
| 1353 | struct device_attribute *devattr, | ||
| 1354 | char *buf) | ||
| 1355 | { | ||
| 1356 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1357 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1358 | int cfg = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; | ||
| 1359 | |||
| 1360 | switch (cfg) { | ||
| 1361 | case 4: /* off */ | ||
| 1362 | return sprintf(buf, "0\n"); | ||
| 1363 | case 7: /* manual */ | ||
| 1364 | return sprintf(buf, "1\n"); | ||
| 1365 | default: /* automatic */ | ||
| 1366 | return sprintf(buf, "2\n"); | ||
| 1367 | } | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | static void set_pwm_channel(struct i2c_client *client, | ||
| 1371 | struct adt7462_data *data, | ||
| 1372 | int which, | ||
| 1373 | int value) | ||
| 1374 | { | ||
| 1375 | int temp = data->pwm_cfg[which] & ~ADT7462_PWM_CHANNEL_MASK; | ||
| 1376 | temp |= value << ADT7462_PWM_CHANNEL_SHIFT; | ||
| 1377 | |||
| 1378 | mutex_lock(&data->lock); | ||
| 1379 | data->pwm_cfg[which] = temp; | ||
| 1380 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_CFG(which), temp); | ||
| 1381 | mutex_unlock(&data->lock); | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | static ssize_t set_pwm_auto(struct device *dev, | ||
| 1385 | struct device_attribute *devattr, | ||
| 1386 | const char *buf, | ||
| 1387 | size_t count) | ||
| 1388 | { | ||
| 1389 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1390 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1391 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1392 | long temp; | ||
| 1393 | |||
| 1394 | if (strict_strtol(buf, 10, &temp)) | ||
| 1395 | return -EINVAL; | ||
| 1396 | |||
| 1397 | switch (temp) { | ||
| 1398 | case 0: /* off */ | ||
| 1399 | set_pwm_channel(client, data, attr->index, 4); | ||
| 1400 | return count; | ||
| 1401 | case 1: /* manual */ | ||
| 1402 | set_pwm_channel(client, data, attr->index, 7); | ||
| 1403 | return count; | ||
| 1404 | default: | ||
| 1405 | return -EINVAL; | ||
| 1406 | } | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | static ssize_t show_pwm_auto_temp(struct device *dev, | ||
| 1410 | struct device_attribute *devattr, | ||
| 1411 | char *buf) | ||
| 1412 | { | ||
| 1413 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1414 | struct adt7462_data *data = adt7462_update_device(dev); | ||
| 1415 | int channel = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; | ||
| 1416 | |||
| 1417 | switch (channel) { | ||
| 1418 | case 0: /* temp[1234] only */ | ||
| 1419 | case 1: | ||
| 1420 | case 2: | ||
| 1421 | case 3: | ||
| 1422 | return sprintf(buf, "%d\n", (1 << channel)); | ||
| 1423 | case 5: /* temp1 & temp4 */ | ||
| 1424 | return sprintf(buf, "9\n"); | ||
| 1425 | case 6: | ||
| 1426 | return sprintf(buf, "15\n"); | ||
| 1427 | default: | ||
| 1428 | return sprintf(buf, "0\n"); | ||
| 1429 | } | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | static int cvt_auto_temp(int input) | ||
| 1433 | { | ||
| 1434 | if (input == 0xF) | ||
| 1435 | return 6; | ||
| 1436 | if (input == 0x9) | ||
| 1437 | return 5; | ||
| 1438 | if (input < 1 || !is_power_of_2(input)) | ||
| 1439 | return -EINVAL; | ||
| 1440 | return ilog2(input); | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | static ssize_t set_pwm_auto_temp(struct device *dev, | ||
| 1444 | struct device_attribute *devattr, | ||
| 1445 | const char *buf, | ||
| 1446 | size_t count) | ||
| 1447 | { | ||
| 1448 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 1449 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1450 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1451 | long temp; | ||
| 1452 | |||
| 1453 | if (strict_strtol(buf, 10, &temp)) | ||
| 1454 | return -EINVAL; | ||
| 1455 | |||
| 1456 | temp = cvt_auto_temp(temp); | ||
| 1457 | if (temp < 0) | ||
| 1458 | return temp; | ||
| 1459 | |||
| 1460 | set_pwm_channel(client, data, attr->index, temp); | ||
| 1461 | |||
| 1462 | return count; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
| 1466 | set_temp_max, 0); | ||
| 1467 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
| 1468 | set_temp_max, 1); | ||
| 1469 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
| 1470 | set_temp_max, 2); | ||
| 1471 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
| 1472 | set_temp_max, 3); | ||
| 1473 | |||
| 1474 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
| 1475 | set_temp_min, 0); | ||
| 1476 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
| 1477 | set_temp_min, 1); | ||
| 1478 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
| 1479 | set_temp_min, 2); | ||
| 1480 | static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
| 1481 | set_temp_min, 3); | ||
| 1482 | |||
| 1483 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
| 1484 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
| 1485 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
| 1486 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | ||
| 1487 | |||
| 1488 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0); | ||
| 1489 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1); | ||
| 1490 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2); | ||
| 1491 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3); | ||
| 1492 | |||
| 1493 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1494 | ADT7462_ALARM1 | ADT7462_LT_ALARM); | ||
| 1495 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1496 | ADT7462_ALARM1 | ADT7462_R1T_ALARM); | ||
| 1497 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1498 | ADT7462_ALARM1 | ADT7462_R2T_ALARM); | ||
| 1499 | static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1500 | ADT7462_ALARM1 | ADT7462_R3T_ALARM); | ||
| 1501 | |||
| 1502 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1503 | set_volt_max, 0); | ||
| 1504 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1505 | set_volt_max, 1); | ||
| 1506 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1507 | set_volt_max, 2); | ||
| 1508 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1509 | set_volt_max, 3); | ||
| 1510 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1511 | set_volt_max, 4); | ||
| 1512 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1513 | set_volt_max, 5); | ||
| 1514 | static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1515 | set_volt_max, 6); | ||
| 1516 | static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1517 | set_volt_max, 7); | ||
| 1518 | static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1519 | set_volt_max, 8); | ||
| 1520 | static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1521 | set_volt_max, 9); | ||
| 1522 | static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1523 | set_volt_max, 10); | ||
| 1524 | static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1525 | set_volt_max, 11); | ||
| 1526 | static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
| 1527 | set_volt_max, 12); | ||
| 1528 | |||
| 1529 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1530 | set_volt_min, 0); | ||
| 1531 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1532 | set_volt_min, 1); | ||
| 1533 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1534 | set_volt_min, 2); | ||
| 1535 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1536 | set_volt_min, 3); | ||
| 1537 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1538 | set_volt_min, 4); | ||
| 1539 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1540 | set_volt_min, 5); | ||
| 1541 | static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1542 | set_volt_min, 6); | ||
| 1543 | static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1544 | set_volt_min, 7); | ||
| 1545 | static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1546 | set_volt_min, 8); | ||
| 1547 | static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1548 | set_volt_min, 9); | ||
| 1549 | static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1550 | set_volt_min, 10); | ||
| 1551 | static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1552 | set_volt_min, 11); | ||
| 1553 | static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
| 1554 | set_volt_min, 12); | ||
| 1555 | |||
| 1556 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); | ||
| 1557 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); | ||
| 1558 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); | ||
| 1559 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); | ||
| 1560 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); | ||
| 1561 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); | ||
| 1562 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); | ||
| 1563 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); | ||
| 1564 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); | ||
| 1565 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); | ||
| 1566 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); | ||
| 1567 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); | ||
| 1568 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); | ||
| 1569 | |||
| 1570 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0); | ||
| 1571 | static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1); | ||
| 1572 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2); | ||
| 1573 | static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3); | ||
| 1574 | static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4); | ||
| 1575 | static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5); | ||
| 1576 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6); | ||
| 1577 | static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7); | ||
| 1578 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8); | ||
| 1579 | static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9); | ||
| 1580 | static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10); | ||
| 1581 | static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11); | ||
| 1582 | static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12); | ||
| 1583 | |||
| 1584 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1585 | ADT7462_ALARM2 | ADT7462_V0_ALARM); | ||
| 1586 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1587 | ADT7462_ALARM2 | ADT7462_V7_ALARM); | ||
| 1588 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1589 | ADT7462_ALARM2 | ADT7462_V2_ALARM); | ||
| 1590 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1591 | ADT7462_ALARM2 | ADT7462_V6_ALARM); | ||
| 1592 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1593 | ADT7462_ALARM2 | ADT7462_V5_ALARM); | ||
| 1594 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1595 | ADT7462_ALARM2 | ADT7462_V4_ALARM); | ||
| 1596 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1597 | ADT7462_ALARM2 | ADT7462_V3_ALARM); | ||
| 1598 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1599 | ADT7462_ALARM2 | ADT7462_V1_ALARM); | ||
| 1600 | static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1601 | ADT7462_ALARM3 | ADT7462_V10_ALARM); | ||
| 1602 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1603 | ADT7462_ALARM3 | ADT7462_V9_ALARM); | ||
| 1604 | static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1605 | ADT7462_ALARM3 | ADT7462_V8_ALARM); | ||
| 1606 | static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1607 | ADT7462_ALARM3 | ADT7462_V11_ALARM); | ||
| 1608 | static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1609 | ADT7462_ALARM3 | ADT7462_V12_ALARM); | ||
| 1610 | |||
| 1611 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1612 | set_fan_min, 0); | ||
| 1613 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1614 | set_fan_min, 1); | ||
| 1615 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1616 | set_fan_min, 2); | ||
| 1617 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1618 | set_fan_min, 3); | ||
| 1619 | static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1620 | set_fan_min, 4); | ||
| 1621 | static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1622 | set_fan_min, 5); | ||
| 1623 | static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1624 | set_fan_min, 6); | ||
| 1625 | static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
| 1626 | set_fan_min, 7); | ||
| 1627 | |||
| 1628 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
| 1629 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
| 1630 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | ||
| 1631 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | ||
| 1632 | static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); | ||
| 1633 | static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); | ||
| 1634 | static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); | ||
| 1635 | static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); | ||
| 1636 | |||
| 1637 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1638 | ADT7462_ALARM4 | ADT7462_F0_ALARM); | ||
| 1639 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1640 | ADT7462_ALARM4 | ADT7462_F1_ALARM); | ||
| 1641 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1642 | ADT7462_ALARM4 | ADT7462_F2_ALARM); | ||
| 1643 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1644 | ADT7462_ALARM4 | ADT7462_F3_ALARM); | ||
| 1645 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1646 | ADT7462_ALARM4 | ADT7462_F4_ALARM); | ||
| 1647 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1648 | ADT7462_ALARM4 | ADT7462_F5_ALARM); | ||
| 1649 | static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1650 | ADT7462_ALARM4 | ADT7462_F6_ALARM); | ||
| 1651 | static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL, | ||
| 1652 | ADT7462_ALARM4 | ADT7462_F7_ALARM); | ||
| 1653 | |||
| 1654 | static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, | ||
| 1655 | show_force_pwm_max, set_force_pwm_max, 0); | ||
| 1656 | |||
| 1657 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); | ||
| 1658 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); | ||
| 1659 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); | ||
| 1660 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); | ||
| 1661 | |||
| 1662 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
| 1663 | show_pwm_min, set_pwm_min, 0); | ||
| 1664 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
| 1665 | show_pwm_min, set_pwm_min, 1); | ||
| 1666 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
| 1667 | show_pwm_min, set_pwm_min, 2); | ||
| 1668 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
| 1669 | show_pwm_min, set_pwm_min, 3); | ||
| 1670 | |||
| 1671 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
| 1672 | show_pwm_max, set_pwm_max, 0); | ||
| 1673 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
| 1674 | show_pwm_max, set_pwm_max, 1); | ||
| 1675 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
| 1676 | show_pwm_max, set_pwm_max, 2); | ||
| 1677 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
| 1678 | show_pwm_max, set_pwm_max, 3); | ||
| 1679 | |||
| 1680 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
| 1681 | show_pwm_hyst, set_pwm_hyst, 0); | ||
| 1682 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
| 1683 | show_pwm_hyst, set_pwm_hyst, 1); | ||
| 1684 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
| 1685 | show_pwm_hyst, set_pwm_hyst, 2); | ||
| 1686 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
| 1687 | show_pwm_hyst, set_pwm_hyst, 3); | ||
| 1688 | |||
| 1689 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
| 1690 | show_pwm_hyst, set_pwm_hyst, 0); | ||
| 1691 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
| 1692 | show_pwm_hyst, set_pwm_hyst, 1); | ||
| 1693 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
| 1694 | show_pwm_hyst, set_pwm_hyst, 2); | ||
| 1695 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
| 1696 | show_pwm_hyst, set_pwm_hyst, 3); | ||
| 1697 | |||
| 1698 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
| 1699 | show_pwm_tmin, set_pwm_tmin, 0); | ||
| 1700 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
| 1701 | show_pwm_tmin, set_pwm_tmin, 1); | ||
| 1702 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
| 1703 | show_pwm_tmin, set_pwm_tmin, 2); | ||
| 1704 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
| 1705 | show_pwm_tmin, set_pwm_tmin, 3); | ||
| 1706 | |||
| 1707 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
| 1708 | show_pwm_tmax, set_pwm_tmax, 0); | ||
| 1709 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
| 1710 | show_pwm_tmax, set_pwm_tmax, 1); | ||
| 1711 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
| 1712 | show_pwm_tmax, set_pwm_tmax, 2); | ||
| 1713 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
| 1714 | show_pwm_tmax, set_pwm_tmax, 3); | ||
| 1715 | |||
| 1716 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
| 1717 | set_pwm_auto, 0); | ||
| 1718 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
| 1719 | set_pwm_auto, 1); | ||
| 1720 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
| 1721 | set_pwm_auto, 2); | ||
| 1722 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
| 1723 | set_pwm_auto, 3); | ||
| 1724 | |||
| 1725 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
| 1726 | show_pwm_auto_temp, set_pwm_auto_temp, 0); | ||
| 1727 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
| 1728 | show_pwm_auto_temp, set_pwm_auto_temp, 1); | ||
| 1729 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
| 1730 | show_pwm_auto_temp, set_pwm_auto_temp, 2); | ||
| 1731 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
| 1732 | show_pwm_auto_temp, set_pwm_auto_temp, 3); | ||
| 1733 | |||
| 1734 | static struct attribute *adt7462_attr[] = | ||
| 1735 | { | ||
| 1736 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
| 1737 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
| 1738 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
| 1739 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
| 1740 | |||
| 1741 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
| 1742 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
| 1743 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
| 1744 | &sensor_dev_attr_temp4_min.dev_attr.attr, | ||
| 1745 | |||
| 1746 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
| 1747 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
| 1748 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
| 1749 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
| 1750 | |||
| 1751 | &sensor_dev_attr_temp1_label.dev_attr.attr, | ||
| 1752 | &sensor_dev_attr_temp2_label.dev_attr.attr, | ||
| 1753 | &sensor_dev_attr_temp3_label.dev_attr.attr, | ||
| 1754 | &sensor_dev_attr_temp4_label.dev_attr.attr, | ||
| 1755 | |||
| 1756 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
| 1757 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
| 1758 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
| 1759 | &sensor_dev_attr_temp4_alarm.dev_attr.attr, | ||
| 1760 | |||
| 1761 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
| 1762 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
| 1763 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
| 1764 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
| 1765 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
| 1766 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
| 1767 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
| 1768 | &sensor_dev_attr_in8_max.dev_attr.attr, | ||
| 1769 | &sensor_dev_attr_in9_max.dev_attr.attr, | ||
| 1770 | &sensor_dev_attr_in10_max.dev_attr.attr, | ||
| 1771 | &sensor_dev_attr_in11_max.dev_attr.attr, | ||
| 1772 | &sensor_dev_attr_in12_max.dev_attr.attr, | ||
| 1773 | &sensor_dev_attr_in13_max.dev_attr.attr, | ||
| 1774 | |||
| 1775 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
| 1776 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
| 1777 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
| 1778 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
| 1779 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
| 1780 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
| 1781 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
| 1782 | &sensor_dev_attr_in8_min.dev_attr.attr, | ||
| 1783 | &sensor_dev_attr_in9_min.dev_attr.attr, | ||
| 1784 | &sensor_dev_attr_in10_min.dev_attr.attr, | ||
| 1785 | &sensor_dev_attr_in11_min.dev_attr.attr, | ||
| 1786 | &sensor_dev_attr_in12_min.dev_attr.attr, | ||
| 1787 | &sensor_dev_attr_in13_min.dev_attr.attr, | ||
| 1788 | |||
| 1789 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
| 1790 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
| 1791 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
| 1792 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
| 1793 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
| 1794 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
| 1795 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
| 1796 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
| 1797 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
| 1798 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
| 1799 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
| 1800 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
| 1801 | &sensor_dev_attr_in13_input.dev_attr.attr, | ||
| 1802 | |||
| 1803 | &sensor_dev_attr_in1_label.dev_attr.attr, | ||
| 1804 | &sensor_dev_attr_in2_label.dev_attr.attr, | ||
| 1805 | &sensor_dev_attr_in3_label.dev_attr.attr, | ||
| 1806 | &sensor_dev_attr_in4_label.dev_attr.attr, | ||
| 1807 | &sensor_dev_attr_in5_label.dev_attr.attr, | ||
| 1808 | &sensor_dev_attr_in6_label.dev_attr.attr, | ||
| 1809 | &sensor_dev_attr_in7_label.dev_attr.attr, | ||
| 1810 | &sensor_dev_attr_in8_label.dev_attr.attr, | ||
| 1811 | &sensor_dev_attr_in9_label.dev_attr.attr, | ||
| 1812 | &sensor_dev_attr_in10_label.dev_attr.attr, | ||
| 1813 | &sensor_dev_attr_in11_label.dev_attr.attr, | ||
| 1814 | &sensor_dev_attr_in12_label.dev_attr.attr, | ||
| 1815 | &sensor_dev_attr_in13_label.dev_attr.attr, | ||
| 1816 | |||
| 1817 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
| 1818 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
| 1819 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
| 1820 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
| 1821 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
| 1822 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
| 1823 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
| 1824 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | ||
| 1825 | &sensor_dev_attr_in9_alarm.dev_attr.attr, | ||
| 1826 | &sensor_dev_attr_in10_alarm.dev_attr.attr, | ||
| 1827 | &sensor_dev_attr_in11_alarm.dev_attr.attr, | ||
| 1828 | &sensor_dev_attr_in12_alarm.dev_attr.attr, | ||
| 1829 | &sensor_dev_attr_in13_alarm.dev_attr.attr, | ||
| 1830 | |||
| 1831 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
| 1832 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
| 1833 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
| 1834 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
| 1835 | &sensor_dev_attr_fan5_min.dev_attr.attr, | ||
| 1836 | &sensor_dev_attr_fan6_min.dev_attr.attr, | ||
| 1837 | &sensor_dev_attr_fan7_min.dev_attr.attr, | ||
| 1838 | &sensor_dev_attr_fan8_min.dev_attr.attr, | ||
| 1839 | |||
| 1840 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
| 1841 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
| 1842 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
| 1843 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
| 1844 | &sensor_dev_attr_fan5_input.dev_attr.attr, | ||
| 1845 | &sensor_dev_attr_fan6_input.dev_attr.attr, | ||
| 1846 | &sensor_dev_attr_fan7_input.dev_attr.attr, | ||
| 1847 | &sensor_dev_attr_fan8_input.dev_attr.attr, | ||
| 1848 | |||
| 1849 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
| 1850 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
| 1851 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
| 1852 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | ||
| 1853 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | ||
| 1854 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | ||
| 1855 | &sensor_dev_attr_fan7_alarm.dev_attr.attr, | ||
| 1856 | &sensor_dev_attr_fan8_alarm.dev_attr.attr, | ||
| 1857 | |||
| 1858 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, | ||
| 1859 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
| 1860 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
| 1861 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
| 1862 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
| 1863 | |||
| 1864 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
| 1865 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | ||
| 1866 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | ||
| 1867 | &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, | ||
| 1868 | |||
| 1869 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
| 1870 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | ||
| 1871 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | ||
| 1872 | &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, | ||
| 1873 | |||
| 1874 | &sensor_dev_attr_temp1_auto_point1_hyst.dev_attr.attr, | ||
| 1875 | &sensor_dev_attr_temp2_auto_point1_hyst.dev_attr.attr, | ||
| 1876 | &sensor_dev_attr_temp3_auto_point1_hyst.dev_attr.attr, | ||
| 1877 | &sensor_dev_attr_temp4_auto_point1_hyst.dev_attr.attr, | ||
| 1878 | |||
| 1879 | &sensor_dev_attr_temp1_auto_point2_hyst.dev_attr.attr, | ||
| 1880 | &sensor_dev_attr_temp2_auto_point2_hyst.dev_attr.attr, | ||
| 1881 | &sensor_dev_attr_temp3_auto_point2_hyst.dev_attr.attr, | ||
| 1882 | &sensor_dev_attr_temp4_auto_point2_hyst.dev_attr.attr, | ||
| 1883 | |||
| 1884 | &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, | ||
| 1885 | &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, | ||
| 1886 | &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, | ||
| 1887 | &sensor_dev_attr_temp4_auto_point1_temp.dev_attr.attr, | ||
| 1888 | |||
| 1889 | &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, | ||
| 1890 | &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, | ||
| 1891 | &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, | ||
| 1892 | &sensor_dev_attr_temp4_auto_point2_temp.dev_attr.attr, | ||
| 1893 | |||
| 1894 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
| 1895 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
| 1896 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
| 1897 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
| 1898 | |||
| 1899 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | ||
| 1900 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | ||
| 1901 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | ||
| 1902 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, | ||
| 1903 | NULL | ||
| 1904 | }; | ||
| 1905 | |||
| 1906 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
| 1907 | static int adt7462_detect(struct i2c_client *client, int kind, | ||
| 1908 | struct i2c_board_info *info) | ||
| 1909 | { | ||
| 1910 | struct i2c_adapter *adapter = client->adapter; | ||
| 1911 | |||
| 1912 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 1913 | return -ENODEV; | ||
| 1914 | |||
| 1915 | if (kind <= 0) { | ||
| 1916 | int vendor, device, revision; | ||
| 1917 | |||
| 1918 | vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR); | ||
| 1919 | if (vendor != ADT7462_VENDOR) | ||
| 1920 | return -ENODEV; | ||
| 1921 | |||
| 1922 | device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE); | ||
| 1923 | if (device != ADT7462_DEVICE) | ||
| 1924 | return -ENODEV; | ||
| 1925 | |||
| 1926 | revision = i2c_smbus_read_byte_data(client, | ||
| 1927 | ADT7462_REG_REVISION); | ||
| 1928 | if (revision != ADT7462_REVISION) | ||
| 1929 | return -ENODEV; | ||
| 1930 | } else | ||
| 1931 | dev_dbg(&adapter->dev, "detection forced\n"); | ||
| 1932 | |||
| 1933 | strlcpy(info->type, "adt7462", I2C_NAME_SIZE); | ||
| 1934 | |||
| 1935 | return 0; | ||
| 1936 | } | ||
| 1937 | |||
| 1938 | static int adt7462_probe(struct i2c_client *client, | ||
| 1939 | const struct i2c_device_id *id) | ||
| 1940 | { | ||
| 1941 | struct adt7462_data *data; | ||
| 1942 | int err; | ||
| 1943 | |||
| 1944 | data = kzalloc(sizeof(struct adt7462_data), GFP_KERNEL); | ||
| 1945 | if (!data) { | ||
| 1946 | err = -ENOMEM; | ||
| 1947 | goto exit; | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | i2c_set_clientdata(client, data); | ||
| 1951 | mutex_init(&data->lock); | ||
| 1952 | |||
| 1953 | dev_info(&client->dev, "%s chip found\n", client->name); | ||
| 1954 | |||
| 1955 | /* Register sysfs hooks */ | ||
| 1956 | data->attrs.attrs = adt7462_attr; | ||
| 1957 | err = sysfs_create_group(&client->dev.kobj, &data->attrs); | ||
| 1958 | if (err) | ||
| 1959 | goto exit_free; | ||
| 1960 | |||
| 1961 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
| 1962 | if (IS_ERR(data->hwmon_dev)) { | ||
| 1963 | err = PTR_ERR(data->hwmon_dev); | ||
| 1964 | goto exit_remove; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | return 0; | ||
| 1968 | |||
| 1969 | exit_remove: | ||
| 1970 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
| 1971 | exit_free: | ||
| 1972 | kfree(data); | ||
| 1973 | exit: | ||
| 1974 | return err; | ||
| 1975 | } | ||
| 1976 | |||
| 1977 | static int adt7462_remove(struct i2c_client *client) | ||
| 1978 | { | ||
| 1979 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
| 1980 | |||
| 1981 | hwmon_device_unregister(data->hwmon_dev); | ||
| 1982 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
| 1983 | kfree(data); | ||
| 1984 | return 0; | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | static int __init adt7462_init(void) | ||
| 1988 | { | ||
| 1989 | return i2c_add_driver(&adt7462_driver); | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | static void __exit adt7462_exit(void) | ||
| 1993 | { | ||
| 1994 | i2c_del_driver(&adt7462_driver); | ||
| 1995 | } | ||
| 1996 | |||
| 1997 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
| 1998 | MODULE_DESCRIPTION("ADT7462 driver"); | ||
| 1999 | MODULE_LICENSE("GPL"); | ||
| 2000 | |||
| 2001 | module_init(adt7462_init); | ||
| 2002 | module_exit(adt7462_exit); | ||
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index d368d8f845e1..1311a595147e 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
| @@ -137,6 +137,8 @@ I2C_CLIENT_INSMOD_1(adt7470); | |||
| 137 | #define FAN_PERIOD_INVALID 65535 | 137 | #define FAN_PERIOD_INVALID 65535 |
| 138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
| 139 | 139 | ||
| 140 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
| 141 | |||
| 140 | struct adt7470_data { | 142 | struct adt7470_data { |
| 141 | struct device *hwmon_dev; | 143 | struct device *hwmon_dev; |
| 142 | struct attribute_group attrs; | 144 | struct attribute_group attrs; |
| @@ -353,7 +355,13 @@ static ssize_t set_temp_min(struct device *dev, | |||
| 353 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 355 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 354 | struct i2c_client *client = to_i2c_client(dev); | 356 | struct i2c_client *client = to_i2c_client(dev); |
| 355 | struct adt7470_data *data = i2c_get_clientdata(client); | 357 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 356 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 358 | long temp; |
| 359 | |||
| 360 | if (strict_strtol(buf, 10, &temp)) | ||
| 361 | return -EINVAL; | ||
| 362 | |||
| 363 | temp = ROUND_DIV(temp, 1000); | ||
| 364 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 357 | 365 | ||
| 358 | mutex_lock(&data->lock); | 366 | mutex_lock(&data->lock); |
| 359 | data->temp_min[attr->index] = temp; | 367 | data->temp_min[attr->index] = temp; |
| @@ -381,7 +389,13 @@ static ssize_t set_temp_max(struct device *dev, | |||
| 381 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 389 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 382 | struct i2c_client *client = to_i2c_client(dev); | 390 | struct i2c_client *client = to_i2c_client(dev); |
| 383 | struct adt7470_data *data = i2c_get_clientdata(client); | 391 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 384 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 392 | long temp; |
| 393 | |||
| 394 | if (strict_strtol(buf, 10, &temp)) | ||
| 395 | return -EINVAL; | ||
| 396 | |||
| 397 | temp = ROUND_DIV(temp, 1000); | ||
| 398 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 385 | 399 | ||
| 386 | mutex_lock(&data->lock); | 400 | mutex_lock(&data->lock); |
| 387 | data->temp_max[attr->index] = temp; | 401 | data->temp_max[attr->index] = temp; |
| @@ -430,11 +444,13 @@ static ssize_t set_fan_max(struct device *dev, | |||
| 430 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 444 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 431 | struct i2c_client *client = to_i2c_client(dev); | 445 | struct i2c_client *client = to_i2c_client(dev); |
| 432 | struct adt7470_data *data = i2c_get_clientdata(client); | 446 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 433 | int temp = simple_strtol(buf, NULL, 10); | 447 | long temp; |
| 434 | 448 | ||
| 435 | if (!temp) | 449 | if (strict_strtol(buf, 10, &temp) || !temp) |
| 436 | return -EINVAL; | 450 | return -EINVAL; |
| 451 | |||
| 437 | temp = FAN_RPM_TO_PERIOD(temp); | 452 | temp = FAN_RPM_TO_PERIOD(temp); |
| 453 | temp = SENSORS_LIMIT(temp, 1, 65534); | ||
| 438 | 454 | ||
| 439 | mutex_lock(&data->lock); | 455 | mutex_lock(&data->lock); |
| 440 | data->fan_max[attr->index] = temp; | 456 | data->fan_max[attr->index] = temp; |
| @@ -465,11 +481,13 @@ static ssize_t set_fan_min(struct device *dev, | |||
| 465 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 481 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 466 | struct i2c_client *client = to_i2c_client(dev); | 482 | struct i2c_client *client = to_i2c_client(dev); |
| 467 | struct adt7470_data *data = i2c_get_clientdata(client); | 483 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 468 | int temp = simple_strtol(buf, NULL, 10); | 484 | long temp; |
| 469 | 485 | ||
| 470 | if (!temp) | 486 | if (strict_strtol(buf, 10, &temp) || !temp) |
| 471 | return -EINVAL; | 487 | return -EINVAL; |
| 488 | |||
| 472 | temp = FAN_RPM_TO_PERIOD(temp); | 489 | temp = FAN_RPM_TO_PERIOD(temp); |
| 490 | temp = SENSORS_LIMIT(temp, 1, 65534); | ||
| 473 | 491 | ||
| 474 | mutex_lock(&data->lock); | 492 | mutex_lock(&data->lock); |
| 475 | data->fan_min[attr->index] = temp; | 493 | data->fan_min[attr->index] = temp; |
| @@ -507,9 +525,12 @@ static ssize_t set_force_pwm_max(struct device *dev, | |||
| 507 | { | 525 | { |
| 508 | struct i2c_client *client = to_i2c_client(dev); | 526 | struct i2c_client *client = to_i2c_client(dev); |
| 509 | struct adt7470_data *data = i2c_get_clientdata(client); | 527 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 510 | int temp = simple_strtol(buf, NULL, 10); | 528 | long temp; |
| 511 | u8 reg; | 529 | u8 reg; |
| 512 | 530 | ||
| 531 | if (strict_strtol(buf, 10, &temp)) | ||
| 532 | return -EINVAL; | ||
| 533 | |||
| 513 | mutex_lock(&data->lock); | 534 | mutex_lock(&data->lock); |
| 514 | data->force_pwm_max = temp; | 535 | data->force_pwm_max = temp; |
| 515 | reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | 536 | reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); |
| @@ -537,7 +558,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
| 537 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 558 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 538 | struct i2c_client *client = to_i2c_client(dev); | 559 | struct i2c_client *client = to_i2c_client(dev); |
| 539 | struct adt7470_data *data = i2c_get_clientdata(client); | 560 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 540 | int temp = simple_strtol(buf, NULL, 10); | 561 | long temp; |
| 562 | |||
| 563 | if (strict_strtol(buf, 10, &temp)) | ||
| 564 | return -EINVAL; | ||
| 565 | |||
| 566 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 541 | 567 | ||
| 542 | mutex_lock(&data->lock); | 568 | mutex_lock(&data->lock); |
| 543 | data->pwm[attr->index] = temp; | 569 | data->pwm[attr->index] = temp; |
| @@ -564,7 +590,12 @@ static ssize_t set_pwm_max(struct device *dev, | |||
| 564 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 590 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 565 | struct i2c_client *client = to_i2c_client(dev); | 591 | struct i2c_client *client = to_i2c_client(dev); |
| 566 | struct adt7470_data *data = i2c_get_clientdata(client); | 592 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 567 | int temp = simple_strtol(buf, NULL, 10); | 593 | long temp; |
| 594 | |||
| 595 | if (strict_strtol(buf, 10, &temp)) | ||
| 596 | return -EINVAL; | ||
| 597 | |||
| 598 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 568 | 599 | ||
| 569 | mutex_lock(&data->lock); | 600 | mutex_lock(&data->lock); |
| 570 | data->pwm_max[attr->index] = temp; | 601 | data->pwm_max[attr->index] = temp; |
| @@ -592,7 +623,12 @@ static ssize_t set_pwm_min(struct device *dev, | |||
| 592 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 623 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 593 | struct i2c_client *client = to_i2c_client(dev); | 624 | struct i2c_client *client = to_i2c_client(dev); |
| 594 | struct adt7470_data *data = i2c_get_clientdata(client); | 625 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 595 | int temp = simple_strtol(buf, NULL, 10); | 626 | long temp; |
| 627 | |||
| 628 | if (strict_strtol(buf, 10, &temp)) | ||
| 629 | return -EINVAL; | ||
| 630 | |||
| 631 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 596 | 632 | ||
| 597 | mutex_lock(&data->lock); | 633 | mutex_lock(&data->lock); |
| 598 | data->pwm_min[attr->index] = temp; | 634 | data->pwm_min[attr->index] = temp; |
| @@ -630,7 +666,13 @@ static ssize_t set_pwm_tmin(struct device *dev, | |||
| 630 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 666 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 631 | struct i2c_client *client = to_i2c_client(dev); | 667 | struct i2c_client *client = to_i2c_client(dev); |
| 632 | struct adt7470_data *data = i2c_get_clientdata(client); | 668 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 633 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 669 | long temp; |
| 670 | |||
| 671 | if (strict_strtol(buf, 10, &temp)) | ||
| 672 | return -EINVAL; | ||
| 673 | |||
| 674 | temp = ROUND_DIV(temp, 1000); | ||
| 675 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 634 | 676 | ||
| 635 | mutex_lock(&data->lock); | 677 | mutex_lock(&data->lock); |
| 636 | data->pwm_tmin[attr->index] = temp; | 678 | data->pwm_tmin[attr->index] = temp; |
| @@ -658,11 +700,14 @@ static ssize_t set_pwm_auto(struct device *dev, | |||
| 658 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 700 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 659 | struct i2c_client *client = to_i2c_client(dev); | 701 | struct i2c_client *client = to_i2c_client(dev); |
| 660 | struct adt7470_data *data = i2c_get_clientdata(client); | 702 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 661 | int temp = simple_strtol(buf, NULL, 10); | ||
| 662 | int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index); | 703 | int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index); |
| 663 | int pwm_auto_reg_mask; | 704 | int pwm_auto_reg_mask; |
| 705 | long temp; | ||
| 664 | u8 reg; | 706 | u8 reg; |
| 665 | 707 | ||
| 708 | if (strict_strtol(buf, 10, &temp)) | ||
| 709 | return -EINVAL; | ||
| 710 | |||
| 666 | if (attr->index % 2) | 711 | if (attr->index % 2) |
| 667 | pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK; | 712 | pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK; |
| 668 | else | 713 | else |
| @@ -716,10 +761,14 @@ static ssize_t set_pwm_auto_temp(struct device *dev, | |||
| 716 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 761 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 717 | struct i2c_client *client = to_i2c_client(dev); | 762 | struct i2c_client *client = to_i2c_client(dev); |
| 718 | struct adt7470_data *data = i2c_get_clientdata(client); | 763 | struct adt7470_data *data = i2c_get_clientdata(client); |
| 719 | int temp = cvt_auto_temp(simple_strtol(buf, NULL, 10)); | ||
| 720 | int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index); | 764 | int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index); |
| 765 | long temp; | ||
| 721 | u8 reg; | 766 | u8 reg; |
| 722 | 767 | ||
| 768 | if (strict_strtol(buf, 10, &temp)) | ||
| 769 | return -EINVAL; | ||
| 770 | |||
| 771 | temp = cvt_auto_temp(temp); | ||
| 723 | if (temp < 0) | 772 | if (temp < 0) |
| 724 | return temp; | 773 | return temp; |
| 725 | 774 | ||
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index b9a8ea30c99c..18aa30866a6c 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c | |||
| @@ -129,6 +129,8 @@ I2C_CLIENT_INSMOD_1(adt7473); | |||
| 129 | #define FAN_PERIOD_INVALID 65535 | 129 | #define FAN_PERIOD_INVALID 65535 |
| 130 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 130 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
| 131 | 131 | ||
| 132 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
| 133 | |||
| 132 | struct adt7473_data { | 134 | struct adt7473_data { |
| 133 | struct device *hwmon_dev; | 135 | struct device *hwmon_dev; |
| 134 | struct attribute_group attrs; | 136 | struct attribute_group attrs; |
| @@ -357,7 +359,12 @@ static ssize_t set_volt_min(struct device *dev, | |||
| 357 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 359 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 358 | struct i2c_client *client = to_i2c_client(dev); | 360 | struct i2c_client *client = to_i2c_client(dev); |
| 359 | struct adt7473_data *data = i2c_get_clientdata(client); | 361 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 360 | int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); | 362 | long volt; |
| 363 | |||
| 364 | if (strict_strtol(buf, 10, &volt)) | ||
| 365 | return -EINVAL; | ||
| 366 | |||
| 367 | volt = encode_volt(attr->index, volt); | ||
| 361 | 368 | ||
| 362 | mutex_lock(&data->lock); | 369 | mutex_lock(&data->lock); |
| 363 | data->volt_min[attr->index] = volt; | 370 | data->volt_min[attr->index] = volt; |
| @@ -386,7 +393,12 @@ static ssize_t set_volt_max(struct device *dev, | |||
| 386 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 393 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 387 | struct i2c_client *client = to_i2c_client(dev); | 394 | struct i2c_client *client = to_i2c_client(dev); |
| 388 | struct adt7473_data *data = i2c_get_clientdata(client); | 395 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 389 | int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); | 396 | long volt; |
| 397 | |||
| 398 | if (strict_strtol(buf, 10, &volt)) | ||
| 399 | return -EINVAL; | ||
| 400 | |||
| 401 | volt = encode_volt(attr->index, volt); | ||
| 390 | 402 | ||
| 391 | mutex_lock(&data->lock); | 403 | mutex_lock(&data->lock); |
| 392 | data->volt_max[attr->index] = volt; | 404 | data->volt_max[attr->index] = volt; |
| @@ -419,7 +431,8 @@ static int decode_temp(u8 twos_complement, u8 raw) | |||
| 419 | 431 | ||
| 420 | static u8 encode_temp(u8 twos_complement, int cooked) | 432 | static u8 encode_temp(u8 twos_complement, int cooked) |
| 421 | { | 433 | { |
| 422 | return twos_complement ? cooked & 0xFF : cooked + 64; | 434 | u8 ret = twos_complement ? cooked & 0xFF : cooked + 64; |
| 435 | return SENSORS_LIMIT(ret, 0, 255); | ||
| 423 | } | 436 | } |
| 424 | 437 | ||
| 425 | static ssize_t show_temp_min(struct device *dev, | 438 | static ssize_t show_temp_min(struct device *dev, |
| @@ -441,7 +454,12 @@ static ssize_t set_temp_min(struct device *dev, | |||
| 441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 454 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 442 | struct i2c_client *client = to_i2c_client(dev); | 455 | struct i2c_client *client = to_i2c_client(dev); |
| 443 | struct adt7473_data *data = i2c_get_clientdata(client); | 456 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 444 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 457 | long temp; |
| 458 | |||
| 459 | if (strict_strtol(buf, 10, &temp)) | ||
| 460 | return -EINVAL; | ||
| 461 | |||
| 462 | temp = ROUND_DIV(temp, 1000); | ||
| 445 | temp = encode_temp(data->temp_twos_complement, temp); | 463 | temp = encode_temp(data->temp_twos_complement, temp); |
| 446 | 464 | ||
| 447 | mutex_lock(&data->lock); | 465 | mutex_lock(&data->lock); |
| @@ -472,7 +490,12 @@ static ssize_t set_temp_max(struct device *dev, | |||
| 472 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 490 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 473 | struct i2c_client *client = to_i2c_client(dev); | 491 | struct i2c_client *client = to_i2c_client(dev); |
| 474 | struct adt7473_data *data = i2c_get_clientdata(client); | 492 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 475 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 493 | long temp; |
| 494 | |||
| 495 | if (strict_strtol(buf, 10, &temp)) | ||
| 496 | return -EINVAL; | ||
| 497 | |||
| 498 | temp = ROUND_DIV(temp, 1000); | ||
| 476 | temp = encode_temp(data->temp_twos_complement, temp); | 499 | temp = encode_temp(data->temp_twos_complement, temp); |
| 477 | 500 | ||
| 478 | mutex_lock(&data->lock); | 501 | mutex_lock(&data->lock); |
| @@ -515,11 +538,13 @@ static ssize_t set_fan_min(struct device *dev, | |||
| 515 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 538 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 516 | struct i2c_client *client = to_i2c_client(dev); | 539 | struct i2c_client *client = to_i2c_client(dev); |
| 517 | struct adt7473_data *data = i2c_get_clientdata(client); | 540 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 518 | int temp = simple_strtol(buf, NULL, 10); | 541 | long temp; |
| 519 | 542 | ||
| 520 | if (!temp) | 543 | if (strict_strtol(buf, 10, &temp) || !temp) |
| 521 | return -EINVAL; | 544 | return -EINVAL; |
| 545 | |||
| 522 | temp = FAN_RPM_TO_PERIOD(temp); | 546 | temp = FAN_RPM_TO_PERIOD(temp); |
| 547 | temp = SENSORS_LIMIT(temp, 1, 65534); | ||
| 523 | 548 | ||
| 524 | mutex_lock(&data->lock); | 549 | mutex_lock(&data->lock); |
| 525 | data->fan_min[attr->index] = temp; | 550 | data->fan_min[attr->index] = temp; |
| @@ -558,7 +583,10 @@ static ssize_t set_max_duty_at_crit(struct device *dev, | |||
| 558 | u8 reg; | 583 | u8 reg; |
| 559 | struct i2c_client *client = to_i2c_client(dev); | 584 | struct i2c_client *client = to_i2c_client(dev); |
| 560 | struct adt7473_data *data = i2c_get_clientdata(client); | 585 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 561 | int temp = simple_strtol(buf, NULL, 10); | 586 | long temp; |
| 587 | |||
| 588 | if (strict_strtol(buf, 10, &temp)) | ||
| 589 | return -EINVAL; | ||
| 562 | 590 | ||
| 563 | mutex_lock(&data->lock); | 591 | mutex_lock(&data->lock); |
| 564 | data->max_duty_at_overheat = !!temp; | 592 | data->max_duty_at_overheat = !!temp; |
| @@ -587,7 +615,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
| 587 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 615 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 588 | struct i2c_client *client = to_i2c_client(dev); | 616 | struct i2c_client *client = to_i2c_client(dev); |
| 589 | struct adt7473_data *data = i2c_get_clientdata(client); | 617 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 590 | int temp = simple_strtol(buf, NULL, 10); | 618 | long temp; |
| 619 | |||
| 620 | if (strict_strtol(buf, 10, &temp)) | ||
| 621 | return -EINVAL; | ||
| 622 | |||
| 623 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 591 | 624 | ||
| 592 | mutex_lock(&data->lock); | 625 | mutex_lock(&data->lock); |
| 593 | data->pwm[attr->index] = temp; | 626 | data->pwm[attr->index] = temp; |
| @@ -614,7 +647,12 @@ static ssize_t set_pwm_max(struct device *dev, | |||
| 614 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 647 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 615 | struct i2c_client *client = to_i2c_client(dev); | 648 | struct i2c_client *client = to_i2c_client(dev); |
| 616 | struct adt7473_data *data = i2c_get_clientdata(client); | 649 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 617 | int temp = simple_strtol(buf, NULL, 10); | 650 | long temp; |
| 651 | |||
| 652 | if (strict_strtol(buf, 10, &temp)) | ||
| 653 | return -EINVAL; | ||
| 654 | |||
| 655 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 618 | 656 | ||
| 619 | mutex_lock(&data->lock); | 657 | mutex_lock(&data->lock); |
| 620 | data->pwm_max[attr->index] = temp; | 658 | data->pwm_max[attr->index] = temp; |
| @@ -642,7 +680,12 @@ static ssize_t set_pwm_min(struct device *dev, | |||
| 642 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 680 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 643 | struct i2c_client *client = to_i2c_client(dev); | 681 | struct i2c_client *client = to_i2c_client(dev); |
| 644 | struct adt7473_data *data = i2c_get_clientdata(client); | 682 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 645 | int temp = simple_strtol(buf, NULL, 10); | 683 | long temp; |
| 684 | |||
| 685 | if (strict_strtol(buf, 10, &temp)) | ||
| 686 | return -EINVAL; | ||
| 687 | |||
| 688 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
| 646 | 689 | ||
| 647 | mutex_lock(&data->lock); | 690 | mutex_lock(&data->lock); |
| 648 | data->pwm_min[attr->index] = temp; | 691 | data->pwm_min[attr->index] = temp; |
| @@ -672,7 +715,12 @@ static ssize_t set_temp_tmax(struct device *dev, | |||
| 672 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 715 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 673 | struct i2c_client *client = to_i2c_client(dev); | 716 | struct i2c_client *client = to_i2c_client(dev); |
| 674 | struct adt7473_data *data = i2c_get_clientdata(client); | 717 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 675 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 718 | long temp; |
| 719 | |||
| 720 | if (strict_strtol(buf, 10, &temp)) | ||
| 721 | return -EINVAL; | ||
| 722 | |||
| 723 | temp = ROUND_DIV(temp, 1000); | ||
| 676 | temp = encode_temp(data->temp_twos_complement, temp); | 724 | temp = encode_temp(data->temp_twos_complement, temp); |
| 677 | 725 | ||
| 678 | mutex_lock(&data->lock); | 726 | mutex_lock(&data->lock); |
| @@ -703,7 +751,12 @@ static ssize_t set_temp_tmin(struct device *dev, | |||
| 703 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 751 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 704 | struct i2c_client *client = to_i2c_client(dev); | 752 | struct i2c_client *client = to_i2c_client(dev); |
| 705 | struct adt7473_data *data = i2c_get_clientdata(client); | 753 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 706 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 754 | long temp; |
| 755 | |||
| 756 | if (strict_strtol(buf, 10, &temp)) | ||
| 757 | return -EINVAL; | ||
| 758 | |||
| 759 | temp = ROUND_DIV(temp, 1000); | ||
| 707 | temp = encode_temp(data->temp_twos_complement, temp); | 760 | temp = encode_temp(data->temp_twos_complement, temp); |
| 708 | 761 | ||
| 709 | mutex_lock(&data->lock); | 762 | mutex_lock(&data->lock); |
| @@ -741,7 +794,10 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
| 741 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 794 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 742 | struct i2c_client *client = to_i2c_client(dev); | 795 | struct i2c_client *client = to_i2c_client(dev); |
| 743 | struct adt7473_data *data = i2c_get_clientdata(client); | 796 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 744 | int temp = simple_strtol(buf, NULL, 10); | 797 | long temp; |
| 798 | |||
| 799 | if (strict_strtol(buf, 10, &temp)) | ||
| 800 | return -EINVAL; | ||
| 745 | 801 | ||
| 746 | switch (temp) { | 802 | switch (temp) { |
| 747 | case 0: | 803 | case 0: |
| @@ -805,7 +861,10 @@ static ssize_t set_pwm_auto_temp(struct device *dev, | |||
| 805 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 861 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 806 | struct i2c_client *client = to_i2c_client(dev); | 862 | struct i2c_client *client = to_i2c_client(dev); |
| 807 | struct adt7473_data *data = i2c_get_clientdata(client); | 863 | struct adt7473_data *data = i2c_get_clientdata(client); |
| 808 | int temp = simple_strtol(buf, NULL, 10); | 864 | long temp; |
| 865 | |||
| 866 | if (strict_strtol(buf, 10, &temp)) | ||
| 867 | return -EINVAL; | ||
| 809 | 868 | ||
| 810 | switch (temp) { | 869 | switch (temp) { |
| 811 | case 1: | 870 | case 1: |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index bc011da79e14..086c2a5cef0b 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
| @@ -116,6 +116,21 @@ static const char* temperature_sensors_sets[][36] = { | |||
| 116 | /* Set 9: Macbook Pro 3,1 (Santa Rosa) */ | 116 | /* Set 9: Macbook Pro 3,1 (Santa Rosa) */ |
| 117 | { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", | 117 | { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", |
| 118 | "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, | 118 | "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, |
| 119 | /* Set 10: iMac 5,1 */ | ||
| 120 | { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL }, | ||
| 121 | /* Set 11: Macbook 5,1 */ | ||
| 122 | { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P", | ||
| 123 | "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL }, | ||
| 124 | /* Set 12: Macbook Pro 5,1 */ | ||
| 125 | { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D", | ||
| 126 | "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0", | ||
| 127 | "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL }, | ||
| 128 | /* Set 13: iMac 8,1 */ | ||
| 129 | { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", | ||
| 130 | "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL }, | ||
| 131 | /* Set 14: iMac 6,1 */ | ||
| 132 | { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", | ||
| 133 | "TO0P", "Tp0P", NULL }, | ||
| 119 | }; | 134 | }; |
| 120 | 135 | ||
| 121 | /* List of keys used to read/write fan speeds */ | 136 | /* List of keys used to read/write fan speeds */ |
| @@ -1268,7 +1283,7 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
| 1268 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, | 1283 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, |
| 1269 | /* iMac: temperature set 5 */ | 1284 | /* iMac: temperature set 5 */ |
| 1270 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, | 1285 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, |
| 1271 | /* MacBook3: accelerometer and temperature set 6 */ | 1286 | /* MacBook3, MacBook4: accelerometer and temperature set 6 */ |
| 1272 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, | 1287 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, |
| 1273 | /* MacBook Air: accelerometer, backlight and temperature set 7 */ | 1288 | /* MacBook Air: accelerometer, backlight and temperature set 7 */ |
| 1274 | { .accelerometer = 1, .light = 1, .temperature_set = 7 }, | 1289 | { .accelerometer = 1, .light = 1, .temperature_set = 7 }, |
| @@ -1276,6 +1291,16 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
| 1276 | { .accelerometer = 1, .light = 1, .temperature_set = 8 }, | 1291 | { .accelerometer = 1, .light = 1, .temperature_set = 8 }, |
| 1277 | /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ | 1292 | /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ |
| 1278 | { .accelerometer = 1, .light = 1, .temperature_set = 9 }, | 1293 | { .accelerometer = 1, .light = 1, .temperature_set = 9 }, |
| 1294 | /* iMac 5: light sensor only, temperature set 10 */ | ||
| 1295 | { .accelerometer = 0, .light = 0, .temperature_set = 10 }, | ||
| 1296 | /* MacBook 5: accelerometer, backlight and temperature set 11 */ | ||
| 1297 | { .accelerometer = 1, .light = 1, .temperature_set = 11 }, | ||
| 1298 | /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */ | ||
| 1299 | { .accelerometer = 1, .light = 1, .temperature_set = 12 }, | ||
| 1300 | /* iMac 8: light sensor only, temperature set 13 */ | ||
| 1301 | { .accelerometer = 0, .light = 0, .temperature_set = 13 }, | ||
| 1302 | /* iMac 6: light sensor only, temperature set 14 */ | ||
| 1303 | { .accelerometer = 0, .light = 0, .temperature_set = 14 }, | ||
| 1279 | }; | 1304 | }; |
| 1280 | 1305 | ||
| 1281 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1306 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
| @@ -1285,6 +1310,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
| 1285 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1310 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
| 1286 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, | 1311 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, |
| 1287 | &applesmc_dmi_data[7]}, | 1312 | &applesmc_dmi_data[7]}, |
| 1313 | { applesmc_dmi_match, "Apple MacBook Pro 5", { | ||
| 1314 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1315 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, | ||
| 1316 | &applesmc_dmi_data[12]}, | ||
| 1288 | { applesmc_dmi_match, "Apple MacBook Pro 4", { | 1317 | { applesmc_dmi_match, "Apple MacBook Pro 4", { |
| 1289 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1318 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
| 1290 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, | 1319 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, |
| @@ -1305,6 +1334,14 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
| 1305 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1334 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1306 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, | 1335 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, |
| 1307 | &applesmc_dmi_data[6]}, | 1336 | &applesmc_dmi_data[6]}, |
| 1337 | { applesmc_dmi_match, "Apple MacBook 4", { | ||
| 1338 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1339 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") }, | ||
| 1340 | &applesmc_dmi_data[6]}, | ||
| 1341 | { applesmc_dmi_match, "Apple MacBook 5", { | ||
| 1342 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1343 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") }, | ||
| 1344 | &applesmc_dmi_data[11]}, | ||
| 1308 | { applesmc_dmi_match, "Apple MacBook", { | 1345 | { applesmc_dmi_match, "Apple MacBook", { |
| 1309 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1346 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1310 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, | 1347 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, |
| @@ -1317,6 +1354,22 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
| 1317 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1354 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1318 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, | 1355 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, |
| 1319 | &applesmc_dmi_data[4]}, | 1356 | &applesmc_dmi_data[4]}, |
| 1357 | { applesmc_dmi_match, "Apple MacPro", { | ||
| 1358 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1359 | DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, | ||
| 1360 | &applesmc_dmi_data[4]}, | ||
| 1361 | { applesmc_dmi_match, "Apple iMac 8", { | ||
| 1362 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1363 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, | ||
| 1364 | &applesmc_dmi_data[13]}, | ||
| 1365 | { applesmc_dmi_match, "Apple iMac 6", { | ||
| 1366 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1367 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") }, | ||
| 1368 | &applesmc_dmi_data[14]}, | ||
| 1369 | { applesmc_dmi_match, "Apple iMac 5", { | ||
| 1370 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 1371 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") }, | ||
| 1372 | &applesmc_dmi_data[10]}, | ||
| 1320 | { applesmc_dmi_match, "Apple iMac", { | 1373 | { applesmc_dmi_match, "Apple iMac", { |
| 1321 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1374 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1322 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, | 1375 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, |
| @@ -1511,3 +1564,4 @@ module_exit(applesmc_exit); | |||
| 1511 | MODULE_AUTHOR("Nicolas Boichat"); | 1564 | MODULE_AUTHOR("Nicolas Boichat"); |
| 1512 | MODULE_DESCRIPTION("Apple SMC"); | 1565 | MODULE_DESCRIPTION("Apple SMC"); |
| 1513 | MODULE_LICENSE("GPL v2"); | 1566 | MODULE_LICENSE("GPL v2"); |
| 1567 | MODULE_DEVICE_TABLE(dmi, applesmc_whitelist); | ||
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 7b0ed5dea399..fe74609a7feb 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
| @@ -88,9 +88,11 @@ | |||
| 88 | static DEFINE_IDR(aem_idr); | 88 | static DEFINE_IDR(aem_idr); |
| 89 | static DEFINE_SPINLOCK(aem_idr_lock); | 89 | static DEFINE_SPINLOCK(aem_idr_lock); |
| 90 | 90 | ||
| 91 | static struct device_driver aem_driver = { | 91 | static struct platform_driver aem_driver = { |
| 92 | .name = DRVNAME, | 92 | .driver = { |
| 93 | .bus = &platform_bus_type, | 93 | .name = DRVNAME, |
| 94 | .bus = &platform_bus_type, | ||
| 95 | } | ||
| 94 | }; | 96 | }; |
| 95 | 97 | ||
| 96 | struct aem_ipmi_data { | 98 | struct aem_ipmi_data { |
| @@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
| 583 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 585 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
| 584 | if (!data->pdev) | 586 | if (!data->pdev) |
| 585 | goto dev_err; | 587 | goto dev_err; |
| 586 | data->pdev->dev.driver = &aem_driver; | 588 | data->pdev->dev.driver = &aem_driver.driver; |
| 587 | 589 | ||
| 588 | res = platform_device_add(data->pdev); | 590 | res = platform_device_add(data->pdev); |
| 589 | if (res) | 591 | if (res) |
| @@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
| 716 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 718 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
| 717 | if (!data->pdev) | 719 | if (!data->pdev) |
| 718 | goto dev_err; | 720 | goto dev_err; |
| 719 | data->pdev->dev.driver = &aem_driver; | 721 | data->pdev->dev.driver = &aem_driver.driver; |
| 720 | 722 | ||
| 721 | res = platform_device_add(data->pdev); | 723 | res = platform_device_add(data->pdev); |
| 722 | if (res) | 724 | if (res) |
| @@ -1085,7 +1087,7 @@ static int __init aem_init(void) | |||
| 1085 | { | 1087 | { |
| 1086 | int res; | 1088 | int res; |
| 1087 | 1089 | ||
| 1088 | res = driver_register(&aem_driver); | 1090 | res = driver_register(&aem_driver.driver); |
| 1089 | if (res) { | 1091 | if (res) { |
| 1090 | printk(KERN_ERR "Can't register aem driver\n"); | 1092 | printk(KERN_ERR "Can't register aem driver\n"); |
| 1091 | return res; | 1093 | return res; |
| @@ -1097,7 +1099,7 @@ static int __init aem_init(void) | |||
| 1097 | return 0; | 1099 | return 0; |
| 1098 | 1100 | ||
| 1099 | ipmi_reg_err: | 1101 | ipmi_reg_err: |
| 1100 | driver_unregister(&aem_driver); | 1102 | driver_unregister(&aem_driver.driver); |
| 1101 | return res; | 1103 | return res; |
| 1102 | 1104 | ||
| 1103 | } | 1105 | } |
| @@ -1107,7 +1109,7 @@ static void __exit aem_exit(void) | |||
| 1107 | struct aem_data *p1, *next1; | 1109 | struct aem_data *p1, *next1; |
| 1108 | 1110 | ||
| 1109 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | 1111 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); |
| 1110 | driver_unregister(&aem_driver); | 1112 | driver_unregister(&aem_driver.driver); |
| 1111 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | 1113 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) |
| 1112 | aem_delete(p1); | 1114 | aem_delete(p1); |
| 1113 | } | 1115 | } |
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c new file mode 100644 index 000000000000..c002144c76bc --- /dev/null +++ b/drivers/hwmon/lis3lv02d.c | |||
| @@ -0,0 +1,581 @@ | |||
| 1 | /* | ||
| 2 | * lis3lv02d.c - ST LIS3LV02DL accelerometer driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007-2008 Yan Burman | ||
| 5 | * Copyright (C) 2008 Eric Piel | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/dmi.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/types.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | #include <linux/interrupt.h> | ||
| 29 | #include <linux/input.h> | ||
| 30 | #include <linux/kthread.h> | ||
| 31 | #include <linux/semaphore.h> | ||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/wait.h> | ||
| 34 | #include <linux/poll.h> | ||
| 35 | #include <linux/freezer.h> | ||
| 36 | #include <linux/uaccess.h> | ||
| 37 | #include <acpi/acpi_drivers.h> | ||
| 38 | #include <asm/atomic.h> | ||
| 39 | #include "lis3lv02d.h" | ||
| 40 | |||
| 41 | #define DRIVER_NAME "lis3lv02d" | ||
| 42 | #define ACPI_MDPS_CLASS "accelerometer" | ||
| 43 | |||
| 44 | /* joystick device poll interval in milliseconds */ | ||
| 45 | #define MDPS_POLL_INTERVAL 50 | ||
| 46 | /* | ||
| 47 | * The sensor can also generate interrupts (DRDY) but it's pretty pointless | ||
| 48 | * because their are generated even if the data do not change. So it's better | ||
| 49 | * to keep the interrupt for the free-fall event. The values are updated at | ||
| 50 | * 40Hz (at the lowest frequency), but as it can be pretty time consuming on | ||
| 51 | * some low processor, we poll the sensor only at 20Hz... enough for the | ||
| 52 | * joystick. | ||
| 53 | */ | ||
| 54 | |||
| 55 | /* Maximum value our axis may get for the input device (signed 12 bits) */ | ||
| 56 | #define MDPS_MAX_VAL 2048 | ||
| 57 | |||
| 58 | struct axis_conversion { | ||
| 59 | s8 x; | ||
| 60 | s8 y; | ||
| 61 | s8 z; | ||
| 62 | }; | ||
| 63 | |||
| 64 | struct acpi_lis3lv02d { | ||
| 65 | struct acpi_device *device; /* The ACPI device */ | ||
| 66 | struct input_dev *idev; /* input device */ | ||
| 67 | struct task_struct *kthread; /* kthread for input */ | ||
| 68 | struct mutex lock; | ||
| 69 | struct platform_device *pdev; /* platform device */ | ||
| 70 | atomic_t count; /* interrupt count after last read */ | ||
| 71 | int xcalib; /* calibrated null value for x */ | ||
| 72 | int ycalib; /* calibrated null value for y */ | ||
| 73 | int zcalib; /* calibrated null value for z */ | ||
| 74 | unsigned char is_on; /* whether the device is on or off */ | ||
| 75 | unsigned char usage; /* usage counter */ | ||
| 76 | struct axis_conversion ac; /* hw -> logical axis */ | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct acpi_lis3lv02d adev; | ||
| 80 | |||
| 81 | static int lis3lv02d_remove_fs(void); | ||
| 82 | static int lis3lv02d_add_fs(struct acpi_device *device); | ||
| 83 | |||
| 84 | /* For automatic insertion of the module */ | ||
| 85 | static struct acpi_device_id lis3lv02d_device_ids[] = { | ||
| 86 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ | ||
| 87 | {"", 0}, | ||
| 88 | }; | ||
| 89 | MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); | ||
| 90 | |||
| 91 | /** | ||
| 92 | * lis3lv02d_acpi_init - ACPI _INI method: initialize the device. | ||
| 93 | * @handle: the handle of the device | ||
| 94 | * | ||
| 95 | * Returns AE_OK on success. | ||
| 96 | */ | ||
| 97 | static inline acpi_status lis3lv02d_acpi_init(acpi_handle handle) | ||
| 98 | { | ||
| 99 | return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL); | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * lis3lv02d_acpi_read - ACPI ALRD method: read a register | ||
| 104 | * @handle: the handle of the device | ||
| 105 | * @reg: the register to read | ||
| 106 | * @ret: result of the operation | ||
| 107 | * | ||
| 108 | * Returns AE_OK on success. | ||
| 109 | */ | ||
| 110 | static acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret) | ||
| 111 | { | ||
| 112 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
| 113 | struct acpi_object_list args = { 1, &arg0 }; | ||
| 114 | unsigned long long lret; | ||
| 115 | acpi_status status; | ||
| 116 | |||
| 117 | arg0.integer.value = reg; | ||
| 118 | |||
| 119 | status = acpi_evaluate_integer(handle, "ALRD", &args, &lret); | ||
| 120 | *ret = lret; | ||
| 121 | return status; | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * lis3lv02d_acpi_write - ACPI ALWR method: write to a register | ||
| 126 | * @handle: the handle of the device | ||
| 127 | * @reg: the register to write to | ||
| 128 | * @val: the value to write | ||
| 129 | * | ||
| 130 | * Returns AE_OK on success. | ||
| 131 | */ | ||
| 132 | static acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val) | ||
| 133 | { | ||
| 134 | unsigned long long ret; /* Not used when writting */ | ||
| 135 | union acpi_object in_obj[2]; | ||
| 136 | struct acpi_object_list args = { 2, in_obj }; | ||
| 137 | |||
| 138 | in_obj[0].type = ACPI_TYPE_INTEGER; | ||
| 139 | in_obj[0].integer.value = reg; | ||
| 140 | in_obj[1].type = ACPI_TYPE_INTEGER; | ||
| 141 | in_obj[1].integer.value = val; | ||
| 142 | |||
| 143 | return acpi_evaluate_integer(handle, "ALWR", &args, &ret); | ||
| 144 | } | ||
| 145 | |||
| 146 | static s16 lis3lv02d_read_16(acpi_handle handle, int reg) | ||
| 147 | { | ||
| 148 | u8 lo, hi; | ||
| 149 | |||
| 150 | lis3lv02d_acpi_read(handle, reg, &lo); | ||
| 151 | lis3lv02d_acpi_read(handle, reg + 1, &hi); | ||
| 152 | /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ | ||
| 153 | return (s16)((hi << 8) | lo); | ||
| 154 | } | ||
| 155 | |||
| 156 | /** | ||
| 157 | * lis3lv02d_get_axis - For the given axis, give the value converted | ||
| 158 | * @axis: 1,2,3 - can also be negative | ||
| 159 | * @hw_values: raw values returned by the hardware | ||
| 160 | * | ||
| 161 | * Returns the converted value. | ||
| 162 | */ | ||
| 163 | static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3]) | ||
| 164 | { | ||
| 165 | if (axis > 0) | ||
| 166 | return hw_values[axis - 1]; | ||
| 167 | else | ||
| 168 | return -hw_values[-axis - 1]; | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer | ||
| 173 | * @handle: the handle to the device | ||
| 174 | * @x: where to store the X axis value | ||
| 175 | * @y: where to store the Y axis value | ||
| 176 | * @z: where to store the Z axis value | ||
| 177 | * | ||
| 178 | * Note that 40Hz input device can eat up about 10% CPU at 800MHZ | ||
| 179 | */ | ||
| 180 | static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) | ||
| 181 | { | ||
| 182 | int position[3]; | ||
| 183 | |||
| 184 | position[0] = lis3lv02d_read_16(handle, OUTX_L); | ||
| 185 | position[1] = lis3lv02d_read_16(handle, OUTY_L); | ||
| 186 | position[2] = lis3lv02d_read_16(handle, OUTZ_L); | ||
| 187 | |||
| 188 | *x = lis3lv02d_get_axis(adev.ac.x, position); | ||
| 189 | *y = lis3lv02d_get_axis(adev.ac.y, position); | ||
| 190 | *z = lis3lv02d_get_axis(adev.ac.z, position); | ||
| 191 | } | ||
| 192 | |||
| 193 | static inline void lis3lv02d_poweroff(acpi_handle handle) | ||
| 194 | { | ||
| 195 | adev.is_on = 0; | ||
| 196 | /* disable X,Y,Z axis and power down */ | ||
| 197 | lis3lv02d_acpi_write(handle, CTRL_REG1, 0x00); | ||
| 198 | } | ||
| 199 | |||
| 200 | static void lis3lv02d_poweron(acpi_handle handle) | ||
| 201 | { | ||
| 202 | u8 val; | ||
| 203 | |||
| 204 | adev.is_on = 1; | ||
| 205 | lis3lv02d_acpi_init(handle); | ||
| 206 | lis3lv02d_acpi_write(handle, FF_WU_CFG, 0); | ||
| 207 | /* | ||
| 208 | * BDU: LSB and MSB values are not updated until both have been read. | ||
| 209 | * So the value read will always be correct. | ||
| 210 | * IEN: Interrupt for free-fall and DD, not for data-ready. | ||
| 211 | */ | ||
| 212 | lis3lv02d_acpi_read(handle, CTRL_REG2, &val); | ||
| 213 | val |= CTRL2_BDU | CTRL2_IEN; | ||
| 214 | lis3lv02d_acpi_write(handle, CTRL_REG2, val); | ||
| 215 | } | ||
| 216 | |||
| 217 | #ifdef CONFIG_PM | ||
| 218 | static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) | ||
| 219 | { | ||
| 220 | /* make sure the device is off when we suspend */ | ||
| 221 | lis3lv02d_poweroff(device->handle); | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int lis3lv02d_resume(struct acpi_device *device) | ||
| 226 | { | ||
| 227 | /* put back the device in the right state (ACPI might turn it on) */ | ||
| 228 | mutex_lock(&adev.lock); | ||
| 229 | if (adev.usage > 0) | ||
| 230 | lis3lv02d_poweron(device->handle); | ||
| 231 | else | ||
| 232 | lis3lv02d_poweroff(device->handle); | ||
| 233 | mutex_unlock(&adev.lock); | ||
| 234 | return 0; | ||
| 235 | } | ||
| 236 | #else | ||
| 237 | #define lis3lv02d_suspend NULL | ||
| 238 | #define lis3lv02d_resume NULL | ||
| 239 | #endif | ||
| 240 | |||
| 241 | |||
| 242 | /* | ||
| 243 | * To be called before starting to use the device. It makes sure that the | ||
| 244 | * device will always be on until a call to lis3lv02d_decrease_use(). Not to be | ||
| 245 | * used from interrupt context. | ||
| 246 | */ | ||
| 247 | static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev) | ||
| 248 | { | ||
| 249 | mutex_lock(&dev->lock); | ||
| 250 | dev->usage++; | ||
| 251 | if (dev->usage == 1) { | ||
| 252 | if (!dev->is_on) | ||
| 253 | lis3lv02d_poweron(dev->device->handle); | ||
| 254 | } | ||
| 255 | mutex_unlock(&dev->lock); | ||
| 256 | } | ||
| 257 | |||
| 258 | /* | ||
| 259 | * To be called whenever a usage of the device is stopped. | ||
| 260 | * It will make sure to turn off the device when there is not usage. | ||
| 261 | */ | ||
| 262 | static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) | ||
| 263 | { | ||
| 264 | mutex_lock(&dev->lock); | ||
| 265 | dev->usage--; | ||
| 266 | if (dev->usage == 0) | ||
| 267 | lis3lv02d_poweroff(dev->device->handle); | ||
| 268 | mutex_unlock(&dev->lock); | ||
| 269 | } | ||
| 270 | |||
| 271 | /** | ||
| 272 | * lis3lv02d_joystick_kthread - Kthread polling function | ||
| 273 | * @data: unused - here to conform to threadfn prototype | ||
| 274 | */ | ||
| 275 | static int lis3lv02d_joystick_kthread(void *data) | ||
| 276 | { | ||
| 277 | int x, y, z; | ||
| 278 | |||
| 279 | while (!kthread_should_stop()) { | ||
| 280 | lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); | ||
| 281 | input_report_abs(adev.idev, ABS_X, x - adev.xcalib); | ||
| 282 | input_report_abs(adev.idev, ABS_Y, y - adev.ycalib); | ||
| 283 | input_report_abs(adev.idev, ABS_Z, z - adev.zcalib); | ||
| 284 | |||
| 285 | input_sync(adev.idev); | ||
| 286 | |||
| 287 | try_to_freeze(); | ||
| 288 | msleep_interruptible(MDPS_POLL_INTERVAL); | ||
| 289 | } | ||
| 290 | |||
| 291 | return 0; | ||
| 292 | } | ||
| 293 | |||
| 294 | static int lis3lv02d_joystick_open(struct input_dev *input) | ||
| 295 | { | ||
| 296 | lis3lv02d_increase_use(&adev); | ||
| 297 | adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); | ||
| 298 | if (IS_ERR(adev.kthread)) { | ||
| 299 | lis3lv02d_decrease_use(&adev); | ||
| 300 | return PTR_ERR(adev.kthread); | ||
| 301 | } | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | static void lis3lv02d_joystick_close(struct input_dev *input) | ||
| 307 | { | ||
| 308 | kthread_stop(adev.kthread); | ||
| 309 | lis3lv02d_decrease_use(&adev); | ||
| 310 | } | ||
| 311 | |||
| 312 | |||
| 313 | static inline void lis3lv02d_calibrate_joystick(void) | ||
| 314 | { | ||
| 315 | lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); | ||
| 316 | } | ||
| 317 | |||
| 318 | static int lis3lv02d_joystick_enable(void) | ||
| 319 | { | ||
| 320 | int err; | ||
| 321 | |||
| 322 | if (adev.idev) | ||
| 323 | return -EINVAL; | ||
| 324 | |||
| 325 | adev.idev = input_allocate_device(); | ||
| 326 | if (!adev.idev) | ||
| 327 | return -ENOMEM; | ||
| 328 | |||
| 329 | lis3lv02d_calibrate_joystick(); | ||
| 330 | |||
| 331 | adev.idev->name = "ST LIS3LV02DL Accelerometer"; | ||
| 332 | adev.idev->phys = DRIVER_NAME "/input0"; | ||
| 333 | adev.idev->id.bustype = BUS_HOST; | ||
| 334 | adev.idev->id.vendor = 0; | ||
| 335 | adev.idev->dev.parent = &adev.pdev->dev; | ||
| 336 | adev.idev->open = lis3lv02d_joystick_open; | ||
| 337 | adev.idev->close = lis3lv02d_joystick_close; | ||
| 338 | |||
| 339 | set_bit(EV_ABS, adev.idev->evbit); | ||
| 340 | input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); | ||
| 341 | input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); | ||
| 342 | input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); | ||
| 343 | |||
| 344 | err = input_register_device(adev.idev); | ||
| 345 | if (err) { | ||
| 346 | input_free_device(adev.idev); | ||
| 347 | adev.idev = NULL; | ||
| 348 | } | ||
| 349 | |||
| 350 | return err; | ||
| 351 | } | ||
| 352 | |||
| 353 | static void lis3lv02d_joystick_disable(void) | ||
| 354 | { | ||
| 355 | if (!adev.idev) | ||
| 356 | return; | ||
| 357 | |||
| 358 | input_unregister_device(adev.idev); | ||
| 359 | adev.idev = NULL; | ||
| 360 | } | ||
| 361 | |||
| 362 | |||
| 363 | /* | ||
| 364 | * Initialise the accelerometer and the various subsystems. | ||
| 365 | * Should be rather independant of the bus system. | ||
| 366 | */ | ||
| 367 | static int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) | ||
| 368 | { | ||
| 369 | mutex_init(&dev->lock); | ||
| 370 | lis3lv02d_add_fs(dev->device); | ||
| 371 | lis3lv02d_increase_use(dev); | ||
| 372 | |||
| 373 | if (lis3lv02d_joystick_enable()) | ||
| 374 | printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); | ||
| 375 | |||
| 376 | lis3lv02d_decrease_use(dev); | ||
| 377 | return 0; | ||
| 378 | } | ||
| 379 | |||
| 380 | static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) | ||
| 381 | { | ||
| 382 | adev.ac = *((struct axis_conversion *)dmi->driver_data); | ||
| 383 | printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); | ||
| 384 | |||
| 385 | return 1; | ||
| 386 | } | ||
| 387 | |||
| 388 | /* Represents, for each axis seen by userspace, the corresponding hw axis (+1). | ||
| 389 | * If the value is negative, the opposite of the hw value is used. */ | ||
| 390 | static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3}; | ||
| 391 | static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; | ||
| 392 | static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; | ||
| 393 | static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; | ||
| 394 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; | ||
| 395 | static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; | ||
| 396 | |||
| 397 | #define AXIS_DMI_MATCH(_ident, _name, _axis) { \ | ||
| 398 | .ident = _ident, \ | ||
| 399 | .callback = lis3lv02d_dmi_matched, \ | ||
| 400 | .matches = { \ | ||
| 401 | DMI_MATCH(DMI_PRODUCT_NAME, _name) \ | ||
| 402 | }, \ | ||
| 403 | .driver_data = &lis3lv02d_axis_##_axis \ | ||
| 404 | } | ||
| 405 | static struct dmi_system_id lis3lv02d_dmi_ids[] = { | ||
| 406 | /* product names are truncated to match all kinds of a same model */ | ||
| 407 | AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), | ||
| 408 | AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted), | ||
| 409 | AXIS_DMI_MATCH("NX9420", "HP Compaq nx9420", x_inverted), | ||
| 410 | AXIS_DMI_MATCH("NW9440", "HP Compaq nw9440", x_inverted), | ||
| 411 | AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), | ||
| 412 | AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), | ||
| 413 | AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), | ||
| 414 | { NULL, } | ||
| 415 | /* Laptop models without axis info (yet): | ||
| 416 | * "NC651xx" "HP Compaq 651" | ||
| 417 | * "NC671xx" "HP Compaq 671" | ||
| 418 | * "NC6910" "HP Compaq 6910" | ||
| 419 | * HP Compaq 8710x Notebook PC / Mobile Workstation | ||
| 420 | * "NC2400" "HP Compaq nc2400" | ||
| 421 | * "NX74x0" "HP Compaq nx74" | ||
| 422 | * "NX6325" "HP Compaq nx6325" | ||
| 423 | * "NC4400" "HP Compaq nc4400" | ||
| 424 | */ | ||
| 425 | }; | ||
| 426 | |||
| 427 | static int lis3lv02d_add(struct acpi_device *device) | ||
| 428 | { | ||
| 429 | u8 val; | ||
| 430 | |||
| 431 | if (!device) | ||
| 432 | return -EINVAL; | ||
| 433 | |||
| 434 | adev.device = device; | ||
| 435 | strcpy(acpi_device_name(device), DRIVER_NAME); | ||
| 436 | strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); | ||
| 437 | device->driver_data = &adev; | ||
| 438 | |||
| 439 | lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val); | ||
| 440 | if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) { | ||
| 441 | printk(KERN_ERR DRIVER_NAME | ||
| 442 | ": Accelerometer chip not LIS3LV02D{L,Q}\n"); | ||
| 443 | } | ||
| 444 | |||
| 445 | /* If possible use a "standard" axes order */ | ||
| 446 | if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { | ||
| 447 | printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " | ||
| 448 | "using default axes configuration\n"); | ||
| 449 | adev.ac = lis3lv02d_axis_normal; | ||
| 450 | } | ||
| 451 | |||
| 452 | return lis3lv02d_init_device(&adev); | ||
| 453 | } | ||
| 454 | |||
| 455 | static int lis3lv02d_remove(struct acpi_device *device, int type) | ||
| 456 | { | ||
| 457 | if (!device) | ||
| 458 | return -EINVAL; | ||
| 459 | |||
| 460 | lis3lv02d_joystick_disable(); | ||
| 461 | lis3lv02d_poweroff(device->handle); | ||
| 462 | |||
| 463 | return lis3lv02d_remove_fs(); | ||
| 464 | } | ||
| 465 | |||
| 466 | |||
| 467 | /* Sysfs stuff */ | ||
| 468 | static ssize_t lis3lv02d_position_show(struct device *dev, | ||
| 469 | struct device_attribute *attr, char *buf) | ||
| 470 | { | ||
| 471 | int x, y, z; | ||
| 472 | |||
| 473 | lis3lv02d_increase_use(&adev); | ||
| 474 | lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); | ||
| 475 | lis3lv02d_decrease_use(&adev); | ||
| 476 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); | ||
| 477 | } | ||
| 478 | |||
| 479 | static ssize_t lis3lv02d_calibrate_show(struct device *dev, | ||
| 480 | struct device_attribute *attr, char *buf) | ||
| 481 | { | ||
| 482 | return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib); | ||
| 483 | } | ||
| 484 | |||
| 485 | static ssize_t lis3lv02d_calibrate_store(struct device *dev, | ||
| 486 | struct device_attribute *attr, | ||
| 487 | const char *buf, size_t count) | ||
| 488 | { | ||
| 489 | lis3lv02d_increase_use(&adev); | ||
| 490 | lis3lv02d_calibrate_joystick(); | ||
| 491 | lis3lv02d_decrease_use(&adev); | ||
| 492 | return count; | ||
| 493 | } | ||
| 494 | |||
| 495 | /* conversion btw sampling rate and the register values */ | ||
| 496 | static int lis3lv02dl_df_val[4] = {40, 160, 640, 2560}; | ||
| 497 | static ssize_t lis3lv02d_rate_show(struct device *dev, | ||
| 498 | struct device_attribute *attr, char *buf) | ||
| 499 | { | ||
| 500 | u8 ctrl; | ||
| 501 | int val; | ||
| 502 | |||
| 503 | lis3lv02d_increase_use(&adev); | ||
| 504 | lis3lv02d_acpi_read(adev.device->handle, CTRL_REG1, &ctrl); | ||
| 505 | lis3lv02d_decrease_use(&adev); | ||
| 506 | val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; | ||
| 507 | return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); | ||
| 508 | } | ||
| 509 | |||
| 510 | static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL); | ||
| 511 | static DEVICE_ATTR(calibrate, S_IRUGO|S_IWUSR, lis3lv02d_calibrate_show, | ||
| 512 | lis3lv02d_calibrate_store); | ||
| 513 | static DEVICE_ATTR(rate, S_IRUGO, lis3lv02d_rate_show, NULL); | ||
| 514 | |||
| 515 | static struct attribute *lis3lv02d_attributes[] = { | ||
| 516 | &dev_attr_position.attr, | ||
| 517 | &dev_attr_calibrate.attr, | ||
| 518 | &dev_attr_rate.attr, | ||
| 519 | NULL | ||
| 520 | }; | ||
| 521 | |||
| 522 | static struct attribute_group lis3lv02d_attribute_group = { | ||
| 523 | .attrs = lis3lv02d_attributes | ||
| 524 | }; | ||
| 525 | |||
| 526 | static int lis3lv02d_add_fs(struct acpi_device *device) | ||
| 527 | { | ||
| 528 | adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); | ||
| 529 | if (IS_ERR(adev.pdev)) | ||
| 530 | return PTR_ERR(adev.pdev); | ||
| 531 | |||
| 532 | return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); | ||
| 533 | } | ||
| 534 | |||
| 535 | static int lis3lv02d_remove_fs(void) | ||
| 536 | { | ||
| 537 | sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); | ||
| 538 | platform_device_unregister(adev.pdev); | ||
| 539 | return 0; | ||
| 540 | } | ||
| 541 | |||
| 542 | /* For the HP MDPS aka 3D Driveguard */ | ||
| 543 | static struct acpi_driver lis3lv02d_driver = { | ||
| 544 | .name = DRIVER_NAME, | ||
| 545 | .class = ACPI_MDPS_CLASS, | ||
| 546 | .ids = lis3lv02d_device_ids, | ||
| 547 | .ops = { | ||
| 548 | .add = lis3lv02d_add, | ||
| 549 | .remove = lis3lv02d_remove, | ||
| 550 | .suspend = lis3lv02d_suspend, | ||
| 551 | .resume = lis3lv02d_resume, | ||
| 552 | } | ||
| 553 | }; | ||
| 554 | |||
| 555 | static int __init lis3lv02d_init_module(void) | ||
| 556 | { | ||
| 557 | int ret; | ||
| 558 | |||
| 559 | if (acpi_disabled) | ||
| 560 | return -ENODEV; | ||
| 561 | |||
| 562 | ret = acpi_bus_register_driver(&lis3lv02d_driver); | ||
| 563 | if (ret < 0) | ||
| 564 | return ret; | ||
| 565 | |||
| 566 | printk(KERN_INFO DRIVER_NAME " driver loaded.\n"); | ||
| 567 | |||
| 568 | return 0; | ||
| 569 | } | ||
| 570 | |||
| 571 | static void __exit lis3lv02d_exit_module(void) | ||
| 572 | { | ||
| 573 | acpi_bus_unregister_driver(&lis3lv02d_driver); | ||
| 574 | } | ||
| 575 | |||
| 576 | MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); | ||
| 577 | MODULE_AUTHOR("Yan Burman and Eric Piel"); | ||
| 578 | MODULE_LICENSE("GPL"); | ||
| 579 | |||
| 580 | module_init(lis3lv02d_init_module); | ||
| 581 | module_exit(lis3lv02d_exit_module); | ||
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h new file mode 100644 index 000000000000..330cfc60e948 --- /dev/null +++ b/drivers/hwmon/lis3lv02d.h | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /* | ||
| 2 | * lis3lv02d.h - ST LIS3LV02DL accelerometer driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007-2008 Yan Burman | ||
| 5 | * Copyright (C) 2008 Eric Piel | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to | ||
| 24 | * be connected via SPI. There exists also several similar chips (such as LIS302DL or | ||
| 25 | * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. | ||
| 26 | * They can also be connected via I²C. | ||
| 27 | */ | ||
| 28 | |||
| 29 | #define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ | ||
| 30 | #define LIS302DL_ID 0x3B /* Also the LIS202DL! */ | ||
| 31 | |||
| 32 | enum lis3lv02d_reg { | ||
| 33 | WHO_AM_I = 0x0F, | ||
| 34 | OFFSET_X = 0x16, | ||
| 35 | OFFSET_Y = 0x17, | ||
| 36 | OFFSET_Z = 0x18, | ||
| 37 | GAIN_X = 0x19, | ||
| 38 | GAIN_Y = 0x1A, | ||
| 39 | GAIN_Z = 0x1B, | ||
| 40 | CTRL_REG1 = 0x20, | ||
| 41 | CTRL_REG2 = 0x21, | ||
| 42 | CTRL_REG3 = 0x22, | ||
| 43 | HP_FILTER_RESET = 0x23, | ||
| 44 | STATUS_REG = 0x27, | ||
| 45 | OUTX_L = 0x28, | ||
| 46 | OUTX_H = 0x29, | ||
| 47 | OUTY_L = 0x2A, | ||
| 48 | OUTY_H = 0x2B, | ||
| 49 | OUTZ_L = 0x2C, | ||
| 50 | OUTZ_H = 0x2D, | ||
| 51 | FF_WU_CFG = 0x30, | ||
| 52 | FF_WU_SRC = 0x31, | ||
| 53 | FF_WU_ACK = 0x32, | ||
| 54 | FF_WU_THS_L = 0x34, | ||
| 55 | FF_WU_THS_H = 0x35, | ||
| 56 | FF_WU_DURATION = 0x36, | ||
| 57 | DD_CFG = 0x38, | ||
| 58 | DD_SRC = 0x39, | ||
| 59 | DD_ACK = 0x3A, | ||
| 60 | DD_THSI_L = 0x3C, | ||
| 61 | DD_THSI_H = 0x3D, | ||
| 62 | DD_THSE_L = 0x3E, | ||
| 63 | DD_THSE_H = 0x3F, | ||
| 64 | }; | ||
| 65 | |||
| 66 | enum lis3lv02d_ctrl1 { | ||
| 67 | CTRL1_Xen = 0x01, | ||
| 68 | CTRL1_Yen = 0x02, | ||
| 69 | CTRL1_Zen = 0x04, | ||
| 70 | CTRL1_ST = 0x08, | ||
| 71 | CTRL1_DF0 = 0x10, | ||
| 72 | CTRL1_DF1 = 0x20, | ||
| 73 | CTRL1_PD0 = 0x40, | ||
| 74 | CTRL1_PD1 = 0x80, | ||
| 75 | }; | ||
| 76 | enum lis3lv02d_ctrl2 { | ||
| 77 | CTRL2_DAS = 0x01, | ||
| 78 | CTRL2_SIM = 0x02, | ||
| 79 | CTRL2_DRDY = 0x04, | ||
| 80 | CTRL2_IEN = 0x08, | ||
| 81 | CTRL2_BOOT = 0x10, | ||
| 82 | CTRL2_BLE = 0x20, | ||
| 83 | CTRL2_BDU = 0x40, /* Block Data Update */ | ||
| 84 | CTRL2_FS = 0x80, /* Full Scale selection */ | ||
| 85 | }; | ||
| 86 | |||
| 87 | |||
| 88 | enum lis3lv02d_ctrl3 { | ||
| 89 | CTRL3_CFS0 = 0x01, | ||
| 90 | CTRL3_CFS1 = 0x02, | ||
| 91 | CTRL3_FDS = 0x10, | ||
| 92 | CTRL3_HPFF = 0x20, | ||
| 93 | CTRL3_HPDD = 0x40, | ||
| 94 | CTRL3_ECK = 0x80, | ||
| 95 | }; | ||
| 96 | |||
| 97 | enum lis3lv02d_status_reg { | ||
| 98 | STATUS_XDA = 0x01, | ||
| 99 | STATUS_YDA = 0x02, | ||
| 100 | STATUS_ZDA = 0x04, | ||
| 101 | STATUS_XYZDA = 0x08, | ||
| 102 | STATUS_XOR = 0x10, | ||
| 103 | STATUS_YOR = 0x20, | ||
| 104 | STATUS_ZOR = 0x40, | ||
| 105 | STATUS_XYZOR = 0x80, | ||
| 106 | }; | ||
| 107 | |||
| 108 | enum lis3lv02d_ff_wu_cfg { | ||
| 109 | FF_WU_CFG_XLIE = 0x01, | ||
| 110 | FF_WU_CFG_XHIE = 0x02, | ||
| 111 | FF_WU_CFG_YLIE = 0x04, | ||
| 112 | FF_WU_CFG_YHIE = 0x08, | ||
| 113 | FF_WU_CFG_ZLIE = 0x10, | ||
| 114 | FF_WU_CFG_ZHIE = 0x20, | ||
| 115 | FF_WU_CFG_LIR = 0x40, | ||
| 116 | FF_WU_CFG_AOI = 0x80, | ||
| 117 | }; | ||
| 118 | |||
| 119 | enum lis3lv02d_ff_wu_src { | ||
| 120 | FF_WU_SRC_XL = 0x01, | ||
| 121 | FF_WU_SRC_XH = 0x02, | ||
| 122 | FF_WU_SRC_YL = 0x04, | ||
| 123 | FF_WU_SRC_YH = 0x08, | ||
| 124 | FF_WU_SRC_ZL = 0x10, | ||
| 125 | FF_WU_SRC_ZH = 0x20, | ||
| 126 | FF_WU_SRC_IA = 0x40, | ||
| 127 | }; | ||
| 128 | |||
| 129 | enum lis3lv02d_dd_cfg { | ||
| 130 | DD_CFG_XLIE = 0x01, | ||
| 131 | DD_CFG_XHIE = 0x02, | ||
| 132 | DD_CFG_YLIE = 0x04, | ||
| 133 | DD_CFG_YHIE = 0x08, | ||
| 134 | DD_CFG_ZLIE = 0x10, | ||
| 135 | DD_CFG_ZHIE = 0x20, | ||
| 136 | DD_CFG_LIR = 0x40, | ||
| 137 | DD_CFG_IEND = 0x80, | ||
| 138 | }; | ||
| 139 | |||
| 140 | enum lis3lv02d_dd_src { | ||
| 141 | DD_SRC_XL = 0x01, | ||
| 142 | DD_SRC_XH = 0x02, | ||
| 143 | DD_SRC_YL = 0x04, | ||
| 144 | DD_SRC_YH = 0x08, | ||
| 145 | DD_SRC_ZL = 0x10, | ||
| 146 | DD_SRC_ZH = 0x20, | ||
| 147 | DD_SRC_IA = 0x40, | ||
| 148 | }; | ||
| 149 | |||
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 3ff0285396fa..cfc1ee90f5a3 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
| @@ -39,7 +39,8 @@ | |||
| 39 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | 39 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
| 40 | 40 | ||
| 41 | /* Insmod parameters */ | 41 | /* Insmod parameters */ |
| 42 | I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | 42 | I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, |
| 43 | emc6d102); | ||
| 43 | 44 | ||
| 44 | /* The LM85 registers */ | 45 | /* The LM85 registers */ |
| 45 | 46 | ||
| @@ -59,6 +60,12 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
| 59 | 60 | ||
| 60 | #define LM85_REG_COMPANY 0x3e | 61 | #define LM85_REG_COMPANY 0x3e |
| 61 | #define LM85_REG_VERSTEP 0x3f | 62 | #define LM85_REG_VERSTEP 0x3f |
| 63 | |||
| 64 | #define ADT7468_REG_CFG5 0x7c | ||
| 65 | #define ADT7468_OFF64 0x01 | ||
| 66 | #define IS_ADT7468_OFF64(data) \ | ||
| 67 | ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64)) | ||
| 68 | |||
| 62 | /* These are the recognized values for the above regs */ | 69 | /* These are the recognized values for the above regs */ |
| 63 | #define LM85_COMPANY_NATIONAL 0x01 | 70 | #define LM85_COMPANY_NATIONAL 0x01 |
| 64 | #define LM85_COMPANY_ANALOG_DEV 0x41 | 71 | #define LM85_COMPANY_ANALOG_DEV 0x41 |
| @@ -70,6 +77,8 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
| 70 | #define LM85_VERSTEP_ADM1027 0x60 | 77 | #define LM85_VERSTEP_ADM1027 0x60 |
| 71 | #define LM85_VERSTEP_ADT7463 0x62 | 78 | #define LM85_VERSTEP_ADT7463 0x62 |
| 72 | #define LM85_VERSTEP_ADT7463C 0x6A | 79 | #define LM85_VERSTEP_ADT7463C 0x6A |
| 80 | #define LM85_VERSTEP_ADT7468_1 0x71 | ||
| 81 | #define LM85_VERSTEP_ADT7468_2 0x72 | ||
| 73 | #define LM85_VERSTEP_EMC6D100_A0 0x60 | 82 | #define LM85_VERSTEP_EMC6D100_A0 0x60 |
| 74 | #define LM85_VERSTEP_EMC6D100_A1 0x61 | 83 | #define LM85_VERSTEP_EMC6D100_A1 0x61 |
| 75 | #define LM85_VERSTEP_EMC6D102 0x65 | 84 | #define LM85_VERSTEP_EMC6D102 0x65 |
| @@ -306,6 +315,7 @@ struct lm85_data { | |||
| 306 | u8 vid; /* Register value */ | 315 | u8 vid; /* Register value */ |
| 307 | u8 vrm; /* VRM version */ | 316 | u8 vrm; /* VRM version */ |
| 308 | u32 alarms; /* Register encoding, combined */ | 317 | u32 alarms; /* Register encoding, combined */ |
| 318 | u8 cfg5; /* Config Register 5 on ADT7468 */ | ||
| 309 | struct lm85_autofan autofan[3]; | 319 | struct lm85_autofan autofan[3]; |
| 310 | struct lm85_zone zone[3]; | 320 | struct lm85_zone zone[3]; |
| 311 | }; | 321 | }; |
| @@ -685,6 +695,9 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 685 | struct lm85_data *data = i2c_get_clientdata(client); | 695 | struct lm85_data *data = i2c_get_clientdata(client); |
| 686 | long val = simple_strtol(buf, NULL, 10); | 696 | long val = simple_strtol(buf, NULL, 10); |
| 687 | 697 | ||
| 698 | if (IS_ADT7468_OFF64(data)) | ||
| 699 | val += 64; | ||
| 700 | |||
| 688 | mutex_lock(&data->update_lock); | 701 | mutex_lock(&data->update_lock); |
| 689 | data->temp_min[nr] = TEMP_TO_REG(val); | 702 | data->temp_min[nr] = TEMP_TO_REG(val); |
| 690 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); | 703 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); |
| @@ -708,6 +721,9 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 708 | struct lm85_data *data = i2c_get_clientdata(client); | 721 | struct lm85_data *data = i2c_get_clientdata(client); |
| 709 | long val = simple_strtol(buf, NULL, 10); | 722 | long val = simple_strtol(buf, NULL, 10); |
| 710 | 723 | ||
| 724 | if (IS_ADT7468_OFF64(data)) | ||
| 725 | val += 64; | ||
| 726 | |||
| 711 | mutex_lock(&data->update_lock); | 727 | mutex_lock(&data->update_lock); |
| 712 | data->temp_max[nr] = TEMP_TO_REG(val); | 728 | data->temp_max[nr] = TEMP_TO_REG(val); |
| 713 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); | 729 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); |
| @@ -1163,6 +1179,10 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
| 1163 | case LM85_VERSTEP_ADT7463C: | 1179 | case LM85_VERSTEP_ADT7463C: |
| 1164 | kind = adt7463; | 1180 | kind = adt7463; |
| 1165 | break; | 1181 | break; |
| 1182 | case LM85_VERSTEP_ADT7468_1: | ||
| 1183 | case LM85_VERSTEP_ADT7468_2: | ||
| 1184 | kind = adt7468; | ||
| 1185 | break; | ||
| 1166 | } | 1186 | } |
| 1167 | } else if (company == LM85_COMPANY_SMSC) { | 1187 | } else if (company == LM85_COMPANY_SMSC) { |
| 1168 | switch (verstep) { | 1188 | switch (verstep) { |
| @@ -1195,6 +1215,9 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
| 1195 | case adt7463: | 1215 | case adt7463: |
| 1196 | type_name = "adt7463"; | 1216 | type_name = "adt7463"; |
| 1197 | break; | 1217 | break; |
| 1218 | case adt7468: | ||
| 1219 | type_name = "adt7468"; | ||
| 1220 | break; | ||
| 1198 | case emc6d100: | 1221 | case emc6d100: |
| 1199 | type_name = "emc6d100"; | 1222 | type_name = "emc6d100"; |
| 1200 | break; | 1223 | break; |
| @@ -1246,10 +1269,11 @@ static int lm85_probe(struct i2c_client *client, | |||
| 1246 | if (err) | 1269 | if (err) |
| 1247 | goto err_kfree; | 1270 | goto err_kfree; |
| 1248 | 1271 | ||
| 1249 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used | 1272 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used |
| 1250 | as a sixth digital VID input rather than an analog input. */ | 1273 | as a sixth digital VID input rather than an analog input. */ |
| 1251 | data->vid = lm85_read_value(client, LM85_REG_VID); | 1274 | data->vid = lm85_read_value(client, LM85_REG_VID); |
| 1252 | if (!(data->type == adt7463 && (data->vid & 0x80))) | 1275 | if (!((data->type == adt7463 || data->type == adt7468) && |
| 1276 | (data->vid & 0x80))) | ||
| 1253 | if ((err = sysfs_create_group(&client->dev.kobj, | 1277 | if ((err = sysfs_create_group(&client->dev.kobj, |
| 1254 | &lm85_group_in4))) | 1278 | &lm85_group_in4))) |
| 1255 | goto err_remove_files; | 1279 | goto err_remove_files; |
| @@ -1357,7 +1381,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1357 | * There are 2 additional resolution bits per channel and we | 1381 | * There are 2 additional resolution bits per channel and we |
| 1358 | * have room for 4, so we shift them to the left. | 1382 | * have room for 4, so we shift them to the left. |
| 1359 | */ | 1383 | */ |
| 1360 | if (data->type == adm1027 || data->type == adt7463) { | 1384 | if (data->type == adm1027 || data->type == adt7463 || |
| 1385 | data->type == adt7468) { | ||
| 1361 | int ext1 = lm85_read_value(client, | 1386 | int ext1 = lm85_read_value(client, |
| 1362 | ADM1027_REG_EXTEND_ADC1); | 1387 | ADM1027_REG_EXTEND_ADC1); |
| 1363 | int ext2 = lm85_read_value(client, | 1388 | int ext2 = lm85_read_value(client, |
| @@ -1382,16 +1407,23 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1382 | lm85_read_value(client, LM85_REG_FAN(i)); | 1407 | lm85_read_value(client, LM85_REG_FAN(i)); |
| 1383 | } | 1408 | } |
| 1384 | 1409 | ||
| 1385 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1410 | if (!((data->type == adt7463 || data->type == adt7468) && |
| 1411 | (data->vid & 0x80))) { | ||
| 1386 | data->in[4] = lm85_read_value(client, | 1412 | data->in[4] = lm85_read_value(client, |
| 1387 | LM85_REG_IN(4)); | 1413 | LM85_REG_IN(4)); |
| 1388 | } | 1414 | } |
| 1389 | 1415 | ||
| 1416 | if (data->type == adt7468) | ||
| 1417 | data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5); | ||
| 1418 | |||
| 1390 | for (i = 0; i <= 2; ++i) { | 1419 | for (i = 0; i <= 2; ++i) { |
| 1391 | data->temp[i] = | 1420 | data->temp[i] = |
| 1392 | lm85_read_value(client, LM85_REG_TEMP(i)); | 1421 | lm85_read_value(client, LM85_REG_TEMP(i)); |
| 1393 | data->pwm[i] = | 1422 | data->pwm[i] = |
| 1394 | lm85_read_value(client, LM85_REG_PWM(i)); | 1423 | lm85_read_value(client, LM85_REG_PWM(i)); |
| 1424 | |||
| 1425 | if (IS_ADT7468_OFF64(data)) | ||
| 1426 | data->temp[i] -= 64; | ||
| 1395 | } | 1427 | } |
| 1396 | 1428 | ||
| 1397 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); | 1429 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); |
| @@ -1446,7 +1478,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1446 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); | 1478 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); |
| 1447 | } | 1479 | } |
| 1448 | 1480 | ||
| 1449 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1481 | if (!((data->type == adt7463 || data->type == adt7468) && |
| 1482 | (data->vid & 0x80))) { | ||
| 1450 | data->in_min[4] = lm85_read_value(client, | 1483 | data->in_min[4] = lm85_read_value(client, |
| 1451 | LM85_REG_IN_MIN(4)); | 1484 | LM85_REG_IN_MIN(4)); |
| 1452 | data->in_max[4] = lm85_read_value(client, | 1485 | data->in_max[4] = lm85_read_value(client, |
| @@ -1481,6 +1514,13 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1481 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); | 1514 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); |
| 1482 | data->zone[i].critical = | 1515 | data->zone[i].critical = |
| 1483 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); | 1516 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); |
| 1517 | |||
| 1518 | if (IS_ADT7468_OFF64(data)) { | ||
| 1519 | data->temp_min[i] -= 64; | ||
| 1520 | data->temp_max[i] -= 64; | ||
| 1521 | data->zone[i].limit -= 64; | ||
| 1522 | data->zone[i].critical -= 64; | ||
| 1523 | } | ||
| 1484 | } | 1524 | } |
| 1485 | 1525 | ||
| 1486 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); | 1526 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 59ba2086d2f9..a257cd5cd134 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
| @@ -189,8 +189,6 @@ static void i2c_parport_attach (struct parport *port) | |||
| 189 | if (adapter_parm[type].init.val) | 189 | if (adapter_parm[type].init.val) |
| 190 | line_set(port, 1, &adapter_parm[type].init); | 190 | line_set(port, 1, &adapter_parm[type].init); |
| 191 | 191 | ||
| 192 | parport_release(adapter->pdev); | ||
| 193 | |||
| 194 | if (i2c_bit_add_bus(&adapter->adapter) < 0) { | 192 | if (i2c_bit_add_bus(&adapter->adapter) < 0) { |
| 195 | printk(KERN_ERR "i2c-parport: Unable to register with I2C\n"); | 193 | printk(KERN_ERR "i2c-parport: Unable to register with I2C\n"); |
| 196 | goto ERROR1; | 194 | goto ERROR1; |
| @@ -202,6 +200,7 @@ static void i2c_parport_attach (struct parport *port) | |||
| 202 | return; | 200 | return; |
| 203 | 201 | ||
| 204 | ERROR1: | 202 | ERROR1: |
| 203 | parport_release(adapter->pdev); | ||
| 205 | parport_unregister_device(adapter->pdev); | 204 | parport_unregister_device(adapter->pdev); |
| 206 | ERROR0: | 205 | ERROR0: |
| 207 | kfree(adapter); | 206 | kfree(adapter); |
| @@ -221,6 +220,7 @@ static void i2c_parport_detach (struct parport *port) | |||
| 221 | if (adapter_parm[type].init.val) | 220 | if (adapter_parm[type].init.val) |
| 222 | line_set(port, 0, &adapter_parm[type].init); | 221 | line_set(port, 0, &adapter_parm[type].init); |
| 223 | 222 | ||
| 223 | parport_release(adapter->pdev); | ||
| 224 | parport_unregister_device(adapter->pdev); | 224 | parport_unregister_device(adapter->pdev); |
| 225 | if (prev) | 225 | if (prev) |
| 226 | prev->next = adapter->next; | 226 | prev->next = adapter->next; |
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 640cbb237328..3384a717fec0 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
| @@ -318,7 +318,8 @@ static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd) | |||
| 318 | } else | 318 | } else |
| 319 | data = i2c_op(pd, OP_RX, 0); | 319 | data = i2c_op(pd, OP_RX, 0); |
| 320 | 320 | ||
| 321 | pd->msg->buf[real_pos] = data; | 321 | if (real_pos >= 0) |
| 322 | pd->msg->buf[real_pos] = data; | ||
| 322 | } while (0); | 323 | } while (0); |
| 323 | 324 | ||
| 324 | pd->pos++; | 325 | pd->pos++; |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 28902ebd5539..e0d56ef2bcb0 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
| 28 | #include <linux/gpio.h> | ||
| 28 | #include <linux/usb/ch9.h> | 29 | #include <linux/usb/ch9.h> |
| 29 | #include <linux/usb/gadget.h> | 30 | #include <linux/usb/gadget.h> |
| 30 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
| @@ -33,7 +34,10 @@ | |||
| 33 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| 34 | 35 | ||
| 35 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
| 37 | #include <asm/mach-types.h> | ||
| 38 | |||
| 36 | #include <mach/usb.h> | 39 | #include <mach/usb.h> |
| 40 | #include <mach/mux.h> | ||
| 37 | 41 | ||
| 38 | 42 | ||
| 39 | #ifndef DEBUG | 43 | #ifndef DEBUG |
| @@ -88,14 +92,9 @@ struct isp1301 { | |||
| 88 | 92 | ||
| 89 | /*-------------------------------------------------------------------------*/ | 93 | /*-------------------------------------------------------------------------*/ |
| 90 | 94 | ||
| 91 | #ifdef CONFIG_MACH_OMAP_H2 | ||
| 92 | |||
| 93 | /* board-specific PM hooks */ | 95 | /* board-specific PM hooks */ |
| 94 | 96 | ||
| 95 | #include <asm/gpio.h> | 97 | #if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) |
| 96 | #include <mach/mux.h> | ||
| 97 | #include <asm/mach-types.h> | ||
| 98 | |||
| 99 | 98 | ||
| 100 | #if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) | 99 | #if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) |
| 101 | 100 | ||
| @@ -135,6 +134,33 @@ static inline void notresponding(struct isp1301 *isp) | |||
| 135 | 134 | ||
| 136 | #endif | 135 | #endif |
| 137 | 136 | ||
| 137 | #if defined(CONFIG_MACH_OMAP_H4) | ||
| 138 | |||
| 139 | static void enable_vbus_draw(struct isp1301 *isp, unsigned mA) | ||
| 140 | { | ||
| 141 | /* H4 controls this by DIP switch S2.4; no soft control. | ||
| 142 | * ON means the charger is always enabled. Leave it OFF | ||
| 143 | * unless the OTG port is used only in B-peripheral mode. | ||
| 144 | */ | ||
| 145 | } | ||
| 146 | |||
| 147 | static void enable_vbus_source(struct isp1301 *isp) | ||
| 148 | { | ||
| 149 | /* this board won't supply more than 8mA vbus power. | ||
| 150 | * some boards can switch a 100ma "unit load" (or more). | ||
| 151 | */ | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | /* products will deliver OTG messages with LEDs, GUI, etc */ | ||
| 156 | static inline void notresponding(struct isp1301 *isp) | ||
| 157 | { | ||
| 158 | printk(KERN_NOTICE "OTG device not responding.\n"); | ||
| 159 | } | ||
| 160 | |||
| 161 | |||
| 162 | #endif | ||
| 163 | |||
| 138 | /*-------------------------------------------------------------------------*/ | 164 | /*-------------------------------------------------------------------------*/ |
| 139 | 165 | ||
| 140 | static struct i2c_driver isp1301_driver; | 166 | static struct i2c_driver isp1301_driver; |
| @@ -334,8 +360,7 @@ static int gadget_suspend(struct isp1301 *isp) | |||
| 334 | * NOTE: guaranteeing certain response times might mean we shouldn't | 360 | * NOTE: guaranteeing certain response times might mean we shouldn't |
| 335 | * share keventd's work queue; a realtime task might be safest. | 361 | * share keventd's work queue; a realtime task might be safest. |
| 336 | */ | 362 | */ |
| 337 | void | 363 | static void isp1301_defer_work(struct isp1301 *isp, int work) |
| 338 | isp1301_defer_work(struct isp1301 *isp, int work) | ||
| 339 | { | 364 | { |
| 340 | int status; | 365 | int status; |
| 341 | 366 | ||
| @@ -512,7 +537,6 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) | |||
| 512 | otg_ctrl &= ~OTG_XCEIV_INPUTS; | 537 | otg_ctrl &= ~OTG_XCEIV_INPUTS; |
| 513 | otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); | 538 | otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); |
| 514 | 539 | ||
| 515 | |||
| 516 | if (int_src & INTR_SESS_VLD) | 540 | if (int_src & INTR_SESS_VLD) |
| 517 | otg_ctrl |= OTG_ASESSVLD; | 541 | otg_ctrl |= OTG_ASESSVLD; |
| 518 | else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) { | 542 | else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) { |
| @@ -886,11 +910,11 @@ static int otg_probe(struct platform_device *dev) | |||
| 886 | 910 | ||
| 887 | static int otg_remove(struct platform_device *dev) | 911 | static int otg_remove(struct platform_device *dev) |
| 888 | { | 912 | { |
| 889 | otg_dev = 0; | 913 | otg_dev = NULL; |
| 890 | return 0; | 914 | return 0; |
| 891 | } | 915 | } |
| 892 | 916 | ||
| 893 | struct platform_driver omap_otg_driver = { | 917 | static struct platform_driver omap_otg_driver = { |
| 894 | .probe = otg_probe, | 918 | .probe = otg_probe, |
| 895 | .remove = otg_remove, | 919 | .remove = otg_remove, |
| 896 | .driver = { | 920 | .driver = { |
| @@ -1212,6 +1236,8 @@ static void isp1301_release(struct device *dev) | |||
| 1212 | 1236 | ||
| 1213 | isp = dev_get_drvdata(dev); | 1237 | isp = dev_get_drvdata(dev); |
| 1214 | 1238 | ||
| 1239 | /* FIXME -- not with a "new style" driver, it doesn't!! */ | ||
| 1240 | |||
| 1215 | /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ | 1241 | /* ugly -- i2c hijacks our memory hook to wait_for_completion() */ |
| 1216 | if (isp->i2c_release) | 1242 | if (isp->i2c_release) |
| 1217 | isp->i2c_release(dev); | 1243 | isp->i2c_release(dev); |
| @@ -1233,7 +1259,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c) | |||
| 1233 | otg_unbind(isp); | 1259 | otg_unbind(isp); |
| 1234 | #endif | 1260 | #endif |
| 1235 | if (machine_is_omap_h2()) | 1261 | if (machine_is_omap_h2()) |
| 1236 | omap_free_gpio(2); | 1262 | gpio_free(2); |
| 1237 | 1263 | ||
| 1238 | isp->timer.data = 0; | 1264 | isp->timer.data = 0; |
| 1239 | set_bit(WORK_STOP, &isp->todo); | 1265 | set_bit(WORK_STOP, &isp->todo); |
| @@ -1241,7 +1267,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c) | |||
| 1241 | flush_scheduled_work(); | 1267 | flush_scheduled_work(); |
| 1242 | 1268 | ||
| 1243 | put_device(&i2c->dev); | 1269 | put_device(&i2c->dev); |
| 1244 | the_transceiver = 0; | 1270 | the_transceiver = NULL; |
| 1245 | 1271 | ||
| 1246 | return 0; | 1272 | return 0; |
| 1247 | } | 1273 | } |
| @@ -1295,7 +1321,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) | |||
| 1295 | if (!host) { | 1321 | if (!host) { |
| 1296 | omap_writew(0, OTG_IRQ_EN); | 1322 | omap_writew(0, OTG_IRQ_EN); |
| 1297 | power_down(isp); | 1323 | power_down(isp); |
| 1298 | isp->otg.host = 0; | 1324 | isp->otg.host = NULL; |
| 1299 | return 0; | 1325 | return 0; |
| 1300 | } | 1326 | } |
| 1301 | 1327 | ||
| @@ -1344,7 +1370,9 @@ static int | |||
| 1344 | isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) | 1370 | isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) |
| 1345 | { | 1371 | { |
| 1346 | struct isp1301 *isp = container_of(otg, struct isp1301, otg); | 1372 | struct isp1301 *isp = container_of(otg, struct isp1301, otg); |
| 1373 | #ifndef CONFIG_USB_OTG | ||
| 1347 | u32 l; | 1374 | u32 l; |
| 1375 | #endif | ||
| 1348 | 1376 | ||
| 1349 | if (!otg || isp != the_transceiver) | 1377 | if (!otg || isp != the_transceiver) |
| 1350 | return -ENODEV; | 1378 | return -ENODEV; |
| @@ -1354,7 +1382,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) | |||
| 1354 | if (!isp->otg.default_a) | 1382 | if (!isp->otg.default_a) |
| 1355 | enable_vbus_draw(isp, 0); | 1383 | enable_vbus_draw(isp, 0); |
| 1356 | usb_gadget_vbus_disconnect(isp->otg.gadget); | 1384 | usb_gadget_vbus_disconnect(isp->otg.gadget); |
| 1357 | isp->otg.gadget = 0; | 1385 | isp->otg.gadget = NULL; |
| 1358 | power_down(isp); | 1386 | power_down(isp); |
| 1359 | return 0; | 1387 | return 0; |
| 1360 | } | 1388 | } |
| @@ -1379,7 +1407,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) | |||
| 1379 | power_up(isp); | 1407 | power_up(isp); |
| 1380 | isp->otg.state = OTG_STATE_B_IDLE; | 1408 | isp->otg.state = OTG_STATE_B_IDLE; |
| 1381 | 1409 | ||
| 1382 | if (machine_is_omap_h2()) | 1410 | if (machine_is_omap_h2() || machine_is_omap_h3()) |
| 1383 | isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); | 1411 | isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); |
| 1384 | 1412 | ||
| 1385 | isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, | 1413 | isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, |
| @@ -1499,7 +1527,8 @@ isp1301_start_hnp(struct otg_transceiver *dev) | |||
| 1499 | 1527 | ||
| 1500 | /*-------------------------------------------------------------------------*/ | 1528 | /*-------------------------------------------------------------------------*/ |
| 1501 | 1529 | ||
| 1502 | static int __init isp1301_probe(struct i2c_client *i2c) | 1530 | static int __init |
| 1531 | isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | ||
| 1503 | { | 1532 | { |
| 1504 | int status; | 1533 | int status; |
| 1505 | struct isp1301 *isp; | 1534 | struct isp1301 *isp; |
| @@ -1647,7 +1676,7 @@ module_init(isp_init); | |||
| 1647 | static void __exit isp_exit(void) | 1676 | static void __exit isp_exit(void) |
| 1648 | { | 1677 | { |
| 1649 | if (the_transceiver) | 1678 | if (the_transceiver) |
| 1650 | otg_set_transceiver(0); | 1679 | otg_set_transceiver(NULL); |
| 1651 | i2c_del_driver(&isp1301_driver); | 1680 | i2c_del_driver(&isp1301_driver); |
| 1652 | } | 1681 | } |
| 1653 | module_exit(isp_exit); | 1682 | module_exit(isp_exit); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 5a485c22660a..c6a63f46bc15 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -631,7 +631,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
| 631 | 631 | ||
| 632 | /* detach any active clients. This must be done first, because | 632 | /* detach any active clients. This must be done first, because |
| 633 | * it can fail; in which case we give up. */ | 633 | * it can fail; in which case we give up. */ |
| 634 | list_for_each_entry_safe(client, _n, &adap->clients, list) { | 634 | list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) { |
| 635 | struct i2c_driver *driver; | 635 | struct i2c_driver *driver; |
| 636 | 636 | ||
| 637 | driver = client->driver; | 637 | driver = client->driver; |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 6d7401772a8f..e6857e01d1ba 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
| @@ -669,10 +669,12 @@ config BLK_DEV_CELLEB | |||
| 669 | 669 | ||
| 670 | endif | 670 | endif |
| 671 | 671 | ||
| 672 | # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF | ||
| 672 | config BLK_DEV_IDE_PMAC | 673 | config BLK_DEV_IDE_PMAC |
| 673 | tristate "PowerMac on-board IDE support" | 674 | tristate "PowerMac on-board IDE support" |
| 674 | depends on PPC_PMAC && IDE=y | 675 | depends on PPC_PMAC && IDE=y |
| 675 | select IDE_TIMINGS | 676 | select IDE_TIMINGS |
| 677 | select BLK_DEV_IDEDMA_PCI | ||
| 676 | help | 678 | help |
| 677 | This driver provides support for the on-board IDE controller on | 679 | This driver provides support for the on-board IDE controller on |
| 678 | most of the recent Apple Power Macintoshes and PowerBooks. | 680 | most of the recent Apple Power Macintoshes and PowerBooks. |
| @@ -689,16 +691,6 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST | |||
| 689 | CD-ROM on hda. This option changes this to more natural hda for | 691 | CD-ROM on hda. This option changes this to more natural hda for |
| 690 | hard disk and hdc for CD-ROM. | 692 | hard disk and hdc for CD-ROM. |
| 691 | 693 | ||
| 692 | config BLK_DEV_IDEDMA_PMAC | ||
| 693 | bool "PowerMac IDE DMA support" | ||
| 694 | depends on BLK_DEV_IDE_PMAC | ||
| 695 | select BLK_DEV_IDEDMA_PCI | ||
| 696 | help | ||
| 697 | This option allows the driver for the on-board IDE controller on | ||
| 698 | Power Macintoshes and PowerBooks to use DMA (direct memory access) | ||
| 699 | to transfer data to and from memory. Saying Y is safe and improves | ||
| 700 | performance. | ||
| 701 | |||
| 702 | config BLK_DEV_IDE_AU1XXX | 694 | config BLK_DEV_IDE_AU1XXX |
| 703 | bool "IDE for AMD Alchemy Au1200" | 695 | bool "IDE for AMD Alchemy Au1200" |
| 704 | depends on SOC_AU1200 | 696 | depends on SOC_AU1200 |
| @@ -912,7 +904,7 @@ config BLK_DEV_UMC8672 | |||
| 912 | endif | 904 | endif |
| 913 | 905 | ||
| 914 | config BLK_DEV_IDEDMA | 906 | config BLK_DEV_IDEDMA |
| 915 | def_bool BLK_DEV_IDEDMA_SFF || BLK_DEV_IDEDMA_PMAC || \ | 907 | def_bool BLK_DEV_IDEDMA_SFF || \ |
| 916 | BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA | 908 | BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA |
| 917 | 909 | ||
| 918 | endif # IDE | 910 | endif # IDE |
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index daf9dce39e52..45d2356bb725 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) | 6 | * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) |
| 7 | * May be copied or modified under the terms of the GNU General Public License | 7 | * May be copied or modified under the terms of the GNU General Public License |
| 8 | * Copyright (C) 2002 Alan Cox <alan@redhat.com> | 8 | * Copyright (C) 2002 Alan Cox |
| 9 | * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> | 9 | * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> |
| 10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> | 10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> |
| 11 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 11 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> |
| @@ -591,7 +591,7 @@ static int __init ali15x3_ide_init(void) | |||
| 591 | 591 | ||
| 592 | static void __exit ali15x3_ide_exit(void) | 592 | static void __exit ali15x3_ide_exit(void) |
| 593 | { | 593 | { |
| 594 | return pci_unregister_driver(&alim15x3_pci_driver); | 594 | pci_unregister_driver(&alim15x3_pci_driver); |
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | module_init(ali15x3_ide_init); | 597 | module_init(ali15x3_ide_init); |
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 81ec73134eda..c6bcd3014a29 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * IDE driver for Linux. | 3 | * IDE driver for Linux. |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2000-2002 Vojtech Pavlik | 5 | * Copyright (c) 2000-2002 Vojtech Pavlik |
| 6 | * Copyright (c) 2007 Bartlomiej Zolnierkiewicz | 6 | * Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz |
| 7 | * | 7 | * |
| 8 | * Based on the work of: | 8 | * Based on the work of: |
| 9 | * Andre Hedrick | 9 | * Andre Hedrick |
| @@ -263,6 +263,15 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_ | |||
| 263 | d.udma_mask = ATA_UDMA5; | 263 | d.udma_mask = ATA_UDMA5; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | /* | ||
| 267 | * It seems that on some nVidia controllers using AltStatus | ||
| 268 | * register can be unreliable so default to Status register | ||
| 269 | * if the device is in Compatibility Mode. | ||
| 270 | */ | ||
| 271 | if (dev->vendor == PCI_VENDOR_ID_NVIDIA && | ||
| 272 | ide_pci_is_in_compatibility_mode(dev)) | ||
| 273 | d.host_flags |= IDE_HFLAG_BROKEN_ALTSTATUS; | ||
| 274 | |||
| 266 | printk(KERN_INFO "%s %s: UDMA%s controller\n", | 275 | printk(KERN_INFO "%s %s: UDMA%s controller\n", |
| 267 | d.name, pci_name(dev), amd_dma[fls(d.udma_mask) - 1]); | 276 | d.name, pci_name(dev), amd_dma[fls(d.udma_mask) - 1]); |
| 268 | 277 | ||
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index a7909e9c720e..f5afd46ed51c 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c | |||
| @@ -52,7 +52,7 @@ | |||
| 52 | * different clocks on read/write. This requires overloading rw_disk and | 52 | * different clocks on read/write. This requires overloading rw_disk and |
| 53 | * other deeply crazy things. Thanks to <http://www.hoerstreich.de> for | 53 | * other deeply crazy things. Thanks to <http://www.hoerstreich.de> for |
| 54 | * keeping me sane. | 54 | * keeping me sane. |
| 55 | * Alan Cox <alan@redhat.com> | 55 | * Alan Cox <alan@lxorguk.ukuu.org.uk> |
| 56 | * | 56 | * |
| 57 | * - fix the clock turnaround code: it was writing to the wrong ports when | 57 | * - fix the clock turnaround code: it was writing to the wrong ports when |
| 58 | * called for the secondary channel, caching the current clock mode per- | 58 | * called for the secondary channel, caching the current clock mode per- |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 2d848010499d..81f70caeb40f 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c | |||
| @@ -419,7 +419,7 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, | |||
| 419 | hw->chipset = ide_acorn; | 419 | hw->chipset = ide_acorn; |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | static int __init | 422 | static int __devinit |
| 423 | icside_register_v5(struct icside_state *state, struct expansion_card *ec) | 423 | icside_register_v5(struct icside_state *state, struct expansion_card *ec) |
| 424 | { | 424 | { |
| 425 | void __iomem *base; | 425 | void __iomem *base; |
| @@ -473,7 +473,7 @@ static const struct ide_port_info icside_v6_port_info __initdata = { | |||
| 473 | .swdma_mask = ATA_SWDMA2, | 473 | .swdma_mask = ATA_SWDMA2, |
| 474 | }; | 474 | }; |
| 475 | 475 | ||
| 476 | static int __init | 476 | static int __devinit |
| 477 | icside_register_v6(struct icside_state *state, struct expansion_card *ec) | 477 | icside_register_v6(struct icside_state *state, struct expansion_card *ec) |
| 478 | { | 478 | { |
| 479 | void __iomem *ioc_base, *easi_base; | 479 | void __iomem *ioc_base, *easi_base; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 48b5eda3ab41..42ab6d8715f2 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -1250,7 +1250,8 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
| 1250 | * separate masks. | 1250 | * separate masks. |
| 1251 | */ | 1251 | */ |
| 1252 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; | 1252 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; |
| 1253 | if ((unsigned long)buf & alignment || rq->data_len & alignment | 1253 | if ((unsigned long)buf & alignment |
| 1254 | || rq->data_len & q->dma_pad_mask | ||
| 1254 | || object_is_on_stack(buf)) | 1255 | || object_is_on_stack(buf)) |
| 1255 | drive->dma = 0; | 1256 | drive->dma = 0; |
| 1256 | } | 1257 | } |
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index cb199c815b53..f50210fe558f 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c | |||
| @@ -444,6 +444,7 @@ static struct pcmcia_device_id ide_ids[] = { | |||
| 444 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 444 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
| 445 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 445 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
| 446 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | 446 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), |
| 447 | PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506), | ||
| 447 | PCMCIA_DEVICE_NULL, | 448 | PCMCIA_DEVICE_NULL, |
| 448 | }; | 449 | }; |
| 449 | MODULE_DEVICE_TABLE(pcmcia, ide_ids); | 450 | MODULE_DEVICE_TABLE(pcmcia, ide_ids); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index e5adebe8ac2c..eb9fac4d0f0c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) | 2 | * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) |
| 3 | * Copyright (C) 1998-2002 Linux ATA Development | 3 | * Copyright (C) 1998-2002 Linux ATA Development |
| 4 | * Andre Hedrick <andre@linux-ide.org> | 4 | * Andre Hedrick <andre@linux-ide.org> |
| 5 | * Copyright (C) 2003 Red Hat <alan@redhat.com> | 5 | * Copyright (C) 2003 Red Hat |
| 6 | * Copyright (C) 2003-2005, 2007 Bartlomiej Zolnierkiewicz | 6 | * Copyright (C) 2003-2005, 2007 Bartlomiej Zolnierkiewicz |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 7b6662854374..b8078b3231f7 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c | |||
| @@ -281,7 +281,12 @@ static int ide_gd_media_changed(struct gendisk *disk) | |||
| 281 | static int ide_gd_revalidate_disk(struct gendisk *disk) | 281 | static int ide_gd_revalidate_disk(struct gendisk *disk) |
| 282 | { | 282 | { |
| 283 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | 283 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
| 284 | set_capacity(disk, ide_gd_capacity(idkp->drive)); | 284 | ide_drive_t *drive = idkp->drive; |
| 285 | |||
| 286 | if (ide_gd_media_changed(disk)) | ||
| 287 | drive->disk_ops->get_capacity(drive); | ||
| 288 | |||
| 289 | set_capacity(disk, ide_gd_capacity(drive)); | ||
| 285 | return 0; | 290 | return 0; |
| 286 | } | 291 | } |
| 287 | 292 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 7162d67562af..cc35d6dbd410 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -132,10 +132,14 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) | |||
| 132 | } | 132 | } |
| 133 | EXPORT_SYMBOL(ide_end_request); | 133 | EXPORT_SYMBOL(ide_end_request); |
| 134 | 134 | ||
| 135 | static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) | 135 | static void ide_complete_power_step(ide_drive_t *drive, struct request *rq) |
| 136 | { | 136 | { |
| 137 | struct request_pm_state *pm = rq->data; | 137 | struct request_pm_state *pm = rq->data; |
| 138 | 138 | ||
| 139 | #ifdef DEBUG_PM | ||
| 140 | printk(KERN_INFO "%s: complete_power_step(step: %d)\n", | ||
| 141 | drive->name, pm->pm_step); | ||
| 142 | #endif | ||
| 139 | if (drive->media != ide_disk) | 143 | if (drive->media != ide_disk) |
| 140 | return; | 144 | return; |
| 141 | 145 | ||
| @@ -172,7 +176,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 172 | /* Not supported? Switch to next step now. */ | 176 | /* Not supported? Switch to next step now. */ |
| 173 | if (ata_id_flush_enabled(drive->id) == 0 || | 177 | if (ata_id_flush_enabled(drive->id) == 0 || |
| 174 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { | 178 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { |
| 175 | ide_complete_power_step(drive, rq, 0, 0); | 179 | ide_complete_power_step(drive, rq); |
| 176 | return ide_stopped; | 180 | return ide_stopped; |
| 177 | } | 181 | } |
| 178 | if (ata_id_flush_ext_enabled(drive->id)) | 182 | if (ata_id_flush_ext_enabled(drive->id)) |
| @@ -191,7 +195,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 191 | if (drive->media != ide_disk) | 195 | if (drive->media != ide_disk) |
| 192 | pm->pm_step = IDE_PM_RESTORE_DMA; | 196 | pm->pm_step = IDE_PM_RESTORE_DMA; |
| 193 | else | 197 | else |
| 194 | ide_complete_power_step(drive, rq, 0, 0); | 198 | ide_complete_power_step(drive, rq); |
| 195 | return ide_stopped; | 199 | return ide_stopped; |
| 196 | case IDE_PM_IDLE: /* Resume step 2 (idle) */ | 200 | case IDE_PM_IDLE: /* Resume step 2 (idle) */ |
| 197 | args->tf.command = ATA_CMD_IDLEIMMEDIATE; | 201 | args->tf.command = ATA_CMD_IDLEIMMEDIATE; |
| @@ -322,11 +326,8 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
| 322 | } | 326 | } |
| 323 | } else if (blk_pm_request(rq)) { | 327 | } else if (blk_pm_request(rq)) { |
| 324 | struct request_pm_state *pm = rq->data; | 328 | struct request_pm_state *pm = rq->data; |
| 325 | #ifdef DEBUG_PM | 329 | |
| 326 | printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n", | 330 | ide_complete_power_step(drive, rq); |
| 327 | drive->name, rq->pm->pm_step, stat, err); | ||
| 328 | #endif | ||
| 329 | ide_complete_power_step(drive, rq, stat, err); | ||
| 330 | if (pm->pm_step == IDE_PM_COMPLETED) | 331 | if (pm->pm_step == IDE_PM_COMPLETED) |
| 331 | ide_complete_pm_request(drive, rq); | 332 | ide_complete_pm_request(drive, rq); |
| 332 | return; | 333 | return; |
| @@ -804,7 +805,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
| 804 | struct request_pm_state *pm = rq->data; | 805 | struct request_pm_state *pm = rq->data; |
| 805 | #ifdef DEBUG_PM | 806 | #ifdef DEBUG_PM |
| 806 | printk("%s: start_power_step(step: %d)\n", | 807 | printk("%s: start_power_step(step: %d)\n", |
| 807 | drive->name, rq->pm->pm_step); | 808 | drive->name, pm->pm_step); |
| 808 | #endif | 809 | #endif |
| 809 | startstop = ide_start_power_step(drive, rq); | 810 | startstop = ide_start_power_step(drive, rq); |
| 810 | if (startstop == ide_stopped && | 811 | if (startstop == ide_stopped && |
| @@ -967,14 +968,13 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
| 967 | ide_startstop_t startstop; | 968 | ide_startstop_t startstop; |
| 968 | int loops = 0; | 969 | int loops = 0; |
| 969 | 970 | ||
| 970 | /* for atari only: POSSIBLY BROKEN HERE(?) */ | ||
| 971 | ide_get_lock(ide_intr, hwgroup); | ||
| 972 | |||
| 973 | /* caller must own ide_lock */ | 971 | /* caller must own ide_lock */ |
| 974 | BUG_ON(!irqs_disabled()); | 972 | BUG_ON(!irqs_disabled()); |
| 975 | 973 | ||
| 976 | while (!hwgroup->busy) { | 974 | while (!hwgroup->busy) { |
| 977 | hwgroup->busy = 1; | 975 | hwgroup->busy = 1; |
| 976 | /* for atari only */ | ||
| 977 | ide_get_lock(ide_intr, hwgroup); | ||
| 978 | drive = choose_drive(hwgroup); | 978 | drive = choose_drive(hwgroup); |
| 979 | if (drive == NULL) { | 979 | if (drive == NULL) { |
| 980 | int sleeping = 0; | 980 | int sleeping = 0; |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index bb7a1ed8094e..c41c3b9b6f02 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> | 2 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> |
| 3 | * Copyright (C) 2003 Red Hat <alan@redhat.com> | 3 | * Copyright (C) 2003 Red Hat |
| 4 | * | 4 | * |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| @@ -457,18 +457,14 @@ int drive_is_ready (ide_drive_t *drive) | |||
| 457 | if (drive->waiting_for_dma) | 457 | if (drive->waiting_for_dma) |
| 458 | return hwif->dma_ops->dma_test_irq(drive); | 458 | return hwif->dma_ops->dma_test_irq(drive); |
| 459 | 459 | ||
| 460 | #if 0 | ||
| 461 | /* need to guarantee 400ns since last command was issued */ | ||
| 462 | udelay(1); | ||
| 463 | #endif | ||
| 464 | |||
| 465 | /* | 460 | /* |
| 466 | * We do a passive status test under shared PCI interrupts on | 461 | * We do a passive status test under shared PCI interrupts on |
| 467 | * cards that truly share the ATA side interrupt, but may also share | 462 | * cards that truly share the ATA side interrupt, but may also share |
| 468 | * an interrupt with another pci card/device. We make no assumptions | 463 | * an interrupt with another pci card/device. We make no assumptions |
| 469 | * about possible isa-pnp and pci-pnp issues yet. | 464 | * about possible isa-pnp and pci-pnp issues yet. |
| 470 | */ | 465 | */ |
| 471 | if (hwif->io_ports.ctl_addr) | 466 | if (hwif->io_ports.ctl_addr && |
| 467 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) | ||
| 472 | stat = hwif->tp_ops->read_altstatus(hwif); | 468 | stat = hwif->tp_ops->read_altstatus(hwif); |
| 473 | else | 469 | else |
| 474 | /* Note: this may clear a pending IRQ!! */ | 470 | /* Note: this may clear a pending IRQ!! */ |
| @@ -610,6 +606,7 @@ static const struct drive_list_entry ivb_list[] = { | |||
| 610 | { "TSSTcorp CDDVDW SH-S202N" , "SB01" }, | 606 | { "TSSTcorp CDDVDW SH-S202N" , "SB01" }, |
| 611 | { "TSSTcorp CDDVDW SH-S202H" , "SB00" }, | 607 | { "TSSTcorp CDDVDW SH-S202H" , "SB00" }, |
| 612 | { "TSSTcorp CDDVDW SH-S202H" , "SB01" }, | 608 | { "TSSTcorp CDDVDW SH-S202H" , "SB01" }, |
| 609 | { "SAMSUNG SP0822N" , "WA100-10" }, | ||
| 613 | { NULL , NULL } | 610 | { NULL , NULL } |
| 614 | }; | 611 | }; |
| 615 | 612 | ||
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c index 474f96a7c076..bddae2b329a0 100644 --- a/drivers/ide/ide-pci-generic.c +++ b/drivers/ide/ide-pci-generic.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> | 2 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> |
| 3 | * Portions (C) Copyright 2002 Red Hat Inc <alan@redhat.com> | 3 | * Portions (C) Copyright 2002 Red Hat Inc |
| 4 | * | 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License as published by the | 6 | * under the terms of the GNU General Public License as published by the |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 1649ea54f76c..c55bdbd22314 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -266,7 +266,8 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
| 266 | /* take a deep breath */ | 266 | /* take a deep breath */ |
| 267 | msleep(50); | 267 | msleep(50); |
| 268 | 268 | ||
| 269 | if (io_ports->ctl_addr) { | 269 | if (io_ports->ctl_addr && |
| 270 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { | ||
| 270 | a = tp_ops->read_altstatus(hwif); | 271 | a = tp_ops->read_altstatus(hwif); |
| 271 | s = tp_ops->read_status(hwif); | 272 | s = tp_ops->read_status(hwif); |
| 272 | if ((a ^ s) & ~ATA_IDX) | 273 | if ((a ^ s) & ~ATA_IDX) |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index c31d0dd7a532..f3cddd1b2f8f 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 1997-1998 Mark Lord | 2 | * Copyright (C) 1997-1998 Mark Lord |
| 3 | * Copyright (C) 2003 Red Hat <alan@redhat.com> | 3 | * Copyright (C) 2003 Red Hat |
| 4 | * | 4 | * |
| 5 | * Some code was moved here from ide.c, see it for original copyrights. | 5 | * Some code was moved here from ide.c, see it for original copyrights. |
| 6 | */ | 6 | */ |
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 995e18bb3139..ef004089761b 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2004 Red Hat <alan@redhat.com> | 2 | * Copyright (C) 2004 Red Hat |
| 3 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | 3 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz |
| 4 | * | 4 | * |
| 5 | * May be copied or modified under the terms of the GNU General Public License | 5 | * May be copied or modified under the terms of the GNU General Public License |
diff --git a/drivers/ide/jmicron.c b/drivers/ide/jmicron.c index 9a68433cf46d..bf2be6431b20 100644 --- a/drivers/ide/jmicron.c +++ b/drivers/ide/jmicron.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | ||
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2006 Red Hat <alan@redhat.com> | 3 | * Copyright (C) 2006 Red Hat |
| 4 | * | 4 | * |
| 5 | * May be copied or modified under the terms of the GNU General Public License | 5 | * May be copied or modified under the terms of the GNU General Public License |
| 6 | */ | 6 | */ |
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index d63f9fdca76b..61d2d920a5cd 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer | 2 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer |
| 3 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | 3 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> |
| 4 | * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> | 4 | * Copyright (C) 2003 Red Hat |
| 5 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> | 5 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> |
| 6 | * | 6 | * |
| 7 | * May be copied or modified under the terms of the GNU General Public License | 7 | * May be copied or modified under the terms of the GNU General Public License |
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 2e19d6298536..7c481bb56fab 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c | |||
| @@ -66,7 +66,6 @@ typedef struct pmac_ide_hwif { | |||
| 66 | struct macio_dev *mdev; | 66 | struct macio_dev *mdev; |
| 67 | u32 timings[4]; | 67 | u32 timings[4]; |
| 68 | volatile u32 __iomem * *kauai_fcr; | 68 | volatile u32 __iomem * *kauai_fcr; |
| 69 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 70 | /* Those fields are duplicating what is in hwif. We currently | 69 | /* Those fields are duplicating what is in hwif. We currently |
| 71 | * can't use the hwif ones because of some assumptions that are | 70 | * can't use the hwif ones because of some assumptions that are |
| 72 | * beeing done by the generic code about the kind of dma controller | 71 | * beeing done by the generic code about the kind of dma controller |
| @@ -74,8 +73,6 @@ typedef struct pmac_ide_hwif { | |||
| 74 | */ | 73 | */ |
| 75 | volatile struct dbdma_regs __iomem * dma_regs; | 74 | volatile struct dbdma_regs __iomem * dma_regs; |
| 76 | struct dbdma_cmd* dma_table_cpu; | 75 | struct dbdma_cmd* dma_table_cpu; |
| 77 | #endif | ||
| 78 | |||
| 79 | } pmac_ide_hwif_t; | 76 | } pmac_ide_hwif_t; |
| 80 | 77 | ||
| 81 | enum { | 78 | enum { |
| @@ -222,8 +219,6 @@ static const char* model_name[] = { | |||
| 222 | #define KAUAI_FCR_UATA_RESET_N 0x00000002 | 219 | #define KAUAI_FCR_UATA_RESET_N 0x00000002 |
| 223 | #define KAUAI_FCR_UATA_ENABLE 0x00000001 | 220 | #define KAUAI_FCR_UATA_ENABLE 0x00000001 |
| 224 | 221 | ||
| 225 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 226 | |||
| 227 | /* Rounded Multiword DMA timings | 222 | /* Rounded Multiword DMA timings |
| 228 | * | 223 | * |
| 229 | * I gave up finding a generic formula for all controller | 224 | * I gave up finding a generic formula for all controller |
| @@ -413,8 +408,6 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq); | |||
| 413 | static void pmac_ide_selectproc(ide_drive_t *drive); | 408 | static void pmac_ide_selectproc(ide_drive_t *drive); |
| 414 | static void pmac_ide_kauai_selectproc(ide_drive_t *drive); | 409 | static void pmac_ide_kauai_selectproc(ide_drive_t *drive); |
| 415 | 410 | ||
| 416 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | ||
| 417 | |||
| 418 | #define PMAC_IDE_REG(x) \ | 411 | #define PMAC_IDE_REG(x) \ |
| 419 | ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x))) | 412 | ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x))) |
| 420 | 413 | ||
| @@ -584,8 +577,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 584 | pmac_ide_do_update_timings(drive); | 577 | pmac_ide_do_update_timings(drive); |
| 585 | } | 578 | } |
| 586 | 579 | ||
| 587 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 588 | |||
| 589 | /* | 580 | /* |
| 590 | * Calculate KeyLargo ATA/66 UDMA timings | 581 | * Calculate KeyLargo ATA/66 UDMA timings |
| 591 | */ | 582 | */ |
| @@ -786,7 +777,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, | |||
| 786 | drive->name, speed & 0xf, *timings); | 777 | drive->name, speed & 0xf, *timings); |
| 787 | #endif | 778 | #endif |
| 788 | } | 779 | } |
| 789 | #endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */ | ||
| 790 | 780 | ||
| 791 | static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) | 781 | static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) |
| 792 | { | 782 | { |
| @@ -804,7 +794,6 @@ static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 804 | tl[0] = *timings; | 794 | tl[0] = *timings; |
| 805 | tl[1] = *timings2; | 795 | tl[1] = *timings2; |
| 806 | 796 | ||
| 807 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 808 | if (speed >= XFER_UDMA_0) { | 797 | if (speed >= XFER_UDMA_0) { |
| 809 | if (pmif->kind == controller_kl_ata4) | 798 | if (pmif->kind == controller_kl_ata4) |
| 810 | ret = set_timings_udma_ata4(&tl[0], speed); | 799 | ret = set_timings_udma_ata4(&tl[0], speed); |
| @@ -817,7 +806,7 @@ static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 817 | ret = -1; | 806 | ret = -1; |
| 818 | } else | 807 | } else |
| 819 | set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed); | 808 | set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed); |
| 820 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 809 | |
| 821 | if (ret) | 810 | if (ret) |
| 822 | return; | 811 | return; |
| 823 | 812 | ||
| @@ -1008,9 +997,7 @@ static const struct ide_port_info pmac_port_info = { | |||
| 1008 | .chipset = ide_pmac, | 997 | .chipset = ide_pmac, |
| 1009 | .tp_ops = &pmac_tp_ops, | 998 | .tp_ops = &pmac_tp_ops, |
| 1010 | .port_ops = &pmac_ide_port_ops, | 999 | .port_ops = &pmac_ide_port_ops, |
| 1011 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 1012 | .dma_ops = &pmac_dma_ops, | 1000 | .dma_ops = &pmac_dma_ops, |
| 1013 | #endif | ||
| 1014 | .host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | | 1001 | .host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | |
| 1015 | IDE_HFLAG_POST_SET_MODE | | 1002 | IDE_HFLAG_POST_SET_MODE | |
| 1016 | IDE_HFLAG_MMIO | | 1003 | IDE_HFLAG_MMIO | |
| @@ -1182,7 +1169,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
| 1182 | pmif->regbase = regbase; | 1169 | pmif->regbase = regbase; |
| 1183 | pmif->irq = irq; | 1170 | pmif->irq = irq; |
| 1184 | pmif->kauai_fcr = NULL; | 1171 | pmif->kauai_fcr = NULL; |
| 1185 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | 1172 | |
| 1186 | if (macio_resource_count(mdev) >= 2) { | 1173 | if (macio_resource_count(mdev) >= 2) { |
| 1187 | if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) | 1174 | if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) |
| 1188 | printk(KERN_WARNING "ide-pmac: can't request DMA " | 1175 | printk(KERN_WARNING "ide-pmac: can't request DMA " |
| @@ -1192,7 +1179,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
| 1192 | pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); | 1179 | pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); |
| 1193 | } else | 1180 | } else |
| 1194 | pmif->dma_regs = NULL; | 1181 | pmif->dma_regs = NULL; |
| 1195 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 1182 | |
| 1196 | dev_set_drvdata(&mdev->ofdev.dev, pmif); | 1183 | dev_set_drvdata(&mdev->ofdev.dev, pmif); |
| 1197 | 1184 | ||
| 1198 | memset(&hw, 0, sizeof(hw)); | 1185 | memset(&hw, 0, sizeof(hw)); |
| @@ -1300,9 +1287,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1300 | 1287 | ||
| 1301 | base = ioremap(rbase, rlen); | 1288 | base = ioremap(rbase, rlen); |
| 1302 | pmif->regbase = (unsigned long) base + 0x2000; | 1289 | pmif->regbase = (unsigned long) base + 0x2000; |
| 1303 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 1304 | pmif->dma_regs = base + 0x1000; | 1290 | pmif->dma_regs = base + 0x1000; |
| 1305 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | ||
| 1306 | pmif->kauai_fcr = base; | 1291 | pmif->kauai_fcr = base; |
| 1307 | pmif->irq = pdev->irq; | 1292 | pmif->irq = pdev->irq; |
| 1308 | 1293 | ||
| @@ -1434,8 +1419,6 @@ out: | |||
| 1434 | return error; | 1419 | return error; |
| 1435 | } | 1420 | } |
| 1436 | 1421 | ||
| 1437 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
| 1438 | |||
| 1439 | /* | 1422 | /* |
| 1440 | * pmac_ide_build_dmatable builds the DBDMA command list | 1423 | * pmac_ide_build_dmatable builds the DBDMA command list |
| 1441 | * for a transfer and sets the DBDMA channel to point to it. | 1424 | * for a transfer and sets the DBDMA channel to point to it. |
| @@ -1723,13 +1706,6 @@ static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif, | |||
| 1723 | 1706 | ||
| 1724 | return 0; | 1707 | return 0; |
| 1725 | } | 1708 | } |
| 1726 | #else | ||
| 1727 | static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif, | ||
| 1728 | const struct ide_port_info *d) | ||
| 1729 | { | ||
| 1730 | return -EOPNOTSUPP; | ||
| 1731 | } | ||
| 1732 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | ||
| 1733 | 1709 | ||
| 1734 | module_init(pmac_ide_probe); | 1710 | module_init(pmac_ide_probe); |
| 1735 | 1711 | ||
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c index f26aa5d54efb..0f48f9dacfa5 100644 --- a/drivers/ide/scc_pata.c +++ b/drivers/ide/scc_pata.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * This code is based on drivers/ide/pci/siimage.c: | 6 | * This code is based on drivers/ide/pci/siimage.c: |
| 7 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> | 7 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> |
| 8 | * Copyright (C) 2003 Red Hat <alan@redhat.com> | 8 | * Copyright (C) 2003 Red Hat |
| 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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c index 7defa0ae2014..a687a7dfea6f 100644 --- a/drivers/ide/sgiioc4.c +++ b/drivers/ide/sgiioc4.c | |||
| @@ -550,7 +550,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = { | |||
| 550 | .dma_timeout = ide_dma_timeout, | 550 | .dma_timeout = ide_dma_timeout, |
| 551 | }; | 551 | }; |
| 552 | 552 | ||
| 553 | static const struct ide_port_info sgiioc4_port_info __devinitdata = { | 553 | static const struct ide_port_info sgiioc4_port_info __devinitconst = { |
| 554 | .name = DRV_NAME, | 554 | .name = DRV_NAME, |
| 555 | .chipset = ide_pci, | 555 | .chipset = ide_pci, |
| 556 | .init_dma = ide_dma_sgiioc4, | 556 | .init_dma = ide_dma_sgiioc4, |
| @@ -633,7 +633,7 @@ out: | |||
| 633 | return ret; | 633 | return ret; |
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | int | 636 | int __devinit |
| 637 | ioc4_ide_attach_one(struct ioc4_driver_data *idd) | 637 | ioc4_ide_attach_one(struct ioc4_driver_data *idd) |
| 638 | { | 638 | { |
| 639 | /* PCI-RT does not bring out IDE connection. | 639 | /* PCI-RT does not bring out IDE connection. |
| @@ -645,7 +645,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd) | |||
| 645 | return pci_init_sgiioc4(idd->idd_pdev); | 645 | return pci_init_sgiioc4(idd->idd_pdev); |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | static struct ioc4_submodule ioc4_ide_submodule = { | 648 | static struct ioc4_submodule __devinitdata ioc4_ide_submodule = { |
| 649 | .is_name = "IOC4_ide", | 649 | .is_name = "IOC4_ide", |
| 650 | .is_owner = THIS_MODULE, | 650 | .is_owner = THIS_MODULE, |
| 651 | .is_probe = ioc4_ide_attach_one, | 651 | .is_probe = ioc4_ide_attach_one, |
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c index c3107df7773d..7d622d20bc4c 100644 --- a/drivers/ide/siimage.c +++ b/drivers/ide/siimage.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> | 2 | * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> |
| 3 | * Copyright (C) 2003 Red Hat <alan@redhat.com> | 3 | * Copyright (C) 2003 Red Hat |
| 4 | * Copyright (C) 2007-2008 MontaVista Software, Inc. | 4 | * Copyright (C) 2007-2008 MontaVista Software, Inc. |
| 5 | * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz | 5 | * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz |
| 6 | * | 6 | * |
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index fa660f931a11..9120063e8f87 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c | |||
| @@ -26,12 +26,13 @@ static void tx4938ide_tune_ebusc(unsigned int ebus_ch, | |||
| 26 | unsigned int sp = (cr >> 4) & 3; | 26 | unsigned int sp = (cr >> 4) & 3; |
| 27 | unsigned int clock = gbus_clock / (4 - sp); | 27 | unsigned int clock = gbus_clock / (4 - sp); |
| 28 | unsigned int cycle = 1000000000 / clock; | 28 | unsigned int cycle = 1000000000 / clock; |
| 29 | unsigned int wt, shwt; | 29 | unsigned int shwt; |
| 30 | int wt; | ||
| 30 | 31 | ||
| 31 | /* Minimum DIOx- active time */ | 32 | /* Minimum DIOx- active time */ |
| 32 | wt = DIV_ROUND_UP(t->act8b, cycle) - 2; | 33 | wt = DIV_ROUND_UP(t->act8b, cycle) - 2; |
| 33 | /* IORDY setup time: 35ns */ | 34 | /* IORDY setup time: 35ns */ |
| 34 | wt = max(wt, DIV_ROUND_UP(35, cycle)); | 35 | wt = max_t(int, wt, DIV_ROUND_UP(35, cycle)); |
| 35 | /* actual wait-cycle is max(wt & ~1, 1) */ | 36 | /* actual wait-cycle is max(wt & ~1, 1) */ |
| 36 | if (wt > 2 && (wt & 1)) | 37 | if (wt > 2 && (wt & 1)) |
| 37 | wt++; | 38 | wt++; |
| @@ -39,10 +40,17 @@ static void tx4938ide_tune_ebusc(unsigned int ebus_ch, | |||
| 39 | /* Address-valid to DIOR/DIOW setup */ | 40 | /* Address-valid to DIOR/DIOW setup */ |
| 40 | shwt = DIV_ROUND_UP(t->setup, cycle); | 41 | shwt = DIV_ROUND_UP(t->setup, cycle); |
| 41 | 42 | ||
| 43 | /* -DIOx recovery time (SHWT * 4) and cycle time requirement */ | ||
| 44 | while ((shwt * 4 + wt + (wt ? 2 : 3)) * cycle < t->cycle) | ||
| 45 | shwt++; | ||
| 46 | if (shwt > 7) { | ||
| 47 | pr_warning("tx4938ide: SHWT violation (%d)\n", shwt); | ||
| 48 | shwt = 7; | ||
| 49 | } | ||
| 42 | pr_debug("tx4938ide: ebus %d, bus cycle %dns, WT %d, SHWT %d\n", | 50 | pr_debug("tx4938ide: ebus %d, bus cycle %dns, WT %d, SHWT %d\n", |
| 43 | ebus_ch, cycle, wt, shwt); | 51 | ebus_ch, cycle, wt, shwt); |
| 44 | 52 | ||
| 45 | __raw_writeq((cr & ~(0x3f007ull)) | (wt << 12) | shwt, | 53 | __raw_writeq((cr & ~0x3f007ull) | (wt << 12) | shwt, |
| 46 | &tx4938_ebuscptr->cr[ebus_ch]); | 54 | &tx4938_ebuscptr->cr[ebus_ch]); |
| 47 | } | 55 | } |
| 48 | 56 | ||
| @@ -228,7 +236,7 @@ static int __init tx4938ide_probe(struct platform_device *pdev) | |||
| 228 | struct resource *res; | 236 | struct resource *res; |
| 229 | struct tx4938ide_platform_info *pdata = pdev->dev.platform_data; | 237 | struct tx4938ide_platform_info *pdata = pdev->dev.platform_data; |
| 230 | int irq, ret, i; | 238 | int irq, ret, i; |
| 231 | unsigned long mapbase; | 239 | unsigned long mapbase, mapctl; |
| 232 | struct ide_port_info d = tx4938ide_port_info; | 240 | struct ide_port_info d = tx4938ide_port_info; |
| 233 | 241 | ||
| 234 | irq = platform_get_irq(pdev, 0); | 242 | irq = platform_get_irq(pdev, 0); |
| @@ -242,38 +250,43 @@ static int __init tx4938ide_probe(struct platform_device *pdev) | |||
| 242 | res->end - res->start + 1, "tx4938ide")) | 250 | res->end - res->start + 1, "tx4938ide")) |
| 243 | return -EBUSY; | 251 | return -EBUSY; |
| 244 | mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start, | 252 | mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start, |
| 245 | res->end - res->start + 1); | 253 | 8 << pdata->ioport_shift); |
| 246 | if (!mapbase) | 254 | mapctl = (unsigned long)devm_ioremap(&pdev->dev, |
| 255 | res->start + 0x10000 + | ||
| 256 | (6 << pdata->ioport_shift), | ||
| 257 | 1 << pdata->ioport_shift); | ||
| 258 | if (!mapbase || !mapctl) | ||
| 247 | return -EBUSY; | 259 | return -EBUSY; |
| 248 | 260 | ||
| 249 | memset(&hw, 0, sizeof(hw)); | 261 | memset(&hw, 0, sizeof(hw)); |
| 250 | if (pdata->ioport_shift) { | 262 | if (pdata->ioport_shift) { |
| 251 | unsigned long port = mapbase; | 263 | unsigned long port = mapbase; |
| 264 | unsigned long ctl = mapctl; | ||
| 252 | 265 | ||
| 253 | hw.io_ports_array[0] = port; | 266 | hw.io_ports_array[0] = port; |
| 254 | #ifdef __BIG_ENDIAN | 267 | #ifdef __BIG_ENDIAN |
| 255 | port++; | 268 | port++; |
| 269 | ctl++; | ||
| 256 | #endif | 270 | #endif |
| 257 | for (i = 1; i <= 7; i++) | 271 | for (i = 1; i <= 7; i++) |
| 258 | hw.io_ports_array[i] = | 272 | hw.io_ports_array[i] = |
| 259 | port + (i << pdata->ioport_shift); | 273 | port + (i << pdata->ioport_shift); |
| 260 | hw.io_ports.ctl_addr = | 274 | hw.io_ports.ctl_addr = ctl; |
| 261 | port + 0x10000 + (6 << pdata->ioport_shift); | ||
| 262 | } else | 275 | } else |
| 263 | ide_std_init_ports(&hw, mapbase, mapbase + 0x10006); | 276 | ide_std_init_ports(&hw, mapbase, mapctl); |
| 264 | hw.irq = irq; | 277 | hw.irq = irq; |
| 265 | hw.dev = &pdev->dev; | 278 | hw.dev = &pdev->dev; |
| 266 | 279 | ||
| 267 | pr_info("TX4938 IDE interface (base %#lx, irq %d)\n", mapbase, hw.irq); | 280 | pr_info("TX4938 IDE interface (base %#lx, ctl %#lx, irq %d)\n", |
| 281 | mapbase, mapctl, hw.irq); | ||
| 268 | if (pdata->gbus_clock) | 282 | if (pdata->gbus_clock) |
| 269 | tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, 0); | 283 | tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, 0); |
| 270 | else | 284 | else |
| 271 | d.port_ops = NULL; | 285 | d.port_ops = NULL; |
| 272 | ret = ide_host_add(&d, hws, &host); | 286 | ret = ide_host_add(&d, hws, &host); |
| 273 | if (ret) | 287 | if (!ret) |
| 274 | return ret; | 288 | platform_set_drvdata(pdev, host); |
| 275 | platform_set_drvdata(pdev, host); | 289 | return ret; |
| 276 | return 0; | ||
| 277 | } | 290 | } |
| 278 | 291 | ||
| 279 | static int __exit tx4938ide_remove(struct platform_device *pdev) | 292 | static int __exit tx4938ide_remove(struct platform_device *pdev) |
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig index 108264de0ac9..f15e90a453d1 100644 --- a/drivers/idle/Kconfig +++ b/drivers/idle/Kconfig | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | 1 | ||
| 2 | menu "Memory power savings" | 2 | menu "Memory power savings" |
| 3 | depends on X86_64 | ||
| 3 | 4 | ||
| 4 | config I7300_IDLE_IOAT_CHANNEL | 5 | config I7300_IDLE_IOAT_CHANNEL |
| 5 | bool | 6 | bool |
| @@ -7,7 +8,7 @@ config I7300_IDLE_IOAT_CHANNEL | |||
| 7 | config I7300_IDLE | 8 | config I7300_IDLE |
| 8 | tristate "Intel chipset idle memory power saving driver" | 9 | tristate "Intel chipset idle memory power saving driver" |
| 9 | select I7300_IDLE_IOAT_CHANNEL | 10 | select I7300_IDLE_IOAT_CHANNEL |
| 10 | depends on X86_64 && EXPERIMENTAL | 11 | depends on EXPERIMENTAL |
| 11 | help | 12 | help |
| 12 | Enable memory power savings when idle with certain Intel server | 13 | Enable memory power savings when idle with certain Intel server |
| 13 | chipsets. The chipset must have I/O AT support, such as the | 14 | chipsets. The chipset must have I/O AT support, such as the |
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 2f83543a9dfc..c19f23267157 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c | |||
| @@ -1270,8 +1270,14 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1270 | struct video_card *video = file_to_video_card(file); | 1270 | struct video_card *video = file_to_video_card(file); |
| 1271 | int retval = -EINVAL; | 1271 | int retval = -EINVAL; |
| 1272 | 1272 | ||
| 1273 | /* serialize mmap */ | 1273 | /* |
| 1274 | mutex_lock(&video->mtx); | 1274 | * We cannot use the blocking variant mutex_lock here because .mmap |
| 1275 | * is called with mmap_sem held, while .ioctl, .read, .write acquire | ||
| 1276 | * video->mtx and subsequently call copy_to/from_user which will | ||
| 1277 | * grab mmap_sem in case of a page fault. | ||
| 1278 | */ | ||
| 1279 | if (!mutex_trylock(&video->mtx)) | ||
| 1280 | return -EAGAIN; | ||
| 1275 | 1281 | ||
| 1276 | if ( ! video_card_initialized(video) ) { | 1282 | if ( ! video_card_initialized(video) ) { |
| 1277 | retval = do_dv1394_init_default(video); | 1283 | retval = do_dv1394_init_default(video); |
| @@ -1828,9 +1834,6 @@ static int dv1394_release(struct inode *inode, struct file *file) | |||
| 1828 | /* OK to free the DMA buffer, no more mappings can exist */ | 1834 | /* OK to free the DMA buffer, no more mappings can exist */ |
| 1829 | do_dv1394_shutdown(video, 1); | 1835 | do_dv1394_shutdown(video, 1); |
| 1830 | 1836 | ||
| 1831 | /* clean up async I/O users */ | ||
| 1832 | dv1394_fasync(-1, file, 0); | ||
| 1833 | |||
| 1834 | /* give someone else a turn */ | 1837 | /* give someone else a turn */ |
| 1835 | clear_bit(0, &video->open); | 1838 | clear_bit(0, &video->open); |
| 1836 | 1839 | ||
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c index 918ffc4fc8ac..272543a42a43 100644 --- a/drivers/ieee1394/highlevel.c +++ b/drivers/ieee1394/highlevel.c | |||
| @@ -46,10 +46,6 @@ static DEFINE_RWLOCK(hl_irqs_lock); | |||
| 46 | 46 | ||
| 47 | static DEFINE_RWLOCK(addr_space_lock); | 47 | static DEFINE_RWLOCK(addr_space_lock); |
| 48 | 48 | ||
| 49 | /* addr_space list will have zero and max already included as bounds */ | ||
| 50 | static struct hpsb_address_ops dummy_ops = { NULL, NULL, NULL, NULL }; | ||
| 51 | static struct hpsb_address_serve dummy_zero_addr, dummy_max_addr; | ||
| 52 | |||
| 53 | 49 | ||
| 54 | static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl, | 50 | static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl, |
| 55 | struct hpsb_host *host) | 51 | struct hpsb_host *host) |
| @@ -481,20 +477,23 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, | |||
| 481 | return retval; | 477 | return retval; |
| 482 | } | 478 | } |
| 483 | 479 | ||
| 480 | static struct hpsb_address_ops dummy_ops; | ||
| 481 | |||
| 482 | /* dummy address spaces as lower and upper bounds of the host's a.s. list */ | ||
| 484 | static void init_hpsb_highlevel(struct hpsb_host *host) | 483 | static void init_hpsb_highlevel(struct hpsb_host *host) |
| 485 | { | 484 | { |
| 486 | INIT_LIST_HEAD(&dummy_zero_addr.host_list); | 485 | INIT_LIST_HEAD(&host->dummy_zero_addr.host_list); |
| 487 | INIT_LIST_HEAD(&dummy_zero_addr.hl_list); | 486 | INIT_LIST_HEAD(&host->dummy_zero_addr.hl_list); |
| 488 | INIT_LIST_HEAD(&dummy_max_addr.host_list); | 487 | INIT_LIST_HEAD(&host->dummy_max_addr.host_list); |
| 489 | INIT_LIST_HEAD(&dummy_max_addr.hl_list); | 488 | INIT_LIST_HEAD(&host->dummy_max_addr.hl_list); |
| 490 | 489 | ||
| 491 | dummy_zero_addr.op = dummy_max_addr.op = &dummy_ops; | 490 | host->dummy_zero_addr.op = host->dummy_max_addr.op = &dummy_ops; |
| 492 | 491 | ||
| 493 | dummy_zero_addr.start = dummy_zero_addr.end = 0; | 492 | host->dummy_zero_addr.start = host->dummy_zero_addr.end = 0; |
| 494 | dummy_max_addr.start = dummy_max_addr.end = ((u64) 1) << 48; | 493 | host->dummy_max_addr.start = host->dummy_max_addr.end = ((u64) 1) << 48; |
| 495 | 494 | ||
| 496 | list_add_tail(&dummy_zero_addr.host_list, &host->addr_space); | 495 | list_add_tail(&host->dummy_zero_addr.host_list, &host->addr_space); |
| 497 | list_add_tail(&dummy_max_addr.host_list, &host->addr_space); | 496 | list_add_tail(&host->dummy_max_addr.host_list, &host->addr_space); |
| 498 | } | 497 | } |
| 499 | 498 | ||
| 500 | void highlevel_add_host(struct hpsb_host *host) | 499 | void highlevel_add_host(struct hpsb_host *host) |
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 8dd09d850419..237d0c9d69c6 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c | |||
| @@ -155,11 +155,11 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
| 155 | memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); | 155 | memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); |
| 156 | h->device.parent = dev; | 156 | h->device.parent = dev; |
| 157 | set_dev_node(&h->device, dev_to_node(dev)); | 157 | set_dev_node(&h->device, dev_to_node(dev)); |
| 158 | snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); | 158 | dev_set_name(&h->device, "fw-host%d", h->id); |
| 159 | 159 | ||
| 160 | h->host_dev.parent = &h->device; | 160 | h->host_dev.parent = &h->device; |
| 161 | h->host_dev.class = &hpsb_host_class; | 161 | h->host_dev.class = &hpsb_host_class; |
| 162 | snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); | 162 | dev_set_name(&h->host_dev, "fw-host%d", h->id); |
| 163 | 163 | ||
| 164 | if (device_register(&h->device)) | 164 | if (device_register(&h->device)) |
| 165 | goto fail; | 165 | goto fail; |
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index e4e8aeb4d778..dd229950acca 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h | |||
| @@ -13,6 +13,7 @@ struct module; | |||
| 13 | 13 | ||
| 14 | #include "ieee1394_types.h" | 14 | #include "ieee1394_types.h" |
| 15 | #include "csr.h" | 15 | #include "csr.h" |
| 16 | #include "highlevel.h" | ||
| 16 | 17 | ||
| 17 | struct hpsb_packet; | 18 | struct hpsb_packet; |
| 18 | struct hpsb_iso; | 19 | struct hpsb_iso; |
| @@ -72,6 +73,9 @@ struct hpsb_host { | |||
| 72 | struct { DECLARE_BITMAP(map, 64); } tl_pool[ALL_NODES]; | 73 | struct { DECLARE_BITMAP(map, 64); } tl_pool[ALL_NODES]; |
| 73 | 74 | ||
| 74 | struct csr_control csr; | 75 | struct csr_control csr; |
| 76 | |||
| 77 | struct hpsb_address_serve dummy_zero_addr; | ||
| 78 | struct hpsb_address_serve dummy_max_addr; | ||
| 75 | }; | 79 | }; |
| 76 | 80 | ||
| 77 | enum devctl_cmd { | 81 | enum devctl_cmd { |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 2376b729e876..d333ae22459c 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
| @@ -826,13 +826,11 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, | |||
| 826 | memcpy(&ne->device, &nodemgr_dev_template_ne, | 826 | memcpy(&ne->device, &nodemgr_dev_template_ne, |
| 827 | sizeof(ne->device)); | 827 | sizeof(ne->device)); |
| 828 | ne->device.parent = &host->device; | 828 | ne->device.parent = &host->device; |
| 829 | snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", | 829 | dev_set_name(&ne->device, "%016Lx", (unsigned long long)(ne->guid)); |
| 830 | (unsigned long long)(ne->guid)); | ||
| 831 | 830 | ||
| 832 | ne->node_dev.parent = &ne->device; | 831 | ne->node_dev.parent = &ne->device; |
| 833 | ne->node_dev.class = &nodemgr_ne_class; | 832 | ne->node_dev.class = &nodemgr_ne_class; |
| 834 | snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx", | 833 | dev_set_name(&ne->node_dev, "%016Lx", (unsigned long long)(ne->guid)); |
| 835 | (unsigned long long)(ne->guid)); | ||
| 836 | 834 | ||
| 837 | if (device_register(&ne->device)) | 835 | if (device_register(&ne->device)) |
| 838 | goto fail_devreg; | 836 | goto fail_devreg; |
| @@ -932,13 +930,11 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
| 932 | 930 | ||
| 933 | ud->device.parent = parent; | 931 | ud->device.parent = parent; |
| 934 | 932 | ||
| 935 | snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", | 933 | dev_set_name(&ud->device, "%s-%u", dev_name(&ne->device), ud->id); |
| 936 | ne->device.bus_id, ud->id); | ||
| 937 | 934 | ||
| 938 | ud->unit_dev.parent = &ud->device; | 935 | ud->unit_dev.parent = &ud->device; |
| 939 | ud->unit_dev.class = &nodemgr_ud_class; | 936 | ud->unit_dev.class = &nodemgr_ud_class; |
| 940 | snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u", | 937 | dev_set_name(&ud->unit_dev, "%s-%u", dev_name(&ne->device), ud->id); |
| 941 | ne->device.bus_id, ud->id); | ||
| 942 | 938 | ||
| 943 | if (device_register(&ud->device)) | 939 | if (device_register(&ud->device)) |
| 944 | goto fail_devreg; | 940 | goto fail_devreg; |
| @@ -953,7 +949,7 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
| 953 | fail_classdevreg: | 949 | fail_classdevreg: |
| 954 | device_unregister(&ud->device); | 950 | device_unregister(&ud->device); |
| 955 | fail_devreg: | 951 | fail_devreg: |
| 956 | HPSB_ERR("Failed to create unit %s", ud->device.bus_id); | 952 | HPSB_ERR("Failed to create unit %s", dev_name(&ud->device)); |
| 957 | } | 953 | } |
| 958 | 954 | ||
| 959 | 955 | ||
| @@ -1689,6 +1685,7 @@ static int nodemgr_host_thread(void *data) | |||
| 1689 | g = get_hpsb_generation(host); | 1685 | g = get_hpsb_generation(host); |
| 1690 | for (i = 0; i < 4 ; i++) { | 1686 | for (i = 0; i < 4 ; i++) { |
| 1691 | msleep_interruptible(63); | 1687 | msleep_interruptible(63); |
| 1688 | try_to_freeze(); | ||
| 1692 | if (kthread_should_stop()) | 1689 | if (kthread_should_stop()) |
| 1693 | goto exit; | 1690 | goto exit; |
| 1694 | 1691 | ||
| @@ -1729,6 +1726,7 @@ static int nodemgr_host_thread(void *data) | |||
| 1729 | /* Sleep 3 seconds */ | 1726 | /* Sleep 3 seconds */ |
| 1730 | for (i = 3000/200; i; i--) { | 1727 | for (i = 3000/200; i; i--) { |
| 1731 | msleep_interruptible(200); | 1728 | msleep_interruptible(200); |
| 1729 | try_to_freeze(); | ||
| 1732 | if (kthread_should_stop()) | 1730 | if (kthread_should_stop()) |
| 1733 | goto exit; | 1731 | goto exit; |
| 1734 | 1732 | ||
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 9f19ac492106..bf7e761c12b1 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
| @@ -2268,7 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, | |||
| 2268 | return -EFAULT; | 2268 | return -EFAULT; |
| 2269 | } | 2269 | } |
| 2270 | 2270 | ||
| 2271 | mutex_lock(&fi->state_mutex); | 2271 | if (!mutex_trylock(&fi->state_mutex)) |
| 2272 | return -EAGAIN; | ||
| 2272 | 2273 | ||
| 2273 | switch (fi->state) { | 2274 | switch (fi->state) { |
| 2274 | case opened: | 2275 | case opened: |
| @@ -2548,7 +2549,8 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 2548 | struct file_info *fi = file->private_data; | 2549 | struct file_info *fi = file->private_data; |
| 2549 | int ret; | 2550 | int ret; |
| 2550 | 2551 | ||
| 2551 | mutex_lock(&fi->state_mutex); | 2552 | if (!mutex_trylock(&fi->state_mutex)) |
| 2553 | return -EAGAIN; | ||
| 2552 | 2554 | ||
| 2553 | if (fi->iso_state == RAW1394_ISO_INACTIVE) | 2555 | if (fi->iso_state == RAW1394_ISO_INACTIVE) |
| 2554 | ret = -EINVAL; | 2556 | ret = -EINVAL; |
| @@ -2669,7 +2671,8 @@ static long raw1394_ioctl(struct file *file, unsigned int cmd, | |||
| 2669 | break; | 2671 | break; |
| 2670 | } | 2672 | } |
| 2671 | 2673 | ||
| 2672 | mutex_lock(&fi->state_mutex); | 2674 | if (!mutex_trylock(&fi->state_mutex)) |
| 2675 | return -EAGAIN; | ||
| 2673 | 2676 | ||
| 2674 | switch (fi->iso_state) { | 2677 | switch (fi->iso_state) { |
| 2675 | case RAW1394_ISO_INACTIVE: | 2678 | case RAW1394_ISO_INACTIVE: |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index c52f6e6e8af2..a373c18cf7b8 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
| @@ -402,6 +402,11 @@ static const struct { | |||
| 402 | }, | 402 | }, |
| 403 | /* iPod mini */ { | 403 | /* iPod mini */ { |
| 404 | .firmware_revision = 0x0a2700, | 404 | .firmware_revision = 0x0a2700, |
| 405 | .model_id = 0x000022, | ||
| 406 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | ||
| 407 | }, | ||
| 408 | /* iPod mini */ { | ||
| 409 | .firmware_revision = 0x0a2700, | ||
| 405 | .model_id = 0x000023, | 410 | .model_id = 0x000023, |
| 406 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, | 411 | .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, |
| 407 | }, | 412 | }, |
| @@ -890,12 +895,13 @@ static void sbp2_host_reset(struct hpsb_host *host) | |||
| 890 | return; | 895 | return; |
| 891 | 896 | ||
| 892 | read_lock_irqsave(&sbp2_hi_logical_units_lock, flags); | 897 | read_lock_irqsave(&sbp2_hi_logical_units_lock, flags); |
| 898 | |||
| 893 | list_for_each_entry(lu, &hi->logical_units, lu_list) | 899 | list_for_each_entry(lu, &hi->logical_units, lu_list) |
| 894 | if (likely(atomic_read(&lu->state) != | 900 | if (atomic_cmpxchg(&lu->state, |
| 895 | SBP2LU_STATE_IN_SHUTDOWN)) { | 901 | SBP2LU_STATE_RUNNING, SBP2LU_STATE_IN_RESET) |
| 896 | atomic_set(&lu->state, SBP2LU_STATE_IN_RESET); | 902 | == SBP2LU_STATE_RUNNING) |
| 897 | scsi_block_requests(lu->shost); | 903 | scsi_block_requests(lu->shost); |
| 898 | } | 904 | |
| 899 | read_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags); | 905 | read_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags); |
| 900 | } | 906 | } |
| 901 | 907 | ||
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index d85af1b67027..eb36a81dd09b 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -358,8 +358,6 @@ static int ib_uverbs_event_close(struct inode *inode, struct file *filp) | |||
| 358 | } | 358 | } |
| 359 | spin_unlock_irq(&file->lock); | 359 | spin_unlock_irq(&file->lock); |
| 360 | 360 | ||
| 361 | ib_uverbs_event_fasync(-1, filp, 0); | ||
| 362 | |||
| 363 | if (file->is_async) { | 361 | if (file->is_async) { |
| 364 | ib_unregister_event_handler(&file->uverbs_file->event_handler); | 362 | ib_unregister_event_handler(&file->uverbs_file->event_handler); |
| 365 | kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); | 363 | kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index ecff98043589..160ef482712d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
| @@ -1102,9 +1102,7 @@ static u64 fw_vers_string_to_u64(struct iwch_dev *iwch_dev) | |||
| 1102 | char *cp, *next; | 1102 | char *cp, *next; |
| 1103 | unsigned fw_maj, fw_min, fw_mic; | 1103 | unsigned fw_maj, fw_min, fw_mic; |
| 1104 | 1104 | ||
| 1105 | rtnl_lock(); | ||
| 1106 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1105 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
| 1107 | rtnl_unlock(); | ||
| 1108 | 1106 | ||
| 1109 | next = info.fw_version + 1; | 1107 | next = info.fw_version + 1; |
| 1110 | cp = strsep(&next, "."); | 1108 | cp = strsep(&next, "."); |
| @@ -1192,9 +1190,7 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, ch | |||
| 1192 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; | 1190 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; |
| 1193 | 1191 | ||
| 1194 | PDBG("%s dev 0x%p\n", __func__, dev); | 1192 | PDBG("%s dev 0x%p\n", __func__, dev); |
| 1195 | rtnl_lock(); | ||
| 1196 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1193 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
| 1197 | rtnl_unlock(); | ||
| 1198 | return sprintf(buf, "%s\n", info.fw_version); | 1194 | return sprintf(buf, "%s\n", info.fw_version); |
| 1199 | } | 1195 | } |
| 1200 | 1196 | ||
| @@ -1207,9 +1203,7 @@ static ssize_t show_hca(struct device *dev, struct device_attribute *attr, | |||
| 1207 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; | 1203 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; |
| 1208 | 1204 | ||
| 1209 | PDBG("%s dev 0x%p\n", __func__, dev); | 1205 | PDBG("%s dev 0x%p\n", __func__, dev); |
| 1210 | rtnl_lock(); | ||
| 1211 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1206 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
| 1212 | rtnl_unlock(); | ||
| 1213 | return sprintf(buf, "%s\n", info.driver); | 1207 | return sprintf(buf, "%s\n", info.driver); |
| 1214 | } | 1208 | } |
| 1215 | 1209 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 3e4585c2318a..19661b2f0406 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -745,7 +745,6 @@ int iwch_post_zb_read(struct iwch_qp *qhp) | |||
| 745 | wqe->read.rdmaop = T3_READ_REQ; | 745 | wqe->read.rdmaop = T3_READ_REQ; |
| 746 | wqe->read.reserved[0] = 0; | 746 | wqe->read.reserved[0] = 0; |
| 747 | wqe->read.reserved[1] = 0; | 747 | wqe->read.reserved[1] = 0; |
| 748 | wqe->read.reserved[2] = 0; | ||
| 749 | wqe->read.rem_stag = cpu_to_be32(1); | 748 | wqe->read.rem_stag = cpu_to_be32(1); |
| 750 | wqe->read.rem_to = cpu_to_be64(1); | 749 | wqe->read.rem_to = cpu_to_be64(1); |
| 751 | wqe->read.local_stag = cpu_to_be32(1); | 750 | wqe->read.local_stag = cpu_to_be32(1); |
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 4df887af66a5..7fc35cf0cddf 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
| @@ -163,7 +163,8 @@ struct ehca_mod_qp_parm { | |||
| 163 | /* struct for tracking if cqes have been reported to the application */ | 163 | /* struct for tracking if cqes have been reported to the application */ |
| 164 | struct ehca_qmap_entry { | 164 | struct ehca_qmap_entry { |
| 165 | u16 app_wr_id; | 165 | u16 app_wr_id; |
| 166 | u16 reported; | 166 | u8 reported; |
| 167 | u8 cqe_req; | ||
| 167 | }; | 168 | }; |
| 168 | 169 | ||
| 169 | struct ehca_queue_map { | 170 | struct ehca_queue_map { |
| @@ -171,6 +172,7 @@ struct ehca_queue_map { | |||
| 171 | unsigned int entries; | 172 | unsigned int entries; |
| 172 | unsigned int tail; | 173 | unsigned int tail; |
| 173 | unsigned int left_to_poll; | 174 | unsigned int left_to_poll; |
| 175 | unsigned int next_wqe_idx; /* Idx to first wqe to be flushed */ | ||
| 174 | }; | 176 | }; |
| 175 | 177 | ||
| 176 | struct ehca_qp { | 178 | struct ehca_qp { |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index cb55be04442c..757035ea246f 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
| @@ -359,36 +359,48 @@ static void notify_port_conf_change(struct ehca_shca *shca, int port_num) | |||
| 359 | *old_attr = new_attr; | 359 | *old_attr = new_attr; |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | /* replay modify_qp for sqps -- return 0 if all is well, 1 if AQP1 destroyed */ | ||
| 363 | static int replay_modify_qp(struct ehca_sport *sport) | ||
| 364 | { | ||
| 365 | int aqp1_destroyed; | ||
| 366 | unsigned long flags; | ||
| 367 | |||
| 368 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | ||
| 369 | |||
| 370 | aqp1_destroyed = !sport->ibqp_sqp[IB_QPT_GSI]; | ||
| 371 | |||
| 372 | if (sport->ibqp_sqp[IB_QPT_SMI]) | ||
| 373 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); | ||
| 374 | if (!aqp1_destroyed) | ||
| 375 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); | ||
| 376 | |||
| 377 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
| 378 | |||
| 379 | return aqp1_destroyed; | ||
| 380 | } | ||
| 381 | |||
| 362 | static void parse_ec(struct ehca_shca *shca, u64 eqe) | 382 | static void parse_ec(struct ehca_shca *shca, u64 eqe) |
| 363 | { | 383 | { |
| 364 | u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe); | 384 | u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe); |
| 365 | u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe); | 385 | u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe); |
| 366 | u8 spec_event; | 386 | u8 spec_event; |
| 367 | struct ehca_sport *sport = &shca->sport[port - 1]; | 387 | struct ehca_sport *sport = &shca->sport[port - 1]; |
| 368 | unsigned long flags; | ||
| 369 | 388 | ||
| 370 | switch (ec) { | 389 | switch (ec) { |
| 371 | case 0x30: /* port availability change */ | 390 | case 0x30: /* port availability change */ |
| 372 | if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { | 391 | if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { |
| 373 | int suppress_event; | 392 | /* only replay modify_qp calls in autodetect mode; |
| 374 | /* replay modify_qp for sqps */ | 393 | * if AQP1 was destroyed, the port is already down |
| 375 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | 394 | * again and we can drop the event. |
| 376 | suppress_event = !sport->ibqp_sqp[IB_QPT_GSI]; | 395 | */ |
| 377 | if (sport->ibqp_sqp[IB_QPT_SMI]) | 396 | if (ehca_nr_ports < 0) |
| 378 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); | 397 | if (replay_modify_qp(sport)) |
| 379 | if (!suppress_event) | 398 | break; |
| 380 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); | ||
| 381 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
| 382 | |||
| 383 | /* AQP1 was destroyed, ignore this event */ | ||
| 384 | if (suppress_event) | ||
| 385 | break; | ||
| 386 | 399 | ||
| 387 | sport->port_state = IB_PORT_ACTIVE; | 400 | sport->port_state = IB_PORT_ACTIVE; |
| 388 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, | 401 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, |
| 389 | "is active"); | 402 | "is active"); |
| 390 | ehca_query_sma_attr(shca, port, | 403 | ehca_query_sma_attr(shca, port, &sport->saved_attr); |
| 391 | &sport->saved_attr); | ||
| 392 | } else { | 404 | } else { |
| 393 | sport->port_state = IB_PORT_DOWN; | 405 | sport->port_state = IB_PORT_DOWN; |
| 394 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, | 406 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index bb02a86aa526..bec7e0249358 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
| @@ -994,8 +994,7 @@ static int ehca_mem_notifier(struct notifier_block *nb, | |||
| 994 | if (printk_timed_ratelimit(&ehca_dmem_warn_time, | 994 | if (printk_timed_ratelimit(&ehca_dmem_warn_time, |
| 995 | 30 * 1000)) | 995 | 30 * 1000)) |
| 996 | ehca_gen_err("DMEM operations are not allowed" | 996 | ehca_gen_err("DMEM operations are not allowed" |
| 997 | "as long as an ehca adapter is" | 997 | "in conjunction with eHCA"); |
| 998 | "attached to the LPAR"); | ||
| 999 | return NOTIFY_BAD; | 998 | return NOTIFY_BAD; |
| 1000 | } | 999 | } |
| 1001 | } | 1000 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4d54b9f64567..cadbf0cdd910 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
| @@ -435,9 +435,13 @@ static void reset_queue_map(struct ehca_queue_map *qmap) | |||
| 435 | { | 435 | { |
| 436 | int i; | 436 | int i; |
| 437 | 437 | ||
| 438 | qmap->tail = 0; | 438 | qmap->tail = qmap->entries - 1; |
| 439 | for (i = 0; i < qmap->entries; i++) | 439 | qmap->left_to_poll = 0; |
| 440 | qmap->next_wqe_idx = 0; | ||
| 441 | for (i = 0; i < qmap->entries; i++) { | ||
| 440 | qmap->map[i].reported = 1; | 442 | qmap->map[i].reported = 1; |
| 443 | qmap->map[i].cqe_req = 0; | ||
| 444 | } | ||
| 441 | } | 445 | } |
| 442 | 446 | ||
| 443 | /* | 447 | /* |
| @@ -860,6 +864,11 @@ static struct ehca_qp *internal_create_qp( | |||
| 860 | if (qp_type == IB_QPT_GSI) { | 864 | if (qp_type == IB_QPT_GSI) { |
| 861 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); | 865 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); |
| 862 | if (h_ret != H_SUCCESS) { | 866 | if (h_ret != H_SUCCESS) { |
| 867 | kfree(my_qp->mod_qp_parm); | ||
| 868 | my_qp->mod_qp_parm = NULL; | ||
| 869 | /* the QP pointer is no longer valid */ | ||
| 870 | shca->sport[init_attr->port_num - 1].ibqp_sqp[qp_type] = | ||
| 871 | NULL; | ||
| 863 | ret = ehca2ib_return_code(h_ret); | 872 | ret = ehca2ib_return_code(h_ret); |
| 864 | goto create_qp_exit6; | 873 | goto create_qp_exit6; |
| 865 | } | 874 | } |
| @@ -1116,6 +1125,7 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue, | |||
| 1116 | void *wqe_v; | 1125 | void *wqe_v; |
| 1117 | u64 q_ofs; | 1126 | u64 q_ofs; |
| 1118 | u32 wqe_idx; | 1127 | u32 wqe_idx; |
| 1128 | unsigned int tail_idx; | ||
| 1119 | 1129 | ||
| 1120 | /* convert real to abs address */ | 1130 | /* convert real to abs address */ |
| 1121 | wqe_p = wqe_p & (~(1UL << 63)); | 1131 | wqe_p = wqe_p & (~(1UL << 63)); |
| @@ -1128,12 +1138,17 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue, | |||
| 1128 | return -EFAULT; | 1138 | return -EFAULT; |
| 1129 | } | 1139 | } |
| 1130 | 1140 | ||
| 1141 | tail_idx = (qmap->tail + 1) % qmap->entries; | ||
| 1131 | wqe_idx = q_ofs / ipz_queue->qe_size; | 1142 | wqe_idx = q_ofs / ipz_queue->qe_size; |
| 1132 | if (wqe_idx < qmap->tail) | ||
| 1133 | qmap->left_to_poll = (qmap->entries - qmap->tail) + wqe_idx; | ||
| 1134 | else | ||
| 1135 | qmap->left_to_poll = wqe_idx - qmap->tail; | ||
| 1136 | 1143 | ||
| 1144 | /* check all processed wqes, whether a cqe is requested or not */ | ||
| 1145 | while (tail_idx != wqe_idx) { | ||
| 1146 | if (qmap->map[tail_idx].cqe_req) | ||
| 1147 | qmap->left_to_poll++; | ||
| 1148 | tail_idx = (tail_idx + 1) % qmap->entries; | ||
| 1149 | } | ||
| 1150 | /* save index in queue, where we have to start flushing */ | ||
| 1151 | qmap->next_wqe_idx = wqe_idx; | ||
| 1137 | return 0; | 1152 | return 0; |
| 1138 | } | 1153 | } |
| 1139 | 1154 | ||
| @@ -1180,10 +1195,14 @@ static int check_for_left_cqes(struct ehca_qp *my_qp, struct ehca_shca *shca) | |||
| 1180 | } else { | 1195 | } else { |
| 1181 | spin_lock_irqsave(&my_qp->send_cq->spinlock, flags); | 1196 | spin_lock_irqsave(&my_qp->send_cq->spinlock, flags); |
| 1182 | my_qp->sq_map.left_to_poll = 0; | 1197 | my_qp->sq_map.left_to_poll = 0; |
| 1198 | my_qp->sq_map.next_wqe_idx = (my_qp->sq_map.tail + 1) % | ||
| 1199 | my_qp->sq_map.entries; | ||
| 1183 | spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags); | 1200 | spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags); |
| 1184 | 1201 | ||
| 1185 | spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags); | 1202 | spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags); |
| 1186 | my_qp->rq_map.left_to_poll = 0; | 1203 | my_qp->rq_map.left_to_poll = 0; |
| 1204 | my_qp->rq_map.next_wqe_idx = (my_qp->rq_map.tail + 1) % | ||
| 1205 | my_qp->rq_map.entries; | ||
| 1187 | spin_unlock_irqrestore(&my_qp->recv_cq->spinlock, flags); | 1206 | spin_unlock_irqrestore(&my_qp->recv_cq->spinlock, flags); |
| 1188 | } | 1207 | } |
| 1189 | 1208 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index 64928079eafa..00a648f4316c 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c | |||
| @@ -179,6 +179,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
| 179 | 179 | ||
| 180 | qmap_entry->app_wr_id = get_app_wr_id(send_wr->wr_id); | 180 | qmap_entry->app_wr_id = get_app_wr_id(send_wr->wr_id); |
| 181 | qmap_entry->reported = 0; | 181 | qmap_entry->reported = 0; |
| 182 | qmap_entry->cqe_req = 0; | ||
| 182 | 183 | ||
| 183 | switch (send_wr->opcode) { | 184 | switch (send_wr->opcode) { |
| 184 | case IB_WR_SEND: | 185 | case IB_WR_SEND: |
| @@ -203,8 +204,10 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
| 203 | 204 | ||
| 204 | if ((send_wr->send_flags & IB_SEND_SIGNALED || | 205 | if ((send_wr->send_flags & IB_SEND_SIGNALED || |
| 205 | qp->init_attr.sq_sig_type == IB_SIGNAL_ALL_WR) | 206 | qp->init_attr.sq_sig_type == IB_SIGNAL_ALL_WR) |
| 206 | && !hidden) | 207 | && !hidden) { |
| 207 | wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM; | 208 | wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM; |
| 209 | qmap_entry->cqe_req = 1; | ||
| 210 | } | ||
| 208 | 211 | ||
| 209 | if (send_wr->opcode == IB_WR_SEND_WITH_IMM || | 212 | if (send_wr->opcode == IB_WR_SEND_WITH_IMM || |
| 210 | send_wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) { | 213 | send_wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) { |
| @@ -569,6 +572,7 @@ static int internal_post_recv(struct ehca_qp *my_qp, | |||
| 569 | qmap_entry = &my_qp->rq_map.map[rq_map_idx]; | 572 | qmap_entry = &my_qp->rq_map.map[rq_map_idx]; |
| 570 | qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id); | 573 | qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id); |
| 571 | qmap_entry->reported = 0; | 574 | qmap_entry->reported = 0; |
| 575 | qmap_entry->cqe_req = 1; | ||
| 572 | 576 | ||
| 573 | wqe_cnt++; | 577 | wqe_cnt++; |
| 574 | } /* eof for cur_recv_wr */ | 578 | } /* eof for cur_recv_wr */ |
| @@ -706,27 +710,34 @@ repoll: | |||
| 706 | goto repoll; | 710 | goto repoll; |
| 707 | wc->qp = &my_qp->ib_qp; | 711 | wc->qp = &my_qp->ib_qp; |
| 708 | 712 | ||
| 713 | qmap_tail_idx = get_app_wr_id(cqe->work_request_id); | ||
| 714 | if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT)) | ||
| 715 | /* We got a send completion. */ | ||
| 716 | qmap = &my_qp->sq_map; | ||
| 717 | else | ||
| 718 | /* We got a receive completion. */ | ||
| 719 | qmap = &my_qp->rq_map; | ||
| 720 | |||
| 721 | /* advance the tail pointer */ | ||
| 722 | qmap->tail = qmap_tail_idx; | ||
| 723 | |||
| 709 | if (is_error) { | 724 | if (is_error) { |
| 710 | /* | 725 | /* |
| 711 | * set left_to_poll to 0 because in error state, we will not | 726 | * set left_to_poll to 0 because in error state, we will not |
| 712 | * get any additional CQEs | 727 | * get any additional CQEs |
| 713 | */ | 728 | */ |
| 714 | ehca_add_to_err_list(my_qp, 1); | 729 | my_qp->sq_map.next_wqe_idx = (my_qp->sq_map.tail + 1) % |
| 730 | my_qp->sq_map.entries; | ||
| 715 | my_qp->sq_map.left_to_poll = 0; | 731 | my_qp->sq_map.left_to_poll = 0; |
| 732 | ehca_add_to_err_list(my_qp, 1); | ||
| 716 | 733 | ||
| 734 | my_qp->rq_map.next_wqe_idx = (my_qp->rq_map.tail + 1) % | ||
| 735 | my_qp->rq_map.entries; | ||
| 736 | my_qp->rq_map.left_to_poll = 0; | ||
| 717 | if (HAS_RQ(my_qp)) | 737 | if (HAS_RQ(my_qp)) |
| 718 | ehca_add_to_err_list(my_qp, 0); | 738 | ehca_add_to_err_list(my_qp, 0); |
| 719 | my_qp->rq_map.left_to_poll = 0; | ||
| 720 | } | 739 | } |
| 721 | 740 | ||
| 722 | qmap_tail_idx = get_app_wr_id(cqe->work_request_id); | ||
| 723 | if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT)) | ||
| 724 | /* We got a send completion. */ | ||
| 725 | qmap = &my_qp->sq_map; | ||
| 726 | else | ||
| 727 | /* We got a receive completion. */ | ||
| 728 | qmap = &my_qp->rq_map; | ||
| 729 | |||
| 730 | qmap_entry = &qmap->map[qmap_tail_idx]; | 741 | qmap_entry = &qmap->map[qmap_tail_idx]; |
| 731 | if (qmap_entry->reported) { | 742 | if (qmap_entry->reported) { |
| 732 | ehca_warn(cq->device, "Double cqe on qp_num=%#x", | 743 | ehca_warn(cq->device, "Double cqe on qp_num=%#x", |
| @@ -738,10 +749,6 @@ repoll: | |||
| 738 | wc->wr_id = replace_wr_id(cqe->work_request_id, qmap_entry->app_wr_id); | 749 | wc->wr_id = replace_wr_id(cqe->work_request_id, qmap_entry->app_wr_id); |
| 739 | qmap_entry->reported = 1; | 750 | qmap_entry->reported = 1; |
| 740 | 751 | ||
| 741 | /* this is a proper completion, we need to advance the tail pointer */ | ||
| 742 | if (++qmap->tail == qmap->entries) | ||
| 743 | qmap->tail = 0; | ||
| 744 | |||
| 745 | /* if left_to_poll is decremented to 0, add the QP to the error list */ | 752 | /* if left_to_poll is decremented to 0, add the QP to the error list */ |
| 746 | if (qmap->left_to_poll > 0) { | 753 | if (qmap->left_to_poll > 0) { |
| 747 | qmap->left_to_poll--; | 754 | qmap->left_to_poll--; |
| @@ -805,13 +812,14 @@ static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq, | |||
| 805 | else | 812 | else |
| 806 | qmap = &my_qp->rq_map; | 813 | qmap = &my_qp->rq_map; |
| 807 | 814 | ||
| 808 | qmap_entry = &qmap->map[qmap->tail]; | 815 | qmap_entry = &qmap->map[qmap->next_wqe_idx]; |
| 809 | 816 | ||
| 810 | while ((nr < num_entries) && (qmap_entry->reported == 0)) { | 817 | while ((nr < num_entries) && (qmap_entry->reported == 0)) { |
| 811 | /* generate flush CQE */ | 818 | /* generate flush CQE */ |
| 819 | |||
| 812 | memset(wc, 0, sizeof(*wc)); | 820 | memset(wc, 0, sizeof(*wc)); |
| 813 | 821 | ||
| 814 | offset = qmap->tail * ipz_queue->qe_size; | 822 | offset = qmap->next_wqe_idx * ipz_queue->qe_size; |
| 815 | wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset); | 823 | wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset); |
| 816 | if (!wqe) { | 824 | if (!wqe) { |
| 817 | ehca_err(cq->device, "Invalid wqe offset=%#lx on " | 825 | ehca_err(cq->device, "Invalid wqe offset=%#lx on " |
| @@ -850,11 +858,12 @@ static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq, | |||
| 850 | 858 | ||
| 851 | wc->qp = &my_qp->ib_qp; | 859 | wc->qp = &my_qp->ib_qp; |
| 852 | 860 | ||
| 853 | /* mark as reported and advance tail pointer */ | 861 | /* mark as reported and advance next_wqe pointer */ |
| 854 | qmap_entry->reported = 1; | 862 | qmap_entry->reported = 1; |
| 855 | if (++qmap->tail == qmap->entries) | 863 | qmap->next_wqe_idx++; |
| 856 | qmap->tail = 0; | 864 | if (qmap->next_wqe_idx == qmap->entries) |
| 857 | qmap_entry = &qmap->map[qmap->tail]; | 865 | qmap->next_wqe_idx = 0; |
| 866 | qmap_entry = &qmap->map[qmap->next_wqe_idx]; | ||
| 858 | 867 | ||
| 859 | wc++; nr++; | 868 | wc++; nr++; |
| 860 | } | 869 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index fc0f6d9e6030..2296832f94da 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
| @@ -156,7 +156,7 @@ bail: | |||
| 156 | /** | 156 | /** |
| 157 | * ipath_get_rwqe - copy the next RWQE into the QP's RWQE | 157 | * ipath_get_rwqe - copy the next RWQE into the QP's RWQE |
| 158 | * @qp: the QP | 158 | * @qp: the QP |
| 159 | * @wr_id_only: update wr_id only, not SGEs | 159 | * @wr_id_only: update qp->r_wr_id only, not qp->r_sge |
| 160 | * | 160 | * |
| 161 | * Return 0 if no RWQE is available, otherwise return 1. | 161 | * Return 0 if no RWQE is available, otherwise return 1. |
| 162 | * | 162 | * |
| @@ -173,8 +173,6 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
| 173 | u32 tail; | 173 | u32 tail; |
| 174 | int ret; | 174 | int ret; |
| 175 | 175 | ||
| 176 | qp->r_sge.sg_list = qp->r_sg_list; | ||
| 177 | |||
| 178 | if (qp->ibqp.srq) { | 176 | if (qp->ibqp.srq) { |
| 179 | srq = to_isrq(qp->ibqp.srq); | 177 | srq = to_isrq(qp->ibqp.srq); |
| 180 | handler = srq->ibsrq.event_handler; | 178 | handler = srq->ibsrq.event_handler; |
| @@ -206,8 +204,10 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
| 206 | wqe = get_rwqe_ptr(rq, tail); | 204 | wqe = get_rwqe_ptr(rq, tail); |
| 207 | if (++tail >= rq->size) | 205 | if (++tail >= rq->size) |
| 208 | tail = 0; | 206 | tail = 0; |
| 209 | } while (!wr_id_only && !ipath_init_sge(qp, wqe, &qp->r_len, | 207 | if (wr_id_only) |
| 210 | &qp->r_sge)); | 208 | break; |
| 209 | qp->r_sge.sg_list = qp->r_sg_list; | ||
| 210 | } while (!ipath_init_sge(qp, wqe, &qp->r_len, &qp->r_sge)); | ||
| 211 | qp->r_wr_id = wqe->wr_id; | 211 | qp->r_wr_id = wqe->wr_id; |
| 212 | wq->tail = tail; | 212 | wq->tail = tail; |
| 213 | 213 | ||
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index d0866a3636e2..18308494a195 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
| @@ -343,6 +343,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata) | |||
| 343 | { | 343 | { |
| 344 | struct mlx4_ib_dev *dev = to_mdev(ibcq->device); | 344 | struct mlx4_ib_dev *dev = to_mdev(ibcq->device); |
| 345 | struct mlx4_ib_cq *cq = to_mcq(ibcq); | 345 | struct mlx4_ib_cq *cq = to_mcq(ibcq); |
| 346 | struct mlx4_mtt mtt; | ||
| 346 | int outst_cqe; | 347 | int outst_cqe; |
| 347 | int err; | 348 | int err; |
| 348 | 349 | ||
| @@ -376,10 +377,13 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata) | |||
| 376 | goto out; | 377 | goto out; |
| 377 | } | 378 | } |
| 378 | 379 | ||
| 380 | mtt = cq->buf.mtt; | ||
| 381 | |||
| 379 | err = mlx4_cq_resize(dev->dev, &cq->mcq, entries, &cq->resize_buf->buf.mtt); | 382 | err = mlx4_cq_resize(dev->dev, &cq->mcq, entries, &cq->resize_buf->buf.mtt); |
| 380 | if (err) | 383 | if (err) |
| 381 | goto err_buf; | 384 | goto err_buf; |
| 382 | 385 | ||
| 386 | mlx4_mtt_cleanup(dev->dev, &mtt); | ||
| 383 | if (ibcq->uobject) { | 387 | if (ibcq->uobject) { |
| 384 | cq->buf = cq->resize_buf->buf; | 388 | cq->buf = cq->resize_buf->buf; |
| 385 | cq->ibcq.cqe = cq->resize_buf->cqe; | 389 | cq->ibcq.cqe = cq->resize_buf->cqe; |
| @@ -406,6 +410,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata) | |||
| 406 | goto out; | 410 | goto out; |
| 407 | 411 | ||
| 408 | err_buf: | 412 | err_buf: |
| 413 | mlx4_mtt_cleanup(dev->dev, &cq->resize_buf->buf.mtt); | ||
| 409 | if (!ibcq->uobject) | 414 | if (!ibcq->uobject) |
| 410 | mlx4_ib_free_cq_buf(dev, &cq->resize_buf->buf, | 415 | mlx4_ib_free_cq_buf(dev, &cq->resize_buf->buf, |
| 411 | cq->resize_buf->cqe); | 416 | cq->resize_buf->cqe); |
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 87f5c5a87b98..8e4d26d56a95 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
| @@ -205,6 +205,7 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, | |||
| 205 | goto err_mr; | 205 | goto err_mr; |
| 206 | 206 | ||
| 207 | mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; | 207 | mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; |
| 208 | mr->umem = NULL; | ||
| 208 | 209 | ||
| 209 | return &mr->ibmr; | 210 | return &mr->ibmr; |
| 210 | 211 | ||
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index a2b04d62b1a4..aa1dc41f04c8 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
| @@ -95,6 +95,10 @@ unsigned int wqm_quanta = 0x10000; | |||
| 95 | module_param(wqm_quanta, int, 0644); | 95 | module_param(wqm_quanta, int, 0644); |
| 96 | MODULE_PARM_DESC(wqm_quanta, "WQM quanta"); | 96 | MODULE_PARM_DESC(wqm_quanta, "WQM quanta"); |
| 97 | 97 | ||
| 98 | static unsigned int limit_maxrdreqsz; | ||
| 99 | module_param(limit_maxrdreqsz, bool, 0644); | ||
| 100 | MODULE_PARM_DESC(limit_maxrdreqsz, "Limit max read request size to 256 Bytes"); | ||
| 101 | |||
| 98 | LIST_HEAD(nes_adapter_list); | 102 | LIST_HEAD(nes_adapter_list); |
| 99 | static LIST_HEAD(nes_dev_list); | 103 | static LIST_HEAD(nes_dev_list); |
| 100 | 104 | ||
| @@ -588,6 +592,18 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
| 588 | nesdev->nesadapter->port_count; | 592 | nesdev->nesadapter->port_count; |
| 589 | } | 593 | } |
| 590 | 594 | ||
| 595 | if ((limit_maxrdreqsz || | ||
| 596 | ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) && | ||
| 597 | (hw_rev == NE020_REV1))) && | ||
| 598 | (pcie_get_readrq(pcidev) > 256)) { | ||
| 599 | if (pcie_set_readrq(pcidev, 256)) | ||
| 600 | printk(KERN_ERR PFX "Unable to set max read request" | ||
| 601 | " to 256 bytes\n"); | ||
| 602 | else | ||
| 603 | nes_debug(NES_DBG_INIT, "Max read request size set" | ||
| 604 | " to 256 bytes\n"); | ||
| 605 | } | ||
| 606 | |||
| 591 | tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); | 607 | tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); |
| 592 | 608 | ||
| 593 | /* bring up the Control QP */ | 609 | /* bring up the Control QP */ |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 610b9d859597..bc0b4de04450 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #define NES_PHY_TYPE_ARGUS 4 | 40 | #define NES_PHY_TYPE_ARGUS 4 |
| 41 | #define NES_PHY_TYPE_PUMA_1G 5 | 41 | #define NES_PHY_TYPE_PUMA_1G 5 |
| 42 | #define NES_PHY_TYPE_PUMA_10G 6 | 42 | #define NES_PHY_TYPE_PUMA_10G 6 |
| 43 | #define NES_PHY_TYPE_GLADIUS 7 | ||
| 43 | 44 | ||
| 44 | #define NES_MULTICAST_PF_MAX 8 | 45 | #define NES_MULTICAST_PF_MAX 8 |
| 45 | 46 | ||
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 932e56fcf774..d36c9a0bf1bb 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
| @@ -220,14 +220,14 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, | |||
| 220 | if (nesqp->ibqp_state > IB_QPS_RTS) | 220 | if (nesqp->ibqp_state > IB_QPS_RTS) |
| 221 | return -EINVAL; | 221 | return -EINVAL; |
| 222 | 222 | ||
| 223 | spin_lock_irqsave(&nesqp->lock, flags); | 223 | spin_lock_irqsave(&nesqp->lock, flags); |
| 224 | 224 | ||
| 225 | head = nesqp->hwqp.sq_head; | 225 | head = nesqp->hwqp.sq_head; |
| 226 | qsize = nesqp->hwqp.sq_tail; | 226 | qsize = nesqp->hwqp.sq_tail; |
| 227 | 227 | ||
| 228 | /* Check for SQ overflow */ | 228 | /* Check for SQ overflow */ |
| 229 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { | 229 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { |
| 230 | spin_unlock_irqrestore(&nesqp->lock, flags); | 230 | spin_unlock_irqrestore(&nesqp->lock, flags); |
| 231 | return -EINVAL; | 231 | return -EINVAL; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| @@ -269,7 +269,7 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, | |||
| 269 | nes_write32(nesdev->regs+NES_WQE_ALLOC, | 269 | nes_write32(nesdev->regs+NES_WQE_ALLOC, |
| 270 | (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); | 270 | (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); |
| 271 | 271 | ||
| 272 | spin_unlock_irqrestore(&nesqp->lock, flags); | 272 | spin_unlock_irqrestore(&nesqp->lock, flags); |
| 273 | 273 | ||
| 274 | return 0; | 274 | return 0; |
| 275 | } | 275 | } |
| @@ -349,7 +349,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
| 349 | if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { | 349 | if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { |
| 350 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 350 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
| 351 | ret = -ENOMEM; | 351 | ret = -ENOMEM; |
| 352 | goto failed_vpbl_alloc; | 352 | goto failed_vpbl_avail; |
| 353 | } else { | 353 | } else { |
| 354 | nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; | 354 | nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; |
| 355 | } | 355 | } |
| @@ -357,7 +357,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
| 357 | if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { | 357 | if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { |
| 358 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 358 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
| 359 | ret = -ENOMEM; | 359 | ret = -ENOMEM; |
| 360 | goto failed_vpbl_alloc; | 360 | goto failed_vpbl_avail; |
| 361 | } else { | 361 | } else { |
| 362 | nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; | 362 | nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; |
| 363 | } | 363 | } |
| @@ -391,14 +391,14 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
| 391 | goto failed_vpbl_alloc; | 391 | goto failed_vpbl_alloc; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_KERNEL); | 394 | nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; |
| 395 | nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_ATOMIC); | ||
| 395 | if (!nesfmr->root_vpbl.leaf_vpbl) { | 396 | if (!nesfmr->root_vpbl.leaf_vpbl) { |
| 396 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 397 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
| 397 | ret = -ENOMEM; | 398 | ret = -ENOMEM; |
| 398 | goto failed_leaf_vpbl_alloc; | 399 | goto failed_leaf_vpbl_alloc; |
| 399 | } | 400 | } |
| 400 | 401 | ||
| 401 | nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; | ||
| 402 | nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" | 402 | nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" |
| 403 | " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", | 403 | " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", |
| 404 | nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); | 404 | nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); |
| @@ -519,6 +519,16 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
| 519 | nesfmr->root_vpbl.pbl_pbase); | 519 | nesfmr->root_vpbl.pbl_pbase); |
| 520 | 520 | ||
| 521 | failed_vpbl_alloc: | 521 | failed_vpbl_alloc: |
| 522 | if (nesfmr->nesmr.pbls_used != 0) { | ||
| 523 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | ||
| 524 | if (nesfmr->nesmr.pbl_4k) | ||
| 525 | nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; | ||
| 526 | else | ||
| 527 | nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; | ||
| 528 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
| 529 | } | ||
| 530 | |||
| 531 | failed_vpbl_avail: | ||
| 522 | kfree(nesfmr); | 532 | kfree(nesfmr); |
| 523 | 533 | ||
| 524 | failed_fmr_alloc: | 534 | failed_fmr_alloc: |
| @@ -534,18 +544,14 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
| 534 | */ | 544 | */ |
| 535 | static int nes_dealloc_fmr(struct ib_fmr *ibfmr) | 545 | static int nes_dealloc_fmr(struct ib_fmr *ibfmr) |
| 536 | { | 546 | { |
| 547 | unsigned long flags; | ||
| 537 | struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); | 548 | struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); |
| 538 | struct nes_fmr *nesfmr = to_nesfmr(nesmr); | 549 | struct nes_fmr *nesfmr = to_nesfmr(nesmr); |
| 539 | struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); | 550 | struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); |
| 540 | struct nes_device *nesdev = nesvnic->nesdev; | 551 | struct nes_device *nesdev = nesvnic->nesdev; |
| 541 | struct nes_mr temp_nesmr = *nesmr; | 552 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
| 542 | int i = 0; | 553 | int i = 0; |
| 543 | 554 | ||
| 544 | temp_nesmr.ibmw.device = ibfmr->device; | ||
| 545 | temp_nesmr.ibmw.pd = ibfmr->pd; | ||
| 546 | temp_nesmr.ibmw.rkey = ibfmr->rkey; | ||
| 547 | temp_nesmr.ibmw.uobject = NULL; | ||
| 548 | |||
| 549 | /* free the resources */ | 555 | /* free the resources */ |
| 550 | if (nesfmr->leaf_pbl_cnt == 0) { | 556 | if (nesfmr->leaf_pbl_cnt == 0) { |
| 551 | /* single PBL case */ | 557 | /* single PBL case */ |
| @@ -561,8 +567,24 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr) | |||
| 561 | pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, | 567 | pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, |
| 562 | nesfmr->root_vpbl.pbl_pbase); | 568 | nesfmr->root_vpbl.pbl_pbase); |
| 563 | } | 569 | } |
| 570 | nesmr->ibmw.device = ibfmr->device; | ||
| 571 | nesmr->ibmw.pd = ibfmr->pd; | ||
| 572 | nesmr->ibmw.rkey = ibfmr->rkey; | ||
| 573 | nesmr->ibmw.uobject = NULL; | ||
| 564 | 574 | ||
| 565 | return nes_dealloc_mw(&temp_nesmr.ibmw); | 575 | if (nesfmr->nesmr.pbls_used != 0) { |
| 576 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | ||
| 577 | if (nesfmr->nesmr.pbl_4k) { | ||
| 578 | nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; | ||
| 579 | WARN_ON(nesadapter->free_4kpbl > nesadapter->max_4kpbl); | ||
| 580 | } else { | ||
| 581 | nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; | ||
| 582 | WARN_ON(nesadapter->free_256pbl > nesadapter->max_256pbl); | ||
| 583 | } | ||
| 584 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
| 585 | } | ||
| 586 | |||
| 587 | return nes_dealloc_mw(&nesmr->ibmw); | ||
| 566 | } | 588 | } |
| 567 | 589 | ||
| 568 | 590 | ||
| @@ -1595,7 +1617,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, | |||
| 1595 | nes_ucontext->mcrqf = req.mcrqf; | 1617 | nes_ucontext->mcrqf = req.mcrqf; |
| 1596 | if (nes_ucontext->mcrqf) { | 1618 | if (nes_ucontext->mcrqf) { |
| 1597 | if (nes_ucontext->mcrqf & 0x80000000) | 1619 | if (nes_ucontext->mcrqf & 0x80000000) |
| 1598 | nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 12 + (nes_ucontext->mcrqf & 0xf) - 1; | 1620 | nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 28 + 2 * ((nes_ucontext->mcrqf & 0xf) - 1); |
| 1599 | else if (nes_ucontext->mcrqf & 0x40000000) | 1621 | else if (nes_ucontext->mcrqf & 0x40000000) |
| 1600 | nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff; | 1622 | nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff; |
| 1601 | else | 1623 | else |
| @@ -3212,7 +3234,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
| 3212 | if (nesqp->ibqp_state > IB_QPS_RTS) | 3234 | if (nesqp->ibqp_state > IB_QPS_RTS) |
| 3213 | return -EINVAL; | 3235 | return -EINVAL; |
| 3214 | 3236 | ||
| 3215 | spin_lock_irqsave(&nesqp->lock, flags); | 3237 | spin_lock_irqsave(&nesqp->lock, flags); |
| 3216 | 3238 | ||
| 3217 | head = nesqp->hwqp.sq_head; | 3239 | head = nesqp->hwqp.sq_head; |
| 3218 | 3240 | ||
| @@ -3337,7 +3359,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
| 3337 | (counter << 24) | 0x00800000 | nesqp->hwqp.qp_id); | 3359 | (counter << 24) | 0x00800000 | nesqp->hwqp.qp_id); |
| 3338 | } | 3360 | } |
| 3339 | 3361 | ||
| 3340 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3362 | spin_unlock_irqrestore(&nesqp->lock, flags); |
| 3341 | 3363 | ||
| 3342 | if (err) | 3364 | if (err) |
| 3343 | *bad_wr = ib_wr; | 3365 | *bad_wr = ib_wr; |
| @@ -3368,7 +3390,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
| 3368 | if (nesqp->ibqp_state > IB_QPS_RTS) | 3390 | if (nesqp->ibqp_state > IB_QPS_RTS) |
| 3369 | return -EINVAL; | 3391 | return -EINVAL; |
| 3370 | 3392 | ||
| 3371 | spin_lock_irqsave(&nesqp->lock, flags); | 3393 | spin_lock_irqsave(&nesqp->lock, flags); |
| 3372 | 3394 | ||
| 3373 | head = nesqp->hwqp.rq_head; | 3395 | head = nesqp->hwqp.rq_head; |
| 3374 | 3396 | ||
| @@ -3421,7 +3443,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
| 3421 | nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter<<24) | nesqp->hwqp.qp_id); | 3443 | nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter<<24) | nesqp->hwqp.qp_id); |
| 3422 | } | 3444 | } |
| 3423 | 3445 | ||
| 3424 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3446 | spin_unlock_irqrestore(&nesqp->lock, flags); |
| 3425 | 3447 | ||
| 3426 | if (err) | 3448 | if (err) |
| 3427 | *bad_wr = ib_wr; | 3449 | *bad_wr = ib_wr; |
| @@ -3453,7 +3475,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
| 3453 | 3475 | ||
| 3454 | nes_debug(NES_DBG_CQ, "\n"); | 3476 | nes_debug(NES_DBG_CQ, "\n"); |
| 3455 | 3477 | ||
| 3456 | spin_lock_irqsave(&nescq->lock, flags); | 3478 | spin_lock_irqsave(&nescq->lock, flags); |
| 3457 | 3479 | ||
| 3458 | head = nescq->hw_cq.cq_head; | 3480 | head = nescq->hw_cq.cq_head; |
| 3459 | cq_size = nescq->hw_cq.cq_size; | 3481 | cq_size = nescq->hw_cq.cq_size; |
| @@ -3562,7 +3584,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
| 3562 | nes_debug(NES_DBG_CQ, "Reporting %u completions for CQ%u.\n", | 3584 | nes_debug(NES_DBG_CQ, "Reporting %u completions for CQ%u.\n", |
| 3563 | cqe_count, nescq->hw_cq.cq_number); | 3585 | cqe_count, nescq->hw_cq.cq_number); |
| 3564 | 3586 | ||
| 3565 | spin_unlock_irqrestore(&nescq->lock, flags); | 3587 | spin_unlock_irqrestore(&nescq->lock, flags); |
| 3566 | 3588 | ||
| 3567 | return cqe_count; | 3589 | return cqe_count; |
| 3568 | } | 3590 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index fddded7900d1..85257f6b9576 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -106,12 +106,13 @@ int ipoib_open(struct net_device *dev) | |||
| 106 | 106 | ||
| 107 | ipoib_dbg(priv, "bringing up interface\n"); | 107 | ipoib_dbg(priv, "bringing up interface\n"); |
| 108 | 108 | ||
| 109 | napi_enable(&priv->napi); | ||
| 110 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
| 111 | 110 | ||
| 112 | if (ipoib_pkey_dev_delay_open(dev)) | 111 | if (ipoib_pkey_dev_delay_open(dev)) |
| 113 | return 0; | 112 | return 0; |
| 114 | 113 | ||
| 114 | napi_enable(&priv->napi); | ||
| 115 | |||
| 115 | if (ipoib_ib_dev_open(dev)) { | 116 | if (ipoib_ib_dev_open(dev)) { |
| 116 | napi_disable(&priv->napi); | 117 | napi_disable(&priv->napi); |
| 117 | return -EINVAL; | 118 | return -EINVAL; |
| @@ -546,6 +547,7 @@ static int path_rec_start(struct net_device *dev, | |||
| 546 | if (path->query_id < 0) { | 547 | if (path->query_id < 0) { |
| 547 | ipoib_warn(priv, "ib_sa_path_rec_get failed: %d\n", path->query_id); | 548 | ipoib_warn(priv, "ib_sa_path_rec_get failed: %d\n", path->query_id); |
| 548 | path->query = NULL; | 549 | path->query = NULL; |
| 550 | complete(&path->done); | ||
| 549 | return path->query_id; | 551 | return path->query_id; |
| 550 | } | 552 | } |
| 551 | 553 | ||
| @@ -662,7 +664,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
| 662 | skb_push(skb, sizeof *phdr); | 664 | skb_push(skb, sizeof *phdr); |
| 663 | __skb_queue_tail(&path->queue, skb); | 665 | __skb_queue_tail(&path->queue, skb); |
| 664 | 666 | ||
| 665 | if (path_rec_start(dev, path)) { | 667 | if (!path->query && path_rec_start(dev, path)) { |
| 666 | spin_unlock_irqrestore(&priv->lock, flags); | 668 | spin_unlock_irqrestore(&priv->lock, flags); |
| 667 | path_free(dev, path); | 669 | path_free(dev, path); |
| 668 | return; | 670 | return; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 3524bef62be6..1070db330d35 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -235,7 +235,6 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
| 235 | evdev_ungrab(evdev, client); | 235 | evdev_ungrab(evdev, client); |
| 236 | mutex_unlock(&evdev->mutex); | 236 | mutex_unlock(&evdev->mutex); |
| 237 | 237 | ||
| 238 | evdev_fasync(-1, file, 0); | ||
| 239 | evdev_detach_client(evdev, client); | 238 | evdev_detach_client(evdev, client); |
| 240 | kfree(client); | 239 | kfree(client); |
| 241 | 240 | ||
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 6790e975a98c..bc4e40f3ede7 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
| @@ -397,8 +397,9 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
| 397 | { | 397 | { |
| 398 | struct ml_device *ml = dev->ff->private; | 398 | struct ml_device *ml = dev->ff->private; |
| 399 | struct ml_effect_state *state = &ml->states[effect_id]; | 399 | struct ml_effect_state *state = &ml->states[effect_id]; |
| 400 | unsigned long flags; | ||
| 400 | 401 | ||
| 401 | spin_lock_bh(&ml->timer_lock); | 402 | spin_lock_irqsave(&ml->timer_lock, flags); |
| 402 | 403 | ||
| 403 | if (value > 0) { | 404 | if (value > 0) { |
| 404 | debug("initiated play"); | 405 | debug("initiated play"); |
| @@ -424,7 +425,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
| 424 | ml_play_effects(ml); | 425 | ml_play_effects(ml); |
| 425 | } | 426 | } |
| 426 | 427 | ||
| 427 | spin_unlock_bh(&ml->timer_lock); | 428 | spin_unlock_irqrestore(&ml->timer_lock, flags); |
| 428 | 429 | ||
| 429 | return 0; | 430 | return 0; |
| 430 | } | 431 | } |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 65d7077a75a1..a85b1485e774 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -244,7 +244,6 @@ static int joydev_release(struct inode *inode, struct file *file) | |||
| 244 | struct joydev_client *client = file->private_data; | 244 | struct joydev_client *client = file->private_data; |
| 245 | struct joydev *joydev = client->joydev; | 245 | struct joydev *joydev = client->joydev; |
| 246 | 246 | ||
| 247 | joydev_fasync(-1, file, 0); | ||
| 248 | joydev_detach_client(joydev, client); | 247 | joydev_detach_client(joydev, client); |
| 249 | kfree(client); | 248 | kfree(client); |
| 250 | 249 | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 22016ca15351..379b7ff354ec 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -824,7 +824,7 @@ static void atkbd_disconnect(struct serio *serio) | |||
| 824 | atkbd_disable(atkbd); | 824 | atkbd_disable(atkbd); |
| 825 | 825 | ||
| 826 | /* make sure we don't have a command in flight */ | 826 | /* make sure we don't have a command in flight */ |
| 827 | flush_scheduled_work(); | 827 | cancel_delayed_work_sync(&atkbd->event_work); |
| 828 | 828 | ||
| 829 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | 829 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); |
| 830 | input_unregister_device(atkbd->dev); | 830 | input_unregister_device(atkbd->dev); |
| @@ -868,6 +868,22 @@ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) | |||
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | /* | 870 | /* |
| 871 | * Inventec system with broken key release on volume keys | ||
| 872 | */ | ||
| 873 | static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd) | ||
| 874 | { | ||
| 875 | const unsigned int forced_release_keys[] = { | ||
| 876 | 0xae, 0xb0, | ||
| 877 | }; | ||
| 878 | int i; | ||
| 879 | |||
| 880 | if (atkbd->set == 2) | ||
| 881 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
| 882 | __set_bit(forced_release_keys[i], | ||
| 883 | atkbd->force_release_mask); | ||
| 884 | } | ||
| 885 | |||
| 886 | /* | ||
| 871 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 887 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
| 872 | * according to the selected scancode set | 888 | * according to the selected scancode set |
| 873 | */ | 889 | */ |
| @@ -1468,6 +1484,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1468 | .callback = atkbd_setup_fixup, | 1484 | .callback = atkbd_setup_fixup, |
| 1469 | .driver_data = atkbd_hp_keymap_fixup, | 1485 | .driver_data = atkbd_hp_keymap_fixup, |
| 1470 | }, | 1486 | }, |
| 1487 | { | ||
| 1488 | .ident = "Inventec Symphony", | ||
| 1489 | .matches = { | ||
| 1490 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | ||
| 1491 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | ||
| 1492 | }, | ||
| 1493 | .callback = atkbd_setup_fixup, | ||
| 1494 | .driver_data = atkbd_inventec_keymap_fixup, | ||
| 1495 | }, | ||
| 1471 | { } | 1496 | { } |
| 1472 | }; | 1497 | }; |
| 1473 | 1498 | ||
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index bce160f4349b..86457feccfc4 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | static char *phone = "kip1000"; | 43 | static char *phone = "kip1000"; |
| 44 | module_param(phone, charp, S_IRUSR); | 44 | module_param(phone, charp, S_IRUSR); |
| 45 | MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01}"); | 45 | MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01, atcom}"); |
| 46 | 46 | ||
| 47 | enum { | 47 | enum { |
| 48 | /* HID Registers */ | 48 | /* HID Registers */ |
| @@ -258,6 +258,37 @@ static unsigned short keymap_usbph01(int scancode) | |||
| 258 | } | 258 | } |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | /* | ||
| 262 | * Keymap for ATCom AU-100 | ||
| 263 | * http://www.atcom.cn/En_products_AU100.html | ||
| 264 | * http://www.packetizer.com/products/au100/ | ||
| 265 | * http://www.voip-info.org/wiki/view/AU-100 | ||
| 266 | * | ||
| 267 | * Contributed by daniel@gimpelevich.san-francisco.ca.us | ||
| 268 | */ | ||
| 269 | static unsigned short keymap_atcom(int scancode) | ||
| 270 | { | ||
| 271 | switch (scancode) { /* phone key: */ | ||
| 272 | case 0x82: return KEY_NUMERIC_0; /* 0 */ | ||
| 273 | case 0x11: return KEY_NUMERIC_1; /* 1 */ | ||
| 274 | case 0x12: return KEY_NUMERIC_2; /* 2 */ | ||
| 275 | case 0x14: return KEY_NUMERIC_3; /* 3 */ | ||
| 276 | case 0x21: return KEY_NUMERIC_4; /* 4 */ | ||
| 277 | case 0x22: return KEY_NUMERIC_5; /* 5 */ | ||
| 278 | case 0x24: return KEY_NUMERIC_6; /* 6 */ | ||
| 279 | case 0x41: return KEY_NUMERIC_7; /* 7 */ | ||
| 280 | case 0x42: return KEY_NUMERIC_8; /* 8 */ | ||
| 281 | case 0x44: return KEY_NUMERIC_9; /* 9 */ | ||
| 282 | case 0x84: return KEY_NUMERIC_POUND; /* # */ | ||
| 283 | case 0x81: return KEY_NUMERIC_STAR; /* * */ | ||
| 284 | case 0x18: return KEY_ENTER; /* pickup */ | ||
| 285 | case 0x28: return KEY_ESC; /* hangup */ | ||
| 286 | case 0x48: return KEY_LEFT; /* left arrow */ | ||
| 287 | case 0x88: return KEY_RIGHT; /* right arrow */ | ||
| 288 | default: return special_keymap(scancode); | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 261 | static unsigned short (*keymap)(int) = keymap_kip1000; | 292 | static unsigned short (*keymap)(int) = keymap_kip1000; |
| 262 | 293 | ||
| 263 | /* | 294 | /* |
| @@ -840,6 +871,10 @@ static int __init cm109_select_keymap(void) | |||
| 840 | keymap = keymap_usbph01; | 871 | keymap = keymap_usbph01; |
| 841 | printk(KERN_INFO KBUILD_MODNAME ": " | 872 | printk(KERN_INFO KBUILD_MODNAME ": " |
| 842 | "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n"); | 873 | "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n"); |
| 874 | } else if (!strcasecmp(phone, "atcom")) { | ||
| 875 | keymap = keymap_atcom; | ||
| 876 | printk(KERN_INFO KBUILD_MODNAME ": " | ||
| 877 | "Keymap for ATCom AU-100 phone loaded\n"); | ||
| 843 | } else { | 878 | } else { |
| 844 | printk(KERN_ERR KBUILD_MODNAME ": " | 879 | printk(KERN_ERR KBUILD_MODNAME ": " |
| 845 | "Unsupported phone: %s\n", phone); | 880 | "Unsupported phone: %s\n", phone); |
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 82ec6b1b6467..216a559f55ea 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c | |||
| @@ -71,7 +71,6 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, | |||
| 71 | static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); | 71 | static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); |
| 72 | 72 | ||
| 73 | static int hp_sdc_rtc_open(struct inode *inode, struct file *file); | 73 | static int hp_sdc_rtc_open(struct inode *inode, struct file *file); |
| 74 | static int hp_sdc_rtc_release(struct inode *inode, struct file *file); | ||
| 75 | static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on); | 74 | static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on); |
| 76 | 75 | ||
| 77 | static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, | 76 | static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, |
| @@ -414,17 +413,6 @@ static int hp_sdc_rtc_open(struct inode *inode, struct file *file) | |||
| 414 | return 0; | 413 | return 0; |
| 415 | } | 414 | } |
| 416 | 415 | ||
| 417 | static int hp_sdc_rtc_release(struct inode *inode, struct file *file) | ||
| 418 | { | ||
| 419 | /* Turn off interrupts? */ | ||
| 420 | |||
| 421 | if (file->f_flags & FASYNC) { | ||
| 422 | hp_sdc_rtc_fasync (-1, file, 0); | ||
| 423 | } | ||
| 424 | |||
| 425 | return 0; | ||
| 426 | } | ||
| 427 | |||
| 428 | static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on) | 416 | static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on) |
| 429 | { | 417 | { |
| 430 | return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue); | 418 | return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue); |
| @@ -680,7 +668,6 @@ static const struct file_operations hp_sdc_rtc_fops = { | |||
| 680 | .poll = hp_sdc_rtc_poll, | 668 | .poll = hp_sdc_rtc_poll, |
| 681 | .ioctl = hp_sdc_rtc_ioctl, | 669 | .ioctl = hp_sdc_rtc_ioctl, |
| 682 | .open = hp_sdc_rtc_open, | 670 | .open = hp_sdc_rtc_open, |
| 683 | .release = hp_sdc_rtc_release, | ||
| 684 | .fasync = hp_sdc_rtc_fasync, | 671 | .fasync = hp_sdc_rtc_fasync, |
| 685 | }; | 672 | }; |
| 686 | 673 | ||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index e82d34201e97..88f04bf2ad6c 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
| @@ -125,7 +125,7 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
| 125 | */ | 125 | */ |
| 126 | static int hgpk_validate_byte(unsigned char *packet) | 126 | static int hgpk_validate_byte(unsigned char *packet) |
| 127 | { | 127 | { |
| 128 | return (packet[0] & 0x0C) == 0x08; | 128 | return (packet[0] & 0x0C) != 0x08; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | static void hgpk_process_packet(struct psmouse *psmouse) | 131 | static void hgpk_process_packet(struct psmouse *psmouse) |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 8137e50ded87..d8c056fe7e98 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -519,7 +519,6 @@ static int mousedev_release(struct inode *inode, struct file *file) | |||
| 519 | struct mousedev_client *client = file->private_data; | 519 | struct mousedev_client *client = file->private_data; |
| 520 | struct mousedev *mousedev = client->mousedev; | 520 | struct mousedev *mousedev = client->mousedev; |
| 521 | 521 | ||
| 522 | mousedev_fasync(-1, file, 0); | ||
| 523 | mousedev_detach_client(mousedev, client); | 522 | mousedev_detach_client(mousedev, client); |
| 524 | kfree(client); | 523 | kfree(client); |
| 525 | 524 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index eec375cd10e6..29e686388a2c 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -337,6 +337,20 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
| 337 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), | 337 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), |
| 338 | }, | 338 | }, |
| 339 | }, | 339 | }, |
| 340 | { | ||
| 341 | .ident = "Dell XPS M1530", | ||
| 342 | .matches = { | ||
| 343 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 344 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), | ||
| 345 | }, | ||
| 346 | }, | ||
| 347 | { | ||
| 348 | .ident = "Compal HEL80I", | ||
| 349 | .matches = { | ||
| 350 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), | ||
| 351 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), | ||
| 352 | }, | ||
| 353 | }, | ||
| 340 | { } | 354 | { } |
| 341 | }; | 355 | }; |
| 342 | 356 | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 470770c09260..06bbd0e74c6f 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
| @@ -135,7 +135,6 @@ static int serio_raw_release(struct inode *inode, struct file *file) | |||
| 135 | 135 | ||
| 136 | mutex_lock(&serio_raw_mutex); | 136 | mutex_lock(&serio_raw_mutex); |
| 137 | 137 | ||
| 138 | serio_raw_fasync(-1, file, 0); | ||
| 139 | serio_raw_cleanup(serio_raw); | 138 | serio_raw_cleanup(serio_raw); |
| 140 | 139 | ||
| 141 | mutex_unlock(&serio_raw_mutex); | 140 | mutex_unlock(&serio_raw_mutex); |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index ca62ec639f8f..677680e9f54f 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
| @@ -66,6 +66,7 @@ | |||
| 66 | * - Support Intuos3 4x6 | 66 | * - Support Intuos3 4x6 |
| 67 | * v1.47 (pc) - Added support for Bamboo | 67 | * v1.47 (pc) - Added support for Bamboo |
| 68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX | 68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX |
| 69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) | ||
| 69 | */ | 70 | */ |
| 70 | 71 | ||
| 71 | /* | 72 | /* |
| @@ -86,7 +87,7 @@ | |||
| 86 | /* | 87 | /* |
| 87 | * Version Information | 88 | * Version Information |
| 88 | */ | 89 | */ |
| 89 | #define DRIVER_VERSION "v1.48" | 90 | #define DRIVER_VERSION "v1.49" |
| 90 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 91 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
| 91 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 92 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
| 92 | #define DRIVER_LICENSE "GPL" | 93 | #define DRIVER_LICENSE "GPL" |
| @@ -103,15 +104,15 @@ struct wacom { | |||
| 103 | struct usb_device *usbdev; | 104 | struct usb_device *usbdev; |
| 104 | struct usb_interface *intf; | 105 | struct usb_interface *intf; |
| 105 | struct urb *irq; | 106 | struct urb *irq; |
| 106 | struct wacom_wac * wacom_wac; | 107 | struct wacom_wac *wacom_wac; |
| 107 | struct mutex lock; | 108 | struct mutex lock; |
| 108 | unsigned int open:1; | 109 | unsigned int open:1; |
| 109 | char phys[32]; | 110 | char phys[32]; |
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | struct wacom_combo { | 113 | struct wacom_combo { |
| 113 | struct wacom * wacom; | 114 | struct wacom *wacom; |
| 114 | struct urb * urb; | 115 | struct urb *urb; |
| 115 | }; | 116 | }; |
| 116 | 117 | ||
| 117 | extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); | 118 | extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); |
| @@ -132,7 +133,7 @@ extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wa | |||
| 132 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 133 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
| 133 | extern __u16 wacom_le16_to_cpu(unsigned char *data); | 134 | extern __u16 wacom_le16_to_cpu(unsigned char *data); |
| 134 | extern __u16 wacom_be16_to_cpu(unsigned char *data); | 135 | extern __u16 wacom_be16_to_cpu(unsigned char *data); |
| 135 | extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); | 136 | extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id); |
| 136 | extern const struct usb_device_id * get_device_table(void); | 137 | extern const struct usb_device_id *get_device_table(void); |
| 137 | 138 | ||
| 138 | #endif | 139 | #endif |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 09e227aa0d49..484496daa0f3 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
| @@ -14,8 +14,41 @@ | |||
| 14 | #include "wacom.h" | 14 | #include "wacom.h" |
| 15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
| 16 | 16 | ||
| 17 | /* defines to get HID report descriptor */ | ||
| 18 | #define HID_DEVICET_HID (USB_TYPE_CLASS | 0x01) | ||
| 19 | #define HID_DEVICET_REPORT (USB_TYPE_CLASS | 0x02) | ||
| 20 | #define HID_USAGE_UNDEFINED 0x00 | ||
| 21 | #define HID_USAGE_PAGE 0x05 | ||
| 22 | #define HID_USAGE_PAGE_DIGITIZER 0x0d | ||
| 23 | #define HID_USAGE_PAGE_DESKTOP 0x01 | ||
| 24 | #define HID_USAGE 0x09 | ||
| 25 | #define HID_USAGE_X 0x30 | ||
| 26 | #define HID_USAGE_Y 0x31 | ||
| 27 | #define HID_USAGE_X_TILT 0x3d | ||
| 28 | #define HID_USAGE_Y_TILT 0x3e | ||
| 29 | #define HID_USAGE_FINGER 0x22 | ||
| 30 | #define HID_USAGE_STYLUS 0x20 | ||
| 31 | #define HID_COLLECTION 0xc0 | ||
| 32 | |||
| 33 | enum { | ||
| 34 | WCM_UNDEFINED = 0, | ||
| 35 | WCM_DESKTOP, | ||
| 36 | WCM_DIGITIZER, | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct hid_descriptor { | ||
| 40 | struct usb_descriptor_header header; | ||
| 41 | __le16 bcdHID; | ||
| 42 | u8 bCountryCode; | ||
| 43 | u8 bNumDescriptors; | ||
| 44 | u8 bDescriptorType; | ||
| 45 | __le16 wDescriptorLength; | ||
| 46 | } __attribute__ ((packed)); | ||
| 47 | |||
| 48 | /* defines to get/set USB message */ | ||
| 17 | #define USB_REQ_GET_REPORT 0x01 | 49 | #define USB_REQ_GET_REPORT 0x01 |
| 18 | #define USB_REQ_SET_REPORT 0x09 | 50 | #define USB_REQ_SET_REPORT 0x09 |
| 51 | #define WAC_HID_FEATURE_REPORT 0x03 | ||
| 19 | 52 | ||
| 20 | static int usb_get_report(struct usb_interface *intf, unsigned char type, | 53 | static int usb_get_report(struct usb_interface *intf, unsigned char type, |
| 21 | unsigned char id, void *buf, int size) | 54 | unsigned char id, void *buf, int size) |
| @@ -80,25 +113,21 @@ static void wacom_sys_irq(struct urb *urb) | |||
| 80 | void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) | 113 | void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) |
| 81 | { | 114 | { |
| 82 | input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); | 115 | input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); |
| 83 | return; | ||
| 84 | } | 116 | } |
| 85 | 117 | ||
| 86 | void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) | 118 | void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) |
| 87 | { | 119 | { |
| 88 | input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); | 120 | input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); |
| 89 | return; | ||
| 90 | } | 121 | } |
| 91 | 122 | ||
| 92 | void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) | 123 | void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) |
| 93 | { | 124 | { |
| 94 | input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); | 125 | input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); |
| 95 | return; | ||
| 96 | } | 126 | } |
| 97 | 127 | ||
| 98 | void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) | 128 | void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) |
| 99 | { | 129 | { |
| 100 | input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); | 130 | input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); |
| 101 | return; | ||
| 102 | } | 131 | } |
| 103 | 132 | ||
| 104 | __u16 wacom_be16_to_cpu(unsigned char *data) | 133 | __u16 wacom_be16_to_cpu(unsigned char *data) |
| @@ -118,7 +147,6 @@ __u16 wacom_le16_to_cpu(unsigned char *data) | |||
| 118 | void wacom_input_sync(void *wcombo) | 147 | void wacom_input_sync(void *wcombo) |
| 119 | { | 148 | { |
| 120 | input_sync(get_input_dev((struct wacom_combo *)wcombo)); | 149 | input_sync(get_input_dev((struct wacom_combo *)wcombo)); |
| 121 | return; | ||
| 122 | } | 150 | } |
| 123 | 151 | ||
| 124 | static int wacom_open(struct input_dev *dev) | 152 | static int wacom_open(struct input_dev *dev) |
| @@ -160,7 +188,7 @@ static void wacom_close(struct input_dev *dev) | |||
| 160 | 188 | ||
| 161 | void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 189 | void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| 162 | { | 190 | { |
| 163 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) | | 191 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) | |
| 164 | BIT_MASK(BTN_5); | 192 | BIT_MASK(BTN_5); |
| 165 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 193 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
| 166 | } | 194 | } |
| @@ -170,7 +198,7 @@ void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 170 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); | 198 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); |
| 171 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | 199 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); |
| 172 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | 200 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); |
| 173 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | | 201 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | |
| 174 | BIT_MASK(BTN_4); | 202 | BIT_MASK(BTN_4); |
| 175 | } | 203 | } |
| 176 | 204 | ||
| @@ -178,7 +206,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 178 | { | 206 | { |
| 179 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | 207 | input_dev->evbit[0] |= BIT_MASK(EV_REL); |
| 180 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); | 208 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); |
| 181 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | |
| 182 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | 210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); |
| 183 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
| 184 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); | 212 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); |
| @@ -188,7 +216,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 188 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 216 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| 189 | { | 217 | { |
| 190 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | 218 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); |
| 191 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | | 219 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | |
| 192 | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); | 220 | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); |
| 193 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | 221 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
| 194 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 222 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| @@ -196,14 +224,14 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 196 | 224 | ||
| 197 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 225 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| 198 | { | 226 | { |
| 199 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) | | 227 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | |
| 200 | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); | 228 | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); |
| 201 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | 229 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
| 202 | } | 230 | } |
| 203 | 231 | ||
| 204 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 232 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| 205 | { | 233 | { |
| 206 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); | 234 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); |
| 207 | } | 235 | } |
| 208 | 236 | ||
| 209 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 237 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| @@ -211,7 +239,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 211 | input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); | 239 | input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); |
| 212 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | 240 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); |
| 213 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); | 241 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); |
| 214 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 242 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | |
| 215 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | | 243 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | |
| 216 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | 244 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); |
| 217 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 245 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
| @@ -228,8 +256,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 228 | 256 | ||
| 229 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 257 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| 230 | { | 258 | { |
| 231 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) | | 259 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); |
| 232 | BIT_MASK(BTN_TOOL_RUBBER); | ||
| 233 | } | 260 | } |
| 234 | 261 | ||
| 235 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 262 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| @@ -237,15 +264,129 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 237 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); | 264 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); |
| 238 | } | 265 | } |
| 239 | 266 | ||
| 267 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | ||
| 268 | struct wacom_wac *wacom_wac) | ||
| 269 | { | ||
| 270 | struct usb_device *dev = interface_to_usbdev(intf); | ||
| 271 | struct wacom_features *features = wacom_wac->features; | ||
| 272 | char limit = 0, result = 0; | ||
| 273 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; | ||
| 274 | unsigned char *report; | ||
| 275 | |||
| 276 | report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); | ||
| 277 | if (!report) | ||
| 278 | return -ENOMEM; | ||
| 279 | |||
| 280 | /* retrive report descriptors */ | ||
| 281 | do { | ||
| 282 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
| 283 | USB_REQ_GET_DESCRIPTOR, | ||
| 284 | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
| 285 | HID_DEVICET_REPORT << 8, | ||
| 286 | intf->altsetting[0].desc.bInterfaceNumber, /* interface */ | ||
| 287 | report, | ||
| 288 | hid_desc->wDescriptorLength, | ||
| 289 | 5000); /* 5 secs */ | ||
| 290 | } while (result < 0 && limit++ < 5); | ||
| 291 | |||
| 292 | if (result < 0) | ||
| 293 | goto out; | ||
| 294 | |||
| 295 | for (i = 0; i < hid_desc->wDescriptorLength; i++) { | ||
| 296 | |||
| 297 | switch (report[i]) { | ||
| 298 | case HID_USAGE_PAGE: | ||
| 299 | switch (report[i + 1]) { | ||
| 300 | case HID_USAGE_PAGE_DIGITIZER: | ||
| 301 | usage = WCM_DIGITIZER; | ||
| 302 | i++; | ||
| 303 | break; | ||
| 304 | |||
| 305 | case HID_USAGE_PAGE_DESKTOP: | ||
| 306 | usage = WCM_DESKTOP; | ||
| 307 | i++; | ||
| 308 | break; | ||
| 309 | } | ||
| 310 | break; | ||
| 311 | |||
| 312 | case HID_USAGE: | ||
| 313 | switch (report[i + 1]) { | ||
| 314 | case HID_USAGE_X: | ||
| 315 | if (usage == WCM_DESKTOP) { | ||
| 316 | if (finger) { | ||
| 317 | features->touch_x_max = | ||
| 318 | features->touch_y_max = | ||
| 319 | wacom_le16_to_cpu(&report[i + 3]); | ||
| 320 | features->x_max = | ||
| 321 | wacom_le16_to_cpu(&report[i + 6]); | ||
| 322 | i += 7; | ||
| 323 | } else if (pen) { | ||
| 324 | features->x_max = | ||
| 325 | wacom_le16_to_cpu(&report[i + 3]); | ||
| 326 | i += 4; | ||
| 327 | } | ||
| 328 | } else if (usage == WCM_DIGITIZER) { | ||
| 329 | /* max pressure isn't reported | ||
| 330 | features->pressure_max = (unsigned short) | ||
| 331 | (report[i+4] << 8 | report[i + 3]); | ||
| 332 | */ | ||
| 333 | features->pressure_max = 255; | ||
| 334 | i += 4; | ||
| 335 | } | ||
| 336 | break; | ||
| 337 | |||
| 338 | case HID_USAGE_Y: | ||
| 339 | if (usage == WCM_DESKTOP) | ||
| 340 | features->y_max = | ||
| 341 | wacom_le16_to_cpu(&report[i + 3]); | ||
| 342 | i += 4; | ||
| 343 | break; | ||
| 344 | |||
| 345 | case HID_USAGE_FINGER: | ||
| 346 | finger = 1; | ||
| 347 | i++; | ||
| 348 | break; | ||
| 349 | |||
| 350 | case HID_USAGE_STYLUS: | ||
| 351 | pen = 1; | ||
| 352 | i++; | ||
| 353 | break; | ||
| 354 | |||
| 355 | case HID_USAGE_UNDEFINED: | ||
| 356 | if (usage == WCM_DESKTOP && finger) /* capacity */ | ||
| 357 | features->pressure_max = | ||
| 358 | wacom_le16_to_cpu(&report[i + 3]); | ||
| 359 | i += 4; | ||
| 360 | break; | ||
| 361 | } | ||
| 362 | break; | ||
| 363 | |||
| 364 | case HID_COLLECTION: | ||
| 365 | /* reset UsagePage ans Finger */ | ||
| 366 | finger = usage = 0; | ||
| 367 | break; | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | result = 0; | ||
| 372 | |||
| 373 | out: | ||
| 374 | kfree(report); | ||
| 375 | return result; | ||
| 376 | } | ||
| 377 | |||
| 240 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 378 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| 241 | { | 379 | { |
| 242 | struct usb_device *dev = interface_to_usbdev(intf); | 380 | struct usb_device *dev = interface_to_usbdev(intf); |
| 381 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
| 243 | struct usb_endpoint_descriptor *endpoint; | 382 | struct usb_endpoint_descriptor *endpoint; |
| 244 | struct wacom *wacom; | 383 | struct wacom *wacom; |
| 245 | struct wacom_wac *wacom_wac; | 384 | struct wacom_wac *wacom_wac; |
| 385 | struct wacom_features *features; | ||
| 246 | struct input_dev *input_dev; | 386 | struct input_dev *input_dev; |
| 247 | int error = -ENOMEM; | 387 | int error = -ENOMEM; |
| 248 | char rep_data[2], limit = 0; | 388 | char rep_data[2], limit = 0; |
| 389 | struct hid_descriptor *hid_desc; | ||
| 249 | 390 | ||
| 250 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 391 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
| 251 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); | 392 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); |
| @@ -268,8 +409,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 268 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); | 409 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); |
| 269 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 410 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
| 270 | 411 | ||
| 271 | wacom_wac->features = get_wacom_feature(id); | 412 | wacom_wac->features = features = get_wacom_feature(id); |
| 272 | BUG_ON(wacom_wac->features->pktlen > 10); | 413 | BUG_ON(features->pktlen > 10); |
| 273 | 414 | ||
| 274 | input_dev->name = wacom_wac->features->name; | 415 | input_dev->name = wacom_wac->features->name; |
| 275 | wacom->wacom_wac = wacom_wac; | 416 | wacom->wacom_wac = wacom_wac; |
| @@ -282,18 +423,37 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 282 | input_dev->open = wacom_open; | 423 | input_dev->open = wacom_open; |
| 283 | input_dev->close = wacom_close; | 424 | input_dev->close = wacom_close; |
| 284 | 425 | ||
| 426 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | ||
| 427 | |||
| 428 | /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ | ||
| 429 | if (wacom_wac->features->type == TABLETPC) { | ||
| 430 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | ||
| 431 | if (usb_get_extra_descriptor(&interface->endpoint[0], | ||
| 432 | HID_DEVICET_REPORT, &hid_desc)) { | ||
| 433 | printk("wacom: can not retrive extra class descriptor\n"); | ||
| 434 | goto fail2; | ||
| 435 | } | ||
| 436 | } | ||
| 437 | error = wacom_parse_hid(intf, hid_desc, wacom_wac); | ||
| 438 | if (error) | ||
| 439 | goto fail2; | ||
| 440 | } | ||
| 441 | |||
| 285 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 442 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
| 286 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | 443 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | |
| 287 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); | 444 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); |
| 288 | input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); | 445 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); |
| 289 | input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); | 446 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); |
| 290 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); | 447 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); |
| 448 | if (features->type == TABLETPC) { | ||
| 449 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
| 450 | input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); | ||
| 451 | input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); | ||
| 452 | } | ||
| 291 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 453 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
| 292 | 454 | ||
| 293 | wacom_init_input_dev(input_dev, wacom_wac); | 455 | wacom_init_input_dev(input_dev, wacom_wac); |
| 294 | 456 | ||
| 295 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | ||
| 296 | |||
| 297 | usb_fill_int_urb(wacom->irq, dev, | 457 | usb_fill_int_urb(wacom->irq, dev, |
| 298 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 458 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
| 299 | wacom_wac->data, wacom_wac->features->pktlen, | 459 | wacom_wac->data, wacom_wac->features->pktlen, |
| @@ -305,13 +465,22 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 305 | if (error) | 465 | if (error) |
| 306 | goto fail3; | 466 | goto fail3; |
| 307 | 467 | ||
| 308 | /* Ask the tablet to report tablet data. Repeat until it succeeds */ | 468 | /* |
| 309 | do { | 469 | * Ask the tablet to report tablet data if it is not a Tablet PC. |
| 310 | rep_data[0] = 2; | 470 | * Repeat until it succeeds |
| 311 | rep_data[1] = 2; | 471 | */ |
| 312 | usb_set_report(intf, 3, 2, rep_data, 2); | 472 | if (wacom_wac->features->type != TABLETPC) { |
| 313 | usb_get_report(intf, 3, 2, rep_data, 2); | 473 | do { |
| 314 | } while (rep_data[1] != 2 && limit++ < 5); | 474 | rep_data[0] = 2; |
| 475 | rep_data[1] = 2; | ||
| 476 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
| 477 | 2, rep_data, 2); | ||
| 478 | if (error >= 0) | ||
| 479 | error = usb_get_report(intf, | ||
| 480 | WAC_HID_FEATURE_REPORT, 2, | ||
| 481 | rep_data, 2); | ||
| 482 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | ||
| 483 | } | ||
| 315 | 484 | ||
| 316 | usb_set_intfdata(intf, wacom); | 485 | usb_set_intfdata(intf, wacom); |
| 317 | return 0; | 486 | return 0; |
| @@ -333,7 +502,8 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
| 333 | usb_kill_urb(wacom->irq); | 502 | usb_kill_urb(wacom->irq); |
| 334 | input_unregister_device(wacom->dev); | 503 | input_unregister_device(wacom->dev); |
| 335 | usb_free_urb(wacom->irq); | 504 | usb_free_urb(wacom->irq); |
| 336 | usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); | 505 | usb_buffer_free(interface_to_usbdev(intf), 10, |
| 506 | wacom->wacom_wac->data, wacom->data_dma); | ||
| 337 | kfree(wacom->wacom_wac); | 507 | kfree(wacom->wacom_wac); |
| 338 | kfree(wacom); | 508 | kfree(wacom); |
| 339 | } | 509 | } |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index bf3d9a8b2c1b..8dc8d1e59bea 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -535,31 +535,147 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 535 | return 1; | 535 | return 1; |
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | ||
| 539 | { | ||
| 540 | char *data = wacom->data; | ||
| 541 | int prox = 0, pressure; | ||
| 542 | static int stylusInProx, touchInProx = 1, touchOut; | ||
| 543 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | ||
| 544 | |||
| 545 | dbg("wacom_tpc_irq: received report #%d", data[0]); | ||
| 546 | |||
| 547 | if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ | ||
| 548 | if (urb->actual_length == 5) { /* with touch */ | ||
| 549 | prox = data[0] & 0x03; | ||
| 550 | } else { /* with capacity */ | ||
| 551 | prox = data[1] & 0x03; | ||
| 552 | } | ||
| 553 | |||
| 554 | if (!stylusInProx) { /* stylus not in prox */ | ||
| 555 | if (prox) { | ||
| 556 | if (touchInProx) { | ||
| 557 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | ||
| 558 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
| 559 | if (urb->actual_length != 5) { | ||
| 560 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
| 561 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
| 562 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
| 563 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
| 564 | } else { | ||
| 565 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
| 566 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
| 567 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
| 568 | } | ||
| 569 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
| 570 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | ||
| 571 | touchOut = 1; | ||
| 572 | return 1; | ||
| 573 | } | ||
| 574 | } else { | ||
| 575 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
| 576 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | ||
| 577 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
| 578 | touchOut = 0; | ||
| 579 | touchInProx = 1; | ||
| 580 | return 1; | ||
| 581 | } | ||
| 582 | } else if (touchOut || !prox) { /* force touch out-prox */ | ||
| 583 | wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); | ||
| 584 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
| 585 | touchOut = 0; | ||
| 586 | touchInProx = 1; | ||
| 587 | return 1; | ||
| 588 | } | ||
| 589 | } else if (data[0] == 2) { /* Penabled */ | ||
| 590 | prox = data[1] & 0x20; | ||
| 591 | |||
| 592 | touchInProx = 0; | ||
| 593 | |||
| 594 | wacom->id[0] = ERASER_DEVICE_ID; | ||
| 595 | |||
| 596 | /* | ||
| 597 | * if going from out of proximity into proximity select between the eraser | ||
| 598 | * and the pen based on the state of the stylus2 button, choose eraser if | ||
| 599 | * pressed else choose pen. if not a proximity change from out to in, send | ||
| 600 | * an out of proximity for previous tool then a in for new tool. | ||
| 601 | */ | ||
| 602 | if (prox) { /* in prox */ | ||
| 603 | if (!wacom->tool[0]) { | ||
| 604 | /* Going into proximity select tool */ | ||
| 605 | wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
| 606 | if (wacom->tool[1] == BTN_TOOL_PEN) | ||
| 607 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
| 608 | } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { | ||
| 609 | /* | ||
| 610 | * was entered with stylus2 pressed | ||
| 611 | * report out proximity for previous tool | ||
| 612 | */ | ||
| 613 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
| 614 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
| 615 | wacom_input_sync(wcombo); | ||
| 616 | |||
| 617 | /* set new tool */ | ||
| 618 | wacom->tool[1] = BTN_TOOL_PEN; | ||
| 619 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
| 620 | return 0; | ||
| 621 | } | ||
| 622 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | ||
| 623 | /* Unknown tool selected default to pen tool */ | ||
| 624 | wacom->tool[1] = BTN_TOOL_PEN; | ||
| 625 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
| 626 | } | ||
| 627 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | ||
| 628 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | ||
| 629 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
| 630 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
| 631 | pressure = ((data[7] & 0x01) << 8) | data[6]; | ||
| 632 | if (pressure < 0) | ||
| 633 | pressure = wacom->features->pressure_max + pressure + 1; | ||
| 634 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | ||
| 635 | wacom_report_key(wcombo, BTN_TOUCH, pressure); | ||
| 636 | } else { | ||
| 637 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
| 638 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
| 639 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
| 640 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
| 641 | } | ||
| 642 | wacom_report_key(wcombo, wacom->tool[1], prox); | ||
| 643 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
| 644 | stylusInProx = prox; | ||
| 645 | wacom->tool[0] = prox; | ||
| 646 | return 1; | ||
| 647 | } | ||
| 648 | return 0; | ||
| 649 | } | ||
| 650 | |||
| 538 | int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | 651 | int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) |
| 539 | { | 652 | { |
| 540 | switch (wacom_wac->features->type) { | 653 | switch (wacom_wac->features->type) { |
| 541 | case PENPARTNER: | 654 | case PENPARTNER: |
| 542 | return (wacom_penpartner_irq(wacom_wac, wcombo)); | 655 | return wacom_penpartner_irq(wacom_wac, wcombo); |
| 543 | break; | 656 | |
| 544 | case PL: | 657 | case PL: |
| 545 | return (wacom_pl_irq(wacom_wac, wcombo)); | 658 | return wacom_pl_irq(wacom_wac, wcombo); |
| 546 | break; | 659 | |
| 547 | case WACOM_G4: | 660 | case WACOM_G4: |
| 548 | case GRAPHIRE: | 661 | case GRAPHIRE: |
| 549 | case WACOM_MO: | 662 | case WACOM_MO: |
| 550 | return (wacom_graphire_irq(wacom_wac, wcombo)); | 663 | return wacom_graphire_irq(wacom_wac, wcombo); |
| 551 | break; | 664 | |
| 552 | case PTU: | 665 | case PTU: |
| 553 | return (wacom_ptu_irq(wacom_wac, wcombo)); | 666 | return wacom_ptu_irq(wacom_wac, wcombo); |
| 554 | break; | 667 | |
| 555 | case INTUOS: | 668 | case INTUOS: |
| 556 | case INTUOS3S: | 669 | case INTUOS3S: |
| 557 | case INTUOS3: | 670 | case INTUOS3: |
| 558 | case INTUOS3L: | 671 | case INTUOS3L: |
| 559 | case CINTIQ: | 672 | case CINTIQ: |
| 560 | case WACOM_BEE: | 673 | case WACOM_BEE: |
| 561 | return (wacom_intuos_irq(wacom_wac, wcombo)); | 674 | return wacom_intuos_irq(wacom_wac, wcombo); |
| 562 | break; | 675 | |
| 676 | case TABLETPC: | ||
| 677 | return wacom_tpc_irq(wacom_wac, wcombo); | ||
| 678 | |||
| 563 | default: | 679 | default: |
| 564 | return 0; | 680 | return 0; |
| 565 | } | 681 | } |
| @@ -586,13 +702,15 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
| 586 | /* fall through */ | 702 | /* fall through */ |
| 587 | case INTUOS3S: | 703 | case INTUOS3S: |
| 588 | input_dev_i3s(input_dev, wacom_wac); | 704 | input_dev_i3s(input_dev, wacom_wac); |
| 705 | /* fall through */ | ||
| 589 | case INTUOS: | 706 | case INTUOS: |
| 590 | input_dev_i(input_dev, wacom_wac); | 707 | input_dev_i(input_dev, wacom_wac); |
| 591 | break; | 708 | break; |
| 592 | case PL: | 709 | case PL: |
| 593 | case PTU: | 710 | case PTU: |
| 711 | case TABLETPC: | ||
| 594 | input_dev_pl(input_dev, wacom_wac); | 712 | input_dev_pl(input_dev, wacom_wac); |
| 595 | break; | 713 | /* fall through */ |
| 596 | case PENPARTNER: | 714 | case PENPARTNER: |
| 597 | input_dev_pt(input_dev, wacom_wac); | 715 | input_dev_pt(input_dev, wacom_wac); |
| 598 | break; | 716 | break; |
| @@ -611,6 +729,7 @@ static struct wacom_features wacom_features[] = { | |||
| 611 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, | 729 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, |
| 612 | { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, | 730 | { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, |
| 613 | { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, | 731 | { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, |
| 732 | { "Wacom Bamboo1 Medium",8, 16704, 12064, 511, 63, GRAPHIRE }, | ||
| 614 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 733 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
| 615 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, | 734 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, |
| 616 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 735 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
| @@ -650,6 +769,10 @@ static struct wacom_features wacom_features[] = { | |||
| 650 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 769 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, |
| 651 | { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, | 770 | { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, |
| 652 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, | 771 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, |
| 772 | { "Wacom DTU1931", 8, 37832, 30305, 511, 0, PL }, | ||
| 773 | { "Wacom ISDv4 90", 8, 26202, 16325, 255, 0, TABLETPC }, | ||
| 774 | { "Wacom ISDv4 93", 8, 26202, 16325, 255, 0, TABLETPC }, | ||
| 775 | { "Wacom ISDv4 9A", 8, 26202, 16325, 255, 0, TABLETPC }, | ||
| 653 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 776 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, |
| 654 | { } | 777 | { } |
| 655 | }; | 778 | }; |
| @@ -665,6 +788,7 @@ static struct usb_device_id wacom_ids[] = { | |||
| 665 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, | 788 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, |
| 666 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, | 789 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, |
| 667 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, | 790 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, |
| 791 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) }, | ||
| 668 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, | 792 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, |
| 669 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, | 793 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, |
| 670 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, | 794 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, |
| @@ -704,18 +828,26 @@ static struct usb_device_id wacom_ids[] = { | |||
| 704 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 828 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, |
| 705 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, | 829 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, |
| 706 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, | 830 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, |
| 831 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) }, | ||
| 832 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, | ||
| 833 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, | ||
| 834 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, | ||
| 707 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 835 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
| 708 | { } | 836 | { } |
| 709 | }; | 837 | }; |
| 710 | 838 | ||
| 711 | const struct usb_device_id * get_device_table(void) { | 839 | const struct usb_device_id *get_device_table(void) |
| 712 | const struct usb_device_id * id_table = wacom_ids; | 840 | { |
| 841 | const struct usb_device_id *id_table = wacom_ids; | ||
| 842 | |||
| 713 | return id_table; | 843 | return id_table; |
| 714 | } | 844 | } |
| 715 | 845 | ||
| 716 | struct wacom_features * get_wacom_feature(const struct usb_device_id * id) { | 846 | struct wacom_features * get_wacom_feature(const struct usb_device_id *id) |
| 847 | { | ||
| 717 | int index = id - wacom_ids; | 848 | int index = id - wacom_ids; |
| 718 | struct wacom_features *wf = &wacom_features[index]; | 849 | struct wacom_features *wf = &wacom_features[index]; |
| 850 | |||
| 719 | return wf; | 851 | return wf; |
| 720 | } | 852 | } |
| 721 | 853 | ||
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 3342bc05847d..f9c8b69673b7 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #define WACOM_WAC_H | 10 | #define WACOM_WAC_H |
| 11 | 11 | ||
| 12 | #define STYLUS_DEVICE_ID 0x02 | 12 | #define STYLUS_DEVICE_ID 0x02 |
| 13 | #define TOUCH_DEVICE_ID 0x03 | ||
| 13 | #define CURSOR_DEVICE_ID 0x06 | 14 | #define CURSOR_DEVICE_ID 0x06 |
| 14 | #define ERASER_DEVICE_ID 0x0A | 15 | #define ERASER_DEVICE_ID 0x0A |
| 15 | #define PAD_DEVICE_ID 0x0F | 16 | #define PAD_DEVICE_ID 0x0F |
| @@ -27,6 +28,7 @@ enum { | |||
| 27 | CINTIQ, | 28 | CINTIQ, |
| 28 | WACOM_BEE, | 29 | WACOM_BEE, |
| 29 | WACOM_MO, | 30 | WACOM_MO, |
| 31 | TABLETPC, | ||
| 30 | MAX_TYPE | 32 | MAX_TYPE |
| 31 | }; | 33 | }; |
| 32 | 34 | ||
| @@ -38,6 +40,8 @@ struct wacom_features { | |||
| 38 | int pressure_max; | 40 | int pressure_max; |
| 39 | int distance_max; | 41 | int distance_max; |
| 40 | int type; | 42 | int type; |
| 43 | int touch_x_max; | ||
| 44 | int touch_y_max; | ||
| 41 | }; | 45 | }; |
| 42 | 46 | ||
| 43 | struct wacom_wac { | 47 | struct wacom_wac { |
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index d20689cdbd5d..8f38c5e55ce6 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
| @@ -262,7 +262,7 @@ static int elo_setup_10(struct elo *elo) | |||
| 262 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 262 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
| 263 | 263 | ||
| 264 | printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, " | 264 | printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, " |
| 265 | "features: %x02x, controller: 0x%02x\n", | 265 | "features: 0x%02x, controller: 0x%02x\n", |
| 266 | elo_types[(packet[1] -'0') & 0x03], | 266 | elo_types[(packet[1] -'0') & 0x03], |
| 267 | packet[5], packet[4], packet[3], packet[7]); | 267 | packet[5], packet[4], packet[3], packet[7]); |
| 268 | 268 | ||
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index 3ab6362f043c..928d2ed8865f 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
| @@ -323,7 +323,7 @@ static struct xenbus_device_id xenkbd_ids[] = { | |||
| 323 | { "" } | 323 | { "" } |
| 324 | }; | 324 | }; |
| 325 | 325 | ||
| 326 | static struct xenbus_driver xenkbd = { | 326 | static struct xenbus_driver xenkbd_driver = { |
| 327 | .name = "vkbd", | 327 | .name = "vkbd", |
| 328 | .owner = THIS_MODULE, | 328 | .owner = THIS_MODULE, |
| 329 | .ids = xenkbd_ids, | 329 | .ids = xenkbd_ids, |
| @@ -342,12 +342,12 @@ static int __init xenkbd_init(void) | |||
| 342 | if (xen_initial_domain()) | 342 | if (xen_initial_domain()) |
| 343 | return -ENODEV; | 343 | return -ENODEV; |
| 344 | 344 | ||
| 345 | return xenbus_register_frontend(&xenkbd); | 345 | return xenbus_register_frontend(&xenkbd_driver); |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static void __exit xenkbd_cleanup(void) | 348 | static void __exit xenkbd_cleanup(void) |
| 349 | { | 349 | { |
| 350 | xenbus_unregister_driver(&xenkbd); | 350 | xenbus_unregister_driver(&xenkbd_driver); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | module_init(xenkbd_init); | 353 | module_init(xenkbd_init); |
diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c index 1e288eeb5e2a..6461a32bc838 100644 --- a/drivers/isdn/hardware/avm/b1isa.c +++ b/drivers/isdn/hardware/avm/b1isa.c | |||
| @@ -233,10 +233,8 @@ static void __exit b1isa_exit(void) | |||
| 233 | int i; | 233 | int i; |
| 234 | 234 | ||
| 235 | for (i = 0; i < MAX_CARDS; i++) { | 235 | for (i = 0; i < MAX_CARDS; i++) { |
| 236 | if (!io[i]) | 236 | if (isa_dev[i].resource[0].start) |
| 237 | break; | 237 | b1isa_remove(&isa_dev[i]); |
| 238 | |||
| 239 | b1isa_remove(&isa_dev[i]); | ||
| 240 | } | 238 | } |
| 241 | unregister_capi_driver(&capi_driver_b1isa); | 239 | unregister_capi_driver(&capi_driver_b1isa); |
| 242 | } | 240 | } |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 84d75a3f5d17..ded9d0baf607 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
| @@ -1213,7 +1213,7 @@ static void HiSax_shiftcards(int idx) | |||
| 1213 | memcpy(&cards[i], &cards[i + 1], sizeof(cards[i])); | 1213 | memcpy(&cards[i], &cards[i + 1], sizeof(cards[i])); |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | static int HiSax_inithardware(int *busy_flag) | 1216 | static int __init HiSax_inithardware(int *busy_flag) |
| 1217 | { | 1217 | { |
| 1218 | int foundcards = 0; | 1218 | int foundcards = 0; |
| 1219 | int i = 0; | 1219 | int i = 0; |
| @@ -1542,7 +1542,9 @@ static void __exit HiSax_exit(void) | |||
| 1542 | printk(KERN_INFO "HiSax module removed\n"); | 1542 | printk(KERN_INFO "HiSax module removed\n"); |
| 1543 | } | 1543 | } |
| 1544 | 1544 | ||
| 1545 | int hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card) | 1545 | #ifdef CONFIG_HOTPLUG |
| 1546 | |||
| 1547 | int __devinit hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card) | ||
| 1546 | { | 1548 | { |
| 1547 | u_char ids[16]; | 1549 | u_char ids[16]; |
| 1548 | int ret = -1; | 1550 | int ret = -1; |
| @@ -1563,6 +1565,8 @@ error: | |||
| 1563 | } | 1565 | } |
| 1564 | 1566 | ||
| 1565 | EXPORT_SYMBOL(hisax_init_pcmcia); | 1567 | EXPORT_SYMBOL(hisax_init_pcmcia); |
| 1568 | #endif | ||
| 1569 | |||
| 1566 | EXPORT_SYMBOL(HiSax_closecard); | 1570 | EXPORT_SYMBOL(HiSax_closecard); |
| 1567 | 1571 | ||
| 1568 | #include "hisax_if.h" | 1572 | #include "hisax_if.h" |
| @@ -1580,6 +1584,11 @@ static void hisax_bc_close(struct BCState *bcs); | |||
| 1580 | static void hisax_bh(struct work_struct *work); | 1584 | static void hisax_bh(struct work_struct *work); |
| 1581 | static void EChannel_proc_rcv(struct hisax_d_if *d_if); | 1585 | static void EChannel_proc_rcv(struct hisax_d_if *d_if); |
| 1582 | 1586 | ||
| 1587 | static int hisax_setup_card_dynamic(struct IsdnCard *card) | ||
| 1588 | { | ||
| 1589 | return 2; | ||
| 1590 | } | ||
| 1591 | |||
| 1583 | int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], | 1592 | int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], |
| 1584 | char *name, int protocol) | 1593 | char *name, int protocol) |
| 1585 | { | 1594 | { |
| @@ -1599,7 +1608,8 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], | |||
| 1599 | cards[i].protocol = protocol; | 1608 | cards[i].protocol = protocol; |
| 1600 | sprintf(id, "%s%d", name, i); | 1609 | sprintf(id, "%s%d", name, i); |
| 1601 | nrcards++; | 1610 | nrcards++; |
| 1602 | retval = checkcard(i, id, NULL, hisax_d_if->owner, hisax_cs_setup_card); | 1611 | retval = checkcard(i, id, NULL, hisax_d_if->owner, |
| 1612 | hisax_setup_card_dynamic); | ||
| 1603 | if (retval == 0) { // yuck | 1613 | if (retval == 0) { // yuck |
| 1604 | cards[i].typ = 0; | 1614 | cards[i].typ = 0; |
| 1605 | nrcards--; | 1615 | nrcards--; |
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c index cfa8fa5e44ab..3f2a0a20c19b 100644 --- a/drivers/isdn/hysdn/hysdn_net.c +++ b/drivers/isdn/hysdn/hysdn_net.c | |||
| @@ -83,12 +83,12 @@ net_open(struct net_device *dev) | |||
| 83 | 83 | ||
| 84 | /* Fill in the MAC-level header (if not already set) */ | 84 | /* Fill in the MAC-level header (if not already set) */ |
| 85 | if (!card->mac_addr[0]) { | 85 | if (!card->mac_addr[0]) { |
| 86 | for (i = 0; i < ETH_ALEN - sizeof(unsigned long); i++) | 86 | for (i = 0; i < ETH_ALEN; i++) |
| 87 | dev->dev_addr[i] = 0xfc; | 87 | dev->dev_addr[i] = 0xfc; |
| 88 | if ((in_dev = dev->ip_ptr) != NULL) { | 88 | if ((in_dev = dev->ip_ptr) != NULL) { |
| 89 | struct in_ifaddr *ifa = in_dev->ifa_list; | 89 | struct in_ifaddr *ifa = in_dev->ifa_list; |
| 90 | if (ifa != NULL) | 90 | if (ifa != NULL) |
| 91 | memcpy(dev->dev_addr + (ETH_ALEN - sizeof(unsigned long)), &ifa->ifa_local, sizeof(unsigned long)); | 91 | memcpy(dev->dev_addr + (ETH_ALEN - sizeof(ifa->ifa_local)), &ifa->ifa_local, sizeof(ifa->ifa_local)); |
| 92 | } | 92 | } |
| 93 | } else | 93 | } else |
| 94 | memcpy(dev->dev_addr, card->mac_addr, ETH_ALEN); | 94 | memcpy(dev->dev_addr, card->mac_addr, ETH_ALEN); |
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index bb904a0a98bd..1bfc55d7a26c 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
| @@ -1641,8 +1641,10 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp) | |||
| 1641 | /* slarp reply, send own ip/netmask; if values are nonsense remote | 1641 | /* slarp reply, send own ip/netmask; if values are nonsense remote |
| 1642 | * should think we are unable to provide it with an address via SLARP */ | 1642 | * should think we are unable to provide it with an address via SLARP */ |
| 1643 | p += put_u32(p, CISCO_SLARP_REPLY); | 1643 | p += put_u32(p, CISCO_SLARP_REPLY); |
| 1644 | p += put_u32(p, addr); // address | 1644 | *(__be32 *)p = addr; // address |
| 1645 | p += put_u32(p, mask); // netmask | 1645 | p += 4; |
| 1646 | *(__be32 *)p = mask; // netmask | ||
| 1647 | p += 4; | ||
| 1646 | p += put_u16(p, 0); // unused | 1648 | p += put_u16(p, 0); // unused |
| 1647 | 1649 | ||
| 1648 | isdn_net_write_super(lp, skb); | 1650 | isdn_net_write_super(lp, skb); |
diff --git a/drivers/leds/leds-hp-disk.c b/drivers/leds/leds-hp-disk.c index 74645ab15660..44fa757d8254 100644 --- a/drivers/leds/leds-hp-disk.c +++ b/drivers/leds/leds-hp-disk.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| 28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
| 29 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
| 30 | #include <linux/version.h> | ||
| 31 | #include <linux/leds.h> | 30 | #include <linux/leds.h> |
| 32 | #include <acpi/acpi_drivers.h> | 31 | #include <acpi/acpi_drivers.h> |
| 33 | 32 | ||
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 2c21d4f25cc8..a98ab72adf95 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c | |||
| @@ -288,7 +288,7 @@ static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) | |||
| 288 | cancel_rearming_delayed_work(&rm->cpu[1].sniffer); | 288 | cancel_rearming_delayed_work(&rm->cpu[1].sniffer); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | static int rackmeter_setup(struct rackmeter *rm) | 291 | static int __devinit rackmeter_setup(struct rackmeter *rm) |
| 292 | { | 292 | { |
| 293 | pr_debug("rackmeter: setting up i2s..\n"); | 293 | pr_debug("rackmeter: setting up i2s..\n"); |
| 294 | rackmeter_setup_i2s(rm); | 294 | rackmeter_setup_i2s(rm); |
| @@ -582,12 +582,12 @@ static struct of_device_id rackmeter_match[] = { | |||
| 582 | { } | 582 | { } |
| 583 | }; | 583 | }; |
| 584 | 584 | ||
| 585 | static struct macio_driver rackmeter_drv = { | 585 | static struct macio_driver rackmeter_driver = { |
| 586 | .name = "rackmeter", | 586 | .name = "rackmeter", |
| 587 | .owner = THIS_MODULE, | 587 | .owner = THIS_MODULE, |
| 588 | .match_table = rackmeter_match, | 588 | .match_table = rackmeter_match, |
| 589 | .probe = rackmeter_probe, | 589 | .probe = rackmeter_probe, |
| 590 | .remove = rackmeter_remove, | 590 | .remove = __devexit_p(rackmeter_remove), |
| 591 | .shutdown = rackmeter_shutdown, | 591 | .shutdown = rackmeter_shutdown, |
| 592 | }; | 592 | }; |
| 593 | 593 | ||
| @@ -596,14 +596,14 @@ static int __init rackmeter_init(void) | |||
| 596 | { | 596 | { |
| 597 | pr_debug("rackmeter_init()\n"); | 597 | pr_debug("rackmeter_init()\n"); |
| 598 | 598 | ||
| 599 | return macio_register_driver(&rackmeter_drv); | 599 | return macio_register_driver(&rackmeter_driver); |
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | static void __exit rackmeter_exit(void) | 602 | static void __exit rackmeter_exit(void) |
| 603 | { | 603 | { |
| 604 | pr_debug("rackmeter_exit()\n"); | 604 | pr_debug("rackmeter_exit()\n"); |
| 605 | 605 | ||
| 606 | macio_unregister_driver(&rackmeter_drv); | 606 | macio_unregister_driver(&rackmeter_driver); |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | module_init(rackmeter_init); | 609 | module_init(rackmeter_init); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 4840733cd903..3d7f4923cd13 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
| @@ -441,13 +441,13 @@ static void process_queued_ios(struct work_struct *work) | |||
| 441 | __choose_pgpath(m); | 441 | __choose_pgpath(m); |
| 442 | 442 | ||
| 443 | pgpath = m->current_pgpath; | 443 | pgpath = m->current_pgpath; |
| 444 | m->pgpath_to_activate = m->current_pgpath; | ||
| 445 | 444 | ||
| 446 | if ((pgpath && !m->queue_io) || | 445 | if ((pgpath && !m->queue_io) || |
| 447 | (!pgpath && !m->queue_if_no_path)) | 446 | (!pgpath && !m->queue_if_no_path)) |
| 448 | must_queue = 0; | 447 | must_queue = 0; |
| 449 | 448 | ||
| 450 | if (m->pg_init_required && !m->pg_init_in_progress) { | 449 | if (m->pg_init_required && !m->pg_init_in_progress && pgpath) { |
| 450 | m->pgpath_to_activate = pgpath; | ||
| 451 | m->pg_init_count++; | 451 | m->pg_init_count++; |
| 452 | m->pg_init_required = 0; | 452 | m->pg_init_required = 0; |
| 453 | m->pg_init_in_progress = 1; | 453 | m->pg_init_in_progress = 1; |
| @@ -708,6 +708,10 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) | |||
| 708 | m->hw_handler_name = NULL; | 708 | m->hw_handler_name = NULL; |
| 709 | return -EINVAL; | 709 | return -EINVAL; |
| 710 | } | 710 | } |
| 711 | |||
| 712 | if (hw_argc > 1) | ||
| 713 | DMWARN("Ignoring user-specified arguments for " | ||
| 714 | "hardware handler \"%s\"", m->hw_handler_name); | ||
| 711 | consume(as, hw_argc - 1); | 715 | consume(as, hw_argc - 1); |
| 712 | 716 | ||
| 713 | return 0; | 717 | return 0; |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 9d7b53ed75b2..ec43f9fa4b2a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
| @@ -1032,6 +1032,7 @@ static void mirror_dtr(struct dm_target *ti) | |||
| 1032 | 1032 | ||
| 1033 | del_timer_sync(&ms->timer); | 1033 | del_timer_sync(&ms->timer); |
| 1034 | flush_workqueue(ms->kmirrord_wq); | 1034 | flush_workqueue(ms->kmirrord_wq); |
| 1035 | flush_scheduled_work(); | ||
| 1035 | dm_kcopyd_client_destroy(ms->kcopyd_client); | 1036 | dm_kcopyd_client_destroy(ms->kcopyd_client); |
| 1036 | destroy_workqueue(ms->kmirrord_wq); | 1037 | destroy_workqueue(ms->kmirrord_wq); |
| 1037 | free_context(ms, ti, ms->nr_mirrors); | 1038 | free_context(ms, ti, ms->nr_mirrors); |
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index a2d068dbe9e2..9e4ef88d421e 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
| @@ -320,8 +320,10 @@ int __init dm_stripe_init(void) | |||
| 320 | int r; | 320 | int r; |
| 321 | 321 | ||
| 322 | r = dm_register_target(&stripe_target); | 322 | r = dm_register_target(&stripe_target); |
| 323 | if (r < 0) | 323 | if (r < 0) { |
| 324 | DMWARN("target registration failed"); | 324 | DMWARN("target registration failed"); |
| 325 | return r; | ||
| 326 | } | ||
| 325 | 327 | ||
| 326 | kstriped = create_singlethread_workqueue("kstriped"); | 328 | kstriped = create_singlethread_workqueue("kstriped"); |
| 327 | if (!kstriped) { | 329 | if (!kstriped) { |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index a63161aec487..04e5fd742c2c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
| @@ -668,7 +668,7 @@ static void check_for_valid_limits(struct io_restrictions *rs) | |||
| 668 | if (!rs->max_segment_size) | 668 | if (!rs->max_segment_size) |
| 669 | rs->max_segment_size = MAX_SEGMENT_SIZE; | 669 | rs->max_segment_size = MAX_SEGMENT_SIZE; |
| 670 | if (!rs->seg_boundary_mask) | 670 | if (!rs->seg_boundary_mask) |
| 671 | rs->seg_boundary_mask = -1; | 671 | rs->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; |
| 672 | if (!rs->bounce_pfn) | 672 | if (!rs->bounce_pfn) |
| 673 | rs->bounce_pfn = -1; | 673 | rs->bounce_pfn = -1; |
| 674 | } | 674 | } |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6963ad148408..c99e4728ff41 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -375,7 +375,7 @@ static void start_io_acct(struct dm_io *io) | |||
| 375 | dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); | 375 | dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | static int end_io_acct(struct dm_io *io) | 378 | static void end_io_acct(struct dm_io *io) |
| 379 | { | 379 | { |
| 380 | struct mapped_device *md = io->md; | 380 | struct mapped_device *md = io->md; |
| 381 | struct bio *bio = io->bio; | 381 | struct bio *bio = io->bio; |
| @@ -391,7 +391,9 @@ static int end_io_acct(struct dm_io *io) | |||
| 391 | dm_disk(md)->part0.in_flight = pending = | 391 | dm_disk(md)->part0.in_flight = pending = |
| 392 | atomic_dec_return(&md->pending); | 392 | atomic_dec_return(&md->pending); |
| 393 | 393 | ||
| 394 | return !pending; | 394 | /* nudge anyone waiting on suspend queue */ |
| 395 | if (!pending) | ||
| 396 | wake_up(&md->wait); | ||
| 395 | } | 397 | } |
| 396 | 398 | ||
| 397 | /* | 399 | /* |
| @@ -499,9 +501,7 @@ static void dec_pending(struct dm_io *io, int error) | |||
| 499 | spin_unlock_irqrestore(&io->md->pushback_lock, flags); | 501 | spin_unlock_irqrestore(&io->md->pushback_lock, flags); |
| 500 | } | 502 | } |
| 501 | 503 | ||
| 502 | if (end_io_acct(io)) | 504 | end_io_acct(io); |
| 503 | /* nudge anyone waiting on suspend queue */ | ||
| 504 | wake_up(&io->md->wait); | ||
| 505 | 505 | ||
| 506 | if (io->error != DM_ENDIO_REQUEUE) { | 506 | if (io->error != DM_ENDIO_REQUEUE) { |
| 507 | blk_add_trace_bio(io->md->queue, io->bio, | 507 | blk_add_trace_bio(io->md->queue, io->bio, |
| @@ -937,16 +937,24 @@ static void dm_unplug_all(struct request_queue *q) | |||
| 937 | 937 | ||
| 938 | static int dm_any_congested(void *congested_data, int bdi_bits) | 938 | static int dm_any_congested(void *congested_data, int bdi_bits) |
| 939 | { | 939 | { |
| 940 | int r; | 940 | int r = bdi_bits; |
| 941 | struct mapped_device *md = (struct mapped_device *) congested_data; | 941 | struct mapped_device *md = congested_data; |
| 942 | struct dm_table *map = dm_get_table(md); | 942 | struct dm_table *map; |
| 943 | 943 | ||
| 944 | if (!map || test_bit(DMF_BLOCK_IO, &md->flags)) | 944 | atomic_inc(&md->pending); |
| 945 | r = bdi_bits; | 945 | |
| 946 | else | 946 | if (!test_bit(DMF_BLOCK_IO, &md->flags)) { |
| 947 | r = dm_table_any_congested(map, bdi_bits); | 947 | map = dm_get_table(md); |
| 948 | if (map) { | ||
| 949 | r = dm_table_any_congested(map, bdi_bits); | ||
| 950 | dm_table_put(map); | ||
| 951 | } | ||
| 952 | } | ||
| 953 | |||
| 954 | if (!atomic_dec_return(&md->pending)) | ||
| 955 | /* nudge anyone waiting on suspend queue */ | ||
| 956 | wake_up(&md->wait); | ||
| 948 | 957 | ||
| 949 | dm_table_put(map); | ||
| 950 | return r; | 958 | return r; |
| 951 | } | 959 | } |
| 952 | 960 | ||
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 190147c79e79..3b90c5c924ec 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
| @@ -148,6 +148,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 148 | 148 | ||
| 149 | min_sectors = conf->array_sectors; | 149 | min_sectors = conf->array_sectors; |
| 150 | sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *)); | 150 | sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *)); |
| 151 | if (min_sectors == 0) | ||
| 152 | min_sectors = 1; | ||
| 151 | 153 | ||
| 152 | /* min_sectors is the minimum spacing that will fit the hash | 154 | /* min_sectors is the minimum spacing that will fit the hash |
| 153 | * table in one PAGE. This may be much smaller than needed. | 155 | * table in one PAGE. This may be much smaller than needed. |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9abf6ed16535..1b1d32694f6f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -3884,7 +3884,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3884 | if (mode == 0) { | 3884 | if (mode == 0) { |
| 3885 | mdk_rdev_t *rdev; | 3885 | mdk_rdev_t *rdev; |
| 3886 | struct list_head *tmp; | 3886 | struct list_head *tmp; |
| 3887 | struct block_device *bdev; | ||
| 3888 | 3887 | ||
| 3889 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); | 3888 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); |
| 3890 | 3889 | ||
| @@ -3941,11 +3940,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3941 | mddev->degraded = 0; | 3940 | mddev->degraded = 0; |
| 3942 | mddev->barriers_work = 0; | 3941 | mddev->barriers_work = 0; |
| 3943 | mddev->safemode = 0; | 3942 | mddev->safemode = 0; |
| 3944 | bdev = bdget_disk(mddev->gendisk, 0); | ||
| 3945 | if (bdev) { | ||
| 3946 | blkdev_ioctl(bdev, 0, BLKRRPART, 0); | ||
| 3947 | bdput(bdev); | ||
| 3948 | } | ||
| 3949 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); | 3943 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); |
| 3950 | 3944 | ||
| 3951 | } else if (mddev->pers) | 3945 | } else if (mddev->pers) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index da5129a24b18..970a96ef9b18 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -1137,7 +1137,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1137 | if (!enough(conf)) | 1137 | if (!enough(conf)) |
| 1138 | return -EINVAL; | 1138 | return -EINVAL; |
| 1139 | 1139 | ||
| 1140 | if (rdev->raid_disk) | 1140 | if (rdev->raid_disk >= 0) |
| 1141 | first = last = rdev->raid_disk; | 1141 | first = last = rdev->raid_disk; |
| 1142 | 1142 | ||
| 1143 | if (rdev->saved_raid_disk >= 0 && | 1143 | if (rdev->saved_raid_disk >= 0 && |
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 14e627ef6465..c1d92f838ca8 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
| @@ -376,7 +376,7 @@ static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb) | |||
| 376 | pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr); | 376 | pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr); |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | static void __devinit dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb) | 379 | static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb) |
| 380 | { | 380 | { |
| 381 | outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK)); | 381 | outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK)); |
| 382 | outb(1, dm_io_mem(DM1105_CR)); | 382 | outb(1, dm_io_mem(DM1105_CR)); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 5689d1f1d444..7a421e9dba5a 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
| @@ -223,6 +223,8 @@ static void dvb_frontend_init(struct dvb_frontend *fe) | |||
| 223 | if (fe->ops.init) | 223 | if (fe->ops.init) |
| 224 | fe->ops.init(fe); | 224 | fe->ops.init(fe); |
| 225 | if (fe->ops.tuner_ops.init) { | 225 | if (fe->ops.tuner_ops.init) { |
| 226 | if (fe->ops.i2c_gate_ctrl) | ||
| 227 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 226 | fe->ops.tuner_ops.init(fe); | 228 | fe->ops.tuner_ops.init(fe); |
| 227 | if (fe->ops.i2c_gate_ctrl) | 229 | if (fe->ops.i2c_gate_ctrl) |
| 228 | fe->ops.i2c_gate_ctrl(fe, 0); | 230 | fe->ops.i2c_gate_ctrl(fe, 0); |
| @@ -583,6 +585,8 @@ restart: | |||
| 583 | if (fe->ops.set_voltage) | 585 | if (fe->ops.set_voltage) |
| 584 | fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); | 586 | fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); |
| 585 | if (fe->ops.tuner_ops.sleep) { | 587 | if (fe->ops.tuner_ops.sleep) { |
| 588 | if (fe->ops.i2c_gate_ctrl) | ||
| 589 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 586 | fe->ops.tuner_ops.sleep(fe); | 590 | fe->ops.tuner_ops.sleep(fe); |
| 587 | if (fe->ops.i2c_gate_ctrl) | 591 | if (fe->ops.i2c_gate_ctrl) |
| 588 | fe->ops.i2c_gate_ctrl(fe, 0); | 592 | fe->ops.i2c_gate_ctrl(fe, 0); |
| @@ -932,7 +936,8 @@ void dtv_property_dump(struct dtv_property *tvp) | |||
| 932 | int is_legacy_delivery_system(fe_delivery_system_t s) | 936 | int is_legacy_delivery_system(fe_delivery_system_t s) |
| 933 | { | 937 | { |
| 934 | if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || | 938 | if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || |
| 935 | (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS)) | 939 | (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) || |
| 940 | (s == SYS_ATSC)) | ||
| 936 | return 1; | 941 | return 1; |
| 937 | 942 | ||
| 938 | return 0; | 943 | return 0; |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3c13bcfa6385..62b68c291d99 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
| @@ -261,7 +261,7 @@ config DVB_USB_DW2102 | |||
| 261 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers | 261 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers |
| 262 | and the TeVii S650. | 262 | and the TeVii S650. |
| 263 | 263 | ||
| 264 | config DVB_USB_CINERGY_T2 | 264 | config DVB_USB_CINERGY_T2 |
| 265 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" | 265 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" |
| 266 | depends on DVB_USB | 266 | depends on DVB_USB |
| 267 | help | 267 | help |
| @@ -283,6 +283,7 @@ config DVB_USB_ANYSEE | |||
| 283 | config DVB_USB_DTV5100 | 283 | config DVB_USB_DTV5100 |
| 284 | tristate "AME DTV-5100 USB2.0 DVB-T support" | 284 | tristate "AME DTV-5100 USB2.0 DVB-T support" |
| 285 | depends on DVB_USB | 285 | depends on DVB_USB |
| 286 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
| 286 | select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE | 287 | select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE |
| 287 | help | 288 | help |
| 288 | Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. | 289 | Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. |
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index cb0829c038ce..e9ab0249d133 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
| @@ -31,13 +31,13 @@ | |||
| 31 | #include "mc44s80x.h" | 31 | #include "mc44s80x.h" |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | int dvb_usb_af9015_debug; | 34 | static int dvb_usb_af9015_debug; |
| 35 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); | 35 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); |
| 36 | MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); | 36 | MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); |
| 37 | int dvb_usb_af9015_remote; | 37 | static int dvb_usb_af9015_remote; |
| 38 | module_param_named(remote, dvb_usb_af9015_remote, int, 0644); | 38 | module_param_named(remote, dvb_usb_af9015_remote, int, 0644); |
| 39 | MODULE_PARM_DESC(remote, "select remote"); | 39 | MODULE_PARM_DESC(remote, "select remote"); |
| 40 | int dvb_usb_af9015_dual_mode; | 40 | static int dvb_usb_af9015_dual_mode; |
| 41 | module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); | 41 | module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); |
| 42 | MODULE_PARM_DESC(dual_mode, "enable dual mode"); | 42 | MODULE_PARM_DESC(dual_mode, "enable dual mode"); |
| 43 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 43 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
| @@ -46,7 +46,7 @@ static DEFINE_MUTEX(af9015_usb_mutex); | |||
| 46 | 46 | ||
| 47 | static struct af9015_config af9015_config; | 47 | static struct af9015_config af9015_config; |
| 48 | static struct dvb_usb_device_properties af9015_properties[2]; | 48 | static struct dvb_usb_device_properties af9015_properties[2]; |
| 49 | int af9015_properties_count = ARRAY_SIZE(af9015_properties); | 49 | static int af9015_properties_count = ARRAY_SIZE(af9015_properties); |
| 50 | 50 | ||
| 51 | static struct af9013_config af9015_af9013_config[] = { | 51 | static struct af9013_config af9015_af9013_config[] = { |
| 52 | { | 52 | { |
| @@ -549,7 +549,7 @@ static int af9015_eeprom_dump(struct dvb_usb_device *d) | |||
| 549 | return 0; | 549 | return 0; |
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | int af9015_download_ir_table(struct dvb_usb_device *d) | 552 | static int af9015_download_ir_table(struct dvb_usb_device *d) |
| 553 | { | 553 | { |
| 554 | int i, packets = 0, ret; | 554 | int i, packets = 0, ret; |
| 555 | u16 addr = 0x9a56; /* ir-table start address */ | 555 | u16 addr = 0x9a56; /* ir-table start address */ |
| @@ -681,12 +681,6 @@ static int af9015_download_firmware(struct usb_device *udev, | |||
| 681 | goto error; | 681 | goto error; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | /* firmware is running, reconnect device in the usb bus */ | ||
| 685 | req.cmd = RECONNECT_USB; | ||
| 686 | ret = af9015_rw_udev(udev, &req); | ||
| 687 | if (ret) | ||
| 688 | err("reconnect failed: %d", ret); | ||
| 689 | |||
| 690 | error: | 684 | error: |
| 691 | return ret; | 685 | return ret; |
| 692 | } | 686 | } |
| @@ -999,7 +993,7 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
| 999 | } | 993 | } |
| 1000 | 994 | ||
| 1001 | /* init 2nd I2C adapter */ | 995 | /* init 2nd I2C adapter */ |
| 1002 | int af9015_i2c_init(struct dvb_usb_device *d) | 996 | static int af9015_i2c_init(struct dvb_usb_device *d) |
| 1003 | { | 997 | { |
| 1004 | int ret; | 998 | int ret; |
| 1005 | struct af9015_state *state = d->priv; | 999 | struct af9015_state *state = d->priv; |
| @@ -1208,6 +1202,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
| 1208 | .usb_ctrl = DEVICE_SPECIFIC, | 1202 | .usb_ctrl = DEVICE_SPECIFIC, |
| 1209 | .download_firmware = af9015_download_firmware, | 1203 | .download_firmware = af9015_download_firmware, |
| 1210 | .firmware = "dvb-usb-af9015.fw", | 1204 | .firmware = "dvb-usb-af9015.fw", |
| 1205 | .no_reconnect = 1, | ||
| 1211 | 1206 | ||
| 1212 | .size_of_priv = sizeof(struct af9015_state), \ | 1207 | .size_of_priv = sizeof(struct af9015_state), \ |
| 1213 | 1208 | ||
| @@ -1306,6 +1301,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
| 1306 | .usb_ctrl = DEVICE_SPECIFIC, | 1301 | .usb_ctrl = DEVICE_SPECIFIC, |
| 1307 | .download_firmware = af9015_download_firmware, | 1302 | .download_firmware = af9015_download_firmware, |
| 1308 | .firmware = "dvb-usb-af9015.fw", | 1303 | .firmware = "dvb-usb-af9015.fw", |
| 1304 | .no_reconnect = 1, | ||
| 1309 | 1305 | ||
| 1310 | .size_of_priv = sizeof(struct af9015_state), \ | 1306 | .size_of_priv = sizeof(struct af9015_state), \ |
| 1311 | 1307 | ||
| @@ -1419,7 +1415,7 @@ static int af9015_usb_probe(struct usb_interface *intf, | |||
| 1419 | return ret; | 1415 | return ret; |
| 1420 | } | 1416 | } |
| 1421 | 1417 | ||
| 1422 | void af9015_i2c_exit(struct dvb_usb_device *d) | 1418 | static void af9015_i2c_exit(struct dvb_usb_device *d) |
| 1423 | { | 1419 | { |
| 1424 | struct af9015_state *state = d->priv; | 1420 | struct af9015_state *state = d->priv; |
| 1425 | deb_info("%s: \n", __func__); | 1421 | deb_info("%s: \n", __func__); |
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 882e8a4b3681..6c3c97293316 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #define DVB_USB_LOG_PREFIX "af9015" | 27 | #define DVB_USB_LOG_PREFIX "af9015" |
| 28 | #include "dvb-usb.h" | 28 | #include "dvb-usb.h" |
| 29 | 29 | ||
| 30 | extern int dvb_usb_af9015_debug; | ||
| 31 | #define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) | 30 | #define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) |
| 32 | #define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) | 31 | #define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) |
| 33 | #define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) | 32 | #define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) |
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index c786359fba03..cd2edbcaa097 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
| @@ -46,7 +46,7 @@ module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644); | |||
| 46 | MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); | 46 | MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); |
| 47 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 47 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
| 48 | 48 | ||
| 49 | static struct mutex anysee_usb_mutex; | 49 | static DEFINE_MUTEX(anysee_usb_mutex); |
| 50 | 50 | ||
| 51 | static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, | 51 | static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, |
| 52 | u8 *rbuf, u8 rlen) | 52 | u8 *rbuf, u8 rlen) |
| @@ -456,8 +456,6 @@ static int anysee_probe(struct usb_interface *intf, | |||
| 456 | struct usb_host_interface *alt; | 456 | struct usb_host_interface *alt; |
| 457 | int ret; | 457 | int ret; |
| 458 | 458 | ||
| 459 | mutex_init(&anysee_usb_mutex); | ||
| 460 | |||
| 461 | /* There is one interface with two alternate settings. | 459 | /* There is one interface with two alternate settings. |
| 462 | Alternate setting 0 is for bulk transfer. | 460 | Alternate setting 0 is for bulk transfer. |
| 463 | Alternate setting 1 is for isochronous transfer. | 461 | Alternate setting 1 is for isochronous transfer. |
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 739193943c17..8b544fe79b0d 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
| @@ -22,7 +22,7 @@ extern int dvb_usb_dib0700_debug; | |||
| 22 | 22 | ||
| 23 | #define REQUEST_I2C_READ 0x2 | 23 | #define REQUEST_I2C_READ 0x2 |
| 24 | #define REQUEST_I2C_WRITE 0x3 | 24 | #define REQUEST_I2C_WRITE 0x3 |
| 25 | #define REQUEST_POLL_RC 0x4 | 25 | #define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ |
| 26 | #define REQUEST_JUMPRAM 0x8 | 26 | #define REQUEST_JUMPRAM 0x8 |
| 27 | #define REQUEST_SET_CLOCK 0xB | 27 | #define REQUEST_SET_CLOCK 0xB |
| 28 | #define REQUEST_SET_GPIO 0xC | 28 | #define REQUEST_SET_GPIO 0xC |
| @@ -40,11 +40,14 @@ struct dib0700_state { | |||
| 40 | u16 mt2060_if1[2]; | 40 | u16 mt2060_if1[2]; |
| 41 | u8 rc_toggle; | 41 | u8 rc_toggle; |
| 42 | u8 rc_counter; | 42 | u8 rc_counter; |
| 43 | u8 rc_func_version; | ||
| 43 | u8 is_dib7000pc; | 44 | u8 is_dib7000pc; |
| 44 | u8 fw_use_new_i2c_api; | 45 | u8 fw_use_new_i2c_api; |
| 45 | u8 disable_streaming_master_mode; | 46 | u8 disable_streaming_master_mode; |
| 46 | }; | 47 | }; |
| 47 | 48 | ||
| 49 | extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | ||
| 50 | u32 *romversion, u32 *ramversion, u32 *fwtype); | ||
| 48 | extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); | 51 | extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); |
| 49 | extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); | 52 | extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); |
| 50 | extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); | 53 | extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index dd53cee3896d..200b215f4d8b 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
| @@ -19,6 +19,22 @@ MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (defau | |||
| 19 | 19 | ||
| 20 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 20 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
| 21 | 21 | ||
| 22 | |||
| 23 | int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | ||
| 24 | u32 *romversion, u32 *ramversion, u32 *fwtype) | ||
| 25 | { | ||
| 26 | u8 b[16]; | ||
| 27 | int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), | ||
| 28 | REQUEST_GET_VERSION, | ||
| 29 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | ||
| 30 | b, sizeof(b), USB_CTRL_GET_TIMEOUT); | ||
| 31 | *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; | ||
| 32 | *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; | ||
| 33 | *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; | ||
| 34 | *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; | ||
| 35 | return ret; | ||
| 36 | } | ||
| 37 | |||
| 22 | /* expecting rx buffer: request data[0] data[1] ... data[2] */ | 38 | /* expecting rx buffer: request data[0] data[1] ... data[2] */ |
| 23 | static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen) | 39 | static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen) |
| 24 | { | 40 | { |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 0cfccc24b190..f28d3ae59e04 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
| @@ -38,6 +38,7 @@ static struct mt2060_config bristol_mt2060_config[2] = { | |||
| 38 | } | 38 | } |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | |||
| 41 | static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = { | 42 | static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = { |
| 42 | .band_caps = BAND_VHF | BAND_UHF, | 43 | .band_caps = BAND_VHF | BAND_UHF, |
| 43 | .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0), | 44 | .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0), |
| @@ -451,8 +452,13 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; | |||
| 451 | 452 | ||
| 452 | /* Number of keypresses to ignore before start repeating */ | 453 | /* Number of keypresses to ignore before start repeating */ |
| 453 | #define RC_REPEAT_DELAY 2 | 454 | #define RC_REPEAT_DELAY 2 |
| 455 | #define RC_REPEAT_DELAY_V1_20 5 | ||
| 454 | 456 | ||
| 455 | static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 457 | |
| 458 | |||
| 459 | /* Used by firmware versions < 1.20 (deprecated) */ | ||
| 460 | static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event, | ||
| 461 | int *state) | ||
| 456 | { | 462 | { |
| 457 | u8 key[4]; | 463 | u8 key[4]; |
| 458 | int i; | 464 | int i; |
| @@ -529,6 +535,137 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
| 529 | return 0; | 535 | return 0; |
| 530 | } | 536 | } |
| 531 | 537 | ||
| 538 | /* This is the structure of the RC response packet starting in firmware 1.20 */ | ||
| 539 | struct dib0700_rc_response { | ||
| 540 | u8 report_id; | ||
| 541 | u8 data_state; | ||
| 542 | u8 system_msb; | ||
| 543 | u8 system_lsb; | ||
| 544 | u8 data; | ||
| 545 | u8 not_data; | ||
| 546 | }; | ||
| 547 | |||
| 548 | /* This supports the new IR response format for firmware v1.20 */ | ||
| 549 | static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, | ||
| 550 | int *state) | ||
| 551 | { | ||
| 552 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; | ||
| 553 | struct dib0700_state *st = d->priv; | ||
| 554 | struct dib0700_rc_response poll_reply; | ||
| 555 | u8 buf[6]; | ||
| 556 | int i; | ||
| 557 | int status; | ||
| 558 | int actlen; | ||
| 559 | int found = 0; | ||
| 560 | |||
| 561 | /* Set initial results in case we exit the function early */ | ||
| 562 | *event = 0; | ||
| 563 | *state = REMOTE_NO_KEY_PRESSED; | ||
| 564 | |||
| 565 | /* Firmware v1.20 provides RC data via bulk endpoint 1 */ | ||
| 566 | status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf, | ||
| 567 | sizeof(buf), &actlen, 50); | ||
| 568 | if (status < 0) { | ||
| 569 | /* No data available (meaning no key press) */ | ||
| 570 | return 0; | ||
| 571 | } | ||
| 572 | |||
| 573 | if (actlen != sizeof(buf)) { | ||
| 574 | /* We didn't get back the 6 byte message we expected */ | ||
| 575 | err("Unexpected RC response size [%d]", actlen); | ||
| 576 | return -1; | ||
| 577 | } | ||
| 578 | |||
| 579 | poll_reply.report_id = buf[0]; | ||
| 580 | poll_reply.data_state = buf[1]; | ||
| 581 | poll_reply.system_msb = buf[2]; | ||
| 582 | poll_reply.system_lsb = buf[3]; | ||
| 583 | poll_reply.data = buf[4]; | ||
| 584 | poll_reply.not_data = buf[5]; | ||
| 585 | |||
| 586 | /* | ||
| 587 | info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n", | ||
| 588 | poll_reply.report_id, poll_reply.data_state, | ||
| 589 | poll_reply.system_msb, poll_reply.system_lsb, | ||
| 590 | poll_reply.data, poll_reply.not_data); | ||
| 591 | */ | ||
| 592 | |||
| 593 | if ((poll_reply.data + poll_reply.not_data) != 0xff) { | ||
| 594 | /* Key failed integrity check */ | ||
| 595 | err("key failed integrity check: %02x %02x %02x %02x", | ||
| 596 | poll_reply.system_msb, poll_reply.system_lsb, | ||
| 597 | poll_reply.data, poll_reply.not_data); | ||
| 598 | return -1; | ||
| 599 | } | ||
| 600 | |||
| 601 | /* Find the key in the map */ | ||
| 602 | for (i = 0; i < d->props.rc_key_map_size; i++) { | ||
| 603 | if (keymap[i].custom == poll_reply.system_lsb && | ||
| 604 | keymap[i].data == poll_reply.data) { | ||
| 605 | *event = keymap[i].event; | ||
| 606 | found = 1; | ||
| 607 | break; | ||
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | if (found == 0) { | ||
| 612 | err("Unknown remote controller key: %02x %02x %02x %02x", | ||
| 613 | poll_reply.system_msb, poll_reply.system_lsb, | ||
| 614 | poll_reply.data, poll_reply.not_data); | ||
| 615 | d->last_event = 0; | ||
| 616 | return 0; | ||
| 617 | } | ||
| 618 | |||
| 619 | if (poll_reply.data_state == 1) { | ||
| 620 | /* New key hit */ | ||
| 621 | st->rc_counter = 0; | ||
| 622 | *event = keymap[i].event; | ||
| 623 | *state = REMOTE_KEY_PRESSED; | ||
| 624 | d->last_event = keymap[i].event; | ||
| 625 | } else if (poll_reply.data_state == 2) { | ||
| 626 | /* Key repeated */ | ||
| 627 | st->rc_counter++; | ||
| 628 | |||
| 629 | /* prevents unwanted double hits */ | ||
| 630 | if (st->rc_counter > RC_REPEAT_DELAY_V1_20) { | ||
| 631 | *event = d->last_event; | ||
| 632 | *state = REMOTE_KEY_PRESSED; | ||
| 633 | st->rc_counter = RC_REPEAT_DELAY_V1_20; | ||
| 634 | } | ||
| 635 | } else { | ||
| 636 | err("Unknown data state [%d]", poll_reply.data_state); | ||
| 637 | } | ||
| 638 | |||
| 639 | return 0; | ||
| 640 | } | ||
| 641 | |||
| 642 | static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||
| 643 | { | ||
| 644 | struct dib0700_state *st = d->priv; | ||
| 645 | |||
| 646 | /* Because some people may have improperly named firmware files, | ||
| 647 | let's figure out whether to use the new firmware call or the legacy | ||
| 648 | call based on the firmware version embedded in the file */ | ||
| 649 | if (st->rc_func_version == 0) { | ||
| 650 | u32 hwver, romver, ramver, fwtype; | ||
| 651 | int ret = dib0700_get_version(d, &hwver, &romver, &ramver, | ||
| 652 | &fwtype); | ||
| 653 | if (ret < 0) { | ||
| 654 | err("Could not determine version info"); | ||
| 655 | return -1; | ||
| 656 | } | ||
| 657 | if (ramver < 0x10200) | ||
| 658 | st->rc_func_version = 1; | ||
| 659 | else | ||
| 660 | st->rc_func_version = 2; | ||
| 661 | } | ||
| 662 | |||
| 663 | if (st->rc_func_version == 2) | ||
| 664 | return dib0700_rc_query_v1_20(d, event, state); | ||
| 665 | else | ||
| 666 | return dib0700_rc_query_legacy(d, event, state); | ||
| 667 | } | ||
| 668 | |||
| 532 | static struct dvb_usb_rc_key dib0700_rc_keys[] = { | 669 | static struct dvb_usb_rc_key dib0700_rc_keys[] = { |
| 533 | /* Key codes for the tiny Pinnacle remote*/ | 670 | /* Key codes for the tiny Pinnacle remote*/ |
| 534 | { 0x07, 0x00, KEY_MUTE }, | 671 | { 0x07, 0x00, KEY_MUTE }, |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index 5cef12a07f72..6fe71c6745eb 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c | |||
| @@ -13,14 +13,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, | |||
| 13 | { | 13 | { |
| 14 | int actlen,ret = -ENOMEM; | 14 | int actlen,ret = -ENOMEM; |
| 15 | 15 | ||
| 16 | if (!d || wbuf == NULL || wlen == 0) | ||
| 17 | return -EINVAL; | ||
| 18 | |||
| 16 | if (d->props.generic_bulk_ctrl_endpoint == 0) { | 19 | if (d->props.generic_bulk_ctrl_endpoint == 0) { |
| 17 | err("endpoint for generic control not specified."); | 20 | err("endpoint for generic control not specified."); |
| 18 | return -EINVAL; | 21 | return -EINVAL; |
| 19 | } | 22 | } |
| 20 | 23 | ||
| 21 | if (wbuf == NULL || wlen == 0) | ||
| 22 | return -EINVAL; | ||
| 23 | |||
| 24 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | 24 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) |
| 25 | return ret; | 25 | return ret; |
| 26 | 26 | ||
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c index 397f51a7b2ad..da93b9e982c0 100644 --- a/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/drivers/media/dvb/dvb-usb/usb-urb.c | |||
| @@ -135,7 +135,7 @@ stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]) | |||
| 135 | 135 | ||
| 136 | static int usb_bulk_urb_init(struct usb_data_stream *stream) | 136 | static int usb_bulk_urb_init(struct usb_data_stream *stream) |
| 137 | { | 137 | { |
| 138 | int i; | 138 | int i, j; |
| 139 | 139 | ||
| 140 | if ((i = usb_allocate_stream_buffers(stream,stream->props.count, | 140 | if ((i = usb_allocate_stream_buffers(stream,stream->props.count, |
| 141 | stream->props.u.bulk.buffersize)) < 0) | 141 | stream->props.u.bulk.buffersize)) < 0) |
| @@ -143,9 +143,13 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) | |||
| 143 | 143 | ||
| 144 | /* allocate the URBs */ | 144 | /* allocate the URBs */ |
| 145 | for (i = 0; i < stream->props.count; i++) { | 145 | for (i = 0; i < stream->props.count; i++) { |
| 146 | if ((stream->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL) | 146 | stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); |
| 147 | if (!stream->urb_list[i]) { | ||
| 148 | deb_mem("not enough memory for urb_alloc_urb!.\n"); | ||
| 149 | for (j = 0; j < i; j++) | ||
| 150 | usb_free_urb(stream->urb_list[i]); | ||
| 147 | return -ENOMEM; | 151 | return -ENOMEM; |
| 148 | 152 | } | |
| 149 | usb_fill_bulk_urb( stream->urb_list[i], stream->udev, | 153 | usb_fill_bulk_urb( stream->urb_list[i], stream->udev, |
| 150 | usb_rcvbulkpipe(stream->udev,stream->props.endpoint), | 154 | usb_rcvbulkpipe(stream->udev,stream->props.endpoint), |
| 151 | stream->buf_list[i], | 155 | stream->buf_list[i], |
| @@ -170,9 +174,14 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) | |||
| 170 | for (i = 0; i < stream->props.count; i++) { | 174 | for (i = 0; i < stream->props.count; i++) { |
| 171 | struct urb *urb; | 175 | struct urb *urb; |
| 172 | int frame_offset = 0; | 176 | int frame_offset = 0; |
| 173 | if ((stream->urb_list[i] = | 177 | |
| 174 | usb_alloc_urb(stream->props.u.isoc.framesperurb,GFP_ATOMIC)) == NULL) | 178 | stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC); |
| 179 | if (!stream->urb_list[i]) { | ||
| 180 | deb_mem("not enough memory for urb_alloc_urb!\n"); | ||
| 181 | for (j = 0; j < i; j++) | ||
| 182 | usb_free_urb(stream->urb_list[i]); | ||
| 175 | return -ENOMEM; | 183 | return -ENOMEM; |
| 184 | } | ||
| 176 | 185 | ||
| 177 | urb = stream->urb_list[i]; | 186 | urb = stream->urb_list[i]; |
| 178 | 187 | ||
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 21c1060cf10e..692b68a9e73b 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
| @@ -1187,7 +1187,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
| 1187 | if (tmp) | 1187 | if (tmp) |
| 1188 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | 1188 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; |
| 1189 | 1189 | ||
| 1190 | if (!*status & FE_HAS_SIGNAL) { | 1190 | if (!(*status & FE_HAS_SIGNAL)) { |
| 1191 | /* AGC lock */ | 1191 | /* AGC lock */ |
| 1192 | ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); | 1192 | ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); |
| 1193 | if (ret) | 1193 | if (ret) |
| @@ -1196,7 +1196,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
| 1196 | *status |= FE_HAS_SIGNAL; | 1196 | *status |= FE_HAS_SIGNAL; |
| 1197 | } | 1197 | } |
| 1198 | 1198 | ||
| 1199 | if (!*status & FE_HAS_CARRIER) { | 1199 | if (!(*status & FE_HAS_CARRIER)) { |
| 1200 | /* CFO lock */ | 1200 | /* CFO lock */ |
| 1201 | ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); | 1201 | ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); |
| 1202 | if (ret) | 1202 | if (ret) |
| @@ -1205,7 +1205,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
| 1205 | *status |= FE_HAS_CARRIER; | 1205 | *status |= FE_HAS_CARRIER; |
| 1206 | } | 1206 | } |
| 1207 | 1207 | ||
| 1208 | if (!*status & FE_HAS_CARRIER) { | 1208 | if (!(*status & FE_HAS_CARRIER)) { |
| 1209 | /* SFOE lock */ | 1209 | /* SFOE lock */ |
| 1210 | ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); | 1210 | ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); |
| 1211 | if (ret) | 1211 | if (ret) |
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 6f9b77360440..e98d6caf2c23 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c | |||
| @@ -95,7 +95,7 @@ static struct sms_board sms_boards[] = { | |||
| 95 | [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { | 95 | [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { |
| 96 | .name = "Hauppauge WinTV MiniStick", | 96 | .name = "Hauppauge WinTV MiniStick", |
| 97 | .type = SMS_NOVA_B0, | 97 | .type = SMS_NOVA_B0, |
| 98 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw", | 98 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", |
| 99 | }, | 99 | }, |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 66ab0c6e9783..4a3f2b8ea37d 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
| @@ -808,6 +808,12 @@ static int ttusb_alloc_iso_urbs(struct ttusb *ttusb) | |||
| 808 | ISO_BUF_COUNT, | 808 | ISO_BUF_COUNT, |
| 809 | &ttusb->iso_dma_handle); | 809 | &ttusb->iso_dma_handle); |
| 810 | 810 | ||
| 811 | if (!ttusb->iso_buffer) { | ||
| 812 | dprintk("%s: pci_alloc_consistent - not enough memory\n", | ||
| 813 | __func__); | ||
| 814 | return -ENOMEM; | ||
| 815 | } | ||
| 816 | |||
| 811 | memset(ttusb->iso_buffer, 0, | 817 | memset(ttusb->iso_buffer, 0, |
| 812 | ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT); | 818 | ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT); |
| 813 | 819 | ||
| @@ -1659,7 +1665,14 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 1659 | 1665 | ||
| 1660 | ttusb_setup_interfaces(ttusb); | 1666 | ttusb_setup_interfaces(ttusb); |
| 1661 | 1667 | ||
| 1662 | ttusb_alloc_iso_urbs(ttusb); | 1668 | result = ttusb_alloc_iso_urbs(ttusb); |
| 1669 | if (result < 0) { | ||
| 1670 | dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__); | ||
| 1671 | mutex_unlock(&ttusb->semi2c); | ||
| 1672 | kfree(ttusb); | ||
| 1673 | return result; | ||
| 1674 | } | ||
| 1675 | |||
| 1663 | if (ttusb_init_controller(ttusb)) | 1676 | if (ttusb_init_controller(ttusb)) |
| 1664 | printk("ttusb_init_controller: error\n"); | 1677 | printk("ttusb_init_controller: error\n"); |
| 1665 | 1678 | ||
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index ab33fec8a19f..0aa96df80fc2 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
| @@ -1157,6 +1157,12 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) | |||
| 1157 | ISO_BUF_COUNT), | 1157 | ISO_BUF_COUNT), |
| 1158 | &dec->iso_dma_handle); | 1158 | &dec->iso_dma_handle); |
| 1159 | 1159 | ||
| 1160 | if (!dec->iso_buffer) { | ||
| 1161 | dprintk("%s: pci_alloc_consistent - not enough memory\n", | ||
| 1162 | __func__); | ||
| 1163 | return -ENOMEM; | ||
| 1164 | } | ||
| 1165 | |||
| 1160 | memset(dec->iso_buffer, 0, | 1166 | memset(dec->iso_buffer, 0, |
| 1161 | ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT)); | 1167 | ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT)); |
| 1162 | 1168 | ||
| @@ -1254,6 +1260,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) | |||
| 1254 | dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE, | 1260 | dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE, |
| 1255 | GFP_ATOMIC, &dec->irq_dma_handle); | 1261 | GFP_ATOMIC, &dec->irq_dma_handle); |
| 1256 | if(!dec->irq_buffer) { | 1262 | if(!dec->irq_buffer) { |
| 1263 | usb_free_urb(dec->irq_urb); | ||
| 1257 | return -ENOMEM; | 1264 | return -ENOMEM; |
| 1258 | } | 1265 | } |
| 1259 | usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe, | 1266 | usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe, |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 04cd7c04bdde..5189c4eb439f 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
| @@ -355,6 +355,20 @@ config USB_SI470X | |||
| 355 | tristate "Silicon Labs Si470x FM Radio Receiver support" | 355 | tristate "Silicon Labs Si470x FM Radio Receiver support" |
| 356 | depends on USB && VIDEO_V4L2 | 356 | depends on USB && VIDEO_V4L2 |
| 357 | ---help--- | 357 | ---help--- |
| 358 | This is a driver for USB devices with the Silicon Labs SI470x | ||
| 359 | chip. Currently these devices are known to work: | ||
| 360 | - 10c4:818a: Silicon Labs USB FM Radio Reference Design | ||
| 361 | - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) | ||
| 362 | - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) | ||
| 363 | |||
| 364 | Sound is provided by the ALSA USB Audio/MIDI driver. Therefore | ||
| 365 | if you don't want to use the device solely for RDS receiving, | ||
| 366 | it is recommended to also select SND_USB_AUDIO. | ||
| 367 | |||
| 368 | Please have a look at the documentation, especially on how | ||
| 369 | to redirect the audio stream from the radio to your sound device: | ||
| 370 | Documentation/video4linux/si470x.txt | ||
| 371 | |||
| 358 | Say Y here if you want to connect this type of radio to your | 372 | Say Y here if you want to connect this type of radio to your |
| 359 | computer's USB port. | 373 | computer's USB port. |
| 360 | 374 | ||
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 5920cd306975..3e1830293de5 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: | 4 | * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: |
| 5 | * - Silicon Labs USB FM Radio Reference Design | 5 | * - Silicon Labs USB FM Radio Reference Design |
| 6 | * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) | 6 | * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) |
| 7 | * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700) | ||
| 7 | * | 8 | * |
| 8 | * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net> | 9 | * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net> |
| 9 | * | 10 | * |
| @@ -24,19 +25,6 @@ | |||
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | /* | 27 | /* |
| 27 | * User Notes: | ||
| 28 | * - USB Audio is provided by the alsa snd_usb_audio module. | ||
| 29 | * For listing you have to redirect the sound, for example using: | ||
| 30 | * arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B - | ||
| 31 | * - regarding module parameters in /sys/module/radio_si470x/parameters: | ||
| 32 | * the contents of read-only files (0444) are not updated, even if | ||
| 33 | * space, band and de are changed using private video controls | ||
| 34 | * - increase tune_timeout, if you often get -EIO errors | ||
| 35 | * - hw_freq_seek returns -EAGAIN, when timed out or band limit is reached | ||
| 36 | */ | ||
| 37 | |||
| 38 | |||
| 39 | /* | ||
| 40 | * History: | 28 | * History: |
| 41 | * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net> | 29 | * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net> |
| 42 | * Version 1.0.0 | 30 | * Version 1.0.0 |
| @@ -105,6 +93,9 @@ | |||
| 105 | * - afc indication | 93 | * - afc indication |
| 106 | * - more safety checks, let si470x_get_freq return errno | 94 | * - more safety checks, let si470x_get_freq return errno |
| 107 | * - vidioc behavior corrected according to v4l2 spec | 95 | * - vidioc behavior corrected according to v4l2 spec |
| 96 | * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com> | ||
| 97 | * - add support for KWorld USB FM Radio FM700 | ||
| 98 | * - blacklisted KWorld radio in hid-core.c and hid-ids.h | ||
| 108 | * | 99 | * |
| 109 | * ToDo: | 100 | * ToDo: |
| 110 | * - add firmware download/update support | 101 | * - add firmware download/update support |
| @@ -145,6 +136,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { | |||
| 145 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, | 136 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, |
| 146 | /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ | 137 | /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ |
| 147 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, | 138 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, |
| 139 | /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ | ||
| 140 | { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, | ||
| 148 | /* Terminating entry */ | 141 | /* Terminating entry */ |
| 149 | { } | 142 | { } |
| 150 | }; | 143 | }; |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index a8c068e1de1c..1740b9ebdcef 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
| @@ -1476,12 +1476,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) | |||
| 1476 | { | 1476 | { |
| 1477 | struct cafe_camera *cam; | 1477 | struct cafe_camera *cam; |
| 1478 | 1478 | ||
| 1479 | lock_kernel(); | ||
| 1480 | cam = cafe_find_dev(iminor(inode)); | 1479 | cam = cafe_find_dev(iminor(inode)); |
| 1481 | if (cam == NULL) { | 1480 | if (cam == NULL) |
| 1482 | unlock_kernel(); | ||
| 1483 | return -ENODEV; | 1481 | return -ENODEV; |
| 1484 | } | ||
| 1485 | filp->private_data = cam; | 1482 | filp->private_data = cam; |
| 1486 | 1483 | ||
| 1487 | mutex_lock(&cam->s_mutex); | 1484 | mutex_lock(&cam->s_mutex); |
| @@ -1493,7 +1490,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) | |||
| 1493 | } | 1490 | } |
| 1494 | (cam->users)++; | 1491 | (cam->users)++; |
| 1495 | mutex_unlock(&cam->s_mutex); | 1492 | mutex_unlock(&cam->s_mutex); |
| 1496 | unlock_kernel(); | ||
| 1497 | return 0; | 1493 | return 0; |
| 1498 | } | 1494 | } |
| 1499 | 1495 | ||
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index bd5d9de5a008..e6ca4012b5f0 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
| @@ -867,6 +867,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 867 | case VIDIOC_STREAMON32: | 867 | case VIDIOC_STREAMON32: |
| 868 | case VIDIOC_STREAMOFF32: | 868 | case VIDIOC_STREAMOFF32: |
| 869 | case VIDIOC_G_PARM: | 869 | case VIDIOC_G_PARM: |
| 870 | case VIDIOC_S_PARM: | ||
| 870 | case VIDIOC_G_STD: | 871 | case VIDIOC_G_STD: |
| 871 | case VIDIOC_S_STD: | 872 | case VIDIOC_S_STD: |
| 872 | case VIDIOC_G_TUNER: | 873 | case VIDIOC_G_TUNER: |
| @@ -885,6 +886,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 885 | case VIDIOC_S_INPUT32: | 886 | case VIDIOC_S_INPUT32: |
| 886 | case VIDIOC_TRY_FMT32: | 887 | case VIDIOC_TRY_FMT32: |
| 887 | case VIDIOC_S_HW_FREQ_SEEK: | 888 | case VIDIOC_S_HW_FREQ_SEEK: |
| 889 | case VIDIOC_ENUM_FRAMESIZES: | ||
| 890 | case VIDIOC_ENUM_FRAMEINTERVALS: | ||
| 888 | ret = do_video_ioctl(file, cmd, arg); | 891 | ret = do_video_ioctl(file, cmd, arg); |
| 889 | break; | 892 | break; |
| 890 | 893 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 7a1a7830a6b3..7874d9790a51 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
| @@ -448,7 +448,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
| 448 | mutex_init(&cx->gpio_lock); | 448 | mutex_init(&cx->gpio_lock); |
| 449 | 449 | ||
| 450 | spin_lock_init(&cx->lock); | 450 | spin_lock_init(&cx->lock); |
| 451 | spin_lock_init(&cx->dma_reg_lock); | 451 | |
| 452 | cx->work_queue = create_singlethread_workqueue(cx->name); | ||
| 453 | if (cx->work_queue == NULL) { | ||
| 454 | CX18_ERR("Could not create work queue\n"); | ||
| 455 | return -1; | ||
| 456 | } | ||
| 457 | |||
| 458 | INIT_WORK(&cx->work, cx18_work_handler); | ||
| 452 | 459 | ||
| 453 | /* start counting open_id at 1 */ | 460 | /* start counting open_id at 1 */ |
| 454 | cx->open_id = 1; | 461 | cx->open_id = 1; |
| @@ -581,10 +588,10 @@ static void cx18_load_and_init_modules(struct cx18 *cx) | |||
| 581 | 588 | ||
| 582 | #ifdef MODULE | 589 | #ifdef MODULE |
| 583 | /* load modules */ | 590 | /* load modules */ |
| 584 | #ifndef CONFIG_MEDIA_TUNER | 591 | #ifdef CONFIG_MEDIA_TUNER_MODULE |
| 585 | hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); | 592 | hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); |
| 586 | #endif | 593 | #endif |
| 587 | #ifndef CONFIG_VIDEO_CS5345 | 594 | #ifdef CONFIG_VIDEO_CS5345_MODULE |
| 588 | hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); | 595 | hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); |
| 589 | #endif | 596 | #endif |
| 590 | #endif | 597 | #endif |
| @@ -832,6 +839,7 @@ free_map: | |||
| 832 | free_mem: | 839 | free_mem: |
| 833 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); | 840 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); |
| 834 | free_workqueue: | 841 | free_workqueue: |
| 842 | destroy_workqueue(cx->work_queue); | ||
| 835 | err: | 843 | err: |
| 836 | if (retval == 0) | 844 | if (retval == 0) |
| 837 | retval = -ENODEV; | 845 | retval = -ENODEV; |
| @@ -932,6 +940,9 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
| 932 | 940 | ||
| 933 | cx18_halt_firmware(cx); | 941 | cx18_halt_firmware(cx); |
| 934 | 942 | ||
| 943 | flush_workqueue(cx->work_queue); | ||
| 944 | destroy_workqueue(cx->work_queue); | ||
| 945 | |||
| 935 | cx18_streams_cleanup(cx, 1); | 946 | cx18_streams_cleanup(cx, 1); |
| 936 | 947 | ||
| 937 | exit_cx18_i2c(cx); | 948 | exit_cx18_i2c(cx); |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index a4b1708fafe7..bbdd5f25041d 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
| @@ -199,12 +199,15 @@ struct cx18_options { | |||
| 199 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ | 199 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ |
| 200 | 200 | ||
| 201 | /* per-cx18, i_flags */ | 201 | /* per-cx18, i_flags */ |
| 202 | #define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */ | 202 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ |
| 203 | #define CX18_F_I_EOS 4 /* End of encoder stream reached */ | 203 | #define CX18_F_I_EOS 4 /* End of encoder stream */ |
| 204 | #define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */ | 204 | #define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ |
| 205 | #define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ | 205 | #define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ |
| 206 | #define CX18_F_I_INITED 21 /* set after first open */ | 206 | #define CX18_F_I_HAVE_WORK 15 /* there is work to be done */ |
| 207 | #define CX18_F_I_FAILED 22 /* set if first open failed */ | 207 | #define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */ |
| 208 | #define CX18_F_I_INITED 21 /* set after first open */ | ||
| 209 | #define CX18_F_I_FAILED 22 /* set if first open failed */ | ||
| 210 | #define CX18_F_I_WORK_INITED 23 /* worker thread initialized */ | ||
| 208 | 211 | ||
| 209 | /* These are the VBI types as they appear in the embedded VBI private packets. */ | 212 | /* These are the VBI types as they appear in the embedded VBI private packets. */ |
| 210 | #define CX18_SLICED_TYPE_TELETEXT_B (1) | 213 | #define CX18_SLICED_TYPE_TELETEXT_B (1) |
| @@ -402,8 +405,6 @@ struct cx18 { | |||
| 402 | spinlock_t lock; /* lock access to this struct */ | 405 | spinlock_t lock; /* lock access to this struct */ |
| 403 | int search_pack_header; | 406 | int search_pack_header; |
| 404 | 407 | ||
| 405 | spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ | ||
| 406 | |||
| 407 | int open_id; /* incremented each time an open occurs, used as | 408 | int open_id; /* incremented each time an open occurs, used as |
| 408 | unique ID. Starts at 1, so 0 can be used as | 409 | unique ID. Starts at 1, so 0 can be used as |
| 409 | uninitialized value in the stream->id. */ | 410 | uninitialized value in the stream->id. */ |
| @@ -433,6 +434,9 @@ struct cx18 { | |||
| 433 | /* when the current DMA is finished this queue is woken up */ | 434 | /* when the current DMA is finished this queue is woken up */ |
| 434 | wait_queue_head_t dma_waitq; | 435 | wait_queue_head_t dma_waitq; |
| 435 | 436 | ||
| 437 | struct workqueue_struct *work_queue; | ||
| 438 | struct work_struct work; | ||
| 439 | |||
| 436 | /* i2c */ | 440 | /* i2c */ |
| 437 | struct i2c_adapter i2c_adap[2]; | 441 | struct i2c_adapter i2c_adap[2]; |
| 438 | struct i2c_algo_bit_data i2c_algo[2]; | 442 | struct i2c_algo_bit_data i2c_algo[2]; |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index afc694e7bdb2..4542e2e5e3d7 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include "cx18-dvb.h" | 23 | #include "cx18-dvb.h" |
| 24 | #include "cx18-io.h" | 24 | #include "cx18-io.h" |
| 25 | #include "cx18-streams.h" | 25 | #include "cx18-streams.h" |
| 26 | #include "cx18-queue.h" | ||
| 27 | #include "cx18-scb.h" | ||
| 26 | #include "cx18-cards.h" | 28 | #include "cx18-cards.h" |
| 27 | #include "s5h1409.h" | 29 | #include "s5h1409.h" |
| 28 | #include "mxl5005s.h" | 30 | #include "mxl5005s.h" |
| @@ -300,3 +302,24 @@ static int dvb_register(struct cx18_stream *stream) | |||
| 300 | 302 | ||
| 301 | return ret; | 303 | return ret; |
| 302 | } | 304 | } |
| 305 | |||
| 306 | void cx18_dvb_work_handler(struct cx18 *cx) | ||
| 307 | { | ||
| 308 | struct cx18_buffer *buf; | ||
| 309 | struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_TS]; | ||
| 310 | |||
| 311 | while ((buf = cx18_dequeue(s, &s->q_full)) != NULL) { | ||
| 312 | if (s->dvb.enabled) | ||
| 313 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | ||
| 314 | buf->bytesused); | ||
| 315 | |||
| 316 | cx18_enqueue(s, buf, &s->q_free); | ||
| 317 | cx18_buf_sync_for_device(s, buf); | ||
| 318 | if (s->handle == CX18_INVALID_TASK_HANDLE) /* FIXME: improve */ | ||
| 319 | continue; | ||
| 320 | |||
| 321 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, | ||
| 322 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, | ||
| 323 | 1, buf->id, s->buf_size); | ||
| 324 | } | ||
| 325 | } | ||
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h index bf8d8f6f5455..bbdcefc87f28 100644 --- a/drivers/media/video/cx18/cx18-dvb.h +++ b/drivers/media/video/cx18/cx18-dvb.h | |||
| @@ -23,3 +23,4 @@ | |||
| 23 | 23 | ||
| 24 | int cx18_dvb_register(struct cx18_stream *stream); | 24 | int cx18_dvb_register(struct cx18_stream *stream); |
| 25 | void cx18_dvb_unregister(struct cx18_stream *stream); | 25 | void cx18_dvb_unregister(struct cx18_stream *stream); |
| 26 | void cx18_dvb_work_handler(struct cx18 *cx); | ||
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c index 700ab9439c16..220fae8d4ad7 100644 --- a/drivers/media/video/cx18/cx18-io.c +++ b/drivers/media/video/cx18/cx18-io.c | |||
| @@ -88,6 +88,19 @@ void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) | |||
| 88 | cx18_log_write_retries(cx, i, addr); | 88 | cx18_log_write_retries(cx, i, addr); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, | ||
| 92 | u32 eval, u32 mask) | ||
| 93 | { | ||
| 94 | int i; | ||
| 95 | eval &= mask; | ||
| 96 | for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { | ||
| 97 | cx18_writel_noretry(cx, val, addr); | ||
| 98 | if (eval == (cx18_readl_noretry(cx, addr) & mask)) | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | cx18_log_write_retries(cx, i, addr); | ||
| 102 | } | ||
| 103 | |||
| 91 | void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) | 104 | void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) |
| 92 | { | 105 | { |
| 93 | int i; | 106 | int i; |
| @@ -218,7 +231,7 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) | |||
| 218 | void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) | 231 | void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) |
| 219 | { | 232 | { |
| 220 | u32 r; | 233 | u32 r; |
| 221 | cx18_write_reg(cx, val, SW1_INT_STATUS); | 234 | cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val); |
| 222 | r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); | 235 | r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); |
| 223 | cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); | 236 | cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); |
| 224 | } | 237 | } |
| @@ -233,7 +246,7 @@ void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) | |||
| 233 | void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) | 246 | void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) |
| 234 | { | 247 | { |
| 235 | u32 r; | 248 | u32 r; |
| 236 | cx18_write_reg(cx, val, SW2_INT_STATUS); | 249 | cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val); |
| 237 | r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); | 250 | r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); |
| 238 | cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); | 251 | cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); |
| 239 | } | 252 | } |
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h index 287a5e8bf67b..425244453ea7 100644 --- a/drivers/media/video/cx18/cx18-io.h +++ b/drivers/media/video/cx18/cx18-io.h | |||
| @@ -133,6 +133,8 @@ static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) | |||
| 133 | cx18_writel_noretry(cx, val, addr); | 133 | cx18_writel_noretry(cx, val, addr); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, | ||
| 137 | u32 eval, u32 mask); | ||
| 136 | 138 | ||
| 137 | static inline | 139 | static inline |
| 138 | void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) | 140 | void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) |
| @@ -271,6 +273,21 @@ static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) | |||
| 271 | cx18_write_reg_noretry(cx, val, reg); | 273 | cx18_write_reg_noretry(cx, val, reg); |
| 272 | } | 274 | } |
| 273 | 275 | ||
| 276 | static inline void _cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, | ||
| 277 | u32 eval, u32 mask) | ||
| 278 | { | ||
| 279 | _cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask); | ||
| 280 | } | ||
| 281 | |||
| 282 | static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, | ||
| 283 | u32 eval, u32 mask) | ||
| 284 | { | ||
| 285 | if (cx18_retry_mmio) | ||
| 286 | _cx18_write_reg_expect(cx, val, reg, eval, mask); | ||
| 287 | else | ||
| 288 | cx18_write_reg_noretry(cx, val, reg); | ||
| 289 | } | ||
| 290 | |||
| 274 | 291 | ||
| 275 | static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg) | 292 | static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg) |
| 276 | { | 293 | { |
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index 360330f5463f..5fbfbd0f1493 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c | |||
| @@ -29,8 +29,20 @@ | |||
| 29 | #include "cx18-mailbox.h" | 29 | #include "cx18-mailbox.h" |
| 30 | #include "cx18-vbi.h" | 30 | #include "cx18-vbi.h" |
| 31 | #include "cx18-scb.h" | 31 | #include "cx18-scb.h" |
| 32 | #include "cx18-dvb.h" | ||
| 32 | 33 | ||
| 33 | #define DMA_MAGIC_COOKIE 0x000001fe | 34 | void cx18_work_handler(struct work_struct *work) |
| 35 | { | ||
| 36 | struct cx18 *cx = container_of(work, struct cx18, work); | ||
| 37 | if (test_and_clear_bit(CX18_F_I_WORK_INITED, &cx->i_flags)) { | ||
| 38 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | ||
| 39 | /* This thread must use the FIFO scheduler as it | ||
| 40 | * is realtime sensitive. */ | ||
| 41 | sched_setscheduler(current, SCHED_FIFO, ¶m); | ||
| 42 | } | ||
| 43 | if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags)) | ||
| 44 | cx18_dvb_work_handler(cx); | ||
| 45 | } | ||
| 34 | 46 | ||
| 35 | static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | 47 | static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) |
| 36 | { | 48 | { |
| @@ -67,17 +79,11 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | |||
| 67 | if (buf) { | 79 | if (buf) { |
| 68 | cx18_buf_sync_for_cpu(s, buf); | 80 | cx18_buf_sync_for_cpu(s, buf); |
| 69 | if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { | 81 | if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { |
| 70 | /* process the buffer here */ | 82 | CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", |
| 71 | CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n", | ||
| 72 | buf->bytesused); | ||
| 73 | |||
| 74 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | ||
| 75 | buf->bytesused); | 83 | buf->bytesused); |
| 76 | 84 | ||
| 77 | cx18_buf_sync_for_device(s, buf); | 85 | set_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags); |
| 78 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, | 86 | set_bit(CX18_F_I_HAVE_WORK, &cx->i_flags); |
| 79 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, | ||
| 80 | 1, buf->id, s->buf_size); | ||
| 81 | } else | 87 | } else |
| 82 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); | 88 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); |
| 83 | } else { | 89 | } else { |
| @@ -109,7 +115,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb) | |||
| 109 | CX18_INFO("FW version: %s\n", p - 1); | 115 | CX18_INFO("FW version: %s\n", p - 1); |
| 110 | } | 116 | } |
| 111 | 117 | ||
| 112 | static void hpu_cmd(struct cx18 *cx, u32 sw1) | 118 | static void epu_cmd(struct cx18 *cx, u32 sw1) |
| 113 | { | 119 | { |
| 114 | struct cx18_mailbox mb; | 120 | struct cx18_mailbox mb; |
| 115 | 121 | ||
| @@ -125,12 +131,31 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1) | |||
| 125 | epu_debug(cx, &mb); | 131 | epu_debug(cx, &mb); |
| 126 | break; | 132 | break; |
| 127 | default: | 133 | default: |
| 128 | CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd); | 134 | CX18_WARN("Unknown CPU_TO_EPU mailbox command %#08x\n", |
| 135 | mb.cmd); | ||
| 129 | break; | 136 | break; |
| 130 | } | 137 | } |
| 131 | } | 138 | } |
| 132 | if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU)) | 139 | |
| 133 | CX18_WARN("Unexpected interrupt %08x\n", sw1); | 140 | if (sw1 & IRQ_APU_TO_EPU) { |
| 141 | cx18_memcpy_fromio(cx, &mb, &cx->scb->apu2epu_mb, sizeof(mb)); | ||
| 142 | CX18_WARN("Unknown APU_TO_EPU mailbox command %#08x\n", mb.cmd); | ||
| 143 | } | ||
| 144 | |||
| 145 | if (sw1 & IRQ_HPU_TO_EPU) { | ||
| 146 | cx18_memcpy_fromio(cx, &mb, &cx->scb->hpu2epu_mb, sizeof(mb)); | ||
| 147 | CX18_WARN("Unknown HPU_TO_EPU mailbox command %#08x\n", mb.cmd); | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | static void xpu_ack(struct cx18 *cx, u32 sw2) | ||
| 152 | { | ||
| 153 | if (sw2 & IRQ_CPU_TO_EPU_ACK) | ||
| 154 | wake_up(&cx->mb_cpu_waitq); | ||
| 155 | if (sw2 & IRQ_APU_TO_EPU_ACK) | ||
| 156 | wake_up(&cx->mb_apu_waitq); | ||
| 157 | if (sw2 & IRQ_HPU_TO_EPU_ACK) | ||
| 158 | wake_up(&cx->mb_hpu_waitq); | ||
| 134 | } | 159 | } |
| 135 | 160 | ||
| 136 | irqreturn_t cx18_irq_handler(int irq, void *dev_id) | 161 | irqreturn_t cx18_irq_handler(int irq, void *dev_id) |
| @@ -140,43 +165,36 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) | |||
| 140 | u32 sw2, sw2_mask; | 165 | u32 sw2, sw2_mask; |
| 141 | u32 hw2, hw2_mask; | 166 | u32 hw2, hw2_mask; |
| 142 | 167 | ||
| 143 | spin_lock(&cx->dma_reg_lock); | 168 | sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); |
| 144 | 169 | sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; | |
| 170 | sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); | ||
| 171 | sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; | ||
| 145 | hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); | 172 | hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); |
| 146 | hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; | 173 | hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; |
| 147 | sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; | ||
| 148 | sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; | ||
| 149 | sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; | ||
| 150 | sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; | ||
| 151 | 174 | ||
| 152 | cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS); | 175 | if (sw1) |
| 153 | cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS); | 176 | cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1); |
| 154 | cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); | 177 | if (sw2) |
| 178 | cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2); | ||
| 179 | if (hw2) | ||
| 180 | cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); | ||
| 155 | 181 | ||
| 156 | if (sw1 || sw2 || hw2) | 182 | if (sw1 || sw2 || hw2) |
| 157 | CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); | 183 | CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); |
| 158 | 184 | ||
| 159 | /* To do: interrupt-based I2C handling | 185 | /* To do: interrupt-based I2C handling |
| 160 | if (hw2 & 0x00c00000) { | 186 | if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) { |
| 161 | } | 187 | } |
| 162 | */ | 188 | */ |
| 163 | 189 | ||
| 164 | if (sw2) { | 190 | if (sw2) |
| 165 | if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) | | 191 | xpu_ack(cx, sw2); |
| 166 | cx18_readl(cx, &cx->scb->cpu2epu_irq_ack))) | ||
| 167 | wake_up(&cx->mb_cpu_waitq); | ||
| 168 | if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) | | ||
| 169 | cx18_readl(cx, &cx->scb->apu2epu_irq_ack))) | ||
| 170 | wake_up(&cx->mb_apu_waitq); | ||
| 171 | if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack)) | ||
| 172 | wake_up(&cx->mb_epu_waitq); | ||
| 173 | if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack)) | ||
| 174 | wake_up(&cx->mb_hpu_waitq); | ||
| 175 | } | ||
| 176 | 192 | ||
| 177 | if (sw1) | 193 | if (sw1) |
| 178 | hpu_cmd(cx, sw1); | 194 | epu_cmd(cx, sw1); |
| 179 | spin_unlock(&cx->dma_reg_lock); | 195 | |
| 196 | if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags)) | ||
| 197 | queue_work(cx->work_queue, &cx->work); | ||
| 180 | 198 | ||
| 181 | return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE; | 199 | return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; |
| 182 | } | 200 | } |
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h index 379f704f5cba..6173ca3bc9e4 100644 --- a/drivers/media/video/cx18/cx18-irq.h +++ b/drivers/media/video/cx18/cx18-irq.h | |||
| @@ -32,6 +32,4 @@ | |||
| 32 | 32 | ||
| 33 | irqreturn_t cx18_irq_handler(int irq, void *dev_id); | 33 | irqreturn_t cx18_irq_handler(int irq, void *dev_id); |
| 34 | 34 | ||
| 35 | void cx18_irq_work_handler(struct work_struct *work); | 35 | void cx18_work_handler(struct work_struct *work); |
| 36 | void cx18_dma_stream_dec_prepare(struct cx18_stream *s, u32 offset, int lock); | ||
| 37 | void cx18_unfinished_dma(unsigned long arg); | ||
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 9d18dd22de76..acff7dfb60df 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
| @@ -83,7 +83,7 @@ static const struct cx18_api_info api_info[] = { | |||
| 83 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), | 83 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), |
| 84 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), | 84 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), |
| 85 | API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), | 85 | API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), |
| 86 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0), | 86 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), |
| 87 | API_ENTRY(0, 0, 0), | 87 | API_ENTRY(0, 0, 0), |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| @@ -176,7 +176,7 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) | |||
| 176 | 176 | ||
| 177 | cx18_setup_page(cx, SCB_OFFSET); | 177 | cx18_setup_page(cx, SCB_OFFSET); |
| 178 | cx18_write_sync(cx, mb->request, &ack_mb->ack); | 178 | cx18_write_sync(cx, mb->request, &ack_mb->ack); |
| 179 | cx18_write_reg(cx, ack_irq, SW2_INT_SET); | 179 | cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq); |
| 180 | return 0; | 180 | return 0; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| @@ -225,7 +225,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
| 225 | } | 225 | } |
| 226 | if (info->flags & API_FAST) | 226 | if (info->flags & API_FAST) |
| 227 | timeout /= 2; | 227 | timeout /= 2; |
| 228 | cx18_write_reg(cx, irq, SW1_INT_SET); | 228 | cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); |
| 229 | 229 | ||
| 230 | while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) | 230 | while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) |
| 231 | && cnt < 660) { | 231 | && cnt < 660) { |
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index a33ba04a2686..174682c2582f 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c | |||
| @@ -88,15 +88,13 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, | |||
| 88 | 88 | ||
| 89 | if (buf->id != id) | 89 | if (buf->id != id) |
| 90 | continue; | 90 | continue; |
| 91 | |||
| 91 | buf->bytesused = bytesused; | 92 | buf->bytesused = bytesused; |
| 92 | /* the transport buffers are handled differently, | 93 | atomic_dec(&s->q_free.buffers); |
| 93 | they are not moved to the full queue */ | 94 | atomic_inc(&s->q_full.buffers); |
| 94 | if (s->type != CX18_ENC_STREAM_TYPE_TS) { | 95 | s->q_full.bytesused += buf->bytesused; |
| 95 | atomic_dec(&s->q_free.buffers); | 96 | list_move_tail(&buf->list, &s->q_full.list); |
| 96 | atomic_inc(&s->q_full.buffers); | 97 | |
| 97 | s->q_full.bytesused += buf->bytesused; | ||
| 98 | list_move_tail(&buf->list, &s->q_full.list); | ||
| 99 | } | ||
| 100 | spin_unlock(&s->qlock); | 98 | spin_unlock(&s->qlock); |
| 101 | return buf; | 99 | return buf; |
| 102 | } | 100 | } |
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h index 86b4cb15d163..594713bbed68 100644 --- a/drivers/media/video/cx18/cx18-scb.h +++ b/drivers/media/video/cx18/cx18-scb.h | |||
| @@ -128,22 +128,22 @@ struct cx18_scb { | |||
| 128 | u32 apu2cpu_irq; | 128 | u32 apu2cpu_irq; |
| 129 | /* Value to write to register SW2 register set (0xC7003140) after the | 129 | /* Value to write to register SW2 register set (0xC7003140) after the |
| 130 | command is cleared */ | 130 | command is cleared */ |
| 131 | u32 apu2cpu_irq_ack; | 131 | u32 cpu2apu_irq_ack; |
| 132 | u32 reserved2[13]; | 132 | u32 reserved2[13]; |
| 133 | 133 | ||
| 134 | u32 hpu2cpu_mb_offset; | 134 | u32 hpu2cpu_mb_offset; |
| 135 | u32 hpu2cpu_irq; | 135 | u32 hpu2cpu_irq; |
| 136 | u32 hpu2cpu_irq_ack; | 136 | u32 cpu2hpu_irq_ack; |
| 137 | u32 reserved3[13]; | 137 | u32 reserved3[13]; |
| 138 | 138 | ||
| 139 | u32 ppu2cpu_mb_offset; | 139 | u32 ppu2cpu_mb_offset; |
| 140 | u32 ppu2cpu_irq; | 140 | u32 ppu2cpu_irq; |
| 141 | u32 ppu2cpu_irq_ack; | 141 | u32 cpu2ppu_irq_ack; |
| 142 | u32 reserved4[13]; | 142 | u32 reserved4[13]; |
| 143 | 143 | ||
| 144 | u32 epu2cpu_mb_offset; | 144 | u32 epu2cpu_mb_offset; |
| 145 | u32 epu2cpu_irq; | 145 | u32 epu2cpu_irq; |
| 146 | u32 epu2cpu_irq_ack; | 146 | u32 cpu2epu_irq_ack; |
| 147 | u32 reserved5[13]; | 147 | u32 reserved5[13]; |
| 148 | u32 reserved6[8]; | 148 | u32 reserved6[8]; |
| 149 | 149 | ||
| @@ -153,22 +153,22 @@ struct cx18_scb { | |||
| 153 | u32 reserved11[7]; | 153 | u32 reserved11[7]; |
| 154 | u32 cpu2apu_mb_offset; | 154 | u32 cpu2apu_mb_offset; |
| 155 | u32 cpu2apu_irq; | 155 | u32 cpu2apu_irq; |
| 156 | u32 cpu2apu_irq_ack; | 156 | u32 apu2cpu_irq_ack; |
| 157 | u32 reserved12[13]; | 157 | u32 reserved12[13]; |
| 158 | 158 | ||
| 159 | u32 hpu2apu_mb_offset; | 159 | u32 hpu2apu_mb_offset; |
| 160 | u32 hpu2apu_irq; | 160 | u32 hpu2apu_irq; |
| 161 | u32 hpu2apu_irq_ack; | 161 | u32 apu2hpu_irq_ack; |
| 162 | u32 reserved13[13]; | 162 | u32 reserved13[13]; |
| 163 | 163 | ||
| 164 | u32 ppu2apu_mb_offset; | 164 | u32 ppu2apu_mb_offset; |
| 165 | u32 ppu2apu_irq; | 165 | u32 ppu2apu_irq; |
| 166 | u32 ppu2apu_irq_ack; | 166 | u32 apu2ppu_irq_ack; |
| 167 | u32 reserved14[13]; | 167 | u32 reserved14[13]; |
| 168 | 168 | ||
| 169 | u32 epu2apu_mb_offset; | 169 | u32 epu2apu_mb_offset; |
| 170 | u32 epu2apu_irq; | 170 | u32 epu2apu_irq; |
| 171 | u32 epu2apu_irq_ack; | 171 | u32 apu2epu_irq_ack; |
| 172 | u32 reserved15[13]; | 172 | u32 reserved15[13]; |
| 173 | u32 reserved16[8]; | 173 | u32 reserved16[8]; |
| 174 | 174 | ||
| @@ -178,22 +178,22 @@ struct cx18_scb { | |||
| 178 | u32 reserved21[7]; | 178 | u32 reserved21[7]; |
| 179 | u32 cpu2hpu_mb_offset; | 179 | u32 cpu2hpu_mb_offset; |
| 180 | u32 cpu2hpu_irq; | 180 | u32 cpu2hpu_irq; |
| 181 | u32 cpu2hpu_irq_ack; | 181 | u32 hpu2cpu_irq_ack; |
| 182 | u32 reserved22[13]; | 182 | u32 reserved22[13]; |
| 183 | 183 | ||
| 184 | u32 apu2hpu_mb_offset; | 184 | u32 apu2hpu_mb_offset; |
| 185 | u32 apu2hpu_irq; | 185 | u32 apu2hpu_irq; |
| 186 | u32 apu2hpu_irq_ack; | 186 | u32 hpu2apu_irq_ack; |
| 187 | u32 reserved23[13]; | 187 | u32 reserved23[13]; |
| 188 | 188 | ||
| 189 | u32 ppu2hpu_mb_offset; | 189 | u32 ppu2hpu_mb_offset; |
| 190 | u32 ppu2hpu_irq; | 190 | u32 ppu2hpu_irq; |
| 191 | u32 ppu2hpu_irq_ack; | 191 | u32 hpu2ppu_irq_ack; |
| 192 | u32 reserved24[13]; | 192 | u32 reserved24[13]; |
| 193 | 193 | ||
| 194 | u32 epu2hpu_mb_offset; | 194 | u32 epu2hpu_mb_offset; |
| 195 | u32 epu2hpu_irq; | 195 | u32 epu2hpu_irq; |
| 196 | u32 epu2hpu_irq_ack; | 196 | u32 hpu2epu_irq_ack; |
| 197 | u32 reserved25[13]; | 197 | u32 reserved25[13]; |
| 198 | u32 reserved26[8]; | 198 | u32 reserved26[8]; |
| 199 | 199 | ||
| @@ -203,22 +203,22 @@ struct cx18_scb { | |||
| 203 | u32 reserved31[7]; | 203 | u32 reserved31[7]; |
| 204 | u32 cpu2ppu_mb_offset; | 204 | u32 cpu2ppu_mb_offset; |
| 205 | u32 cpu2ppu_irq; | 205 | u32 cpu2ppu_irq; |
| 206 | u32 cpu2ppu_irq_ack; | 206 | u32 ppu2cpu_irq_ack; |
| 207 | u32 reserved32[13]; | 207 | u32 reserved32[13]; |
| 208 | 208 | ||
| 209 | u32 apu2ppu_mb_offset; | 209 | u32 apu2ppu_mb_offset; |
| 210 | u32 apu2ppu_irq; | 210 | u32 apu2ppu_irq; |
| 211 | u32 apu2ppu_irq_ack; | 211 | u32 ppu2apu_irq_ack; |
| 212 | u32 reserved33[13]; | 212 | u32 reserved33[13]; |
| 213 | 213 | ||
| 214 | u32 hpu2ppu_mb_offset; | 214 | u32 hpu2ppu_mb_offset; |
| 215 | u32 hpu2ppu_irq; | 215 | u32 hpu2ppu_irq; |
| 216 | u32 hpu2ppu_irq_ack; | 216 | u32 ppu2hpu_irq_ack; |
| 217 | u32 reserved34[13]; | 217 | u32 reserved34[13]; |
| 218 | 218 | ||
| 219 | u32 epu2ppu_mb_offset; | 219 | u32 epu2ppu_mb_offset; |
| 220 | u32 epu2ppu_irq; | 220 | u32 epu2ppu_irq; |
| 221 | u32 epu2ppu_irq_ack; | 221 | u32 ppu2epu_irq_ack; |
| 222 | u32 reserved35[13]; | 222 | u32 reserved35[13]; |
| 223 | u32 reserved36[8]; | 223 | u32 reserved36[8]; |
| 224 | 224 | ||
| @@ -228,22 +228,22 @@ struct cx18_scb { | |||
| 228 | u32 reserved41[7]; | 228 | u32 reserved41[7]; |
| 229 | u32 cpu2epu_mb_offset; | 229 | u32 cpu2epu_mb_offset; |
| 230 | u32 cpu2epu_irq; | 230 | u32 cpu2epu_irq; |
| 231 | u32 cpu2epu_irq_ack; | 231 | u32 epu2cpu_irq_ack; |
| 232 | u32 reserved42[13]; | 232 | u32 reserved42[13]; |
| 233 | 233 | ||
| 234 | u32 apu2epu_mb_offset; | 234 | u32 apu2epu_mb_offset; |
| 235 | u32 apu2epu_irq; | 235 | u32 apu2epu_irq; |
| 236 | u32 apu2epu_irq_ack; | 236 | u32 epu2apu_irq_ack; |
| 237 | u32 reserved43[13]; | 237 | u32 reserved43[13]; |
| 238 | 238 | ||
| 239 | u32 hpu2epu_mb_offset; | 239 | u32 hpu2epu_mb_offset; |
| 240 | u32 hpu2epu_irq; | 240 | u32 hpu2epu_irq; |
| 241 | u32 hpu2epu_irq_ack; | 241 | u32 epu2hpu_irq_ack; |
| 242 | u32 reserved44[13]; | 242 | u32 reserved44[13]; |
| 243 | 243 | ||
| 244 | u32 ppu2epu_mb_offset; | 244 | u32 ppu2epu_mb_offset; |
| 245 | u32 ppu2epu_irq; | 245 | u32 ppu2epu_irq; |
| 246 | u32 ppu2epu_irq_ack; | 246 | u32 epu2ppu_irq_ack; |
| 247 | u32 reserved45[13]; | 247 | u32 reserved45[13]; |
| 248 | u32 reserved46[8]; | 248 | u32 reserved46[8]; |
| 249 | 249 | ||
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 078be6319556..d3ae5b4dfca7 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
| @@ -1078,7 +1078,7 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
| 1078 | } | 1078 | } |
| 1079 | } | 1079 | } |
| 1080 | 1080 | ||
| 1081 | if (blackbird_initialize_codec(dev) < 0) { | 1081 | if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { |
| 1082 | if (drv) | 1082 | if (drv) |
| 1083 | drv->request_release(drv); | 1083 | drv->request_release(drv); |
| 1084 | unlock_kernel(); | 1084 | unlock_kernel(); |
| @@ -1109,6 +1109,8 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
| 1109 | fh->mpegq.field); | 1109 | fh->mpegq.field); |
| 1110 | unlock_kernel(); | 1110 | unlock_kernel(); |
| 1111 | 1111 | ||
| 1112 | atomic_inc(&dev->core->mpeg_users); | ||
| 1113 | |||
| 1112 | return 0; | 1114 | return 0; |
| 1113 | } | 1115 | } |
| 1114 | 1116 | ||
| @@ -1118,7 +1120,7 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
| 1118 | struct cx8802_dev *dev = fh->dev; | 1120 | struct cx8802_dev *dev = fh->dev; |
| 1119 | struct cx8802_driver *drv = NULL; | 1121 | struct cx8802_driver *drv = NULL; |
| 1120 | 1122 | ||
| 1121 | if (dev->mpeg_active) | 1123 | if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1) |
| 1122 | blackbird_stop_codec(dev); | 1124 | blackbird_stop_codec(dev); |
| 1123 | 1125 | ||
| 1124 | cx8802_cancel_buffers(fh->dev); | 1126 | cx8802_cancel_buffers(fh->dev); |
| @@ -1138,6 +1140,8 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
| 1138 | if (drv) | 1140 | if (drv) |
| 1139 | drv->request_release(drv); | 1141 | drv->request_release(drv); |
| 1140 | 1142 | ||
| 1143 | atomic_dec(&dev->core->mpeg_users); | ||
| 1144 | |||
| 1141 | return 0; | 1145 | return 0; |
| 1142 | } | 1146 | } |
| 1143 | 1147 | ||
| @@ -1158,6 +1162,10 @@ static unsigned int | |||
| 1158 | mpeg_poll(struct file *file, struct poll_table_struct *wait) | 1162 | mpeg_poll(struct file *file, struct poll_table_struct *wait) |
| 1159 | { | 1163 | { |
| 1160 | struct cx8802_fh *fh = file->private_data; | 1164 | struct cx8802_fh *fh = file->private_data; |
| 1165 | struct cx8802_dev *dev = fh->dev; | ||
| 1166 | |||
| 1167 | if (!dev->mpeg_active) | ||
| 1168 | blackbird_start_codec(file, fh); | ||
| 1161 | 1169 | ||
| 1162 | return videobuf_poll_stream(file, &fh->mpegq, wait); | 1170 | return videobuf_poll_stream(file, &fh->mpegq, wait); |
| 1163 | } | 1171 | } |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index cf6c30d4e545..309ca5e68063 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
| @@ -598,6 +598,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
| 598 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; | 598 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; |
| 599 | int mfe_shared = 0; /* bus not shared by default */ | 599 | int mfe_shared = 0; /* bus not shared by default */ |
| 600 | 600 | ||
| 601 | if (0 != core->i2c_rc) { | ||
| 602 | printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); | ||
| 603 | goto frontend_detach; | ||
| 604 | } | ||
| 605 | |||
| 601 | /* Get the first frontend */ | 606 | /* Get the first frontend */ |
| 602 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | 607 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); |
| 603 | if (!fe0) | 608 | if (!fe0) |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a1c435b4b1cd..3ebdcd1d83f8 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
| @@ -769,10 +769,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
| 769 | struct cx8802_dev *dev; | 769 | struct cx8802_dev *dev; |
| 770 | struct cx88_core *core; | 770 | struct cx88_core *core; |
| 771 | int err; | 771 | int err; |
| 772 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | ||
| 773 | struct videobuf_dvb_frontend *demod; | ||
| 774 | int i; | ||
| 775 | #endif | ||
| 776 | 772 | ||
| 777 | /* general setup */ | 773 | /* general setup */ |
| 778 | core = cx88_core_get(pci_dev); | 774 | core = cx88_core_get(pci_dev); |
| @@ -803,15 +799,21 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
| 803 | mutex_init(&dev->frontends.lock); | 799 | mutex_init(&dev->frontends.lock); |
| 804 | INIT_LIST_HEAD(&dev->frontends.felist); | 800 | INIT_LIST_HEAD(&dev->frontends.felist); |
| 805 | 801 | ||
| 806 | if (core->board.num_frontends) | 802 | if (core->board.num_frontends) { |
| 807 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); | 803 | struct videobuf_dvb_frontend *fe; |
| 808 | 804 | int i; | |
| 809 | for (i = 1; i <= core->board.num_frontends; i++) { | 805 | |
| 810 | demod = videobuf_dvb_alloc_frontend(&dev->frontends, i); | 806 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, |
| 811 | if(demod == NULL) { | 807 | core->board.num_frontends); |
| 812 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | 808 | for (i = 1; i <= core->board.num_frontends; i++) { |
| 813 | err = -ENOMEM; | 809 | fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); |
| 814 | goto fail_free; | 810 | if(fe == NULL) { |
| 811 | printk(KERN_ERR "%s() failed to alloc\n", | ||
| 812 | __func__); | ||
| 813 | videobuf_dvb_dealloc_frontends(&dev->frontends); | ||
| 814 | err = -ENOMEM; | ||
| 815 | goto fail_free; | ||
| 816 | } | ||
| 815 | } | 817 | } |
| 816 | } | 818 | } |
| 817 | #endif | 819 | #endif |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 61265fd04d56..b96ce991d968 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
| @@ -1216,8 +1216,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
| 1216 | struct cx8800_fh *fh = priv; | 1216 | struct cx8800_fh *fh = priv; |
| 1217 | struct cx8800_dev *dev = fh->dev; | 1217 | struct cx8800_dev *dev = fh->dev; |
| 1218 | 1218 | ||
| 1219 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) | 1219 | /* We should remember that this driver also supports teletext, */ |
| 1220 | /* so we have to test if the v4l2_buf_type is VBI capture data. */ | ||
| 1221 | if (unlikely((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
| 1222 | (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))) | ||
| 1220 | return -EINVAL; | 1223 | return -EINVAL; |
| 1224 | |||
| 1221 | if (unlikely(i != fh->type)) | 1225 | if (unlikely(i != fh->type)) |
| 1222 | return -EINVAL; | 1226 | return -EINVAL; |
| 1223 | 1227 | ||
| @@ -1232,8 +1236,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
| 1232 | struct cx8800_dev *dev = fh->dev; | 1236 | struct cx8800_dev *dev = fh->dev; |
| 1233 | int err, res; | 1237 | int err, res; |
| 1234 | 1238 | ||
| 1235 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1239 | if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && |
| 1240 | (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) | ||
| 1236 | return -EINVAL; | 1241 | return -EINVAL; |
| 1242 | |||
| 1237 | if (i != fh->type) | 1243 | if (i != fh->type) |
| 1238 | return -EINVAL; | 1244 | return -EINVAL; |
| 1239 | 1245 | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 76207c2856b7..f4240965be32 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
| @@ -352,6 +352,7 @@ struct cx88_core { | |||
| 352 | /* various v4l controls */ | 352 | /* various v4l controls */ |
| 353 | u32 freq; | 353 | u32 freq; |
| 354 | atomic_t users; | 354 | atomic_t users; |
| 355 | atomic_t mpeg_users; | ||
| 355 | 356 | ||
| 356 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ | 357 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ |
| 357 | struct cx8802_dev *dvbdev; | 358 | struct cx8802_dev *dvbdev; |
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index ac3292d7646c..7a8d49ef646e 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
| @@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev) | |||
| 62 | 62 | ||
| 63 | dprintk("Stopping isoc\n"); | 63 | dprintk("Stopping isoc\n"); |
| 64 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { | 64 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { |
| 65 | usb_kill_urb(dev->adev->urb[i]); | 65 | usb_unlink_urb(dev->adev->urb[i]); |
| 66 | usb_free_urb(dev->adev->urb[i]); | 66 | usb_free_urb(dev->adev->urb[i]); |
| 67 | dev->adev->urb[i] = NULL; | 67 | dev->adev->urb[i] = NULL; |
| 68 | } | 68 | } |
| @@ -75,7 +75,6 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 75 | struct em28xx *dev = urb->context; | 75 | struct em28xx *dev = urb->context; |
| 76 | int i; | 76 | int i; |
| 77 | unsigned int oldptr; | 77 | unsigned int oldptr; |
| 78 | unsigned long flags; | ||
| 79 | int period_elapsed = 0; | 78 | int period_elapsed = 0; |
| 80 | int status; | 79 | int status; |
| 81 | unsigned char *cp; | 80 | unsigned char *cp; |
| @@ -96,9 +95,21 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 96 | if (!length) | 95 | if (!length) |
| 97 | continue; | 96 | continue; |
| 98 | 97 | ||
| 99 | spin_lock_irqsave(&dev->adev->slock, flags); | ||
| 100 | |||
| 101 | oldptr = dev->adev->hwptr_done_capture; | 98 | oldptr = dev->adev->hwptr_done_capture; |
| 99 | if (oldptr + length >= runtime->buffer_size) { | ||
| 100 | unsigned int cnt = | ||
| 101 | runtime->buffer_size - oldptr; | ||
| 102 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 103 | cnt * stride); | ||
| 104 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
| 105 | length * stride - cnt * stride); | ||
| 106 | } else { | ||
| 107 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 108 | length * stride); | ||
| 109 | } | ||
| 110 | |||
| 111 | snd_pcm_stream_lock(substream); | ||
| 112 | |||
| 102 | dev->adev->hwptr_done_capture += length; | 113 | dev->adev->hwptr_done_capture += length; |
| 103 | if (dev->adev->hwptr_done_capture >= | 114 | if (dev->adev->hwptr_done_capture >= |
| 104 | runtime->buffer_size) | 115 | runtime->buffer_size) |
| @@ -113,19 +124,7 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 113 | period_elapsed = 1; | 124 | period_elapsed = 1; |
| 114 | } | 125 | } |
| 115 | 126 | ||
| 116 | spin_unlock_irqrestore(&dev->adev->slock, flags); | 127 | snd_pcm_stream_unlock(substream); |
| 117 | |||
| 118 | if (oldptr + length >= runtime->buffer_size) { | ||
| 119 | unsigned int cnt = | ||
| 120 | runtime->buffer_size - oldptr; | ||
| 121 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 122 | cnt * stride); | ||
| 123 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
| 124 | length * stride - cnt * stride); | ||
| 125 | } else { | ||
| 126 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 127 | length * stride); | ||
| 128 | } | ||
| 129 | } | 128 | } |
| 130 | if (period_elapsed) | 129 | if (period_elapsed) |
| 131 | snd_pcm_period_elapsed(substream); | 130 | snd_pcm_period_elapsed(substream); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 5d837c16ee22..15e2b525310d 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -69,19 +69,33 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
| 69 | int ret, byte; | 69 | int ret, byte; |
| 70 | 70 | ||
| 71 | if (dev->state & DEV_DISCONNECTED) | 71 | if (dev->state & DEV_DISCONNECTED) |
| 72 | return(-ENODEV); | 72 | return -ENODEV; |
| 73 | |||
| 74 | if (len > URB_MAX_CTRL_SIZE) | ||
| 75 | return -EINVAL; | ||
| 73 | 76 | ||
| 74 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); | 77 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); |
| 75 | 78 | ||
| 79 | mutex_lock(&dev->ctrl_urb_lock); | ||
| 76 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 80 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| 77 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 81 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 78 | 0x0000, reg, buf, len, HZ); | 82 | 0x0000, reg, dev->urb_buf, len, HZ); |
| 83 | if (ret < 0) { | ||
| 84 | if (reg_debug) | ||
| 85 | printk(" failed!\n"); | ||
| 86 | mutex_unlock(&dev->ctrl_urb_lock); | ||
| 87 | return ret; | ||
| 88 | } | ||
| 89 | |||
| 90 | if (len) | ||
| 91 | memcpy(buf, dev->urb_buf, len); | ||
| 92 | |||
| 93 | mutex_unlock(&dev->ctrl_urb_lock); | ||
| 79 | 94 | ||
| 80 | if (reg_debug) { | 95 | if (reg_debug) { |
| 81 | printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); | 96 | printk("%02x values: ", ret); |
| 82 | for (byte = 0; byte < len; byte++) | 97 | for (byte = 0; byte < len; byte++) |
| 83 | printk(" %02x", (unsigned char)buf[byte]); | 98 | printk(" %02x", (unsigned char)buf[byte]); |
| 84 | |||
| 85 | printk("\n"); | 99 | printk("\n"); |
| 86 | } | 100 | } |
| 87 | 101 | ||
| @@ -102,16 +116,20 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | |||
| 102 | 116 | ||
| 103 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); | 117 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); |
| 104 | 118 | ||
| 119 | mutex_lock(&dev->ctrl_urb_lock); | ||
| 105 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 120 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| 106 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 121 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 107 | 0x0000, reg, &val, 1, HZ); | 122 | 0x0000, reg, dev->urb_buf, 1, HZ); |
| 108 | 123 | val = dev->urb_buf[0]; | |
| 109 | if (reg_debug) | 124 | mutex_unlock(&dev->ctrl_urb_lock); |
| 110 | printk(ret < 0 ? " failed!\n" : | ||
| 111 | "%02x\n", (unsigned char) val); | ||
| 112 | 125 | ||
| 113 | if (ret < 0) | 126 | if (ret < 0) { |
| 127 | printk(" failed!\n"); | ||
| 114 | return ret; | 128 | return ret; |
| 129 | } | ||
| 130 | |||
| 131 | if (reg_debug) | ||
| 132 | printk("%02x\n", (unsigned char) val); | ||
| 115 | 133 | ||
| 116 | return val; | 134 | return val; |
| 117 | } | 135 | } |
| @@ -130,19 +148,13 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 130 | { | 148 | { |
| 131 | int ret; | 149 | int ret; |
| 132 | 150 | ||
| 133 | /*usb_control_msg seems to expect a kmalloced buffer */ | ||
| 134 | unsigned char *bufs; | ||
| 135 | |||
| 136 | if (dev->state & DEV_DISCONNECTED) | 151 | if (dev->state & DEV_DISCONNECTED) |
| 137 | return -ENODEV; | 152 | return -ENODEV; |
| 138 | 153 | ||
| 139 | if (len < 1) | 154 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) |
| 140 | return -EINVAL; | 155 | return -EINVAL; |
| 141 | 156 | ||
| 142 | bufs = kmalloc(len, GFP_KERNEL); | ||
| 143 | |||
| 144 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | 157 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); |
| 145 | |||
| 146 | if (reg_debug) { | 158 | if (reg_debug) { |
| 147 | int i; | 159 | int i; |
| 148 | for (i = 0; i < len; ++i) | 160 | for (i = 0; i < len; ++i) |
| @@ -150,16 +162,16 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 150 | printk("\n"); | 162 | printk("\n"); |
| 151 | } | 163 | } |
| 152 | 164 | ||
| 153 | if (!bufs) | 165 | mutex_lock(&dev->ctrl_urb_lock); |
| 154 | return -ENOMEM; | 166 | memcpy(dev->urb_buf, buf, len); |
| 155 | memcpy(bufs, buf, len); | ||
| 156 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 167 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, |
| 157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 168 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 158 | 0x0000, reg, bufs, len, HZ); | 169 | 0x0000, reg, dev->urb_buf, len, HZ); |
| 170 | mutex_unlock(&dev->ctrl_urb_lock); | ||
| 171 | |||
| 159 | if (dev->wait_after_write) | 172 | if (dev->wait_after_write) |
| 160 | msleep(dev->wait_after_write); | 173 | msleep(dev->wait_after_write); |
| 161 | 174 | ||
| 162 | kfree(bufs); | ||
| 163 | return ret; | 175 | return ret; |
| 164 | } | 176 | } |
| 165 | 177 | ||
| @@ -270,6 +282,8 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
| 270 | break; | 282 | break; |
| 271 | case EM28XX_AMUX_LINE_IN: | 283 | case EM28XX_AMUX_LINE_IN: |
| 272 | input = EM28XX_AUDIO_SRC_LINE; | 284 | input = EM28XX_AUDIO_SRC_LINE; |
| 285 | video = disable; | ||
| 286 | line = enable; | ||
| 273 | break; | 287 | break; |
| 274 | case EM28XX_AMUX_AC97_VIDEO: | 288 | case EM28XX_AMUX_AC97_VIDEO: |
| 275 | input = EM28XX_AUDIO_SRC_LINE; | 289 | input = EM28XX_AUDIO_SRC_LINE; |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 3bab56b997fc..2360c61ddca9 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
| @@ -337,9 +337,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | |||
| 337 | /* Check if board has eeprom */ | 337 | /* Check if board has eeprom */ |
| 338 | err = i2c_master_recv(&dev->i2c_client, &buf, 0); | 338 | err = i2c_master_recv(&dev->i2c_client, &buf, 0); |
| 339 | if (err < 0) { | 339 | if (err < 0) { |
| 340 | em28xx_errdev("%s: i2c_master_recv failed! err [%d]\n", | 340 | em28xx_errdev("board has no eeprom\n"); |
| 341 | __func__, err); | 341 | memset(eedata, 0, len); |
| 342 | return err; | 342 | return -ENODEV; |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | buf = 0; | 345 | buf = 0; |
| @@ -609,14 +609,16 @@ int em28xx_i2c_register(struct em28xx *dev) | |||
| 609 | dev->i2c_client.adapter = &dev->i2c_adap; | 609 | dev->i2c_client.adapter = &dev->i2c_adap; |
| 610 | 610 | ||
| 611 | retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); | 611 | retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); |
| 612 | if (retval < 0) { | 612 | if ((retval < 0) && (retval != -ENODEV)) { |
| 613 | em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", | 613 | em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", |
| 614 | __func__, retval); | 614 | __func__, retval); |
| 615 | |||
| 615 | return retval; | 616 | return retval; |
| 616 | } | 617 | } |
| 617 | 618 | ||
| 618 | if (i2c_scan) | 619 | if (i2c_scan) |
| 619 | em28xx_do_i2c_scan(dev); | 620 | em28xx_do_i2c_scan(dev); |
| 621 | |||
| 620 | return 0; | 622 | return 0; |
| 621 | } | 623 | } |
| 622 | 624 | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index a1ab2ef45578..610f535a257c 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -73,6 +73,7 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
| 73 | MODULE_LICENSE("GPL"); | 73 | MODULE_LICENSE("GPL"); |
| 74 | 74 | ||
| 75 | static LIST_HEAD(em28xx_devlist); | 75 | static LIST_HEAD(em28xx_devlist); |
| 76 | static DEFINE_MUTEX(em28xx_devlist_mutex); | ||
| 76 | 77 | ||
| 77 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 78 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
| 78 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 79 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
| @@ -1519,7 +1520,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 1519 | struct em28xx_fh *fh; | 1520 | struct em28xx_fh *fh; |
| 1520 | enum v4l2_buf_type fh_type = 0; | 1521 | enum v4l2_buf_type fh_type = 0; |
| 1521 | 1522 | ||
| 1522 | lock_kernel(); | 1523 | mutex_lock(&em28xx_devlist_mutex); |
| 1523 | list_for_each_entry(h, &em28xx_devlist, devlist) { | 1524 | list_for_each_entry(h, &em28xx_devlist, devlist) { |
| 1524 | if (h->vdev->minor == minor) { | 1525 | if (h->vdev->minor == minor) { |
| 1525 | dev = h; | 1526 | dev = h; |
| @@ -1535,10 +1536,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 1535 | dev = h; | 1536 | dev = h; |
| 1536 | } | 1537 | } |
| 1537 | } | 1538 | } |
| 1538 | if (NULL == dev) { | 1539 | mutex_unlock(&em28xx_devlist_mutex); |
| 1539 | unlock_kernel(); | 1540 | if (NULL == dev) |
| 1540 | return -ENODEV; | 1541 | return -ENODEV; |
| 1541 | } | 1542 | |
| 1543 | mutex_lock(&dev->lock); | ||
| 1542 | 1544 | ||
| 1543 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | 1545 | em28xx_videodbg("open minor=%d type=%s users=%d\n", |
| 1544 | minor, v4l2_type_names[fh_type], dev->users); | 1546 | minor, v4l2_type_names[fh_type], dev->users); |
| @@ -1547,10 +1549,9 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 1547 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | 1549 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); |
| 1548 | if (!fh) { | 1550 | if (!fh) { |
| 1549 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); | 1551 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); |
| 1550 | unlock_kernel(); | 1552 | mutex_unlock(&dev->lock); |
| 1551 | return -ENOMEM; | 1553 | return -ENOMEM; |
| 1552 | } | 1554 | } |
| 1553 | mutex_lock(&dev->lock); | ||
| 1554 | fh->dev = dev; | 1555 | fh->dev = dev; |
| 1555 | fh->radio = radio; | 1556 | fh->radio = radio; |
| 1556 | fh->type = fh_type; | 1557 | fh->type = fh_type; |
| @@ -1584,7 +1585,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
| 1584 | sizeof(struct em28xx_buffer), fh); | 1585 | sizeof(struct em28xx_buffer), fh); |
| 1585 | 1586 | ||
| 1586 | mutex_unlock(&dev->lock); | 1587 | mutex_unlock(&dev->lock); |
| 1587 | unlock_kernel(); | ||
| 1588 | 1588 | ||
| 1589 | return errCode; | 1589 | return errCode; |
| 1590 | } | 1590 | } |
| @@ -1871,6 +1871,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) | |||
| 1871 | { | 1871 | { |
| 1872 | struct em28xx *dev = NULL; | 1872 | struct em28xx *dev = NULL; |
| 1873 | 1873 | ||
| 1874 | mutex_lock(&em28xx_devlist_mutex); | ||
| 1874 | mutex_lock(&em28xx_extension_devlist_lock); | 1875 | mutex_lock(&em28xx_extension_devlist_lock); |
| 1875 | list_add_tail(&ops->next, &em28xx_extension_devlist); | 1876 | list_add_tail(&ops->next, &em28xx_extension_devlist); |
| 1876 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | 1877 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
| @@ -1879,6 +1880,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) | |||
| 1879 | } | 1880 | } |
| 1880 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); | 1881 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); |
| 1881 | mutex_unlock(&em28xx_extension_devlist_lock); | 1882 | mutex_unlock(&em28xx_extension_devlist_lock); |
| 1883 | mutex_unlock(&em28xx_devlist_mutex); | ||
| 1882 | return 0; | 1884 | return 0; |
| 1883 | } | 1885 | } |
| 1884 | EXPORT_SYMBOL(em28xx_register_extension); | 1886 | EXPORT_SYMBOL(em28xx_register_extension); |
| @@ -1887,6 +1889,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) | |||
| 1887 | { | 1889 | { |
| 1888 | struct em28xx *dev = NULL; | 1890 | struct em28xx *dev = NULL; |
| 1889 | 1891 | ||
| 1892 | mutex_lock(&em28xx_devlist_mutex); | ||
| 1890 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | 1893 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
| 1891 | if (dev) | 1894 | if (dev) |
| 1892 | ops->fini(dev); | 1895 | ops->fini(dev); |
| @@ -1896,6 +1899,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) | |||
| 1896 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); | 1899 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); |
| 1897 | list_del(&ops->next); | 1900 | list_del(&ops->next); |
| 1898 | mutex_unlock(&em28xx_extension_devlist_lock); | 1901 | mutex_unlock(&em28xx_extension_devlist_lock); |
| 1902 | mutex_unlock(&em28xx_devlist_mutex); | ||
| 1899 | } | 1903 | } |
| 1900 | EXPORT_SYMBOL(em28xx_unregister_extension); | 1904 | EXPORT_SYMBOL(em28xx_unregister_extension); |
| 1901 | 1905 | ||
| @@ -1921,6 +1925,60 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
| 1921 | } | 1925 | } |
| 1922 | 1926 | ||
| 1923 | 1927 | ||
| 1928 | static int register_analog_devices(struct em28xx *dev) | ||
| 1929 | { | ||
| 1930 | int ret; | ||
| 1931 | |||
| 1932 | /* allocate and fill video video_device struct */ | ||
| 1933 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | ||
| 1934 | if (!dev->vdev) { | ||
| 1935 | em28xx_errdev("cannot allocate video_device.\n"); | ||
| 1936 | return -ENODEV; | ||
| 1937 | } | ||
| 1938 | |||
| 1939 | /* register v4l2 video video_device */ | ||
| 1940 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | ||
| 1941 | video_nr[dev->devno]); | ||
| 1942 | if (ret) { | ||
| 1943 | em28xx_errdev("unable to register video device (error=%i).\n", | ||
| 1944 | ret); | ||
| 1945 | return ret; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | /* Allocate and fill vbi video_device struct */ | ||
| 1949 | dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); | ||
| 1950 | |||
| 1951 | /* register v4l2 vbi video_device */ | ||
| 1952 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | ||
| 1953 | vbi_nr[dev->devno]); | ||
| 1954 | if (ret < 0) { | ||
| 1955 | em28xx_errdev("unable to register vbi device\n"); | ||
| 1956 | return ret; | ||
| 1957 | } | ||
| 1958 | |||
| 1959 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | ||
| 1960 | dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); | ||
| 1961 | if (!dev->radio_dev) { | ||
| 1962 | em28xx_errdev("cannot allocate video_device.\n"); | ||
| 1963 | return -ENODEV; | ||
| 1964 | } | ||
| 1965 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
| 1966 | radio_nr[dev->devno]); | ||
| 1967 | if (ret < 0) { | ||
| 1968 | em28xx_errdev("can't register radio device\n"); | ||
| 1969 | return ret; | ||
| 1970 | } | ||
| 1971 | em28xx_info("Registered radio device as /dev/radio%d\n", | ||
| 1972 | dev->radio_dev->num); | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", | ||
| 1976 | dev->vdev->num, dev->vbi_dev->num); | ||
| 1977 | |||
| 1978 | return 0; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | |||
| 1924 | /* | 1982 | /* |
| 1925 | * em28xx_init_dev() | 1983 | * em28xx_init_dev() |
| 1926 | * allocates and inits the device structs, registers i2c bus and v4l device | 1984 | * allocates and inits the device structs, registers i2c bus and v4l device |
| @@ -1936,6 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1936 | 1994 | ||
| 1937 | dev->udev = udev; | 1995 | dev->udev = udev; |
| 1938 | mutex_init(&dev->lock); | 1996 | mutex_init(&dev->lock); |
| 1997 | mutex_init(&dev->ctrl_urb_lock); | ||
| 1939 | spin_lock_init(&dev->slock); | 1998 | spin_lock_init(&dev->slock); |
| 1940 | init_waitqueue_head(&dev->open); | 1999 | init_waitqueue_head(&dev->open); |
| 1941 | init_waitqueue_head(&dev->wait_frame); | 2000 | init_waitqueue_head(&dev->wait_frame); |
| @@ -1953,8 +2012,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 1953 | errCode = em28xx_config(dev); | 2012 | errCode = em28xx_config(dev); |
| 1954 | if (errCode) { | 2013 | if (errCode) { |
| 1955 | em28xx_errdev("error configuring device\n"); | 2014 | em28xx_errdev("error configuring device\n"); |
| 1956 | em28xx_devused &= ~(1<<dev->devno); | ||
| 1957 | kfree(dev); | ||
| 1958 | return -ENOMEM; | 2015 | return -ENOMEM; |
| 1959 | } | 2016 | } |
| 1960 | 2017 | ||
| @@ -2001,50 +2058,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 2001 | return errCode; | 2058 | return errCode; |
| 2002 | } | 2059 | } |
| 2003 | 2060 | ||
| 2004 | list_add_tail(&dev->devlist, &em28xx_devlist); | ||
| 2005 | |||
| 2006 | /* allocate and fill video video_device struct */ | ||
| 2007 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | ||
| 2008 | if (NULL == dev->vdev) { | ||
| 2009 | em28xx_errdev("cannot allocate video_device.\n"); | ||
| 2010 | goto fail_unreg; | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | /* register v4l2 video video_device */ | ||
| 2014 | retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | ||
| 2015 | video_nr[dev->devno]); | ||
| 2016 | if (retval) { | ||
| 2017 | em28xx_errdev("unable to register video device (error=%i).\n", | ||
| 2018 | retval); | ||
| 2019 | goto fail_unreg; | ||
| 2020 | } | ||
| 2021 | |||
| 2022 | /* Allocate and fill vbi video_device struct */ | ||
| 2023 | dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); | ||
| 2024 | /* register v4l2 vbi video_device */ | ||
| 2025 | if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | ||
| 2026 | vbi_nr[dev->devno]) < 0) { | ||
| 2027 | em28xx_errdev("unable to register vbi device\n"); | ||
| 2028 | retval = -ENODEV; | ||
| 2029 | goto fail_unreg; | ||
| 2030 | } | ||
| 2031 | |||
| 2032 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | ||
| 2033 | dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); | ||
| 2034 | if (NULL == dev->radio_dev) { | ||
| 2035 | em28xx_errdev("cannot allocate video_device.\n"); | ||
| 2036 | goto fail_unreg; | ||
| 2037 | } | ||
| 2038 | retval = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
| 2039 | radio_nr[dev->devno]); | ||
| 2040 | if (retval < 0) { | ||
| 2041 | em28xx_errdev("can't register radio device\n"); | ||
| 2042 | goto fail_unreg; | ||
| 2043 | } | ||
| 2044 | em28xx_info("Registered radio device as /dev/radio%d\n", | ||
| 2045 | dev->radio_dev->num); | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | /* init video dma queues */ | 2061 | /* init video dma queues */ |
| 2049 | INIT_LIST_HEAD(&dev->vidq.active); | 2062 | INIT_LIST_HEAD(&dev->vidq.active); |
| 2050 | INIT_LIST_HEAD(&dev->vidq.queued); | 2063 | INIT_LIST_HEAD(&dev->vidq.queued); |
| @@ -2071,8 +2084,14 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 2071 | 2084 | ||
| 2072 | video_mux(dev, 0); | 2085 | video_mux(dev, 0); |
| 2073 | 2086 | ||
| 2074 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", | 2087 | mutex_lock(&em28xx_devlist_mutex); |
| 2075 | dev->vdev->num, dev->vbi_dev->num); | 2088 | list_add_tail(&dev->devlist, &em28xx_devlist); |
| 2089 | retval = register_analog_devices(dev); | ||
| 2090 | if (retval < 0) { | ||
| 2091 | em28xx_release_resources(dev); | ||
| 2092 | mutex_unlock(&em28xx_devlist_mutex); | ||
| 2093 | goto fail_reg_devices; | ||
| 2094 | } | ||
| 2076 | 2095 | ||
| 2077 | mutex_lock(&em28xx_extension_devlist_lock); | 2096 | mutex_lock(&em28xx_extension_devlist_lock); |
| 2078 | if (!list_empty(&em28xx_extension_devlist)) { | 2097 | if (!list_empty(&em28xx_extension_devlist)) { |
| @@ -2082,13 +2101,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 2082 | } | 2101 | } |
| 2083 | } | 2102 | } |
| 2084 | mutex_unlock(&em28xx_extension_devlist_lock); | 2103 | mutex_unlock(&em28xx_extension_devlist_lock); |
| 2104 | mutex_unlock(&em28xx_devlist_mutex); | ||
| 2085 | 2105 | ||
| 2086 | return 0; | 2106 | return 0; |
| 2087 | 2107 | ||
| 2088 | fail_unreg: | 2108 | fail_reg_devices: |
| 2089 | em28xx_release_resources(dev); | ||
| 2090 | mutex_unlock(&dev->lock); | 2109 | mutex_unlock(&dev->lock); |
| 2091 | kfree(dev); | ||
| 2092 | return retval; | 2110 | return retval; |
| 2093 | } | 2111 | } |
| 2094 | 2112 | ||
| @@ -2231,8 +2249,12 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 2231 | 2249 | ||
| 2232 | /* allocate device struct */ | 2250 | /* allocate device struct */ |
| 2233 | retval = em28xx_init_dev(&dev, udev, nr); | 2251 | retval = em28xx_init_dev(&dev, udev, nr); |
| 2234 | if (retval) | 2252 | if (retval) { |
| 2253 | em28xx_devused &= ~(1<<dev->devno); | ||
| 2254 | kfree(dev); | ||
| 2255 | |||
| 2235 | return retval; | 2256 | return retval; |
| 2257 | } | ||
| 2236 | 2258 | ||
| 2237 | em28xx_info("Found %s\n", em28xx_boards[dev->model].name); | 2259 | em28xx_info("Found %s\n", em28xx_boards[dev->model].name); |
| 2238 | 2260 | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 82781178e0a3..5956e9b3062f 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
| @@ -102,6 +102,9 @@ | |||
| 102 | #define EM28XX_MIN_BUF 4 | 102 | #define EM28XX_MIN_BUF 4 |
| 103 | #define EM28XX_DEF_BUF 8 | 103 | #define EM28XX_DEF_BUF 8 |
| 104 | 104 | ||
| 105 | /*Limits the max URB message size */ | ||
| 106 | #define URB_MAX_CTRL_SIZE 80 | ||
| 107 | |||
| 105 | /* Params for validated field */ | 108 | /* Params for validated field */ |
| 106 | #define EM28XX_BOARD_NOT_VALIDATED 1 | 109 | #define EM28XX_BOARD_NOT_VALIDATED 1 |
| 107 | #define EM28XX_BOARD_VALIDATED 0 | 110 | #define EM28XX_BOARD_VALIDATED 0 |
| @@ -430,6 +433,7 @@ struct em28xx { | |||
| 430 | 433 | ||
| 431 | /* locks */ | 434 | /* locks */ |
| 432 | struct mutex lock; | 435 | struct mutex lock; |
| 436 | struct mutex ctrl_urb_lock; /* protects urb_buf */ | ||
| 433 | /* spinlock_t queue_lock; */ | 437 | /* spinlock_t queue_lock; */ |
| 434 | struct list_head inqueue, outqueue; | 438 | struct list_head inqueue, outqueue; |
| 435 | wait_queue_head_t open, wait_frame, wait_stream; | 439 | wait_queue_head_t open, wait_frame, wait_stream; |
| @@ -451,6 +455,8 @@ struct em28xx { | |||
| 451 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | 455 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ |
| 452 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ | 456 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ |
| 453 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ | 457 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ |
| 458 | char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ | ||
| 459 | |||
| 454 | /* helper funcs that call usb_control_msg */ | 460 | /* helper funcs that call usb_control_msg */ |
| 455 | int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, | 461 | int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, |
| 456 | char *buf, int len); | 462 | char *buf, int len); |
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 4d0817471c9f..6b557c057fac 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
| @@ -3,16 +3,16 @@ menuconfig USB_GSPCA | |||
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | default m | 4 | default m |
| 5 | ---help--- | 5 | ---help--- |
| 6 | Say Y here if you want to enable selecting webcams based | 6 | Say Y here if you want to enable selecting webcams based |
| 7 | on the GSPCA framework. | 7 | on the GSPCA framework. |
| 8 | 8 | ||
| 9 | See <file:Documentation/video4linux/gspca.txt> for more info. | 9 | See <file:Documentation/video4linux/gspca.txt> for more info. |
| 10 | 10 | ||
| 11 | This driver uses the Video For Linux API. You must say Y or M to | 11 | This driver uses the Video For Linux API. You must say Y or M to |
| 12 | "Video For Linux" to use this driver. | 12 | "Video For Linux" to use this driver. |
| 13 | 13 | ||
| 14 | To compile this driver as modules, choose M here: the | 14 | To compile this driver as modules, choose M here: the |
| 15 | modules will be called gspca_main. | 15 | modules will be called gspca_main. |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | if USB_GSPCA && VIDEO_V4L2 | 18 | if USB_GSPCA && VIDEO_V4L2 |
| @@ -23,190 +23,190 @@ config USB_GSPCA_CONEX | |||
| 23 | tristate "Conexant Camera Driver" | 23 | tristate "Conexant Camera Driver" |
| 24 | depends on VIDEO_V4L2 && USB_GSPCA | 24 | depends on VIDEO_V4L2 && USB_GSPCA |
| 25 | help | 25 | help |
| 26 | Say Y here if you want support for cameras based on the Conexant chip. | 26 | Say Y here if you want support for cameras based on the Conexant chip. |
| 27 | 27 | ||
| 28 | To compile this driver as a module, choose M here: the | 28 | To compile this driver as a module, choose M here: the |
| 29 | module will be called gspca_conex. | 29 | module will be called gspca_conex. |
| 30 | 30 | ||
| 31 | config USB_GSPCA_ETOMS | 31 | config USB_GSPCA_ETOMS |
| 32 | tristate "Etoms USB Camera Driver" | 32 | tristate "Etoms USB Camera Driver" |
| 33 | depends on VIDEO_V4L2 && USB_GSPCA | 33 | depends on VIDEO_V4L2 && USB_GSPCA |
| 34 | help | 34 | help |
| 35 | Say Y here if you want support for cameras based on the Etoms chip. | 35 | Say Y here if you want support for cameras based on the Etoms chip. |
| 36 | 36 | ||
| 37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
| 38 | module will be called gspca_etoms. | 38 | module will be called gspca_etoms. |
| 39 | 39 | ||
| 40 | config USB_GSPCA_FINEPIX | 40 | config USB_GSPCA_FINEPIX |
| 41 | tristate "Fujifilm FinePix USB V4L2 driver" | 41 | tristate "Fujifilm FinePix USB V4L2 driver" |
| 42 | depends on VIDEO_V4L2 && USB_GSPCA | 42 | depends on VIDEO_V4L2 && USB_GSPCA |
| 43 | help | 43 | help |
| 44 | Say Y here if you want support for cameras based on the FinePix chip. | 44 | Say Y here if you want support for cameras based on the FinePix chip. |
| 45 | 45 | ||
| 46 | To compile this driver as a module, choose M here: the | 46 | To compile this driver as a module, choose M here: the |
| 47 | module will be called gspca_finepix. | 47 | module will be called gspca_finepix. |
| 48 | 48 | ||
| 49 | config USB_GSPCA_MARS | 49 | config USB_GSPCA_MARS |
| 50 | tristate "Mars USB Camera Driver" | 50 | tristate "Mars USB Camera Driver" |
| 51 | depends on VIDEO_V4L2 && USB_GSPCA | 51 | depends on VIDEO_V4L2 && USB_GSPCA |
| 52 | help | 52 | help |
| 53 | Say Y here if you want support for cameras based on the Mars chip. | 53 | Say Y here if you want support for cameras based on the Mars chip. |
| 54 | 54 | ||
| 55 | To compile this driver as a module, choose M here: the | 55 | To compile this driver as a module, choose M here: the |
| 56 | module will be called gspca_mars. | 56 | module will be called gspca_mars. |
| 57 | 57 | ||
| 58 | config USB_GSPCA_OV519 | 58 | config USB_GSPCA_OV519 |
| 59 | tristate "OV519 USB Camera Driver" | 59 | tristate "OV519 USB Camera Driver" |
| 60 | depends on VIDEO_V4L2 && USB_GSPCA | 60 | depends on VIDEO_V4L2 && USB_GSPCA |
| 61 | help | 61 | help |
| 62 | Say Y here if you want support for cameras based on the OV519 chip. | 62 | Say Y here if you want support for cameras based on the OV519 chip. |
| 63 | 63 | ||
| 64 | To compile this driver as a module, choose M here: the | 64 | To compile this driver as a module, choose M here: the |
| 65 | module will be called gspca_ov519. | 65 | module will be called gspca_ov519. |
| 66 | 66 | ||
| 67 | config USB_GSPCA_PAC207 | 67 | config USB_GSPCA_PAC207 |
| 68 | tristate "Pixart PAC207 USB Camera Driver" | 68 | tristate "Pixart PAC207 USB Camera Driver" |
| 69 | depends on VIDEO_V4L2 && USB_GSPCA | 69 | depends on VIDEO_V4L2 && USB_GSPCA |
| 70 | help | 70 | help |
| 71 | Say Y here if you want support for cameras based on the PAC207 chip. | 71 | Say Y here if you want support for cameras based on the PAC207 chip. |
| 72 | 72 | ||
| 73 | To compile this driver as a module, choose M here: the | 73 | To compile this driver as a module, choose M here: the |
| 74 | module will be called gspca_pac207. | 74 | module will be called gspca_pac207. |
| 75 | 75 | ||
| 76 | config USB_GSPCA_PAC7311 | 76 | config USB_GSPCA_PAC7311 |
| 77 | tristate "Pixart PAC7311 USB Camera Driver" | 77 | tristate "Pixart PAC7311 USB Camera Driver" |
| 78 | depends on VIDEO_V4L2 && USB_GSPCA | 78 | depends on VIDEO_V4L2 && USB_GSPCA |
| 79 | help | 79 | help |
| 80 | Say Y here if you want support for cameras based on the PAC7311 chip. | 80 | Say Y here if you want support for cameras based on the PAC7311 chip. |
| 81 | 81 | ||
| 82 | To compile this driver as a module, choose M here: the | 82 | To compile this driver as a module, choose M here: the |
| 83 | module will be called gspca_pac7311. | 83 | module will be called gspca_pac7311. |
| 84 | 84 | ||
| 85 | config USB_GSPCA_SONIXB | 85 | config USB_GSPCA_SONIXB |
| 86 | tristate "SN9C102 USB Camera Driver" | 86 | tristate "SN9C102 USB Camera Driver" |
| 87 | depends on VIDEO_V4L2 && USB_GSPCA | 87 | depends on VIDEO_V4L2 && USB_GSPCA |
| 88 | help | 88 | help |
| 89 | Say Y here if you want support for cameras based on the SONIXB chip. | 89 | Say Y here if you want support for cameras based on the SONIXB chip. |
| 90 | 90 | ||
| 91 | To compile this driver as a module, choose M here: the | 91 | To compile this driver as a module, choose M here: the |
| 92 | module will be called gspca_sonixb. | 92 | module will be called gspca_sonixb. |
| 93 | 93 | ||
| 94 | config USB_GSPCA_SONIXJ | 94 | config USB_GSPCA_SONIXJ |
| 95 | tristate "SONIX JPEG USB Camera Driver" | 95 | tristate "SONIX JPEG USB Camera Driver" |
| 96 | depends on VIDEO_V4L2 && USB_GSPCA | 96 | depends on VIDEO_V4L2 && USB_GSPCA |
| 97 | help | 97 | help |
| 98 | Say Y here if you want support for cameras based on the SONIXJ chip. | 98 | Say Y here if you want support for cameras based on the SONIXJ chip. |
| 99 | 99 | ||
| 100 | To compile this driver as a module, choose M here: the | 100 | To compile this driver as a module, choose M here: the |
| 101 | module will be called gspca_sonixj | 101 | module will be called gspca_sonixj |
| 102 | 102 | ||
| 103 | config USB_GSPCA_SPCA500 | 103 | config USB_GSPCA_SPCA500 |
| 104 | tristate "SPCA500 USB Camera Driver" | 104 | tristate "SPCA500 USB Camera Driver" |
| 105 | depends on VIDEO_V4L2 && USB_GSPCA | 105 | depends on VIDEO_V4L2 && USB_GSPCA |
| 106 | help | 106 | help |
| 107 | Say Y here if you want support for cameras based on the SPCA500 chip. | 107 | Say Y here if you want support for cameras based on the SPCA500 chip. |
| 108 | 108 | ||
| 109 | To compile this driver as a module, choose M here: the | 109 | To compile this driver as a module, choose M here: the |
| 110 | module will be called gspca_spca500. | 110 | module will be called gspca_spca500. |
| 111 | 111 | ||
| 112 | config USB_GSPCA_SPCA501 | 112 | config USB_GSPCA_SPCA501 |
| 113 | tristate "SPCA501 USB Camera Driver" | 113 | tristate "SPCA501 USB Camera Driver" |
| 114 | depends on VIDEO_V4L2 && USB_GSPCA | 114 | depends on VIDEO_V4L2 && USB_GSPCA |
| 115 | help | 115 | help |
| 116 | Say Y here if you want support for cameras based on the SPCA501 chip. | 116 | Say Y here if you want support for cameras based on the SPCA501 chip. |
| 117 | 117 | ||
| 118 | To compile this driver as a module, choose M here: the | 118 | To compile this driver as a module, choose M here: the |
| 119 | module will be called gspca_spca501. | 119 | module will be called gspca_spca501. |
| 120 | 120 | ||
| 121 | config USB_GSPCA_SPCA505 | 121 | config USB_GSPCA_SPCA505 |
| 122 | tristate "SPCA505 USB Camera Driver" | 122 | tristate "SPCA505 USB Camera Driver" |
| 123 | depends on VIDEO_V4L2 && USB_GSPCA | 123 | depends on VIDEO_V4L2 && USB_GSPCA |
| 124 | help | 124 | help |
| 125 | Say Y here if you want support for cameras based on the SPCA505 chip. | 125 | Say Y here if you want support for cameras based on the SPCA505 chip. |
| 126 | 126 | ||
| 127 | To compile this driver as a module, choose M here: the | 127 | To compile this driver as a module, choose M here: the |
| 128 | module will be called gspca_spca505. | 128 | module will be called gspca_spca505. |
| 129 | 129 | ||
| 130 | config USB_GSPCA_SPCA506 | 130 | config USB_GSPCA_SPCA506 |
| 131 | tristate "SPCA506 USB Camera Driver" | 131 | tristate "SPCA506 USB Camera Driver" |
| 132 | depends on VIDEO_V4L2 && USB_GSPCA | 132 | depends on VIDEO_V4L2 && USB_GSPCA |
| 133 | help | 133 | help |
| 134 | Say Y here if you want support for cameras based on the SPCA506 chip. | 134 | Say Y here if you want support for cameras based on the SPCA506 chip. |
| 135 | 135 | ||
| 136 | To compile this driver as a module, choose M here: the | 136 | To compile this driver as a module, choose M here: the |
| 137 | module will be called gspca_spca506. | 137 | module will be called gspca_spca506. |
| 138 | 138 | ||
| 139 | config USB_GSPCA_SPCA508 | 139 | config USB_GSPCA_SPCA508 |
| 140 | tristate "SPCA508 USB Camera Driver" | 140 | tristate "SPCA508 USB Camera Driver" |
| 141 | depends on VIDEO_V4L2 && USB_GSPCA | 141 | depends on VIDEO_V4L2 && USB_GSPCA |
| 142 | help | 142 | help |
| 143 | Say Y here if you want support for cameras based on the SPCA508 chip. | 143 | Say Y here if you want support for cameras based on the SPCA508 chip. |
| 144 | 144 | ||
| 145 | To compile this driver as a module, choose M here: the | 145 | To compile this driver as a module, choose M here: the |
| 146 | module will be called gspca_spca508. | 146 | module will be called gspca_spca508. |
| 147 | 147 | ||
| 148 | config USB_GSPCA_SPCA561 | 148 | config USB_GSPCA_SPCA561 |
| 149 | tristate "SPCA561 USB Camera Driver" | 149 | tristate "SPCA561 USB Camera Driver" |
| 150 | depends on VIDEO_V4L2 && USB_GSPCA | 150 | depends on VIDEO_V4L2 && USB_GSPCA |
| 151 | help | 151 | help |
| 152 | Say Y here if you want support for cameras based on the SPCA561 chip. | 152 | Say Y here if you want support for cameras based on the SPCA561 chip. |
| 153 | 153 | ||
| 154 | To compile this driver as a module, choose M here: the | 154 | To compile this driver as a module, choose M here: the |
| 155 | module will be called gspca_spca561. | 155 | module will be called gspca_spca561. |
| 156 | 156 | ||
| 157 | config USB_GSPCA_STK014 | 157 | config USB_GSPCA_STK014 |
| 158 | tristate "Syntek DV4000 (STK014) USB Camera Driver" | 158 | tristate "Syntek DV4000 (STK014) USB Camera Driver" |
| 159 | depends on VIDEO_V4L2 && USB_GSPCA | 159 | depends on VIDEO_V4L2 && USB_GSPCA |
| 160 | help | 160 | help |
| 161 | Say Y here if you want support for cameras based on the STK014 chip. | 161 | Say Y here if you want support for cameras based on the STK014 chip. |
| 162 | 162 | ||
| 163 | To compile this driver as a module, choose M here: the | 163 | To compile this driver as a module, choose M here: the |
| 164 | module will be called gspca_stk014. | 164 | module will be called gspca_stk014. |
| 165 | 165 | ||
| 166 | config USB_GSPCA_SUNPLUS | 166 | config USB_GSPCA_SUNPLUS |
| 167 | tristate "SUNPLUS USB Camera Driver" | 167 | tristate "SUNPLUS USB Camera Driver" |
| 168 | depends on VIDEO_V4L2 && USB_GSPCA | 168 | depends on VIDEO_V4L2 && USB_GSPCA |
| 169 | help | 169 | help |
| 170 | Say Y here if you want support for cameras based on the Sunplus | 170 | Say Y here if you want support for cameras based on the Sunplus |
| 171 | SPCA504(abc) SPCA533 SPCA536 chips. | 171 | SPCA504(abc) SPCA533 SPCA536 chips. |
| 172 | 172 | ||
| 173 | To compile this driver as a module, choose M here: the | 173 | To compile this driver as a module, choose M here: the |
| 174 | module will be called gspca_spca5xx. | 174 | module will be called gspca_spca5xx. |
| 175 | 175 | ||
| 176 | config USB_GSPCA_T613 | 176 | config USB_GSPCA_T613 |
| 177 | tristate "T613 (JPEG Compliance) USB Camera Driver" | 177 | tristate "T613 (JPEG Compliance) USB Camera Driver" |
| 178 | depends on VIDEO_V4L2 && USB_GSPCA | 178 | depends on VIDEO_V4L2 && USB_GSPCA |
| 179 | help | 179 | help |
| 180 | Say Y here if you want support for cameras based on the T613 chip. | 180 | Say Y here if you want support for cameras based on the T613 chip. |
| 181 | 181 | ||
| 182 | To compile this driver as a module, choose M here: the | 182 | To compile this driver as a module, choose M here: the |
| 183 | module will be called gspca_t613. | 183 | module will be called gspca_t613. |
| 184 | 184 | ||
| 185 | config USB_GSPCA_TV8532 | 185 | config USB_GSPCA_TV8532 |
| 186 | tristate "TV8532 USB Camera Driver" | 186 | tristate "TV8532 USB Camera Driver" |
| 187 | depends on VIDEO_V4L2 && USB_GSPCA | 187 | depends on VIDEO_V4L2 && USB_GSPCA |
| 188 | help | 188 | help |
| 189 | Say Y here if you want support for cameras based on the TV8531 chip. | 189 | Say Y here if you want support for cameras based on the TV8531 chip. |
| 190 | 190 | ||
| 191 | To compile this driver as a module, choose M here: the | 191 | To compile this driver as a module, choose M here: the |
| 192 | module will be called gspca_tv8532. | 192 | module will be called gspca_tv8532. |
| 193 | 193 | ||
| 194 | config USB_GSPCA_VC032X | 194 | config USB_GSPCA_VC032X |
| 195 | tristate "VC032X USB Camera Driver" | 195 | tristate "VC032X USB Camera Driver" |
| 196 | depends on VIDEO_V4L2 && USB_GSPCA | 196 | depends on VIDEO_V4L2 && USB_GSPCA |
| 197 | help | 197 | help |
| 198 | Say Y here if you want support for cameras based on the VC032X chip. | 198 | Say Y here if you want support for cameras based on the VC032X chip. |
| 199 | 199 | ||
| 200 | To compile this driver as a module, choose M here: the | 200 | To compile this driver as a module, choose M here: the |
| 201 | module will be called gspca_vc032x. | 201 | module will be called gspca_vc032x. |
| 202 | 202 | ||
| 203 | config USB_GSPCA_ZC3XX | 203 | config USB_GSPCA_ZC3XX |
| 204 | tristate "VC3xx USB Camera Driver" | 204 | tristate "ZC3XX USB Camera Driver" |
| 205 | depends on VIDEO_V4L2 && USB_GSPCA | 205 | depends on VIDEO_V4L2 && USB_GSPCA |
| 206 | help | 206 | help |
| 207 | Say Y here if you want support for cameras based on the ZC3XX chip. | 207 | Say Y here if you want support for cameras based on the ZC3XX chip. |
| 208 | 208 | ||
| 209 | To compile this driver as a module, choose M here: the | 209 | To compile this driver as a module, choose M here: the |
| 210 | module will be called gspca_zc3xx. | 210 | module will be called gspca_zc3xx. |
| 211 | 211 | ||
| 212 | endif | 212 | endif |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index a9d51ba7c57c..de28354ea5ba 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
| @@ -846,10 +846,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 846 | return 0; | 846 | return 0; |
| 847 | } | 847 | } |
| 848 | 848 | ||
| 849 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 849 | static void sd_stop0(struct gspca_dev *gspca_dev) | 850 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 850 | { | 851 | { |
| 851 | int retry = 50; | 852 | int retry = 50; |
| 852 | 853 | ||
| 854 | if (!gspca_dev->present) | ||
| 855 | return; | ||
| 853 | reg_w_val(gspca_dev, 0x0000, 0x00); | 856 | reg_w_val(gspca_dev, 0x0000, 0x00); |
| 854 | reg_r(gspca_dev, 0x0002, 1); | 857 | reg_r(gspca_dev, 0x0002, 1); |
| 855 | reg_w_val(gspca_dev, 0x0053, 0x00); | 858 | reg_w_val(gspca_dev, 0x0053, 0x00); |
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index 65d3cbfe6b27..607942fd7970 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c | |||
| @@ -276,6 +276,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 276 | /* Stop the state machine */ | 276 | /* Stop the state machine */ |
| 277 | if (dev->state != FPIX_NOP) | 277 | if (dev->state != FPIX_NOP) |
| 278 | wait_for_completion(&dev->can_close); | 278 | wait_for_completion(&dev->can_close); |
| 279 | } | ||
| 280 | |||
| 281 | /* called on streamoff with alt 0 and disconnect */ | ||
| 282 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
| 283 | { | ||
| 284 | struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; | ||
| 279 | 285 | ||
| 280 | usb_free_urb(dev->control_urb); | 286 | usb_free_urb(dev->control_urb); |
| 281 | dev->control_urb = NULL; | 287 | dev->control_urb = NULL; |
| @@ -385,6 +391,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 385 | error: | 391 | error: |
| 386 | /* Free the ressources */ | 392 | /* Free the ressources */ |
| 387 | sd_stopN(gspca_dev); | 393 | sd_stopN(gspca_dev); |
| 394 | sd_stop0(gspca_dev); | ||
| 388 | return ret; | 395 | return ret; |
| 389 | } | 396 | } |
| 390 | 397 | ||
| @@ -425,6 +432,7 @@ static const struct sd_desc sd_desc = { | |||
| 425 | .init = sd_init, | 432 | .init = sd_init, |
| 426 | .start = sd_start, | 433 | .start = sd_start, |
| 427 | .stopN = sd_stopN, | 434 | .stopN = sd_stopN, |
| 435 | .stop0 = sd_stop0, | ||
| 428 | }; | 436 | }; |
| 429 | 437 | ||
| 430 | /* -- device connect -- */ | 438 | /* -- device connect -- */ |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index e48fbfc8ad05..748a87e82e44 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
| @@ -646,15 +646,14 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) | |||
| 646 | { | 646 | { |
| 647 | gspca_dev->streaming = 0; | 647 | gspca_dev->streaming = 0; |
| 648 | atomic_set(&gspca_dev->nevent, 0); | 648 | atomic_set(&gspca_dev->nevent, 0); |
| 649 | if (gspca_dev->present) { | 649 | if (gspca_dev->present |
| 650 | if (gspca_dev->sd_desc->stopN) | 650 | && gspca_dev->sd_desc->stopN) |
| 651 | gspca_dev->sd_desc->stopN(gspca_dev); | 651 | gspca_dev->sd_desc->stopN(gspca_dev); |
| 652 | destroy_urbs(gspca_dev); | 652 | destroy_urbs(gspca_dev); |
| 653 | gspca_set_alt0(gspca_dev); | 653 | gspca_set_alt0(gspca_dev); |
| 654 | if (gspca_dev->sd_desc->stop0) | 654 | if (gspca_dev->sd_desc->stop0) |
| 655 | gspca_dev->sd_desc->stop0(gspca_dev); | 655 | gspca_dev->sd_desc->stop0(gspca_dev); |
| 656 | PDEBUG(D_STREAM, "stream off OK"); | 656 | PDEBUG(D_STREAM, "stream off OK"); |
| 657 | } | ||
| 658 | } | 657 | } |
| 659 | 658 | ||
| 660 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | 659 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) |
| @@ -863,7 +862,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
| 863 | int ret; | 862 | int ret; |
| 864 | 863 | ||
| 865 | PDEBUG(D_STREAM, "%s open", current->comm); | 864 | PDEBUG(D_STREAM, "%s open", current->comm); |
| 866 | gspca_dev = (struct gspca_dev *) video_devdata(file); | 865 | gspca_dev = video_drvdata(file); |
| 867 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 866 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
| 868 | return -ERESTARTSYS; | 867 | return -ERESTARTSYS; |
| 869 | if (!gspca_dev->present) { | 868 | if (!gspca_dev->present) { |
| @@ -875,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file) | |||
| 875 | ret = -EBUSY; | 874 | ret = -EBUSY; |
| 876 | goto out; | 875 | goto out; |
| 877 | } | 876 | } |
| 877 | |||
| 878 | /* protect the subdriver against rmmod */ | ||
| 879 | if (!try_module_get(gspca_dev->module)) { | ||
| 880 | ret = -ENODEV; | ||
| 881 | goto out; | ||
| 882 | } | ||
| 883 | |||
| 878 | gspca_dev->users++; | 884 | gspca_dev->users++; |
| 879 | 885 | ||
| 880 | /* one more user */ | 886 | /* one more user */ |
| @@ -884,10 +890,10 @@ static int dev_open(struct inode *inode, struct file *file) | |||
| 884 | #ifdef GSPCA_DEBUG | 890 | #ifdef GSPCA_DEBUG |
| 885 | /* activate the v4l2 debug */ | 891 | /* activate the v4l2 debug */ |
| 886 | if (gspca_debug & D_V4L2) | 892 | if (gspca_debug & D_V4L2) |
| 887 | gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL | 893 | gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL |
| 888 | | V4L2_DEBUG_IOCTL_ARG; | 894 | | V4L2_DEBUG_IOCTL_ARG; |
| 889 | else | 895 | else |
| 890 | gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL | 896 | gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL |
| 891 | | V4L2_DEBUG_IOCTL_ARG); | 897 | | V4L2_DEBUG_IOCTL_ARG); |
| 892 | #endif | 898 | #endif |
| 893 | ret = 0; | 899 | ret = 0; |
| @@ -921,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file) | |||
| 921 | gspca_dev->memory = GSPCA_MEMORY_NO; | 927 | gspca_dev->memory = GSPCA_MEMORY_NO; |
| 922 | } | 928 | } |
| 923 | file->private_data = NULL; | 929 | file->private_data = NULL; |
| 930 | module_put(gspca_dev->module); | ||
| 924 | mutex_unlock(&gspca_dev->queue_lock); | 931 | mutex_unlock(&gspca_dev->queue_lock); |
| 925 | 932 | ||
| 926 | PDEBUG(D_STREAM, "close done"); | 933 | PDEBUG(D_STREAM, "close done"); |
| @@ -1748,11 +1755,6 @@ out: | |||
| 1748 | return ret; | 1755 | return ret; |
| 1749 | } | 1756 | } |
| 1750 | 1757 | ||
| 1751 | static void dev_release(struct video_device *vfd) | ||
| 1752 | { | ||
| 1753 | /* nothing */ | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | static struct file_operations dev_fops = { | 1758 | static struct file_operations dev_fops = { |
| 1757 | .owner = THIS_MODULE, | 1759 | .owner = THIS_MODULE, |
| 1758 | .open = dev_open, | 1760 | .open = dev_open, |
| @@ -1800,7 +1802,7 @@ static struct video_device gspca_template = { | |||
| 1800 | .name = "gspca main driver", | 1802 | .name = "gspca main driver", |
| 1801 | .fops = &dev_fops, | 1803 | .fops = &dev_fops, |
| 1802 | .ioctl_ops = &dev_ioctl_ops, | 1804 | .ioctl_ops = &dev_ioctl_ops, |
| 1803 | .release = dev_release, /* mandatory */ | 1805 | .release = video_device_release, |
| 1804 | .minor = -1, | 1806 | .minor = -1, |
| 1805 | }; | 1807 | }; |
| 1806 | 1808 | ||
| @@ -1869,17 +1871,18 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
| 1869 | init_waitqueue_head(&gspca_dev->wq); | 1871 | init_waitqueue_head(&gspca_dev->wq); |
| 1870 | 1872 | ||
| 1871 | /* init video stuff */ | 1873 | /* init video stuff */ |
| 1872 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); | 1874 | gspca_dev->vdev = video_device_alloc(); |
| 1873 | gspca_dev->vdev.parent = &dev->dev; | 1875 | memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template); |
| 1874 | memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); | 1876 | gspca_dev->vdev->parent = &dev->dev; |
| 1875 | gspca_dev->vdev.fops = &gspca_dev->fops; | 1877 | gspca_dev->module = module; |
| 1876 | gspca_dev->fops.owner = module; /* module protection */ | ||
| 1877 | gspca_dev->present = 1; | 1878 | gspca_dev->present = 1; |
| 1878 | ret = video_register_device(&gspca_dev->vdev, | 1879 | video_set_drvdata(gspca_dev->vdev, gspca_dev); |
| 1880 | ret = video_register_device(gspca_dev->vdev, | ||
| 1879 | VFL_TYPE_GRABBER, | 1881 | VFL_TYPE_GRABBER, |
| 1880 | video_nr); | 1882 | video_nr); |
| 1881 | if (ret < 0) { | 1883 | if (ret < 0) { |
| 1882 | err("video_register_device err %d", ret); | 1884 | err("video_register_device err %d", ret); |
| 1885 | video_device_release(gspca_dev->vdev); | ||
| 1883 | goto out; | 1886 | goto out; |
| 1884 | } | 1887 | } |
| 1885 | 1888 | ||
| @@ -1887,7 +1890,8 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
| 1887 | PDEBUG(D_PROBE, "probe ok"); | 1890 | PDEBUG(D_PROBE, "probe ok"); |
| 1888 | return 0; | 1891 | return 0; |
| 1889 | out: | 1892 | out: |
| 1890 | kref_put(&gspca_dev->kref, gspca_delete); | 1893 | kfree(gspca_dev->usb_buf); |
| 1894 | kfree(gspca_dev); | ||
| 1891 | return ret; | 1895 | return ret; |
| 1892 | } | 1896 | } |
| 1893 | EXPORT_SYMBOL(gspca_dev_probe); | 1897 | EXPORT_SYMBOL(gspca_dev_probe); |
| @@ -1905,7 +1909,7 @@ void gspca_disconnect(struct usb_interface *intf) | |||
| 1905 | usb_set_intfdata(intf, NULL); | 1909 | usb_set_intfdata(intf, NULL); |
| 1906 | 1910 | ||
| 1907 | /* We don't want people trying to open up the device */ | 1911 | /* We don't want people trying to open up the device */ |
| 1908 | video_unregister_device(&gspca_dev->vdev); | 1912 | video_unregister_device(gspca_dev->vdev); |
| 1909 | 1913 | ||
| 1910 | gspca_dev->present = 0; | 1914 | gspca_dev->present = 0; |
| 1911 | gspca_dev->streaming = 0; | 1915 | gspca_dev->streaming = 0; |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 1d9dc90b4791..d25e8d69373b 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
| @@ -97,7 +97,7 @@ struct sd_desc { | |||
| 97 | cam_pkt_op pkt_scan; | 97 | cam_pkt_op pkt_scan; |
| 98 | /* optional operations */ | 98 | /* optional operations */ |
| 99 | cam_v_op stopN; /* called on stream off - main alt */ | 99 | cam_v_op stopN; /* called on stream off - main alt */ |
| 100 | cam_v_op stop0; /* called on stream off - alt 0 */ | 100 | cam_v_op stop0; /* called on stream off & disconnect - alt 0 */ |
| 101 | cam_v_op dq_callback; /* called when a frame has been dequeued */ | 101 | cam_v_op dq_callback; /* called when a frame has been dequeued */ |
| 102 | cam_jpg_op get_jcomp; | 102 | cam_jpg_op get_jcomp; |
| 103 | cam_jpg_op set_jcomp; | 103 | cam_jpg_op set_jcomp; |
| @@ -120,8 +120,8 @@ struct gspca_frame { | |||
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | struct gspca_dev { | 122 | struct gspca_dev { |
| 123 | struct video_device vdev; /* !! must be the first item */ | 123 | struct video_device *vdev; |
| 124 | struct file_operations fops; | 124 | struct module *module; /* subdriver handling the device */ |
| 125 | struct usb_device *dev; | 125 | struct usb_device *dev; |
| 126 | struct kref kref; | 126 | struct kref kref; |
| 127 | struct file *capt_file; /* file doing video capture */ | 127 | struct file *capt_file; /* file doing video capture */ |
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index e5ff9a6199ef..fbd45e235d97 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
| @@ -749,10 +749,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 749 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ | 749 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ |
| 750 | } | 750 | } |
| 751 | 751 | ||
| 752 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 752 | static void sd_stop0(struct gspca_dev *gspca_dev) | 753 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 753 | { | 754 | { |
| 754 | struct sd *sd = (struct sd *) gspca_dev; | 755 | struct sd *sd = (struct sd *) gspca_dev; |
| 755 | 756 | ||
| 757 | if (!gspca_dev->present) | ||
| 758 | return; | ||
| 756 | if (sd->sensor == SENSOR_PAC7302) { | 759 | if (sd->sensor == SENSOR_PAC7302) { |
| 757 | reg_w(gspca_dev, 0xff, 0x01); | 760 | reg_w(gspca_dev, 0xff, 0x01); |
| 758 | reg_w(gspca_dev, 0x78, 0x40); | 761 | reg_w(gspca_dev, 0x78, 0x40); |
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index b742f260c7ca..e29954c1c38c 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c | |||
| @@ -2022,8 +2022,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 2022 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); | 2022 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); |
| 2023 | } | 2023 | } |
| 2024 | 2024 | ||
| 2025 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 2025 | static void sd_stop0(struct gspca_dev *gspca_dev) | 2026 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 2026 | { | 2027 | { |
| 2028 | if (!gspca_dev->present) | ||
| 2029 | return; | ||
| 2027 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); | 2030 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); |
| 2028 | } | 2031 | } |
| 2029 | 2032 | ||
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index b345749213cf..895b9fe4018c 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c | |||
| @@ -742,8 +742,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 742 | reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); | 742 | reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 745 | static void sd_stop0(struct gspca_dev *gspca_dev) | 746 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 746 | { | 747 | { |
| 748 | if (!gspca_dev->present) | ||
| 749 | return; | ||
| 750 | |||
| 747 | /* This maybe reset or power control */ | 751 | /* This maybe reset or power control */ |
| 748 | reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); | 752 | reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); |
| 749 | reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); | 753 | reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 020a03c466c1..c3de4e44123d 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
| @@ -766,10 +766,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 766 | } | 766 | } |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 769 | static void sd_stop0(struct gspca_dev *gspca_dev) | 770 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 770 | { | 771 | { |
| 771 | struct sd *sd = (struct sd *) gspca_dev; | 772 | struct sd *sd = (struct sd *) gspca_dev; |
| 772 | 773 | ||
| 774 | if (!gspca_dev->present) | ||
| 775 | return; | ||
| 773 | if (sd->chip_revision == Rev012A) { | 776 | if (sd->chip_revision == Rev012A) { |
| 774 | reg_w_val(gspca_dev->dev, 0x8118, 0x29); | 777 | reg_w_val(gspca_dev->dev, 0x8118, 0x29); |
| 775 | reg_w_val(gspca_dev->dev, 0x8114, 0x08); | 778 | reg_w_val(gspca_dev->dev, 0x8114, 0x08); |
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index be46d9232540..17af353ddd1c 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c | |||
| @@ -1633,10 +1633,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 1633 | reg_w(dev, 0xa0, 0x09, 0xb003); | 1633 | reg_w(dev, 0xa0, 0x09, 0xb003); |
| 1634 | } | 1634 | } |
| 1635 | 1635 | ||
| 1636 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 1636 | static void sd_stop0(struct gspca_dev *gspca_dev) | 1637 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 1637 | { | 1638 | { |
| 1638 | struct usb_device *dev = gspca_dev->dev; | 1639 | struct usb_device *dev = gspca_dev->dev; |
| 1639 | 1640 | ||
| 1641 | if (!gspca_dev->present) | ||
| 1642 | return; | ||
| 1640 | reg_w(dev, 0x89, 0xffff, 0xffff); | 1643 | reg_w(dev, 0x89, 0xffff, 0xffff); |
| 1641 | } | 1644 | } |
| 1642 | 1645 | ||
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index d0a4451dc46f..0befacf49855 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
| @@ -2266,7 +2266,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = { | |||
| 2266 | {} | 2266 | {} |
| 2267 | }; | 2267 | }; |
| 2268 | 2268 | ||
| 2269 | static const struct usb_action hv7131bxx_Initial[] = { | 2269 | static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */ |
| 2270 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | 2270 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, |
| 2271 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | 2271 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, |
| 2272 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | 2272 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, |
| @@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = { | |||
| 2290 | {0xaa, 0x14, 0x0001}, | 2290 | {0xaa, 0x14, 0x0001}, |
| 2291 | {0xaa, 0x15, 0x00e8}, | 2291 | {0xaa, 0x15, 0x00e8}, |
| 2292 | {0xaa, 0x16, 0x0002}, | 2292 | {0xaa, 0x16, 0x0002}, |
| 2293 | {0xaa, 0x17, 0x0086}, | 2293 | {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */ |
| 2294 | {0xaa, 0x31, 0x0038}, | 2294 | {0xaa, 0x31, 0x0038}, |
| 2295 | {0xaa, 0x32, 0x0038}, | 2295 | {0xaa, 0x32, 0x0038}, |
| 2296 | {0xaa, 0x33, 0x0038}, | 2296 | {0xaa, 0x33, 0x0038}, |
| @@ -2309,7 +2309,7 @@ static const struct usb_action hv7131bxx_Initial[] = { | |||
| 2309 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | 2309 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, |
| 2310 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | 2310 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, |
| 2311 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | 2311 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, |
| 2312 | {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ | 2312 | {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */ |
| 2313 | {0xa1, 0x01, 0x0002}, | 2313 | {0xa1, 0x01, 0x0002}, |
| 2314 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | 2314 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, |
| 2315 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | 2315 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, |
| @@ -2374,7 +2374,7 @@ static const struct usb_action hv7131bxx_Initial[] = { | |||
| 2374 | {} | 2374 | {} |
| 2375 | }; | 2375 | }; |
| 2376 | 2376 | ||
| 2377 | static const struct usb_action hv7131bxx_InitialScale[] = { | 2377 | static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/ |
| 2378 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | 2378 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, |
| 2379 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | 2379 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, |
| 2380 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | 2380 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, |
| @@ -6388,6 +6388,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
| 6388 | /*fixme: is it really write to 011d and 018d for all other sensors? */ | 6388 | /*fixme: is it really write to 011d and 018d for all other sensors? */ |
| 6389 | brightness = sd->brightness; | 6389 | brightness = sd->brightness; |
| 6390 | reg_w(gspca_dev->dev, brightness, 0x011d); | 6390 | reg_w(gspca_dev->dev, brightness, 0x011d); |
| 6391 | if (sd->sensor == SENSOR_HV7131B) | ||
| 6392 | return; | ||
| 6391 | if (brightness < 0x70) | 6393 | if (brightness < 0x70) |
| 6392 | brightness += 0x10; | 6394 | brightness += 0x10; |
| 6393 | else | 6395 | else |
| @@ -6529,6 +6531,7 @@ static void setquality(struct gspca_dev *gspca_dev) | |||
| 6529 | 6531 | ||
| 6530 | switch (sd->sensor) { | 6532 | switch (sd->sensor) { |
| 6531 | case SENSOR_GC0305: | 6533 | case SENSOR_GC0305: |
| 6534 | case SENSOR_HV7131B: | ||
| 6532 | case SENSOR_OV7620: | 6535 | case SENSOR_OV7620: |
| 6533 | case SENSOR_PO2030: | 6536 | case SENSOR_PO2030: |
| 6534 | return; | 6537 | return; |
| @@ -7209,7 +7212,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 7209 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 7212 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; |
| 7210 | zc3_init = init_tb[(int) sd->sensor][mode]; | 7213 | zc3_init = init_tb[(int) sd->sensor][mode]; |
| 7211 | switch (sd->sensor) { | 7214 | switch (sd->sensor) { |
| 7212 | case SENSOR_HV7131B: | ||
| 7213 | case SENSOR_HV7131C: | 7215 | case SENSOR_HV7131C: |
| 7214 | zcxx_probeSensor(gspca_dev); | 7216 | zcxx_probeSensor(gspca_dev); |
| 7215 | break; | 7217 | break; |
| @@ -7334,10 +7336,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 7334 | return 0; | 7336 | return 0; |
| 7335 | } | 7337 | } |
| 7336 | 7338 | ||
| 7339 | /* called on streamoff with alt 0 and on disconnect */ | ||
| 7337 | static void sd_stop0(struct gspca_dev *gspca_dev) | 7340 | static void sd_stop0(struct gspca_dev *gspca_dev) |
| 7338 | { | 7341 | { |
| 7339 | struct sd *sd = (struct sd *) gspca_dev; | 7342 | struct sd *sd = (struct sd *) gspca_dev; |
| 7340 | 7343 | ||
| 7344 | if (!gspca_dev->present) | ||
| 7345 | return; | ||
| 7341 | send_unknown(gspca_dev->dev, sd->sensor); | 7346 | send_unknown(gspca_dev->dev, sd->sensor); |
| 7342 | } | 7347 | } |
| 7343 | 7348 | ||
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 0069898bddab..c46bfb1569e3 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config VIDEO_IVTV | 1 | config VIDEO_IVTV |
| 2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" | 2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" |
| 3 | depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL | 3 | depends on VIDEO_V4L2 && PCI && I2C |
| 4 | depends on INPUT # due to VIDEO_IR | 4 | depends on INPUT # due to VIDEO_IR |
| 5 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
| 6 | select VIDEO_IR | 6 | select VIDEO_IR |
| @@ -12,7 +12,6 @@ config VIDEO_IVTV | |||
| 12 | select VIDEO_SAA711X | 12 | select VIDEO_SAA711X |
| 13 | select VIDEO_SAA717X | 13 | select VIDEO_SAA717X |
| 14 | select VIDEO_SAA7127 | 14 | select VIDEO_SAA7127 |
| 15 | select VIDEO_TVAUDIO | ||
| 16 | select VIDEO_CS53L32A | 15 | select VIDEO_CS53L32A |
| 17 | select VIDEO_M52790 | 16 | select VIDEO_M52790 |
| 18 | select VIDEO_WM8775 | 17 | select VIDEO_WM8775 |
| @@ -32,7 +31,7 @@ config VIDEO_IVTV | |||
| 32 | 31 | ||
| 33 | config VIDEO_FB_IVTV | 32 | config VIDEO_FB_IVTV |
| 34 | tristate "Conexant cx23415 framebuffer support" | 33 | tristate "Conexant cx23415 framebuffer support" |
| 35 | depends on VIDEO_IVTV && FB && EXPERIMENTAL | 34 | depends on VIDEO_IVTV && FB |
| 36 | select FB_CFB_FILLRECT | 35 | select FB_CFB_FILLRECT |
| 37 | select FB_CFB_COPYAREA | 36 | select FB_CFB_COPYAREA |
| 38 | select FB_CFB_IMAGEBLIT | 37 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index d36485023b68..b69cc1d55e5b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
| @@ -875,43 +875,43 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) | |||
| 875 | 875 | ||
| 876 | #ifdef MODULE | 876 | #ifdef MODULE |
| 877 | /* load modules */ | 877 | /* load modules */ |
| 878 | #ifndef CONFIG_MEDIA_TUNER | 878 | #ifdef CONFIG_MEDIA_TUNER_MODULE |
| 879 | hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); | 879 | hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); |
| 880 | #endif | 880 | #endif |
| 881 | #ifndef CONFIG_VIDEO_CX25840 | 881 | #ifdef CONFIG_VIDEO_CX25840_MODULE |
| 882 | hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840); | 882 | hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840); |
| 883 | #endif | 883 | #endif |
| 884 | #ifndef CONFIG_VIDEO_SAA711X | 884 | #ifdef CONFIG_VIDEO_SAA711X_MODULE |
| 885 | hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X); | 885 | hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X); |
| 886 | #endif | 886 | #endif |
| 887 | #ifndef CONFIG_VIDEO_SAA7127 | 887 | #ifdef CONFIG_VIDEO_SAA7127_MODULE |
| 888 | hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); | 888 | hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); |
| 889 | #endif | 889 | #endif |
| 890 | #ifndef CONFIG_VIDEO_SAA717X | 890 | #ifdef CONFIG_VIDEO_SAA717X_MODULE |
| 891 | hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); | 891 | hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); |
| 892 | #endif | 892 | #endif |
| 893 | #ifndef CONFIG_VIDEO_UPD64031A | 893 | #ifdef CONFIG_VIDEO_UPD64031A_MODULE |
| 894 | hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); | 894 | hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); |
| 895 | #endif | 895 | #endif |
| 896 | #ifndef CONFIG_VIDEO_UPD64083 | 896 | #ifdef CONFIG_VIDEO_UPD64083_MODULE |
| 897 | hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X); | 897 | hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X); |
| 898 | #endif | 898 | #endif |
| 899 | #ifndef CONFIG_VIDEO_MSP3400 | 899 | #ifdef CONFIG_VIDEO_MSP3400_MODULE |
| 900 | hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX); | 900 | hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX); |
| 901 | #endif | 901 | #endif |
| 902 | #ifndef CONFIG_VIDEO_VP27SMPX | 902 | #ifdef CONFIG_VIDEO_VP27SMPX_MODULE |
| 903 | hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX); | 903 | hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX); |
| 904 | #endif | 904 | #endif |
| 905 | #ifndef CONFIG_VIDEO_WM8775 | 905 | #ifdef CONFIG_VIDEO_WM8775_MODULE |
| 906 | hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775); | 906 | hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775); |
| 907 | #endif | 907 | #endif |
| 908 | #ifndef CONFIG_VIDEO_WM8739 | 908 | #ifdef CONFIG_VIDEO_WM8739_MODULE |
| 909 | hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739); | 909 | hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739); |
| 910 | #endif | 910 | #endif |
| 911 | #ifndef CONFIG_VIDEO_CS53L32A | 911 | #ifdef CONFIG_VIDEO_CS53L32A_MODULE |
| 912 | hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A); | 912 | hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A); |
| 913 | #endif | 913 | #endif |
| 914 | #ifndef CONFIG_VIDEO_M52790 | 914 | #ifdef CONFIG_VIDEO_M52790_MODULE |
| 915 | hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); | 915 | hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); |
| 916 | #endif | 916 | #endif |
| 917 | #endif | 917 | #endif |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 5272926db73e..3c3f8cf73108 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
| @@ -192,7 +192,7 @@ struct s2255_dmaqueue { | |||
| 192 | #define S2255_FW_FAILED 3 | 192 | #define S2255_FW_FAILED 3 |
| 193 | #define S2255_FW_DISCONNECTING 4 | 193 | #define S2255_FW_DISCONNECTING 4 |
| 194 | 194 | ||
| 195 | #define S2255_FW_MARKER 0x22552f2f | 195 | #define S2255_FW_MARKER cpu_to_le32(0x22552f2f) |
| 196 | /* 2255 read states */ | 196 | /* 2255 read states */ |
| 197 | #define S2255_READ_IDLE 0 | 197 | #define S2255_READ_IDLE 0 |
| 198 | #define S2255_READ_FRAME 1 | 198 | #define S2255_READ_FRAME 1 |
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index adf2ba79496a..37860698f782 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
| @@ -47,7 +47,7 @@ module_param(debug, int, 0); | |||
| 47 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 47 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
| 48 | 48 | ||
| 49 | #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ | 49 | #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ |
| 50 | #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ | 50 | #define SAA7110_MAX_OUTPUT 1 /* 1 YUV */ |
| 51 | 51 | ||
| 52 | #define SAA7110_NR_REG 0x35 | 52 | #define SAA7110_NR_REG 0x35 |
| 53 | 53 | ||
| @@ -327,7 +327,7 @@ saa7110_command (struct i2c_client *client, | |||
| 327 | 327 | ||
| 328 | case DECODER_SET_INPUT: | 328 | case DECODER_SET_INPUT: |
| 329 | v = *(int *) arg; | 329 | v = *(int *) arg; |
| 330 | if (v < 0 || v > SAA7110_MAX_INPUT) { | 330 | if (v < 0 || v >= SAA7110_MAX_INPUT) { |
| 331 | v4l_dbg(1, debug, client, "input=%d not available\n", v); | 331 | v4l_dbg(1, debug, client, "input=%d not available\n", v); |
| 332 | return -EINVAL; | 332 | return -EINVAL; |
| 333 | } | 333 | } |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 249184452949..dfbe08a9ad9b 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
| @@ -941,7 +941,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
| 941 | dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); | 941 | dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); |
| 942 | goto fail1; | 942 | goto fail1; |
| 943 | } | 943 | } |
| 944 | dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); | 944 | dev->lmmio = ioremap(pci_resource_start(pci_dev, 0), |
| 945 | pci_resource_len(pci_dev, 0)); | ||
| 945 | dev->bmmio = (__u8 __iomem *)dev->lmmio; | 946 | dev->bmmio = (__u8 __iomem *)dev->lmmio; |
| 946 | if (NULL == dev->lmmio) { | 947 | if (NULL == dev->lmmio) { |
| 947 | err = -EIO; | 948 | err = -EIO; |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index b59e47272abf..3720f0e03a16 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * experimental driver for simple i2c audio chips. | 2 | * Driver for simple i2c audio chips. |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2000 Gerd Knorr | 4 | * Copyright (c) 2000 Gerd Knorr |
| 5 | * based on code by: | 5 | * based on code by: |
| @@ -7,6 +7,10 @@ | |||
| 7 | * Steve VanDeBogart (vandebo@uclink.berkeley.edu) | 7 | * Steve VanDeBogart (vandebo@uclink.berkeley.edu) |
| 8 | * Greg Alexander (galexand@acm.org) | 8 | * Greg Alexander (galexand@acm.org) |
| 9 | * | 9 | * |
| 10 | * Copyright(c) 2005-2008 Mauro Carvalho Chehab | ||
| 11 | * - Some cleanups, code fixes, etc | ||
| 12 | * - Convert it to V4L2 API | ||
| 13 | * | ||
| 10 | * This code is placed under the terms of the GNU General Public License | 14 | * This code is placed under the terms of the GNU General Public License |
| 11 | * | 15 | * |
| 12 | * OPTIONS: | 16 | * OPTIONS: |
| @@ -30,6 +34,7 @@ | |||
| 30 | 34 | ||
| 31 | #include <media/tvaudio.h> | 35 | #include <media/tvaudio.h> |
| 32 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
| 37 | #include <media/v4l2-ioctl.h> | ||
| 33 | #include <media/v4l2-chip-ident.h> | 38 | #include <media/v4l2-chip-ident.h> |
| 34 | #include <media/v4l2-i2c-drv-legacy.h> | 39 | #include <media/v4l2-i2c-drv-legacy.h> |
| 35 | 40 | ||
| @@ -58,7 +63,6 @@ typedef int (*checkit)(struct CHIPSTATE*); | |||
| 58 | typedef int (*initialize)(struct CHIPSTATE*); | 63 | typedef int (*initialize)(struct CHIPSTATE*); |
| 59 | typedef int (*getmode)(struct CHIPSTATE*); | 64 | typedef int (*getmode)(struct CHIPSTATE*); |
| 60 | typedef void (*setmode)(struct CHIPSTATE*, int mode); | 65 | typedef void (*setmode)(struct CHIPSTATE*, int mode); |
| 61 | typedef void (*checkmode)(struct CHIPSTATE*); | ||
| 62 | 66 | ||
| 63 | /* i2c command */ | 67 | /* i2c command */ |
| 64 | typedef struct AUDIOCMD { | 68 | typedef struct AUDIOCMD { |
| @@ -79,6 +83,7 @@ struct CHIPDESC { | |||
| 79 | #define CHIP_HAS_VOLUME 1 | 83 | #define CHIP_HAS_VOLUME 1 |
| 80 | #define CHIP_HAS_BASSTREBLE 2 | 84 | #define CHIP_HAS_BASSTREBLE 2 |
| 81 | #define CHIP_HAS_INPUTSEL 4 | 85 | #define CHIP_HAS_INPUTSEL 4 |
| 86 | #define CHIP_NEED_CHECKMODE 8 | ||
| 82 | 87 | ||
| 83 | /* various i2c command sequences */ | 88 | /* various i2c command sequences */ |
| 84 | audiocmd init; | 89 | audiocmd init; |
| @@ -96,23 +101,20 @@ struct CHIPDESC { | |||
| 96 | getmode getmode; | 101 | getmode getmode; |
| 97 | setmode setmode; | 102 | setmode setmode; |
| 98 | 103 | ||
| 99 | /* check / autoswitch audio after channel switches */ | ||
| 100 | checkmode checkmode; | ||
| 101 | |||
| 102 | /* input switch register + values for v4l inputs */ | 104 | /* input switch register + values for v4l inputs */ |
| 103 | int inputreg; | 105 | int inputreg; |
| 104 | int inputmap[4]; | 106 | int inputmap[4]; |
| 105 | int inputmute; | 107 | int inputmute; |
| 106 | int inputmask; | 108 | int inputmask; |
| 107 | }; | 109 | }; |
| 108 | static struct CHIPDESC chiplist[]; | ||
| 109 | 110 | ||
| 110 | /* current state of the chip */ | 111 | /* current state of the chip */ |
| 111 | struct CHIPSTATE { | 112 | struct CHIPSTATE { |
| 112 | struct i2c_client *c; | 113 | struct i2c_client *c; |
| 113 | 114 | ||
| 114 | /* index into CHIPDESC array */ | 115 | /* chip-specific description - should point to |
| 115 | int type; | 116 | an entry at CHIPDESC table */ |
| 117 | struct CHIPDESC *desc; | ||
| 116 | 118 | ||
| 117 | /* shadow register set */ | 119 | /* shadow register set */ |
| 118 | audiocmd shadow; | 120 | audiocmd shadow; |
| @@ -152,7 +154,7 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
| 152 | { | 154 | { |
| 153 | unsigned char buffer[2]; | 155 | unsigned char buffer[2]; |
| 154 | 156 | ||
| 155 | if (-1 == subaddr) { | 157 | if (subaddr < 0) { |
| 156 | v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", | 158 | v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", |
| 157 | chip->c->name, val); | 159 | chip->c->name, val); |
| 158 | chip->shadow.bytes[1] = val; | 160 | chip->shadow.bytes[1] = val; |
| @@ -163,6 +165,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
| 163 | return -1; | 165 | return -1; |
| 164 | } | 166 | } |
| 165 | } else { | 167 | } else { |
| 168 | if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | ||
| 169 | v4l_info(chip->c, | ||
| 170 | "Tried to access a non-existent register: %d\n", | ||
| 171 | subaddr); | ||
| 172 | return -EINVAL; | ||
| 173 | } | ||
| 174 | |||
| 166 | v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", | 175 | v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", |
| 167 | chip->c->name, subaddr, val); | 176 | chip->c->name, subaddr, val); |
| 168 | chip->shadow.bytes[subaddr+1] = val; | 177 | chip->shadow.bytes[subaddr+1] = val; |
| @@ -177,12 +186,20 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
| 177 | return 0; | 186 | return 0; |
| 178 | } | 187 | } |
| 179 | 188 | ||
| 180 | static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask) | 189 | static int chip_write_masked(struct CHIPSTATE *chip, |
| 190 | int subaddr, int val, int mask) | ||
| 181 | { | 191 | { |
| 182 | if (mask != 0) { | 192 | if (mask != 0) { |
| 183 | if (-1 == subaddr) { | 193 | if (subaddr < 0) { |
| 184 | val = (chip->shadow.bytes[1] & ~mask) | (val & mask); | 194 | val = (chip->shadow.bytes[1] & ~mask) | (val & mask); |
| 185 | } else { | 195 | } else { |
| 196 | if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | ||
| 197 | v4l_info(chip->c, | ||
| 198 | "Tried to access a non-existent register: %d\n", | ||
| 199 | subaddr); | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | |||
| 186 | val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); | 203 | val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); |
| 187 | } | 204 | } |
| 188 | } | 205 | } |
| @@ -228,6 +245,15 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) | |||
| 228 | if (0 == cmd->count) | 245 | if (0 == cmd->count) |
| 229 | return 0; | 246 | return 0; |
| 230 | 247 | ||
| 248 | if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | ||
| 249 | v4l_info(chip->c, | ||
| 250 | "Tried to access a non-existent register range: %d to %d\n", | ||
| 251 | cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1); | ||
| 252 | return -EINVAL; | ||
| 253 | } | ||
| 254 | |||
| 255 | /* FIXME: it seems that the shadow bytes are wrong bellow !*/ | ||
| 256 | |||
| 231 | /* update our shadow register set; print bytes if (debug > 0) */ | 257 | /* update our shadow register set; print bytes if (debug > 0) */ |
| 232 | v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", | 258 | v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", |
| 233 | chip->c->name, name,cmd->bytes[0]); | 259 | chip->c->name, name,cmd->bytes[0]); |
| @@ -263,7 +289,8 @@ static void chip_thread_wake(unsigned long data) | |||
| 263 | static int chip_thread(void *data) | 289 | static int chip_thread(void *data) |
| 264 | { | 290 | { |
| 265 | struct CHIPSTATE *chip = data; | 291 | struct CHIPSTATE *chip = data; |
| 266 | struct CHIPDESC *desc = chiplist + chip->type; | 292 | struct CHIPDESC *desc = chip->desc; |
| 293 | int mode; | ||
| 267 | 294 | ||
| 268 | v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name); | 295 | v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name); |
| 269 | set_freezable(); | 296 | set_freezable(); |
| @@ -282,7 +309,26 @@ static int chip_thread(void *data) | |||
| 282 | continue; | 309 | continue; |
| 283 | 310 | ||
| 284 | /* have a look what's going on */ | 311 | /* have a look what's going on */ |
| 285 | desc->checkmode(chip); | 312 | mode = desc->getmode(chip); |
| 313 | if (mode == chip->prevmode) | ||
| 314 | continue; | ||
| 315 | |||
| 316 | /* chip detected a new audio mode - set it */ | ||
| 317 | v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", | ||
| 318 | chip->c->name); | ||
| 319 | |||
| 320 | chip->prevmode = mode; | ||
| 321 | |||
| 322 | if (mode & V4L2_TUNER_MODE_STEREO) | ||
| 323 | desc->setmode(chip, V4L2_TUNER_MODE_STEREO); | ||
| 324 | if (mode & V4L2_TUNER_MODE_LANG1_LANG2) | ||
| 325 | desc->setmode(chip, V4L2_TUNER_MODE_STEREO); | ||
| 326 | else if (mode & V4L2_TUNER_MODE_LANG1) | ||
| 327 | desc->setmode(chip, V4L2_TUNER_MODE_LANG1); | ||
| 328 | else if (mode & V4L2_TUNER_MODE_LANG2) | ||
| 329 | desc->setmode(chip, V4L2_TUNER_MODE_LANG2); | ||
| 330 | else | ||
| 331 | desc->setmode(chip, V4L2_TUNER_MODE_MONO); | ||
| 286 | 332 | ||
| 287 | /* schedule next check */ | 333 | /* schedule next check */ |
| 288 | mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); | 334 | mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); |
| @@ -292,29 +338,6 @@ static int chip_thread(void *data) | |||
| 292 | return 0; | 338 | return 0; |
| 293 | } | 339 | } |
| 294 | 340 | ||
| 295 | static void generic_checkmode(struct CHIPSTATE *chip) | ||
| 296 | { | ||
| 297 | struct CHIPDESC *desc = chiplist + chip->type; | ||
| 298 | int mode = desc->getmode(chip); | ||
| 299 | |||
| 300 | if (mode == chip->prevmode) | ||
| 301 | return; | ||
| 302 | |||
| 303 | v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", chip->c->name); | ||
| 304 | chip->prevmode = mode; | ||
| 305 | |||
| 306 | if (mode & V4L2_TUNER_MODE_STEREO) | ||
| 307 | desc->setmode(chip,V4L2_TUNER_MODE_STEREO); | ||
| 308 | if (mode & V4L2_TUNER_MODE_LANG1_LANG2) | ||
| 309 | desc->setmode(chip,V4L2_TUNER_MODE_STEREO); | ||
| 310 | else if (mode & V4L2_TUNER_MODE_LANG1) | ||
| 311 | desc->setmode(chip,V4L2_TUNER_MODE_LANG1); | ||
| 312 | else if (mode & V4L2_TUNER_MODE_LANG2) | ||
| 313 | desc->setmode(chip,V4L2_TUNER_MODE_LANG2); | ||
| 314 | else | ||
| 315 | desc->setmode(chip,V4L2_TUNER_MODE_MONO); | ||
| 316 | } | ||
| 317 | |||
| 318 | /* ---------------------------------------------------------------------- */ | 341 | /* ---------------------------------------------------------------------- */ |
| 319 | /* audio chip descriptions - defines+functions for tda9840 */ | 342 | /* audio chip descriptions - defines+functions for tda9840 */ |
| 320 | 343 | ||
| @@ -777,7 +800,7 @@ static struct tda9874a_MODES { | |||
| 777 | char *name; | 800 | char *name; |
| 778 | audiocmd cmd; | 801 | audiocmd cmd; |
| 779 | } tda9874a_modelist[9] = { | 802 | } tda9874a_modelist[9] = { |
| 780 | { "A2, B/G", | 803 | { "A2, B/G", /* default */ |
| 781 | { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} }, | 804 | { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} }, |
| 782 | { "A2, M (Korea)", | 805 | { "A2, M (Korea)", |
| 783 | { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} }, | 806 | { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} }, |
| @@ -791,7 +814,7 @@ static struct tda9874a_MODES { | |||
| 791 | { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} }, | 814 | { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} }, |
| 792 | { "NICAM, B/G", | 815 | { "NICAM, B/G", |
| 793 | { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} }, | 816 | { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} }, |
| 794 | { "NICAM, D/K", /* default */ | 817 | { "NICAM, D/K", |
| 795 | { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} }, | 818 | { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} }, |
| 796 | { "NICAM, L", | 819 | { "NICAM, L", |
| 797 | { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} } | 820 | { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} } |
| @@ -981,7 +1004,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) | |||
| 981 | { | 1004 | { |
| 982 | if (tda9874a_SIF > 2) | 1005 | if (tda9874a_SIF > 2) |
| 983 | tda9874a_SIF = 1; | 1006 | tda9874a_SIF = 1; |
| 984 | if (tda9874a_STD > 8) | 1007 | if (tda9874a_STD >= ARRAY_SIZE(tda9874a_modelist)) |
| 985 | tda9874a_STD = 0; | 1008 | tda9874a_STD = 0; |
| 986 | if(tda9874a_AMSEL > 1) | 1009 | if(tda9874a_AMSEL > 1) |
| 987 | tda9874a_AMSEL = 0; | 1010 | tda9874a_AMSEL = 0; |
| @@ -1089,7 +1112,7 @@ static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; } | |||
| 1089 | 1112 | ||
| 1090 | static int tda8425_initialize(struct CHIPSTATE *chip) | 1113 | static int tda8425_initialize(struct CHIPSTATE *chip) |
| 1091 | { | 1114 | { |
| 1092 | struct CHIPDESC *desc = chiplist + chip->type; | 1115 | struct CHIPDESC *desc = chip->desc; |
| 1093 | int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, | 1116 | int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, |
| 1094 | /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF}; | 1117 | /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF}; |
| 1095 | 1118 | ||
| @@ -1259,27 +1282,28 @@ static struct CHIPDESC chiplist[] = { | |||
| 1259 | .addr_lo = I2C_ADDR_TDA9840 >> 1, | 1282 | .addr_lo = I2C_ADDR_TDA9840 >> 1, |
| 1260 | .addr_hi = I2C_ADDR_TDA9840 >> 1, | 1283 | .addr_hi = I2C_ADDR_TDA9840 >> 1, |
| 1261 | .registers = 5, | 1284 | .registers = 5, |
| 1285 | .flags = CHIP_NEED_CHECKMODE, | ||
| 1262 | 1286 | ||
| 1287 | /* callbacks */ | ||
| 1263 | .checkit = tda9840_checkit, | 1288 | .checkit = tda9840_checkit, |
| 1264 | .getmode = tda9840_getmode, | 1289 | .getmode = tda9840_getmode, |
| 1265 | .setmode = tda9840_setmode, | 1290 | .setmode = tda9840_setmode, |
| 1266 | .checkmode = generic_checkmode, | ||
| 1267 | 1291 | ||
| 1268 | .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN | 1292 | .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN |
| 1269 | /* ,TDA9840_SW, TDA9840_MONO */} } | 1293 | /* ,TDA9840_SW, TDA9840_MONO */} } |
| 1270 | }, | 1294 | }, |
| 1271 | { | 1295 | { |
| 1272 | .name = "tda9873h", | 1296 | .name = "tda9873h", |
| 1273 | .checkit = tda9873_checkit, | ||
| 1274 | .insmodopt = &tda9873, | 1297 | .insmodopt = &tda9873, |
| 1275 | .addr_lo = I2C_ADDR_TDA985x_L >> 1, | 1298 | .addr_lo = I2C_ADDR_TDA985x_L >> 1, |
| 1276 | .addr_hi = I2C_ADDR_TDA985x_H >> 1, | 1299 | .addr_hi = I2C_ADDR_TDA985x_H >> 1, |
| 1277 | .registers = 3, | 1300 | .registers = 3, |
| 1278 | .flags = CHIP_HAS_INPUTSEL, | 1301 | .flags = CHIP_HAS_INPUTSEL | CHIP_NEED_CHECKMODE, |
| 1279 | 1302 | ||
| 1303 | /* callbacks */ | ||
| 1304 | .checkit = tda9873_checkit, | ||
| 1280 | .getmode = tda9873_getmode, | 1305 | .getmode = tda9873_getmode, |
| 1281 | .setmode = tda9873_setmode, | 1306 | .setmode = tda9873_setmode, |
| 1282 | .checkmode = generic_checkmode, | ||
| 1283 | 1307 | ||
| 1284 | .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, | 1308 | .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, |
| 1285 | .inputreg = TDA9873_SW, | 1309 | .inputreg = TDA9873_SW, |
| @@ -1290,15 +1314,16 @@ static struct CHIPDESC chiplist[] = { | |||
| 1290 | }, | 1314 | }, |
| 1291 | { | 1315 | { |
| 1292 | .name = "tda9874h/a", | 1316 | .name = "tda9874h/a", |
| 1293 | .checkit = tda9874a_checkit, | ||
| 1294 | .initialize = tda9874a_initialize, | ||
| 1295 | .insmodopt = &tda9874a, | 1317 | .insmodopt = &tda9874a, |
| 1296 | .addr_lo = I2C_ADDR_TDA9874 >> 1, | 1318 | .addr_lo = I2C_ADDR_TDA9874 >> 1, |
| 1297 | .addr_hi = I2C_ADDR_TDA9874 >> 1, | 1319 | .addr_hi = I2C_ADDR_TDA9874 >> 1, |
| 1320 | .flags = CHIP_NEED_CHECKMODE, | ||
| 1298 | 1321 | ||
| 1322 | /* callbacks */ | ||
| 1323 | .initialize = tda9874a_initialize, | ||
| 1324 | .checkit = tda9874a_checkit, | ||
| 1299 | .getmode = tda9874a_getmode, | 1325 | .getmode = tda9874a_getmode, |
| 1300 | .setmode = tda9874a_setmode, | 1326 | .setmode = tda9874a_setmode, |
| 1301 | .checkmode = generic_checkmode, | ||
| 1302 | }, | 1327 | }, |
| 1303 | { | 1328 | { |
| 1304 | .name = "tda9850", | 1329 | .name = "tda9850", |
| @@ -1324,10 +1349,11 @@ static struct CHIPDESC chiplist[] = { | |||
| 1324 | .rightreg = TDA9855_VR, | 1349 | .rightreg = TDA9855_VR, |
| 1325 | .bassreg = TDA9855_BA, | 1350 | .bassreg = TDA9855_BA, |
| 1326 | .treblereg = TDA9855_TR, | 1351 | .treblereg = TDA9855_TR, |
| 1352 | |||
| 1353 | /* callbacks */ | ||
| 1327 | .volfunc = tda9855_volume, | 1354 | .volfunc = tda9855_volume, |
| 1328 | .bassfunc = tda9855_bass, | 1355 | .bassfunc = tda9855_bass, |
| 1329 | .treblefunc = tda9855_treble, | 1356 | .treblefunc = tda9855_treble, |
| 1330 | |||
| 1331 | .getmode = tda985x_getmode, | 1357 | .getmode = tda985x_getmode, |
| 1332 | .setmode = tda985x_setmode, | 1358 | .setmode = tda985x_setmode, |
| 1333 | 1359 | ||
| @@ -1348,6 +1374,8 @@ static struct CHIPDESC chiplist[] = { | |||
| 1348 | .rightreg = TEA6300_VL, | 1374 | .rightreg = TEA6300_VL, |
| 1349 | .bassreg = TEA6300_BA, | 1375 | .bassreg = TEA6300_BA, |
| 1350 | .treblereg = TEA6300_TR, | 1376 | .treblereg = TEA6300_TR, |
| 1377 | |||
| 1378 | /* callbacks */ | ||
| 1351 | .volfunc = tea6300_shift10, | 1379 | .volfunc = tea6300_shift10, |
| 1352 | .bassfunc = tea6300_shift12, | 1380 | .bassfunc = tea6300_shift12, |
| 1353 | .treblefunc = tea6300_shift12, | 1381 | .treblefunc = tea6300_shift12, |
| @@ -1358,7 +1386,6 @@ static struct CHIPDESC chiplist[] = { | |||
| 1358 | }, | 1386 | }, |
| 1359 | { | 1387 | { |
| 1360 | .name = "tea6320", | 1388 | .name = "tea6320", |
| 1361 | .initialize = tea6320_initialize, | ||
| 1362 | .insmodopt = &tea6320, | 1389 | .insmodopt = &tea6320, |
| 1363 | .addr_lo = I2C_ADDR_TEA6300 >> 1, | 1390 | .addr_lo = I2C_ADDR_TEA6300 >> 1, |
| 1364 | .addr_hi = I2C_ADDR_TEA6300 >> 1, | 1391 | .addr_hi = I2C_ADDR_TEA6300 >> 1, |
| @@ -1369,6 +1396,9 @@ static struct CHIPDESC chiplist[] = { | |||
| 1369 | .rightreg = TEA6320_V, | 1396 | .rightreg = TEA6320_V, |
| 1370 | .bassreg = TEA6320_BA, | 1397 | .bassreg = TEA6320_BA, |
| 1371 | .treblereg = TEA6320_TR, | 1398 | .treblereg = TEA6320_TR, |
| 1399 | |||
| 1400 | /* callbacks */ | ||
| 1401 | .initialize = tea6320_initialize, | ||
| 1372 | .volfunc = tea6320_volume, | 1402 | .volfunc = tea6320_volume, |
| 1373 | .bassfunc = tea6320_shift11, | 1403 | .bassfunc = tea6320_shift11, |
| 1374 | .treblefunc = tea6320_shift11, | 1404 | .treblefunc = tea6320_shift11, |
| @@ -1401,16 +1431,18 @@ static struct CHIPDESC chiplist[] = { | |||
| 1401 | .rightreg = TDA8425_VR, | 1431 | .rightreg = TDA8425_VR, |
| 1402 | .bassreg = TDA8425_BA, | 1432 | .bassreg = TDA8425_BA, |
| 1403 | .treblereg = TDA8425_TR, | 1433 | .treblereg = TDA8425_TR, |
| 1434 | |||
| 1435 | /* callbacks */ | ||
| 1436 | .initialize = tda8425_initialize, | ||
| 1404 | .volfunc = tda8425_shift10, | 1437 | .volfunc = tda8425_shift10, |
| 1405 | .bassfunc = tda8425_shift12, | 1438 | .bassfunc = tda8425_shift12, |
| 1406 | .treblefunc = tda8425_shift12, | 1439 | .treblefunc = tda8425_shift12, |
| 1440 | .setmode = tda8425_setmode, | ||
| 1407 | 1441 | ||
| 1408 | .inputreg = TDA8425_S1, | 1442 | .inputreg = TDA8425_S1, |
| 1409 | .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 }, | 1443 | .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 }, |
| 1410 | .inputmute = TDA8425_S1_OFF, | 1444 | .inputmute = TDA8425_S1_OFF, |
| 1411 | 1445 | ||
| 1412 | .setmode = tda8425_setmode, | ||
| 1413 | .initialize = tda8425_initialize, | ||
| 1414 | }, | 1446 | }, |
| 1415 | { | 1447 | { |
| 1416 | .name = "pic16c54 (PV951)", | 1448 | .name = "pic16c54 (PV951)", |
| @@ -1434,10 +1466,11 @@ static struct CHIPDESC chiplist[] = { | |||
| 1434 | .addr_lo = I2C_ADDR_TDA9840 >> 1, | 1466 | .addr_lo = I2C_ADDR_TDA9840 >> 1, |
| 1435 | .addr_hi = I2C_ADDR_TDA9840 >> 1, | 1467 | .addr_hi = I2C_ADDR_TDA9840 >> 1, |
| 1436 | .registers = 2, | 1468 | .registers = 2, |
| 1469 | .flags = CHIP_NEED_CHECKMODE, | ||
| 1437 | 1470 | ||
| 1471 | /* callbacks */ | ||
| 1438 | .getmode = ta8874z_getmode, | 1472 | .getmode = ta8874z_getmode, |
| 1439 | .setmode = ta8874z_setmode, | 1473 | .setmode = ta8874z_setmode, |
| 1440 | .checkmode = generic_checkmode, | ||
| 1441 | 1474 | ||
| 1442 | .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, | 1475 | .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, |
| 1443 | }, | 1476 | }, |
| @@ -1481,6 +1514,7 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1481 | } | 1514 | } |
| 1482 | if (desc->name == NULL) { | 1515 | if (desc->name == NULL) { |
| 1483 | v4l_dbg(1, debug, client, "no matching chip description found\n"); | 1516 | v4l_dbg(1, debug, client, "no matching chip description found\n"); |
| 1517 | kfree(chip); | ||
| 1484 | return -EIO; | 1518 | return -EIO; |
| 1485 | } | 1519 | } |
| 1486 | v4l_info(client, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name); | 1520 | v4l_info(client, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name); |
| @@ -1494,7 +1528,7 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1494 | /* fill required data structures */ | 1528 | /* fill required data structures */ |
| 1495 | if (!id) | 1529 | if (!id) |
| 1496 | strlcpy(client->name, desc->name, I2C_NAME_SIZE); | 1530 | strlcpy(client->name, desc->name, I2C_NAME_SIZE); |
| 1497 | chip->type = desc-chiplist; | 1531 | chip->desc = desc; |
| 1498 | chip->shadow.count = desc->registers+1; | 1532 | chip->shadow.count = desc->registers+1; |
| 1499 | chip->prevmode = -1; | 1533 | chip->prevmode = -1; |
| 1500 | chip->audmode = V4L2_TUNER_MODE_LANG1; | 1534 | chip->audmode = V4L2_TUNER_MODE_LANG1; |
| @@ -1506,20 +1540,49 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 1506 | chip_cmd(chip,"init",&desc->init); | 1540 | chip_cmd(chip,"init",&desc->init); |
| 1507 | 1541 | ||
| 1508 | if (desc->flags & CHIP_HAS_VOLUME) { | 1542 | if (desc->flags & CHIP_HAS_VOLUME) { |
| 1509 | chip->left = desc->leftinit ? desc->leftinit : 65535; | 1543 | if (!desc->volfunc) { |
| 1510 | chip->right = desc->rightinit ? desc->rightinit : 65535; | 1544 | /* This shouldn't be happen. Warn user, but keep working |
| 1511 | chip_write(chip,desc->leftreg,desc->volfunc(chip->left)); | 1545 | without volume controls |
| 1512 | chip_write(chip,desc->rightreg,desc->volfunc(chip->right)); | 1546 | */ |
| 1547 | v4l_info(chip->c, "volume callback undefined!\n"); | ||
| 1548 | desc->flags &= ~CHIP_HAS_VOLUME; | ||
| 1549 | } else { | ||
| 1550 | chip->left = desc->leftinit ? desc->leftinit : 65535; | ||
| 1551 | chip->right = desc->rightinit ? desc->rightinit : 65535; | ||
| 1552 | chip_write(chip, desc->leftreg, | ||
| 1553 | desc->volfunc(chip->left)); | ||
| 1554 | chip_write(chip, desc->rightreg, | ||
| 1555 | desc->volfunc(chip->right)); | ||
| 1556 | } | ||
| 1513 | } | 1557 | } |
| 1514 | if (desc->flags & CHIP_HAS_BASSTREBLE) { | 1558 | if (desc->flags & CHIP_HAS_BASSTREBLE) { |
| 1515 | chip->treble = desc->trebleinit ? desc->trebleinit : 32768; | 1559 | if (!desc->bassfunc || !desc->treblefunc) { |
| 1516 | chip->bass = desc->bassinit ? desc->bassinit : 32768; | 1560 | /* This shouldn't be happen. Warn user, but keep working |
| 1517 | chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); | 1561 | without bass/treble controls |
| 1518 | chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); | 1562 | */ |
| 1563 | v4l_info(chip->c, "bass/treble callbacks undefined!\n"); | ||
| 1564 | desc->flags &= ~CHIP_HAS_BASSTREBLE; | ||
| 1565 | } else { | ||
| 1566 | chip->treble = desc->trebleinit ? | ||
| 1567 | desc->trebleinit : 32768; | ||
| 1568 | chip->bass = desc->bassinit ? | ||
| 1569 | desc->bassinit : 32768; | ||
| 1570 | chip_write(chip, desc->bassreg, | ||
| 1571 | desc->bassfunc(chip->bass)); | ||
| 1572 | chip_write(chip, desc->treblereg, | ||
| 1573 | desc->treblefunc(chip->treble)); | ||
| 1574 | } | ||
| 1519 | } | 1575 | } |
| 1520 | 1576 | ||
| 1521 | chip->thread = NULL; | 1577 | chip->thread = NULL; |
| 1522 | if (desc->checkmode) { | 1578 | if (desc->flags & CHIP_NEED_CHECKMODE) { |
| 1579 | if (!desc->getmode || !desc->setmode) { | ||
| 1580 | /* This shouldn't be happen. Warn user, but keep working | ||
| 1581 | without kthread | ||
| 1582 | */ | ||
| 1583 | v4l_info(chip->c, "set/get mode callbacks undefined!\n"); | ||
| 1584 | return 0; | ||
| 1585 | } | ||
| 1523 | /* start async thread */ | 1586 | /* start async thread */ |
| 1524 | init_timer(&chip->wt); | 1587 | init_timer(&chip->wt); |
| 1525 | chip->wt.function = chip_thread_wake; | 1588 | chip->wt.function = chip_thread_wake; |
| @@ -1552,7 +1615,7 @@ static int chip_remove(struct i2c_client *client) | |||
| 1552 | static int tvaudio_get_ctrl(struct CHIPSTATE *chip, | 1615 | static int tvaudio_get_ctrl(struct CHIPSTATE *chip, |
| 1553 | struct v4l2_control *ctrl) | 1616 | struct v4l2_control *ctrl) |
| 1554 | { | 1617 | { |
| 1555 | struct CHIPDESC *desc = chiplist + chip->type; | 1618 | struct CHIPDESC *desc = chip->desc; |
| 1556 | 1619 | ||
| 1557 | switch (ctrl->id) { | 1620 | switch (ctrl->id) { |
| 1558 | case V4L2_CID_AUDIO_MUTE: | 1621 | case V4L2_CID_AUDIO_MUTE: |
| @@ -1576,13 +1639,13 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip, | |||
| 1576 | return 0; | 1639 | return 0; |
| 1577 | } | 1640 | } |
| 1578 | case V4L2_CID_AUDIO_BASS: | 1641 | case V4L2_CID_AUDIO_BASS: |
| 1579 | if (desc->flags & CHIP_HAS_BASSTREBLE) | 1642 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
| 1580 | break; | 1643 | break; |
| 1581 | ctrl->value = chip->bass; | 1644 | ctrl->value = chip->bass; |
| 1582 | return 0; | 1645 | return 0; |
| 1583 | case V4L2_CID_AUDIO_TREBLE: | 1646 | case V4L2_CID_AUDIO_TREBLE: |
| 1584 | if (desc->flags & CHIP_HAS_BASSTREBLE) | 1647 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
| 1585 | return -EINVAL; | 1648 | break; |
| 1586 | ctrl->value = chip->treble; | 1649 | ctrl->value = chip->treble; |
| 1587 | return 0; | 1650 | return 0; |
| 1588 | } | 1651 | } |
| @@ -1592,7 +1655,7 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip, | |||
| 1592 | static int tvaudio_set_ctrl(struct CHIPSTATE *chip, | 1655 | static int tvaudio_set_ctrl(struct CHIPSTATE *chip, |
| 1593 | struct v4l2_control *ctrl) | 1656 | struct v4l2_control *ctrl) |
| 1594 | { | 1657 | { |
| 1595 | struct CHIPDESC *desc = chiplist + chip->type; | 1658 | struct CHIPDESC *desc = chip->desc; |
| 1596 | 1659 | ||
| 1597 | switch (ctrl->id) { | 1660 | switch (ctrl->id) { |
| 1598 | case V4L2_CID_AUDIO_MUTE: | 1661 | case V4L2_CID_AUDIO_MUTE: |
| @@ -1642,16 +1705,15 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip, | |||
| 1642 | return 0; | 1705 | return 0; |
| 1643 | } | 1706 | } |
| 1644 | case V4L2_CID_AUDIO_BASS: | 1707 | case V4L2_CID_AUDIO_BASS: |
| 1645 | if (desc->flags & CHIP_HAS_BASSTREBLE) | 1708 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
| 1646 | break; | 1709 | break; |
| 1647 | chip->bass = ctrl->value; | 1710 | chip->bass = ctrl->value; |
| 1648 | chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); | 1711 | chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); |
| 1649 | 1712 | ||
| 1650 | return 0; | 1713 | return 0; |
| 1651 | case V4L2_CID_AUDIO_TREBLE: | 1714 | case V4L2_CID_AUDIO_TREBLE: |
| 1652 | if (desc->flags & CHIP_HAS_BASSTREBLE) | 1715 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
| 1653 | return -EINVAL; | 1716 | break; |
| 1654 | |||
| 1655 | chip->treble = ctrl->value; | 1717 | chip->treble = ctrl->value; |
| 1656 | chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); | 1718 | chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); |
| 1657 | 1719 | ||
| @@ -1668,9 +1730,12 @@ static int chip_command(struct i2c_client *client, | |||
| 1668 | unsigned int cmd, void *arg) | 1730 | unsigned int cmd, void *arg) |
| 1669 | { | 1731 | { |
| 1670 | struct CHIPSTATE *chip = i2c_get_clientdata(client); | 1732 | struct CHIPSTATE *chip = i2c_get_clientdata(client); |
| 1671 | struct CHIPDESC *desc = chiplist + chip->type; | 1733 | struct CHIPDESC *desc = chip->desc; |
| 1672 | 1734 | ||
| 1673 | v4l_dbg(1, debug, chip->c, "%s: chip_command 0x%x\n", chip->c->name, cmd); | 1735 | if (debug > 0) { |
| 1736 | v4l_i2c_print_ioctl(chip->c, cmd); | ||
| 1737 | printk("\n"); | ||
| 1738 | } | ||
| 1674 | 1739 | ||
| 1675 | switch (cmd) { | 1740 | switch (cmd) { |
| 1676 | case AUDC_SET_RADIO: | 1741 | case AUDC_SET_RADIO: |
| @@ -1695,7 +1760,7 @@ static int chip_command(struct i2c_client *client, | |||
| 1695 | break; | 1760 | break; |
| 1696 | case V4L2_CID_AUDIO_BASS: | 1761 | case V4L2_CID_AUDIO_BASS: |
| 1697 | case V4L2_CID_AUDIO_TREBLE: | 1762 | case V4L2_CID_AUDIO_TREBLE: |
| 1698 | if (desc->flags & CHIP_HAS_BASSTREBLE) | 1763 | if (!(desc->flags & CHIP_HAS_BASSTREBLE)) |
| 1699 | return -EINVAL; | 1764 | return -EINVAL; |
| 1700 | break; | 1765 | break; |
| 1701 | default: | 1766 | default: |
| @@ -1792,12 +1857,20 @@ static int chip_command(struct i2c_client *client, | |||
| 1792 | break; | 1857 | break; |
| 1793 | case VIDIOC_S_FREQUENCY: | 1858 | case VIDIOC_S_FREQUENCY: |
| 1794 | chip->mode = 0; /* automatic */ | 1859 | chip->mode = 0; /* automatic */ |
| 1795 | if (desc->checkmode && desc->setmode) { | 1860 | |
| 1861 | /* For chips that provide getmode and setmode, and doesn't | ||
| 1862 | automatically follows the stereo carrier, a kthread is | ||
| 1863 | created to set the audio standard. In this case, when then | ||
| 1864 | the video channel is changed, tvaudio starts on MONO mode. | ||
| 1865 | After waiting for 2 seconds, the kernel thread is called, | ||
| 1866 | to follow whatever audio standard is pointed by the | ||
| 1867 | audio carrier. | ||
| 1868 | */ | ||
| 1869 | if (chip->thread) { | ||
| 1796 | desc->setmode(chip,V4L2_TUNER_MODE_MONO); | 1870 | desc->setmode(chip,V4L2_TUNER_MODE_MONO); |
| 1797 | if (chip->prevmode != V4L2_TUNER_MODE_MONO) | 1871 | if (chip->prevmode != V4L2_TUNER_MODE_MONO) |
| 1798 | chip->prevmode = -1; /* reset previous mode */ | 1872 | chip->prevmode = -1; /* reset previous mode */ |
| 1799 | mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); | 1873 | mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); |
| 1800 | /* the thread will call checkmode() later */ | ||
| 1801 | } | 1874 | } |
| 1802 | break; | 1875 | break; |
| 1803 | 1876 | ||
| @@ -1836,9 +1909,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { | |||
| 1836 | .legacy_probe = chip_legacy_probe, | 1909 | .legacy_probe = chip_legacy_probe, |
| 1837 | .id_table = chip_id, | 1910 | .id_table = chip_id, |
| 1838 | }; | 1911 | }; |
| 1839 | |||
| 1840 | /* | ||
| 1841 | * Local variables: | ||
| 1842 | * c-basic-offset: 8 | ||
| 1843 | * End: | ||
| 1844 | */ | ||
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c index 28421d386f1e..c710bcd1df48 100644 --- a/drivers/media/video/usbvideo/ibmcam.c +++ b/drivers/media/video/usbvideo/ibmcam.c | |||
| @@ -3695,7 +3695,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 3695 | unsigned char video_ep = 0; | 3695 | unsigned char video_ep = 0; |
| 3696 | 3696 | ||
| 3697 | if (debug >= 1) | 3697 | if (debug >= 1) |
| 3698 | dev_info(&uvd->dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); | 3698 | dev_info(&dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); |
| 3699 | 3699 | ||
| 3700 | /* We don't handle multi-config cameras */ | 3700 | /* We don't handle multi-config cameras */ |
| 3701 | if (dev->descriptor.bNumConfigurations != 1) | 3701 | if (dev->descriptor.bNumConfigurations != 1) |
| @@ -3746,7 +3746,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 3746 | brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ | 3746 | brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ |
| 3747 | break; | 3747 | break; |
| 3748 | } | 3748 | } |
| 3749 | dev_info(&uvd->dev->dev, | 3749 | dev_info(&dev->dev, |
| 3750 | "%s USB camera found (model %d, rev. 0x%04x)\n", | 3750 | "%s USB camera found (model %d, rev. 0x%04x)\n", |
| 3751 | brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); | 3751 | brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); |
| 3752 | } while (0); | 3752 | } while (0); |
| @@ -3754,7 +3754,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 3754 | /* Validate found interface: must have one ISO endpoint */ | 3754 | /* Validate found interface: must have one ISO endpoint */ |
| 3755 | nas = intf->num_altsetting; | 3755 | nas = intf->num_altsetting; |
| 3756 | if (debug > 0) | 3756 | if (debug > 0) |
| 3757 | dev_info(&uvd->dev->dev, "Number of alternate settings=%d.\n", | 3757 | dev_info(&dev->dev, "Number of alternate settings=%d.\n", |
| 3758 | nas); | 3758 | nas); |
| 3759 | if (nas < 2) { | 3759 | if (nas < 2) { |
| 3760 | err("Too few alternate settings for this camera!"); | 3760 | err("Too few alternate settings for this camera!"); |
| @@ -3799,7 +3799,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 3799 | actInterface = i; | 3799 | actInterface = i; |
| 3800 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); | 3800 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); |
| 3801 | if (debug > 0) | 3801 | if (debug > 0) |
| 3802 | dev_info(&uvd->dev->dev, | 3802 | dev_info(&dev->dev, |
| 3803 | "Active setting=%d. " | 3803 | "Active setting=%d. " |
| 3804 | "maxPS=%d.\n", i, maxPS); | 3804 | "maxPS=%d.\n", i, maxPS); |
| 3805 | } else | 3805 | } else |
| @@ -3840,7 +3840,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 3840 | RESTRICT_TO_RANGE(framerate, 0, 5); | 3840 | RESTRICT_TO_RANGE(framerate, 0, 5); |
| 3841 | break; | 3841 | break; |
| 3842 | default: | 3842 | default: |
| 3843 | dev_info(&uvd->dev->dev, "IBM camera: using 320x240\n"); | 3843 | dev_info(&dev->dev, "IBM camera: using 320x240\n"); |
| 3844 | size = SIZE_320x240; | 3844 | size = SIZE_320x240; |
| 3845 | /* No break here */ | 3845 | /* No break here */ |
| 3846 | case SIZE_320x240: | 3846 | case SIZE_320x240: |
| @@ -3869,7 +3869,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
| 3869 | canvasY = 120; | 3869 | canvasY = 120; |
| 3870 | break; | 3870 | break; |
| 3871 | default: | 3871 | default: |
| 3872 | dev_info(&uvd->dev->dev, "IBM NetCamera: using 176x144\n"); | 3872 | dev_info(&dev->dev, "IBM NetCamera: using 176x144\n"); |
| 3873 | size = SIZE_176x144; | 3873 | size = SIZE_176x144; |
| 3874 | /* No break here */ | 3874 | /* No break here */ |
| 3875 | case SIZE_176x144: | 3875 | case SIZE_176x144: |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index f5233f3d9eff..b89f476cd0a9 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
| @@ -559,12 +559,6 @@ mptctl_fasync(int fd, struct file *filep, int mode) | |||
| 559 | return ret; | 559 | return ret; |
| 560 | } | 560 | } |
| 561 | 561 | ||
| 562 | static int | ||
| 563 | mptctl_release(struct inode *inode, struct file *filep) | ||
| 564 | { | ||
| 565 | return fasync_helper(-1, filep, 0, &async_queue); | ||
| 566 | } | ||
| 567 | |||
| 568 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 562 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 569 | /* | 563 | /* |
| 570 | * MPT ioctl handler | 564 | * MPT ioctl handler |
| @@ -2706,7 +2700,6 @@ mptctl_hp_targetinfo(unsigned long arg) | |||
| 2706 | static const struct file_operations mptctl_fops = { | 2700 | static const struct file_operations mptctl_fops = { |
| 2707 | .owner = THIS_MODULE, | 2701 | .owner = THIS_MODULE, |
| 2708 | .llseek = no_llseek, | 2702 | .llseek = no_llseek, |
| 2709 | .release = mptctl_release, | ||
| 2710 | .fasync = mptctl_fasync, | 2703 | .fasync = mptctl_fasync, |
| 2711 | .unlocked_ioctl = mptctl_ioctl, | 2704 | .unlocked_ioctl = mptctl_ioctl, |
| 2712 | #ifdef CONFIG_COMPAT | 2705 | #ifdef CONFIG_COMPAT |
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index a1abf95cf751..603ffd008c73 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c | |||
| @@ -77,12 +77,6 @@ MODULE_VERSION(my_VERSION); | |||
| 77 | * Fusion MPT LAN private structures | 77 | * Fusion MPT LAN private structures |
| 78 | */ | 78 | */ |
| 79 | 79 | ||
| 80 | struct NAA_Hosed { | ||
| 81 | u16 NAA; | ||
| 82 | u8 ieee[FC_ALEN]; | ||
| 83 | struct NAA_Hosed *next; | ||
| 84 | }; | ||
| 85 | |||
| 86 | struct BufferControl { | 80 | struct BufferControl { |
| 87 | struct sk_buff *skb; | 81 | struct sk_buff *skb; |
| 88 | dma_addr_t dma; | 82 | dma_addr_t dma; |
| @@ -159,11 +153,6 @@ static u8 LanCtx = MPT_MAX_PROTOCOL_DRIVERS; | |||
| 159 | static u32 max_buckets_out = 127; | 153 | static u32 max_buckets_out = 127; |
| 160 | static u32 tx_max_out_p = 127 - 16; | 154 | static u32 tx_max_out_p = 127 - 16; |
| 161 | 155 | ||
| 162 | #ifdef QLOGIC_NAA_WORKAROUND | ||
| 163 | static struct NAA_Hosed *mpt_bad_naa = NULL; | ||
| 164 | DEFINE_RWLOCK(bad_naa_lock); | ||
| 165 | #endif | ||
| 166 | |||
| 167 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 156 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 168 | /** | 157 | /** |
| 169 | * lan_reply - Handle all data sent from the hardware. | 158 | * lan_reply - Handle all data sent from the hardware. |
| @@ -780,30 +769,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) | |||
| 780 | // ctx, skb, skb->data)); | 769 | // ctx, skb, skb->data)); |
| 781 | 770 | ||
| 782 | mac = skb_mac_header(skb); | 771 | mac = skb_mac_header(skb); |
| 783 | #ifdef QLOGIC_NAA_WORKAROUND | ||
| 784 | { | ||
| 785 | struct NAA_Hosed *nh; | ||
| 786 | |||
| 787 | /* Munge the NAA for Tx packets to QLogic boards, which don't follow | ||
| 788 | RFC 2625. The longer I look at this, the more my opinion of Qlogic | ||
| 789 | drops. */ | ||
| 790 | read_lock_irq(&bad_naa_lock); | ||
| 791 | for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) { | ||
| 792 | if ((nh->ieee[0] == mac[0]) && | ||
| 793 | (nh->ieee[1] == mac[1]) && | ||
| 794 | (nh->ieee[2] == mac[2]) && | ||
| 795 | (nh->ieee[3] == mac[3]) && | ||
| 796 | (nh->ieee[4] == mac[4]) && | ||
| 797 | (nh->ieee[5] == mac[5])) { | ||
| 798 | cur_naa = nh->NAA; | ||
| 799 | dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value " | ||
| 800 | "= %04x.\n", cur_naa)); | ||
| 801 | break; | ||
| 802 | } | ||
| 803 | } | ||
| 804 | read_unlock_irq(&bad_naa_lock); | ||
| 805 | } | ||
| 806 | #endif | ||
| 807 | 772 | ||
| 808 | pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | | 773 | pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | |
| 809 | (mac[0] << 8) | | 774 | (mac[0] << 8) | |
| @@ -1572,79 +1537,6 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 1572 | 1537 | ||
| 1573 | fcllc = (struct fcllc *)skb->data; | 1538 | fcllc = (struct fcllc *)skb->data; |
| 1574 | 1539 | ||
| 1575 | #ifdef QLOGIC_NAA_WORKAROUND | ||
| 1576 | { | ||
| 1577 | u16 source_naa = fch->stype, found = 0; | ||
| 1578 | |||
| 1579 | /* Workaround for QLogic not following RFC 2625 in regards to the NAA | ||
| 1580 | value. */ | ||
| 1581 | |||
| 1582 | if ((source_naa & 0xF000) == 0) | ||
| 1583 | source_naa = swab16(source_naa); | ||
| 1584 | |||
| 1585 | if (fcllc->ethertype == htons(ETH_P_ARP)) | ||
| 1586 | dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of " | ||
| 1587 | "%04x.\n", source_naa)); | ||
| 1588 | |||
| 1589 | if ((fcllc->ethertype == htons(ETH_P_ARP)) && | ||
| 1590 | ((source_naa >> 12) != MPT_LAN_NAA_RFC2625)){ | ||
| 1591 | struct NAA_Hosed *nh, *prevnh; | ||
| 1592 | int i; | ||
| 1593 | |||
| 1594 | dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from " | ||
| 1595 | "system with non-RFC 2625 NAA value (%04x).\n", | ||
| 1596 | source_naa)); | ||
| 1597 | |||
| 1598 | write_lock_irq(&bad_naa_lock); | ||
| 1599 | for (prevnh = nh = mpt_bad_naa; nh != NULL; | ||
| 1600 | prevnh=nh, nh=nh->next) { | ||
| 1601 | if ((nh->ieee[0] == fch->saddr[0]) && | ||
| 1602 | (nh->ieee[1] == fch->saddr[1]) && | ||
| 1603 | (nh->ieee[2] == fch->saddr[2]) && | ||
| 1604 | (nh->ieee[3] == fch->saddr[3]) && | ||
| 1605 | (nh->ieee[4] == fch->saddr[4]) && | ||
| 1606 | (nh->ieee[5] == fch->saddr[5])) { | ||
| 1607 | found = 1; | ||
| 1608 | dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re" | ||
| 1609 | "q/Rep w/ bad NAA from system already" | ||
| 1610 | " in DB.\n")); | ||
| 1611 | break; | ||
| 1612 | } | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | if ((!found) && (nh == NULL)) { | ||
| 1616 | |||
| 1617 | nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL); | ||
| 1618 | dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/" | ||
| 1619 | " bad NAA from system not yet in DB.\n")); | ||
| 1620 | |||
| 1621 | if (nh != NULL) { | ||
| 1622 | nh->next = NULL; | ||
| 1623 | if (!mpt_bad_naa) | ||
| 1624 | mpt_bad_naa = nh; | ||
| 1625 | if (prevnh) | ||
| 1626 | prevnh->next = nh; | ||
| 1627 | |||
| 1628 | nh->NAA = source_naa; /* Set the S_NAA value. */ | ||
| 1629 | for (i = 0; i < FC_ALEN; i++) | ||
| 1630 | nh->ieee[i] = fch->saddr[i]; | ||
| 1631 | dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:" | ||
| 1632 | "%02x:%02x with non-compliant S_NAA value.\n", | ||
| 1633 | fch->saddr[0], fch->saddr[1], fch->saddr[2], | ||
| 1634 | fch->saddr[3], fch->saddr[4],fch->saddr[5])); | ||
| 1635 | } else { | ||
| 1636 | printk (KERN_ERR "mptlan/type_trans: Unable to" | ||
| 1637 | " kmalloc a NAA_Hosed struct.\n"); | ||
| 1638 | } | ||
| 1639 | } else if (!found) { | ||
| 1640 | printk (KERN_ERR "mptlan/type_trans: found not" | ||
| 1641 | " set, but nh isn't null. Evil " | ||
| 1642 | "funkiness abounds.\n"); | ||
| 1643 | } | ||
| 1644 | write_unlock_irq(&bad_naa_lock); | ||
| 1645 | } | ||
| 1646 | } | ||
| 1647 | #endif | ||
| 1648 | 1540 | ||
| 1649 | /* Strip the SNAP header from ARP packets since we don't | 1541 | /* Strip the SNAP header from ARP packets since we don't |
| 1650 | * pass them through to the 802.2/SNAP layers. | 1542 | * pass them through to the 802.2/SNAP layers. |
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 84bdc2ee69e6..a443e136dc41 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
| @@ -354,7 +354,7 @@ static inline void i2o_block_sglist_free(struct i2o_block_request *ireq) | |||
| 354 | * @req: the request to prepare | 354 | * @req: the request to prepare |
| 355 | * | 355 | * |
| 356 | * Allocate the necessary i2o_block_request struct and connect it to | 356 | * Allocate the necessary i2o_block_request struct and connect it to |
| 357 | * the request. This is needed that we not loose the SG list later on. | 357 | * the request. This is needed that we not lose the SG list later on. |
| 358 | * | 358 | * |
| 359 | * Returns BLKPREP_OK on success or BLKPREP_DEFER on failure. | 359 | * Returns BLKPREP_OK on success or BLKPREP_DEFER on failure. |
| 360 | */ | 360 | */ |
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index a3fabdbe6ca6..f3384c32b9a1 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
| @@ -1097,28 +1097,17 @@ static int cfg_fasync(int fd, struct file *fp, int on) | |||
| 1097 | static int cfg_release(struct inode *inode, struct file *file) | 1097 | static int cfg_release(struct inode *inode, struct file *file) |
| 1098 | { | 1098 | { |
| 1099 | ulong id = (ulong) file->private_data; | 1099 | ulong id = (ulong) file->private_data; |
| 1100 | struct i2o_cfg_info *p1, *p2; | 1100 | struct i2o_cfg_info *p, **q; |
| 1101 | unsigned long flags; | 1101 | unsigned long flags; |
| 1102 | 1102 | ||
| 1103 | lock_kernel(); | 1103 | lock_kernel(); |
| 1104 | p1 = p2 = NULL; | ||
| 1105 | |||
| 1106 | spin_lock_irqsave(&i2o_config_lock, flags); | 1104 | spin_lock_irqsave(&i2o_config_lock, flags); |
| 1107 | for (p1 = open_files; p1;) { | 1105 | for (q = &open_files; (p = *q) != NULL; q = &p->next) { |
| 1108 | if (p1->q_id == id) { | 1106 | if (p->q_id == id) { |
| 1109 | 1107 | *q = p->next; | |
| 1110 | if (p1->fasync) | 1108 | kfree(p); |
| 1111 | cfg_fasync(-1, file, 0); | ||
| 1112 | if (p2) | ||
| 1113 | p2->next = p1->next; | ||
| 1114 | else | ||
| 1115 | open_files = p1->next; | ||
| 1116 | |||
| 1117 | kfree(p1); | ||
| 1118 | break; | 1109 | break; |
| 1119 | } | 1110 | } |
| 1120 | p2 = p1; | ||
| 1121 | p1 = p1->next; | ||
| 1122 | } | 1111 | } |
| 1123 | spin_unlock_irqrestore(&i2o_config_lock, flags); | 1112 | spin_unlock_irqrestore(&i2o_config_lock, flags); |
| 1124 | unlock_kernel(); | 1113 | unlock_kernel(); |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index be2b5926d26c..6e53a30bfd38 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
| @@ -49,7 +49,6 @@ static int i2o_hrt_get(struct i2o_controller *c); | |||
| 49 | /** | 49 | /** |
| 50 | * i2o_msg_get_wait - obtain an I2O message from the IOP | 50 | * i2o_msg_get_wait - obtain an I2O message from the IOP |
| 51 | * @c: I2O controller | 51 | * @c: I2O controller |
| 52 | * @msg: pointer to a I2O message pointer | ||
| 53 | * @wait: how long to wait until timeout | 52 | * @wait: how long to wait until timeout |
| 54 | * | 53 | * |
| 55 | * This function waits up to wait seconds for a message slot to be | 54 | * This function waits up to wait seconds for a message slot to be |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b550267c8d5e..257277394f8c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
| @@ -81,7 +81,7 @@ config MFD_TMIO | |||
| 81 | 81 | ||
| 82 | config MFD_T7L66XB | 82 | config MFD_T7L66XB |
| 83 | bool "Support Toshiba T7L66XB" | 83 | bool "Support Toshiba T7L66XB" |
| 84 | depends on ARM | 84 | depends on ARM && HAVE_CLK |
| 85 | select MFD_CORE | 85 | select MFD_CORE |
| 86 | select MFD_TMIO | 86 | select MFD_TMIO |
| 87 | help | 87 | help |
| @@ -89,7 +89,7 @@ config MFD_T7L66XB | |||
| 89 | 89 | ||
| 90 | config MFD_TC6387XB | 90 | config MFD_TC6387XB |
| 91 | bool "Support Toshiba TC6387XB" | 91 | bool "Support Toshiba TC6387XB" |
| 92 | depends on ARM | 92 | depends on ARM && HAVE_CLK |
| 93 | select MFD_CORE | 93 | select MFD_CORE |
| 94 | select MFD_TMIO | 94 | select MFD_TMIO |
| 95 | help | 95 | help |
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index b57326ae464d..0b5bd85dfcec 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c | |||
| @@ -267,7 +267,7 @@ static int da9030_mask_events(struct da903x_chip *chip, unsigned int events) | |||
| 267 | { | 267 | { |
| 268 | uint8_t v[3]; | 268 | uint8_t v[3]; |
| 269 | 269 | ||
| 270 | chip->events_mask &= ~events; | 270 | chip->events_mask |= events; |
| 271 | 271 | ||
| 272 | v[0] = (chip->events_mask & 0xff); | 272 | v[0] = (chip->events_mask & 0xff); |
| 273 | v[1] = (chip->events_mask >> 8) & 0xff; | 273 | v[1] = (chip->events_mask >> 8) & 0xff; |
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 8dfe21bb3bd1..3e0ce0e50ea2 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c | |||
| @@ -30,7 +30,12 @@ static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, | |||
| 30 | ret = i2c_master_send(wm8350->i2c_client, ®, 1); | 30 | ret = i2c_master_send(wm8350->i2c_client, ®, 1); |
| 31 | if (ret < 0) | 31 | if (ret < 0) |
| 32 | return ret; | 32 | return ret; |
| 33 | return i2c_master_recv(wm8350->i2c_client, dest, bytes); | 33 | ret = i2c_master_recv(wm8350->i2c_client, dest, bytes); |
| 34 | if (ret < 0) | ||
| 35 | return ret; | ||
| 36 | if (ret != bytes) | ||
| 37 | return -EIO; | ||
| 38 | return 0; | ||
| 34 | } | 39 | } |
| 35 | 40 | ||
| 36 | static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg, | 41 | static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg, |
| @@ -38,13 +43,19 @@ static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg, | |||
| 38 | { | 43 | { |
| 39 | /* we add 1 byte for device register */ | 44 | /* we add 1 byte for device register */ |
| 40 | u8 msg[(WM8350_MAX_REGISTER << 1) + 1]; | 45 | u8 msg[(WM8350_MAX_REGISTER << 1) + 1]; |
| 46 | int ret; | ||
| 41 | 47 | ||
| 42 | if (bytes > ((WM8350_MAX_REGISTER << 1) + 1)) | 48 | if (bytes > ((WM8350_MAX_REGISTER << 1) + 1)) |
| 43 | return -EINVAL; | 49 | return -EINVAL; |
| 44 | 50 | ||
| 45 | msg[0] = reg; | 51 | msg[0] = reg; |
| 46 | memcpy(&msg[1], src, bytes); | 52 | memcpy(&msg[1], src, bytes); |
| 47 | return i2c_master_send(wm8350->i2c_client, msg, bytes + 1); | 53 | ret = i2c_master_send(wm8350->i2c_client, msg, bytes + 1); |
| 54 | if (ret < 0) | ||
| 55 | return ret; | ||
| 56 | if (ret != bytes + 1) | ||
| 57 | return -EIO; | ||
| 58 | return 0; | ||
| 48 | } | 59 | } |
| 49 | 60 | ||
| 50 | static int wm8350_i2c_probe(struct i2c_client *i2c, | 61 | static int wm8350_i2c_probe(struct i2c_client *i2c, |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 9494400e8fd0..fee7304102af 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -227,10 +227,20 @@ config HP_WMI | |||
| 227 | To compile this driver as a module, choose M here: the module will | 227 | To compile this driver as a module, choose M here: the module will |
| 228 | be called hp-wmi. | 228 | be called hp-wmi. |
| 229 | 229 | ||
| 230 | config ICS932S401 | ||
| 231 | tristate "Integrated Circuits ICS932S401" | ||
| 232 | depends on I2C && EXPERIMENTAL | ||
| 233 | help | ||
| 234 | If you say yes here you get support for the Integrated Circuits | ||
| 235 | ICS932S401 clock control chips. | ||
| 236 | |||
| 237 | This driver can also be built as a module. If so, the module | ||
| 238 | will be called ics932s401. | ||
| 239 | |||
| 230 | config MSI_LAPTOP | 240 | config MSI_LAPTOP |
| 231 | tristate "MSI Laptop Extras" | 241 | tristate "MSI Laptop Extras" |
| 232 | depends on X86 | 242 | depends on X86 |
| 233 | depends on ACPI_EC | 243 | depends on ACPI |
| 234 | depends on BACKLIGHT_CLASS_DEVICE | 244 | depends on BACKLIGHT_CLASS_DEVICE |
| 235 | ---help--- | 245 | ---help--- |
| 236 | This is a driver for laptops built by MSI (MICRO-STAR | 246 | This is a driver for laptops built by MSI (MICRO-STAR |
| @@ -260,7 +270,7 @@ config PANASONIC_LAPTOP | |||
| 260 | config COMPAL_LAPTOP | 270 | config COMPAL_LAPTOP |
| 261 | tristate "Compal Laptop Extras" | 271 | tristate "Compal Laptop Extras" |
| 262 | depends on X86 | 272 | depends on X86 |
| 263 | depends on ACPI_EC | 273 | depends on ACPI |
| 264 | depends on BACKLIGHT_CLASS_DEVICE | 274 | depends on BACKLIGHT_CLASS_DEVICE |
| 265 | ---help--- | 275 | ---help--- |
| 266 | This is a driver for laptops built by Compal: | 276 | This is a driver for laptops built by Compal: |
| @@ -488,4 +498,6 @@ config SGI_GRU_DEBUG | |||
| 488 | This option enables addition debugging code for the SGI GRU driver. If | 498 | This option enables addition debugging code for the SGI GRU driver. If |
| 489 | you are unsure, say N. | 499 | you are unsure, say N. |
| 490 | 500 | ||
| 501 | source "drivers/misc/c2port/Kconfig" | ||
| 502 | |||
| 491 | endif # MISC_DEVICES | 503 | endif # MISC_DEVICES |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 909e2468cdc9..817f7f5ab3bd 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
| @@ -14,6 +14,7 @@ obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o | |||
| 14 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o | 14 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o |
| 15 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o | 15 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o |
| 16 | obj-$(CONFIG_HP_WMI) += hp-wmi.o | 16 | obj-$(CONFIG_HP_WMI) += hp-wmi.o |
| 17 | obj-$(CONFIG_ICS932S401) += ics932s401.o | ||
| 17 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o | 18 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o |
| 18 | obj-$(CONFIG_LKDTM) += lkdtm.o | 19 | obj-$(CONFIG_LKDTM) += lkdtm.o |
| 19 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o | 20 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o |
| @@ -31,3 +32,4 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o | |||
| 31 | obj-$(CONFIG_SGI_XP) += sgi-xp/ | 32 | obj-$(CONFIG_SGI_XP) += sgi-xp/ |
| 32 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ | 33 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ |
| 33 | obj-$(CONFIG_HP_ILO) += hpilo.o | 34 | obj-$(CONFIG_HP_ILO) += hpilo.o |
| 35 | obj-$(CONFIG_C2PORT) += c2port/ | ||
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index 0532a2de2ce4..94c9f911824e 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c | |||
| @@ -1297,6 +1297,12 @@ static int __init acer_wmi_init(void) | |||
| 1297 | 1297 | ||
| 1298 | set_quirks(); | 1298 | set_quirks(); |
| 1299 | 1299 | ||
| 1300 | if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { | ||
| 1301 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | ||
| 1302 | printk(ACER_INFO "Brightness must be controlled by " | ||
| 1303 | "generic video driver\n"); | ||
| 1304 | } | ||
| 1305 | |||
| 1300 | if (platform_driver_register(&acer_platform_driver)) { | 1306 | if (platform_driver_register(&acer_platform_driver)) { |
| 1301 | printk(ACER_ERR "Unable to register platform driver.\n"); | 1307 | printk(ACER_ERR "Unable to register platform driver.\n"); |
| 1302 | goto error_platform_register; | 1308 | goto error_platform_register; |
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index a9d5228724a6..8fb8b3591048 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
| @@ -1208,9 +1208,13 @@ static int __init asus_laptop_init(void) | |||
| 1208 | 1208 | ||
| 1209 | dev = acpi_get_physical_device(hotk->device->handle); | 1209 | dev = acpi_get_physical_device(hotk->device->handle); |
| 1210 | 1210 | ||
| 1211 | result = asus_backlight_init(dev); | 1211 | if (!acpi_video_backlight_support()) { |
| 1212 | if (result) | 1212 | result = asus_backlight_init(dev); |
| 1213 | goto fail_backlight; | 1213 | if (result) |
| 1214 | goto fail_backlight; | ||
| 1215 | } else | ||
| 1216 | printk(ASUS_INFO "Brightness ignored, must be controlled by " | ||
| 1217 | "ACPI video driver\n"); | ||
| 1214 | 1218 | ||
| 1215 | result = asus_led_init(dev); | 1219 | result = asus_led_init(dev); |
| 1216 | if (result) | 1220 | if (result) |
diff --git a/drivers/misc/c2port/Kconfig b/drivers/misc/c2port/Kconfig new file mode 100644 index 000000000000..e46af9a5810d --- /dev/null +++ b/drivers/misc/c2port/Kconfig | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | # | ||
| 2 | # C2 port devices | ||
| 3 | # | ||
| 4 | |||
| 5 | menuconfig C2PORT | ||
| 6 | tristate "Silicon Labs C2 port support (EXPERIMENTAL)" | ||
| 7 | depends on EXPERIMENTAL | ||
| 8 | default no | ||
| 9 | help | ||
| 10 | This option enables support for Silicon Labs C2 port used to | ||
| 11 | program Silicon micro controller chips (and other 8051 compatible). | ||
| 12 | |||
| 13 | If your board have no such micro controllers you don't need this | ||
| 14 | interface at all. | ||
| 15 | |||
| 16 | To compile this driver as a module, choose M here: the module will | ||
| 17 | be called c2port_core. Note that you also need a client module | ||
| 18 | usually called c2port-*. | ||
| 19 | |||
| 20 | If you are not sure, say N here. | ||
| 21 | |||
| 22 | if C2PORT | ||
| 23 | |||
| 24 | config C2PORT_DURAMAR_2150 | ||
| 25 | tristate "C2 port support for Eurotech's Duramar 2150 (EXPERIMENTAL)" | ||
| 26 | depends on X86 && C2PORT | ||
| 27 | default no | ||
| 28 | help | ||
| 29 | This option enables C2 support for the Eurotech's Duramar 2150 | ||
| 30 | on board micro controller. | ||
| 31 | |||
| 32 | To compile this driver as a module, choose M here: the module will | ||
| 33 | be called c2port-duramar2150. | ||
| 34 | |||
| 35 | endif # C2PORT | ||
diff --git a/drivers/misc/c2port/Makefile b/drivers/misc/c2port/Makefile new file mode 100644 index 000000000000..3b2cf43d60f5 --- /dev/null +++ b/drivers/misc/c2port/Makefile | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | obj-$(CONFIG_C2PORT) += core.o | ||
| 2 | |||
| 3 | obj-$(CONFIG_C2PORT_DURAMAR_2150) += c2port-duramar2150.o | ||
diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c new file mode 100644 index 000000000000..338dcc121507 --- /dev/null +++ b/drivers/misc/c2port/c2port-duramar2150.c | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs C2 port Linux support for Eurotech Duramar 2150 | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it> | ||
| 5 | * Copyright (c) 2008 Eurotech S.p.A. <info@eurotech.it> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/c2port.h> | ||
| 19 | |||
| 20 | #define DATA_PORT 0x325 | ||
| 21 | #define DIR_PORT 0x326 | ||
| 22 | #define C2D (1 << 0) | ||
| 23 | #define C2CK (1 << 1) | ||
| 24 | |||
| 25 | static DEFINE_MUTEX(update_lock); | ||
| 26 | |||
| 27 | /* | ||
| 28 | * C2 port operations | ||
| 29 | */ | ||
| 30 | |||
| 31 | static void duramar2150_c2port_access(struct c2port_device *dev, int status) | ||
| 32 | { | ||
| 33 | u8 v; | ||
| 34 | |||
| 35 | mutex_lock(&update_lock); | ||
| 36 | |||
| 37 | v = inb(DIR_PORT); | ||
| 38 | |||
| 39 | /* 0 = input, 1 = output */ | ||
| 40 | if (status) | ||
| 41 | outb(v | (C2D | C2CK), DIR_PORT); | ||
| 42 | else | ||
| 43 | /* When access is "off" is important that both lines are set | ||
| 44 | * as inputs or hi-impedence */ | ||
| 45 | outb(v & ~(C2D | C2CK), DIR_PORT); | ||
| 46 | |||
| 47 | mutex_unlock(&update_lock); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void duramar2150_c2port_c2d_dir(struct c2port_device *dev, int dir) | ||
| 51 | { | ||
| 52 | u8 v; | ||
| 53 | |||
| 54 | mutex_lock(&update_lock); | ||
| 55 | |||
| 56 | v = inb(DIR_PORT); | ||
| 57 | |||
| 58 | if (dir) | ||
| 59 | outb(v & ~C2D, DIR_PORT); | ||
| 60 | else | ||
| 61 | outb(v | C2D, DIR_PORT); | ||
| 62 | |||
| 63 | mutex_unlock(&update_lock); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int duramar2150_c2port_c2d_get(struct c2port_device *dev) | ||
| 67 | { | ||
| 68 | return inb(DATA_PORT) & C2D; | ||
| 69 | } | ||
| 70 | |||
| 71 | static void duramar2150_c2port_c2d_set(struct c2port_device *dev, int status) | ||
| 72 | { | ||
| 73 | u8 v; | ||
| 74 | |||
| 75 | mutex_lock(&update_lock); | ||
| 76 | |||
| 77 | v = inb(DATA_PORT); | ||
| 78 | |||
| 79 | if (status) | ||
| 80 | outb(v | C2D, DATA_PORT); | ||
| 81 | else | ||
| 82 | outb(v & ~C2D, DATA_PORT); | ||
| 83 | |||
| 84 | mutex_unlock(&update_lock); | ||
| 85 | } | ||
| 86 | |||
| 87 | static void duramar2150_c2port_c2ck_set(struct c2port_device *dev, int status) | ||
| 88 | { | ||
| 89 | u8 v; | ||
| 90 | |||
| 91 | mutex_lock(&update_lock); | ||
| 92 | |||
| 93 | v = inb(DATA_PORT); | ||
| 94 | |||
| 95 | if (status) | ||
| 96 | outb(v | C2CK, DATA_PORT); | ||
| 97 | else | ||
| 98 | outb(v & ~C2CK, DATA_PORT); | ||
| 99 | |||
| 100 | mutex_unlock(&update_lock); | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct c2port_ops duramar2150_c2port_ops = { | ||
| 104 | .block_size = 512, /* bytes */ | ||
| 105 | .blocks_num = 30, /* total flash size: 15360 bytes */ | ||
| 106 | |||
| 107 | .access = duramar2150_c2port_access, | ||
| 108 | .c2d_dir = duramar2150_c2port_c2d_dir, | ||
| 109 | .c2d_get = duramar2150_c2port_c2d_get, | ||
| 110 | .c2d_set = duramar2150_c2port_c2d_set, | ||
| 111 | .c2ck_set = duramar2150_c2port_c2ck_set, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct c2port_device *duramar2150_c2port_dev; | ||
| 115 | |||
| 116 | /* | ||
| 117 | * Module stuff | ||
| 118 | */ | ||
| 119 | |||
| 120 | static int __init duramar2150_c2port_init(void) | ||
| 121 | { | ||
| 122 | struct resource *res; | ||
| 123 | int ret = 0; | ||
| 124 | |||
| 125 | res = request_region(0x325, 2, "c2port"); | ||
| 126 | if (!res) | ||
| 127 | return -EBUSY; | ||
| 128 | |||
| 129 | duramar2150_c2port_dev = c2port_device_register("uc", | ||
| 130 | &duramar2150_c2port_ops, NULL); | ||
| 131 | if (!duramar2150_c2port_dev) { | ||
| 132 | ret = -ENODEV; | ||
| 133 | goto free_region; | ||
| 134 | } | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | |||
| 138 | free_region: | ||
| 139 | release_region(0x325, 2); | ||
| 140 | return ret; | ||
| 141 | } | ||
| 142 | |||
| 143 | static void __exit duramar2150_c2port_exit(void) | ||
| 144 | { | ||
| 145 | /* Setup the GPIOs as input by default (access = 0) */ | ||
| 146 | duramar2150_c2port_access(duramar2150_c2port_dev, 0); | ||
| 147 | |||
| 148 | c2port_device_unregister(duramar2150_c2port_dev); | ||
| 149 | |||
| 150 | release_region(0x325, 2); | ||
| 151 | } | ||
| 152 | |||
| 153 | module_init(duramar2150_c2port_init); | ||
| 154 | module_exit(duramar2150_c2port_exit); | ||
| 155 | |||
| 156 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
| 157 | MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for Duramar 2150"); | ||
| 158 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c new file mode 100644 index 000000000000..0207dd59090d --- /dev/null +++ b/drivers/misc/c2port/core.c | |||
| @@ -0,0 +1,1003 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs C2 port core Linux support | ||
| 3 | * | ||
| 4 | * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it> | ||
| 5 | * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/errno.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/ctype.h> | ||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/idr.h> | ||
| 21 | #include <linux/sched.h> | ||
| 22 | |||
| 23 | #include <linux/c2port.h> | ||
| 24 | |||
| 25 | #define DRIVER_NAME "c2port" | ||
| 26 | #define DRIVER_VERSION "0.51.0" | ||
| 27 | |||
| 28 | static DEFINE_SPINLOCK(c2port_idr_lock); | ||
| 29 | static DEFINE_IDR(c2port_idr); | ||
| 30 | |||
| 31 | /* | ||
| 32 | * Local variables | ||
| 33 | */ | ||
| 34 | |||
| 35 | static struct class *c2port_class; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * C2 registers & commands defines | ||
| 39 | */ | ||
| 40 | |||
| 41 | /* C2 registers */ | ||
| 42 | #define C2PORT_DEVICEID 0x00 | ||
| 43 | #define C2PORT_REVID 0x01 | ||
| 44 | #define C2PORT_FPCTL 0x02 | ||
| 45 | #define C2PORT_FPDAT 0xB4 | ||
| 46 | |||
| 47 | /* C2 interface commands */ | ||
| 48 | #define C2PORT_GET_VERSION 0x01 | ||
| 49 | #define C2PORT_DEVICE_ERASE 0x03 | ||
| 50 | #define C2PORT_BLOCK_READ 0x06 | ||
| 51 | #define C2PORT_BLOCK_WRITE 0x07 | ||
| 52 | #define C2PORT_PAGE_ERASE 0x08 | ||
| 53 | |||
| 54 | /* C2 status return codes */ | ||
| 55 | #define C2PORT_INVALID_COMMAND 0x00 | ||
| 56 | #define C2PORT_COMMAND_FAILED 0x02 | ||
| 57 | #define C2PORT_COMMAND_OK 0x0d | ||
| 58 | |||
| 59 | /* | ||
| 60 | * C2 port low level signal managements | ||
| 61 | */ | ||
| 62 | |||
| 63 | static void c2port_reset(struct c2port_device *dev) | ||
| 64 | { | ||
| 65 | struct c2port_ops *ops = dev->ops; | ||
| 66 | |||
| 67 | /* To reset the device we have to keep clock line low for at least | ||
| 68 | * 20us. | ||
| 69 | */ | ||
| 70 | local_irq_disable(); | ||
| 71 | ops->c2ck_set(dev, 0); | ||
| 72 | udelay(25); | ||
| 73 | ops->c2ck_set(dev, 1); | ||
| 74 | local_irq_enable(); | ||
| 75 | |||
| 76 | udelay(1); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void c2port_strobe_ck(struct c2port_device *dev) | ||
| 80 | { | ||
| 81 | struct c2port_ops *ops = dev->ops; | ||
| 82 | |||
| 83 | /* During hi-low-hi transition we disable local IRQs to avoid | ||
| 84 | * interructions since C2 port specification says that it must be | ||
| 85 | * shorter than 5us, otherwise the microcontroller may consider | ||
| 86 | * it as a reset signal! | ||
| 87 | */ | ||
| 88 | local_irq_disable(); | ||
| 89 | ops->c2ck_set(dev, 0); | ||
| 90 | udelay(1); | ||
| 91 | ops->c2ck_set(dev, 1); | ||
| 92 | local_irq_enable(); | ||
| 93 | |||
| 94 | udelay(1); | ||
| 95 | } | ||
| 96 | |||
| 97 | /* | ||
| 98 | * C2 port basic functions | ||
| 99 | */ | ||
| 100 | |||
| 101 | static void c2port_write_ar(struct c2port_device *dev, u8 addr) | ||
| 102 | { | ||
| 103 | struct c2port_ops *ops = dev->ops; | ||
| 104 | int i; | ||
| 105 | |||
| 106 | /* START field */ | ||
| 107 | c2port_strobe_ck(dev); | ||
| 108 | |||
| 109 | /* INS field (11b, LSB first) */ | ||
| 110 | ops->c2d_dir(dev, 0); | ||
| 111 | ops->c2d_set(dev, 1); | ||
| 112 | c2port_strobe_ck(dev); | ||
| 113 | ops->c2d_set(dev, 1); | ||
| 114 | c2port_strobe_ck(dev); | ||
| 115 | |||
| 116 | /* ADDRESS field */ | ||
| 117 | for (i = 0; i < 8; i++) { | ||
| 118 | ops->c2d_set(dev, addr & 0x01); | ||
| 119 | c2port_strobe_ck(dev); | ||
| 120 | |||
| 121 | addr >>= 1; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* STOP field */ | ||
| 125 | ops->c2d_dir(dev, 1); | ||
| 126 | c2port_strobe_ck(dev); | ||
| 127 | } | ||
| 128 | |||
| 129 | static int c2port_read_ar(struct c2port_device *dev, u8 *addr) | ||
| 130 | { | ||
| 131 | struct c2port_ops *ops = dev->ops; | ||
| 132 | int i; | ||
| 133 | |||
| 134 | /* START field */ | ||
| 135 | c2port_strobe_ck(dev); | ||
| 136 | |||
| 137 | /* INS field (10b, LSB first) */ | ||
| 138 | ops->c2d_dir(dev, 0); | ||
| 139 | ops->c2d_set(dev, 0); | ||
| 140 | c2port_strobe_ck(dev); | ||
| 141 | ops->c2d_set(dev, 1); | ||
| 142 | c2port_strobe_ck(dev); | ||
| 143 | |||
| 144 | /* ADDRESS field */ | ||
| 145 | ops->c2d_dir(dev, 1); | ||
| 146 | *addr = 0; | ||
| 147 | for (i = 0; i < 8; i++) { | ||
| 148 | *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */ | ||
| 149 | |||
| 150 | c2port_strobe_ck(dev); | ||
| 151 | if (ops->c2d_get(dev)) | ||
| 152 | *addr |= 0x80; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* STOP field */ | ||
| 156 | c2port_strobe_ck(dev); | ||
| 157 | |||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | |||
| 161 | static int c2port_write_dr(struct c2port_device *dev, u8 data) | ||
| 162 | { | ||
| 163 | struct c2port_ops *ops = dev->ops; | ||
| 164 | int timeout, i; | ||
| 165 | |||
| 166 | /* START field */ | ||
| 167 | c2port_strobe_ck(dev); | ||
| 168 | |||
| 169 | /* INS field (01b, LSB first) */ | ||
| 170 | ops->c2d_dir(dev, 0); | ||
| 171 | ops->c2d_set(dev, 1); | ||
| 172 | c2port_strobe_ck(dev); | ||
| 173 | ops->c2d_set(dev, 0); | ||
| 174 | c2port_strobe_ck(dev); | ||
| 175 | |||
| 176 | /* LENGTH field (00b, LSB first -> 1 byte) */ | ||
| 177 | ops->c2d_set(dev, 0); | ||
| 178 | c2port_strobe_ck(dev); | ||
| 179 | ops->c2d_set(dev, 0); | ||
| 180 | c2port_strobe_ck(dev); | ||
| 181 | |||
| 182 | /* DATA field */ | ||
| 183 | for (i = 0; i < 8; i++) { | ||
| 184 | ops->c2d_set(dev, data & 0x01); | ||
| 185 | c2port_strobe_ck(dev); | ||
| 186 | |||
| 187 | data >>= 1; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* WAIT field */ | ||
| 191 | ops->c2d_dir(dev, 1); | ||
| 192 | timeout = 20; | ||
| 193 | do { | ||
| 194 | c2port_strobe_ck(dev); | ||
| 195 | if (ops->c2d_get(dev)) | ||
| 196 | break; | ||
| 197 | |||
| 198 | udelay(1); | ||
| 199 | } while (--timeout > 0); | ||
| 200 | if (timeout == 0) | ||
| 201 | return -EIO; | ||
| 202 | |||
| 203 | /* STOP field */ | ||
| 204 | c2port_strobe_ck(dev); | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int c2port_read_dr(struct c2port_device *dev, u8 *data) | ||
| 210 | { | ||
| 211 | struct c2port_ops *ops = dev->ops; | ||
| 212 | int timeout, i; | ||
| 213 | |||
| 214 | /* START field */ | ||
| 215 | c2port_strobe_ck(dev); | ||
| 216 | |||
| 217 | /* INS field (00b, LSB first) */ | ||
| 218 | ops->c2d_dir(dev, 0); | ||
| 219 | ops->c2d_set(dev, 0); | ||
| 220 | c2port_strobe_ck(dev); | ||
| 221 | ops->c2d_set(dev, 0); | ||
| 222 | c2port_strobe_ck(dev); | ||
| 223 | |||
| 224 | /* LENGTH field (00b, LSB first -> 1 byte) */ | ||
| 225 | ops->c2d_set(dev, 0); | ||
| 226 | c2port_strobe_ck(dev); | ||
| 227 | ops->c2d_set(dev, 0); | ||
| 228 | c2port_strobe_ck(dev); | ||
| 229 | |||
| 230 | /* WAIT field */ | ||
| 231 | ops->c2d_dir(dev, 1); | ||
| 232 | timeout = 20; | ||
| 233 | do { | ||
| 234 | c2port_strobe_ck(dev); | ||
| 235 | if (ops->c2d_get(dev)) | ||
| 236 | break; | ||
| 237 | |||
| 238 | udelay(1); | ||
| 239 | } while (--timeout > 0); | ||
| 240 | if (timeout == 0) | ||
| 241 | return -EIO; | ||
| 242 | |||
| 243 | /* DATA field */ | ||
| 244 | *data = 0; | ||
| 245 | for (i = 0; i < 8; i++) { | ||
| 246 | *data >>= 1; /* shift in 8-bit DATA field LSB first */ | ||
| 247 | |||
| 248 | c2port_strobe_ck(dev); | ||
| 249 | if (ops->c2d_get(dev)) | ||
| 250 | *data |= 0x80; | ||
| 251 | } | ||
| 252 | |||
| 253 | /* STOP field */ | ||
| 254 | c2port_strobe_ck(dev); | ||
| 255 | |||
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | static int c2port_poll_in_busy(struct c2port_device *dev) | ||
| 260 | { | ||
| 261 | u8 addr; | ||
| 262 | int ret, timeout = 20; | ||
| 263 | |||
| 264 | do { | ||
| 265 | ret = (c2port_read_ar(dev, &addr)); | ||
| 266 | if (ret < 0) | ||
| 267 | return -EIO; | ||
| 268 | |||
| 269 | if (!(addr & 0x02)) | ||
| 270 | break; | ||
| 271 | |||
| 272 | udelay(1); | ||
| 273 | } while (--timeout > 0); | ||
| 274 | if (timeout == 0) | ||
| 275 | return -EIO; | ||
| 276 | |||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | |||
| 280 | static int c2port_poll_out_ready(struct c2port_device *dev) | ||
| 281 | { | ||
| 282 | u8 addr; | ||
| 283 | int ret, timeout = 10000; /* erase flash needs long time... */ | ||
| 284 | |||
| 285 | do { | ||
| 286 | ret = (c2port_read_ar(dev, &addr)); | ||
| 287 | if (ret < 0) | ||
| 288 | return -EIO; | ||
| 289 | |||
| 290 | if (addr & 0x01) | ||
| 291 | break; | ||
| 292 | |||
| 293 | udelay(1); | ||
| 294 | } while (--timeout > 0); | ||
| 295 | if (timeout == 0) | ||
| 296 | return -EIO; | ||
| 297 | |||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | /* | ||
| 302 | * sysfs methods | ||
| 303 | */ | ||
| 304 | |||
| 305 | static ssize_t c2port_show_name(struct device *dev, | ||
| 306 | struct device_attribute *attr, char *buf) | ||
| 307 | { | ||
| 308 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 309 | |||
| 310 | return sprintf(buf, "%s\n", c2dev->name); | ||
| 311 | } | ||
| 312 | |||
| 313 | static ssize_t c2port_show_flash_blocks_num(struct device *dev, | ||
| 314 | struct device_attribute *attr, char *buf) | ||
| 315 | { | ||
| 316 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 317 | struct c2port_ops *ops = c2dev->ops; | ||
| 318 | |||
| 319 | return sprintf(buf, "%d\n", ops->blocks_num); | ||
| 320 | } | ||
| 321 | |||
| 322 | static ssize_t c2port_show_flash_block_size(struct device *dev, | ||
| 323 | struct device_attribute *attr, char *buf) | ||
| 324 | { | ||
| 325 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 326 | struct c2port_ops *ops = c2dev->ops; | ||
| 327 | |||
| 328 | return sprintf(buf, "%d\n", ops->block_size); | ||
| 329 | } | ||
| 330 | |||
| 331 | static ssize_t c2port_show_flash_size(struct device *dev, | ||
| 332 | struct device_attribute *attr, char *buf) | ||
| 333 | { | ||
| 334 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 335 | struct c2port_ops *ops = c2dev->ops; | ||
| 336 | |||
| 337 | return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size); | ||
| 338 | } | ||
| 339 | |||
| 340 | static ssize_t c2port_show_access(struct device *dev, | ||
| 341 | struct device_attribute *attr, char *buf) | ||
| 342 | { | ||
| 343 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 344 | |||
| 345 | return sprintf(buf, "%d\n", c2dev->access); | ||
| 346 | } | ||
| 347 | |||
| 348 | static ssize_t c2port_store_access(struct device *dev, | ||
| 349 | struct device_attribute *attr, | ||
| 350 | const char *buf, size_t count) | ||
| 351 | { | ||
| 352 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 353 | struct c2port_ops *ops = c2dev->ops; | ||
| 354 | int status, ret; | ||
| 355 | |||
| 356 | ret = sscanf(buf, "%d", &status); | ||
| 357 | if (ret != 1) | ||
| 358 | return -EINVAL; | ||
| 359 | |||
| 360 | mutex_lock(&c2dev->mutex); | ||
| 361 | |||
| 362 | c2dev->access = !!status; | ||
| 363 | |||
| 364 | /* If access is "on" clock should be HIGH _before_ setting the line | ||
| 365 | * as output and data line should be set as INPUT anyway */ | ||
| 366 | if (c2dev->access) | ||
| 367 | ops->c2ck_set(c2dev, 1); | ||
| 368 | ops->access(c2dev, c2dev->access); | ||
| 369 | if (c2dev->access) | ||
| 370 | ops->c2d_dir(c2dev, 1); | ||
| 371 | |||
| 372 | mutex_unlock(&c2dev->mutex); | ||
| 373 | |||
| 374 | return count; | ||
| 375 | } | ||
| 376 | |||
| 377 | static ssize_t c2port_store_reset(struct device *dev, | ||
| 378 | struct device_attribute *attr, | ||
| 379 | const char *buf, size_t count) | ||
| 380 | { | ||
| 381 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 382 | |||
| 383 | /* Check the device access status */ | ||
| 384 | if (!c2dev->access) | ||
| 385 | return -EBUSY; | ||
| 386 | |||
| 387 | mutex_lock(&c2dev->mutex); | ||
| 388 | |||
| 389 | c2port_reset(c2dev); | ||
| 390 | c2dev->flash_access = 0; | ||
| 391 | |||
| 392 | mutex_unlock(&c2dev->mutex); | ||
| 393 | |||
| 394 | return count; | ||
| 395 | } | ||
| 396 | |||
| 397 | static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf) | ||
| 398 | { | ||
| 399 | u8 data; | ||
| 400 | int ret; | ||
| 401 | |||
| 402 | /* Select DEVICEID register for C2 data register accesses */ | ||
| 403 | c2port_write_ar(dev, C2PORT_DEVICEID); | ||
| 404 | |||
| 405 | /* Read and return the device ID register */ | ||
| 406 | ret = c2port_read_dr(dev, &data); | ||
| 407 | if (ret < 0) | ||
| 408 | return ret; | ||
| 409 | |||
| 410 | return sprintf(buf, "%d\n", data); | ||
| 411 | } | ||
| 412 | |||
| 413 | static ssize_t c2port_show_dev_id(struct device *dev, | ||
| 414 | struct device_attribute *attr, char *buf) | ||
| 415 | { | ||
| 416 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 417 | ssize_t ret; | ||
| 418 | |||
| 419 | /* Check the device access status */ | ||
| 420 | if (!c2dev->access) | ||
| 421 | return -EBUSY; | ||
| 422 | |||
| 423 | mutex_lock(&c2dev->mutex); | ||
| 424 | ret = __c2port_show_dev_id(c2dev, buf); | ||
| 425 | mutex_unlock(&c2dev->mutex); | ||
| 426 | |||
| 427 | if (ret < 0) | ||
| 428 | dev_err(dev, "cannot read from %s\n", c2dev->name); | ||
| 429 | |||
| 430 | return ret; | ||
| 431 | } | ||
| 432 | |||
| 433 | static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf) | ||
| 434 | { | ||
| 435 | u8 data; | ||
| 436 | int ret; | ||
| 437 | |||
| 438 | /* Select REVID register for C2 data register accesses */ | ||
| 439 | c2port_write_ar(dev, C2PORT_REVID); | ||
| 440 | |||
| 441 | /* Read and return the revision ID register */ | ||
| 442 | ret = c2port_read_dr(dev, &data); | ||
| 443 | if (ret < 0) | ||
| 444 | return ret; | ||
| 445 | |||
| 446 | return sprintf(buf, "%d\n", data); | ||
| 447 | } | ||
| 448 | |||
| 449 | static ssize_t c2port_show_rev_id(struct device *dev, | ||
| 450 | struct device_attribute *attr, char *buf) | ||
| 451 | { | ||
| 452 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 453 | ssize_t ret; | ||
| 454 | |||
| 455 | /* Check the device access status */ | ||
| 456 | if (!c2dev->access) | ||
| 457 | return -EBUSY; | ||
| 458 | |||
| 459 | mutex_lock(&c2dev->mutex); | ||
| 460 | ret = __c2port_show_rev_id(c2dev, buf); | ||
| 461 | mutex_unlock(&c2dev->mutex); | ||
| 462 | |||
| 463 | if (ret < 0) | ||
| 464 | dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name); | ||
| 465 | |||
| 466 | return ret; | ||
| 467 | } | ||
| 468 | |||
| 469 | static ssize_t c2port_show_flash_access(struct device *dev, | ||
| 470 | struct device_attribute *attr, char *buf) | ||
| 471 | { | ||
| 472 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 473 | |||
| 474 | return sprintf(buf, "%d\n", c2dev->flash_access); | ||
| 475 | } | ||
| 476 | |||
| 477 | static ssize_t __c2port_store_flash_access(struct c2port_device *dev, | ||
| 478 | int status) | ||
| 479 | { | ||
| 480 | int ret; | ||
| 481 | |||
| 482 | /* Check the device access status */ | ||
| 483 | if (!dev->access) | ||
| 484 | return -EBUSY; | ||
| 485 | |||
| 486 | dev->flash_access = !!status; | ||
| 487 | |||
| 488 | /* If flash_access is off we have nothing to do... */ | ||
| 489 | if (dev->flash_access == 0) | ||
| 490 | return 0; | ||
| 491 | |||
| 492 | /* Target the C2 flash programming control register for C2 data | ||
| 493 | * register access */ | ||
| 494 | c2port_write_ar(dev, C2PORT_FPCTL); | ||
| 495 | |||
| 496 | /* Write the first keycode to enable C2 Flash programming */ | ||
| 497 | ret = c2port_write_dr(dev, 0x02); | ||
| 498 | if (ret < 0) | ||
| 499 | return ret; | ||
| 500 | |||
| 501 | /* Write the second keycode to enable C2 Flash programming */ | ||
| 502 | ret = c2port_write_dr(dev, 0x01); | ||
| 503 | if (ret < 0) | ||
| 504 | return ret; | ||
| 505 | |||
| 506 | /* Delay for at least 20ms to ensure the target is ready for | ||
| 507 | * C2 flash programming */ | ||
| 508 | mdelay(25); | ||
| 509 | |||
| 510 | return 0; | ||
| 511 | } | ||
| 512 | |||
| 513 | static ssize_t c2port_store_flash_access(struct device *dev, | ||
| 514 | struct device_attribute *attr, | ||
| 515 | const char *buf, size_t count) | ||
| 516 | { | ||
| 517 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 518 | int status; | ||
| 519 | ssize_t ret; | ||
| 520 | |||
| 521 | ret = sscanf(buf, "%d", &status); | ||
| 522 | if (ret != 1) | ||
| 523 | return -EINVAL; | ||
| 524 | |||
| 525 | mutex_lock(&c2dev->mutex); | ||
| 526 | ret = __c2port_store_flash_access(c2dev, status); | ||
| 527 | mutex_unlock(&c2dev->mutex); | ||
| 528 | |||
| 529 | if (ret < 0) { | ||
| 530 | dev_err(c2dev->dev, "cannot enable %s flash programming\n", | ||
| 531 | c2dev->name); | ||
| 532 | return ret; | ||
| 533 | } | ||
| 534 | |||
| 535 | return count; | ||
| 536 | } | ||
| 537 | |||
| 538 | static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) | ||
| 539 | { | ||
| 540 | u8 status; | ||
| 541 | int ret; | ||
| 542 | |||
| 543 | /* Target the C2 flash programming data register for C2 data register | ||
| 544 | * access. | ||
| 545 | */ | ||
| 546 | c2port_write_ar(dev, C2PORT_FPDAT); | ||
| 547 | |||
| 548 | /* Send device erase command */ | ||
| 549 | c2port_write_dr(dev, C2PORT_DEVICE_ERASE); | ||
| 550 | |||
| 551 | /* Wait for input acknowledge */ | ||
| 552 | ret = c2port_poll_in_busy(dev); | ||
| 553 | if (ret < 0) | ||
| 554 | return ret; | ||
| 555 | |||
| 556 | /* Should check status before starting FLASH access sequence */ | ||
| 557 | |||
| 558 | /* Wait for status information */ | ||
| 559 | ret = c2port_poll_out_ready(dev); | ||
| 560 | if (ret < 0) | ||
| 561 | return ret; | ||
| 562 | |||
| 563 | /* Read flash programming interface status */ | ||
| 564 | ret = c2port_read_dr(dev, &status); | ||
| 565 | if (ret < 0) | ||
| 566 | return ret; | ||
| 567 | if (status != C2PORT_COMMAND_OK) | ||
| 568 | return -EBUSY; | ||
| 569 | |||
| 570 | /* Send a three-byte arming sequence to enable the device erase. | ||
| 571 | * If the sequence is not received correctly, the command will be | ||
| 572 | * ignored. | ||
| 573 | * Sequence is: 0xde, 0xad, 0xa5. | ||
| 574 | */ | ||
| 575 | c2port_write_dr(dev, 0xde); | ||
| 576 | ret = c2port_poll_in_busy(dev); | ||
| 577 | if (ret < 0) | ||
| 578 | return ret; | ||
| 579 | c2port_write_dr(dev, 0xad); | ||
| 580 | ret = c2port_poll_in_busy(dev); | ||
| 581 | if (ret < 0) | ||
| 582 | return ret; | ||
| 583 | c2port_write_dr(dev, 0xa5); | ||
| 584 | ret = c2port_poll_in_busy(dev); | ||
| 585 | if (ret < 0) | ||
| 586 | return ret; | ||
| 587 | |||
| 588 | ret = c2port_poll_out_ready(dev); | ||
| 589 | if (ret < 0) | ||
| 590 | return ret; | ||
| 591 | |||
| 592 | return 0; | ||
| 593 | } | ||
| 594 | |||
| 595 | static ssize_t c2port_store_flash_erase(struct device *dev, | ||
| 596 | struct device_attribute *attr, | ||
| 597 | const char *buf, size_t count) | ||
| 598 | { | ||
| 599 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
| 600 | int ret; | ||
| 601 | |||
| 602 | /* Check the device and flash access status */ | ||
| 603 | if (!c2dev->access || !c2dev->flash_access) | ||
| 604 | return -EBUSY; | ||
| 605 | |||
| 606 | mutex_lock(&c2dev->mutex); | ||
| 607 | ret = __c2port_write_flash_erase(c2dev); | ||
| 608 | mutex_unlock(&c2dev->mutex); | ||
| 609 | |||
| 610 | if (ret < 0) { | ||
| 611 | dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name); | ||
| 612 | return ret; | ||
| 613 | } | ||
| 614 | |||
| 615 | return count; | ||
| 616 | } | ||
| 617 | |||
| 618 | static ssize_t __c2port_read_flash_data(struct c2port_device *dev, | ||
| 619 | char *buffer, loff_t offset, size_t count) | ||
| 620 | { | ||
| 621 | struct c2port_ops *ops = dev->ops; | ||
| 622 | u8 status, nread = 128; | ||
| 623 | int i, ret; | ||
| 624 | |||
| 625 | /* Check for flash end */ | ||
| 626 | if (offset >= ops->block_size * ops->blocks_num) | ||
| 627 | return 0; | ||
| 628 | |||
| 629 | if (ops->block_size * ops->blocks_num - offset < nread) | ||
| 630 | nread = ops->block_size * ops->blocks_num - offset; | ||
| 631 | if (count < nread) | ||
| 632 | nread = count; | ||
| 633 | if (nread == 0) | ||
| 634 | return nread; | ||
| 635 | |||
| 636 | /* Target the C2 flash programming data register for C2 data register | ||
| 637 | * access */ | ||
| 638 | c2port_write_ar(dev, C2PORT_FPDAT); | ||
| 639 | |||
| 640 | /* Send flash block read command */ | ||
| 641 | c2port_write_dr(dev, C2PORT_BLOCK_READ); | ||
| 642 | |||
| 643 | /* Wait for input acknowledge */ | ||
| 644 | ret = c2port_poll_in_busy(dev); | ||
| 645 | if (ret < 0) | ||
| 646 | return ret; | ||
| 647 | |||
| 648 | /* Should check status before starting FLASH access sequence */ | ||
| 649 | |||
| 650 | /* Wait for status information */ | ||
| 651 | ret = c2port_poll_out_ready(dev); | ||
| 652 | if (ret < 0) | ||
| 653 | return ret; | ||
| 654 | |||
| 655 | /* Read flash programming interface status */ | ||
| 656 | ret = c2port_read_dr(dev, &status); | ||
| 657 | if (ret < 0) | ||
| 658 | return ret; | ||
| 659 | if (status != C2PORT_COMMAND_OK) | ||
| 660 | return -EBUSY; | ||
| 661 | |||
| 662 | /* Send address high byte */ | ||
| 663 | c2port_write_dr(dev, offset >> 8); | ||
| 664 | ret = c2port_poll_in_busy(dev); | ||
| 665 | if (ret < 0) | ||
| 666 | return ret; | ||
| 667 | |||
| 668 | /* Send address low byte */ | ||
| 669 | c2port_write_dr(dev, offset & 0x00ff); | ||
| 670 | ret = c2port_poll_in_busy(dev); | ||
| 671 | if (ret < 0) | ||
| 672 | return ret; | ||
| 673 | |||
| 674 | /* Send address block size */ | ||
| 675 | c2port_write_dr(dev, nread); | ||
| 676 | ret = c2port_poll_in_busy(dev); | ||
| 677 | if (ret < 0) | ||
| 678 | return ret; | ||
| 679 | |||
| 680 | /* Should check status before reading FLASH block */ | ||
| 681 | |||
| 682 | /* Wait for status information */ | ||
| 683 | ret = c2port_poll_out_ready(dev); | ||
| 684 | if (ret < 0) | ||
| 685 | return ret; | ||
| 686 | |||
| 687 | /* Read flash programming interface status */ | ||
| 688 | ret = c2port_read_dr(dev, &status); | ||
| 689 | if (ret < 0) | ||
| 690 | return ret; | ||
| 691 | if (status != C2PORT_COMMAND_OK) | ||
| 692 | return -EBUSY; | ||
| 693 | |||
| 694 | /* Read flash block */ | ||
| 695 | for (i = 0; i < nread; i++) { | ||
| 696 | ret = c2port_poll_out_ready(dev); | ||
| 697 | if (ret < 0) | ||
| 698 | return ret; | ||
| 699 | |||
| 700 | ret = c2port_read_dr(dev, buffer+i); | ||
| 701 | if (ret < 0) | ||
| 702 | return ret; | ||
| 703 | } | ||
| 704 | |||
| 705 | return nread; | ||
| 706 | } | ||
| 707 | |||
| 708 | static ssize_t c2port_read_flash_data(struct kobject *kobj, | ||
| 709 | struct bin_attribute *attr, | ||
| 710 | char *buffer, loff_t offset, size_t count) | ||
| 711 | { | ||
| 712 | struct c2port_device *c2dev = | ||
| 713 | dev_get_drvdata(container_of(kobj, | ||
| 714 | struct device, kobj)); | ||
| 715 | ssize_t ret; | ||
| 716 | |||
| 717 | /* Check the device and flash access status */ | ||
| 718 | if (!c2dev->access || !c2dev->flash_access) | ||
| 719 | return -EBUSY; | ||
| 720 | |||
| 721 | mutex_lock(&c2dev->mutex); | ||
| 722 | ret = __c2port_read_flash_data(c2dev, buffer, offset, count); | ||
| 723 | mutex_unlock(&c2dev->mutex); | ||
| 724 | |||
| 725 | if (ret < 0) | ||
| 726 | dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name); | ||
| 727 | |||
| 728 | return ret; | ||
| 729 | } | ||
| 730 | |||
| 731 | static ssize_t __c2port_write_flash_data(struct c2port_device *dev, | ||
| 732 | char *buffer, loff_t offset, size_t count) | ||
| 733 | { | ||
| 734 | struct c2port_ops *ops = dev->ops; | ||
| 735 | u8 status, nwrite = 128; | ||
| 736 | int i, ret; | ||
| 737 | |||
| 738 | if (nwrite > count) | ||
| 739 | nwrite = count; | ||
| 740 | if (ops->block_size * ops->blocks_num - offset < nwrite) | ||
| 741 | nwrite = ops->block_size * ops->blocks_num - offset; | ||
| 742 | |||
| 743 | /* Check for flash end */ | ||
| 744 | if (offset >= ops->block_size * ops->blocks_num) | ||
| 745 | return -EINVAL; | ||
| 746 | |||
| 747 | /* Target the C2 flash programming data register for C2 data register | ||
| 748 | * access */ | ||
| 749 | c2port_write_ar(dev, C2PORT_FPDAT); | ||
| 750 | |||
| 751 | /* Send flash block write command */ | ||
| 752 | c2port_write_dr(dev, C2PORT_BLOCK_WRITE); | ||
| 753 | |||
| 754 | /* Wait for input acknowledge */ | ||
| 755 | ret = c2port_poll_in_busy(dev); | ||
| 756 | if (ret < 0) | ||
| 757 | return ret; | ||
| 758 | |||
| 759 | /* Should check status before starting FLASH access sequence */ | ||
| 760 | |||
| 761 | /* Wait for status information */ | ||
| 762 | ret = c2port_poll_out_ready(dev); | ||
| 763 | if (ret < 0) | ||
| 764 | return ret; | ||
| 765 | |||
| 766 | /* Read flash programming interface status */ | ||
| 767 | ret = c2port_read_dr(dev, &status); | ||
| 768 | if (ret < 0) | ||
| 769 | return ret; | ||
| 770 | if (status != C2PORT_COMMAND_OK) | ||
| 771 | return -EBUSY; | ||
| 772 | |||
| 773 | /* Send address high byte */ | ||
| 774 | c2port_write_dr(dev, offset >> 8); | ||
| 775 | ret = c2port_poll_in_busy(dev); | ||
| 776 | if (ret < 0) | ||
| 777 | return ret; | ||
| 778 | |||
| 779 | /* Send address low byte */ | ||
| 780 | c2port_write_dr(dev, offset & 0x00ff); | ||
| 781 | ret = c2port_poll_in_busy(dev); | ||
| 782 | if (ret < 0) | ||
| 783 | return ret; | ||
| 784 | |||
| 785 | /* Send address block size */ | ||
| 786 | c2port_write_dr(dev, nwrite); | ||
| 787 | ret = c2port_poll_in_busy(dev); | ||
| 788 | if (ret < 0) | ||
| 789 | return ret; | ||
| 790 | |||
| 791 | /* Should check status before writing FLASH block */ | ||
| 792 | |||
| 793 | /* Wait for status information */ | ||
| 794 | ret = c2port_poll_out_ready(dev); | ||
| 795 | if (ret < 0) | ||
| 796 | return ret; | ||
| 797 | |||
| 798 | /* Read flash programming interface status */ | ||
| 799 | ret = c2port_read_dr(dev, &status); | ||
| 800 | if (ret < 0) | ||
| 801 | return ret; | ||
| 802 | if (status != C2PORT_COMMAND_OK) | ||
| 803 | return -EBUSY; | ||
| 804 | |||
| 805 | /* Write flash block */ | ||
| 806 | for (i = 0; i < nwrite; i++) { | ||
| 807 | ret = c2port_write_dr(dev, *(buffer+i)); | ||
| 808 | if (ret < 0) | ||
| 809 | return ret; | ||
| 810 | |||
| 811 | ret = c2port_poll_in_busy(dev); | ||
| 812 | if (ret < 0) | ||
| 813 | return ret; | ||
| 814 | |||
| 815 | } | ||
| 816 | |||
| 817 | /* Wait for last flash write to complete */ | ||
| 818 | ret = c2port_poll_out_ready(dev); | ||
| 819 | if (ret < 0) | ||
| 820 | return ret; | ||
| 821 | |||
| 822 | return nwrite; | ||
| 823 | } | ||
| 824 | |||
| 825 | static ssize_t c2port_write_flash_data(struct kobject *kobj, | ||
| 826 | struct bin_attribute *attr, | ||
| 827 | char *buffer, loff_t offset, size_t count) | ||
| 828 | { | ||
| 829 | struct c2port_device *c2dev = | ||
| 830 | dev_get_drvdata(container_of(kobj, | ||
| 831 | struct device, kobj)); | ||
| 832 | int ret; | ||
| 833 | |||
| 834 | /* Check the device access status */ | ||
| 835 | if (!c2dev->access || !c2dev->flash_access) | ||
| 836 | return -EBUSY; | ||
| 837 | |||
| 838 | mutex_lock(&c2dev->mutex); | ||
| 839 | ret = __c2port_write_flash_data(c2dev, buffer, offset, count); | ||
| 840 | mutex_unlock(&c2dev->mutex); | ||
| 841 | |||
| 842 | if (ret < 0) | ||
| 843 | dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name); | ||
| 844 | |||
| 845 | return ret; | ||
| 846 | } | ||
| 847 | |||
| 848 | /* | ||
| 849 | * Class attributes | ||
| 850 | */ | ||
| 851 | |||
| 852 | static struct device_attribute c2port_attrs[] = { | ||
| 853 | __ATTR(name, 0444, c2port_show_name, NULL), | ||
| 854 | __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL), | ||
| 855 | __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL), | ||
| 856 | __ATTR(flash_size, 0444, c2port_show_flash_size, NULL), | ||
| 857 | __ATTR(access, 0644, c2port_show_access, c2port_store_access), | ||
| 858 | __ATTR(reset, 0200, NULL, c2port_store_reset), | ||
| 859 | __ATTR(dev_id, 0444, c2port_show_dev_id, NULL), | ||
| 860 | __ATTR(rev_id, 0444, c2port_show_rev_id, NULL), | ||
| 861 | |||
| 862 | __ATTR(flash_access, 0644, c2port_show_flash_access, | ||
| 863 | c2port_store_flash_access), | ||
| 864 | __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase), | ||
| 865 | __ATTR_NULL, | ||
| 866 | }; | ||
| 867 | |||
| 868 | static struct bin_attribute c2port_bin_attrs = { | ||
| 869 | .attr = { | ||
| 870 | .name = "flash_data", | ||
| 871 | .mode = 0644 | ||
| 872 | }, | ||
| 873 | .read = c2port_read_flash_data, | ||
| 874 | .write = c2port_write_flash_data, | ||
| 875 | /* .size is computed at run-time */ | ||
| 876 | }; | ||
| 877 | |||
| 878 | /* | ||
| 879 | * Exported functions | ||
| 880 | */ | ||
| 881 | |||
| 882 | struct c2port_device *c2port_device_register(char *name, | ||
| 883 | struct c2port_ops *ops, void *devdata) | ||
| 884 | { | ||
| 885 | struct c2port_device *c2dev; | ||
| 886 | int id, ret; | ||
| 887 | |||
| 888 | if (unlikely(!ops) || unlikely(!ops->access) || \ | ||
| 889 | unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \ | ||
| 890 | unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set)) | ||
| 891 | return ERR_PTR(-EINVAL); | ||
| 892 | |||
| 893 | c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL); | ||
| 894 | if (unlikely(!c2dev)) | ||
| 895 | return ERR_PTR(-ENOMEM); | ||
| 896 | |||
| 897 | ret = idr_pre_get(&c2port_idr, GFP_KERNEL); | ||
| 898 | if (!ret) { | ||
| 899 | ret = -ENOMEM; | ||
| 900 | goto error_idr_get_new; | ||
| 901 | } | ||
| 902 | |||
| 903 | spin_lock_irq(&c2port_idr_lock); | ||
| 904 | ret = idr_get_new(&c2port_idr, c2dev, &id); | ||
| 905 | spin_unlock_irq(&c2port_idr_lock); | ||
| 906 | |||
| 907 | if (ret < 0) | ||
| 908 | goto error_idr_get_new; | ||
| 909 | c2dev->id = id; | ||
| 910 | |||
| 911 | c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, | ||
| 912 | "c2port%d", id); | ||
| 913 | if (unlikely(!c2dev->dev)) { | ||
| 914 | ret = -ENOMEM; | ||
| 915 | goto error_device_create; | ||
| 916 | } | ||
| 917 | dev_set_drvdata(c2dev->dev, c2dev); | ||
| 918 | |||
| 919 | strncpy(c2dev->name, name, C2PORT_NAME_LEN); | ||
| 920 | c2dev->ops = ops; | ||
| 921 | mutex_init(&c2dev->mutex); | ||
| 922 | |||
| 923 | /* Create binary file */ | ||
| 924 | c2port_bin_attrs.size = ops->blocks_num * ops->block_size; | ||
| 925 | ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs); | ||
| 926 | if (unlikely(ret)) | ||
| 927 | goto error_device_create_bin_file; | ||
| 928 | |||
| 929 | /* By default C2 port access is off */ | ||
| 930 | c2dev->access = c2dev->flash_access = 0; | ||
| 931 | ops->access(c2dev, 0); | ||
| 932 | |||
| 933 | dev_info(c2dev->dev, "C2 port %s added\n", name); | ||
| 934 | dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes " | ||
| 935 | "(%d bytes total)\n", | ||
| 936 | name, ops->blocks_num, ops->block_size, | ||
| 937 | ops->blocks_num * ops->block_size); | ||
| 938 | |||
| 939 | return c2dev; | ||
| 940 | |||
| 941 | error_device_create_bin_file: | ||
| 942 | device_destroy(c2port_class, 0); | ||
| 943 | |||
| 944 | error_device_create: | ||
| 945 | spin_lock_irq(&c2port_idr_lock); | ||
| 946 | idr_remove(&c2port_idr, id); | ||
| 947 | spin_unlock_irq(&c2port_idr_lock); | ||
| 948 | |||
| 949 | error_idr_get_new: | ||
| 950 | kfree(c2dev); | ||
| 951 | |||
| 952 | return ERR_PTR(ret); | ||
| 953 | } | ||
| 954 | EXPORT_SYMBOL(c2port_device_register); | ||
| 955 | |||
| 956 | void c2port_device_unregister(struct c2port_device *c2dev) | ||
| 957 | { | ||
| 958 | if (!c2dev) | ||
| 959 | return; | ||
| 960 | |||
| 961 | dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name); | ||
| 962 | |||
| 963 | device_remove_bin_file(c2dev->dev, &c2port_bin_attrs); | ||
| 964 | spin_lock_irq(&c2port_idr_lock); | ||
| 965 | idr_remove(&c2port_idr, c2dev->id); | ||
| 966 | spin_unlock_irq(&c2port_idr_lock); | ||
| 967 | |||
| 968 | device_destroy(c2port_class, c2dev->id); | ||
| 969 | |||
| 970 | kfree(c2dev); | ||
| 971 | } | ||
| 972 | EXPORT_SYMBOL(c2port_device_unregister); | ||
| 973 | |||
| 974 | /* | ||
| 975 | * Module stuff | ||
| 976 | */ | ||
| 977 | |||
| 978 | static int __init c2port_init(void) | ||
| 979 | { | ||
| 980 | printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION | ||
| 981 | " - (C) 2007 Rodolfo Giometti\n"); | ||
| 982 | |||
| 983 | c2port_class = class_create(THIS_MODULE, "c2port"); | ||
| 984 | if (!c2port_class) { | ||
| 985 | printk(KERN_ERR "c2port: failed to allocate class\n"); | ||
| 986 | return -ENOMEM; | ||
| 987 | } | ||
| 988 | c2port_class->dev_attrs = c2port_attrs; | ||
| 989 | |||
| 990 | return 0; | ||
| 991 | } | ||
| 992 | |||
| 993 | static void __exit c2port_exit(void) | ||
| 994 | { | ||
| 995 | class_destroy(c2port_class); | ||
| 996 | } | ||
| 997 | |||
| 998 | module_init(c2port_init); | ||
| 999 | module_exit(c2port_exit); | ||
| 1000 | |||
| 1001 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
| 1002 | MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION); | ||
| 1003 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c index 344b790a6253..11003bba10d3 100644 --- a/drivers/misc/compal-laptop.c +++ b/drivers/misc/compal-laptop.c | |||
| @@ -326,12 +326,14 @@ static int __init compal_init(void) | |||
| 326 | 326 | ||
| 327 | /* Register backlight stuff */ | 327 | /* Register backlight stuff */ |
| 328 | 328 | ||
| 329 | compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, | 329 | if (!acpi_video_backlight_support()) { |
| 330 | &compalbl_ops); | 330 | compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, |
| 331 | if (IS_ERR(compalbl_device)) | 331 | &compalbl_ops); |
| 332 | return PTR_ERR(compalbl_device); | 332 | if (IS_ERR(compalbl_device)) |
| 333 | return PTR_ERR(compalbl_device); | ||
| 333 | 334 | ||
| 334 | compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; | 335 | compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; |
| 336 | } | ||
| 335 | 337 | ||
| 336 | ret = platform_driver_register(&compal_driver); | 338 | ret = platform_driver_register(&compal_driver); |
| 337 | if (ret) | 339 | if (ret) |
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c index 9ef98b2d5039..02fe2b8b8939 100644 --- a/drivers/misc/eeepc-laptop.c +++ b/drivers/misc/eeepc-laptop.c | |||
| @@ -825,9 +825,15 @@ static int __init eeepc_laptop_init(void) | |||
| 825 | return -ENODEV; | 825 | return -ENODEV; |
| 826 | } | 826 | } |
| 827 | dev = acpi_get_physical_device(ehotk->device->handle); | 827 | dev = acpi_get_physical_device(ehotk->device->handle); |
| 828 | result = eeepc_backlight_init(dev); | 828 | |
| 829 | if (result) | 829 | if (!acpi_video_backlight_support()) { |
| 830 | goto fail_backlight; | 830 | result = eeepc_backlight_init(dev); |
| 831 | if (result) | ||
| 832 | goto fail_backlight; | ||
| 833 | } else | ||
| 834 | printk(EEEPC_INFO "Backlight controlled by ACPI video " | ||
| 835 | "driver\n"); | ||
| 836 | |||
| 831 | result = eeepc_hwmon_init(dev); | 837 | result = eeepc_hwmon_init(dev); |
| 832 | if (result) | 838 | if (result) |
| 833 | goto fail_hwmon; | 839 | goto fail_hwmon; |
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c index d2cf0bfe3163..a7dd3e9fb79d 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/misc/fujitsu-laptop.c | |||
| @@ -464,6 +464,14 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id) | |||
| 464 | return 0; | 464 | return 0; |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | static int dmi_check_cb_s6420(const struct dmi_system_id *id) | ||
| 468 | { | ||
| 469 | dmi_check_cb_common(id); | ||
| 470 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | ||
| 471 | fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ | ||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | |||
| 467 | static int dmi_check_cb_p8010(const struct dmi_system_id *id) | 475 | static int dmi_check_cb_p8010(const struct dmi_system_id *id) |
| 468 | { | 476 | { |
| 469 | dmi_check_cb_common(id); | 477 | dmi_check_cb_common(id); |
| @@ -473,7 +481,7 @@ static int dmi_check_cb_p8010(const struct dmi_system_id *id) | |||
| 473 | return 0; | 481 | return 0; |
| 474 | } | 482 | } |
| 475 | 483 | ||
| 476 | static struct dmi_system_id __initdata fujitsu_dmi_table[] = { | 484 | static struct dmi_system_id fujitsu_dmi_table[] = { |
| 477 | { | 485 | { |
| 478 | .ident = "Fujitsu Siemens S6410", | 486 | .ident = "Fujitsu Siemens S6410", |
| 479 | .matches = { | 487 | .matches = { |
| @@ -482,6 +490,13 @@ static struct dmi_system_id __initdata fujitsu_dmi_table[] = { | |||
| 482 | }, | 490 | }, |
| 483 | .callback = dmi_check_cb_s6410}, | 491 | .callback = dmi_check_cb_s6410}, |
| 484 | { | 492 | { |
| 493 | .ident = "Fujitsu Siemens S6420", | ||
| 494 | .matches = { | ||
| 495 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
| 496 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"), | ||
| 497 | }, | ||
| 498 | .callback = dmi_check_cb_s6420}, | ||
| 499 | { | ||
| 485 | .ident = "Fujitsu LifeBook P8010", | 500 | .ident = "Fujitsu LifeBook P8010", |
| 486 | .matches = { | 501 | .matches = { |
| 487 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 502 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
| @@ -990,16 +1005,16 @@ static int __init fujitsu_init(void) | |||
| 990 | 1005 | ||
| 991 | /* Register backlight stuff */ | 1006 | /* Register backlight stuff */ |
| 992 | 1007 | ||
| 993 | fujitsu->bl_device = | 1008 | if (!acpi_video_backlight_support()) { |
| 994 | backlight_device_register("fujitsu-laptop", NULL, NULL, | 1009 | fujitsu->bl_device = |
| 995 | &fujitsubl_ops); | 1010 | backlight_device_register("fujitsu-laptop", NULL, NULL, |
| 996 | if (IS_ERR(fujitsu->bl_device)) | 1011 | &fujitsubl_ops); |
| 997 | return PTR_ERR(fujitsu->bl_device); | 1012 | if (IS_ERR(fujitsu->bl_device)) |
| 998 | 1013 | return PTR_ERR(fujitsu->bl_device); | |
| 999 | max_brightness = fujitsu->max_brightness; | 1014 | max_brightness = fujitsu->max_brightness; |
| 1000 | 1015 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | |
| 1001 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | 1016 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; |
| 1002 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; | 1017 | } |
| 1003 | 1018 | ||
| 1004 | ret = platform_driver_register(&fujitsupf_driver); | 1019 | ret = platform_driver_register(&fujitsupf_driver); |
| 1005 | if (ret) | 1020 | if (ret) |
| @@ -1035,7 +1050,8 @@ fail_hotkey: | |||
| 1035 | 1050 | ||
| 1036 | fail_backlight: | 1051 | fail_backlight: |
| 1037 | 1052 | ||
| 1038 | backlight_device_unregister(fujitsu->bl_device); | 1053 | if (fujitsu->bl_device) |
| 1054 | backlight_device_unregister(fujitsu->bl_device); | ||
| 1039 | 1055 | ||
| 1040 | fail_platform_device2: | 1056 | fail_platform_device2: |
| 1041 | 1057 | ||
| @@ -1062,7 +1078,8 @@ static void __exit fujitsu_cleanup(void) | |||
| 1062 | &fujitsupf_attribute_group); | 1078 | &fujitsupf_attribute_group); |
| 1063 | platform_device_unregister(fujitsu->pf_device); | 1079 | platform_device_unregister(fujitsu->pf_device); |
| 1064 | platform_driver_unregister(&fujitsupf_driver); | 1080 | platform_driver_unregister(&fujitsupf_driver); |
| 1065 | backlight_device_unregister(fujitsu->bl_device); | 1081 | if (fujitsu->bl_device) |
| 1082 | backlight_device_unregister(fujitsu->bl_device); | ||
| 1066 | 1083 | ||
| 1067 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1084 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); |
| 1068 | 1085 | ||
diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c new file mode 100644 index 000000000000..6e43ab4231ae --- /dev/null +++ b/drivers/misc/ics932s401.c | |||
| @@ -0,0 +1,515 @@ | |||
| 1 | /* | ||
| 2 | * A driver for the Integrated Circuits ICS932S401 | ||
| 3 | * Copyright (C) 2008 IBM | ||
| 4 | * | ||
| 5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/jiffies.h> | ||
| 24 | #include <linux/i2c.h> | ||
| 25 | #include <linux/err.h> | ||
| 26 | #include <linux/mutex.h> | ||
| 27 | #include <linux/delay.h> | ||
| 28 | #include <linux/log2.h> | ||
| 29 | |||
| 30 | /* Addresses to scan */ | ||
| 31 | static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END }; | ||
| 32 | |||
| 33 | /* Insmod parameters */ | ||
| 34 | I2C_CLIENT_INSMOD_1(ics932s401); | ||
| 35 | |||
| 36 | /* ICS932S401 registers */ | ||
| 37 | #define ICS932S401_REG_CFG2 0x01 | ||
| 38 | #define ICS932S401_CFG1_SPREAD 0x01 | ||
| 39 | #define ICS932S401_REG_CFG7 0x06 | ||
| 40 | #define ICS932S401_FS_MASK 0x07 | ||
| 41 | #define ICS932S401_REG_VENDOR_REV 0x07 | ||
| 42 | #define ICS932S401_VENDOR 1 | ||
| 43 | #define ICS932S401_VENDOR_MASK 0x0F | ||
| 44 | #define ICS932S401_REV 4 | ||
| 45 | #define ICS932S401_REV_SHIFT 4 | ||
| 46 | #define ICS932S401_REG_DEVICE 0x09 | ||
| 47 | #define ICS932S401_DEVICE 11 | ||
| 48 | #define ICS932S401_REG_CTRL 0x0A | ||
| 49 | #define ICS932S401_MN_ENABLED 0x80 | ||
| 50 | #define ICS932S401_CPU_ALT 0x04 | ||
| 51 | #define ICS932S401_SRC_ALT 0x08 | ||
| 52 | #define ICS932S401_REG_CPU_M_CTRL 0x0B | ||
| 53 | #define ICS932S401_M_MASK 0x3F | ||
| 54 | #define ICS932S401_REG_CPU_N_CTRL 0x0C | ||
| 55 | #define ICS932S401_REG_CPU_SPREAD1 0x0D | ||
| 56 | #define ICS932S401_REG_CPU_SPREAD2 0x0E | ||
| 57 | #define ICS932S401_SPREAD_MASK 0x7FFF | ||
| 58 | #define ICS932S401_REG_SRC_M_CTRL 0x0F | ||
| 59 | #define ICS932S401_REG_SRC_N_CTRL 0x10 | ||
| 60 | #define ICS932S401_REG_SRC_SPREAD1 0x11 | ||
| 61 | #define ICS932S401_REG_SRC_SPREAD2 0x12 | ||
| 62 | #define ICS932S401_REG_CPU_DIVISOR 0x13 | ||
| 63 | #define ICS932S401_CPU_DIVISOR_SHIFT 4 | ||
| 64 | #define ICS932S401_REG_PCISRC_DIVISOR 0x14 | ||
| 65 | #define ICS932S401_SRC_DIVISOR_MASK 0x0F | ||
| 66 | #define ICS932S401_PCI_DIVISOR_SHIFT 4 | ||
| 67 | |||
| 68 | /* Base clock is 14.318MHz */ | ||
| 69 | #define BASE_CLOCK 14318 | ||
| 70 | |||
| 71 | #define NUM_REGS 21 | ||
| 72 | #define NUM_MIRRORED_REGS 15 | ||
| 73 | |||
| 74 | static int regs_to_copy[NUM_MIRRORED_REGS] = { | ||
| 75 | ICS932S401_REG_CFG2, | ||
| 76 | ICS932S401_REG_CFG7, | ||
| 77 | ICS932S401_REG_VENDOR_REV, | ||
| 78 | ICS932S401_REG_DEVICE, | ||
| 79 | ICS932S401_REG_CTRL, | ||
| 80 | ICS932S401_REG_CPU_M_CTRL, | ||
| 81 | ICS932S401_REG_CPU_N_CTRL, | ||
| 82 | ICS932S401_REG_CPU_SPREAD1, | ||
| 83 | ICS932S401_REG_CPU_SPREAD2, | ||
| 84 | ICS932S401_REG_SRC_M_CTRL, | ||
| 85 | ICS932S401_REG_SRC_N_CTRL, | ||
| 86 | ICS932S401_REG_SRC_SPREAD1, | ||
| 87 | ICS932S401_REG_SRC_SPREAD2, | ||
| 88 | ICS932S401_REG_CPU_DIVISOR, | ||
| 89 | ICS932S401_REG_PCISRC_DIVISOR, | ||
| 90 | }; | ||
| 91 | |||
| 92 | /* How often do we reread sensors values? (In jiffies) */ | ||
| 93 | #define SENSOR_REFRESH_INTERVAL (2 * HZ) | ||
| 94 | |||
| 95 | /* How often do we reread sensor limit values? (In jiffies) */ | ||
| 96 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | ||
| 97 | |||
| 98 | struct ics932s401_data { | ||
| 99 | struct attribute_group attrs; | ||
| 100 | struct mutex lock; | ||
| 101 | char sensors_valid; | ||
| 102 | unsigned long sensors_last_updated; /* In jiffies */ | ||
| 103 | |||
| 104 | u8 regs[NUM_REGS]; | ||
| 105 | }; | ||
| 106 | |||
| 107 | static int ics932s401_probe(struct i2c_client *client, | ||
| 108 | const struct i2c_device_id *id); | ||
| 109 | static int ics932s401_detect(struct i2c_client *client, int kind, | ||
| 110 | struct i2c_board_info *info); | ||
| 111 | static int ics932s401_remove(struct i2c_client *client); | ||
| 112 | |||
| 113 | static const struct i2c_device_id ics932s401_id[] = { | ||
| 114 | { "ics932s401", ics932s401 }, | ||
| 115 | { } | ||
| 116 | }; | ||
| 117 | MODULE_DEVICE_TABLE(i2c, ics932s401_id); | ||
| 118 | |||
| 119 | static struct i2c_driver ics932s401_driver = { | ||
| 120 | .class = I2C_CLASS_HWMON, | ||
| 121 | .driver = { | ||
| 122 | .name = "ics932s401", | ||
| 123 | }, | ||
| 124 | .probe = ics932s401_probe, | ||
| 125 | .remove = ics932s401_remove, | ||
| 126 | .id_table = ics932s401_id, | ||
| 127 | .detect = ics932s401_detect, | ||
| 128 | .address_data = &addr_data, | ||
| 129 | }; | ||
| 130 | |||
| 131 | static struct ics932s401_data *ics932s401_update_device(struct device *dev) | ||
| 132 | { | ||
| 133 | struct i2c_client *client = to_i2c_client(dev); | ||
| 134 | struct ics932s401_data *data = i2c_get_clientdata(client); | ||
| 135 | unsigned long local_jiffies = jiffies; | ||
| 136 | int i, temp; | ||
| 137 | |||
| 138 | mutex_lock(&data->lock); | ||
| 139 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
| 140 | SENSOR_REFRESH_INTERVAL) | ||
| 141 | && data->sensors_valid) | ||
| 142 | goto out; | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Each register must be read as a word and then right shifted 8 bits. | ||
| 146 | * Not really sure why this is; setting the "byte count programming" | ||
| 147 | * register to 1 does not fix this problem. | ||
| 148 | */ | ||
| 149 | for (i = 0; i < NUM_MIRRORED_REGS; i++) { | ||
| 150 | temp = i2c_smbus_read_word_data(client, regs_to_copy[i]); | ||
| 151 | data->regs[regs_to_copy[i]] = temp >> 8; | ||
| 152 | } | ||
| 153 | |||
| 154 | data->sensors_last_updated = local_jiffies; | ||
| 155 | data->sensors_valid = 1; | ||
| 156 | |||
| 157 | out: | ||
| 158 | mutex_unlock(&data->lock); | ||
| 159 | return data; | ||
| 160 | } | ||
| 161 | |||
| 162 | static ssize_t show_spread_enabled(struct device *dev, | ||
| 163 | struct device_attribute *devattr, | ||
| 164 | char *buf) | ||
| 165 | { | ||
| 166 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 167 | |||
| 168 | if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD) | ||
| 169 | return sprintf(buf, "1\n"); | ||
| 170 | |||
| 171 | return sprintf(buf, "0\n"); | ||
| 172 | } | ||
| 173 | |||
| 174 | /* bit to cpu khz map */ | ||
| 175 | static const int fs_speeds[] = { | ||
| 176 | 266666, | ||
| 177 | 133333, | ||
| 178 | 200000, | ||
| 179 | 166666, | ||
| 180 | 333333, | ||
| 181 | 100000, | ||
| 182 | 400000, | ||
| 183 | 0, | ||
| 184 | }; | ||
| 185 | |||
| 186 | /* clock divisor map */ | ||
| 187 | static const int divisors[] = {2, 3, 5, 15, 4, 6, 10, 30, 8, 12, 20, 60, 16, | ||
| 188 | 24, 40, 120}; | ||
| 189 | |||
| 190 | /* Calculate CPU frequency from the M/N registers. */ | ||
| 191 | static int calculate_cpu_freq(struct ics932s401_data *data) | ||
| 192 | { | ||
| 193 | int m, n, freq; | ||
| 194 | |||
| 195 | m = data->regs[ICS932S401_REG_CPU_M_CTRL] & ICS932S401_M_MASK; | ||
| 196 | n = data->regs[ICS932S401_REG_CPU_N_CTRL]; | ||
| 197 | |||
| 198 | /* Pull in bits 8 & 9 from the M register */ | ||
| 199 | n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x80) << 1; | ||
| 200 | n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x40) << 3; | ||
| 201 | |||
| 202 | freq = BASE_CLOCK * (n + 8) / (m + 2); | ||
| 203 | freq /= divisors[data->regs[ICS932S401_REG_CPU_DIVISOR] >> | ||
| 204 | ICS932S401_CPU_DIVISOR_SHIFT]; | ||
| 205 | |||
| 206 | return freq; | ||
| 207 | } | ||
| 208 | |||
| 209 | static ssize_t show_cpu_clock(struct device *dev, | ||
| 210 | struct device_attribute *devattr, | ||
| 211 | char *buf) | ||
| 212 | { | ||
| 213 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 214 | |||
| 215 | return sprintf(buf, "%d\n", calculate_cpu_freq(data)); | ||
| 216 | } | ||
| 217 | |||
| 218 | static ssize_t show_cpu_clock_sel(struct device *dev, | ||
| 219 | struct device_attribute *devattr, | ||
| 220 | char *buf) | ||
| 221 | { | ||
| 222 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 223 | int freq; | ||
| 224 | |||
| 225 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED) | ||
| 226 | freq = calculate_cpu_freq(data); | ||
| 227 | else { | ||
| 228 | /* Freq is neatly wrapped up for us */ | ||
| 229 | int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK; | ||
| 230 | freq = fs_speeds[fid]; | ||
| 231 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) { | ||
| 232 | switch (freq) { | ||
| 233 | case 166666: | ||
| 234 | freq = 160000; | ||
| 235 | break; | ||
| 236 | case 333333: | ||
| 237 | freq = 320000; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | return sprintf(buf, "%d\n", freq); | ||
| 244 | } | ||
| 245 | |||
| 246 | /* Calculate SRC frequency from the M/N registers. */ | ||
| 247 | static int calculate_src_freq(struct ics932s401_data *data) | ||
| 248 | { | ||
| 249 | int m, n, freq; | ||
| 250 | |||
| 251 | m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK; | ||
| 252 | n = data->regs[ICS932S401_REG_SRC_N_CTRL]; | ||
| 253 | |||
| 254 | /* Pull in bits 8 & 9 from the M register */ | ||
| 255 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1; | ||
| 256 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3; | ||
| 257 | |||
| 258 | freq = BASE_CLOCK * (n + 8) / (m + 2); | ||
| 259 | freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] & | ||
| 260 | ICS932S401_SRC_DIVISOR_MASK]; | ||
| 261 | |||
| 262 | return freq; | ||
| 263 | } | ||
| 264 | |||
| 265 | static ssize_t show_src_clock(struct device *dev, | ||
| 266 | struct device_attribute *devattr, | ||
| 267 | char *buf) | ||
| 268 | { | ||
| 269 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 270 | |||
| 271 | return sprintf(buf, "%d\n", calculate_src_freq(data)); | ||
| 272 | } | ||
| 273 | |||
| 274 | static ssize_t show_src_clock_sel(struct device *dev, | ||
| 275 | struct device_attribute *devattr, | ||
| 276 | char *buf) | ||
| 277 | { | ||
| 278 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 279 | int freq; | ||
| 280 | |||
| 281 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED) | ||
| 282 | freq = calculate_src_freq(data); | ||
| 283 | else | ||
| 284 | /* Freq is neatly wrapped up for us */ | ||
| 285 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT && | ||
| 286 | data->regs[ICS932S401_REG_CTRL] & ICS932S401_SRC_ALT) | ||
| 287 | freq = 96000; | ||
| 288 | else | ||
| 289 | freq = 100000; | ||
| 290 | |||
| 291 | return sprintf(buf, "%d\n", freq); | ||
| 292 | } | ||
| 293 | |||
| 294 | /* Calculate PCI frequency from the SRC M/N registers. */ | ||
| 295 | static int calculate_pci_freq(struct ics932s401_data *data) | ||
| 296 | { | ||
| 297 | int m, n, freq; | ||
| 298 | |||
| 299 | m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK; | ||
| 300 | n = data->regs[ICS932S401_REG_SRC_N_CTRL]; | ||
| 301 | |||
| 302 | /* Pull in bits 8 & 9 from the M register */ | ||
| 303 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1; | ||
| 304 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3; | ||
| 305 | |||
| 306 | freq = BASE_CLOCK * (n + 8) / (m + 2); | ||
| 307 | freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] >> | ||
| 308 | ICS932S401_PCI_DIVISOR_SHIFT]; | ||
| 309 | |||
| 310 | return freq; | ||
| 311 | } | ||
| 312 | |||
| 313 | static ssize_t show_pci_clock(struct device *dev, | ||
| 314 | struct device_attribute *devattr, | ||
| 315 | char *buf) | ||
| 316 | { | ||
| 317 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 318 | |||
| 319 | return sprintf(buf, "%d\n", calculate_pci_freq(data)); | ||
| 320 | } | ||
| 321 | |||
| 322 | static ssize_t show_pci_clock_sel(struct device *dev, | ||
| 323 | struct device_attribute *devattr, | ||
| 324 | char *buf) | ||
| 325 | { | ||
| 326 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 327 | int freq; | ||
| 328 | |||
| 329 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED) | ||
| 330 | freq = calculate_pci_freq(data); | ||
| 331 | else | ||
| 332 | freq = 33333; | ||
| 333 | |||
| 334 | return sprintf(buf, "%d\n", freq); | ||
| 335 | } | ||
| 336 | |||
| 337 | static ssize_t show_value(struct device *dev, | ||
| 338 | struct device_attribute *devattr, | ||
| 339 | char *buf); | ||
| 340 | |||
| 341 | static ssize_t show_spread(struct device *dev, | ||
| 342 | struct device_attribute *devattr, | ||
| 343 | char *buf); | ||
| 344 | |||
| 345 | static DEVICE_ATTR(spread_enabled, S_IRUGO, show_spread_enabled, NULL); | ||
| 346 | static DEVICE_ATTR(cpu_clock_selection, S_IRUGO, show_cpu_clock_sel, NULL); | ||
| 347 | static DEVICE_ATTR(cpu_clock, S_IRUGO, show_cpu_clock, NULL); | ||
| 348 | static DEVICE_ATTR(src_clock_selection, S_IRUGO, show_src_clock_sel, NULL); | ||
| 349 | static DEVICE_ATTR(src_clock, S_IRUGO, show_src_clock, NULL); | ||
| 350 | static DEVICE_ATTR(pci_clock_selection, S_IRUGO, show_pci_clock_sel, NULL); | ||
| 351 | static DEVICE_ATTR(pci_clock, S_IRUGO, show_pci_clock, NULL); | ||
| 352 | static DEVICE_ATTR(usb_clock, S_IRUGO, show_value, NULL); | ||
| 353 | static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL); | ||
| 354 | static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL); | ||
| 355 | static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL); | ||
| 356 | |||
| 357 | static struct attribute *ics932s401_attr[] = | ||
| 358 | { | ||
| 359 | &dev_attr_spread_enabled.attr, | ||
| 360 | &dev_attr_cpu_clock_selection.attr, | ||
| 361 | &dev_attr_cpu_clock.attr, | ||
| 362 | &dev_attr_src_clock_selection.attr, | ||
| 363 | &dev_attr_src_clock.attr, | ||
| 364 | &dev_attr_pci_clock_selection.attr, | ||
| 365 | &dev_attr_pci_clock.attr, | ||
| 366 | &dev_attr_usb_clock.attr, | ||
| 367 | &dev_attr_ref_clock.attr, | ||
| 368 | &dev_attr_cpu_spread.attr, | ||
| 369 | &dev_attr_src_spread.attr, | ||
| 370 | NULL | ||
| 371 | }; | ||
| 372 | |||
| 373 | static ssize_t show_value(struct device *dev, | ||
| 374 | struct device_attribute *devattr, | ||
| 375 | char *buf) | ||
| 376 | { | ||
| 377 | int x; | ||
| 378 | |||
| 379 | if (devattr == &dev_attr_usb_clock) | ||
| 380 | x = 48000; | ||
| 381 | else if (devattr == &dev_attr_ref_clock) | ||
| 382 | x = BASE_CLOCK; | ||
| 383 | else | ||
| 384 | BUG(); | ||
| 385 | |||
| 386 | return sprintf(buf, "%d\n", x); | ||
| 387 | } | ||
| 388 | |||
| 389 | static ssize_t show_spread(struct device *dev, | ||
| 390 | struct device_attribute *devattr, | ||
| 391 | char *buf) | ||
| 392 | { | ||
| 393 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
| 394 | int reg; | ||
| 395 | unsigned long val; | ||
| 396 | |||
| 397 | if (!(data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)) | ||
| 398 | return sprintf(buf, "0%%\n"); | ||
| 399 | |||
| 400 | if (devattr == &dev_attr_src_spread) | ||
| 401 | reg = ICS932S401_REG_SRC_SPREAD1; | ||
| 402 | else if (devattr == &dev_attr_cpu_spread) | ||
| 403 | reg = ICS932S401_REG_CPU_SPREAD1; | ||
| 404 | else | ||
| 405 | BUG(); | ||
| 406 | |||
| 407 | val = data->regs[reg] | (data->regs[reg + 1] << 8); | ||
| 408 | val &= ICS932S401_SPREAD_MASK; | ||
| 409 | |||
| 410 | /* Scale 0..2^14 to -0.5. */ | ||
| 411 | val = 500000 * val / 16384; | ||
| 412 | return sprintf(buf, "-0.%lu%%\n", val); | ||
| 413 | } | ||
| 414 | |||
| 415 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
| 416 | static int ics932s401_detect(struct i2c_client *client, int kind, | ||
| 417 | struct i2c_board_info *info) | ||
| 418 | { | ||
| 419 | struct i2c_adapter *adapter = client->adapter; | ||
| 420 | |||
| 421 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 422 | return -ENODEV; | ||
| 423 | |||
| 424 | if (kind <= 0) { | ||
| 425 | int vendor, device, revision; | ||
| 426 | |||
| 427 | vendor = i2c_smbus_read_word_data(client, | ||
| 428 | ICS932S401_REG_VENDOR_REV); | ||
| 429 | vendor >>= 8; | ||
| 430 | revision = vendor >> ICS932S401_REV_SHIFT; | ||
| 431 | vendor &= ICS932S401_VENDOR_MASK; | ||
| 432 | if (vendor != ICS932S401_VENDOR) | ||
| 433 | return -ENODEV; | ||
| 434 | |||
| 435 | device = i2c_smbus_read_word_data(client, | ||
| 436 | ICS932S401_REG_DEVICE); | ||
| 437 | device >>= 8; | ||
| 438 | if (device != ICS932S401_DEVICE) | ||
| 439 | return -ENODEV; | ||
| 440 | |||
| 441 | if (revision != ICS932S401_REV) | ||
| 442 | dev_info(&adapter->dev, "Unknown revision %d\n", | ||
| 443 | revision); | ||
| 444 | } else | ||
| 445 | dev_dbg(&adapter->dev, "detection forced\n"); | ||
| 446 | |||
| 447 | strlcpy(info->type, "ics932s401", I2C_NAME_SIZE); | ||
| 448 | |||
| 449 | return 0; | ||
| 450 | } | ||
| 451 | |||
| 452 | static int ics932s401_probe(struct i2c_client *client, | ||
| 453 | const struct i2c_device_id *id) | ||
| 454 | { | ||
| 455 | struct ics932s401_data *data; | ||
| 456 | int err; | ||
| 457 | |||
| 458 | data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL); | ||
| 459 | if (!data) { | ||
| 460 | err = -ENOMEM; | ||
| 461 | goto exit; | ||
| 462 | } | ||
| 463 | |||
| 464 | i2c_set_clientdata(client, data); | ||
| 465 | mutex_init(&data->lock); | ||
| 466 | |||
| 467 | dev_info(&client->dev, "%s chip found\n", client->name); | ||
| 468 | |||
| 469 | /* Register sysfs hooks */ | ||
| 470 | data->attrs.attrs = ics932s401_attr; | ||
| 471 | err = sysfs_create_group(&client->dev.kobj, &data->attrs); | ||
| 472 | if (err) | ||
| 473 | goto exit_free; | ||
| 474 | |||
| 475 | return 0; | ||
| 476 | |||
| 477 | exit_free: | ||
| 478 | kfree(data); | ||
| 479 | exit: | ||
| 480 | return err; | ||
| 481 | } | ||
| 482 | |||
| 483 | static int ics932s401_remove(struct i2c_client *client) | ||
| 484 | { | ||
| 485 | struct ics932s401_data *data = i2c_get_clientdata(client); | ||
| 486 | |||
| 487 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
| 488 | kfree(data); | ||
| 489 | return 0; | ||
| 490 | } | ||
| 491 | |||
| 492 | static int __init ics932s401_init(void) | ||
| 493 | { | ||
| 494 | return i2c_add_driver(&ics932s401_driver); | ||
| 495 | } | ||
| 496 | |||
| 497 | static void __exit ics932s401_exit(void) | ||
| 498 | { | ||
| 499 | i2c_del_driver(&ics932s401_driver); | ||
| 500 | } | ||
| 501 | |||
| 502 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
| 503 | MODULE_DESCRIPTION("ICS932S401 driver"); | ||
| 504 | MODULE_LICENSE("GPL"); | ||
| 505 | |||
| 506 | module_init(ics932s401_init); | ||
| 507 | module_exit(ics932s401_exit); | ||
| 508 | |||
| 509 | /* IBM IntelliStation Z30 */ | ||
| 510 | MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*"); | ||
| 511 | MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*"); | ||
| 512 | |||
| 513 | /* IBM x3650/x3550 */ | ||
| 514 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650*"); | ||
| 515 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550*"); | ||
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c index e00a2756e97e..27b7662955bb 100644 --- a/drivers/misc/intel_menlow.c +++ b/drivers/misc/intel_menlow.c | |||
| @@ -52,6 +52,11 @@ MODULE_LICENSE("GPL"); | |||
| 52 | #define MEMORY_ARG_CUR_BANDWIDTH 1 | 52 | #define MEMORY_ARG_CUR_BANDWIDTH 1 |
| 53 | #define MEMORY_ARG_MAX_BANDWIDTH 0 | 53 | #define MEMORY_ARG_MAX_BANDWIDTH 0 |
| 54 | 54 | ||
| 55 | /* | ||
| 56 | * GTHS returning 'n' would mean that [0,n-1] states are supported | ||
| 57 | * In that case max_cstate would be n-1 | ||
| 58 | * GTHS returning '0' would mean that no bandwidth control states are supported | ||
| 59 | */ | ||
| 55 | static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | 60 | static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, |
| 56 | unsigned long *max_state) | 61 | unsigned long *max_state) |
| 57 | { | 62 | { |
| @@ -71,6 +76,9 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | |||
| 71 | if (ACPI_FAILURE(status)) | 76 | if (ACPI_FAILURE(status)) |
| 72 | return -EFAULT; | 77 | return -EFAULT; |
| 73 | 78 | ||
| 79 | if (!value) | ||
| 80 | return -EINVAL; | ||
| 81 | |||
| 74 | *max_state = value - 1; | 82 | *max_state = value - 1; |
| 75 | return 0; | 83 | return 0; |
| 76 | } | 84 | } |
| @@ -121,7 +129,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
| 121 | if (memory_get_int_max_bandwidth(cdev, &max_state)) | 129 | if (memory_get_int_max_bandwidth(cdev, &max_state)) |
| 122 | return -EFAULT; | 130 | return -EFAULT; |
| 123 | 131 | ||
| 124 | if (max_state < 0 || state > max_state) | 132 | if (state > max_state) |
| 125 | return -EINVAL; | 133 | return -EINVAL; |
| 126 | 134 | ||
| 127 | arg_list.count = 1; | 135 | arg_list.count = 1; |
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c index de898c6938f3..759763d18e4c 100644 --- a/drivers/misc/msi-laptop.c +++ b/drivers/misc/msi-laptop.c | |||
| @@ -347,12 +347,16 @@ static int __init msi_init(void) | |||
| 347 | 347 | ||
| 348 | /* Register backlight stuff */ | 348 | /* Register backlight stuff */ |
| 349 | 349 | ||
| 350 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL, | 350 | if (acpi_video_backlight_support()) { |
| 351 | &msibl_ops); | 351 | printk(KERN_INFO "MSI: Brightness ignored, must be controlled " |
| 352 | if (IS_ERR(msibl_device)) | 352 | "by ACPI video driver\n"); |
| 353 | return PTR_ERR(msibl_device); | 353 | } else { |
| 354 | 354 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, | |
| 355 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; | 355 | NULL, &msibl_ops); |
| 356 | if (IS_ERR(msibl_device)) | ||
| 357 | return PTR_ERR(msibl_device); | ||
| 358 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; | ||
| 359 | } | ||
| 356 | 360 | ||
| 357 | ret = platform_driver_register(&msipf_driver); | 361 | ret = platform_driver_register(&msipf_driver); |
| 358 | if (ret) | 362 | if (ret) |
diff --git a/drivers/misc/panasonic-laptop.c b/drivers/misc/panasonic-laptop.c index a2cb598d8ab5..4a1bc64485d5 100644 --- a/drivers/misc/panasonic-laptop.c +++ b/drivers/misc/panasonic-laptop.c | |||
| @@ -116,7 +116,6 @@ | |||
| 116 | * | 116 | * |
| 117 | */ | 117 | */ |
| 118 | 118 | ||
| 119 | #include <linux/version.h> | ||
| 120 | #include <linux/kernel.h> | 119 | #include <linux/kernel.h> |
| 121 | #include <linux/module.h> | 120 | #include <linux/module.h> |
| 122 | #include <linux/init.h> | 121 | #include <linux/init.h> |
diff --git a/drivers/misc/sgi-gru/Makefile b/drivers/misc/sgi-gru/Makefile index d03597a521b0..9e9170b3599a 100644 --- a/drivers/misc/sgi-gru/Makefile +++ b/drivers/misc/sgi-gru/Makefile | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | ifdef CONFIG_SGI_GRU_DEBUG | ||
| 2 | EXTRA_CFLAGS += -DDEBUG | ||
| 3 | endif | ||
| 4 | |||
| 1 | obj-$(CONFIG_SGI_GRU) := gru.o | 5 | obj-$(CONFIG_SGI_GRU) := gru.o |
| 2 | gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o | 6 | gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o |
| 3 | 7 | ||
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c index 8c389d606c30..3ee698ad8599 100644 --- a/drivers/misc/sgi-gru/grufault.c +++ b/drivers/misc/sgi-gru/grufault.c | |||
| @@ -254,7 +254,11 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr, | |||
| 254 | return 1; | 254 | return 1; |
| 255 | 255 | ||
| 256 | *paddr = pte_pfn(pte) << PAGE_SHIFT; | 256 | *paddr = pte_pfn(pte) << PAGE_SHIFT; |
| 257 | #ifdef CONFIG_HUGETLB_PAGE | ||
| 257 | *pageshift = is_vm_hugetlb_page(vma) ? HPAGE_SHIFT : PAGE_SHIFT; | 258 | *pageshift = is_vm_hugetlb_page(vma) ? HPAGE_SHIFT : PAGE_SHIFT; |
| 259 | #else | ||
| 260 | *pageshift = PAGE_SHIFT; | ||
| 261 | #endif | ||
| 258 | return 0; | 262 | return 0; |
| 259 | 263 | ||
| 260 | err: | 264 | err: |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 5c027b6b4e5a..650983806392 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
| @@ -481,7 +481,7 @@ struct vm_operations_struct gru_vm_ops = { | |||
| 481 | .fault = gru_fault, | 481 | .fault = gru_fault, |
| 482 | }; | 482 | }; |
| 483 | 483 | ||
| 484 | module_init(gru_init); | 484 | fs_initcall(gru_init); |
| 485 | module_exit(gru_exit); | 485 | module_exit(gru_exit); |
| 486 | 486 | ||
| 487 | module_param(gru_options, ulong, 0644); | 487 | module_param(gru_options, ulong, 0644); |
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index f483c4221f76..571b211608d1 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
| @@ -1038,7 +1038,11 @@ static int sony_nc_add(struct acpi_device *device) | |||
| 1038 | goto outinput; | 1038 | goto outinput; |
| 1039 | } | 1039 | } |
| 1040 | 1040 | ||
| 1041 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &handle))) { | 1041 | if (acpi_video_backlight_support()) { |
| 1042 | printk(KERN_INFO DRV_PFX "brightness ignored, must be " | ||
| 1043 | "controlled by ACPI video driver\n"); | ||
| 1044 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | ||
| 1045 | &handle))) { | ||
| 1042 | sony_backlight_device = backlight_device_register("sony", NULL, | 1046 | sony_backlight_device = backlight_device_register("sony", NULL, |
| 1043 | NULL, | 1047 | NULL, |
| 1044 | &sony_backlight_ops); | 1048 | &sony_backlight_ops); |
| @@ -1920,7 +1924,6 @@ static int sonypi_misc_fasync(int fd, struct file *filp, int on) | |||
| 1920 | 1924 | ||
| 1921 | static int sonypi_misc_release(struct inode *inode, struct file *file) | 1925 | static int sonypi_misc_release(struct inode *inode, struct file *file) |
| 1922 | { | 1926 | { |
| 1923 | sonypi_misc_fasync(-1, file, 0); | ||
| 1924 | atomic_dec(&sonypi_compat.open_count); | 1927 | atomic_dec(&sonypi_compat.open_count); |
| 1925 | return 0; | 1928 | return 0; |
| 1926 | } | 1929 | } |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 4db1cf9078d9..899766e16fa8 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
| @@ -4932,16 +4932,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
| 4932 | */ | 4932 | */ |
| 4933 | b = tpacpi_check_std_acpi_brightness_support(); | 4933 | b = tpacpi_check_std_acpi_brightness_support(); |
| 4934 | if (b > 0) { | 4934 | if (b > 0) { |
| 4935 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | 4935 | |
| 4936 | printk(TPACPI_NOTICE | 4936 | if (acpi_video_backlight_support()) { |
| 4937 | "Lenovo BIOS switched to ACPI backlight " | 4937 | if (brightness_enable > 1) { |
| 4938 | "control mode\n"); | 4938 | printk(TPACPI_NOTICE |
| 4939 | } | 4939 | "Standard ACPI backlight interface " |
| 4940 | if (brightness_enable > 1) { | 4940 | "available, not loading native one.\n"); |
| 4941 | printk(TPACPI_NOTICE | 4941 | return 1; |
| 4942 | "standard ACPI backlight interface " | 4942 | } else if (brightness_enable == 1) { |
| 4943 | "available, not loading native one...\n"); | 4943 | printk(TPACPI_NOTICE |
| 4944 | return 1; | 4944 | "Backlight control force enabled, even if standard " |
| 4945 | "ACPI backlight interface is available\n"); | ||
| 4946 | } | ||
| 4947 | } else { | ||
| 4948 | if (brightness_enable > 1) { | ||
| 4949 | printk(TPACPI_NOTICE | ||
| 4950 | "Standard ACPI backlight interface not " | ||
| 4951 | "available, thinkpad_acpi native " | ||
| 4952 | "brightness control enabled\n"); | ||
| 4953 | } | ||
| 4945 | } | 4954 | } |
| 4946 | } | 4955 | } |
| 4947 | 4956 | ||
| @@ -5309,6 +5318,7 @@ static enum fan_control_commands fan_control_commands; | |||
| 5309 | 5318 | ||
| 5310 | static u8 fan_control_initial_status; | 5319 | static u8 fan_control_initial_status; |
| 5311 | static u8 fan_control_desired_level; | 5320 | static u8 fan_control_desired_level; |
| 5321 | static u8 fan_control_resume_level; | ||
| 5312 | static int fan_watchdog_maxinterval; | 5322 | static int fan_watchdog_maxinterval; |
| 5313 | 5323 | ||
| 5314 | static struct mutex fan_mutex; | 5324 | static struct mutex fan_mutex; |
| @@ -5431,8 +5441,8 @@ static int fan_set_level(int level) | |||
| 5431 | 5441 | ||
| 5432 | case TPACPI_FAN_WR_ACPI_FANS: | 5442 | case TPACPI_FAN_WR_ACPI_FANS: |
| 5433 | case TPACPI_FAN_WR_TPEC: | 5443 | case TPACPI_FAN_WR_TPEC: |
| 5434 | if ((level != TP_EC_FAN_AUTO) && | 5444 | if (!(level & TP_EC_FAN_AUTO) && |
| 5435 | (level != TP_EC_FAN_FULLSPEED) && | 5445 | !(level & TP_EC_FAN_FULLSPEED) && |
| 5436 | ((level < 0) || (level > 7))) | 5446 | ((level < 0) || (level > 7))) |
| 5437 | return -EINVAL; | 5447 | return -EINVAL; |
| 5438 | 5448 | ||
| @@ -5996,38 +6006,67 @@ static void fan_exit(void) | |||
| 5996 | 6006 | ||
| 5997 | static void fan_suspend(pm_message_t state) | 6007 | static void fan_suspend(pm_message_t state) |
| 5998 | { | 6008 | { |
| 6009 | int rc; | ||
| 6010 | |||
| 5999 | if (!fan_control_allowed) | 6011 | if (!fan_control_allowed) |
| 6000 | return; | 6012 | return; |
| 6001 | 6013 | ||
| 6002 | /* Store fan status in cache */ | 6014 | /* Store fan status in cache */ |
| 6003 | fan_get_status_safe(NULL); | 6015 | fan_control_resume_level = 0; |
| 6016 | rc = fan_get_status_safe(&fan_control_resume_level); | ||
| 6017 | if (rc < 0) | ||
| 6018 | printk(TPACPI_NOTICE | ||
| 6019 | "failed to read fan level for later " | ||
| 6020 | "restore during resume: %d\n", rc); | ||
| 6021 | |||
| 6022 | /* if it is undefined, don't attempt to restore it. | ||
| 6023 | * KEEP THIS LAST */ | ||
| 6004 | if (tp_features.fan_ctrl_status_undef) | 6024 | if (tp_features.fan_ctrl_status_undef) |
| 6005 | fan_control_desired_level = TP_EC_FAN_AUTO; | 6025 | fan_control_resume_level = 0; |
| 6006 | } | 6026 | } |
| 6007 | 6027 | ||
| 6008 | static void fan_resume(void) | 6028 | static void fan_resume(void) |
| 6009 | { | 6029 | { |
| 6010 | u8 saved_fan_level; | ||
| 6011 | u8 current_level = 7; | 6030 | u8 current_level = 7; |
| 6012 | bool do_set = false; | 6031 | bool do_set = false; |
| 6032 | int rc; | ||
| 6013 | 6033 | ||
| 6014 | /* DSDT *always* updates status on resume */ | 6034 | /* DSDT *always* updates status on resume */ |
| 6015 | tp_features.fan_ctrl_status_undef = 0; | 6035 | tp_features.fan_ctrl_status_undef = 0; |
| 6016 | 6036 | ||
| 6017 | saved_fan_level = fan_control_desired_level; | ||
| 6018 | if (!fan_control_allowed || | 6037 | if (!fan_control_allowed || |
| 6038 | !fan_control_resume_level || | ||
| 6019 | (fan_get_status_safe(¤t_level) < 0)) | 6039 | (fan_get_status_safe(¤t_level) < 0)) |
| 6020 | return; | 6040 | return; |
| 6021 | 6041 | ||
| 6022 | switch (fan_control_access_mode) { | 6042 | switch (fan_control_access_mode) { |
| 6023 | case TPACPI_FAN_WR_ACPI_SFAN: | 6043 | case TPACPI_FAN_WR_ACPI_SFAN: |
| 6024 | do_set = (saved_fan_level > current_level); | 6044 | /* never decrease fan level */ |
| 6045 | do_set = (fan_control_resume_level > current_level); | ||
| 6025 | break; | 6046 | break; |
| 6026 | case TPACPI_FAN_WR_ACPI_FANS: | 6047 | case TPACPI_FAN_WR_ACPI_FANS: |
| 6027 | case TPACPI_FAN_WR_TPEC: | 6048 | case TPACPI_FAN_WR_TPEC: |
| 6028 | do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) || | 6049 | /* never decrease fan level, scale is: |
| 6029 | (saved_fan_level == 7 && | 6050 | * TP_EC_FAN_FULLSPEED > 7 >= TP_EC_FAN_AUTO |
| 6030 | !(current_level & TP_EC_FAN_FULLSPEED))); | 6051 | * |
| 6052 | * We expect the firmware to set either 7 or AUTO, but we | ||
| 6053 | * handle FULLSPEED out of paranoia. | ||
| 6054 | * | ||
| 6055 | * So, we can safely only restore FULLSPEED or 7, anything | ||
| 6056 | * else could slow the fan. Restoring AUTO is useless, at | ||
| 6057 | * best that's exactly what the DSDT already set (it is the | ||
| 6058 | * slower it uses). | ||
| 6059 | * | ||
| 6060 | * Always keep in mind that the DSDT *will* have set the | ||
| 6061 | * fans to what the vendor supposes is the best level. We | ||
| 6062 | * muck with it only to speed the fan up. | ||
| 6063 | */ | ||
| 6064 | if (fan_control_resume_level != 7 && | ||
| 6065 | !(fan_control_resume_level & TP_EC_FAN_FULLSPEED)) | ||
| 6066 | return; | ||
| 6067 | else | ||
| 6068 | do_set = !(current_level & TP_EC_FAN_FULLSPEED) && | ||
| 6069 | (current_level != fan_control_resume_level); | ||
| 6031 | break; | 6070 | break; |
| 6032 | default: | 6071 | default: |
| 6033 | return; | 6072 | return; |
| @@ -6035,8 +6074,11 @@ static void fan_resume(void) | |||
| 6035 | if (do_set) { | 6074 | if (do_set) { |
| 6036 | printk(TPACPI_NOTICE | 6075 | printk(TPACPI_NOTICE |
| 6037 | "restoring fan level to 0x%02x\n", | 6076 | "restoring fan level to 0x%02x\n", |
| 6038 | saved_fan_level); | 6077 | fan_control_resume_level); |
| 6039 | fan_set_level_safe(saved_fan_level); | 6078 | rc = fan_set_level_safe(fan_control_resume_level); |
| 6079 | if (rc < 0) | ||
| 6080 | printk(TPACPI_NOTICE | ||
| 6081 | "failed to restore fan level: %d\n", rc); | ||
| 6040 | } | 6082 | } |
| 6041 | } | 6083 | } |
| 6042 | 6084 | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 0d9b2d6f9ebf..f210a8ee6861 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
| @@ -216,8 +216,7 @@ int mmc_add_card(struct mmc_card *card) | |||
| 216 | int ret; | 216 | int ret; |
| 217 | const char *type; | 217 | const char *type; |
| 218 | 218 | ||
| 219 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), | 219 | dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); |
| 220 | "%s:%04x", mmc_hostname(card->host), card->rca); | ||
| 221 | 220 | ||
| 222 | switch (card->type) { | 221 | switch (card->type) { |
| 223 | case MMC_TYPE_MMC: | 222 | case MMC_TYPE_MMC: |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 044d84eeed7c..f7284b905eb3 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |||
| 280 | (card->host->ios.clock / 1000); | 280 | (card->host->ios.clock / 1000); |
| 281 | 281 | ||
| 282 | if (data->flags & MMC_DATA_WRITE) | 282 | if (data->flags & MMC_DATA_WRITE) |
| 283 | limit_us = 250000; | 283 | /* |
| 284 | * The limit is really 250 ms, but that is | ||
| 285 | * insufficient for some crappy cards. | ||
| 286 | */ | ||
| 287 | limit_us = 300000; | ||
| 284 | else | 288 | else |
| 285 | limit_us = 100000; | 289 | limit_us = 100000; |
| 286 | 290 | ||
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 6da80fd4d974..5e945e64ead7 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
| @@ -73,8 +73,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
| 73 | if (err) | 73 | if (err) |
| 74 | goto free; | 74 | goto free; |
| 75 | 75 | ||
| 76 | snprintf(host->class_dev.bus_id, BUS_ID_SIZE, | 76 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
| 77 | "mmc%d", host->index); | ||
| 78 | 77 | ||
| 79 | host->parent = dev; | 78 | host->parent = dev; |
| 80 | host->class_dev.parent = dev; | 79 | host->class_dev.parent = dev; |
| @@ -121,7 +120,7 @@ int mmc_add_host(struct mmc_host *host) | |||
| 121 | WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && | 120 | WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && |
| 122 | !host->ops->enable_sdio_irq); | 121 | !host->ops->enable_sdio_irq); |
| 123 | 122 | ||
| 124 | led_trigger_register_simple(host->class_dev.bus_id, &host->led); | 123 | led_trigger_register_simple(dev_name(&host->class_dev), &host->led); |
| 125 | 124 | ||
| 126 | err = device_add(&host->class_dev); | 125 | err = device_add(&host->class_dev); |
| 127 | if (err) | 126 | if (err) |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 233d0f9b3c4b..46284b527397 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
| @@ -239,8 +239,7 @@ int sdio_add_func(struct sdio_func *func) | |||
| 239 | { | 239 | { |
| 240 | int ret; | 240 | int ret; |
| 241 | 241 | ||
| 242 | snprintf(func->dev.bus_id, sizeof(func->dev.bus_id), | 242 | dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); |
| 243 | "%s:%d", mmc_card_id(func->card), func->num); | ||
| 244 | 243 | ||
| 245 | ret = device_add(&func->dev); | 244 | ret = device_add(&func->dev); |
| 246 | if (ret == 0) | 245 | if (ret == 0) |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 07faf5412a1f..ad00e1632317 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -1348,7 +1348,7 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
| 1348 | goto fail_add_host; | 1348 | goto fail_add_host; |
| 1349 | 1349 | ||
| 1350 | dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", | 1350 | dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", |
| 1351 | mmc->class_dev.bus_id, | 1351 | dev_name(&mmc->class_dev), |
| 1352 | host->dma_dev ? "" : ", no DMA", | 1352 | host->dma_dev ? "" : ", no DMA", |
| 1353 | (host->pdata && host->pdata->get_ro) | 1353 | (host->pdata && host->pdata->get_ro) |
| 1354 | ? "" : ", no WP", | 1354 | ? "" : ", no WP", |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 30f64b1f2354..4d010a984bed 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -1733,7 +1733,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 1733 | mmc_add_host(mmc); | 1733 | mmc_add_host(mmc); |
| 1734 | 1734 | ||
| 1735 | printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", | 1735 | printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", |
| 1736 | mmc_hostname(mmc), host->hw_name, mmc_dev(mmc)->bus_id, | 1736 | mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), |
| 1737 | (host->flags & SDHCI_USE_ADMA)?"A":"", | 1737 | (host->flags & SDHCI_USE_ADMA)?"A":"", |
| 1738 | (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); | 1738 | (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); |
| 1739 | 1739 | ||
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 13844843e8de..82554ddec6b3 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c | |||
| @@ -632,7 +632,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 632 | 632 | ||
| 633 | if (host->req) { | 633 | if (host->req) { |
| 634 | printk(KERN_ERR "%s : unfinished request detected\n", | 634 | printk(KERN_ERR "%s : unfinished request detected\n", |
| 635 | sock->dev.bus_id); | 635 | dev_name(&sock->dev)); |
| 636 | mrq->cmd->error = -ETIMEDOUT; | 636 | mrq->cmd->error = -ETIMEDOUT; |
| 637 | goto err_out; | 637 | goto err_out; |
| 638 | } | 638 | } |
| @@ -672,7 +672,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 672 | ? PCI_DMA_TODEVICE | 672 | ? PCI_DMA_TODEVICE |
| 673 | : PCI_DMA_FROMDEVICE)) { | 673 | : PCI_DMA_FROMDEVICE)) { |
| 674 | printk(KERN_ERR "%s : scatterlist map failed\n", | 674 | printk(KERN_ERR "%s : scatterlist map failed\n", |
| 675 | sock->dev.bus_id); | 675 | dev_name(&sock->dev)); |
| 676 | mrq->cmd->error = -ENOMEM; | 676 | mrq->cmd->error = -ENOMEM; |
| 677 | goto err_out; | 677 | goto err_out; |
| 678 | } | 678 | } |
| @@ -684,7 +684,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 684 | : PCI_DMA_FROMDEVICE); | 684 | : PCI_DMA_FROMDEVICE); |
| 685 | if (host->sg_len < 1) { | 685 | if (host->sg_len < 1) { |
| 686 | printk(KERN_ERR "%s : scatterlist map failed\n", | 686 | printk(KERN_ERR "%s : scatterlist map failed\n", |
| 687 | sock->dev.bus_id); | 687 | dev_name(&sock->dev)); |
| 688 | tifm_unmap_sg(sock, &host->bounce_buf, 1, | 688 | tifm_unmap_sg(sock, &host->bounce_buf, 1, |
| 689 | r_data->flags & MMC_DATA_WRITE | 689 | r_data->flags & MMC_DATA_WRITE |
| 690 | ? PCI_DMA_TODEVICE | 690 | ? PCI_DMA_TODEVICE |
| @@ -748,7 +748,7 @@ static void tifm_sd_end_cmd(unsigned long data) | |||
| 748 | 748 | ||
| 749 | if (!mrq) { | 749 | if (!mrq) { |
| 750 | printk(KERN_ERR " %s : no request to complete?\n", | 750 | printk(KERN_ERR " %s : no request to complete?\n", |
| 751 | sock->dev.bus_id); | 751 | dev_name(&sock->dev)); |
| 752 | spin_unlock_irqrestore(&sock->lock, flags); | 752 | spin_unlock_irqrestore(&sock->lock, flags); |
| 753 | return; | 753 | return; |
| 754 | } | 754 | } |
| @@ -789,7 +789,7 @@ static void tifm_sd_abort(unsigned long data) | |||
| 789 | printk(KERN_ERR | 789 | printk(KERN_ERR |
| 790 | "%s : card failed to respond for a long period of time " | 790 | "%s : card failed to respond for a long period of time " |
| 791 | "(%x, %x)\n", | 791 | "(%x, %x)\n", |
| 792 | host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags); | 792 | dev_name(&host->dev->dev), host->req->cmd->opcode, host->cmd_flags); |
| 793 | 793 | ||
| 794 | tifm_eject(host->dev); | 794 | tifm_eject(host->dev); |
| 795 | } | 795 | } |
| @@ -906,7 +906,7 @@ static int tifm_sd_initialize_host(struct tifm_sd *host) | |||
| 906 | 906 | ||
| 907 | if (rc) { | 907 | if (rc) { |
| 908 | printk(KERN_ERR "%s : controller failed to reset\n", | 908 | printk(KERN_ERR "%s : controller failed to reset\n", |
| 909 | sock->dev.bus_id); | 909 | dev_name(&sock->dev)); |
| 910 | return -ENODEV; | 910 | return -ENODEV; |
| 911 | } | 911 | } |
| 912 | 912 | ||
| @@ -933,7 +933,7 @@ static int tifm_sd_initialize_host(struct tifm_sd *host) | |||
| 933 | if (rc) { | 933 | if (rc) { |
| 934 | printk(KERN_ERR | 934 | printk(KERN_ERR |
| 935 | "%s : card not ready - probe failed on initialization\n", | 935 | "%s : card not ready - probe failed on initialization\n", |
| 936 | sock->dev.bus_id); | 936 | dev_name(&sock->dev)); |
| 937 | return -ENODEV; | 937 | return -ENODEV; |
| 938 | } | 938 | } |
| 939 | 939 | ||
| @@ -954,7 +954,7 @@ static int tifm_sd_probe(struct tifm_dev *sock) | |||
| 954 | if (!(TIFM_SOCK_STATE_OCCUPIED | 954 | if (!(TIFM_SOCK_STATE_OCCUPIED |
| 955 | & readl(sock->addr + SOCK_PRESENT_STATE))) { | 955 | & readl(sock->addr + SOCK_PRESENT_STATE))) { |
| 956 | printk(KERN_WARNING "%s : card gone, unexpectedly\n", | 956 | printk(KERN_WARNING "%s : card gone, unexpectedly\n", |
| 957 | sock->dev.bus_id); | 957 | dev_name(&sock->dev)); |
| 958 | return rc; | 958 | return rc; |
| 959 | } | 959 | } |
| 960 | 960 | ||
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 3e6f5d8609e8..d74ec46aa032 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
| @@ -406,19 +406,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
| 406 | /* Set the default CFI lock/unlock addresses */ | 406 | /* Set the default CFI lock/unlock addresses */ |
| 407 | cfi->addr_unlock1 = 0x555; | 407 | cfi->addr_unlock1 = 0x555; |
| 408 | cfi->addr_unlock2 = 0x2aa; | 408 | cfi->addr_unlock2 = 0x2aa; |
| 409 | /* Modify the unlock address if we are in compatibility mode */ | ||
| 410 | if ( /* x16 in x8 mode */ | ||
| 411 | ((cfi->device_type == CFI_DEVICETYPE_X8) && | ||
| 412 | (cfi->cfiq->InterfaceDesc == | ||
| 413 | CFI_INTERFACE_X8_BY_X16_ASYNC)) || | ||
| 414 | /* x32 in x16 mode */ | ||
| 415 | ((cfi->device_type == CFI_DEVICETYPE_X16) && | ||
| 416 | (cfi->cfiq->InterfaceDesc == | ||
| 417 | CFI_INTERFACE_X16_BY_X32_ASYNC))) | ||
| 418 | { | ||
| 419 | cfi->addr_unlock1 = 0xaaa; | ||
| 420 | cfi->addr_unlock2 = 0x555; | ||
| 421 | } | ||
| 422 | 409 | ||
| 423 | } /* CFI mode */ | 410 | } /* CFI mode */ |
| 424 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { | 411 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { |
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index f84ab6182148..2f3f2f719ba4 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c | |||
| @@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, | |||
| 1808 | * several first banks can contain 0x7f instead of actual ID | 1808 | * several first banks can contain 0x7f instead of actual ID |
| 1809 | */ | 1809 | */ |
| 1810 | do { | 1810 | do { |
| 1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), | 1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi); |
| 1812 | cfi_interleave(cfi), | ||
| 1813 | cfi->device_type); | ||
| 1814 | mask = (1 << (cfi->device_type * 8)) - 1; | 1812 | mask = (1 << (cfi->device_type * 8)) - 1; |
| 1815 | result = map_read(map, base + ofs); | 1813 | result = map_read(map, base + ofs); |
| 1816 | bank++; | 1814 | bank++; |
| @@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base, | |||
| 1824 | { | 1822 | { |
| 1825 | map_word result; | 1823 | map_word result; |
| 1826 | unsigned long mask; | 1824 | unsigned long mask; |
| 1827 | u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type); | 1825 | u32 ofs = cfi_build_cmd_addr(1, map, cfi); |
| 1828 | mask = (1 << (cfi->device_type * 8)) -1; | 1826 | mask = (1 << (cfi->device_type * 8)) -1; |
| 1829 | result = map_read(map, base + ofs); | 1827 | result = map_read(map, base + ofs); |
| 1830 | return result.x[0] & mask; | 1828 | return result.x[0] & mask; |
| @@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
| 2067 | 2065 | ||
| 2068 | } | 2066 | } |
| 2069 | /* Ensure the unlock addresses we try stay inside the map */ | 2067 | /* Ensure the unlock addresses we try stay inside the map */ |
| 2070 | probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type); | 2068 | probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi); |
| 2071 | probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type); | 2069 | probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi); |
| 2072 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || | 2070 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || |
| 2073 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) | 2071 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) |
| 2074 | goto retry; | 2072 | goto retry; |
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 76a76751da36..6659b2275c0c 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
| @@ -37,9 +37,9 @@ | |||
| 37 | #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ | 37 | #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ |
| 38 | #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ | 38 | #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ |
| 39 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ | 39 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ |
| 40 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ | 40 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ |
| 41 | #define OPCODE_BE_32K 0x52 /* Erase 32KiB block */ | 41 | #define OPCODE_BE_32K 0x52 /* Erase 32KiB block */ |
| 42 | #define OPCODE_BE 0xc7 /* Erase whole flash block */ | 42 | #define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ |
| 43 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ | 43 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ |
| 44 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */ | 44 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */ |
| 45 | 45 | ||
| @@ -167,7 +167,7 @@ static int wait_till_ready(struct m25p *flash) | |||
| 167 | * | 167 | * |
| 168 | * Returns 0 if successful, non-zero otherwise. | 168 | * Returns 0 if successful, non-zero otherwise. |
| 169 | */ | 169 | */ |
| 170 | static int erase_block(struct m25p *flash) | 170 | static int erase_chip(struct m25p *flash) |
| 171 | { | 171 | { |
| 172 | DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n", | 172 | DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n", |
| 173 | flash->spi->dev.bus_id, __func__, | 173 | flash->spi->dev.bus_id, __func__, |
| @@ -181,7 +181,7 @@ static int erase_block(struct m25p *flash) | |||
| 181 | write_enable(flash); | 181 | write_enable(flash); |
| 182 | 182 | ||
| 183 | /* Set up command buffer. */ | 183 | /* Set up command buffer. */ |
| 184 | flash->command[0] = OPCODE_BE; | 184 | flash->command[0] = OPCODE_CHIP_ERASE; |
| 185 | 185 | ||
| 186 | spi_write(flash->spi, flash->command, 1); | 186 | spi_write(flash->spi, flash->command, 1); |
| 187 | 187 | ||
| @@ -250,15 +250,18 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 250 | 250 | ||
| 251 | mutex_lock(&flash->lock); | 251 | mutex_lock(&flash->lock); |
| 252 | 252 | ||
| 253 | /* REVISIT in some cases we could speed up erasing large regions | 253 | /* whole-chip erase? */ |
| 254 | * by using OPCODE_SE instead of OPCODE_BE_4K | 254 | if (len == flash->mtd.size && erase_chip(flash)) { |
| 255 | */ | ||
| 256 | |||
| 257 | /* now erase those sectors */ | ||
| 258 | if (len == flash->mtd.size && erase_block(flash)) { | ||
| 259 | instr->state = MTD_ERASE_FAILED; | 255 | instr->state = MTD_ERASE_FAILED; |
| 260 | mutex_unlock(&flash->lock); | 256 | mutex_unlock(&flash->lock); |
| 261 | return -EIO; | 257 | return -EIO; |
| 258 | |||
| 259 | /* REVISIT in some cases we could speed up erasing large regions | ||
| 260 | * by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up | ||
| 261 | * to use "small sector erase", but that's not always optimal. | ||
| 262 | */ | ||
| 263 | |||
| 264 | /* "sector"-at-a-time erase */ | ||
| 262 | } else { | 265 | } else { |
| 263 | while (len) { | 266 | while (len) { |
| 264 | if (erase_sector(flash, addr)) { | 267 | if (erase_sector(flash, addr)) { |
| @@ -574,10 +577,11 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
| 574 | for (tmp = 0, info = m25p_data; | 577 | for (tmp = 0, info = m25p_data; |
| 575 | tmp < ARRAY_SIZE(m25p_data); | 578 | tmp < ARRAY_SIZE(m25p_data); |
| 576 | tmp++, info++) { | 579 | tmp++, info++) { |
| 577 | if (info->jedec_id == jedec) | 580 | if (info->jedec_id == jedec) { |
| 578 | if (ext_jedec != 0 && info->ext_id != ext_jedec) | 581 | if (info->ext_id != 0 && info->ext_id != ext_jedec) |
| 579 | continue; | 582 | continue; |
| 580 | return info; | 583 | return info; |
| 584 | } | ||
| 581 | } | 585 | } |
| 582 | dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); | 586 | dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); |
| 583 | return NULL; | 587 | return NULL; |
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c index e5059aa3c724..8d92d8db9a98 100644 --- a/drivers/mtd/maps/cdb89712.c +++ b/drivers/mtd/maps/cdb89712.c | |||
| @@ -14,7 +14,18 @@ | |||
| 14 | #include <linux/mtd/map.h> | 14 | #include <linux/mtd/map.h> |
| 15 | #include <linux/mtd/partitions.h> | 15 | #include <linux/mtd/partitions.h> |
| 16 | 16 | ||
| 17 | 17 | /* dynamic ioremap() areas */ | |
| 18 | #define FLASH_START 0x00000000 | ||
| 19 | #define FLASH_SIZE 0x800000 | ||
| 20 | #define FLASH_WIDTH 4 | ||
| 21 | |||
| 22 | #define SRAM_START 0x60000000 | ||
| 23 | #define SRAM_SIZE 0xc000 | ||
| 24 | #define SRAM_WIDTH 4 | ||
| 25 | |||
| 26 | #define BOOTROM_START 0x70000000 | ||
| 27 | #define BOOTROM_SIZE 0x80 | ||
| 28 | #define BOOTROM_WIDTH 4 | ||
| 18 | 29 | ||
| 19 | 30 | ||
| 20 | static struct mtd_info *flash_mtd; | 31 | static struct mtd_info *flash_mtd; |
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 35fef655ccc4..3b959fad1c4e 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c | |||
| @@ -24,8 +24,8 @@ static struct mtd_info *mymtd; | |||
| 24 | static struct map_info h720x_map = { | 24 | static struct map_info h720x_map = { |
| 25 | .name = "H720X", | 25 | .name = "H720X", |
| 26 | .bankwidth = 4, | 26 | .bankwidth = 4, |
| 27 | .size = FLASH_SIZE, | 27 | .size = H720X_FLASH_SIZE, |
| 28 | .phys = FLASH_PHYS, | 28 | .phys = H720X_FLASH_PHYS, |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | static struct mtd_partition h720x_partitions[] = { | 31 | static struct mtd_partition h720x_partitions[] = { |
| @@ -70,7 +70,7 @@ int __init h720x_mtd_init(void) | |||
| 70 | 70 | ||
| 71 | char *part_type = NULL; | 71 | char *part_type = NULL; |
| 72 | 72 | ||
| 73 | h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE); | 73 | h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size); |
| 74 | 74 | ||
| 75 | if (!h720x_map.virt) { | 75 | if (!h720x_map.virt) { |
| 76 | printk(KERN_ERR "H720x-MTD: ioremap failed\n"); | 76 | printk(KERN_ERR "H720x-MTD: ioremap failed\n"); |
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 42d844f8f6bf..dfbf3f270cea 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
| 20 | #include <linux/mtd/physmap.h> | 20 | #include <linux/mtd/physmap.h> |
| 21 | #include <linux/mtd/concat.h> | 21 | #include <linux/mtd/concat.h> |
| 22 | #include <asm/io.h> | 22 | #include <linux/io.h> |
| 23 | 23 | ||
| 24 | #define MAX_RESOURCES 4 | 24 | #define MAX_RESOURCES 4 |
| 25 | 25 | ||
| @@ -27,7 +27,6 @@ struct physmap_flash_info { | |||
| 27 | struct mtd_info *mtd[MAX_RESOURCES]; | 27 | struct mtd_info *mtd[MAX_RESOURCES]; |
| 28 | struct mtd_info *cmtd; | 28 | struct mtd_info *cmtd; |
| 29 | struct map_info map[MAX_RESOURCES]; | 29 | struct map_info map[MAX_RESOURCES]; |
| 30 | struct resource *res; | ||
| 31 | #ifdef CONFIG_MTD_PARTITIONS | 30 | #ifdef CONFIG_MTD_PARTITIONS |
| 32 | int nr_parts; | 31 | int nr_parts; |
| 33 | struct mtd_partition *parts; | 32 | struct mtd_partition *parts; |
| @@ -70,16 +69,7 @@ static int physmap_flash_remove(struct platform_device *dev) | |||
| 70 | #endif | 69 | #endif |
| 71 | map_destroy(info->mtd[i]); | 70 | map_destroy(info->mtd[i]); |
| 72 | } | 71 | } |
| 73 | |||
| 74 | if (info->map[i].virt != NULL) | ||
| 75 | iounmap(info->map[i].virt); | ||
| 76 | } | ||
| 77 | |||
| 78 | if (info->res != NULL) { | ||
| 79 | release_resource(info->res); | ||
| 80 | kfree(info->res); | ||
| 81 | } | 72 | } |
| 82 | |||
| 83 | return 0; | 73 | return 0; |
| 84 | } | 74 | } |
| 85 | 75 | ||
| @@ -101,7 +91,8 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
| 101 | if (physmap_data == NULL) | 91 | if (physmap_data == NULL) |
| 102 | return -ENODEV; | 92 | return -ENODEV; |
| 103 | 93 | ||
| 104 | info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); | 94 | info = devm_kzalloc(&dev->dev, sizeof(struct physmap_flash_info), |
| 95 | GFP_KERNEL); | ||
| 105 | if (info == NULL) { | 96 | if (info == NULL) { |
| 106 | err = -ENOMEM; | 97 | err = -ENOMEM; |
| 107 | goto err_out; | 98 | goto err_out; |
| @@ -114,10 +105,10 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
| 114 | (unsigned long long)(dev->resource[i].end - dev->resource[i].start + 1), | 105 | (unsigned long long)(dev->resource[i].end - dev->resource[i].start + 1), |
| 115 | (unsigned long long)dev->resource[i].start); | 106 | (unsigned long long)dev->resource[i].start); |
| 116 | 107 | ||
| 117 | info->res = request_mem_region(dev->resource[i].start, | 108 | if (!devm_request_mem_region(&dev->dev, |
| 118 | dev->resource[i].end - dev->resource[i].start + 1, | 109 | dev->resource[i].start, |
| 119 | dev->dev.bus_id); | 110 | dev->resource[i].end - dev->resource[i].start + 1, |
| 120 | if (info->res == NULL) { | 111 | dev->dev.bus_id)) { |
| 121 | dev_err(&dev->dev, "Could not reserve memory region\n"); | 112 | dev_err(&dev->dev, "Could not reserve memory region\n"); |
| 122 | err = -ENOMEM; | 113 | err = -ENOMEM; |
| 123 | goto err_out; | 114 | goto err_out; |
| @@ -129,7 +120,8 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
| 129 | info->map[i].bankwidth = physmap_data->width; | 120 | info->map[i].bankwidth = physmap_data->width; |
| 130 | info->map[i].set_vpp = physmap_data->set_vpp; | 121 | info->map[i].set_vpp = physmap_data->set_vpp; |
| 131 | 122 | ||
| 132 | info->map[i].virt = ioremap(info->map[i].phys, info->map[i].size); | 123 | info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys, |
| 124 | info->map[i].size); | ||
| 133 | if (info->map[i].virt == NULL) { | 125 | if (info->map[i].virt == NULL) { |
| 134 | dev_err(&dev->dev, "Failed to ioremap flash region\n"); | 126 | dev_err(&dev->dev, "Failed to ioremap flash region\n"); |
| 135 | err = EIO; | 127 | err = EIO; |
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 024e3fffd4bb..a83192f80eba 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
| @@ -163,9 +163,11 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | |||
| 163 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); | 163 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); |
| 164 | 164 | ||
| 165 | #ifdef CONFIG_MTD_OF_PARTS | 165 | #ifdef CONFIG_MTD_OF_PARTS |
| 166 | if (ret == 0) | 166 | if (ret == 0) { |
| 167 | ret = of_mtd_parse_partitions(fun->dev, &fun->mtd, | 167 | ret = of_mtd_parse_partitions(fun->dev, flash_np, &fun->parts); |
| 168 | flash_np, &fun->parts); | 168 | if (ret < 0) |
| 169 | goto err; | ||
| 170 | } | ||
| 169 | #endif | 171 | #endif |
| 170 | if (ret > 0) | 172 | if (ret > 0) |
| 171 | ret = add_mtd_partitions(&fun->mtd, fun->parts, ret); | 173 | ret = add_mtd_partitions(&fun->mtd, fun->parts, ret); |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 75c899039023..9bd6c9ac8443 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
| @@ -141,6 +141,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev, | |||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | lpcctl = pci_resource_start(pdev, 0); | 143 | lpcctl = pci_resource_start(pdev, 0); |
| 144 | pci_dev_put(pdev); | ||
| 144 | 145 | ||
| 145 | if (!request_region(lpcctl, 4, driver_name)) { | 146 | if (!request_region(lpcctl, 4, driver_name)) { |
| 146 | err = -EBUSY; | 147 | err = -EBUSY; |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index c0fa9c9edf08..15f0a26730ae 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
| @@ -269,6 +269,7 @@ static struct pxa3xx_nand_timing stm2GbX16_timing = { | |||
| 269 | 269 | ||
| 270 | static struct pxa3xx_nand_flash stm2GbX16 = { | 270 | static struct pxa3xx_nand_flash stm2GbX16 = { |
| 271 | .timing = &stm2GbX16_timing, | 271 | .timing = &stm2GbX16_timing, |
| 272 | .cmdset = &largepage_cmdset, | ||
| 272 | .page_per_block = 64, | 273 | .page_per_block = 64, |
| 273 | .page_size = 2048, | 274 | .page_size = 2048, |
| 274 | .flash_width = 16, | 275 | .flash_width = 16, |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 8387e05daae2..a7e4d985f5ef 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
| @@ -32,20 +32,18 @@ | |||
| 32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
| 34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 35 | #include <linux/dma-mapping.h> | ||
| 36 | #include <linux/io.h> | ||
| 35 | 37 | ||
| 36 | #include <asm/io.h> | ||
| 37 | #include <asm/mach/flash.h> | 38 | #include <asm/mach/flash.h> |
| 38 | #include <asm/arch/gpmc.h> | 39 | #include <mach/gpmc.h> |
| 39 | #include <asm/arch/onenand.h> | 40 | #include <mach/onenand.h> |
| 40 | #include <asm/arch/gpio.h> | 41 | #include <mach/gpio.h> |
| 41 | #include <asm/arch/gpmc.h> | 42 | #include <mach/pm.h> |
| 42 | #include <asm/arch/pm.h> | ||
| 43 | 43 | ||
| 44 | #include <linux/dma-mapping.h> | 44 | #include <mach/dma.h> |
| 45 | #include <asm/dma-mapping.h> | ||
| 46 | #include <asm/arch/dma.h> | ||
| 47 | 45 | ||
| 48 | #include <asm/arch/board.h> | 46 | #include <mach/board.h> |
| 49 | 47 | ||
| 50 | #define DRIVER_NAME "omap2-onenand" | 48 | #define DRIVER_NAME "omap2-onenand" |
| 51 | 49 | ||
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index e04bcf1dff87..d8966bae0e0b 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
| @@ -1022,7 +1022,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
| 1022 | } | 1022 | } |
| 1023 | 1023 | ||
| 1024 | /* | 1024 | /* |
| 1025 | * OK, now the LEB is locked and we can safely start moving iy. Since | 1025 | * OK, now the LEB is locked and we can safely start moving it. Since |
| 1026 | * this function utilizes thie @ubi->peb1_buf buffer which is shared | 1026 | * this function utilizes thie @ubi->peb1_buf buffer which is shared |
| 1027 | * with some other functions, so lock the buffer by taking the | 1027 | * with some other functions, so lock the buffer by taking the |
| 1028 | * @ubi->buf_mutex. | 1028 | * @ubi->buf_mutex. |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 4f2daa5bbecf..41d47e1cf15c 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
| @@ -320,7 +320,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | err = ubi_io_read_data(ubi, buf, pnum, 0, len); | 322 | err = ubi_io_read_data(ubi, buf, pnum, 0, len); |
| 323 | if (err && err != UBI_IO_BITFLIPS) | 323 | if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) |
| 324 | goto out_free_buf; | 324 | goto out_free_buf; |
| 325 | 325 | ||
| 326 | data_crc = be32_to_cpu(vid_hdr->data_crc); | 326 | data_crc = be32_to_cpu(vid_hdr->data_crc); |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 05d70937b543..dcb6dac1dc54 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -1396,7 +1396,8 @@ int ubi_thread(void *u) | |||
| 1396 | ubi_msg("%s: %d consecutive failures", | 1396 | ubi_msg("%s: %d consecutive failures", |
| 1397 | ubi->bgt_name, WL_MAX_FAILURES); | 1397 | ubi->bgt_name, WL_MAX_FAILURES); |
| 1398 | ubi_ro_mode(ubi); | 1398 | ubi_ro_mode(ubi); |
| 1399 | break; | 1399 | ubi->thread_enabled = 0; |
| 1400 | continue; | ||
| 1400 | } | 1401 | } |
| 1401 | } else | 1402 | } else |
| 1402 | failures = 0; | 1403 | failures = 0; |
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 3a7bc524af33..c7a4f3bcc2bc 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
| @@ -94,7 +94,7 @@ | |||
| 94 | #include <asm/io.h> | 94 | #include <asm/io.h> |
| 95 | #include <asm/irq.h> | 95 | #include <asm/irq.h> |
| 96 | 96 | ||
| 97 | static char version[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; | 97 | static char version[] __devinitdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; |
| 98 | 98 | ||
| 99 | #ifdef EL3_DEBUG | 99 | #ifdef EL3_DEBUG |
| 100 | static int el3_debug = EL3_DEBUG; | 100 | static int el3_debug = EL3_DEBUG; |
| @@ -186,7 +186,7 @@ static int max_interrupt_work = 10; | |||
| 186 | static int nopnp; | 186 | static int nopnp; |
| 187 | #endif | 187 | #endif |
| 188 | 188 | ||
| 189 | static int __init el3_common_init(struct net_device *dev); | 189 | static int __devinit el3_common_init(struct net_device *dev); |
| 190 | static void el3_common_remove(struct net_device *dev); | 190 | static void el3_common_remove(struct net_device *dev); |
| 191 | static ushort id_read_eeprom(int index); | 191 | static ushort id_read_eeprom(int index); |
| 192 | static ushort read_eeprom(int ioaddr, int index); | 192 | static ushort read_eeprom(int ioaddr, int index); |
| @@ -537,7 +537,7 @@ static struct mca_driver el3_mca_driver = { | |||
| 537 | static int mca_registered; | 537 | static int mca_registered; |
| 538 | #endif /* CONFIG_MCA */ | 538 | #endif /* CONFIG_MCA */ |
| 539 | 539 | ||
| 540 | static int __init el3_common_init(struct net_device *dev) | 540 | static int __devinit el3_common_init(struct net_device *dev) |
| 541 | { | 541 | { |
| 542 | struct el3_private *lp = netdev_priv(dev); | 542 | struct el3_private *lp = netdev_priv(dev); |
| 543 | int err; | 543 | int err; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f749b40f954e..231eeaf1d552 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -1825,9 +1825,10 @@ config FEC2 | |||
| 1825 | 1825 | ||
| 1826 | config FEC_MPC52xx | 1826 | config FEC_MPC52xx |
| 1827 | tristate "MPC52xx FEC driver" | 1827 | tristate "MPC52xx FEC driver" |
| 1828 | depends on PPC_MPC52xx && PPC_BESTCOMM_FEC | 1828 | depends on PPC_MPC52xx && PPC_BESTCOMM |
| 1829 | select CRC32 | 1829 | select CRC32 |
| 1830 | select PHYLIB | 1830 | select PHYLIB |
| 1831 | select PPC_BESTCOMM_FEC | ||
| 1831 | ---help--- | 1832 | ---help--- |
| 1832 | This option enables support for the MPC5200's on-chip | 1833 | This option enables support for the MPC5200's on-chip |
| 1833 | Fast Ethernet Controller | 1834 | Fast Ethernet Controller |
| @@ -2010,9 +2011,13 @@ config IGB_LRO | |||
| 2010 | If in doubt, say N. | 2011 | If in doubt, say N. |
| 2011 | 2012 | ||
| 2012 | config IGB_DCA | 2013 | config IGB_DCA |
| 2013 | bool "Enable DCA" | 2014 | bool "Direct Cache Access (DCA) Support" |
| 2014 | default y | 2015 | default y |
| 2015 | depends on IGB && DCA && !(IGB=y && DCA=m) | 2016 | depends on IGB && DCA && !(IGB=y && DCA=m) |
| 2017 | ---help--- | ||
| 2018 | Say Y here if you want to use Direct Cache Access (DCA) in the | ||
| 2019 | driver. DCA is a method for warming the CPU cache before data | ||
| 2020 | is used, with the intent of lessening the impact of cache misses. | ||
| 2016 | 2021 | ||
| 2017 | source "drivers/net/ixp2000/Kconfig" | 2022 | source "drivers/net/ixp2000/Kconfig" |
| 2018 | 2023 | ||
| @@ -2437,9 +2442,13 @@ config IXGBE | |||
| 2437 | will be called ixgbe. | 2442 | will be called ixgbe. |
| 2438 | 2443 | ||
| 2439 | config IXGBE_DCA | 2444 | config IXGBE_DCA |
| 2440 | bool | 2445 | bool "Direct Cache Access (DCA) Support" |
| 2441 | default y | 2446 | default y |
| 2442 | depends on IXGBE && DCA && !(IXGBE=y && DCA=m) | 2447 | depends on IXGBE && DCA && !(IXGBE=y && DCA=m) |
| 2448 | ---help--- | ||
| 2449 | Say Y here if you want to use Direct Cache Access (DCA) in the | ||
| 2450 | driver. DCA is a method for warming the CPU cache before data | ||
| 2451 | is used, with the intent of lessening the impact of cache misses. | ||
| 2443 | 2452 | ||
| 2444 | config IXGB | 2453 | config IXGB |
| 2445 | tristate "Intel(R) PRO/10GbE support" | 2454 | tristate "Intel(R) PRO/10GbE support" |
| @@ -2489,9 +2498,13 @@ config MYRI10GE | |||
| 2489 | will be called myri10ge. | 2498 | will be called myri10ge. |
| 2490 | 2499 | ||
| 2491 | config MYRI10GE_DCA | 2500 | config MYRI10GE_DCA |
| 2492 | bool | 2501 | bool "Direct Cache Access (DCA) Support" |
| 2493 | default y | 2502 | default y |
| 2494 | depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m) | 2503 | depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m) |
| 2504 | ---help--- | ||
| 2505 | Say Y here if you want to use Direct Cache Access (DCA) in the | ||
| 2506 | driver. DCA is a method for warming the CPU cache before data | ||
| 2507 | is used, with the intent of lessening the impact of cache misses. | ||
| 2495 | 2508 | ||
| 2496 | config NETXEN_NIC | 2509 | config NETXEN_NIC |
| 2497 | tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC" | 2510 | tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC" |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index f19acf8b9220..017383ad5ec6 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
| @@ -114,7 +114,7 @@ obj-$(CONFIG_EL2) += 3c503.o 8390p.o | |||
| 114 | obj-$(CONFIG_NE2000) += ne.o 8390p.o | 114 | obj-$(CONFIG_NE2000) += ne.o 8390p.o |
| 115 | obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o | 115 | obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o |
| 116 | obj-$(CONFIG_HPLAN) += hp.o 8390p.o | 116 | obj-$(CONFIG_HPLAN) += hp.o 8390p.o |
| 117 | obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o | 117 | obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o |
| 118 | obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o | 118 | obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o |
| 119 | obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o | 119 | obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o |
| 120 | obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o | 120 | obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o |
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index ba1be0b3a8c8..07a6697e3635 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c | |||
| @@ -644,10 +644,6 @@ This function frees the transmiter and receiver descriptor rings. | |||
| 644 | */ | 644 | */ |
| 645 | static void amd8111e_free_ring(struct amd8111e_priv* lp) | 645 | static void amd8111e_free_ring(struct amd8111e_priv* lp) |
| 646 | { | 646 | { |
| 647 | |||
| 648 | /* Free transmit and receive skbs */ | ||
| 649 | amd8111e_free_skbs(lp->amd8111e_net_dev); | ||
| 650 | |||
| 651 | /* Free transmit and receive descriptor rings */ | 647 | /* Free transmit and receive descriptor rings */ |
| 652 | if(lp->rx_ring){ | 648 | if(lp->rx_ring){ |
| 653 | pci_free_consistent(lp->pci_dev, | 649 | pci_free_consistent(lp->pci_dev, |
| @@ -1233,7 +1229,9 @@ static int amd8111e_close(struct net_device * dev) | |||
| 1233 | 1229 | ||
| 1234 | amd8111e_disable_interrupt(lp); | 1230 | amd8111e_disable_interrupt(lp); |
| 1235 | amd8111e_stop_chip(lp); | 1231 | amd8111e_stop_chip(lp); |
| 1236 | amd8111e_free_ring(lp); | 1232 | |
| 1233 | /* Free transmit and receive skbs */ | ||
| 1234 | amd8111e_free_skbs(lp->amd8111e_net_dev); | ||
| 1237 | 1235 | ||
| 1238 | netif_carrier_off(lp->amd8111e_net_dev); | 1236 | netif_carrier_off(lp->amd8111e_net_dev); |
| 1239 | 1237 | ||
| @@ -1243,6 +1241,7 @@ static int amd8111e_close(struct net_device * dev) | |||
| 1243 | 1241 | ||
| 1244 | spin_unlock_irq(&lp->lock); | 1242 | spin_unlock_irq(&lp->lock); |
| 1245 | free_irq(dev->irq, dev); | 1243 | free_irq(dev->irq, dev); |
| 1244 | amd8111e_free_ring(lp); | ||
| 1246 | 1245 | ||
| 1247 | /* Update the statistics before closing */ | 1246 | /* Update the statistics before closing */ |
| 1248 | amd8111e_get_stats(dev); | 1247 | amd8111e_get_stats(dev); |
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 0fa53464efb2..6f431a887e7e 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c | |||
| @@ -1080,7 +1080,8 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
| 1080 | init_timer(&lp->check_timer); | 1080 | init_timer(&lp->check_timer); |
| 1081 | lp->check_timer.data = (unsigned long)dev; | 1081 | lp->check_timer.data = (unsigned long)dev; |
| 1082 | lp->check_timer.function = at91ether_check_link; | 1082 | lp->check_timer.function = at91ether_check_link; |
| 1083 | } | 1083 | } else if (lp->board_data.phy_irq_pin >= 32) |
| 1084 | gpio_request(lp->board_data.phy_irq_pin, "ethernet_phy"); | ||
| 1084 | 1085 | ||
| 1085 | /* Display ethernet banner */ | 1086 | /* Display ethernet banner */ |
| 1086 | printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n", | 1087 | printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n", |
| @@ -1167,6 +1168,9 @@ static int __devexit at91ether_remove(struct platform_device *pdev) | |||
| 1167 | struct net_device *dev = platform_get_drvdata(pdev); | 1168 | struct net_device *dev = platform_get_drvdata(pdev); |
| 1168 | struct at91_private *lp = netdev_priv(dev); | 1169 | struct at91_private *lp = netdev_priv(dev); |
| 1169 | 1170 | ||
| 1171 | if (lp->board_data.phy_irq_pin >= 32) | ||
| 1172 | gpio_free(lp->board_data.phy_irq_pin); | ||
| 1173 | |||
| 1170 | unregister_netdev(dev); | 1174 | unregister_netdev(dev); |
| 1171 | free_irq(dev->irq, dev); | 1175 | free_irq(dev->irq, dev); |
| 1172 | dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); | 1176 | dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); |
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index b645fa0f3f64..c49550d507a0 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h | |||
| @@ -46,7 +46,6 @@ | |||
| 46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
| 47 | #include <linux/pagemap.h> | 47 | #include <linux/pagemap.h> |
| 48 | #include <linux/tcp.h> | 48 | #include <linux/tcp.h> |
| 49 | #include <linux/mii.h> | ||
| 50 | #include <linux/ethtool.h> | 49 | #include <linux/ethtool.h> |
| 51 | #include <linux/if_vlan.h> | 50 | #include <linux/if_vlan.h> |
| 52 | #include <linux/workqueue.h> | 51 | #include <linux/workqueue.h> |
diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c index 8cbc1b59bd62..4a7700620119 100644 --- a/drivers/net/atl1e/atl1e_hw.c +++ b/drivers/net/atl1e/atl1e_hw.c | |||
| @@ -163,9 +163,6 @@ int atl1e_read_mac_addr(struct atl1e_hw *hw) | |||
| 163 | * atl1e_hash_mc_addr | 163 | * atl1e_hash_mc_addr |
| 164 | * purpose | 164 | * purpose |
| 165 | * set hash value for a multicast address | 165 | * set hash value for a multicast address |
| 166 | * hash calcu processing : | ||
| 167 | * 1. calcu 32bit CRC for multicast address | ||
| 168 | * 2. reverse crc with MSB to LSB | ||
| 169 | */ | 166 | */ |
| 170 | u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr) | 167 | u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr) |
| 171 | { | 168 | { |
| @@ -174,7 +171,6 @@ u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr) | |||
| 174 | int i; | 171 | int i; |
| 175 | 172 | ||
| 176 | crc32 = ether_crc_le(6, mc_addr); | 173 | crc32 = ether_crc_le(6, mc_addr); |
| 177 | crc32 = ~crc32; | ||
| 178 | for (i = 0; i < 32; i++) | 174 | for (i = 0; i < 32; i++) |
| 179 | value |= (((crc32 >> i) & 1) << (31 - i)); | 175 | value |= (((crc32 >> i) & 1) << (31 - i)); |
| 180 | 176 | ||
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 3cf59a7f5a1c..aef403d299ee 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
| @@ -2310,7 +2310,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count, | |||
| 2310 | if (tpd != ptpd) | 2310 | if (tpd != ptpd) |
| 2311 | memcpy(tpd, ptpd, sizeof(struct tx_packet_desc)); | 2311 | memcpy(tpd, ptpd, sizeof(struct tx_packet_desc)); |
| 2312 | tpd->buffer_addr = cpu_to_le64(buffer_info->dma); | 2312 | tpd->buffer_addr = cpu_to_le64(buffer_info->dma); |
| 2313 | tpd->word2 = (cpu_to_le16(buffer_info->length) & | 2313 | tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT); |
| 2314 | tpd->word2 |= (cpu_to_le16(buffer_info->length) & | ||
| 2314 | TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT; | 2315 | TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT; |
| 2315 | 2316 | ||
| 2316 | /* | 2317 | /* |
| @@ -2409,8 +2410,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
| 2409 | vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | | 2410 | vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | |
| 2410 | ((vlan_tag >> 9) & 0x8); | 2411 | ((vlan_tag >> 9) & 0x8); |
| 2411 | ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT; | 2412 | ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT; |
| 2412 | ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) << | 2413 | ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) << |
| 2413 | TPD_VL_TAGGED_SHIFT; | 2414 | TPD_VLANTAG_SHIFT; |
| 2414 | } | 2415 | } |
| 2415 | 2416 | ||
| 2416 | tso = atl1_tso(adapter, skb, ptpd); | 2417 | tso = atl1_tso(adapter, skb, ptpd); |
| @@ -3403,14 +3404,8 @@ static void atl1_get_wol(struct net_device *netdev, | |||
| 3403 | { | 3404 | { |
| 3404 | struct atl1_adapter *adapter = netdev_priv(netdev); | 3405 | struct atl1_adapter *adapter = netdev_priv(netdev); |
| 3405 | 3406 | ||
| 3406 | wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; | 3407 | wol->supported = WAKE_MAGIC; |
| 3407 | wol->wolopts = 0; | 3408 | wol->wolopts = 0; |
| 3408 | if (adapter->wol & ATLX_WUFC_EX) | ||
| 3409 | wol->wolopts |= WAKE_UCAST; | ||
| 3410 | if (adapter->wol & ATLX_WUFC_MC) | ||
| 3411 | wol->wolopts |= WAKE_MCAST; | ||
| 3412 | if (adapter->wol & ATLX_WUFC_BC) | ||
| 3413 | wol->wolopts |= WAKE_BCAST; | ||
| 3414 | if (adapter->wol & ATLX_WUFC_MAG) | 3409 | if (adapter->wol & ATLX_WUFC_MAG) |
| 3415 | wol->wolopts |= WAKE_MAGIC; | 3410 | wol->wolopts |= WAKE_MAGIC; |
| 3416 | return; | 3411 | return; |
| @@ -3421,15 +3416,10 @@ static int atl1_set_wol(struct net_device *netdev, | |||
| 3421 | { | 3416 | { |
| 3422 | struct atl1_adapter *adapter = netdev_priv(netdev); | 3417 | struct atl1_adapter *adapter = netdev_priv(netdev); |
| 3423 | 3418 | ||
| 3424 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) | 3419 | if (wol->wolopts & (WAKE_PHY | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | |
| 3420 | WAKE_ARP | WAKE_MAGICSECURE)) | ||
| 3425 | return -EOPNOTSUPP; | 3421 | return -EOPNOTSUPP; |
| 3426 | adapter->wol = 0; | 3422 | adapter->wol = 0; |
| 3427 | if (wol->wolopts & WAKE_UCAST) | ||
| 3428 | adapter->wol |= ATLX_WUFC_EX; | ||
| 3429 | if (wol->wolopts & WAKE_MCAST) | ||
| 3430 | adapter->wol |= ATLX_WUFC_MC; | ||
| 3431 | if (wol->wolopts & WAKE_BCAST) | ||
| 3432 | adapter->wol |= ATLX_WUFC_BC; | ||
| 3433 | if (wol->wolopts & WAKE_MAGIC) | 3423 | if (wol->wolopts & WAKE_MAGIC) |
| 3434 | adapter->wol |= ATLX_WUFC_MAG; | 3424 | adapter->wol |= ATLX_WUFC_MAG; |
| 3435 | return 0; | 3425 | return 0; |
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h index a5015b14a429..ffa73fc8d95e 100644 --- a/drivers/net/atlx/atl1.h +++ b/drivers/net/atlx/atl1.h | |||
| @@ -504,7 +504,7 @@ struct rx_free_desc { | |||
| 504 | #define TPD_PKTNT_MASK 0x0001 | 504 | #define TPD_PKTNT_MASK 0x0001 |
| 505 | #define TPD_PKTINT_SHIFT 15 | 505 | #define TPD_PKTINT_SHIFT 15 |
| 506 | #define TPD_VLANTAG_MASK 0xFFFF | 506 | #define TPD_VLANTAG_MASK 0xFFFF |
| 507 | #define TPD_VLAN_SHIFT 16 | 507 | #define TPD_VLANTAG_SHIFT 16 |
| 508 | 508 | ||
| 509 | /* tpd word 3 bits 0:13 */ | 509 | /* tpd word 3 bits 0:13 */ |
| 510 | #define TPD_EOP_MASK 0x0001 | 510 | #define TPD_EOP_MASK 0x0001 |
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index f5bdc92c1a65..8571e8c0bc67 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c | |||
| @@ -1690,9 +1690,11 @@ static int atl2_resume(struct pci_dev *pdev) | |||
| 1690 | 1690 | ||
| 1691 | ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); | 1691 | ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); |
| 1692 | 1692 | ||
| 1693 | err = atl2_request_irq(adapter); | 1693 | if (netif_running(netdev)) { |
| 1694 | if (netif_running(netdev) && err) | 1694 | err = atl2_request_irq(adapter); |
| 1695 | return err; | 1695 | if (err) |
| 1696 | return err; | ||
| 1697 | } | ||
| 1696 | 1698 | ||
| 1697 | atl2_reset_hw(&adapter->hw); | 1699 | atl2_reset_hw(&adapter->hw); |
| 1698 | 1700 | ||
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 430d430bce29..a1a3d0e5d2b4 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -3144,6 +3144,28 @@ bnx2_has_work(struct bnx2_napi *bnapi) | |||
| 3144 | return 0; | 3144 | return 0; |
| 3145 | } | 3145 | } |
| 3146 | 3146 | ||
| 3147 | static void | ||
| 3148 | bnx2_chk_missed_msi(struct bnx2 *bp) | ||
| 3149 | { | ||
| 3150 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; | ||
| 3151 | u32 msi_ctrl; | ||
| 3152 | |||
| 3153 | if (bnx2_has_work(bnapi)) { | ||
| 3154 | msi_ctrl = REG_RD(bp, BNX2_PCICFG_MSI_CONTROL); | ||
| 3155 | if (!(msi_ctrl & BNX2_PCICFG_MSI_CONTROL_ENABLE)) | ||
| 3156 | return; | ||
| 3157 | |||
| 3158 | if (bnapi->last_status_idx == bp->idle_chk_status_idx) { | ||
| 3159 | REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl & | ||
| 3160 | ~BNX2_PCICFG_MSI_CONTROL_ENABLE); | ||
| 3161 | REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl); | ||
| 3162 | bnx2_msi(bp->irq_tbl[0].vector, bnapi); | ||
| 3163 | } | ||
| 3164 | } | ||
| 3165 | |||
| 3166 | bp->idle_chk_status_idx = bnapi->last_status_idx; | ||
| 3167 | } | ||
| 3168 | |||
| 3147 | static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi) | 3169 | static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi) |
| 3148 | { | 3170 | { |
| 3149 | struct status_block *sblk = bnapi->status_blk.msi; | 3171 | struct status_block *sblk = bnapi->status_blk.msi; |
| @@ -3218,14 +3240,15 @@ static int bnx2_poll(struct napi_struct *napi, int budget) | |||
| 3218 | 3240 | ||
| 3219 | work_done = bnx2_poll_work(bp, bnapi, work_done, budget); | 3241 | work_done = bnx2_poll_work(bp, bnapi, work_done, budget); |
| 3220 | 3242 | ||
| 3221 | if (unlikely(work_done >= budget)) | ||
| 3222 | break; | ||
| 3223 | |||
| 3224 | /* bnapi->last_status_idx is used below to tell the hw how | 3243 | /* bnapi->last_status_idx is used below to tell the hw how |
| 3225 | * much work has been processed, so we must read it before | 3244 | * much work has been processed, so we must read it before |
| 3226 | * checking for more work. | 3245 | * checking for more work. |
| 3227 | */ | 3246 | */ |
| 3228 | bnapi->last_status_idx = sblk->status_idx; | 3247 | bnapi->last_status_idx = sblk->status_idx; |
| 3248 | |||
| 3249 | if (unlikely(work_done >= budget)) | ||
| 3250 | break; | ||
| 3251 | |||
| 3229 | rmb(); | 3252 | rmb(); |
| 3230 | if (likely(!bnx2_has_work(bnapi))) { | 3253 | if (likely(!bnx2_has_work(bnapi))) { |
| 3231 | netif_rx_complete(bp->dev, napi); | 3254 | netif_rx_complete(bp->dev, napi); |
| @@ -4570,6 +4593,8 @@ bnx2_init_chip(struct bnx2 *bp) | |||
| 4570 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) | 4593 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) |
| 4571 | bp->bnx2_napi[i].last_status_idx = 0; | 4594 | bp->bnx2_napi[i].last_status_idx = 0; |
| 4572 | 4595 | ||
| 4596 | bp->idle_chk_status_idx = 0xffff; | ||
| 4597 | |||
| 4573 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; | 4598 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; |
| 4574 | 4599 | ||
| 4575 | /* Set up how to generate a link change interrupt. */ | 4600 | /* Set up how to generate a link change interrupt. */ |
| @@ -5718,6 +5743,10 @@ bnx2_timer(unsigned long data) | |||
| 5718 | if (atomic_read(&bp->intr_sem) != 0) | 5743 | if (atomic_read(&bp->intr_sem) != 0) |
| 5719 | goto bnx2_restart_timer; | 5744 | goto bnx2_restart_timer; |
| 5720 | 5745 | ||
| 5746 | if ((bp->flags & (BNX2_FLAG_USING_MSI | BNX2_FLAG_ONE_SHOT_MSI)) == | ||
| 5747 | BNX2_FLAG_USING_MSI) | ||
| 5748 | bnx2_chk_missed_msi(bp); | ||
| 5749 | |||
| 5721 | bnx2_send_heart_beat(bp); | 5750 | bnx2_send_heart_beat(bp); |
| 5722 | 5751 | ||
| 5723 | bp->stats_blk->stat_FwRxDrop = | 5752 | bp->stats_blk->stat_FwRxDrop = |
| @@ -7204,10 +7233,13 @@ static void | |||
| 7204 | poll_bnx2(struct net_device *dev) | 7233 | poll_bnx2(struct net_device *dev) |
| 7205 | { | 7234 | { |
| 7206 | struct bnx2 *bp = netdev_priv(dev); | 7235 | struct bnx2 *bp = netdev_priv(dev); |
| 7236 | int i; | ||
| 7207 | 7237 | ||
| 7208 | disable_irq(bp->pdev->irq); | 7238 | for (i = 0; i < bp->irq_nvecs; i++) { |
| 7209 | bnx2_interrupt(bp->pdev->irq, dev); | 7239 | disable_irq(bp->irq_tbl[i].vector); |
| 7210 | enable_irq(bp->pdev->irq); | 7240 | bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]); |
| 7241 | enable_irq(bp->irq_tbl[i].vector); | ||
| 7242 | } | ||
| 7211 | } | 7243 | } |
| 7212 | #endif | 7244 | #endif |
| 7213 | 7245 | ||
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 617d95340160..0b032c3c7b61 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
| @@ -378,6 +378,9 @@ struct l2_fhdr { | |||
| 378 | * pci_config_l definition | 378 | * pci_config_l definition |
| 379 | * offset: 0000 | 379 | * offset: 0000 |
| 380 | */ | 380 | */ |
| 381 | #define BNX2_PCICFG_MSI_CONTROL 0x00000058 | ||
| 382 | #define BNX2_PCICFG_MSI_CONTROL_ENABLE (1L<<16) | ||
| 383 | |||
| 381 | #define BNX2_PCICFG_MISC_CONFIG 0x00000068 | 384 | #define BNX2_PCICFG_MISC_CONFIG 0x00000068 |
| 382 | #define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2) | 385 | #define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2) |
| 383 | #define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3) | 386 | #define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3) |
| @@ -6863,6 +6866,9 @@ struct bnx2 { | |||
| 6863 | 6866 | ||
| 6864 | u8 num_tx_rings; | 6867 | u8 num_tx_rings; |
| 6865 | u8 num_rx_rings; | 6868 | u8 num_rx_rings; |
| 6869 | |||
| 6870 | u32 idle_chk_status_idx; | ||
| 6871 | |||
| 6866 | }; | 6872 | }; |
| 6867 | 6873 | ||
| 6868 | #define REG_RD(bp, offset) \ | 6874 | #define REG_RD(bp, offset) \ |
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index 130927cfc75b..a6c0b3abba29 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h | |||
| @@ -564,14 +564,15 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { | |||
| 564 | 564 | ||
| 565 | static void bnx2x_init_pxp(struct bnx2x *bp) | 565 | static void bnx2x_init_pxp(struct bnx2x *bp) |
| 566 | { | 566 | { |
| 567 | u16 devctl; | ||
| 567 | int r_order, w_order; | 568 | int r_order, w_order; |
| 568 | u32 val, i; | 569 | u32 val, i; |
| 569 | 570 | ||
| 570 | pci_read_config_word(bp->pdev, | 571 | pci_read_config_word(bp->pdev, |
| 571 | bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val); | 572 | bp->pcie_cap + PCI_EXP_DEVCTL, &devctl); |
| 572 | DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val); | 573 | DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); |
| 573 | w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5); | 574 | w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); |
| 574 | r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12); | 575 | r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12); |
| 575 | 576 | ||
| 576 | if (r_order > MAX_RD_ORD) { | 577 | if (r_order > MAX_RD_ORD) { |
| 577 | DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", | 578 | DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", |
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index fce745148ff9..600210d7eff9 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
| @@ -59,8 +59,8 @@ | |||
| 59 | #include "bnx2x.h" | 59 | #include "bnx2x.h" |
| 60 | #include "bnx2x_init.h" | 60 | #include "bnx2x_init.h" |
| 61 | 61 | ||
| 62 | #define DRV_MODULE_VERSION "1.45.22" | 62 | #define DRV_MODULE_VERSION "1.45.23" |
| 63 | #define DRV_MODULE_RELDATE "2008/09/09" | 63 | #define DRV_MODULE_RELDATE "2008/11/03" |
| 64 | #define BNX2X_BC_VER 0x040200 | 64 | #define BNX2X_BC_VER 0x040200 |
| 65 | 65 | ||
| 66 | /* Time in jiffies before concluding the transmitter is hung */ | 66 | /* Time in jiffies before concluding the transmitter is hung */ |
| @@ -6481,6 +6481,7 @@ load_int_disable: | |||
| 6481 | bnx2x_free_irq(bp); | 6481 | bnx2x_free_irq(bp); |
| 6482 | load_error: | 6482 | load_error: |
| 6483 | bnx2x_free_mem(bp); | 6483 | bnx2x_free_mem(bp); |
| 6484 | bp->port.pmf = 0; | ||
| 6484 | 6485 | ||
| 6485 | /* TBD we really need to reset the chip | 6486 | /* TBD we really need to reset the chip |
| 6486 | if we want to recover from this */ | 6487 | if we want to recover from this */ |
| @@ -6791,6 +6792,7 @@ unload_error: | |||
| 6791 | /* Report UNLOAD_DONE to MCP */ | 6792 | /* Report UNLOAD_DONE to MCP */ |
| 6792 | if (!BP_NOMCP(bp)) | 6793 | if (!BP_NOMCP(bp)) |
| 6793 | bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); | 6794 | bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); |
| 6795 | bp->port.pmf = 0; | ||
| 6794 | 6796 | ||
| 6795 | /* Free SKBs, SGEs, TPA pool and driver internals */ | 6797 | /* Free SKBs, SGEs, TPA pool and driver internals */ |
| 6796 | bnx2x_free_skbs(bp); | 6798 | bnx2x_free_skbs(bp); |
| @@ -10204,8 +10206,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
| 10204 | return -ENOMEM; | 10206 | return -ENOMEM; |
| 10205 | } | 10207 | } |
| 10206 | 10208 | ||
| 10207 | netif_carrier_off(dev); | ||
| 10208 | |||
| 10209 | bp = netdev_priv(dev); | 10209 | bp = netdev_priv(dev); |
| 10210 | bp->msglevel = debug; | 10210 | bp->msglevel = debug; |
| 10211 | 10211 | ||
| @@ -10229,6 +10229,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
| 10229 | goto init_one_exit; | 10229 | goto init_one_exit; |
| 10230 | } | 10230 | } |
| 10231 | 10231 | ||
| 10232 | netif_carrier_off(dev); | ||
| 10233 | |||
| 10232 | bp->common.name = board_info[ent->driver_data].name; | 10234 | bp->common.name = board_info[ent->driver_data].name; |
| 10233 | printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx," | 10235 | printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx," |
| 10234 | " IRQ %d, ", dev->name, bp->common.name, | 10236 | " IRQ %d, ", dev->name, bp->common.name, |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index ade5f3f6693b..87437c788476 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
| @@ -169,11 +169,14 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_ | |||
| 169 | /* clear slave from tx_hashtbl */ | 169 | /* clear slave from tx_hashtbl */ |
| 170 | tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; | 170 | tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; |
| 171 | 171 | ||
| 172 | index = SLAVE_TLB_INFO(slave).head; | 172 | /* skip this if we've already freed the tx hash table */ |
| 173 | while (index != TLB_NULL_INDEX) { | 173 | if (tx_hash_table) { |
| 174 | u32 next_index = tx_hash_table[index].next; | 174 | index = SLAVE_TLB_INFO(slave).head; |
| 175 | tlb_init_table_entry(&tx_hash_table[index], save_load); | 175 | while (index != TLB_NULL_INDEX) { |
| 176 | index = next_index; | 176 | u32 next_index = tx_hash_table[index].next; |
| 177 | tlb_init_table_entry(&tx_hash_table[index], save_load); | ||
| 178 | index = next_index; | ||
| 179 | } | ||
| 177 | } | 180 | } |
| 178 | 181 | ||
| 179 | tlb_init_slave(slave); | 182 | tlb_init_slave(slave); |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 832739f38db4..a3efba59eee9 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1979,6 +1979,20 @@ void bond_destroy(struct bonding *bond) | |||
| 1979 | unregister_netdevice(bond->dev); | 1979 | unregister_netdevice(bond->dev); |
| 1980 | } | 1980 | } |
| 1981 | 1981 | ||
| 1982 | static void bond_destructor(struct net_device *bond_dev) | ||
| 1983 | { | ||
| 1984 | struct bonding *bond = bond_dev->priv; | ||
| 1985 | |||
| 1986 | if (bond->wq) | ||
| 1987 | destroy_workqueue(bond->wq); | ||
| 1988 | |||
| 1989 | netif_addr_lock_bh(bond_dev); | ||
| 1990 | bond_mc_list_destroy(bond); | ||
| 1991 | netif_addr_unlock_bh(bond_dev); | ||
| 1992 | |||
| 1993 | free_netdev(bond_dev); | ||
| 1994 | } | ||
| 1995 | |||
| 1982 | /* | 1996 | /* |
| 1983 | * First release a slave and than destroy the bond if no more slaves iare left. | 1997 | * First release a slave and than destroy the bond if no more slaves iare left. |
| 1984 | * Must be under rtnl_lock when this function is called. | 1998 | * Must be under rtnl_lock when this function is called. |
| @@ -2376,6 +2390,9 @@ static void bond_miimon_commit(struct bonding *bond) | |||
| 2376 | continue; | 2390 | continue; |
| 2377 | 2391 | ||
| 2378 | case BOND_LINK_DOWN: | 2392 | case BOND_LINK_DOWN: |
| 2393 | if (slave->link_failure_count < UINT_MAX) | ||
| 2394 | slave->link_failure_count++; | ||
| 2395 | |||
| 2379 | slave->link = BOND_LINK_DOWN; | 2396 | slave->link = BOND_LINK_DOWN; |
| 2380 | 2397 | ||
| 2381 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || | 2398 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || |
| @@ -4550,7 +4567,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
| 4550 | 4567 | ||
| 4551 | bond_set_mode_ops(bond, bond->params.mode); | 4568 | bond_set_mode_ops(bond, bond->params.mode); |
| 4552 | 4569 | ||
| 4553 | bond_dev->destructor = free_netdev; | 4570 | bond_dev->destructor = bond_destructor; |
| 4554 | 4571 | ||
| 4555 | /* Initialize the device options */ | 4572 | /* Initialize the device options */ |
| 4556 | bond_dev->tx_queue_len = 0; | 4573 | bond_dev->tx_queue_len = 0; |
| @@ -4589,20 +4606,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
| 4589 | return 0; | 4606 | return 0; |
| 4590 | } | 4607 | } |
| 4591 | 4608 | ||
| 4592 | /* De-initialize device specific data. | ||
| 4593 | * Caller must hold rtnl_lock. | ||
| 4594 | */ | ||
| 4595 | static void bond_deinit(struct net_device *bond_dev) | ||
| 4596 | { | ||
| 4597 | struct bonding *bond = bond_dev->priv; | ||
| 4598 | |||
| 4599 | list_del(&bond->bond_list); | ||
| 4600 | |||
| 4601 | #ifdef CONFIG_PROC_FS | ||
| 4602 | bond_remove_proc_entry(bond); | ||
| 4603 | #endif | ||
| 4604 | } | ||
| 4605 | |||
| 4606 | static void bond_work_cancel_all(struct bonding *bond) | 4609 | static void bond_work_cancel_all(struct bonding *bond) |
| 4607 | { | 4610 | { |
| 4608 | write_lock_bh(&bond->lock); | 4611 | write_lock_bh(&bond->lock); |
| @@ -4624,6 +4627,22 @@ static void bond_work_cancel_all(struct bonding *bond) | |||
| 4624 | cancel_delayed_work(&bond->ad_work); | 4627 | cancel_delayed_work(&bond->ad_work); |
| 4625 | } | 4628 | } |
| 4626 | 4629 | ||
| 4630 | /* De-initialize device specific data. | ||
| 4631 | * Caller must hold rtnl_lock. | ||
| 4632 | */ | ||
| 4633 | static void bond_deinit(struct net_device *bond_dev) | ||
| 4634 | { | ||
| 4635 | struct bonding *bond = bond_dev->priv; | ||
| 4636 | |||
| 4637 | list_del(&bond->bond_list); | ||
| 4638 | |||
| 4639 | bond_work_cancel_all(bond); | ||
| 4640 | |||
| 4641 | #ifdef CONFIG_PROC_FS | ||
| 4642 | bond_remove_proc_entry(bond); | ||
| 4643 | #endif | ||
| 4644 | } | ||
| 4645 | |||
| 4627 | /* Unregister and free all bond devices. | 4646 | /* Unregister and free all bond devices. |
| 4628 | * Caller must hold rtnl_lock. | 4647 | * Caller must hold rtnl_lock. |
| 4629 | */ | 4648 | */ |
| @@ -4635,9 +4654,6 @@ static void bond_free_all(void) | |||
| 4635 | struct net_device *bond_dev = bond->dev; | 4654 | struct net_device *bond_dev = bond->dev; |
| 4636 | 4655 | ||
| 4637 | bond_work_cancel_all(bond); | 4656 | bond_work_cancel_all(bond); |
| 4638 | netif_addr_lock_bh(bond_dev); | ||
| 4639 | bond_mc_list_destroy(bond); | ||
| 4640 | netif_addr_unlock_bh(bond_dev); | ||
| 4641 | /* Release the bonded slaves */ | 4657 | /* Release the bonded slaves */ |
| 4642 | bond_release_all(bond_dev); | 4658 | bond_release_all(bond_dev); |
| 4643 | bond_destroy(bond); | 4659 | bond_destroy(bond); |
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index d6c7d2aa761b..7092df50ff78 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c | |||
| @@ -1035,10 +1035,6 @@ MODULE_PARM_DESC(copybreak, "Receive copy threshold"); | |||
| 1035 | * @pdev: the PCI device that received the packet | 1035 | * @pdev: the PCI device that received the packet |
| 1036 | * @fl: the SGE free list holding the packet | 1036 | * @fl: the SGE free list holding the packet |
| 1037 | * @len: the actual packet length, excluding any SGE padding | 1037 | * @len: the actual packet length, excluding any SGE padding |
| 1038 | * @dma_pad: padding at beginning of buffer left by SGE DMA | ||
| 1039 | * @skb_pad: padding to be used if the packet is copied | ||
| 1040 | * @copy_thres: length threshold under which a packet should be copied | ||
| 1041 | * @drop_thres: # of remaining buffers before we start dropping packets | ||
| 1042 | * | 1038 | * |
| 1043 | * Get the next packet from a free list and complete setup of the | 1039 | * Get the next packet from a free list and complete setup of the |
| 1044 | * sk_buff. If the packet is small we make a copy and recycle the | 1040 | * sk_buff. If the packet is small we make a copy and recycle the |
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 65d0a9103297..7e8a63106bdf 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c | |||
| @@ -32,14 +32,14 @@ | |||
| 32 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
| 33 | #include <linux/ethtool.h> | 33 | #include <linux/ethtool.h> |
| 34 | 34 | ||
| 35 | #include <asm/arch/svinto.h>/* DMA and register descriptions */ | 35 | #include <arch/svinto.h>/* DMA and register descriptions */ |
| 36 | #include <asm/io.h> /* CRIS_LED_* I/O functions */ | 36 | #include <asm/io.h> /* CRIS_LED_* I/O functions */ |
| 37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
| 38 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
| 39 | #include <asm/system.h> | 39 | #include <asm/system.h> |
| 40 | #include <asm/ethernet.h> | 40 | #include <asm/ethernet.h> |
| 41 | #include <asm/cache.h> | 41 | #include <asm/cache.h> |
| 42 | #include <asm/arch/io_interface_mux.h> | 42 | #include <arch/io_interface_mux.h> |
| 43 | 43 | ||
| 44 | //#define ETHDEBUG | 44 | //#define ETHDEBUG |
| 45 | #define D(x) | 45 | #define D(x) |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 1ace41a13ac3..2c341f83d327 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
| @@ -1307,8 +1307,10 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
| 1307 | u32 fw_vers = 0; | 1307 | u32 fw_vers = 0; |
| 1308 | u32 tp_vers = 0; | 1308 | u32 tp_vers = 0; |
| 1309 | 1309 | ||
| 1310 | spin_lock(&adapter->stats_lock); | ||
| 1310 | t3_get_fw_version(adapter, &fw_vers); | 1311 | t3_get_fw_version(adapter, &fw_vers); |
| 1311 | t3_get_tp_version(adapter, &tp_vers); | 1312 | t3_get_tp_version(adapter, &tp_vers); |
| 1313 | spin_unlock(&adapter->stats_lock); | ||
| 1312 | 1314 | ||
| 1313 | strcpy(info->driver, DRV_NAME); | 1315 | strcpy(info->driver, DRV_NAME); |
| 1314 | strcpy(info->version, DRV_VERSION); | 1316 | strcpy(info->version, DRV_VERSION); |
| @@ -2699,7 +2701,7 @@ static void set_nqsets(struct adapter *adap) | |||
| 2699 | int hwports = adap->params.nports; | 2701 | int hwports = adap->params.nports; |
| 2700 | int nqsets = SGE_QSETS; | 2702 | int nqsets = SGE_QSETS; |
| 2701 | 2703 | ||
| 2702 | if (adap->params.rev > 0) { | 2704 | if (adap->params.rev > 0 && adap->flags & USING_MSIX) { |
| 2703 | if (hwports == 2 && | 2705 | if (hwports == 2 && |
| 2704 | (hwports * nqsets > SGE_QSETS || | 2706 | (hwports * nqsets > SGE_QSETS || |
| 2705 | num_cpus >= nqsets / hwports)) | 2707 | num_cpus >= nqsets / hwports)) |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 968f64be3743..9a0898b0dbce 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
| @@ -572,7 +572,7 @@ struct t3_vpd { | |||
| 572 | u32 pad; /* for multiple-of-4 sizing and alignment */ | 572 | u32 pad; /* for multiple-of-4 sizing and alignment */ |
| 573 | }; | 573 | }; |
| 574 | 574 | ||
| 575 | #define EEPROM_MAX_POLL 4 | 575 | #define EEPROM_MAX_POLL 40 |
| 576 | #define EEPROM_STAT_ADDR 0x4000 | 576 | #define EEPROM_STAT_ADDR 0x4000 |
| 577 | #define VPD_BASE 0xc00 | 577 | #define VPD_BASE 0xc00 |
| 578 | 578 | ||
| @@ -3690,6 +3690,12 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
| 3690 | ; | 3690 | ; |
| 3691 | 3691 | ||
| 3692 | pti = &port_types[adapter->params.vpd.port_type[j]]; | 3692 | pti = &port_types[adapter->params.vpd.port_type[j]]; |
| 3693 | if (!pti->phy_prep) { | ||
| 3694 | CH_ALERT(adapter, "Invalid port type index %d\n", | ||
| 3695 | adapter->params.vpd.port_type[j]); | ||
| 3696 | return -EINVAL; | ||
| 3697 | } | ||
| 3698 | |||
| 3693 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, | 3699 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, |
| 3694 | ai->mdio_ops); | 3700 | ai->mdio_ops); |
| 3695 | if (ret) | 3701 | if (ret) |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3d69fae781cf..e8bfcce6b319 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -166,7 +166,7 @@ | |||
| 166 | 166 | ||
| 167 | #define DRV_NAME "e100" | 167 | #define DRV_NAME "e100" |
| 168 | #define DRV_EXT "-NAPI" | 168 | #define DRV_EXT "-NAPI" |
| 169 | #define DRV_VERSION "3.5.23-k4"DRV_EXT | 169 | #define DRV_VERSION "3.5.23-k6"DRV_EXT |
| 170 | #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" | 170 | #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" |
| 171 | #define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" | 171 | #define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" |
| 172 | #define PFX DRV_NAME ": " | 172 | #define PFX DRV_NAME ": " |
| @@ -1804,7 +1804,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) | |||
| 1804 | struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; | 1804 | struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; |
| 1805 | put_unaligned_le32(rx->dma_addr, &prev_rfd->link); | 1805 | put_unaligned_le32(rx->dma_addr, &prev_rfd->link); |
| 1806 | pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, | 1806 | pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, |
| 1807 | sizeof(struct rfd), PCI_DMA_TODEVICE); | 1807 | sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL); |
| 1808 | } | 1808 | } |
| 1809 | 1809 | ||
| 1810 | return 0; | 1810 | return 0; |
| @@ -1823,7 +1823,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
| 1823 | 1823 | ||
| 1824 | /* Need to sync before taking a peek at cb_complete bit */ | 1824 | /* Need to sync before taking a peek at cb_complete bit */ |
| 1825 | pci_dma_sync_single_for_cpu(nic->pdev, rx->dma_addr, | 1825 | pci_dma_sync_single_for_cpu(nic->pdev, rx->dma_addr, |
| 1826 | sizeof(struct rfd), PCI_DMA_FROMDEVICE); | 1826 | sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL); |
| 1827 | rfd_status = le16_to_cpu(rfd->status); | 1827 | rfd_status = le16_to_cpu(rfd->status); |
| 1828 | 1828 | ||
| 1829 | DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status); | 1829 | DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status); |
| @@ -1850,7 +1850,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
| 1850 | 1850 | ||
| 1851 | /* Get data */ | 1851 | /* Get data */ |
| 1852 | pci_unmap_single(nic->pdev, rx->dma_addr, | 1852 | pci_unmap_single(nic->pdev, rx->dma_addr, |
| 1853 | RFD_BUF_LEN, PCI_DMA_FROMDEVICE); | 1853 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); |
| 1854 | 1854 | ||
| 1855 | /* If this buffer has the el bit, but we think the receiver | 1855 | /* If this buffer has the el bit, but we think the receiver |
| 1856 | * is still running, check to see if it really stopped while | 1856 | * is still running, check to see if it really stopped while |
| @@ -1943,7 +1943,7 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, | |||
| 1943 | new_before_last_rfd->command |= cpu_to_le16(cb_el); | 1943 | new_before_last_rfd->command |= cpu_to_le16(cb_el); |
| 1944 | pci_dma_sync_single_for_device(nic->pdev, | 1944 | pci_dma_sync_single_for_device(nic->pdev, |
| 1945 | new_before_last_rx->dma_addr, sizeof(struct rfd), | 1945 | new_before_last_rx->dma_addr, sizeof(struct rfd), |
| 1946 | PCI_DMA_TODEVICE); | 1946 | PCI_DMA_BIDIRECTIONAL); |
| 1947 | 1947 | ||
| 1948 | /* Now that we have a new stopping point, we can clear the old | 1948 | /* Now that we have a new stopping point, we can clear the old |
| 1949 | * stopping point. We must sync twice to get the proper | 1949 | * stopping point. We must sync twice to get the proper |
| @@ -1951,11 +1951,11 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, | |||
| 1951 | old_before_last_rfd->command &= ~cpu_to_le16(cb_el); | 1951 | old_before_last_rfd->command &= ~cpu_to_le16(cb_el); |
| 1952 | pci_dma_sync_single_for_device(nic->pdev, | 1952 | pci_dma_sync_single_for_device(nic->pdev, |
| 1953 | old_before_last_rx->dma_addr, sizeof(struct rfd), | 1953 | old_before_last_rx->dma_addr, sizeof(struct rfd), |
| 1954 | PCI_DMA_TODEVICE); | 1954 | PCI_DMA_BIDIRECTIONAL); |
| 1955 | old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN); | 1955 | old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN); |
| 1956 | pci_dma_sync_single_for_device(nic->pdev, | 1956 | pci_dma_sync_single_for_device(nic->pdev, |
| 1957 | old_before_last_rx->dma_addr, sizeof(struct rfd), | 1957 | old_before_last_rx->dma_addr, sizeof(struct rfd), |
| 1958 | PCI_DMA_TODEVICE); | 1958 | PCI_DMA_BIDIRECTIONAL); |
| 1959 | } | 1959 | } |
| 1960 | 1960 | ||
| 1961 | if(restart_required) { | 1961 | if(restart_required) { |
| @@ -1978,7 +1978,7 @@ static void e100_rx_clean_list(struct nic *nic) | |||
| 1978 | for(rx = nic->rxs, i = 0; i < count; rx++, i++) { | 1978 | for(rx = nic->rxs, i = 0; i < count; rx++, i++) { |
| 1979 | if(rx->skb) { | 1979 | if(rx->skb) { |
| 1980 | pci_unmap_single(nic->pdev, rx->dma_addr, | 1980 | pci_unmap_single(nic->pdev, rx->dma_addr, |
| 1981 | RFD_BUF_LEN, PCI_DMA_FROMDEVICE); | 1981 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); |
| 1982 | dev_kfree_skb(rx->skb); | 1982 | dev_kfree_skb(rx->skb); |
| 1983 | } | 1983 | } |
| 1984 | } | 1984 | } |
| @@ -2021,7 +2021,7 @@ static int e100_rx_alloc_list(struct nic *nic) | |||
| 2021 | before_last->command |= cpu_to_le16(cb_el); | 2021 | before_last->command |= cpu_to_le16(cb_el); |
| 2022 | before_last->size = 0; | 2022 | before_last->size = 0; |
| 2023 | pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, | 2023 | pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, |
| 2024 | sizeof(struct rfd), PCI_DMA_TODEVICE); | 2024 | sizeof(struct rfd), PCI_DMA_BIDIRECTIONAL); |
| 2025 | 2025 | ||
| 2026 | nic->rx_to_use = nic->rx_to_clean = nic->rxs; | 2026 | nic->rx_to_use = nic->rx_to_clean = nic->rxs; |
| 2027 | nic->ru_running = RU_SUSPENDED; | 2027 | nic->ru_running = RU_SUSPENDED; |
| @@ -2222,7 +2222,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) | |||
| 2222 | msleep(10); | 2222 | msleep(10); |
| 2223 | 2223 | ||
| 2224 | pci_dma_sync_single_for_cpu(nic->pdev, nic->rx_to_clean->dma_addr, | 2224 | pci_dma_sync_single_for_cpu(nic->pdev, nic->rx_to_clean->dma_addr, |
| 2225 | RFD_BUF_LEN, PCI_DMA_FROMDEVICE); | 2225 | RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); |
| 2226 | 2226 | ||
| 2227 | if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), | 2227 | if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), |
| 2228 | skb->data, ETH_DATA_LEN)) | 2228 | skb->data, ETH_DATA_LEN)) |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 6a3893acfe04..c854c96f5ab3 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
| @@ -1774,7 +1774,8 @@ static void e1000_get_wol(struct net_device *netdev, | |||
| 1774 | 1774 | ||
| 1775 | /* this function will set ->supported = 0 and return 1 if wol is not | 1775 | /* this function will set ->supported = 0 and return 1 if wol is not |
| 1776 | * supported by this hardware */ | 1776 | * supported by this hardware */ |
| 1777 | if (e1000_wol_exclusion(adapter, wol)) | 1777 | if (e1000_wol_exclusion(adapter, wol) || |
| 1778 | !device_can_wakeup(&adapter->pdev->dev)) | ||
| 1778 | return; | 1779 | return; |
| 1779 | 1780 | ||
| 1780 | /* apply any specific unsupported masks here */ | 1781 | /* apply any specific unsupported masks here */ |
| @@ -1811,7 +1812,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
| 1811 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) | 1812 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) |
| 1812 | return -EOPNOTSUPP; | 1813 | return -EOPNOTSUPP; |
| 1813 | 1814 | ||
| 1814 | if (e1000_wol_exclusion(adapter, wol)) | 1815 | if (e1000_wol_exclusion(adapter, wol) || |
| 1816 | !device_can_wakeup(&adapter->pdev->dev)) | ||
| 1815 | return wol->wolopts ? -EOPNOTSUPP : 0; | 1817 | return wol->wolopts ? -EOPNOTSUPP : 0; |
| 1816 | 1818 | ||
| 1817 | switch (hw->device_id) { | 1819 | switch (hw->device_id) { |
| @@ -1838,6 +1840,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
| 1838 | if (wol->wolopts & WAKE_MAGIC) | 1840 | if (wol->wolopts & WAKE_MAGIC) |
| 1839 | adapter->wol |= E1000_WUFC_MAG; | 1841 | adapter->wol |= E1000_WUFC_MAG; |
| 1840 | 1842 | ||
| 1843 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
| 1844 | |||
| 1841 | return 0; | 1845 | return 0; |
| 1842 | } | 1846 | } |
| 1843 | 1847 | ||
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index fac82152e4c8..872799b746f5 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -1179,6 +1179,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 1179 | 1179 | ||
| 1180 | /* initialize the wol settings based on the eeprom settings */ | 1180 | /* initialize the wol settings based on the eeprom settings */ |
| 1181 | adapter->wol = adapter->eeprom_wol; | 1181 | adapter->wol = adapter->eeprom_wol; |
| 1182 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
| 1182 | 1183 | ||
| 1183 | /* print bus type/speed/width info */ | 1184 | /* print bus type/speed/width info */ |
| 1184 | DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ", | 1185 | DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ", |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index c55de1c027af..c55fd6fdb91c 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
| @@ -299,6 +299,7 @@ struct e1000_adapter { | |||
| 299 | unsigned long led_status; | 299 | unsigned long led_status; |
| 300 | 300 | ||
| 301 | unsigned int flags; | 301 | unsigned int flags; |
| 302 | unsigned int flags2; | ||
| 302 | struct work_struct downshift_task; | 303 | struct work_struct downshift_task; |
| 303 | struct work_struct update_phy_task; | 304 | struct work_struct update_phy_task; |
| 304 | }; | 305 | }; |
| @@ -306,6 +307,7 @@ struct e1000_adapter { | |||
| 306 | struct e1000_info { | 307 | struct e1000_info { |
| 307 | enum e1000_mac_type mac; | 308 | enum e1000_mac_type mac; |
| 308 | unsigned int flags; | 309 | unsigned int flags; |
| 310 | unsigned int flags2; | ||
| 309 | u32 pba; | 311 | u32 pba; |
| 310 | s32 (*get_variants)(struct e1000_adapter *); | 312 | s32 (*get_variants)(struct e1000_adapter *); |
| 311 | struct e1000_mac_operations *mac_ops; | 313 | struct e1000_mac_operations *mac_ops; |
| @@ -347,6 +349,9 @@ struct e1000_info { | |||
| 347 | #define FLAG_RX_RESTART_NOW (1 << 30) | 349 | #define FLAG_RX_RESTART_NOW (1 << 30) |
| 348 | #define FLAG_MSI_TEST_FAILED (1 << 31) | 350 | #define FLAG_MSI_TEST_FAILED (1 << 31) |
| 349 | 351 | ||
| 352 | /* CRC Stripping defines */ | ||
| 353 | #define FLAG2_CRC_STRIPPING (1 << 0) | ||
| 354 | |||
| 350 | #define E1000_RX_DESC_PS(R, i) \ | 355 | #define E1000_RX_DESC_PS(R, i) \ |
| 351 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) | 356 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) |
| 352 | #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) | 357 | #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 70c11c811a08..62421ce96311 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
| @@ -1713,7 +1713,8 @@ static void e1000_get_wol(struct net_device *netdev, | |||
| 1713 | wol->supported = 0; | 1713 | wol->supported = 0; |
| 1714 | wol->wolopts = 0; | 1714 | wol->wolopts = 0; |
| 1715 | 1715 | ||
| 1716 | if (!(adapter->flags & FLAG_HAS_WOL)) | 1716 | if (!(adapter->flags & FLAG_HAS_WOL) || |
| 1717 | !device_can_wakeup(&adapter->pdev->dev)) | ||
| 1717 | return; | 1718 | return; |
| 1718 | 1719 | ||
| 1719 | wol->supported = WAKE_UCAST | WAKE_MCAST | | 1720 | wol->supported = WAKE_UCAST | WAKE_MCAST | |
| @@ -1751,7 +1752,8 @@ static int e1000_set_wol(struct net_device *netdev, | |||
| 1751 | if (wol->wolopts & WAKE_MAGICSECURE) | 1752 | if (wol->wolopts & WAKE_MAGICSECURE) |
| 1752 | return -EOPNOTSUPP; | 1753 | return -EOPNOTSUPP; |
| 1753 | 1754 | ||
| 1754 | if (!(adapter->flags & FLAG_HAS_WOL)) | 1755 | if (!(adapter->flags & FLAG_HAS_WOL) || |
| 1756 | !device_can_wakeup(&adapter->pdev->dev)) | ||
| 1755 | return wol->wolopts ? -EOPNOTSUPP : 0; | 1757 | return wol->wolopts ? -EOPNOTSUPP : 0; |
| 1756 | 1758 | ||
| 1757 | /* these settings will always override what we currently have */ | 1759 | /* these settings will always override what we currently have */ |
| @@ -1770,6 +1772,8 @@ static int e1000_set_wol(struct net_device *netdev, | |||
| 1770 | if (wol->wolopts & WAKE_ARP) | 1772 | if (wol->wolopts & WAKE_ARP) |
| 1771 | adapter->wol |= E1000_WUFC_ARP; | 1773 | adapter->wol |= E1000_WUFC_ARP; |
| 1772 | 1774 | ||
| 1775 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
| 1776 | |||
| 1773 | return 0; | 1777 | return 0; |
| 1774 | } | 1778 | } |
| 1775 | 1779 | ||
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index abd492b7336d..122539a0e1fe 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
| @@ -345,7 +345,6 @@ no_buffers: | |||
| 345 | /** | 345 | /** |
| 346 | * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers | 346 | * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers |
| 347 | * @adapter: address of board private structure | 347 | * @adapter: address of board private structure |
| 348 | * @rx_ring: pointer to receive ring structure | ||
| 349 | * @cleaned_count: number of buffers to allocate this pass | 348 | * @cleaned_count: number of buffers to allocate this pass |
| 350 | **/ | 349 | **/ |
| 351 | 350 | ||
| @@ -499,6 +498,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
| 499 | goto next_desc; | 498 | goto next_desc; |
| 500 | } | 499 | } |
| 501 | 500 | ||
| 501 | /* adjust length to remove Ethernet CRC */ | ||
| 502 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | ||
| 503 | length -= 4; | ||
| 504 | |||
| 502 | total_rx_bytes += length; | 505 | total_rx_bytes += length; |
| 503 | total_rx_packets++; | 506 | total_rx_packets++; |
| 504 | 507 | ||
| @@ -804,6 +807,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
| 804 | pci_dma_sync_single_for_device(pdev, ps_page->dma, | 807 | pci_dma_sync_single_for_device(pdev, ps_page->dma, |
| 805 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 808 | PAGE_SIZE, PCI_DMA_FROMDEVICE); |
| 806 | 809 | ||
| 810 | /* remove the CRC */ | ||
| 811 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | ||
| 812 | l1 -= 4; | ||
| 813 | |||
| 807 | skb_put(skb, l1); | 814 | skb_put(skb, l1); |
| 808 | goto copydone; | 815 | goto copydone; |
| 809 | } /* if */ | 816 | } /* if */ |
| @@ -825,6 +832,12 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
| 825 | skb->truesize += length; | 832 | skb->truesize += length; |
| 826 | } | 833 | } |
| 827 | 834 | ||
| 835 | /* strip the ethernet crc, problem is we're using pages now so | ||
| 836 | * this whole operation can get a little cpu intensive | ||
| 837 | */ | ||
| 838 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | ||
| 839 | pskb_trim(skb, skb->len - 4); | ||
| 840 | |||
| 828 | copydone: | 841 | copydone: |
| 829 | total_rx_bytes += skb->len; | 842 | total_rx_bytes += skb->len; |
| 830 | total_rx_packets++; | 843 | total_rx_packets++; |
| @@ -2301,8 +2314,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
| 2301 | else | 2314 | else |
| 2302 | rctl |= E1000_RCTL_LPE; | 2315 | rctl |= E1000_RCTL_LPE; |
| 2303 | 2316 | ||
| 2304 | /* Enable hardware CRC frame stripping */ | 2317 | /* Some systems expect that the CRC is included in SMBUS traffic. The |
| 2305 | rctl |= E1000_RCTL_SECRC; | 2318 | * hardware strips the CRC before sending to both SMBUS (BMC) and to |
| 2319 | * host memory when this is enabled | ||
| 2320 | */ | ||
| 2321 | if (adapter->flags2 & FLAG2_CRC_STRIPPING) | ||
| 2322 | rctl |= E1000_RCTL_SECRC; | ||
| 2306 | 2323 | ||
| 2307 | /* Setup buffer sizes */ | 2324 | /* Setup buffer sizes */ |
| 2308 | rctl &= ~E1000_RCTL_SZ_4096; | 2325 | rctl &= ~E1000_RCTL_SZ_4096; |
| @@ -4766,6 +4783,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 4766 | adapter->ei = ei; | 4783 | adapter->ei = ei; |
| 4767 | adapter->pba = ei->pba; | 4784 | adapter->pba = ei->pba; |
| 4768 | adapter->flags = ei->flags; | 4785 | adapter->flags = ei->flags; |
| 4786 | adapter->flags2 = ei->flags2; | ||
| 4769 | adapter->hw.adapter = adapter; | 4787 | adapter->hw.adapter = adapter; |
| 4770 | adapter->hw.mac.type = ei->mac; | 4788 | adapter->hw.mac.type = ei->mac; |
| 4771 | adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; | 4789 | adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; |
| @@ -4970,6 +4988,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 4970 | 4988 | ||
| 4971 | /* initialize the wol settings based on the eeprom settings */ | 4989 | /* initialize the wol settings based on the eeprom settings */ |
| 4972 | adapter->wol = adapter->eeprom_wol; | 4990 | adapter->wol = adapter->eeprom_wol; |
| 4991 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
| 4973 | 4992 | ||
| 4974 | /* reset the hardware with the new settings */ | 4993 | /* reset the hardware with the new settings */ |
| 4975 | e1000e_reset(adapter); | 4994 | e1000e_reset(adapter); |
| @@ -5008,6 +5027,7 @@ err_hw_init: | |||
| 5008 | err_sw_init: | 5027 | err_sw_init: |
| 5009 | if (adapter->hw.flash_address) | 5028 | if (adapter->hw.flash_address) |
| 5010 | iounmap(adapter->hw.flash_address); | 5029 | iounmap(adapter->hw.flash_address); |
| 5030 | e1000e_reset_interrupt_capability(adapter); | ||
| 5011 | err_flashmap: | 5031 | err_flashmap: |
| 5012 | iounmap(adapter->hw.hw_addr); | 5032 | iounmap(adapter->hw.hw_addr); |
| 5013 | err_ioremap: | 5033 | err_ioremap: |
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 77a3d7207a5f..e909f96698e8 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c | |||
| @@ -151,6 +151,16 @@ E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); | |||
| 151 | */ | 151 | */ |
| 152 | E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); | 152 | E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); |
| 153 | 153 | ||
| 154 | /* | ||
| 155 | * Enable CRC Stripping | ||
| 156 | * | ||
| 157 | * Valid Range: 0, 1 | ||
| 158 | * | ||
| 159 | * Default Value: 1 (enabled) | ||
| 160 | */ | ||
| 161 | E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \ | ||
| 162 | "the CRC"); | ||
| 163 | |||
| 154 | struct e1000_option { | 164 | struct e1000_option { |
| 155 | enum { enable_option, range_option, list_option } type; | 165 | enum { enable_option, range_option, list_option } type; |
| 156 | const char *name; | 166 | const char *name; |
| @@ -404,6 +414,21 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) | |||
| 404 | adapter->flags |= FLAG_SMART_POWER_DOWN; | 414 | adapter->flags |= FLAG_SMART_POWER_DOWN; |
| 405 | } | 415 | } |
| 406 | } | 416 | } |
| 417 | { /* CRC Stripping */ | ||
| 418 | const struct e1000_option opt = { | ||
| 419 | .type = enable_option, | ||
| 420 | .name = "CRC Stripping", | ||
| 421 | .err = "defaulting to enabled", | ||
| 422 | .def = OPTION_ENABLED | ||
| 423 | }; | ||
| 424 | |||
| 425 | if (num_CrcStripping > bd) { | ||
| 426 | unsigned int crc_stripping = CrcStripping[bd]; | ||
| 427 | e1000_validate_option(&crc_stripping, &opt, adapter); | ||
| 428 | if (crc_stripping == OPTION_ENABLED) | ||
| 429 | adapter->flags2 |= FLAG2_CRC_STRIPPING; | ||
| 430 | } | ||
| 431 | } | ||
| 407 | { /* Kumeran Lock Loss Workaround */ | 432 | { /* Kumeran Lock Loss Workaround */ |
| 408 | const struct e1000_option opt = { | 433 | const struct e1000_option opt = { |
| 409 | .type = enable_option, | 434 | .type = enable_option, |
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index e1b441effbbe..c414554ac321 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c | |||
| @@ -568,6 +568,17 @@ static u16 erxrdpt_workaround(u16 next_packet_ptr, u16 start, u16 end) | |||
| 568 | return erxrdpt; | 568 | return erxrdpt; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | /* | ||
| 572 | * Calculate wrap around when reading beyond the end of the RX buffer | ||
| 573 | */ | ||
| 574 | static u16 rx_packet_start(u16 ptr) | ||
| 575 | { | ||
| 576 | if (ptr + RSV_SIZE > RXEND_INIT) | ||
| 577 | return (ptr + RSV_SIZE) - (RXEND_INIT - RXSTART_INIT + 1); | ||
| 578 | else | ||
| 579 | return ptr + RSV_SIZE; | ||
| 580 | } | ||
| 581 | |||
| 571 | static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end) | 582 | static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end) |
| 572 | { | 583 | { |
| 573 | u16 erxrdpt; | 584 | u16 erxrdpt; |
| @@ -938,8 +949,9 @@ static void enc28j60_hw_rx(struct net_device *ndev) | |||
| 938 | skb->dev = ndev; | 949 | skb->dev = ndev; |
| 939 | skb_reserve(skb, NET_IP_ALIGN); | 950 | skb_reserve(skb, NET_IP_ALIGN); |
| 940 | /* copy the packet from the receive buffer */ | 951 | /* copy the packet from the receive buffer */ |
| 941 | enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv), | 952 | enc28j60_mem_read(priv, |
| 942 | len, skb_put(skb, len)); | 953 | rx_packet_start(priv->next_pk_ptr), |
| 954 | len, skb_put(skb, len)); | ||
| 943 | if (netif_msg_pktdata(priv)) | 955 | if (netif_msg_pktdata(priv)) |
| 944 | dump_packet(__func__, skb->len, skb->data); | 956 | dump_packet(__func__, skb->len, skb->data); |
| 945 | skb->protocol = eth_type_trans(skb, ndev); | 957 | skb->protocol = eth_type_trans(skb, ndev); |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index cb51c1fb0338..a6f49d025787 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
| @@ -1099,7 +1099,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, | |||
| 1099 | ndev->stop = fs_enet_close; | 1099 | ndev->stop = fs_enet_close; |
| 1100 | ndev->get_stats = fs_enet_get_stats; | 1100 | ndev->get_stats = fs_enet_get_stats; |
| 1101 | ndev->set_multicast_list = fs_set_multicast_list; | 1101 | ndev->set_multicast_list = fs_set_multicast_list; |
| 1102 | 1102 | #ifdef CONFIG_NET_POLL_CONTROLLER | |
| 1103 | ndev->poll_controller = fs_enet_netpoll; | ||
| 1104 | #endif | ||
| 1103 | if (fpi->use_napi) | 1105 | if (fpi->use_napi) |
| 1104 | netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, | 1106 | netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, |
| 1105 | fpi->napi_weight); | 1107 | fpi->napi_weight); |
| @@ -1209,7 +1211,7 @@ static void __exit fs_cleanup(void) | |||
| 1209 | static void fs_enet_netpoll(struct net_device *dev) | 1211 | static void fs_enet_netpoll(struct net_device *dev) |
| 1210 | { | 1212 | { |
| 1211 | disable_irq(dev->irq); | 1213 | disable_irq(dev->irq); |
| 1212 | fs_enet_interrupt(dev->irq, dev, NULL); | 1214 | fs_enet_interrupt(dev->irq, dev); |
| 1213 | enable_irq(dev->irq); | 1215 | enable_irq(dev->irq); |
| 1214 | } | 1216 | } |
| 1215 | #endif | 1217 | #endif |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 64b201134fdb..c4af949bf860 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
| @@ -586,6 +586,18 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
| 586 | struct gfar_mii __iomem *regs = | 586 | struct gfar_mii __iomem *regs = |
| 587 | (void __iomem *)&priv->regs->gfar_mii_regs; | 587 | (void __iomem *)&priv->regs->gfar_mii_regs; |
| 588 | int tbipa = gfar_read(&priv->regs->tbipa); | 588 | int tbipa = gfar_read(&priv->regs->tbipa); |
| 589 | struct mii_bus *bus = gfar_get_miibus(priv); | ||
| 590 | |||
| 591 | if (bus) | ||
| 592 | mutex_lock(&bus->mdio_lock); | ||
| 593 | |||
| 594 | /* If the link is already up, we must already be ok, and don't need to | ||
| 595 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | ||
| 596 | * everything for us? Resetting it takes the link down and requires | ||
| 597 | * several seconds for it to come back. | ||
| 598 | */ | ||
| 599 | if (gfar_local_mdio_read(regs, tbipa, MII_BMSR) & BMSR_LSTATUS) | ||
| 600 | goto done; | ||
| 589 | 601 | ||
| 590 | /* Single clk mode, mii mode off(for serdes communication) */ | 602 | /* Single clk mode, mii mode off(for serdes communication) */ |
| 591 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); | 603 | gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); |
| @@ -596,6 +608,10 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
| 596 | 608 | ||
| 597 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | | 609 | gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | |
| 598 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); | 610 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); |
| 611 | |||
| 612 | done: | ||
| 613 | if (bus) | ||
| 614 | mutex_unlock(&bus->mdio_lock); | ||
| 599 | } | 615 | } |
| 600 | 616 | ||
| 601 | static void init_registers(struct net_device *dev) | 617 | static void init_registers(struct net_device *dev) |
| @@ -1391,6 +1407,10 @@ static int gfar_clean_tx_ring(struct net_device *dev) | |||
| 1391 | if (bdp->status & TXBD_DEF) | 1407 | if (bdp->status & TXBD_DEF) |
| 1392 | dev->stats.collisions++; | 1408 | dev->stats.collisions++; |
| 1393 | 1409 | ||
| 1410 | /* Unmap the DMA memory */ | ||
| 1411 | dma_unmap_single(&priv->dev->dev, bdp->bufPtr, | ||
| 1412 | bdp->length, DMA_TO_DEVICE); | ||
| 1413 | |||
| 1394 | /* Free the sk buffer associated with this TxBD */ | 1414 | /* Free the sk buffer associated with this TxBD */ |
| 1395 | dev_kfree_skb_irq(priv->tx_skbuff[priv->skb_dirtytx]); | 1415 | dev_kfree_skb_irq(priv->tx_skbuff[priv->skb_dirtytx]); |
| 1396 | 1416 | ||
| @@ -1650,6 +1670,9 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) | |||
| 1650 | 1670 | ||
| 1651 | skb = priv->rx_skbuff[priv->skb_currx]; | 1671 | skb = priv->rx_skbuff[priv->skb_currx]; |
| 1652 | 1672 | ||
| 1673 | dma_unmap_single(&priv->dev->dev, bdp->bufPtr, | ||
| 1674 | priv->rx_buffer_size, DMA_FROM_DEVICE); | ||
| 1675 | |||
| 1653 | /* We drop the frame if we failed to allocate a new buffer */ | 1676 | /* We drop the frame if we failed to allocate a new buffer */ |
| 1654 | if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || | 1677 | if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || |
| 1655 | bdp->status & RXBD_ERR)) { | 1678 | bdp->status & RXBD_ERR)) { |
| @@ -1658,14 +1681,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) | |||
| 1658 | if (unlikely(!newskb)) | 1681 | if (unlikely(!newskb)) |
| 1659 | newskb = skb; | 1682 | newskb = skb; |
| 1660 | 1683 | ||
| 1661 | if (skb) { | 1684 | if (skb) |
| 1662 | dma_unmap_single(&priv->dev->dev, | ||
| 1663 | bdp->bufPtr, | ||
| 1664 | priv->rx_buffer_size, | ||
| 1665 | DMA_FROM_DEVICE); | ||
| 1666 | |||
| 1667 | dev_kfree_skb_any(skb); | 1685 | dev_kfree_skb_any(skb); |
| 1668 | } | ||
| 1669 | } else { | 1686 | } else { |
| 1670 | /* Increment the number of packets */ | 1687 | /* Increment the number of packets */ |
| 1671 | dev->stats.rx_packets++; | 1688 | dev->stats.rx_packets++; |
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index bf73eea98010..0e2595d24933 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c | |||
| @@ -269,6 +269,27 @@ static struct device_driver gianfar_mdio_driver = { | |||
| 269 | .remove = gfar_mdio_remove, | 269 | .remove = gfar_mdio_remove, |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | static int match_mdio_bus(struct device *dev, void *data) | ||
| 273 | { | ||
| 274 | const struct gfar_private *priv = data; | ||
| 275 | const struct platform_device *pdev = to_platform_device(dev); | ||
| 276 | |||
| 277 | return !strcmp(pdev->name, gianfar_mdio_driver.name) && | ||
| 278 | pdev->id == priv->einfo->mdio_bus; | ||
| 279 | } | ||
| 280 | |||
| 281 | /* Given a gfar_priv structure, find the mii_bus controlled by this device (not | ||
| 282 | * necessarily the same as the bus the gfar's PHY is on), if one exists. | ||
| 283 | * Normally only the first gianfar controls a mii_bus. */ | ||
| 284 | struct mii_bus *gfar_get_miibus(const struct gfar_private *priv) | ||
| 285 | { | ||
| 286 | /*const*/ struct device *d; | ||
| 287 | |||
| 288 | d = bus_find_device(gianfar_mdio_driver.bus, NULL, (void *)priv, | ||
| 289 | match_mdio_bus); | ||
| 290 | return d ? dev_get_drvdata(d) : NULL; | ||
| 291 | } | ||
| 292 | |||
| 272 | int __init gfar_mdio_init(void) | 293 | int __init gfar_mdio_init(void) |
| 273 | { | 294 | { |
| 274 | return driver_register(&gianfar_mdio_driver); | 295 | return driver_register(&gianfar_mdio_driver); |
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h index 2af28b16a0e2..02dc970ca1ff 100644 --- a/drivers/net/gianfar_mii.h +++ b/drivers/net/gianfar_mii.h | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #ifndef __GIANFAR_MII_H | 18 | #ifndef __GIANFAR_MII_H |
| 19 | #define __GIANFAR_MII_H | 19 | #define __GIANFAR_MII_H |
| 20 | 20 | ||
| 21 | struct gfar_private; /* forward ref */ | ||
| 22 | |||
| 21 | #define MIIMIND_BUSY 0x00000001 | 23 | #define MIIMIND_BUSY 0x00000001 |
| 22 | #define MIIMIND_NOTVALID 0x00000004 | 24 | #define MIIMIND_NOTVALID 0x00000004 |
| 23 | 25 | ||
| @@ -44,6 +46,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); | |||
| 44 | int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, | 46 | int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, |
| 45 | int regnum, u16 value); | 47 | int regnum, u16 value); |
| 46 | int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); | 48 | int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); |
| 49 | struct mii_bus *gfar_get_miibus(const struct gfar_private *priv); | ||
| 47 | int __init gfar_mdio_init(void); | 50 | int __init gfar_mdio_init(void); |
| 48 | void gfar_mdio_exit(void); | 51 | void gfar_mdio_exit(void); |
| 49 | #endif /* GIANFAR_PHY_H */ | 52 | #endif /* GIANFAR_PHY_H */ |
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index fbbd3e660c27..c01e290d09d2 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c | |||
| @@ -230,7 +230,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) | |||
| 230 | dev->open = &hpp_open; | 230 | dev->open = &hpp_open; |
| 231 | dev->stop = &hpp_close; | 231 | dev->stop = &hpp_close; |
| 232 | #ifdef CONFIG_NET_POLL_CONTROLLER | 232 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 233 | dev->poll_controller = ei_poll; | 233 | dev->poll_controller = eip_poll; |
| 234 | #endif | 234 | #endif |
| 235 | 235 | ||
| 236 | ei_status.name = name; | 236 | ei_status.name = name; |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 58906c984be9..89964fa739a0 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
| @@ -1776,7 +1776,8 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
| 1776 | 1776 | ||
| 1777 | /* this function will set ->supported = 0 and return 1 if wol is not | 1777 | /* this function will set ->supported = 0 and return 1 if wol is not |
| 1778 | * supported by this hardware */ | 1778 | * supported by this hardware */ |
| 1779 | if (igb_wol_exclusion(adapter, wol)) | 1779 | if (igb_wol_exclusion(adapter, wol) || |
| 1780 | !device_can_wakeup(&adapter->pdev->dev)) | ||
| 1780 | return; | 1781 | return; |
| 1781 | 1782 | ||
| 1782 | /* apply any specific unsupported masks here */ | 1783 | /* apply any specific unsupported masks here */ |
| @@ -1805,7 +1806,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
| 1805 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) | 1806 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) |
| 1806 | return -EOPNOTSUPP; | 1807 | return -EOPNOTSUPP; |
| 1807 | 1808 | ||
| 1808 | if (igb_wol_exclusion(adapter, wol)) | 1809 | if (igb_wol_exclusion(adapter, wol) || |
| 1810 | !device_can_wakeup(&adapter->pdev->dev)) | ||
| 1809 | return wol->wolopts ? -EOPNOTSUPP : 0; | 1811 | return wol->wolopts ? -EOPNOTSUPP : 0; |
| 1810 | 1812 | ||
| 1811 | switch (hw->device_id) { | 1813 | switch (hw->device_id) { |
| @@ -1825,6 +1827,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
| 1825 | if (wol->wolopts & WAKE_MAGIC) | 1827 | if (wol->wolopts & WAKE_MAGIC) |
| 1826 | adapter->wol |= E1000_WUFC_MAG; | 1828 | adapter->wol |= E1000_WUFC_MAG; |
| 1827 | 1829 | ||
| 1830 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
| 1831 | |||
| 1828 | return 0; | 1832 | return 0; |
| 1829 | } | 1833 | } |
| 1830 | 1834 | ||
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 1f397cd99414..20d27e622ec1 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -1019,10 +1019,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
| 1019 | state &= ~PCIE_LINK_STATE_L0S; | 1019 | state &= ~PCIE_LINK_STATE_L0S; |
| 1020 | pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL, | 1020 | pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL, |
| 1021 | state); | 1021 | state); |
| 1022 | printk(KERN_INFO "Disabling ASPM L0s upstream switch " | 1022 | dev_info(&pdev->dev, |
| 1023 | "port %x:%x.%x\n", us_dev->bus->number, | 1023 | "Disabling ASPM L0s upstream switch port %s\n", |
| 1024 | PCI_SLOT(us_dev->devfn), | 1024 | pci_name(us_dev)); |
| 1025 | PCI_FUNC(us_dev->devfn)); | ||
| 1026 | } | 1025 | } |
| 1027 | default: | 1026 | default: |
| 1028 | break; | 1027 | break; |
| @@ -1244,6 +1243,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
| 1244 | 1243 | ||
| 1245 | /* initialize the wol settings based on the eeprom settings */ | 1244 | /* initialize the wol settings based on the eeprom settings */ |
| 1246 | adapter->wol = adapter->eeprom_wol; | 1245 | adapter->wol = adapter->eeprom_wol; |
| 1246 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
| 1247 | 1247 | ||
| 1248 | /* reset the hardware with the new settings */ | 1248 | /* reset the hardware with the new settings */ |
| 1249 | igb_reset(adapter); | 1249 | igb_reset(adapter); |
| @@ -1980,7 +1980,6 @@ static void igb_configure_rx(struct igb_adapter *adapter) | |||
| 1980 | 1980 | ||
| 1981 | /** | 1981 | /** |
| 1982 | * igb_free_tx_resources - Free Tx Resources per Queue | 1982 | * igb_free_tx_resources - Free Tx Resources per Queue |
| 1983 | * @adapter: board private structure | ||
| 1984 | * @tx_ring: Tx descriptor ring for a specific queue | 1983 | * @tx_ring: Tx descriptor ring for a specific queue |
| 1985 | * | 1984 | * |
| 1986 | * Free all transmit software resources | 1985 | * Free all transmit software resources |
| @@ -2033,7 +2032,6 @@ static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter, | |||
| 2033 | 2032 | ||
| 2034 | /** | 2033 | /** |
| 2035 | * igb_clean_tx_ring - Free Tx Buffers | 2034 | * igb_clean_tx_ring - Free Tx Buffers |
| 2036 | * @adapter: board private structure | ||
| 2037 | * @tx_ring: ring to be cleaned | 2035 | * @tx_ring: ring to be cleaned |
| 2038 | **/ | 2036 | **/ |
| 2039 | static void igb_clean_tx_ring(struct igb_ring *tx_ring) | 2037 | static void igb_clean_tx_ring(struct igb_ring *tx_ring) |
| @@ -2080,7 +2078,6 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter) | |||
| 2080 | 2078 | ||
| 2081 | /** | 2079 | /** |
| 2082 | * igb_free_rx_resources - Free Rx Resources | 2080 | * igb_free_rx_resources - Free Rx Resources |
| 2083 | * @adapter: board private structure | ||
| 2084 | * @rx_ring: ring to clean the resources from | 2081 | * @rx_ring: ring to clean the resources from |
| 2085 | * | 2082 | * |
| 2086 | * Free all receive software resources | 2083 | * Free all receive software resources |
| @@ -2120,7 +2117,6 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter) | |||
| 2120 | 2117 | ||
| 2121 | /** | 2118 | /** |
| 2122 | * igb_clean_rx_ring - Free Rx Buffers per Queue | 2119 | * igb_clean_rx_ring - Free Rx Buffers per Queue |
| 2123 | * @adapter: board private structure | ||
| 2124 | * @rx_ring: ring to free buffers from | 2120 | * @rx_ring: ring to free buffers from |
| 2125 | **/ | 2121 | **/ |
| 2126 | static void igb_clean_rx_ring(struct igb_ring *rx_ring) | 2122 | static void igb_clean_rx_ring(struct igb_ring *rx_ring) |
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 7373dafbb3f7..059369885be1 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c | |||
| @@ -1112,7 +1112,7 @@ static void ipg_nic_rx_free_skb(struct net_device *dev) | |||
| 1112 | struct ipg_rx *rxfd = sp->rxd + entry; | 1112 | struct ipg_rx *rxfd = sp->rxd + entry; |
| 1113 | 1113 | ||
| 1114 | pci_unmap_single(sp->pdev, | 1114 | pci_unmap_single(sp->pdev, |
| 1115 | le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), | 1115 | le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, |
| 1116 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1116 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
| 1117 | dev_kfree_skb_irq(sp->rx_buff[entry]); | 1117 | dev_kfree_skb_irq(sp->rx_buff[entry]); |
| 1118 | sp->rx_buff[entry] = NULL; | 1118 | sp->rx_buff[entry] = NULL; |
| @@ -1179,7 +1179,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev) | |||
| 1179 | */ | 1179 | */ |
| 1180 | if (sp->rx_buff[entry]) { | 1180 | if (sp->rx_buff[entry]) { |
| 1181 | pci_unmap_single(sp->pdev, | 1181 | pci_unmap_single(sp->pdev, |
| 1182 | le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), | 1182 | le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, |
| 1183 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1183 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
| 1184 | 1184 | ||
| 1185 | dev_kfree_skb_irq(sp->rx_buff[entry]); | 1185 | dev_kfree_skb_irq(sp->rx_buff[entry]); |
| @@ -1246,7 +1246,7 @@ static void ipg_nic_rx_with_start(struct net_device *dev, | |||
| 1246 | if (jumbo->found_start) | 1246 | if (jumbo->found_start) |
| 1247 | dev_kfree_skb_irq(jumbo->skb); | 1247 | dev_kfree_skb_irq(jumbo->skb); |
| 1248 | 1248 | ||
| 1249 | pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), | 1249 | pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, |
| 1250 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1250 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
| 1251 | 1251 | ||
| 1252 | skb_put(skb, sp->rxfrag_size); | 1252 | skb_put(skb, sp->rxfrag_size); |
| @@ -1349,7 +1349,7 @@ static int ipg_nic_rx_jumbo(struct net_device *dev) | |||
| 1349 | unsigned int entry = curr % IPG_RFDLIST_LENGTH; | 1349 | unsigned int entry = curr % IPG_RFDLIST_LENGTH; |
| 1350 | struct ipg_rx *rxfd = sp->rxd + entry; | 1350 | struct ipg_rx *rxfd = sp->rxd + entry; |
| 1351 | 1351 | ||
| 1352 | if (!(rxfd->rfs & le64_to_cpu(IPG_RFS_RFDDONE))) | 1352 | if (!(rxfd->rfs & cpu_to_le64(IPG_RFS_RFDDONE))) |
| 1353 | break; | 1353 | break; |
| 1354 | 1354 | ||
| 1355 | switch (ipg_nic_rx_check_frame_type(dev)) { | 1355 | switch (ipg_nic_rx_check_frame_type(dev)) { |
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c index 2482d61662a2..2e67ae015d91 100644 --- a/drivers/net/irda/ks959-sir.c +++ b/drivers/net/irda/ks959-sir.c | |||
| @@ -118,7 +118,6 @@ | |||
| 118 | #include <linux/errno.h> | 118 | #include <linux/errno.h> |
| 119 | #include <linux/init.h> | 119 | #include <linux/init.h> |
| 120 | #include <linux/slab.h> | 120 | #include <linux/slab.h> |
| 121 | #include <linux/module.h> | ||
| 122 | #include <linux/kref.h> | 121 | #include <linux/kref.h> |
| 123 | #include <linux/usb.h> | 122 | #include <linux/usb.h> |
| 124 | #include <linux/device.h> | 123 | #include <linux/device.h> |
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c index 1e0de93fd618..3843b5faba8b 100644 --- a/drivers/net/irda/ksdazzle-sir.c +++ b/drivers/net/irda/ksdazzle-sir.c | |||
| @@ -82,7 +82,6 @@ | |||
| 82 | #include <linux/errno.h> | 82 | #include <linux/errno.h> |
| 83 | #include <linux/init.h> | 83 | #include <linux/init.h> |
| 84 | #include <linux/slab.h> | 84 | #include <linux/slab.h> |
| 85 | #include <linux/module.h> | ||
| 86 | #include <linux/kref.h> | 85 | #include <linux/kref.h> |
| 87 | #include <linux/usb.h> | 86 | #include <linux/usb.h> |
| 88 | #include <linux/device.h> | 87 | #include <linux/device.h> |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7548fb7360d9..5236f633ee36 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -1287,13 +1287,39 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) | |||
| 1287 | return; | 1287 | return; |
| 1288 | } | 1288 | } |
| 1289 | 1289 | ||
| 1290 | static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter); | 1290 | /** |
| 1291 | * ixgbe_irq_disable - Mask off interrupt generation on the NIC | ||
| 1292 | * @adapter: board private structure | ||
| 1293 | **/ | ||
| 1294 | static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) | ||
| 1295 | { | ||
| 1296 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); | ||
| 1297 | IXGBE_WRITE_FLUSH(&adapter->hw); | ||
| 1298 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | ||
| 1299 | int i; | ||
| 1300 | for (i = 0; i < adapter->num_msix_vectors; i++) | ||
| 1301 | synchronize_irq(adapter->msix_entries[i].vector); | ||
| 1302 | } else { | ||
| 1303 | synchronize_irq(adapter->pdev->irq); | ||
| 1304 | } | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | /** | ||
| 1308 | * ixgbe_irq_enable - Enable default interrupt generation settings | ||
| 1309 | * @adapter: board private structure | ||
| 1310 | **/ | ||
| 1311 | static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) | ||
| 1312 | { | ||
| 1313 | u32 mask; | ||
| 1314 | mask = IXGBE_EIMS_ENABLE_MASK; | ||
| 1315 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); | ||
| 1316 | IXGBE_WRITE_FLUSH(&adapter->hw); | ||
| 1317 | } | ||
| 1291 | 1318 | ||
| 1292 | /** | 1319 | /** |
| 1293 | * ixgbe_intr - legacy mode Interrupt Handler | 1320 | * ixgbe_intr - legacy mode Interrupt Handler |
| 1294 | * @irq: interrupt number | 1321 | * @irq: interrupt number |
| 1295 | * @data: pointer to a network interface device structure | 1322 | * @data: pointer to a network interface device structure |
| 1296 | * @pt_regs: CPU registers structure | ||
| 1297 | **/ | 1323 | **/ |
| 1298 | static irqreturn_t ixgbe_intr(int irq, void *data) | 1324 | static irqreturn_t ixgbe_intr(int irq, void *data) |
| 1299 | { | 1325 | { |
| @@ -1394,35 +1420,6 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) | |||
| 1394 | } | 1420 | } |
| 1395 | 1421 | ||
| 1396 | /** | 1422 | /** |
| 1397 | * ixgbe_irq_disable - Mask off interrupt generation on the NIC | ||
| 1398 | * @adapter: board private structure | ||
| 1399 | **/ | ||
| 1400 | static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) | ||
| 1401 | { | ||
| 1402 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); | ||
| 1403 | IXGBE_WRITE_FLUSH(&adapter->hw); | ||
| 1404 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | ||
| 1405 | int i; | ||
| 1406 | for (i = 0; i < adapter->num_msix_vectors; i++) | ||
| 1407 | synchronize_irq(adapter->msix_entries[i].vector); | ||
| 1408 | } else { | ||
| 1409 | synchronize_irq(adapter->pdev->irq); | ||
| 1410 | } | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | /** | ||
| 1414 | * ixgbe_irq_enable - Enable default interrupt generation settings | ||
| 1415 | * @adapter: board private structure | ||
| 1416 | **/ | ||
| 1417 | static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) | ||
| 1418 | { | ||
| 1419 | u32 mask; | ||
| 1420 | mask = IXGBE_EIMS_ENABLE_MASK; | ||
| 1421 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); | ||
| 1422 | IXGBE_WRITE_FLUSH(&adapter->hw); | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | /** | ||
| 1426 | * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts | 1423 | * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts |
| 1427 | * | 1424 | * |
| 1428 | **/ | 1425 | **/ |
| @@ -2332,7 +2329,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, | |||
| 2332 | * Once we know the feature-set enabled for the device, we'll cache | 2329 | * Once we know the feature-set enabled for the device, we'll cache |
| 2333 | * the register offset the descriptor ring is assigned to. | 2330 | * the register offset the descriptor ring is assigned to. |
| 2334 | **/ | 2331 | **/ |
| 2335 | static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) | 2332 | static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) |
| 2336 | { | 2333 | { |
| 2337 | int feature_mask = 0, rss_i; | 2334 | int feature_mask = 0, rss_i; |
| 2338 | int i, txr_idx, rxr_idx; | 2335 | int i, txr_idx, rxr_idx; |
| @@ -2369,7 +2366,7 @@ static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) | |||
| 2369 | * number of queues at compile-time. The polling_netdev array is | 2366 | * number of queues at compile-time. The polling_netdev array is |
| 2370 | * intended for Multiqueue, but should work fine with a single queue. | 2367 | * intended for Multiqueue, but should work fine with a single queue. |
| 2371 | **/ | 2368 | **/ |
| 2372 | static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter) | 2369 | static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) |
| 2373 | { | 2370 | { |
| 2374 | int i; | 2371 | int i; |
| 2375 | 2372 | ||
| @@ -2410,8 +2407,7 @@ err_tx_ring_allocation: | |||
| 2410 | * Attempt to configure the interrupts using the best available | 2407 | * Attempt to configure the interrupts using the best available |
| 2411 | * capabilities of the hardware and the kernel. | 2408 | * capabilities of the hardware and the kernel. |
| 2412 | **/ | 2409 | **/ |
| 2413 | static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter | 2410 | static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) |
| 2414 | *adapter) | ||
| 2415 | { | 2411 | { |
| 2416 | int err = 0; | 2412 | int err = 0; |
| 2417 | int vector, v_budget; | 2413 | int vector, v_budget; |
| @@ -2503,7 +2499,7 @@ static void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter) | |||
| 2503 | * - Hardware queue count (num_*_queues) | 2499 | * - Hardware queue count (num_*_queues) |
| 2504 | * - defined by miscellaneous hardware support/features (RSS, etc.) | 2500 | * - defined by miscellaneous hardware support/features (RSS, etc.) |
| 2505 | **/ | 2501 | **/ |
| 2506 | static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) | 2502 | static int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) |
| 2507 | { | 2503 | { |
| 2508 | int err; | 2504 | int err; |
| 2509 | 2505 | ||
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 81c6cdc3851f..665e70d620fc 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
| @@ -912,23 +912,23 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) | |||
| 912 | skb_put(skb, framesize); | 912 | skb_put(skb, framesize); |
| 913 | skb->protocol = eth_type_trans(skb, jme->dev); | 913 | skb->protocol = eth_type_trans(skb, jme->dev); |
| 914 | 914 | ||
| 915 | if (jme_rxsum_ok(jme, rxdesc->descwb.flags)) | 915 | if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) |
| 916 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 916 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 917 | else | 917 | else |
| 918 | skb->ip_summed = CHECKSUM_NONE; | 918 | skb->ip_summed = CHECKSUM_NONE; |
| 919 | 919 | ||
| 920 | if (rxdesc->descwb.flags & RXWBFLAG_TAGON) { | 920 | if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { |
| 921 | if (jme->vlgrp) { | 921 | if (jme->vlgrp) { |
| 922 | jme->jme_vlan_rx(skb, jme->vlgrp, | 922 | jme->jme_vlan_rx(skb, jme->vlgrp, |
| 923 | le32_to_cpu(rxdesc->descwb.vlan)); | 923 | le16_to_cpu(rxdesc->descwb.vlan)); |
| 924 | NET_STAT(jme).rx_bytes += 4; | 924 | NET_STAT(jme).rx_bytes += 4; |
| 925 | } | 925 | } |
| 926 | } else { | 926 | } else { |
| 927 | jme->jme_rx(skb); | 927 | jme->jme_rx(skb); |
| 928 | } | 928 | } |
| 929 | 929 | ||
| 930 | if ((le16_to_cpu(rxdesc->descwb.flags) & RXWBFLAG_DEST) == | 930 | if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_DEST)) == |
| 931 | RXWBFLAG_DEST_MUL) | 931 | cpu_to_le16(RXWBFLAG_DEST_MUL)) |
| 932 | ++(NET_STAT(jme).multicast); | 932 | ++(NET_STAT(jme).multicast); |
| 933 | 933 | ||
| 934 | jme->dev->last_rx = jiffies; | 934 | jme->dev->last_rx = jiffies; |
| @@ -961,7 +961,7 @@ jme_process_receive(struct jme_adapter *jme, int limit) | |||
| 961 | rxdesc = rxring->desc; | 961 | rxdesc = rxring->desc; |
| 962 | rxdesc += i; | 962 | rxdesc += i; |
| 963 | 963 | ||
| 964 | if ((rxdesc->descwb.flags & RXWBFLAG_OWN) || | 964 | if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) || |
| 965 | !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL)) | 965 | !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL)) |
| 966 | goto out; | 966 | goto out; |
| 967 | 967 | ||
| @@ -1763,10 +1763,9 @@ jme_expand_header(struct jme_adapter *jme, struct sk_buff *skb) | |||
| 1763 | } | 1763 | } |
| 1764 | 1764 | ||
| 1765 | static int | 1765 | static int |
| 1766 | jme_tx_tso(struct sk_buff *skb, | 1766 | jme_tx_tso(struct sk_buff *skb, __le16 *mss, u8 *flags) |
| 1767 | u16 *mss, u8 *flags) | ||
| 1768 | { | 1767 | { |
| 1769 | *mss = skb_shinfo(skb)->gso_size << TXDESC_MSS_SHIFT; | 1768 | *mss = cpu_to_le16(skb_shinfo(skb)->gso_size << TXDESC_MSS_SHIFT); |
| 1770 | if (*mss) { | 1769 | if (*mss) { |
| 1771 | *flags |= TXFLAG_LSEN; | 1770 | *flags |= TXFLAG_LSEN; |
| 1772 | 1771 | ||
| @@ -1826,11 +1825,11 @@ jme_tx_csum(struct jme_adapter *jme, struct sk_buff *skb, u8 *flags) | |||
| 1826 | } | 1825 | } |
| 1827 | 1826 | ||
| 1828 | static inline void | 1827 | static inline void |
| 1829 | jme_tx_vlan(struct sk_buff *skb, u16 *vlan, u8 *flags) | 1828 | jme_tx_vlan(struct sk_buff *skb, __le16 *vlan, u8 *flags) |
| 1830 | { | 1829 | { |
| 1831 | if (vlan_tx_tag_present(skb)) { | 1830 | if (vlan_tx_tag_present(skb)) { |
| 1832 | *flags |= TXFLAG_TAGON; | 1831 | *flags |= TXFLAG_TAGON; |
| 1833 | *vlan = vlan_tx_tag_get(skb); | 1832 | *vlan = cpu_to_le16(vlan_tx_tag_get(skb)); |
| 1834 | } | 1833 | } |
| 1835 | } | 1834 | } |
| 1836 | 1835 | ||
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 3b43bfd85a0f..b1ac63ab8c16 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
| @@ -76,15 +76,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 76 | 76 | ||
| 77 | skb->protocol = eth_type_trans(skb,dev); | 77 | skb->protocol = eth_type_trans(skb,dev); |
| 78 | 78 | ||
| 79 | #ifdef LOOPBACK_TSO | ||
| 80 | if (skb_is_gso(skb)) { | ||
| 81 | BUG_ON(skb->protocol != htons(ETH_P_IP)); | ||
| 82 | BUG_ON(ip_hdr(skb)->protocol != IPPROTO_TCP); | ||
| 83 | |||
| 84 | emulate_large_send_offload(skb); | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | #endif | ||
| 88 | dev->last_rx = jiffies; | 79 | dev->last_rx = jiffies; |
| 89 | 80 | ||
| 90 | /* it's OK to use per_cpu_ptr() because BHs are off */ | 81 | /* it's OK to use per_cpu_ptr() because BHs are off */ |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 42394505bb50..590039cbb146 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
| @@ -70,6 +70,9 @@ static void macvlan_broadcast(struct sk_buff *skb, | |||
| 70 | struct sk_buff *nskb; | 70 | struct sk_buff *nskb; |
| 71 | unsigned int i; | 71 | unsigned int i; |
| 72 | 72 | ||
| 73 | if (skb->protocol == htons(ETH_P_PAUSE)) | ||
| 74 | return; | ||
| 75 | |||
| 73 | for (i = 0; i < MACVLAN_HASH_SIZE; i++) { | 76 | for (i = 0; i < MACVLAN_HASH_SIZE; i++) { |
| 74 | hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) { | 77 | hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) { |
| 75 | dev = vlan->dev; | 78 | dev = vlan->dev; |
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index a339afbeed38..96e709d6440a 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c | |||
| @@ -656,10 +656,10 @@ static int mlx4_en_start_port(struct net_device *dev) | |||
| 656 | /* Configure port */ | 656 | /* Configure port */ |
| 657 | err = mlx4_SET_PORT_general(mdev->dev, priv->port, | 657 | err = mlx4_SET_PORT_general(mdev->dev, priv->port, |
| 658 | priv->rx_skb_size + ETH_FCS_LEN, | 658 | priv->rx_skb_size + ETH_FCS_LEN, |
| 659 | mdev->profile.tx_pause, | 659 | priv->prof->tx_pause, |
| 660 | mdev->profile.tx_ppp, | 660 | priv->prof->tx_ppp, |
| 661 | mdev->profile.rx_pause, | 661 | priv->prof->rx_pause, |
| 662 | mdev->profile.rx_ppp); | 662 | priv->prof->rx_ppp); |
| 663 | if (err) { | 663 | if (err) { |
| 664 | mlx4_err(mdev, "Failed setting port general configurations" | 664 | mlx4_err(mdev, "Failed setting port general configurations" |
| 665 | " for port %d, with error %d\n", priv->port, err); | 665 | " for port %d, with error %d\n", priv->port, err); |
| @@ -706,7 +706,7 @@ tx_err: | |||
| 706 | mlx4_en_release_rss_steer(priv); | 706 | mlx4_en_release_rss_steer(priv); |
| 707 | rx_err: | 707 | rx_err: |
| 708 | for (i = 0; i < priv->rx_ring_num; i++) | 708 | for (i = 0; i < priv->rx_ring_num; i++) |
| 709 | mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[rx_index]); | 709 | mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]); |
| 710 | cq_err: | 710 | cq_err: |
| 711 | while (rx_index--) | 711 | while (rx_index--) |
| 712 | mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); | 712 | mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); |
diff --git a/drivers/net/mlx4/en_params.c b/drivers/net/mlx4/en_params.c index c2e69b1bcd0a..95706ee1c019 100644 --- a/drivers/net/mlx4/en_params.c +++ b/drivers/net/mlx4/en_params.c | |||
| @@ -90,6 +90,7 @@ MLX4_EN_PARM_INT(rx_ring_size2, MLX4_EN_AUTO_CONF, "Rx ring size for port 2"); | |||
| 90 | int mlx4_en_get_profile(struct mlx4_en_dev *mdev) | 90 | int mlx4_en_get_profile(struct mlx4_en_dev *mdev) |
| 91 | { | 91 | { |
| 92 | struct mlx4_en_profile *params = &mdev->profile; | 92 | struct mlx4_en_profile *params = &mdev->profile; |
| 93 | int i; | ||
| 93 | 94 | ||
| 94 | params->rx_moder_cnt = min_t(int, rx_moder_cnt, MLX4_EN_AUTO_CONF); | 95 | params->rx_moder_cnt = min_t(int, rx_moder_cnt, MLX4_EN_AUTO_CONF); |
| 95 | params->rx_moder_time = min_t(int, rx_moder_time, MLX4_EN_AUTO_CONF); | 96 | params->rx_moder_time = min_t(int, rx_moder_time, MLX4_EN_AUTO_CONF); |
| @@ -97,11 +98,13 @@ int mlx4_en_get_profile(struct mlx4_en_dev *mdev) | |||
| 97 | params->rss_xor = (rss_xor != 0); | 98 | params->rss_xor = (rss_xor != 0); |
| 98 | params->rss_mask = rss_mask & 0x1f; | 99 | params->rss_mask = rss_mask & 0x1f; |
| 99 | params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); | 100 | params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); |
| 100 | params->rx_pause = pprx; | 101 | for (i = 1; i <= MLX4_MAX_PORTS; i++) { |
| 101 | params->rx_ppp = pfcrx; | 102 | params->prof[i].rx_pause = pprx; |
| 102 | params->tx_pause = pptx; | 103 | params->prof[i].rx_ppp = pfcrx; |
| 103 | params->tx_ppp = pfctx; | 104 | params->prof[i].tx_pause = pptx; |
| 104 | if (params->rx_ppp || params->tx_ppp) { | 105 | params->prof[i].tx_ppp = pfctx; |
| 106 | } | ||
| 107 | if (pfcrx || pfctx) { | ||
| 105 | params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM; | 108 | params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM; |
| 106 | params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM; | 109 | params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM; |
| 107 | } else { | 110 | } else { |
| @@ -407,14 +410,14 @@ static int mlx4_en_set_pauseparam(struct net_device *dev, | |||
| 407 | struct mlx4_en_dev *mdev = priv->mdev; | 410 | struct mlx4_en_dev *mdev = priv->mdev; |
| 408 | int err; | 411 | int err; |
| 409 | 412 | ||
| 410 | mdev->profile.tx_pause = pause->tx_pause != 0; | 413 | priv->prof->tx_pause = pause->tx_pause != 0; |
| 411 | mdev->profile.rx_pause = pause->rx_pause != 0; | 414 | priv->prof->rx_pause = pause->rx_pause != 0; |
| 412 | err = mlx4_SET_PORT_general(mdev->dev, priv->port, | 415 | err = mlx4_SET_PORT_general(mdev->dev, priv->port, |
| 413 | priv->rx_skb_size + ETH_FCS_LEN, | 416 | priv->rx_skb_size + ETH_FCS_LEN, |
| 414 | mdev->profile.tx_pause, | 417 | priv->prof->tx_pause, |
| 415 | mdev->profile.tx_ppp, | 418 | priv->prof->tx_ppp, |
| 416 | mdev->profile.rx_pause, | 419 | priv->prof->rx_pause, |
| 417 | mdev->profile.rx_ppp); | 420 | priv->prof->rx_ppp); |
| 418 | if (err) | 421 | if (err) |
| 419 | mlx4_err(mdev, "Failed setting pause params to\n"); | 422 | mlx4_err(mdev, "Failed setting pause params to\n"); |
| 420 | 423 | ||
| @@ -425,10 +428,9 @@ static void mlx4_en_get_pauseparam(struct net_device *dev, | |||
| 425 | struct ethtool_pauseparam *pause) | 428 | struct ethtool_pauseparam *pause) |
| 426 | { | 429 | { |
| 427 | struct mlx4_en_priv *priv = netdev_priv(dev); | 430 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 428 | struct mlx4_en_dev *mdev = priv->mdev; | ||
| 429 | 431 | ||
| 430 | pause->tx_pause = mdev->profile.tx_pause; | 432 | pause->tx_pause = priv->prof->tx_pause; |
| 431 | pause->rx_pause = mdev->profile.rx_pause; | 433 | pause->rx_pause = priv->prof->rx_pause; |
| 432 | } | 434 | } |
| 433 | 435 | ||
| 434 | static void mlx4_en_get_ringparam(struct net_device *dev, | 436 | static void mlx4_en_get_ringparam(struct net_device *dev, |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 468921b8f4b6..90a0281d15ea 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
| @@ -753,6 +753,7 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
| 753 | struct mlx4_priv *priv = mlx4_priv(dev); | 753 | struct mlx4_priv *priv = mlx4_priv(dev); |
| 754 | int err; | 754 | int err; |
| 755 | int port; | 755 | int port; |
| 756 | __be32 ib_port_default_caps; | ||
| 756 | 757 | ||
| 757 | err = mlx4_init_uar_table(dev); | 758 | err = mlx4_init_uar_table(dev); |
| 758 | if (err) { | 759 | if (err) { |
| @@ -852,6 +853,13 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
| 852 | } | 853 | } |
| 853 | 854 | ||
| 854 | for (port = 1; port <= dev->caps.num_ports; port++) { | 855 | for (port = 1; port <= dev->caps.num_ports; port++) { |
| 856 | ib_port_default_caps = 0; | ||
| 857 | err = mlx4_get_port_ib_caps(dev, port, &ib_port_default_caps); | ||
| 858 | if (err) | ||
| 859 | mlx4_warn(dev, "failed to get port %d default " | ||
| 860 | "ib capabilities (%d). Continuing with " | ||
| 861 | "caps = 0\n", port, err); | ||
| 862 | dev->caps.ib_port_def_cap[port] = ib_port_default_caps; | ||
| 855 | err = mlx4_SET_PORT(dev, port); | 863 | err = mlx4_SET_PORT(dev, port); |
| 856 | if (err) { | 864 | if (err) { |
| 857 | mlx4_err(dev, "Failed to set port %d, aborting\n", | 865 | mlx4_err(dev, "Failed to set port %d, aborting\n", |
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index fa431fad0eec..34c909deaff3 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h | |||
| @@ -87,6 +87,9 @@ enum { | |||
| 87 | 87 | ||
| 88 | #ifdef CONFIG_MLX4_DEBUG | 88 | #ifdef CONFIG_MLX4_DEBUG |
| 89 | extern int mlx4_debug_level; | 89 | extern int mlx4_debug_level; |
| 90 | #else /* CONFIG_MLX4_DEBUG */ | ||
| 91 | #define mlx4_debug_level (0) | ||
| 92 | #endif /* CONFIG_MLX4_DEBUG */ | ||
| 90 | 93 | ||
| 91 | #define mlx4_dbg(mdev, format, arg...) \ | 94 | #define mlx4_dbg(mdev, format, arg...) \ |
| 92 | do { \ | 95 | do { \ |
| @@ -94,12 +97,6 @@ extern int mlx4_debug_level; | |||
| 94 | dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \ | 97 | dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \ |
| 95 | } while (0) | 98 | } while (0) |
| 96 | 99 | ||
| 97 | #else /* CONFIG_MLX4_DEBUG */ | ||
| 98 | |||
| 99 | #define mlx4_dbg(mdev, format, arg...) do { (void) mdev; } while (0) | ||
| 100 | |||
| 101 | #endif /* CONFIG_MLX4_DEBUG */ | ||
| 102 | |||
| 103 | #define mlx4_err(mdev, format, arg...) \ | 100 | #define mlx4_err(mdev, format, arg...) \ |
| 104 | dev_err(&mdev->pdev->dev, format, ## arg) | 101 | dev_err(&mdev->pdev->dev, format, ## arg) |
| 105 | #define mlx4_info(mdev, format, arg...) \ | 102 | #define mlx4_info(mdev, format, arg...) \ |
| @@ -388,5 +385,6 @@ void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); | |||
| 388 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); | 385 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); |
| 389 | 386 | ||
| 390 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port); | 387 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port); |
| 388 | int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); | ||
| 391 | 389 | ||
| 392 | #endif /* MLX4_H */ | 390 | #endif /* MLX4_H */ |
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 11fb17c6e97b..98ddc0811f93 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h | |||
| @@ -322,6 +322,10 @@ struct mlx4_en_port_profile { | |||
| 322 | u32 rx_ring_num; | 322 | u32 rx_ring_num; |
| 323 | u32 tx_ring_size; | 323 | u32 tx_ring_size; |
| 324 | u32 rx_ring_size; | 324 | u32 rx_ring_size; |
| 325 | u8 rx_pause; | ||
| 326 | u8 rx_ppp; | ||
| 327 | u8 tx_pause; | ||
| 328 | u8 tx_ppp; | ||
| 325 | }; | 329 | }; |
| 326 | 330 | ||
| 327 | struct mlx4_en_profile { | 331 | struct mlx4_en_profile { |
| @@ -333,10 +337,6 @@ struct mlx4_en_profile { | |||
| 333 | int rx_moder_cnt; | 337 | int rx_moder_cnt; |
| 334 | int rx_moder_time; | 338 | int rx_moder_time; |
| 335 | int auto_moder; | 339 | int auto_moder; |
| 336 | u8 rx_pause; | ||
| 337 | u8 rx_ppp; | ||
| 338 | u8 tx_pause; | ||
| 339 | u8 tx_ppp; | ||
| 340 | u8 no_reset; | 340 | u8 no_reset; |
| 341 | struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1]; | 341 | struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1]; |
| 342 | }; | 342 | }; |
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c index e2fdab42c4ce..0a057e5dc63b 100644 --- a/drivers/net/mlx4/port.c +++ b/drivers/net/mlx4/port.c | |||
| @@ -258,6 +258,42 @@ out: | |||
| 258 | } | 258 | } |
| 259 | EXPORT_SYMBOL_GPL(mlx4_unregister_vlan); | 259 | EXPORT_SYMBOL_GPL(mlx4_unregister_vlan); |
| 260 | 260 | ||
| 261 | int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) | ||
| 262 | { | ||
| 263 | struct mlx4_cmd_mailbox *inmailbox, *outmailbox; | ||
| 264 | u8 *inbuf, *outbuf; | ||
| 265 | int err; | ||
| 266 | |||
| 267 | inmailbox = mlx4_alloc_cmd_mailbox(dev); | ||
| 268 | if (IS_ERR(inmailbox)) | ||
| 269 | return PTR_ERR(inmailbox); | ||
| 270 | |||
| 271 | outmailbox = mlx4_alloc_cmd_mailbox(dev); | ||
| 272 | if (IS_ERR(outmailbox)) { | ||
| 273 | mlx4_free_cmd_mailbox(dev, inmailbox); | ||
| 274 | return PTR_ERR(outmailbox); | ||
| 275 | } | ||
| 276 | |||
| 277 | inbuf = inmailbox->buf; | ||
| 278 | outbuf = outmailbox->buf; | ||
| 279 | memset(inbuf, 0, 256); | ||
| 280 | memset(outbuf, 0, 256); | ||
| 281 | inbuf[0] = 1; | ||
| 282 | inbuf[1] = 1; | ||
| 283 | inbuf[2] = 1; | ||
| 284 | inbuf[3] = 1; | ||
| 285 | *(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015); | ||
| 286 | *(__be32 *) (&inbuf[20]) = cpu_to_be32(port); | ||
| 287 | |||
| 288 | err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3, | ||
| 289 | MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); | ||
| 290 | if (!err) | ||
| 291 | *caps = *(__be32 *) (outbuf + 84); | ||
| 292 | mlx4_free_cmd_mailbox(dev, inmailbox); | ||
| 293 | mlx4_free_cmd_mailbox(dev, outmailbox); | ||
| 294 | return err; | ||
| 295 | } | ||
| 296 | |||
| 261 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | 297 | int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) |
| 262 | { | 298 | { |
| 263 | struct mlx4_cmd_mailbox *mailbox; | 299 | struct mlx4_cmd_mailbox *mailbox; |
| @@ -273,7 +309,8 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port) | |||
| 273 | ((u8 *) mailbox->buf)[3] = 6; | 309 | ((u8 *) mailbox->buf)[3] = 6; |
| 274 | ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15); | 310 | ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15); |
| 275 | ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15); | 311 | ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15); |
| 276 | } | 312 | } else |
| 313 | ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; | ||
| 277 | err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT, | 314 | err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT, |
| 278 | MLX4_CMD_TIME_CLASS_B); | 315 | MLX4_CMD_TIME_CLASS_B); |
| 279 | 316 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index a9c8c08044b1..e513f76f2a9f 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
| @@ -899,7 +899,8 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
| 899 | if (skb != NULL) { | 899 | if (skb != NULL) { |
| 900 | if (skb_queue_len(&mp->rx_recycle) < | 900 | if (skb_queue_len(&mp->rx_recycle) < |
| 901 | mp->default_rx_ring_size && | 901 | mp->default_rx_ring_size && |
| 902 | skb_recycle_check(skb, mp->skb_size)) | 902 | skb_recycle_check(skb, mp->skb_size + |
| 903 | dma_get_cache_alignment() - 1)) | ||
| 903 | __skb_queue_head(&mp->rx_recycle, skb); | 904 | __skb_queue_head(&mp->rx_recycle, skb); |
| 904 | else | 905 | else |
| 905 | dev_kfree_skb(skb); | 906 | dev_kfree_skb(skb); |
| @@ -1066,9 +1067,12 @@ static int smi_wait_ready(struct mv643xx_eth_shared_private *msp) | |||
| 1066 | return 0; | 1067 | return 0; |
| 1067 | } | 1068 | } |
| 1068 | 1069 | ||
| 1069 | if (!wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp), | 1070 | if (!smi_is_done(msp)) { |
| 1070 | msecs_to_jiffies(100))) | 1071 | wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp), |
| 1071 | return -ETIMEDOUT; | 1072 | msecs_to_jiffies(100)); |
| 1073 | if (!smi_is_done(msp)) | ||
| 1074 | return -ETIMEDOUT; | ||
| 1075 | } | ||
| 1072 | 1076 | ||
| 1073 | return 0; | 1077 | return 0; |
| 1074 | } | 1078 | } |
| @@ -2432,8 +2436,8 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev) | |||
| 2432 | struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; | 2436 | struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; |
| 2433 | 2437 | ||
| 2434 | if (pd == NULL || pd->shared_smi == NULL) { | 2438 | if (pd == NULL || pd->shared_smi == NULL) { |
| 2435 | mdiobus_free(msp->smi_bus); | ||
| 2436 | mdiobus_unregister(msp->smi_bus); | 2439 | mdiobus_unregister(msp->smi_bus); |
| 2440 | mdiobus_free(msp->smi_bus); | ||
| 2437 | } | 2441 | } |
| 2438 | if (msp->err_interrupt != NO_IRQ) | 2442 | if (msp->err_interrupt != NO_IRQ) |
| 2439 | free_irq(msp->err_interrupt, msp); | 2443 | free_irq(msp->err_interrupt, msp); |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index b1556b2e404c..b37867097308 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
| @@ -75,7 +75,7 @@ | |||
| 75 | #include "myri10ge_mcp.h" | 75 | #include "myri10ge_mcp.h" |
| 76 | #include "myri10ge_mcp_gen_header.h" | 76 | #include "myri10ge_mcp_gen_header.h" |
| 77 | 77 | ||
| 78 | #define MYRI10GE_VERSION_STR "1.4.3-1.371" | 78 | #define MYRI10GE_VERSION_STR "1.4.3-1.378" |
| 79 | 79 | ||
| 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); | 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); |
| 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); | 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); |
| @@ -1393,6 +1393,8 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) | |||
| 1393 | if (tx->req == tx->done) { | 1393 | if (tx->req == tx->done) { |
| 1394 | tx->queue_active = 0; | 1394 | tx->queue_active = 0; |
| 1395 | put_be32(htonl(1), tx->send_stop); | 1395 | put_be32(htonl(1), tx->send_stop); |
| 1396 | mb(); | ||
| 1397 | mmiowb(); | ||
| 1396 | } | 1398 | } |
| 1397 | __netif_tx_unlock(dev_queue); | 1399 | __netif_tx_unlock(dev_queue); |
| 1398 | } | 1400 | } |
| @@ -2864,6 +2866,8 @@ again: | |||
| 2864 | if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { | 2866 | if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { |
| 2865 | tx->queue_active = 1; | 2867 | tx->queue_active = 1; |
| 2866 | put_be32(htonl(1), tx->send_go); | 2868 | put_be32(htonl(1), tx->send_go); |
| 2869 | mb(); | ||
| 2870 | mmiowb(); | ||
| 2867 | } | 2871 | } |
| 2868 | tx->pkt_start++; | 2872 | tx->pkt_start++; |
| 2869 | if ((avail - count) < MXGEFW_MAX_SEND_DESC) { | 2873 | if ((avail - count) < MXGEFW_MAX_SEND_DESC) { |
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index b9bed82e1d21..b289a0a2b945 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c | |||
| @@ -401,6 +401,8 @@ static int netx_eth_drv_probe(struct platform_device *pdev) | |||
| 401 | priv->xmac_base = priv->xc->xmac_base; | 401 | priv->xmac_base = priv->xc->xmac_base; |
| 402 | priv->sram_base = priv->xc->sram_base; | 402 | priv->sram_base = priv->xc->sram_base; |
| 403 | 403 | ||
| 404 | spin_lock_init(&priv->lock); | ||
| 405 | |||
| 404 | ret = pfifo_request(PFIFO_MASK(priv->id)); | 406 | ret = pfifo_request(PFIFO_MASK(priv->id)); |
| 405 | if (ret) { | 407 | if (ret) { |
| 406 | printk("unable to request PFIFO\n"); | 408 | printk("unable to request PFIFO\n"); |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index ebc812702903..1b6f548c4411 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
| @@ -33,8 +33,8 @@ | |||
| 33 | 33 | ||
| 34 | #define DRV_MODULE_NAME "niu" | 34 | #define DRV_MODULE_NAME "niu" |
| 35 | #define PFX DRV_MODULE_NAME ": " | 35 | #define PFX DRV_MODULE_NAME ": " |
| 36 | #define DRV_MODULE_VERSION "0.9" | 36 | #define DRV_MODULE_VERSION "1.0" |
| 37 | #define DRV_MODULE_RELDATE "May 4, 2008" | 37 | #define DRV_MODULE_RELDATE "Nov 14, 2008" |
| 38 | 38 | ||
| 39 | static char version[] __devinitdata = | 39 | static char version[] __devinitdata = |
| 40 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 40 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
| @@ -51,8 +51,7 @@ MODULE_VERSION(DRV_MODULE_VERSION); | |||
| 51 | #ifndef readq | 51 | #ifndef readq |
| 52 | static u64 readq(void __iomem *reg) | 52 | static u64 readq(void __iomem *reg) |
| 53 | { | 53 | { |
| 54 | return (((u64)readl(reg + 0x4UL) << 32) | | 54 | return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32); |
| 55 | (u64)readl(reg)); | ||
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | static void writeq(u64 val, void __iomem *reg) | 57 | static void writeq(u64 val, void __iomem *reg) |
| @@ -407,7 +406,7 @@ static int esr2_set_rx_cfg(struct niu *np, unsigned long channel, u32 val) | |||
| 407 | } | 406 | } |
| 408 | 407 | ||
| 409 | /* Mode is always 10G fiber. */ | 408 | /* Mode is always 10G fiber. */ |
| 410 | static int serdes_init_niu(struct niu *np) | 409 | static int serdes_init_niu_10g_fiber(struct niu *np) |
| 411 | { | 410 | { |
| 412 | struct niu_link_config *lp = &np->link_config; | 411 | struct niu_link_config *lp = &np->link_config; |
| 413 | u32 tx_cfg, rx_cfg; | 412 | u32 tx_cfg, rx_cfg; |
| @@ -444,6 +443,223 @@ static int serdes_init_niu(struct niu *np) | |||
| 444 | return 0; | 443 | return 0; |
| 445 | } | 444 | } |
| 446 | 445 | ||
| 446 | static int serdes_init_niu_1g_serdes(struct niu *np) | ||
| 447 | { | ||
| 448 | struct niu_link_config *lp = &np->link_config; | ||
| 449 | u16 pll_cfg, pll_sts; | ||
| 450 | int max_retry = 100; | ||
| 451 | u64 sig, mask, val; | ||
| 452 | u32 tx_cfg, rx_cfg; | ||
| 453 | unsigned long i; | ||
| 454 | int err; | ||
| 455 | |||
| 456 | tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV | | ||
| 457 | PLL_TX_CFG_RATE_HALF); | ||
| 458 | rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | | ||
| 459 | PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | | ||
| 460 | PLL_RX_CFG_RATE_HALF); | ||
| 461 | |||
| 462 | if (np->port == 0) | ||
| 463 | rx_cfg |= PLL_RX_CFG_EQ_LP_ADAPTIVE; | ||
| 464 | |||
| 465 | if (lp->loopback_mode == LOOPBACK_PHY) { | ||
| 466 | u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; | ||
| 467 | |||
| 468 | mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, | ||
| 469 | ESR2_TI_PLL_TEST_CFG_L, test_cfg); | ||
| 470 | |||
| 471 | tx_cfg |= PLL_TX_CFG_ENTEST; | ||
| 472 | rx_cfg |= PLL_RX_CFG_ENTEST; | ||
| 473 | } | ||
| 474 | |||
| 475 | /* Initialize PLL for 1G */ | ||
| 476 | pll_cfg = (PLL_CFG_ENPLL | PLL_CFG_MPY_8X); | ||
| 477 | |||
| 478 | err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, | ||
| 479 | ESR2_TI_PLL_CFG_L, pll_cfg); | ||
| 480 | if (err) { | ||
| 481 | dev_err(np->device, PFX "NIU Port %d " | ||
| 482 | "serdes_init_niu_1g_serdes: " | ||
| 483 | "mdio write to ESR2_TI_PLL_CFG_L failed", np->port); | ||
| 484 | return err; | ||
| 485 | } | ||
| 486 | |||
| 487 | pll_sts = PLL_CFG_ENPLL; | ||
| 488 | |||
| 489 | err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, | ||
| 490 | ESR2_TI_PLL_STS_L, pll_sts); | ||
| 491 | if (err) { | ||
| 492 | dev_err(np->device, PFX "NIU Port %d " | ||
| 493 | "serdes_init_niu_1g_serdes: " | ||
| 494 | "mdio write to ESR2_TI_PLL_STS_L failed", np->port); | ||
| 495 | return err; | ||
| 496 | } | ||
| 497 | |||
| 498 | udelay(200); | ||
| 499 | |||
| 500 | /* Initialize all 4 lanes of the SERDES. */ | ||
| 501 | for (i = 0; i < 4; i++) { | ||
| 502 | err = esr2_set_tx_cfg(np, i, tx_cfg); | ||
| 503 | if (err) | ||
| 504 | return err; | ||
| 505 | } | ||
| 506 | |||
| 507 | for (i = 0; i < 4; i++) { | ||
| 508 | err = esr2_set_rx_cfg(np, i, rx_cfg); | ||
| 509 | if (err) | ||
| 510 | return err; | ||
| 511 | } | ||
| 512 | |||
| 513 | switch (np->port) { | ||
| 514 | case 0: | ||
| 515 | val = (ESR_INT_SRDY0_P0 | ESR_INT_DET0_P0); | ||
| 516 | mask = val; | ||
| 517 | break; | ||
| 518 | |||
| 519 | case 1: | ||
| 520 | val = (ESR_INT_SRDY0_P1 | ESR_INT_DET0_P1); | ||
| 521 | mask = val; | ||
| 522 | break; | ||
| 523 | |||
| 524 | default: | ||
| 525 | return -EINVAL; | ||
| 526 | } | ||
| 527 | |||
| 528 | while (max_retry--) { | ||
| 529 | sig = nr64(ESR_INT_SIGNALS); | ||
| 530 | if ((sig & mask) == val) | ||
| 531 | break; | ||
| 532 | |||
| 533 | mdelay(500); | ||
| 534 | } | ||
| 535 | |||
| 536 | if ((sig & mask) != val) { | ||
| 537 | dev_err(np->device, PFX "Port %u signal bits [%08x] are not " | ||
| 538 | "[%08x]\n", np->port, (int) (sig & mask), (int) val); | ||
| 539 | return -ENODEV; | ||
| 540 | } | ||
| 541 | |||
| 542 | return 0; | ||
| 543 | } | ||
| 544 | |||
| 545 | static int serdes_init_niu_10g_serdes(struct niu *np) | ||
| 546 | { | ||
| 547 | struct niu_link_config *lp = &np->link_config; | ||
| 548 | u32 tx_cfg, rx_cfg, pll_cfg, pll_sts; | ||
| 549 | int max_retry = 100; | ||
| 550 | u64 sig, mask, val; | ||
| 551 | unsigned long i; | ||
| 552 | int err; | ||
| 553 | |||
| 554 | tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV); | ||
| 555 | rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | | ||
| 556 | PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | | ||
| 557 | PLL_RX_CFG_EQ_LP_ADAPTIVE); | ||
| 558 | |||
| 559 | if (lp->loopback_mode == LOOPBACK_PHY) { | ||
| 560 | u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; | ||
| 561 | |||
| 562 | mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, | ||
| 563 | ESR2_TI_PLL_TEST_CFG_L, test_cfg); | ||
| 564 | |||
| 565 | tx_cfg |= PLL_TX_CFG_ENTEST; | ||
| 566 | rx_cfg |= PLL_RX_CFG_ENTEST; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* Initialize PLL for 10G */ | ||
| 570 | pll_cfg = (PLL_CFG_ENPLL | PLL_CFG_MPY_10X); | ||
| 571 | |||
| 572 | err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, | ||
| 573 | ESR2_TI_PLL_CFG_L, pll_cfg & 0xffff); | ||
| 574 | if (err) { | ||
| 575 | dev_err(np->device, PFX "NIU Port %d " | ||
| 576 | "serdes_init_niu_10g_serdes: " | ||
| 577 | "mdio write to ESR2_TI_PLL_CFG_L failed", np->port); | ||
| 578 | return err; | ||
| 579 | } | ||
| 580 | |||
| 581 | pll_sts = PLL_CFG_ENPLL; | ||
| 582 | |||
| 583 | err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, | ||
| 584 | ESR2_TI_PLL_STS_L, pll_sts & 0xffff); | ||
| 585 | if (err) { | ||
| 586 | dev_err(np->device, PFX "NIU Port %d " | ||
| 587 | "serdes_init_niu_10g_serdes: " | ||
| 588 | "mdio write to ESR2_TI_PLL_STS_L failed", np->port); | ||
| 589 | return err; | ||
| 590 | } | ||
| 591 | |||
| 592 | udelay(200); | ||
| 593 | |||
| 594 | /* Initialize all 4 lanes of the SERDES. */ | ||
| 595 | for (i = 0; i < 4; i++) { | ||
| 596 | err = esr2_set_tx_cfg(np, i, tx_cfg); | ||
| 597 | if (err) | ||
| 598 | return err; | ||
| 599 | } | ||
| 600 | |||
| 601 | for (i = 0; i < 4; i++) { | ||
| 602 | err = esr2_set_rx_cfg(np, i, rx_cfg); | ||
| 603 | if (err) | ||
| 604 | return err; | ||
| 605 | } | ||
| 606 | |||
| 607 | /* check if serdes is ready */ | ||
| 608 | |||
| 609 | switch (np->port) { | ||
| 610 | case 0: | ||
| 611 | mask = ESR_INT_SIGNALS_P0_BITS; | ||
| 612 | val = (ESR_INT_SRDY0_P0 | | ||
| 613 | ESR_INT_DET0_P0 | | ||
| 614 | ESR_INT_XSRDY_P0 | | ||
| 615 | ESR_INT_XDP_P0_CH3 | | ||
| 616 | ESR_INT_XDP_P0_CH2 | | ||
| 617 | ESR_INT_XDP_P0_CH1 | | ||
| 618 | ESR_INT_XDP_P0_CH0); | ||
| 619 | break; | ||
| 620 | |||
| 621 | case 1: | ||
| 622 | mask = ESR_INT_SIGNALS_P1_BITS; | ||
| 623 | val = (ESR_INT_SRDY0_P1 | | ||
| 624 | ESR_INT_DET0_P1 | | ||
| 625 | ESR_INT_XSRDY_P1 | | ||
| 626 | ESR_INT_XDP_P1_CH3 | | ||
| 627 | ESR_INT_XDP_P1_CH2 | | ||
| 628 | ESR_INT_XDP_P1_CH1 | | ||
| 629 | ESR_INT_XDP_P1_CH0); | ||
| 630 | break; | ||
| 631 | |||
| 632 | default: | ||
| 633 | return -EINVAL; | ||
| 634 | } | ||
| 635 | |||
| 636 | while (max_retry--) { | ||
| 637 | sig = nr64(ESR_INT_SIGNALS); | ||
| 638 | if ((sig & mask) == val) | ||
| 639 | break; | ||
| 640 | |||
| 641 | mdelay(500); | ||
| 642 | } | ||
| 643 | |||
| 644 | if ((sig & mask) != val) { | ||
| 645 | pr_info(PFX "NIU Port %u signal bits [%08x] are not " | ||
| 646 | "[%08x] for 10G...trying 1G\n", | ||
| 647 | np->port, (int) (sig & mask), (int) val); | ||
| 648 | |||
| 649 | /* 10G failed, try initializing at 1G */ | ||
| 650 | err = serdes_init_niu_1g_serdes(np); | ||
| 651 | if (!err) { | ||
| 652 | np->flags &= ~NIU_FLAGS_10G; | ||
| 653 | np->mac_xcvr = MAC_XCVR_PCS; | ||
| 654 | } else { | ||
| 655 | dev_err(np->device, PFX "Port %u 10G/1G SERDES " | ||
| 656 | "Link Failed \n", np->port); | ||
| 657 | return -ENODEV; | ||
| 658 | } | ||
| 659 | } | ||
| 660 | return 0; | ||
| 661 | } | ||
| 662 | |||
| 447 | static int esr_read_rxtx_ctrl(struct niu *np, unsigned long chan, u32 *val) | 663 | static int esr_read_rxtx_ctrl(struct niu *np, unsigned long chan, u32 *val) |
| 448 | { | 664 | { |
| 449 | int err; | 665 | int err; |
| @@ -1955,13 +2171,23 @@ static const struct niu_phy_ops phy_ops_10g_serdes = { | |||
| 1955 | .link_status = link_status_10g_serdes, | 2171 | .link_status = link_status_10g_serdes, |
| 1956 | }; | 2172 | }; |
| 1957 | 2173 | ||
| 2174 | static const struct niu_phy_ops phy_ops_10g_serdes_niu = { | ||
| 2175 | .serdes_init = serdes_init_niu_10g_serdes, | ||
| 2176 | .link_status = link_status_10g_serdes, | ||
| 2177 | }; | ||
| 2178 | |||
| 2179 | static const struct niu_phy_ops phy_ops_1g_serdes_niu = { | ||
| 2180 | .serdes_init = serdes_init_niu_1g_serdes, | ||
| 2181 | .link_status = link_status_1g_serdes, | ||
| 2182 | }; | ||
| 2183 | |||
| 1958 | static const struct niu_phy_ops phy_ops_1g_rgmii = { | 2184 | static const struct niu_phy_ops phy_ops_1g_rgmii = { |
| 1959 | .xcvr_init = xcvr_init_1g_rgmii, | 2185 | .xcvr_init = xcvr_init_1g_rgmii, |
| 1960 | .link_status = link_status_1g_rgmii, | 2186 | .link_status = link_status_1g_rgmii, |
| 1961 | }; | 2187 | }; |
| 1962 | 2188 | ||
| 1963 | static const struct niu_phy_ops phy_ops_10g_fiber_niu = { | 2189 | static const struct niu_phy_ops phy_ops_10g_fiber_niu = { |
| 1964 | .serdes_init = serdes_init_niu, | 2190 | .serdes_init = serdes_init_niu_10g_fiber, |
| 1965 | .xcvr_init = xcvr_init_10g, | 2191 | .xcvr_init = xcvr_init_10g, |
| 1966 | .link_status = link_status_10g, | 2192 | .link_status = link_status_10g, |
| 1967 | }; | 2193 | }; |
| @@ -1999,11 +2225,21 @@ struct niu_phy_template { | |||
| 1999 | u32 phy_addr_base; | 2225 | u32 phy_addr_base; |
| 2000 | }; | 2226 | }; |
| 2001 | 2227 | ||
| 2002 | static const struct niu_phy_template phy_template_niu = { | 2228 | static const struct niu_phy_template phy_template_niu_10g_fiber = { |
| 2003 | .ops = &phy_ops_10g_fiber_niu, | 2229 | .ops = &phy_ops_10g_fiber_niu, |
| 2004 | .phy_addr_base = 16, | 2230 | .phy_addr_base = 16, |
| 2005 | }; | 2231 | }; |
| 2006 | 2232 | ||
| 2233 | static const struct niu_phy_template phy_template_niu_10g_serdes = { | ||
| 2234 | .ops = &phy_ops_10g_serdes_niu, | ||
| 2235 | .phy_addr_base = 0, | ||
| 2236 | }; | ||
| 2237 | |||
| 2238 | static const struct niu_phy_template phy_template_niu_1g_serdes = { | ||
| 2239 | .ops = &phy_ops_1g_serdes_niu, | ||
| 2240 | .phy_addr_base = 0, | ||
| 2241 | }; | ||
| 2242 | |||
| 2007 | static const struct niu_phy_template phy_template_10g_fiber = { | 2243 | static const struct niu_phy_template phy_template_10g_fiber = { |
| 2008 | .ops = &phy_ops_10g_fiber, | 2244 | .ops = &phy_ops_10g_fiber, |
| 2009 | .phy_addr_base = 8, | 2245 | .phy_addr_base = 8, |
| @@ -2183,8 +2419,25 @@ static int niu_determine_phy_disposition(struct niu *np) | |||
| 2183 | u32 phy_addr_off = 0; | 2419 | u32 phy_addr_off = 0; |
| 2184 | 2420 | ||
| 2185 | if (plat_type == PLAT_TYPE_NIU) { | 2421 | if (plat_type == PLAT_TYPE_NIU) { |
| 2186 | tp = &phy_template_niu; | 2422 | switch (np->flags & |
| 2187 | phy_addr_off += np->port; | 2423 | (NIU_FLAGS_10G | |
| 2424 | NIU_FLAGS_FIBER | | ||
| 2425 | NIU_FLAGS_XCVR_SERDES)) { | ||
| 2426 | case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: | ||
| 2427 | /* 10G Serdes */ | ||
| 2428 | tp = &phy_template_niu_10g_serdes; | ||
| 2429 | break; | ||
| 2430 | case NIU_FLAGS_XCVR_SERDES: | ||
| 2431 | /* 1G Serdes */ | ||
| 2432 | tp = &phy_template_niu_1g_serdes; | ||
| 2433 | break; | ||
| 2434 | case NIU_FLAGS_10G | NIU_FLAGS_FIBER: | ||
| 2435 | /* 10G Fiber */ | ||
| 2436 | default: | ||
| 2437 | tp = &phy_template_niu_10g_fiber; | ||
| 2438 | phy_addr_off += np->port; | ||
| 2439 | break; | ||
| 2440 | } | ||
| 2188 | } else { | 2441 | } else { |
| 2189 | switch (np->flags & | 2442 | switch (np->flags & |
| 2190 | (NIU_FLAGS_10G | | 2443 | (NIU_FLAGS_10G | |
| @@ -7214,6 +7467,12 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np, | |||
| 7214 | np->flags |= NIU_FLAGS_10G; | 7467 | np->flags |= NIU_FLAGS_10G; |
| 7215 | np->flags &= ~NIU_FLAGS_FIBER; | 7468 | np->flags &= ~NIU_FLAGS_FIBER; |
| 7216 | np->mac_xcvr = MAC_XCVR_XPCS; | 7469 | np->mac_xcvr = MAC_XCVR_XPCS; |
| 7470 | } else if (!strcmp(phy_prop, "xgsd") || !strcmp(phy_prop, "gsd")) { | ||
| 7471 | /* 10G Serdes or 1G Serdes, default to 10G */ | ||
| 7472 | np->flags |= NIU_FLAGS_10G; | ||
| 7473 | np->flags &= ~NIU_FLAGS_FIBER; | ||
| 7474 | np->flags |= NIU_FLAGS_XCVR_SERDES; | ||
| 7475 | np->mac_xcvr = MAC_XCVR_XPCS; | ||
| 7217 | } else { | 7476 | } else { |
| 7218 | return -EINVAL; | 7477 | return -EINVAL; |
| 7219 | } | 7478 | } |
| @@ -7742,6 +8001,8 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
| 7742 | u32 val; | 8001 | u32 val; |
| 7743 | int err; | 8002 | int err; |
| 7744 | 8003 | ||
| 8004 | num_10g = num_1g = 0; | ||
| 8005 | |||
| 7745 | if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || | 8006 | if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || |
| 7746 | !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { | 8007 | !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { |
| 7747 | num_10g = 0; | 8008 | num_10g = 0; |
| @@ -7758,6 +8019,16 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
| 7758 | parent->num_ports = 2; | 8019 | parent->num_ports = 2; |
| 7759 | val = (phy_encode(PORT_TYPE_10G, 0) | | 8020 | val = (phy_encode(PORT_TYPE_10G, 0) | |
| 7760 | phy_encode(PORT_TYPE_10G, 1)); | 8021 | phy_encode(PORT_TYPE_10G, 1)); |
| 8022 | } else if ((np->flags & NIU_FLAGS_XCVR_SERDES) && | ||
| 8023 | (parent->plat_type == PLAT_TYPE_NIU)) { | ||
| 8024 | /* this is the Monza case */ | ||
| 8025 | if (np->flags & NIU_FLAGS_10G) { | ||
| 8026 | val = (phy_encode(PORT_TYPE_10G, 0) | | ||
| 8027 | phy_encode(PORT_TYPE_10G, 1)); | ||
| 8028 | } else { | ||
| 8029 | val = (phy_encode(PORT_TYPE_1G, 0) | | ||
| 8030 | phy_encode(PORT_TYPE_1G, 1)); | ||
| 8031 | } | ||
| 7761 | } else { | 8032 | } else { |
| 7762 | err = fill_phy_probe_info(np, parent, info); | 8033 | err = fill_phy_probe_info(np, parent, info); |
| 7763 | if (err) | 8034 | if (err) |
| @@ -8657,7 +8928,9 @@ static void __devinit niu_device_announce(struct niu *np) | |||
| 8657 | dev->name, | 8928 | dev->name, |
| 8658 | (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), | 8929 | (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), |
| 8659 | (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), | 8930 | (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), |
| 8660 | (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), | 8931 | (np->flags & NIU_FLAGS_FIBER ? "FIBER" : |
| 8932 | (np->flags & NIU_FLAGS_XCVR_SERDES ? "SERDES" : | ||
| 8933 | "COPPER")), | ||
| 8661 | (np->mac_xcvr == MAC_XCVR_MII ? "MII" : | 8934 | (np->mac_xcvr == MAC_XCVR_MII ? "MII" : |
| 8662 | (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), | 8935 | (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), |
| 8663 | np->vpd.phy_type); | 8936 | np->vpd.phy_type); |
| @@ -8667,7 +8940,6 @@ static void __devinit niu_device_announce(struct niu *np) | |||
| 8667 | static int __devinit niu_pci_init_one(struct pci_dev *pdev, | 8940 | static int __devinit niu_pci_init_one(struct pci_dev *pdev, |
| 8668 | const struct pci_device_id *ent) | 8941 | const struct pci_device_id *ent) |
| 8669 | { | 8942 | { |
| 8670 | unsigned long niureg_base, niureg_len; | ||
| 8671 | union niu_parent_id parent_id; | 8943 | union niu_parent_id parent_id; |
| 8672 | struct net_device *dev; | 8944 | struct net_device *dev; |
| 8673 | struct niu *np; | 8945 | struct niu *np; |
| @@ -8758,10 +9030,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, | |||
| 8758 | 9030 | ||
| 8759 | dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); | 9031 | dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); |
| 8760 | 9032 | ||
| 8761 | niureg_base = pci_resource_start(pdev, 0); | 9033 | np->regs = pci_ioremap_bar(pdev, 0); |
| 8762 | niureg_len = pci_resource_len(pdev, 0); | ||
| 8763 | |||
| 8764 | np->regs = ioremap_nocache(niureg_base, niureg_len); | ||
| 8765 | if (!np->regs) { | 9034 | if (!np->regs) { |
| 8766 | dev_err(&pdev->dev, PFX "Cannot map device registers, " | 9035 | dev_err(&pdev->dev, PFX "Cannot map device registers, " |
| 8767 | "aborting.\n"); | 9036 | "aborting.\n"); |
diff --git a/drivers/net/niu.h b/drivers/net/niu.h index c6fa883daa22..180ca8ae93de 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h | |||
| @@ -1048,6 +1048,13 @@ | |||
| 1048 | #define PLL_CFG_LD_SHIFT 8 | 1048 | #define PLL_CFG_LD_SHIFT 8 |
| 1049 | #define PLL_CFG_MPY 0x0000001e | 1049 | #define PLL_CFG_MPY 0x0000001e |
| 1050 | #define PLL_CFG_MPY_SHIFT 1 | 1050 | #define PLL_CFG_MPY_SHIFT 1 |
| 1051 | #define PLL_CFG_MPY_4X 0x0 | ||
| 1052 | #define PLL_CFG_MPY_5X 0x00000002 | ||
| 1053 | #define PLL_CFG_MPY_6X 0x00000004 | ||
| 1054 | #define PLL_CFG_MPY_8X 0x00000008 | ||
| 1055 | #define PLL_CFG_MPY_10X 0x0000000a | ||
| 1056 | #define PLL_CFG_MPY_12X 0x0000000c | ||
| 1057 | #define PLL_CFG_MPY_12P5X 0x0000000e | ||
| 1051 | #define PLL_CFG_ENPLL 0x00000001 | 1058 | #define PLL_CFG_ENPLL 0x00000001 |
| 1052 | 1059 | ||
| 1053 | #define ESR2_TI_PLL_STS_L (ESR2_BASE + 0x002) | 1060 | #define ESR2_TI_PLL_STS_L (ESR2_BASE + 0x002) |
| @@ -1093,6 +1100,9 @@ | |||
| 1093 | #define PLL_TX_CFG_INVPAIR 0x00000080 | 1100 | #define PLL_TX_CFG_INVPAIR 0x00000080 |
| 1094 | #define PLL_TX_CFG_RATE 0x00000060 | 1101 | #define PLL_TX_CFG_RATE 0x00000060 |
| 1095 | #define PLL_TX_CFG_RATE_SHIFT 5 | 1102 | #define PLL_TX_CFG_RATE_SHIFT 5 |
| 1103 | #define PLL_TX_CFG_RATE_FULL 0x0 | ||
| 1104 | #define PLL_TX_CFG_RATE_HALF 0x20 | ||
| 1105 | #define PLL_TX_CFG_RATE_QUAD 0x40 | ||
| 1096 | #define PLL_TX_CFG_BUSWIDTH 0x0000001c | 1106 | #define PLL_TX_CFG_BUSWIDTH 0x0000001c |
| 1097 | #define PLL_TX_CFG_BUSWIDTH_SHIFT 2 | 1107 | #define PLL_TX_CFG_BUSWIDTH_SHIFT 2 |
| 1098 | #define PLL_TX_CFG_ENTEST 0x00000002 | 1108 | #define PLL_TX_CFG_ENTEST 0x00000002 |
| @@ -1132,6 +1142,9 @@ | |||
| 1132 | #define PLL_RX_CFG_INVPAIR 0x00000080 | 1142 | #define PLL_RX_CFG_INVPAIR 0x00000080 |
| 1133 | #define PLL_RX_CFG_RATE 0x00000060 | 1143 | #define PLL_RX_CFG_RATE 0x00000060 |
| 1134 | #define PLL_RX_CFG_RATE_SHIFT 5 | 1144 | #define PLL_RX_CFG_RATE_SHIFT 5 |
| 1145 | #define PLL_RX_CFG_RATE_FULL 0x0 | ||
| 1146 | #define PLL_RX_CFG_RATE_HALF 0x20 | ||
| 1147 | #define PLL_RX_CFG_RATE_QUAD 0x40 | ||
| 1135 | #define PLL_RX_CFG_BUSWIDTH 0x0000001c | 1148 | #define PLL_RX_CFG_BUSWIDTH 0x0000001c |
| 1136 | #define PLL_RX_CFG_BUSWIDTH_SHIFT 2 | 1149 | #define PLL_RX_CFG_BUSWIDTH_SHIFT 2 |
| 1137 | #define PLL_RX_CFG_ENTEST 0x00000002 | 1150 | #define PLL_RX_CFG_ENTEST 0x00000002 |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index b37a498939ae..0418045166c3 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
| @@ -779,6 +779,7 @@ static struct pcmcia_device_id axnet_ids[] = { | |||
| 779 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2), | 779 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2), |
| 780 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8), | 780 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8), |
| 781 | PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609), | 781 | PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609), |
| 782 | PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875), | ||
| 782 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04), | 783 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04), |
| 783 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116), | 784 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116), |
| 784 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058), | 785 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058), |
| @@ -1174,7 +1175,6 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1174 | * ax_interrupt - handle the interrupts from an 8390 | 1175 | * ax_interrupt - handle the interrupts from an 8390 |
| 1175 | * @irq: interrupt number | 1176 | * @irq: interrupt number |
| 1176 | * @dev_id: a pointer to the net_device | 1177 | * @dev_id: a pointer to the net_device |
| 1177 | * @regs: unused | ||
| 1178 | * | 1178 | * |
| 1179 | * Handle the ether interface interrupts. We pull packets from | 1179 | * Handle the ether interface interrupts. We pull packets from |
| 1180 | * the 8390 via the card specific functions and fire them at the networking | 1180 | * the 8390 via the card specific functions and fire them at the networking |
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index cf3cca4642f2..f51944b28cfa 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c | |||
| @@ -349,7 +349,7 @@ static int ibmtr_suspend(struct pcmcia_device *link) | |||
| 349 | return 0; | 349 | return 0; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static int ibmtr_resume(struct pcmcia_device *link) | 352 | static int __devinit ibmtr_resume(struct pcmcia_device *link) |
| 353 | { | 353 | { |
| 354 | ibmtr_dev_t *info = link->priv; | 354 | ibmtr_dev_t *info = link->priv; |
| 355 | struct net_device *dev = info->dev; | 355 | struct net_device *dev = info->dev; |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index e40d6301aa7a..ce486f094492 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
| @@ -1693,7 +1693,6 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
| 1693 | PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8), | 1693 | PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8), |
| 1694 | PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76), | 1694 | PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76), |
| 1695 | PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e), | 1695 | PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e), |
| 1696 | PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875), | ||
| 1697 | PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f), | 1696 | PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f), |
| 1698 | PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1), | 1697 | PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1), |
| 1699 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b), | 1698 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b), |
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 4aa547947040..eb6411c4694f 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
| @@ -227,6 +227,59 @@ static int m88e1111_config_init(struct phy_device *phydev) | |||
| 227 | return 0; | 227 | return 0; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | static int m88e1118_config_aneg(struct phy_device *phydev) | ||
| 231 | { | ||
| 232 | int err; | ||
| 233 | |||
| 234 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
| 235 | if (err < 0) | ||
| 236 | return err; | ||
| 237 | |||
| 238 | err = phy_write(phydev, MII_M1011_PHY_SCR, | ||
| 239 | MII_M1011_PHY_SCR_AUTO_CROSS); | ||
| 240 | if (err < 0) | ||
| 241 | return err; | ||
| 242 | |||
| 243 | err = genphy_config_aneg(phydev); | ||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int m88e1118_config_init(struct phy_device *phydev) | ||
| 248 | { | ||
| 249 | int err; | ||
| 250 | |||
| 251 | /* Change address */ | ||
| 252 | err = phy_write(phydev, 0x16, 0x0002); | ||
| 253 | if (err < 0) | ||
| 254 | return err; | ||
| 255 | |||
| 256 | /* Enable 1000 Mbit */ | ||
| 257 | err = phy_write(phydev, 0x15, 0x1070); | ||
| 258 | if (err < 0) | ||
| 259 | return err; | ||
| 260 | |||
| 261 | /* Change address */ | ||
| 262 | err = phy_write(phydev, 0x16, 0x0003); | ||
| 263 | if (err < 0) | ||
| 264 | return err; | ||
| 265 | |||
| 266 | /* Adjust LED Control */ | ||
| 267 | err = phy_write(phydev, 0x10, 0x021e); | ||
| 268 | if (err < 0) | ||
| 269 | return err; | ||
| 270 | |||
| 271 | /* Reset address */ | ||
| 272 | err = phy_write(phydev, 0x16, 0x0); | ||
| 273 | if (err < 0) | ||
| 274 | return err; | ||
| 275 | |||
| 276 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
| 277 | if (err < 0) | ||
| 278 | return err; | ||
| 279 | |||
| 280 | return 0; | ||
| 281 | } | ||
| 282 | |||
| 230 | static int m88e1145_config_init(struct phy_device *phydev) | 283 | static int m88e1145_config_init(struct phy_device *phydev) |
| 231 | { | 284 | { |
| 232 | int err; | 285 | int err; |
| @@ -416,6 +469,19 @@ static struct phy_driver marvell_drivers[] = { | |||
| 416 | .driver = { .owner = THIS_MODULE }, | 469 | .driver = { .owner = THIS_MODULE }, |
| 417 | }, | 470 | }, |
| 418 | { | 471 | { |
| 472 | .phy_id = 0x01410e10, | ||
| 473 | .phy_id_mask = 0xfffffff0, | ||
| 474 | .name = "Marvell 88E1118", | ||
| 475 | .features = PHY_GBIT_FEATURES, | ||
| 476 | .flags = PHY_HAS_INTERRUPT, | ||
| 477 | .config_init = &m88e1118_config_init, | ||
| 478 | .config_aneg = &m88e1118_config_aneg, | ||
| 479 | .read_status = &genphy_read_status, | ||
| 480 | .ack_interrupt = &marvell_ack_interrupt, | ||
| 481 | .config_intr = &marvell_config_intr, | ||
| 482 | .driver = {.owner = THIS_MODULE,}, | ||
| 483 | }, | ||
| 484 | { | ||
| 419 | .phy_id = 0x01410cd0, | 485 | .phy_id = 0x01410cd0, |
| 420 | .phy_id_mask = 0xfffffff0, | 486 | .phy_id_mask = 0xfffffff0, |
| 421 | .name = "Marvell 88E1145", | 487 | .name = "Marvell 88E1145", |
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index d0ed1ef284a8..536bda1f428b 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
| @@ -136,7 +136,7 @@ void mdiobus_unregister(struct mii_bus *bus) | |||
| 136 | BUG_ON(bus->state != MDIOBUS_REGISTERED); | 136 | BUG_ON(bus->state != MDIOBUS_REGISTERED); |
| 137 | bus->state = MDIOBUS_UNREGISTERED; | 137 | bus->state = MDIOBUS_UNREGISTERED; |
| 138 | 138 | ||
| 139 | device_unregister(&bus->dev); | 139 | device_del(&bus->dev); |
| 140 | for (i = 0; i < PHY_MAX_ADDR; i++) { | 140 | for (i = 0; i < PHY_MAX_ADDR; i++) { |
| 141 | if (bus->phy_map[i]) | 141 | if (bus->phy_map[i]) |
| 142 | device_unregister(&bus->phy_map[i]->dev); | 142 | device_unregister(&bus->phy_map[i]->dev); |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e11b03b2b25a..25acbbde4a60 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -227,8 +227,17 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) | |||
| 227 | if (r) | 227 | if (r) |
| 228 | return ERR_PTR(r); | 228 | return ERR_PTR(r); |
| 229 | 229 | ||
| 230 | /* If the phy_id is all Fs, there is no device there */ | 230 | /* If the phy_id is mostly Fs, there is no device there */ |
| 231 | if (0xffffffff == phy_id) | 231 | if ((phy_id & 0x1fffffff) == 0x1fffffff) |
| 232 | return NULL; | ||
| 233 | |||
| 234 | /* | ||
| 235 | * Broken hardware is sometimes missing the pull down resistor on the | ||
| 236 | * MDIO line, which results in reads to non-existent devices returning | ||
| 237 | * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent | ||
| 238 | * device as well. | ||
| 239 | */ | ||
| 240 | if (phy_id == 0) | ||
| 232 | return NULL; | 241 | return NULL; |
| 233 | 242 | ||
| 234 | dev = phy_device_create(bus, addr, phy_id); | 243 | dev = phy_device_create(bus, addr, phy_id); |
| @@ -564,20 +573,32 @@ EXPORT_SYMBOL(genphy_restart_aneg); | |||
| 564 | */ | 573 | */ |
| 565 | int genphy_config_aneg(struct phy_device *phydev) | 574 | int genphy_config_aneg(struct phy_device *phydev) |
| 566 | { | 575 | { |
| 567 | int result = 0; | 576 | int result; |
| 568 | 577 | ||
| 569 | if (AUTONEG_ENABLE == phydev->autoneg) { | 578 | if (AUTONEG_ENABLE != phydev->autoneg) |
| 570 | int result = genphy_config_advert(phydev); | 579 | return genphy_setup_forced(phydev); |
| 571 | 580 | ||
| 572 | if (result < 0) /* error */ | 581 | result = genphy_config_advert(phydev); |
| 573 | return result; | 582 | |
| 583 | if (result < 0) /* error */ | ||
| 584 | return result; | ||
| 585 | |||
| 586 | if (result == 0) { | ||
| 587 | /* Advertisment hasn't changed, but maybe aneg was never on to | ||
| 588 | * begin with? Or maybe phy was isolated? */ | ||
| 589 | int ctl = phy_read(phydev, MII_BMCR); | ||
| 590 | |||
| 591 | if (ctl < 0) | ||
| 592 | return ctl; | ||
| 593 | |||
| 594 | if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) | ||
| 595 | result = 1; /* do restart aneg */ | ||
| 596 | } | ||
| 574 | 597 | ||
| 575 | /* Only restart aneg if we are advertising something different | 598 | /* Only restart aneg if we are advertising something different |
| 576 | * than we were before. */ | 599 | * than we were before. */ |
| 577 | if (result > 0) | 600 | if (result > 0) |
| 578 | result = genphy_restart_aneg(phydev); | 601 | result = genphy_restart_aneg(phydev); |
| 579 | } else | ||
| 580 | result = genphy_setup_forced(phydev); | ||
| 581 | 602 | ||
| 582 | return result; | 603 | return result; |
| 583 | } | 604 | } |
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 8874497b6bbf..dd3b2447e85a 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #define MII_VSC8244_IMASK_DUPLEX 0x1000 | 34 | #define MII_VSC8244_IMASK_DUPLEX 0x1000 |
| 35 | #define MII_VSC8244_IMASK_MASK 0xf000 | 35 | #define MII_VSC8244_IMASK_MASK 0xf000 |
| 36 | 36 | ||
| 37 | #define MII_VSC8221_IMASK_MASK 0xa000 | ||
| 38 | |||
| 37 | /* Vitesse Interrupt Status Register */ | 39 | /* Vitesse Interrupt Status Register */ |
| 38 | #define MII_VSC8244_ISTAT 0x1a | 40 | #define MII_VSC8244_ISTAT 0x1a |
| 39 | #define MII_VSC8244_ISTAT_STATUS 0x8000 | 41 | #define MII_VSC8244_ISTAT_STATUS 0x8000 |
| @@ -49,6 +51,12 @@ | |||
| 49 | #define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 | 51 | #define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 |
| 50 | #define MII_VSC8244_AUXCONSTAT_100 0x0008 | 52 | #define MII_VSC8244_AUXCONSTAT_100 0x0008 |
| 51 | 53 | ||
| 54 | #define MII_VSC8221_AUXCONSTAT_INIT 0x0004 /* need to set this bit? */ | ||
| 55 | #define MII_VSC8221_AUXCONSTAT_RESERVED 0x0004 | ||
| 56 | |||
| 57 | #define PHY_ID_VSC8244 0x000fc6c0 | ||
| 58 | #define PHY_ID_VSC8221 0x000fc550 | ||
| 59 | |||
| 52 | MODULE_DESCRIPTION("Vitesse PHY driver"); | 60 | MODULE_DESCRIPTION("Vitesse PHY driver"); |
| 53 | MODULE_AUTHOR("Kriston Carson"); | 61 | MODULE_AUTHOR("Kriston Carson"); |
| 54 | MODULE_LICENSE("GPL"); | 62 | MODULE_LICENSE("GPL"); |
| @@ -95,13 +103,15 @@ static int vsc824x_ack_interrupt(struct phy_device *phydev) | |||
| 95 | return (err < 0) ? err : 0; | 103 | return (err < 0) ? err : 0; |
| 96 | } | 104 | } |
| 97 | 105 | ||
| 98 | static int vsc824x_config_intr(struct phy_device *phydev) | 106 | static int vsc82xx_config_intr(struct phy_device *phydev) |
| 99 | { | 107 | { |
| 100 | int err; | 108 | int err; |
| 101 | 109 | ||
| 102 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | 110 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
| 103 | err = phy_write(phydev, MII_VSC8244_IMASK, | 111 | err = phy_write(phydev, MII_VSC8244_IMASK, |
| 104 | MII_VSC8244_IMASK_MASK); | 112 | phydev->drv->phy_id == PHY_ID_VSC8244 ? |
| 113 | MII_VSC8244_IMASK_MASK : | ||
| 114 | MII_VSC8221_IMASK_MASK); | ||
| 105 | else { | 115 | else { |
| 106 | /* | 116 | /* |
| 107 | * The Vitesse PHY cannot clear the interrupt | 117 | * The Vitesse PHY cannot clear the interrupt |
| @@ -120,7 +130,7 @@ static int vsc824x_config_intr(struct phy_device *phydev) | |||
| 120 | 130 | ||
| 121 | /* Vitesse 824x */ | 131 | /* Vitesse 824x */ |
| 122 | static struct phy_driver vsc8244_driver = { | 132 | static struct phy_driver vsc8244_driver = { |
| 123 | .phy_id = 0x000fc6c0, | 133 | .phy_id = PHY_ID_VSC8244, |
| 124 | .name = "Vitesse VSC8244", | 134 | .name = "Vitesse VSC8244", |
| 125 | .phy_id_mask = 0x000fffc0, | 135 | .phy_id_mask = 0x000fffc0, |
| 126 | .features = PHY_GBIT_FEATURES, | 136 | .features = PHY_GBIT_FEATURES, |
| @@ -129,19 +139,55 @@ static struct phy_driver vsc8244_driver = { | |||
| 129 | .config_aneg = &genphy_config_aneg, | 139 | .config_aneg = &genphy_config_aneg, |
| 130 | .read_status = &genphy_read_status, | 140 | .read_status = &genphy_read_status, |
| 131 | .ack_interrupt = &vsc824x_ack_interrupt, | 141 | .ack_interrupt = &vsc824x_ack_interrupt, |
| 132 | .config_intr = &vsc824x_config_intr, | 142 | .config_intr = &vsc82xx_config_intr, |
| 133 | .driver = { .owner = THIS_MODULE,}, | 143 | .driver = { .owner = THIS_MODULE,}, |
| 134 | }; | 144 | }; |
| 135 | 145 | ||
| 136 | static int __init vsc8244_init(void) | 146 | static int vsc8221_config_init(struct phy_device *phydev) |
| 137 | { | 147 | { |
| 138 | return phy_driver_register(&vsc8244_driver); | 148 | int err; |
| 149 | |||
| 150 | err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, | ||
| 151 | MII_VSC8221_AUXCONSTAT_INIT); | ||
| 152 | return err; | ||
| 153 | |||
| 154 | /* Perhaps we should set EXT_CON1 based on the interface? | ||
| 155 | Options are 802.3Z SerDes or SGMII */ | ||
| 156 | } | ||
| 157 | |||
| 158 | /* Vitesse 8221 */ | ||
| 159 | static struct phy_driver vsc8221_driver = { | ||
| 160 | .phy_id = PHY_ID_VSC8221, | ||
| 161 | .phy_id_mask = 0x000ffff0, | ||
| 162 | .name = "Vitesse VSC8221", | ||
| 163 | .features = PHY_GBIT_FEATURES, | ||
| 164 | .flags = PHY_HAS_INTERRUPT, | ||
| 165 | .config_init = &vsc8221_config_init, | ||
| 166 | .config_aneg = &genphy_config_aneg, | ||
| 167 | .read_status = &genphy_read_status, | ||
| 168 | .ack_interrupt = &vsc824x_ack_interrupt, | ||
| 169 | .config_intr = &vsc82xx_config_intr, | ||
| 170 | .driver = { .owner = THIS_MODULE,}, | ||
| 171 | }; | ||
| 172 | |||
| 173 | static int __init vsc82xx_init(void) | ||
| 174 | { | ||
| 175 | int err; | ||
| 176 | |||
| 177 | err = phy_driver_register(&vsc8244_driver); | ||
| 178 | if (err < 0) | ||
| 179 | return err; | ||
| 180 | err = phy_driver_register(&vsc8221_driver); | ||
| 181 | if (err < 0) | ||
| 182 | phy_driver_unregister(&vsc8244_driver); | ||
| 183 | return err; | ||
| 139 | } | 184 | } |
| 140 | 185 | ||
| 141 | static void __exit vsc8244_exit(void) | 186 | static void __exit vsc82xx_exit(void) |
| 142 | { | 187 | { |
| 143 | phy_driver_unregister(&vsc8244_driver); | 188 | phy_driver_unregister(&vsc8244_driver); |
| 189 | phy_driver_unregister(&vsc8221_driver); | ||
| 144 | } | 190 | } |
| 145 | 191 | ||
| 146 | module_init(vsc8244_init); | 192 | module_init(vsc82xx_init); |
| 147 | module_exit(vsc8244_exit); | 193 | module_exit(vsc82xx_exit); |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index fc6f4b8c64b3..b646e92134dc 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
| @@ -399,11 +399,11 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
| 399 | if (skb->len < len) | 399 | if (skb->len < len) |
| 400 | goto drop; | 400 | goto drop; |
| 401 | 401 | ||
| 402 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | 402 | if (pskb_trim_rcsum(skb, len)) |
| 403 | if (!po) | ||
| 404 | goto drop; | 403 | goto drop; |
| 405 | 404 | ||
| 406 | if (pskb_trim_rcsum(skb, len)) | 405 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); |
| 406 | if (!po) | ||
| 407 | goto drop; | 407 | goto drop; |
| 408 | 408 | ||
| 409 | return sk_receive_skb(sk_pppox(po), skb, 0); | 409 | return sk_receive_skb(sk_pppox(po), skb, 0); |
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 185b1dff10a8..e98d9773158d 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
| @@ -1353,6 +1353,7 @@ static int pppol2tp_release(struct socket *sock) | |||
| 1353 | kfree_skb(skb); | 1353 | kfree_skb(skb); |
| 1354 | sock_put(sk); | 1354 | sock_put(sk); |
| 1355 | } | 1355 | } |
| 1356 | sock_put(sk); | ||
| 1356 | } | 1357 | } |
| 1357 | 1358 | ||
| 1358 | release_sock(sk); | 1359 | release_sock(sk); |
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 3cdd07c45b6d..508452c02151 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c | |||
| @@ -1515,9 +1515,6 @@ static u32 ql_get_link_state(struct ql3_adapter *qdev) | |||
| 1515 | linkState = LS_UP; | 1515 | linkState = LS_UP; |
| 1516 | } else { | 1516 | } else { |
| 1517 | linkState = LS_DOWN; | 1517 | linkState = LS_DOWN; |
| 1518 | if (netif_msg_link(qdev)) | ||
| 1519 | printk(KERN_WARNING PFX | ||
| 1520 | "%s: Link is down.\n", qdev->ndev->name); | ||
| 1521 | } | 1518 | } |
| 1522 | return linkState; | 1519 | return linkState; |
| 1523 | } | 1520 | } |
| @@ -1581,10 +1578,6 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev) | |||
| 1581 | ql_mac_enable(qdev, 1); | 1578 | ql_mac_enable(qdev, 1); |
| 1582 | } | 1579 | } |
| 1583 | 1580 | ||
| 1584 | if (netif_msg_link(qdev)) | ||
| 1585 | printk(KERN_DEBUG PFX | ||
| 1586 | "%s: Change port_link_state LS_DOWN to LS_UP.\n", | ||
| 1587 | qdev->ndev->name); | ||
| 1588 | qdev->port_link_state = LS_UP; | 1581 | qdev->port_link_state = LS_UP; |
| 1589 | netif_start_queue(qdev->ndev); | 1582 | netif_start_queue(qdev->ndev); |
| 1590 | netif_carrier_on(qdev->ndev); | 1583 | netif_carrier_on(qdev->ndev); |
| @@ -1655,14 +1648,9 @@ static void ql_link_state_machine_work(struct work_struct *work) | |||
| 1655 | /* Fall Through */ | 1648 | /* Fall Through */ |
| 1656 | 1649 | ||
| 1657 | case LS_DOWN: | 1650 | case LS_DOWN: |
| 1658 | if (netif_msg_link(qdev)) | ||
| 1659 | printk(KERN_DEBUG PFX | ||
| 1660 | "%s: port_link_state = LS_DOWN.\n", | ||
| 1661 | qdev->ndev->name); | ||
| 1662 | if (curr_link_state == LS_UP) { | 1651 | if (curr_link_state == LS_UP) { |
| 1663 | if (netif_msg_link(qdev)) | 1652 | if (netif_msg_link(qdev)) |
| 1664 | printk(KERN_DEBUG PFX | 1653 | printk(KERN_INFO PFX "%s: Link is up.\n", |
| 1665 | "%s: curr_link_state = LS_UP.\n", | ||
| 1666 | qdev->ndev->name); | 1654 | qdev->ndev->name); |
| 1667 | if (ql_is_auto_neg_complete(qdev)) | 1655 | if (ql_is_auto_neg_complete(qdev)) |
| 1668 | ql_finish_auto_neg(qdev); | 1656 | ql_finish_auto_neg(qdev); |
| @@ -1670,6 +1658,7 @@ static void ql_link_state_machine_work(struct work_struct *work) | |||
| 1670 | if (qdev->port_link_state == LS_UP) | 1658 | if (qdev->port_link_state == LS_UP) |
| 1671 | ql_link_down_detect_clear(qdev); | 1659 | ql_link_down_detect_clear(qdev); |
| 1672 | 1660 | ||
| 1661 | qdev->port_link_state = LS_UP; | ||
| 1673 | } | 1662 | } |
| 1674 | break; | 1663 | break; |
| 1675 | 1664 | ||
| @@ -1678,12 +1667,14 @@ static void ql_link_state_machine_work(struct work_struct *work) | |||
| 1678 | * See if the link is currently down or went down and came | 1667 | * See if the link is currently down or went down and came |
| 1679 | * back up | 1668 | * back up |
| 1680 | */ | 1669 | */ |
| 1681 | if ((curr_link_state == LS_DOWN) || ql_link_down_detect(qdev)) { | 1670 | if (curr_link_state == LS_DOWN) { |
| 1682 | if (netif_msg_link(qdev)) | 1671 | if (netif_msg_link(qdev)) |
| 1683 | printk(KERN_INFO PFX "%s: Link is down.\n", | 1672 | printk(KERN_INFO PFX "%s: Link is down.\n", |
| 1684 | qdev->ndev->name); | 1673 | qdev->ndev->name); |
| 1685 | qdev->port_link_state = LS_DOWN; | 1674 | qdev->port_link_state = LS_DOWN; |
| 1686 | } | 1675 | } |
| 1676 | if (ql_link_down_detect(qdev)) | ||
| 1677 | qdev->port_link_state = LS_DOWN; | ||
| 1687 | break; | 1678 | break; |
| 1688 | } | 1679 | } |
| 1689 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | 1680 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index fa98af58223e..cd0d0873d978 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
| @@ -174,8 +174,8 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { | |||
| 174 | 174 | ||
| 175 | /* EEPROM range with gPXE configuration */ | 175 | /* EEPROM range with gPXE configuration */ |
| 176 | #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB | 176 | #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB |
| 177 | #define EFX_ETHTOOL_EEPROM_MIN 0x100U | 177 | #define EFX_ETHTOOL_EEPROM_MIN 0x800U |
| 178 | #define EFX_ETHTOOL_EEPROM_MAX 0x400U | 178 | #define EFX_ETHTOOL_EEPROM_MAX 0x1800U |
| 179 | 179 | ||
| 180 | /************************************************************************** | 180 | /************************************************************************** |
| 181 | * | 181 | * |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index a24bb68887ab..59f242a67714 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
| @@ -927,7 +927,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 927 | struct sh_eth_private *mdp = netdev_priv(ndev); | 927 | struct sh_eth_private *mdp = netdev_priv(ndev); |
| 928 | struct sh_eth_txdesc *txdesc; | 928 | struct sh_eth_txdesc *txdesc; |
| 929 | u32 entry; | 929 | u32 entry; |
| 930 | int flags; | 930 | unsigned long flags; |
| 931 | 931 | ||
| 932 | spin_lock_irqsave(&mdp->lock, flags); | 932 | spin_lock_irqsave(&mdp->lock, flags); |
| 933 | if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) { | 933 | if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) { |
| @@ -1141,7 +1141,7 @@ static int sh_mdio_init(struct net_device *ndev, int id) | |||
| 1141 | /* Hook up MII support for ethtool */ | 1141 | /* Hook up MII support for ethtool */ |
| 1142 | mdp->mii_bus->name = "sh_mii"; | 1142 | mdp->mii_bus->name = "sh_mii"; |
| 1143 | mdp->mii_bus->parent = &ndev->dev; | 1143 | mdp->mii_bus->parent = &ndev->dev; |
| 1144 | mdp->mii_bus->id[0] = id; | 1144 | snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%x", id); |
| 1145 | 1145 | ||
| 1146 | /* PHY IRQ */ | 1146 | /* PHY IRQ */ |
| 1147 | mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 1147 | mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index fa3a460f8e2f..8e8337e8b072 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
| @@ -1630,7 +1630,6 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev) | |||
| 1630 | * sis900_interrupt - sis900 interrupt handler | 1630 | * sis900_interrupt - sis900 interrupt handler |
| 1631 | * @irq: the irq number | 1631 | * @irq: the irq number |
| 1632 | * @dev_instance: the client data object | 1632 | * @dev_instance: the client data object |
| 1633 | * @regs: snapshot of processor context | ||
| 1634 | * | 1633 | * |
| 1635 | * The interrupt handler does all of the Rx thread work, | 1634 | * The interrupt handler does all of the Rx thread work, |
| 1636 | * and cleans up after the Tx thread | 1635 | * and cleans up after the Tx thread |
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index f59c7772f344..9a16a79b67d0 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
| @@ -499,7 +499,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) | |||
| 499 | #else | 499 | #else |
| 500 | SMC_PUSH_DATA(lp, buf, len); | 500 | SMC_PUSH_DATA(lp, buf, len); |
| 501 | dev->trans_start = jiffies; | 501 | dev->trans_start = jiffies; |
| 502 | dev_kfree_skb(skb); | 502 | dev_kfree_skb_irq(skb); |
| 503 | #endif | 503 | #endif |
| 504 | if (!lp->tx_throttle) { | 504 | if (!lp->tx_throttle) { |
| 505 | netif_wake_queue(dev); | 505 | netif_wake_queue(dev); |
| @@ -1735,7 +1735,7 @@ static const struct ethtool_ops smc911x_ethtool_ops = { | |||
| 1735 | * This routine has a simple purpose -- make the SMC chip generate an | 1735 | * This routine has a simple purpose -- make the SMC chip generate an |
| 1736 | * interrupt, so an auto-detect routine can detect it, and find the IRQ, | 1736 | * interrupt, so an auto-detect routine can detect it, and find the IRQ, |
| 1737 | */ | 1737 | */ |
| 1738 | static int __init smc911x_findirq(struct net_device *dev) | 1738 | static int __devinit smc911x_findirq(struct net_device *dev) |
| 1739 | { | 1739 | { |
| 1740 | struct smc911x_local *lp = netdev_priv(dev); | 1740 | struct smc911x_local *lp = netdev_priv(dev); |
| 1741 | int timeout = 20; | 1741 | int timeout = 20; |
| @@ -1799,7 +1799,7 @@ static int __init smc911x_findirq(struct net_device *dev) | |||
| 1799 | * o actually GRAB the irq. | 1799 | * o actually GRAB the irq. |
| 1800 | * o GRAB the region | 1800 | * o GRAB the region |
| 1801 | */ | 1801 | */ |
| 1802 | static int __init smc911x_probe(struct net_device *dev) | 1802 | static int __devinit smc911x_probe(struct net_device *dev) |
| 1803 | { | 1803 | { |
| 1804 | struct smc911x_local *lp = netdev_priv(dev); | 1804 | struct smc911x_local *lp = netdev_priv(dev); |
| 1805 | int i, retval; | 1805 | int i, retval; |
| @@ -1813,7 +1813,7 @@ static int __init smc911x_probe(struct net_device *dev) | |||
| 1813 | val = SMC_GET_BYTE_TEST(lp); | 1813 | val = SMC_GET_BYTE_TEST(lp); |
| 1814 | DBG(SMC_DEBUG_MISC, "%s: endian probe returned 0x%04x\n", CARDNAME, val); | 1814 | DBG(SMC_DEBUG_MISC, "%s: endian probe returned 0x%04x\n", CARDNAME, val); |
| 1815 | if (val != 0x87654321) { | 1815 | if (val != 0x87654321) { |
| 1816 | printk(KERN_ERR "Invalid chip endian 0x08%x\n",val); | 1816 | printk(KERN_ERR "Invalid chip endian 0x%08x\n",val); |
| 1817 | retval = -ENODEV; | 1817 | retval = -ENODEV; |
| 1818 | goto err_out; | 1818 | goto err_out; |
| 1819 | } | 1819 | } |
| @@ -2048,9 +2048,11 @@ err_out: | |||
| 2048 | * 0 --> there is a device | 2048 | * 0 --> there is a device |
| 2049 | * anything else, error | 2049 | * anything else, error |
| 2050 | */ | 2050 | */ |
| 2051 | static int smc911x_drv_probe(struct platform_device *pdev) | 2051 | static int __devinit smc911x_drv_probe(struct platform_device *pdev) |
| 2052 | { | 2052 | { |
| 2053 | #ifdef SMC_DYNAMIC_BUS_CONFIG | ||
| 2053 | struct smc911x_platdata *pd = pdev->dev.platform_data; | 2054 | struct smc911x_platdata *pd = pdev->dev.platform_data; |
| 2055 | #endif | ||
| 2054 | struct net_device *ndev; | 2056 | struct net_device *ndev; |
| 2055 | struct resource *res; | 2057 | struct resource *res; |
| 2056 | struct smc911x_local *lp; | 2058 | struct smc911x_local *lp; |
| @@ -2122,7 +2124,7 @@ out: | |||
| 2122 | return ret; | 2124 | return ret; |
| 2123 | } | 2125 | } |
| 2124 | 2126 | ||
| 2125 | static int smc911x_drv_remove(struct platform_device *pdev) | 2127 | static int __devexit smc911x_drv_remove(struct platform_device *pdev) |
| 2126 | { | 2128 | { |
| 2127 | struct net_device *ndev = platform_get_drvdata(pdev); | 2129 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 2128 | struct smc911x_local *lp = netdev_priv(ndev); | 2130 | struct smc911x_local *lp = netdev_priv(ndev); |
| @@ -2182,9 +2184,9 @@ static int smc911x_drv_resume(struct platform_device *dev) | |||
| 2182 | 2184 | ||
| 2183 | if (netif_running(ndev)) { | 2185 | if (netif_running(ndev)) { |
| 2184 | smc911x_reset(ndev); | 2186 | smc911x_reset(ndev); |
| 2185 | smc911x_enable(ndev); | ||
| 2186 | if (lp->phy_type != 0) | 2187 | if (lp->phy_type != 0) |
| 2187 | smc911x_phy_configure(&lp->phy_configure); | 2188 | smc911x_phy_configure(&lp->phy_configure); |
| 2189 | smc911x_enable(ndev); | ||
| 2188 | netif_device_attach(ndev); | 2190 | netif_device_attach(ndev); |
| 2189 | } | 2191 | } |
| 2190 | } | 2192 | } |
| @@ -2193,7 +2195,7 @@ static int smc911x_drv_resume(struct platform_device *dev) | |||
| 2193 | 2195 | ||
| 2194 | static struct platform_driver smc911x_driver = { | 2196 | static struct platform_driver smc911x_driver = { |
| 2195 | .probe = smc911x_drv_probe, | 2197 | .probe = smc911x_drv_probe, |
| 2196 | .remove = smc911x_drv_remove, | 2198 | .remove = __devexit_p(smc911x_drv_remove), |
| 2197 | .suspend = smc911x_drv_suspend, | 2199 | .suspend = smc911x_drv_suspend, |
| 2198 | .resume = smc911x_drv_resume, | 2200 | .resume = smc911x_drv_resume, |
| 2199 | .driver = { | 2201 | .driver = { |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index c70870e0fd61..35c56abf4113 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
| @@ -1696,7 +1696,7 @@ static const struct ethtool_ops smc_ethtool_ops = { | |||
| 1696 | * I just deleted auto_irq.c, since it was never built... | 1696 | * I just deleted auto_irq.c, since it was never built... |
| 1697 | * --jgarzik | 1697 | * --jgarzik |
| 1698 | */ | 1698 | */ |
| 1699 | static int __init smc_findirq(struct smc_local *lp) | 1699 | static int __devinit smc_findirq(struct smc_local *lp) |
| 1700 | { | 1700 | { |
| 1701 | void __iomem *ioaddr = lp->base; | 1701 | void __iomem *ioaddr = lp->base; |
| 1702 | int timeout = 20; | 1702 | int timeout = 20; |
| @@ -1770,7 +1770,7 @@ static int __init smc_findirq(struct smc_local *lp) | |||
| 1770 | * o actually GRAB the irq. | 1770 | * o actually GRAB the irq. |
| 1771 | * o GRAB the region | 1771 | * o GRAB the region |
| 1772 | */ | 1772 | */ |
| 1773 | static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, | 1773 | static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr, |
| 1774 | unsigned long irq_flags) | 1774 | unsigned long irq_flags) |
| 1775 | { | 1775 | { |
| 1776 | struct smc_local *lp = netdev_priv(dev); | 1776 | struct smc_local *lp = netdev_priv(dev); |
| @@ -2060,7 +2060,7 @@ static int smc_request_attrib(struct platform_device *pdev, | |||
| 2060 | struct net_device *ndev) | 2060 | struct net_device *ndev) |
| 2061 | { | 2061 | { |
| 2062 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); | 2062 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); |
| 2063 | struct smc_local *lp = netdev_priv(ndev); | 2063 | struct smc_local *lp __maybe_unused = netdev_priv(ndev); |
| 2064 | 2064 | ||
| 2065 | if (!res) | 2065 | if (!res) |
| 2066 | return 0; | 2066 | return 0; |
| @@ -2075,7 +2075,7 @@ static void smc_release_attrib(struct platform_device *pdev, | |||
| 2075 | struct net_device *ndev) | 2075 | struct net_device *ndev) |
| 2076 | { | 2076 | { |
| 2077 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); | 2077 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); |
| 2078 | struct smc_local *lp = netdev_priv(ndev); | 2078 | struct smc_local *lp __maybe_unused = netdev_priv(ndev); |
| 2079 | 2079 | ||
| 2080 | if (res) | 2080 | if (res) |
| 2081 | release_mem_region(res->start, ATTRIB_SIZE); | 2081 | release_mem_region(res->start, ATTRIB_SIZE); |
| @@ -2126,7 +2126,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * | |||
| 2126 | * 0 --> there is a device | 2126 | * 0 --> there is a device |
| 2127 | * anything else, error | 2127 | * anything else, error |
| 2128 | */ | 2128 | */ |
| 2129 | static int smc_drv_probe(struct platform_device *pdev) | 2129 | static int __devinit smc_drv_probe(struct platform_device *pdev) |
| 2130 | { | 2130 | { |
| 2131 | struct smc91x_platdata *pd = pdev->dev.platform_data; | 2131 | struct smc91x_platdata *pd = pdev->dev.platform_data; |
| 2132 | struct smc_local *lp; | 2132 | struct smc_local *lp; |
| @@ -2240,7 +2240,7 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
| 2240 | return ret; | 2240 | return ret; |
| 2241 | } | 2241 | } |
| 2242 | 2242 | ||
| 2243 | static int smc_drv_remove(struct platform_device *pdev) | 2243 | static int __devexit smc_drv_remove(struct platform_device *pdev) |
| 2244 | { | 2244 | { |
| 2245 | struct net_device *ndev = platform_get_drvdata(pdev); | 2245 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 2246 | struct smc_local *lp = netdev_priv(ndev); | 2246 | struct smc_local *lp = netdev_priv(ndev); |
| @@ -2305,7 +2305,7 @@ static int smc_drv_resume(struct platform_device *dev) | |||
| 2305 | 2305 | ||
| 2306 | static struct platform_driver smc_driver = { | 2306 | static struct platform_driver smc_driver = { |
| 2307 | .probe = smc_drv_probe, | 2307 | .probe = smc_drv_probe, |
| 2308 | .remove = smc_drv_remove, | 2308 | .remove = __devexit_p(smc_drv_remove), |
| 2309 | .suspend = smc_drv_suspend, | 2309 | .suspend = smc_drv_suspend, |
| 2310 | .resume = smc_drv_resume, | 2310 | .resume = smc_drv_resume, |
| 2311 | .driver = { | 2311 | .driver = { |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index b6435d0d71f9..07599b492359 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
| @@ -672,7 +672,6 @@ write_hash: | |||
| 672 | /** | 672 | /** |
| 673 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data | 673 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data |
| 674 | * @card: card structure | 674 | * @card: card structure |
| 675 | * @descr: descriptor structure to fill out | ||
| 676 | * @skb: packet to use | 675 | * @skb: packet to use |
| 677 | * | 676 | * |
| 678 | * returns 0 on success, <0 on failure. | 677 | * returns 0 on success, <0 on failure. |
| @@ -867,7 +866,6 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
| 867 | /** | 866 | /** |
| 868 | * spider_net_kick_tx_dma - enables TX DMA processing | 867 | * spider_net_kick_tx_dma - enables TX DMA processing |
| 869 | * @card: card structure | 868 | * @card: card structure |
| 870 | * @descr: descriptor address to enable TX processing at | ||
| 871 | * | 869 | * |
| 872 | * This routine will start the transmit DMA running if | 870 | * This routine will start the transmit DMA running if |
| 873 | * it is not already running. This routine ned only be | 871 | * it is not already running. This routine ned only be |
| @@ -1637,7 +1635,6 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg, | |||
| 1637 | * spider_net_interrupt - interrupt handler for spider_net | 1635 | * spider_net_interrupt - interrupt handler for spider_net |
| 1638 | * @irq: interrupt number | 1636 | * @irq: interrupt number |
| 1639 | * @ptr: pointer to net_device | 1637 | * @ptr: pointer to net_device |
| 1640 | * @regs: PU registers | ||
| 1641 | * | 1638 | * |
| 1642 | * returns IRQ_HANDLED, if interrupt was for driver, or IRQ_NONE, if no | 1639 | * returns IRQ_HANDLED, if interrupt was for driver, or IRQ_NONE, if no |
| 1643 | * interrupt found raised by card. | 1640 | * interrupt found raised by card. |
| @@ -2419,7 +2416,6 @@ spider_net_undo_pci_setup(struct spider_net_card *card) | |||
| 2419 | 2416 | ||
| 2420 | /** | 2417 | /** |
| 2421 | * spider_net_setup_pci_dev - sets up the device in terms of PCI operations | 2418 | * spider_net_setup_pci_dev - sets up the device in terms of PCI operations |
| 2422 | * @card: card structure | ||
| 2423 | * @pdev: PCI device | 2419 | * @pdev: PCI device |
| 2424 | * | 2420 | * |
| 2425 | * Returns the card structure or NULL if any errors occur | 2421 | * Returns the card structure or NULL if any errors occur |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 4291458955ef..1349e419673c 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
| @@ -1714,7 +1714,7 @@ static void gem_init_phy(struct gem *gp) | |||
| 1714 | /* Reset PCS unit. */ | 1714 | /* Reset PCS unit. */ |
| 1715 | val = readl(gp->regs + PCS_MIICTRL); | 1715 | val = readl(gp->regs + PCS_MIICTRL); |
| 1716 | val |= PCS_MIICTRL_RST; | 1716 | val |= PCS_MIICTRL_RST; |
| 1717 | writeb(val, gp->regs + PCS_MIICTRL); | 1717 | writel(val, gp->regs + PCS_MIICTRL); |
| 1718 | 1718 | ||
| 1719 | limit = 32; | 1719 | limit = 32; |
| 1720 | while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) { | 1720 | while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) { |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 6daea0c91862..33b6d1b122fb 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -1070,8 +1070,6 @@ static int tun_chr_close(struct inode *inode, struct file *file) | |||
| 1070 | 1070 | ||
| 1071 | DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); | 1071 | DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); |
| 1072 | 1072 | ||
| 1073 | tun_chr_fasync(-1, file, 0); | ||
| 1074 | |||
| 1075 | rtnl_lock(); | 1073 | rtnl_lock(); |
| 1076 | 1074 | ||
| 1077 | /* Detach from net device */ | 1075 | /* Detach from net device */ |
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index cfbbfee55836..68a7f5414133 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
| 38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
| 39 | #include <asm/types.h> | 39 | #include <asm/types.h> |
| 40 | #include <asm/uaccess.h> | ||
| 41 | 40 | ||
| 42 | #include "ucc_geth.h" | 41 | #include "ucc_geth.h" |
| 43 | #include "ucc_geth_mii.h" | 42 | #include "ucc_geth_mii.h" |
| @@ -324,17 +323,17 @@ static void uec_get_ethtool_stats(struct net_device *netdev, | |||
| 324 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) { | 323 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) { |
| 325 | base = (u32 __iomem *)&ugeth->ug_regs->tx64; | 324 | base = (u32 __iomem *)&ugeth->ug_regs->tx64; |
| 326 | for (i = 0; i < UEC_HW_STATS_LEN; i++) | 325 | for (i = 0; i < UEC_HW_STATS_LEN; i++) |
| 327 | data[j++] = (u64)in_be32(&base[i]); | 326 | data[j++] = in_be32(&base[i]); |
| 328 | } | 327 | } |
| 329 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { | 328 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { |
| 330 | base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram; | 329 | base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram; |
| 331 | for (i = 0; i < UEC_TX_FW_STATS_LEN; i++) | 330 | for (i = 0; i < UEC_TX_FW_STATS_LEN; i++) |
| 332 | data[j++] = (u64)in_be32(&base[i]); | 331 | data[j++] = base ? in_be32(&base[i]) : 0; |
| 333 | } | 332 | } |
| 334 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { | 333 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { |
| 335 | base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram; | 334 | base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram; |
| 336 | for (i = 0; i < UEC_RX_FW_STATS_LEN; i++) | 335 | for (i = 0; i < UEC_RX_FW_STATS_LEN; i++) |
| 337 | data[j++] = (u64)in_be32(&base[i]); | 336 | data[j++] = base ? in_be32(&base[i]) : 0; |
| 338 | } | 337 | } |
| 339 | } | 338 | } |
| 340 | 339 | ||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 37ecf845edfe..de57490103fc 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
| @@ -1102,12 +1102,14 @@ static int ax88178_link_reset(struct usbnet *dev) | |||
| 1102 | mode = AX88178_MEDIUM_DEFAULT; | 1102 | mode = AX88178_MEDIUM_DEFAULT; |
| 1103 | 1103 | ||
| 1104 | if (ecmd.speed == SPEED_1000) | 1104 | if (ecmd.speed == SPEED_1000) |
| 1105 | mode |= AX_MEDIUM_GM | AX_MEDIUM_ENCK; | 1105 | mode |= AX_MEDIUM_GM; |
| 1106 | else if (ecmd.speed == SPEED_100) | 1106 | else if (ecmd.speed == SPEED_100) |
| 1107 | mode |= AX_MEDIUM_PS; | 1107 | mode |= AX_MEDIUM_PS; |
| 1108 | else | 1108 | else |
| 1109 | mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM); | 1109 | mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM); |
| 1110 | 1110 | ||
| 1111 | mode |= AX_MEDIUM_ENCK; | ||
| 1112 | |||
| 1111 | if (ecmd.duplex == DUPLEX_FULL) | 1113 | if (ecmd.duplex == DUPLEX_FULL) |
| 1112 | mode |= AX_MEDIUM_FD; | 1114 | mode |= AX_MEDIUM_FD; |
| 1113 | else | 1115 | else |
| @@ -1444,6 +1446,10 @@ static const struct usb_device_id products [] = { | |||
| 1444 | // Apple USB Ethernet Adapter | 1446 | // Apple USB Ethernet Adapter |
| 1445 | USB_DEVICE(0x05ac, 0x1402), | 1447 | USB_DEVICE(0x05ac, 0x1402), |
| 1446 | .driver_info = (unsigned long) &ax88772_info, | 1448 | .driver_info = (unsigned long) &ax88772_info, |
| 1449 | }, { | ||
| 1450 | // Cables-to-Go USB Ethernet Adapter | ||
| 1451 | USB_DEVICE(0x0b95, 0x772a), | ||
| 1452 | .driver_info = (unsigned long) &ax88772_info, | ||
| 1447 | }, | 1453 | }, |
| 1448 | { }, // END | 1454 | { }, // END |
| 1449 | }; | 1455 | }; |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1164c52e2c0a..8e90891f0e42 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -2184,19 +2184,20 @@ static void hso_create_rfkill(struct hso_device *hso_dev, | |||
| 2184 | struct usb_interface *interface) | 2184 | struct usb_interface *interface) |
| 2185 | { | 2185 | { |
| 2186 | struct hso_net *hso_net = dev2net(hso_dev); | 2186 | struct hso_net *hso_net = dev2net(hso_dev); |
| 2187 | struct device *dev = hso_dev->dev; | 2187 | struct device *dev = &hso_net->net->dev; |
| 2188 | char *rfkn; | 2188 | char *rfkn; |
| 2189 | 2189 | ||
| 2190 | hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, | 2190 | hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, |
| 2191 | RFKILL_TYPE_WLAN); | 2191 | RFKILL_TYPE_WWAN); |
| 2192 | if (!hso_net->rfkill) { | 2192 | if (!hso_net->rfkill) { |
| 2193 | dev_err(dev, "%s - Out of memory", __func__); | 2193 | dev_err(dev, "%s - Out of memory\n", __func__); |
| 2194 | return; | 2194 | return; |
| 2195 | } | 2195 | } |
| 2196 | rfkn = kzalloc(20, GFP_KERNEL); | 2196 | rfkn = kzalloc(20, GFP_KERNEL); |
| 2197 | if (!rfkn) { | 2197 | if (!rfkn) { |
| 2198 | rfkill_free(hso_net->rfkill); | 2198 | rfkill_free(hso_net->rfkill); |
| 2199 | dev_err(dev, "%s - Out of memory", __func__); | 2199 | hso_net->rfkill = NULL; |
| 2200 | dev_err(dev, "%s - Out of memory\n", __func__); | ||
| 2200 | return; | 2201 | return; |
| 2201 | } | 2202 | } |
| 2202 | snprintf(rfkn, 20, "hso-%d", | 2203 | snprintf(rfkn, 20, "hso-%d", |
| @@ -2209,7 +2210,8 @@ static void hso_create_rfkill(struct hso_device *hso_dev, | |||
| 2209 | kfree(rfkn); | 2210 | kfree(rfkn); |
| 2210 | hso_net->rfkill->name = NULL; | 2211 | hso_net->rfkill->name = NULL; |
| 2211 | rfkill_free(hso_net->rfkill); | 2212 | rfkill_free(hso_net->rfkill); |
| 2212 | dev_err(dev, "%s - Failed to register rfkill", __func__); | 2213 | hso_net->rfkill = NULL; |
| 2214 | dev_err(dev, "%s - Failed to register rfkill\n", __func__); | ||
| 2213 | return; | 2215 | return; |
| 2214 | } | 2216 | } |
| 2215 | } | 2217 | } |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 3590ea5a902d..11cb3e504e1c 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
| @@ -2296,7 +2296,7 @@ static void velocity_set_multi(struct net_device *dev) | |||
| 2296 | } | 2296 | } |
| 2297 | 2297 | ||
| 2298 | mac_set_cam_mask(regs, vptr->mCAMmask); | 2298 | mac_set_cam_mask(regs, vptr->mCAMmask); |
| 2299 | rx_mode = (RCR_AM | RCR_AB); | 2299 | rx_mode = RCR_AM | RCR_AB | RCR_AP; |
| 2300 | } | 2300 | } |
| 2301 | if (dev->mtu > 1500) | 2301 | if (dev->mtu > 1500) |
| 2302 | rx_mode |= RCR_AL; | 2302 | rx_mode |= RCR_AL; |
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index ccd9cd35ecbe..5bf7e01ef0e9 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c | |||
| @@ -695,7 +695,6 @@ EXPORT_SYMBOL(z8530_nop); | |||
| 695 | * z8530_interrupt - Handle an interrupt from a Z8530 | 695 | * z8530_interrupt - Handle an interrupt from a Z8530 |
| 696 | * @irq: Interrupt number | 696 | * @irq: Interrupt number |
| 697 | * @dev_id: The Z8530 device that is interrupting. | 697 | * @dev_id: The Z8530 device that is interrupting. |
| 698 | * @regs: unused | ||
| 699 | * | 698 | * |
| 700 | * A Z85[2]30 device has stuck its hand in the air for attention. | 699 | * A Z85[2]30 device has stuck its hand in the air for attention. |
| 701 | * We scan both the channels on the chip for events and then call | 700 | * We scan both the channels on the chip for events and then call |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index cfd4d052d666..2d14255eb103 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
| @@ -240,6 +240,10 @@ static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | |||
| 240 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 240 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
| 241 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | 241 | static int ath5k_beacon_update(struct ieee80211_hw *hw, |
| 242 | struct sk_buff *skb); | 242 | struct sk_buff *skb); |
| 243 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
| 244 | struct ieee80211_vif *vif, | ||
| 245 | struct ieee80211_bss_conf *bss_conf, | ||
| 246 | u32 changes); | ||
| 243 | 247 | ||
| 244 | static struct ieee80211_ops ath5k_hw_ops = { | 248 | static struct ieee80211_ops ath5k_hw_ops = { |
| 245 | .tx = ath5k_tx, | 249 | .tx = ath5k_tx, |
| @@ -256,6 +260,7 @@ static struct ieee80211_ops ath5k_hw_ops = { | |||
| 256 | .get_tx_stats = ath5k_get_tx_stats, | 260 | .get_tx_stats = ath5k_get_tx_stats, |
| 257 | .get_tsf = ath5k_get_tsf, | 261 | .get_tsf = ath5k_get_tsf, |
| 258 | .reset_tsf = ath5k_reset_tsf, | 262 | .reset_tsf = ath5k_reset_tsf, |
| 263 | .bss_info_changed = ath5k_bss_info_changed, | ||
| 259 | }; | 264 | }; |
| 260 | 265 | ||
| 261 | /* | 266 | /* |
| @@ -2942,7 +2947,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
| 2942 | sc->opmode != NL80211_IFTYPE_MESH_POINT && | 2947 | sc->opmode != NL80211_IFTYPE_MESH_POINT && |
| 2943 | test_bit(ATH_STAT_PROMISC, sc->status)) | 2948 | test_bit(ATH_STAT_PROMISC, sc->status)) |
| 2944 | rfilt |= AR5K_RX_FILTER_PROM; | 2949 | rfilt |= AR5K_RX_FILTER_PROM; |
| 2945 | if (sc->opmode == NL80211_IFTYPE_STATION || | 2950 | if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) || |
| 2946 | sc->opmode == NL80211_IFTYPE_ADHOC) { | 2951 | sc->opmode == NL80211_IFTYPE_ADHOC) { |
| 2947 | rfilt |= AR5K_RX_FILTER_BEACON; | 2952 | rfilt |= AR5K_RX_FILTER_BEACON; |
| 2948 | } | 2953 | } |
| @@ -3083,4 +3088,32 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 3083 | end: | 3088 | end: |
| 3084 | return ret; | 3089 | return ret; |
| 3085 | } | 3090 | } |
| 3091 | static void | ||
| 3092 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) | ||
| 3093 | { | ||
| 3094 | struct ath5k_softc *sc = hw->priv; | ||
| 3095 | struct ath5k_hw *ah = sc->ah; | ||
| 3096 | u32 rfilt; | ||
| 3097 | rfilt = ath5k_hw_get_rx_filter(ah); | ||
| 3098 | if (enable) | ||
| 3099 | rfilt |= AR5K_RX_FILTER_BEACON; | ||
| 3100 | else | ||
| 3101 | rfilt &= ~AR5K_RX_FILTER_BEACON; | ||
| 3102 | ath5k_hw_set_rx_filter(ah, rfilt); | ||
| 3103 | sc->filter_flags = rfilt; | ||
| 3104 | } | ||
| 3086 | 3105 | ||
| 3106 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
| 3107 | struct ieee80211_vif *vif, | ||
| 3108 | struct ieee80211_bss_conf *bss_conf, | ||
| 3109 | u32 changes) | ||
| 3110 | { | ||
| 3111 | struct ath5k_softc *sc = hw->priv; | ||
| 3112 | if (changes & BSS_CHANGED_ASSOC) { | ||
| 3113 | mutex_lock(&sc->lock); | ||
| 3114 | sc->assoc = bss_conf->assoc; | ||
| 3115 | if (sc->opmode == NL80211_IFTYPE_STATION) | ||
| 3116 | set_beacon_filter(hw, sc->assoc); | ||
| 3117 | mutex_unlock(&sc->lock); | ||
| 3118 | } | ||
| 3119 | } | ||
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index 06d1054ca94b..facc60ddada2 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
| @@ -179,6 +179,7 @@ struct ath5k_softc { | |||
| 179 | 179 | ||
| 180 | struct timer_list calib_tim; /* calibration timer */ | 180 | struct timer_list calib_tim; /* calibration timer */ |
| 181 | int power_level; /* Requested tx power in dbm */ | 181 | int power_level; /* Requested tx power in dbm */ |
| 182 | bool assoc; /* assocate state */ | ||
| 182 | }; | 183 | }; |
| 183 | 184 | ||
| 184 | #define ath5k_hw_hasbssidmask(_ah) \ | 185 | #define ath5k_hw_hasbssidmask(_ah) \ |
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index 8f92d670f614..ccaeb5c219d2 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
| @@ -339,7 +339,7 @@ static struct { | |||
| 339 | { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" }, | 339 | { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" }, |
| 340 | { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, | 340 | { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, |
| 341 | { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, | 341 | { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, |
| 342 | { ATH5K_DEBUG_LED, "led", "LED mamagement" }, | 342 | { ATH5K_DEBUG_LED, "led", "LED management" }, |
| 343 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, | 343 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, |
| 344 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | 344 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, |
| 345 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, | 345 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, |
| @@ -417,19 +417,19 @@ ath5k_debug_init_device(struct ath5k_softc *sc) | |||
| 417 | sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | 417 | sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), |
| 418 | ath5k_global_debugfs); | 418 | ath5k_global_debugfs); |
| 419 | 419 | ||
| 420 | sc->debug.debugfs_debug = debugfs_create_file("debug", 0666, | 420 | sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUGO, |
| 421 | sc->debug.debugfs_phydir, sc, &fops_debug); | 421 | sc->debug.debugfs_phydir, sc, &fops_debug); |
| 422 | 422 | ||
| 423 | sc->debug.debugfs_registers = debugfs_create_file("registers", 0444, | 423 | sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO, |
| 424 | sc->debug.debugfs_phydir, sc, &fops_registers); | 424 | sc->debug.debugfs_phydir, sc, &fops_registers); |
| 425 | 425 | ||
| 426 | sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666, | 426 | sc->debug.debugfs_tsf = debugfs_create_file("tsf", S_IWUSR | S_IRUGO, |
| 427 | sc->debug.debugfs_phydir, sc, &fops_tsf); | 427 | sc->debug.debugfs_phydir, sc, &fops_tsf); |
| 428 | 428 | ||
| 429 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666, | 429 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO, |
| 430 | sc->debug.debugfs_phydir, sc, &fops_beacon); | 430 | sc->debug.debugfs_phydir, sc, &fops_beacon); |
| 431 | 431 | ||
| 432 | sc->debug.debugfs_reset = debugfs_create_file("reset", 0222, | 432 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, |
| 433 | sc->debug.debugfs_phydir, sc, &fops_reset); | 433 | sc->debug.debugfs_phydir, sc, &fops_reset); |
| 434 | } | 434 | } |
| 435 | 435 | ||
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c index dd1374052ba9..5e362a7a3620 100644 --- a/drivers/net/wireless/ath5k/desc.c +++ b/drivers/net/wireless/ath5k/desc.c | |||
| @@ -531,10 +531,10 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
| 531 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 531 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
| 532 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 532 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, |
| 533 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); | 533 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); |
| 534 | rs->rs_antenna = rx_status->rx_status_0 & | 534 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, |
| 535 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA; | 535 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
| 536 | rs->rs_more = rx_status->rx_status_0 & | 536 | rs->rs_more = !!(rx_status->rx_status_0 & |
| 537 | AR5K_5210_RX_DESC_STATUS0_MORE; | 537 | AR5K_5210_RX_DESC_STATUS0_MORE); |
| 538 | /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ | 538 | /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ |
| 539 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 539 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
| 540 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 540 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
| @@ -607,10 +607,10 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
| 607 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 607 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
| 608 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 608 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, |
| 609 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | 609 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); |
| 610 | rs->rs_antenna = rx_status->rx_status_0 & | 610 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, |
| 611 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA; | 611 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
| 612 | rs->rs_more = rx_status->rx_status_0 & | 612 | rs->rs_more = !!(rx_status->rx_status_0 & |
| 613 | AR5K_5212_RX_DESC_STATUS0_MORE; | 613 | AR5K_5212_RX_DESC_STATUS0_MORE); |
| 614 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 614 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
| 615 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 615 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
| 616 | rs->rs_status = 0; | 616 | rs->rs_status = 0; |
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c index ea2e1a20b499..ceaa6c475c06 100644 --- a/drivers/net/wireless/ath5k/initvals.c +++ b/drivers/net/wireless/ath5k/initvals.c | |||
| @@ -806,6 +806,8 @@ static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = { | |||
| 806 | { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, | 806 | { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, |
| 807 | { AR5K_PHY(642), | 807 | { AR5K_PHY(642), |
| 808 | { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, | 808 | { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, |
| 809 | { 0xa228, | ||
| 810 | { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } }, | ||
| 809 | { 0xa23c, | 811 | { 0xa23c, |
| 810 | { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } }, | 812 | { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } }, |
| 811 | }; | 813 | }; |
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index 8f1886834e61..1b6d45b6772d 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c | |||
| @@ -537,9 +537,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
| 537 | mdelay(1); | 537 | mdelay(1); |
| 538 | 538 | ||
| 539 | /* | 539 | /* |
| 540 | * Write some more initial register settings | 540 | * Write some more initial register settings for revised chips |
| 541 | */ | 541 | */ |
| 542 | if (ah->ah_version == AR5K_AR5212) { | 542 | if (ah->ah_version == AR5K_AR5212 && |
| 543 | ah->ah_phy_revision > 0x41) { | ||
| 543 | ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); | 544 | ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); |
| 544 | 545 | ||
| 545 | if (channel->hw_value == CHANNEL_G) | 546 | if (channel->hw_value == CHANNEL_G) |
| @@ -558,19 +559,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
| 558 | else | 559 | else |
| 559 | ath5k_hw_reg_write(ah, 0x00000000, 0x994c); | 560 | ath5k_hw_reg_write(ah, 0x00000000, 0x994c); |
| 560 | 561 | ||
| 561 | /* Some bits are disabled here, we know nothing about | 562 | /* Got this from legacy-hal */ |
| 562 | * register 0xa228 yet, most of the times this ends up | 563 | AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200); |
| 563 | * with a value 0x9b5 -haven't seen any dump with | 564 | |
| 564 | * a different value- */ | 565 | AR5K_REG_MASKED_BITS(ah, 0xa228, 0x800, 0xfffe03ff); |
| 565 | /* Got this from decompiling binary HAL */ | ||
| 566 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
| 567 | data &= 0xfffffdff; | ||
| 568 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
| 569 | |||
| 570 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
| 571 | data &= 0xfffe03ff; | ||
| 572 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
| 573 | data = 0; | ||
| 574 | 566 | ||
| 575 | /* Just write 0x9b5 ? */ | 567 | /* Just write 0x9b5 ? */ |
| 576 | /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */ | 568 | /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */ |
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 9e15c30bbc06..4dd1c1bda0fb 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c | |||
| @@ -170,7 +170,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
| 170 | skb = (struct sk_buff *)bf->bf_mpdu; | 170 | skb = (struct sk_buff *)bf->bf_mpdu; |
| 171 | if (skb) { | 171 | if (skb) { |
| 172 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, | 172 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, |
| 173 | skb_end_pointer(skb) - skb->head, | 173 | skb->len, |
| 174 | PCI_DMA_TODEVICE); | 174 | PCI_DMA_TODEVICE); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| @@ -193,7 +193,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
| 193 | 193 | ||
| 194 | bf->bf_buf_addr = bf->bf_dmacontext = | 194 | bf->bf_buf_addr = bf->bf_dmacontext = |
| 195 | pci_map_single(sc->pdev, skb->data, | 195 | pci_map_single(sc->pdev, skb->data, |
| 196 | skb_end_pointer(skb) - skb->head, | 196 | skb->len, |
| 197 | PCI_DMA_TODEVICE); | 197 | PCI_DMA_TODEVICE); |
| 198 | 198 | ||
| 199 | skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); | 199 | skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); |
| @@ -352,7 +352,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
| 352 | if (bf->bf_mpdu != NULL) { | 352 | if (bf->bf_mpdu != NULL) { |
| 353 | skb = (struct sk_buff *)bf->bf_mpdu; | 353 | skb = (struct sk_buff *)bf->bf_mpdu; |
| 354 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, | 354 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, |
| 355 | skb_end_pointer(skb) - skb->head, | 355 | skb->len, |
| 356 | PCI_DMA_TODEVICE); | 356 | PCI_DMA_TODEVICE); |
| 357 | dev_kfree_skb_any(skb); | 357 | dev_kfree_skb_any(skb); |
| 358 | bf->bf_mpdu = NULL; | 358 | bf->bf_mpdu = NULL; |
| @@ -412,7 +412,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
| 412 | 412 | ||
| 413 | bf->bf_buf_addr = bf->bf_dmacontext = | 413 | bf->bf_buf_addr = bf->bf_dmacontext = |
| 414 | pci_map_single(sc->pdev, skb->data, | 414 | pci_map_single(sc->pdev, skb->data, |
| 415 | skb_end_pointer(skb) - skb->head, | 415 | skb->len, |
| 416 | PCI_DMA_TODEVICE); | 416 | PCI_DMA_TODEVICE); |
| 417 | bf->bf_mpdu = skb; | 417 | bf->bf_mpdu = skb; |
| 418 | 418 | ||
| @@ -439,7 +439,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) | |||
| 439 | if (bf->bf_mpdu != NULL) { | 439 | if (bf->bf_mpdu != NULL) { |
| 440 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; | 440 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; |
| 441 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, | 441 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, |
| 442 | skb_end_pointer(skb) - skb->head, | 442 | skb->len, |
| 443 | PCI_DMA_TODEVICE); | 443 | PCI_DMA_TODEVICE); |
| 444 | dev_kfree_skb_any(skb); | 444 | dev_kfree_skb_any(skb); |
| 445 | bf->bf_mpdu = NULL; | 445 | bf->bf_mpdu = NULL; |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 4983402af559..504a0444d89f 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
| @@ -49,10 +49,12 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | |||
| 49 | ASSERT(skb != NULL); | 49 | ASSERT(skb != NULL); |
| 50 | ds->ds_vdata = skb->data; | 50 | ds->ds_vdata = skb->data; |
| 51 | 51 | ||
| 52 | /* setup rx descriptors */ | 52 | /* setup rx descriptors. The sc_rxbufsize here tells the harware |
| 53 | * how much data it can DMA to us and that we are prepared | ||
| 54 | * to process */ | ||
| 53 | ath9k_hw_setuprxdesc(ah, | 55 | ath9k_hw_setuprxdesc(ah, |
| 54 | ds, | 56 | ds, |
| 55 | skb_tailroom(skb), /* buffer size */ | 57 | sc->sc_rxbufsize, |
| 56 | 0); | 58 | 0); |
| 57 | 59 | ||
| 58 | if (sc->sc_rxlink == NULL) | 60 | if (sc->sc_rxlink == NULL) |
| @@ -398,6 +400,13 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, | |||
| 398 | * in rx'd frames. | 400 | * in rx'd frames. |
| 399 | */ | 401 | */ |
| 400 | 402 | ||
| 403 | /* Note: the kernel can allocate a value greater than | ||
| 404 | * what we ask it to give us. We really only need 4 KB as that | ||
| 405 | * is this hardware supports and in fact we need at least 3849 | ||
| 406 | * as that is the MAX AMSDU size this hardware supports. | ||
| 407 | * Unfortunately this means we may get 8 KB here from the | ||
| 408 | * kernel... and that is actually what is observed on some | ||
| 409 | * systems :( */ | ||
| 401 | skb = dev_alloc_skb(len + sc->sc_cachelsz - 1); | 410 | skb = dev_alloc_skb(len + sc->sc_cachelsz - 1); |
| 402 | if (skb != NULL) { | 411 | if (skb != NULL) { |
| 403 | off = ((unsigned long) skb->data) % sc->sc_cachelsz; | 412 | off = ((unsigned long) skb->data) % sc->sc_cachelsz; |
| @@ -456,7 +465,7 @@ static int ath_rx_indicate(struct ath_softc *sc, | |||
| 456 | if (nskb != NULL) { | 465 | if (nskb != NULL) { |
| 457 | bf->bf_mpdu = nskb; | 466 | bf->bf_mpdu = nskb; |
| 458 | bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data, | 467 | bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data, |
| 459 | skb_end_pointer(nskb) - nskb->head, | 468 | sc->sc_rxbufsize, |
| 460 | PCI_DMA_FROMDEVICE); | 469 | PCI_DMA_FROMDEVICE); |
| 461 | bf->bf_dmacontext = bf->bf_buf_addr; | 470 | bf->bf_dmacontext = bf->bf_buf_addr; |
| 462 | ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; | 471 | ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; |
| @@ -542,7 +551,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
| 542 | 551 | ||
| 543 | bf->bf_mpdu = skb; | 552 | bf->bf_mpdu = skb; |
| 544 | bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, | 553 | bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, |
| 545 | skb_end_pointer(skb) - skb->head, | 554 | sc->sc_rxbufsize, |
| 546 | PCI_DMA_FROMDEVICE); | 555 | PCI_DMA_FROMDEVICE); |
| 547 | bf->bf_dmacontext = bf->bf_buf_addr; | 556 | bf->bf_dmacontext = bf->bf_buf_addr; |
| 548 | ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; | 557 | ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; |
| @@ -1007,7 +1016,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
| 1007 | 1016 | ||
| 1008 | pci_dma_sync_single_for_cpu(sc->pdev, | 1017 | pci_dma_sync_single_for_cpu(sc->pdev, |
| 1009 | bf->bf_buf_addr, | 1018 | bf->bf_buf_addr, |
| 1010 | skb_tailroom(skb), | 1019 | sc->sc_rxbufsize, |
| 1011 | PCI_DMA_FROMDEVICE); | 1020 | PCI_DMA_FROMDEVICE); |
| 1012 | pci_unmap_single(sc->pdev, | 1021 | pci_unmap_single(sc->pdev, |
| 1013 | bf->bf_buf_addr, | 1022 | bf->bf_buf_addr, |
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index ffdf4876121b..a68f97c39359 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h | |||
| @@ -918,9 +918,12 @@ struct hostap_interface { | |||
| 918 | 918 | ||
| 919 | /* | 919 | /* |
| 920 | * TX meta data - stored in skb->cb buffer, so this must not be increased over | 920 | * TX meta data - stored in skb->cb buffer, so this must not be increased over |
| 921 | * the 40-byte limit | 921 | * the 48-byte limit. |
| 922 | * THE PADDING THIS STARTS WITH IS A HORRIBLE HACK THAT SHOULD NOT LIVE | ||
| 923 | * TO SEE THE DAY. | ||
| 922 | */ | 924 | */ |
| 923 | struct hostap_skb_tx_data { | 925 | struct hostap_skb_tx_data { |
| 926 | unsigned int __padding_for_default_qdiscs; | ||
| 924 | u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ | 927 | u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ |
| 925 | u8 rate; /* transmit rate */ | 928 | u8 rate; /* transmit rate */ |
| 926 | #define HOSTAP_TX_FLAGS_WDS BIT(0) | 929 | #define HOSTAP_TX_FLAGS_WDS BIT(0) |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index dcce3542d5a7..7a9f901d4ff6 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
| @@ -3897,6 +3897,7 @@ static int ipw_disassociate(void *data) | |||
| 3897 | if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) | 3897 | if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) |
| 3898 | return 0; | 3898 | return 0; |
| 3899 | ipw_send_disassociate(data, 0); | 3899 | ipw_send_disassociate(data, 0); |
| 3900 | netif_carrier_off(priv->net_dev); | ||
| 3900 | return 1; | 3901 | return 1; |
| 3901 | } | 3902 | } |
| 3902 | 3903 | ||
| @@ -10190,6 +10191,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
| 10190 | u16 remaining_bytes; | 10191 | u16 remaining_bytes; |
| 10191 | int fc; | 10192 | int fc; |
| 10192 | 10193 | ||
| 10194 | if (!(priv->status & STATUS_ASSOCIATED)) | ||
| 10195 | goto drop; | ||
| 10196 | |||
| 10193 | hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); | 10197 | hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); |
| 10194 | switch (priv->ieee->iw_mode) { | 10198 | switch (priv->ieee->iw_mode) { |
| 10195 | case IW_MODE_ADHOC: | 10199 | case IW_MODE_ADHOC: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 24a1aeb6448f..c4c0371c763b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -1384,9 +1384,11 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
| 1384 | 1384 | ||
| 1385 | rxq->queue[i] = NULL; | 1385 | rxq->queue[i] = NULL; |
| 1386 | 1386 | ||
| 1387 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, | 1387 | dma_sync_single_range_for_cpu( |
| 1388 | priv->hw_params.rx_buf_size, | 1388 | &priv->pci_dev->dev, rxb->real_dma_addr, |
| 1389 | PCI_DMA_FROMDEVICE); | 1389 | rxb->aligned_dma_addr - rxb->real_dma_addr, |
| 1390 | priv->hw_params.rx_buf_size, | ||
| 1391 | PCI_DMA_FROMDEVICE); | ||
| 1390 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1392 | pkt = (struct iwl_rx_packet *)rxb->skb->data; |
| 1391 | 1393 | ||
| 1392 | /* Reclaim a command buffer only if this packet is a response | 1394 | /* Reclaim a command buffer only if this packet is a response |
| @@ -1436,8 +1438,8 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
| 1436 | rxb->skb = NULL; | 1438 | rxb->skb = NULL; |
| 1437 | } | 1439 | } |
| 1438 | 1440 | ||
| 1439 | pci_unmap_single(priv->pci_dev, rxb->dma_addr, | 1441 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, |
| 1440 | priv->hw_params.rx_buf_size, | 1442 | priv->hw_params.rx_buf_size + 256, |
| 1441 | PCI_DMA_FROMDEVICE); | 1443 | PCI_DMA_FROMDEVICE); |
| 1442 | spin_lock_irqsave(&rxq->lock, flags); | 1444 | spin_lock_irqsave(&rxq->lock, flags); |
| 1443 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 1445 | list_add_tail(&rxb->list, &priv->rxq.rx_used); |
| @@ -2090,7 +2092,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
| 2090 | iwl4965_error_recovery(priv); | 2092 | iwl4965_error_recovery(priv); |
| 2091 | 2093 | ||
| 2092 | iwl_power_update_mode(priv, 1); | 2094 | iwl_power_update_mode(priv, 1); |
| 2093 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | ||
| 2094 | 2095 | ||
| 2095 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) | 2096 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) |
| 2096 | iwl4965_set_mode(priv, priv->iw_mode); | 2097 | iwl4965_set_mode(priv, priv->iw_mode); |
| @@ -3252,7 +3253,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
| 3252 | return; | 3253 | return; |
| 3253 | } | 3254 | } |
| 3254 | 3255 | ||
| 3255 | iwl_scan_cancel_timeout(priv, 100); | 3256 | if (iwl_scan_cancel(priv)) { |
| 3257 | /* cancel scan failed, just live w/ bad key and rely | ||
| 3258 | briefly on SW decryption */ | ||
| 3259 | return; | ||
| 3260 | } | ||
| 3256 | 3261 | ||
| 3257 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); | 3262 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); |
| 3258 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 3263 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4c312c55f90c..01a845851338 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -290,6 +290,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv) | |||
| 290 | priv->num_stations = 0; | 290 | priv->num_stations = 0; |
| 291 | memset(priv->stations, 0, sizeof(priv->stations)); | 291 | memset(priv->stations, 0, sizeof(priv->stations)); |
| 292 | 292 | ||
| 293 | /* clean ucode key table bit map */ | ||
| 294 | priv->ucode_key_table = 0; | ||
| 295 | |||
| 293 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 296 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
| 294 | } | 297 | } |
| 295 | EXPORT_SYMBOL(iwl_clear_stations_table); | 298 | EXPORT_SYMBOL(iwl_clear_stations_table); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c018121085e9..9966d4e384ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
| @@ -89,7 +89,8 @@ extern struct iwl_cfg iwl5100_abg_cfg; | |||
| 89 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 89 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
| 90 | 90 | ||
| 91 | struct iwl_rx_mem_buffer { | 91 | struct iwl_rx_mem_buffer { |
| 92 | dma_addr_t dma_addr; | 92 | dma_addr_t real_dma_addr; |
| 93 | dma_addr_t aligned_dma_addr; | ||
| 93 | struct sk_buff *skb; | 94 | struct sk_buff *skb; |
| 94 | struct list_head list; | 95 | struct list_head list; |
| 95 | }; | 96 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 7cde9d76ff5d..0509c16dbe75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
| @@ -204,7 +204,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) | |||
| 204 | list_del(element); | 204 | list_del(element); |
| 205 | 205 | ||
| 206 | /* Point to Rx buffer via next RBD in circular buffer */ | 206 | /* Point to Rx buffer via next RBD in circular buffer */ |
| 207 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr); | 207 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->aligned_dma_addr); |
| 208 | rxq->queue[rxq->write] = rxb; | 208 | rxq->queue[rxq->write] = rxb; |
| 209 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 209 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
| 210 | rxq->free_count--; | 210 | rxq->free_count--; |
| @@ -251,7 +251,7 @@ void iwl_rx_allocate(struct iwl_priv *priv) | |||
| 251 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | 251 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); |
| 252 | 252 | ||
| 253 | /* Alloc a new receive buffer */ | 253 | /* Alloc a new receive buffer */ |
| 254 | rxb->skb = alloc_skb(priv->hw_params.rx_buf_size, | 254 | rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256, |
| 255 | __GFP_NOWARN | GFP_ATOMIC); | 255 | __GFP_NOWARN | GFP_ATOMIC); |
| 256 | if (!rxb->skb) { | 256 | if (!rxb->skb) { |
| 257 | if (net_ratelimit()) | 257 | if (net_ratelimit()) |
| @@ -266,9 +266,17 @@ void iwl_rx_allocate(struct iwl_priv *priv) | |||
| 266 | list_del(element); | 266 | list_del(element); |
| 267 | 267 | ||
| 268 | /* Get physical address of RB/SKB */ | 268 | /* Get physical address of RB/SKB */ |
| 269 | rxb->dma_addr = | 269 | rxb->real_dma_addr = pci_map_single( |
| 270 | pci_map_single(priv->pci_dev, rxb->skb->data, | 270 | priv->pci_dev, |
| 271 | priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); | 271 | rxb->skb->data, |
| 272 | priv->hw_params.rx_buf_size + 256, | ||
| 273 | PCI_DMA_FROMDEVICE); | ||
| 274 | /* dma address must be no more than 36 bits */ | ||
| 275 | BUG_ON(rxb->real_dma_addr & ~DMA_BIT_MASK(36)); | ||
| 276 | /* and also 256 byte aligned! */ | ||
| 277 | rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256); | ||
| 278 | skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr); | ||
| 279 | |||
| 272 | list_add_tail(&rxb->list, &rxq->rx_free); | 280 | list_add_tail(&rxb->list, &rxq->rx_free); |
| 273 | rxq->free_count++; | 281 | rxq->free_count++; |
| 274 | } | 282 | } |
| @@ -300,8 +308,8 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
| 300 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 308 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
| 301 | if (rxq->pool[i].skb != NULL) { | 309 | if (rxq->pool[i].skb != NULL) { |
| 302 | pci_unmap_single(priv->pci_dev, | 310 | pci_unmap_single(priv->pci_dev, |
| 303 | rxq->pool[i].dma_addr, | 311 | rxq->pool[i].real_dma_addr, |
| 304 | priv->hw_params.rx_buf_size, | 312 | priv->hw_params.rx_buf_size + 256, |
| 305 | PCI_DMA_FROMDEVICE); | 313 | PCI_DMA_FROMDEVICE); |
| 306 | dev_kfree_skb(rxq->pool[i].skb); | 314 | dev_kfree_skb(rxq->pool[i].skb); |
| 307 | } | 315 | } |
| @@ -354,8 +362,8 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
| 354 | * to an SKB, so we need to unmap and free potential storage */ | 362 | * to an SKB, so we need to unmap and free potential storage */ |
| 355 | if (rxq->pool[i].skb != NULL) { | 363 | if (rxq->pool[i].skb != NULL) { |
| 356 | pci_unmap_single(priv->pci_dev, | 364 | pci_unmap_single(priv->pci_dev, |
| 357 | rxq->pool[i].dma_addr, | 365 | rxq->pool[i].real_dma_addr, |
| 358 | priv->hw_params.rx_buf_size, | 366 | priv->hw_params.rx_buf_size + 256, |
| 359 | PCI_DMA_FROMDEVICE); | 367 | PCI_DMA_FROMDEVICE); |
| 360 | priv->alloc_rxb_skb--; | 368 | priv->alloc_rxb_skb--; |
| 361 | dev_kfree_skb(rxq->pool[i].skb); | 369 | dev_kfree_skb(rxq->pool[i].skb); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 3b0bee331a33..c89365e2ca58 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
| @@ -896,6 +896,13 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
| 896 | return; | 896 | return; |
| 897 | 897 | ||
| 898 | done: | 898 | done: |
| 899 | /* Cannot perform scan. Make sure we clear scanning | ||
| 900 | * bits from status so next scan request can be performed. | ||
| 901 | * If we don't clear scanning status bit here all next scan | ||
| 902 | * will fail | ||
| 903 | */ | ||
| 904 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
| 905 | clear_bit(STATUS_SCANNING, &priv->status); | ||
| 899 | /* inform mac80211 scan aborted */ | 906 | /* inform mac80211 scan aborted */ |
| 900 | queue_work(priv->workqueue, &priv->scan_completed); | 907 | queue_work(priv->workqueue, &priv->scan_completed); |
| 901 | mutex_unlock(&priv->mutex); | 908 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 61797f3f8d5c..26f7084d3011 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
| @@ -475,7 +475,7 @@ static int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | |||
| 475 | if (!test_and_set_bit(i, &priv->ucode_key_table)) | 475 | if (!test_and_set_bit(i, &priv->ucode_key_table)) |
| 476 | return i; | 476 | return i; |
| 477 | 477 | ||
| 478 | return -1; | 478 | return WEP_INVALID_OFFSET; |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | 481 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) |
| @@ -620,6 +620,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | |||
| 620 | /* else, we are overriding an existing key => no need to allocated room | 620 | /* else, we are overriding an existing key => no need to allocated room |
| 621 | * in uCode. */ | 621 | * in uCode. */ |
| 622 | 622 | ||
| 623 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | ||
| 624 | "no space for new kew"); | ||
| 625 | |||
| 623 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 626 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
| 624 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 627 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
| 625 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 628 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
| @@ -637,6 +640,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
| 637 | { | 640 | { |
| 638 | unsigned long flags; | 641 | unsigned long flags; |
| 639 | __le16 key_flags = 0; | 642 | __le16 key_flags = 0; |
| 643 | int ret; | ||
| 640 | 644 | ||
| 641 | key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); | 645 | key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); |
| 642 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 646 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
| @@ -664,14 +668,18 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
| 664 | /* else, we are overriding an existing key => no need to allocated room | 668 | /* else, we are overriding an existing key => no need to allocated room |
| 665 | * in uCode. */ | 669 | * in uCode. */ |
| 666 | 670 | ||
| 671 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | ||
| 672 | "no space for new kew"); | ||
| 673 | |||
| 667 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 674 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
| 668 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 675 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
| 669 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 676 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
| 670 | 677 | ||
| 678 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
| 679 | |||
| 671 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 680 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
| 672 | 681 | ||
| 673 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); | 682 | return ret; |
| 674 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
| 675 | } | 683 | } |
| 676 | 684 | ||
| 677 | static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | 685 | static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, |
| @@ -696,6 +704,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | |||
| 696 | /* else, we are overriding an existing key => no need to allocated room | 704 | /* else, we are overriding an existing key => no need to allocated room |
| 697 | * in uCode. */ | 705 | * in uCode. */ |
| 698 | 706 | ||
| 707 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | ||
| 708 | "no space for new kew"); | ||
| 709 | |||
| 699 | /* This copy is acutally not needed: we get the key with each TX */ | 710 | /* This copy is acutally not needed: we get the key with each TX */ |
| 700 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); | 711 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); |
| 701 | 712 | ||
| @@ -734,6 +745,13 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
| 734 | return 0; | 745 | return 0; |
| 735 | } | 746 | } |
| 736 | 747 | ||
| 748 | if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { | ||
| 749 | IWL_WARNING("Removing wrong key %d 0x%x\n", | ||
| 750 | keyconf->keyidx, key_flags); | ||
| 751 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
| 752 | return 0; | ||
| 753 | } | ||
| 754 | |||
| 737 | if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, | 755 | if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, |
| 738 | &priv->ucode_key_table)) | 756 | &priv->ucode_key_table)) |
| 739 | IWL_ERROR("index %d not used in uCode key table.\n", | 757 | IWL_ERROR("index %d not used in uCode key table.\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d15a2c997954..45a6b0c35695 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
| @@ -5768,7 +5768,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
| 5768 | if (priv->error_recovering) | 5768 | if (priv->error_recovering) |
| 5769 | iwl3945_error_recovery(priv); | 5769 | iwl3945_error_recovery(priv); |
| 5770 | 5770 | ||
| 5771 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | ||
| 5772 | return; | 5771 | return; |
| 5773 | 5772 | ||
| 5774 | restart: | 5773 | restart: |
| @@ -6256,6 +6255,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
| 6256 | n_probes, | 6255 | n_probes, |
| 6257 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6256 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
| 6258 | 6257 | ||
| 6258 | if (scan->channel_count == 0) { | ||
| 6259 | IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); | ||
| 6260 | goto done; | ||
| 6261 | } | ||
| 6262 | |||
| 6259 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 6263 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
| 6260 | scan->channel_count * sizeof(struct iwl3945_scan_channel); | 6264 | scan->channel_count * sizeof(struct iwl3945_scan_channel); |
| 6261 | cmd.data = scan; | 6265 | cmd.data = scan; |
| @@ -6273,6 +6277,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
| 6273 | return; | 6277 | return; |
| 6274 | 6278 | ||
| 6275 | done: | 6279 | done: |
| 6280 | /* can not perform scan make sure we clear scanning | ||
| 6281 | * bits from status so next scan request can be performed. | ||
| 6282 | * if we dont clear scanning status bit here all next scan | ||
| 6283 | * will fail | ||
| 6284 | */ | ||
| 6285 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
| 6286 | clear_bit(STATUS_SCANNING, &priv->status); | ||
| 6287 | |||
| 6276 | /* inform mac80211 scan aborted */ | 6288 | /* inform mac80211 scan aborted */ |
| 6277 | queue_work(priv->workqueue, &priv->scan_completed); | 6289 | queue_work(priv->workqueue, &priv->scan_completed); |
| 6278 | mutex_unlock(&priv->mutex); | 6290 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 297696de2da0..8265c7d25edc 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
| @@ -605,9 +605,9 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, | |||
| 605 | if (ret == 0) { | 605 | if (ret == 0) { |
| 606 | *curlevel = le16_to_cpu(cmd.curlevel); | 606 | *curlevel = le16_to_cpu(cmd.curlevel); |
| 607 | if (minlevel) | 607 | if (minlevel) |
| 608 | *minlevel = le16_to_cpu(cmd.minlevel); | 608 | *minlevel = cmd.minlevel; |
| 609 | if (maxlevel) | 609 | if (maxlevel) |
| 610 | *maxlevel = le16_to_cpu(cmd.maxlevel); | 610 | *maxlevel = cmd.maxlevel; |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | lbs_deb_leave(LBS_DEB_CMD); | 613 | lbs_deb_leave(LBS_DEB_CMD); |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 8f66903641b9..22c4c6110521 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
| @@ -598,8 +598,8 @@ static int lbs_process_bss(struct bss_descriptor *bss, | |||
| 598 | 598 | ||
| 599 | switch (elem->id) { | 599 | switch (elem->id) { |
| 600 | case MFIE_TYPE_SSID: | 600 | case MFIE_TYPE_SSID: |
| 601 | bss->ssid_len = elem->len; | 601 | bss->ssid_len = min_t(int, 32, elem->len); |
| 602 | memcpy(bss->ssid, elem->data, elem->len); | 602 | memcpy(bss->ssid, elem->data, bss->ssid_len); |
| 603 | lbs_deb_scan("got SSID IE: '%s', len %u\n", | 603 | lbs_deb_scan("got SSID IE: '%s', len %u\n", |
| 604 | escape_essid(bss->ssid, bss->ssid_len), | 604 | escape_essid(bss->ssid, bss->ssid_len), |
| 605 | bss->ssid_len); | 605 | bss->ssid_len); |
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 1cc03a8dd67a..59634c33b1f9 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c | |||
| @@ -331,7 +331,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, | |||
| 331 | /* Fill the receive configuration URB and initialise the Rx call back */ | 331 | /* Fill the receive configuration URB and initialise the Rx call back */ |
| 332 | usb_fill_bulk_urb(cardp->rx_urb, cardp->udev, | 332 | usb_fill_bulk_urb(cardp->rx_urb, cardp->udev, |
| 333 | usb_rcvbulkpipe(cardp->udev, cardp->ep_in), | 333 | usb_rcvbulkpipe(cardp->udev, cardp->ep_in), |
| 334 | (void *) (skb->tail), | 334 | skb_tail_pointer(skb), |
| 335 | MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp); | 335 | MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp); |
| 336 | 336 | ||
| 337 | cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; | 337 | cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index f839ce044afd..95511ac22470 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | menuconfig RT2X00 | 1 | menuconfig RT2X00 |
| 2 | bool "Ralink driver support" | 2 | tristate "Ralink driver support" |
| 3 | depends on MAC80211 && WLAN_80211 && EXPERIMENTAL | 3 | depends on MAC80211 && WLAN_80211 && EXPERIMENTAL |
| 4 | ---help--- | 4 | ---help--- |
| 5 | This will enable the experimental support for the Ralink drivers, | 5 | This will enable the experimental support for the Ralink drivers, |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 431e3c78bf27..69eb0132593b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
| @@ -48,6 +48,9 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { | |||
| 48 | {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, | 48 | {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, |
| 49 | /* Sitecom */ | 49 | /* Sitecom */ |
| 50 | {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, | 50 | {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, |
| 51 | {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, | ||
| 52 | /* Abocom */ | ||
| 53 | {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, | ||
| 51 | {} | 54 | {} |
| 52 | }; | 55 | }; |
| 53 | 56 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index fe1867b25ff7..cac732f4047f 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
| @@ -615,7 +615,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
| 615 | struct ieee80211_hdr *tx_hdr; | 615 | struct ieee80211_hdr *tx_hdr; |
| 616 | 616 | ||
| 617 | tx_hdr = (struct ieee80211_hdr *)skb->data; | 617 | tx_hdr = (struct ieee80211_hdr *)skb->data; |
| 618 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) | 618 | if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN))) |
| 619 | { | 619 | { |
| 620 | __skb_unlink(skb, q); | 620 | __skb_unlink(skb, q); |
| 621 | tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1); | 621 | tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1); |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index a60ae86bd5c9..a3ccd8c1c716 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
| @@ -61,6 +61,7 @@ static struct usb_device_id usb_ids[] = { | |||
| 61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, | 61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, |
| 62 | /* ZD1211B */ | 62 | /* ZD1211B */ |
| 63 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, | 63 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, |
| 64 | { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, | ||
| 64 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, | 65 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, |
| 65 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, | 66 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, |
| 66 | { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, | 67 | { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, |
| @@ -82,6 +83,7 @@ static struct usb_device_id usb_ids[] = { | |||
| 82 | { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B }, | 83 | { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B }, |
| 83 | { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, | 84 | { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, |
| 84 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, | 85 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, |
| 86 | { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, | ||
| 85 | /* "Driverless" devices that need ejecting */ | 87 | /* "Driverless" devices that need ejecting */ |
| 86 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, | 88 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, |
| 87 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, | 89 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index c6948d8f53f6..6d017adc914a 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -1785,7 +1785,7 @@ static int __devexit xennet_remove(struct xenbus_device *dev) | |||
| 1785 | return 0; | 1785 | return 0; |
| 1786 | } | 1786 | } |
| 1787 | 1787 | ||
| 1788 | static struct xenbus_driver netfront = { | 1788 | static struct xenbus_driver netfront_driver = { |
| 1789 | .name = "vif", | 1789 | .name = "vif", |
| 1790 | .owner = THIS_MODULE, | 1790 | .owner = THIS_MODULE, |
| 1791 | .ids = netfront_ids, | 1791 | .ids = netfront_ids, |
| @@ -1805,7 +1805,7 @@ static int __init netif_init(void) | |||
| 1805 | 1805 | ||
| 1806 | printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n"); | 1806 | printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n"); |
| 1807 | 1807 | ||
| 1808 | return xenbus_register_frontend(&netfront); | 1808 | return xenbus_register_frontend(&netfront_driver); |
| 1809 | } | 1809 | } |
| 1810 | module_init(netif_init); | 1810 | module_init(netif_init); |
| 1811 | 1811 | ||
| @@ -1815,7 +1815,7 @@ static void __exit netif_exit(void) | |||
| 1815 | if (xen_initial_domain()) | 1815 | if (xen_initial_domain()) |
| 1816 | return; | 1816 | return; |
| 1817 | 1817 | ||
| 1818 | xenbus_unregister_driver(&netfront); | 1818 | xenbus_unregister_driver(&netfront_driver); |
| 1819 | } | 1819 | } |
| 1820 | module_exit(netif_exit); | 1820 | module_exit(netif_exit); |
| 1821 | 1821 | ||
diff --git a/drivers/of/device.c b/drivers/of/device.c index 51e5214071da..224ae6bc67b6 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
| @@ -105,7 +105,16 @@ EXPORT_SYMBOL(of_release_dev); | |||
| 105 | int of_device_register(struct of_device *ofdev) | 105 | int of_device_register(struct of_device *ofdev) |
| 106 | { | 106 | { |
| 107 | BUG_ON(ofdev->node == NULL); | 107 | BUG_ON(ofdev->node == NULL); |
| 108 | return device_register(&ofdev->dev); | 108 | |
| 109 | device_initialize(&ofdev->dev); | ||
| 110 | |||
| 111 | /* device_add will assume that this device is on the same node as | ||
| 112 | * the parent. If there is no parent defined, set the node | ||
| 113 | * explicitly */ | ||
| 114 | if (!ofdev->dev.parent) | ||
| 115 | set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->node)); | ||
| 116 | |||
| 117 | return device_add(&ofdev->dev); | ||
| 109 | } | 118 | } |
| 110 | EXPORT_SYMBOL(of_device_register); | 119 | EXPORT_SYMBOL(of_device_register); |
| 111 | 120 | ||
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c index d962ba0dd87a..191a3202cecc 100644 --- a/drivers/oprofile/event_buffer.c +++ b/drivers/oprofile/event_buffer.c | |||
| @@ -105,7 +105,7 @@ static int event_buffer_open(struct inode *inode, struct file *file) | |||
| 105 | if (!capable(CAP_SYS_ADMIN)) | 105 | if (!capable(CAP_SYS_ADMIN)) |
| 106 | return -EPERM; | 106 | return -EPERM; |
| 107 | 107 | ||
| 108 | if (test_and_set_bit(0, &buffer_opened)) | 108 | if (test_and_set_bit_lock(0, &buffer_opened)) |
| 109 | return -EBUSY; | 109 | return -EBUSY; |
| 110 | 110 | ||
| 111 | /* Register as a user of dcookies | 111 | /* Register as a user of dcookies |
| @@ -129,7 +129,7 @@ static int event_buffer_open(struct inode *inode, struct file *file) | |||
| 129 | fail: | 129 | fail: |
| 130 | dcookie_unregister(file->private_data); | 130 | dcookie_unregister(file->private_data); |
| 131 | out: | 131 | out: |
| 132 | clear_bit(0, &buffer_opened); | 132 | __clear_bit_unlock(0, &buffer_opened); |
| 133 | return err; | 133 | return err; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| @@ -141,7 +141,7 @@ static int event_buffer_release(struct inode *inode, struct file *file) | |||
| 141 | dcookie_unregister(file->private_data); | 141 | dcookie_unregister(file->private_data); |
| 142 | buffer_pos = 0; | 142 | buffer_pos = 0; |
| 143 | atomic_set(&buffer_ready, 0); | 143 | atomic_set(&buffer_ready, 0); |
| 144 | clear_bit(0, &buffer_opened); | 144 | __clear_bit_unlock(0, &buffer_opened); |
| 145 | return 0; | 145 | return 0; |
| 146 | } | 146 | } |
| 147 | 147 | ||
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 209b4a464bcf..855f389eea40 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig | |||
| @@ -36,7 +36,7 @@ if PARPORT | |||
| 36 | config PARPORT_PC | 36 | config PARPORT_PC |
| 37 | tristate "PC-style hardware" | 37 | tristate "PC-style hardware" |
| 38 | depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && \ | 38 | depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && \ |
| 39 | (!M68K || ISA) && !MN10300 && !AVR32 | 39 | (!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN |
| 40 | ---help--- | 40 | ---help--- |
| 41 | You should say Y here if you have a PC-style parallel port. All | 41 | You should say Y here if you have a PC-style parallel port. All |
| 42 | IBM PC compatible computers and some Alphas have PC-style | 42 | IBM PC compatible computers and some Alphas have PC-style |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index e2e95b36a603..101ed49a2d15 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
| @@ -70,6 +70,8 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc | |||
| 70 | * parallel ports and <S> is the number of serial ports. | 70 | * parallel ports and <S> is the number of serial ports. |
| 71 | */ | 71 | */ |
| 72 | card->numports = (dev->subsystem_device & 0xf0) >> 4; | 72 | card->numports = (dev->subsystem_device & 0xf0) >> 4; |
| 73 | if (card->numports > ARRAY_SIZE(card->addr)) | ||
| 74 | card->numports = ARRAY_SIZE(card->addr); | ||
| 73 | return 0; | 75 | return 0; |
| 74 | } | 76 | } |
| 75 | 77 | ||
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index a2692724b68f..5c8baa43ac9c 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
| @@ -1655,12 +1655,14 @@ int __init init_dmars(void) | |||
| 1655 | iommu->flush.flush_context = __iommu_flush_context; | 1655 | iommu->flush.flush_context = __iommu_flush_context; |
| 1656 | iommu->flush.flush_iotlb = __iommu_flush_iotlb; | 1656 | iommu->flush.flush_iotlb = __iommu_flush_iotlb; |
| 1657 | printk(KERN_INFO "IOMMU 0x%Lx: using Register based " | 1657 | printk(KERN_INFO "IOMMU 0x%Lx: using Register based " |
| 1658 | "invalidation\n", drhd->reg_base_addr); | 1658 | "invalidation\n", |
| 1659 | (unsigned long long)drhd->reg_base_addr); | ||
| 1659 | } else { | 1660 | } else { |
| 1660 | iommu->flush.flush_context = qi_flush_context; | 1661 | iommu->flush.flush_context = qi_flush_context; |
| 1661 | iommu->flush.flush_iotlb = qi_flush_iotlb; | 1662 | iommu->flush.flush_iotlb = qi_flush_iotlb; |
| 1662 | printk(KERN_INFO "IOMMU 0x%Lx: using Queued " | 1663 | printk(KERN_INFO "IOMMU 0x%Lx: using Queued " |
| 1663 | "invalidation\n", drhd->reg_base_addr); | 1664 | "invalidation\n", |
| 1665 | (unsigned long long)drhd->reg_base_addr); | ||
| 1664 | } | 1666 | } |
| 1665 | } | 1667 | } |
| 1666 | 1668 | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index b3a63edb6901..ae5ec76dca77 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -63,7 +63,7 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
| 63 | union acpi_object in_params[4]; | 63 | union acpi_object in_params[4]; |
| 64 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | 64 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; |
| 65 | union acpi_object *out_obj; | 65 | union acpi_object *out_obj; |
| 66 | u32 osc_dw0, flags = osc_args->capbuf[OSC_QUERY_TYPE]; | 66 | u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE]; |
| 67 | 67 | ||
| 68 | /* Setting up input parameters */ | 68 | /* Setting up input parameters */ |
| 69 | input.count = 4; | 69 | input.count = 4; |
| @@ -92,15 +92,16 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
| 92 | status = AE_TYPE; | 92 | status = AE_TYPE; |
| 93 | goto out_kfree; | 93 | goto out_kfree; |
| 94 | } | 94 | } |
| 95 | osc_dw0 = *((u32 *)out_obj->buffer.pointer); | 95 | /* Need to ignore the bit0 in result code */ |
| 96 | if (osc_dw0) { | 96 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); |
| 97 | if (osc_dw0 & OSC_REQUEST_ERROR) | 97 | if (errors) { |
| 98 | if (errors & OSC_REQUEST_ERROR) | ||
| 98 | printk(KERN_DEBUG "_OSC request fails\n"); | 99 | printk(KERN_DEBUG "_OSC request fails\n"); |
| 99 | if (osc_dw0 & OSC_INVALID_UUID_ERROR) | 100 | if (errors & OSC_INVALID_UUID_ERROR) |
| 100 | printk(KERN_DEBUG "_OSC invalid UUID\n"); | 101 | printk(KERN_DEBUG "_OSC invalid UUID\n"); |
| 101 | if (osc_dw0 & OSC_INVALID_REVISION_ERROR) | 102 | if (errors & OSC_INVALID_REVISION_ERROR) |
| 102 | printk(KERN_DEBUG "_OSC invalid revision\n"); | 103 | printk(KERN_DEBUG "_OSC invalid revision\n"); |
| 103 | if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { | 104 | if (errors & OSC_CAPABILITIES_MASK_ERROR) { |
| 104 | if (flags & OSC_QUERY_ENABLE) | 105 | if (flags & OSC_QUERY_ENABLE) |
| 105 | goto out_success; | 106 | goto out_success; |
| 106 | printk(KERN_DEBUG "_OSC FW not grant req. control\n"); | 107 | printk(KERN_DEBUG "_OSC FW not grant req. control\n"); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 110022d78689..5d72866897a8 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -575,7 +575,7 @@ static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct | |||
| 575 | 575 | ||
| 576 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 576 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
| 577 | start = vma->vm_pgoff; | 577 | start = vma->vm_pgoff; |
| 578 | size = pci_resource_len(pdev, resno) >> PAGE_SHIFT; | 578 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |
| 579 | if (start < size && size - start >= nr) | 579 | if (start < size && size - start >= nr) |
| 580 | return 1; | 580 | return 1; |
| 581 | WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", | 581 | WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 21f2ac639cab..061d1ee0046a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1832,7 +1832,7 @@ int pci_reset_function(struct pci_dev *dev) | |||
| 1832 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | 1832 | if (!(cap & PCI_EXP_DEVCAP_FLR)) |
| 1833 | return -ENOTTY; | 1833 | return -ENOTTY; |
| 1834 | 1834 | ||
| 1835 | if (!dev->msi_enabled && !dev->msix_enabled) | 1835 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
| 1836 | disable_irq(dev->irq); | 1836 | disable_irq(dev->irq); |
| 1837 | pci_save_state(dev); | 1837 | pci_save_state(dev); |
| 1838 | 1838 | ||
| @@ -1841,7 +1841,7 @@ int pci_reset_function(struct pci_dev *dev) | |||
| 1841 | r = pci_execute_reset_function(dev); | 1841 | r = pci_execute_reset_function(dev); |
| 1842 | 1842 | ||
| 1843 | pci_restore_state(dev); | 1843 | pci_restore_state(dev); |
| 1844 | if (!dev->msi_enabled && !dev->msix_enabled) | 1844 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
| 1845 | enable_irq(dev->irq); | 1845 | enable_irq(dev->irq); |
| 1846 | 1846 | ||
| 1847 | return r; | 1847 | return r; |
| @@ -2042,7 +2042,7 @@ static int __devinit pci_init(void) | |||
| 2042 | return 0; | 2042 | return 0; |
| 2043 | } | 2043 | } |
| 2044 | 2044 | ||
| 2045 | static int __devinit pci_setup(char *str) | 2045 | static int __init pci_setup(char *str) |
| 2046 | { | 2046 | { |
| 2047 | while (str) { | 2047 | while (str) { |
| 2048 | char *k = strchr(str, ','); | 2048 | char *k = strchr(str, ','); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 8f63f4c6b85f..9aad608bcf3f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/jiffies.h> | ||
| 19 | #include <linux/pci-aspm.h> | 20 | #include <linux/pci-aspm.h> |
| 20 | #include "../pci.h" | 21 | #include "../pci.h" |
| 21 | 22 | ||
| @@ -161,11 +162,12 @@ static void pcie_check_clock_pm(struct pci_dev *pdev) | |||
| 161 | */ | 162 | */ |
| 162 | static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | 163 | static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) |
| 163 | { | 164 | { |
| 164 | int pos, child_pos; | 165 | int pos, child_pos, i = 0; |
| 165 | u16 reg16 = 0; | 166 | u16 reg16 = 0; |
| 166 | struct pci_dev *child_dev; | 167 | struct pci_dev *child_dev; |
| 167 | int same_clock = 1; | 168 | int same_clock = 1; |
| 168 | 169 | unsigned long start_jiffies; | |
| 170 | u16 child_regs[8], parent_reg; | ||
| 169 | /* | 171 | /* |
| 170 | * all functions of a slot should have the same Slot Clock | 172 | * all functions of a slot should have the same Slot Clock |
| 171 | * Configuration, so just check one function | 173 | * Configuration, so just check one function |
| @@ -191,16 +193,19 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | |||
| 191 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | 193 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); |
| 192 | pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, | 194 | pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, |
| 193 | ®16); | 195 | ®16); |
| 196 | child_regs[i] = reg16; | ||
| 194 | if (same_clock) | 197 | if (same_clock) |
| 195 | reg16 |= PCI_EXP_LNKCTL_CCC; | 198 | reg16 |= PCI_EXP_LNKCTL_CCC; |
| 196 | else | 199 | else |
| 197 | reg16 &= ~PCI_EXP_LNKCTL_CCC; | 200 | reg16 &= ~PCI_EXP_LNKCTL_CCC; |
| 198 | pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, | 201 | pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL, |
| 199 | reg16); | 202 | reg16); |
| 203 | i++; | ||
| 200 | } | 204 | } |
| 201 | 205 | ||
| 202 | /* Configure upstream component */ | 206 | /* Configure upstream component */ |
| 203 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | 207 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); |
| 208 | parent_reg = reg16; | ||
| 204 | if (same_clock) | 209 | if (same_clock) |
| 205 | reg16 |= PCI_EXP_LNKCTL_CCC; | 210 | reg16 |= PCI_EXP_LNKCTL_CCC; |
| 206 | else | 211 | else |
| @@ -212,12 +217,30 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | |||
| 212 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); | 217 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); |
| 213 | 218 | ||
| 214 | /* Wait for link training end */ | 219 | /* Wait for link training end */ |
| 215 | while (1) { | 220 | /* break out after waiting for 1 second */ |
| 221 | start_jiffies = jiffies; | ||
| 222 | while ((jiffies - start_jiffies) < HZ) { | ||
| 216 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); | 223 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); |
| 217 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | 224 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) |
| 218 | break; | 225 | break; |
| 219 | cpu_relax(); | 226 | cpu_relax(); |
| 220 | } | 227 | } |
| 228 | /* training failed -> recover */ | ||
| 229 | if ((jiffies - start_jiffies) >= HZ) { | ||
| 230 | dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure" | ||
| 231 | " common clock\n"); | ||
| 232 | i = 0; | ||
| 233 | list_for_each_entry(child_dev, &pdev->subordinate->devices, | ||
| 234 | bus_list) { | ||
| 235 | child_pos = pci_find_capability(child_dev, | ||
| 236 | PCI_CAP_ID_EXP); | ||
| 237 | pci_write_config_word(child_dev, | ||
| 238 | child_pos + PCI_EXP_LNKCTL, | ||
| 239 | child_regs[i]); | ||
| 240 | i++; | ||
| 241 | } | ||
| 242 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, parent_reg); | ||
| 243 | } | ||
| 221 | } | 244 | } |
| 222 | 245 | ||
| 223 | /* | 246 | /* |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bbf66ea8fd87..5f4f85f56cb7 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 23 | #include <linux/acpi.h> | 23 | #include <linux/acpi.h> |
| 24 | #include <linux/kallsyms.h> | 24 | #include <linux/kallsyms.h> |
| 25 | #include <linux/dmi.h> | ||
| 25 | #include "pci.h" | 26 | #include "pci.h" |
| 26 | 27 | ||
| 27 | int isa_dma_bridge_buggy; | 28 | int isa_dma_bridge_buggy; |
| @@ -1692,24 +1693,24 @@ static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev) | |||
| 1692 | } | 1693 | } |
| 1693 | } | 1694 | } |
| 1694 | 1695 | ||
| 1695 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1696 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 1696 | PCI_DEVICE_ID_NX2_5706, | 1697 | PCI_DEVICE_ID_NX2_5706, |
| 1697 | quirk_brcm_570x_limit_vpd); | 1698 | quirk_brcm_570x_limit_vpd); |
| 1698 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1699 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 1699 | PCI_DEVICE_ID_NX2_5706S, | 1700 | PCI_DEVICE_ID_NX2_5706S, |
| 1700 | quirk_brcm_570x_limit_vpd); | 1701 | quirk_brcm_570x_limit_vpd); |
| 1701 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1702 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 1702 | PCI_DEVICE_ID_NX2_5708, | 1703 | PCI_DEVICE_ID_NX2_5708, |
| 1703 | quirk_brcm_570x_limit_vpd); | 1704 | quirk_brcm_570x_limit_vpd); |
| 1704 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1705 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 1705 | PCI_DEVICE_ID_NX2_5708S, | 1706 | PCI_DEVICE_ID_NX2_5708S, |
| 1706 | quirk_brcm_570x_limit_vpd); | 1707 | quirk_brcm_570x_limit_vpd); |
| 1707 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1708 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 1708 | PCI_DEVICE_ID_NX2_5709, | 1709 | PCI_DEVICE_ID_NX2_5709, |
| 1709 | quirk_brcm_570x_limit_vpd); | 1710 | quirk_brcm_570x_limit_vpd); |
| 1710 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1711 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 1711 | PCI_DEVICE_ID_NX2_5709S, | 1712 | PCI_DEVICE_ID_NX2_5709S, |
| 1712 | quirk_brcm_570x_limit_vpd); | 1713 | quirk_brcm_570x_limit_vpd); |
| 1713 | 1714 | ||
| 1714 | #ifdef CONFIG_PCI_MSI | 1715 | #ifdef CONFIG_PCI_MSI |
| 1715 | /* Some chipsets do not support MSI. We cannot easily rely on setting | 1716 | /* Some chipsets do not support MSI. We cannot easily rely on setting |
| @@ -1828,6 +1829,22 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | |||
| 1828 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | 1829 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, |
| 1829 | ht_enable_msi_mapping); | 1830 | ht_enable_msi_mapping); |
| 1830 | 1831 | ||
| 1832 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi | ||
| 1833 | * for the MCP55 NIC. It is not yet determined whether the msi problem | ||
| 1834 | * also affects other devices. As for now, turn off msi for this device. | ||
| 1835 | */ | ||
| 1836 | static void __devinit nvenet_msi_disable(struct pci_dev *dev) | ||
| 1837 | { | ||
| 1838 | if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) { | ||
| 1839 | dev_info(&dev->dev, | ||
| 1840 | "Disabling msi for MCP55 NIC on P5N32-SLI Premium\n"); | ||
| 1841 | dev->no_msi = 1; | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, | ||
| 1845 | PCI_DEVICE_ID_NVIDIA_NVENET_15, | ||
| 1846 | nvenet_msi_disable); | ||
| 1847 | |||
| 1831 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | 1848 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) |
| 1832 | { | 1849 | { |
| 1833 | struct pci_dev *host_bridge; | 1850 | struct pci_dev *host_bridge; |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 1f5f6143f35c..132a78159b60 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
| @@ -100,7 +100,8 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size) | |||
| 100 | * pci_map_rom - map a PCI ROM to kernel space | 100 | * pci_map_rom - map a PCI ROM to kernel space |
| 101 | * @pdev: pointer to pci device struct | 101 | * @pdev: pointer to pci device struct |
| 102 | * @size: pointer to receive size of pci window over ROM | 102 | * @size: pointer to receive size of pci window over ROM |
| 103 | * @return: kernel virtual pointer to image of ROM | 103 | * |
| 104 | * Return: kernel virtual pointer to image of ROM | ||
| 104 | * | 105 | * |
| 105 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, | 106 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, |
| 106 | * the shadow BIOS copy will be returned instead of the | 107 | * the shadow BIOS copy will be returned instead of the |
| @@ -167,7 +168,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
| 167 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy | 168 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy |
| 168 | * @pdev: pointer to pci device struct | 169 | * @pdev: pointer to pci device struct |
| 169 | * @size: pointer to receive size of pci window over ROM | 170 | * @size: pointer to receive size of pci window over ROM |
| 170 | * @return: kernel virtual pointer to image of ROM | 171 | * |
| 172 | * Return: kernel virtual pointer to image of ROM | ||
| 171 | * | 173 | * |
| 172 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, | 174 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, |
| 173 | * the shadow BIOS copy will be returned instead of the | 175 | * the shadow BIOS copy will be returned instead of the |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 4dd1c3e157ae..5a8ccb4f604d 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
| @@ -253,6 +253,7 @@ placeholder: | |||
| 253 | __func__, pci_domain_nr(parent), parent->number, slot_nr); | 253 | __func__, pci_domain_nr(parent), parent->number, slot_nr); |
| 254 | 254 | ||
| 255 | out: | 255 | out: |
| 256 | kfree(slot_name); | ||
| 256 | up_write(&pci_bus_sem); | 257 | up_write(&pci_bus_sem); |
| 257 | return slot; | 258 | return slot; |
| 258 | err: | 259 | err: |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index f57eeae3830a..222904411a13 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
| @@ -188,10 +188,6 @@ config PCMCIA_M8XX | |||
| 188 | 188 | ||
| 189 | This driver is also available as a module called m8xx_pcmcia. | 189 | This driver is also available as a module called m8xx_pcmcia. |
| 190 | 190 | ||
| 191 | config HD64465_PCMCIA | ||
| 192 | tristate "HD64465 host bridge support" | ||
| 193 | depends on HD64465 && PCMCIA | ||
| 194 | |||
| 195 | config PCMCIA_AU1X00 | 191 | config PCMCIA_AU1X00 |
| 196 | tristate "Au1x00 pcmcia support" | 192 | tristate "Au1x00 pcmcia support" |
| 197 | depends on SOC_AU1X00 && PCMCIA | 193 | depends on SOC_AU1X00 && PCMCIA |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 23e492bf75cf..238629ad7f7c 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
| @@ -22,7 +22,6 @@ obj-$(CONFIG_I82365) += i82365.o | |||
| 22 | obj-$(CONFIG_I82092) += i82092.o | 22 | obj-$(CONFIG_I82092) += i82092.o |
| 23 | obj-$(CONFIG_TCIC) += tcic.o | 23 | obj-$(CONFIG_TCIC) += tcic.o |
| 24 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o | 24 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o |
| 25 | obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o | ||
| 26 | obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o | 25 | obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o |
| 27 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o | 26 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o |
| 28 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o | 27 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o |
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index dcce9f5d8465..4a110b7b2673 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
| @@ -351,10 +351,11 @@ int verify_cis_cache(struct pcmcia_socket *s) | |||
| 351 | char *buf; | 351 | char *buf; |
| 352 | 352 | ||
| 353 | buf = kmalloc(256, GFP_KERNEL); | 353 | buf = kmalloc(256, GFP_KERNEL); |
| 354 | if (buf == NULL) | 354 | if (buf == NULL) { |
| 355 | dev_printk(KERN_WARNING, &s->dev, | 355 | dev_printk(KERN_WARNING, &s->dev, |
| 356 | "no memory for verifying CIS\n"); | 356 | "no memory for verifying CIS\n"); |
| 357 | return -ENOMEM; | 357 | return -ENOMEM; |
| 358 | } | ||
| 358 | list_for_each_entry(cis, &s->cis_cache, node) { | 359 | list_for_each_entry(cis, &s->cis_cache, node) { |
| 359 | int len = cis->len; | 360 | int len = cis->len; |
| 360 | 361 | ||
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index c68c5d338285..0660ad182589 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
| @@ -186,12 +186,6 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) | |||
| 186 | 186 | ||
| 187 | spin_lock_init(&socket->lock); | 187 | spin_lock_init(&socket->lock); |
| 188 | 188 | ||
| 189 | if (socket->resource_ops->init) { | ||
| 190 | ret = socket->resource_ops->init(socket); | ||
| 191 | if (ret) | ||
| 192 | return (ret); | ||
| 193 | } | ||
| 194 | |||
| 195 | /* try to obtain a socket number [yes, it gets ugly if we | 189 | /* try to obtain a socket number [yes, it gets ugly if we |
| 196 | * register more than 2^sizeof(unsigned int) pcmcia | 190 | * register more than 2^sizeof(unsigned int) pcmcia |
| 197 | * sockets... but the socket number is deprecated | 191 | * sockets... but the socket number is deprecated |
| @@ -226,7 +220,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) | |||
| 226 | /* set proper values in socket->dev */ | 220 | /* set proper values in socket->dev */ |
| 227 | dev_set_drvdata(&socket->dev, socket); | 221 | dev_set_drvdata(&socket->dev, socket); |
| 228 | socket->dev.class = &pcmcia_socket_class; | 222 | socket->dev.class = &pcmcia_socket_class; |
| 229 | snprintf(socket->dev.bus_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock); | 223 | dev_set_name(&socket->dev, "pcmcia_socket%u", socket->sock); |
| 230 | 224 | ||
| 231 | /* base address = 0, map = 0 */ | 225 | /* base address = 0, map = 0 */ |
| 232 | socket->cis_mem.flags = 0; | 226 | socket->cis_mem.flags = 0; |
| @@ -239,6 +233,12 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) | |||
| 239 | mutex_init(&socket->skt_mutex); | 233 | mutex_init(&socket->skt_mutex); |
| 240 | spin_lock_init(&socket->thread_lock); | 234 | spin_lock_init(&socket->thread_lock); |
| 241 | 235 | ||
| 236 | if (socket->resource_ops->init) { | ||
| 237 | ret = socket->resource_ops->init(socket); | ||
| 238 | if (ret) | ||
| 239 | goto err; | ||
| 240 | } | ||
| 241 | |||
| 242 | tsk = kthread_run(pccardd, socket, "pccardd"); | 242 | tsk = kthread_run(pccardd, socket, "pccardd"); |
| 243 | if (IS_ERR(tsk)) { | 243 | if (IS_ERR(tsk)) { |
| 244 | ret = PTR_ERR(tsk); | 244 | ret = PTR_ERR(tsk); |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 795660255490..47cab31ff6e4 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
| @@ -622,7 +622,6 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
| 622 | { | 622 | { |
| 623 | struct pcmcia_device *p_dev, *tmp_dev; | 623 | struct pcmcia_device *p_dev, *tmp_dev; |
| 624 | unsigned long flags; | 624 | unsigned long flags; |
| 625 | int bus_id_len; | ||
| 626 | 625 | ||
| 627 | s = pcmcia_get_socket(s); | 626 | s = pcmcia_get_socket(s); |
| 628 | if (!s) | 627 | if (!s) |
| @@ -650,12 +649,12 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
| 650 | /* by default don't allow DMA */ | 649 | /* by default don't allow DMA */ |
| 651 | p_dev->dma_mask = DMA_MASK_NONE; | 650 | p_dev->dma_mask = DMA_MASK_NONE; |
| 652 | p_dev->dev.dma_mask = &p_dev->dma_mask; | 651 | p_dev->dev.dma_mask = &p_dev->dma_mask; |
| 653 | bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); | 652 | dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); |
| 654 | 653 | if (!dev_name(&p_dev->dev)) | |
| 655 | p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL); | 654 | goto err_free; |
| 655 | p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev)); | ||
| 656 | if (!p_dev->devname) | 656 | if (!p_dev->devname) |
| 657 | goto err_free; | 657 | goto err_free; |
| 658 | sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); | ||
| 659 | ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname); | 658 | ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname); |
| 660 | 659 | ||
| 661 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 660 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); |
| @@ -668,6 +667,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
| 668 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) | 667 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) |
| 669 | if (p_dev->func == tmp_dev->func) { | 668 | if (p_dev->func == tmp_dev->func) { |
| 670 | p_dev->function_config = tmp_dev->function_config; | 669 | p_dev->function_config = tmp_dev->function_config; |
| 670 | p_dev->io = tmp_dev->io; | ||
| 671 | p_dev->irq = tmp_dev->irq; | ||
| 671 | kref_get(&p_dev->function_config->ref); | 672 | kref_get(&p_dev->function_config->ref); |
| 672 | } | 673 | } |
| 673 | 674 | ||
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c deleted file mode 100644 index 9ef69cdb3183..000000000000 --- a/drivers/pcmcia/hd64465_ss.c +++ /dev/null | |||
| @@ -1,939 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Device driver for the PCMCIA controller module of the | ||
| 3 | * Hitachi HD64465 handheld companion chip. | ||
| 4 | * | ||
| 5 | * Note that the HD64465 provides a very thin PCMCIA host bridge | ||
| 6 | * layer, requiring a lot of the work of supporting cards to be | ||
| 7 | * performed by the processor. For example: mapping of card | ||
| 8 | * interrupts to processor IRQs is done by IRQ demuxing software; | ||
| 9 | * IO and memory mappings are fixed; setting voltages according | ||
| 10 | * to card Voltage Select pins etc is done in software. | ||
| 11 | * | ||
| 12 | * Note also that this driver uses only the simple, fixed, | ||
| 13 | * 16MB, 16-bit wide mappings to PCMCIA spaces defined by the | ||
| 14 | * HD64465. Larger mappings, smaller mappings, or mappings of | ||
| 15 | * different width to the same socket, are all possible only by | ||
| 16 | * involving the SH7750's MMU, which is considered unnecessary here. | ||
| 17 | * The downside is that it may be possible for some drivers to | ||
| 18 | * break because they need or expect 8-bit mappings. | ||
| 19 | * | ||
| 20 | * This driver currently supports only the following configuration: | ||
| 21 | * SH7750 CPU, HD64465, TPS2206 voltage control chip. | ||
| 22 | * | ||
| 23 | * by Greg Banks <gbanks@pocketpenguins.com> | ||
| 24 | * (c) 2000 PocketPenguins Inc | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/types.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/init.h> | ||
| 30 | #include <linux/string.h> | ||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/ioport.h> | ||
| 33 | #include <linux/mm.h> | ||
| 34 | #include <linux/vmalloc.h> | ||
| 35 | #include <asm/errno.h> | ||
| 36 | #include <linux/irq.h> | ||
| 37 | #include <linux/interrupt.h> | ||
| 38 | #include <linux/platform_device.h> | ||
| 39 | |||
| 40 | #include <asm/io.h> | ||
| 41 | #include <asm/hd64465/hd64465.h> | ||
| 42 | #include <asm/hd64465/io.h> | ||
| 43 | |||
| 44 | #include <pcmcia/cs_types.h> | ||
| 45 | #include <pcmcia/cs.h> | ||
| 46 | #include <pcmcia/cistpl.h> | ||
| 47 | #include <pcmcia/ds.h> | ||
| 48 | #include <pcmcia/ss.h> | ||
| 49 | |||
| 50 | #define MODNAME "hd64465_ss" | ||
| 51 | |||
| 52 | /* #define HD64465_DEBUG 1 */ | ||
| 53 | |||
| 54 | #if HD64465_DEBUG | ||
| 55 | #define DPRINTK(args...) printk(MODNAME ": " args) | ||
| 56 | #else | ||
| 57 | #define DPRINTK(args...) | ||
| 58 | #endif | ||
| 59 | |||
| 60 | extern int hd64465_io_debug; | ||
| 61 | extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); | ||
| 62 | extern void p3_iounmap(void *addr); | ||
| 63 | |||
| 64 | /*============================================================*/ | ||
| 65 | |||
| 66 | #define HS_IO_MAP_SIZE (64*1024) | ||
| 67 | |||
| 68 | typedef struct hs_socket_t | ||
| 69 | { | ||
| 70 | unsigned int number; | ||
| 71 | u_int irq; | ||
| 72 | u_long mem_base; | ||
| 73 | void *io_base; | ||
| 74 | u_long mem_length; | ||
| 75 | u_int ctrl_base; | ||
| 76 | socket_state_t state; | ||
| 77 | pccard_io_map io_maps[MAX_IO_WIN]; | ||
| 78 | pccard_mem_map mem_maps[MAX_WIN]; | ||
| 79 | struct pcmcia_socket socket; | ||
| 80 | } hs_socket_t; | ||
| 81 | |||
| 82 | |||
| 83 | |||
| 84 | #define HS_MAX_SOCKETS 2 | ||
| 85 | static hs_socket_t hs_sockets[HS_MAX_SOCKETS]; | ||
| 86 | |||
| 87 | #define hs_in(sp, r) inb((sp)->ctrl_base + (r)) | ||
| 88 | #define hs_out(sp, v, r) outb(v, (sp)->ctrl_base + (r)) | ||
| 89 | |||
| 90 | |||
| 91 | /* translate a boolean value to a bit in a register */ | ||
| 92 | #define bool_to_regbit(sp, r, bi, bo) \ | ||
| 93 | do { \ | ||
| 94 | unsigned short v = hs_in(sp, r); \ | ||
| 95 | if (bo) \ | ||
| 96 | v |= (bi); \ | ||
| 97 | else \ | ||
| 98 | v &= ~(bi); \ | ||
| 99 | hs_out(sp, v, r); \ | ||
| 100 | } while(0) | ||
| 101 | |||
| 102 | /* register offsets from HD64465_REG_PCC[01]ISR */ | ||
| 103 | #define ISR 0x0 | ||
| 104 | #define GCR 0x2 | ||
| 105 | #define CSCR 0x4 | ||
| 106 | #define CSCIER 0x6 | ||
| 107 | #define SCR 0x8 | ||
| 108 | |||
| 109 | |||
| 110 | /* Mask and values for CSCIER register */ | ||
| 111 | #define IER_MASK 0x80 | ||
| 112 | #define IER_ON 0x3f /* interrupts on */ | ||
| 113 | #define IER_OFF 0x00 /* interrupts off */ | ||
| 114 | |||
| 115 | /*============================================================*/ | ||
| 116 | |||
| 117 | #if HD64465_DEBUG > 10 | ||
| 118 | |||
| 119 | static void cis_hex_dump(const unsigned char *x, int len) | ||
| 120 | { | ||
| 121 | int i; | ||
| 122 | |||
| 123 | for (i=0 ; i<len ; i++) | ||
| 124 | { | ||
| 125 | if (!(i & 0xf)) | ||
| 126 | printk("\n%08x", (unsigned)(x + i)); | ||
| 127 | printk(" %02x", *(volatile unsigned short*)x); | ||
| 128 | x += 2; | ||
| 129 | } | ||
| 130 | printk("\n"); | ||
| 131 | } | ||
| 132 | |||
| 133 | #endif | ||
| 134 | /*============================================================*/ | ||
| 135 | |||
| 136 | /* | ||
| 137 | * This code helps create the illusion that the IREQ line from | ||
| 138 | * the PC card is mapped to one of the CPU's IRQ lines by the | ||
| 139 | * host bridge hardware (which is how every host bridge *except* | ||
| 140 | * the HD64465 works). In particular, it supports enabling | ||
| 141 | * and disabling the IREQ line by code which knows nothing | ||
| 142 | * about the host bridge (e.g. device drivers, IDE code) using | ||
| 143 | * the request_irq(), free_irq(), probe_irq_on() and probe_irq_off() | ||
| 144 | * functions. Also, it supports sharing the mapped IRQ with | ||
| 145 | * real hardware IRQs from the -IRL0-3 lines. | ||
| 146 | */ | ||
| 147 | |||
| 148 | #define HS_NUM_MAPPED_IRQS 16 /* Limitation of the PCMCIA code */ | ||
| 149 | static struct | ||
| 150 | { | ||
| 151 | /* index is mapped irq number */ | ||
| 152 | hs_socket_t *sock; | ||
| 153 | hw_irq_controller *old_handler; | ||
| 154 | } hs_mapped_irq[HS_NUM_MAPPED_IRQS]; | ||
| 155 | |||
| 156 | static void hs_socket_enable_ireq(hs_socket_t *sp) | ||
| 157 | { | ||
| 158 | unsigned short cscier; | ||
| 159 | |||
| 160 | DPRINTK("hs_socket_enable_ireq(sock=%d)\n", sp->number); | ||
| 161 | |||
| 162 | cscier = hs_in(sp, CSCIER); | ||
| 163 | cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK; | ||
| 164 | cscier |= HD64465_PCCCSCIER_PIREQE_LEVEL; | ||
| 165 | hs_out(sp, cscier, CSCIER); | ||
| 166 | } | ||
| 167 | |||
| 168 | static void hs_socket_disable_ireq(hs_socket_t *sp) | ||
| 169 | { | ||
| 170 | unsigned short cscier; | ||
| 171 | |||
| 172 | DPRINTK("hs_socket_disable_ireq(sock=%d)\n", sp->number); | ||
| 173 | |||
| 174 | cscier = hs_in(sp, CSCIER); | ||
| 175 | cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK; | ||
| 176 | hs_out(sp, cscier, CSCIER); | ||
| 177 | } | ||
| 178 | |||
| 179 | static unsigned int hs_startup_irq(unsigned int irq) | ||
| 180 | { | ||
| 181 | hs_socket_enable_ireq(hs_mapped_irq[irq].sock); | ||
| 182 | hs_mapped_irq[irq].old_handler->startup(irq); | ||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void hs_shutdown_irq(unsigned int irq) | ||
| 187 | { | ||
| 188 | hs_socket_disable_ireq(hs_mapped_irq[irq].sock); | ||
| 189 | hs_mapped_irq[irq].old_handler->shutdown(irq); | ||
| 190 | } | ||
| 191 | |||
| 192 | static void hs_enable_irq(unsigned int irq) | ||
| 193 | { | ||
| 194 | hs_socket_enable_ireq(hs_mapped_irq[irq].sock); | ||
| 195 | hs_mapped_irq[irq].old_handler->enable(irq); | ||
| 196 | } | ||
| 197 | |||
| 198 | static void hs_disable_irq(unsigned int irq) | ||
| 199 | { | ||
| 200 | hs_socket_disable_ireq(hs_mapped_irq[irq].sock); | ||
| 201 | hs_mapped_irq[irq].old_handler->disable(irq); | ||
| 202 | } | ||
| 203 | |||
| 204 | extern struct hw_interrupt_type no_irq_type; | ||
| 205 | |||
| 206 | static void hs_mask_and_ack_irq(unsigned int irq) | ||
| 207 | { | ||
| 208 | hs_socket_disable_ireq(hs_mapped_irq[irq].sock); | ||
| 209 | /* ack_none() spuriously complains about an unexpected IRQ */ | ||
| 210 | if (hs_mapped_irq[irq].old_handler != &no_irq_type) | ||
| 211 | hs_mapped_irq[irq].old_handler->ack(irq); | ||
| 212 | } | ||
| 213 | |||
| 214 | static void hs_end_irq(unsigned int irq) | ||
| 215 | { | ||
| 216 | hs_socket_enable_ireq(hs_mapped_irq[irq].sock); | ||
| 217 | hs_mapped_irq[irq].old_handler->end(irq); | ||
| 218 | } | ||
| 219 | |||
| 220 | |||
| 221 | static struct hw_interrupt_type hd64465_ss_irq_type = { | ||
| 222 | .typename = "PCMCIA-IRQ", | ||
| 223 | .startup = hs_startup_irq, | ||
| 224 | .shutdown = hs_shutdown_irq, | ||
| 225 | .enable = hs_enable_irq, | ||
| 226 | .disable = hs_disable_irq, | ||
| 227 | .ack = hs_mask_and_ack_irq, | ||
| 228 | .end = hs_end_irq | ||
| 229 | }; | ||
| 230 | |||
| 231 | /* | ||
| 232 | * This function should only ever be called with interrupts disabled. | ||
| 233 | */ | ||
| 234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | ||
| 235 | { | ||
| 236 | struct irq_desc *desc; | ||
| 237 | |||
| 238 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); | ||
| 239 | |||
| 240 | if (irq >= HS_NUM_MAPPED_IRQS) | ||
| 241 | return; | ||
| 242 | |||
| 243 | desc = irq_to_desc(irq); | ||
| 244 | hs_mapped_irq[irq].sock = sp; | ||
| 245 | /* insert ourselves as the irq controller */ | ||
| 246 | hs_mapped_irq[irq].old_handler = desc->chip; | ||
| 247 | desc->chip = &hd64465_ss_irq_type; | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 251 | /* | ||
| 252 | * This function should only ever be called with interrupts disabled. | ||
| 253 | */ | ||
| 254 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) | ||
| 255 | { | ||
| 256 | struct irq_desc *desc; | ||
| 257 | |||
| 258 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); | ||
| 259 | |||
| 260 | if (irq >= HS_NUM_MAPPED_IRQS) | ||
| 261 | return; | ||
| 262 | |||
| 263 | desc = irq_to_desc(irq); | ||
| 264 | /* restore the original irq controller */ | ||
| 265 | desc->chip = hs_mapped_irq[irq].old_handler; | ||
| 266 | } | ||
| 267 | |||
| 268 | /*============================================================*/ | ||
| 269 | |||
| 270 | |||
| 271 | /* | ||
| 272 | * Set Vpp and Vcc (in tenths of a Volt). Does not | ||
| 273 | * support the hi-Z state. | ||
| 274 | * | ||
| 275 | * Note, this assumes the board uses a TPS2206 chip to control | ||
| 276 | * the Vcc and Vpp voltages to the hs_sockets. If your board | ||
| 277 | * uses the MIC2563 (also supported by the HD64465) then you | ||
| 278 | * will have to modify this function. | ||
| 279 | */ | ||
| 280 | /* 0V 3.3V 5.5V */ | ||
| 281 | static const u_char hs_tps2206_avcc[3] = { 0x00, 0x04, 0x08 }; | ||
| 282 | static const u_char hs_tps2206_bvcc[3] = { 0x00, 0x80, 0x40 }; | ||
| 283 | |||
| 284 | static int hs_set_voltages(hs_socket_t *sp, int Vcc, int Vpp) | ||
| 285 | { | ||
| 286 | u_int psr; | ||
| 287 | u_int vcci = 0; | ||
| 288 | u_int sock = sp->number; | ||
| 289 | |||
| 290 | DPRINTK("hs_set_voltage(%d, %d, %d)\n", sock, Vcc, Vpp); | ||
| 291 | |||
| 292 | switch (Vcc) | ||
| 293 | { | ||
| 294 | case 0: vcci = 0; break; | ||
| 295 | case 33: vcci = 1; break; | ||
| 296 | case 50: vcci = 2; break; | ||
| 297 | default: return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | /* Note: Vpp = 120 not supported -- Greg Banks */ | ||
| 301 | if (Vpp != 0 && Vpp != Vcc) | ||
| 302 | return 0; | ||
| 303 | |||
| 304 | /* The PSR register holds 8 of the 9 bits which control | ||
| 305 | * the TPS2206 via its serial interface. | ||
| 306 | */ | ||
| 307 | psr = inw(HD64465_REG_PCCPSR); | ||
| 308 | switch (sock) | ||
| 309 | { | ||
| 310 | case 0: | ||
| 311 | psr &= 0x0f; | ||
| 312 | psr |= hs_tps2206_avcc[vcci]; | ||
| 313 | psr |= (Vpp == 0 ? 0x00 : 0x02); | ||
| 314 | break; | ||
| 315 | case 1: | ||
| 316 | psr &= 0xf0; | ||
| 317 | psr |= hs_tps2206_bvcc[vcci]; | ||
| 318 | psr |= (Vpp == 0 ? 0x00 : 0x20); | ||
| 319 | break; | ||
| 320 | }; | ||
| 321 | outw(psr, HD64465_REG_PCCPSR); | ||
| 322 | |||
| 323 | return 1; | ||
| 324 | } | ||
| 325 | |||
| 326 | |||
| 327 | /*============================================================*/ | ||
| 328 | |||
| 329 | /* | ||
| 330 | * Drive the RESET line to the card. | ||
| 331 | */ | ||
| 332 | static void hs_reset_socket(hs_socket_t *sp, int on) | ||
| 333 | { | ||
| 334 | unsigned short v; | ||
| 335 | |||
| 336 | v = hs_in(sp, GCR); | ||
| 337 | if (on) | ||
| 338 | v |= HD64465_PCCGCR_PCCR; | ||
| 339 | else | ||
| 340 | v &= ~HD64465_PCCGCR_PCCR; | ||
| 341 | hs_out(sp, v, GCR); | ||
| 342 | } | ||
| 343 | |||
| 344 | /*============================================================*/ | ||
| 345 | |||
| 346 | static int hs_init(struct pcmcia_socket *s) | ||
| 347 | { | ||
| 348 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | ||
| 349 | |||
| 350 | DPRINTK("hs_init(%d)\n", sp->number); | ||
| 351 | |||
| 352 | return 0; | ||
| 353 | } | ||
| 354 | |||
| 355 | /*============================================================*/ | ||
| 356 | |||
| 357 | |||
| 358 | static int hs_get_status(struct pcmcia_socket *s, u_int *value) | ||
| 359 | { | ||
| 360 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | ||
| 361 | unsigned int isr; | ||
| 362 | u_int status = 0; | ||
| 363 | |||
| 364 | |||
| 365 | isr = hs_in(sp, ISR); | ||
| 366 | |||
| 367 | /* Card is seated and powered when *both* CD pins are low */ | ||
| 368 | if ((isr & HD64465_PCCISR_PCD_MASK) == 0) | ||
| 369 | { | ||
| 370 | status |= SS_DETECT; /* card present */ | ||
| 371 | |||
| 372 | switch (isr & HD64465_PCCISR_PBVD_MASK) | ||
| 373 | { | ||
| 374 | case HD64465_PCCISR_PBVD_BATGOOD: | ||
| 375 | break; | ||
| 376 | case HD64465_PCCISR_PBVD_BATWARN: | ||
| 377 | status |= SS_BATWARN; | ||
| 378 | break; | ||
| 379 | default: | ||
| 380 | status |= SS_BATDEAD; | ||
| 381 | break; | ||
| 382 | } | ||
| 383 | |||
| 384 | if (isr & HD64465_PCCISR_PREADY) | ||
| 385 | status |= SS_READY; | ||
| 386 | |||
| 387 | if (isr & HD64465_PCCISR_PMWP) | ||
| 388 | status |= SS_WRPROT; | ||
| 389 | |||
| 390 | /* Voltage Select pins interpreted as per Table 4-5 of the std. | ||
| 391 | * Assuming we have the TPS2206, the socket is a "Low Voltage | ||
| 392 | * key, 3.3V and 5V available, no X.XV available". | ||
| 393 | */ | ||
| 394 | switch (isr & (HD64465_PCCISR_PVS2|HD64465_PCCISR_PVS1)) | ||
| 395 | { | ||
| 396 | case HD64465_PCCISR_PVS1: | ||
| 397 | printk(KERN_NOTICE MODNAME ": cannot handle X.XV card, ignored\n"); | ||
| 398 | status = 0; | ||
| 399 | break; | ||
| 400 | case 0: | ||
| 401 | case HD64465_PCCISR_PVS2: | ||
| 402 | /* 3.3V */ | ||
| 403 | status |= SS_3VCARD; | ||
| 404 | break; | ||
| 405 | case HD64465_PCCISR_PVS2|HD64465_PCCISR_PVS1: | ||
| 406 | /* 5V */ | ||
| 407 | break; | ||
| 408 | } | ||
| 409 | |||
| 410 | /* TODO: SS_POWERON */ | ||
| 411 | /* TODO: SS_STSCHG */ | ||
| 412 | } | ||
| 413 | |||
| 414 | DPRINTK("hs_get_status(%d) = %x\n", sock, status); | ||
| 415 | |||
| 416 | *value = status; | ||
| 417 | return 0; | ||
| 418 | } | ||
| 419 | |||
| 420 | /*============================================================*/ | ||
| 421 | |||
| 422 | static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state) | ||
| 423 | { | ||
| 424 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | ||
| 425 | u_long flags; | ||
| 426 | u_int changed; | ||
| 427 | unsigned short cscier; | ||
| 428 | |||
| 429 | DPRINTK("hs_set_socket(sock=%d, flags=%x, csc_mask=%x, Vcc=%d, Vpp=%d, io_irq=%d)\n", | ||
| 430 | sock, state->flags, state->csc_mask, state->Vcc, state->Vpp, state->io_irq); | ||
| 431 | |||
| 432 | local_irq_save(flags); /* Don't want interrupts happening here */ | ||
| 433 | |||
| 434 | if (state->Vpp != sp->state.Vpp || | ||
| 435 | state->Vcc != sp->state.Vcc) { | ||
| 436 | if (!hs_set_voltages(sp, state->Vcc, state->Vpp)) { | ||
| 437 | local_irq_restore(flags); | ||
| 438 | return -EINVAL; | ||
| 439 | } | ||
| 440 | } | ||
| 441 | |||
| 442 | /* hd64465_io_debug = 1; */ | ||
| 443 | /* | ||
| 444 | * Handle changes in the Card Status Change mask, | ||
| 445 | * by propagating to the CSCR register | ||
| 446 | */ | ||
| 447 | changed = sp->state.csc_mask ^ state->csc_mask; | ||
| 448 | cscier = hs_in(sp, CSCIER); | ||
| 449 | |||
| 450 | if (changed & SS_DETECT) { | ||
| 451 | if (state->csc_mask & SS_DETECT) | ||
| 452 | cscier |= HD64465_PCCCSCIER_PCDE; | ||
| 453 | else | ||
| 454 | cscier &= ~HD64465_PCCCSCIER_PCDE; | ||
| 455 | } | ||
| 456 | |||
| 457 | if (changed & SS_READY) { | ||
| 458 | if (state->csc_mask & SS_READY) | ||
| 459 | cscier |= HD64465_PCCCSCIER_PRE; | ||
| 460 | else | ||
| 461 | cscier &= ~HD64465_PCCCSCIER_PRE; | ||
| 462 | } | ||
| 463 | |||
| 464 | if (changed & SS_BATDEAD) { | ||
| 465 | if (state->csc_mask & SS_BATDEAD) | ||
| 466 | cscier |= HD64465_PCCCSCIER_PBDE; | ||
| 467 | else | ||
| 468 | cscier &= ~HD64465_PCCCSCIER_PBDE; | ||
| 469 | } | ||
| 470 | |||
| 471 | if (changed & SS_BATWARN) { | ||
| 472 | if (state->csc_mask & SS_BATWARN) | ||
| 473 | cscier |= HD64465_PCCCSCIER_PBWE; | ||
| 474 | else | ||
| 475 | cscier &= ~HD64465_PCCCSCIER_PBWE; | ||
| 476 | } | ||
| 477 | |||
| 478 | if (changed & SS_STSCHG) { | ||
| 479 | if (state->csc_mask & SS_STSCHG) | ||
| 480 | cscier |= HD64465_PCCCSCIER_PSCE; | ||
| 481 | else | ||
| 482 | cscier &= ~HD64465_PCCCSCIER_PSCE; | ||
| 483 | } | ||
| 484 | |||
| 485 | hs_out(sp, cscier, CSCIER); | ||
| 486 | |||
| 487 | if (sp->state.io_irq && !state->io_irq) | ||
| 488 | hs_unmap_irq(sp, sp->state.io_irq); | ||
| 489 | else if (!sp->state.io_irq && state->io_irq) | ||
| 490 | hs_map_irq(sp, state->io_irq); | ||
| 491 | |||
| 492 | |||
| 493 | /* | ||
| 494 | * Handle changes in the flags field, | ||
| 495 | * by propagating to config registers. | ||
| 496 | */ | ||
| 497 | changed = sp->state.flags ^ state->flags; | ||
| 498 | |||
| 499 | if (changed & SS_IOCARD) { | ||
| 500 | DPRINTK("card type: %s\n", | ||
| 501 | (state->flags & SS_IOCARD ? "i/o" : "memory" )); | ||
| 502 | bool_to_regbit(sp, GCR, HD64465_PCCGCR_PCCT, | ||
| 503 | state->flags & SS_IOCARD); | ||
| 504 | } | ||
| 505 | |||
| 506 | if (changed & SS_RESET) { | ||
| 507 | DPRINTK("%s reset card\n", | ||
| 508 | (state->flags & SS_RESET ? "start" : "stop")); | ||
| 509 | bool_to_regbit(sp, GCR, HD64465_PCCGCR_PCCR, | ||
| 510 | state->flags & SS_RESET); | ||
| 511 | } | ||
| 512 | |||
| 513 | if (changed & SS_OUTPUT_ENA) { | ||
| 514 | DPRINTK("%sabling card output\n", | ||
| 515 | (state->flags & SS_OUTPUT_ENA ? "en" : "dis")); | ||
| 516 | bool_to_regbit(sp, GCR, HD64465_PCCGCR_PDRV, | ||
| 517 | state->flags & SS_OUTPUT_ENA); | ||
| 518 | } | ||
| 519 | |||
| 520 | /* TODO: SS_SPKR_ENA */ | ||
| 521 | |||
| 522 | /* hd64465_io_debug = 0; */ | ||
| 523 | sp->state = *state; | ||
| 524 | |||
| 525 | local_irq_restore(flags); | ||
| 526 | |||
| 527 | #if HD64465_DEBUG > 10 | ||
| 528 | if (state->flags & SS_OUTPUT_ENA) | ||
| 529 | cis_hex_dump((const unsigned char*)sp->mem_base, 0x100); | ||
| 530 | #endif | ||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | |||
| 534 | /*============================================================*/ | ||
| 535 | |||
| 536 | static int hs_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | ||
| 537 | { | ||
| 538 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | ||
| 539 | int map = io->map; | ||
| 540 | int sock = sp->number; | ||
| 541 | struct pccard_io_map *sio; | ||
| 542 | pgprot_t prot; | ||
| 543 | |||
| 544 | DPRINTK("hs_set_io_map(sock=%d, map=%d, flags=0x%x, speed=%dns, start=%#lx, stop=%#lx)\n", | ||
| 545 | sock, map, io->flags, io->speed, io->start, io->stop); | ||
| 546 | if (map >= MAX_IO_WIN) | ||
| 547 | return -EINVAL; | ||
| 548 | sio = &sp->io_maps[map]; | ||
| 549 | |||
| 550 | /* check for null changes */ | ||
| 551 | if (io->flags == sio->flags && | ||
| 552 | io->start == sio->start && | ||
| 553 | io->stop == sio->stop) | ||
| 554 | return 0; | ||
| 555 | |||
| 556 | if (io->flags & MAP_AUTOSZ) | ||
| 557 | prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IODYN); | ||
| 558 | else if (io->flags & MAP_16BIT) | ||
| 559 | prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IO16); | ||
| 560 | else | ||
| 561 | prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IO8); | ||
| 562 | |||
| 563 | /* TODO: handle MAP_USE_WAIT */ | ||
| 564 | if (io->flags & MAP_USE_WAIT) | ||
| 565 | printk(KERN_INFO MODNAME ": MAP_USE_WAIT unimplemented\n"); | ||
| 566 | /* TODO: handle MAP_PREFETCH */ | ||
| 567 | if (io->flags & MAP_PREFETCH) | ||
| 568 | printk(KERN_INFO MODNAME ": MAP_PREFETCH unimplemented\n"); | ||
| 569 | /* TODO: handle MAP_WRPROT */ | ||
| 570 | if (io->flags & MAP_WRPROT) | ||
| 571 | printk(KERN_INFO MODNAME ": MAP_WRPROT unimplemented\n"); | ||
| 572 | /* TODO: handle MAP_0WS */ | ||
| 573 | if (io->flags & MAP_0WS) | ||
| 574 | printk(KERN_INFO MODNAME ": MAP_0WS unimplemented\n"); | ||
| 575 | |||
| 576 | if (io->flags & MAP_ACTIVE) { | ||
| 577 | unsigned long pstart, psize, paddrbase; | ||
| 578 | |||
| 579 | paddrbase = virt_to_phys((void*)(sp->mem_base + 2 * HD64465_PCC_WINDOW)); | ||
| 580 | pstart = io->start & PAGE_MASK; | ||
| 581 | psize = ((io->stop + PAGE_SIZE) & PAGE_MASK) - pstart; | ||
| 582 | |||
| 583 | /* | ||
| 584 | * Change PTEs in only that portion of the mapping requested | ||
| 585 | * by the caller. This means that most of the time, most of | ||
| 586 | * the PTEs in the io_vma will be unmapped and only the bottom | ||
| 587 | * page will be mapped. But the code allows for weird cards | ||
| 588 | * that might want IO ports > 4K. | ||
| 589 | */ | ||
| 590 | sp->io_base = p3_ioremap(paddrbase + pstart, psize, pgprot_val(prot)); | ||
| 591 | |||
| 592 | /* | ||
| 593 | * Change the mapping used by inb() outb() etc | ||
| 594 | */ | ||
| 595 | hd64465_port_map(io->start, | ||
| 596 | io->stop - io->start + 1, | ||
| 597 | (unsigned long)sp->io_base + io->start, 0); | ||
| 598 | } else { | ||
| 599 | hd64465_port_unmap(sio->start, sio->stop - sio->start + 1); | ||
| 600 | p3_iounmap(sp->io_base); | ||
| 601 | } | ||
| 602 | |||
| 603 | *sio = *io; | ||
| 604 | return 0; | ||
| 605 | } | ||
| 606 | |||
| 607 | /*============================================================*/ | ||
| 608 | |||
| 609 | static int hs_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) | ||
| 610 | { | ||
| 611 | hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); | ||
| 612 | struct pccard_mem_map *smem; | ||
| 613 | int map = mem->map; | ||
| 614 | unsigned long paddr; | ||
| 615 | |||
| 616 | #if 0 | ||
| 617 | DPRINTK("hs_set_mem_map(sock=%d, map=%d, flags=0x%x, card_start=0x%08x)\n", | ||
| 618 | sock, map, mem->flags, mem->card_start); | ||
| 619 | #endif | ||
| 620 | |||
| 621 | if (map >= MAX_WIN) | ||
| 622 | return -EINVAL; | ||
| 623 | smem = &sp->mem_maps[map]; | ||
| 624 | |||
| 625 | paddr = sp->mem_base; /* base of Attribute mapping */ | ||
| 626 | if (!(mem->flags & MAP_ATTRIB)) | ||
| 627 | paddr += HD64465_PCC_WINDOW; /* base of Common mapping */ | ||
| 628 | paddr += mem->card_start; | ||
| 629 | |||
| 630 | /* Because we specified SS_CAP_STATIC_MAP, we are obliged | ||
| 631 | * at this time to report the system address corresponding | ||
| 632 | * to the card address requested. This is how Socket Services | ||
| 633 | * queries our fixed mapping. I wish this fact had been | ||
| 634 | * documented - Greg Banks. | ||
| 635 | */ | ||
| 636 | mem->static_start = paddr; | ||
| 637 | |||
| 638 | *smem = *mem; | ||
| 639 | |||
| 640 | return 0; | ||
| 641 | } | ||
| 642 | |||
| 643 | /* TODO: do we need to use the MMU to access Common memory ??? */ | ||
| 644 | |||
| 645 | /*============================================================*/ | ||
| 646 | |||
| 647 | /* | ||
| 648 | * This function is registered with the HD64465 glue code to do a | ||
| 649 | * secondary demux step on the PCMCIA interrupts. It handles | ||
| 650 | * mapping the IREQ request from the card to a standard Linux | ||
| 651 | * IRQ, as requested by SocketServices. | ||
| 652 | */ | ||
| 653 | static int hs_irq_demux(int irq, void *dev) | ||
| 654 | { | ||
| 655 | hs_socket_t *sp = dev; | ||
| 656 | u_int cscr; | ||
| 657 | |||
| 658 | DPRINTK("hs_irq_demux(irq=%d)\n", irq); | ||
| 659 | |||
| 660 | if (sp->state.io_irq && | ||
| 661 | (cscr = hs_in(sp, CSCR)) & HD64465_PCCCSCR_PIREQ) { | ||
| 662 | cscr &= ~HD64465_PCCCSCR_PIREQ; | ||
| 663 | hs_out(sp, cscr, CSCR); | ||
| 664 | return sp->state.io_irq; | ||
| 665 | } | ||
| 666 | |||
| 667 | return irq; | ||
| 668 | } | ||
| 669 | |||
| 670 | /*============================================================*/ | ||
| 671 | |||
| 672 | /* | ||
| 673 | * Interrupt handling routine. | ||
| 674 | */ | ||
| 675 | |||
| 676 | static irqreturn_t hs_interrupt(int irq, void *dev) | ||
| 677 | { | ||
| 678 | hs_socket_t *sp = dev; | ||
| 679 | u_int events = 0; | ||
| 680 | u_int cscr; | ||
| 681 | |||
| 682 | cscr = hs_in(sp, CSCR); | ||
| 683 | |||
| 684 | DPRINTK("hs_interrupt, cscr=%04x\n", cscr); | ||
| 685 | |||
| 686 | /* check for bus-related changes to be reported to Socket Services */ | ||
| 687 | if (cscr & HD64465_PCCCSCR_PCDC) { | ||
| 688 | /* double-check for a 16-bit card, as we don't support CardBus */ | ||
| 689 | if ((hs_in(sp, ISR) & HD64465_PCCISR_PCD_MASK) != 0) { | ||
| 690 | printk(KERN_NOTICE MODNAME | ||
| 691 | ": socket %d, card not a supported card type or not inserted correctly\n", | ||
| 692 | sp->number); | ||
| 693 | /* Don't do the rest unless a card is present */ | ||
| 694 | cscr &= ~(HD64465_PCCCSCR_PCDC| | ||
| 695 | HD64465_PCCCSCR_PRC| | ||
| 696 | HD64465_PCCCSCR_PBW| | ||
| 697 | HD64465_PCCCSCR_PBD| | ||
| 698 | HD64465_PCCCSCR_PSC); | ||
| 699 | } else { | ||
| 700 | cscr &= ~HD64465_PCCCSCR_PCDC; | ||
| 701 | events |= SS_DETECT; /* card insertion or removal */ | ||
| 702 | } | ||
| 703 | } | ||
| 704 | if (cscr & HD64465_PCCCSCR_PRC) { | ||
| 705 | cscr &= ~HD64465_PCCCSCR_PRC; | ||
| 706 | events |= SS_READY; /* ready signal changed */ | ||
| 707 | } | ||
| 708 | if (cscr & HD64465_PCCCSCR_PBW) { | ||
| 709 | cscr &= ~HD64465_PCCCSCR_PSC; | ||
| 710 | events |= SS_BATWARN; /* battery warning */ | ||
| 711 | } | ||
| 712 | if (cscr & HD64465_PCCCSCR_PBD) { | ||
| 713 | cscr &= ~HD64465_PCCCSCR_PSC; | ||
| 714 | events |= SS_BATDEAD; /* battery dead */ | ||
| 715 | } | ||
| 716 | if (cscr & HD64465_PCCCSCR_PSC) { | ||
| 717 | cscr &= ~HD64465_PCCCSCR_PSC; | ||
| 718 | events |= SS_STSCHG; /* STSCHG (status changed) signal */ | ||
| 719 | } | ||
| 720 | |||
| 721 | if (cscr & HD64465_PCCCSCR_PIREQ) { | ||
| 722 | cscr &= ~HD64465_PCCCSCR_PIREQ; | ||
| 723 | |||
| 724 | /* This should have been dealt with during irq demux */ | ||
| 725 | printk(KERN_NOTICE MODNAME ": unexpected IREQ from card\n"); | ||
| 726 | } | ||
| 727 | |||
| 728 | hs_out(sp, cscr, CSCR); | ||
| 729 | |||
| 730 | if (events) | ||
| 731 | pcmcia_parse_events(&sp->socket, events); | ||
| 732 | |||
| 733 | return IRQ_HANDLED; | ||
| 734 | } | ||
| 735 | |||
| 736 | /*============================================================*/ | ||
| 737 | |||
| 738 | static struct pccard_operations hs_operations = { | ||
| 739 | .init = hs_init, | ||
| 740 | .get_status = hs_get_status, | ||
| 741 | .set_socket = hs_set_socket, | ||
| 742 | .set_io_map = hs_set_io_map, | ||
| 743 | .set_mem_map = hs_set_mem_map, | ||
| 744 | }; | ||
| 745 | |||
| 746 | static int hs_init_socket(hs_socket_t *sp, int irq, unsigned long mem_base, | ||
| 747 | unsigned int ctrl_base) | ||
| 748 | { | ||
| 749 | unsigned short v; | ||
| 750 | int i, err; | ||
| 751 | |||
| 752 | memset(sp, 0, sizeof(*sp)); | ||
| 753 | sp->irq = irq; | ||
| 754 | sp->mem_base = mem_base; | ||
| 755 | sp->mem_length = 4*HD64465_PCC_WINDOW; /* 16MB */ | ||
| 756 | sp->ctrl_base = ctrl_base; | ||
| 757 | |||
| 758 | for (i=0 ; i<MAX_IO_WIN ; i++) | ||
| 759 | sp->io_maps[i].map = i; | ||
| 760 | for (i=0 ; i<MAX_WIN ; i++) | ||
| 761 | sp->mem_maps[i].map = i; | ||
| 762 | |||
| 763 | hd64465_register_irq_demux(sp->irq, hs_irq_demux, sp); | ||
| 764 | |||
| 765 | if ((err = request_irq(sp->irq, hs_interrupt, IRQF_DISABLED, MODNAME, sp)) < 0) | ||
| 766 | return err; | ||
| 767 | if (request_mem_region(sp->mem_base, sp->mem_length, MODNAME) == 0) { | ||
| 768 | sp->mem_base = 0; | ||
| 769 | return -ENOMEM; | ||
| 770 | } | ||
| 771 | |||
| 772 | |||
| 773 | /* According to section 3.2 of the PCMCIA standard, low-voltage | ||
| 774 | * capable cards must implement cold insertion, i.e. Vpp and | ||
| 775 | * Vcc set to 0 before card is inserted. | ||
| 776 | */ | ||
| 777 | /*hs_set_voltages(sp, 0, 0);*/ | ||
| 778 | |||
| 779 | /* hi-Z the outputs to the card and set 16MB map mode */ | ||
| 780 | v = hs_in(sp, GCR); | ||
| 781 | v &= ~HD64465_PCCGCR_PCCT; /* memory-only card */ | ||
| 782 | hs_out(sp, v, GCR); | ||
| 783 | |||
| 784 | v = hs_in(sp, GCR); | ||
| 785 | v |= HD64465_PCCGCR_PDRV; /* enable outputs to card */ | ||
| 786 | hs_out(sp, v, GCR); | ||
| 787 | |||
| 788 | v = hs_in(sp, GCR); | ||
| 789 | v |= HD64465_PCCGCR_PMMOD; /* 16MB mapping mode */ | ||
| 790 | hs_out(sp, v, GCR); | ||
| 791 | |||
| 792 | v = hs_in(sp, GCR); | ||
| 793 | /* lowest 16MB of Common */ | ||
| 794 | v &= ~(HD64465_PCCGCR_PPA25|HD64465_PCCGCR_PPA24); | ||
| 795 | hs_out(sp, v, GCR); | ||
| 796 | |||
| 797 | hs_reset_socket(sp, 1); | ||
| 798 | |||
| 799 | printk(KERN_INFO "HD64465 PCMCIA bridge socket %d at 0x%08lx irq %d\n", | ||
| 800 | i, sp->mem_base, sp->irq); | ||
| 801 | |||
| 802 | return 0; | ||
| 803 | } | ||
| 804 | |||
| 805 | static void hs_exit_socket(hs_socket_t *sp) | ||
| 806 | { | ||
| 807 | unsigned short cscier, gcr; | ||
| 808 | unsigned long flags; | ||
| 809 | |||
| 810 | local_irq_save(flags); | ||
| 811 | |||
| 812 | /* turn off interrupts in hardware */ | ||
| 813 | cscier = hs_in(sp, CSCIER); | ||
| 814 | cscier = (cscier & IER_MASK) | IER_OFF; | ||
| 815 | hs_out(sp, cscier, CSCIER); | ||
| 816 | |||
| 817 | /* hi-Z the outputs to the card */ | ||
| 818 | gcr = hs_in(sp, GCR); | ||
| 819 | gcr &= HD64465_PCCGCR_PDRV; | ||
| 820 | hs_out(sp, gcr, GCR); | ||
| 821 | |||
| 822 | /* power the card down */ | ||
| 823 | hs_set_voltages(sp, 0, 0); | ||
| 824 | |||
| 825 | if (sp->mem_base != 0) | ||
| 826 | release_mem_region(sp->mem_base, sp->mem_length); | ||
| 827 | if (sp->irq != 0) { | ||
| 828 | free_irq(sp->irq, hs_interrupt); | ||
| 829 | hd64465_unregister_irq_demux(sp->irq); | ||
| 830 | } | ||
| 831 | |||
| 832 | local_irq_restore(flags); | ||
| 833 | } | ||
| 834 | |||
| 835 | static struct device_driver hd64465_driver = { | ||
| 836 | .name = "hd64465-pcmcia", | ||
| 837 | .bus = &platform_bus_type, | ||
| 838 | .suspend = pcmcia_socket_dev_suspend, | ||
| 839 | .resume = pcmcia_socket_dev_resume, | ||
| 840 | }; | ||
| 841 | |||
| 842 | static struct platform_device hd64465_device = { | ||
| 843 | .name = "hd64465-pcmcia", | ||
| 844 | .id = 0, | ||
| 845 | }; | ||
| 846 | |||
| 847 | static int __init init_hs(void) | ||
| 848 | { | ||
| 849 | int i; | ||
| 850 | unsigned short v; | ||
| 851 | |||
| 852 | /* hd64465_io_debug = 1; */ | ||
| 853 | if (driver_register(&hd64465_driver)) | ||
| 854 | return -EINVAL; | ||
| 855 | |||
| 856 | /* Wake both sockets out of STANDBY mode */ | ||
| 857 | /* TODO: wait 15ms */ | ||
| 858 | v = inw(HD64465_REG_SMSCR); | ||
| 859 | v &= ~(HD64465_SMSCR_PC0ST|HD64465_SMSCR_PC1ST); | ||
| 860 | outw(v, HD64465_REG_SMSCR); | ||
| 861 | |||
| 862 | /* keep power controller out of shutdown mode */ | ||
| 863 | v = inb(HD64465_REG_PCC0SCR); | ||
| 864 | v |= HD64465_PCCSCR_SHDN; | ||
| 865 | outb(v, HD64465_REG_PCC0SCR); | ||
| 866 | |||
| 867 | /* use serial (TPS2206) power controller */ | ||
| 868 | v = inb(HD64465_REG_PCC0CSCR); | ||
| 869 | v |= HD64465_PCCCSCR_PSWSEL; | ||
| 870 | outb(v, HD64465_REG_PCC0CSCR); | ||
| 871 | |||
| 872 | /* | ||
| 873 | * Setup hs_sockets[] structures and request system resources. | ||
| 874 | * TODO: on memory allocation failure, power down the socket | ||
| 875 | * before quitting. | ||
| 876 | */ | ||
| 877 | for (i=0; i<HS_MAX_SOCKETS; i++) { | ||
| 878 | hs_set_voltages(&hs_sockets[i], 0, 0); | ||
| 879 | |||
| 880 | hs_sockets[i].socket.features |= SS_CAP_PCCARD | SS_CAP_STATIC_MAP; /* mappings are fixed in host memory */ | ||
| 881 | hs_sockets[i].socket.resource_ops = &pccard_static_ops; | ||
| 882 | hs_sockets[i].socket.irq_mask = 0xffde;/*0xffff*/ /* IRQs mapped in s/w so can do any, really */ | ||
| 883 | hs_sockets[i].socket.map_size = HD64465_PCC_WINDOW; /* 16MB fixed window size */ | ||
| 884 | |||
| 885 | hs_sockets[i].socket.owner = THIS_MODULE; | ||
| 886 | hs_sockets[i].socket.ss_entry = &hs_operations; | ||
| 887 | } | ||
| 888 | |||
| 889 | i = hs_init_socket(&hs_sockets[0], | ||
| 890 | HD64465_IRQ_PCMCIA0, | ||
| 891 | HD64465_PCC0_BASE, | ||
| 892 | HD64465_REG_PCC0ISR); | ||
| 893 | if (i < 0) { | ||
| 894 | unregister_driver(&hd64465_driver); | ||
| 895 | return i; | ||
| 896 | } | ||
| 897 | i = hs_init_socket(&hs_sockets[1], | ||
| 898 | HD64465_IRQ_PCMCIA1, | ||
| 899 | HD64465_PCC1_BASE, | ||
| 900 | HD64465_REG_PCC1ISR); | ||
| 901 | if (i < 0) { | ||
| 902 | unregister_driver(&hd64465_driver); | ||
| 903 | return i; | ||
| 904 | } | ||
| 905 | |||
| 906 | /* hd64465_io_debug = 0; */ | ||
| 907 | |||
| 908 | platform_device_register(&hd64465_device); | ||
| 909 | |||
| 910 | for (i=0; i<HS_MAX_SOCKETS; i++) { | ||
| 911 | unsigned int ret; | ||
| 912 | hs_sockets[i].socket.dev.parent = &hd64465_device.dev; | ||
| 913 | hs_sockets[i].number = i; | ||
| 914 | ret = pcmcia_register_socket(&hs_sockets[i].socket); | ||
| 915 | if (ret && i) | ||
| 916 | pcmcia_unregister_socket(&hs_sockets[0].socket); | ||
| 917 | } | ||
| 918 | |||
| 919 | return 0; | ||
| 920 | } | ||
| 921 | |||
| 922 | static void __exit exit_hs(void) | ||
| 923 | { | ||
| 924 | int i; | ||
| 925 | |||
| 926 | for (i=0 ; i<HS_MAX_SOCKETS ; i++) { | ||
| 927 | pcmcia_unregister_socket(&hs_sockets[i].socket); | ||
| 928 | hs_exit_socket(&hs_sockets[i]); | ||
| 929 | } | ||
| 930 | |||
| 931 | platform_device_unregister(&hd64465_device); | ||
| 932 | unregister_driver(&hd64465_driver); | ||
| 933 | } | ||
| 934 | |||
| 935 | module_init(init_hs); | ||
| 936 | module_exit(exit_hs); | ||
| 937 | |||
| 938 | /*============================================================*/ | ||
| 939 | /*END*/ | ||
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 76d4a98f0955..f5d0ba8e22d5 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
| @@ -302,9 +302,10 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
| 302 | /* We only allow changing Vpp1 and Vpp2 to the same value */ | 302 | /* We only allow changing Vpp1 and Vpp2 to the same value */ |
| 303 | if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && | 303 | if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && |
| 304 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | 304 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { |
| 305 | if (mod->Vpp1 != mod->Vpp2) | 305 | if (mod->Vpp1 != mod->Vpp2) { |
| 306 | ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n"); | 306 | ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n"); |
| 307 | return -EINVAL; | 307 | return -EINVAL; |
| 308 | } | ||
| 308 | s->socket.Vpp = mod->Vpp1; | 309 | s->socket.Vpp = mod->Vpp1; |
| 309 | if (s->ops->set_socket(s, &s->socket)) { | 310 | if (s->ops->set_socket(s, &s->socket)) { |
| 310 | dev_printk(KERN_WARNING, &s->dev, | 311 | dev_printk(KERN_WARNING, &s->dev, |
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 17f4ecf1c0c5..9ca22c7aafb2 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
| @@ -71,7 +71,7 @@ static DEFINE_MUTEX(rsrc_mutex); | |||
| 71 | ======================================================================*/ | 71 | ======================================================================*/ |
| 72 | 72 | ||
| 73 | static struct resource * | 73 | static struct resource * |
| 74 | make_resource(resource_size_t b, resource_size_t n, int flags, char *name) | 74 | make_resource(resource_size_t b, resource_size_t n, int flags, const char *name) |
| 75 | { | 75 | { |
| 76 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 76 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
| 77 | 77 | ||
| @@ -624,7 +624,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star | |||
| 624 | static struct resource *nonstatic_find_io_region(unsigned long base, int num, | 624 | static struct resource *nonstatic_find_io_region(unsigned long base, int num, |
| 625 | unsigned long align, struct pcmcia_socket *s) | 625 | unsigned long align, struct pcmcia_socket *s) |
| 626 | { | 626 | { |
| 627 | struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.bus_id); | 627 | struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); |
| 628 | struct socket_data *s_data = s->resource_data; | 628 | struct socket_data *s_data = s->resource_data; |
| 629 | struct pcmcia_align_data data; | 629 | struct pcmcia_align_data data; |
| 630 | unsigned long min = base; | 630 | unsigned long min = base; |
| @@ -658,7 +658,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, | |||
| 658 | static struct resource * nonstatic_find_mem_region(u_long base, u_long num, | 658 | static struct resource * nonstatic_find_mem_region(u_long base, u_long num, |
| 659 | u_long align, int low, struct pcmcia_socket *s) | 659 | u_long align, int low, struct pcmcia_socket *s) |
| 660 | { | 660 | { |
| 661 | struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.bus_id); | 661 | struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev)); |
| 662 | struct socket_data *s_data = s->resource_data; | 662 | struct socket_data *s_data = s->resource_data; |
| 663 | struct pcmcia_align_data data; | 663 | struct pcmcia_align_data data; |
| 664 | unsigned long min, max; | 664 | unsigned long min, max; |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 478a4a739c00..c3f1c8e9d254 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| 13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/pnp.h> | ||
| 16 | #include <linux/stat.h> | 15 | #include <linux/stat.h> |
| 17 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
| 18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c index 85edf945ab86..204158cf7a55 100644 --- a/drivers/ps3/ps3-lpm.c +++ b/drivers/ps3/ps3-lpm.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
| 25 | #include <asm/smp.h> | ||
| 25 | #include <asm/time.h> | 26 | #include <asm/time.h> |
| 26 | #include <asm/ps3.h> | 27 | #include <asm/ps3.h> |
| 27 | #include <asm/lv1call.h> | 28 | #include <asm/lv1call.h> |
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a926c896475e..643a6b98462b 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
| @@ -879,7 +879,7 @@ static void rio_update_route_tables(struct rio_mport *port) | |||
| 879 | * link, then start recursive peer enumeration. Returns %0 if | 879 | * link, then start recursive peer enumeration. Returns %0 if |
| 880 | * enumeration succeeds or %-EBUSY if enumeration fails. | 880 | * enumeration succeeds or %-EBUSY if enumeration fails. |
| 881 | */ | 881 | */ |
| 882 | int rio_enum_mport(struct rio_mport *mport) | 882 | int __devinit rio_enum_mport(struct rio_mport *mport) |
| 883 | { | 883 | { |
| 884 | struct rio_net *net = NULL; | 884 | struct rio_net *net = NULL; |
| 885 | int rc = 0; | 885 | int rc = 0; |
| @@ -972,7 +972,7 @@ static void rio_enum_timeout(unsigned long data) | |||
| 972 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY | 972 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY |
| 973 | * on failure. | 973 | * on failure. |
| 974 | */ | 974 | */ |
| 975 | int rio_disc_mport(struct rio_mport *mport) | 975 | int __devinit rio_disc_mport(struct rio_mport *mport) |
| 976 | { | 976 | { |
| 977 | struct rio_net *net = NULL; | 977 | struct rio_net *net = NULL; |
| 978 | int enum_timeout_flag = 0; | 978 | int enum_timeout_flag = 0; |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 680661abbc4b..6395c780008b 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
| @@ -467,7 +467,7 @@ static int __devinit rio_init(void) | |||
| 467 | 467 | ||
| 468 | device_initcall(rio_init); | 468 | device_initcall(rio_init); |
| 469 | 469 | ||
| 470 | int rio_init_mports(void) | 470 | int __devinit rio_init_mports(void) |
| 471 | { | 471 | { |
| 472 | int rc = 0; | 472 | int rc = 0; |
| 473 | struct rio_mport *port; | 473 | struct rio_mport *port; |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4dada6ee1119..39360e2a4540 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | menu "Voltage and Current regulators" | 1 | menuconfig REGULATOR |
| 2 | |||
| 3 | config REGULATOR | ||
| 4 | bool "Voltage and Current Regulator Support" | 2 | bool "Voltage and Current Regulator Support" |
| 5 | default n | 3 | default n |
| 6 | help | 4 | help |
| @@ -23,21 +21,20 @@ config REGULATOR | |||
| 23 | 21 | ||
| 24 | If unsure, say no. | 22 | If unsure, say no. |
| 25 | 23 | ||
| 24 | if REGULATOR | ||
| 25 | |||
| 26 | config REGULATOR_DEBUG | 26 | config REGULATOR_DEBUG |
| 27 | bool "Regulator debug support" | 27 | bool "Regulator debug support" |
| 28 | depends on REGULATOR | ||
| 29 | help | 28 | help |
| 30 | Say yes here to enable debugging support. | 29 | Say yes here to enable debugging support. |
| 31 | 30 | ||
| 32 | config REGULATOR_FIXED_VOLTAGE | 31 | config REGULATOR_FIXED_VOLTAGE |
| 33 | tristate | 32 | tristate |
| 34 | default n | 33 | default n |
| 35 | select REGULATOR | ||
| 36 | 34 | ||
| 37 | config REGULATOR_VIRTUAL_CONSUMER | 35 | config REGULATOR_VIRTUAL_CONSUMER |
| 38 | tristate "Virtual regulator consumer support" | 36 | tristate "Virtual regulator consumer support" |
| 39 | default n | 37 | default n |
| 40 | select REGULATOR | ||
| 41 | help | 38 | help |
| 42 | This driver provides a virtual consumer for the voltage and | 39 | This driver provides a virtual consumer for the voltage and |
| 43 | current regulator API which provides sysfs controls for | 40 | current regulator API which provides sysfs controls for |
| @@ -49,7 +46,6 @@ config REGULATOR_VIRTUAL_CONSUMER | |||
| 49 | config REGULATOR_BQ24022 | 46 | config REGULATOR_BQ24022 |
| 50 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" | 47 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" |
| 51 | default n | 48 | default n |
| 52 | select REGULATOR | ||
| 53 | help | 49 | help |
| 54 | This driver controls a TI bq24022 Charger attached via | 50 | This driver controls a TI bq24022 Charger attached via |
| 55 | GPIOs. The provided current regulator can enable/disable | 51 | GPIOs. The provided current regulator can enable/disable |
| @@ -59,7 +55,6 @@ config REGULATOR_BQ24022 | |||
| 59 | config REGULATOR_WM8350 | 55 | config REGULATOR_WM8350 |
| 60 | tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC" | 56 | tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC" |
| 61 | depends on MFD_WM8350 | 57 | depends on MFD_WM8350 |
| 62 | select REGULATOR | ||
| 63 | help | 58 | help |
| 64 | This driver provides support for the voltage and current regulators | 59 | This driver provides support for the voltage and current regulators |
| 65 | of the WM8350 AudioPlus PMIC. | 60 | of the WM8350 AudioPlus PMIC. |
| @@ -67,7 +62,6 @@ config REGULATOR_WM8350 | |||
| 67 | config REGULATOR_WM8400 | 62 | config REGULATOR_WM8400 |
| 68 | tristate "Wolfson Microelectroncis WM8400 AudioPlus PMIC" | 63 | tristate "Wolfson Microelectroncis WM8400 AudioPlus PMIC" |
| 69 | depends on MFD_WM8400 | 64 | depends on MFD_WM8400 |
| 70 | select REGULATOR | ||
| 71 | help | 65 | help |
| 72 | This driver provides support for the voltage regulators of the | 66 | This driver provides support for the voltage regulators of the |
| 73 | WM8400 AudioPlus PMIC. | 67 | WM8400 AudioPlus PMIC. |
| @@ -75,9 +69,8 @@ config REGULATOR_WM8400 | |||
| 75 | config REGULATOR_DA903X | 69 | config REGULATOR_DA903X |
| 76 | tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC" | 70 | tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC" |
| 77 | depends on PMIC_DA903X | 71 | depends on PMIC_DA903X |
| 78 | select REGULATOR | ||
| 79 | help | 72 | help |
| 80 | Say y here to support the BUCKs and LDOs regulators found on | 73 | Say y here to support the BUCKs and LDOs regulators found on |
| 81 | Dialog Semiconductor DA9030/DA9034 PMIC. | 74 | Dialog Semiconductor DA9030/DA9034 PMIC. |
| 82 | 75 | ||
| 83 | endmenu | 76 | endif |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8abbb2020af9..123092d8a984 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -277,6 +277,14 @@ config RTC_DRV_FM3130 | |||
| 277 | This driver can also be built as a module. If so the module | 277 | This driver can also be built as a module. If so the module |
| 278 | will be called rtc-fm3130. | 278 | will be called rtc-fm3130. |
| 279 | 279 | ||
| 280 | config RTC_DRV_RX8581 | ||
| 281 | tristate "Epson RX-8581" | ||
| 282 | help | ||
| 283 | If you say yes here you will get support for the Epson RX-8581. | ||
| 284 | |||
| 285 | This driver can also be built as a module. If so the module | ||
| 286 | will be called rtc-rx8581. | ||
| 287 | |||
| 280 | endif # I2C | 288 | endif # I2C |
| 281 | 289 | ||
| 282 | comment "SPI RTC drivers" | 290 | comment "SPI RTC drivers" |
| @@ -302,6 +310,17 @@ config RTC_DRV_DS1305 | |||
| 302 | This driver can also be built as a module. If so, the module | 310 | This driver can also be built as a module. If so, the module |
| 303 | will be called rtc-ds1305. | 311 | will be called rtc-ds1305. |
| 304 | 312 | ||
| 313 | config RTC_DRV_DS1390 | ||
| 314 | tristate "Dallas/Maxim DS1390/93/94" | ||
| 315 | help | ||
| 316 | If you say yes here you get support for the DS1390/93/94 chips. | ||
| 317 | |||
| 318 | This driver only supports the RTC feature, and not other chip | ||
| 319 | features such as alarms and trickle charging. | ||
| 320 | |||
| 321 | This driver can also be built as a module. If so, the module | ||
| 322 | will be called rtc-ds1390. | ||
| 323 | |||
| 305 | config RTC_DRV_MAX6902 | 324 | config RTC_DRV_MAX6902 |
| 306 | tristate "Maxim MAX6902" | 325 | tristate "Maxim MAX6902" |
| 307 | help | 326 | help |
| @@ -468,6 +487,16 @@ config RTC_DRV_V3020 | |||
| 468 | This driver can also be built as a module. If so, the module | 487 | This driver can also be built as a module. If so, the module |
| 469 | will be called rtc-v3020. | 488 | will be called rtc-v3020. |
| 470 | 489 | ||
| 490 | config RTC_DRV_WM8350 | ||
| 491 | tristate "Wolfson Microelectronics WM8350 RTC" | ||
| 492 | depends on MFD_WM8350 | ||
| 493 | help | ||
| 494 | If you say yes here you will get support for the RTC subsystem | ||
| 495 | of the Wolfson Microelectronics WM8350. | ||
| 496 | |||
| 497 | This driver can also be built as a module. If so, the module | ||
| 498 | will be called "rtc-wm8350". | ||
| 499 | |||
| 471 | comment "on-CPU RTC drivers" | 500 | comment "on-CPU RTC drivers" |
| 472 | 501 | ||
| 473 | config RTC_DRV_OMAP | 502 | config RTC_DRV_OMAP |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index e9e8474cc8fe..6e79c912bf9e 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -28,6 +28,7 @@ obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | |||
| 28 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o | 28 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o |
| 29 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o | 29 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o |
| 30 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o | 30 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o |
| 31 | obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o | ||
| 31 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | 32 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o |
| 32 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 33 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
| 33 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 34 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
| @@ -57,6 +58,7 @@ obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | |||
| 57 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 58 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
| 58 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 59 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
| 59 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 60 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
| 61 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | ||
| 60 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 62 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o |
| 61 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 63 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
| 62 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 64 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
| @@ -66,4 +68,5 @@ obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | |||
| 66 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o | 68 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o |
| 67 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 69 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
| 68 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 70 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
| 71 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o | ||
| 69 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 72 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 7af60b98d8a4..a04c1b6b1575 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -271,7 +271,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
| 271 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); | 271 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); |
| 272 | do { | 272 | do { |
| 273 | alarm->time.tm_year++; | 273 | alarm->time.tm_year++; |
| 274 | } while (!rtc_valid_tm(&alarm->time)); | 274 | } while (rtc_valid_tm(&alarm->time) != 0); |
| 275 | break; | 275 | break; |
| 276 | 276 | ||
| 277 | default: | 277 | default: |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5549231179a2..6cf8e282338f 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
| @@ -794,7 +794,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
| 794 | goto cleanup2; | 794 | goto cleanup2; |
| 795 | } | 795 | } |
| 796 | 796 | ||
| 797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram, %s irqs\n", | 797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", |
| 798 | cmos_rtc.rtc->dev.bus_id, | 798 | cmos_rtc.rtc->dev.bus_id, |
| 799 | is_valid_irq(rtc_irq) | 799 | is_valid_irq(rtc_irq) |
| 800 | ? (cmos_rtc.mon_alrm | 800 | ? (cmos_rtc.mon_alrm |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 079e9ed907e0..ecdea44ae4e5 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
| @@ -446,9 +446,6 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | |||
| 446 | if (rtc->ops->release) | 446 | if (rtc->ops->release) |
| 447 | rtc->ops->release(rtc->dev.parent); | 447 | rtc->ops->release(rtc->dev.parent); |
| 448 | 448 | ||
| 449 | if (file->f_flags & FASYNC) | ||
| 450 | rtc_dev_fasync(-1, file, 0); | ||
| 451 | |||
| 452 | clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); | 449 | clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); |
| 453 | return 0; | 450 | return 0; |
| 454 | } | 451 | } |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c new file mode 100644 index 000000000000..599e976bf014 --- /dev/null +++ b/drivers/rtc/rtc-ds1390.c | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | /* | ||
| 2 | * rtc-ds1390.c -- driver for DS1390/93/94 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Mercury IMC Ltd | ||
| 5 | * Written by Mark Jackson <mpfj@mimc.co.uk> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * NOTE : Currently this driver only supports the bare minimum for read | ||
| 12 | * and write the RTC. The extra features provided by the chip family | ||
| 13 | * (alarms, trickle charger, different control registers) are unavailable. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/rtc.h> | ||
| 18 | #include <linux/spi/spi.h> | ||
| 19 | #include <linux/bcd.h> | ||
| 20 | |||
| 21 | #define DS1390_REG_100THS 0x00 | ||
| 22 | #define DS1390_REG_SECONDS 0x01 | ||
| 23 | #define DS1390_REG_MINUTES 0x02 | ||
| 24 | #define DS1390_REG_HOURS 0x03 | ||
| 25 | #define DS1390_REG_DAY 0x04 | ||
| 26 | #define DS1390_REG_DATE 0x05 | ||
| 27 | #define DS1390_REG_MONTH_CENT 0x06 | ||
| 28 | #define DS1390_REG_YEAR 0x07 | ||
| 29 | |||
| 30 | #define DS1390_REG_ALARM_100THS 0x08 | ||
| 31 | #define DS1390_REG_ALARM_SECONDS 0x09 | ||
| 32 | #define DS1390_REG_ALARM_MINUTES 0x0A | ||
| 33 | #define DS1390_REG_ALARM_HOURS 0x0B | ||
| 34 | #define DS1390_REG_ALARM_DAY_DATE 0x0C | ||
| 35 | |||
| 36 | #define DS1390_REG_CONTROL 0x0D | ||
| 37 | #define DS1390_REG_STATUS 0x0E | ||
| 38 | #define DS1390_REG_TRICKLE 0x0F | ||
| 39 | |||
| 40 | struct ds1390 { | ||
| 41 | struct rtc_device *rtc; | ||
| 42 | u8 txrx_buf[9]; /* cmd + 8 registers */ | ||
| 43 | }; | ||
| 44 | |||
| 45 | static void ds1390_set_reg(struct device *dev, unsigned char address, | ||
| 46 | unsigned char data) | ||
| 47 | { | ||
| 48 | struct spi_device *spi = to_spi_device(dev); | ||
| 49 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
| 50 | |||
| 51 | /* Set MSB to indicate write */ | ||
| 52 | chip->txrx_buf[0] = address | 0x80; | ||
| 53 | chip->txrx_buf[1] = data; | ||
| 54 | |||
| 55 | /* do the i/o */ | ||
| 56 | spi_write_then_read(spi, chip->txrx_buf, 2, NULL, 0); | ||
| 57 | } | ||
| 58 | |||
| 59 | static int ds1390_get_reg(struct device *dev, unsigned char address, | ||
| 60 | unsigned char *data) | ||
| 61 | { | ||
| 62 | struct spi_device *spi = to_spi_device(dev); | ||
| 63 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
| 64 | int status; | ||
| 65 | |||
| 66 | if (!data) | ||
| 67 | return -EINVAL; | ||
| 68 | |||
| 69 | /* Clear MSB to indicate read */ | ||
| 70 | chip->txrx_buf[0] = address & 0x7f; | ||
| 71 | /* do the i/o */ | ||
| 72 | status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 1); | ||
| 73 | if (status != 0) | ||
| 74 | return status; | ||
| 75 | |||
| 76 | *data = chip->txrx_buf[1]; | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt) | ||
| 82 | { | ||
| 83 | struct spi_device *spi = to_spi_device(dev); | ||
| 84 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
| 85 | int status; | ||
| 86 | |||
| 87 | /* build the message */ | ||
| 88 | chip->txrx_buf[0] = DS1390_REG_SECONDS; | ||
| 89 | |||
| 90 | /* do the i/o */ | ||
| 91 | status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 8); | ||
| 92 | if (status != 0) | ||
| 93 | return status; | ||
| 94 | |||
| 95 | /* The chip sends data in this order: | ||
| 96 | * Seconds, Minutes, Hours, Day, Date, Month / Century, Year */ | ||
| 97 | dt->tm_sec = bcd2bin(chip->txrx_buf[0]); | ||
| 98 | dt->tm_min = bcd2bin(chip->txrx_buf[1]); | ||
| 99 | dt->tm_hour = bcd2bin(chip->txrx_buf[2]); | ||
| 100 | dt->tm_wday = bcd2bin(chip->txrx_buf[3]); | ||
| 101 | dt->tm_mday = bcd2bin(chip->txrx_buf[4]); | ||
| 102 | /* mask off century bit */ | ||
| 103 | dt->tm_mon = bcd2bin(chip->txrx_buf[5] & 0x7f) - 1; | ||
| 104 | /* adjust for century bit */ | ||
| 105 | dt->tm_year = bcd2bin(chip->txrx_buf[6]) + ((chip->txrx_buf[5] & 0x80) ? 100 : 0); | ||
| 106 | |||
| 107 | return rtc_valid_tm(dt); | ||
| 108 | } | ||
| 109 | |||
| 110 | static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt) | ||
| 111 | { | ||
| 112 | struct spi_device *spi = to_spi_device(dev); | ||
| 113 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
| 114 | |||
| 115 | /* build the message */ | ||
| 116 | chip->txrx_buf[0] = DS1390_REG_SECONDS | 0x80; | ||
| 117 | chip->txrx_buf[1] = bin2bcd(dt->tm_sec); | ||
| 118 | chip->txrx_buf[2] = bin2bcd(dt->tm_min); | ||
| 119 | chip->txrx_buf[3] = bin2bcd(dt->tm_hour); | ||
| 120 | chip->txrx_buf[4] = bin2bcd(dt->tm_wday); | ||
| 121 | chip->txrx_buf[5] = bin2bcd(dt->tm_mday); | ||
| 122 | chip->txrx_buf[6] = bin2bcd(dt->tm_mon + 1) | | ||
| 123 | ((dt->tm_year > 99) ? 0x80 : 0x00); | ||
| 124 | chip->txrx_buf[7] = bin2bcd(dt->tm_year % 100); | ||
| 125 | |||
| 126 | /* do the i/o */ | ||
| 127 | return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); | ||
| 128 | } | ||
| 129 | |||
| 130 | static int ds1390_read_time(struct device *dev, struct rtc_time *tm) | ||
| 131 | { | ||
| 132 | return ds1390_get_datetime(dev, tm); | ||
| 133 | } | ||
| 134 | |||
| 135 | static int ds1390_set_time(struct device *dev, struct rtc_time *tm) | ||
| 136 | { | ||
| 137 | return ds1390_set_datetime(dev, tm); | ||
| 138 | } | ||
| 139 | |||
| 140 | static const struct rtc_class_ops ds1390_rtc_ops = { | ||
| 141 | .read_time = ds1390_read_time, | ||
| 142 | .set_time = ds1390_set_time, | ||
| 143 | }; | ||
| 144 | |||
| 145 | static int __devinit ds1390_probe(struct spi_device *spi) | ||
| 146 | { | ||
| 147 | struct rtc_device *rtc; | ||
| 148 | unsigned char tmp; | ||
| 149 | struct ds1390 *chip; | ||
| 150 | int res; | ||
| 151 | |||
| 152 | printk(KERN_DEBUG "DS1390 SPI RTC driver\n"); | ||
| 153 | |||
| 154 | rtc = rtc_device_register("ds1390", | ||
| 155 | &spi->dev, &ds1390_rtc_ops, THIS_MODULE); | ||
| 156 | if (IS_ERR(rtc)) { | ||
| 157 | printk(KERN_ALERT "RTC : unable to register device\n"); | ||
| 158 | return PTR_ERR(rtc); | ||
| 159 | } | ||
| 160 | |||
| 161 | spi->mode = SPI_MODE_3; | ||
| 162 | spi->bits_per_word = 8; | ||
| 163 | spi_setup(spi); | ||
| 164 | |||
| 165 | chip = kzalloc(sizeof *chip, GFP_KERNEL); | ||
| 166 | if (!chip) { | ||
| 167 | printk(KERN_ALERT "RTC : unable to allocate device memory\n"); | ||
| 168 | rtc_device_unregister(rtc); | ||
| 169 | return -ENOMEM; | ||
| 170 | } | ||
| 171 | chip->rtc = rtc; | ||
| 172 | dev_set_drvdata(&spi->dev, chip); | ||
| 173 | |||
| 174 | res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); | ||
| 175 | if (res) { | ||
| 176 | printk(KERN_ALERT "RTC : unable to read device\n"); | ||
| 177 | rtc_device_unregister(rtc); | ||
| 178 | return res; | ||
| 179 | } | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | static int __devexit ds1390_remove(struct spi_device *spi) | ||
| 185 | { | ||
| 186 | struct ds1390 *chip = platform_get_drvdata(spi); | ||
| 187 | struct rtc_device *rtc = chip->rtc; | ||
| 188 | |||
| 189 | if (rtc) | ||
| 190 | rtc_device_unregister(rtc); | ||
| 191 | |||
| 192 | kfree(chip); | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | static struct spi_driver ds1390_driver = { | ||
| 198 | .driver = { | ||
| 199 | .name = "rtc-ds1390", | ||
| 200 | .owner = THIS_MODULE, | ||
| 201 | }, | ||
| 202 | .probe = ds1390_probe, | ||
| 203 | .remove = __devexit_p(ds1390_remove), | ||
| 204 | }; | ||
| 205 | |||
| 206 | static __init int ds1390_init(void) | ||
| 207 | { | ||
| 208 | return spi_register_driver(&ds1390_driver); | ||
| 209 | } | ||
| 210 | module_init(ds1390_init); | ||
| 211 | |||
| 212 | static __exit void ds1390_exit(void) | ||
| 213 | { | ||
| 214 | spi_unregister_driver(&ds1390_driver); | ||
| 215 | } | ||
| 216 | module_exit(ds1390_exit); | ||
| 217 | |||
| 218 | MODULE_DESCRIPTION("DS1390/93/94 SPI RTC driver"); | ||
| 219 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); | ||
| 220 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 341d7a5b45a2..4e91419e8911 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
| @@ -209,12 +209,18 @@ static int ds1672_probe(struct i2c_client *client, | |||
| 209 | return err; | 209 | return err; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | static struct i2c_device_id ds1672_id[] = { | ||
| 213 | { "ds1672", 0 }, | ||
| 214 | { } | ||
| 215 | }; | ||
| 216 | |||
| 212 | static struct i2c_driver ds1672_driver = { | 217 | static struct i2c_driver ds1672_driver = { |
| 213 | .driver = { | 218 | .driver = { |
| 214 | .name = "rtc-ds1672", | 219 | .name = "rtc-ds1672", |
| 215 | }, | 220 | }, |
| 216 | .probe = &ds1672_probe, | 221 | .probe = &ds1672_probe, |
| 217 | .remove = &ds1672_remove, | 222 | .remove = &ds1672_remove, |
| 223 | .id_table = ds1672_id, | ||
| 218 | }; | 224 | }; |
| 219 | 225 | ||
| 220 | static int __init ds1672_init(void) | 226 | static int __init ds1672_init(void) |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 04b63dab6932..43afb7ab5289 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
| @@ -87,6 +87,10 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
| 87 | dev_dbg(dev, "Century bit is enabled\n"); | 87 | dev_dbg(dev, "Century bit is enabled\n"); |
| 88 | tm->tm_year += 100; /* one century */ | 88 | tm->tm_year += 100; /* one century */ |
| 89 | } | 89 | } |
| 90 | #ifdef CONFIG_SPARC | ||
| 91 | /* Sun SPARC machines count years since 1968 */ | ||
| 92 | tm->tm_year += 68; | ||
| 93 | #endif | ||
| 90 | 94 | ||
| 91 | tm->tm_wday = bcd2bin(val & 0x07); | 95 | tm->tm_wday = bcd2bin(val & 0x07); |
| 92 | tm->tm_hour = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F); | 96 | tm->tm_hour = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F); |
| @@ -110,11 +114,20 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 110 | struct m48t59_private *m48t59 = platform_get_drvdata(pdev); | 114 | struct m48t59_private *m48t59 = platform_get_drvdata(pdev); |
| 111 | unsigned long flags; | 115 | unsigned long flags; |
| 112 | u8 val = 0; | 116 | u8 val = 0; |
| 117 | int year = tm->tm_year; | ||
| 118 | |||
| 119 | #ifdef CONFIG_SPARC | ||
| 120 | /* Sun SPARC machines count years since 1968 */ | ||
| 121 | year -= 68; | ||
| 122 | #endif | ||
| 113 | 123 | ||
| 114 | dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n", | 124 | dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n", |
| 115 | tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, | 125 | year + 1900, tm->tm_mon, tm->tm_mday, |
| 116 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 126 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
| 117 | 127 | ||
| 128 | if (year < 0) | ||
| 129 | return -EINVAL; | ||
| 130 | |||
| 118 | spin_lock_irqsave(&m48t59->lock, flags); | 131 | spin_lock_irqsave(&m48t59->lock, flags); |
| 119 | /* Issue the WRITE command */ | 132 | /* Issue the WRITE command */ |
| 120 | M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL); | 133 | M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL); |
| @@ -125,9 +138,9 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 125 | M48T59_WRITE((bin2bcd(tm->tm_mday) & 0x3F), M48T59_MDAY); | 138 | M48T59_WRITE((bin2bcd(tm->tm_mday) & 0x3F), M48T59_MDAY); |
| 126 | /* tm_mon is 0-11 */ | 139 | /* tm_mon is 0-11 */ |
| 127 | M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH); | 140 | M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH); |
| 128 | M48T59_WRITE(bin2bcd(tm->tm_year % 100), M48T59_YEAR); | 141 | M48T59_WRITE(bin2bcd(year % 100), M48T59_YEAR); |
| 129 | 142 | ||
| 130 | if (pdata->type == M48T59RTC_TYPE_M48T59 && (tm->tm_year / 100)) | 143 | if (pdata->type == M48T59RTC_TYPE_M48T59 && (year / 100)) |
| 131 | val = (M48T59_WDAY_CEB | M48T59_WDAY_CB); | 144 | val = (M48T59_WDAY_CEB | M48T59_WDAY_CB); |
| 132 | val |= (bin2bcd(tm->tm_wday) & 0x07); | 145 | val |= (bin2bcd(tm->tm_wday) & 0x07); |
| 133 | M48T59_WRITE(val, M48T59_WDAY); | 146 | M48T59_WRITE(val, M48T59_WDAY); |
| @@ -159,6 +172,10 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 159 | M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); | 172 | M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); |
| 160 | 173 | ||
| 161 | tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); | 174 | tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); |
| 175 | #ifdef CONFIG_SPARC | ||
| 176 | /* Sun SPARC machines count years since 1968 */ | ||
| 177 | tm->tm_year += 68; | ||
| 178 | #endif | ||
| 162 | /* tm_mon is 0-11 */ | 179 | /* tm_mon is 0-11 */ |
| 163 | tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; | 180 | tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; |
| 164 | 181 | ||
| @@ -192,11 +209,20 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 192 | struct rtc_time *tm = &alrm->time; | 209 | struct rtc_time *tm = &alrm->time; |
| 193 | u8 mday, hour, min, sec; | 210 | u8 mday, hour, min, sec; |
| 194 | unsigned long flags; | 211 | unsigned long flags; |
| 212 | int year = tm->tm_year; | ||
| 213 | |||
| 214 | #ifdef CONFIG_SPARC | ||
| 215 | /* Sun SPARC machines count years since 1968 */ | ||
| 216 | year -= 68; | ||
| 217 | #endif | ||
| 195 | 218 | ||
| 196 | /* If no irq, we don't support ALARM */ | 219 | /* If no irq, we don't support ALARM */ |
| 197 | if (m48t59->irq == NO_IRQ) | 220 | if (m48t59->irq == NO_IRQ) |
| 198 | return -EIO; | 221 | return -EIO; |
| 199 | 222 | ||
| 223 | if (year < 0) | ||
| 224 | return -EINVAL; | ||
| 225 | |||
| 200 | /* | 226 | /* |
| 201 | * 0xff means "always match" | 227 | * 0xff means "always match" |
| 202 | */ | 228 | */ |
| @@ -228,7 +254,7 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 228 | spin_unlock_irqrestore(&m48t59->lock, flags); | 254 | spin_unlock_irqrestore(&m48t59->lock, flags); |
| 229 | 255 | ||
| 230 | dev_dbg(dev, "RTC set alarm time %04d-%02d-%02d %02d/%02d/%02d\n", | 256 | dev_dbg(dev, "RTC set alarm time %04d-%02d-%02d %02d/%02d/%02d\n", |
| 231 | tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, | 257 | year + 1900, tm->tm_mon, tm->tm_mday, |
| 232 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 258 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
| 233 | return 0; | 259 | return 0; |
| 234 | } | 260 | } |
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 80782798763f..a4f6665ab3c5 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c | |||
| @@ -247,12 +247,18 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 247 | return 0; | 247 | return 0; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | static struct i2c_device_id max6900_id[] = { | ||
| 251 | { "max6900", 0 }, | ||
| 252 | { } | ||
| 253 | }; | ||
| 254 | |||
| 250 | static struct i2c_driver max6900_driver = { | 255 | static struct i2c_driver max6900_driver = { |
| 251 | .driver = { | 256 | .driver = { |
| 252 | .name = "rtc-max6900", | 257 | .name = "rtc-max6900", |
| 253 | }, | 258 | }, |
| 254 | .probe = max6900_probe, | 259 | .probe = max6900_probe, |
| 255 | .remove = max6900_remove, | 260 | .remove = max6900_remove, |
| 261 | .id_table = max6900_id, | ||
| 256 | }; | 262 | }; |
| 257 | 263 | ||
| 258 | static int __init max6900_init(void) | 264 | static int __init max6900_init(void) |
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c new file mode 100644 index 000000000000..c9522f3bc21c --- /dev/null +++ b/drivers/rtc/rtc-rx8581.c | |||
| @@ -0,0 +1,281 @@ | |||
| 1 | /* | ||
| 2 | * An I2C driver for the Epson RX8581 RTC | ||
| 3 | * | ||
| 4 | * Author: Martyn Welch <martyn.welch@gefanuc.com> | ||
| 5 | * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * Based on: rtc-pcf8563.c (An I2C driver for the Philips PCF8563 RTC) | ||
| 12 | * Copyright 2005-06 Tower Technologies | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/i2c.h> | ||
| 17 | #include <linux/bcd.h> | ||
| 18 | #include <linux/rtc.h> | ||
| 19 | #include <linux/log2.h> | ||
| 20 | |||
| 21 | #define DRV_VERSION "0.1" | ||
| 22 | |||
| 23 | #define RX8581_REG_SC 0x00 /* Second in BCD */ | ||
| 24 | #define RX8581_REG_MN 0x01 /* Minute in BCD */ | ||
| 25 | #define RX8581_REG_HR 0x02 /* Hour in BCD */ | ||
| 26 | #define RX8581_REG_DW 0x03 /* Day of Week */ | ||
| 27 | #define RX8581_REG_DM 0x04 /* Day of Month in BCD */ | ||
| 28 | #define RX8581_REG_MO 0x05 /* Month in BCD */ | ||
| 29 | #define RX8581_REG_YR 0x06 /* Year in BCD */ | ||
| 30 | #define RX8581_REG_RAM 0x07 /* RAM */ | ||
| 31 | #define RX8581_REG_AMN 0x08 /* Alarm Min in BCD*/ | ||
| 32 | #define RX8581_REG_AHR 0x09 /* Alarm Hour in BCD */ | ||
| 33 | #define RX8581_REG_ADM 0x0A | ||
| 34 | #define RX8581_REG_ADW 0x0A | ||
| 35 | #define RX8581_REG_TMR0 0x0B | ||
| 36 | #define RX8581_REG_TMR1 0x0C | ||
| 37 | #define RX8581_REG_EXT 0x0D /* Extension Register */ | ||
| 38 | #define RX8581_REG_FLAG 0x0E /* Flag Register */ | ||
| 39 | #define RX8581_REG_CTRL 0x0F /* Control Register */ | ||
| 40 | |||
| 41 | |||
| 42 | /* Flag Register bit definitions */ | ||
| 43 | #define RX8581_FLAG_UF 0x20 /* Update */ | ||
| 44 | #define RX8581_FLAG_TF 0x10 /* Timer */ | ||
| 45 | #define RX8581_FLAG_AF 0x08 /* Alarm */ | ||
| 46 | #define RX8581_FLAG_VLF 0x02 /* Voltage Low */ | ||
| 47 | |||
| 48 | /* Control Register bit definitions */ | ||
| 49 | #define RX8581_CTRL_UIE 0x20 /* Update Interrupt Enable */ | ||
| 50 | #define RX8581_CTRL_TIE 0x10 /* Timer Interrupt Enable */ | ||
| 51 | #define RX8581_CTRL_AIE 0x08 /* Alarm Interrupt Enable */ | ||
| 52 | #define RX8581_CTRL_STOP 0x02 /* STOP bit */ | ||
| 53 | #define RX8581_CTRL_RESET 0x01 /* RESET bit */ | ||
| 54 | |||
| 55 | static struct i2c_driver rx8581_driver; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * In the routines that deal directly with the rx8581 hardware, we use | ||
| 59 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
| 60 | */ | ||
| 61 | static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
| 62 | { | ||
| 63 | unsigned char date[7]; | ||
| 64 | int data, err; | ||
| 65 | |||
| 66 | /* First we ensure that the "update flag" is not set, we read the | ||
| 67 | * time and date then re-read the "update flag". If the update flag | ||
| 68 | * has been set, we know that the time has changed during the read so | ||
| 69 | * we repeat the whole process again. | ||
| 70 | */ | ||
| 71 | data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); | ||
| 72 | if (data < 0) { | ||
| 73 | dev_err(&client->dev, "Unable to read device flags\n"); | ||
| 74 | return -EIO; | ||
| 75 | } | ||
| 76 | |||
| 77 | do { | ||
| 78 | /* If update flag set, clear it */ | ||
| 79 | if (data & RX8581_FLAG_UF) { | ||
| 80 | err = i2c_smbus_write_byte_data(client, | ||
| 81 | RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF)); | ||
| 82 | if (err != 0) { | ||
| 83 | dev_err(&client->dev, "Unable to write device " | ||
| 84 | "flags\n"); | ||
| 85 | return -EIO; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /* Now read time and date */ | ||
| 90 | err = i2c_smbus_read_i2c_block_data(client, RX8581_REG_SC, | ||
| 91 | 7, date); | ||
| 92 | if (err < 0) { | ||
| 93 | dev_err(&client->dev, "Unable to read date\n"); | ||
| 94 | return -EIO; | ||
| 95 | } | ||
| 96 | |||
| 97 | /* Check flag register */ | ||
| 98 | data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); | ||
| 99 | if (data < 0) { | ||
| 100 | dev_err(&client->dev, "Unable to read device flags\n"); | ||
| 101 | return -EIO; | ||
| 102 | } | ||
| 103 | } while (data & RX8581_FLAG_UF); | ||
| 104 | |||
| 105 | if (data & RX8581_FLAG_VLF) | ||
| 106 | dev_info(&client->dev, | ||
| 107 | "low voltage detected, date/time is not reliable.\n"); | ||
| 108 | |||
| 109 | dev_dbg(&client->dev, | ||
| 110 | "%s: raw data is sec=%02x, min=%02x, hr=%02x, " | ||
| 111 | "wday=%02x, mday=%02x, mon=%02x, year=%02x\n", | ||
| 112 | __func__, | ||
| 113 | date[0], date[1], date[2], date[3], date[4], date[5], date[6]); | ||
| 114 | |||
| 115 | tm->tm_sec = bcd2bin(date[RX8581_REG_SC] & 0x7F); | ||
| 116 | tm->tm_min = bcd2bin(date[RX8581_REG_MN] & 0x7F); | ||
| 117 | tm->tm_hour = bcd2bin(date[RX8581_REG_HR] & 0x3F); /* rtc hr 0-23 */ | ||
| 118 | tm->tm_wday = ilog2(date[RX8581_REG_DW] & 0x7F); | ||
| 119 | tm->tm_mday = bcd2bin(date[RX8581_REG_DM] & 0x3F); | ||
| 120 | tm->tm_mon = bcd2bin(date[RX8581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ | ||
| 121 | tm->tm_year = bcd2bin(date[RX8581_REG_YR]); | ||
| 122 | if (tm->tm_year < 70) | ||
| 123 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
| 124 | |||
| 125 | |||
| 126 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | ||
| 127 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
| 128 | __func__, | ||
| 129 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
| 130 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
| 131 | |||
| 132 | err = rtc_valid_tm(tm); | ||
| 133 | if (err < 0) | ||
| 134 | dev_err(&client->dev, "retrieved date/time is not valid.\n"); | ||
| 135 | |||
| 136 | return err; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
| 140 | { | ||
| 141 | int data, err; | ||
| 142 | unsigned char buf[7]; | ||
| 143 | |||
| 144 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " | ||
| 145 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
| 146 | __func__, | ||
| 147 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
| 148 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
| 149 | |||
| 150 | /* hours, minutes and seconds */ | ||
| 151 | buf[RX8581_REG_SC] = bin2bcd(tm->tm_sec); | ||
| 152 | buf[RX8581_REG_MN] = bin2bcd(tm->tm_min); | ||
| 153 | buf[RX8581_REG_HR] = bin2bcd(tm->tm_hour); | ||
| 154 | |||
| 155 | buf[RX8581_REG_DM] = bin2bcd(tm->tm_mday); | ||
| 156 | |||
| 157 | /* month, 1 - 12 */ | ||
| 158 | buf[RX8581_REG_MO] = bin2bcd(tm->tm_mon + 1); | ||
| 159 | |||
| 160 | /* year and century */ | ||
| 161 | buf[RX8581_REG_YR] = bin2bcd(tm->tm_year % 100); | ||
| 162 | buf[RX8581_REG_DW] = (0x1 << tm->tm_wday); | ||
| 163 | |||
| 164 | /* Stop the clock */ | ||
| 165 | data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL); | ||
| 166 | if (data < 0) { | ||
| 167 | dev_err(&client->dev, "Unable to read control register\n"); | ||
| 168 | return -EIO; | ||
| 169 | } | ||
| 170 | |||
| 171 | err = i2c_smbus_write_byte_data(client, RX8581_REG_FLAG, | ||
| 172 | (data | RX8581_CTRL_STOP)); | ||
| 173 | if (err < 0) { | ||
| 174 | dev_err(&client->dev, "Unable to write control register\n"); | ||
| 175 | return -EIO; | ||
| 176 | } | ||
| 177 | |||
| 178 | /* write register's data */ | ||
| 179 | err = i2c_smbus_write_i2c_block_data(client, RX8581_REG_SC, 7, buf); | ||
| 180 | if (err < 0) { | ||
| 181 | dev_err(&client->dev, "Unable to write to date registers\n"); | ||
| 182 | return -EIO; | ||
| 183 | } | ||
| 184 | |||
| 185 | /* Restart the clock */ | ||
| 186 | data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL); | ||
| 187 | if (data < 0) { | ||
| 188 | dev_err(&client->dev, "Unable to read control register\n"); | ||
| 189 | return -EIO; | ||
| 190 | } | ||
| 191 | |||
| 192 | err = i2c_smbus_write_byte_data(client, RX8581_REG_FLAG, | ||
| 193 | (data | ~(RX8581_CTRL_STOP))); | ||
| 194 | if (err != 0) { | ||
| 195 | dev_err(&client->dev, "Unable to write control register\n"); | ||
| 196 | return -EIO; | ||
| 197 | } | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 203 | { | ||
| 204 | return rx8581_get_datetime(to_i2c_client(dev), tm); | ||
| 205 | } | ||
| 206 | |||
| 207 | static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 208 | { | ||
| 209 | return rx8581_set_datetime(to_i2c_client(dev), tm); | ||
| 210 | } | ||
| 211 | |||
| 212 | static const struct rtc_class_ops rx8581_rtc_ops = { | ||
| 213 | .read_time = rx8581_rtc_read_time, | ||
| 214 | .set_time = rx8581_rtc_set_time, | ||
| 215 | }; | ||
| 216 | |||
| 217 | static int __devinit rx8581_probe(struct i2c_client *client, | ||
| 218 | const struct i2c_device_id *id) | ||
| 219 | { | ||
| 220 | struct rtc_device *rtc; | ||
| 221 | |||
| 222 | dev_dbg(&client->dev, "%s\n", __func__); | ||
| 223 | |||
| 224 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
| 225 | return -ENODEV; | ||
| 226 | |||
| 227 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | ||
| 228 | |||
| 229 | rtc = rtc_device_register(rx8581_driver.driver.name, | ||
| 230 | &client->dev, &rx8581_rtc_ops, THIS_MODULE); | ||
| 231 | |||
| 232 | if (IS_ERR(rtc)) | ||
| 233 | return PTR_ERR(rtc); | ||
| 234 | |||
| 235 | i2c_set_clientdata(client, rtc); | ||
| 236 | |||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | |||
| 240 | static int __devexit rx8581_remove(struct i2c_client *client) | ||
| 241 | { | ||
| 242 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
| 243 | |||
| 244 | rtc_device_unregister(rtc); | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | static const struct i2c_device_id rx8581_id[] = { | ||
| 250 | { "rx8581", 0 }, | ||
| 251 | { } | ||
| 252 | }; | ||
| 253 | MODULE_DEVICE_TABLE(i2c, rx8581_id); | ||
| 254 | |||
| 255 | static struct i2c_driver rx8581_driver = { | ||
| 256 | .driver = { | ||
| 257 | .name = "rtc-rx8581", | ||
| 258 | .owner = THIS_MODULE, | ||
| 259 | }, | ||
| 260 | .probe = rx8581_probe, | ||
| 261 | .remove = __devexit_p(rx8581_remove), | ||
| 262 | .id_table = rx8581_id, | ||
| 263 | }; | ||
| 264 | |||
| 265 | static int __init rx8581_init(void) | ||
| 266 | { | ||
| 267 | return i2c_add_driver(&rx8581_driver); | ||
| 268 | } | ||
| 269 | |||
| 270 | static void __exit rx8581_exit(void) | ||
| 271 | { | ||
| 272 | i2c_del_driver(&rx8581_driver); | ||
| 273 | } | ||
| 274 | |||
| 275 | MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); | ||
| 276 | MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); | ||
| 277 | MODULE_LICENSE("GPL"); | ||
| 278 | MODULE_VERSION(DRV_VERSION); | ||
| 279 | |||
| 280 | module_init(rx8581_init); | ||
| 281 | module_exit(rx8581_exit); | ||
diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c index 7ccb0dd700af..5be98bfd7ed3 100644 --- a/drivers/rtc/rtc-starfire.c +++ b/drivers/rtc/rtc-starfire.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include <linux/time.h> | ||
| 10 | #include <linux/rtc.h> | 9 | #include <linux/rtc.h> |
| 11 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 12 | 11 | ||
| @@ -16,11 +15,6 @@ MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); | |||
| 16 | MODULE_DESCRIPTION("Starfire RTC driver"); | 15 | MODULE_DESCRIPTION("Starfire RTC driver"); |
| 17 | MODULE_LICENSE("GPL"); | 16 | MODULE_LICENSE("GPL"); |
| 18 | 17 | ||
| 19 | struct starfire_rtc { | ||
| 20 | struct rtc_device *rtc; | ||
| 21 | spinlock_t lock; | ||
| 22 | }; | ||
| 23 | |||
| 24 | static u32 starfire_get_time(void) | 18 | static u32 starfire_get_time(void) |
| 25 | { | 19 | { |
| 26 | static char obp_gettod[32]; | 20 | static char obp_gettod[32]; |
| @@ -35,64 +29,31 @@ static u32 starfire_get_time(void) | |||
| 35 | 29 | ||
| 36 | static int starfire_read_time(struct device *dev, struct rtc_time *tm) | 30 | static int starfire_read_time(struct device *dev, struct rtc_time *tm) |
| 37 | { | 31 | { |
| 38 | struct starfire_rtc *p = dev_get_drvdata(dev); | 32 | rtc_time_to_tm(starfire_get_time(), tm); |
| 39 | unsigned long flags, secs; | 33 | return rtc_valid_tm(tm); |
| 40 | |||
| 41 | spin_lock_irqsave(&p->lock, flags); | ||
| 42 | secs = starfire_get_time(); | ||
| 43 | spin_unlock_irqrestore(&p->lock, flags); | ||
| 44 | |||
| 45 | rtc_time_to_tm(secs, tm); | ||
| 46 | |||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static int starfire_set_time(struct device *dev, struct rtc_time *tm) | ||
| 51 | { | ||
| 52 | unsigned long secs; | ||
| 53 | int err; | ||
| 54 | |||
| 55 | err = rtc_tm_to_time(tm, &secs); | ||
| 56 | if (err) | ||
| 57 | return err; | ||
| 58 | |||
| 59 | /* Do nothing, time is set using the service processor | ||
| 60 | * console on this platform. | ||
| 61 | */ | ||
| 62 | return 0; | ||
| 63 | } | 34 | } |
| 64 | 35 | ||
| 65 | static const struct rtc_class_ops starfire_rtc_ops = { | 36 | static const struct rtc_class_ops starfire_rtc_ops = { |
| 66 | .read_time = starfire_read_time, | 37 | .read_time = starfire_read_time, |
| 67 | .set_time = starfire_set_time, | ||
| 68 | }; | 38 | }; |
| 69 | 39 | ||
| 70 | static int __devinit starfire_rtc_probe(struct platform_device *pdev) | 40 | static int __init starfire_rtc_probe(struct platform_device *pdev) |
| 71 | { | 41 | { |
| 72 | struct starfire_rtc *p = kzalloc(sizeof(*p), GFP_KERNEL); | 42 | struct rtc_device *rtc = rtc_device_register("starfire", &pdev->dev, |
| 73 | 43 | &starfire_rtc_ops, THIS_MODULE); | |
| 74 | if (!p) | 44 | if (IS_ERR(rtc)) |
| 75 | return -ENOMEM; | 45 | return PTR_ERR(rtc); |
| 76 | 46 | ||
| 77 | spin_lock_init(&p->lock); | 47 | platform_set_drvdata(pdev, rtc); |
| 78 | 48 | ||
| 79 | p->rtc = rtc_device_register("starfire", &pdev->dev, | ||
| 80 | &starfire_rtc_ops, THIS_MODULE); | ||
| 81 | if (IS_ERR(p->rtc)) { | ||
| 82 | int err = PTR_ERR(p->rtc); | ||
| 83 | kfree(p); | ||
| 84 | return err; | ||
| 85 | } | ||
| 86 | platform_set_drvdata(pdev, p); | ||
| 87 | return 0; | 49 | return 0; |
| 88 | } | 50 | } |
| 89 | 51 | ||
| 90 | static int __devexit starfire_rtc_remove(struct platform_device *pdev) | 52 | static int __exit starfire_rtc_remove(struct platform_device *pdev) |
| 91 | { | 53 | { |
| 92 | struct starfire_rtc *p = platform_get_drvdata(pdev); | 54 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
| 93 | 55 | ||
| 94 | rtc_device_unregister(p->rtc); | 56 | rtc_device_unregister(rtc); |
| 95 | kfree(p); | ||
| 96 | 57 | ||
| 97 | return 0; | 58 | return 0; |
| 98 | } | 59 | } |
| @@ -102,13 +63,12 @@ static struct platform_driver starfire_rtc_driver = { | |||
| 102 | .name = "rtc-starfire", | 63 | .name = "rtc-starfire", |
| 103 | .owner = THIS_MODULE, | 64 | .owner = THIS_MODULE, |
| 104 | }, | 65 | }, |
| 105 | .probe = starfire_rtc_probe, | 66 | .remove = __exit_p(starfire_rtc_remove), |
| 106 | .remove = __devexit_p(starfire_rtc_remove), | ||
| 107 | }; | 67 | }; |
| 108 | 68 | ||
| 109 | static int __init starfire_rtc_init(void) | 69 | static int __init starfire_rtc_init(void) |
| 110 | { | 70 | { |
| 111 | return platform_driver_register(&starfire_rtc_driver); | 71 | return platform_driver_probe(&starfire_rtc_driver, starfire_rtc_probe); |
| 112 | } | 72 | } |
| 113 | 73 | ||
| 114 | static void __exit starfire_rtc_exit(void) | 74 | static void __exit starfire_rtc_exit(void) |
diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c index 2012ccbb4a53..5b2261052a65 100644 --- a/drivers/rtc/rtc-sun4v.c +++ b/drivers/rtc/rtc-sun4v.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* rtc-sun4c.c: Hypervisor based RTC for SUN4V systems. | 1 | /* rtc-sun4v.c: Hypervisor based RTC for SUN4V systems. |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> |
| 4 | */ | 4 | */ |
| @@ -7,21 +7,11 @@ | |||
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
| 9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 10 | #include <linux/time.h> | ||
| 11 | #include <linux/rtc.h> | 10 | #include <linux/rtc.h> |
| 12 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 13 | 12 | ||
| 14 | #include <asm/hypervisor.h> | 13 | #include <asm/hypervisor.h> |
| 15 | 14 | ||
| 16 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); | ||
| 17 | MODULE_DESCRIPTION("SUN4V RTC driver"); | ||
| 18 | MODULE_LICENSE("GPL"); | ||
| 19 | |||
| 20 | struct sun4v_rtc { | ||
| 21 | struct rtc_device *rtc; | ||
| 22 | spinlock_t lock; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static unsigned long hypervisor_get_time(void) | 15 | static unsigned long hypervisor_get_time(void) |
| 26 | { | 16 | { |
| 27 | unsigned long ret, time; | 17 | unsigned long ret, time; |
| @@ -45,15 +35,7 @@ retry: | |||
| 45 | 35 | ||
| 46 | static int sun4v_read_time(struct device *dev, struct rtc_time *tm) | 36 | static int sun4v_read_time(struct device *dev, struct rtc_time *tm) |
| 47 | { | 37 | { |
| 48 | struct sun4v_rtc *p = dev_get_drvdata(dev); | 38 | rtc_time_to_tm(hypervisor_get_time(), tm); |
| 49 | unsigned long flags, secs; | ||
| 50 | |||
| 51 | spin_lock_irqsave(&p->lock, flags); | ||
| 52 | secs = hypervisor_get_time(); | ||
| 53 | spin_unlock_irqrestore(&p->lock, flags); | ||
| 54 | |||
| 55 | rtc_time_to_tm(secs, tm); | ||
| 56 | |||
| 57 | return 0; | 39 | return 0; |
| 58 | } | 40 | } |
| 59 | 41 | ||
| @@ -80,19 +62,14 @@ retry: | |||
| 80 | 62 | ||
| 81 | static int sun4v_set_time(struct device *dev, struct rtc_time *tm) | 63 | static int sun4v_set_time(struct device *dev, struct rtc_time *tm) |
| 82 | { | 64 | { |
| 83 | struct sun4v_rtc *p = dev_get_drvdata(dev); | 65 | unsigned long secs; |
| 84 | unsigned long flags, secs; | ||
| 85 | int err; | 66 | int err; |
| 86 | 67 | ||
| 87 | err = rtc_tm_to_time(tm, &secs); | 68 | err = rtc_tm_to_time(tm, &secs); |
| 88 | if (err) | 69 | if (err) |
| 89 | return err; | 70 | return err; |
| 90 | 71 | ||
| 91 | spin_lock_irqsave(&p->lock, flags); | 72 | return hypervisor_set_time(secs); |
| 92 | err = hypervisor_set_time(secs); | ||
| 93 | spin_unlock_irqrestore(&p->lock, flags); | ||
| 94 | |||
| 95 | return err; | ||
| 96 | } | 73 | } |
| 97 | 74 | ||
| 98 | static const struct rtc_class_ops sun4v_rtc_ops = { | 75 | static const struct rtc_class_ops sun4v_rtc_ops = { |
| @@ -100,33 +77,22 @@ static const struct rtc_class_ops sun4v_rtc_ops = { | |||
| 100 | .set_time = sun4v_set_time, | 77 | .set_time = sun4v_set_time, |
| 101 | }; | 78 | }; |
| 102 | 79 | ||
| 103 | static int __devinit sun4v_rtc_probe(struct platform_device *pdev) | 80 | static int __init sun4v_rtc_probe(struct platform_device *pdev) |
| 104 | { | 81 | { |
| 105 | struct sun4v_rtc *p = kzalloc(sizeof(*p), GFP_KERNEL); | 82 | struct rtc_device *rtc = rtc_device_register("sun4v", &pdev->dev, |
| 106 | |||
| 107 | if (!p) | ||
| 108 | return -ENOMEM; | ||
| 109 | |||
| 110 | spin_lock_init(&p->lock); | ||
| 111 | |||
| 112 | p->rtc = rtc_device_register("sun4v", &pdev->dev, | ||
| 113 | &sun4v_rtc_ops, THIS_MODULE); | 83 | &sun4v_rtc_ops, THIS_MODULE); |
| 114 | if (IS_ERR(p->rtc)) { | 84 | if (IS_ERR(rtc)) |
| 115 | int err = PTR_ERR(p->rtc); | 85 | return PTR_ERR(rtc); |
| 116 | kfree(p); | 86 | |
| 117 | return err; | 87 | platform_set_drvdata(pdev, rtc); |
| 118 | } | ||
| 119 | platform_set_drvdata(pdev, p); | ||
| 120 | return 0; | 88 | return 0; |
| 121 | } | 89 | } |
| 122 | 90 | ||
| 123 | static int __devexit sun4v_rtc_remove(struct platform_device *pdev) | 91 | static int __exit sun4v_rtc_remove(struct platform_device *pdev) |
| 124 | { | 92 | { |
| 125 | struct sun4v_rtc *p = platform_get_drvdata(pdev); | 93 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
| 126 | |||
| 127 | rtc_device_unregister(p->rtc); | ||
| 128 | kfree(p); | ||
| 129 | 94 | ||
| 95 | rtc_device_unregister(rtc); | ||
| 130 | return 0; | 96 | return 0; |
| 131 | } | 97 | } |
| 132 | 98 | ||
| @@ -135,13 +101,12 @@ static struct platform_driver sun4v_rtc_driver = { | |||
| 135 | .name = "rtc-sun4v", | 101 | .name = "rtc-sun4v", |
| 136 | .owner = THIS_MODULE, | 102 | .owner = THIS_MODULE, |
| 137 | }, | 103 | }, |
| 138 | .probe = sun4v_rtc_probe, | 104 | .remove = __exit_p(sun4v_rtc_remove), |
| 139 | .remove = __devexit_p(sun4v_rtc_remove), | ||
| 140 | }; | 105 | }; |
| 141 | 106 | ||
| 142 | static int __init sun4v_rtc_init(void) | 107 | static int __init sun4v_rtc_init(void) |
| 143 | { | 108 | { |
| 144 | return platform_driver_register(&sun4v_rtc_driver); | 109 | return platform_driver_probe(&sun4v_rtc_driver, sun4v_rtc_probe); |
| 145 | } | 110 | } |
| 146 | 111 | ||
| 147 | static void __exit sun4v_rtc_exit(void) | 112 | static void __exit sun4v_rtc_exit(void) |
| @@ -151,3 +116,7 @@ static void __exit sun4v_rtc_exit(void) | |||
| 151 | 116 | ||
| 152 | module_init(sun4v_rtc_init); | 117 | module_init(sun4v_rtc_init); |
| 153 | module_exit(sun4v_rtc_exit); | 118 | module_exit(sun4v_rtc_exit); |
| 119 | |||
| 120 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); | ||
| 121 | MODULE_DESCRIPTION("SUN4V RTC driver"); | ||
| 122 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index abe87a4d2665..01d8da9afdc8 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c | |||
| @@ -337,7 +337,7 @@ static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | #else | 339 | #else |
| 340 | #define omap_rtc_ioctl NULL | 340 | #define twl4030_rtc_ioctl NULL |
| 341 | #endif | 341 | #endif |
| 342 | 342 | ||
| 343 | static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) | 343 | static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) |
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c new file mode 100644 index 000000000000..5c5e3aa91385 --- /dev/null +++ b/drivers/rtc/rtc-wm8350.c | |||
| @@ -0,0 +1,514 @@ | |||
| 1 | /* | ||
| 2 | * Real Time Clock driver for Wolfson Microelectronics WM8350 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. | ||
| 5 | * | ||
| 6 | * Author: Liam Girdwood | ||
| 7 | * linux@wolfsonmicro.com | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 12 | * option) any later version. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/time.h> | ||
| 19 | #include <linux/rtc.h> | ||
| 20 | #include <linux/bcd.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/ioctl.h> | ||
| 23 | #include <linux/completion.h> | ||
| 24 | #include <linux/mfd/wm8350/rtc.h> | ||
| 25 | #include <linux/mfd/wm8350/core.h> | ||
| 26 | #include <linux/delay.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | |||
| 29 | #define WM8350_SET_ALM_RETRIES 5 | ||
| 30 | #define WM8350_SET_TIME_RETRIES 5 | ||
| 31 | #define WM8350_GET_TIME_RETRIES 5 | ||
| 32 | |||
| 33 | #define to_wm8350_from_rtc_dev(d) container_of(d, struct wm8350, rtc.pdev.dev) | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Read current time and date in RTC | ||
| 37 | */ | ||
| 38 | static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
| 39 | { | ||
| 40 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
| 41 | u16 time1[4], time2[4]; | ||
| 42 | int retries = WM8350_GET_TIME_RETRIES, ret; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Read the time twice and compare. | ||
| 46 | * If time1 == time2, then time is valid else retry. | ||
| 47 | */ | ||
| 48 | do { | ||
| 49 | ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES, | ||
| 50 | 4, time1); | ||
| 51 | if (ret < 0) | ||
| 52 | return ret; | ||
| 53 | ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES, | ||
| 54 | 4, time2); | ||
| 55 | if (ret < 0) | ||
| 56 | return ret; | ||
| 57 | |||
| 58 | if (memcmp(time1, time2, sizeof(time1)) == 0) { | ||
| 59 | tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK; | ||
| 60 | |||
| 61 | tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK) | ||
| 62 | >> WM8350_RTC_MINS_SHIFT; | ||
| 63 | |||
| 64 | tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK; | ||
| 65 | |||
| 66 | tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT) | ||
| 67 | & 0x7) - 1; | ||
| 68 | |||
| 69 | tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK) | ||
| 70 | >> WM8350_RTC_MTH_SHIFT) - 1; | ||
| 71 | |||
| 72 | tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK); | ||
| 73 | |||
| 74 | tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK) | ||
| 75 | >> WM8350_RTC_YHUNDREDS_SHIFT) * 100; | ||
| 76 | tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK; | ||
| 77 | |||
| 78 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, | ||
| 79 | tm->tm_year); | ||
| 80 | tm->tm_year -= 1900; | ||
| 81 | |||
| 82 | dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n", | ||
| 83 | retries, | ||
| 84 | time1[0], time1[1], time1[2], time1[3]); | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | } while (retries--); | ||
| 89 | |||
| 90 | dev_err(dev, "timed out reading RTC time\n"); | ||
| 91 | return -EIO; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Set current time and date in RTC | ||
| 96 | */ | ||
| 97 | static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
| 98 | { | ||
| 99 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
| 100 | u16 time[4]; | ||
| 101 | u16 rtc_ctrl; | ||
| 102 | int ret, retries = WM8350_SET_TIME_RETRIES; | ||
| 103 | |||
| 104 | time[0] = tm->tm_sec; | ||
| 105 | time[0] |= tm->tm_min << WM8350_RTC_MINS_SHIFT; | ||
| 106 | time[1] = tm->tm_hour; | ||
| 107 | time[1] |= (tm->tm_wday + 1) << WM8350_RTC_DAY_SHIFT; | ||
| 108 | time[2] = tm->tm_mday; | ||
| 109 | time[2] |= (tm->tm_mon + 1) << WM8350_RTC_MTH_SHIFT; | ||
| 110 | time[3] = ((tm->tm_year + 1900) / 100) << WM8350_RTC_YHUNDREDS_SHIFT; | ||
| 111 | time[3] |= (tm->tm_year + 1900) % 100; | ||
| 112 | |||
| 113 | dev_dbg(dev, "Setting: %04x %04x %04x %04x\n", | ||
| 114 | time[0], time[1], time[2], time[3]); | ||
| 115 | |||
| 116 | /* Set RTC_SET to stop the clock */ | ||
| 117 | ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET); | ||
| 118 | if (ret < 0) | ||
| 119 | return ret; | ||
| 120 | |||
| 121 | /* Wait until confirmation of stopping */ | ||
| 122 | do { | ||
| 123 | rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
| 124 | schedule_timeout_uninterruptible(msecs_to_jiffies(1)); | ||
| 125 | } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS)); | ||
| 126 | |||
| 127 | if (!retries) { | ||
| 128 | dev_err(dev, "timed out on set confirmation\n"); | ||
| 129 | return -EIO; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Write time to RTC */ | ||
| 133 | ret = wm8350_block_write(wm8350, WM8350_RTC_SECONDS_MINUTES, 4, time); | ||
| 134 | if (ret < 0) | ||
| 135 | return ret; | ||
| 136 | |||
| 137 | /* Clear RTC_SET to start the clock */ | ||
| 138 | ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
| 139 | WM8350_RTC_SET); | ||
| 140 | return ret; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Read alarm time and date in RTC | ||
| 145 | */ | ||
| 146 | static int wm8350_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 147 | { | ||
| 148 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
| 149 | struct rtc_time *tm = &alrm->time; | ||
| 150 | u16 time[4]; | ||
| 151 | int ret; | ||
| 152 | |||
| 153 | ret = wm8350_block_read(wm8350, WM8350_ALARM_SECONDS_MINUTES, 4, time); | ||
| 154 | if (ret < 0) | ||
| 155 | return ret; | ||
| 156 | |||
| 157 | tm->tm_sec = time[0] & WM8350_RTC_ALMSECS_MASK; | ||
| 158 | if (tm->tm_sec == WM8350_RTC_ALMSECS_MASK) | ||
| 159 | tm->tm_sec = -1; | ||
| 160 | |||
| 161 | tm->tm_min = time[0] & WM8350_RTC_ALMMINS_MASK; | ||
| 162 | if (tm->tm_min == WM8350_RTC_ALMMINS_MASK) | ||
| 163 | tm->tm_min = -1; | ||
| 164 | else | ||
| 165 | tm->tm_min >>= WM8350_RTC_ALMMINS_SHIFT; | ||
| 166 | |||
| 167 | tm->tm_hour = time[1] & WM8350_RTC_ALMHRS_MASK; | ||
| 168 | if (tm->tm_hour == WM8350_RTC_ALMHRS_MASK) | ||
| 169 | tm->tm_hour = -1; | ||
| 170 | |||
| 171 | tm->tm_wday = ((time[1] >> WM8350_RTC_ALMDAY_SHIFT) & 0x7) - 1; | ||
| 172 | if (tm->tm_wday > 7) | ||
| 173 | tm->tm_wday = -1; | ||
| 174 | |||
| 175 | tm->tm_mon = time[2] & WM8350_RTC_ALMMTH_MASK; | ||
| 176 | if (tm->tm_mon == WM8350_RTC_ALMMTH_MASK) | ||
| 177 | tm->tm_mon = -1; | ||
| 178 | else | ||
| 179 | tm->tm_mon = (tm->tm_mon >> WM8350_RTC_ALMMTH_SHIFT) - 1; | ||
| 180 | |||
| 181 | tm->tm_mday = (time[2] & WM8350_RTC_ALMDATE_MASK); | ||
| 182 | if (tm->tm_mday == WM8350_RTC_ALMDATE_MASK) | ||
| 183 | tm->tm_mday = -1; | ||
| 184 | |||
| 185 | tm->tm_year = -1; | ||
| 186 | |||
| 187 | alrm->enabled = !(time[3] & WM8350_RTC_ALMSTS); | ||
| 188 | |||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350) | ||
| 193 | { | ||
| 194 | int retries = WM8350_SET_ALM_RETRIES; | ||
| 195 | u16 rtc_ctrl; | ||
| 196 | int ret; | ||
| 197 | |||
| 198 | /* Set RTC_SET to stop the clock */ | ||
| 199 | ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
| 200 | WM8350_RTC_ALMSET); | ||
| 201 | if (ret < 0) | ||
| 202 | return ret; | ||
| 203 | |||
| 204 | /* Wait until confirmation of stopping */ | ||
| 205 | do { | ||
| 206 | rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
| 207 | schedule_timeout_uninterruptible(msecs_to_jiffies(1)); | ||
| 208 | } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS)); | ||
| 209 | |||
| 210 | if (!(rtc_ctrl & WM8350_RTC_ALMSTS)) | ||
| 211 | return -ETIMEDOUT; | ||
| 212 | |||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int wm8350_rtc_start_alarm(struct wm8350 *wm8350) | ||
| 217 | { | ||
| 218 | int ret; | ||
| 219 | int retries = WM8350_SET_ALM_RETRIES; | ||
| 220 | u16 rtc_ctrl; | ||
| 221 | |||
| 222 | ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
| 223 | WM8350_RTC_ALMSET); | ||
| 224 | if (ret < 0) | ||
| 225 | return ret; | ||
| 226 | |||
| 227 | /* Wait until confirmation */ | ||
| 228 | do { | ||
| 229 | rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
| 230 | schedule_timeout_uninterruptible(msecs_to_jiffies(1)); | ||
| 231 | } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS); | ||
| 232 | |||
| 233 | if (rtc_ctrl & WM8350_RTC_ALMSTS) | ||
| 234 | return -ETIMEDOUT; | ||
| 235 | |||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
| 240 | { | ||
| 241 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
| 242 | struct rtc_time *tm = &alrm->time; | ||
| 243 | u16 time[3]; | ||
| 244 | int ret; | ||
| 245 | |||
| 246 | memset(time, 0, sizeof(time)); | ||
| 247 | |||
| 248 | if (tm->tm_sec != -1) | ||
| 249 | time[0] |= tm->tm_sec; | ||
| 250 | else | ||
| 251 | time[0] |= WM8350_RTC_ALMSECS_MASK; | ||
| 252 | |||
| 253 | if (tm->tm_min != -1) | ||
| 254 | time[0] |= tm->tm_min << WM8350_RTC_ALMMINS_SHIFT; | ||
| 255 | else | ||
| 256 | time[0] |= WM8350_RTC_ALMMINS_MASK; | ||
| 257 | |||
| 258 | if (tm->tm_hour != -1) | ||
| 259 | time[1] |= tm->tm_hour; | ||
| 260 | else | ||
| 261 | time[1] |= WM8350_RTC_ALMHRS_MASK; | ||
| 262 | |||
| 263 | if (tm->tm_wday != -1) | ||
| 264 | time[1] |= (tm->tm_wday + 1) << WM8350_RTC_ALMDAY_SHIFT; | ||
| 265 | else | ||
| 266 | time[1] |= WM8350_RTC_ALMDAY_MASK; | ||
| 267 | |||
| 268 | if (tm->tm_mday != -1) | ||
| 269 | time[2] |= tm->tm_mday; | ||
| 270 | else | ||
| 271 | time[2] |= WM8350_RTC_ALMDATE_MASK; | ||
| 272 | |||
| 273 | if (tm->tm_mon != -1) | ||
| 274 | time[2] |= (tm->tm_mon + 1) << WM8350_RTC_ALMMTH_SHIFT; | ||
| 275 | else | ||
| 276 | time[2] |= WM8350_RTC_ALMMTH_MASK; | ||
| 277 | |||
| 278 | ret = wm8350_rtc_stop_alarm(wm8350); | ||
| 279 | if (ret < 0) | ||
| 280 | return ret; | ||
| 281 | |||
| 282 | /* Write time to RTC */ | ||
| 283 | ret = wm8350_block_write(wm8350, WM8350_ALARM_SECONDS_MINUTES, | ||
| 284 | 3, time); | ||
| 285 | if (ret < 0) | ||
| 286 | return ret; | ||
| 287 | |||
| 288 | if (alrm->enabled) | ||
| 289 | ret = wm8350_rtc_start_alarm(wm8350); | ||
| 290 | |||
| 291 | return ret; | ||
| 292 | } | ||
| 293 | |||
| 294 | /* | ||
| 295 | * Handle commands from user-space | ||
| 296 | */ | ||
| 297 | static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
| 298 | unsigned long arg) | ||
| 299 | { | ||
| 300 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
| 301 | |||
| 302 | switch (cmd) { | ||
| 303 | case RTC_AIE_OFF: | ||
| 304 | return wm8350_rtc_stop_alarm(wm8350); | ||
| 305 | case RTC_AIE_ON: | ||
| 306 | return wm8350_rtc_start_alarm(wm8350); | ||
| 307 | |||
| 308 | case RTC_UIE_OFF: | ||
| 309 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
| 310 | break; | ||
| 311 | case RTC_UIE_ON: | ||
| 312 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
| 313 | break; | ||
| 314 | |||
| 315 | default: | ||
| 316 | return -ENOIOCTLCMD; | ||
| 317 | } | ||
| 318 | |||
| 319 | return 0; | ||
| 320 | } | ||
| 321 | |||
| 322 | static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq, | ||
| 323 | void *data) | ||
| 324 | { | ||
| 325 | struct rtc_device *rtc = wm8350->rtc.rtc; | ||
| 326 | int ret; | ||
| 327 | |||
| 328 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); | ||
| 329 | |||
| 330 | /* Make it one shot */ | ||
| 331 | ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
| 332 | WM8350_RTC_ALMSET); | ||
| 333 | if (ret != 0) { | ||
| 334 | dev_err(&(wm8350->rtc.pdev->dev), | ||
| 335 | "Failed to disable alarm: %d\n", ret); | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq, | ||
| 340 | void *data) | ||
| 341 | { | ||
| 342 | struct rtc_device *rtc = wm8350->rtc.rtc; | ||
| 343 | |||
| 344 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF); | ||
| 345 | } | ||
| 346 | |||
| 347 | static const struct rtc_class_ops wm8350_rtc_ops = { | ||
| 348 | .ioctl = wm8350_rtc_ioctl, | ||
| 349 | .read_time = wm8350_rtc_readtime, | ||
| 350 | .set_time = wm8350_rtc_settime, | ||
| 351 | .read_alarm = wm8350_rtc_readalarm, | ||
| 352 | .set_alarm = wm8350_rtc_setalarm, | ||
| 353 | }; | ||
| 354 | |||
| 355 | #ifdef CONFIG_PM | ||
| 356 | static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 357 | { | ||
| 358 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); | ||
| 359 | int ret = 0; | ||
| 360 | u16 reg; | ||
| 361 | |||
| 362 | reg = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
| 363 | |||
| 364 | if (device_may_wakeup(&wm8350->rtc.pdev->dev) && | ||
| 365 | reg & WM8350_RTC_ALMSTS) { | ||
| 366 | ret = wm8350_rtc_stop_alarm(wm8350); | ||
| 367 | if (ret != 0) | ||
| 368 | dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", | ||
| 369 | ret); | ||
| 370 | } | ||
| 371 | |||
| 372 | return ret; | ||
| 373 | } | ||
| 374 | |||
| 375 | static int wm8350_rtc_resume(struct platform_device *pdev) | ||
| 376 | { | ||
| 377 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); | ||
| 378 | int ret; | ||
| 379 | |||
| 380 | if (wm8350->rtc.alarm_enabled) { | ||
| 381 | ret = wm8350_rtc_start_alarm(wm8350); | ||
| 382 | if (ret != 0) | ||
| 383 | dev_err(&pdev->dev, | ||
| 384 | "Failed to restart RTC alarm: %d\n", ret); | ||
| 385 | } | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | #else | ||
| 391 | #define wm8350_rtc_suspend NULL | ||
| 392 | #define wm8350_rtc_resume NULL | ||
| 393 | #endif | ||
| 394 | |||
| 395 | static int wm8350_rtc_probe(struct platform_device *pdev) | ||
| 396 | { | ||
| 397 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
| 398 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; | ||
| 399 | int ret = 0; | ||
| 400 | u16 timectl, power5; | ||
| 401 | |||
| 402 | timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
| 403 | if (timectl & WM8350_RTC_BCD) { | ||
| 404 | dev_err(&pdev->dev, "RTC BCD mode not supported\n"); | ||
| 405 | return -EINVAL; | ||
| 406 | } | ||
| 407 | if (timectl & WM8350_RTC_12HR) { | ||
| 408 | dev_err(&pdev->dev, "RTC 12 hour mode not supported\n"); | ||
| 409 | return -EINVAL; | ||
| 410 | } | ||
| 411 | |||
| 412 | /* enable the RTC if it's not already enabled */ | ||
| 413 | power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); | ||
| 414 | if (!(power5 & WM8350_RTC_TICK_ENA)) { | ||
| 415 | dev_info(wm8350->dev, "Starting RTC\n"); | ||
| 416 | |||
| 417 | wm8350_reg_unlock(wm8350); | ||
| 418 | |||
| 419 | ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, | ||
| 420 | WM8350_RTC_TICK_ENA); | ||
| 421 | if (ret < 0) { | ||
| 422 | dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret); | ||
| 423 | return ret; | ||
| 424 | } | ||
| 425 | |||
| 426 | wm8350_reg_lock(wm8350); | ||
| 427 | } | ||
| 428 | |||
| 429 | if (timectl & WM8350_RTC_STS) { | ||
| 430 | int retries; | ||
| 431 | |||
| 432 | ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
| 433 | WM8350_RTC_SET); | ||
| 434 | if (ret < 0) { | ||
| 435 | dev_err(&pdev->dev, "failed to start: %d\n", ret); | ||
| 436 | return ret; | ||
| 437 | } | ||
| 438 | |||
| 439 | retries = WM8350_SET_TIME_RETRIES; | ||
| 440 | do { | ||
| 441 | timectl = wm8350_reg_read(wm8350, | ||
| 442 | WM8350_RTC_TIME_CONTROL); | ||
| 443 | } while (timectl & WM8350_RTC_STS && retries--); | ||
| 444 | |||
| 445 | if (retries == 0) { | ||
| 446 | dev_err(&pdev->dev, "failed to start: timeout\n"); | ||
| 447 | return -ENODEV; | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 | device_init_wakeup(&pdev->dev, 1); | ||
| 452 | |||
| 453 | wm_rtc->rtc = rtc_device_register("wm8350", &pdev->dev, | ||
| 454 | &wm8350_rtc_ops, THIS_MODULE); | ||
| 455 | if (IS_ERR(wm_rtc->rtc)) { | ||
| 456 | ret = PTR_ERR(wm_rtc->rtc); | ||
| 457 | dev_err(&pdev->dev, "failed to register RTC: %d\n", ret); | ||
| 458 | return ret; | ||
| 459 | } | ||
| 460 | |||
| 461 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
| 462 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_PER); | ||
| 463 | |||
| 464 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, | ||
| 465 | wm8350_rtc_update_handler, NULL); | ||
| 466 | |||
| 467 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, | ||
| 468 | wm8350_rtc_alarm_handler, NULL); | ||
| 469 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM); | ||
| 470 | |||
| 471 | return 0; | ||
| 472 | } | ||
| 473 | |||
| 474 | static int __devexit wm8350_rtc_remove(struct platform_device *pdev) | ||
| 475 | { | ||
| 476 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
| 477 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; | ||
| 478 | |||
| 479 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
| 480 | |||
| 481 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
| 482 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM); | ||
| 483 | |||
| 484 | rtc_device_unregister(wm_rtc->rtc); | ||
| 485 | |||
| 486 | return 0; | ||
| 487 | } | ||
| 488 | |||
| 489 | static struct platform_driver wm8350_rtc_driver = { | ||
| 490 | .probe = wm8350_rtc_probe, | ||
| 491 | .remove = __devexit_p(wm8350_rtc_remove), | ||
| 492 | .suspend = wm8350_rtc_suspend, | ||
| 493 | .resume = wm8350_rtc_resume, | ||
| 494 | .driver = { | ||
| 495 | .name = "wm8350-rtc", | ||
| 496 | }, | ||
| 497 | }; | ||
| 498 | |||
| 499 | static int __init wm8350_rtc_init(void) | ||
| 500 | { | ||
| 501 | return platform_driver_register(&wm8350_rtc_driver); | ||
| 502 | } | ||
| 503 | module_init(wm8350_rtc_init); | ||
| 504 | |||
| 505 | static void __exit wm8350_rtc_exit(void) | ||
| 506 | { | ||
| 507 | platform_driver_unregister(&wm8350_rtc_driver); | ||
| 508 | } | ||
| 509 | module_exit(wm8350_rtc_exit); | ||
| 510 | |||
| 511 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
| 512 | MODULE_DESCRIPTION("RTC driver for the WM8350"); | ||
| 513 | MODULE_LICENSE("GPL"); | ||
| 514 | MODULE_ALIAS("platform:wm8350-rtc"); | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4b76fca64a6f..363bd1303d21 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
| @@ -1746,6 +1746,11 @@ restart: | |||
| 1746 | goto restart; | 1746 | goto restart; |
| 1747 | } | 1747 | } |
| 1748 | 1748 | ||
| 1749 | /* log sense for fatal error */ | ||
| 1750 | if (cqr->status == DASD_CQR_FAILED) { | ||
| 1751 | dasd_log_sense(cqr, &cqr->irb); | ||
| 1752 | } | ||
| 1753 | |||
| 1749 | /* First of all call extended error reporting. */ | 1754 | /* First of all call extended error reporting. */ |
| 1750 | if (dasd_eer_enabled(base) && | 1755 | if (dasd_eer_enabled(base) && |
| 1751 | cqr->status == DASD_CQR_FAILED) { | 1756 | cqr->status == DASD_CQR_FAILED) { |
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index eb5f1b8bc57f..ec9c0bcf66ee 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
| @@ -324,6 +324,9 @@ static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) | |||
| 324 | case 0x0120: | 324 | case 0x0120: |
| 325 | break; | 325 | break; |
| 326 | default: | 326 | default: |
| 327 | pr_warning("assign storage failed (cmd=0x%08x, " | ||
| 328 | "response=0x%04x, rn=0x%04x)\n", cmd, | ||
| 329 | sccb->header.response_code, rn); | ||
| 327 | rc = -EIO; | 330 | rc = -EIO; |
| 328 | break; | 331 | break; |
| 329 | } | 332 | } |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 4e78c82194b4..4e4008325e28 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -874,11 +874,15 @@ void ccw_device_move_to_orphanage(struct work_struct *work) | |||
| 874 | replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); | 874 | replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); |
| 875 | if (replacing_cdev) { | 875 | if (replacing_cdev) { |
| 876 | sch_attach_disconnected_device(sch, replacing_cdev); | 876 | sch_attach_disconnected_device(sch, replacing_cdev); |
| 877 | /* Release reference from get_disc_ccwdev_by_dev_id() */ | ||
| 878 | put_device(&cdev->dev); | ||
| 877 | return; | 879 | return; |
| 878 | } | 880 | } |
| 879 | replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id); | 881 | replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id); |
| 880 | if (replacing_cdev) { | 882 | if (replacing_cdev) { |
| 881 | sch_attach_orphaned_device(sch, replacing_cdev); | 883 | sch_attach_orphaned_device(sch, replacing_cdev); |
| 884 | /* Release reference from get_orphaned_ccwdev_by_dev_id() */ | ||
| 885 | put_device(&cdev->dev); | ||
| 882 | return; | 886 | return; |
| 883 | } | 887 | } |
| 884 | sch_create_and_recog_new_device(sch); | 888 | sch_create_and_recog_new_device(sch); |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index ff4a6931bb8e..3d442444c618 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
| @@ -322,13 +322,13 @@ static int __init kvm_devices_init(void) | |||
| 322 | return rc; | 322 | return rc; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | rc = vmem_add_mapping(PFN_PHYS(max_pfn), PAGE_SIZE); | 325 | rc = vmem_add_mapping(real_memory_size, PAGE_SIZE); |
| 326 | if (rc) { | 326 | if (rc) { |
| 327 | s390_root_dev_unregister(kvm_root); | 327 | s390_root_dev_unregister(kvm_root); |
| 328 | return rc; | 328 | return rc; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | kvm_devices = (void *) PFN_PHYS(max_pfn); | 331 | kvm_devices = (void *) real_memory_size; |
| 332 | 332 | ||
| 333 | ctl_set_bit(0, 9); | 333 | ctl_set_bit(0, 9); |
| 334 | register_external_interrupt(0x2603, kvm_extint_handler); | 334 | register_external_interrupt(0x2603, kvm_extint_handler); |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 3b56220fb900..3d4e3e3f3fc0 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
| @@ -610,7 +610,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, | |||
| 610 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); | 610 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); |
| 611 | atomic_set(&port->refcount, 0); | 611 | atomic_set(&port->refcount, 0); |
| 612 | 612 | ||
| 613 | dev_set_name(&port->sysfs_device, "0x%016llx", wwpn); | 613 | dev_set_name(&port->sysfs_device, "0x%016llx", |
| 614 | (unsigned long long)wwpn); | ||
| 614 | port->sysfs_device.parent = &adapter->ccw_device->dev; | 615 | port->sysfs_device.parent = &adapter->ccw_device->dev; |
| 615 | 616 | ||
| 616 | port->sysfs_device.release = zfcp_sysfs_port_release; | 617 | port->sysfs_device.release = zfcp_sysfs_port_release; |
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index b04038c74786..951a8d409d1d 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
| @@ -116,7 +116,9 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device) | |||
| 116 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85, | 116 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85, |
| 117 | NULL); | 117 | NULL); |
| 118 | zfcp_erp_wait(adapter); | 118 | zfcp_erp_wait(adapter); |
| 119 | goto out; | 119 | up(&zfcp_data.config_sema); |
| 120 | flush_work(&adapter->scan_work); | ||
| 121 | return 0; | ||
| 120 | 122 | ||
| 121 | out_scsi_register: | 123 | out_scsi_register: |
| 122 | zfcp_erp_thread_kill(adapter); | 124 | zfcp_erp_thread_kill(adapter); |
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 060f5f2352ec..31012d58cfb7 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
| @@ -30,7 +30,7 @@ static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len, | |||
| 30 | dump->offset = offset; | 30 | dump->offset = offset; |
| 31 | dump->size = min(from_len - offset, room); | 31 | dump->size = min(from_len - offset, room); |
| 32 | memcpy(dump->data, from + offset, dump->size); | 32 | memcpy(dump->data, from + offset, dump->size); |
| 33 | debug_event(dbf, level, dump, dump->size); | 33 | debug_event(dbf, level, dump, dump->size + sizeof(*dump)); |
| 34 | } | 34 | } |
| 35 | } | 35 | } |
| 36 | 36 | ||
| @@ -108,7 +108,7 @@ static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view, | |||
| 108 | t.tv_sec, t.tv_nsec); | 108 | t.tv_sec, t.tv_nsec); |
| 109 | zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); | 109 | zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); |
| 110 | } else { | 110 | } else { |
| 111 | zfcp_dbf_outd(&p, NULL, dump->data, dump->size, dump->offset, | 111 | zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset, |
| 112 | dump->total_size); | 112 | dump->total_size); |
| 113 | if ((dump->offset + dump->size) == dump->total_size) | 113 | if ((dump->offset + dump->size) == dump->total_size) |
| 114 | p += sprintf(p, "\n"); | 114 | p += sprintf(p, "\n"); |
| @@ -366,6 +366,7 @@ static void zfcp_hba_dbf_view_response(char **p, | |||
| 366 | break; | 366 | break; |
| 367 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); | 367 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); |
| 368 | zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); | 368 | zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); |
| 369 | p += sprintf(*p, "\n"); | ||
| 369 | break; | 370 | break; |
| 370 | 371 | ||
| 371 | case FSF_QTCB_OPEN_PORT_WITH_DID: | 372 | case FSF_QTCB_OPEN_PORT_WITH_DID: |
| @@ -465,7 +466,8 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view, | |||
| 465 | else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0) | 466 | else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0) |
| 466 | zfcp_hba_dbf_view_berr(&p, &r->u.berr); | 467 | zfcp_hba_dbf_view_berr(&p, &r->u.berr); |
| 467 | 468 | ||
| 468 | p += sprintf(p, "\n"); | 469 | if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0) |
| 470 | p += sprintf(p, "\n"); | ||
| 469 | return p - out_buf; | 471 | return p - out_buf; |
| 470 | } | 472 | } |
| 471 | 473 | ||
| @@ -880,6 +882,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | |||
| 880 | struct ct_hdr *hdr = sg_virt(ct->req); | 882 | struct ct_hdr *hdr = sg_virt(ct->req); |
| 881 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | 883 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; |
| 882 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; | 884 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; |
| 885 | int level = 3; | ||
| 883 | unsigned long flags; | 886 | unsigned long flags; |
| 884 | 887 | ||
| 885 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); | 888 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); |
| @@ -896,9 +899,10 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | |||
| 896 | oct->options = hdr->options; | 899 | oct->options = hdr->options; |
| 897 | oct->max_res_size = hdr->max_res_size; | 900 | oct->max_res_size = hdr->max_res_size; |
| 898 | oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr), | 901 | oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr), |
| 899 | ZFCP_DBF_CT_PAYLOAD); | 902 | ZFCP_DBF_SAN_MAX_PAYLOAD); |
| 900 | memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len); | 903 | debug_event(adapter->san_dbf, level, r, sizeof(*r)); |
| 901 | debug_event(adapter->san_dbf, 3, r, sizeof(*r)); | 904 | zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level, |
| 905 | (void *)hdr + sizeof(struct ct_hdr), oct->len); | ||
| 902 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | 906 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); |
| 903 | } | 907 | } |
| 904 | 908 | ||
| @@ -914,6 +918,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | |||
| 914 | struct ct_hdr *hdr = sg_virt(ct->resp); | 918 | struct ct_hdr *hdr = sg_virt(ct->resp); |
| 915 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | 919 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; |
| 916 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; | 920 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; |
| 921 | int level = 3; | ||
| 917 | unsigned long flags; | 922 | unsigned long flags; |
| 918 | 923 | ||
| 919 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); | 924 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); |
| @@ -929,9 +934,10 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | |||
| 929 | rct->expl = hdr->reason_code_expl; | 934 | rct->expl = hdr->reason_code_expl; |
| 930 | rct->vendor_unique = hdr->vendor_unique; | 935 | rct->vendor_unique = hdr->vendor_unique; |
| 931 | rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr), | 936 | rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr), |
| 932 | ZFCP_DBF_CT_PAYLOAD); | 937 | ZFCP_DBF_SAN_MAX_PAYLOAD); |
| 933 | memcpy(rct->payload, (void *)hdr + sizeof(struct ct_hdr), rct->len); | 938 | debug_event(adapter->san_dbf, level, r, sizeof(*r)); |
| 934 | debug_event(adapter->san_dbf, 3, r, sizeof(*r)); | 939 | zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level, |
| 940 | (void *)hdr + sizeof(struct ct_hdr), rct->len); | ||
| 935 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | 941 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); |
| 936 | } | 942 | } |
| 937 | 943 | ||
| @@ -954,7 +960,7 @@ static void zfcp_san_dbf_event_els(const char *tag, int level, | |||
| 954 | rec->u.els.ls_code = ls_code; | 960 | rec->u.els.ls_code = ls_code; |
| 955 | debug_event(adapter->san_dbf, level, rec, sizeof(*rec)); | 961 | debug_event(adapter->san_dbf, level, rec, sizeof(*rec)); |
| 956 | zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level, | 962 | zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level, |
| 957 | buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD)); | 963 | buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD)); |
| 958 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | 964 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); |
| 959 | } | 965 | } |
| 960 | 966 | ||
| @@ -1008,8 +1014,6 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view, | |||
| 1008 | char *out_buf, const char *in_buf) | 1014 | char *out_buf, const char *in_buf) |
| 1009 | { | 1015 | { |
| 1010 | struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf; | 1016 | struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf; |
| 1011 | char *buffer = NULL; | ||
| 1012 | int buflen = 0, total = 0; | ||
| 1013 | char *p = out_buf; | 1017 | char *p = out_buf; |
| 1014 | 1018 | ||
| 1015 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | 1019 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) |
| @@ -1029,9 +1033,6 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view, | |||
| 1029 | zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype); | 1033 | zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype); |
| 1030 | zfcp_dbf_out(&p, "options", "0x%02x", ct->options); | 1034 | zfcp_dbf_out(&p, "options", "0x%02x", ct->options); |
| 1031 | zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size); | 1035 | zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size); |
| 1032 | total = ct->len; | ||
| 1033 | buffer = ct->payload; | ||
| 1034 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); | ||
| 1035 | } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { | 1036 | } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { |
| 1036 | struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp; | 1037 | struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp; |
| 1037 | zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code); | 1038 | zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code); |
| @@ -1039,23 +1040,12 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view, | |||
| 1039 | zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code); | 1040 | zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code); |
| 1040 | zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl); | 1041 | zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl); |
| 1041 | zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique); | 1042 | zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique); |
| 1042 | total = ct->len; | ||
| 1043 | buffer = ct->payload; | ||
| 1044 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); | ||
| 1045 | } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || | 1043 | } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || |
| 1046 | strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || | 1044 | strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || |
| 1047 | strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { | 1045 | strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { |
| 1048 | struct zfcp_san_dbf_record_els *els = &r->u.els; | 1046 | struct zfcp_san_dbf_record_els *els = &r->u.els; |
| 1049 | zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code); | 1047 | zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code); |
| 1050 | total = els->len; | ||
| 1051 | buffer = els->payload; | ||
| 1052 | buflen = min(total, ZFCP_DBF_ELS_PAYLOAD); | ||
| 1053 | } | 1048 | } |
| 1054 | |||
| 1055 | zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total); | ||
| 1056 | if (buflen == total) | ||
| 1057 | p += sprintf(p, "\n"); | ||
| 1058 | |||
| 1059 | return p - out_buf; | 1049 | return p - out_buf; |
| 1060 | } | 1050 | } |
| 1061 | 1051 | ||
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index e8f450801fea..5d6b2dff855b 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h | |||
| @@ -163,8 +163,6 @@ struct zfcp_san_dbf_record_ct_request { | |||
| 163 | u8 options; | 163 | u8 options; |
| 164 | u16 max_res_size; | 164 | u16 max_res_size; |
| 165 | u32 len; | 165 | u32 len; |
| 166 | #define ZFCP_DBF_CT_PAYLOAD 24 | ||
| 167 | u8 payload[ZFCP_DBF_CT_PAYLOAD]; | ||
| 168 | } __attribute__ ((packed)); | 166 | } __attribute__ ((packed)); |
| 169 | 167 | ||
| 170 | struct zfcp_san_dbf_record_ct_response { | 168 | struct zfcp_san_dbf_record_ct_response { |
| @@ -174,15 +172,11 @@ struct zfcp_san_dbf_record_ct_response { | |||
| 174 | u8 expl; | 172 | u8 expl; |
| 175 | u8 vendor_unique; | 173 | u8 vendor_unique; |
| 176 | u32 len; | 174 | u32 len; |
| 177 | u8 payload[ZFCP_DBF_CT_PAYLOAD]; | ||
| 178 | } __attribute__ ((packed)); | 175 | } __attribute__ ((packed)); |
| 179 | 176 | ||
| 180 | struct zfcp_san_dbf_record_els { | 177 | struct zfcp_san_dbf_record_els { |
| 181 | u8 ls_code; | 178 | u8 ls_code; |
| 182 | u32 len; | 179 | u32 len; |
| 183 | #define ZFCP_DBF_ELS_PAYLOAD 32 | ||
| 184 | #define ZFCP_DBF_ELS_MAX_PAYLOAD 1024 | ||
| 185 | u8 payload[ZFCP_DBF_ELS_PAYLOAD]; | ||
| 186 | } __attribute__ ((packed)); | 180 | } __attribute__ ((packed)); |
| 187 | 181 | ||
| 188 | struct zfcp_san_dbf_record { | 182 | struct zfcp_san_dbf_record { |
| @@ -196,6 +190,8 @@ struct zfcp_san_dbf_record { | |||
| 196 | struct zfcp_san_dbf_record_ct_response ct_resp; | 190 | struct zfcp_san_dbf_record_ct_response ct_resp; |
| 197 | struct zfcp_san_dbf_record_els els; | 191 | struct zfcp_san_dbf_record_els els; |
| 198 | } u; | 192 | } u; |
| 193 | #define ZFCP_DBF_SAN_MAX_PAYLOAD 1024 | ||
| 194 | u8 payload[32]; | ||
| 199 | } __attribute__ ((packed)); | 195 | } __attribute__ ((packed)); |
| 200 | 196 | ||
| 201 | struct zfcp_scsi_dbf_record { | 197 | struct zfcp_scsi_dbf_record { |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 9040f738ff33..c557ba34e1aa 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
| @@ -472,6 +472,7 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act) | |||
| 472 | ZFCP_STATUS_ERP_TIMEDOUT)) { | 472 | ZFCP_STATUS_ERP_TIMEDOUT)) { |
| 473 | act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; | 473 | act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; |
| 474 | zfcp_rec_dbf_event_action(142, act); | 474 | zfcp_rec_dbf_event_action(142, act); |
| 475 | act->fsf_req->erp_action = NULL; | ||
| 475 | } | 476 | } |
| 476 | if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) | 477 | if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) |
| 477 | zfcp_rec_dbf_event_action(143, act); | 478 | zfcp_rec_dbf_event_action(143, act); |
| @@ -719,7 +720,6 @@ static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act, | |||
| 719 | goto failed_openfcp; | 720 | goto failed_openfcp; |
| 720 | 721 | ||
| 721 | atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &act->adapter->status); | 722 | atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &act->adapter->status); |
| 722 | schedule_work(&act->adapter->scan_work); | ||
| 723 | 723 | ||
| 724 | return ZFCP_ERP_SUCCEEDED; | 724 | return ZFCP_ERP_SUCCEEDED; |
| 725 | 725 | ||
| @@ -1185,7 +1185,9 @@ static void zfcp_erp_scsi_scan(struct work_struct *work) | |||
| 1185 | container_of(work, struct zfcp_erp_add_work, work); | 1185 | container_of(work, struct zfcp_erp_add_work, work); |
| 1186 | struct zfcp_unit *unit = p->unit; | 1186 | struct zfcp_unit *unit = p->unit; |
| 1187 | struct fc_rport *rport = unit->port->rport; | 1187 | struct fc_rport *rport = unit->port->rport; |
| 1188 | scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, | 1188 | |
| 1189 | if (rport && rport->port_state == FC_PORTSTATE_ONLINE) | ||
| 1190 | scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, | ||
| 1189 | scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0); | 1191 | scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0); |
| 1190 | atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | 1192 | atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); |
| 1191 | zfcp_unit_put(unit); | 1193 | zfcp_unit_put(unit); |
| @@ -1281,6 +1283,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | |||
| 1281 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 1283 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
| 1282 | if (result != ZFCP_ERP_SUCCEEDED) | 1284 | if (result != ZFCP_ERP_SUCCEEDED) |
| 1283 | zfcp_erp_rports_del(adapter); | 1285 | zfcp_erp_rports_del(adapter); |
| 1286 | else | ||
| 1287 | schedule_work(&adapter->scan_work); | ||
| 1284 | zfcp_adapter_put(adapter); | 1288 | zfcp_adapter_put(adapter); |
| 1285 | break; | 1289 | break; |
| 1286 | } | 1290 | } |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 1a7c80a77ff5..8aab3091a7b1 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
| @@ -50,7 +50,8 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) | |||
| 50 | if (mutex_lock_interruptible(&wka_port->mutex)) | 50 | if (mutex_lock_interruptible(&wka_port->mutex)) |
| 51 | return -ERESTARTSYS; | 51 | return -ERESTARTSYS; |
| 52 | 52 | ||
| 53 | if (wka_port->status != ZFCP_WKA_PORT_ONLINE) { | 53 | if (wka_port->status == ZFCP_WKA_PORT_OFFLINE || |
| 54 | wka_port->status == ZFCP_WKA_PORT_CLOSING) { | ||
| 54 | wka_port->status = ZFCP_WKA_PORT_OPENING; | 55 | wka_port->status = ZFCP_WKA_PORT_OPENING; |
| 55 | if (zfcp_fsf_open_wka_port(wka_port)) | 56 | if (zfcp_fsf_open_wka_port(wka_port)) |
| 56 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 57 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; |
| @@ -125,8 +126,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
| 125 | 126 | ||
| 126 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 127 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
| 127 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | 128 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { |
| 128 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ | 129 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_PHYS_OPEN)) |
| 129 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID)) | ||
| 130 | /* Try to connect to unused ports anyway. */ | 130 | /* Try to connect to unused ports anyway. */ |
| 131 | zfcp_erp_port_reopen(port, | 131 | zfcp_erp_port_reopen(port, |
| 132 | ZFCP_STATUS_COMMON_ERP_FAILED, | 132 | ZFCP_STATUS_COMMON_ERP_FAILED, |
| @@ -610,7 +610,6 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
| 610 | int ret, i; | 610 | int ret, i; |
| 611 | struct zfcp_gpn_ft *gpn_ft; | 611 | struct zfcp_gpn_ft *gpn_ft; |
| 612 | 612 | ||
| 613 | zfcp_erp_wait(adapter); /* wait until adapter is finished with ERP */ | ||
| 614 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) | 613 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) |
| 615 | return 0; | 614 | return 0; |
| 616 | 615 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 5ae1d497e5ed..dc0367690405 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -683,6 +683,7 @@ static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool) | |||
| 683 | if (!req) | 683 | if (!req) |
| 684 | return NULL; | 684 | return NULL; |
| 685 | memset(req, 0, sizeof(*req)); | 685 | memset(req, 0, sizeof(*req)); |
| 686 | req->pool = pool; | ||
| 686 | return req; | 687 | return req; |
| 687 | } | 688 | } |
| 688 | 689 | ||
| @@ -769,28 +770,24 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
| 769 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | 770 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) |
| 770 | { | 771 | { |
| 771 | struct zfcp_adapter *adapter = req->adapter; | 772 | struct zfcp_adapter *adapter = req->adapter; |
| 772 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 773 | unsigned long flags; |
| 773 | int idx; | 774 | int idx; |
| 774 | 775 | ||
| 775 | /* put allocated FSF request into hash table */ | 776 | /* put allocated FSF request into hash table */ |
| 776 | spin_lock(&adapter->req_list_lock); | 777 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
| 777 | idx = zfcp_reqlist_hash(req->req_id); | 778 | idx = zfcp_reqlist_hash(req->req_id); |
| 778 | list_add_tail(&req->list, &adapter->req_list[idx]); | 779 | list_add_tail(&req->list, &adapter->req_list[idx]); |
| 779 | spin_unlock(&adapter->req_list_lock); | 780 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
| 780 | 781 | ||
| 781 | req->qdio_outb_usage = atomic_read(&req_q->count); | 782 | req->qdio_outb_usage = atomic_read(&adapter->req_q.count); |
| 782 | req->issued = get_clock(); | 783 | req->issued = get_clock(); |
| 783 | if (zfcp_qdio_send(req)) { | 784 | if (zfcp_qdio_send(req)) { |
| 784 | /* Queues are down..... */ | ||
| 785 | del_timer(&req->timer); | 785 | del_timer(&req->timer); |
| 786 | spin_lock(&adapter->req_list_lock); | 786 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
| 787 | zfcp_reqlist_remove(adapter, req); | 787 | /* lookup request again, list might have changed */ |
| 788 | spin_unlock(&adapter->req_list_lock); | 788 | if (zfcp_reqlist_find_safe(adapter, req)) |
| 789 | /* undo changes in request queue made for this request */ | 789 | zfcp_reqlist_remove(adapter, req); |
| 790 | atomic_add(req->sbal_number, &req_q->count); | 790 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
| 791 | req_q->first -= req->sbal_number; | ||
| 792 | req_q->first += QDIO_MAX_BUFFERS_PER_Q; | ||
| 793 | req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ | ||
| 794 | zfcp_erp_adapter_reopen(adapter, 0, 116, req); | 791 | zfcp_erp_adapter_reopen(adapter, 0, 116, req); |
| 795 | return -EIO; | 792 | return -EIO; |
| 796 | } | 793 | } |
| @@ -933,8 +930,10 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
| 933 | goto out; | 930 | goto out; |
| 934 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | 931 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, |
| 935 | req_flags, adapter->pool.fsf_req_abort); | 932 | req_flags, adapter->pool.fsf_req_abort); |
| 936 | if (IS_ERR(req)) | 933 | if (IS_ERR(req)) { |
| 934 | req = NULL; | ||
| 937 | goto out; | 935 | goto out; |
| 936 | } | ||
| 938 | 937 | ||
| 939 | if (unlikely(!(atomic_read(&unit->status) & | 938 | if (unlikely(!(atomic_read(&unit->status) & |
| 940 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 939 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
| @@ -1587,6 +1586,7 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) | |||
| 1587 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 1586 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; |
| 1588 | break; | 1587 | break; |
| 1589 | case FSF_PORT_ALREADY_OPEN: | 1588 | case FSF_PORT_ALREADY_OPEN: |
| 1589 | break; | ||
| 1590 | case FSF_GOOD: | 1590 | case FSF_GOOD: |
| 1591 | wka_port->handle = header->port_handle; | 1591 | wka_port->handle = header->port_handle; |
| 1592 | wka_port->status = ZFCP_WKA_PORT_ONLINE; | 1592 | wka_port->status = ZFCP_WKA_PORT_ONLINE; |
| @@ -2116,18 +2116,21 @@ static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | |||
| 2116 | 2116 | ||
| 2117 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2117 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) |
| 2118 | { | 2118 | { |
| 2119 | struct scsi_cmnd *scpnt = req->data; | 2119 | struct scsi_cmnd *scpnt; |
| 2120 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 2120 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) |
| 2121 | &(req->qtcb->bottom.io.fcp_rsp); | 2121 | &(req->qtcb->bottom.io.fcp_rsp); |
| 2122 | u32 sns_len; | 2122 | u32 sns_len; |
| 2123 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; | 2123 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; |
| 2124 | unsigned long flags; | 2124 | unsigned long flags; |
| 2125 | 2125 | ||
| 2126 | if (unlikely(!scpnt)) | ||
| 2127 | return; | ||
| 2128 | |||
| 2129 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2126 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
| 2130 | 2127 | ||
| 2128 | scpnt = req->data; | ||
| 2129 | if (unlikely(!scpnt)) { | ||
| 2130 | read_unlock_irqrestore(&req->adapter->abort_lock, flags); | ||
| 2131 | return; | ||
| 2132 | } | ||
| 2133 | |||
| 2131 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { | 2134 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { |
| 2132 | set_host_byte(scpnt, DID_SOFT_ERROR); | 2135 | set_host_byte(scpnt, DID_SOFT_ERROR); |
| 2133 | set_driver_byte(scpnt, SUGGEST_RETRY); | 2136 | set_driver_byte(scpnt, SUGGEST_RETRY); |
| @@ -2445,8 +2448,10 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
| 2445 | goto out; | 2448 | goto out; |
| 2446 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | 2449 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, |
| 2447 | adapter->pool.fsf_req_scsi); | 2450 | adapter->pool.fsf_req_scsi); |
| 2448 | if (IS_ERR(req)) | 2451 | if (IS_ERR(req)) { |
| 2452 | req = NULL; | ||
| 2449 | goto out; | 2453 | goto out; |
| 2454 | } | ||
| 2450 | 2455 | ||
| 2451 | req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; | 2456 | req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; |
| 2452 | req->data = unit; | 2457 | req->data = unit; |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index ca8f85f3dad4..468c880f8b6d 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
| @@ -24,14 +24,10 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu) | |||
| 24 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | 24 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) |
| 25 | { | 25 | { |
| 26 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 26 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; |
| 27 | WARN_ON(!unit); | 27 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); |
| 28 | if (unit) { | 28 | unit->device = NULL; |
| 29 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | 29 | zfcp_erp_unit_failed(unit, 12, NULL); |
| 30 | sdpnt->hostdata = NULL; | 30 | zfcp_unit_put(unit); |
| 31 | unit->device = NULL; | ||
| 32 | zfcp_erp_unit_failed(unit, 12, NULL); | ||
| 33 | zfcp_unit_put(unit); | ||
| 34 | } | ||
| 35 | } | 31 | } |
| 36 | 32 | ||
| 37 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) | 33 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) |
| @@ -92,7 +88,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
| 92 | ret = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, 0, | 88 | ret = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, 0, |
| 93 | ZFCP_REQ_AUTO_CLEANUP); | 89 | ZFCP_REQ_AUTO_CLEANUP); |
| 94 | if (unlikely(ret == -EBUSY)) | 90 | if (unlikely(ret == -EBUSY)) |
| 95 | zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); | 91 | return SCSI_MLQUEUE_DEVICE_BUSY; |
| 96 | else if (unlikely(ret < 0)) | 92 | else if (unlikely(ret < 0)) |
| 97 | return SCSI_MLQUEUE_HOST_BUSY; | 93 | return SCSI_MLQUEUE_HOST_BUSY; |
| 98 | 94 | ||
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 2bec9ccc0293..a9a9893a5f95 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c | |||
| @@ -36,7 +36,6 @@ | |||
| 36 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
| 37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 38 | #include <linux/string.h> | 38 | #include <linux/string.h> |
| 39 | #include <linux/smp_lock.h> | ||
| 40 | #include <linux/genhd.h> | 39 | #include <linux/genhd.h> |
| 41 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
| 42 | 41 | ||
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 9aa301c1ed07..162cd927d94b 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
| @@ -427,8 +427,8 @@ static int aac_slave_configure(struct scsi_device *sdev) | |||
| 427 | * Firmware has an individual device recovery time typically | 427 | * Firmware has an individual device recovery time typically |
| 428 | * of 35 seconds, give us a margin. | 428 | * of 35 seconds, give us a margin. |
| 429 | */ | 429 | */ |
| 430 | if (sdev->timeout < (45 * HZ)) | 430 | if (sdev->request_queue->rq_timeout < (45 * HZ)) |
| 431 | sdev->timeout = 45 * HZ; | 431 | blk_queue_rq_timeout(sdev->request_queue, 45*HZ); |
| 432 | for (cid = 0; cid < aac->maximum_num_containers; ++cid) | 432 | for (cid = 0; cid < aac->maximum_num_containers; ++cid) |
| 433 | if (aac->fsa_dev[cid].valid) | 433 | if (aac->fsa_dev[cid].valid) |
| 434 | ++num_lsu; | 434 | ++num_lsu; |
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 218777bfc143..399fe559e4de 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
| @@ -13872,8 +13872,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
| 13872 | advansys_wide_free_mem(boardp); | 13872 | advansys_wide_free_mem(boardp); |
| 13873 | free_irq(boardp->irq, shost); | 13873 | free_irq(boardp->irq, shost); |
| 13874 | err_free_dma: | 13874 | err_free_dma: |
| 13875 | #ifdef CONFIG_ISA | ||
| 13875 | if (shost->dma_channel != NO_ISA_DMA) | 13876 | if (shost->dma_channel != NO_ISA_DMA) |
| 13876 | free_dma(shost->dma_channel); | 13877 | free_dma(shost->dma_channel); |
| 13878 | #endif | ||
| 13877 | err_free_proc: | 13879 | err_free_proc: |
| 13878 | kfree(boardp->prtbuf); | 13880 | kfree(boardp->prtbuf); |
| 13879 | err_unmap: | 13881 | err_unmap: |
| @@ -13894,10 +13896,12 @@ static int advansys_release(struct Scsi_Host *shost) | |||
| 13894 | ASC_DBG(1, "begin\n"); | 13896 | ASC_DBG(1, "begin\n"); |
| 13895 | scsi_remove_host(shost); | 13897 | scsi_remove_host(shost); |
| 13896 | free_irq(board->irq, shost); | 13898 | free_irq(board->irq, shost); |
| 13899 | #ifdef CONFIG_ISA | ||
| 13897 | if (shost->dma_channel != NO_ISA_DMA) { | 13900 | if (shost->dma_channel != NO_ISA_DMA) { |
| 13898 | ASC_DBG(1, "free_dma()\n"); | 13901 | ASC_DBG(1, "free_dma()\n"); |
| 13899 | free_dma(shost->dma_channel); | 13902 | free_dma(shost->dma_channel); |
| 13900 | } | 13903 | } |
| 13904 | #endif | ||
| 13901 | if (ASC_NARROW_BOARD(board)) { | 13905 | if (ASC_NARROW_BOARD(board)) { |
| 13902 | dma_unmap_single(board->dev, | 13906 | dma_unmap_single(board->dev, |
| 13903 | board->dvc_var.asc_dvc_var.overrun_dma, | 13907 | board->dvc_var.asc_dvc_var.overrun_dma, |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 8aba4fdfb522..6194ed5d02c4 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
| @@ -2445,7 +2445,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) | |||
| 2445 | hba_status = detailed_status >> 8; | 2445 | hba_status = detailed_status >> 8; |
| 2446 | 2446 | ||
| 2447 | // calculate resid for sg | 2447 | // calculate resid for sg |
| 2448 | scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5)); | 2448 | scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+20)); |
| 2449 | 2449 | ||
| 2450 | pHba = (adpt_hba*) cmd->device->host->hostdata[0]; | 2450 | pHba = (adpt_hba*) cmd->device->host->hostdata[0]; |
| 2451 | 2451 | ||
| @@ -2456,7 +2456,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) | |||
| 2456 | case I2O_SCSI_DSC_SUCCESS: | 2456 | case I2O_SCSI_DSC_SUCCESS: |
| 2457 | cmd->result = (DID_OK << 16); | 2457 | cmd->result = (DID_OK << 16); |
| 2458 | // handle underflow | 2458 | // handle underflow |
| 2459 | if(readl(reply+5) < cmd->underflow ) { | 2459 | if (readl(reply+20) < cmd->underflow) { |
| 2460 | cmd->result = (DID_ERROR <<16); | 2460 | cmd->result = (DID_ERROR <<16); |
| 2461 | printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name); | 2461 | printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name); |
| 2462 | } | 2462 | } |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index c387c15a2128..fb247fdfa2bd 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
| @@ -588,7 +588,7 @@ static struct pci_driver gdth_pci_driver = { | |||
| 588 | .remove = gdth_pci_remove_one, | 588 | .remove = gdth_pci_remove_one, |
| 589 | }; | 589 | }; |
| 590 | 590 | ||
| 591 | static void gdth_pci_remove_one(struct pci_dev *pdev) | 591 | static void __devexit gdth_pci_remove_one(struct pci_dev *pdev) |
| 592 | { | 592 | { |
| 593 | gdth_ha_str *ha = pci_get_drvdata(pdev); | 593 | gdth_ha_str *ha = pci_get_drvdata(pdev); |
| 594 | 594 | ||
| @@ -600,7 +600,7 @@ static void gdth_pci_remove_one(struct pci_dev *pdev) | |||
| 600 | pci_disable_device(pdev); | 600 | pci_disable_device(pdev); |
| 601 | } | 601 | } |
| 602 | 602 | ||
| 603 | static int gdth_pci_init_one(struct pci_dev *pdev, | 603 | static int __devinit gdth_pci_init_one(struct pci_dev *pdev, |
| 604 | const struct pci_device_id *ent) | 604 | const struct pci_device_id *ent) |
| 605 | { | 605 | { |
| 606 | ushort vendor = pdev->vendor; | 606 | ushort vendor = pdev->vendor; |
| @@ -853,7 +853,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
| 853 | #endif /* CONFIG_ISA */ | 853 | #endif /* CONFIG_ISA */ |
| 854 | 854 | ||
| 855 | #ifdef CONFIG_PCI | 855 | #ifdef CONFIG_PCI |
| 856 | static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr, | 856 | static int __devinit gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr, |
| 857 | gdth_ha_str *ha) | 857 | gdth_ha_str *ha) |
| 858 | { | 858 | { |
| 859 | register gdt6_dpram_str __iomem *dp6_ptr; | 859 | register gdt6_dpram_str __iomem *dp6_ptr; |
| @@ -1237,7 +1237,7 @@ static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr, | |||
| 1237 | 1237 | ||
| 1238 | /* controller protocol functions */ | 1238 | /* controller protocol functions */ |
| 1239 | 1239 | ||
| 1240 | static void __init gdth_enable_int(gdth_ha_str *ha) | 1240 | static void __devinit gdth_enable_int(gdth_ha_str *ha) |
| 1241 | { | 1241 | { |
| 1242 | ulong flags; | 1242 | ulong flags; |
| 1243 | gdt2_dpram_str __iomem *dp2_ptr; | 1243 | gdt2_dpram_str __iomem *dp2_ptr; |
| @@ -1553,7 +1553,7 @@ static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, | |||
| 1553 | 1553 | ||
| 1554 | /* search for devices */ | 1554 | /* search for devices */ |
| 1555 | 1555 | ||
| 1556 | static int __init gdth_search_drives(gdth_ha_str *ha) | 1556 | static int __devinit gdth_search_drives(gdth_ha_str *ha) |
| 1557 | { | 1557 | { |
| 1558 | ushort cdev_cnt, i; | 1558 | ushort cdev_cnt, i; |
| 1559 | int ok; | 1559 | int ok; |
| @@ -4935,7 +4935,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) | |||
| 4935 | #endif /* CONFIG_EISA */ | 4935 | #endif /* CONFIG_EISA */ |
| 4936 | 4936 | ||
| 4937 | #ifdef CONFIG_PCI | 4937 | #ifdef CONFIG_PCI |
| 4938 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, | 4938 | static int __devinit gdth_pci_probe_one(gdth_pci_str *pcistr, |
| 4939 | gdth_ha_str **ha_out) | 4939 | gdth_ha_str **ha_out) |
| 4940 | { | 4940 | { |
| 4941 | struct Scsi_Host *shp; | 4941 | struct Scsi_Host *shp; |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 87e09f35d3d4..6cad1758243a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
| @@ -1442,7 +1442,7 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev) | |||
| 1442 | spin_lock_irqsave(shost->host_lock, lock_flags); | 1442 | spin_lock_irqsave(shost->host_lock, lock_flags); |
| 1443 | if (sdev->type == TYPE_DISK) { | 1443 | if (sdev->type == TYPE_DISK) { |
| 1444 | sdev->allow_restart = 1; | 1444 | sdev->allow_restart = 1; |
| 1445 | sdev->timeout = 60 * HZ; | 1445 | blk_queue_rq_timeout(sdev->request_queue, 60 * HZ); |
| 1446 | } | 1446 | } |
| 1447 | scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); | 1447 | scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); |
| 1448 | spin_unlock_irqrestore(shost->host_lock, lock_flags); | 1448 | spin_unlock_irqrestore(shost->host_lock, lock_flags); |
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 28c9da7d4a5c..7dc62deb4087 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
| @@ -4402,6 +4402,10 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) | |||
| 4402 | scb_t *scb; | 4402 | scb_t *scb; |
| 4403 | int rval; | 4403 | int rval; |
| 4404 | 4404 | ||
| 4405 | scmd = scsi_allocate_command(GFP_KERNEL); | ||
| 4406 | if (!scmd) | ||
| 4407 | return -ENOMEM; | ||
| 4408 | |||
| 4405 | /* | 4409 | /* |
| 4406 | * The internal commands share one command id and hence are | 4410 | * The internal commands share one command id and hence are |
| 4407 | * serialized. This is so because we want to reserve maximum number of | 4411 | * serialized. This is so because we want to reserve maximum number of |
| @@ -4412,12 +4416,11 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) | |||
| 4412 | scb = &adapter->int_scb; | 4416 | scb = &adapter->int_scb; |
| 4413 | memset(scb, 0, sizeof(scb_t)); | 4417 | memset(scb, 0, sizeof(scb_t)); |
| 4414 | 4418 | ||
| 4415 | scmd = &adapter->int_scmd; | ||
| 4416 | memset(scmd, 0, sizeof(Scsi_Cmnd)); | ||
| 4417 | |||
| 4418 | sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); | 4419 | sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); |
| 4419 | scmd->device = sdev; | 4420 | scmd->device = sdev; |
| 4420 | 4421 | ||
| 4422 | memset(adapter->int_cdb, 0, sizeof(adapter->int_cdb)); | ||
| 4423 | scmd->cmnd = adapter->int_cdb; | ||
| 4421 | scmd->device->host = adapter->host; | 4424 | scmd->device->host = adapter->host; |
| 4422 | scmd->host_scribble = (void *)scb; | 4425 | scmd->host_scribble = (void *)scb; |
| 4423 | scmd->cmnd[0] = MEGA_INTERNAL_CMD; | 4426 | scmd->cmnd[0] = MEGA_INTERNAL_CMD; |
| @@ -4456,6 +4459,8 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) | |||
| 4456 | 4459 | ||
| 4457 | mutex_unlock(&adapter->int_mtx); | 4460 | mutex_unlock(&adapter->int_mtx); |
| 4458 | 4461 | ||
| 4462 | scsi_free_command(GFP_KERNEL, scmd); | ||
| 4463 | |||
| 4459 | return rval; | 4464 | return rval; |
| 4460 | } | 4465 | } |
| 4461 | 4466 | ||
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index ee70bd4ae4ba..795201fa0b48 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h | |||
| @@ -888,8 +888,8 @@ typedef struct { | |||
| 888 | 888 | ||
| 889 | u8 sglen; /* f/w supported scatter-gather list length */ | 889 | u8 sglen; /* f/w supported scatter-gather list length */ |
| 890 | 890 | ||
| 891 | unsigned char int_cdb[MAX_COMMAND_SIZE]; | ||
| 891 | scb_t int_scb; | 892 | scb_t int_scb; |
| 892 | Scsi_Cmnd int_scmd; | ||
| 893 | struct mutex int_mtx; /* To synchronize the internal | 893 | struct mutex int_mtx; /* To synchronize the internal |
| 894 | commands */ | 894 | commands */ |
| 895 | struct completion int_waitq; /* wait queue for internal | 895 | struct completion int_waitq; /* wait queue for internal |
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index afe1de998763..17ce7abe17ee 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
| @@ -1016,7 +1016,8 @@ static int megasas_slave_configure(struct scsi_device *sdev) | |||
| 1016 | * The RAID firmware may require extended timeouts. | 1016 | * The RAID firmware may require extended timeouts. |
| 1017 | */ | 1017 | */ |
| 1018 | if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) | 1018 | if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) |
| 1019 | sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ; | 1019 | blk_queue_rq_timeout(sdev->request_queue, |
| 1020 | MEGASAS_DEFAULT_CMD_TIMEOUT * HZ); | ||
| 1020 | return 0; | 1021 | return 0; |
| 1021 | } | 1022 | } |
| 1022 | 1023 | ||
| @@ -2988,17 +2989,6 @@ static int megasas_mgmt_open(struct inode *inode, struct file *filep) | |||
| 2988 | } | 2989 | } |
| 2989 | 2990 | ||
| 2990 | /** | 2991 | /** |
| 2991 | * megasas_mgmt_release - char node "release" entry point | ||
| 2992 | */ | ||
| 2993 | static int megasas_mgmt_release(struct inode *inode, struct file *filep) | ||
| 2994 | { | ||
| 2995 | filep->private_data = NULL; | ||
| 2996 | fasync_helper(-1, filep, 0, &megasas_async_queue); | ||
| 2997 | |||
| 2998 | return 0; | ||
| 2999 | } | ||
| 3000 | |||
| 3001 | /** | ||
| 3002 | * megasas_mgmt_fasync - Async notifier registration from applications | 2992 | * megasas_mgmt_fasync - Async notifier registration from applications |
| 3003 | * | 2993 | * |
| 3004 | * This function adds the calling process to a driver global queue. When an | 2994 | * This function adds the calling process to a driver global queue. When an |
| @@ -3345,7 +3335,6 @@ megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd, | |||
| 3345 | static const struct file_operations megasas_mgmt_fops = { | 3335 | static const struct file_operations megasas_mgmt_fops = { |
| 3346 | .owner = THIS_MODULE, | 3336 | .owner = THIS_MODULE, |
| 3347 | .open = megasas_mgmt_open, | 3337 | .open = megasas_mgmt_open, |
| 3348 | .release = megasas_mgmt_release, | ||
| 3349 | .fasync = megasas_mgmt_fasync, | 3338 | .fasync = megasas_mgmt_fasync, |
| 3350 | .unlocked_ioctl = megasas_mgmt_ioctl, | 3339 | .unlocked_ioctl = megasas_mgmt_ioctl, |
| 3351 | #ifdef CONFIG_COMPAT | 3340 | #ifdef CONFIG_COMPAT |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f25f41a499e5..b97194096d8e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -2547,7 +2547,6 @@ typedef struct scsi_qla_host { | |||
| 2547 | uint8_t fcode_revision[16]; | 2547 | uint8_t fcode_revision[16]; |
| 2548 | uint32_t fw_revision[4]; | 2548 | uint32_t fw_revision[4]; |
| 2549 | 2549 | ||
| 2550 | uint16_t fdt_odd_index; | ||
| 2551 | uint32_t fdt_wrt_disable; | 2550 | uint32_t fdt_wrt_disable; |
| 2552 | uint32_t fdt_erase_cmd; | 2551 | uint32_t fdt_erase_cmd; |
| 2553 | uint32_t fdt_block_size; | 2552 | uint32_t fdt_block_size; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a470f2d3270d..4218f20f5ed5 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -140,7 +140,6 @@ int | |||
| 140 | qla2100_pci_config(scsi_qla_host_t *ha) | 140 | qla2100_pci_config(scsi_qla_host_t *ha) |
| 141 | { | 141 | { |
| 142 | uint16_t w; | 142 | uint16_t w; |
| 143 | uint32_t d; | ||
| 144 | unsigned long flags; | 143 | unsigned long flags; |
| 145 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 144 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
| 146 | 145 | ||
| @@ -151,10 +150,7 @@ qla2100_pci_config(scsi_qla_host_t *ha) | |||
| 151 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 150 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); |
| 152 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); | 151 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); |
| 153 | 152 | ||
| 154 | /* Reset expansion ROM address decode enable */ | 153 | pci_disable_rom(ha->pdev); |
| 155 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); | ||
| 156 | d &= ~PCI_ROM_ADDRESS_ENABLE; | ||
| 157 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | ||
| 158 | 154 | ||
| 159 | /* Get PCI bus information. */ | 155 | /* Get PCI bus information. */ |
| 160 | spin_lock_irqsave(&ha->hardware_lock, flags); | 156 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| @@ -174,7 +170,6 @@ int | |||
| 174 | qla2300_pci_config(scsi_qla_host_t *ha) | 170 | qla2300_pci_config(scsi_qla_host_t *ha) |
| 175 | { | 171 | { |
| 176 | uint16_t w; | 172 | uint16_t w; |
| 177 | uint32_t d; | ||
| 178 | unsigned long flags = 0; | 173 | unsigned long flags = 0; |
| 179 | uint32_t cnt; | 174 | uint32_t cnt; |
| 180 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 175 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
| @@ -236,10 +231,7 @@ qla2300_pci_config(scsi_qla_host_t *ha) | |||
| 236 | 231 | ||
| 237 | pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); | 232 | pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); |
| 238 | 233 | ||
| 239 | /* Reset expansion ROM address decode enable */ | 234 | pci_disable_rom(ha->pdev); |
| 240 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); | ||
| 241 | d &= ~PCI_ROM_ADDRESS_ENABLE; | ||
| 242 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | ||
| 243 | 235 | ||
| 244 | /* Get PCI bus information. */ | 236 | /* Get PCI bus information. */ |
| 245 | spin_lock_irqsave(&ha->hardware_lock, flags); | 237 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| @@ -259,7 +251,6 @@ int | |||
| 259 | qla24xx_pci_config(scsi_qla_host_t *ha) | 251 | qla24xx_pci_config(scsi_qla_host_t *ha) |
| 260 | { | 252 | { |
| 261 | uint16_t w; | 253 | uint16_t w; |
| 262 | uint32_t d; | ||
| 263 | unsigned long flags = 0; | 254 | unsigned long flags = 0; |
| 264 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 255 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
| 265 | 256 | ||
| @@ -281,10 +272,7 @@ qla24xx_pci_config(scsi_qla_host_t *ha) | |||
| 281 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) | 272 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) |
| 282 | pcie_set_readrq(ha->pdev, 2048); | 273 | pcie_set_readrq(ha->pdev, 2048); |
| 283 | 274 | ||
| 284 | /* Reset expansion ROM address decode enable */ | 275 | pci_disable_rom(ha->pdev); |
| 285 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); | ||
| 286 | d &= ~PCI_ROM_ADDRESS_ENABLE; | ||
| 287 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | ||
| 288 | 276 | ||
| 289 | ha->chip_revision = ha->pdev->revision; | 277 | ha->chip_revision = ha->pdev->revision; |
| 290 | 278 | ||
| @@ -306,7 +294,6 @@ int | |||
| 306 | qla25xx_pci_config(scsi_qla_host_t *ha) | 294 | qla25xx_pci_config(scsi_qla_host_t *ha) |
| 307 | { | 295 | { |
| 308 | uint16_t w; | 296 | uint16_t w; |
| 309 | uint32_t d; | ||
| 310 | 297 | ||
| 311 | pci_set_master(ha->pdev); | 298 | pci_set_master(ha->pdev); |
| 312 | pci_try_set_mwi(ha->pdev); | 299 | pci_try_set_mwi(ha->pdev); |
| @@ -320,10 +307,7 @@ qla25xx_pci_config(scsi_qla_host_t *ha) | |||
| 320 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) | 307 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) |
| 321 | pcie_set_readrq(ha->pdev, 2048); | 308 | pcie_set_readrq(ha->pdev, 2048); |
| 322 | 309 | ||
| 323 | /* Reset expansion ROM address decode enable */ | 310 | pci_disable_rom(ha->pdev); |
| 324 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); | ||
| 325 | d &= ~PCI_ROM_ADDRESS_ENABLE; | ||
| 326 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | ||
| 327 | 311 | ||
| 328 | ha->chip_revision = ha->pdev->revision; | 312 | ha->chip_revision = ha->pdev->revision; |
| 329 | 313 | ||
| @@ -980,7 +964,6 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
| 980 | &ha->fw_minor_version, | 964 | &ha->fw_minor_version, |
| 981 | &ha->fw_subminor_version, | 965 | &ha->fw_subminor_version, |
| 982 | &ha->fw_attributes, &ha->fw_memory_size); | 966 | &ha->fw_attributes, &ha->fw_memory_size); |
| 983 | qla2x00_resize_request_q(ha); | ||
| 984 | ha->flags.npiv_supported = 0; | 967 | ha->flags.npiv_supported = 0; |
| 985 | if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) || | 968 | if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) || |
| 986 | IS_QLA84XX(ha)) && | 969 | IS_QLA84XX(ha)) && |
| @@ -992,6 +975,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
| 992 | ha->max_npiv_vports = | 975 | ha->max_npiv_vports = |
| 993 | MIN_MULTI_ID_FABRIC - 1; | 976 | MIN_MULTI_ID_FABRIC - 1; |
| 994 | } | 977 | } |
| 978 | qla2x00_resize_request_q(ha); | ||
| 995 | 979 | ||
| 996 | if (ql2xallocfwdump) | 980 | if (ql2xallocfwdump) |
| 997 | qla2x00_alloc_fw_dump(ha); | 981 | qla2x00_alloc_fw_dump(ha); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 36bc6851e23d..3402746ec128 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
| @@ -1964,7 +1964,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
| 1964 | *cur_iocb_cnt = mcp->mb[7]; | 1964 | *cur_iocb_cnt = mcp->mb[7]; |
| 1965 | if (orig_iocb_cnt) | 1965 | if (orig_iocb_cnt) |
| 1966 | *orig_iocb_cnt = mcp->mb[10]; | 1966 | *orig_iocb_cnt = mcp->mb[10]; |
| 1967 | if (max_npiv_vports) | 1967 | if (ha->flags.npiv_supported && max_npiv_vports) |
| 1968 | *max_npiv_vports = mcp->mb[11]; | 1968 | *max_npiv_vports = mcp->mb[11]; |
| 1969 | } | 1969 | } |
| 1970 | 1970 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 21dd182ad512..35567203ef61 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -728,6 +728,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
| 728 | if (ha->isp_ops->abort_command(ha, sp)) { | 728 | if (ha->isp_ops->abort_command(ha, sp)) { |
| 729 | DEBUG2(printk("%s(%ld): abort_command " | 729 | DEBUG2(printk("%s(%ld): abort_command " |
| 730 | "mbx failed.\n", __func__, ha->host_no)); | 730 | "mbx failed.\n", __func__, ha->host_no)); |
| 731 | ret = FAILED; | ||
| 731 | } else { | 732 | } else { |
| 732 | DEBUG3(printk("%s(%ld): abort_command " | 733 | DEBUG3(printk("%s(%ld): abort_command " |
| 733 | "mbx success.\n", __func__, ha->host_no)); | 734 | "mbx success.\n", __func__, ha->host_no)); |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 90a13211717f..e4af678eb2d6 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
| @@ -722,6 +722,7 @@ done: | |||
| 722 | static void | 722 | static void |
| 723 | qla2xxx_get_fdt_info(scsi_qla_host_t *ha) | 723 | qla2xxx_get_fdt_info(scsi_qla_host_t *ha) |
| 724 | { | 724 | { |
| 725 | #define FLASH_BLK_SIZE_4K 0x1000 | ||
| 725 | #define FLASH_BLK_SIZE_32K 0x8000 | 726 | #define FLASH_BLK_SIZE_32K 0x8000 |
| 726 | #define FLASH_BLK_SIZE_64K 0x10000 | 727 | #define FLASH_BLK_SIZE_64K 0x10000 |
| 727 | const char *loc, *locations[] = { "MID", "FDT" }; | 728 | const char *loc, *locations[] = { "MID", "FDT" }; |
| @@ -755,7 +756,6 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *ha) | |||
| 755 | loc = locations[1]; | 756 | loc = locations[1]; |
| 756 | mid = le16_to_cpu(fdt->man_id); | 757 | mid = le16_to_cpu(fdt->man_id); |
| 757 | fid = le16_to_cpu(fdt->id); | 758 | fid = le16_to_cpu(fdt->id); |
| 758 | ha->fdt_odd_index = mid == 0x1f; | ||
| 759 | ha->fdt_wrt_disable = fdt->wrt_disable_bits; | 759 | ha->fdt_wrt_disable = fdt->wrt_disable_bits; |
| 760 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); | 760 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); |
| 761 | ha->fdt_block_size = le32_to_cpu(fdt->block_size); | 761 | ha->fdt_block_size = le32_to_cpu(fdt->block_size); |
| @@ -788,8 +788,7 @@ no_flash_data: | |||
| 788 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; | 788 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
| 789 | break; | 789 | break; |
| 790 | case 0x1f: /* Atmel 26DF081A. */ | 790 | case 0x1f: /* Atmel 26DF081A. */ |
| 791 | ha->fdt_odd_index = 1; | 791 | ha->fdt_block_size = FLASH_BLK_SIZE_4K; |
| 792 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; | ||
| 793 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320); | 792 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320); |
| 794 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339); | 793 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339); |
| 795 | ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336); | 794 | ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336); |
| @@ -801,9 +800,9 @@ no_flash_data: | |||
| 801 | } | 800 | } |
| 802 | done: | 801 | done: |
| 803 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x " | 802 | DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x " |
| 804 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", loc, mid, fid, | 803 | "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n", loc, mid, fid, |
| 805 | ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, | 804 | ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, |
| 806 | ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable, | 805 | ha->fdt_unprotect_sec_cmd, ha->fdt_wrt_disable, |
| 807 | ha->fdt_block_size)); | 806 | ha->fdt_block_size)); |
| 808 | } | 807 | } |
| 809 | 808 | ||
| @@ -987,13 +986,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
| 987 | qla24xx_unprotect_flash(ha); | 986 | qla24xx_unprotect_flash(ha); |
| 988 | 987 | ||
| 989 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 988 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
| 990 | if (ha->fdt_odd_index) { | 989 | |
| 991 | findex = faddr << 2; | 990 | findex = faddr; |
| 992 | fdata = findex & sec_mask; | 991 | fdata = (findex & sec_mask) << 2; |
| 993 | } else { | ||
| 994 | findex = faddr; | ||
| 995 | fdata = (findex & sec_mask) << 2; | ||
| 996 | } | ||
| 997 | 992 | ||
| 998 | /* Are we at the beginning of a sector? */ | 993 | /* Are we at the beginning of a sector? */ |
| 999 | if ((findex & rest_addr) == 0) { | 994 | if ((findex & rest_addr) == 0) { |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index be5e299df528..eea6720adf16 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | /* | 7 | /* |
| 8 | * Driver version | 8 | * Driver version |
| 9 | */ | 9 | */ |
| 10 | #define QLA2XXX_VERSION "8.02.01-k8" | 10 | #define QLA2XXX_VERSION "8.02.01-k9" |
| 11 | 11 | ||
| 12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
| 13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 94ed262bdf0c..edfaf241c5ba 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -932,8 +932,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd) | |||
| 932 | int i, rtn = NEEDS_RETRY; | 932 | int i, rtn = NEEDS_RETRY; |
| 933 | 933 | ||
| 934 | for (i = 0; rtn == NEEDS_RETRY && i < 2; i++) | 934 | for (i = 0; rtn == NEEDS_RETRY && i < 2; i++) |
| 935 | rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, | 935 | rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, scmd->device->request_queue->rq_timeout, 0); |
| 936 | scmd->device->timeout, 0); | ||
| 937 | 936 | ||
| 938 | if (rtn == SUCCESS) | 937 | if (rtn == SUCCESS) |
| 939 | return 0; | 938 | return 0; |
| @@ -1340,9 +1339,10 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
| 1340 | * LLD/transport was disrupted during processing of the IO. | 1339 | * LLD/transport was disrupted during processing of the IO. |
| 1341 | * The transport class is now blocked/blocking, | 1340 | * The transport class is now blocked/blocking, |
| 1342 | * and the transport will decide what to do with the IO | 1341 | * and the transport will decide what to do with the IO |
| 1343 | * based on its timers and recovery capablilities. | 1342 | * based on its timers and recovery capablilities if |
| 1343 | * there are enough retries. | ||
| 1344 | */ | 1344 | */ |
| 1345 | return ADD_TO_MLQUEUE; | 1345 | goto maybe_retry; |
| 1346 | case DID_TRANSPORT_FAILFAST: | 1346 | case DID_TRANSPORT_FAILFAST: |
| 1347 | /* | 1347 | /* |
| 1348 | * The transport decided to failfast the IO (most likely | 1348 | * The transport decided to failfast the IO (most likely |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f5d3b96890dc..fa45a1a66867 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -567,15 +567,18 @@ static inline int scsi_host_is_busy(struct Scsi_Host *shost) | |||
| 567 | */ | 567 | */ |
| 568 | static void scsi_run_queue(struct request_queue *q) | 568 | static void scsi_run_queue(struct request_queue *q) |
| 569 | { | 569 | { |
| 570 | struct scsi_device *starved_head = NULL, *sdev = q->queuedata; | 570 | struct scsi_device *sdev = q->queuedata; |
| 571 | struct Scsi_Host *shost = sdev->host; | 571 | struct Scsi_Host *shost = sdev->host; |
| 572 | LIST_HEAD(starved_list); | ||
| 572 | unsigned long flags; | 573 | unsigned long flags; |
| 573 | 574 | ||
| 574 | if (scsi_target(sdev)->single_lun) | 575 | if (scsi_target(sdev)->single_lun) |
| 575 | scsi_single_lun_run(sdev); | 576 | scsi_single_lun_run(sdev); |
| 576 | 577 | ||
| 577 | spin_lock_irqsave(shost->host_lock, flags); | 578 | spin_lock_irqsave(shost->host_lock, flags); |
| 578 | while (!list_empty(&shost->starved_list) && !scsi_host_is_busy(shost)) { | 579 | list_splice_init(&shost->starved_list, &starved_list); |
| 580 | |||
| 581 | while (!list_empty(&starved_list)) { | ||
| 579 | int flagset; | 582 | int flagset; |
| 580 | 583 | ||
| 581 | /* | 584 | /* |
| @@ -588,24 +591,18 @@ static void scsi_run_queue(struct request_queue *q) | |||
| 588 | * scsi_request_fn must get the host_lock before checking | 591 | * scsi_request_fn must get the host_lock before checking |
| 589 | * or modifying starved_list or starved_entry. | 592 | * or modifying starved_list or starved_entry. |
| 590 | */ | 593 | */ |
| 591 | sdev = list_entry(shost->starved_list.next, | 594 | if (scsi_host_is_busy(shost)) |
| 592 | struct scsi_device, starved_entry); | ||
| 593 | /* | ||
| 594 | * The *queue_ready functions can add a device back onto the | ||
| 595 | * starved list's tail, so we must check for a infinite loop. | ||
| 596 | */ | ||
| 597 | if (sdev == starved_head) | ||
| 598 | break; | 595 | break; |
| 599 | if (!starved_head) | ||
| 600 | starved_head = sdev; | ||
| 601 | 596 | ||
| 597 | sdev = list_entry(starved_list.next, | ||
| 598 | struct scsi_device, starved_entry); | ||
| 599 | list_del_init(&sdev->starved_entry); | ||
| 602 | if (scsi_target_is_busy(scsi_target(sdev))) { | 600 | if (scsi_target_is_busy(scsi_target(sdev))) { |
| 603 | list_move_tail(&sdev->starved_entry, | 601 | list_move_tail(&sdev->starved_entry, |
| 604 | &shost->starved_list); | 602 | &shost->starved_list); |
| 605 | continue; | 603 | continue; |
| 606 | } | 604 | } |
| 607 | 605 | ||
| 608 | list_del_init(&sdev->starved_entry); | ||
| 609 | spin_unlock(shost->host_lock); | 606 | spin_unlock(shost->host_lock); |
| 610 | 607 | ||
| 611 | spin_lock(sdev->request_queue->queue_lock); | 608 | spin_lock(sdev->request_queue->queue_lock); |
| @@ -621,6 +618,8 @@ static void scsi_run_queue(struct request_queue *q) | |||
| 621 | 618 | ||
| 622 | spin_lock(shost->host_lock); | 619 | spin_lock(shost->host_lock); |
| 623 | } | 620 | } |
| 621 | /* put any unprocessed entries back */ | ||
| 622 | list_splice(&starved_list, &shost->starved_list); | ||
| 624 | spin_unlock_irqrestore(shost->host_lock, flags); | 623 | spin_unlock_irqrestore(shost->host_lock, flags); |
| 625 | 624 | ||
| 626 | blk_run_queue(q); | 625 | blk_run_queue(q); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c9e1242eaf25..5081b3981d3c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -757,7 +757,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 757 | * access to the device is prohibited. | 757 | * access to the device is prohibited. |
| 758 | */ | 758 | */ |
| 759 | error = scsi_nonblockable_ioctl(sdp, cmd, p, | 759 | error = scsi_nonblockable_ioctl(sdp, cmd, p, |
| 760 | (mode & FMODE_NDELAY_NOW) != 0); | 760 | (mode & FMODE_NDELAY) != 0); |
| 761 | if (!scsi_block_when_processing_errors(sdp) || !error) | 761 | if (!scsi_block_when_processing_errors(sdp) || !error) |
| 762 | return error; | 762 | return error; |
| 763 | 763 | ||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 9adf35bd8b56..5103855242ae 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
| @@ -327,7 +327,6 @@ sg_release(struct inode *inode, struct file *filp) | |||
| 327 | if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) | 327 | if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) |
| 328 | return -ENXIO; | 328 | return -ENXIO; |
| 329 | SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name)); | 329 | SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name)); |
| 330 | sg_fasync(-1, filp, 0); /* remove filp from async notification list */ | ||
| 331 | if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */ | 330 | if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */ |
| 332 | if (!sdp->detached) { | 331 | if (!sdp->detached) { |
| 333 | scsi_device_put(sdp->device); | 332 | scsi_device_put(sdp->device); |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 62b6633e3a97..45b66b98a516 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
| @@ -521,7 +521,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
| 521 | * if it doesn't recognise the ioctl | 521 | * if it doesn't recognise the ioctl |
| 522 | */ | 522 | */ |
| 523 | ret = scsi_nonblockable_ioctl(sdev, cmd, argp, | 523 | ret = scsi_nonblockable_ioctl(sdev, cmd, argp, |
| 524 | (mode & FMODE_NDELAY_NOW) != 0); | 524 | (mode & FMODE_NDELAY) != 0); |
| 525 | if (ret != -ENODEV) | 525 | if (ret != -ENODEV) |
| 526 | return ret; | 526 | return ret; |
| 527 | return scsi_ioctl(sdev, cmd, argp); | 527 | return scsi_ioctl(sdev, cmd, argp); |
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 3790906a77d1..2fa830c0be27 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
| @@ -477,7 +477,7 @@ stex_slave_config(struct scsi_device *sdev) | |||
| 477 | { | 477 | { |
| 478 | sdev->use_10_for_rw = 1; | 478 | sdev->use_10_for_rw = 1; |
| 479 | sdev->use_10_for_ms = 1; | 479 | sdev->use_10_for_ms = 1; |
| 480 | sdev->timeout = 60 * HZ; | 480 | blk_queue_rq_timeout(sdev->request_queue, 60 * HZ); |
| 481 | sdev->tagged_supported = 1; | 481 | sdev->tagged_supported = 1; |
| 482 | 482 | ||
| 483 | return 0; | 483 | return 0; |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 61fb8b6d19af..d5efd6c77904 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
| @@ -1258,6 +1258,8 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
| 1258 | atmel_port->clk = clk_get(&pdev->dev, "usart"); | 1258 | atmel_port->clk = clk_get(&pdev->dev, "usart"); |
| 1259 | clk_enable(atmel_port->clk); | 1259 | clk_enable(atmel_port->clk); |
| 1260 | port->uartclk = clk_get_rate(atmel_port->clk); | 1260 | port->uartclk = clk_get_rate(atmel_port->clk); |
| 1261 | clk_disable(atmel_port->clk); | ||
| 1262 | /* only enable clock when USART is in use */ | ||
| 1261 | } | 1263 | } |
| 1262 | 1264 | ||
| 1263 | atmel_port->use_dma_rx = data->use_dma_rx; | 1265 | atmel_port->use_dma_rx = data->use_dma_rx; |
| @@ -1379,6 +1381,8 @@ static int __init atmel_console_setup(struct console *co, char *options) | |||
| 1379 | return -ENODEV; | 1381 | return -ENODEV; |
| 1380 | } | 1382 | } |
| 1381 | 1383 | ||
| 1384 | clk_enable(atmel_ports[co->index].clk); | ||
| 1385 | |||
| 1382 | UART_PUT_IDR(port, -1); | 1386 | UART_PUT_IDR(port, -1); |
| 1383 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); | 1387 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); |
| 1384 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); | 1388 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); |
| @@ -1403,7 +1407,7 @@ static struct console atmel_console = { | |||
| 1403 | .data = &atmel_uart, | 1407 | .data = &atmel_uart, |
| 1404 | }; | 1408 | }; |
| 1405 | 1409 | ||
| 1406 | #define ATMEL_CONSOLE_DEVICE &atmel_console | 1410 | #define ATMEL_CONSOLE_DEVICE (&atmel_console) |
| 1407 | 1411 | ||
| 1408 | /* | 1412 | /* |
| 1409 | * Early console initialization (before VM subsystem initialized). | 1413 | * Early console initialization (before VM subsystem initialized). |
| @@ -1534,6 +1538,15 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
| 1534 | if (ret) | 1538 | if (ret) |
| 1535 | goto err_add_port; | 1539 | goto err_add_port; |
| 1536 | 1540 | ||
| 1541 | if (atmel_is_console_port(&port->uart) | ||
| 1542 | && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { | ||
| 1543 | /* | ||
| 1544 | * The serial core enabled the clock for us, so undo | ||
| 1545 | * the clk_enable() in atmel_console_setup() | ||
| 1546 | */ | ||
| 1547 | clk_disable(port->clk); | ||
| 1548 | } | ||
| 1549 | |||
| 1537 | device_init_wakeup(&pdev->dev, 1); | 1550 | device_init_wakeup(&pdev->dev, 1); |
| 1538 | platform_set_drvdata(pdev, port); | 1551 | platform_set_drvdata(pdev, port); |
| 1539 | 1552 | ||
| @@ -1544,7 +1557,6 @@ err_add_port: | |||
| 1544 | port->rx_ring.buf = NULL; | 1557 | port->rx_ring.buf = NULL; |
| 1545 | err_alloc_ring: | 1558 | err_alloc_ring: |
| 1546 | if (!atmel_is_console_port(&port->uart)) { | 1559 | if (!atmel_is_console_port(&port->uart)) { |
| 1547 | clk_disable(port->clk); | ||
| 1548 | clk_put(port->clk); | 1560 | clk_put(port->clk); |
| 1549 | port->clk = NULL; | 1561 | port->clk = NULL; |
| 1550 | } | 1562 | } |
| @@ -1568,7 +1580,6 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev) | |||
| 1568 | 1580 | ||
| 1569 | /* "port" is allocated statically, so we shouldn't free it */ | 1581 | /* "port" is allocated statically, so we shouldn't free it */ |
| 1570 | 1582 | ||
| 1571 | clk_disable(atmel_port->clk); | ||
| 1572 | clk_put(atmel_port->clk); | 1583 | clk_put(atmel_port->clk); |
| 1573 | 1584 | ||
| 1574 | return ret; | 1585 | return ret; |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 211c21797ce0..8b2c619a09f2 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
| @@ -34,14 +34,14 @@ static char *serial_version = "$Revision: 1.25 $"; | |||
| 34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
| 35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
| 36 | 36 | ||
| 37 | #include <asm/arch/svinto.h> | 37 | #include <arch/svinto.h> |
| 38 | 38 | ||
| 39 | /* non-arch dependent serial structures are in linux/serial.h */ | 39 | /* non-arch dependent serial structures are in linux/serial.h */ |
| 40 | #include <linux/serial.h> | 40 | #include <linux/serial.h> |
| 41 | /* while we keep our own stuff (struct e100_serial) in a local .h file */ | 41 | /* while we keep our own stuff (struct e100_serial) in a local .h file */ |
| 42 | #include "crisv10.h" | 42 | #include "crisv10.h" |
| 43 | #include <asm/fasttimer.h> | 43 | #include <asm/fasttimer.h> |
| 44 | #include <asm/arch/io_interface_mux.h> | 44 | #include <arch/io_interface_mux.h> |
| 45 | 45 | ||
| 46 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER | 46 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER |
| 47 | #ifndef CONFIG_ETRAX_FAST_TIMER | 47 | #ifndef CONFIG_ETRAX_FAST_TIMER |
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h index e3c5c8c3c09b..f36a729280bc 100644 --- a/drivers/serial/crisv10.h +++ b/drivers/serial/crisv10.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include <linux/circ_buf.h> | 10 | #include <linux/circ_buf.h> |
| 11 | #include <asm/termios.h> | 11 | #include <asm/termios.h> |
| 12 | #include <asm/dma.h> | 12 | #include <asm/dma.h> |
| 13 | #include <asm/arch/io_interface_mux.h> | 13 | #include <arch/io_interface_mux.h> |
| 14 | 14 | ||
| 15 | /* Software state per channel */ | 15 | /* Software state per channel */ |
| 16 | 16 | ||
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c index 6dd98f9fb89c..ae3699d77dd0 100644 --- a/drivers/serial/ioc3_serial.c +++ b/drivers/serial/ioc3_serial.c | |||
| @@ -2149,7 +2149,7 @@ out4: | |||
| 2149 | return ret; | 2149 | return ret; |
| 2150 | } | 2150 | } |
| 2151 | 2151 | ||
| 2152 | static struct ioc3_submodule ioc3uart_submodule = { | 2152 | static struct ioc3_submodule ioc3uart_ops = { |
| 2153 | .name = "IOC3uart", | 2153 | .name = "IOC3uart", |
| 2154 | .probe = ioc3uart_probe, | 2154 | .probe = ioc3uart_probe, |
| 2155 | .remove = ioc3uart_remove, | 2155 | .remove = ioc3uart_remove, |
| @@ -2173,7 +2173,7 @@ static int __devinit ioc3uart_init(void) | |||
| 2173 | __func__); | 2173 | __func__); |
| 2174 | return ret; | 2174 | return ret; |
| 2175 | } | 2175 | } |
| 2176 | ret = ioc3_register_submodule(&ioc3uart_submodule); | 2176 | ret = ioc3_register_submodule(&ioc3uart_ops); |
| 2177 | if (ret) | 2177 | if (ret) |
| 2178 | uart_unregister_driver(&ioc3_uart); | 2178 | uart_unregister_driver(&ioc3_uart); |
| 2179 | return ret; | 2179 | return ret; |
| @@ -2181,7 +2181,7 @@ static int __devinit ioc3uart_init(void) | |||
| 2181 | 2181 | ||
| 2182 | static void __devexit ioc3uart_exit(void) | 2182 | static void __devexit ioc3uart_exit(void) |
| 2183 | { | 2183 | { |
| 2184 | ioc3_unregister_submodule(&ioc3uart_submodule); | 2184 | ioc3_unregister_submodule(&ioc3uart_ops); |
| 2185 | uart_unregister_driver(&ioc3_uart); | 2185 | uart_unregister_driver(&ioc3_uart); |
| 2186 | } | 2186 | } |
| 2187 | 2187 | ||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 6117d3db0b66..28c00c3d58f5 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
| @@ -591,8 +591,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
| 591 | /* Update the per-port timeout */ | 591 | /* Update the per-port timeout */ |
| 592 | uart_update_timeout(port, new->c_cflag, baud); | 592 | uart_update_timeout(port, new->c_cflag, baud); |
| 593 | 593 | ||
| 594 | /* Do our best to flush TX & RX, so we don't loose anything */ | 594 | /* Do our best to flush TX & RX, so we don't lose anything */ |
| 595 | /* But we don't wait indefinitly ! */ | 595 | /* But we don't wait indefinitely ! */ |
| 596 | j = 5000000; /* Maximum wait */ | 596 | j = 5000000; /* Maximum wait */ |
| 597 | /* FIXME Can't receive chars since set_termios might be called at early | 597 | /* FIXME Can't receive chars since set_termios might be called at early |
| 598 | * boot for the console, all stuff is not yet ready to receive at that | 598 | * boot for the console, all stuff is not yet ready to receive at that |
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c index 317d239ab740..29cbb0afef8e 100644 --- a/drivers/serial/s3c2440.c +++ b/drivers/serial/s3c2440.c | |||
| @@ -177,5 +177,5 @@ module_exit(s3c2440_serial_exit); | |||
| 177 | 177 | ||
| 178 | MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver"); | 178 | MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver"); |
| 179 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 179 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
| 180 | MODULE_LICENSE("GPLi v2"); | 180 | MODULE_LICENSE("GPL v2"); |
| 181 | MODULE_ALIAS("platform:s3c2440-uart"); | 181 | MODULE_ALIAS("platform:s3c2440-uart"); |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f0658d2c45b2..165fc010978c 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
| @@ -144,9 +144,9 @@ static void put_char(struct uart_port *port, char c) | |||
| 144 | status = sci_in(port, SCxSR); | 144 | status = sci_in(port, SCxSR); |
| 145 | } while (!(status & SCxSR_TDxE(port))); | 145 | } while (!(status & SCxSR_TDxE(port))); |
| 146 | 146 | ||
| 147 | sci_out(port, SCxTDR, c); | ||
| 148 | sci_in(port, SCxSR); /* Dummy read */ | 147 | sci_in(port, SCxSR); /* Dummy read */ |
| 149 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); | 148 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); |
| 149 | sci_out(port, SCxTDR, c); | ||
| 150 | 150 | ||
| 151 | spin_unlock_irqrestore(&port->lock, flags); | 151 | spin_unlock_irqrestore(&port->lock, flags); |
| 152 | } | 152 | } |
| @@ -250,8 +250,7 @@ static inline void h8300_sci_disable(struct uart_port *port) | |||
| 250 | } | 250 | } |
| 251 | #endif | 251 | #endif |
| 252 | 252 | ||
| 253 | #if defined(SCI_ONLY) || defined(SCI_AND_SCIF) && \ | 253 | #if defined(__H8300H__) || defined(__H8300S__) |
| 254 | defined(__H8300H__) || defined(__H8300S__) | ||
| 255 | static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) | 254 | static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) |
| 256 | { | 255 | { |
| 257 | int ch = (port->mapbase - SMR0) >> 3; | 256 | int ch = (port->mapbase - SMR0) >> 3; |
| @@ -285,11 +284,6 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) | |||
| 285 | #define sci_init_pins_irda NULL | 284 | #define sci_init_pins_irda NULL |
| 286 | #endif | 285 | #endif |
| 287 | 286 | ||
| 288 | #ifdef SCI_ONLY | ||
| 289 | #define sci_init_pins_scif NULL | ||
| 290 | #endif | ||
| 291 | |||
| 292 | #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) | ||
| 293 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 287 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
| 294 | static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) | 288 | static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) |
| 295 | { | 289 | { |
| @@ -449,7 +443,6 @@ static inline int scif_rxroom(struct uart_port *port) | |||
| 449 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | 443 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; |
| 450 | } | 444 | } |
| 451 | #endif | 445 | #endif |
| 452 | #endif /* SCIF_ONLY || SCI_AND_SCIF */ | ||
| 453 | 446 | ||
| 454 | static inline int sci_txroom(struct uart_port *port) | 447 | static inline int sci_txroom(struct uart_port *port) |
| 455 | { | 448 | { |
| @@ -485,12 +478,10 @@ static void sci_transmit_chars(struct uart_port *port) | |||
| 485 | return; | 478 | return; |
| 486 | } | 479 | } |
| 487 | 480 | ||
| 488 | #ifndef SCI_ONLY | 481 | if (port->type == PORT_SCI) |
| 489 | if (port->type == PORT_SCIF) | ||
| 490 | count = scif_txroom(port); | ||
| 491 | else | ||
| 492 | #endif | ||
| 493 | count = sci_txroom(port); | 482 | count = sci_txroom(port); |
| 483 | else | ||
| 484 | count = scif_txroom(port); | ||
| 494 | 485 | ||
| 495 | do { | 486 | do { |
| 496 | unsigned char c; | 487 | unsigned char c; |
| @@ -519,12 +510,10 @@ static void sci_transmit_chars(struct uart_port *port) | |||
| 519 | } else { | 510 | } else { |
| 520 | ctrl = sci_in(port, SCSCR); | 511 | ctrl = sci_in(port, SCSCR); |
| 521 | 512 | ||
| 522 | #if !defined(SCI_ONLY) | 513 | if (port->type != PORT_SCI) { |
| 523 | if (port->type == PORT_SCIF) { | ||
| 524 | sci_in(port, SCxSR); /* Dummy read */ | 514 | sci_in(port, SCxSR); /* Dummy read */ |
| 525 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); | 515 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); |
| 526 | } | 516 | } |
| 527 | #endif | ||
| 528 | 517 | ||
| 529 | ctrl |= SCI_CTRL_FLAGS_TIE; | 518 | ctrl |= SCI_CTRL_FLAGS_TIE; |
| 530 | sci_out(port, SCSCR, ctrl); | 519 | sci_out(port, SCSCR, ctrl); |
| @@ -547,12 +536,10 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
| 547 | return; | 536 | return; |
| 548 | 537 | ||
| 549 | while (1) { | 538 | while (1) { |
| 550 | #if !defined(SCI_ONLY) | 539 | if (port->type == PORT_SCI) |
| 551 | if (port->type == PORT_SCIF) | ||
| 552 | count = scif_rxroom(port); | ||
| 553 | else | ||
| 554 | #endif | ||
| 555 | count = sci_rxroom(port); | 540 | count = sci_rxroom(port); |
| 541 | else | ||
| 542 | count = scif_rxroom(port); | ||
| 556 | 543 | ||
| 557 | /* Don't copy more bytes than there is room for in the buffer */ | 544 | /* Don't copy more bytes than there is room for in the buffer */ |
| 558 | count = tty_buffer_request_room(tty, count); | 545 | count = tty_buffer_request_room(tty, count); |
| @@ -727,7 +714,7 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
| 727 | 714 | ||
| 728 | #if defined(SCIF_ORER) | 715 | #if defined(SCIF_ORER) |
| 729 | /* XXX: Handle SCIF overrun error */ | 716 | /* XXX: Handle SCIF overrun error */ |
| 730 | if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { | 717 | if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { |
| 731 | sci_out(port, SCLSR, 0); | 718 | sci_out(port, SCLSR, 0); |
| 732 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { | 719 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { |
| 733 | copied++; | 720 | copied++; |
| @@ -810,26 +797,27 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) | |||
| 810 | 797 | ||
| 811 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | 798 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) |
| 812 | { | 799 | { |
| 813 | unsigned short ssr_status, scr_status; | 800 | unsigned short ssr_status, scr_status; |
| 814 | struct uart_port *port = ptr; | 801 | struct uart_port *port = ptr; |
| 802 | irqreturn_t ret = IRQ_NONE; | ||
| 815 | 803 | ||
| 816 | ssr_status = sci_in(port,SCxSR); | 804 | ssr_status = sci_in(port,SCxSR); |
| 817 | scr_status = sci_in(port,SCSCR); | 805 | scr_status = sci_in(port,SCSCR); |
| 818 | 806 | ||
| 819 | /* Tx Interrupt */ | 807 | /* Tx Interrupt */ |
| 820 | if ((ssr_status & 0x0020) && (scr_status & 0x0080)) | 808 | if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) |
| 821 | sci_tx_interrupt(irq, ptr); | 809 | ret = sci_tx_interrupt(irq, ptr); |
| 822 | /* Rx Interrupt */ | 810 | /* Rx Interrupt */ |
| 823 | if ((ssr_status & 0x0002) && (scr_status & 0x0040)) | 811 | if ((ssr_status & 0x0002) && (scr_status & SCI_CTRL_FLAGS_RIE)) |
| 824 | sci_rx_interrupt(irq, ptr); | 812 | ret = sci_rx_interrupt(irq, ptr); |
| 825 | /* Error Interrupt */ | 813 | /* Error Interrupt */ |
| 826 | if ((ssr_status & 0x0080) && (scr_status & 0x0400)) | 814 | if ((ssr_status & 0x0080) && (scr_status & SCI_CTRL_FLAGS_REIE)) |
| 827 | sci_er_interrupt(irq, ptr); | 815 | ret = sci_er_interrupt(irq, ptr); |
| 828 | /* Break Interrupt */ | 816 | /* Break Interrupt */ |
| 829 | if ((ssr_status & 0x0010) && (scr_status & 0x0200)) | 817 | if ((ssr_status & 0x0010) && (scr_status & SCI_CTRL_FLAGS_REIE)) |
| 830 | sci_br_interrupt(irq, ptr); | 818 | ret = sci_br_interrupt(irq, ptr); |
| 831 | 819 | ||
| 832 | return IRQ_HANDLED; | 820 | return ret; |
| 833 | } | 821 | } |
| 834 | 822 | ||
| 835 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) | 823 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) |
| @@ -1054,10 +1042,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1054 | 1042 | ||
| 1055 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ | 1043 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ |
| 1056 | 1044 | ||
| 1057 | #if !defined(SCI_ONLY) | 1045 | if (port->type != PORT_SCI) |
| 1058 | if (port->type == PORT_SCIF) | ||
| 1059 | sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); | 1046 | sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); |
| 1060 | #endif | ||
| 1061 | 1047 | ||
| 1062 | smr_val = sci_in(port, SCSMR) & 3; | 1048 | smr_val = sci_in(port, SCSMR) & 3; |
| 1063 | if ((termios->c_cflag & CSIZE) == CS7) | 1049 | if ((termios->c_cflag & CSIZE) == CS7) |
| @@ -1099,6 +1085,7 @@ static const char *sci_type(struct uart_port *port) | |||
| 1099 | case PORT_SCI: return "sci"; | 1085 | case PORT_SCI: return "sci"; |
| 1100 | case PORT_SCIF: return "scif"; | 1086 | case PORT_SCIF: return "scif"; |
| 1101 | case PORT_IRDA: return "irda"; | 1087 | case PORT_IRDA: return "irda"; |
| 1088 | case PORT_SCIFA: return "scifa"; | ||
| 1102 | } | 1089 | } |
| 1103 | 1090 | ||
| 1104 | return NULL; | 1091 | return NULL; |
| @@ -1126,6 +1113,7 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
| 1126 | s->init_pins = sci_init_pins_sci; | 1113 | s->init_pins = sci_init_pins_sci; |
| 1127 | break; | 1114 | break; |
| 1128 | case PORT_SCIF: | 1115 | case PORT_SCIF: |
| 1116 | case PORT_SCIFA: | ||
| 1129 | s->init_pins = sci_init_pins_scif; | 1117 | s->init_pins = sci_init_pins_scif; |
| 1130 | break; | 1118 | break; |
| 1131 | case PORT_IRDA: | 1119 | case PORT_IRDA: |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 7cd28b226800..9f33b064172e 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | # define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */ | 16 | # define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */ |
| 17 | # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ | 17 | # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ |
| 18 | # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ | 18 | # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ |
| 19 | # define SCI_AND_SCIF | ||
| 20 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | 19 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) |
| 21 | # define SCIF0 0xA4400000 | 20 | # define SCIF0 0xA4400000 |
| 22 | # define SCIF2 0xA4410000 | 21 | # define SCIF2 0xA4410000 |
| @@ -30,17 +29,15 @@ | |||
| 30 | * SCIF0 (0xA4400000) -> Internal clock, SCK pin as serial clock output | 29 | * SCIF0 (0xA4400000) -> Internal clock, SCK pin as serial clock output |
| 31 | */ | 30 | */ |
| 32 | # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 | 31 | # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 |
| 33 | # define SCIF_ONLY | ||
| 34 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 32 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
| 35 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 33 | defined(CONFIG_CPU_SUBTYPE_SH7721) |
| 36 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ | 34 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ |
| 37 | # define SCIF_ONLY | ||
| 38 | #define SCIF_ORER 0x0200 /* overrun error bit */ | 35 | #define SCIF_ORER 0x0200 /* overrun error bit */ |
| 39 | #elif defined(CONFIG_SH_RTS7751R2D) | 36 | #elif defined(CONFIG_SH_RTS7751R2D) |
| 37 | # define SCSPTR1 0xFFE0001C /* 8 bit SCIF */ | ||
| 40 | # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ | 38 | # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ |
| 41 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 39 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 42 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 40 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 43 | # define SCIF_ONLY | ||
| 44 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | 41 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
| 45 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | 42 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ |
| 46 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | 43 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ |
| @@ -53,28 +50,24 @@ | |||
| 53 | # define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \ | 50 | # define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \ |
| 54 | 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \ | 51 | 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \ |
| 55 | 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ ) | 52 | 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ ) |
| 56 | # define SCI_AND_SCIF | ||
| 57 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | 53 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) |
| 58 | # define SCSPTR0 0xfe600024 /* 16 bit SCIF */ | 54 | # define SCSPTR0 0xfe600024 /* 16 bit SCIF */ |
| 59 | # define SCSPTR1 0xfe610024 /* 16 bit SCIF */ | 55 | # define SCSPTR1 0xfe610024 /* 16 bit SCIF */ |
| 60 | # define SCSPTR2 0xfe620024 /* 16 bit SCIF */ | 56 | # define SCSPTR2 0xfe620024 /* 16 bit SCIF */ |
| 61 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 57 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 62 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 58 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 63 | # define SCIF_ONLY | ||
| 64 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 59 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
| 65 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ | 60 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ |
| 66 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 61 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 67 | # define PACR 0xa4050100 | 62 | # define PACR 0xa4050100 |
| 68 | # define PBCR 0xa4050102 | 63 | # define PBCR 0xa4050102 |
| 69 | # define SCSCR_INIT(port) 0x3B | 64 | # define SCSCR_INIT(port) 0x3B |
| 70 | # define SCIF_ONLY | ||
| 71 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) | 65 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) |
| 72 | # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ | 66 | # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ |
| 73 | # define SCSPTR1 0xffe10010 /* 16 bit SCIF */ | 67 | # define SCSPTR1 0xffe10010 /* 16 bit SCIF */ |
| 74 | # define SCSPTR2 0xffe20010 /* 16 bit SCIF */ | 68 | # define SCSPTR2 0xffe20010 /* 16 bit SCIF */ |
| 75 | # define SCSPTR3 0xffe30010 /* 16 bit SCIF */ | 69 | # define SCSPTR3 0xffe30010 /* 16 bit SCIF */ |
| 76 | # define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */ | 70 | # define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */ |
| 77 | # define SCIF_ONLY | ||
| 78 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 71 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
| 79 | # define PADR 0xA4050120 | 72 | # define PADR 0xA4050120 |
| 80 | # define PSDR 0xA405013e | 73 | # define PSDR 0xA405013e |
| @@ -82,7 +75,6 @@ | |||
| 82 | # define PSCR 0xA405011E | 75 | # define PSCR 0xA405011E |
| 83 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 76 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 84 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 77 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 85 | # define SCIF_ONLY | ||
| 86 | #elif defined(CONFIG_CPU_SUBTYPE_SH7366) | 78 | #elif defined(CONFIG_CPU_SUBTYPE_SH7366) |
| 87 | # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ | 79 | # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ |
| 88 | # define SCSPTR0 SCPDR0 | 80 | # define SCSPTR0 SCPDR0 |
| @@ -97,12 +89,10 @@ | |||
| 97 | # define SCSPTR5 0xa4050128 | 89 | # define SCSPTR5 0xa4050128 |
| 98 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 90 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 99 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 91 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 100 | # define SCIF_ONLY | ||
| 101 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | 92 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) |
| 102 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ | 93 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ |
| 103 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 94 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 104 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 95 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 105 | # define SCIF_ONLY | ||
| 106 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 96 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) |
| 107 | # define SCIF_BASE_ADDR 0x01030000 | 97 | # define SCIF_BASE_ADDR 0x01030000 |
| 108 | # define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR | 98 | # define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR |
| @@ -111,14 +101,11 @@ | |||
| 111 | # define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ | 101 | # define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ |
| 112 | # define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */ | 102 | # define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */ |
| 113 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0, TE=1,RE=1,REIE=1 */ | 103 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0, TE=1,RE=1,REIE=1 */ |
| 114 | # define SCIF_ONLY | ||
| 115 | #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) | 104 | #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) |
| 116 | # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ | 105 | # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ |
| 117 | # define SCI_ONLY | ||
| 118 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | 106 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) |
| 119 | #elif defined(CONFIG_H8S2678) | 107 | #elif defined(CONFIG_H8S2678) |
| 120 | # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ | 108 | # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ |
| 121 | # define SCI_ONLY | ||
| 122 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | 109 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) |
| 123 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 110 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
| 124 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | 111 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ |
| @@ -126,20 +113,17 @@ | |||
| 126 | # define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */ | 113 | # define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */ |
| 127 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 114 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 128 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 115 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 129 | # define SCIF_ONLY | ||
| 130 | #elif defined(CONFIG_CPU_SUBTYPE_SH7770) | 116 | #elif defined(CONFIG_CPU_SUBTYPE_SH7770) |
| 131 | # define SCSPTR0 0xff923020 /* 16 bit SCIF */ | 117 | # define SCSPTR0 0xff923020 /* 16 bit SCIF */ |
| 132 | # define SCSPTR1 0xff924020 /* 16 bit SCIF */ | 118 | # define SCSPTR1 0xff924020 /* 16 bit SCIF */ |
| 133 | # define SCSPTR2 0xff925020 /* 16 bit SCIF */ | 119 | # define SCSPTR2 0xff925020 /* 16 bit SCIF */ |
| 134 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 120 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 135 | # define SCSCR_INIT(port) 0x3c /* TIE=0,RIE=0,TE=1,RE=1,REIE=1,cke=2 */ | 121 | # define SCSCR_INIT(port) 0x3c /* TIE=0,RIE=0,TE=1,RE=1,REIE=1,cke=2 */ |
| 136 | # define SCIF_ONLY | ||
| 137 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | 122 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) |
| 138 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | 123 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ |
| 139 | # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ | 124 | # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ |
| 140 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 125 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
| 141 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 126 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 142 | # define SCIF_ONLY | ||
| 143 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) | 127 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) |
| 144 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ | 128 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ |
| 145 | # define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ | 129 | # define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ |
| @@ -149,7 +133,6 @@ | |||
| 149 | # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ | 133 | # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ |
| 150 | # define SCIF_OPER 0x0001 /* Overrun error bit */ | 134 | # define SCIF_OPER 0x0001 /* Overrun error bit */ |
| 151 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 135 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 152 | # define SCIF_ONLY | ||
| 153 | #elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ | 136 | #elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ |
| 154 | defined(CONFIG_CPU_SUBTYPE_SH7206) || \ | 137 | defined(CONFIG_CPU_SUBTYPE_SH7206) || \ |
| 155 | defined(CONFIG_CPU_SUBTYPE_SH7263) | 138 | defined(CONFIG_CPU_SUBTYPE_SH7263) |
| @@ -158,14 +141,12 @@ | |||
| 158 | # define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ | 141 | # define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ |
| 159 | # define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ | 142 | # define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ |
| 160 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 143 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 161 | # define SCIF_ONLY | ||
| 162 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) | 144 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) |
| 163 | # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ | 145 | # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ |
| 164 | # define SCSPTR1 0xf8410020 /* 16 bit SCIF */ | 146 | # define SCSPTR1 0xf8410020 /* 16 bit SCIF */ |
| 165 | # define SCSPTR2 0xf8420020 /* 16 bit SCIF */ | 147 | # define SCSPTR2 0xf8420020 /* 16 bit SCIF */ |
| 166 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 148 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
| 167 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 149 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 168 | # define SCIF_ONLY | ||
| 169 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | 150 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) |
| 170 | # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ | 151 | # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ |
| 171 | # define SCSPTR1 0xffc40020 /* 16 bit SCIF */ | 152 | # define SCSPTR1 0xffc40020 /* 16 bit SCIF */ |
| @@ -173,7 +154,6 @@ | |||
| 173 | # define SCSPTR3 0xffc60020 /* 16 bit SCIF */ | 154 | # define SCSPTR3 0xffc60020 /* 16 bit SCIF */ |
| 174 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 155 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
| 175 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 156 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
| 176 | # define SCIF_ONLY | ||
| 177 | #else | 157 | #else |
| 178 | # error CPU subtype not defined | 158 | # error CPU subtype not defined |
| 179 | #endif | 159 | #endif |
| @@ -186,6 +166,7 @@ | |||
| 186 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | 166 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
| 187 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ | 167 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ |
| 188 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | 168 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ |
| 169 | defined(CONFIG_CPU_SUBTYPE_SH7722) || \ | ||
| 189 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | 170 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ |
| 190 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | 171 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ |
| 191 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ | 172 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ |
| @@ -244,55 +225,28 @@ | |||
| 244 | # define SCIF_TXROOM_MAX 16 | 225 | # define SCIF_TXROOM_MAX 16 |
| 245 | #endif | 226 | #endif |
| 246 | 227 | ||
| 247 | #if defined(SCI_ONLY) | 228 | #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) |
| 248 | # define SCxSR_TEND(port) SCI_TEND | 229 | #define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) |
| 249 | # define SCxSR_ERRORS(port) SCI_ERRORS | 230 | #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) |
| 250 | # define SCxSR_RDxF(port) SCI_RDRF | 231 | #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) |
| 251 | # define SCxSR_TDxE(port) SCI_TDRE | 232 | #define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) |
| 252 | # define SCxSR_ORER(port) SCI_ORER | 233 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) |
| 253 | # define SCxSR_FER(port) SCI_FER | 234 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) |
| 254 | # define SCxSR_PER(port) SCI_PER | 235 | |
| 255 | # define SCxSR_BRK(port) 0x00 | ||
| 256 | # define SCxSR_RDxF_CLEAR(port) 0xbc | ||
| 257 | # define SCxSR_ERROR_CLEAR(port) 0xc4 | ||
| 258 | # define SCxSR_TDxE_CLEAR(port) 0x78 | ||
| 259 | # define SCxSR_BREAK_CLEAR(port) 0xc4 | ||
| 260 | #elif defined(SCIF_ONLY) | ||
| 261 | # define SCxSR_TEND(port) SCIF_TEND | ||
| 262 | # define SCxSR_ERRORS(port) SCIF_ERRORS | ||
| 263 | # define SCxSR_RDxF(port) SCIF_RDF | ||
| 264 | # define SCxSR_TDxE(port) SCIF_TDFE | ||
| 265 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) | 236 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) |
| 266 | # define SCxSR_ORER(port) SCIF_ORER | 237 | # define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER) |
| 267 | #else | 238 | #else |
| 268 | # define SCxSR_ORER(port) 0x0000 | 239 | # define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : 0x0000) |
| 269 | #endif | 240 | #endif |
| 270 | # define SCxSR_FER(port) SCIF_FER | 241 | |
| 271 | # define SCxSR_PER(port) SCIF_PER | ||
| 272 | # define SCxSR_BRK(port) SCIF_BRK | ||
| 273 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 242 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
| 274 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 243 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
| 275 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 244 | defined(CONFIG_CPU_SUBTYPE_SH7721) |
| 276 | # define SCxSR_RDxF_CLEAR(port) (sci_in(port,SCxSR)&0xfffc) | 245 | # define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) |
| 277 | # define SCxSR_ERROR_CLEAR(port) (sci_in(port,SCxSR)&0xfd73) | 246 | # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) |
| 278 | # define SCxSR_TDxE_CLEAR(port) (sci_in(port,SCxSR)&0xffdf) | 247 | # define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) |
| 279 | # define SCxSR_BREAK_CLEAR(port) (sci_in(port,SCxSR)&0xffe3) | 248 | # define SCxSR_BREAK_CLEAR(port) (sci_in(port, SCxSR) & 0xffe3) |
| 280 | #else | ||
| 281 | /* SH7705 can also use this, clearing is same between 7705 and 7709 */ | ||
| 282 | # define SCxSR_RDxF_CLEAR(port) 0x00fc | ||
| 283 | # define SCxSR_ERROR_CLEAR(port) 0x0073 | ||
| 284 | # define SCxSR_TDxE_CLEAR(port) 0x00df | ||
| 285 | # define SCxSR_BREAK_CLEAR(port) 0x00e3 | ||
| 286 | #endif | ||
| 287 | #else | 249 | #else |
| 288 | # define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) | ||
| 289 | # define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) | ||
| 290 | # define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) | ||
| 291 | # define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) | ||
| 292 | # define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : 0x0000) | ||
| 293 | # define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) | ||
| 294 | # define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) | ||
| 295 | # define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) | ||
| 296 | # define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc) | 250 | # define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc) |
| 297 | # define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073) | 251 | # define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073) |
| 298 | # define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df) | 252 | # define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df) |
| @@ -335,18 +289,18 @@ | |||
| 335 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | 289 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ |
| 336 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ | 290 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ |
| 337 | { \ | 291 | { \ |
| 338 | if (port->type == PORT_SCI) { \ | 292 | if (port->type == PORT_SCIF) { \ |
| 339 | SCI_IN(sci_size, sci_offset) \ | 293 | SCI_IN(scif_size, scif_offset) \ |
| 340 | } else { \ | 294 | } else { /* PORT_SCI or PORT_SCIFA */ \ |
| 341 | SCI_IN(scif_size, scif_offset); \ | 295 | SCI_IN(sci_size, sci_offset); \ |
| 342 | } \ | 296 | } \ |
| 343 | } \ | 297 | } \ |
| 344 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ | 298 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ |
| 345 | { \ | 299 | { \ |
| 346 | if (port->type == PORT_SCI) { \ | 300 | if (port->type == PORT_SCIF) { \ |
| 347 | SCI_OUT(sci_size, sci_offset, value) \ | 301 | SCI_OUT(scif_size, scif_offset, value) \ |
| 348 | } else { \ | 302 | } else { /* PORT_SCI or PORT_SCIFA */ \ |
| 349 | SCI_OUT(scif_size, scif_offset, value); \ | 303 | SCI_OUT(sci_size, sci_offset, value); \ |
| 350 | } \ | 304 | } \ |
| 351 | } | 305 | } |
| 352 | 306 | ||
| @@ -574,18 +528,20 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
| 574 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ | 528 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ |
| 575 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | 529 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ |
| 576 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | 530 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ |
| 577 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ | 531 | defined(CONFIG_CPU_SUBTYPE_SH7091) |
| 578 | defined(CONFIG_CPU_SUBTYPE_SH4_202) | ||
| 579 | static inline int sci_rxd_in(struct uart_port *port) | 532 | static inline int sci_rxd_in(struct uart_port *port) |
| 580 | { | 533 | { |
| 581 | #ifndef SCIF_ONLY | ||
| 582 | if (port->mapbase == 0xffe00000) | 534 | if (port->mapbase == 0xffe00000) |
| 583 | return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ | 535 | return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ |
| 584 | #endif | ||
| 585 | #ifndef SCI_ONLY | ||
| 586 | if (port->mapbase == 0xffe80000) | 536 | if (port->mapbase == 0xffe80000) |
| 587 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ | 537 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ |
| 588 | #endif | 538 | return 1; |
| 539 | } | ||
| 540 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | ||
| 541 | static inline int sci_rxd_in(struct uart_port *port) | ||
| 542 | { | ||
| 543 | if (port->mapbase == 0xffe80000) | ||
| 544 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ | ||
| 589 | return 1; | 545 | return 1; |
| 590 | } | 546 | } |
| 591 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | 547 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) |
| @@ -651,7 +607,7 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
| 651 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 607 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) |
| 652 | static inline int sci_rxd_in(struct uart_port *port) | 608 | static inline int sci_rxd_in(struct uart_port *port) |
| 653 | { | 609 | { |
| 654 | return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */ | 610 | return sci_in(port, SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ |
| 655 | } | 611 | } |
| 656 | #elif defined(__H8300H__) || defined(__H8300S__) | 612 | #elif defined(__H8300H__) || defined(__H8300S__) |
| 657 | static inline int sci_rxd_in(struct uart_port *port) | 613 | static inline int sci_rxd_in(struct uart_port *port) |
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 6a3f8fb0c9dd..3317148a4b93 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
| @@ -286,8 +286,8 @@ static void ulite_release_port(struct uart_port *port) | |||
| 286 | 286 | ||
| 287 | static int ulite_request_port(struct uart_port *port) | 287 | static int ulite_request_port(struct uart_port *port) |
| 288 | { | 288 | { |
| 289 | pr_debug("ulite console: port=%p; port->mapbase=%x\n", | 289 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", |
| 290 | port, port->mapbase); | 290 | port, (unsigned long long) port->mapbase); |
| 291 | 291 | ||
| 292 | if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) { | 292 | if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) { |
| 293 | dev_err(port->dev, "Memory region busy\n"); | 293 | dev_err(port->dev, "Memory region busy\n"); |
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 02f9320f3efc..8abae4ad0fa5 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
| @@ -766,6 +766,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
| 766 | /* Initialize the hardware */ | 766 | /* Initialize the hardware */ |
| 767 | clk_enable(clk); | 767 | clk_enable(clk); |
| 768 | spi_writel(as, CR, SPI_BIT(SWRST)); | 768 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 769 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | ||
| 769 | spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); | 770 | spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); |
| 770 | spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); | 771 | spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); |
| 771 | spi_writel(as, CR, SPI_BIT(SPIEN)); | 772 | spi_writel(as, CR, SPI_BIT(SPIEN)); |
| @@ -782,6 +783,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
| 782 | 783 | ||
| 783 | out_reset_hw: | 784 | out_reset_hw: |
| 784 | spi_writel(as, CR, SPI_BIT(SWRST)); | 785 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 786 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | ||
| 785 | clk_disable(clk); | 787 | clk_disable(clk); |
| 786 | free_irq(irq, master); | 788 | free_irq(irq, master); |
| 787 | out_unmap_regs: | 789 | out_unmap_regs: |
| @@ -805,6 +807,7 @@ static int __exit atmel_spi_remove(struct platform_device *pdev) | |||
| 805 | spin_lock_irq(&as->lock); | 807 | spin_lock_irq(&as->lock); |
| 806 | as->stopping = 1; | 808 | as->stopping = 1; |
| 807 | spi_writel(as, CR, SPI_BIT(SWRST)); | 809 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 810 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | ||
| 808 | spi_readl(as, SR); | 811 | spi_readl(as, SR); |
| 809 | spin_unlock_irq(&as->lock); | 812 | spin_unlock_irq(&as->lock); |
| 810 | 813 | ||
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index 87b73e0169c5..b02f25c702fd 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c | |||
| @@ -369,10 +369,23 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) | |||
| 369 | dma_rx_addr = t->rx_dma; | 369 | dma_rx_addr = t->rx_dma; |
| 370 | 370 | ||
| 371 | /* | 371 | /* |
| 372 | * check if buffers are already dma mapped, map them otherwise | 372 | * check if buffers are already dma mapped, map them otherwise: |
| 373 | * - first map the TX buffer, so cache data gets written to memory | ||
| 374 | * - then map the RX buffer, so that cache entries (with | ||
| 375 | * soon-to-be-stale data) get removed | ||
| 373 | * use rx buffer in place of tx if tx buffer was not provided | 376 | * use rx buffer in place of tx if tx buffer was not provided |
| 374 | * use temp rx buffer (preallocated or realloc to fit) for rx dma | 377 | * use temp rx buffer (preallocated or realloc to fit) for rx dma |
| 375 | */ | 378 | */ |
| 379 | if (t->tx_buf) { | ||
| 380 | if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ | ||
| 381 | dma_tx_addr = dma_map_single(hw->dev, | ||
| 382 | (void *)t->tx_buf, | ||
| 383 | t->len, DMA_TO_DEVICE); | ||
| 384 | if (dma_mapping_error(hw->dev, dma_tx_addr)) | ||
| 385 | dev_err(hw->dev, "tx dma map error\n"); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 376 | if (t->rx_buf) { | 389 | if (t->rx_buf) { |
| 377 | if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ | 390 | if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ |
| 378 | dma_rx_addr = dma_map_single(hw->dev, | 391 | dma_rx_addr = dma_map_single(hw->dev, |
| @@ -396,15 +409,8 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) | |||
| 396 | dma_sync_single_for_device(hw->dev, dma_rx_addr, | 409 | dma_sync_single_for_device(hw->dev, dma_rx_addr, |
| 397 | t->len, DMA_FROM_DEVICE); | 410 | t->len, DMA_FROM_DEVICE); |
| 398 | } | 411 | } |
| 399 | if (t->tx_buf) { | 412 | |
| 400 | if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ | 413 | if (!t->tx_buf) { |
| 401 | dma_tx_addr = dma_map_single(hw->dev, | ||
| 402 | (void *)t->tx_buf, | ||
| 403 | t->len, DMA_TO_DEVICE); | ||
| 404 | if (dma_mapping_error(hw->dev, dma_tx_addr)) | ||
| 405 | dev_err(hw->dev, "tx dma map error\n"); | ||
| 406 | } | ||
| 407 | } else { | ||
| 408 | dma_sync_single_for_device(hw->dev, dma_rx_addr, | 414 | dma_sync_single_for_device(hw->dev, dma_rx_addr, |
| 409 | t->len, DMA_BIDIRECTIONAL); | 415 | t->len, DMA_BIDIRECTIONAL); |
| 410 | hw->tx = hw->rx; | 416 | hw->tx = hw->rx; |
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 0debe11b67b4..3b97803e1d11 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c | |||
| @@ -142,6 +142,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, | |||
| 142 | unsigned rfalarm; | 142 | unsigned rfalarm; |
| 143 | unsigned send_at_once = MPC52xx_PSC_BUFSIZE; | 143 | unsigned send_at_once = MPC52xx_PSC_BUFSIZE; |
| 144 | unsigned recv_at_once; | 144 | unsigned recv_at_once; |
| 145 | int last_block = 0; | ||
| 145 | 146 | ||
| 146 | if (!t->tx_buf && !t->rx_buf && t->len) | 147 | if (!t->tx_buf && !t->rx_buf && t->len) |
| 147 | return -EINVAL; | 148 | return -EINVAL; |
| @@ -151,15 +152,17 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, | |||
| 151 | while (rb < t->len) { | 152 | while (rb < t->len) { |
| 152 | if (t->len - rb > MPC52xx_PSC_BUFSIZE) { | 153 | if (t->len - rb > MPC52xx_PSC_BUFSIZE) { |
| 153 | rfalarm = MPC52xx_PSC_RFALARM; | 154 | rfalarm = MPC52xx_PSC_RFALARM; |
| 155 | last_block = 0; | ||
| 154 | } else { | 156 | } else { |
| 155 | send_at_once = t->len - sb; | 157 | send_at_once = t->len - sb; |
| 156 | rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb); | 158 | rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb); |
| 159 | last_block = 1; | ||
| 157 | } | 160 | } |
| 158 | 161 | ||
| 159 | dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once); | 162 | dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once); |
| 160 | for (; send_at_once; sb++, send_at_once--) { | 163 | for (; send_at_once; sb++, send_at_once--) { |
| 161 | /* set EOF flag before the last word is sent */ | 164 | /* set EOF flag before the last word is sent */ |
| 162 | if (send_at_once == 1) | 165 | if (send_at_once == 1 && last_block) |
| 163 | out_8(&psc->ircr2, 0x01); | 166 | out_8(&psc->ircr2, 0x01); |
| 164 | 167 | ||
| 165 | if (tx_buf) | 168 | if (tx_buf) |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index dae87b1a4c6e..cf12f2d84be2 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
| @@ -352,21 +352,21 @@ static int map_dma_buffers(struct driver_data *drv_data) | |||
| 352 | } else | 352 | } else |
| 353 | drv_data->tx_map_len = drv_data->len; | 353 | drv_data->tx_map_len = drv_data->len; |
| 354 | 354 | ||
| 355 | /* Stream map the rx buffer */ | 355 | /* Stream map the tx buffer. Always do DMA_TO_DEVICE first |
| 356 | drv_data->rx_dma = dma_map_single(dev, drv_data->rx, | 356 | * so we flush the cache *before* invalidating it, in case |
| 357 | drv_data->rx_map_len, | 357 | * the tx and rx buffers overlap. |
| 358 | DMA_FROM_DEVICE); | 358 | */ |
| 359 | if (dma_mapping_error(dev, drv_data->rx_dma)) | ||
| 360 | return 0; | ||
| 361 | |||
| 362 | /* Stream map the tx buffer */ | ||
| 363 | drv_data->tx_dma = dma_map_single(dev, drv_data->tx, | 359 | drv_data->tx_dma = dma_map_single(dev, drv_data->tx, |
| 364 | drv_data->tx_map_len, | 360 | drv_data->tx_map_len, DMA_TO_DEVICE); |
| 365 | DMA_TO_DEVICE); | 361 | if (dma_mapping_error(dev, drv_data->tx_dma)) |
| 362 | return 0; | ||
| 366 | 363 | ||
| 367 | if (dma_mapping_error(dev, drv_data->tx_dma)) { | 364 | /* Stream map the rx buffer */ |
| 368 | dma_unmap_single(dev, drv_data->rx_dma, | 365 | drv_data->rx_dma = dma_map_single(dev, drv_data->rx, |
| 369 | drv_data->rx_map_len, DMA_FROM_DEVICE); | 366 | drv_data->rx_map_len, DMA_FROM_DEVICE); |
| 367 | if (dma_mapping_error(dev, drv_data->rx_dma)) { | ||
| 368 | dma_unmap_single(dev, drv_data->tx_dma, | ||
| 369 | drv_data->tx_map_len, DMA_TO_DEVICE); | ||
| 370 | return 0; | 370 | return 0; |
| 371 | } | 371 | } |
| 372 | 372 | ||
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 61ba147e384d..269a55ec52ef 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
| @@ -506,20 +506,6 @@ static int map_dma_buffers(struct driver_data *drv_data) | |||
| 506 | if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx)) | 506 | if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx)) |
| 507 | return -1; | 507 | return -1; |
| 508 | 508 | ||
| 509 | /* NULL rx means write-only transfer and no map needed | ||
| 510 | since rx DMA will not be used */ | ||
| 511 | if (drv_data->rx) { | ||
| 512 | buf = drv_data->rx; | ||
| 513 | drv_data->rx_dma = dma_map_single( | ||
| 514 | dev, | ||
| 515 | buf, | ||
| 516 | drv_data->len, | ||
| 517 | DMA_FROM_DEVICE); | ||
| 518 | if (dma_mapping_error(dev, drv_data->rx_dma)) | ||
| 519 | return -1; | ||
| 520 | drv_data->rx_dma_needs_unmap = 1; | ||
| 521 | } | ||
| 522 | |||
| 523 | if (drv_data->tx == NULL) { | 509 | if (drv_data->tx == NULL) { |
| 524 | /* Read only message --> use drv_data->dummy_dma_buf for dummy | 510 | /* Read only message --> use drv_data->dummy_dma_buf for dummy |
| 525 | writes to achive reads */ | 511 | writes to achive reads */ |
| @@ -533,18 +519,31 @@ static int map_dma_buffers(struct driver_data *drv_data) | |||
| 533 | buf, | 519 | buf, |
| 534 | drv_data->tx_map_len, | 520 | drv_data->tx_map_len, |
| 535 | DMA_TO_DEVICE); | 521 | DMA_TO_DEVICE); |
| 536 | if (dma_mapping_error(dev, drv_data->tx_dma)) { | 522 | if (dma_mapping_error(dev, drv_data->tx_dma)) |
| 537 | if (drv_data->rx_dma) { | ||
| 538 | dma_unmap_single(dev, | ||
| 539 | drv_data->rx_dma, | ||
| 540 | drv_data->len, | ||
| 541 | DMA_FROM_DEVICE); | ||
| 542 | drv_data->rx_dma_needs_unmap = 0; | ||
| 543 | } | ||
| 544 | return -1; | 523 | return -1; |
| 545 | } | ||
| 546 | drv_data->tx_dma_needs_unmap = 1; | 524 | drv_data->tx_dma_needs_unmap = 1; |
| 547 | 525 | ||
| 526 | /* NULL rx means write-only transfer and no map needed | ||
| 527 | * since rx DMA will not be used */ | ||
| 528 | if (drv_data->rx) { | ||
| 529 | buf = drv_data->rx; | ||
| 530 | drv_data->rx_dma = dma_map_single(dev, | ||
| 531 | buf, | ||
| 532 | drv_data->len, | ||
| 533 | DMA_FROM_DEVICE); | ||
| 534 | if (dma_mapping_error(dev, drv_data->rx_dma)) { | ||
| 535 | if (drv_data->tx_dma) { | ||
| 536 | dma_unmap_single(dev, | ||
| 537 | drv_data->tx_dma, | ||
| 538 | drv_data->tx_map_len, | ||
| 539 | DMA_TO_DEVICE); | ||
| 540 | drv_data->tx_dma_needs_unmap = 0; | ||
| 541 | } | ||
| 542 | return -1; | ||
| 543 | } | ||
| 544 | drv_data->rx_dma_needs_unmap = 1; | ||
| 545 | } | ||
| 546 | |||
| 548 | return 0; | 547 | return 0; |
| 549 | } | 548 | } |
| 550 | 549 | ||
| @@ -1457,7 +1456,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
| 1457 | struct device *dev = &pdev->dev; | 1456 | struct device *dev = &pdev->dev; |
| 1458 | struct spi_imx_master *platform_info; | 1457 | struct spi_imx_master *platform_info; |
| 1459 | struct spi_master *master; | 1458 | struct spi_master *master; |
| 1460 | struct driver_data *drv_data = NULL; | 1459 | struct driver_data *drv_data; |
| 1461 | struct resource *res; | 1460 | struct resource *res; |
| 1462 | int irq, status = 0; | 1461 | int irq, status = 0; |
| 1463 | 1462 | ||
| @@ -1468,14 +1467,6 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
| 1468 | goto err_no_pdata; | 1467 | goto err_no_pdata; |
| 1469 | } | 1468 | } |
| 1470 | 1469 | ||
| 1471 | drv_data->clk = clk_get(&pdev->dev, "perclk2"); | ||
| 1472 | if (IS_ERR(drv_data->clk)) { | ||
| 1473 | dev_err(&pdev->dev, "probe - cannot get get\n"); | ||
| 1474 | status = PTR_ERR(drv_data->clk); | ||
| 1475 | goto err_no_clk; | ||
| 1476 | } | ||
| 1477 | clk_enable(drv_data->clk); | ||
| 1478 | |||
| 1479 | /* Allocate master with space for drv_data */ | 1470 | /* Allocate master with space for drv_data */ |
| 1480 | master = spi_alloc_master(dev, sizeof(struct driver_data)); | 1471 | master = spi_alloc_master(dev, sizeof(struct driver_data)); |
| 1481 | if (!master) { | 1472 | if (!master) { |
| @@ -1496,6 +1487,14 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
| 1496 | 1487 | ||
| 1497 | drv_data->dummy_dma_buf = SPI_DUMMY_u32; | 1488 | drv_data->dummy_dma_buf = SPI_DUMMY_u32; |
| 1498 | 1489 | ||
| 1490 | drv_data->clk = clk_get(&pdev->dev, "perclk2"); | ||
| 1491 | if (IS_ERR(drv_data->clk)) { | ||
| 1492 | dev_err(&pdev->dev, "probe - cannot get clock\n"); | ||
| 1493 | status = PTR_ERR(drv_data->clk); | ||
| 1494 | goto err_no_clk; | ||
| 1495 | } | ||
| 1496 | clk_enable(drv_data->clk); | ||
| 1497 | |||
| 1499 | /* Find and map resources */ | 1498 | /* Find and map resources */ |
| 1500 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1499 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1501 | if (!res) { | 1500 | if (!res) { |
| @@ -1631,12 +1630,13 @@ err_no_iomap: | |||
| 1631 | kfree(drv_data->ioarea); | 1630 | kfree(drv_data->ioarea); |
| 1632 | 1631 | ||
| 1633 | err_no_iores: | 1632 | err_no_iores: |
| 1634 | spi_master_put(master); | ||
| 1635 | |||
| 1636 | err_no_pdata: | ||
| 1637 | clk_disable(drv_data->clk); | 1633 | clk_disable(drv_data->clk); |
| 1638 | clk_put(drv_data->clk); | 1634 | clk_put(drv_data->clk); |
| 1635 | |||
| 1639 | err_no_clk: | 1636 | err_no_clk: |
| 1637 | spi_master_put(master); | ||
| 1638 | |||
| 1639 | err_no_pdata: | ||
| 1640 | err_no_mem: | 1640 | err_no_mem: |
| 1641 | return status; | 1641 | return status; |
| 1642 | } | 1642 | } |
diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c index cc1f647f579b..f2447a5476bb 100644 --- a/drivers/spi/spi_s3c24xx_gpio.c +++ b/drivers/spi/spi_s3c24xx_gpio.c | |||
| @@ -34,7 +34,7 @@ struct s3c2410_spigpio { | |||
| 34 | 34 | ||
| 35 | static inline struct s3c2410_spigpio *spidev_to_sg(struct spi_device *spi) | 35 | static inline struct s3c2410_spigpio *spidev_to_sg(struct spi_device *spi) |
| 36 | { | 36 | { |
| 37 | return spi->controller_data; | 37 | return spi_master_get_devdata(spi->master); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | static inline void setsck(struct spi_device *dev, int on) | 40 | static inline void setsck(struct spi_device *dev, int on) |
| @@ -118,6 +118,7 @@ static int s3c2410_spigpio_probe(struct platform_device *dev) | |||
| 118 | /* setup spi bitbang adaptor */ | 118 | /* setup spi bitbang adaptor */ |
| 119 | sp->bitbang.master = spi_master_get(master); | 119 | sp->bitbang.master = spi_master_get(master); |
| 120 | sp->bitbang.master->bus_num = info->bus_num; | 120 | sp->bitbang.master->bus_num = info->bus_num; |
| 121 | sp->bitbang.master->num_chipselect = info->num_chipselect; | ||
| 121 | sp->bitbang.chipselect = s3c2410_spigpio_chipselect; | 122 | sp->bitbang.chipselect = s3c2410_spigpio_chipselect; |
| 122 | 123 | ||
| 123 | sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0; | 124 | sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0; |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 89a43755a453..5d869c4d3eb2 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
| @@ -597,7 +597,9 @@ static int spidev_probe(struct spi_device *spi) | |||
| 597 | } | 597 | } |
| 598 | mutex_unlock(&device_list_lock); | 598 | mutex_unlock(&device_list_lock); |
| 599 | 599 | ||
| 600 | if (status != 0) | 600 | if (status == 0) |
| 601 | spi_set_drvdata(spi, spidev); | ||
| 602 | else | ||
| 601 | kfree(spidev); | 603 | kfree(spidev); |
| 602 | 604 | ||
| 603 | return status; | 605 | return status; |
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 307b1f62d949..b1b947edcf01 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | menu "Sonics Silicon Backplane" | ||
| 2 | |||
| 3 | config SSB_POSSIBLE | 1 | config SSB_POSSIBLE |
| 4 | bool | 2 | bool |
| 5 | depends on HAS_IOMEM && HAS_DMA | 3 | depends on HAS_IOMEM && HAS_DMA |
| 6 | default y | 4 | default y |
| 7 | 5 | ||
| 6 | menu "Sonics Silicon Backplane" | ||
| 7 | depends on SSB_POSSIBLE | ||
| 8 | |||
| 8 | config SSB | 9 | config SSB |
| 9 | tristate "Sonics Silicon Backplane support" | 10 | tristate "Sonics Silicon Backplane support" |
| 10 | depends on SSB_POSSIBLE | 11 | depends on SSB_POSSIBLE |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e1654f59eb70..c95b286a1239 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
| @@ -21,7 +21,23 @@ menuconfig STAGING | |||
| 21 | 21 | ||
| 22 | If in doubt, say N here. | 22 | If in doubt, say N here. |
| 23 | 23 | ||
| 24 | if STAGING | 24 | |
| 25 | config STAGING_EXCLUDE_BUILD | ||
| 26 | bool "Exclude Staging drivers from being built" if STAGING | ||
| 27 | default y | ||
| 28 | ---help--- | ||
| 29 | Are you sure you really want to build the staging drivers? | ||
| 30 | They taint your kernel, don't live up to the normal Linux | ||
| 31 | kernel quality standards, are a bit crufty around the edges, | ||
| 32 | and might go off and kick your dog when you aren't paying | ||
| 33 | attention. | ||
| 34 | |||
| 35 | Say N here to be able to select and build the Staging drivers. | ||
| 36 | This option is primarily here to prevent them from being built | ||
| 37 | when selecting 'make allyesconfg' and 'make allmodconfig' so | ||
| 38 | don't be all that put off, your dog will be just fine. | ||
| 39 | |||
| 40 | if !STAGING_EXCLUDE_BUILD | ||
| 25 | 41 | ||
| 26 | source "drivers/staging/et131x/Kconfig" | 42 | source "drivers/staging/et131x/Kconfig" |
| 27 | 43 | ||
| @@ -45,4 +61,4 @@ source "drivers/staging/at76_usb/Kconfig" | |||
| 45 | 61 | ||
| 46 | source "drivers/staging/poch/Kconfig" | 62 | source "drivers/staging/poch/Kconfig" |
| 47 | 63 | ||
| 48 | endif # STAGING | 64 | endif # !STAGING_EXCLUDE_BUILD |
diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c index b8f2c5e9dee5..fd4007e329e7 100644 --- a/drivers/staging/echo/echo.c +++ b/drivers/staging/echo/echo.c | |||
| @@ -106,7 +106,6 @@ | |||
| 106 | 106 | ||
| 107 | #include <linux/kernel.h> /* We're doing kernel work */ | 107 | #include <linux/kernel.h> /* We're doing kernel work */ |
| 108 | #include <linux/module.h> | 108 | #include <linux/module.h> |
| 109 | #include <linux/kernel.h> | ||
| 110 | #include <linux/slab.h> | 109 | #include <linux/slab.h> |
| 111 | 110 | ||
| 112 | #include "bit_operations.h" | 111 | #include "bit_operations.h" |
diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c index 0b33773bb4f6..0394e2709278 100644 --- a/drivers/staging/me4000/me4000.c +++ b/drivers/staging/me4000/me4000.c | |||
| @@ -39,7 +39,6 @@ | |||
| 39 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
| 40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
| 41 | #include <asm/system.h> | 41 | #include <asm/system.h> |
| 42 | #include <asm/uaccess.h> | ||
| 43 | 42 | ||
| 44 | /* Include-File for the Meilhaus ME-4000 I/O board */ | 43 | /* Include-File for the Meilhaus ME-4000 I/O board */ |
| 45 | #include "me4000.h" | 44 | #include "me4000.h" |
| @@ -1633,9 +1632,6 @@ static int me4000_release(struct inode *inode_p, struct file *file_p) | |||
| 1633 | 1632 | ||
| 1634 | free_irq(ext_int_context->irq, ext_int_context); | 1633 | free_irq(ext_int_context->irq, ext_int_context); |
| 1635 | 1634 | ||
| 1636 | /* Delete the fasync structure and free memory */ | ||
| 1637 | me4000_ext_int_fasync(0, file_p, 0); | ||
| 1638 | |||
| 1639 | /* Mark as unused */ | 1635 | /* Mark as unused */ |
| 1640 | ext_int_context->in_use = 0; | 1636 | ext_int_context->in_use = 0; |
| 1641 | } else { | 1637 | } else { |
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig index 7426235ccc44..217fb7e62c2f 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/staging/usbip/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config USB_IP_COMMON | 1 | config USB_IP_COMMON |
| 2 | tristate "USB IP support (EXPERIMENTAL)" | 2 | tristate "USB IP support (EXPERIMENTAL)" |
| 3 | depends on USB && EXPERIMENTAL | 3 | depends on USB && NET && EXPERIMENTAL |
| 4 | default N | 4 | default N |
| 5 | ---help--- | 5 | ---help--- |
| 6 | This enables pushing USB packets over IP to allow remote | 6 | This enables pushing USB packets over IP to allow remote |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 41b6530b8f25..a913efc69669 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
| @@ -2328,7 +2328,6 @@ static int ixj_release(struct inode *inode, struct file *file_p) | |||
| 2328 | j->rec_codec = j->play_codec = 0; | 2328 | j->rec_codec = j->play_codec = 0; |
| 2329 | j->rec_frame_size = j->play_frame_size = 0; | 2329 | j->rec_frame_size = j->play_frame_size = 0; |
| 2330 | j->flags.cidsent = j->flags.cidring = 0; | 2330 | j->flags.cidsent = j->flags.cidring = 0; |
| 2331 | ixj_fasync(-1, file_p, 0); /* remove from list of async notification */ | ||
| 2332 | 2331 | ||
| 2333 | if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) { | 2332 | if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) { |
| 2334 | ixj_set_port(j, PORT_PSTN); | 2333 | ixj_set_port(j, PORT_PSTN); |
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index 37caf4d69037..b52cc830c0b4 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
| 9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
| 10 | * | 10 | * |
| 11 | * Author: Alan Cox, <alan@redhat.com> | 11 | * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk> |
| 12 | * | 12 | * |
| 13 | * Fixes: Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com> | 13 | * Fixes: Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com> |
| 14 | * phone_register_device now works with unit!=PHONE_UNIT_ANY | 14 | * phone_register_device now works with unit!=PHONE_UNIT_ANY |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index f9b4647255aa..2d2440cd57a9 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
| @@ -367,9 +367,6 @@ static int uio_release(struct inode *inode, struct file *filep) | |||
| 367 | ret = idev->info->release(idev->info, inode); | 367 | ret = idev->info->release(idev->info, inode); |
| 368 | 368 | ||
| 369 | module_put(idev->owner); | 369 | module_put(idev->owner); |
| 370 | |||
| 371 | if (filep->f_flags & FASYNC) | ||
| 372 | ret = uio_fasync(-1, filep, 0); | ||
| 373 | kfree(listener); | 370 | kfree(listener); |
| 374 | return ret; | 371 | return ret; |
| 375 | } | 372 | } |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 20104443081a..d50a99f70aee 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -158,16 +158,12 @@ static int acm_wb_is_avail(struct acm *acm) | |||
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | /* | 160 | /* |
| 161 | * Finish write. | 161 | * Finish write. Caller must hold acm->write_lock |
| 162 | */ | 162 | */ |
| 163 | static void acm_write_done(struct acm *acm, struct acm_wb *wb) | 163 | static void acm_write_done(struct acm *acm, struct acm_wb *wb) |
| 164 | { | 164 | { |
| 165 | unsigned long flags; | ||
| 166 | |||
| 167 | spin_lock_irqsave(&acm->write_lock, flags); | ||
| 168 | wb->use = 0; | 165 | wb->use = 0; |
| 169 | acm->transmitting--; | 166 | acm->transmitting--; |
| 170 | spin_unlock_irqrestore(&acm->write_lock, flags); | ||
| 171 | } | 167 | } |
| 172 | 168 | ||
| 173 | /* | 169 | /* |
| @@ -482,6 +478,7 @@ static void acm_write_bulk(struct urb *urb) | |||
| 482 | { | 478 | { |
| 483 | struct acm_wb *wb = urb->context; | 479 | struct acm_wb *wb = urb->context; |
| 484 | struct acm *acm = wb->instance; | 480 | struct acm *acm = wb->instance; |
| 481 | unsigned long flags; | ||
| 485 | 482 | ||
| 486 | if (verbose || urb->status | 483 | if (verbose || urb->status |
| 487 | || (urb->actual_length != urb->transfer_buffer_length)) | 484 | || (urb->actual_length != urb->transfer_buffer_length)) |
| @@ -490,7 +487,9 @@ static void acm_write_bulk(struct urb *urb) | |||
| 490 | urb->transfer_buffer_length, | 487 | urb->transfer_buffer_length, |
| 491 | urb->status); | 488 | urb->status); |
| 492 | 489 | ||
| 490 | spin_lock_irqsave(&acm->write_lock, flags); | ||
| 493 | acm_write_done(acm, wb); | 491 | acm_write_done(acm, wb); |
| 492 | spin_unlock_irqrestore(&acm->write_lock, flags); | ||
| 494 | if (ACM_READY(acm)) | 493 | if (ACM_READY(acm)) |
| 495 | schedule_work(&acm->work); | 494 | schedule_work(&acm->work); |
| 496 | else | 495 | else |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 887738577b28..6d1048faf08e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
| 1091 | continue; | 1091 | continue; |
| 1092 | dev_dbg(&dev->dev, "unregistering interface %s\n", | 1092 | dev_dbg(&dev->dev, "unregistering interface %s\n", |
| 1093 | dev_name(&interface->dev)); | 1093 | dev_name(&interface->dev)); |
| 1094 | interface->unregistering = 1; | ||
| 1094 | usb_remove_sysfs_intf_files(interface); | 1095 | usb_remove_sysfs_intf_files(interface); |
| 1095 | device_del(&interface->dev); | 1096 | device_del(&interface->dev); |
| 1096 | } | 1097 | } |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index f66fba11fbd5..4fb65fdc9dc3 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
| @@ -840,7 +840,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) | |||
| 840 | struct usb_host_interface *alt = intf->cur_altsetting; | 840 | struct usb_host_interface *alt = intf->cur_altsetting; |
| 841 | int retval; | 841 | int retval; |
| 842 | 842 | ||
| 843 | if (intf->sysfs_files_created) | 843 | if (intf->sysfs_files_created || intf->unregistering) |
| 844 | return 0; | 844 | return 0; |
| 845 | 845 | ||
| 846 | /* The interface string may be present in some altsettings | 846 | /* The interface string may be present in some altsettings |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 4342bd9c3bb6..1f68af9db3f7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
| @@ -85,8 +85,8 @@ EXPORT_SYMBOL_GPL(usb_alloc_urb); | |||
| 85 | * Must be called when a user of a urb is finished with it. When the last user | 85 | * Must be called when a user of a urb is finished with it. When the last user |
| 86 | * of the urb calls this function, the memory of the urb is freed. | 86 | * of the urb calls this function, the memory of the urb is freed. |
| 87 | * | 87 | * |
| 88 | * Note: The transfer buffer associated with the urb is not freed, that must be | 88 | * Note: The transfer buffer associated with the urb is not freed unless the |
| 89 | * done elsewhere. | 89 | * URB_FREE_BUFFER transfer flag is set. |
| 90 | */ | 90 | */ |
| 91 | void usb_free_urb(struct urb *urb) | 91 | void usb_free_urb(struct urb *urb) |
| 92 | { | 92 | { |
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 5ee1590b8e9c..c1d34df0b157 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
| @@ -463,7 +463,11 @@ static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value, | |||
| 463 | notify->wLength = cpu_to_le16(length); | 463 | notify->wLength = cpu_to_le16(length); |
| 464 | memcpy(buf, data, length); | 464 | memcpy(buf, data, length); |
| 465 | 465 | ||
| 466 | /* ep_queue() can complete immediately if it fills the fifo... */ | ||
| 467 | spin_unlock(&acm->lock); | ||
| 466 | status = usb_ep_queue(ep, req, GFP_ATOMIC); | 468 | status = usb_ep_queue(ep, req, GFP_ATOMIC); |
| 469 | spin_lock(&acm->lock); | ||
| 470 | |||
| 467 | if (status < 0) { | 471 | if (status < 0) { |
| 468 | ERROR(acm->port.func.config->cdev, | 472 | ERROR(acm->port.func.config->cdev, |
| 469 | "acm ttyGS%d can't notify serial state, %d\n", | 473 | "acm ttyGS%d can't notify serial state, %d\n", |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 659b3d9671c4..428b5993575a 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
| @@ -172,7 +172,6 @@ static struct usb_interface_descriptor rndis_data_intf __initdata = { | |||
| 172 | .bDescriptorType = USB_DT_INTERFACE, | 172 | .bDescriptorType = USB_DT_INTERFACE, |
| 173 | 173 | ||
| 174 | /* .bInterfaceNumber = DYNAMIC */ | 174 | /* .bInterfaceNumber = DYNAMIC */ |
| 175 | .bAlternateSetting = 1, | ||
| 176 | .bNumEndpoints = 2, | 175 | .bNumEndpoints = 2, |
| 177 | .bInterfaceClass = USB_CLASS_CDC_DATA, | 176 | .bInterfaceClass = USB_CLASS_CDC_DATA, |
| 178 | .bInterfaceSubClass = 0, | 177 | .bInterfaceSubClass = 0, |
| @@ -303,7 +302,7 @@ static void rndis_response_available(void *_rndis) | |||
| 303 | __le32 *data = req->buf; | 302 | __le32 *data = req->buf; |
| 304 | int status; | 303 | int status; |
| 305 | 304 | ||
| 306 | if (atomic_inc_return(&rndis->notify_count)) | 305 | if (atomic_inc_return(&rndis->notify_count) != 1) |
| 307 | return; | 306 | return; |
| 308 | 307 | ||
| 309 | /* Send RNDIS RESPONSE_AVAILABLE notification; a | 308 | /* Send RNDIS RESPONSE_AVAILABLE notification; a |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 1fe8b44787b3..b3408ff39fba 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
| @@ -2363,6 +2363,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 2363 | nuke(loop_ep, -ESHUTDOWN); | 2363 | nuke(loop_ep, -ESHUTDOWN); |
| 2364 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 2364 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
| 2365 | 2365 | ||
| 2366 | /* report disconnect; the controller is already quiesced */ | ||
| 2367 | driver->disconnect(&udc_controller->gadget); | ||
| 2368 | |||
| 2366 | /* unbind gadget and unhook driver. */ | 2369 | /* unbind gadget and unhook driver. */ |
| 2367 | driver->unbind(&udc_controller->gadget); | 2370 | driver->unbind(&udc_controller->gadget); |
| 2368 | udc_controller->gadget.dev.driver = NULL; | 2371 | udc_controller->gadget.dev.driver = NULL; |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 091bb55c9aa7..f3c6703cffda 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
| @@ -1836,6 +1836,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1836 | nuke(loop_ep, -ESHUTDOWN); | 1836 | nuke(loop_ep, -ESHUTDOWN); |
| 1837 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 1837 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
| 1838 | 1838 | ||
| 1839 | /* report disconnect; the controller is already quiesced */ | ||
| 1840 | driver->disconnect(&udc_controller->gadget); | ||
| 1841 | |||
| 1839 | /* unbind gadget and unhook driver. */ | 1842 | /* unbind gadget and unhook driver. */ |
| 1840 | driver->unbind(&udc_controller->gadget); | 1843 | driver->unbind(&udc_controller->gadget); |
| 1841 | udc_controller->gadget.dev.driver = NULL; | 1844 | udc_controller->gadget.dev.driver = NULL; |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index f4585d3e90d7..eeb26c0f88e5 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
| @@ -1251,7 +1251,6 @@ dev_release (struct inode *inode, struct file *fd) | |||
| 1251 | * alternatively, all host requests will time out. | 1251 | * alternatively, all host requests will time out. |
| 1252 | */ | 1252 | */ |
| 1253 | 1253 | ||
| 1254 | fasync_helper (-1, fd, 0, &dev->fasync); | ||
| 1255 | kfree (dev->buf); | 1254 | kfree (dev->buf); |
| 1256 | dev->buf = NULL; | 1255 | dev->buf = NULL; |
| 1257 | put_dev (dev); | 1256 | put_dev (dev); |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index da6e93c201d2..2dbc0db0b46c 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
| @@ -141,7 +141,11 @@ static int is_vbus_present(void) | |||
| 141 | 141 | ||
| 142 | if (mach->gpio_vbus) { | 142 | if (mach->gpio_vbus) { |
| 143 | int value = gpio_get_value(mach->gpio_vbus); | 143 | int value = gpio_get_value(mach->gpio_vbus); |
| 144 | return mach->gpio_vbus_inverted ? !value : value; | 144 | |
| 145 | if (mach->gpio_vbus_inverted) | ||
| 146 | return !value; | ||
| 147 | else | ||
| 148 | return !!value; | ||
| 145 | } | 149 | } |
| 146 | if (mach->udc_is_connected) | 150 | if (mach->udc_is_connected) |
| 147 | return mach->udc_is_connected(); | 151 | return mach->udc_is_connected(); |
| @@ -982,7 +986,7 @@ static int pxa25x_udc_vbus_session(struct usb_gadget *_gadget, int is_active) | |||
| 982 | struct pxa25x_udc *udc; | 986 | struct pxa25x_udc *udc; |
| 983 | 987 | ||
| 984 | udc = container_of(_gadget, struct pxa25x_udc, gadget); | 988 | udc = container_of(_gadget, struct pxa25x_udc, gadget); |
| 985 | udc->vbus = (is_active != 0); | 989 | udc->vbus = is_active; |
| 986 | DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); | 990 | DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); |
| 987 | pullup(udc); | 991 | pullup(udc); |
| 988 | return 0; | 992 | return 0; |
| @@ -1399,12 +1403,8 @@ lubbock_vbus_irq(int irq, void *_dev) | |||
| 1399 | static irqreturn_t udc_vbus_irq(int irq, void *_dev) | 1403 | static irqreturn_t udc_vbus_irq(int irq, void *_dev) |
| 1400 | { | 1404 | { |
| 1401 | struct pxa25x_udc *dev = _dev; | 1405 | struct pxa25x_udc *dev = _dev; |
| 1402 | int vbus = gpio_get_value(dev->mach->gpio_vbus); | ||
| 1403 | 1406 | ||
| 1404 | if (dev->mach->gpio_vbus_inverted) | 1407 | pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present()); |
| 1405 | vbus = !vbus; | ||
| 1406 | |||
| 1407 | pxa25x_udc_vbus_session(&dev->gadget, vbus); | ||
| 1408 | return IRQ_HANDLED; | 1408 | return IRQ_HANDLED; |
| 1409 | } | 1409 | } |
| 1410 | 1410 | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 56f592dc0b36..f3a75a929e0a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -110,29 +110,18 @@ config USB_ISP116X_HCD | |||
| 110 | 110 | ||
| 111 | config USB_ISP1760_HCD | 111 | config USB_ISP1760_HCD |
| 112 | tristate "ISP 1760 HCD support" | 112 | tristate "ISP 1760 HCD support" |
| 113 | depends on USB && EXPERIMENTAL | 113 | depends on USB && EXPERIMENTAL && (PCI || PPC_OF) |
| 114 | ---help--- | 114 | ---help--- |
| 115 | The ISP1760 chip is a USB 2.0 host controller. | 115 | The ISP1760 chip is a USB 2.0 host controller. |
| 116 | 116 | ||
| 117 | This driver does not support isochronous transfers or OTG. | 117 | This driver does not support isochronous transfers or OTG. |
| 118 | This USB controller is usually attached to a non-DMA-Master | ||
| 119 | capable bus. NXP's eval kit brings this chip on PCI card | ||
| 120 | where the chip itself is behind a PLB to simulate such | ||
| 121 | a bus. | ||
| 118 | 122 | ||
| 119 | To compile this driver as a module, choose M here: the | 123 | To compile this driver as a module, choose M here: the |
| 120 | module will be called isp1760-hcd. | 124 | module will be called isp1760. |
| 121 | |||
| 122 | config USB_ISP1760_PCI | ||
| 123 | bool "Support for the PCI bus" | ||
| 124 | depends on USB_ISP1760_HCD && PCI | ||
| 125 | ---help--- | ||
| 126 | Enables support for the device present on the PCI bus. | ||
| 127 | This should only be required if you happen to have the eval kit from | ||
| 128 | NXP and you are going to test it. | ||
| 129 | |||
| 130 | config USB_ISP1760_OF | ||
| 131 | bool "Support for the OF platform bus" | ||
| 132 | depends on USB_ISP1760_HCD && PPC_OF | ||
| 133 | ---help--- | ||
| 134 | Enables support for the device present on the PowerPC | ||
| 135 | OpenFirmware platform bus. | ||
| 136 | 125 | ||
| 137 | config USB_OHCI_HCD | 126 | config USB_OHCI_HCD |
| 138 | tristate "OHCI HCD support" | 127 | tristate "OHCI HCD support" |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 15a803b206b8..4725d15d096f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
| @@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd) | |||
| 643 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 643 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
| 644 | { | 644 | { |
| 645 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 645 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
| 646 | u32 status, pcd_status = 0, cmd; | 646 | u32 status, masked_status, pcd_status = 0, cmd; |
| 647 | int bh; | 647 | int bh; |
| 648 | 648 | ||
| 649 | spin_lock (&ehci->lock); | 649 | spin_lock (&ehci->lock); |
| @@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
| 656 | goto dead; | 656 | goto dead; |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | status &= INTR_MASK; | 659 | masked_status = status & INTR_MASK; |
| 660 | if (!status) { /* irq sharing? */ | 660 | if (!masked_status) { /* irq sharing? */ |
| 661 | spin_unlock(&ehci->lock); | 661 | spin_unlock(&ehci->lock); |
| 662 | return IRQ_NONE; | 662 | return IRQ_NONE; |
| 663 | } | 663 | } |
| 664 | 664 | ||
| 665 | /* clear (just) interrupts */ | 665 | /* clear (just) interrupts */ |
| 666 | ehci_writel(ehci, status, &ehci->regs->status); | 666 | ehci_writel(ehci, masked_status, &ehci->regs->status); |
| 667 | cmd = ehci_readl(ehci, &ehci->regs->command); | 667 | cmd = ehci_readl(ehci, &ehci->regs->command); |
| 668 | bh = 0; | 668 | bh = 0; |
| 669 | 669 | ||
| @@ -734,18 +734,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
| 734 | 734 | ||
| 735 | /* PCI errors [4.15.2.4] */ | 735 | /* PCI errors [4.15.2.4] */ |
| 736 | if (unlikely ((status & STS_FATAL) != 0)) { | 736 | if (unlikely ((status & STS_FATAL) != 0)) { |
| 737 | ehci_err(ehci, "fatal error\n"); | ||
| 737 | dbg_cmd(ehci, "fatal", cmd); | 738 | dbg_cmd(ehci, "fatal", cmd); |
| 738 | dbg_status(ehci, "fatal", status); | 739 | dbg_status(ehci, "fatal", status); |
| 739 | if (status & STS_HALT) { | 740 | ehci_halt(ehci); |
| 740 | ehci_err (ehci, "fatal error\n"); | ||
| 741 | dead: | 741 | dead: |
| 742 | ehci_reset (ehci); | 742 | ehci_reset(ehci); |
| 743 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); | 743 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
| 744 | /* generic layer kills/unlinks all urbs, then | 744 | /* generic layer kills/unlinks all urbs, then |
| 745 | * uses ehci_stop to clean up the rest | 745 | * uses ehci_stop to clean up the rest |
| 746 | */ | 746 | */ |
| 747 | bh = 1; | 747 | bh = 1; |
| 748 | } | ||
| 749 | } | 748 | } |
| 750 | 749 | ||
| 751 | if (bh) | 750 | if (bh) |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index c46a58f9181d..36864f958444 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
| @@ -66,6 +66,8 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
| 66 | { | 66 | { |
| 67 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 67 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
| 68 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 68 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
| 69 | struct pci_dev *p_smbus; | ||
| 70 | u8 rev; | ||
| 69 | u32 temp; | 71 | u32 temp; |
| 70 | int retval; | 72 | int retval; |
| 71 | 73 | ||
| @@ -166,6 +168,28 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
| 166 | pci_write_config_byte(pdev, 0x4b, tmp | 0x20); | 168 | pci_write_config_byte(pdev, 0x4b, tmp | 0x20); |
| 167 | } | 169 | } |
| 168 | break; | 170 | break; |
| 171 | case PCI_VENDOR_ID_ATI: | ||
| 172 | /* SB600 and old version of SB700 have a bug in EHCI controller, | ||
| 173 | * which causes usb devices lose response in some cases. | ||
| 174 | */ | ||
| 175 | if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) { | ||
| 176 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, | ||
| 177 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, | ||
| 178 | NULL); | ||
| 179 | if (!p_smbus) | ||
| 180 | break; | ||
| 181 | rev = p_smbus->revision; | ||
| 182 | if ((pdev->device == 0x4386) || (rev == 0x3a) | ||
| 183 | || (rev == 0x3b)) { | ||
| 184 | u8 tmp; | ||
| 185 | ehci_info(ehci, "applying AMD SB600/SB700 USB " | ||
| 186 | "freeze workaround\n"); | ||
| 187 | pci_read_config_byte(pdev, 0x53, &tmp); | ||
| 188 | pci_write_config_byte(pdev, 0x53, tmp | (1<<3)); | ||
| 189 | } | ||
| 190 | pci_dev_put(p_smbus); | ||
| 191 | } | ||
| 192 | break; | ||
| 169 | } | 193 | } |
| 170 | 194 | ||
| 171 | ehci_reset(ehci); | 195 | ehci_reset(ehci); |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 0eba894bcb01..9c9da35abc6c 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
| @@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev) | |||
| 205 | 205 | ||
| 206 | tmp = hcd->irq; | 206 | tmp = hcd->irq; |
| 207 | 207 | ||
| 208 | ehci_shutdown(hcd); | ||
| 208 | usb_remove_hcd(hcd); | 209 | usb_remove_hcd(hcd); |
| 209 | 210 | ||
| 210 | ps3_system_bus_set_driver_data(dev, NULL); | 211 | ps3_system_bus_set_driver_data(dev, NULL); |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 4a0c5a78b2ed..a081ee65bde6 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -918,7 +918,7 @@ iso_stream_init ( | |||
| 918 | */ | 918 | */ |
| 919 | stream->usecs = HS_USECS_ISO (maxp); | 919 | stream->usecs = HS_USECS_ISO (maxp); |
| 920 | bandwidth = stream->usecs * 8; | 920 | bandwidth = stream->usecs * 8; |
| 921 | bandwidth /= 1 << (interval - 1); | 921 | bandwidth /= interval; |
| 922 | 922 | ||
| 923 | } else { | 923 | } else { |
| 924 | u32 addr; | 924 | u32 addr; |
| @@ -951,7 +951,7 @@ iso_stream_init ( | |||
| 951 | } else | 951 | } else |
| 952 | stream->raw_mask = smask_out [hs_transfers - 1]; | 952 | stream->raw_mask = smask_out [hs_transfers - 1]; |
| 953 | bandwidth = stream->usecs + stream->c_usecs; | 953 | bandwidth = stream->usecs + stream->c_usecs; |
| 954 | bandwidth /= 1 << (interval + 2); | 954 | bandwidth /= interval << 3; |
| 955 | 955 | ||
| 956 | /* stream->splits gets created from raw_mask later */ | 956 | /* stream->splits gets created from raw_mask later */ |
| 957 | stream->address = cpu_to_hc32(ehci, addr); | 957 | stream->address = cpu_to_hc32(ehci, addr); |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index b11798d17ae5..c7d4b5a06bdb 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
| @@ -183,16 +183,14 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
| 183 | * the async ring; just the I/O watchdog. Note that if a | 183 | * the async ring; just the I/O watchdog. Note that if a |
| 184 | * SHRINK were pending, OFF would never be requested. | 184 | * SHRINK were pending, OFF would never be requested. |
| 185 | */ | 185 | */ |
| 186 | enum ehci_timer_action oldactions = ehci->actions; | 186 | if (timer_pending(&ehci->watchdog) |
| 187 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
| 188 | & ehci->actions)) | ||
| 189 | return; | ||
| 187 | 190 | ||
| 188 | if (!test_and_set_bit (action, &ehci->actions)) { | 191 | if (!test_and_set_bit (action, &ehci->actions)) { |
| 189 | unsigned long t; | 192 | unsigned long t; |
| 190 | 193 | ||
| 191 | if (timer_pending(&ehci->watchdog) | ||
| 192 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
| 193 | & oldactions)) | ||
| 194 | return; | ||
| 195 | |||
| 196 | switch (action) { | 194 | switch (action) { |
| 197 | case TIMER_IO_WATCHDOG: | 195 | case TIMER_IO_WATCHDOG: |
| 198 | t = EHCI_IO_JIFFIES; | 196 | t = EHCI_IO_JIFFIES; |
| @@ -208,7 +206,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
| 208 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | 206 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; |
| 209 | break; | 207 | break; |
| 210 | } | 208 | } |
| 211 | mod_timer(&ehci->watchdog, round_jiffies(t + jiffies)); | 209 | mod_timer(&ehci->watchdog, t + jiffies); |
| 212 | } | 210 | } |
| 213 | } | 211 | } |
| 214 | 212 | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index af849f596135..b87ca7cf4b37 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
| @@ -14,16 +14,16 @@ | |||
| 14 | #include "../core/hcd.h" | 14 | #include "../core/hcd.h" |
| 15 | #include "isp1760-hcd.h" | 15 | #include "isp1760-hcd.h" |
| 16 | 16 | ||
| 17 | #ifdef CONFIG_USB_ISP1760_OF | 17 | #ifdef CONFIG_PPC_OF |
| 18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
| 19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
| 20 | #endif | 20 | #endif |
| 21 | 21 | ||
| 22 | #ifdef CONFIG_USB_ISP1760_PCI | 22 | #ifdef CONFIG_PCI |
| 23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | #ifdef CONFIG_USB_ISP1760_OF | 26 | #ifdef CONFIG_PPC_OF |
| 27 | static int of_isp1760_probe(struct of_device *dev, | 27 | static int of_isp1760_probe(struct of_device *dev, |
| 28 | const struct of_device_id *match) | 28 | const struct of_device_id *match) |
| 29 | { | 29 | { |
| @@ -128,7 +128,7 @@ static struct of_platform_driver isp1760_of_driver = { | |||
| 128 | }; | 128 | }; |
| 129 | #endif | 129 | #endif |
| 130 | 130 | ||
| 131 | #ifdef CONFIG_USB_ISP1760_PCI | 131 | #ifdef CONFIG_PCI |
| 132 | static u32 nxp_pci_io_base; | 132 | static u32 nxp_pci_io_base; |
| 133 | static u32 iolength; | 133 | static u32 iolength; |
| 134 | static u32 pci_mem_phy0; | 134 | static u32 pci_mem_phy0; |
| @@ -288,28 +288,28 @@ static struct pci_driver isp1761_pci_driver = { | |||
| 288 | 288 | ||
| 289 | static int __init isp1760_init(void) | 289 | static int __init isp1760_init(void) |
| 290 | { | 290 | { |
| 291 | int ret = -ENODEV; | 291 | int ret; |
| 292 | 292 | ||
| 293 | init_kmem_once(); | 293 | init_kmem_once(); |
| 294 | 294 | ||
| 295 | #ifdef CONFIG_USB_ISP1760_OF | 295 | #ifdef CONFIG_PPC_OF |
| 296 | ret = of_register_platform_driver(&isp1760_of_driver); | 296 | ret = of_register_platform_driver(&isp1760_of_driver); |
| 297 | if (ret) { | 297 | if (ret) { |
| 298 | deinit_kmem_cache(); | 298 | deinit_kmem_cache(); |
| 299 | return ret; | 299 | return ret; |
| 300 | } | 300 | } |
| 301 | #endif | 301 | #endif |
| 302 | #ifdef CONFIG_USB_ISP1760_PCI | 302 | #ifdef CONFIG_PCI |
| 303 | ret = pci_register_driver(&isp1761_pci_driver); | 303 | ret = pci_register_driver(&isp1761_pci_driver); |
| 304 | if (ret) | 304 | if (ret) |
| 305 | goto unreg_of; | 305 | goto unreg_of; |
| 306 | #endif | 306 | #endif |
| 307 | return ret; | 307 | return ret; |
| 308 | 308 | ||
| 309 | #ifdef CONFIG_USB_ISP1760_PCI | 309 | #ifdef CONFIG_PCI |
| 310 | unreg_of: | 310 | unreg_of: |
| 311 | #endif | 311 | #endif |
| 312 | #ifdef CONFIG_USB_ISP1760_OF | 312 | #ifdef CONFIG_PPC_OF |
| 313 | of_unregister_platform_driver(&isp1760_of_driver); | 313 | of_unregister_platform_driver(&isp1760_of_driver); |
| 314 | #endif | 314 | #endif |
| 315 | deinit_kmem_cache(); | 315 | deinit_kmem_cache(); |
| @@ -319,10 +319,10 @@ module_init(isp1760_init); | |||
| 319 | 319 | ||
| 320 | static void __exit isp1760_exit(void) | 320 | static void __exit isp1760_exit(void) |
| 321 | { | 321 | { |
| 322 | #ifdef CONFIG_USB_ISP1760_OF | 322 | #ifdef CONFIG_PPC_OF |
| 323 | of_unregister_platform_driver(&isp1760_of_driver); | 323 | of_unregister_platform_driver(&isp1760_of_driver); |
| 324 | #endif | 324 | #endif |
| 325 | #ifdef CONFIG_USB_ISP1760_PCI | 325 | #ifdef CONFIG_PCI |
| 326 | pci_unregister_driver(&isp1761_pci_driver); | 326 | pci_unregister_driver(&isp1761_pci_driver); |
| 327 | #endif | 327 | #endif |
| 328 | deinit_kmem_cache(); | 328 | deinit_kmem_cache(); |
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 2089d8a46c4b..3c1a3b5f89f1 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c | |||
| @@ -192,7 +192,7 @@ fail_start: | |||
| 192 | return result; | 192 | return result; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int ps3_ohci_remove (struct ps3_system_bus_device *dev) | 195 | static int ps3_ohci_remove(struct ps3_system_bus_device *dev) |
| 196 | { | 196 | { |
| 197 | unsigned int tmp; | 197 | unsigned int tmp; |
| 198 | struct usb_hcd *hcd = | 198 | struct usb_hcd *hcd = |
| @@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_system_bus_device *dev) | |||
| 205 | 205 | ||
| 206 | tmp = hcd->irq; | 206 | tmp = hcd->irq; |
| 207 | 207 | ||
| 208 | ohci_shutdown(hcd); | ||
| 208 | usb_remove_hcd(hcd); | 209 | usb_remove_hcd(hcd); |
| 209 | 210 | ||
| 210 | ps3_system_bus_set_driver_data(dev, NULL); | 211 | ps3_system_bus_set_driver_data(dev, NULL); |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index c18d8790c410..2376f24f3c83 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
| @@ -1763,11 +1763,12 @@ static void r8a66597_timer(unsigned long _r8a66597) | |||
| 1763 | { | 1763 | { |
| 1764 | struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; | 1764 | struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; |
| 1765 | unsigned long flags; | 1765 | unsigned long flags; |
| 1766 | int port; | ||
| 1766 | 1767 | ||
| 1767 | spin_lock_irqsave(&r8a66597->lock, flags); | 1768 | spin_lock_irqsave(&r8a66597->lock, flags); |
| 1768 | 1769 | ||
| 1769 | r8a66597_root_hub_control(r8a66597, 0); | 1770 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) |
| 1770 | r8a66597_root_hub_control(r8a66597, 1); | 1771 | r8a66597_root_hub_control(r8a66597, port); |
| 1771 | 1772 | ||
| 1772 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1773 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
| 1773 | } | 1774 | } |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 69c34a58e205..b4ec716de7da 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
| @@ -3270,6 +3270,7 @@ static struct usb_device_id sisusb_table [] = { | |||
| 3270 | { USB_DEVICE(0x0711, 0x0900) }, | 3270 | { USB_DEVICE(0x0711, 0x0900) }, |
| 3271 | { USB_DEVICE(0x0711, 0x0901) }, | 3271 | { USB_DEVICE(0x0711, 0x0901) }, |
| 3272 | { USB_DEVICE(0x0711, 0x0902) }, | 3272 | { USB_DEVICE(0x0711, 0x0902) }, |
| 3273 | { USB_DEVICE(0x0711, 0x0903) }, | ||
| 3273 | { USB_DEVICE(0x0711, 0x0918) }, | 3274 | { USB_DEVICE(0x0711, 0x0918) }, |
| 3274 | { USB_DEVICE(0x182d, 0x021c) }, | 3275 | { USB_DEVICE(0x182d, 0x021c) }, |
| 3275 | { USB_DEVICE(0x182d, 0x0269) }, | 3276 | { USB_DEVICE(0x182d, 0x0269) }, |
diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c index 8648470c81ca..63dff9ba73c5 100644 --- a/drivers/usb/misc/vstusb.c +++ b/drivers/usb/misc/vstusb.c | |||
| @@ -620,7 +620,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 620 | __func__); | 620 | __func__); |
| 621 | retval = -EFAULT; | 621 | retval = -EFAULT; |
| 622 | } else { | 622 | } else { |
| 623 | dev_dbg(&dev->dev, "%s: recv %d bytes from pipe %d\n", | 623 | dev_dbg(&dev->dev, "%s: recv %zd bytes from pipe %d\n", |
| 624 | __func__, usb_data.count, usb_data.pipe); | 624 | __func__, usb_data.count, usb_data.pipe); |
| 625 | } | 625 | } |
| 626 | 626 | ||
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index c9de3f027aab..e06810aef2df 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
| @@ -687,7 +687,10 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
| 687 | } | 687 | } |
| 688 | 688 | ||
| 689 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { | 689 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { |
| 690 | step_len = min(nbytes, (size_t)ep->len_cap); | 690 | step_len = ep->len_cap; |
| 691 | step_len -= rp->b_read - sizeof(struct mon_bin_hdr); | ||
| 692 | if (step_len > nbytes) | ||
| 693 | step_len = nbytes; | ||
| 691 | offset = rp->b_out + PKT_SIZE; | 694 | offset = rp->b_out + PKT_SIZE; |
| 692 | offset += rp->b_read - sizeof(struct mon_bin_hdr); | 695 | offset += rp->b_read - sizeof(struct mon_bin_hdr); |
| 693 | if (offset >= rp->b_size) | 696 | if (offset >= rp->b_size) |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4a35745b30be..5280dba9b1fb 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -114,8 +114,8 @@ | |||
| 114 | 114 | ||
| 115 | 115 | ||
| 116 | 116 | ||
| 117 | unsigned debug; | 117 | unsigned musb_debug; |
| 118 | module_param(debug, uint, S_IRUGO | S_IWUSR); | 118 | module_param(musb_debug, uint, S_IRUGO | S_IWUSR); |
| 119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); | 119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); |
| 120 | 120 | ||
| 121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" | 121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" |
| @@ -2248,7 +2248,7 @@ static int __init musb_init(void) | |||
| 2248 | "host" | 2248 | "host" |
| 2249 | #endif | 2249 | #endif |
| 2250 | ", debug=%d\n", | 2250 | ", debug=%d\n", |
| 2251 | musb_driver_name, debug); | 2251 | musb_driver_name, musb_debug); |
| 2252 | return platform_driver_probe(&musb_driver, musb_probe); | 2252 | return platform_driver_probe(&musb_driver, musb_probe); |
| 2253 | } | 2253 | } |
| 2254 | 2254 | ||
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h index 4d2794441b15..9fc1db44c72c 100644 --- a/drivers/usb/musb/musb_debug.h +++ b/drivers/usb/musb/musb_debug.h | |||
| @@ -48,11 +48,11 @@ | |||
| 48 | __func__, __LINE__ , ## args); \ | 48 | __func__, __LINE__ , ## args); \ |
| 49 | } } while (0) | 49 | } } while (0) |
| 50 | 50 | ||
| 51 | extern unsigned debug; | 51 | extern unsigned musb_debug; |
| 52 | 52 | ||
| 53 | static inline int _dbg_level(unsigned l) | 53 | static inline int _dbg_level(unsigned l) |
| 54 | { | 54 | { |
| 55 | return debug >= l; | 55 | return musb_debug >= l; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args) | 58 | #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3133990f04ec..cc64462d4c4e 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -378,6 +378,19 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
| 378 | 378 | ||
| 379 | switch (qh->type) { | 379 | switch (qh->type) { |
| 380 | 380 | ||
| 381 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 382 | case USB_ENDPOINT_XFER_BULK: | ||
| 383 | /* fifo policy for these lists, except that NAKing | ||
| 384 | * should rotate a qh to the end (for fairness). | ||
| 385 | */ | ||
| 386 | if (qh->mux == 1) { | ||
| 387 | head = qh->ring.prev; | ||
| 388 | list_del(&qh->ring); | ||
| 389 | kfree(qh); | ||
| 390 | qh = first_qh(head); | ||
| 391 | break; | ||
| 392 | } | ||
| 393 | |||
| 381 | case USB_ENDPOINT_XFER_ISOC: | 394 | case USB_ENDPOINT_XFER_ISOC: |
| 382 | case USB_ENDPOINT_XFER_INT: | 395 | case USB_ENDPOINT_XFER_INT: |
| 383 | /* this is where periodic bandwidth should be | 396 | /* this is where periodic bandwidth should be |
| @@ -388,17 +401,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
| 388 | kfree(qh); | 401 | kfree(qh); |
| 389 | qh = NULL; | 402 | qh = NULL; |
| 390 | break; | 403 | break; |
| 391 | |||
| 392 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 393 | case USB_ENDPOINT_XFER_BULK: | ||
| 394 | /* fifo policy for these lists, except that NAKing | ||
| 395 | * should rotate a qh to the end (for fairness). | ||
| 396 | */ | ||
| 397 | head = qh->ring.prev; | ||
| 398 | list_del(&qh->ring); | ||
| 399 | kfree(qh); | ||
| 400 | qh = first_qh(head); | ||
| 401 | break; | ||
| 402 | } | 404 | } |
| 403 | } | 405 | } |
| 404 | return qh; | 406 | return qh; |
| @@ -1507,10 +1509,29 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1507 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); | 1509 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); |
| 1508 | 1510 | ||
| 1509 | #ifdef CONFIG_USB_INVENTRA_DMA | 1511 | #ifdef CONFIG_USB_INVENTRA_DMA |
| 1512 | if (usb_pipeisoc(pipe)) { | ||
| 1513 | struct usb_iso_packet_descriptor *d; | ||
| 1514 | |||
| 1515 | d = urb->iso_frame_desc + qh->iso_idx; | ||
| 1516 | d->actual_length = xfer_len; | ||
| 1517 | |||
| 1518 | /* even if there was an error, we did the dma | ||
| 1519 | * for iso_frame_desc->length | ||
| 1520 | */ | ||
| 1521 | if (d->status != EILSEQ && d->status != -EOVERFLOW) | ||
| 1522 | d->status = 0; | ||
| 1523 | |||
| 1524 | if (++qh->iso_idx >= urb->number_of_packets) | ||
| 1525 | done = true; | ||
| 1526 | else | ||
| 1527 | done = false; | ||
| 1528 | |||
| 1529 | } else { | ||
| 1510 | /* done if urb buffer is full or short packet is recd */ | 1530 | /* done if urb buffer is full or short packet is recd */ |
| 1511 | done = (urb->actual_length + xfer_len >= | 1531 | done = (urb->actual_length + xfer_len >= |
| 1512 | urb->transfer_buffer_length | 1532 | urb->transfer_buffer_length |
| 1513 | || dma->actual_len < qh->maxpacket); | 1533 | || dma->actual_len < qh->maxpacket); |
| 1534 | } | ||
| 1514 | 1535 | ||
| 1515 | /* send IN token for next packet, without AUTOREQ */ | 1536 | /* send IN token for next packet, without AUTOREQ */ |
| 1516 | if (!done) { | 1537 | if (!done) { |
| @@ -1547,7 +1568,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1547 | if (dma) { | 1568 | if (dma) { |
| 1548 | struct dma_controller *c; | 1569 | struct dma_controller *c; |
| 1549 | u16 rx_count; | 1570 | u16 rx_count; |
| 1550 | int ret; | 1571 | int ret, length; |
| 1572 | dma_addr_t buf; | ||
| 1551 | 1573 | ||
| 1552 | rx_count = musb_readw(epio, MUSB_RXCOUNT); | 1574 | rx_count = musb_readw(epio, MUSB_RXCOUNT); |
| 1553 | 1575 | ||
| @@ -1560,6 +1582,35 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1560 | 1582 | ||
| 1561 | c = musb->dma_controller; | 1583 | c = musb->dma_controller; |
| 1562 | 1584 | ||
| 1585 | if (usb_pipeisoc(pipe)) { | ||
| 1586 | int status = 0; | ||
| 1587 | struct usb_iso_packet_descriptor *d; | ||
| 1588 | |||
| 1589 | d = urb->iso_frame_desc + qh->iso_idx; | ||
| 1590 | |||
| 1591 | if (iso_err) { | ||
| 1592 | status = -EILSEQ; | ||
| 1593 | urb->error_count++; | ||
| 1594 | } | ||
| 1595 | if (rx_count > d->length) { | ||
| 1596 | if (status == 0) { | ||
| 1597 | status = -EOVERFLOW; | ||
| 1598 | urb->error_count++; | ||
| 1599 | } | ||
| 1600 | DBG(2, "** OVERFLOW %d into %d\n",\ | ||
| 1601 | rx_count, d->length); | ||
| 1602 | |||
| 1603 | length = d->length; | ||
| 1604 | } else | ||
| 1605 | length = rx_count; | ||
| 1606 | d->status = status; | ||
| 1607 | buf = urb->transfer_dma + d->offset; | ||
| 1608 | } else { | ||
| 1609 | length = rx_count; | ||
| 1610 | buf = urb->transfer_dma + | ||
| 1611 | urb->actual_length; | ||
| 1612 | } | ||
| 1613 | |||
| 1563 | dma->desired_mode = 0; | 1614 | dma->desired_mode = 0; |
| 1564 | #ifdef USE_MODE1 | 1615 | #ifdef USE_MODE1 |
| 1565 | /* because of the issue below, mode 1 will | 1616 | /* because of the issue below, mode 1 will |
| @@ -1571,6 +1622,12 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1571 | urb->actual_length) | 1622 | urb->actual_length) |
| 1572 | > qh->maxpacket) | 1623 | > qh->maxpacket) |
| 1573 | dma->desired_mode = 1; | 1624 | dma->desired_mode = 1; |
| 1625 | if (rx_count < hw_ep->max_packet_sz_rx) { | ||
| 1626 | length = rx_count; | ||
| 1627 | dma->bDesiredMode = 0; | ||
| 1628 | } else { | ||
| 1629 | length = urb->transfer_buffer_length; | ||
| 1630 | } | ||
| 1574 | #endif | 1631 | #endif |
| 1575 | 1632 | ||
| 1576 | /* Disadvantage of using mode 1: | 1633 | /* Disadvantage of using mode 1: |
| @@ -1608,12 +1665,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1608 | */ | 1665 | */ |
| 1609 | ret = c->channel_program( | 1666 | ret = c->channel_program( |
| 1610 | dma, qh->maxpacket, | 1667 | dma, qh->maxpacket, |
| 1611 | dma->desired_mode, | 1668 | dma->desired_mode, buf, length); |
| 1612 | urb->transfer_dma | ||
| 1613 | + urb->actual_length, | ||
| 1614 | (dma->desired_mode == 0) | ||
| 1615 | ? rx_count | ||
| 1616 | : urb->transfer_buffer_length); | ||
| 1617 | 1669 | ||
| 1618 | if (!ret) { | 1670 | if (!ret) { |
| 1619 | c->channel_release(dma); | 1671 | c->channel_release(dma); |
| @@ -1631,19 +1683,6 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1631 | } | 1683 | } |
| 1632 | } | 1684 | } |
| 1633 | 1685 | ||
| 1634 | if (dma && usb_pipeisoc(pipe)) { | ||
| 1635 | struct usb_iso_packet_descriptor *d; | ||
| 1636 | int iso_stat = status; | ||
| 1637 | |||
| 1638 | d = urb->iso_frame_desc + qh->iso_idx; | ||
| 1639 | d->actual_length += xfer_len; | ||
| 1640 | if (iso_err) { | ||
| 1641 | iso_stat = -EILSEQ; | ||
| 1642 | urb->error_count++; | ||
| 1643 | } | ||
| 1644 | d->status = iso_stat; | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | finish: | 1686 | finish: |
| 1648 | urb->actual_length += xfer_len; | 1687 | urb->actual_length += xfer_len; |
| 1649 | qh->offset += xfer_len; | 1688 | qh->offset += xfer_len; |
| @@ -1671,22 +1710,9 @@ static int musb_schedule( | |||
| 1671 | struct list_head *head = NULL; | 1710 | struct list_head *head = NULL; |
| 1672 | 1711 | ||
| 1673 | /* use fixed hardware for control and bulk */ | 1712 | /* use fixed hardware for control and bulk */ |
| 1674 | switch (qh->type) { | 1713 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { |
| 1675 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 1676 | head = &musb->control; | 1714 | head = &musb->control; |
| 1677 | hw_ep = musb->control_ep; | 1715 | hw_ep = musb->control_ep; |
| 1678 | break; | ||
| 1679 | case USB_ENDPOINT_XFER_BULK: | ||
| 1680 | hw_ep = musb->bulk_ep; | ||
| 1681 | if (is_in) | ||
| 1682 | head = &musb->in_bulk; | ||
| 1683 | else | ||
| 1684 | head = &musb->out_bulk; | ||
| 1685 | break; | ||
| 1686 | } | ||
| 1687 | if (head) { | ||
| 1688 | idle = list_empty(head); | ||
| 1689 | list_add_tail(&qh->ring, head); | ||
| 1690 | goto success; | 1716 | goto success; |
| 1691 | } | 1717 | } |
| 1692 | 1718 | ||
| @@ -1725,19 +1751,34 @@ static int musb_schedule( | |||
| 1725 | else | 1751 | else |
| 1726 | diff = hw_ep->max_packet_sz_tx - qh->maxpacket; | 1752 | diff = hw_ep->max_packet_sz_tx - qh->maxpacket; |
| 1727 | 1753 | ||
| 1728 | if (diff > 0 && best_diff > diff) { | 1754 | if (diff >= 0 && best_diff > diff) { |
| 1729 | best_diff = diff; | 1755 | best_diff = diff; |
| 1730 | best_end = epnum; | 1756 | best_end = epnum; |
| 1731 | } | 1757 | } |
| 1732 | } | 1758 | } |
| 1733 | if (best_end < 0) | 1759 | /* use bulk reserved ep1 if no other ep is free */ |
| 1760 | if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) { | ||
| 1761 | hw_ep = musb->bulk_ep; | ||
| 1762 | if (is_in) | ||
| 1763 | head = &musb->in_bulk; | ||
| 1764 | else | ||
| 1765 | head = &musb->out_bulk; | ||
| 1766 | goto success; | ||
| 1767 | } else if (best_end < 0) { | ||
| 1734 | return -ENOSPC; | 1768 | return -ENOSPC; |
| 1769 | } | ||
| 1735 | 1770 | ||
| 1736 | idle = 1; | 1771 | idle = 1; |
| 1772 | qh->mux = 0; | ||
| 1737 | hw_ep = musb->endpoints + best_end; | 1773 | hw_ep = musb->endpoints + best_end; |
| 1738 | musb->periodic[best_end] = qh; | 1774 | musb->periodic[best_end] = qh; |
| 1739 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); | 1775 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); |
| 1740 | success: | 1776 | success: |
| 1777 | if (head) { | ||
| 1778 | idle = list_empty(head); | ||
| 1779 | list_add_tail(&qh->ring, head); | ||
| 1780 | qh->mux = 1; | ||
| 1781 | } | ||
| 1741 | qh->hw_ep = hw_ep; | 1782 | qh->hw_ep = hw_ep; |
| 1742 | qh->hep->hcpriv = qh; | 1783 | qh->hep->hcpriv = qh; |
| 1743 | if (idle) | 1784 | if (idle) |
| @@ -2015,11 +2056,13 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
| 2015 | sched = &musb->control; | 2056 | sched = &musb->control; |
| 2016 | break; | 2057 | break; |
| 2017 | case USB_ENDPOINT_XFER_BULK: | 2058 | case USB_ENDPOINT_XFER_BULK: |
| 2018 | if (usb_pipein(urb->pipe)) | 2059 | if (qh->mux == 1) { |
| 2019 | sched = &musb->in_bulk; | 2060 | if (usb_pipein(urb->pipe)) |
| 2020 | else | 2061 | sched = &musb->in_bulk; |
| 2021 | sched = &musb->out_bulk; | 2062 | else |
| 2022 | break; | 2063 | sched = &musb->out_bulk; |
| 2064 | break; | ||
| 2065 | } | ||
| 2023 | default: | 2066 | default: |
| 2024 | /* REVISIT when we get a schedule tree, periodic | 2067 | /* REVISIT when we get a schedule tree, periodic |
| 2025 | * transfers won't always be at the head of a | 2068 | * transfers won't always be at the head of a |
| @@ -2067,11 +2110,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
| 2067 | sched = &musb->control; | 2110 | sched = &musb->control; |
| 2068 | break; | 2111 | break; |
| 2069 | case USB_ENDPOINT_XFER_BULK: | 2112 | case USB_ENDPOINT_XFER_BULK: |
| 2070 | if (is_in) | 2113 | if (qh->mux == 1) { |
| 2071 | sched = &musb->in_bulk; | 2114 | if (is_in) |
| 2072 | else | 2115 | sched = &musb->in_bulk; |
| 2073 | sched = &musb->out_bulk; | 2116 | else |
| 2074 | break; | 2117 | sched = &musb->out_bulk; |
| 2118 | break; | ||
| 2119 | } | ||
| 2075 | default: | 2120 | default: |
| 2076 | /* REVISIT when we get a schedule tree, periodic transfers | 2121 | /* REVISIT when we get a schedule tree, periodic transfers |
| 2077 | * won't always be at the head of a singleton queue... | 2122 | * won't always be at the head of a singleton queue... |
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 77bcdb9d5b32..0b7fbcd21963 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h | |||
| @@ -53,6 +53,7 @@ struct musb_qh { | |||
| 53 | 53 | ||
| 54 | struct list_head ring; /* of musb_qh */ | 54 | struct list_head ring; /* of musb_qh */ |
| 55 | /* struct musb_qh *next; */ /* for periodic tree */ | 55 | /* struct musb_qh *next; */ /* for periodic tree */ |
| 56 | u8 mux; /* qh multiplexed to hw_ep */ | ||
| 56 | 57 | ||
| 57 | unsigned offset; /* in urb->transfer_buffer */ | 58 | unsigned offset; /* in urb->transfer_buffer */ |
| 58 | unsigned segsize; /* current xfer fragment */ | 59 | unsigned segsize; /* current xfer fragment */ |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 9d2dcb121c5e..ce6c162920f7 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
| @@ -53,7 +53,9 @@ static void musb_do_idle(unsigned long _musb) | |||
| 53 | { | 53 | { |
| 54 | struct musb *musb = (void *)_musb; | 54 | struct musb *musb = (void *)_musb; |
| 55 | unsigned long flags; | 55 | unsigned long flags; |
| 56 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
| 56 | u8 power; | 57 | u8 power; |
| 58 | #endif | ||
| 57 | u8 devctl; | 59 | u8 devctl; |
| 58 | 60 | ||
| 59 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 61 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index b73b036f3d77..ee8fca92a4ac 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
| @@ -605,7 +605,7 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
| 605 | 605 | ||
| 606 | if (musb->board_mode != MUSB_OTG) { | 606 | if (musb->board_mode != MUSB_OTG) { |
| 607 | ERR("Changing mode currently only supported in OTG mode\n"); | 607 | ERR("Changing mode currently only supported in OTG mode\n"); |
| 608 | return; | 608 | return -EINVAL; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); | 611 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 5b20de130e08..5b95009d2fbb 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
| @@ -135,6 +135,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
| 135 | err("no more memory"); | 135 | err("no more memory"); |
| 136 | goto reset_open_count; | 136 | goto reset_open_count; |
| 137 | } | 137 | } |
| 138 | kref_init(&tty->kref); | ||
| 138 | termios = kzalloc(sizeof(*termios), GFP_KERNEL); | 139 | termios = kzalloc(sizeof(*termios), GFP_KERNEL); |
| 139 | if (!termios) { | 140 | if (!termios) { |
| 140 | retval = -ENOMEM; | 141 | retval = -ENOMEM; |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 8008d0bc80ad..cfaf1f085535 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
| @@ -56,6 +56,7 @@ static void cp2101_shutdown(struct usb_serial *); | |||
| 56 | static int debug; | 56 | static int debug; |
| 57 | 57 | ||
| 58 | static struct usb_device_id id_table [] = { | 58 | static struct usb_device_id id_table [] = { |
| 59 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ | ||
| 59 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | 60 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ |
| 60 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | 61 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ |
| 61 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 62 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
| @@ -67,6 +68,7 @@ static struct usb_device_id id_table [] = { | |||
| 67 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | 68 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ |
| 68 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 69 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
| 69 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 70 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
| 71 | { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */ | ||
| 70 | { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ | 72 | { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ |
| 71 | { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ | 73 | { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ |
| 72 | { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ | 74 | { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ |
| @@ -85,6 +87,7 @@ static struct usb_device_id id_table [] = { | |||
| 85 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 87 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
| 86 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 88 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ |
| 87 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 89 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
| 90 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | ||
| 88 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 91 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
| 89 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 92 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
| 90 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ | 93 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 51d7bdea2869..aad1359a3eb1 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -1498,7 +1498,7 @@ static int ftdi_open(struct tty_struct *tty, | |||
| 1498 | priv->interface, buf, 0, WDR_TIMEOUT); | 1498 | priv->interface, buf, 0, WDR_TIMEOUT); |
| 1499 | 1499 | ||
| 1500 | /* Termios defaults are set by usb_serial_init. We don't change | 1500 | /* Termios defaults are set by usb_serial_init. We don't change |
| 1501 | port->tty->termios - this would loose speed settings, etc. | 1501 | port->tty->termios - this would lose speed settings, etc. |
| 1502 | This is same behaviour as serial.c/rs_open() - Kuba */ | 1502 | This is same behaviour as serial.c/rs_open() - Kuba */ |
| 1503 | 1503 | ||
| 1504 | /* ftdi_set_termios will send usb control messages */ | 1504 | /* ftdi_set_termios will send usb control messages */ |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index b679a556b98d..4e2cda93da59 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | * Introduced common header to be used also in USB Gadget Framework. | 26 | * Introduced common header to be used also in USB Gadget Framework. |
| 27 | * Still needs some other style fixes. | 27 | * Still needs some other style fixes. |
| 28 | * | 28 | * |
| 29 | * 2007_Jun_21 Alan Cox <alan@redhat.com> | 29 | * 2007_Jun_21 Alan Cox <alan@lxorguk.ukuu.org.uk> |
| 30 | * Minimal cleanups for some of the driver problens and tty layer abuse. | 30 | * Minimal cleanups for some of the driver problens and tty layer abuse. |
| 31 | * Still needs fixing to allow multiple dongles. | 31 | * Still needs fixing to allow multiple dongles. |
| 32 | * | 32 | * |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index bd07eaa300b9..809697b3c7fc 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -160,6 +160,11 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
| 160 | 160 | ||
| 161 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 161 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
| 162 | 162 | ||
| 163 | /* YISO PRODUCTS */ | ||
| 164 | |||
| 165 | #define YISO_VENDOR_ID 0x0EAB | ||
| 166 | #define YISO_PRODUCT_U893 0xC893 | ||
| 167 | |||
| 163 | /* MERLIN EVDO PRODUCTS */ | 168 | /* MERLIN EVDO PRODUCTS */ |
| 164 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 | 169 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 |
| 165 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 | 170 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 |
| @@ -219,6 +224,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
| 219 | #define ONDA_VENDOR_ID 0x19d2 | 224 | #define ONDA_VENDOR_ID 0x19d2 |
| 220 | #define ONDA_PRODUCT_MSA501HS 0x0001 | 225 | #define ONDA_PRODUCT_MSA501HS 0x0001 |
| 221 | #define ONDA_PRODUCT_ET502HS 0x0002 | 226 | #define ONDA_PRODUCT_ET502HS 0x0002 |
| 227 | #define ONDA_PRODUCT_MT503HS 0x0200 | ||
| 222 | 228 | ||
| 223 | #define BANDRICH_VENDOR_ID 0x1A8D | 229 | #define BANDRICH_VENDOR_ID 0x1A8D |
| 224 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 230 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
| @@ -408,6 +414,41 @@ static struct usb_device_id option_ids[] = { | |||
| 408 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, | 414 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, |
| 409 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, | 415 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, |
| 410 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, | 416 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, |
| 417 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0003) }, | ||
| 418 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0004) }, | ||
| 419 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0005) }, | ||
| 420 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0006) }, | ||
| 421 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0007) }, | ||
| 422 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0008) }, | ||
| 423 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0009) }, | ||
| 424 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000a) }, | ||
| 425 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000b) }, | ||
| 426 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000c) }, | ||
| 427 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000d) }, | ||
| 428 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000e) }, | ||
| 429 | { USB_DEVICE(ONDA_VENDOR_ID, 0x000f) }, | ||
| 430 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0010) }, | ||
| 431 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0011) }, | ||
| 432 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0012) }, | ||
| 433 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0013) }, | ||
| 434 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0014) }, | ||
| 435 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0015) }, | ||
| 436 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0016) }, | ||
| 437 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0017) }, | ||
| 438 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0018) }, | ||
| 439 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0019) }, | ||
| 440 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0020) }, | ||
| 441 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0021) }, | ||
| 442 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0022) }, | ||
| 443 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0023) }, | ||
| 444 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0024) }, | ||
| 445 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0025) }, | ||
| 446 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0026) }, | ||
| 447 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0027) }, | ||
| 448 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0028) }, | ||
| 449 | { USB_DEVICE(ONDA_VENDOR_ID, 0x0029) }, | ||
| 450 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MT503HS) }, | ||
| 451 | { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) }, | ||
| 411 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 452 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
| 412 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 453 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
| 413 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) }, | 454 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) }, |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 3d9249632ae1..c68b738900bd 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | # USB Storage driver configuration | 2 | # USB Storage driver configuration |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'" | 5 | comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;" |
| 6 | comment "may also be needed; see USB_STORAGE Help for more information" | 6 | comment "see USB_STORAGE Help for more information" |
| 7 | depends on USB | 7 | depends on USB |
| 8 | 8 | ||
| 9 | config USB_STORAGE | 9 | config USB_STORAGE |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index fb9e20e624c1..e61f2bfc64ad 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -167,6 +167,13 @@ UNUSUAL_DEV( 0x0421, 0x005d, 0x0001, 0x0600, | |||
| 167 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 167 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 168 | US_FL_FIX_CAPACITY ), | 168 | US_FL_FIX_CAPACITY ), |
| 169 | 169 | ||
| 170 | /* Patch for Nokia 5310 capacity */ | ||
| 171 | UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591, | ||
| 172 | "Nokia", | ||
| 173 | "5310", | ||
| 174 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 175 | US_FL_FIX_CAPACITY ), | ||
| 176 | |||
| 170 | /* Reported by Mario Rettig <mariorettig@web.de> */ | 177 | /* Reported by Mario Rettig <mariorettig@web.de> */ |
| 171 | UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, | 178 | UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, |
| 172 | "Nokia", | 179 | "Nokia", |
| @@ -233,14 +240,14 @@ UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, | |||
| 233 | US_FL_MAX_SECTORS_64 ), | 240 | US_FL_MAX_SECTORS_64 ), |
| 234 | 241 | ||
| 235 | /* Reported by Cedric Godin <cedric@belbone.be> */ | 242 | /* Reported by Cedric Godin <cedric@belbone.be> */ |
| 236 | UNUSUAL_DEV( 0x0421, 0x04b9, 0x0551, 0x0551, | 243 | UNUSUAL_DEV( 0x0421, 0x04b9, 0x0500, 0x0551, |
| 237 | "Nokia", | 244 | "Nokia", |
| 238 | "5300", | 245 | "5300", |
| 239 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 246 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 240 | US_FL_FIX_CAPACITY ), | 247 | US_FL_FIX_CAPACITY ), |
| 241 | 248 | ||
| 242 | /* Reported by Richard Nauber <RichardNauber@web.de> */ | 249 | /* Reported by Richard Nauber <RichardNauber@web.de> */ |
| 243 | UNUSUAL_DEV( 0x0421, 0x04fa, 0x0601, 0x0601, | 250 | UNUSUAL_DEV( 0x0421, 0x04fa, 0x0550, 0x0660, |
| 244 | "Nokia", | 251 | "Nokia", |
| 245 | "6300", | 252 | "6300", |
| 246 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 253 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| @@ -253,6 +260,14 @@ UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591, | |||
| 253 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 260 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 254 | US_FL_FIX_CAPACITY ), | 261 | US_FL_FIX_CAPACITY ), |
| 255 | 262 | ||
| 263 | /* Submitted by Ricky Wong Yung Fei <evilbladewarrior@gmail.com> */ | ||
| 264 | /* Nokia 7610 Supernova - Too many sectors reported in usb storage mode */ | ||
| 265 | UNUSUAL_DEV( 0x0421, 0x00f5, 0x0000, 0x0470, | ||
| 266 | "Nokia", | ||
| 267 | "7610 Supernova", | ||
| 268 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 269 | US_FL_FIX_CAPACITY ), | ||
| 270 | |||
| 256 | /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ | 271 | /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ |
| 257 | UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, | 272 | UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, |
| 258 | "SMSC", | 273 | "SMSC", |
| @@ -303,6 +318,18 @@ UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, | |||
| 303 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), | 318 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), |
| 304 | #endif | 319 | #endif |
| 305 | 320 | ||
| 321 | /* Reported by Tamas Kerecsen <kerecsen@bigfoot.com> | ||
| 322 | * Obviously the PROM has not been customized by the VAR; | ||
| 323 | * the Vendor and Product string descriptors are: | ||
| 324 | * Generic Mass Storage (PROTOTYPE--Remember to change idVendor) | ||
| 325 | * Generic Manufacturer (PROTOTYPE--Remember to change idVendor) | ||
| 326 | */ | ||
| 327 | UNUSUAL_DEV( 0x045e, 0xffff, 0x0000, 0x0000, | ||
| 328 | "Mitac", | ||
| 329 | "GPS", | ||
| 330 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 331 | US_FL_MAX_SECTORS_64 ), | ||
| 332 | |||
| 306 | /* | 333 | /* |
| 307 | * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.) | 334 | * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.) |
| 308 | * Reported by Pete Zaitcev <zaitcev@redhat.com> | 335 | * Reported by Pete Zaitcev <zaitcev@redhat.com> |
| @@ -362,6 +389,13 @@ UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, | |||
| 362 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 389 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 363 | US_FL_FIX_CAPACITY), | 390 | US_FL_FIX_CAPACITY), |
| 364 | 391 | ||
| 392 | /* Reported by Tobias Kunze Briseno <t-linux@fictive.com> */ | ||
| 393 | UNUSUAL_DEV( 0x04b0, 0x0403, 0x0200, 0x0200, | ||
| 394 | "NIKON", | ||
| 395 | "NIKON DSC D2H", | ||
| 396 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 397 | US_FL_FIX_CAPACITY), | ||
| 398 | |||
| 365 | /* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */ | 399 | /* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */ |
| 366 | UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, | 400 | UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, |
| 367 | "NIKON", | 401 | "NIKON", |
| @@ -418,6 +452,13 @@ UNUSUAL_DEV( 0x04b0, 0x0417, 0x0100, 0x0100, | |||
| 418 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 452 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 419 | US_FL_FIX_CAPACITY), | 453 | US_FL_FIX_CAPACITY), |
| 420 | 454 | ||
| 455 | /* Reported by paul ready <lxtwin@homecall.co.uk> */ | ||
| 456 | UNUSUAL_DEV( 0x04b0, 0x0419, 0x0100, 0x0200, | ||
| 457 | "NIKON", | ||
| 458 | "NIKON DSC D300", | ||
| 459 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 460 | US_FL_FIX_CAPACITY), | ||
| 461 | |||
| 421 | /* Reported by Doug Maxey (dwm@austin.ibm.com) */ | 462 | /* Reported by Doug Maxey (dwm@austin.ibm.com) */ |
| 422 | UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, | 463 | UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, |
| 423 | "IBM", | 464 | "IBM", |
| @@ -1258,6 +1299,13 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, | |||
| 1258 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1299 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 1259 | US_FL_FIX_INQUIRY), | 1300 | US_FL_FIX_INQUIRY), |
| 1260 | 1301 | ||
| 1302 | /* Reported by Luciano Rocha <luciano@eurotux.com> */ | ||
| 1303 | UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001, | ||
| 1304 | "Argosy", | ||
| 1305 | "Storage", | ||
| 1306 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 1307 | US_FL_FIX_CAPACITY), | ||
| 1308 | |||
| 1261 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. | 1309 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. |
| 1262 | * Flag will support Bulk devices which use a standards-violating 32-byte | 1310 | * Flag will support Bulk devices which use a standards-violating 32-byte |
| 1263 | * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with | 1311 | * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 0f13448c6f79..3f3ce13fef43 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
| @@ -2083,6 +2083,38 @@ config FB_METRONOME | |||
| 2083 | controller. The pre-release name for this device was 8track | 2083 | controller. The pre-release name for this device was 8track |
| 2084 | and could also have been called by some vendors as PVI-nnnn. | 2084 | and could also have been called by some vendors as PVI-nnnn. |
| 2085 | 2085 | ||
| 2086 | config FB_MB862XX | ||
| 2087 | tristate "Fujitsu MB862xx GDC support" | ||
| 2088 | depends on FB | ||
| 2089 | select FB_CFB_FILLRECT | ||
| 2090 | select FB_CFB_COPYAREA | ||
| 2091 | select FB_CFB_IMAGEBLIT | ||
| 2092 | ---help--- | ||
| 2093 | Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. | ||
| 2094 | |||
| 2095 | config FB_MB862XX_PCI_GDC | ||
| 2096 | bool "Carmine/Coral-P(A) GDC" | ||
| 2097 | depends on PCI && FB_MB862XX | ||
| 2098 | ---help--- | ||
| 2099 | This enables framebuffer support for Fujitsu Carmine/Coral-P(A) | ||
| 2100 | PCI graphics controller devices. | ||
| 2101 | |||
| 2102 | config FB_MB862XX_LIME | ||
| 2103 | bool "Lime GDC" | ||
| 2104 | depends on FB_MB862XX | ||
| 2105 | depends on OF && !FB_MB862XX_PCI_GDC | ||
| 2106 | select FB_FOREIGN_ENDIAN | ||
| 2107 | select FB_LITTLE_ENDIAN | ||
| 2108 | ---help--- | ||
| 2109 | Framebuffer support for Fujitsu Lime GDC on host CPU bus. | ||
| 2110 | |||
| 2111 | config FB_PRE_INIT_FB | ||
| 2112 | bool "Don't reinitialize, use bootloader's GDC/Display configuration" | ||
| 2113 | depends on FB_MB862XX_LIME | ||
| 2114 | ---help--- | ||
| 2115 | Select this option if display contents should be inherited as set by | ||
| 2116 | the bootloader. | ||
| 2117 | |||
| 2086 | source "drivers/video/omap/Kconfig" | 2118 | source "drivers/video/omap/Kconfig" |
| 2087 | 2119 | ||
| 2088 | source "drivers/video/backlight/Kconfig" | 2120 | source "drivers/video/backlight/Kconfig" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 248bddc8d0b0..e39e33e797da 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
| @@ -122,6 +122,7 @@ obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o | |||
| 122 | obj-$(CONFIG_FB_OMAP) += omap/ | 122 | obj-$(CONFIG_FB_OMAP) += omap/ |
| 123 | obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o | 123 | obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o |
| 124 | obj-$(CONFIG_FB_CARMINE) += carminefb.o | 124 | obj-$(CONFIG_FB_CARMINE) += carminefb.o |
| 125 | obj-$(CONFIG_FB_MB862XX) += mb862xx/ | ||
| 125 | 126 | ||
| 126 | # Platform or fallback drivers go here | 127 | # Platform or fallback drivers go here |
| 127 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 128 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index f8d0a57a07cb..9a577a800db5 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
| @@ -132,7 +132,7 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) | |||
| 132 | 132 | ||
| 133 | bl = backlight_device_register("backlight", &sinfo->pdev->dev, | 133 | bl = backlight_device_register("backlight", &sinfo->pdev->dev, |
| 134 | sinfo, &atmel_lcdc_bl_ops); | 134 | sinfo, &atmel_lcdc_bl_ops); |
| 135 | if (IS_ERR(sinfo->backlight)) { | 135 | if (IS_ERR(bl)) { |
| 136 | dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n", | 136 | dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n", |
| 137 | PTR_ERR(bl)); | 137 | PTR_ERR(bl)); |
| 138 | return; | 138 | return; |
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index 8718f7349d6b..8da5e5ab8547 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c | |||
| @@ -174,12 +174,12 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, | |||
| 174 | const struct fb_image *image, | 174 | const struct fb_image *image, |
| 175 | u32 fg, u32 bg) | 175 | u32 fg, u32 bg) |
| 176 | { | 176 | { |
| 177 | unsigned int src_bytes, dwords; | 177 | unsigned int dwords; |
| 178 | u32 *bits; | 178 | u32 *bits; |
| 179 | 179 | ||
| 180 | radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, | 180 | radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, |
| 181 | rinfo->dp_gui_mc_base | | 181 | rinfo->dp_gui_mc_base | |
| 182 | GMC_BRUSH_NONE | | 182 | GMC_BRUSH_NONE | GMC_DST_CLIP_LEAVE | |
| 183 | GMC_SRC_DATATYPE_MONO_FG_BG | | 183 | GMC_SRC_DATATYPE_MONO_FG_BG | |
| 184 | ROP3_S | | 184 | ROP3_S | |
| 185 | GMC_BYTE_ORDER_MSB_TO_LSB | | 185 | GMC_BYTE_ORDER_MSB_TO_LSB | |
| @@ -189,9 +189,6 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, | |||
| 189 | radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg); | 189 | radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg); |
| 190 | radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg); | 190 | radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg); |
| 191 | 191 | ||
| 192 | radeon_fifo_wait(rinfo, 1); | ||
| 193 | OUTREG(DST_Y_X, (image->dy << 16) | image->dx); | ||
| 194 | |||
| 195 | /* Ensure the dst cache is flushed and the engine idle before | 192 | /* Ensure the dst cache is flushed and the engine idle before |
| 196 | * issuing the operation. | 193 | * issuing the operation. |
| 197 | * | 194 | * |
| @@ -205,13 +202,19 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, | |||
| 205 | 202 | ||
| 206 | /* X here pads width to a multiple of 32 and uses the clipper to | 203 | /* X here pads width to a multiple of 32 and uses the clipper to |
| 207 | * adjust the result. Is that really necessary ? Things seem to | 204 | * adjust the result. Is that really necessary ? Things seem to |
| 208 | * work ok for me without that and the doco doesn't seem to imply | 205 | * work ok for me without that and the doco doesn't seem to imply] |
| 209 | * there is such a restriction. | 206 | * there is such a restriction. |
| 210 | */ | 207 | */ |
| 211 | OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height); | 208 | radeon_fifo_wait(rinfo, 4); |
| 209 | OUTREG(SC_TOP_LEFT, (image->dy << 16) | image->dx); | ||
| 210 | OUTREG(SC_BOTTOM_RIGHT, ((image->dy + image->height) << 16) | | ||
| 211 | (image->dx + image->width)); | ||
| 212 | OUTREG(DST_Y_X, (image->dy << 16) | image->dx); | ||
| 213 | |||
| 214 | OUTREG(DST_HEIGHT_WIDTH, (image->height << 16) | ((image->width + 31) & ~31)); | ||
| 212 | 215 | ||
| 213 | src_bytes = (((image->width * image->depth) + 7) / 8) * image->height; | 216 | dwords = (image->width + 31) >> 5; |
| 214 | dwords = (src_bytes + 3) / 4; | 217 | dwords *= image->height; |
| 215 | bits = (u32*)(image->data); | 218 | bits = (u32*)(image->data); |
| 216 | 219 | ||
| 217 | while(dwords >= 8) { | 220 | while(dwords >= 8) { |
| @@ -253,7 +256,8 @@ void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 253 | return; | 256 | return; |
| 254 | 257 | ||
| 255 | /* We only do 1 bpp color expansion for now */ | 258 | /* We only do 1 bpp color expansion for now */ |
| 256 | if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) | 259 | if (!accel_cexp || |
| 260 | (info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) | ||
| 257 | goto fallback; | 261 | goto fallback; |
| 258 | 262 | ||
| 259 | /* Fallback if running out of the screen. We may do clipping | 263 | /* Fallback if running out of the screen. We may do clipping |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 9a5821c65ebf..d5b27f9d374d 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
| @@ -282,6 +282,8 @@ static int backlight = 1; | |||
| 282 | static int backlight = 0; | 282 | static int backlight = 0; |
| 283 | #endif | 283 | #endif |
| 284 | 284 | ||
| 285 | int accel_cexp = 0; | ||
| 286 | |||
| 285 | /* | 287 | /* |
| 286 | * prototypes | 288 | * prototypes |
| 287 | */ | 289 | */ |
| @@ -1875,6 +1877,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) | |||
| 1875 | info->fbops = &radeonfb_ops; | 1877 | info->fbops = &radeonfb_ops; |
| 1876 | info->screen_base = rinfo->fb_base; | 1878 | info->screen_base = rinfo->fb_base; |
| 1877 | info->screen_size = rinfo->mapped_vram; | 1879 | info->screen_size = rinfo->mapped_vram; |
| 1880 | |||
| 1878 | /* Fill fix common fields */ | 1881 | /* Fill fix common fields */ |
| 1879 | strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); | 1882 | strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); |
| 1880 | info->fix.smem_start = rinfo->fb_base_phys; | 1883 | info->fix.smem_start = rinfo->fb_base_phys; |
| @@ -1889,8 +1892,25 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) | |||
| 1889 | info->fix.mmio_len = RADEON_REGSIZE; | 1892 | info->fix.mmio_len = RADEON_REGSIZE; |
| 1890 | info->fix.accel = FB_ACCEL_ATI_RADEON; | 1893 | info->fix.accel = FB_ACCEL_ATI_RADEON; |
| 1891 | 1894 | ||
| 1895 | /* Allocate colormap */ | ||
| 1892 | fb_alloc_cmap(&info->cmap, 256, 0); | 1896 | fb_alloc_cmap(&info->cmap, 256, 0); |
| 1893 | 1897 | ||
| 1898 | /* Setup pixmap used for acceleration */ | ||
| 1899 | #define PIXMAP_SIZE (2048 * 4) | ||
| 1900 | |||
| 1901 | info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL); | ||
| 1902 | if (!info->pixmap.addr) { | ||
| 1903 | printk(KERN_ERR "radeonfb: Failed to allocate pixmap !\n"); | ||
| 1904 | noaccel = 1; | ||
| 1905 | goto bail; | ||
| 1906 | } | ||
| 1907 | info->pixmap.size = PIXMAP_SIZE; | ||
| 1908 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
| 1909 | info->pixmap.scan_align = 4; | ||
| 1910 | info->pixmap.buf_align = 4; | ||
| 1911 | info->pixmap.access_align = 32; | ||
| 1912 | |||
| 1913 | bail: | ||
| 1894 | if (noaccel) | 1914 | if (noaccel) |
| 1895 | info->flags |= FBINFO_HWACCEL_DISABLED; | 1915 | info->flags |= FBINFO_HWACCEL_DISABLED; |
| 1896 | 1916 | ||
| @@ -2502,6 +2522,8 @@ static int __init radeonfb_setup (char *options) | |||
| 2502 | } else if (!strncmp(this_opt, "ignore_devlist", 14)) { | 2522 | } else if (!strncmp(this_opt, "ignore_devlist", 14)) { |
| 2503 | ignore_devlist = 1; | 2523 | ignore_devlist = 1; |
| 2504 | #endif | 2524 | #endif |
| 2525 | } else if (!strncmp(this_opt, "accel_cexp", 12)) { | ||
| 2526 | accel_cexp = 1; | ||
| 2505 | } else | 2527 | } else |
| 2506 | mode_option = this_opt; | 2528 | mode_option = this_opt; |
| 2507 | } | 2529 | } |
| @@ -2549,6 +2571,8 @@ module_param(monitor_layout, charp, 0); | |||
| 2549 | MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); | 2571 | MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); |
| 2550 | module_param(force_measure_pll, bool, 0); | 2572 | module_param(force_measure_pll, bool, 0); |
| 2551 | MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)"); | 2573 | MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)"); |
| 2574 | module_param(accel_cexp, bool, 0); | ||
| 2575 | MODULE_PARM_DESC(accel_cexp, "Use acceleration engine for color expansion"); | ||
| 2552 | #ifdef CONFIG_MTRR | 2576 | #ifdef CONFIG_MTRR |
| 2553 | module_param(nomtrr, bool, 0); | 2577 | module_param(nomtrr, bool, 0); |
| 2554 | MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); | 2578 | MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); |
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index ea0b5b47acaf..974ca6d86540 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h | |||
| @@ -638,4 +638,6 @@ static inline void radeonfb_bl_init(struct radeonfb_info *rinfo) {} | |||
| 638 | static inline void radeonfb_bl_exit(struct radeonfb_info *rinfo) {} | 638 | static inline void radeonfb_bl_exit(struct radeonfb_info *rinfo) {} |
| 639 | #endif | 639 | #endif |
| 640 | 640 | ||
| 641 | extern int accel_cexp; | ||
| 642 | |||
| 641 | #endif /* __RADEONFB_H__ */ | 643 | #endif /* __RADEONFB_H__ */ |
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x.c index 242c38250166..93bb4340cc64 100644 --- a/drivers/video/backlight/da903x.c +++ b/drivers/video/backlight/da903x.c | |||
| @@ -119,6 +119,7 @@ static int da903x_backlight_probe(struct platform_device *pdev) | |||
| 119 | default: | 119 | default: |
| 120 | dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", | 120 | dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", |
| 121 | pdev->id); | 121 | pdev->id); |
| 122 | kfree(data); | ||
| 122 | return -EINVAL; | 123 | return -EINVAL; |
| 123 | } | 124 | } |
| 124 | 125 | ||
| @@ -130,6 +131,7 @@ static int da903x_backlight_probe(struct platform_device *pdev) | |||
| 130 | data, &da903x_backlight_ops); | 131 | data, &da903x_backlight_ops); |
| 131 | if (IS_ERR(bl)) { | 132 | if (IS_ERR(bl)) { |
| 132 | dev_err(&pdev->dev, "failed to register backlight\n"); | 133 | dev_err(&pdev->dev, "failed to register backlight\n"); |
| 134 | kfree(data); | ||
| 133 | return PTR_ERR(bl); | 135 | return PTR_ERR(bl); |
| 134 | } | 136 | } |
| 135 | 137 | ||
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 8e1731d3b228..680e57b616cd 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
| @@ -42,10 +42,13 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
| 42 | 42 | ||
| 43 | mutex_lock(&ld->ops_lock); | 43 | mutex_lock(&ld->ops_lock); |
| 44 | if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { | 44 | if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { |
| 45 | if (event == FB_EVENT_BLANK) | 45 | if (event == FB_EVENT_BLANK) { |
| 46 | ld->ops->set_power(ld, *(int *)evdata->data); | 46 | if (ld->ops->set_power) |
| 47 | else | 47 | ld->ops->set_power(ld, *(int *)evdata->data); |
| 48 | ld->ops->set_mode(ld, evdata->data); | 48 | } else { |
| 49 | if (ld->ops->set_mode) | ||
| 50 | ld->ops->set_mode(ld, evdata->data); | ||
| 51 | } | ||
| 49 | } | 52 | } |
| 50 | mutex_unlock(&ld->ops_lock); | 53 | mutex_unlock(&ld->ops_lock); |
| 51 | return 0; | 54 | return 0; |
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 048b139f0e50..a2aa6ddffbe2 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
| @@ -2049,7 +2049,7 @@ static void cirrusfb_pci_unmap(struct fb_info *info) | |||
| 2049 | #endif /* CONFIG_PCI */ | 2049 | #endif /* CONFIG_PCI */ |
| 2050 | 2050 | ||
| 2051 | #ifdef CONFIG_ZORRO | 2051 | #ifdef CONFIG_ZORRO |
| 2052 | static void __devexit cirrusfb_zorro_unmap(struct fb_info *info) | 2052 | static void cirrusfb_zorro_unmap(struct fb_info *info) |
| 2053 | { | 2053 | { |
| 2054 | struct cirrusfb_info *cinfo = info->par; | 2054 | struct cirrusfb_info *cinfo = info->par; |
| 2055 | struct zorro_dev *zdev = to_zorro_dev(info->device); | 2055 | struct zorro_dev *zdev = to_zorro_dev(info->device); |
| @@ -2462,8 +2462,7 @@ static int __init cirrusfb_init(void) | |||
| 2462 | 2462 | ||
| 2463 | #ifndef MODULE | 2463 | #ifndef MODULE |
| 2464 | static int __init cirrusfb_setup(char *options) { | 2464 | static int __init cirrusfb_setup(char *options) { |
| 2465 | char *this_opt, s[32]; | 2465 | char *this_opt; |
| 2466 | int i; | ||
| 2467 | 2466 | ||
| 2468 | DPRINTK("ENTER\n"); | 2467 | DPRINTK("ENTER\n"); |
| 2469 | 2468 | ||
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index b92947d62ad6..0b2adefe9e3d 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
| @@ -2389,16 +2389,13 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | |||
| 2389 | 2389 | ||
| 2390 | if (!fbcon_is_inactive(vc, info)) { | 2390 | if (!fbcon_is_inactive(vc, info)) { |
| 2391 | if (ops->blank_state != blank) { | 2391 | if (ops->blank_state != blank) { |
| 2392 | int ret = 1; | ||
| 2393 | |||
| 2394 | ops->blank_state = blank; | 2392 | ops->blank_state = blank; |
| 2395 | fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); | 2393 | fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); |
| 2396 | ops->cursor_flash = (!blank); | 2394 | ops->cursor_flash = (!blank); |
| 2397 | 2395 | ||
| 2398 | if (info->fbops->fb_blank) | 2396 | if (!(info->flags & FBINFO_MISC_USEREVENT)) |
| 2399 | ret = info->fbops->fb_blank(blank, info); | 2397 | if (fb_blank(info, blank)) |
| 2400 | if (ret) | 2398 | fbcon_generic_blank(vc, info, blank); |
| 2401 | fbcon_generic_blank(vc, info, blank); | ||
| 2402 | } | 2399 | } |
| 2403 | 2400 | ||
| 2404 | if (!blank) | 2401 | if (!blank) |
| @@ -3534,12 +3531,18 @@ static void fbcon_exit(void) | |||
| 3534 | softback_buf = 0UL; | 3531 | softback_buf = 0UL; |
| 3535 | 3532 | ||
| 3536 | for (i = 0; i < FB_MAX; i++) { | 3533 | for (i = 0; i < FB_MAX; i++) { |
| 3534 | int pending; | ||
| 3535 | |||
| 3537 | mapped = 0; | 3536 | mapped = 0; |
| 3538 | info = registered_fb[i]; | 3537 | info = registered_fb[i]; |
| 3539 | 3538 | ||
| 3540 | if (info == NULL) | 3539 | if (info == NULL) |
| 3541 | continue; | 3540 | continue; |
| 3542 | 3541 | ||
| 3542 | pending = cancel_work_sync(&info->queue); | ||
| 3543 | DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : | ||
| 3544 | "no")); | ||
| 3545 | |||
| 3543 | for (j = first_fb_vc; j <= last_fb_vc; j++) { | 3546 | for (j = first_fb_vc; j <= last_fb_vc; j++) { |
| 3544 | if (con2fb_map[j] == i) | 3547 | if (con2fb_map[j] == i) |
| 3545 | mapped = 1; | 3548 | mapped = 1; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 6048b55f2878..3c65b0d67617 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
| @@ -230,7 +230,7 @@ static void fb_set_logo_directpalette(struct fb_info *info, | |||
| 230 | greenshift = info->var.green.offset; | 230 | greenshift = info->var.green.offset; |
| 231 | blueshift = info->var.blue.offset; | 231 | blueshift = info->var.blue.offset; |
| 232 | 232 | ||
| 233 | for (i = 32; i < logo->clutsize; i++) | 233 | for (i = 32; i < 32 + logo->clutsize; i++) |
| 234 | palette[i] = i << redshift | i << greenshift | i << blueshift; | 234 | palette[i] = i << redshift | i << greenshift | i << blueshift; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| @@ -1002,13 +1002,9 @@ fb_blank(struct fb_info *info, int blank) | |||
| 1002 | return ret; | 1002 | return ret; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | static long | 1005 | static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, |
| 1006 | fb_ioctl(struct file *file, unsigned int cmd, | 1006 | unsigned long arg) |
| 1007 | unsigned long arg) | ||
| 1008 | { | 1007 | { |
| 1009 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 1010 | int fbidx = iminor(inode); | ||
| 1011 | struct fb_info *info; | ||
| 1012 | struct fb_ops *fb; | 1008 | struct fb_ops *fb; |
| 1013 | struct fb_var_screeninfo var; | 1009 | struct fb_var_screeninfo var; |
| 1014 | struct fb_fix_screeninfo fix; | 1010 | struct fb_fix_screeninfo fix; |
| @@ -1018,14 +1014,10 @@ fb_ioctl(struct file *file, unsigned int cmd, | |||
| 1018 | void __user *argp = (void __user *)arg; | 1014 | void __user *argp = (void __user *)arg; |
| 1019 | long ret = 0; | 1015 | long ret = 0; |
| 1020 | 1016 | ||
| 1021 | info = registered_fb[fbidx]; | ||
| 1022 | mutex_lock(&info->lock); | ||
| 1023 | fb = info->fbops; | 1017 | fb = info->fbops; |
| 1024 | 1018 | if (!fb) | |
| 1025 | if (!fb) { | ||
| 1026 | mutex_unlock(&info->lock); | ||
| 1027 | return -ENODEV; | 1019 | return -ENODEV; |
| 1028 | } | 1020 | |
| 1029 | switch (cmd) { | 1021 | switch (cmd) { |
| 1030 | case FBIOGET_VSCREENINFO: | 1022 | case FBIOGET_VSCREENINFO: |
| 1031 | ret = copy_to_user(argp, &info->var, | 1023 | ret = copy_to_user(argp, &info->var, |
| @@ -1126,6 +1118,21 @@ fb_ioctl(struct file *file, unsigned int cmd, | |||
| 1126 | else | 1118 | else |
| 1127 | ret = fb->fb_ioctl(info, cmd, arg); | 1119 | ret = fb->fb_ioctl(info, cmd, arg); |
| 1128 | } | 1120 | } |
| 1121 | return ret; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
| 1125 | __acquires(&info->lock) | ||
| 1126 | __releases(&info->lock) | ||
| 1127 | { | ||
| 1128 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 1129 | int fbidx = iminor(inode); | ||
| 1130 | struct fb_info *info; | ||
| 1131 | long ret; | ||
| 1132 | |||
| 1133 | info = registered_fb[fbidx]; | ||
| 1134 | mutex_lock(&info->lock); | ||
| 1135 | ret = do_fb_ioctl(info, cmd, arg); | ||
| 1129 | mutex_unlock(&info->lock); | 1136 | mutex_unlock(&info->lock); |
| 1130 | return ret; | 1137 | return ret; |
| 1131 | } | 1138 | } |
| @@ -1157,8 +1164,8 @@ struct fb_cmap32 { | |||
| 1157 | compat_caddr_t transp; | 1164 | compat_caddr_t transp; |
| 1158 | }; | 1165 | }; |
| 1159 | 1166 | ||
| 1160 | static int fb_getput_cmap(struct inode *inode, struct file *file, | 1167 | static int fb_getput_cmap(struct fb_info *info, unsigned int cmd, |
| 1161 | unsigned int cmd, unsigned long arg) | 1168 | unsigned long arg) |
| 1162 | { | 1169 | { |
| 1163 | struct fb_cmap_user __user *cmap; | 1170 | struct fb_cmap_user __user *cmap; |
| 1164 | struct fb_cmap32 __user *cmap32; | 1171 | struct fb_cmap32 __user *cmap32; |
| @@ -1181,7 +1188,7 @@ static int fb_getput_cmap(struct inode *inode, struct file *file, | |||
| 1181 | put_user(compat_ptr(data), &cmap->transp)) | 1188 | put_user(compat_ptr(data), &cmap->transp)) |
| 1182 | return -EFAULT; | 1189 | return -EFAULT; |
| 1183 | 1190 | ||
| 1184 | err = fb_ioctl(file, cmd, (unsigned long) cmap); | 1191 | err = do_fb_ioctl(info, cmd, (unsigned long) cmap); |
| 1185 | 1192 | ||
| 1186 | if (!err) { | 1193 | if (!err) { |
| 1187 | if (copy_in_user(&cmap32->start, | 1194 | if (copy_in_user(&cmap32->start, |
| @@ -1223,8 +1230,8 @@ static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, | |||
| 1223 | return err; | 1230 | return err; |
| 1224 | } | 1231 | } |
| 1225 | 1232 | ||
| 1226 | static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | 1233 | static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, |
| 1227 | unsigned int cmd, unsigned long arg) | 1234 | unsigned long arg) |
| 1228 | { | 1235 | { |
| 1229 | mm_segment_t old_fs; | 1236 | mm_segment_t old_fs; |
| 1230 | struct fb_fix_screeninfo fix; | 1237 | struct fb_fix_screeninfo fix; |
| @@ -1235,7 +1242,7 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | |||
| 1235 | 1242 | ||
| 1236 | old_fs = get_fs(); | 1243 | old_fs = get_fs(); |
| 1237 | set_fs(KERNEL_DS); | 1244 | set_fs(KERNEL_DS); |
| 1238 | err = fb_ioctl(file, cmd, (unsigned long) &fix); | 1245 | err = do_fb_ioctl(info, cmd, (unsigned long) &fix); |
| 1239 | set_fs(old_fs); | 1246 | set_fs(old_fs); |
| 1240 | 1247 | ||
| 1241 | if (!err) | 1248 | if (!err) |
| @@ -1244,8 +1251,10 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | |||
| 1244 | return err; | 1251 | return err; |
| 1245 | } | 1252 | } |
| 1246 | 1253 | ||
| 1247 | static long | 1254 | static long fb_compat_ioctl(struct file *file, unsigned int cmd, |
| 1248 | fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1255 | unsigned long arg) |
| 1256 | __acquires(&info->lock) | ||
| 1257 | __releases(&info->lock) | ||
| 1249 | { | 1258 | { |
| 1250 | struct inode *inode = file->f_path.dentry->d_inode; | 1259 | struct inode *inode = file->f_path.dentry->d_inode; |
| 1251 | int fbidx = iminor(inode); | 1260 | int fbidx = iminor(inode); |
| @@ -1262,16 +1271,16 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1262 | case FBIOPUT_CON2FBMAP: | 1271 | case FBIOPUT_CON2FBMAP: |
| 1263 | arg = (unsigned long) compat_ptr(arg); | 1272 | arg = (unsigned long) compat_ptr(arg); |
| 1264 | case FBIOBLANK: | 1273 | case FBIOBLANK: |
| 1265 | mutex_unlock(&info->lock); | 1274 | ret = do_fb_ioctl(info, cmd, arg); |
| 1266 | return fb_ioctl(file, cmd, arg); | 1275 | break; |
| 1267 | 1276 | ||
| 1268 | case FBIOGET_FSCREENINFO: | 1277 | case FBIOGET_FSCREENINFO: |
| 1269 | ret = fb_get_fscreeninfo(inode, file, cmd, arg); | 1278 | ret = fb_get_fscreeninfo(info, cmd, arg); |
| 1270 | break; | 1279 | break; |
| 1271 | 1280 | ||
| 1272 | case FBIOGETCMAP: | 1281 | case FBIOGETCMAP: |
| 1273 | case FBIOPUTCMAP: | 1282 | case FBIOPUTCMAP: |
| 1274 | ret = fb_getput_cmap(inode, file, cmd, arg); | 1283 | ret = fb_getput_cmap(info, cmd, arg); |
| 1275 | break; | 1284 | break; |
| 1276 | 1285 | ||
| 1277 | default: | 1286 | default: |
| @@ -1286,6 +1295,8 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1286 | 1295 | ||
| 1287 | static int | 1296 | static int |
| 1288 | fb_mmap(struct file *file, struct vm_area_struct * vma) | 1297 | fb_mmap(struct file *file, struct vm_area_struct * vma) |
| 1298 | __acquires(&info->lock) | ||
| 1299 | __releases(&info->lock) | ||
| 1289 | { | 1300 | { |
| 1290 | int fbidx = iminor(file->f_path.dentry->d_inode); | 1301 | int fbidx = iminor(file->f_path.dentry->d_inode); |
| 1291 | struct fb_info *info = registered_fb[fbidx]; | 1302 | struct fb_info *info = registered_fb[fbidx]; |
| @@ -1339,6 +1350,8 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
| 1339 | 1350 | ||
| 1340 | static int | 1351 | static int |
| 1341 | fb_open(struct inode *inode, struct file *file) | 1352 | fb_open(struct inode *inode, struct file *file) |
| 1353 | __acquires(&info->lock) | ||
| 1354 | __releases(&info->lock) | ||
| 1342 | { | 1355 | { |
| 1343 | int fbidx = iminor(inode); | 1356 | int fbidx = iminor(inode); |
| 1344 | struct fb_info *info; | 1357 | struct fb_info *info; |
| @@ -1374,6 +1387,8 @@ out: | |||
| 1374 | 1387 | ||
| 1375 | static int | 1388 | static int |
| 1376 | fb_release(struct inode *inode, struct file *file) | 1389 | fb_release(struct inode *inode, struct file *file) |
| 1390 | __acquires(&info->lock) | ||
| 1391 | __releases(&info->lock) | ||
| 1377 | { | 1392 | { |
| 1378 | struct fb_info * const info = file->private_data; | 1393 | struct fb_info * const info = file->private_data; |
| 1379 | 1394 | ||
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index b790ddff76f9..ee380d5f3410 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c | |||
| @@ -164,7 +164,6 @@ static struct fb_var_screeninfo macfb_defined = { | |||
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | static struct fb_fix_screeninfo macfb_fix = { | 166 | static struct fb_fix_screeninfo macfb_fix = { |
| 167 | .id = "Macintosh ", | ||
| 168 | .type = FB_TYPE_PACKED_PIXELS, | 167 | .type = FB_TYPE_PACKED_PIXELS, |
| 169 | .accel = FB_ACCEL_NONE, | 168 | .accel = FB_ACCEL_NONE, |
| 170 | }; | 169 | }; |
| @@ -760,22 +759,22 @@ static int __init macfb_init(void) | |||
| 760 | 759 | ||
| 761 | switch(ndev->dr_hw) { | 760 | switch(ndev->dr_hw) { |
| 762 | case NUBUS_DRHW_APPLE_MDC: | 761 | case NUBUS_DRHW_APPLE_MDC: |
| 763 | strcat( macfb_fix.id, "Display Card" ); | 762 | strcpy(macfb_fix.id, "Mac Disp. Card"); |
| 764 | macfb_setpalette = mdc_setpalette; | 763 | macfb_setpalette = mdc_setpalette; |
| 765 | macfb_defined.activate = FB_ACTIVATE_NOW; | 764 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 766 | break; | 765 | break; |
| 767 | case NUBUS_DRHW_APPLE_TFB: | 766 | case NUBUS_DRHW_APPLE_TFB: |
| 768 | strcat( macfb_fix.id, "Toby" ); | 767 | strcpy(macfb_fix.id, "Toby"); |
| 769 | macfb_setpalette = toby_setpalette; | 768 | macfb_setpalette = toby_setpalette; |
| 770 | macfb_defined.activate = FB_ACTIVATE_NOW; | 769 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 771 | break; | 770 | break; |
| 772 | case NUBUS_DRHW_APPLE_JET: | 771 | case NUBUS_DRHW_APPLE_JET: |
| 773 | strcat( macfb_fix.id, "Jet"); | 772 | strcpy(macfb_fix.id, "Jet"); |
| 774 | macfb_setpalette = jet_setpalette; | 773 | macfb_setpalette = jet_setpalette; |
| 775 | macfb_defined.activate = FB_ACTIVATE_NOW; | 774 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 776 | break; | 775 | break; |
| 777 | default: | 776 | default: |
| 778 | strcat( macfb_fix.id, "Generic NuBus" ); | 777 | strcpy(macfb_fix.id, "Generic NuBus"); |
| 779 | break; | 778 | break; |
| 780 | } | 779 | } |
| 781 | } | 780 | } |
| @@ -786,21 +785,11 @@ static int __init macfb_init(void) | |||
| 786 | if (!video_is_nubus) | 785 | if (!video_is_nubus) |
| 787 | switch( mac_bi_data.id ) | 786 | switch( mac_bi_data.id ) |
| 788 | { | 787 | { |
| 789 | /* These don't have onboard video. Eventually, we may | ||
| 790 | be able to write separate framebuffer drivers for | ||
| 791 | them (tobyfb.c, hiresfb.c, etc, etc) */ | ||
| 792 | case MAC_MODEL_II: | ||
| 793 | case MAC_MODEL_IIX: | ||
| 794 | case MAC_MODEL_IICX: | ||
| 795 | case MAC_MODEL_IIFX: | ||
| 796 | strcat( macfb_fix.id, "Generic NuBus" ); | ||
| 797 | break; | ||
| 798 | |||
| 799 | /* Valkyrie Quadras */ | 788 | /* Valkyrie Quadras */ |
| 800 | case MAC_MODEL_Q630: | 789 | case MAC_MODEL_Q630: |
| 801 | /* I'm not sure about this one */ | 790 | /* I'm not sure about this one */ |
| 802 | case MAC_MODEL_P588: | 791 | case MAC_MODEL_P588: |
| 803 | strcat( macfb_fix.id, "Valkyrie built-in" ); | 792 | strcpy(macfb_fix.id, "Valkyrie"); |
| 804 | macfb_setpalette = valkyrie_setpalette; | 793 | macfb_setpalette = valkyrie_setpalette; |
| 805 | macfb_defined.activate = FB_ACTIVATE_NOW; | 794 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 806 | valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000); | 795 | valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000); |
| @@ -823,7 +812,7 @@ static int __init macfb_init(void) | |||
| 823 | case MAC_MODEL_Q700: | 812 | case MAC_MODEL_Q700: |
| 824 | case MAC_MODEL_Q900: | 813 | case MAC_MODEL_Q900: |
| 825 | case MAC_MODEL_Q950: | 814 | case MAC_MODEL_Q950: |
| 826 | strcat( macfb_fix.id, "DAFB built-in" ); | 815 | strcpy(macfb_fix.id, "DAFB"); |
| 827 | macfb_setpalette = dafb_setpalette; | 816 | macfb_setpalette = dafb_setpalette; |
| 828 | macfb_defined.activate = FB_ACTIVATE_NOW; | 817 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 829 | dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); | 818 | dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); |
| @@ -831,7 +820,7 @@ static int __init macfb_init(void) | |||
| 831 | 820 | ||
| 832 | /* LC II uses the V8 framebuffer */ | 821 | /* LC II uses the V8 framebuffer */ |
| 833 | case MAC_MODEL_LCII: | 822 | case MAC_MODEL_LCII: |
| 834 | strcat( macfb_fix.id, "V8 built-in" ); | 823 | strcpy(macfb_fix.id, "V8"); |
| 835 | macfb_setpalette = v8_brazil_setpalette; | 824 | macfb_setpalette = v8_brazil_setpalette; |
| 836 | macfb_defined.activate = FB_ACTIVATE_NOW; | 825 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 837 | v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); | 826 | v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); |
| @@ -843,7 +832,7 @@ static int __init macfb_init(void) | |||
| 843 | case MAC_MODEL_IIVI: | 832 | case MAC_MODEL_IIVI: |
| 844 | case MAC_MODEL_IIVX: | 833 | case MAC_MODEL_IIVX: |
| 845 | case MAC_MODEL_P600: | 834 | case MAC_MODEL_P600: |
| 846 | strcat( macfb_fix.id, "Brazil built-in" ); | 835 | strcpy(macfb_fix.id, "Brazil"); |
| 847 | macfb_setpalette = v8_brazil_setpalette; | 836 | macfb_setpalette = v8_brazil_setpalette; |
| 848 | macfb_defined.activate = FB_ACTIVATE_NOW; | 837 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 849 | v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); | 838 | v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); |
| @@ -860,7 +849,7 @@ static int __init macfb_init(void) | |||
| 860 | case MAC_MODEL_P460: | 849 | case MAC_MODEL_P460: |
| 861 | macfb_setpalette = v8_brazil_setpalette; | 850 | macfb_setpalette = v8_brazil_setpalette; |
| 862 | macfb_defined.activate = FB_ACTIVATE_NOW; | 851 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 863 | strcat( macfb_fix.id, "Sonora built-in" ); | 852 | strcpy(macfb_fix.id, "Sonora"); |
| 864 | v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); | 853 | v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); |
| 865 | break; | 854 | break; |
| 866 | 855 | ||
| @@ -871,7 +860,7 @@ static int __init macfb_init(void) | |||
| 871 | case MAC_MODEL_IISI: | 860 | case MAC_MODEL_IISI: |
| 872 | macfb_setpalette = rbv_setpalette; | 861 | macfb_setpalette = rbv_setpalette; |
| 873 | macfb_defined.activate = FB_ACTIVATE_NOW; | 862 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 874 | strcat( macfb_fix.id, "RBV built-in" ); | 863 | strcpy(macfb_fix.id, "RBV"); |
| 875 | rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); | 864 | rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); |
| 876 | break; | 865 | break; |
| 877 | 866 | ||
| @@ -880,7 +869,7 @@ static int __init macfb_init(void) | |||
| 880 | case MAC_MODEL_C660: | 869 | case MAC_MODEL_C660: |
| 881 | macfb_setpalette = civic_setpalette; | 870 | macfb_setpalette = civic_setpalette; |
| 882 | macfb_defined.activate = FB_ACTIVATE_NOW; | 871 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 883 | strcat( macfb_fix.id, "Civic built-in" ); | 872 | strcpy(macfb_fix.id, "Civic"); |
| 884 | civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); | 873 | civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); |
| 885 | break; | 874 | break; |
| 886 | 875 | ||
| @@ -901,7 +890,7 @@ static int __init macfb_init(void) | |||
| 901 | v8_brazil_cmap_regs = | 890 | v8_brazil_cmap_regs = |
| 902 | ioremap(DAC_BASE, 0x1000); | 891 | ioremap(DAC_BASE, 0x1000); |
| 903 | } | 892 | } |
| 904 | strcat( macfb_fix.id, "LC built-in" ); | 893 | strcpy(macfb_fix.id, "LC"); |
| 905 | break; | 894 | break; |
| 906 | /* We think this may be like the LC II */ | 895 | /* We think this may be like the LC II */ |
| 907 | case MAC_MODEL_CCL: | 896 | case MAC_MODEL_CCL: |
| @@ -911,18 +900,18 @@ static int __init macfb_init(void) | |||
| 911 | v8_brazil_cmap_regs = | 900 | v8_brazil_cmap_regs = |
| 912 | ioremap(DAC_BASE, 0x1000); | 901 | ioremap(DAC_BASE, 0x1000); |
| 913 | } | 902 | } |
| 914 | strcat( macfb_fix.id, "Color Classic built-in" ); | 903 | strcpy(macfb_fix.id, "Color Classic"); |
| 915 | break; | 904 | break; |
| 916 | 905 | ||
| 917 | /* And we *do* mean "weirdos" */ | 906 | /* And we *do* mean "weirdos" */ |
| 918 | case MAC_MODEL_TV: | 907 | case MAC_MODEL_TV: |
| 919 | strcat( macfb_fix.id, "Mac TV built-in" ); | 908 | strcpy(macfb_fix.id, "Mac TV"); |
| 920 | break; | 909 | break; |
| 921 | 910 | ||
| 922 | /* These don't have colour, so no need to worry */ | 911 | /* These don't have colour, so no need to worry */ |
| 923 | case MAC_MODEL_SE30: | 912 | case MAC_MODEL_SE30: |
| 924 | case MAC_MODEL_CLII: | 913 | case MAC_MODEL_CLII: |
| 925 | strcat( macfb_fix.id, "Monochrome built-in" ); | 914 | strcpy(macfb_fix.id, "Monochrome"); |
| 926 | break; | 915 | break; |
| 927 | 916 | ||
| 928 | /* Powerbooks are particularly difficult. Many of | 917 | /* Powerbooks are particularly difficult. Many of |
| @@ -935,7 +924,7 @@ static int __init macfb_init(void) | |||
| 935 | case MAC_MODEL_PB140: | 924 | case MAC_MODEL_PB140: |
| 936 | case MAC_MODEL_PB145: | 925 | case MAC_MODEL_PB145: |
| 937 | case MAC_MODEL_PB170: | 926 | case MAC_MODEL_PB170: |
| 938 | strcat( macfb_fix.id, "DDC built-in" ); | 927 | strcpy(macfb_fix.id, "DDC"); |
| 939 | break; | 928 | break; |
| 940 | 929 | ||
| 941 | /* Internal is GSC, External (if present) is ViSC */ | 930 | /* Internal is GSC, External (if present) is ViSC */ |
| @@ -945,13 +934,13 @@ static int __init macfb_init(void) | |||
| 945 | case MAC_MODEL_PB180: | 934 | case MAC_MODEL_PB180: |
| 946 | case MAC_MODEL_PB210: | 935 | case MAC_MODEL_PB210: |
| 947 | case MAC_MODEL_PB230: | 936 | case MAC_MODEL_PB230: |
| 948 | strcat( macfb_fix.id, "GSC built-in" ); | 937 | strcpy(macfb_fix.id, "GSC"); |
| 949 | break; | 938 | break; |
| 950 | 939 | ||
| 951 | /* Internal is TIM, External is ViSC */ | 940 | /* Internal is TIM, External is ViSC */ |
| 952 | case MAC_MODEL_PB165C: | 941 | case MAC_MODEL_PB165C: |
| 953 | case MAC_MODEL_PB180C: | 942 | case MAC_MODEL_PB180C: |
| 954 | strcat( macfb_fix.id, "TIM built-in" ); | 943 | strcpy(macfb_fix.id, "TIM"); |
| 955 | break; | 944 | break; |
| 956 | 945 | ||
| 957 | /* Internal is CSC, External is Keystone+Ariel. */ | 946 | /* Internal is CSC, External is Keystone+Ariel. */ |
| @@ -963,12 +952,12 @@ static int __init macfb_init(void) | |||
| 963 | case MAC_MODEL_PB280C: | 952 | case MAC_MODEL_PB280C: |
| 964 | macfb_setpalette = csc_setpalette; | 953 | macfb_setpalette = csc_setpalette; |
| 965 | macfb_defined.activate = FB_ACTIVATE_NOW; | 954 | macfb_defined.activate = FB_ACTIVATE_NOW; |
| 966 | strcat( macfb_fix.id, "CSC built-in" ); | 955 | strcpy(macfb_fix.id, "CSC"); |
| 967 | csc_cmap_regs = ioremap(CSC_BASE, 0x1000); | 956 | csc_cmap_regs = ioremap(CSC_BASE, 0x1000); |
| 968 | break; | 957 | break; |
| 969 | 958 | ||
| 970 | default: | 959 | default: |
| 971 | strcat( macfb_fix.id, "Unknown/Unsupported built-in" ); | 960 | strcpy(macfb_fix.id, "Unknown"); |
| 972 | break; | 961 | break; |
| 973 | } | 962 | } |
| 974 | 963 | ||
| @@ -978,16 +967,23 @@ static int __init macfb_init(void) | |||
| 978 | fb_info.pseudo_palette = pseudo_palette; | 967 | fb_info.pseudo_palette = pseudo_palette; |
| 979 | fb_info.flags = FBINFO_DEFAULT; | 968 | fb_info.flags = FBINFO_DEFAULT; |
| 980 | 969 | ||
| 981 | fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); | 970 | err = fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); |
| 971 | if (err) | ||
| 972 | goto fail_unmap; | ||
| 982 | 973 | ||
| 983 | err = register_framebuffer(&fb_info); | 974 | err = register_framebuffer(&fb_info); |
| 984 | if (!err) | 975 | if (err) |
| 985 | printk("fb%d: %s frame buffer device\n", | 976 | goto fail_dealloc; |
| 986 | fb_info.node, fb_info.fix.id); | 977 | |
| 987 | else { | 978 | printk("fb%d: %s frame buffer device\n", |
| 988 | iounmap(fb_info.screen_base); | 979 | fb_info.node, fb_info.fix.id); |
| 989 | iounmap_macfb(); | 980 | return 0; |
| 990 | } | 981 | |
| 982 | fail_dealloc: | ||
| 983 | fb_dealloc_cmap(&fb_info.cmap); | ||
| 984 | fail_unmap: | ||
| 985 | iounmap(fb_info.screen_base); | ||
| 986 | iounmap_macfb(); | ||
| 991 | return err; | 987 | return err; |
| 992 | } | 988 | } |
| 993 | 989 | ||
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/mb862xx/Makefile new file mode 100644 index 000000000000..07664814bb1d --- /dev/null +++ b/drivers/video/mb862xx/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the MB862xx framebuffer driver | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_FB_MB862XX) := mb862xxfb.o | ||
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/mb862xx/mb862xx_reg.h new file mode 100644 index 000000000000..2ba65e118500 --- /dev/null +++ b/drivers/video/mb862xx/mb862xx_reg.h | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | /* | ||
| 2 | * Fujitsu MB862xx Graphics Controller Registers/Bits | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef _MB862XX_REG_H | ||
| 6 | #define _MB862XX_REG_H | ||
| 7 | |||
| 8 | #ifdef MB862XX_MMIO_BOTTOM | ||
| 9 | #define MB862XX_MMIO_BASE 0x03fc0000 | ||
| 10 | #else | ||
| 11 | #define MB862XX_MMIO_BASE 0x01fc0000 | ||
| 12 | #endif | ||
| 13 | #define MB862XX_I2C_BASE 0x0000c000 | ||
| 14 | #define MB862XX_DISP_BASE 0x00010000 | ||
| 15 | #define MB862XX_CAP_BASE 0x00018000 | ||
| 16 | #define MB862XX_DRAW_BASE 0x00030000 | ||
| 17 | #define MB862XX_GEO_BASE 0x00038000 | ||
| 18 | #define MB862XX_PIO_BASE 0x00038000 | ||
| 19 | #define MB862XX_MMIO_SIZE 0x40000 | ||
| 20 | |||
| 21 | /* Host interface/pio registers */ | ||
| 22 | #define GC_IST 0x00000020 | ||
| 23 | #define GC_IMASK 0x00000024 | ||
| 24 | #define GC_SRST 0x0000002c | ||
| 25 | #define GC_CCF 0x00000038 | ||
| 26 | #define GC_CID 0x000000f0 | ||
| 27 | #define GC_REVISION 0x00000084 | ||
| 28 | |||
| 29 | #define GC_CCF_CGE_100 0x00000000 | ||
| 30 | #define GC_CCF_CGE_133 0x00040000 | ||
| 31 | #define GC_CCF_CGE_166 0x00080000 | ||
| 32 | #define GC_CCF_COT_100 0x00000000 | ||
| 33 | #define GC_CCF_COT_133 0x00010000 | ||
| 34 | #define GC_CID_CNAME_MSK 0x0000ff00 | ||
| 35 | #define GC_CID_VERSION_MSK 0x000000ff | ||
| 36 | |||
| 37 | /* define enabled interrupts hereby */ | ||
| 38 | #define GC_INT_EN 0x00000000 | ||
| 39 | |||
| 40 | /* Memory interface mode register */ | ||
| 41 | #define GC_MMR 0x0000fffc | ||
| 42 | |||
| 43 | /* Display Controller registers */ | ||
| 44 | #define GC_DCM0 0x00000000 | ||
| 45 | #define GC_HTP 0x00000004 | ||
| 46 | #define GC_HDB_HDP 0x00000008 | ||
| 47 | #define GC_VSW_HSW_HSP 0x0000000c | ||
| 48 | #define GC_VTR 0x00000010 | ||
| 49 | #define GC_VDP_VSP 0x00000014 | ||
| 50 | #define GC_WY_WX 0x00000018 | ||
| 51 | #define GC_WH_WW 0x0000001c | ||
| 52 | #define GC_L0M 0x00000020 | ||
| 53 | #define GC_L0OA0 0x00000024 | ||
| 54 | #define GC_L0DA0 0x00000028 | ||
| 55 | #define GC_L0DY_L0DX 0x0000002c | ||
| 56 | #define GC_DCM1 0x00000100 | ||
| 57 | #define GC_L0EM 0x00000110 | ||
| 58 | #define GC_L0WY_L0WX 0x00000114 | ||
| 59 | #define GC_L0WH_L0WW 0x00000118 | ||
| 60 | #define GC_DCM2 0x00000104 | ||
| 61 | #define GC_DCM3 0x00000108 | ||
| 62 | #define GC_CPM_CUTC 0x000000a0 | ||
| 63 | #define GC_CUOA0 0x000000a4 | ||
| 64 | #define GC_CUY0_CUX0 0x000000a8 | ||
| 65 | #define GC_CUOA1 0x000000ac | ||
| 66 | #define GC_CUY1_CUX1 0x000000b0 | ||
| 67 | #define GC_L0PAL0 0x00000400 | ||
| 68 | |||
| 69 | #define GC_CPM_CEN0 0x00100000 | ||
| 70 | #define GC_CPM_CEN1 0x00200000 | ||
| 71 | |||
| 72 | #define GC_DCM01_ESY 0x00000004 | ||
| 73 | #define GC_DCM01_SC 0x00003f00 | ||
| 74 | #define GC_DCM01_RESV 0x00004000 | ||
| 75 | #define GC_DCM01_CKS 0x00008000 | ||
| 76 | #define GC_DCM01_L0E 0x00010000 | ||
| 77 | #define GC_DCM01_DEN 0x80000000 | ||
| 78 | #define GC_L0M_L0C_8 0x00000000 | ||
| 79 | #define GC_L0M_L0C_16 0x80000000 | ||
| 80 | #define GC_L0EM_L0EC_24 0x40000000 | ||
| 81 | #define GC_L0M_L0W_UNIT 64 | ||
| 82 | |||
| 83 | #define GC_DISP_REFCLK_400 400 | ||
| 84 | |||
| 85 | /* Carmine specific */ | ||
| 86 | #define MB86297_DRAW_BASE 0x00020000 | ||
| 87 | #define MB86297_DISP0_BASE 0x00100000 | ||
| 88 | #define MB86297_DISP1_BASE 0x00140000 | ||
| 89 | #define MB86297_WRBACK_BASE 0x00180000 | ||
| 90 | #define MB86297_CAP0_BASE 0x00200000 | ||
| 91 | #define MB86297_CAP1_BASE 0x00280000 | ||
| 92 | #define MB86297_DRAMCTRL_BASE 0x00300000 | ||
| 93 | #define MB86297_CTRL_BASE 0x00400000 | ||
| 94 | #define MB86297_I2C_BASE 0x00500000 | ||
| 95 | |||
| 96 | #define GC_CTRL_STATUS 0x00000000 | ||
| 97 | #define GC_CTRL_INT_MASK 0x00000004 | ||
| 98 | #define GC_CTRL_CLK_ENABLE 0x0000000c | ||
| 99 | #define GC_CTRL_SOFT_RST 0x00000010 | ||
| 100 | |||
| 101 | #define GC_CTRL_CLK_EN_DRAM 0x00000001 | ||
| 102 | #define GC_CTRL_CLK_EN_2D3D 0x00000002 | ||
| 103 | #define GC_CTRL_CLK_EN_DISP0 0x00000020 | ||
| 104 | #define GC_CTRL_CLK_EN_DISP1 0x00000040 | ||
| 105 | |||
| 106 | #define GC_2D3D_REV 0x000004b4 | ||
| 107 | #define GC_RE_REVISION 0x24240200 | ||
| 108 | |||
| 109 | /* define enabled interrupts hereby */ | ||
| 110 | #define GC_CARMINE_INT_EN 0x00000004 | ||
| 111 | |||
| 112 | /* DRAM controller */ | ||
| 113 | #define GC_DCTL_MODE_ADD 0x00000000 | ||
| 114 | #define GC_DCTL_SETTIME1_EMODE 0x00000004 | ||
| 115 | #define GC_DCTL_REFRESH_SETTIME2 0x00000008 | ||
| 116 | #define GC_DCTL_RSV0_STATES 0x0000000C | ||
| 117 | #define GC_DCTL_RSV2_RSV1 0x00000010 | ||
| 118 | #define GC_DCTL_DDRIF2_DDRIF1 0x00000014 | ||
| 119 | #define GC_DCTL_IOCONT1_IOCONT0 0x00000024 | ||
| 120 | |||
| 121 | #define GC_DCTL_STATES_MSK 0x0000000f | ||
| 122 | #define GC_DCTL_INIT_WAIT_CNT 3000 | ||
| 123 | #define GC_DCTL_INIT_WAIT_INTERVAL 1 | ||
| 124 | |||
| 125 | /* DRAM ctrl values for Carmine PCI Eval. board */ | ||
| 126 | #define GC_EVB_DCTL_MODE_ADD 0x012105c3 | ||
| 127 | #define GC_EVB_DCTL_MODE_ADD_AFT_RST 0x002105c3 | ||
| 128 | #define GC_EVB_DCTL_SETTIME1_EMODE 0x47498000 | ||
| 129 | #define GC_EVB_DCTL_REFRESH_SETTIME2 0x00422a22 | ||
| 130 | #define GC_EVB_DCTL_RSV0_STATES 0x00200003 | ||
| 131 | #define GC_EVB_DCTL_RSV0_STATES_AFT_RST 0x00200002 | ||
| 132 | #define GC_EVB_DCTL_RSV2_RSV1 0x0000000f | ||
| 133 | #define GC_EVB_DCTL_DDRIF2_DDRIF1 0x00556646 | ||
| 134 | #define GC_EVB_DCTL_IOCONT1_IOCONT0 0x05550555 | ||
| 135 | |||
| 136 | #define GC_DISP_REFCLK_533 533 | ||
| 137 | |||
| 138 | #endif | ||
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c new file mode 100644 index 000000000000..fb64234a3825 --- /dev/null +++ b/drivers/video/mb862xx/mb862xxfb.c | |||
| @@ -0,0 +1,1061 @@ | |||
| 1 | /* | ||
| 2 | * drivers/mb862xx/mb862xxfb.c | ||
| 3 | * | ||
| 4 | * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver | ||
| 5 | * | ||
| 6 | * (C) 2008 Anatolij Gustschin <agust@denx.de> | ||
| 7 | * DENX Software Engineering | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #undef DEBUG | ||
| 16 | |||
| 17 | #include <linux/fb.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/pci.h> | ||
| 22 | #if defined(CONFIG_PPC_OF) | ||
| 23 | #include <linux/of_platform.h> | ||
| 24 | #endif | ||
| 25 | #include "mb862xxfb.h" | ||
| 26 | #include "mb862xx_reg.h" | ||
| 27 | |||
| 28 | #define NR_PALETTE 256 | ||
| 29 | #define MB862XX_MEM_SIZE 0x1000000 | ||
| 30 | #define CORALP_MEM_SIZE 0x4000000 | ||
| 31 | #define CARMINE_MEM_SIZE 0x8000000 | ||
| 32 | #define DRV_NAME "mb862xxfb" | ||
| 33 | |||
| 34 | #if defined(CONFIG_LWMON5) | ||
| 35 | static struct mb862xx_gc_mode lwmon5_gc_mode = { | ||
| 36 | /* Mode for Sharp LQ104V1DG61 TFT LCD Panel */ | ||
| 37 | { "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 }, | ||
| 38 | /* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */ | ||
| 39 | 16, 0x2000000, GC_CCF_COT_100, 0x414fb7f2 | ||
| 40 | }; | ||
| 41 | #endif | ||
| 42 | |||
| 43 | #if defined(CONFIG_SOCRATES) | ||
| 44 | static struct mb862xx_gc_mode socrates_gc_mode = { | ||
| 45 | /* Mode for Prime View PM070WL4 TFT LCD Panel */ | ||
| 46 | { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 }, | ||
| 47 | /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */ | ||
| 48 | 16, 0x1000000, GC_CCF_COT_133, 0x4157ba63 | ||
| 49 | }; | ||
| 50 | #endif | ||
| 51 | |||
| 52 | /* Helpers */ | ||
| 53 | static inline int h_total(struct fb_var_screeninfo *var) | ||
| 54 | { | ||
| 55 | return var->xres + var->left_margin + | ||
| 56 | var->right_margin + var->hsync_len; | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline int v_total(struct fb_var_screeninfo *var) | ||
| 60 | { | ||
| 61 | return var->yres + var->upper_margin + | ||
| 62 | var->lower_margin + var->vsync_len; | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline int hsp(struct fb_var_screeninfo *var) | ||
| 66 | { | ||
| 67 | return var->xres + var->right_margin - 1; | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline int vsp(struct fb_var_screeninfo *var) | ||
| 71 | { | ||
| 72 | return var->yres + var->lower_margin - 1; | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline int d_pitch(struct fb_var_screeninfo *var) | ||
| 76 | { | ||
| 77 | return var->xres * var->bits_per_pixel / 8; | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline unsigned int chan_to_field(unsigned int chan, | ||
| 81 | struct fb_bitfield *bf) | ||
| 82 | { | ||
| 83 | chan &= 0xffff; | ||
| 84 | chan >>= 16 - bf->length; | ||
| 85 | return chan << bf->offset; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int mb862xxfb_setcolreg(unsigned regno, | ||
| 89 | unsigned red, unsigned green, unsigned blue, | ||
| 90 | unsigned transp, struct fb_info *info) | ||
| 91 | { | ||
| 92 | struct mb862xxfb_par *par = info->par; | ||
| 93 | unsigned int val; | ||
| 94 | |||
| 95 | switch (info->fix.visual) { | ||
| 96 | case FB_VISUAL_TRUECOLOR: | ||
| 97 | if (regno < 16) { | ||
| 98 | val = chan_to_field(red, &info->var.red); | ||
| 99 | val |= chan_to_field(green, &info->var.green); | ||
| 100 | val |= chan_to_field(blue, &info->var.blue); | ||
| 101 | par->pseudo_palette[regno] = val; | ||
| 102 | } | ||
| 103 | break; | ||
| 104 | case FB_VISUAL_PSEUDOCOLOR: | ||
| 105 | if (regno < 256) { | ||
| 106 | val = (red >> 8) << 16; | ||
| 107 | val |= (green >> 8) << 8; | ||
| 108 | val |= blue >> 8; | ||
| 109 | outreg(disp, GC_L0PAL0 + (regno * 4), val); | ||
| 110 | } | ||
| 111 | break; | ||
| 112 | default: | ||
| 113 | return 1; /* unsupported type */ | ||
| 114 | } | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int mb862xxfb_check_var(struct fb_var_screeninfo *var, | ||
| 119 | struct fb_info *fbi) | ||
| 120 | { | ||
| 121 | unsigned long tmp; | ||
| 122 | |||
| 123 | if (fbi->dev) | ||
| 124 | dev_dbg(fbi->dev, "%s\n", __func__); | ||
| 125 | |||
| 126 | /* check if these values fit into the registers */ | ||
| 127 | if (var->hsync_len > 255 || var->vsync_len > 255) | ||
| 128 | return -EINVAL; | ||
| 129 | |||
| 130 | if ((var->xres + var->right_margin) >= 4096) | ||
| 131 | return -EINVAL; | ||
| 132 | |||
| 133 | if ((var->yres + var->lower_margin) > 4096) | ||
| 134 | return -EINVAL; | ||
| 135 | |||
| 136 | if (h_total(var) > 4096 || v_total(var) > 4096) | ||
| 137 | return -EINVAL; | ||
| 138 | |||
| 139 | if (var->xres_virtual > 4096 || var->yres_virtual > 4096) | ||
| 140 | return -EINVAL; | ||
| 141 | |||
| 142 | if (var->bits_per_pixel <= 8) | ||
| 143 | var->bits_per_pixel = 8; | ||
| 144 | else if (var->bits_per_pixel <= 16) | ||
| 145 | var->bits_per_pixel = 16; | ||
| 146 | else if (var->bits_per_pixel <= 32) | ||
| 147 | var->bits_per_pixel = 32; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * can cope with 8,16 or 24/32bpp if resulting | ||
| 151 | * pitch is divisible by 64 without remainder | ||
| 152 | */ | ||
| 153 | if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) { | ||
| 154 | int r; | ||
| 155 | |||
| 156 | var->bits_per_pixel = 0; | ||
| 157 | do { | ||
| 158 | var->bits_per_pixel += 8; | ||
| 159 | r = d_pitch(&fbi->var) % GC_L0M_L0W_UNIT; | ||
| 160 | } while (r && var->bits_per_pixel <= 32); | ||
| 161 | |||
| 162 | if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) | ||
| 163 | return -EINVAL; | ||
| 164 | } | ||
| 165 | |||
| 166 | /* line length is going to be 128 bit aligned */ | ||
| 167 | tmp = (var->xres * var->bits_per_pixel) / 8; | ||
| 168 | if ((tmp & 15) != 0) | ||
| 169 | return -EINVAL; | ||
| 170 | |||
| 171 | /* set r/g/b positions and validate bpp */ | ||
| 172 | switch (var->bits_per_pixel) { | ||
| 173 | case 8: | ||
| 174 | var->red.length = var->bits_per_pixel; | ||
| 175 | var->green.length = var->bits_per_pixel; | ||
| 176 | var->blue.length = var->bits_per_pixel; | ||
| 177 | var->red.offset = 0; | ||
| 178 | var->green.offset = 0; | ||
| 179 | var->blue.offset = 0; | ||
| 180 | var->transp.length = 0; | ||
| 181 | break; | ||
| 182 | case 16: | ||
| 183 | var->red.length = 5; | ||
| 184 | var->green.length = 5; | ||
| 185 | var->blue.length = 5; | ||
| 186 | var->red.offset = 10; | ||
| 187 | var->green.offset = 5; | ||
| 188 | var->blue.offset = 0; | ||
| 189 | var->transp.length = 0; | ||
| 190 | break; | ||
| 191 | case 24: | ||
| 192 | case 32: | ||
| 193 | var->transp.length = 8; | ||
| 194 | var->red.length = 8; | ||
| 195 | var->green.length = 8; | ||
| 196 | var->blue.length = 8; | ||
| 197 | var->transp.offset = 24; | ||
| 198 | var->red.offset = 16; | ||
| 199 | var->green.offset = 8; | ||
| 200 | var->blue.offset = 0; | ||
| 201 | break; | ||
| 202 | default: | ||
| 203 | return -EINVAL; | ||
| 204 | } | ||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | |||
| 208 | /* | ||
| 209 | * set display parameters | ||
| 210 | */ | ||
| 211 | static int mb862xxfb_set_par(struct fb_info *fbi) | ||
| 212 | { | ||
| 213 | struct mb862xxfb_par *par = fbi->par; | ||
| 214 | unsigned long reg, sc; | ||
| 215 | |||
| 216 | dev_dbg(par->dev, "%s\n", __func__); | ||
| 217 | |||
| 218 | if (par->pre_init) | ||
| 219 | return 0; | ||
| 220 | |||
| 221 | /* disp off */ | ||
| 222 | reg = inreg(disp, GC_DCM1); | ||
| 223 | reg &= ~GC_DCM01_DEN; | ||
| 224 | outreg(disp, GC_DCM1, reg); | ||
| 225 | |||
| 226 | /* set display reference clock div. */ | ||
| 227 | sc = par->refclk / (1000000 / fbi->var.pixclock) - 1; | ||
| 228 | reg = inreg(disp, GC_DCM1); | ||
| 229 | reg &= ~(GC_DCM01_CKS | GC_DCM01_RESV | GC_DCM01_SC); | ||
| 230 | reg |= sc << 8; | ||
| 231 | outreg(disp, GC_DCM1, reg); | ||
| 232 | dev_dbg(par->dev, "SC 0x%lx\n", sc); | ||
| 233 | |||
| 234 | /* disp dimension, format */ | ||
| 235 | reg = pack(d_pitch(&fbi->var) / GC_L0M_L0W_UNIT, | ||
| 236 | (fbi->var.yres - 1)); | ||
| 237 | if (fbi->var.bits_per_pixel == 16) | ||
| 238 | reg |= GC_L0M_L0C_16; | ||
| 239 | outreg(disp, GC_L0M, reg); | ||
| 240 | |||
| 241 | if (fbi->var.bits_per_pixel == 32) { | ||
| 242 | reg = inreg(disp, GC_L0EM); | ||
| 243 | outreg(disp, GC_L0EM, reg | GC_L0EM_L0EC_24); | ||
| 244 | } | ||
| 245 | outreg(disp, GC_WY_WX, 0); | ||
| 246 | reg = pack(fbi->var.yres - 1, fbi->var.xres); | ||
| 247 | outreg(disp, GC_WH_WW, reg); | ||
| 248 | outreg(disp, GC_L0OA0, 0); | ||
| 249 | outreg(disp, GC_L0DA0, 0); | ||
| 250 | outreg(disp, GC_L0DY_L0DX, 0); | ||
| 251 | outreg(disp, GC_L0WY_L0WX, 0); | ||
| 252 | outreg(disp, GC_L0WH_L0WW, reg); | ||
| 253 | |||
| 254 | /* both HW-cursors off */ | ||
| 255 | reg = inreg(disp, GC_CPM_CUTC); | ||
| 256 | reg &= ~(GC_CPM_CEN0 | GC_CPM_CEN1); | ||
| 257 | outreg(disp, GC_CPM_CUTC, reg); | ||
| 258 | |||
| 259 | /* timings */ | ||
| 260 | reg = pack(fbi->var.xres - 1, fbi->var.xres - 1); | ||
| 261 | outreg(disp, GC_HDB_HDP, reg); | ||
| 262 | reg = pack((fbi->var.yres - 1), vsp(&fbi->var)); | ||
| 263 | outreg(disp, GC_VDP_VSP, reg); | ||
| 264 | reg = ((fbi->var.vsync_len - 1) << 24) | | ||
| 265 | pack((fbi->var.hsync_len - 1), hsp(&fbi->var)); | ||
| 266 | outreg(disp, GC_VSW_HSW_HSP, reg); | ||
| 267 | outreg(disp, GC_HTP, pack(h_total(&fbi->var) - 1, 0)); | ||
| 268 | outreg(disp, GC_VTR, pack(v_total(&fbi->var) - 1, 0)); | ||
| 269 | |||
| 270 | /* display on */ | ||
| 271 | reg = inreg(disp, GC_DCM1); | ||
| 272 | reg |= GC_DCM01_DEN | GC_DCM01_L0E; | ||
| 273 | reg &= ~GC_DCM01_ESY; | ||
| 274 | outreg(disp, GC_DCM1, reg); | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int mb862xxfb_pan(struct fb_var_screeninfo *var, | ||
| 279 | struct fb_info *info) | ||
| 280 | { | ||
| 281 | struct mb862xxfb_par *par = info->par; | ||
| 282 | unsigned long reg; | ||
| 283 | |||
| 284 | reg = pack(var->yoffset, var->xoffset); | ||
| 285 | outreg(disp, GC_L0WY_L0WX, reg); | ||
| 286 | |||
| 287 | reg = pack(var->yres_virtual, var->xres_virtual); | ||
| 288 | outreg(disp, GC_L0WH_L0WW, reg); | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | |||
| 292 | static int mb862xxfb_blank(int mode, struct fb_info *fbi) | ||
| 293 | { | ||
| 294 | struct mb862xxfb_par *par = fbi->par; | ||
| 295 | unsigned long reg; | ||
| 296 | |||
| 297 | dev_dbg(fbi->dev, "blank mode=%d\n", mode); | ||
| 298 | |||
| 299 | switch (mode) { | ||
| 300 | case FB_BLANK_POWERDOWN: | ||
| 301 | reg = inreg(disp, GC_DCM1); | ||
| 302 | reg &= ~GC_DCM01_DEN; | ||
| 303 | outreg(disp, GC_DCM1, reg); | ||
| 304 | break; | ||
| 305 | case FB_BLANK_UNBLANK: | ||
| 306 | reg = inreg(disp, GC_DCM1); | ||
| 307 | reg |= GC_DCM01_DEN; | ||
| 308 | outreg(disp, GC_DCM1, reg); | ||
| 309 | break; | ||
| 310 | case FB_BLANK_NORMAL: | ||
| 311 | case FB_BLANK_VSYNC_SUSPEND: | ||
| 312 | case FB_BLANK_HSYNC_SUSPEND: | ||
| 313 | default: | ||
| 314 | return 1; | ||
| 315 | } | ||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | /* framebuffer ops */ | ||
| 320 | static struct fb_ops mb862xxfb_ops = { | ||
| 321 | .owner = THIS_MODULE, | ||
| 322 | .fb_check_var = mb862xxfb_check_var, | ||
| 323 | .fb_set_par = mb862xxfb_set_par, | ||
| 324 | .fb_setcolreg = mb862xxfb_setcolreg, | ||
| 325 | .fb_blank = mb862xxfb_blank, | ||
| 326 | .fb_pan_display = mb862xxfb_pan, | ||
| 327 | .fb_fillrect = cfb_fillrect, | ||
| 328 | .fb_copyarea = cfb_copyarea, | ||
| 329 | .fb_imageblit = cfb_imageblit, | ||
| 330 | }; | ||
| 331 | |||
| 332 | /* initialize fb_info data */ | ||
| 333 | static int mb862xxfb_init_fbinfo(struct fb_info *fbi) | ||
| 334 | { | ||
| 335 | struct mb862xxfb_par *par = fbi->par; | ||
| 336 | struct mb862xx_gc_mode *mode = par->gc_mode; | ||
| 337 | unsigned long reg; | ||
| 338 | |||
| 339 | fbi->fbops = &mb862xxfb_ops; | ||
| 340 | fbi->pseudo_palette = par->pseudo_palette; | ||
| 341 | fbi->screen_base = par->fb_base; | ||
| 342 | fbi->screen_size = par->mapped_vram; | ||
| 343 | |||
| 344 | strcpy(fbi->fix.id, DRV_NAME); | ||
| 345 | fbi->fix.smem_start = (unsigned long)par->fb_base_phys; | ||
| 346 | fbi->fix.smem_len = par->mapped_vram; | ||
| 347 | fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys; | ||
| 348 | fbi->fix.mmio_len = par->mmio_len; | ||
| 349 | fbi->fix.accel = FB_ACCEL_NONE; | ||
| 350 | fbi->fix.type = FB_TYPE_PACKED_PIXELS; | ||
| 351 | fbi->fix.type_aux = 0; | ||
| 352 | fbi->fix.xpanstep = 1; | ||
| 353 | fbi->fix.ypanstep = 1; | ||
| 354 | fbi->fix.ywrapstep = 0; | ||
| 355 | |||
| 356 | reg = inreg(disp, GC_DCM1); | ||
| 357 | if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E) { | ||
| 358 | /* get the disp mode from active display cfg */ | ||
| 359 | unsigned long sc = ((reg & GC_DCM01_SC) >> 8) + 1; | ||
| 360 | unsigned long hsp, vsp, ht, vt; | ||
| 361 | |||
| 362 | dev_dbg(par->dev, "using bootloader's disp. mode\n"); | ||
| 363 | fbi->var.pixclock = (sc * 1000000) / par->refclk; | ||
| 364 | fbi->var.xres = (inreg(disp, GC_HDB_HDP) & 0x0fff) + 1; | ||
| 365 | reg = inreg(disp, GC_VDP_VSP); | ||
| 366 | fbi->var.yres = ((reg >> 16) & 0x0fff) + 1; | ||
| 367 | vsp = (reg & 0x0fff) + 1; | ||
| 368 | fbi->var.xres_virtual = fbi->var.xres; | ||
| 369 | fbi->var.yres_virtual = fbi->var.yres; | ||
| 370 | reg = inreg(disp, GC_L0EM); | ||
| 371 | if (reg & GC_L0EM_L0EC_24) { | ||
| 372 | fbi->var.bits_per_pixel = 32; | ||
| 373 | } else { | ||
| 374 | reg = inreg(disp, GC_L0M); | ||
| 375 | if (reg & GC_L0M_L0C_16) | ||
| 376 | fbi->var.bits_per_pixel = 16; | ||
| 377 | else | ||
| 378 | fbi->var.bits_per_pixel = 8; | ||
| 379 | } | ||
| 380 | reg = inreg(disp, GC_VSW_HSW_HSP); | ||
| 381 | fbi->var.hsync_len = ((reg & 0xff0000) >> 16) + 1; | ||
| 382 | fbi->var.vsync_len = ((reg & 0x3f000000) >> 24) + 1; | ||
| 383 | hsp = (reg & 0xffff) + 1; | ||
| 384 | ht = ((inreg(disp, GC_HTP) & 0xfff0000) >> 16) + 1; | ||
| 385 | fbi->var.right_margin = hsp - fbi->var.xres; | ||
| 386 | fbi->var.left_margin = ht - hsp - fbi->var.hsync_len; | ||
| 387 | vt = ((inreg(disp, GC_VTR) & 0xfff0000) >> 16) + 1; | ||
| 388 | fbi->var.lower_margin = vsp - fbi->var.yres; | ||
| 389 | fbi->var.upper_margin = vt - vsp - fbi->var.vsync_len; | ||
| 390 | } else if (mode) { | ||
| 391 | dev_dbg(par->dev, "using supplied mode\n"); | ||
| 392 | fb_videomode_to_var(&fbi->var, (struct fb_videomode *)mode); | ||
| 393 | fbi->var.bits_per_pixel = mode->def_bpp ? mode->def_bpp : 8; | ||
| 394 | } else { | ||
| 395 | int ret; | ||
| 396 | |||
| 397 | ret = fb_find_mode(&fbi->var, fbi, "640x480-16@60", | ||
| 398 | NULL, 0, NULL, 16); | ||
| 399 | if (ret == 0 || ret == 4) { | ||
| 400 | dev_err(par->dev, | ||
| 401 | "failed to get initial mode\n"); | ||
| 402 | return -EINVAL; | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | fbi->var.xoffset = 0; | ||
| 407 | fbi->var.yoffset = 0; | ||
| 408 | fbi->var.grayscale = 0; | ||
| 409 | fbi->var.nonstd = 0; | ||
| 410 | fbi->var.height = -1; | ||
| 411 | fbi->var.width = -1; | ||
| 412 | fbi->var.accel_flags = 0; | ||
| 413 | fbi->var.vmode = FB_VMODE_NONINTERLACED; | ||
| 414 | fbi->var.activate = FB_ACTIVATE_NOW; | ||
| 415 | fbi->flags = FBINFO_DEFAULT | | ||
| 416 | #ifdef __BIG_ENDIAN | ||
| 417 | FBINFO_FOREIGN_ENDIAN | | ||
| 418 | #endif | ||
| 419 | FBINFO_HWACCEL_XPAN | | ||
| 420 | FBINFO_HWACCEL_YPAN; | ||
| 421 | |||
| 422 | /* check and possibly fix bpp */ | ||
| 423 | if ((fbi->fbops->fb_check_var)(&fbi->var, fbi)) | ||
| 424 | dev_err(par->dev, "check_var() failed on initial setup?\n"); | ||
| 425 | |||
| 426 | fbi->fix.visual = fbi->var.bits_per_pixel == 8 ? | ||
| 427 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
| 428 | fbi->fix.line_length = (fbi->var.xres_virtual * | ||
| 429 | fbi->var.bits_per_pixel) / 8; | ||
| 430 | return 0; | ||
| 431 | } | ||
| 432 | |||
| 433 | /* | ||
| 434 | * show some display controller and cursor registers | ||
| 435 | */ | ||
| 436 | static ssize_t mb862xxfb_show_dispregs(struct device *dev, | ||
| 437 | struct device_attribute *attr, char *buf) | ||
| 438 | { | ||
| 439 | struct fb_info *fbi = dev_get_drvdata(dev); | ||
| 440 | struct mb862xxfb_par *par = fbi->par; | ||
| 441 | char *ptr = buf; | ||
| 442 | unsigned int reg; | ||
| 443 | |||
| 444 | for (reg = GC_DCM0; reg <= GC_L0DY_L0DX; reg += 4) | ||
| 445 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
| 446 | reg, inreg(disp, reg)); | ||
| 447 | |||
| 448 | for (reg = GC_CPM_CUTC; reg <= GC_CUY1_CUX1; reg += 4) | ||
| 449 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
| 450 | reg, inreg(disp, reg)); | ||
| 451 | |||
| 452 | for (reg = GC_DCM1; reg <= GC_L0WH_L0WW; reg += 4) | ||
| 453 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
| 454 | reg, inreg(disp, reg)); | ||
| 455 | |||
| 456 | return ptr - buf; | ||
| 457 | } | ||
| 458 | |||
| 459 | static DEVICE_ATTR(dispregs, 0444, mb862xxfb_show_dispregs, NULL); | ||
| 460 | |||
| 461 | irqreturn_t mb862xx_intr(int irq, void *dev_id) | ||
| 462 | { | ||
| 463 | struct mb862xxfb_par *par = (struct mb862xxfb_par *) dev_id; | ||
| 464 | unsigned long reg_ist, mask; | ||
| 465 | |||
| 466 | if (!par) | ||
| 467 | return IRQ_NONE; | ||
| 468 | |||
| 469 | if (par->type == BT_CARMINE) { | ||
| 470 | /* Get Interrupt Status */ | ||
| 471 | reg_ist = inreg(ctrl, GC_CTRL_STATUS); | ||
| 472 | mask = inreg(ctrl, GC_CTRL_INT_MASK); | ||
| 473 | if (reg_ist == 0) | ||
| 474 | return IRQ_HANDLED; | ||
| 475 | |||
| 476 | reg_ist &= mask; | ||
| 477 | if (reg_ist == 0) | ||
| 478 | return IRQ_HANDLED; | ||
| 479 | |||
| 480 | /* Clear interrupt status */ | ||
| 481 | outreg(ctrl, 0x0, reg_ist); | ||
| 482 | } else { | ||
| 483 | /* Get status */ | ||
| 484 | reg_ist = inreg(host, GC_IST); | ||
| 485 | mask = inreg(host, GC_IMASK); | ||
| 486 | |||
| 487 | reg_ist &= mask; | ||
| 488 | if (reg_ist == 0) | ||
| 489 | return IRQ_HANDLED; | ||
| 490 | |||
| 491 | /* Clear status */ | ||
| 492 | outreg(host, GC_IST, ~reg_ist); | ||
| 493 | } | ||
| 494 | return IRQ_HANDLED; | ||
| 495 | } | ||
| 496 | |||
| 497 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
| 498 | /* | ||
| 499 | * GDC (Lime, Coral(B/Q), Mint, ...) on host bus | ||
| 500 | */ | ||
| 501 | static int mb862xx_gdc_init(struct mb862xxfb_par *par) | ||
| 502 | { | ||
| 503 | unsigned long ccf, mmr; | ||
| 504 | unsigned long ver, rev; | ||
| 505 | |||
| 506 | if (!par) | ||
| 507 | return -ENODEV; | ||
| 508 | |||
| 509 | #if defined(CONFIG_FB_PRE_INIT_FB) | ||
| 510 | par->pre_init = 1; | ||
| 511 | #endif | ||
| 512 | par->host = par->mmio_base; | ||
| 513 | par->i2c = par->mmio_base + MB862XX_I2C_BASE; | ||
| 514 | par->disp = par->mmio_base + MB862XX_DISP_BASE; | ||
| 515 | par->cap = par->mmio_base + MB862XX_CAP_BASE; | ||
| 516 | par->draw = par->mmio_base + MB862XX_DRAW_BASE; | ||
| 517 | par->geo = par->mmio_base + MB862XX_GEO_BASE; | ||
| 518 | par->pio = par->mmio_base + MB862XX_PIO_BASE; | ||
| 519 | |||
| 520 | par->refclk = GC_DISP_REFCLK_400; | ||
| 521 | |||
| 522 | ver = inreg(host, GC_CID); | ||
| 523 | rev = inreg(pio, GC_REVISION); | ||
| 524 | if ((ver == 0x303) && (rev & 0xffffff00) == 0x20050100) { | ||
| 525 | dev_info(par->dev, "Fujitsu Lime v1.%d found\n", | ||
| 526 | (int)rev & 0xff); | ||
| 527 | par->type = BT_LIME; | ||
| 528 | ccf = par->gc_mode ? par->gc_mode->ccf : GC_CCF_COT_100; | ||
| 529 | mmr = par->gc_mode ? par->gc_mode->mmr : 0x414fb7f2; | ||
| 530 | } else { | ||
| 531 | dev_info(par->dev, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver, rev); | ||
| 532 | return -ENODEV; | ||
| 533 | } | ||
| 534 | |||
| 535 | if (!par->pre_init) { | ||
| 536 | outreg(host, GC_CCF, ccf); | ||
| 537 | udelay(200); | ||
| 538 | outreg(host, GC_MMR, mmr); | ||
| 539 | udelay(10); | ||
| 540 | } | ||
| 541 | |||
| 542 | /* interrupt status */ | ||
| 543 | outreg(host, GC_IST, 0); | ||
| 544 | outreg(host, GC_IMASK, GC_INT_EN); | ||
| 545 | return 0; | ||
| 546 | } | ||
| 547 | |||
| 548 | static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev, | ||
| 549 | const struct of_device_id *id) | ||
| 550 | { | ||
| 551 | struct device_node *np = ofdev->node; | ||
| 552 | struct device *dev = &ofdev->dev; | ||
| 553 | struct mb862xxfb_par *par; | ||
| 554 | struct fb_info *info; | ||
| 555 | struct resource res; | ||
| 556 | resource_size_t res_size; | ||
| 557 | unsigned long ret = -ENODEV; | ||
| 558 | |||
| 559 | if (of_address_to_resource(np, 0, &res)) { | ||
| 560 | dev_err(dev, "Invalid address\n"); | ||
| 561 | return -ENXIO; | ||
| 562 | } | ||
| 563 | |||
| 564 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); | ||
| 565 | if (info == NULL) { | ||
| 566 | dev_err(dev, "cannot allocate framebuffer\n"); | ||
| 567 | return -ENOMEM; | ||
| 568 | } | ||
| 569 | |||
| 570 | par = info->par; | ||
| 571 | par->info = info; | ||
| 572 | par->dev = dev; | ||
| 573 | |||
| 574 | par->irq = irq_of_parse_and_map(np, 0); | ||
| 575 | if (par->irq == NO_IRQ) { | ||
| 576 | dev_err(dev, "failed to map irq\n"); | ||
| 577 | ret = -ENODEV; | ||
| 578 | goto fbrel; | ||
| 579 | } | ||
| 580 | |||
| 581 | res_size = 1 + res.end - res.start; | ||
| 582 | par->res = request_mem_region(res.start, res_size, DRV_NAME); | ||
| 583 | if (par->res == NULL) { | ||
| 584 | dev_err(dev, "Cannot claim framebuffer/mmio\n"); | ||
| 585 | ret = -ENXIO; | ||
| 586 | goto irqdisp; | ||
| 587 | } | ||
| 588 | |||
| 589 | #if defined(CONFIG_LWMON5) | ||
| 590 | par->gc_mode = &lwmon5_gc_mode; | ||
| 591 | #endif | ||
| 592 | |||
| 593 | #if defined(CONFIG_SOCRATES) | ||
| 594 | par->gc_mode = &socrates_gc_mode; | ||
| 595 | #endif | ||
| 596 | |||
| 597 | par->fb_base_phys = res.start; | ||
| 598 | par->mmio_base_phys = res.start + MB862XX_MMIO_BASE; | ||
| 599 | par->mmio_len = MB862XX_MMIO_SIZE; | ||
| 600 | if (par->gc_mode) | ||
| 601 | par->mapped_vram = par->gc_mode->max_vram; | ||
| 602 | else | ||
| 603 | par->mapped_vram = MB862XX_MEM_SIZE; | ||
| 604 | |||
| 605 | par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); | ||
| 606 | if (par->fb_base == NULL) { | ||
| 607 | dev_err(dev, "Cannot map framebuffer\n"); | ||
| 608 | goto rel_reg; | ||
| 609 | } | ||
| 610 | |||
| 611 | par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); | ||
| 612 | if (par->mmio_base == NULL) { | ||
| 613 | dev_err(dev, "Cannot map registers\n"); | ||
| 614 | goto fb_unmap; | ||
| 615 | } | ||
| 616 | |||
| 617 | dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", | ||
| 618 | (u64)par->fb_base_phys, (ulong)par->mapped_vram); | ||
| 619 | dev_dbg(dev, "mmio phys 0x%llx 0x%lx, (irq = %d)\n", | ||
| 620 | (u64)par->mmio_base_phys, (ulong)par->mmio_len, par->irq); | ||
| 621 | |||
| 622 | if (mb862xx_gdc_init(par)) | ||
| 623 | goto io_unmap; | ||
| 624 | |||
| 625 | if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED, | ||
| 626 | DRV_NAME, (void *)par)) { | ||
| 627 | dev_err(dev, "Cannot request irq\n"); | ||
| 628 | goto io_unmap; | ||
| 629 | } | ||
| 630 | |||
| 631 | mb862xxfb_init_fbinfo(info); | ||
| 632 | |||
| 633 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { | ||
| 634 | dev_err(dev, "Could not allocate cmap for fb_info.\n"); | ||
| 635 | goto free_irq; | ||
| 636 | } | ||
| 637 | |||
| 638 | if ((info->fbops->fb_set_par)(info)) | ||
| 639 | dev_err(dev, "set_var() failed on initial setup?\n"); | ||
| 640 | |||
| 641 | if (register_framebuffer(info)) { | ||
| 642 | dev_err(dev, "failed to register framebuffer\n"); | ||
| 643 | goto rel_cmap; | ||
| 644 | } | ||
| 645 | |||
| 646 | dev_set_drvdata(dev, info); | ||
| 647 | |||
| 648 | if (device_create_file(dev, &dev_attr_dispregs)) | ||
| 649 | dev_err(dev, "Can't create sysfs regdump file\n"); | ||
| 650 | return 0; | ||
| 651 | |||
| 652 | rel_cmap: | ||
| 653 | fb_dealloc_cmap(&info->cmap); | ||
| 654 | free_irq: | ||
| 655 | outreg(host, GC_IMASK, 0); | ||
| 656 | free_irq(par->irq, (void *)par); | ||
| 657 | io_unmap: | ||
| 658 | iounmap(par->mmio_base); | ||
| 659 | fb_unmap: | ||
| 660 | iounmap(par->fb_base); | ||
| 661 | rel_reg: | ||
| 662 | release_mem_region(res.start, res_size); | ||
| 663 | irqdisp: | ||
| 664 | irq_dispose_mapping(par->irq); | ||
| 665 | fbrel: | ||
| 666 | dev_set_drvdata(dev, NULL); | ||
| 667 | framebuffer_release(info); | ||
| 668 | return ret; | ||
| 669 | } | ||
| 670 | |||
| 671 | static int __devexit of_platform_mb862xx_remove(struct of_device *ofdev) | ||
| 672 | { | ||
| 673 | struct fb_info *fbi = dev_get_drvdata(&ofdev->dev); | ||
| 674 | struct mb862xxfb_par *par = fbi->par; | ||
| 675 | resource_size_t res_size = 1 + par->res->end - par->res->start; | ||
| 676 | unsigned long reg; | ||
| 677 | |||
| 678 | dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); | ||
| 679 | |||
| 680 | /* display off */ | ||
| 681 | reg = inreg(disp, GC_DCM1); | ||
| 682 | reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); | ||
| 683 | outreg(disp, GC_DCM1, reg); | ||
| 684 | |||
| 685 | /* disable interrupts */ | ||
| 686 | outreg(host, GC_IMASK, 0); | ||
| 687 | |||
| 688 | free_irq(par->irq, (void *)par); | ||
| 689 | irq_dispose_mapping(par->irq); | ||
| 690 | |||
| 691 | device_remove_file(&ofdev->dev, &dev_attr_dispregs); | ||
| 692 | |||
| 693 | unregister_framebuffer(fbi); | ||
| 694 | fb_dealloc_cmap(&fbi->cmap); | ||
| 695 | |||
| 696 | iounmap(par->mmio_base); | ||
| 697 | iounmap(par->fb_base); | ||
| 698 | |||
| 699 | dev_set_drvdata(&ofdev->dev, NULL); | ||
| 700 | release_mem_region(par->res->start, res_size); | ||
| 701 | framebuffer_release(fbi); | ||
| 702 | return 0; | ||
| 703 | } | ||
| 704 | |||
| 705 | /* | ||
| 706 | * common types | ||
| 707 | */ | ||
| 708 | static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { | ||
| 709 | { .compatible = "fujitsu,MB86276", }, | ||
| 710 | { .compatible = "fujitsu,lime", }, | ||
| 711 | { .compatible = "fujitsu,MB86277", }, | ||
| 712 | { .compatible = "fujitsu,mint", }, | ||
| 713 | { .compatible = "fujitsu,MB86293", }, | ||
| 714 | { .compatible = "fujitsu,MB86294", }, | ||
| 715 | { .compatible = "fujitsu,coral", }, | ||
| 716 | { /* end */ } | ||
| 717 | }; | ||
| 718 | |||
| 719 | static struct of_platform_driver of_platform_mb862xxfb_driver = { | ||
| 720 | .owner = THIS_MODULE, | ||
| 721 | .name = DRV_NAME, | ||
| 722 | .match_table = of_platform_mb862xx_tbl, | ||
| 723 | .probe = of_platform_mb862xx_probe, | ||
| 724 | .remove = __devexit_p(of_platform_mb862xx_remove), | ||
| 725 | }; | ||
| 726 | #endif | ||
| 727 | |||
| 728 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
| 729 | static int coralp_init(struct mb862xxfb_par *par) | ||
| 730 | { | ||
| 731 | int cn, ver; | ||
| 732 | |||
| 733 | par->host = par->mmio_base; | ||
| 734 | par->i2c = par->mmio_base + MB862XX_I2C_BASE; | ||
| 735 | par->disp = par->mmio_base + MB862XX_DISP_BASE; | ||
| 736 | par->cap = par->mmio_base + MB862XX_CAP_BASE; | ||
| 737 | par->draw = par->mmio_base + MB862XX_DRAW_BASE; | ||
| 738 | par->geo = par->mmio_base + MB862XX_GEO_BASE; | ||
| 739 | par->pio = par->mmio_base + MB862XX_PIO_BASE; | ||
| 740 | |||
| 741 | par->refclk = GC_DISP_REFCLK_400; | ||
| 742 | |||
| 743 | ver = inreg(host, GC_CID); | ||
| 744 | cn = (ver & GC_CID_CNAME_MSK) >> 8; | ||
| 745 | ver = ver & GC_CID_VERSION_MSK; | ||
| 746 | if (cn == 3) { | ||
| 747 | dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\ | ||
| 748 | (ver == 6) ? "P" : (ver == 8) ? "PA" : "?", | ||
| 749 | par->pdev->revision); | ||
| 750 | outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133); | ||
| 751 | udelay(200); | ||
| 752 | outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL); | ||
| 753 | udelay(10); | ||
| 754 | /* Clear interrupt status */ | ||
| 755 | outreg(host, GC_IST, 0); | ||
| 756 | } else { | ||
| 757 | return -ENODEV; | ||
| 758 | } | ||
| 759 | return 0; | ||
| 760 | } | ||
| 761 | |||
| 762 | static int init_dram_ctrl(struct mb862xxfb_par *par) | ||
| 763 | { | ||
| 764 | unsigned long i = 0; | ||
| 765 | |||
| 766 | /* | ||
| 767 | * Set io mode first! Spec. says IC may be destroyed | ||
| 768 | * if not set to SSTL2/LVCMOS before init. | ||
| 769 | */ | ||
| 770 | outreg(dram_ctrl, GC_DCTL_IOCONT1_IOCONT0, GC_EVB_DCTL_IOCONT1_IOCONT0); | ||
| 771 | |||
| 772 | /* DRAM init */ | ||
| 773 | outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD); | ||
| 774 | outreg(dram_ctrl, GC_DCTL_SETTIME1_EMODE, GC_EVB_DCTL_SETTIME1_EMODE); | ||
| 775 | outreg(dram_ctrl, GC_DCTL_REFRESH_SETTIME2, | ||
| 776 | GC_EVB_DCTL_REFRESH_SETTIME2); | ||
| 777 | outreg(dram_ctrl, GC_DCTL_RSV2_RSV1, GC_EVB_DCTL_RSV2_RSV1); | ||
| 778 | outreg(dram_ctrl, GC_DCTL_DDRIF2_DDRIF1, GC_EVB_DCTL_DDRIF2_DDRIF1); | ||
| 779 | outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES); | ||
| 780 | |||
| 781 | /* DLL reset done? */ | ||
| 782 | while ((inreg(dram_ctrl, GC_DCTL_RSV0_STATES) & GC_DCTL_STATES_MSK)) { | ||
| 783 | udelay(GC_DCTL_INIT_WAIT_INTERVAL); | ||
| 784 | if (i++ > GC_DCTL_INIT_WAIT_CNT) { | ||
| 785 | dev_err(par->dev, "VRAM init failed.\n"); | ||
| 786 | return -EINVAL; | ||
| 787 | } | ||
| 788 | } | ||
| 789 | outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD_AFT_RST); | ||
| 790 | outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES_AFT_RST); | ||
| 791 | return 0; | ||
| 792 | } | ||
| 793 | |||
| 794 | static int carmine_init(struct mb862xxfb_par *par) | ||
| 795 | { | ||
| 796 | unsigned long reg; | ||
| 797 | |||
| 798 | par->ctrl = par->mmio_base + MB86297_CTRL_BASE; | ||
| 799 | par->i2c = par->mmio_base + MB86297_I2C_BASE; | ||
| 800 | par->disp = par->mmio_base + MB86297_DISP0_BASE; | ||
| 801 | par->disp1 = par->mmio_base + MB86297_DISP1_BASE; | ||
| 802 | par->cap = par->mmio_base + MB86297_CAP0_BASE; | ||
| 803 | par->cap1 = par->mmio_base + MB86297_CAP1_BASE; | ||
| 804 | par->draw = par->mmio_base + MB86297_DRAW_BASE; | ||
| 805 | par->dram_ctrl = par->mmio_base + MB86297_DRAMCTRL_BASE; | ||
| 806 | par->wrback = par->mmio_base + MB86297_WRBACK_BASE; | ||
| 807 | |||
| 808 | par->refclk = GC_DISP_REFCLK_533; | ||
| 809 | |||
| 810 | /* warm up */ | ||
| 811 | reg = GC_CTRL_CLK_EN_DRAM | GC_CTRL_CLK_EN_2D3D | GC_CTRL_CLK_EN_DISP0; | ||
| 812 | outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); | ||
| 813 | |||
| 814 | /* check for engine module revision */ | ||
| 815 | if (inreg(draw, GC_2D3D_REV) == GC_RE_REVISION) | ||
| 816 | dev_info(par->dev, "Fujitsu Carmine GDC Rev.%d found\n", | ||
| 817 | par->pdev->revision); | ||
| 818 | else | ||
| 819 | goto err_init; | ||
| 820 | |||
| 821 | reg &= ~GC_CTRL_CLK_EN_2D3D; | ||
| 822 | outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); | ||
| 823 | |||
| 824 | /* set up vram */ | ||
| 825 | if (init_dram_ctrl(par) < 0) | ||
| 826 | goto err_init; | ||
| 827 | |||
| 828 | outreg(ctrl, GC_CTRL_INT_MASK, 0); | ||
| 829 | return 0; | ||
| 830 | |||
| 831 | err_init: | ||
| 832 | outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); | ||
| 833 | return -EINVAL; | ||
| 834 | } | ||
| 835 | |||
| 836 | static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par) | ||
| 837 | { | ||
| 838 | switch (par->type) { | ||
| 839 | case BT_CORALP: | ||
| 840 | return coralp_init(par); | ||
| 841 | case BT_CARMINE: | ||
| 842 | return carmine_init(par); | ||
| 843 | default: | ||
| 844 | return -ENODEV; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | |||
| 848 | #define CHIP_ID(id) \ | ||
| 849 | { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) } | ||
| 850 | |||
| 851 | static struct pci_device_id mb862xx_pci_tbl[] __devinitdata = { | ||
| 852 | /* MB86295/MB86296 */ | ||
| 853 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP), | ||
| 854 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA), | ||
| 855 | /* MB86297 */ | ||
| 856 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE), | ||
| 857 | { 0, } | ||
| 858 | }; | ||
| 859 | |||
| 860 | MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl); | ||
| 861 | |||
| 862 | static int __devinit mb862xx_pci_probe(struct pci_dev *pdev, | ||
| 863 | const struct pci_device_id *ent) | ||
| 864 | { | ||
| 865 | struct mb862xxfb_par *par; | ||
| 866 | struct fb_info *info; | ||
| 867 | struct device *dev = &pdev->dev; | ||
| 868 | int ret; | ||
| 869 | |||
| 870 | ret = pci_enable_device(pdev); | ||
| 871 | if (ret < 0) { | ||
| 872 | dev_err(dev, "Cannot enable PCI device\n"); | ||
| 873 | goto out; | ||
| 874 | } | ||
| 875 | |||
| 876 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); | ||
| 877 | if (!info) { | ||
| 878 | dev_err(dev, "framebuffer alloc failed\n"); | ||
| 879 | ret = -ENOMEM; | ||
| 880 | goto dis_dev; | ||
| 881 | } | ||
| 882 | |||
| 883 | par = info->par; | ||
| 884 | par->info = info; | ||
| 885 | par->dev = dev; | ||
| 886 | par->pdev = pdev; | ||
| 887 | par->irq = pdev->irq; | ||
| 888 | |||
| 889 | ret = pci_request_regions(pdev, DRV_NAME); | ||
| 890 | if (ret < 0) { | ||
| 891 | dev_err(dev, "Cannot reserve region(s) for PCI device\n"); | ||
| 892 | goto rel_fb; | ||
| 893 | } | ||
| 894 | |||
| 895 | switch (pdev->device) { | ||
| 896 | case PCI_DEVICE_ID_FUJITSU_CORALP: | ||
| 897 | case PCI_DEVICE_ID_FUJITSU_CORALPA: | ||
| 898 | par->fb_base_phys = pci_resource_start(par->pdev, 0); | ||
| 899 | par->mapped_vram = CORALP_MEM_SIZE; | ||
| 900 | par->mmio_base_phys = par->fb_base_phys + MB862XX_MMIO_BASE; | ||
| 901 | par->mmio_len = MB862XX_MMIO_SIZE; | ||
| 902 | par->type = BT_CORALP; | ||
| 903 | break; | ||
| 904 | case PCI_DEVICE_ID_FUJITSU_CARMINE: | ||
| 905 | par->fb_base_phys = pci_resource_start(par->pdev, 2); | ||
| 906 | par->mmio_base_phys = pci_resource_start(par->pdev, 3); | ||
| 907 | par->mmio_len = pci_resource_len(par->pdev, 3); | ||
| 908 | par->mapped_vram = CARMINE_MEM_SIZE; | ||
| 909 | par->type = BT_CARMINE; | ||
| 910 | break; | ||
| 911 | default: | ||
| 912 | /* should never occur */ | ||
| 913 | goto rel_reg; | ||
| 914 | } | ||
| 915 | |||
| 916 | par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); | ||
| 917 | if (par->fb_base == NULL) { | ||
| 918 | dev_err(dev, "Cannot map framebuffer\n"); | ||
| 919 | goto rel_reg; | ||
| 920 | } | ||
| 921 | |||
| 922 | par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); | ||
| 923 | if (par->mmio_base == NULL) { | ||
| 924 | dev_err(dev, "Cannot map registers\n"); | ||
| 925 | ret = -EIO; | ||
| 926 | goto fb_unmap; | ||
| 927 | } | ||
| 928 | |||
| 929 | dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", | ||
| 930 | (unsigned long long)par->fb_base_phys, (ulong)par->mapped_vram); | ||
| 931 | dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", | ||
| 932 | (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len); | ||
| 933 | |||
| 934 | if (mb862xx_pci_gdc_init(par)) | ||
| 935 | goto io_unmap; | ||
| 936 | |||
| 937 | if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED | IRQF_SHARED, | ||
| 938 | DRV_NAME, (void *)par)) { | ||
| 939 | dev_err(dev, "Cannot request irq\n"); | ||
| 940 | goto io_unmap; | ||
| 941 | } | ||
| 942 | |||
| 943 | mb862xxfb_init_fbinfo(info); | ||
| 944 | |||
| 945 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { | ||
| 946 | dev_err(dev, "Could not allocate cmap for fb_info.\n"); | ||
| 947 | ret = -ENOMEM; | ||
| 948 | goto free_irq; | ||
| 949 | } | ||
| 950 | |||
| 951 | if ((info->fbops->fb_set_par)(info)) | ||
| 952 | dev_err(dev, "set_var() failed on initial setup?\n"); | ||
| 953 | |||
| 954 | ret = register_framebuffer(info); | ||
| 955 | if (ret < 0) { | ||
| 956 | dev_err(dev, "failed to register framebuffer\n"); | ||
| 957 | goto rel_cmap; | ||
| 958 | } | ||
| 959 | |||
| 960 | pci_set_drvdata(pdev, info); | ||
| 961 | |||
| 962 | if (device_create_file(dev, &dev_attr_dispregs)) | ||
| 963 | dev_err(dev, "Can't create sysfs regdump file\n"); | ||
| 964 | |||
| 965 | if (par->type == BT_CARMINE) | ||
| 966 | outreg(ctrl, GC_CTRL_INT_MASK, GC_CARMINE_INT_EN); | ||
| 967 | else | ||
| 968 | outreg(host, GC_IMASK, GC_INT_EN); | ||
| 969 | |||
| 970 | return 0; | ||
| 971 | |||
| 972 | rel_cmap: | ||
| 973 | fb_dealloc_cmap(&info->cmap); | ||
| 974 | free_irq: | ||
| 975 | free_irq(par->irq, (void *)par); | ||
| 976 | io_unmap: | ||
| 977 | iounmap(par->mmio_base); | ||
| 978 | fb_unmap: | ||
| 979 | iounmap(par->fb_base); | ||
| 980 | rel_reg: | ||
| 981 | pci_release_regions(pdev); | ||
| 982 | rel_fb: | ||
| 983 | framebuffer_release(info); | ||
| 984 | dis_dev: | ||
| 985 | pci_disable_device(pdev); | ||
| 986 | out: | ||
| 987 | return ret; | ||
| 988 | } | ||
| 989 | |||
| 990 | static void __devexit mb862xx_pci_remove(struct pci_dev *pdev) | ||
| 991 | { | ||
| 992 | struct fb_info *fbi = pci_get_drvdata(pdev); | ||
| 993 | struct mb862xxfb_par *par = fbi->par; | ||
| 994 | unsigned long reg; | ||
| 995 | |||
| 996 | dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); | ||
| 997 | |||
| 998 | /* display off */ | ||
| 999 | reg = inreg(disp, GC_DCM1); | ||
| 1000 | reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); | ||
| 1001 | outreg(disp, GC_DCM1, reg); | ||
| 1002 | |||
| 1003 | if (par->type == BT_CARMINE) { | ||
| 1004 | outreg(ctrl, GC_CTRL_INT_MASK, 0); | ||
| 1005 | outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); | ||
| 1006 | } else { | ||
| 1007 | outreg(host, GC_IMASK, 0); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | device_remove_file(&pdev->dev, &dev_attr_dispregs); | ||
| 1011 | |||
| 1012 | pci_set_drvdata(pdev, NULL); | ||
| 1013 | unregister_framebuffer(fbi); | ||
| 1014 | fb_dealloc_cmap(&fbi->cmap); | ||
| 1015 | |||
| 1016 | free_irq(par->irq, (void *)par); | ||
| 1017 | iounmap(par->mmio_base); | ||
| 1018 | iounmap(par->fb_base); | ||
| 1019 | |||
| 1020 | pci_release_regions(pdev); | ||
| 1021 | framebuffer_release(fbi); | ||
| 1022 | pci_disable_device(pdev); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | static struct pci_driver mb862xxfb_pci_driver = { | ||
| 1026 | .name = DRV_NAME, | ||
| 1027 | .id_table = mb862xx_pci_tbl, | ||
| 1028 | .probe = mb862xx_pci_probe, | ||
| 1029 | .remove = __devexit_p(mb862xx_pci_remove), | ||
| 1030 | }; | ||
| 1031 | #endif | ||
| 1032 | |||
| 1033 | static int __devinit mb862xxfb_init(void) | ||
| 1034 | { | ||
| 1035 | int ret = -ENODEV; | ||
| 1036 | |||
| 1037 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
| 1038 | ret = of_register_platform_driver(&of_platform_mb862xxfb_driver); | ||
| 1039 | #endif | ||
| 1040 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
| 1041 | ret = pci_register_driver(&mb862xxfb_pci_driver); | ||
| 1042 | #endif | ||
| 1043 | return ret; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | static void __exit mb862xxfb_exit(void) | ||
| 1047 | { | ||
| 1048 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
| 1049 | of_unregister_platform_driver(&of_platform_mb862xxfb_driver); | ||
| 1050 | #endif | ||
| 1051 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
| 1052 | pci_unregister_driver(&mb862xxfb_pci_driver); | ||
| 1053 | #endif | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | module_init(mb862xxfb_init); | ||
| 1057 | module_exit(mb862xxfb_exit); | ||
| 1058 | |||
| 1059 | MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver"); | ||
| 1060 | MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); | ||
| 1061 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/mb862xx/mb862xxfb.h new file mode 100644 index 000000000000..c4c8f4dd2217 --- /dev/null +++ b/drivers/video/mb862xx/mb862xxfb.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | #ifndef __MB862XX_H__ | ||
| 2 | #define __MB862XX_H__ | ||
| 3 | |||
| 4 | #define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf | ||
| 5 | #define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019 | ||
| 6 | #define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e | ||
| 7 | #define PCI_DEVICE_ID_FUJITSU_CARMINE 0x202b | ||
| 8 | |||
| 9 | #define GC_MMR_CORALP_EVB_VAL 0x11d7fa13 | ||
| 10 | |||
| 11 | enum gdctype { | ||
| 12 | BT_NONE, | ||
| 13 | BT_LIME, | ||
| 14 | BT_MINT, | ||
| 15 | BT_CORAL, | ||
| 16 | BT_CORALP, | ||
| 17 | BT_CARMINE, | ||
| 18 | }; | ||
| 19 | |||
| 20 | struct mb862xx_gc_mode { | ||
| 21 | struct fb_videomode def_mode; /* mode of connected display */ | ||
| 22 | unsigned int def_bpp; /* default depth */ | ||
| 23 | unsigned long max_vram; /* connected SDRAM size */ | ||
| 24 | unsigned long ccf; /* gdc clk */ | ||
| 25 | unsigned long mmr; /* memory mode for SDRAM */ | ||
| 26 | }; | ||
| 27 | |||
| 28 | /* private data */ | ||
| 29 | struct mb862xxfb_par { | ||
| 30 | struct fb_info *info; /* fb info head */ | ||
| 31 | struct device *dev; | ||
| 32 | struct pci_dev *pdev; | ||
| 33 | struct resource *res; /* framebuffer/mmio resource */ | ||
| 34 | |||
| 35 | resource_size_t fb_base_phys; /* fb base, 36-bit PPC440EPx */ | ||
| 36 | resource_size_t mmio_base_phys; /* io base addr */ | ||
| 37 | void __iomem *fb_base; /* remapped framebuffer */ | ||
| 38 | void __iomem *mmio_base; /* remapped registers */ | ||
| 39 | size_t mapped_vram; /* length of remapped vram */ | ||
| 40 | size_t mmio_len; /* length of register region */ | ||
| 41 | |||
| 42 | void __iomem *host; /* relocatable reg. bases */ | ||
| 43 | void __iomem *i2c; | ||
| 44 | void __iomem *disp; | ||
| 45 | void __iomem *disp1; | ||
| 46 | void __iomem *cap; | ||
| 47 | void __iomem *cap1; | ||
| 48 | void __iomem *draw; | ||
| 49 | void __iomem *geo; | ||
| 50 | void __iomem *pio; | ||
| 51 | void __iomem *ctrl; | ||
| 52 | void __iomem *dram_ctrl; | ||
| 53 | void __iomem *wrback; | ||
| 54 | |||
| 55 | unsigned int irq; | ||
| 56 | unsigned int type; /* GDC type */ | ||
| 57 | unsigned int refclk; /* disp. reference clock */ | ||
| 58 | struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */ | ||
| 59 | int pre_init; /* don't init display if 1 */ | ||
| 60 | |||
| 61 | u32 pseudo_palette[16]; | ||
| 62 | }; | ||
| 63 | |||
| 64 | #if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
| 65 | #error "Select Lime GDC or CoralP/Carmine support, but not both together" | ||
| 66 | #endif | ||
| 67 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
| 68 | #define gdc_read __raw_readl | ||
| 69 | #define gdc_write __raw_writel | ||
| 70 | #else | ||
| 71 | #define gdc_read readl | ||
| 72 | #define gdc_write writel | ||
| 73 | #endif | ||
| 74 | |||
| 75 | #define inreg(type, off) \ | ||
| 76 | gdc_read((par->type + (off))) | ||
| 77 | |||
| 78 | #define outreg(type, off, val) \ | ||
| 79 | gdc_write((val), (par->type + (off))) | ||
| 80 | |||
| 81 | #define pack(a, b) (((a) << 16) | (b)) | ||
| 82 | |||
| 83 | #endif | ||
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile index 99da8b6d2c36..ed13889c1162 100644 --- a/drivers/video/omap/Makefile +++ b/drivers/video/omap/Makefile | |||
| @@ -23,7 +23,6 @@ objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o | |||
| 23 | objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o | 23 | objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o |
| 24 | objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o | 24 | objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o |
| 25 | objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o | 25 | objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o |
| 26 | objs-y$(CONFIG_MACH_SX1) += lcd_sx1.o | ||
| 27 | 26 | ||
| 28 | omapfb-objs := $(objs-yy) | 27 | omapfb-objs := $(objs-yy) |
| 29 | 28 | ||
diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c deleted file mode 100644 index e55de201b8ff..000000000000 --- a/drivers/video/omap/lcd_sx1.c +++ /dev/null | |||
| @@ -1,327 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * LCD panel support for the Siemens SX1 mobile phone | ||
| 3 | * | ||
| 4 | * Current version : Vovan888@gmail.com, great help from FCA00000 | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but | ||
| 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along | ||
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | |||
| 26 | #include <mach/gpio.h> | ||
| 27 | #include <mach/omapfb.h> | ||
| 28 | #include <mach/mcbsp.h> | ||
| 29 | #include <mach/mux.h> | ||
| 30 | |||
| 31 | /* | ||
| 32 | * OMAP310 GPIO registers | ||
| 33 | */ | ||
| 34 | #define GPIO_DATA_INPUT 0xfffce000 | ||
| 35 | #define GPIO_DATA_OUTPUT 0xfffce004 | ||
| 36 | #define GPIO_DIR_CONTROL 0xfffce008 | ||
| 37 | #define GPIO_INT_CONTROL 0xfffce00c | ||
| 38 | #define GPIO_INT_MASK 0xfffce010 | ||
| 39 | #define GPIO_INT_STATUS 0xfffce014 | ||
| 40 | #define GPIO_PIN_CONTROL 0xfffce018 | ||
| 41 | |||
| 42 | |||
| 43 | #define A_LCD_SSC_RD 3 | ||
| 44 | #define A_LCD_SSC_SD 7 | ||
| 45 | #define _A_LCD_RESET 9 | ||
| 46 | #define _A_LCD_SSC_CS 12 | ||
| 47 | #define _A_LCD_SSC_A0 13 | ||
| 48 | |||
| 49 | #define DSP_REG 0xE1017024 | ||
| 50 | |||
| 51 | const unsigned char INIT_1[12] = { | ||
| 52 | 0x1C, 0x02, 0x88, 0x00, 0x1E, 0xE0, 0x00, 0xDC, 0x00, 0x02, 0x00 | ||
| 53 | }; | ||
| 54 | |||
| 55 | const unsigned char INIT_2[127] = { | ||
| 56 | 0x15, 0x00, 0x29, 0x00, 0x3E, 0x00, 0x51, 0x00, | ||
| 57 | 0x65, 0x00, 0x7A, 0x00, 0x8D, 0x00, 0xA1, 0x00, | ||
| 58 | 0xB6, 0x00, 0xC7, 0x00, 0xD8, 0x00, 0xEB, 0x00, | ||
| 59 | 0xFB, 0x00, 0x0B, 0x01, 0x1B, 0x01, 0x27, 0x01, | ||
| 60 | 0x34, 0x01, 0x41, 0x01, 0x4C, 0x01, 0x55, 0x01, | ||
| 61 | 0x5F, 0x01, 0x68, 0x01, 0x70, 0x01, 0x78, 0x01, | ||
| 62 | 0x7E, 0x01, 0x86, 0x01, 0x8C, 0x01, 0x94, 0x01, | ||
| 63 | 0x9B, 0x01, 0xA1, 0x01, 0xA4, 0x01, 0xA9, 0x01, | ||
| 64 | 0xAD, 0x01, 0xB2, 0x01, 0xB7, 0x01, 0xBC, 0x01, | ||
| 65 | 0xC0, 0x01, 0xC4, 0x01, 0xC8, 0x01, 0xCB, 0x01, | ||
| 66 | 0xCF, 0x01, 0xD2, 0x01, 0xD5, 0x01, 0xD8, 0x01, | ||
| 67 | 0xDB, 0x01, 0xE0, 0x01, 0xE3, 0x01, 0xE6, 0x01, | ||
| 68 | 0xE8, 0x01, 0xEB, 0x01, 0xEE, 0x01, 0xF1, 0x01, | ||
| 69 | 0xF3, 0x01, 0xF8, 0x01, 0xF9, 0x01, 0xFC, 0x01, | ||
| 70 | 0x00, 0x02, 0x03, 0x02, 0x07, 0x02, 0x09, 0x02, | ||
| 71 | 0x0E, 0x02, 0x13, 0x02, 0x1C, 0x02, 0x00 | ||
| 72 | }; | ||
| 73 | |||
| 74 | const unsigned char INIT_3[15] = { | ||
| 75 | 0x14, 0x26, 0x33, 0x3D, 0x45, 0x4D, 0x53, 0x59, | ||
| 76 | 0x5E, 0x63, 0x67, 0x6D, 0x71, 0x78, 0xFF | ||
| 77 | }; | ||
| 78 | |||
| 79 | static void epson_sendbyte(int flag, unsigned char byte) | ||
| 80 | { | ||
| 81 | int i, shifter = 0x80; | ||
| 82 | |||
| 83 | if (!flag) | ||
| 84 | gpio_set_value(_A_LCD_SSC_A0, 0); | ||
| 85 | mdelay(2); | ||
| 86 | gpio_set_value(A_LCD_SSC_RD, 1); | ||
| 87 | |||
| 88 | gpio_set_value(A_LCD_SSC_SD, flag); | ||
| 89 | |||
| 90 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); | ||
| 91 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); | ||
| 92 | for (i = 0; i < 8; i++) { | ||
| 93 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200); | ||
| 94 | gpio_set_value(A_LCD_SSC_SD, shifter & byte); | ||
| 95 | OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202); | ||
| 96 | shifter >>= 1; | ||
| 97 | } | ||
| 98 | gpio_set_value(_A_LCD_SSC_A0, 1); | ||
| 99 | } | ||
| 100 | |||
| 101 | static void init_system(void) | ||
| 102 | { | ||
| 103 | omap_mcbsp_request(OMAP_MCBSP3); | ||
| 104 | omap_mcbsp_stop(OMAP_MCBSP3); | ||
| 105 | } | ||
| 106 | |||
| 107 | static void setup_GPIO(void) | ||
| 108 | { | ||
| 109 | /* new wave */ | ||
| 110 | gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd"); | ||
| 111 | gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd"); | ||
| 112 | gpio_request(_A_LCD_RESET, "lcd_reset"); | ||
| 113 | gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs"); | ||
| 114 | gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0"); | ||
| 115 | |||
| 116 | /* set GPIOs to output, with initial data */ | ||
| 117 | gpio_direction_output(A_LCD_SSC_RD, 1); | ||
| 118 | gpio_direction_output(A_LCD_SSC_SD, 0); | ||
| 119 | gpio_direction_output(_A_LCD_RESET, 0); | ||
| 120 | gpio_direction_output(_A_LCD_SSC_CS, 1); | ||
| 121 | gpio_direction_output(_A_LCD_SSC_A0, 1); | ||
| 122 | } | ||
| 123 | |||
| 124 | static void display_init(void) | ||
| 125 | { | ||
| 126 | int i; | ||
| 127 | |||
| 128 | omap_cfg_reg(MCBSP3_CLKX); | ||
| 129 | |||
| 130 | mdelay(2); | ||
| 131 | setup_GPIO(); | ||
| 132 | mdelay(2); | ||
| 133 | |||
| 134 | /* reset LCD */ | ||
| 135 | gpio_set_value(A_LCD_SSC_SD, 1); | ||
| 136 | epson_sendbyte(0, 0x25); | ||
| 137 | |||
| 138 | gpio_set_value(_A_LCD_RESET, 0); | ||
| 139 | mdelay(10); | ||
| 140 | gpio_set_value(_A_LCD_RESET, 1); | ||
| 141 | |||
| 142 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 143 | mdelay(2); | ||
| 144 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 145 | |||
| 146 | /* init LCD, phase 1 */ | ||
| 147 | epson_sendbyte(0, 0xCA); | ||
| 148 | for (i = 0; i < 10; i++) | ||
| 149 | epson_sendbyte(1, INIT_1[i]); | ||
| 150 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 151 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 152 | |||
| 153 | /* init LCD phase 2 */ | ||
| 154 | epson_sendbyte(0, 0xCB); | ||
| 155 | for (i = 0; i < 125; i++) | ||
| 156 | epson_sendbyte(1, INIT_2[i]); | ||
| 157 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 158 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 159 | |||
| 160 | /* init LCD phase 2a */ | ||
| 161 | epson_sendbyte(0, 0xCC); | ||
| 162 | for (i = 0; i < 14; i++) | ||
| 163 | epson_sendbyte(1, INIT_3[i]); | ||
| 164 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 165 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 166 | |||
| 167 | /* init LCD phase 3 */ | ||
| 168 | epson_sendbyte(0, 0xBC); | ||
| 169 | epson_sendbyte(1, 0x08); | ||
| 170 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 171 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 172 | |||
| 173 | /* init LCD phase 4 */ | ||
| 174 | epson_sendbyte(0, 0x07); | ||
| 175 | epson_sendbyte(1, 0x05); | ||
| 176 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 177 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 178 | |||
| 179 | /* init LCD phase 5 */ | ||
| 180 | epson_sendbyte(0, 0x94); | ||
| 181 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 182 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 183 | |||
| 184 | /* init LCD phase 6 */ | ||
| 185 | epson_sendbyte(0, 0xC6); | ||
| 186 | epson_sendbyte(1, 0x80); | ||
| 187 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 188 | mdelay(100); /* used to be 1000 */ | ||
| 189 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 190 | |||
| 191 | /* init LCD phase 7 */ | ||
| 192 | epson_sendbyte(0, 0x16); | ||
| 193 | epson_sendbyte(1, 0x02); | ||
| 194 | epson_sendbyte(1, 0x00); | ||
| 195 | epson_sendbyte(1, 0xB1); | ||
| 196 | epson_sendbyte(1, 0x00); | ||
| 197 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 198 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 199 | |||
| 200 | /* init LCD phase 8 */ | ||
| 201 | epson_sendbyte(0, 0x76); | ||
| 202 | epson_sendbyte(1, 0x00); | ||
| 203 | epson_sendbyte(1, 0x00); | ||
| 204 | epson_sendbyte(1, 0xDB); | ||
| 205 | epson_sendbyte(1, 0x00); | ||
| 206 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 207 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 208 | |||
| 209 | /* init LCD phase 9 */ | ||
| 210 | epson_sendbyte(0, 0xAF); | ||
| 211 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 212 | } | ||
| 213 | |||
| 214 | static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) | ||
| 215 | { | ||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static void sx1_panel_cleanup(struct lcd_panel *panel) | ||
| 220 | { | ||
| 221 | } | ||
| 222 | |||
| 223 | static void sx1_panel_disable(struct lcd_panel *panel) | ||
| 224 | { | ||
| 225 | printk(KERN_INFO "SX1: LCD panel disable\n"); | ||
| 226 | sx1_setmmipower(0); | ||
| 227 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 228 | |||
| 229 | epson_sendbyte(0, 0x25); | ||
| 230 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 231 | |||
| 232 | epson_sendbyte(0, 0xAE); | ||
| 233 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 234 | mdelay(100); | ||
| 235 | gpio_set_value(_A_LCD_SSC_CS, 0); | ||
| 236 | |||
| 237 | epson_sendbyte(0, 0x95); | ||
| 238 | gpio_set_value(_A_LCD_SSC_CS, 1); | ||
| 239 | } | ||
| 240 | |||
| 241 | static int sx1_panel_enable(struct lcd_panel *panel) | ||
| 242 | { | ||
| 243 | printk(KERN_INFO "lcd_sx1: LCD panel enable\n"); | ||
| 244 | init_system(); | ||
| 245 | display_init(); | ||
| 246 | |||
| 247 | sx1_setmmipower(1); | ||
| 248 | sx1_setbacklight(0x18); | ||
| 249 | sx1_setkeylight (0x06); | ||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | |||
| 254 | static unsigned long sx1_panel_get_caps(struct lcd_panel *panel) | ||
| 255 | { | ||
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | struct lcd_panel sx1_panel = { | ||
| 260 | .name = "sx1", | ||
| 261 | .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | | ||
| 262 | OMAP_LCDC_INV_HSYNC | OMAP_LCDC_INV_PIX_CLOCK | | ||
| 263 | OMAP_LCDC_INV_OUTPUT_EN, | ||
| 264 | |||
| 265 | .x_res = 176, | ||
| 266 | .y_res = 220, | ||
| 267 | .data_lines = 16, | ||
| 268 | .bpp = 16, | ||
| 269 | .hsw = 5, | ||
| 270 | .hfp = 5, | ||
| 271 | .hbp = 5, | ||
| 272 | .vsw = 2, | ||
| 273 | .vfp = 1, | ||
| 274 | .vbp = 1, | ||
| 275 | .pixel_clock = 1500, | ||
| 276 | |||
| 277 | .init = sx1_panel_init, | ||
| 278 | .cleanup = sx1_panel_cleanup, | ||
| 279 | .enable = sx1_panel_enable, | ||
| 280 | .disable = sx1_panel_disable, | ||
| 281 | .get_caps = sx1_panel_get_caps, | ||
| 282 | }; | ||
| 283 | |||
| 284 | static int sx1_panel_probe(struct platform_device *pdev) | ||
| 285 | { | ||
| 286 | omapfb_register_panel(&sx1_panel); | ||
| 287 | return 0; | ||
| 288 | } | ||
| 289 | |||
| 290 | static int sx1_panel_remove(struct platform_device *pdev) | ||
| 291 | { | ||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | static int sx1_panel_suspend(struct platform_device *pdev, pm_message_t mesg) | ||
| 296 | { | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | static int sx1_panel_resume(struct platform_device *pdev) | ||
| 301 | { | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 305 | struct platform_driver sx1_panel_driver = { | ||
| 306 | .probe = sx1_panel_probe, | ||
| 307 | .remove = sx1_panel_remove, | ||
| 308 | .suspend = sx1_panel_suspend, | ||
| 309 | .resume = sx1_panel_resume, | ||
| 310 | .driver = { | ||
| 311 | .name = "lcd_sx1", | ||
| 312 | .owner = THIS_MODULE, | ||
| 313 | }, | ||
| 314 | }; | ||
| 315 | |||
| 316 | static int sx1_panel_drv_init(void) | ||
| 317 | { | ||
| 318 | return platform_driver_register(&sx1_panel_driver); | ||
| 319 | } | ||
| 320 | |||
| 321 | static void sx1_panel_drv_cleanup(void) | ||
| 322 | { | ||
| 323 | platform_driver_unregister(&sx1_panel_driver); | ||
| 324 | } | ||
| 325 | |||
| 326 | module_init(sx1_panel_drv_init); | ||
| 327 | module_exit(sx1_panel_drv_cleanup); | ||
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 5a5e407dc45f..1a49519dafa4 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
| @@ -392,7 +392,7 @@ static void set_fb_fix(struct fb_info *fbi) | |||
| 392 | int bpp; | 392 | int bpp; |
| 393 | 393 | ||
| 394 | rg = &plane->fbdev->mem_desc.region[plane->idx]; | 394 | rg = &plane->fbdev->mem_desc.region[plane->idx]; |
| 395 | fbi->screen_base = (char __iomem *)rg->vaddr; | 395 | fbi->screen_base = rg->vaddr; |
| 396 | fix->smem_start = rg->paddr; | 396 | fix->smem_start = rg->paddr; |
| 397 | fix->smem_len = rg->size; | 397 | fix->smem_len = rg->size; |
| 398 | 398 | ||
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 97204497d9f7..cc59c52e1103 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
| @@ -804,6 +804,9 @@ static int pxafb_smart_thread(void *arg) | |||
| 804 | 804 | ||
| 805 | static int pxafb_smart_init(struct pxafb_info *fbi) | 805 | static int pxafb_smart_init(struct pxafb_info *fbi) |
| 806 | { | 806 | { |
| 807 | if (!(fbi->lccr0 | LCCR0_LCDT)) | ||
| 808 | return 0; | ||
| 809 | |||
| 807 | fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi, | 810 | fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi, |
| 808 | "lcd_refresh"); | 811 | "lcd_refresh"); |
| 809 | if (IS_ERR(fbi->smart_thread)) { | 812 | if (IS_ERR(fbi->smart_thread)) { |
| @@ -1372,7 +1375,7 @@ static void pxafb_decode_mach_info(struct pxafb_info *fbi, | |||
| 1372 | fbi->cmap_inverse = inf->cmap_inverse; | 1375 | fbi->cmap_inverse = inf->cmap_inverse; |
| 1373 | fbi->cmap_static = inf->cmap_static; | 1376 | fbi->cmap_static = inf->cmap_static; |
| 1374 | 1377 | ||
| 1375 | switch (lcd_conn & 0xf) { | 1378 | switch (lcd_conn & LCD_TYPE_MASK) { |
| 1376 | case LCD_TYPE_MONO_STN: | 1379 | case LCD_TYPE_MONO_STN: |
| 1377 | fbi->lccr0 = LCCR0_CMS; | 1380 | fbi->lccr0 = LCCR0_CMS; |
| 1378 | break; | 1381 | break; |
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c index 2a380011e9ba..7baf2dd12d50 100644 --- a/drivers/video/tmiofb.c +++ b/drivers/video/tmiofb.c | |||
| @@ -222,6 +222,9 @@ static irqreturn_t tmiofb_irq(int irq, void *__info) | |||
| 222 | unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC); | 222 | unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC); |
| 223 | 223 | ||
| 224 | 224 | ||
| 225 | tmio_iowrite16(bbisc, par->lcr + LCR_BBISC); | ||
| 226 | |||
| 227 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
| 225 | /* | 228 | /* |
| 226 | * We were in polling mode and now we got correct irq. | 229 | * We were in polling mode and now we got correct irq. |
| 227 | * Switch back to IRQ-based sync of command FIFO | 230 | * Switch back to IRQ-based sync of command FIFO |
| @@ -231,9 +234,6 @@ static irqreturn_t tmiofb_irq(int irq, void *__info) | |||
| 231 | par->use_polling = false; | 234 | par->use_polling = false; |
| 232 | } | 235 | } |
| 233 | 236 | ||
| 234 | tmio_iowrite16(bbisc, par->lcr + LCR_BBISC); | ||
| 235 | |||
| 236 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
| 237 | if (bbisc & 1) | 237 | if (bbisc & 1) |
| 238 | wake_up(&par->wait_acc); | 238 | wake_up(&par->wait_acc); |
| 239 | #endif | 239 | #endif |
| @@ -938,7 +938,9 @@ static void tmiofb_dump_regs(struct platform_device *dev) | |||
| 938 | static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) | 938 | static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) |
| 939 | { | 939 | { |
| 940 | struct fb_info *info = platform_get_drvdata(dev); | 940 | struct fb_info *info = platform_get_drvdata(dev); |
| 941 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
| 941 | struct tmiofb_par *par = info->par; | 942 | struct tmiofb_par *par = info->par; |
| 943 | #endif | ||
| 942 | struct mfd_cell *cell = dev->dev.platform_data; | 944 | struct mfd_cell *cell = dev->dev.platform_data; |
| 943 | int retval = 0; | 945 | int retval = 0; |
| 944 | 946 | ||
| @@ -950,12 +952,14 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state) | |||
| 950 | info->fbops->fb_sync(info); | 952 | info->fbops->fb_sync(info); |
| 951 | 953 | ||
| 952 | 954 | ||
| 955 | #ifdef CONFIG_FB_TMIO_ACCELL | ||
| 953 | /* | 956 | /* |
| 954 | * The fb should be usable even if interrupts are disabled (and they are | 957 | * The fb should be usable even if interrupts are disabled (and they are |
| 955 | * during suspend/resume). Switch temporary to forced polling. | 958 | * during suspend/resume). Switch temporary to forced polling. |
| 956 | */ | 959 | */ |
| 957 | printk(KERN_INFO "tmiofb: switching to polling\n"); | 960 | printk(KERN_INFO "tmiofb: switching to polling\n"); |
| 958 | par->use_polling = true; | 961 | par->use_polling = true; |
| 962 | #endif | ||
| 959 | tmiofb_hw_stop(dev); | 963 | tmiofb_hw_stop(dev); |
| 960 | 964 | ||
| 961 | if (cell->suspend) | 965 | if (cell->suspend) |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 0132eae06f55..73ac754ad801 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
| @@ -2036,30 +2036,30 @@ static int viafb_vt1636_proc_write(struct file *file, | |||
| 2036 | return count; | 2036 | return count; |
| 2037 | } | 2037 | } |
| 2038 | 2038 | ||
| 2039 | static void viafb_init_proc(struct proc_dir_entry *viafb_entry) | 2039 | static void viafb_init_proc(struct proc_dir_entry **viafb_entry) |
| 2040 | { | 2040 | { |
| 2041 | struct proc_dir_entry *entry; | 2041 | struct proc_dir_entry *entry; |
| 2042 | viafb_entry = proc_mkdir("viafb", NULL); | 2042 | *viafb_entry = proc_mkdir("viafb", NULL); |
| 2043 | if (viafb_entry) { | 2043 | if (viafb_entry) { |
| 2044 | entry = create_proc_entry("dvp0", 0, viafb_entry); | 2044 | entry = create_proc_entry("dvp0", 0, *viafb_entry); |
| 2045 | if (entry) { | 2045 | if (entry) { |
| 2046 | entry->owner = THIS_MODULE; | 2046 | entry->owner = THIS_MODULE; |
| 2047 | entry->read_proc = viafb_dvp0_proc_read; | 2047 | entry->read_proc = viafb_dvp0_proc_read; |
| 2048 | entry->write_proc = viafb_dvp0_proc_write; | 2048 | entry->write_proc = viafb_dvp0_proc_write; |
| 2049 | } | 2049 | } |
| 2050 | entry = create_proc_entry("dvp1", 0, viafb_entry); | 2050 | entry = create_proc_entry("dvp1", 0, *viafb_entry); |
| 2051 | if (entry) { | 2051 | if (entry) { |
| 2052 | entry->owner = THIS_MODULE; | 2052 | entry->owner = THIS_MODULE; |
| 2053 | entry->read_proc = viafb_dvp1_proc_read; | 2053 | entry->read_proc = viafb_dvp1_proc_read; |
| 2054 | entry->write_proc = viafb_dvp1_proc_write; | 2054 | entry->write_proc = viafb_dvp1_proc_write; |
| 2055 | } | 2055 | } |
| 2056 | entry = create_proc_entry("dfph", 0, viafb_entry); | 2056 | entry = create_proc_entry("dfph", 0, *viafb_entry); |
| 2057 | if (entry) { | 2057 | if (entry) { |
| 2058 | entry->owner = THIS_MODULE; | 2058 | entry->owner = THIS_MODULE; |
| 2059 | entry->read_proc = viafb_dfph_proc_read; | 2059 | entry->read_proc = viafb_dfph_proc_read; |
| 2060 | entry->write_proc = viafb_dfph_proc_write; | 2060 | entry->write_proc = viafb_dfph_proc_write; |
| 2061 | } | 2061 | } |
| 2062 | entry = create_proc_entry("dfpl", 0, viafb_entry); | 2062 | entry = create_proc_entry("dfpl", 0, *viafb_entry); |
| 2063 | if (entry) { | 2063 | if (entry) { |
| 2064 | entry->owner = THIS_MODULE; | 2064 | entry->owner = THIS_MODULE; |
| 2065 | entry->read_proc = viafb_dfpl_proc_read; | 2065 | entry->read_proc = viafb_dfpl_proc_read; |
| @@ -2068,7 +2068,7 @@ static void viafb_init_proc(struct proc_dir_entry *viafb_entry) | |||
| 2068 | if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. | 2068 | if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. |
| 2069 | lvds_chip_name || VT1636_LVDS == | 2069 | lvds_chip_name || VT1636_LVDS == |
| 2070 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { | 2070 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { |
| 2071 | entry = create_proc_entry("vt1636", 0, viafb_entry); | 2071 | entry = create_proc_entry("vt1636", 0, *viafb_entry); |
| 2072 | if (entry) { | 2072 | if (entry) { |
| 2073 | entry->owner = THIS_MODULE; | 2073 | entry->owner = THIS_MODULE; |
| 2074 | entry->read_proc = viafb_vt1636_proc_read; | 2074 | entry->read_proc = viafb_vt1636_proc_read; |
| @@ -2087,6 +2087,7 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) | |||
| 2087 | remove_proc_entry("dfpl", viafb_entry); | 2087 | remove_proc_entry("dfpl", viafb_entry); |
| 2088 | remove_proc_entry("vt1636", viafb_entry); | 2088 | remove_proc_entry("vt1636", viafb_entry); |
| 2089 | remove_proc_entry("vt1625", viafb_entry); | 2089 | remove_proc_entry("vt1625", viafb_entry); |
| 2090 | remove_proc_entry("viafb", NULL); | ||
| 2090 | } | 2091 | } |
| 2091 | 2092 | ||
| 2092 | static int __devinit via_pci_probe(void) | 2093 | static int __devinit via_pci_probe(void) |
| @@ -2348,7 +2349,7 @@ static int __devinit via_pci_probe(void) | |||
| 2348 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, | 2349 | viafbinfo->node, viafbinfo->fix.id, default_var.xres, |
| 2349 | default_var.yres, default_var.bits_per_pixel); | 2350 | default_var.yres, default_var.bits_per_pixel); |
| 2350 | 2351 | ||
| 2351 | viafb_init_proc(viaparinfo->proc_entry); | 2352 | viafb_init_proc(&viaparinfo->proc_entry); |
| 2352 | viafb_init_dac(IGA2); | 2353 | viafb_init_dac(IGA2); |
| 2353 | return 0; | 2354 | return 0; |
| 2354 | } | 2355 | } |
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index a463b3dd837b..2493f05e9f61 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
| @@ -668,7 +668,7 @@ static struct xenbus_device_id xenfb_ids[] = { | |||
| 668 | { "" } | 668 | { "" } |
| 669 | }; | 669 | }; |
| 670 | 670 | ||
| 671 | static struct xenbus_driver xenfb = { | 671 | static struct xenbus_driver xenfb_driver = { |
| 672 | .name = "vfb", | 672 | .name = "vfb", |
| 673 | .owner = THIS_MODULE, | 673 | .owner = THIS_MODULE, |
| 674 | .ids = xenfb_ids, | 674 | .ids = xenfb_ids, |
| @@ -687,12 +687,12 @@ static int __init xenfb_init(void) | |||
| 687 | if (xen_initial_domain()) | 687 | if (xen_initial_domain()) |
| 688 | return -ENODEV; | 688 | return -ENODEV; |
| 689 | 689 | ||
| 690 | return xenbus_register_frontend(&xenfb); | 690 | return xenbus_register_frontend(&xenfb_driver); |
| 691 | } | 691 | } |
| 692 | 692 | ||
| 693 | static void __exit xenfb_cleanup(void) | 693 | static void __exit xenfb_cleanup(void) |
| 694 | { | 694 | { |
| 695 | xenbus_unregister_driver(&xenfb); | 695 | xenbus_unregister_driver(&xenfb_driver); |
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | module_init(xenfb_init); | 698 | module_init(xenfb_init); |
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 5da3d2423cc0..40a3a2afbfe7 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
| @@ -298,8 +298,9 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
| 298 | 298 | ||
| 299 | /* Put a banner in the log (for DEBUG) */ | 299 | /* Put a banner in the log (for DEBUG) */ |
| 300 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); | 300 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); |
| 301 | dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", | 301 | dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", |
| 302 | (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize); | 302 | (unsigned long long) drvdata->fb_phys, drvdata->fb_virt, |
| 303 | fbsize); | ||
| 303 | 304 | ||
| 304 | return 0; /* success */ | 305 | return 0; /* success */ |
| 305 | 306 | ||
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index c4493091c655..90616822cd20 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig | |||
| @@ -36,7 +36,7 @@ config W1_MASTER_DS2482 | |||
| 36 | 36 | ||
| 37 | config W1_MASTER_DS1WM | 37 | config W1_MASTER_DS1WM |
| 38 | tristate "Maxim DS1WM 1-wire busmaster" | 38 | tristate "Maxim DS1WM 1-wire busmaster" |
| 39 | depends on W1 && ARM | 39 | depends on W1 && ARM && HAVE_CLK |
| 40 | help | 40 | help |
| 41 | Say Y here to enable the DS1WM 1-wire driver, such as that | 41 | Say Y here to enable the DS1WM 1-wire driver, such as that |
| 42 | in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like | 42 | in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like |
| @@ -52,5 +52,12 @@ config W1_MASTER_GPIO | |||
| 52 | This support is also available as a module. If so, the module | 52 | This support is also available as a module. If so, the module |
| 53 | will be called w1-gpio.ko. | 53 | will be called w1-gpio.ko. |
| 54 | 54 | ||
| 55 | config HDQ_MASTER_OMAP | ||
| 56 | tristate "OMAP HDQ driver" | ||
| 57 | depends on ARCH_OMAP2430 || ARCH_OMAP34XX | ||
| 58 | help | ||
| 59 | Say Y here if you want support for the 1-wire or HDQ Interface | ||
| 60 | on an OMAP processor. | ||
| 61 | |||
| 55 | endmenu | 62 | endmenu |
| 56 | 63 | ||
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile index 1420b5bbdda8..bc4714a75f3a 100644 --- a/drivers/w1/masters/Makefile +++ b/drivers/w1/masters/Makefile | |||
| @@ -7,3 +7,4 @@ obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o | |||
| 7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o | 7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o |
| 8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o | 8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o |
| 9 | obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o | 9 | obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o |
| 10 | obj-$(CONFIG_HDQ_MASTER_OMAP) += omap_hdq.o | ||
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c new file mode 100644 index 000000000000..c973889110c8 --- /dev/null +++ b/drivers/w1/masters/omap_hdq.c | |||
| @@ -0,0 +1,725 @@ | |||
| 1 | /* | ||
| 2 | * drivers/w1/masters/omap_hdq.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007 Texas Instruments, Inc. | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public License | ||
| 7 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 8 | * kind, whether express or implied. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | |||
| 19 | #include <asm/irq.h> | ||
| 20 | #include <mach/hardware.h> | ||
| 21 | |||
| 22 | #include "../w1.h" | ||
| 23 | #include "../w1_int.h" | ||
| 24 | |||
| 25 | #define MOD_NAME "OMAP_HDQ:" | ||
| 26 | |||
| 27 | #define OMAP_HDQ_REVISION 0x00 | ||
| 28 | #define OMAP_HDQ_TX_DATA 0x04 | ||
| 29 | #define OMAP_HDQ_RX_DATA 0x08 | ||
| 30 | #define OMAP_HDQ_CTRL_STATUS 0x0c | ||
| 31 | #define OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK (1<<6) | ||
| 32 | #define OMAP_HDQ_CTRL_STATUS_CLOCKENABLE (1<<5) | ||
| 33 | #define OMAP_HDQ_CTRL_STATUS_GO (1<<4) | ||
| 34 | #define OMAP_HDQ_CTRL_STATUS_INITIALIZATION (1<<2) | ||
| 35 | #define OMAP_HDQ_CTRL_STATUS_DIR (1<<1) | ||
| 36 | #define OMAP_HDQ_CTRL_STATUS_MODE (1<<0) | ||
| 37 | #define OMAP_HDQ_INT_STATUS 0x10 | ||
| 38 | #define OMAP_HDQ_INT_STATUS_TXCOMPLETE (1<<2) | ||
| 39 | #define OMAP_HDQ_INT_STATUS_RXCOMPLETE (1<<1) | ||
| 40 | #define OMAP_HDQ_INT_STATUS_TIMEOUT (1<<0) | ||
| 41 | #define OMAP_HDQ_SYSCONFIG 0x14 | ||
| 42 | #define OMAP_HDQ_SYSCONFIG_SOFTRESET (1<<1) | ||
| 43 | #define OMAP_HDQ_SYSCONFIG_AUTOIDLE (1<<0) | ||
| 44 | #define OMAP_HDQ_SYSSTATUS 0x18 | ||
| 45 | #define OMAP_HDQ_SYSSTATUS_RESETDONE (1<<0) | ||
| 46 | |||
| 47 | #define OMAP_HDQ_FLAG_CLEAR 0 | ||
| 48 | #define OMAP_HDQ_FLAG_SET 1 | ||
| 49 | #define OMAP_HDQ_TIMEOUT (HZ/5) | ||
| 50 | |||
| 51 | #define OMAP_HDQ_MAX_USER 4 | ||
| 52 | |||
| 53 | static DECLARE_WAIT_QUEUE_HEAD(hdq_wait_queue); | ||
| 54 | static int w1_id; | ||
| 55 | |||
| 56 | struct hdq_data { | ||
| 57 | struct device *dev; | ||
| 58 | void __iomem *hdq_base; | ||
| 59 | /* lock status update */ | ||
| 60 | struct mutex hdq_mutex; | ||
| 61 | int hdq_usecount; | ||
| 62 | struct clk *hdq_ick; | ||
| 63 | struct clk *hdq_fck; | ||
| 64 | u8 hdq_irqstatus; | ||
| 65 | /* device lock */ | ||
| 66 | spinlock_t hdq_spinlock; | ||
| 67 | /* | ||
| 68 | * Used to control the call to omap_hdq_get and omap_hdq_put. | ||
| 69 | * HDQ Protocol: Write the CMD|REG_address first, followed by | ||
| 70 | * the data wrire or read. | ||
| 71 | */ | ||
| 72 | int init_trans; | ||
| 73 | }; | ||
| 74 | |||
| 75 | static int __init omap_hdq_probe(struct platform_device *pdev); | ||
| 76 | static int omap_hdq_remove(struct platform_device *pdev); | ||
| 77 | |||
| 78 | static struct platform_driver omap_hdq_driver = { | ||
| 79 | .probe = omap_hdq_probe, | ||
| 80 | .remove = omap_hdq_remove, | ||
| 81 | .driver = { | ||
| 82 | .name = "omap_hdq", | ||
| 83 | }, | ||
| 84 | }; | ||
| 85 | |||
| 86 | static u8 omap_w1_read_byte(void *_hdq); | ||
| 87 | static void omap_w1_write_byte(void *_hdq, u8 byte); | ||
| 88 | static u8 omap_w1_reset_bus(void *_hdq); | ||
| 89 | static void omap_w1_search_bus(void *_hdq, struct w1_master *master_dev, | ||
| 90 | u8 search_type, w1_slave_found_callback slave_found); | ||
| 91 | |||
| 92 | |||
| 93 | static struct w1_bus_master omap_w1_master = { | ||
| 94 | .read_byte = omap_w1_read_byte, | ||
| 95 | .write_byte = omap_w1_write_byte, | ||
| 96 | .reset_bus = omap_w1_reset_bus, | ||
| 97 | .search = omap_w1_search_bus, | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* HDQ register I/O routines */ | ||
| 101 | static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset) | ||
| 102 | { | ||
| 103 | return __raw_readb(hdq_data->hdq_base + offset); | ||
| 104 | } | ||
| 105 | |||
| 106 | static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val) | ||
| 107 | { | ||
| 108 | __raw_writeb(val, hdq_data->hdq_base + offset); | ||
| 109 | } | ||
| 110 | |||
| 111 | static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset, | ||
| 112 | u8 val, u8 mask) | ||
| 113 | { | ||
| 114 | u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask) | ||
| 115 | | (val & mask); | ||
| 116 | __raw_writeb(new_val, hdq_data->hdq_base + offset); | ||
| 117 | |||
| 118 | return new_val; | ||
| 119 | } | ||
| 120 | |||
| 121 | /* | ||
| 122 | * Wait for one or more bits in flag change. | ||
| 123 | * HDQ_FLAG_SET: wait until any bit in the flag is set. | ||
| 124 | * HDQ_FLAG_CLEAR: wait until all bits in the flag are cleared. | ||
| 125 | * return 0 on success and -ETIMEDOUT in the case of timeout. | ||
| 126 | */ | ||
| 127 | static int hdq_wait_for_flag(struct hdq_data *hdq_data, u32 offset, | ||
| 128 | u8 flag, u8 flag_set, u8 *status) | ||
| 129 | { | ||
| 130 | int ret = 0; | ||
| 131 | unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; | ||
| 132 | |||
| 133 | if (flag_set == OMAP_HDQ_FLAG_CLEAR) { | ||
| 134 | /* wait for the flag clear */ | ||
| 135 | while (((*status = hdq_reg_in(hdq_data, offset)) & flag) | ||
| 136 | && time_before(jiffies, timeout)) { | ||
| 137 | schedule_timeout_uninterruptible(1); | ||
| 138 | } | ||
| 139 | if (*status & flag) | ||
| 140 | ret = -ETIMEDOUT; | ||
| 141 | } else if (flag_set == OMAP_HDQ_FLAG_SET) { | ||
| 142 | /* wait for the flag set */ | ||
| 143 | while (!((*status = hdq_reg_in(hdq_data, offset)) & flag) | ||
| 144 | && time_before(jiffies, timeout)) { | ||
| 145 | schedule_timeout_uninterruptible(1); | ||
| 146 | } | ||
| 147 | if (!(*status & flag)) | ||
| 148 | ret = -ETIMEDOUT; | ||
| 149 | } else | ||
| 150 | return -EINVAL; | ||
| 151 | |||
| 152 | return ret; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* write out a byte and fill *status with HDQ_INT_STATUS */ | ||
| 156 | static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | ||
| 157 | { | ||
| 158 | int ret; | ||
| 159 | u8 tmp_status; | ||
| 160 | unsigned long irqflags; | ||
| 161 | |||
| 162 | *status = 0; | ||
| 163 | |||
| 164 | spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); | ||
| 165 | /* clear interrupt flags via a dummy read */ | ||
| 166 | hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
| 167 | /* ISR loads it with new INT_STATUS */ | ||
| 168 | hdq_data->hdq_irqstatus = 0; | ||
| 169 | spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); | ||
| 170 | |||
| 171 | hdq_reg_out(hdq_data, OMAP_HDQ_TX_DATA, val); | ||
| 172 | |||
| 173 | /* set the GO bit */ | ||
| 174 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, OMAP_HDQ_CTRL_STATUS_GO, | ||
| 175 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); | ||
| 176 | /* wait for the TXCOMPLETE bit */ | ||
| 177 | ret = wait_event_timeout(hdq_wait_queue, | ||
| 178 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); | ||
| 179 | if (ret == 0) { | ||
| 180 | dev_dbg(hdq_data->dev, "TX wait elapsed\n"); | ||
| 181 | goto out; | ||
| 182 | } | ||
| 183 | |||
| 184 | *status = hdq_data->hdq_irqstatus; | ||
| 185 | /* check irqstatus */ | ||
| 186 | if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { | ||
| 187 | dev_dbg(hdq_data->dev, "timeout waiting for" | ||
| 188 | "TXCOMPLETE/RXCOMPLETE, %x", *status); | ||
| 189 | ret = -ETIMEDOUT; | ||
| 190 | goto out; | ||
| 191 | } | ||
| 192 | |||
| 193 | /* wait for the GO bit return to zero */ | ||
| 194 | ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 195 | OMAP_HDQ_CTRL_STATUS_GO, | ||
| 196 | OMAP_HDQ_FLAG_CLEAR, &tmp_status); | ||
| 197 | if (ret) { | ||
| 198 | dev_dbg(hdq_data->dev, "timeout waiting GO bit" | ||
| 199 | "return to zero, %x", tmp_status); | ||
| 200 | } | ||
| 201 | |||
| 202 | out: | ||
| 203 | return ret; | ||
| 204 | } | ||
| 205 | |||
| 206 | /* HDQ Interrupt service routine */ | ||
| 207 | static irqreturn_t hdq_isr(int irq, void *_hdq) | ||
| 208 | { | ||
| 209 | struct hdq_data *hdq_data = _hdq; | ||
| 210 | unsigned long irqflags; | ||
| 211 | |||
| 212 | spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); | ||
| 213 | hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
| 214 | spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); | ||
| 215 | dev_dbg(hdq_data->dev, "hdq_isr: %x", hdq_data->hdq_irqstatus); | ||
| 216 | |||
| 217 | if (hdq_data->hdq_irqstatus & | ||
| 218 | (OMAP_HDQ_INT_STATUS_TXCOMPLETE | OMAP_HDQ_INT_STATUS_RXCOMPLETE | ||
| 219 | | OMAP_HDQ_INT_STATUS_TIMEOUT)) { | ||
| 220 | /* wake up sleeping process */ | ||
| 221 | wake_up(&hdq_wait_queue); | ||
| 222 | } | ||
| 223 | |||
| 224 | return IRQ_HANDLED; | ||
| 225 | } | ||
| 226 | |||
| 227 | /* HDQ Mode: always return success */ | ||
| 228 | static u8 omap_w1_reset_bus(void *_hdq) | ||
| 229 | { | ||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | /* W1 search callback function */ | ||
| 234 | static void omap_w1_search_bus(void *_hdq, struct w1_master *master_dev, | ||
| 235 | u8 search_type, w1_slave_found_callback slave_found) | ||
| 236 | { | ||
| 237 | u64 module_id, rn_le, cs, id; | ||
| 238 | |||
| 239 | if (w1_id) | ||
| 240 | module_id = w1_id; | ||
| 241 | else | ||
| 242 | module_id = 0x1; | ||
| 243 | |||
| 244 | rn_le = cpu_to_le64(module_id); | ||
| 245 | /* | ||
| 246 | * HDQ might not obey truly the 1-wire spec. | ||
| 247 | * So calculate CRC based on module parameter. | ||
| 248 | */ | ||
| 249 | cs = w1_calc_crc8((u8 *)&rn_le, 7); | ||
| 250 | id = (cs << 56) | module_id; | ||
| 251 | |||
| 252 | slave_found(master_dev, id); | ||
| 253 | } | ||
| 254 | |||
| 255 | static int _omap_hdq_reset(struct hdq_data *hdq_data) | ||
| 256 | { | ||
| 257 | int ret; | ||
| 258 | u8 tmp_status; | ||
| 259 | |||
| 260 | hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG, OMAP_HDQ_SYSCONFIG_SOFTRESET); | ||
| 261 | /* | ||
| 262 | * Select HDQ mode & enable clocks. | ||
| 263 | * It is observed that INT flags can't be cleared via a read and GO/INIT | ||
| 264 | * won't return to zero if interrupt is disabled. So we always enable | ||
| 265 | * interrupt. | ||
| 266 | */ | ||
| 267 | hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 268 | OMAP_HDQ_CTRL_STATUS_CLOCKENABLE | | ||
| 269 | OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); | ||
| 270 | |||
| 271 | /* wait for reset to complete */ | ||
| 272 | ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_SYSSTATUS, | ||
| 273 | OMAP_HDQ_SYSSTATUS_RESETDONE, OMAP_HDQ_FLAG_SET, &tmp_status); | ||
| 274 | if (ret) | ||
| 275 | dev_dbg(hdq_data->dev, "timeout waiting HDQ reset, %x", | ||
| 276 | tmp_status); | ||
| 277 | else { | ||
| 278 | hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 279 | OMAP_HDQ_CTRL_STATUS_CLOCKENABLE | | ||
| 280 | OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); | ||
| 281 | hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG, | ||
| 282 | OMAP_HDQ_SYSCONFIG_AUTOIDLE); | ||
| 283 | } | ||
| 284 | |||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Issue break pulse to the device */ | ||
| 289 | static int omap_hdq_break(struct hdq_data *hdq_data) | ||
| 290 | { | ||
| 291 | int ret = 0; | ||
| 292 | u8 tmp_status; | ||
| 293 | unsigned long irqflags; | ||
| 294 | |||
| 295 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 296 | if (ret < 0) { | ||
| 297 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
| 298 | ret = -EINTR; | ||
| 299 | goto rtn; | ||
| 300 | } | ||
| 301 | |||
| 302 | spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); | ||
| 303 | /* clear interrupt flags via a dummy read */ | ||
| 304 | hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
| 305 | /* ISR loads it with new INT_STATUS */ | ||
| 306 | hdq_data->hdq_irqstatus = 0; | ||
| 307 | spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); | ||
| 308 | |||
| 309 | /* set the INIT and GO bit */ | ||
| 310 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 311 | OMAP_HDQ_CTRL_STATUS_INITIALIZATION | OMAP_HDQ_CTRL_STATUS_GO, | ||
| 312 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_INITIALIZATION | | ||
| 313 | OMAP_HDQ_CTRL_STATUS_GO); | ||
| 314 | |||
| 315 | /* wait for the TIMEOUT bit */ | ||
| 316 | ret = wait_event_timeout(hdq_wait_queue, | ||
| 317 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); | ||
| 318 | if (ret == 0) { | ||
| 319 | dev_dbg(hdq_data->dev, "break wait elapsed\n"); | ||
| 320 | ret = -EINTR; | ||
| 321 | goto out; | ||
| 322 | } | ||
| 323 | |||
| 324 | tmp_status = hdq_data->hdq_irqstatus; | ||
| 325 | /* check irqstatus */ | ||
| 326 | if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) { | ||
| 327 | dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x", | ||
| 328 | tmp_status); | ||
| 329 | ret = -ETIMEDOUT; | ||
| 330 | goto out; | ||
| 331 | } | ||
| 332 | /* | ||
| 333 | * wait for both INIT and GO bits rerurn to zero. | ||
| 334 | * zero wait time expected for interrupt mode. | ||
| 335 | */ | ||
| 336 | ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 337 | OMAP_HDQ_CTRL_STATUS_INITIALIZATION | | ||
| 338 | OMAP_HDQ_CTRL_STATUS_GO, OMAP_HDQ_FLAG_CLEAR, | ||
| 339 | &tmp_status); | ||
| 340 | if (ret) | ||
| 341 | dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" | ||
| 342 | "return to zero, %x", tmp_status); | ||
| 343 | |||
| 344 | out: | ||
| 345 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 346 | rtn: | ||
| 347 | return ret; | ||
| 348 | } | ||
| 349 | |||
| 350 | static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | ||
| 351 | { | ||
| 352 | int ret = 0; | ||
| 353 | u8 status; | ||
| 354 | unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; | ||
| 355 | |||
| 356 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 357 | if (ret < 0) { | ||
| 358 | ret = -EINTR; | ||
| 359 | goto rtn; | ||
| 360 | } | ||
| 361 | |||
| 362 | if (!hdq_data->hdq_usecount) { | ||
| 363 | ret = -EINVAL; | ||
| 364 | goto out; | ||
| 365 | } | ||
| 366 | |||
| 367 | if (!(hdq_data->hdq_irqstatus & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { | ||
| 368 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 369 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, | ||
| 370 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); | ||
| 371 | /* | ||
| 372 | * The RX comes immediately after TX. It | ||
| 373 | * triggers another interrupt before we | ||
| 374 | * sleep. So we have to wait for RXCOMPLETE bit. | ||
| 375 | */ | ||
| 376 | while (!(hdq_data->hdq_irqstatus | ||
| 377 | & OMAP_HDQ_INT_STATUS_RXCOMPLETE) | ||
| 378 | && time_before(jiffies, timeout)) { | ||
| 379 | schedule_timeout_uninterruptible(1); | ||
| 380 | } | ||
| 381 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, | ||
| 382 | OMAP_HDQ_CTRL_STATUS_DIR); | ||
| 383 | status = hdq_data->hdq_irqstatus; | ||
| 384 | /* check irqstatus */ | ||
| 385 | if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { | ||
| 386 | dev_dbg(hdq_data->dev, "timeout waiting for" | ||
| 387 | "RXCOMPLETE, %x", status); | ||
| 388 | ret = -ETIMEDOUT; | ||
| 389 | goto out; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | /* the data is ready. Read it in! */ | ||
| 393 | *val = hdq_reg_in(hdq_data, OMAP_HDQ_RX_DATA); | ||
| 394 | out: | ||
| 395 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 396 | rtn: | ||
| 397 | return 0; | ||
| 398 | |||
| 399 | } | ||
| 400 | |||
| 401 | /* Enable clocks and set the controller to HDQ mode */ | ||
| 402 | static int omap_hdq_get(struct hdq_data *hdq_data) | ||
| 403 | { | ||
| 404 | int ret = 0; | ||
| 405 | |||
| 406 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 407 | if (ret < 0) { | ||
| 408 | ret = -EINTR; | ||
| 409 | goto rtn; | ||
| 410 | } | ||
| 411 | |||
| 412 | if (OMAP_HDQ_MAX_USER == hdq_data->hdq_usecount) { | ||
| 413 | dev_dbg(hdq_data->dev, "attempt to exceed the max use count"); | ||
| 414 | ret = -EINVAL; | ||
| 415 | goto out; | ||
| 416 | } else { | ||
| 417 | hdq_data->hdq_usecount++; | ||
| 418 | try_module_get(THIS_MODULE); | ||
| 419 | if (1 == hdq_data->hdq_usecount) { | ||
| 420 | if (clk_enable(hdq_data->hdq_ick)) { | ||
| 421 | dev_dbg(hdq_data->dev, "Can not enable ick\n"); | ||
| 422 | ret = -ENODEV; | ||
| 423 | goto clk_err; | ||
| 424 | } | ||
| 425 | if (clk_enable(hdq_data->hdq_fck)) { | ||
| 426 | dev_dbg(hdq_data->dev, "Can not enable fck\n"); | ||
| 427 | clk_disable(hdq_data->hdq_ick); | ||
| 428 | ret = -ENODEV; | ||
| 429 | goto clk_err; | ||
| 430 | } | ||
| 431 | |||
| 432 | /* make sure HDQ is out of reset */ | ||
| 433 | if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) & | ||
| 434 | OMAP_HDQ_SYSSTATUS_RESETDONE)) { | ||
| 435 | ret = _omap_hdq_reset(hdq_data); | ||
| 436 | if (ret) | ||
| 437 | /* back up the count */ | ||
| 438 | hdq_data->hdq_usecount--; | ||
| 439 | } else { | ||
| 440 | /* select HDQ mode & enable clocks */ | ||
| 441 | hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
| 442 | OMAP_HDQ_CTRL_STATUS_CLOCKENABLE | | ||
| 443 | OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); | ||
| 444 | hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG, | ||
| 445 | OMAP_HDQ_SYSCONFIG_AUTOIDLE); | ||
| 446 | hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
| 447 | } | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 | clk_err: | ||
| 452 | clk_put(hdq_data->hdq_ick); | ||
| 453 | clk_put(hdq_data->hdq_fck); | ||
| 454 | out: | ||
| 455 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 456 | rtn: | ||
| 457 | return ret; | ||
| 458 | } | ||
| 459 | |||
| 460 | /* Disable clocks to the module */ | ||
| 461 | static int omap_hdq_put(struct hdq_data *hdq_data) | ||
| 462 | { | ||
| 463 | int ret = 0; | ||
| 464 | |||
| 465 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 466 | if (ret < 0) | ||
| 467 | return -EINTR; | ||
| 468 | |||
| 469 | if (0 == hdq_data->hdq_usecount) { | ||
| 470 | dev_dbg(hdq_data->dev, "attempt to decrement use count" | ||
| 471 | "when it is zero"); | ||
| 472 | ret = -EINVAL; | ||
| 473 | } else { | ||
| 474 | hdq_data->hdq_usecount--; | ||
| 475 | module_put(THIS_MODULE); | ||
| 476 | if (0 == hdq_data->hdq_usecount) { | ||
| 477 | clk_disable(hdq_data->hdq_ick); | ||
| 478 | clk_disable(hdq_data->hdq_fck); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 482 | |||
| 483 | return ret; | ||
| 484 | } | ||
| 485 | |||
| 486 | /* Read a byte of data from the device */ | ||
| 487 | static u8 omap_w1_read_byte(void *_hdq) | ||
| 488 | { | ||
| 489 | struct hdq_data *hdq_data = _hdq; | ||
| 490 | u8 val = 0; | ||
| 491 | int ret; | ||
| 492 | |||
| 493 | ret = hdq_read_byte(hdq_data, &val); | ||
| 494 | if (ret) { | ||
| 495 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 496 | if (ret < 0) { | ||
| 497 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
| 498 | return -EINTR; | ||
| 499 | } | ||
| 500 | hdq_data->init_trans = 0; | ||
| 501 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 502 | omap_hdq_put(hdq_data); | ||
| 503 | return -1; | ||
| 504 | } | ||
| 505 | |||
| 506 | /* Write followed by a read, release the module */ | ||
| 507 | if (hdq_data->init_trans) { | ||
| 508 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 509 | if (ret < 0) { | ||
| 510 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
| 511 | return -EINTR; | ||
| 512 | } | ||
| 513 | hdq_data->init_trans = 0; | ||
| 514 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 515 | omap_hdq_put(hdq_data); | ||
| 516 | } | ||
| 517 | |||
| 518 | return val; | ||
| 519 | } | ||
| 520 | |||
| 521 | /* Write a byte of data to the device */ | ||
| 522 | static void omap_w1_write_byte(void *_hdq, u8 byte) | ||
| 523 | { | ||
| 524 | struct hdq_data *hdq_data = _hdq; | ||
| 525 | int ret; | ||
| 526 | u8 status; | ||
| 527 | |||
| 528 | /* First write to initialize the transfer */ | ||
| 529 | if (hdq_data->init_trans == 0) | ||
| 530 | omap_hdq_get(hdq_data); | ||
| 531 | |||
| 532 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 533 | if (ret < 0) { | ||
| 534 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
| 535 | return; | ||
| 536 | } | ||
| 537 | hdq_data->init_trans++; | ||
| 538 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 539 | |||
| 540 | ret = hdq_write_byte(hdq_data, byte, &status); | ||
| 541 | if (ret == 0) { | ||
| 542 | dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); | ||
| 543 | return; | ||
| 544 | } | ||
| 545 | |||
| 546 | /* Second write, data transfered. Release the module */ | ||
| 547 | if (hdq_data->init_trans > 1) { | ||
| 548 | omap_hdq_put(hdq_data); | ||
| 549 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
| 550 | if (ret < 0) { | ||
| 551 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
| 552 | return; | ||
| 553 | } | ||
| 554 | hdq_data->init_trans = 0; | ||
| 555 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 556 | } | ||
| 557 | |||
| 558 | return; | ||
| 559 | } | ||
| 560 | |||
| 561 | static int __init omap_hdq_probe(struct platform_device *pdev) | ||
| 562 | { | ||
| 563 | struct hdq_data *hdq_data; | ||
| 564 | struct resource *res; | ||
| 565 | int ret, irq; | ||
| 566 | u8 rev; | ||
| 567 | |||
| 568 | hdq_data = kmalloc(sizeof(*hdq_data), GFP_KERNEL); | ||
| 569 | if (!hdq_data) { | ||
| 570 | dev_dbg(&pdev->dev, "unable to allocate memory\n"); | ||
| 571 | ret = -ENOMEM; | ||
| 572 | goto err_kmalloc; | ||
| 573 | } | ||
| 574 | |||
| 575 | hdq_data->dev = &pdev->dev; | ||
| 576 | platform_set_drvdata(pdev, hdq_data); | ||
| 577 | |||
| 578 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 579 | if (!res) { | ||
| 580 | dev_dbg(&pdev->dev, "unable to get resource\n"); | ||
| 581 | ret = -ENXIO; | ||
| 582 | goto err_resource; | ||
| 583 | } | ||
| 584 | |||
| 585 | hdq_data->hdq_base = ioremap(res->start, SZ_4K); | ||
| 586 | if (!hdq_data->hdq_base) { | ||
| 587 | dev_dbg(&pdev->dev, "ioremap failed\n"); | ||
| 588 | ret = -EINVAL; | ||
| 589 | goto err_ioremap; | ||
| 590 | } | ||
| 591 | |||
| 592 | /* get interface & functional clock objects */ | ||
| 593 | hdq_data->hdq_ick = clk_get(&pdev->dev, "hdq_ick"); | ||
| 594 | hdq_data->hdq_fck = clk_get(&pdev->dev, "hdq_fck"); | ||
| 595 | |||
| 596 | if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) { | ||
| 597 | dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n"); | ||
| 598 | if (IS_ERR(hdq_data->hdq_ick)) { | ||
| 599 | ret = PTR_ERR(hdq_data->hdq_ick); | ||
| 600 | goto err_clk; | ||
| 601 | } | ||
| 602 | if (IS_ERR(hdq_data->hdq_fck)) { | ||
| 603 | ret = PTR_ERR(hdq_data->hdq_fck); | ||
| 604 | clk_put(hdq_data->hdq_ick); | ||
| 605 | goto err_clk; | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 609 | hdq_data->hdq_usecount = 0; | ||
| 610 | mutex_init(&hdq_data->hdq_mutex); | ||
| 611 | |||
| 612 | if (clk_enable(hdq_data->hdq_ick)) { | ||
| 613 | dev_dbg(&pdev->dev, "Can not enable ick\n"); | ||
| 614 | ret = -ENODEV; | ||
| 615 | goto err_intfclk; | ||
| 616 | } | ||
| 617 | |||
| 618 | if (clk_enable(hdq_data->hdq_fck)) { | ||
| 619 | dev_dbg(&pdev->dev, "Can not enable fck\n"); | ||
| 620 | ret = -ENODEV; | ||
| 621 | goto err_fnclk; | ||
| 622 | } | ||
| 623 | |||
| 624 | rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION); | ||
| 625 | dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n", | ||
| 626 | (rev >> 4) + '0', (rev & 0x0f) + '0', "Interrupt"); | ||
| 627 | |||
| 628 | spin_lock_init(&hdq_data->hdq_spinlock); | ||
| 629 | |||
| 630 | irq = platform_get_irq(pdev, 0); | ||
| 631 | if (irq < 0) { | ||
| 632 | ret = -ENXIO; | ||
| 633 | goto err_irq; | ||
| 634 | } | ||
| 635 | |||
| 636 | ret = request_irq(irq, hdq_isr, IRQF_DISABLED, "omap_hdq", hdq_data); | ||
| 637 | if (ret < 0) { | ||
| 638 | dev_dbg(&pdev->dev, "could not request irq\n"); | ||
| 639 | goto err_irq; | ||
| 640 | } | ||
| 641 | |||
| 642 | omap_hdq_break(hdq_data); | ||
| 643 | |||
| 644 | /* don't clock the HDQ until it is needed */ | ||
| 645 | clk_disable(hdq_data->hdq_ick); | ||
| 646 | clk_disable(hdq_data->hdq_fck); | ||
| 647 | |||
| 648 | omap_w1_master.data = hdq_data; | ||
| 649 | |||
| 650 | ret = w1_add_master_device(&omap_w1_master); | ||
| 651 | if (ret) { | ||
| 652 | dev_dbg(&pdev->dev, "Failure in registering w1 master\n"); | ||
| 653 | goto err_w1; | ||
| 654 | } | ||
| 655 | |||
| 656 | return 0; | ||
| 657 | |||
| 658 | err_w1: | ||
| 659 | err_irq: | ||
| 660 | clk_disable(hdq_data->hdq_fck); | ||
| 661 | |||
| 662 | err_fnclk: | ||
| 663 | clk_disable(hdq_data->hdq_ick); | ||
| 664 | |||
| 665 | err_intfclk: | ||
| 666 | clk_put(hdq_data->hdq_ick); | ||
| 667 | clk_put(hdq_data->hdq_fck); | ||
| 668 | |||
| 669 | err_clk: | ||
| 670 | iounmap(hdq_data->hdq_base); | ||
| 671 | |||
| 672 | err_ioremap: | ||
| 673 | err_resource: | ||
| 674 | platform_set_drvdata(pdev, NULL); | ||
| 675 | kfree(hdq_data); | ||
| 676 | |||
| 677 | err_kmalloc: | ||
| 678 | return ret; | ||
| 679 | |||
| 680 | } | ||
| 681 | |||
| 682 | static int omap_hdq_remove(struct platform_device *pdev) | ||
| 683 | { | ||
| 684 | struct hdq_data *hdq_data = platform_get_drvdata(pdev); | ||
| 685 | |||
| 686 | mutex_lock(&hdq_data->hdq_mutex); | ||
| 687 | |||
| 688 | if (hdq_data->hdq_usecount) { | ||
| 689 | dev_dbg(&pdev->dev, "removed when use count is not zero\n"); | ||
| 690 | return -EBUSY; | ||
| 691 | } | ||
| 692 | |||
| 693 | mutex_unlock(&hdq_data->hdq_mutex); | ||
| 694 | |||
| 695 | /* remove module dependency */ | ||
| 696 | clk_put(hdq_data->hdq_ick); | ||
| 697 | clk_put(hdq_data->hdq_fck); | ||
| 698 | free_irq(INT_24XX_HDQ_IRQ, hdq_data); | ||
| 699 | platform_set_drvdata(pdev, NULL); | ||
| 700 | iounmap(hdq_data->hdq_base); | ||
| 701 | kfree(hdq_data); | ||
| 702 | |||
| 703 | return 0; | ||
| 704 | } | ||
| 705 | |||
| 706 | static int __init | ||
| 707 | omap_hdq_init(void) | ||
| 708 | { | ||
| 709 | return platform_driver_register(&omap_hdq_driver); | ||
| 710 | } | ||
| 711 | module_init(omap_hdq_init); | ||
| 712 | |||
| 713 | static void __exit | ||
| 714 | omap_hdq_exit(void) | ||
| 715 | { | ||
| 716 | platform_driver_unregister(&omap_hdq_driver); | ||
| 717 | } | ||
| 718 | module_exit(omap_hdq_exit); | ||
| 719 | |||
| 720 | module_param(w1_id, int, S_IRUSR); | ||
| 721 | MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection"); | ||
| 722 | |||
| 723 | MODULE_AUTHOR("Texas Instruments"); | ||
| 724 | MODULE_DESCRIPTION("HDQ driver Library"); | ||
| 725 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 3df29a122f84..8d0b1fb1e52e 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
| @@ -44,4 +44,11 @@ config W1_SLAVE_DS2760 | |||
| 44 | 44 | ||
| 45 | If you are unsure, say N. | 45 | If you are unsure, say N. |
| 46 | 46 | ||
| 47 | config W1_SLAVE_BQ27000 | ||
| 48 | tristate "BQ27000 slave support" | ||
| 49 | depends on W1 | ||
| 50 | help | ||
| 51 | Say Y here if you want to use a hdq | ||
| 52 | bq27000 slave support. | ||
| 53 | |||
| 47 | endmenu | 54 | endmenu |
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index a8eb7524df1d..990f400b6d22 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile | |||
| @@ -6,4 +6,4 @@ obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o | |||
| 6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o | 6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o |
| 7 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o | 7 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o |
| 8 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o | 8 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o |
| 9 | 9 | obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o | |
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c new file mode 100644 index 000000000000..8f4c91f6c680 --- /dev/null +++ b/drivers/w1/slaves/w1_bq27000.c | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | /* | ||
| 2 | * drivers/w1/slaves/w1_bq27000.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007 Texas Instruments, Inc. | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public License | ||
| 7 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 8 | * kind, whether express or implied. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/mutex.h> | ||
| 18 | |||
| 19 | #include "../w1.h" | ||
| 20 | #include "../w1_int.h" | ||
| 21 | #include "../w1_family.h" | ||
| 22 | |||
| 23 | #define HDQ_CMD_READ (0) | ||
| 24 | #define HDQ_CMD_WRITE (1<<7) | ||
| 25 | |||
| 26 | static int F_ID; | ||
| 27 | |||
| 28 | void w1_bq27000_write(struct device *dev, u8 buf, u8 reg) | ||
| 29 | { | ||
| 30 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | ||
| 31 | |||
| 32 | if (!dev) { | ||
| 33 | pr_info("Could not obtain slave dev ptr\n"); | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | |||
| 37 | w1_write_8(sl->master, HDQ_CMD_WRITE | reg); | ||
| 38 | w1_write_8(sl->master, buf); | ||
| 39 | } | ||
| 40 | EXPORT_SYMBOL(w1_bq27000_write); | ||
| 41 | |||
| 42 | int w1_bq27000_read(struct device *dev, u8 reg) | ||
| 43 | { | ||
| 44 | u8 val; | ||
| 45 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | ||
| 46 | |||
| 47 | if (!dev) | ||
| 48 | return 0; | ||
| 49 | |||
| 50 | w1_write_8(sl->master, HDQ_CMD_READ | reg); | ||
| 51 | val = w1_read_8(sl->master); | ||
| 52 | |||
| 53 | return val; | ||
| 54 | } | ||
| 55 | EXPORT_SYMBOL(w1_bq27000_read); | ||
| 56 | |||
| 57 | static int w1_bq27000_add_slave(struct w1_slave *sl) | ||
| 58 | { | ||
| 59 | int ret; | ||
| 60 | int id = 1; | ||
| 61 | struct platform_device *pdev; | ||
| 62 | |||
| 63 | pdev = platform_device_alloc("bq27000-battery", id); | ||
| 64 | if (!pdev) { | ||
| 65 | ret = -ENOMEM; | ||
| 66 | return ret; | ||
| 67 | } | ||
| 68 | pdev->dev.parent = &sl->dev; | ||
| 69 | |||
| 70 | ret = platform_device_add(pdev); | ||
| 71 | if (ret) | ||
| 72 | goto pdev_add_failed; | ||
| 73 | |||
| 74 | dev_set_drvdata(&sl->dev, pdev); | ||
| 75 | |||
| 76 | goto success; | ||
| 77 | |||
| 78 | pdev_add_failed: | ||
| 79 | platform_device_unregister(pdev); | ||
| 80 | success: | ||
| 81 | return ret; | ||
| 82 | } | ||
| 83 | |||
| 84 | static void w1_bq27000_remove_slave(struct w1_slave *sl) | ||
| 85 | { | ||
| 86 | struct platform_device *pdev = dev_get_drvdata(&sl->dev); | ||
| 87 | |||
| 88 | platform_device_unregister(pdev); | ||
| 89 | } | ||
| 90 | |||
| 91 | static struct w1_family_ops w1_bq27000_fops = { | ||
| 92 | .add_slave = w1_bq27000_add_slave, | ||
| 93 | .remove_slave = w1_bq27000_remove_slave, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static struct w1_family w1_bq27000_family = { | ||
| 97 | .fid = 1, | ||
| 98 | .fops = &w1_bq27000_fops, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static int __init w1_bq27000_init(void) | ||
| 102 | { | ||
| 103 | if (F_ID) | ||
| 104 | w1_bq27000_family.fid = F_ID; | ||
| 105 | |||
| 106 | return w1_register_family(&w1_bq27000_family); | ||
| 107 | } | ||
| 108 | |||
| 109 | static void __exit w1_bq27000_exit(void) | ||
| 110 | { | ||
| 111 | w1_unregister_family(&w1_bq27000_family); | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | module_init(w1_bq27000_init); | ||
| 116 | module_exit(w1_bq27000_exit); | ||
| 117 | |||
| 118 | module_param(F_ID, int, S_IRUSR); | ||
| 119 | MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); | ||
| 120 | |||
| 121 | MODULE_LICENSE("GPL"); | ||
| 122 | MODULE_AUTHOR("Texas Instruments Ltd"); | ||
| 123 | MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); | ||
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index cdaa6fffbfc7..97304bd83ec9 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h | |||
| @@ -206,6 +206,7 @@ void w1_slave_detach(struct w1_slave *sl); | |||
| 206 | 206 | ||
| 207 | u8 w1_triplet(struct w1_master *dev, int bdir); | 207 | u8 w1_triplet(struct w1_master *dev, int bdir); |
| 208 | void w1_write_8(struct w1_master *, u8); | 208 | void w1_write_8(struct w1_master *, u8); |
| 209 | u8 w1_read_8(struct w1_master *); | ||
| 209 | int w1_reset_bus(struct w1_master *); | 210 | int w1_reset_bus(struct w1_master *); |
| 210 | u8 w1_calc_crc8(u8 *, int); | 211 | u8 w1_calc_crc8(u8 *, int); |
| 211 | void w1_write_block(struct w1_master *, const u8 *, int); | 212 | void w1_write_block(struct w1_master *, const u8 *, int); |
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index f4f82f1f486e..0d15b0eaf79a 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c | |||
| @@ -217,7 +217,7 @@ u8 w1_triplet(struct w1_master *dev, int bdir) | |||
| 217 | * @param dev the master device | 217 | * @param dev the master device |
| 218 | * @return the byte read | 218 | * @return the byte read |
| 219 | */ | 219 | */ |
| 220 | static u8 w1_read_8(struct w1_master * dev) | 220 | u8 w1_read_8(struct w1_master *dev) |
| 221 | { | 221 | { |
| 222 | int i; | 222 | int i; |
| 223 | u8 res = 0; | 223 | u8 res = 0; |
| @@ -230,6 +230,7 @@ static u8 w1_read_8(struct w1_master * dev) | |||
| 230 | 230 | ||
| 231 | return res; | 231 | return res; |
| 232 | } | 232 | } |
| 233 | EXPORT_SYMBOL_GPL(w1_read_8); | ||
| 233 | 234 | ||
| 234 | /** | 235 | /** |
| 235 | * Writes a series of bytes. | 236 | * Writes a series of bytes. |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 1a22fe782a27..4fd3fa5546b1 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
| @@ -67,11 +67,11 @@ config AT91RM9200_WATCHDOG | |||
| 67 | system when the timeout is reached. | 67 | system when the timeout is reached. |
| 68 | 68 | ||
| 69 | config AT91SAM9X_WATCHDOG | 69 | config AT91SAM9X_WATCHDOG |
| 70 | tristate "AT91SAM9X watchdog" | 70 | tristate "AT91SAM9X / AT91CAP9 watchdog" |
| 71 | depends on WATCHDOG && (ARCH_AT91SAM9260 || ARCH_AT91SAM9261) | 71 | depends on ARCH_AT91 && !ARCH_AT91RM9200 |
| 72 | help | 72 | help |
| 73 | Watchdog timer embedded into AT91SAM9X chips. This will reboot your | 73 | Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will |
| 74 | system when the timeout is reached. | 74 | reboot your system when the timeout is reached. |
| 75 | 75 | ||
| 76 | config 21285_WATCHDOG | 76 | config 21285_WATCHDOG |
| 77 | tristate "DC21285 watchdog" | 77 | tristate "DC21285 watchdog" |
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index b4babfc31586..b1da287f90ec 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
| 31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
| 32 | 32 | ||
| 33 | #include <asm/arch/at91_wdt.h> | 33 | #include <mach/at91_wdt.h> |
| 34 | 34 | ||
| 35 | #define DRV_NAME "AT91SAM9 Watchdog" | 35 | #define DRV_NAME "AT91SAM9 Watchdog" |
| 36 | 36 | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index c3b78a76f173..225398fd5049 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
| @@ -42,8 +42,10 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; | |||
| 42 | 42 | ||
| 43 | #ifdef CONFIG_FSL_BOOKE | 43 | #ifdef CONFIG_FSL_BOOKE |
| 44 | #define WDTP(x) ((((63-x)&0x3)<<30)|(((63-x)&0x3c)<<15)) | 44 | #define WDTP(x) ((((63-x)&0x3)<<30)|(((63-x)&0x3c)<<15)) |
| 45 | #define WDTP_MASK (WDTP(0)) | ||
| 45 | #else | 46 | #else |
| 46 | #define WDTP(x) (TCR_WP(x)) | 47 | #define WDTP(x) (TCR_WP(x)) |
| 48 | #define WDTP_MASK (TCR_WP_MASK) | ||
| 47 | #endif | 49 | #endif |
| 48 | 50 | ||
| 49 | static DEFINE_SPINLOCK(booke_wdt_lock); | 51 | static DEFINE_SPINLOCK(booke_wdt_lock); |
| @@ -65,6 +67,7 @@ static void __booke_wdt_enable(void *data) | |||
| 65 | /* clear status before enabling watchdog */ | 67 | /* clear status before enabling watchdog */ |
| 66 | __booke_wdt_ping(NULL); | 68 | __booke_wdt_ping(NULL); |
| 67 | val = mfspr(SPRN_TCR); | 69 | val = mfspr(SPRN_TCR); |
| 70 | val &= ~WDTP_MASK; | ||
| 68 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); | 71 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); |
| 69 | 72 | ||
| 70 | mtspr(SPRN_TCR, val); | 73 | mtspr(SPRN_TCR, val); |
| @@ -114,7 +117,7 @@ static long booke_wdt_ioctl(struct file *file, | |||
| 114 | case WDIOC_SETTIMEOUT: | 117 | case WDIOC_SETTIMEOUT: |
| 115 | if (get_user(booke_wdt_period, p)) | 118 | if (get_user(booke_wdt_period, p)) |
| 116 | return -EFAULT; | 119 | return -EFAULT; |
| 117 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) | | 120 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP_MASK) | |
| 118 | WDTP(booke_wdt_period)); | 121 | WDTP(booke_wdt_period)); |
| 119 | return 0; | 122 | return 0; |
| 120 | case WDIOC_GETTIMEOUT: | 123 | case WDIOC_GETTIMEOUT: |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index a3765e0be4a8..763c1ea5dce5 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/bootmem.h> | 40 | #include <linux/bootmem.h> |
| 41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
| 42 | #include <asm/desc.h> | 42 | #include <asm/desc.h> |
| 43 | #include <asm/cacheflush.h> | ||
| 43 | 44 | ||
| 44 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ | 45 | #define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ |
| 45 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 | 46 | #define CRU_BIOS_SIGNATURE_VALUE 0x55524324 |
| @@ -394,6 +395,8 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm) | |||
| 394 | smbios_cru64_ptr->double_offset; | 395 | smbios_cru64_ptr->double_offset; |
| 395 | cru_rom_addr = ioremap(cru_physical_address, | 396 | cru_rom_addr = ioremap(cru_physical_address, |
| 396 | smbios_cru64_ptr->double_length); | 397 | smbios_cru64_ptr->double_length); |
| 398 | set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, | ||
| 399 | smbios_cru64_ptr->double_length >> PAGE_SHIFT); | ||
| 397 | } | 400 | } |
| 398 | } | 401 | } |
| 399 | } | 402 | } |
| @@ -482,7 +485,7 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, | |||
| 482 | "Management Log for details.\n"); | 485 | "Management Log for details.\n"); |
| 483 | } | 486 | } |
| 484 | 487 | ||
| 485 | return NOTIFY_STOP; | 488 | return NOTIFY_OK; |
| 486 | } | 489 | } |
| 487 | 490 | ||
| 488 | /* | 491 | /* |
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index ca344a85eb95..2474ebca88f6 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * intel TCO vendor specific watchdog driver support | 2 | * intel TCO vendor specific watchdog driver support |
| 3 | * | 3 | * |
| 4 | * (c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>. | 4 | * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -19,8 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | /* Module and version information */ | 20 | /* Module and version information */ |
| 21 | #define DRV_NAME "iTCO_vendor_support" | 21 | #define DRV_NAME "iTCO_vendor_support" |
| 22 | #define DRV_VERSION "1.01" | 22 | #define DRV_VERSION "1.02" |
| 23 | #define DRV_RELDATE "11-Nov-2006" | ||
| 24 | #define PFX DRV_NAME ": " | 23 | #define PFX DRV_NAME ": " |
| 25 | 24 | ||
| 26 | /* Includes */ | 25 | /* Includes */ |
| @@ -78,24 +77,6 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n | |||
| 78 | * 20.6 seconds. | 77 | * 20.6 seconds. |
| 79 | */ | 78 | */ |
| 80 | 79 | ||
| 81 | static void supermicro_old_pre_start(unsigned long acpibase) | ||
| 82 | { | ||
| 83 | unsigned long val32; | ||
| 84 | |||
| 85 | val32 = inl(SMI_EN); | ||
| 86 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ | ||
| 87 | outl(val32, SMI_EN); /* Needed to activate watchdog */ | ||
| 88 | } | ||
| 89 | |||
| 90 | static void supermicro_old_pre_stop(unsigned long acpibase) | ||
| 91 | { | ||
| 92 | unsigned long val32; | ||
| 93 | |||
| 94 | val32 = inl(SMI_EN); | ||
| 95 | val32 &= 0x00002000; /* Turn on SMI clearing watchdog */ | ||
| 96 | outl(val32, SMI_EN); /* Needed to deactivate watchdog */ | ||
| 97 | } | ||
| 98 | |||
| 99 | static void supermicro_old_pre_keepalive(unsigned long acpibase) | 80 | static void supermicro_old_pre_keepalive(unsigned long acpibase) |
| 100 | { | 81 | { |
| 101 | /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ | 82 | /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ |
| @@ -247,18 +228,14 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) | |||
| 247 | void iTCO_vendor_pre_start(unsigned long acpibase, | 228 | void iTCO_vendor_pre_start(unsigned long acpibase, |
| 248 | unsigned int heartbeat) | 229 | unsigned int heartbeat) |
| 249 | { | 230 | { |
| 250 | if (vendorsupport == SUPERMICRO_OLD_BOARD) | 231 | if (vendorsupport == SUPERMICRO_NEW_BOARD) |
| 251 | supermicro_old_pre_start(acpibase); | ||
| 252 | else if (vendorsupport == SUPERMICRO_NEW_BOARD) | ||
| 253 | supermicro_new_pre_start(heartbeat); | 232 | supermicro_new_pre_start(heartbeat); |
| 254 | } | 233 | } |
| 255 | EXPORT_SYMBOL(iTCO_vendor_pre_start); | 234 | EXPORT_SYMBOL(iTCO_vendor_pre_start); |
| 256 | 235 | ||
| 257 | void iTCO_vendor_pre_stop(unsigned long acpibase) | 236 | void iTCO_vendor_pre_stop(unsigned long acpibase) |
| 258 | { | 237 | { |
| 259 | if (vendorsupport == SUPERMICRO_OLD_BOARD) | 238 | if (vendorsupport == SUPERMICRO_NEW_BOARD) |
| 260 | supermicro_old_pre_stop(acpibase); | ||
| 261 | else if (vendorsupport == SUPERMICRO_NEW_BOARD) | ||
| 262 | supermicro_new_pre_stop(); | 239 | supermicro_new_pre_stop(); |
| 263 | } | 240 | } |
| 264 | EXPORT_SYMBOL(iTCO_vendor_pre_stop); | 241 | EXPORT_SYMBOL(iTCO_vendor_pre_stop); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index bfb93bc2ca9f..5b395a4ddfdf 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) | 2 | * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) |
| 3 | * | 3 | * |
| 4 | * (c) Copyright 2006-2007 Wim Van Sebroeck <wim@iguana.be>. | 4 | * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -20,34 +20,41 @@ | |||
| 20 | * 82801BAM (ICH2-M) : document number 290687-002, 298242-027, | 20 | * 82801BAM (ICH2-M) : document number 290687-002, 298242-027, |
| 21 | * 82801CA (ICH3-S) : document number 290733-003, 290739-013, | 21 | * 82801CA (ICH3-S) : document number 290733-003, 290739-013, |
| 22 | * 82801CAM (ICH3-M) : document number 290716-001, 290718-007, | 22 | * 82801CAM (ICH3-M) : document number 290716-001, 290718-007, |
| 23 | * 82801DB (ICH4) : document number 290744-001, 290745-020, | 23 | * 82801DB (ICH4) : document number 290744-001, 290745-025, |
| 24 | * 82801DBM (ICH4-M) : document number 252337-001, 252663-005, | 24 | * 82801DBM (ICH4-M) : document number 252337-001, 252663-008, |
| 25 | * 82801E (C-ICH) : document number 273599-001, 273645-002, | 25 | * 82801E (C-ICH) : document number 273599-001, 273645-002, |
| 26 | * 82801EB (ICH5) : document number 252516-001, 252517-003, | 26 | * 82801EB (ICH5) : document number 252516-001, 252517-028, |
| 27 | * 82801ER (ICH5R) : document number 252516-001, 252517-003, | 27 | * 82801ER (ICH5R) : document number 252516-001, 252517-028, |
| 28 | * 82801FB (ICH6) : document number 301473-002, 301474-007, | 28 | * 6300ESB (6300ESB) : document number 300641-004, 300884-013, |
| 29 | * 82801FR (ICH6R) : document number 301473-002, 301474-007, | 29 | * 82801FB (ICH6) : document number 301473-002, 301474-026, |
| 30 | * 82801FBM (ICH6-M) : document number 301473-002, 301474-007, | 30 | * 82801FR (ICH6R) : document number 301473-002, 301474-026, |
| 31 | * 82801FW (ICH6W) : document number 301473-001, 301474-007, | 31 | * 82801FBM (ICH6-M) : document number 301473-002, 301474-026, |
| 32 | * 82801FRW (ICH6RW) : document number 301473-001, 301474-007, | 32 | * 82801FW (ICH6W) : document number 301473-001, 301474-026, |
| 33 | * 82801GB (ICH7) : document number 307013-002, 307014-009, | 33 | * 82801FRW (ICH6RW) : document number 301473-001, 301474-026, |
| 34 | * 82801GR (ICH7R) : document number 307013-002, 307014-009, | 34 | * 631xESB (631xESB) : document number 313082-001, 313075-006, |
| 35 | * 82801GDH (ICH7DH) : document number 307013-002, 307014-009, | 35 | * 632xESB (632xESB) : document number 313082-001, 313075-006, |
| 36 | * 82801GBM (ICH7-M) : document number 307013-002, 307014-009, | 36 | * 82801GB (ICH7) : document number 307013-003, 307014-024, |
| 37 | * 82801GHM (ICH7-M DH) : document number 307013-002, 307014-009, | 37 | * 82801GR (ICH7R) : document number 307013-003, 307014-024, |
| 38 | * 82801HB (ICH8) : document number 313056-003, 313057-009, | 38 | * 82801GDH (ICH7DH) : document number 307013-003, 307014-024, |
| 39 | * 82801HR (ICH8R) : document number 313056-003, 313057-009, | 39 | * 82801GBM (ICH7-M) : document number 307013-003, 307014-024, |
| 40 | * 82801HBM (ICH8M) : document number 313056-003, 313057-009, | 40 | * 82801GHM (ICH7-M DH) : document number 307013-003, 307014-024, |
| 41 | * 82801HH (ICH8DH) : document number 313056-003, 313057-009, | 41 | * 82801GU (ICH7-U) : document number 307013-003, 307014-024, |
| 42 | * 82801HO (ICH8DO) : document number 313056-003, 313057-009, | 42 | * 82801HB (ICH8) : document number 313056-003, 313057-017, |
| 43 | * 82801HEM (ICH8M-E) : document number 313056-003, 313057-009, | 43 | * 82801HR (ICH8R) : document number 313056-003, 313057-017, |
| 44 | * 82801IB (ICH9) : document number 316972-001, 316973-006, | 44 | * 82801HBM (ICH8M) : document number 313056-003, 313057-017, |
| 45 | * 82801IR (ICH9R) : document number 316972-001, 316973-006, | 45 | * 82801HH (ICH8DH) : document number 313056-003, 313057-017, |
| 46 | * 82801IH (ICH9DH) : document number 316972-001, 316973-006, | 46 | * 82801HO (ICH8DO) : document number 313056-003, 313057-017, |
| 47 | * 82801IO (ICH9DO) : document number 316972-001, 316973-006, | 47 | * 82801HEM (ICH8M-E) : document number 313056-003, 313057-017, |
| 48 | * 6300ESB (6300ESB) : document number 300641-003, 300884-010, | 48 | * 82801IB (ICH9) : document number 316972-004, 316973-012, |
| 49 | * 631xESB (631xESB) : document number 313082-001, 313075-005, | 49 | * 82801IR (ICH9R) : document number 316972-004, 316973-012, |
| 50 | * 632xESB (632xESB) : document number 313082-001, 313075-005 | 50 | * 82801IH (ICH9DH) : document number 316972-004, 316973-012, |
| 51 | * 82801IO (ICH9DO) : document number 316972-004, 316973-012, | ||
| 52 | * 82801IBM (ICH9M) : document number 316972-004, 316973-012, | ||
| 53 | * 82801IEM (ICH9M-E) : document number 316972-004, 316973-012, | ||
| 54 | * 82801JIB (ICH10) : document number 319973-002, 319974-002, | ||
| 55 | * 82801JIR (ICH10R) : document number 319973-002, 319974-002, | ||
| 56 | * 82801JD (ICH10D) : document number 319973-002, 319974-002, | ||
| 57 | * 82801JDO (ICH10DO) : document number 319973-002, 319974-002 | ||
| 51 | */ | 58 | */ |
| 52 | 59 | ||
| 53 | /* | 60 | /* |
| @@ -56,8 +63,7 @@ | |||
| 56 | 63 | ||
| 57 | /* Module and version information */ | 64 | /* Module and version information */ |
| 58 | #define DRV_NAME "iTCO_wdt" | 65 | #define DRV_NAME "iTCO_wdt" |
| 59 | #define DRV_VERSION "1.03" | 66 | #define DRV_VERSION "1.04" |
| 60 | #define DRV_RELDATE "30-Apr-2008" | ||
| 61 | #define PFX DRV_NAME ": " | 67 | #define PFX DRV_NAME ": " |
| 62 | 68 | ||
| 63 | /* Includes */ | 69 | /* Includes */ |
| @@ -96,19 +102,26 @@ enum iTCO_chipsets { | |||
| 96 | TCO_ICH6, /* ICH6 & ICH6R */ | 102 | TCO_ICH6, /* ICH6 & ICH6R */ |
| 97 | TCO_ICH6M, /* ICH6-M */ | 103 | TCO_ICH6M, /* ICH6-M */ |
| 98 | TCO_ICH6W, /* ICH6W & ICH6RW */ | 104 | TCO_ICH6W, /* ICH6W & ICH6RW */ |
| 105 | TCO_631XESB, /* 631xESB/632xESB */ | ||
| 99 | TCO_ICH7, /* ICH7 & ICH7R */ | 106 | TCO_ICH7, /* ICH7 & ICH7R */ |
| 100 | TCO_ICH7M, /* ICH7-M */ | 107 | TCO_ICH7DH, /* ICH7DH */ |
| 108 | TCO_ICH7M, /* ICH7-M & ICH7-U */ | ||
| 101 | TCO_ICH7MDH, /* ICH7-M DH */ | 109 | TCO_ICH7MDH, /* ICH7-M DH */ |
| 102 | TCO_ICH8, /* ICH8 & ICH8R */ | 110 | TCO_ICH8, /* ICH8 & ICH8R */ |
| 103 | TCO_ICH8ME, /* ICH8M-E */ | ||
| 104 | TCO_ICH8DH, /* ICH8DH */ | 111 | TCO_ICH8DH, /* ICH8DH */ |
| 105 | TCO_ICH8DO, /* ICH8DO */ | 112 | TCO_ICH8DO, /* ICH8DO */ |
| 106 | TCO_ICH8M, /* ICH8M */ | 113 | TCO_ICH8M, /* ICH8M */ |
| 114 | TCO_ICH8ME, /* ICH8M-E */ | ||
| 107 | TCO_ICH9, /* ICH9 */ | 115 | TCO_ICH9, /* ICH9 */ |
| 108 | TCO_ICH9R, /* ICH9R */ | 116 | TCO_ICH9R, /* ICH9R */ |
| 109 | TCO_ICH9DH, /* ICH9DH */ | 117 | TCO_ICH9DH, /* ICH9DH */ |
| 110 | TCO_ICH9DO, /* ICH9DO */ | 118 | TCO_ICH9DO, /* ICH9DO */ |
| 111 | TCO_631XESB, /* 631xESB/632xESB */ | 119 | TCO_ICH9M, /* ICH9M */ |
| 120 | TCO_ICH9ME, /* ICH9M-E */ | ||
| 121 | TCO_ICH10, /* ICH10 */ | ||
| 122 | TCO_ICH10R, /* ICH10R */ | ||
| 123 | TCO_ICH10D, /* ICH10D */ | ||
| 124 | TCO_ICH10DO, /* ICH10DO */ | ||
| 112 | }; | 125 | }; |
| 113 | 126 | ||
| 114 | static struct { | 127 | static struct { |
| @@ -129,19 +142,26 @@ static struct { | |||
| 129 | {"ICH6 or ICH6R", 2}, | 142 | {"ICH6 or ICH6R", 2}, |
| 130 | {"ICH6-M", 2}, | 143 | {"ICH6-M", 2}, |
| 131 | {"ICH6W or ICH6RW", 2}, | 144 | {"ICH6W or ICH6RW", 2}, |
| 145 | {"631xESB/632xESB", 2}, | ||
| 132 | {"ICH7 or ICH7R", 2}, | 146 | {"ICH7 or ICH7R", 2}, |
| 133 | {"ICH7-M", 2}, | 147 | {"ICH7DH", 2}, |
| 148 | {"ICH7-M or ICH7-U", 2}, | ||
| 134 | {"ICH7-M DH", 2}, | 149 | {"ICH7-M DH", 2}, |
| 135 | {"ICH8 or ICH8R", 2}, | 150 | {"ICH8 or ICH8R", 2}, |
| 136 | {"ICH8M-E", 2}, | ||
| 137 | {"ICH8DH", 2}, | 151 | {"ICH8DH", 2}, |
| 138 | {"ICH8DO", 2}, | 152 | {"ICH8DO", 2}, |
| 139 | {"ICH8M", 2}, | 153 | {"ICH8M", 2}, |
| 154 | {"ICH8M-E", 2}, | ||
| 140 | {"ICH9", 2}, | 155 | {"ICH9", 2}, |
| 141 | {"ICH9R", 2}, | 156 | {"ICH9R", 2}, |
| 142 | {"ICH9DH", 2}, | 157 | {"ICH9DH", 2}, |
| 143 | {"ICH9DO", 2}, | 158 | {"ICH9DO", 2}, |
| 144 | {"631xESB/632xESB", 2}, | 159 | {"ICH9M", 2}, |
| 160 | {"ICH9M-E", 2}, | ||
| 161 | {"ICH10", 2}, | ||
| 162 | {"ICH10R", 2}, | ||
| 163 | {"ICH10D", 2}, | ||
| 164 | {"ICH10DO", 2}, | ||
| 145 | {NULL, 0} | 165 | {NULL, 0} |
| 146 | }; | 166 | }; |
| 147 | 167 | ||
| @@ -175,18 +195,6 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
| 175 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)}, | 195 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)}, |
| 176 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)}, | 196 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)}, |
| 177 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)}, | 197 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)}, |
| 178 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)}, | ||
| 179 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, | ||
| 180 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, | ||
| 181 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, | ||
| 182 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)}, | ||
| 183 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, | ||
| 184 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, | ||
| 185 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)}, | ||
| 186 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)}, | ||
| 187 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)}, | ||
| 188 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)}, | ||
| 189 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)}, | ||
| 190 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, | 198 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, |
| 191 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, | 199 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, |
| 192 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, | 200 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, |
| @@ -203,6 +211,25 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
| 203 | { ITCO_PCI_DEVICE(0x267d, TCO_631XESB)}, | 211 | { ITCO_PCI_DEVICE(0x267d, TCO_631XESB)}, |
| 204 | { ITCO_PCI_DEVICE(0x267e, TCO_631XESB)}, | 212 | { ITCO_PCI_DEVICE(0x267e, TCO_631XESB)}, |
| 205 | { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, | 213 | { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, |
| 214 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)}, | ||
| 215 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_30, TCO_ICH7DH)}, | ||
| 216 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, | ||
| 217 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, | ||
| 218 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, | ||
| 219 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, | ||
| 220 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, | ||
| 221 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)}, | ||
| 222 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)}, | ||
| 223 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)}, | ||
| 224 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)}, | ||
| 225 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)}, | ||
| 226 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)}, | ||
| 227 | { ITCO_PCI_DEVICE(0x2919, TCO_ICH9M)}, | ||
| 228 | { ITCO_PCI_DEVICE(0x2917, TCO_ICH9ME)}, | ||
| 229 | { ITCO_PCI_DEVICE(0x3a18, TCO_ICH10)}, | ||
| 230 | { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)}, | ||
| 231 | { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)}, | ||
| 232 | { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, | ||
| 206 | { 0, }, /* End of list */ | 233 | { 0, }, /* End of list */ |
| 207 | }; | 234 | }; |
| 208 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 235 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
| @@ -311,6 +338,7 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) | |||
| 311 | static int iTCO_wdt_start(void) | 338 | static int iTCO_wdt_start(void) |
| 312 | { | 339 | { |
| 313 | unsigned int val; | 340 | unsigned int val; |
| 341 | unsigned long val32; | ||
| 314 | 342 | ||
| 315 | spin_lock(&iTCO_wdt_private.io_lock); | 343 | spin_lock(&iTCO_wdt_private.io_lock); |
| 316 | 344 | ||
| @@ -323,6 +351,18 @@ static int iTCO_wdt_start(void) | |||
| 323 | return -EIO; | 351 | return -EIO; |
| 324 | } | 352 | } |
| 325 | 353 | ||
| 354 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ | ||
| 355 | val32 = inl(SMI_EN); | ||
| 356 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ | ||
| 357 | outl(val32, SMI_EN); | ||
| 358 | |||
| 359 | /* Force the timer to its reload value by writing to the TCO_RLD | ||
| 360 | register */ | ||
| 361 | if (iTCO_wdt_private.iTCO_version == 2) | ||
| 362 | outw(0x01, TCO_RLD); | ||
| 363 | else if (iTCO_wdt_private.iTCO_version == 1) | ||
| 364 | outb(0x01, TCO_RLD); | ||
| 365 | |||
| 326 | /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */ | 366 | /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */ |
| 327 | val = inw(TCO1_CNT); | 367 | val = inw(TCO1_CNT); |
| 328 | val &= 0xf7ff; | 368 | val &= 0xf7ff; |
| @@ -338,6 +378,7 @@ static int iTCO_wdt_start(void) | |||
| 338 | static int iTCO_wdt_stop(void) | 378 | static int iTCO_wdt_stop(void) |
| 339 | { | 379 | { |
| 340 | unsigned int val; | 380 | unsigned int val; |
| 381 | unsigned long val32; | ||
| 341 | 382 | ||
| 342 | spin_lock(&iTCO_wdt_private.io_lock); | 383 | spin_lock(&iTCO_wdt_private.io_lock); |
| 343 | 384 | ||
| @@ -349,6 +390,11 @@ static int iTCO_wdt_stop(void) | |||
| 349 | outw(val, TCO1_CNT); | 390 | outw(val, TCO1_CNT); |
| 350 | val = inw(TCO1_CNT); | 391 | val = inw(TCO1_CNT); |
| 351 | 392 | ||
| 393 | /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ | ||
| 394 | val32 = inl(SMI_EN); | ||
| 395 | val32 |= 0x00002000; | ||
| 396 | outl(val32, SMI_EN); | ||
| 397 | |||
| 352 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | 398 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ |
| 353 | iTCO_wdt_set_NO_REBOOT_bit(); | 399 | iTCO_wdt_set_NO_REBOOT_bit(); |
| 354 | 400 | ||
| @@ -459,7 +505,6 @@ static int iTCO_wdt_open(struct inode *inode, struct file *file) | |||
| 459 | /* | 505 | /* |
| 460 | * Reload and activate timer | 506 | * Reload and activate timer |
| 461 | */ | 507 | */ |
| 462 | iTCO_wdt_keepalive(); | ||
| 463 | iTCO_wdt_start(); | 508 | iTCO_wdt_start(); |
| 464 | return nonseekable_open(inode, file); | 509 | return nonseekable_open(inode, file); |
| 465 | } | 510 | } |
| @@ -604,7 +649,6 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 604 | int ret; | 649 | int ret; |
| 605 | u32 base_address; | 650 | u32 base_address; |
| 606 | unsigned long RCBA; | 651 | unsigned long RCBA; |
| 607 | unsigned long val32; | ||
| 608 | 652 | ||
| 609 | /* | 653 | /* |
| 610 | * Find the ACPI/PM base I/O address which is the base | 654 | * Find the ACPI/PM base I/O address which is the base |
| @@ -644,17 +688,13 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 644 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | 688 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ |
| 645 | iTCO_wdt_set_NO_REBOOT_bit(); | 689 | iTCO_wdt_set_NO_REBOOT_bit(); |
| 646 | 690 | ||
| 647 | /* Set the TCO_EN bit in SMI_EN register */ | 691 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ |
| 648 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { | 692 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { |
| 649 | printk(KERN_ERR PFX | 693 | printk(KERN_ERR PFX |
| 650 | "I/O address 0x%04lx already in use\n", SMI_EN); | 694 | "I/O address 0x%04lx already in use\n", SMI_EN); |
| 651 | ret = -EIO; | 695 | ret = -EIO; |
| 652 | goto out; | 696 | goto out; |
| 653 | } | 697 | } |
| 654 | val32 = inl(SMI_EN); | ||
| 655 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ | ||
| 656 | outl(val32, SMI_EN); | ||
| 657 | release_region(SMI_EN, 4); | ||
| 658 | 698 | ||
| 659 | /* The TCO I/O registers reside in a 32-byte range pointed to | 699 | /* The TCO I/O registers reside in a 32-byte range pointed to |
| 660 | by the TCOBASE value */ | 700 | by the TCOBASE value */ |
| @@ -662,7 +702,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 662 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", | 702 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", |
| 663 | TCOBASE); | 703 | TCOBASE); |
| 664 | ret = -EIO; | 704 | ret = -EIO; |
| 665 | goto out; | 705 | goto unreg_smi_en; |
| 666 | } | 706 | } |
| 667 | 707 | ||
| 668 | printk(KERN_INFO PFX | 708 | printk(KERN_INFO PFX |
| @@ -672,8 +712,9 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 672 | TCOBASE); | 712 | TCOBASE); |
| 673 | 713 | ||
| 674 | /* Clear out the (probably old) status */ | 714 | /* Clear out the (probably old) status */ |
| 675 | outb(0, TCO1_STS); | 715 | outb(8, TCO1_STS); /* Clear the Time Out Status bit */ |
| 676 | outb(3, TCO2_STS); | 716 | outb(2, TCO2_STS); /* Clear SECOND_TO_STS bit */ |
| 717 | outb(4, TCO2_STS); /* Clear BOOT_STS bit */ | ||
| 677 | 718 | ||
| 678 | /* Make sure the watchdog is not running */ | 719 | /* Make sure the watchdog is not running */ |
| 679 | iTCO_wdt_stop(); | 720 | iTCO_wdt_stop(); |
| @@ -701,6 +742,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 701 | 742 | ||
| 702 | unreg_region: | 743 | unreg_region: |
| 703 | release_region(TCOBASE, 0x20); | 744 | release_region(TCOBASE, 0x20); |
| 745 | unreg_smi_en: | ||
| 746 | release_region(SMI_EN, 4); | ||
| 704 | out: | 747 | out: |
| 705 | if (iTCO_wdt_private.iTCO_version == 2) | 748 | if (iTCO_wdt_private.iTCO_version == 2) |
| 706 | iounmap(iTCO_wdt_private.gcs); | 749 | iounmap(iTCO_wdt_private.gcs); |
| @@ -718,6 +761,7 @@ static void __devexit iTCO_wdt_cleanup(void) | |||
| 718 | /* Deregister */ | 761 | /* Deregister */ |
| 719 | misc_deregister(&iTCO_wdt_miscdev); | 762 | misc_deregister(&iTCO_wdt_miscdev); |
| 720 | release_region(TCOBASE, 0x20); | 763 | release_region(TCOBASE, 0x20); |
| 764 | release_region(SMI_EN, 4); | ||
| 721 | if (iTCO_wdt_private.iTCO_version == 2) | 765 | if (iTCO_wdt_private.iTCO_version == 2) |
| 722 | iounmap(iTCO_wdt_private.gcs); | 766 | iounmap(iTCO_wdt_private.gcs); |
| 723 | pci_dev_put(iTCO_wdt_private.pdev); | 767 | pci_dev_put(iTCO_wdt_private.pdev); |
| @@ -782,8 +826,8 @@ static int __init iTCO_wdt_init_module(void) | |||
| 782 | { | 826 | { |
| 783 | int err; | 827 | int err; |
| 784 | 828 | ||
| 785 | printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s (%s)\n", | 829 | printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s\n", |
| 786 | DRV_VERSION, DRV_RELDATE); | 830 | DRV_VERSION); |
| 787 | 831 | ||
| 788 | err = platform_driver_register(&iTCO_wdt_driver); | 832 | err = platform_driver_register(&iTCO_wdt_driver); |
| 789 | if (err) | 833 | if (err) |
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index b4b7b0a4c119..3acce623f209 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c | |||
| @@ -98,6 +98,8 @@ static void mtx1_wdt_reset(void) | |||
| 98 | 98 | ||
| 99 | static void mtx1_wdt_start(void) | 99 | static void mtx1_wdt_start(void) |
| 100 | { | 100 | { |
| 101 | unsigned long flags; | ||
| 102 | |||
| 101 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | 103 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); |
| 102 | if (!mtx1_wdt_device.queue) { | 104 | if (!mtx1_wdt_device.queue) { |
| 103 | mtx1_wdt_device.queue = 1; | 105 | mtx1_wdt_device.queue = 1; |
| @@ -110,6 +112,8 @@ static void mtx1_wdt_start(void) | |||
| 110 | 112 | ||
| 111 | static int mtx1_wdt_stop(void) | 113 | static int mtx1_wdt_stop(void) |
| 112 | { | 114 | { |
| 115 | unsigned long flags; | ||
| 116 | |||
| 113 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); | 117 | spin_lock_irqsave(&mtx1_wdt_device.lock, flags); |
| 114 | if (mtx1_wdt_device.queue) { | 118 | if (mtx1_wdt_device.queue) { |
| 115 | mtx1_wdt_device.queue = 0; | 119 | mtx1_wdt_device.queue = 0; |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 8c83abc73400..526c191e84ea 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <linux/pagemap.h> | 41 | #include <linux/pagemap.h> |
| 42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
| 43 | #include <linux/mutex.h> | 43 | #include <linux/mutex.h> |
| 44 | #include <linux/highmem.h> | ||
| 45 | #include <linux/list.h> | 44 | #include <linux/list.h> |
| 46 | #include <linux/sysdev.h> | 45 | #include <linux/sysdev.h> |
| 47 | 46 | ||
| @@ -123,14 +122,7 @@ static struct timer_list balloon_timer; | |||
| 123 | static void scrub_page(struct page *page) | 122 | static void scrub_page(struct page *page) |
| 124 | { | 123 | { |
| 125 | #ifdef CONFIG_XEN_SCRUB_PAGES | 124 | #ifdef CONFIG_XEN_SCRUB_PAGES |
| 126 | if (PageHighMem(page)) { | 125 | clear_highpage(page); |
| 127 | void *v = kmap(page); | ||
| 128 | clear_page(v); | ||
| 129 | kunmap(v); | ||
| 130 | } else { | ||
| 131 | void *v = page_address(page); | ||
| 132 | clear_page(v); | ||
| 133 | } | ||
| 134 | #endif | 126 | #endif |
| 135 | } | 127 | } |
| 136 | 128 | ||
