diff options
29 files changed, 487 insertions, 366 deletions
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 71f55bbcefc8..615142da4ef6 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 | |||
| @@ -38,9 +38,10 @@ Module Parameters | |||
| 38 | Disable selected features normally supported by the device. This makes it | 38 | Disable selected features normally supported by the device. This makes it |
| 39 | possible to work around possible driver or hardware bugs if the feature in | 39 | possible to work around possible driver or hardware bugs if the feature in |
| 40 | question doesn't work as intended for whatever reason. Bit values: | 40 | question doesn't work as intended for whatever reason. Bit values: |
| 41 | 1 disable SMBus PEC | 41 | 0x01 disable SMBus PEC |
| 42 | 2 disable the block buffer | 42 | 0x02 disable the block buffer |
| 43 | 8 disable the I2C block read functionality | 43 | 0x08 disable the I2C block read functionality |
| 44 | 0x10 don't use interrupts | ||
| 44 | 45 | ||
| 45 | 46 | ||
| 46 | Description | 47 | Description |
| @@ -86,6 +87,12 @@ SMBus 2.0 Support | |||
| 86 | The 82801DB (ICH4) and later chips support several SMBus 2.0 features. | 87 | The 82801DB (ICH4) and later chips support several SMBus 2.0 features. |
| 87 | 88 | ||
| 88 | 89 | ||
| 90 | Interrupt Support | ||
| 91 | ----------------- | ||
| 92 | |||
| 93 | PCI interrupt support is supported on the 82801EB (ICH5) and later chips. | ||
| 94 | |||
| 95 | |||
| 89 | Hidden ICH SMBus | 96 | Hidden ICH SMBus |
| 90 | ---------------- | 97 | ---------------- |
| 91 | 98 | ||
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4 index 475bb4ae0720..1e6634f54c50 100644 --- a/Documentation/i2c/busses/i2c-piix4 +++ b/Documentation/i2c/busses/i2c-piix4 | |||
| @@ -8,6 +8,11 @@ Supported adapters: | |||
| 8 | Datasheet: Only available via NDA from ServerWorks | 8 | Datasheet: Only available via NDA from ServerWorks |
| 9 | * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges | 9 | * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges |
| 10 | Datasheet: Not publicly available | 10 | Datasheet: Not publicly available |
| 11 | SB700 register reference available at: | ||
| 12 | http://support.amd.com/us/Embedded_TechDocs/43009_sb7xx_rrg_pub_1.00.pdf | ||
| 13 | * AMD SP5100 (SB700 derivative found on some server mainboards) | ||
| 14 | Datasheet: Publicly available at the AMD website | ||
| 15 | http://support.amd.com/us/Embedded_TechDocs/44413.pdf | ||
| 11 | * AMD Hudson-2 | 16 | * AMD Hudson-2 |
| 12 | Datasheet: Not publicly available | 17 | Datasheet: Not publicly available |
| 13 | * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge | 18 | * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge |
| @@ -68,6 +73,10 @@ this driver on those mainboards. | |||
| 68 | The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are | 73 | The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are |
| 69 | identical to the PIIX4 in I2C/SMBus support. | 74 | identical to the PIIX4 in I2C/SMBus support. |
| 70 | 75 | ||
| 76 | The AMD SB700 and SP5100 chipsets implement two PIIX4-compatible SMBus | ||
| 77 | controllers. If your BIOS initializes the secondary controller, it will | ||
| 78 | be detected by this driver as an "Auxiliary SMBus Host Controller". | ||
| 79 | |||
| 71 | If you own Force CPCI735 motherboard or other OSB4 based systems you may need | 80 | If you own Force CPCI735 motherboard or other OSB4 based systems you may need |
| 72 | to change the SMBus Interrupt Select register so the SMBus controller uses | 81 | to change the SMBus Interrupt Select register so the SMBus controller uses |
| 73 | the SMI mode. | 82 | the SMI mode. |
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 5aa53374ea2a..3a94b0e6f601 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients | |||
| @@ -245,21 +245,17 @@ static int __init foo_init(void) | |||
| 245 | { | 245 | { |
| 246 | return i2c_add_driver(&foo_driver); | 246 | return i2c_add_driver(&foo_driver); |
| 247 | } | 247 | } |
| 248 | module_init(foo_init); | ||
| 248 | 249 | ||
| 249 | static void __exit foo_cleanup(void) | 250 | static void __exit foo_cleanup(void) |
| 250 | { | 251 | { |
| 251 | i2c_del_driver(&foo_driver); | 252 | i2c_del_driver(&foo_driver); |
| 252 | } | 253 | } |
| 254 | module_exit(foo_cleanup); | ||
| 253 | 255 | ||
| 254 | /* Substitute your own name and email address */ | 256 | The module_i2c_driver() macro can be used to reduce above code. |
| 255 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>" | ||
| 256 | MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices"); | ||
| 257 | |||
| 258 | /* a few non-GPL license types are also allowed */ | ||
| 259 | MODULE_LICENSE("GPL"); | ||
| 260 | 257 | ||
| 261 | module_init(foo_init); | 258 | module_i2c_driver(foo_driver); |
| 262 | module_exit(foo_cleanup); | ||
| 263 | 259 | ||
| 264 | Note that some functions are marked by `__init'. These functions can | 260 | Note that some functions are marked by `__init'. These functions can |
| 265 | be removed after kernel booting (or module loading) is completed. | 261 | be removed after kernel booting (or module loading) is completed. |
| @@ -267,6 +263,17 @@ Likewise, functions marked by `__exit' are dropped by the compiler when | |||
| 267 | the code is built into the kernel, as they would never be called. | 263 | the code is built into the kernel, as they would never be called. |
| 268 | 264 | ||
| 269 | 265 | ||
| 266 | Driver Information | ||
| 267 | ================== | ||
| 268 | |||
| 269 | /* Substitute your own name and email address */ | ||
| 270 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>" | ||
| 271 | MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices"); | ||
| 272 | |||
| 273 | /* a few non-GPL license types are also allowed */ | ||
| 274 | MODULE_LICENSE("GPL"); | ||
| 275 | |||
| 276 | |||
| 270 | Power Management | 277 | Power Management |
| 271 | ================ | 278 | ================ |
| 272 | 279 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7244c8be6063..2e7530a4e7b8 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -133,7 +133,7 @@ config I2C_PIIX4 | |||
| 133 | ATI IXP300 | 133 | ATI IXP300 |
| 134 | ATI IXP400 | 134 | ATI IXP400 |
| 135 | ATI SB600 | 135 | ATI SB600 |
| 136 | ATI SB700 | 136 | ATI SB700/SP5100 |
| 137 | ATI SB800 | 137 | ATI SB800 |
| 138 | AMD Hudson-2 | 138 | AMD Hudson-2 |
| 139 | Serverworks OSB4 | 139 | Serverworks OSB4 |
| @@ -143,6 +143,10 @@ config I2C_PIIX4 | |||
| 143 | Serverworks HT-1100 | 143 | Serverworks HT-1100 |
| 144 | SMSC Victory66 | 144 | SMSC Victory66 |
| 145 | 145 | ||
| 146 | Some AMD chipsets contain two PIIX4-compatible SMBus | ||
| 147 | controllers. This driver will attempt to use both controllers | ||
| 148 | on the SB700/SP5100, if they have been initialized by the BIOS. | ||
| 149 | |||
| 146 | This driver can also be built as a module. If so, the module | 150 | This driver can also be built as a module. If so, the module |
| 147 | will be called i2c-piix4. | 151 | will be called i2c-piix4. |
| 148 | 152 | ||
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index e66d248fc126..125cd8e0ad25 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c | |||
| @@ -531,15 +531,7 @@ static struct pci_driver ali1535_driver = { | |||
| 531 | .remove = __devexit_p(ali1535_remove), | 531 | .remove = __devexit_p(ali1535_remove), |
| 532 | }; | 532 | }; |
| 533 | 533 | ||
| 534 | static int __init i2c_ali1535_init(void) | 534 | module_pci_driver(ali1535_driver); |
| 535 | { | ||
| 536 | return pci_register_driver(&ali1535_driver); | ||
| 537 | } | ||
| 538 | |||
| 539 | static void __exit i2c_ali1535_exit(void) | ||
| 540 | { | ||
| 541 | pci_unregister_driver(&ali1535_driver); | ||
| 542 | } | ||
| 543 | 535 | ||
| 544 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " | 536 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " |
| 545 | "Philip Edelbrock <phil@netroedge.com>, " | 537 | "Philip Edelbrock <phil@netroedge.com>, " |
| @@ -547,6 +539,3 @@ MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " | |||
| 547 | "and Dan Eaton <dan.eaton@rocketlogix.com>"); | 539 | "and Dan Eaton <dan.eaton@rocketlogix.com>"); |
| 548 | MODULE_DESCRIPTION("ALI1535 SMBus driver"); | 540 | MODULE_DESCRIPTION("ALI1535 SMBus driver"); |
| 549 | MODULE_LICENSE("GPL"); | 541 | MODULE_LICENSE("GPL"); |
| 550 | |||
| 551 | module_init(i2c_ali1535_init); | ||
| 552 | module_exit(i2c_ali1535_exit); | ||
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 47ae0091e027..e02d9f86c6a0 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
| @@ -431,18 +431,6 @@ static struct pci_driver ali1563_pci_driver = { | |||
| 431 | .remove = __devexit_p(ali1563_remove), | 431 | .remove = __devexit_p(ali1563_remove), |
| 432 | }; | 432 | }; |
| 433 | 433 | ||
| 434 | static int __init ali1563_init(void) | 434 | module_pci_driver(ali1563_pci_driver); |
| 435 | { | ||
| 436 | return pci_register_driver(&ali1563_pci_driver); | ||
| 437 | } | ||
| 438 | |||
| 439 | module_init(ali1563_init); | ||
| 440 | |||
| 441 | static void __exit ali1563_exit(void) | ||
| 442 | { | ||
| 443 | pci_unregister_driver(&ali1563_pci_driver); | ||
| 444 | } | ||
| 445 | |||
| 446 | module_exit(ali1563_exit); | ||
| 447 | 435 | ||
| 448 | MODULE_LICENSE("GPL"); | 436 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 087ea9caa74d..ce8d26d053a5 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c | |||
| @@ -513,21 +513,10 @@ static struct pci_driver ali15x3_driver = { | |||
| 513 | .remove = __devexit_p(ali15x3_remove), | 513 | .remove = __devexit_p(ali15x3_remove), |
| 514 | }; | 514 | }; |
| 515 | 515 | ||
| 516 | static int __init i2c_ali15x3_init(void) | 516 | module_pci_driver(ali15x3_driver); |
| 517 | { | ||
| 518 | return pci_register_driver(&ali15x3_driver); | ||
| 519 | } | ||
| 520 | |||
| 521 | static void __exit i2c_ali15x3_exit(void) | ||
| 522 | { | ||
| 523 | pci_unregister_driver(&ali15x3_driver); | ||
| 524 | } | ||
| 525 | 517 | ||
| 526 | MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, " | 518 | MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, " |
| 527 | "Philip Edelbrock <phil@netroedge.com>, " | 519 | "Philip Edelbrock <phil@netroedge.com>, " |
| 528 | "and Mark D. Studebaker <mdsxyz123@yahoo.com>"); | 520 | "and Mark D. Studebaker <mdsxyz123@yahoo.com>"); |
| 529 | MODULE_DESCRIPTION("ALI15X3 SMBus driver"); | 521 | MODULE_DESCRIPTION("ALI15X3 SMBus driver"); |
| 530 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
| 531 | |||
| 532 | module_init(i2c_ali15x3_init); | ||
| 533 | module_exit(i2c_ali15x3_exit); | ||
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index eb778bf15c18..304aa03b57b2 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c | |||
| @@ -410,21 +410,10 @@ static struct pci_driver amd756_driver = { | |||
| 410 | .remove = __devexit_p(amd756_remove), | 410 | .remove = __devexit_p(amd756_remove), |
| 411 | }; | 411 | }; |
| 412 | 412 | ||
| 413 | static int __init amd756_init(void) | 413 | module_pci_driver(amd756_driver); |
| 414 | { | ||
| 415 | return pci_register_driver(&amd756_driver); | ||
| 416 | } | ||
| 417 | |||
| 418 | static void __exit amd756_exit(void) | ||
| 419 | { | ||
| 420 | pci_unregister_driver(&amd756_driver); | ||
| 421 | } | ||
| 422 | 414 | ||
| 423 | MODULE_AUTHOR("Merlin Hughes <merlin@merlin.org>"); | 415 | MODULE_AUTHOR("Merlin Hughes <merlin@merlin.org>"); |
| 424 | MODULE_DESCRIPTION("AMD756/766/768/8111 and nVidia nForce SMBus driver"); | 416 | MODULE_DESCRIPTION("AMD756/766/768/8111 and nVidia nForce SMBus driver"); |
| 425 | MODULE_LICENSE("GPL"); | 417 | MODULE_LICENSE("GPL"); |
| 426 | 418 | ||
| 427 | EXPORT_SYMBOL(amd756_smbus); | 419 | EXPORT_SYMBOL(amd756_smbus); |
| 428 | |||
| 429 | module_init(amd756_init) | ||
| 430 | module_exit(amd756_exit) | ||
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index e5ac53b99b04..0919ac1d99aa 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c | |||
| @@ -491,15 +491,4 @@ static struct pci_driver amd8111_driver = { | |||
| 491 | .remove = __devexit_p(amd8111_remove), | 491 | .remove = __devexit_p(amd8111_remove), |
| 492 | }; | 492 | }; |
| 493 | 493 | ||
| 494 | static int __init i2c_amd8111_init(void) | 494 | module_pci_driver(amd8111_driver); |
| 495 | { | ||
| 496 | return pci_register_driver(&amd8111_driver); | ||
| 497 | } | ||
| 498 | |||
| 499 | static void __exit i2c_amd8111_exit(void) | ||
| 500 | { | ||
| 501 | pci_unregister_driver(&amd8111_driver); | ||
| 502 | } | ||
| 503 | |||
| 504 | module_init(i2c_amd8111_init); | ||
| 505 | module_exit(i2c_amd8111_exit); | ||
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 00e8f213f56e..92a1e2c15baa 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c | |||
| @@ -374,17 +374,7 @@ static struct pci_driver dw_i2c_driver = { | |||
| 374 | }, | 374 | }, |
| 375 | }; | 375 | }; |
| 376 | 376 | ||
| 377 | static int __init dw_i2c_init_driver(void) | 377 | module_pci_driver(dw_i2c_driver); |
| 378 | { | ||
| 379 | return pci_register_driver(&dw_i2c_driver); | ||
| 380 | } | ||
| 381 | module_init(dw_i2c_init_driver); | ||
| 382 | |||
| 383 | static void __exit dw_i2c_exit_driver(void) | ||
| 384 | { | ||
| 385 | pci_unregister_driver(&dw_i2c_driver); | ||
| 386 | } | ||
| 387 | module_exit(dw_i2c_exit_driver); | ||
| 388 | 378 | ||
| 389 | MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); | 379 | MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); |
| 390 | MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter"); | 380 | MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter"); |
diff --git a/drivers/i2c/busses/i2c-diolan-u2c.c b/drivers/i2c/busses/i2c-diolan-u2c.c index 7eb19a5222f2..aedb94f34bf7 100644 --- a/drivers/i2c/busses/i2c-diolan-u2c.c +++ b/drivers/i2c/busses/i2c-diolan-u2c.c | |||
| @@ -517,6 +517,6 @@ static struct usb_driver diolan_u2c_driver = { | |||
| 517 | 517 | ||
| 518 | module_usb_driver(diolan_u2c_driver); | 518 | module_usb_driver(diolan_u2c_driver); |
| 519 | 519 | ||
| 520 | MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); | 520 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
| 521 | MODULE_DESCRIPTION(DRIVER_NAME " driver"); | 521 | MODULE_DESCRIPTION(DRIVER_NAME " driver"); |
| 522 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 2f74ae872e1e..259f7697bf25 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
| @@ -953,17 +953,7 @@ static struct pci_driver pch_pcidriver = { | |||
| 953 | .resume = pch_i2c_resume | 953 | .resume = pch_i2c_resume |
| 954 | }; | 954 | }; |
| 955 | 955 | ||
| 956 | static int __init pch_pci_init(void) | 956 | module_pci_driver(pch_pcidriver); |
| 957 | { | ||
| 958 | return pci_register_driver(&pch_pcidriver); | ||
| 959 | } | ||
| 960 | module_init(pch_pci_init); | ||
| 961 | |||
| 962 | static void __exit pch_pci_exit(void) | ||
| 963 | { | ||
| 964 | pci_unregister_driver(&pch_pcidriver); | ||
| 965 | } | ||
| 966 | module_exit(pch_pci_exit); | ||
| 967 | 957 | ||
| 968 | MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C"); | 958 | MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C"); |
| 969 | MODULE_LICENSE("GPL"); | 959 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c index c527de17db4f..c9f95e1666a8 100644 --- a/drivers/i2c/busses/i2c-hydra.c +++ b/drivers/i2c/busses/i2c-hydra.c | |||
| @@ -156,23 +156,8 @@ static struct pci_driver hydra_driver = { | |||
| 156 | .remove = __devexit_p(hydra_remove), | 156 | .remove = __devexit_p(hydra_remove), |
| 157 | }; | 157 | }; |
| 158 | 158 | ||
| 159 | static int __init i2c_hydra_init(void) | 159 | module_pci_driver(hydra_driver); |
| 160 | { | ||
| 161 | return pci_register_driver(&hydra_driver); | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | static void __exit i2c_hydra_exit(void) | ||
| 166 | { | ||
| 167 | pci_unregister_driver(&hydra_driver); | ||
| 168 | } | ||
| 169 | |||
| 170 | |||
| 171 | 160 | ||
| 172 | MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>"); | 161 | MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>"); |
| 173 | MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O"); | 162 | MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O"); |
| 174 | MODULE_LICENSE("GPL"); | 163 | MODULE_LICENSE("GPL"); |
| 175 | |||
| 176 | module_init(i2c_hydra_init); | ||
| 177 | module_exit(i2c_hydra_exit); | ||
| 178 | |||
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ae2945a5e007..898dcf9c7ade 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -60,10 +60,12 @@ | |||
| 60 | Block process call transaction no | 60 | Block process call transaction no |
| 61 | I2C block read transaction yes (doesn't use the block buffer) | 61 | I2C block read transaction yes (doesn't use the block buffer) |
| 62 | Slave mode no | 62 | Slave mode no |
| 63 | Interrupt processing yes | ||
| 63 | 64 | ||
| 64 | See the file Documentation/i2c/busses/i2c-i801 for details. | 65 | See the file Documentation/i2c/busses/i2c-i801 for details. |
| 65 | */ | 66 | */ |
| 66 | 67 | ||
| 68 | #include <linux/interrupt.h> | ||
| 67 | #include <linux/module.h> | 69 | #include <linux/module.h> |
| 68 | #include <linux/pci.h> | 70 | #include <linux/pci.h> |
| 69 | #include <linux/kernel.h> | 71 | #include <linux/kernel.h> |
| @@ -76,6 +78,7 @@ | |||
| 76 | #include <linux/io.h> | 78 | #include <linux/io.h> |
| 77 | #include <linux/dmi.h> | 79 | #include <linux/dmi.h> |
| 78 | #include <linux/slab.h> | 80 | #include <linux/slab.h> |
| 81 | #include <linux/wait.h> | ||
| 79 | 82 | ||
| 80 | /* I801 SMBus address offsets */ | 83 | /* I801 SMBus address offsets */ |
| 81 | #define SMBHSTSTS(p) (0 + (p)->smba) | 84 | #define SMBHSTSTS(p) (0 + (p)->smba) |
| @@ -91,8 +94,12 @@ | |||
| 91 | 94 | ||
| 92 | /* PCI Address Constants */ | 95 | /* PCI Address Constants */ |
| 93 | #define SMBBAR 4 | 96 | #define SMBBAR 4 |
| 97 | #define SMBPCISTS 0x006 | ||
| 94 | #define SMBHSTCFG 0x040 | 98 | #define SMBHSTCFG 0x040 |
| 95 | 99 | ||
| 100 | /* Host status bits for SMBPCISTS */ | ||
| 101 | #define SMBPCISTS_INTS 0x08 | ||
| 102 | |||
| 96 | /* Host configuration bits for SMBHSTCFG */ | 103 | /* Host configuration bits for SMBHSTCFG */ |
| 97 | #define SMBHSTCFG_HST_EN 1 | 104 | #define SMBHSTCFG_HST_EN 1 |
| 98 | #define SMBHSTCFG_SMB_SMI_EN 2 | 105 | #define SMBHSTCFG_SMB_SMI_EN 2 |
| @@ -102,12 +109,8 @@ | |||
| 102 | #define SMBAUXCTL_CRC 1 | 109 | #define SMBAUXCTL_CRC 1 |
| 103 | #define SMBAUXCTL_E32B 2 | 110 | #define SMBAUXCTL_E32B 2 |
| 104 | 111 | ||
| 105 | /* kill bit for SMBHSTCNT */ | ||
| 106 | #define SMBHSTCNT_KILL 2 | ||
| 107 | |||
| 108 | /* Other settings */ | 112 | /* Other settings */ |
| 109 | #define MAX_RETRIES 400 | 113 | #define MAX_RETRIES 400 |
| 110 | #define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ | ||
| 111 | 114 | ||
| 112 | /* I801 command constants */ | 115 | /* I801 command constants */ |
| 113 | #define I801_QUICK 0x00 | 116 | #define I801_QUICK 0x00 |
| @@ -117,10 +120,13 @@ | |||
| 117 | #define I801_PROC_CALL 0x10 /* unimplemented */ | 120 | #define I801_PROC_CALL 0x10 /* unimplemented */ |
| 118 | #define I801_BLOCK_DATA 0x14 | 121 | #define I801_BLOCK_DATA 0x14 |
| 119 | #define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ | 122 | #define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ |
| 120 | #define I801_BLOCK_LAST 0x34 | 123 | |
| 121 | #define I801_I2C_BLOCK_LAST 0x38 /* ICH5 and later */ | 124 | /* I801 Host Control register bits */ |
| 122 | #define I801_START 0x40 | 125 | #define SMBHSTCNT_INTREN 0x01 |
| 123 | #define I801_PEC_EN 0x80 /* ICH3 and later */ | 126 | #define SMBHSTCNT_KILL 0x02 |
| 127 | #define SMBHSTCNT_LAST_BYTE 0x20 | ||
| 128 | #define SMBHSTCNT_START 0x40 | ||
| 129 | #define SMBHSTCNT_PEC_EN 0x80 /* ICH3 and later */ | ||
| 124 | 130 | ||
| 125 | /* I801 Hosts Status register bits */ | 131 | /* I801 Hosts Status register bits */ |
| 126 | #define SMBHSTSTS_BYTE_DONE 0x80 | 132 | #define SMBHSTSTS_BYTE_DONE 0x80 |
| @@ -132,9 +138,11 @@ | |||
| 132 | #define SMBHSTSTS_INTR 0x02 | 138 | #define SMBHSTSTS_INTR 0x02 |
| 133 | #define SMBHSTSTS_HOST_BUSY 0x01 | 139 | #define SMBHSTSTS_HOST_BUSY 0x01 |
| 134 | 140 | ||
| 135 | #define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \ | 141 | #define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ |
| 136 | SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ | 142 | SMBHSTSTS_DEV_ERR) |
| 137 | SMBHSTSTS_INTR) | 143 | |
| 144 | #define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ | ||
| 145 | STATUS_ERROR_FLAGS) | ||
| 138 | 146 | ||
| 139 | /* Older devices have their ID defined in <linux/pci_ids.h> */ | 147 | /* Older devices have their ID defined in <linux/pci_ids.h> */ |
| 140 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 | 148 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 |
| @@ -154,6 +162,17 @@ struct i801_priv { | |||
| 154 | unsigned char original_hstcfg; | 162 | unsigned char original_hstcfg; |
| 155 | struct pci_dev *pci_dev; | 163 | struct pci_dev *pci_dev; |
| 156 | unsigned int features; | 164 | unsigned int features; |
| 165 | |||
| 166 | /* isr processing */ | ||
| 167 | wait_queue_head_t waitq; | ||
| 168 | u8 status; | ||
| 169 | |||
| 170 | /* Command state used by isr for byte-by-byte block transactions */ | ||
| 171 | u8 cmd; | ||
| 172 | bool is_read; | ||
| 173 | int count; | ||
| 174 | int len; | ||
| 175 | u8 *data; | ||
| 157 | }; | 176 | }; |
| 158 | 177 | ||
| 159 | static struct pci_driver i801_driver; | 178 | static struct pci_driver i801_driver; |
| @@ -162,6 +181,7 @@ static struct pci_driver i801_driver; | |||
| 162 | #define FEATURE_BLOCK_BUFFER (1 << 1) | 181 | #define FEATURE_BLOCK_BUFFER (1 << 1) |
| 163 | #define FEATURE_BLOCK_PROC (1 << 2) | 182 | #define FEATURE_BLOCK_PROC (1 << 2) |
| 164 | #define FEATURE_I2C_BLOCK_READ (1 << 3) | 183 | #define FEATURE_I2C_BLOCK_READ (1 << 3) |
| 184 | #define FEATURE_IRQ (1 << 4) | ||
| 165 | /* Not really a feature, but it's convenient to handle it as such */ | 185 | /* Not really a feature, but it's convenient to handle it as such */ |
| 166 | #define FEATURE_IDF (1 << 15) | 186 | #define FEATURE_IDF (1 << 15) |
| 167 | 187 | ||
| @@ -170,6 +190,7 @@ static const char *i801_feature_names[] = { | |||
| 170 | "Block buffer", | 190 | "Block buffer", |
| 171 | "Block process call", | 191 | "Block process call", |
| 172 | "I2C block read", | 192 | "I2C block read", |
| 193 | "Interrupt", | ||
| 173 | }; | 194 | }; |
| 174 | 195 | ||
| 175 | static unsigned int disable_features; | 196 | static unsigned int disable_features; |
| @@ -205,13 +226,22 @@ static int i801_check_pre(struct i801_priv *priv) | |||
| 205 | return 0; | 226 | return 0; |
| 206 | } | 227 | } |
| 207 | 228 | ||
| 208 | /* Convert the status register to an error code, and clear it. */ | 229 | /* |
| 209 | static int i801_check_post(struct i801_priv *priv, int status, int timeout) | 230 | * Convert the status register to an error code, and clear it. |
| 231 | * Note that status only contains the bits we want to clear, not the | ||
| 232 | * actual register value. | ||
| 233 | */ | ||
| 234 | static int i801_check_post(struct i801_priv *priv, int status) | ||
| 210 | { | 235 | { |
| 211 | int result = 0; | 236 | int result = 0; |
| 212 | 237 | ||
| 213 | /* If the SMBus is still busy, we give up */ | 238 | /* |
| 214 | if (timeout) { | 239 | * If the SMBus is still busy, we give up |
| 240 | * Note: This timeout condition only happens when using polling | ||
| 241 | * transactions. For interrupt operation, NAK/timeout is indicated by | ||
| 242 | * DEV_ERR. | ||
| 243 | */ | ||
| 244 | if (unlikely(status < 0)) { | ||
| 215 | dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); | 245 | dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); |
| 216 | /* try to stop the current command */ | 246 | /* try to stop the current command */ |
| 217 | dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); | 247 | dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); |
| @@ -244,64 +274,76 @@ static int i801_check_post(struct i801_priv *priv, int status, int timeout) | |||
| 244 | dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n"); | 274 | dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n"); |
| 245 | } | 275 | } |
| 246 | 276 | ||
| 247 | if (result) { | 277 | /* Clear status flags except BYTE_DONE, to be cleared by caller */ |
| 248 | /* Clear error flags */ | 278 | outb_p(status, SMBHSTSTS(priv)); |
| 249 | outb_p(status & STATUS_FLAGS, SMBHSTSTS(priv)); | ||
| 250 | status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS; | ||
| 251 | if (status) { | ||
| 252 | dev_warn(&priv->pci_dev->dev, "Failed clearing status " | ||
| 253 | "flags at end of transaction (%02x)\n", | ||
| 254 | status); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | 279 | ||
| 258 | return result; | 280 | return result; |
| 259 | } | 281 | } |
| 260 | 282 | ||
| 261 | static int i801_transaction(struct i801_priv *priv, int xact) | 283 | /* Wait for BUSY being cleared and either INTR or an error flag being set */ |
| 284 | static int i801_wait_intr(struct i801_priv *priv) | ||
| 262 | { | 285 | { |
| 263 | int status; | ||
| 264 | int result; | ||
| 265 | int timeout = 0; | 286 | int timeout = 0; |
| 266 | 287 | int status; | |
| 267 | result = i801_check_pre(priv); | ||
| 268 | if (result < 0) | ||
| 269 | return result; | ||
| 270 | |||
| 271 | /* the current contents of SMBHSTCNT can be overwritten, since PEC, | ||
| 272 | * INTREN, SMBSCMD are passed in xact */ | ||
| 273 | outb_p(xact | I801_START, SMBHSTCNT(priv)); | ||
| 274 | 288 | ||
| 275 | /* We will always wait for a fraction of a second! */ | 289 | /* We will always wait for a fraction of a second! */ |
| 276 | do { | 290 | do { |
| 277 | usleep_range(250, 500); | 291 | usleep_range(250, 500); |
| 278 | status = inb_p(SMBHSTSTS(priv)); | 292 | status = inb_p(SMBHSTSTS(priv)); |
| 279 | } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_RETRIES)); | 293 | } while (((status & SMBHSTSTS_HOST_BUSY) || |
| 294 | !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) && | ||
| 295 | (timeout++ < MAX_RETRIES)); | ||
| 280 | 296 | ||
| 281 | result = i801_check_post(priv, status, timeout > MAX_RETRIES); | 297 | if (timeout > MAX_RETRIES) { |
| 282 | if (result < 0) | 298 | dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n"); |
| 283 | return result; | 299 | return -ETIMEDOUT; |
| 284 | 300 | } | |
| 285 | outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv)); | 301 | return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR); |
| 286 | return 0; | ||
| 287 | } | 302 | } |
| 288 | 303 | ||
| 289 | /* wait for INTR bit as advised by Intel */ | 304 | /* Wait for either BYTE_DONE or an error flag being set */ |
| 290 | static void i801_wait_hwpec(struct i801_priv *priv) | 305 | static int i801_wait_byte_done(struct i801_priv *priv) |
| 291 | { | 306 | { |
| 292 | int timeout = 0; | 307 | int timeout = 0; |
| 293 | int status; | 308 | int status; |
| 294 | 309 | ||
| 310 | /* We will always wait for a fraction of a second! */ | ||
| 295 | do { | 311 | do { |
| 296 | usleep_range(250, 500); | 312 | usleep_range(250, 500); |
| 297 | status = inb_p(SMBHSTSTS(priv)); | 313 | status = inb_p(SMBHSTSTS(priv)); |
| 298 | } while ((!(status & SMBHSTSTS_INTR)) | 314 | } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) && |
| 299 | && (timeout++ < MAX_RETRIES)); | 315 | (timeout++ < MAX_RETRIES)); |
| 300 | 316 | ||
| 301 | if (timeout > MAX_RETRIES) | 317 | if (timeout > MAX_RETRIES) { |
| 302 | dev_dbg(&priv->pci_dev->dev, "PEC Timeout!\n"); | 318 | dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n"); |
| 319 | return -ETIMEDOUT; | ||
| 320 | } | ||
| 321 | return status & STATUS_ERROR_FLAGS; | ||
| 322 | } | ||
| 303 | 323 | ||
| 304 | outb_p(status, SMBHSTSTS(priv)); | 324 | static int i801_transaction(struct i801_priv *priv, int xact) |
| 325 | { | ||
| 326 | int status; | ||
| 327 | int result; | ||
| 328 | |||
| 329 | result = i801_check_pre(priv); | ||
| 330 | if (result < 0) | ||
| 331 | return result; | ||
| 332 | |||
| 333 | if (priv->features & FEATURE_IRQ) { | ||
| 334 | outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, | ||
| 335 | SMBHSTCNT(priv)); | ||
| 336 | wait_event(priv->waitq, (status = priv->status)); | ||
| 337 | priv->status = 0; | ||
| 338 | return i801_check_post(priv, status); | ||
| 339 | } | ||
| 340 | |||
| 341 | /* the current contents of SMBHSTCNT can be overwritten, since PEC, | ||
| 342 | * SMBSCMD are passed in xact */ | ||
| 343 | outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv)); | ||
| 344 | |||
| 345 | status = i801_wait_intr(priv); | ||
| 346 | return i801_check_post(priv, status); | ||
| 305 | } | 347 | } |
| 306 | 348 | ||
| 307 | static int i801_block_transaction_by_block(struct i801_priv *priv, | 349 | static int i801_block_transaction_by_block(struct i801_priv *priv, |
| @@ -321,8 +363,8 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, | |||
| 321 | outb_p(data->block[i+1], SMBBLKDAT(priv)); | 363 | outb_p(data->block[i+1], SMBBLKDAT(priv)); |
| 322 | } | 364 | } |
| 323 | 365 | ||
| 324 | status = i801_transaction(priv, I801_BLOCK_DATA | ENABLE_INT9 | | 366 | status = i801_transaction(priv, I801_BLOCK_DATA | |
| 325 | I801_PEC_EN * hwpec); | 367 | (hwpec ? SMBHSTCNT_PEC_EN : 0)); |
| 326 | if (status) | 368 | if (status) |
| 327 | return status; | 369 | return status; |
| 328 | 370 | ||
| @@ -338,6 +380,98 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, | |||
| 338 | return 0; | 380 | return 0; |
| 339 | } | 381 | } |
| 340 | 382 | ||
| 383 | static void i801_isr_byte_done(struct i801_priv *priv) | ||
| 384 | { | ||
| 385 | if (priv->is_read) { | ||
| 386 | /* For SMBus block reads, length is received with first byte */ | ||
| 387 | if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) && | ||
| 388 | (priv->count == 0)) { | ||
| 389 | priv->len = inb_p(SMBHSTDAT0(priv)); | ||
| 390 | if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) { | ||
| 391 | dev_err(&priv->pci_dev->dev, | ||
| 392 | "Illegal SMBus block read size %d\n", | ||
| 393 | priv->len); | ||
| 394 | /* FIXME: Recover */ | ||
| 395 | priv->len = I2C_SMBUS_BLOCK_MAX; | ||
| 396 | } else { | ||
| 397 | dev_dbg(&priv->pci_dev->dev, | ||
| 398 | "SMBus block read size is %d\n", | ||
| 399 | priv->len); | ||
| 400 | } | ||
| 401 | priv->data[-1] = priv->len; | ||
| 402 | } | ||
| 403 | |||
| 404 | /* Read next byte */ | ||
| 405 | if (priv->count < priv->len) | ||
| 406 | priv->data[priv->count++] = inb(SMBBLKDAT(priv)); | ||
| 407 | else | ||
| 408 | dev_dbg(&priv->pci_dev->dev, | ||
| 409 | "Discarding extra byte on block read\n"); | ||
| 410 | |||
| 411 | /* Set LAST_BYTE for last byte of read transaction */ | ||
| 412 | if (priv->count == priv->len - 1) | ||
| 413 | outb_p(priv->cmd | SMBHSTCNT_LAST_BYTE, | ||
| 414 | SMBHSTCNT(priv)); | ||
| 415 | } else if (priv->count < priv->len - 1) { | ||
| 416 | /* Write next byte, except for IRQ after last byte */ | ||
| 417 | outb_p(priv->data[++priv->count], SMBBLKDAT(priv)); | ||
| 418 | } | ||
| 419 | |||
| 420 | /* Clear BYTE_DONE to continue with next byte */ | ||
| 421 | outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * There are two kinds of interrupts: | ||
| 426 | * | ||
| 427 | * 1) i801 signals transaction completion with one of these interrupts: | ||
| 428 | * INTR - Success | ||
| 429 | * DEV_ERR - Invalid command, NAK or communication timeout | ||
| 430 | * BUS_ERR - SMI# transaction collision | ||
| 431 | * FAILED - transaction was canceled due to a KILL request | ||
| 432 | * When any of these occur, update ->status and wake up the waitq. | ||
| 433 | * ->status must be cleared before kicking off the next transaction. | ||
| 434 | * | ||
| 435 | * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt | ||
| 436 | * occurs for each byte of a byte-by-byte to prepare the next byte. | ||
| 437 | */ | ||
| 438 | static irqreturn_t i801_isr(int irq, void *dev_id) | ||
| 439 | { | ||
| 440 | struct i801_priv *priv = dev_id; | ||
| 441 | u16 pcists; | ||
| 442 | u8 status; | ||
| 443 | |||
| 444 | /* Confirm this is our interrupt */ | ||
| 445 | pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); | ||
| 446 | if (!(pcists & SMBPCISTS_INTS)) | ||
| 447 | return IRQ_NONE; | ||
| 448 | |||
| 449 | status = inb_p(SMBHSTSTS(priv)); | ||
| 450 | if (status != 0x42) | ||
| 451 | dev_dbg(&priv->pci_dev->dev, "irq: status = %02x\n", status); | ||
| 452 | |||
| 453 | if (status & SMBHSTSTS_BYTE_DONE) | ||
| 454 | i801_isr_byte_done(priv); | ||
| 455 | |||
| 456 | /* | ||
| 457 | * Clear irq sources and report transaction result. | ||
| 458 | * ->status must be cleared before the next transaction is started. | ||
| 459 | */ | ||
| 460 | status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; | ||
| 461 | if (status) { | ||
| 462 | outb_p(status, SMBHSTSTS(priv)); | ||
| 463 | priv->status |= status; | ||
| 464 | wake_up(&priv->waitq); | ||
| 465 | } | ||
| 466 | |||
| 467 | return IRQ_HANDLED; | ||
| 468 | } | ||
| 469 | |||
| 470 | /* | ||
| 471 | * For "byte-by-byte" block transactions: | ||
| 472 | * I2C write uses cmd=I801_BLOCK_DATA, I2C_EN=1 | ||
| 473 | * I2C read uses cmd=I801_I2C_BLOCK_DATA | ||
| 474 | */ | ||
| 341 | static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, | 475 | static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, |
| 342 | union i2c_smbus_data *data, | 476 | union i2c_smbus_data *data, |
| 343 | char read_write, int command, | 477 | char read_write, int command, |
| @@ -347,7 +481,6 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, | |||
| 347 | int smbcmd; | 481 | int smbcmd; |
| 348 | int status; | 482 | int status; |
| 349 | int result; | 483 | int result; |
| 350 | int timeout; | ||
| 351 | 484 | ||
| 352 | result = i801_check_pre(priv); | 485 | result = i801_check_pre(priv); |
| 353 | if (result < 0) | 486 | if (result < 0) |
| @@ -360,36 +493,39 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, | |||
| 360 | outb_p(data->block[1], SMBBLKDAT(priv)); | 493 | outb_p(data->block[1], SMBBLKDAT(priv)); |
| 361 | } | 494 | } |
| 362 | 495 | ||
| 496 | if (command == I2C_SMBUS_I2C_BLOCK_DATA && | ||
| 497 | read_write == I2C_SMBUS_READ) | ||
| 498 | smbcmd = I801_I2C_BLOCK_DATA; | ||
| 499 | else | ||
| 500 | smbcmd = I801_BLOCK_DATA; | ||
| 501 | |||
| 502 | if (priv->features & FEATURE_IRQ) { | ||
| 503 | priv->is_read = (read_write == I2C_SMBUS_READ); | ||
| 504 | if (len == 1 && priv->is_read) | ||
| 505 | smbcmd |= SMBHSTCNT_LAST_BYTE; | ||
| 506 | priv->cmd = smbcmd | SMBHSTCNT_INTREN; | ||
| 507 | priv->len = len; | ||
| 508 | priv->count = 0; | ||
| 509 | priv->data = &data->block[1]; | ||
| 510 | |||
| 511 | outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); | ||
| 512 | wait_event(priv->waitq, (status = priv->status)); | ||
| 513 | priv->status = 0; | ||
| 514 | return i801_check_post(priv, status); | ||
| 515 | } | ||
| 516 | |||
| 363 | for (i = 1; i <= len; i++) { | 517 | for (i = 1; i <= len; i++) { |
| 364 | if (i == len && read_write == I2C_SMBUS_READ) { | 518 | if (i == len && read_write == I2C_SMBUS_READ) |
| 365 | if (command == I2C_SMBUS_I2C_BLOCK_DATA) | 519 | smbcmd |= SMBHSTCNT_LAST_BYTE; |
| 366 | smbcmd = I801_I2C_BLOCK_LAST; | 520 | outb_p(smbcmd, SMBHSTCNT(priv)); |
| 367 | else | ||
| 368 | smbcmd = I801_BLOCK_LAST; | ||
| 369 | } else { | ||
| 370 | if (command == I2C_SMBUS_I2C_BLOCK_DATA | ||
| 371 | && read_write == I2C_SMBUS_READ) | ||
| 372 | smbcmd = I801_I2C_BLOCK_DATA; | ||
| 373 | else | ||
| 374 | smbcmd = I801_BLOCK_DATA; | ||
| 375 | } | ||
| 376 | outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT(priv)); | ||
| 377 | 521 | ||
| 378 | if (i == 1) | 522 | if (i == 1) |
| 379 | outb_p(inb(SMBHSTCNT(priv)) | I801_START, | 523 | outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START, |
| 380 | SMBHSTCNT(priv)); | 524 | SMBHSTCNT(priv)); |
| 381 | 525 | ||
| 382 | /* We will always wait for a fraction of a second! */ | 526 | status = i801_wait_byte_done(priv); |
| 383 | timeout = 0; | 527 | if (status) |
| 384 | do { | 528 | goto exit; |
| 385 | usleep_range(250, 500); | ||
| 386 | status = inb_p(SMBHSTSTS(priv)); | ||
| 387 | } while ((!(status & SMBHSTSTS_BYTE_DONE)) | ||
| 388 | && (timeout++ < MAX_RETRIES)); | ||
| 389 | |||
| 390 | result = i801_check_post(priv, status, timeout > MAX_RETRIES); | ||
| 391 | if (result < 0) | ||
| 392 | return result; | ||
| 393 | 529 | ||
| 394 | if (i == 1 && read_write == I2C_SMBUS_READ | 530 | if (i == 1 && read_write == I2C_SMBUS_READ |
| 395 | && command != I2C_SMBUS_I2C_BLOCK_DATA) { | 531 | && command != I2C_SMBUS_I2C_BLOCK_DATA) { |
| @@ -416,10 +552,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, | |||
| 416 | outb_p(data->block[i+1], SMBBLKDAT(priv)); | 552 | outb_p(data->block[i+1], SMBBLKDAT(priv)); |
| 417 | 553 | ||
| 418 | /* signals SMBBLKDAT ready */ | 554 | /* signals SMBBLKDAT ready */ |
| 419 | outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS(priv)); | 555 | outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); |
| 420 | } | 556 | } |
| 421 | 557 | ||
| 422 | return 0; | 558 | status = i801_wait_intr(priv); |
| 559 | exit: | ||
| 560 | return i801_check_post(priv, status); | ||
| 423 | } | 561 | } |
| 424 | 562 | ||
| 425 | static int i801_set_block_buffer_mode(struct i801_priv *priv) | 563 | static int i801_set_block_buffer_mode(struct i801_priv *priv) |
| @@ -474,9 +612,6 @@ static int i801_block_transaction(struct i801_priv *priv, | |||
| 474 | read_write, | 612 | read_write, |
| 475 | command, hwpec); | 613 | command, hwpec); |
| 476 | 614 | ||
| 477 | if (result == 0 && hwpec) | ||
| 478 | i801_wait_hwpec(priv); | ||
| 479 | |||
| 480 | if (command == I2C_SMBUS_I2C_BLOCK_DATA | 615 | if (command == I2C_SMBUS_I2C_BLOCK_DATA |
| 481 | && read_write == I2C_SMBUS_WRITE) { | 616 | && read_write == I2C_SMBUS_WRITE) { |
| 482 | /* restore saved configuration register value */ | 617 | /* restore saved configuration register value */ |
| @@ -564,7 +699,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, | |||
| 564 | ret = i801_block_transaction(priv, data, read_write, size, | 699 | ret = i801_block_transaction(priv, data, read_write, size, |
| 565 | hwpec); | 700 | hwpec); |
| 566 | else | 701 | else |
| 567 | ret = i801_transaction(priv, xact | ENABLE_INT9); | 702 | ret = i801_transaction(priv, xact); |
| 568 | 703 | ||
| 569 | /* Some BIOSes don't like it when PEC is enabled at reboot or resume | 704 | /* Some BIOSes don't like it when PEC is enabled at reboot or resume |
| 570 | time, so we forcibly disable it after every transaction. Turn off | 705 | time, so we forcibly disable it after every transaction. Turn off |
| @@ -799,6 +934,16 @@ static int __devinit i801_probe(struct pci_dev *dev, | |||
| 799 | break; | 934 | break; |
| 800 | } | 935 | } |
| 801 | 936 | ||
| 937 | /* IRQ processing tested on CougarPoint PCH, ICH5, ICH7-M and ICH10 */ | ||
| 938 | if (dev->device == PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS || | ||
| 939 | dev->device == PCI_DEVICE_ID_INTEL_82801EB_3 || | ||
| 940 | dev->device == PCI_DEVICE_ID_INTEL_ICH7_17 || | ||
| 941 | dev->device == PCI_DEVICE_ID_INTEL_ICH8_5 || | ||
| 942 | dev->device == PCI_DEVICE_ID_INTEL_ICH9_6 || | ||
| 943 | dev->device == PCI_DEVICE_ID_INTEL_ICH10_4 || | ||
| 944 | dev->device == PCI_DEVICE_ID_INTEL_ICH10_5) | ||
| 945 | priv->features |= FEATURE_IRQ; | ||
| 946 | |||
| 802 | /* Disable features on user request */ | 947 | /* Disable features on user request */ |
| 803 | for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) { | 948 | for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) { |
| 804 | if (priv->features & disable_features & (1 << i)) | 949 | if (priv->features & disable_features & (1 << i)) |
| @@ -846,16 +991,30 @@ static int __devinit i801_probe(struct pci_dev *dev, | |||
| 846 | } | 991 | } |
| 847 | pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp); | 992 | pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp); |
| 848 | 993 | ||
| 849 | if (temp & SMBHSTCFG_SMB_SMI_EN) | 994 | if (temp & SMBHSTCFG_SMB_SMI_EN) { |
| 850 | dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); | 995 | dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); |
| 851 | else | 996 | /* Disable SMBus interrupt feature if SMBus using SMI# */ |
| 852 | dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); | 997 | priv->features &= ~FEATURE_IRQ; |
| 998 | } | ||
| 853 | 999 | ||
| 854 | /* Clear special mode bits */ | 1000 | /* Clear special mode bits */ |
| 855 | if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER)) | 1001 | if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER)) |
| 856 | outb_p(inb_p(SMBAUXCTL(priv)) & | 1002 | outb_p(inb_p(SMBAUXCTL(priv)) & |
| 857 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); | 1003 | ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); |
| 858 | 1004 | ||
| 1005 | if (priv->features & FEATURE_IRQ) { | ||
| 1006 | init_waitqueue_head(&priv->waitq); | ||
| 1007 | |||
| 1008 | err = request_irq(dev->irq, i801_isr, IRQF_SHARED, | ||
| 1009 | i801_driver.name, priv); | ||
| 1010 | if (err) { | ||
| 1011 | dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", | ||
| 1012 | dev->irq, err); | ||
| 1013 | goto exit_release; | ||
| 1014 | } | ||
| 1015 | dev_info(&dev->dev, "SMBus using PCI Interrupt\n"); | ||
| 1016 | } | ||
| 1017 | |||
| 859 | /* set up the sysfs linkage to our parent device */ | 1018 | /* set up the sysfs linkage to our parent device */ |
| 860 | priv->adapter.dev.parent = &dev->dev; | 1019 | priv->adapter.dev.parent = &dev->dev; |
| 861 | 1020 | ||
| @@ -867,14 +1026,18 @@ static int __devinit i801_probe(struct pci_dev *dev, | |||
| 867 | err = i2c_add_adapter(&priv->adapter); | 1026 | err = i2c_add_adapter(&priv->adapter); |
| 868 | if (err) { | 1027 | if (err) { |
| 869 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); | 1028 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); |
| 870 | goto exit_release; | 1029 | goto exit_free_irq; |
| 871 | } | 1030 | } |
| 872 | 1031 | ||
| 873 | i801_probe_optional_slaves(priv); | 1032 | i801_probe_optional_slaves(priv); |
| 874 | 1033 | ||
| 875 | pci_set_drvdata(dev, priv); | 1034 | pci_set_drvdata(dev, priv); |
| 1035 | |||
| 876 | return 0; | 1036 | return 0; |
| 877 | 1037 | ||
| 1038 | exit_free_irq: | ||
| 1039 | if (priv->features & FEATURE_IRQ) | ||
| 1040 | free_irq(dev->irq, priv); | ||
| 878 | exit_release: | 1041 | exit_release: |
| 879 | pci_release_region(dev, SMBBAR); | 1042 | pci_release_region(dev, SMBBAR); |
| 880 | exit: | 1043 | exit: |
| @@ -888,7 +1051,11 @@ static void __devexit i801_remove(struct pci_dev *dev) | |||
| 888 | 1051 | ||
| 889 | i2c_del_adapter(&priv->adapter); | 1052 | i2c_del_adapter(&priv->adapter); |
| 890 | pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); | 1053 | pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); |
| 1054 | |||
| 1055 | if (priv->features & FEATURE_IRQ) | ||
| 1056 | free_irq(dev->irq, priv); | ||
| 891 | pci_release_region(dev, SMBBAR); | 1057 | pci_release_region(dev, SMBBAR); |
| 1058 | |||
| 892 | pci_set_drvdata(dev, NULL); | 1059 | pci_set_drvdata(dev, NULL); |
| 893 | kfree(priv); | 1060 | kfree(priv); |
| 894 | /* | 1061 | /* |
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index 365bad5b890b..7c28f10f95ca 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c | |||
| @@ -1116,18 +1116,7 @@ static struct pci_driver intel_mid_i2c_driver = { | |||
| 1116 | .remove = __devexit_p(intel_mid_i2c_remove), | 1116 | .remove = __devexit_p(intel_mid_i2c_remove), |
| 1117 | }; | 1117 | }; |
| 1118 | 1118 | ||
| 1119 | static int __init intel_mid_i2c_init(void) | 1119 | module_pci_driver(intel_mid_i2c_driver); |
| 1120 | { | ||
| 1121 | return pci_register_driver(&intel_mid_i2c_driver); | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | static void __exit intel_mid_i2c_exit(void) | ||
| 1125 | { | ||
| 1126 | pci_unregister_driver(&intel_mid_i2c_driver); | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | module_init(intel_mid_i2c_init); | ||
| 1130 | module_exit(intel_mid_i2c_exit); | ||
| 1131 | 1120 | ||
| 1132 | MODULE_AUTHOR("Ba Zheng <zheng.ba@intel.com>"); | 1121 | MODULE_AUTHOR("Ba Zheng <zheng.ba@intel.com>"); |
| 1133 | MODULE_DESCRIPTION("I2C driver for Moorestown Platform"); | 1122 | MODULE_DESCRIPTION("I2C driver for Moorestown Platform"); |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 43a96a123920..392303b4be07 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
| @@ -453,16 +453,4 @@ static struct pci_driver nforce2_driver = { | |||
| 453 | .remove = __devexit_p(nforce2_remove), | 453 | .remove = __devexit_p(nforce2_remove), |
| 454 | }; | 454 | }; |
| 455 | 455 | ||
| 456 | static int __init nforce2_init(void) | 456 | module_pci_driver(nforce2_driver); |
| 457 | { | ||
| 458 | return pci_register_driver(&nforce2_driver); | ||
| 459 | } | ||
| 460 | |||
| 461 | static void __exit nforce2_exit(void) | ||
| 462 | { | ||
| 463 | pci_unregister_driver(&nforce2_driver); | ||
| 464 | } | ||
| 465 | |||
| 466 | module_init(nforce2_init); | ||
| 467 | module_exit(nforce2_exit); | ||
| 468 | |||
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 801df6000e9b..c2148332de0f 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
| @@ -545,6 +545,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, | |||
| 545 | if (dev->speed > 400) | 545 | if (dev->speed > 400) |
| 546 | w |= OMAP_I2C_CON_OPMODE_HS; | 546 | w |= OMAP_I2C_CON_OPMODE_HS; |
| 547 | 547 | ||
| 548 | if (msg->flags & I2C_M_STOP) | ||
| 549 | stop = 1; | ||
| 548 | if (msg->flags & I2C_M_TEN) | 550 | if (msg->flags & I2C_M_TEN) |
| 549 | w |= OMAP_I2C_CON_XA; | 551 | w |= OMAP_I2C_CON_XA; |
| 550 | if (!(msg->flags & I2C_M_RD)) | 552 | if (!(msg->flags & I2C_M_RD)) |
| @@ -658,7 +660,8 @@ out: | |||
| 658 | static u32 | 660 | static u32 |
| 659 | omap_i2c_func(struct i2c_adapter *adap) | 661 | omap_i2c_func(struct i2c_adapter *adap) |
| 660 | { | 662 | { |
| 661 | return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); | 663 | return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | |
| 664 | I2C_FUNC_PROTOCOL_MANGLING; | ||
| 662 | } | 665 | } |
| 663 | 666 | ||
| 664 | static inline void | 667 | static inline void |
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c index eaaea73209c5..12edefd4183a 100644 --- a/drivers/i2c/busses/i2c-pasemi.c +++ b/drivers/i2c/busses/i2c-pasemi.c | |||
| @@ -415,19 +415,8 @@ static struct pci_driver pasemi_smb_driver = { | |||
| 415 | .remove = __devexit_p(pasemi_smb_remove), | 415 | .remove = __devexit_p(pasemi_smb_remove), |
| 416 | }; | 416 | }; |
| 417 | 417 | ||
| 418 | static int __init pasemi_smb_init(void) | 418 | module_pci_driver(pasemi_smb_driver); |
| 419 | { | ||
| 420 | return pci_register_driver(&pasemi_smb_driver); | ||
| 421 | } | ||
| 422 | |||
| 423 | static void __exit pasemi_smb_exit(void) | ||
| 424 | { | ||
| 425 | pci_unregister_driver(&pasemi_smb_driver); | ||
| 426 | } | ||
| 427 | 419 | ||
| 428 | MODULE_LICENSE("GPL"); | 420 | MODULE_LICENSE("GPL"); |
| 429 | MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); | 421 | MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); |
| 430 | MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver"); | 422 | MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver"); |
| 431 | |||
| 432 | module_init(pasemi_smb_init); | ||
| 433 | module_exit(pasemi_smb_exit); | ||
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index c14d48dd601a..ef511df2c965 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
| @@ -21,11 +21,12 @@ | |||
| 21 | Supports: | 21 | Supports: |
| 22 | Intel PIIX4, 440MX | 22 | Intel PIIX4, 440MX |
| 23 | Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 | 23 | Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 |
| 24 | ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 | 24 | ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 |
| 25 | AMD Hudson-2 | 25 | AMD Hudson-2 |
| 26 | SMSC Victory66 | 26 | SMSC Victory66 |
| 27 | 27 | ||
| 28 | Note: we assume there can only be one device, with one SMBus interface. | 28 | Note: we assume there can only be one device, with one or more |
| 29 | SMBus interfaces. | ||
| 29 | */ | 30 | */ |
| 30 | 31 | ||
| 31 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| @@ -94,10 +95,8 @@ MODULE_PARM_DESC(force_addr, | |||
| 94 | "Forcibly enable the PIIX4 at the given address. " | 95 | "Forcibly enable the PIIX4 at the given address. " |
| 95 | "EXTREMELY DANGEROUS!"); | 96 | "EXTREMELY DANGEROUS!"); |
| 96 | 97 | ||
| 97 | static unsigned short piix4_smba; | ||
| 98 | static int srvrworks_csb5_delay; | 98 | static int srvrworks_csb5_delay; |
| 99 | static struct pci_driver piix4_driver; | 99 | static struct pci_driver piix4_driver; |
| 100 | static struct i2c_adapter piix4_adapter; | ||
| 101 | 100 | ||
| 102 | static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = { | 101 | static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = { |
| 103 | { | 102 | { |
| @@ -127,10 +126,15 @@ static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = { | |||
| 127 | { }, | 126 | { }, |
| 128 | }; | 127 | }; |
| 129 | 128 | ||
| 129 | struct i2c_piix4_adapdata { | ||
| 130 | unsigned short smba; | ||
| 131 | }; | ||
| 132 | |||
| 130 | static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | 133 | static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, |
| 131 | const struct pci_device_id *id) | 134 | const struct pci_device_id *id) |
| 132 | { | 135 | { |
| 133 | unsigned char temp; | 136 | unsigned char temp; |
| 137 | unsigned short piix4_smba; | ||
| 134 | 138 | ||
| 135 | if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && | 139 | if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && |
| 136 | (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) | 140 | (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) |
| @@ -206,7 +210,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
| 206 | dev_err(&PIIX4_dev->dev, | 210 | dev_err(&PIIX4_dev->dev, |
| 207 | "Host SMBus controller not enabled!\n"); | 211 | "Host SMBus controller not enabled!\n"); |
| 208 | release_region(piix4_smba, SMBIOSIZE); | 212 | release_region(piix4_smba, SMBIOSIZE); |
| 209 | piix4_smba = 0; | ||
| 210 | return -ENODEV; | 213 | return -ENODEV; |
| 211 | } | 214 | } |
| 212 | } | 215 | } |
| @@ -224,12 +227,13 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
| 224 | "SMBus Host Controller at 0x%x, revision %d\n", | 227 | "SMBus Host Controller at 0x%x, revision %d\n", |
| 225 | piix4_smba, temp); | 228 | piix4_smba, temp); |
| 226 | 229 | ||
| 227 | return 0; | 230 | return piix4_smba; |
| 228 | } | 231 | } |
| 229 | 232 | ||
| 230 | static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, | 233 | static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, |
| 231 | const struct pci_device_id *id) | 234 | const struct pci_device_id *id) |
| 232 | { | 235 | { |
| 236 | unsigned short piix4_smba; | ||
| 233 | unsigned short smba_idx = 0xcd6; | 237 | unsigned short smba_idx = 0xcd6; |
| 234 | u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; | 238 | u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; |
| 235 | 239 | ||
| @@ -273,7 +277,6 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, | |||
| 273 | dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " | 277 | dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " |
| 274 | "0x%x already in use!\n", piix4_smba + i2ccfg_offset); | 278 | "0x%x already in use!\n", piix4_smba + i2ccfg_offset); |
| 275 | release_region(piix4_smba, SMBIOSIZE); | 279 | release_region(piix4_smba, SMBIOSIZE); |
| 276 | piix4_smba = 0; | ||
| 277 | return -EBUSY; | 280 | return -EBUSY; |
| 278 | } | 281 | } |
| 279 | i2ccfg = inb_p(piix4_smba + i2ccfg_offset); | 282 | i2ccfg = inb_p(piix4_smba + i2ccfg_offset); |
| @@ -288,30 +291,72 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, | |||
| 288 | "SMBus Host Controller at 0x%x, revision %d\n", | 291 | "SMBus Host Controller at 0x%x, revision %d\n", |
| 289 | piix4_smba, i2ccfg >> 4); | 292 | piix4_smba, i2ccfg >> 4); |
| 290 | 293 | ||
| 291 | return 0; | 294 | return piix4_smba; |
| 295 | } | ||
| 296 | |||
| 297 | static int __devinit piix4_setup_aux(struct pci_dev *PIIX4_dev, | ||
| 298 | const struct pci_device_id *id, | ||
| 299 | unsigned short base_reg_addr) | ||
| 300 | { | ||
| 301 | /* Set up auxiliary SMBus controllers found on some | ||
| 302 | * AMD chipsets e.g. SP5100 (SB700 derivative) */ | ||
| 303 | |||
| 304 | unsigned short piix4_smba; | ||
| 305 | |||
| 306 | /* Read address of auxiliary SMBus controller */ | ||
| 307 | pci_read_config_word(PIIX4_dev, base_reg_addr, &piix4_smba); | ||
| 308 | if ((piix4_smba & 1) == 0) { | ||
| 309 | dev_dbg(&PIIX4_dev->dev, | ||
| 310 | "Auxiliary SMBus controller not enabled\n"); | ||
| 311 | return -ENODEV; | ||
| 312 | } | ||
| 313 | |||
| 314 | piix4_smba &= 0xfff0; | ||
| 315 | if (piix4_smba == 0) { | ||
| 316 | dev_dbg(&PIIX4_dev->dev, | ||
| 317 | "Auxiliary SMBus base address uninitialized\n"); | ||
| 318 | return -ENODEV; | ||
| 319 | } | ||
| 320 | |||
| 321 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) | ||
| 322 | return -ENODEV; | ||
| 323 | |||
| 324 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { | ||
| 325 | dev_err(&PIIX4_dev->dev, "Auxiliary SMBus region 0x%x " | ||
| 326 | "already in use!\n", piix4_smba); | ||
| 327 | return -EBUSY; | ||
| 328 | } | ||
| 329 | |||
| 330 | dev_info(&PIIX4_dev->dev, | ||
| 331 | "Auxiliary SMBus Host Controller at 0x%x\n", | ||
| 332 | piix4_smba); | ||
| 333 | |||
| 334 | return piix4_smba; | ||
| 292 | } | 335 | } |
| 293 | 336 | ||
| 294 | static int piix4_transaction(void) | 337 | static int piix4_transaction(struct i2c_adapter *piix4_adapter) |
| 295 | { | 338 | { |
| 339 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); | ||
| 340 | unsigned short piix4_smba = adapdata->smba; | ||
| 296 | int temp; | 341 | int temp; |
| 297 | int result = 0; | 342 | int result = 0; |
| 298 | int timeout = 0; | 343 | int timeout = 0; |
| 299 | 344 | ||
| 300 | dev_dbg(&piix4_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " | 345 | dev_dbg(&piix4_adapter->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " |
| 301 | "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), | 346 | "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), |
| 302 | inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), | 347 | inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), |
| 303 | inb_p(SMBHSTDAT1)); | 348 | inb_p(SMBHSTDAT1)); |
| 304 | 349 | ||
| 305 | /* Make sure the SMBus host is ready to start transmitting */ | 350 | /* Make sure the SMBus host is ready to start transmitting */ |
| 306 | if ((temp = inb_p(SMBHSTSTS)) != 0x00) { | 351 | if ((temp = inb_p(SMBHSTSTS)) != 0x00) { |
| 307 | dev_dbg(&piix4_adapter.dev, "SMBus busy (%02x). " | 352 | dev_dbg(&piix4_adapter->dev, "SMBus busy (%02x). " |
| 308 | "Resetting...\n", temp); | 353 | "Resetting...\n", temp); |
| 309 | outb_p(temp, SMBHSTSTS); | 354 | outb_p(temp, SMBHSTSTS); |
| 310 | if ((temp = inb_p(SMBHSTSTS)) != 0x00) { | 355 | if ((temp = inb_p(SMBHSTSTS)) != 0x00) { |
| 311 | dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp); | 356 | dev_err(&piix4_adapter->dev, "Failed! (%02x)\n", temp); |
| 312 | return -EBUSY; | 357 | return -EBUSY; |
| 313 | } else { | 358 | } else { |
| 314 | dev_dbg(&piix4_adapter.dev, "Successful!\n"); | 359 | dev_dbg(&piix4_adapter->dev, "Successful!\n"); |
| 315 | } | 360 | } |
| 316 | } | 361 | } |
| 317 | 362 | ||
| @@ -330,35 +375,35 @@ static int piix4_transaction(void) | |||
| 330 | 375 | ||
| 331 | /* If the SMBus is still busy, we give up */ | 376 | /* If the SMBus is still busy, we give up */ |
| 332 | if (timeout == MAX_TIMEOUT) { | 377 | if (timeout == MAX_TIMEOUT) { |
| 333 | dev_err(&piix4_adapter.dev, "SMBus Timeout!\n"); | 378 | dev_err(&piix4_adapter->dev, "SMBus Timeout!\n"); |
| 334 | result = -ETIMEDOUT; | 379 | result = -ETIMEDOUT; |
| 335 | } | 380 | } |
| 336 | 381 | ||
| 337 | if (temp & 0x10) { | 382 | if (temp & 0x10) { |
| 338 | result = -EIO; | 383 | result = -EIO; |
| 339 | dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n"); | 384 | dev_err(&piix4_adapter->dev, "Error: Failed bus transaction\n"); |
| 340 | } | 385 | } |
| 341 | 386 | ||
| 342 | if (temp & 0x08) { | 387 | if (temp & 0x08) { |
| 343 | result = -EIO; | 388 | result = -EIO; |
| 344 | dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be " | 389 | dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be " |
| 345 | "locked until next hard reset. (sorry!)\n"); | 390 | "locked until next hard reset. (sorry!)\n"); |
| 346 | /* Clock stops and slave is stuck in mid-transmission */ | 391 | /* Clock stops and slave is stuck in mid-transmission */ |
| 347 | } | 392 | } |
| 348 | 393 | ||
| 349 | if (temp & 0x04) { | 394 | if (temp & 0x04) { |
| 350 | result = -ENXIO; | 395 | result = -ENXIO; |
| 351 | dev_dbg(&piix4_adapter.dev, "Error: no response!\n"); | 396 | dev_dbg(&piix4_adapter->dev, "Error: no response!\n"); |
| 352 | } | 397 | } |
| 353 | 398 | ||
| 354 | if (inb_p(SMBHSTSTS) != 0x00) | 399 | if (inb_p(SMBHSTSTS) != 0x00) |
| 355 | outb_p(inb(SMBHSTSTS), SMBHSTSTS); | 400 | outb_p(inb(SMBHSTSTS), SMBHSTSTS); |
| 356 | 401 | ||
| 357 | if ((temp = inb_p(SMBHSTSTS)) != 0x00) { | 402 | if ((temp = inb_p(SMBHSTSTS)) != 0x00) { |
| 358 | dev_err(&piix4_adapter.dev, "Failed reset at end of " | 403 | dev_err(&piix4_adapter->dev, "Failed reset at end of " |
| 359 | "transaction (%02x)\n", temp); | 404 | "transaction (%02x)\n", temp); |
| 360 | } | 405 | } |
| 361 | dev_dbg(&piix4_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " | 406 | dev_dbg(&piix4_adapter->dev, "Transaction (post): CNT=%02x, CMD=%02x, " |
| 362 | "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), | 407 | "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), |
| 363 | inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), | 408 | inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), |
| 364 | inb_p(SMBHSTDAT1)); | 409 | inb_p(SMBHSTDAT1)); |
| @@ -370,6 +415,8 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, | |||
| 370 | unsigned short flags, char read_write, | 415 | unsigned short flags, char read_write, |
| 371 | u8 command, int size, union i2c_smbus_data * data) | 416 | u8 command, int size, union i2c_smbus_data * data) |
| 372 | { | 417 | { |
| 418 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap); | ||
| 419 | unsigned short piix4_smba = adapdata->smba; | ||
| 373 | int i, len; | 420 | int i, len; |
| 374 | int status; | 421 | int status; |
| 375 | 422 | ||
| @@ -426,7 +473,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, | |||
| 426 | 473 | ||
| 427 | outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); | 474 | outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); |
| 428 | 475 | ||
| 429 | status = piix4_transaction(); | 476 | status = piix4_transaction(adap); |
| 430 | if (status) | 477 | if (status) |
| 431 | return status; | 478 | return status; |
| 432 | 479 | ||
| @@ -466,12 +513,6 @@ static const struct i2c_algorithm smbus_algorithm = { | |||
| 466 | .functionality = piix4_func, | 513 | .functionality = piix4_func, |
| 467 | }; | 514 | }; |
| 468 | 515 | ||
| 469 | static struct i2c_adapter piix4_adapter = { | ||
| 470 | .owner = THIS_MODULE, | ||
| 471 | .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, | ||
| 472 | .algo = &smbus_algorithm, | ||
| 473 | }; | ||
| 474 | |||
| 475 | static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { | 516 | static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { |
| 476 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, | 517 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, |
| 477 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, | 518 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, |
| @@ -496,6 +537,57 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { | |||
| 496 | 537 | ||
| 497 | MODULE_DEVICE_TABLE (pci, piix4_ids); | 538 | MODULE_DEVICE_TABLE (pci, piix4_ids); |
| 498 | 539 | ||
| 540 | static struct i2c_adapter *piix4_main_adapter; | ||
| 541 | static struct i2c_adapter *piix4_aux_adapter; | ||
| 542 | |||
| 543 | static int __devinit piix4_add_adapter(struct pci_dev *dev, | ||
| 544 | unsigned short smba, | ||
| 545 | struct i2c_adapter **padap) | ||
| 546 | { | ||
| 547 | struct i2c_adapter *adap; | ||
| 548 | struct i2c_piix4_adapdata *adapdata; | ||
| 549 | int retval; | ||
| 550 | |||
| 551 | adap = kzalloc(sizeof(*adap), GFP_KERNEL); | ||
| 552 | if (adap == NULL) { | ||
| 553 | release_region(smba, SMBIOSIZE); | ||
| 554 | return -ENOMEM; | ||
| 555 | } | ||
| 556 | |||
| 557 | adap->owner = THIS_MODULE; | ||
| 558 | adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; | ||
| 559 | adap->algo = &smbus_algorithm; | ||
| 560 | |||
| 561 | adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL); | ||
| 562 | if (adapdata == NULL) { | ||
| 563 | kfree(adap); | ||
| 564 | release_region(smba, SMBIOSIZE); | ||
| 565 | return -ENOMEM; | ||
| 566 | } | ||
| 567 | |||
| 568 | adapdata->smba = smba; | ||
| 569 | |||
| 570 | /* set up the sysfs linkage to our parent device */ | ||
| 571 | adap->dev.parent = &dev->dev; | ||
| 572 | |||
| 573 | snprintf(adap->name, sizeof(adap->name), | ||
| 574 | "SMBus PIIX4 adapter at %04x", smba); | ||
| 575 | |||
| 576 | i2c_set_adapdata(adap, adapdata); | ||
| 577 | |||
| 578 | retval = i2c_add_adapter(adap); | ||
| 579 | if (retval) { | ||
| 580 | dev_err(&dev->dev, "Couldn't register adapter!\n"); | ||
| 581 | kfree(adapdata); | ||
| 582 | kfree(adap); | ||
| 583 | release_region(smba, SMBIOSIZE); | ||
| 584 | return retval; | ||
| 585 | } | ||
| 586 | |||
| 587 | *padap = adap; | ||
| 588 | return 0; | ||
| 589 | } | ||
| 590 | |||
| 499 | static int __devinit piix4_probe(struct pci_dev *dev, | 591 | static int __devinit piix4_probe(struct pci_dev *dev, |
| 500 | const struct pci_device_id *id) | 592 | const struct pci_device_id *id) |
| 501 | { | 593 | { |
| @@ -510,30 +602,52 @@ static int __devinit piix4_probe(struct pci_dev *dev, | |||
| 510 | else | 602 | else |
| 511 | retval = piix4_setup(dev, id); | 603 | retval = piix4_setup(dev, id); |
| 512 | 604 | ||
| 513 | if (retval) | 605 | /* If no main SMBus found, give up */ |
| 606 | if (retval < 0) | ||
| 514 | return retval; | 607 | return retval; |
| 515 | 608 | ||
| 516 | /* set up the sysfs linkage to our parent device */ | 609 | /* Try to register main SMBus adapter, give up if we can't */ |
| 517 | piix4_adapter.dev.parent = &dev->dev; | 610 | retval = piix4_add_adapter(dev, retval, &piix4_main_adapter); |
| 518 | 611 | if (retval < 0) | |
| 519 | snprintf(piix4_adapter.name, sizeof(piix4_adapter.name), | 612 | return retval; |
| 520 | "SMBus PIIX4 adapter at %04x", piix4_smba); | ||
| 521 | 613 | ||
| 522 | if ((retval = i2c_add_adapter(&piix4_adapter))) { | 614 | /* Check for auxiliary SMBus on some AMD chipsets */ |
| 523 | dev_err(&dev->dev, "Couldn't register adapter!\n"); | 615 | if (dev->vendor == PCI_VENDOR_ID_ATI && |
| 524 | release_region(piix4_smba, SMBIOSIZE); | 616 | dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && |
| 525 | piix4_smba = 0; | 617 | dev->revision < 0x40) { |
| 618 | retval = piix4_setup_aux(dev, id, 0x58); | ||
| 619 | if (retval > 0) { | ||
| 620 | /* Try to add the aux adapter if it exists, | ||
| 621 | * piix4_add_adapter will clean up if this fails */ | ||
| 622 | piix4_add_adapter(dev, retval, &piix4_aux_adapter); | ||
| 623 | } | ||
| 526 | } | 624 | } |
| 527 | 625 | ||
| 528 | return retval; | 626 | return 0; |
| 627 | } | ||
| 628 | |||
| 629 | static void __devexit piix4_adap_remove(struct i2c_adapter *adap) | ||
| 630 | { | ||
| 631 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap); | ||
| 632 | |||
| 633 | if (adapdata->smba) { | ||
| 634 | i2c_del_adapter(adap); | ||
| 635 | release_region(adapdata->smba, SMBIOSIZE); | ||
| 636 | kfree(adapdata); | ||
| 637 | kfree(adap); | ||
| 638 | } | ||
| 529 | } | 639 | } |
| 530 | 640 | ||
| 531 | static void __devexit piix4_remove(struct pci_dev *dev) | 641 | static void __devexit piix4_remove(struct pci_dev *dev) |
| 532 | { | 642 | { |
| 533 | if (piix4_smba) { | 643 | if (piix4_main_adapter) { |
| 534 | i2c_del_adapter(&piix4_adapter); | 644 | piix4_adap_remove(piix4_main_adapter); |
| 535 | release_region(piix4_smba, SMBIOSIZE); | 645 | piix4_main_adapter = NULL; |
| 536 | piix4_smba = 0; | 646 | } |
| 647 | |||
| 648 | if (piix4_aux_adapter) { | ||
| 649 | piix4_adap_remove(piix4_aux_adapter); | ||
| 650 | piix4_aux_adapter = NULL; | ||
| 537 | } | 651 | } |
| 538 | } | 652 | } |
| 539 | 653 | ||
| @@ -544,20 +658,9 @@ static struct pci_driver piix4_driver = { | |||
| 544 | .remove = __devexit_p(piix4_remove), | 658 | .remove = __devexit_p(piix4_remove), |
| 545 | }; | 659 | }; |
| 546 | 660 | ||
| 547 | static int __init i2c_piix4_init(void) | 661 | module_pci_driver(piix4_driver); |
| 548 | { | ||
| 549 | return pci_register_driver(&piix4_driver); | ||
| 550 | } | ||
| 551 | |||
| 552 | static void __exit i2c_piix4_exit(void) | ||
| 553 | { | ||
| 554 | pci_unregister_driver(&piix4_driver); | ||
| 555 | } | ||
| 556 | 662 | ||
| 557 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " | 663 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " |
| 558 | "Philip Edelbrock <phil@netroedge.com>"); | 664 | "Philip Edelbrock <phil@netroedge.com>"); |
| 559 | MODULE_DESCRIPTION("PIIX4 SMBus driver"); | 665 | MODULE_DESCRIPTION("PIIX4 SMBus driver"); |
| 560 | MODULE_LICENSE("GPL"); | 666 | MODULE_LICENSE("GPL"); |
| 561 | |||
| 562 | module_init(i2c_piix4_init); | ||
| 563 | module_exit(i2c_piix4_exit); | ||
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c index a05817980556..4dc9bef17d77 100644 --- a/drivers/i2c/busses/i2c-pxa-pci.c +++ b/drivers/i2c/busses/i2c-pxa-pci.c | |||
| @@ -163,17 +163,7 @@ static struct pci_driver ce4100_i2c_driver = { | |||
| 163 | .remove = __devexit_p(ce4100_i2c_remove), | 163 | .remove = __devexit_p(ce4100_i2c_remove), |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | static int __init ce4100_i2c_init(void) | 166 | module_pci_driver(ce4100_i2c_driver); |
| 167 | { | ||
| 168 | return pci_register_driver(&ce4100_i2c_driver); | ||
| 169 | } | ||
| 170 | module_init(ce4100_i2c_init); | ||
| 171 | |||
| 172 | static void __exit ce4100_i2c_exit(void) | ||
| 173 | { | ||
| 174 | pci_unregister_driver(&ce4100_i2c_driver); | ||
| 175 | } | ||
| 176 | module_exit(ce4100_i2c_exit); | ||
| 177 | 167 | ||
| 178 | MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver"); | 168 | MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver"); |
| 179 | MODULE_LICENSE("GPL v2"); | 169 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 15cf78f65ce0..5d6723b7525e 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c | |||
| @@ -513,21 +513,8 @@ static struct pci_driver sis630_driver = { | |||
| 513 | .remove = __devexit_p(sis630_remove), | 513 | .remove = __devexit_p(sis630_remove), |
| 514 | }; | 514 | }; |
| 515 | 515 | ||
| 516 | static int __init i2c_sis630_init(void) | 516 | module_pci_driver(sis630_driver); |
| 517 | { | ||
| 518 | return pci_register_driver(&sis630_driver); | ||
| 519 | } | ||
| 520 | |||
| 521 | |||
| 522 | static void __exit i2c_sis630_exit(void) | ||
| 523 | { | ||
| 524 | pci_unregister_driver(&sis630_driver); | ||
| 525 | } | ||
| 526 | |||
| 527 | 517 | ||
| 528 | MODULE_LICENSE("GPL"); | 518 | MODULE_LICENSE("GPL"); |
| 529 | MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>"); | 519 | MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>"); |
| 530 | MODULE_DESCRIPTION("SIS630 SMBus driver"); | 520 | MODULE_DESCRIPTION("SIS630 SMBus driver"); |
| 531 | |||
| 532 | module_init(i2c_sis630_init); | ||
| 533 | module_exit(i2c_sis630_exit); | ||
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index cc5d149413f7..7b72614a9bc0 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c | |||
| @@ -324,21 +324,8 @@ static struct pci_driver sis96x_driver = { | |||
| 324 | .remove = __devexit_p(sis96x_remove), | 324 | .remove = __devexit_p(sis96x_remove), |
| 325 | }; | 325 | }; |
| 326 | 326 | ||
| 327 | static int __init i2c_sis96x_init(void) | 327 | module_pci_driver(sis96x_driver); |
| 328 | { | ||
| 329 | return pci_register_driver(&sis96x_driver); | ||
| 330 | } | ||
| 331 | |||
| 332 | static void __exit i2c_sis96x_exit(void) | ||
| 333 | { | ||
| 334 | pci_unregister_driver(&sis96x_driver); | ||
| 335 | } | ||
| 336 | 328 | ||
| 337 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); | 329 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); |
| 338 | MODULE_DESCRIPTION("SiS96x SMBus driver"); | 330 | MODULE_DESCRIPTION("SiS96x SMBus driver"); |
| 339 | MODULE_LICENSE("GPL"); | 331 | MODULE_LICENSE("GPL"); |
| 340 | |||
| 341 | /* Register initialization functions using helper macros */ | ||
| 342 | module_init(i2c_sis96x_init); | ||
| 343 | module_exit(i2c_sis96x_exit); | ||
| 344 | |||
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index f07307ff360d..05106368d405 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c | |||
| @@ -143,6 +143,7 @@ static const struct i2c_algorithm usb_algorithm = { | |||
| 143 | static const struct usb_device_id i2c_tiny_usb_table[] = { | 143 | static const struct usb_device_id i2c_tiny_usb_table[] = { |
| 144 | { USB_DEVICE(0x0403, 0xc631) }, /* FTDI */ | 144 | { USB_DEVICE(0x0403, 0xc631) }, /* FTDI */ |
| 145 | { USB_DEVICE(0x1c40, 0x0534) }, /* EZPrototypes */ | 145 | { USB_DEVICE(0x1c40, 0x0534) }, /* EZPrototypes */ |
| 146 | { USB_DEVICE(0x1964, 0x0001) }, /* Robofuzz OSIF */ | ||
| 146 | { } /* Terminating entry */ | 147 | { } /* Terminating entry */ |
| 147 | }; | 148 | }; |
| 148 | 149 | ||
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 713d31ade26b..7ffee71ca190 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c | |||
| @@ -161,20 +161,8 @@ static struct pci_driver vt586b_driver = { | |||
| 161 | .remove = __devexit_p(vt586b_remove), | 161 | .remove = __devexit_p(vt586b_remove), |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
| 164 | static int __init i2c_vt586b_init(void) | 164 | module_pci_driver(vt586b_driver); |
| 165 | { | ||
| 166 | return pci_register_driver(&vt586b_driver); | ||
| 167 | } | ||
| 168 | |||
| 169 | static void __exit i2c_vt586b_exit(void) | ||
| 170 | { | ||
| 171 | pci_unregister_driver(&vt586b_driver); | ||
| 172 | } | ||
| 173 | |||
| 174 | 165 | ||
| 175 | MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>"); | 166 | MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>"); |
| 176 | MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge"); | 167 | MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge"); |
| 177 | MODULE_LICENSE("GPL"); | 168 | MODULE_LICENSE("GPL"); |
| 178 | |||
| 179 | module_init(i2c_vt586b_init); | ||
| 180 | module_exit(i2c_vt586b_exit); | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a6ad32bc0a96..26488aa893d5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -2122,7 +2122,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
| 2122 | int try; | 2122 | int try; |
| 2123 | s32 res; | 2123 | s32 res; |
| 2124 | 2124 | ||
| 2125 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | 2125 | flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; |
| 2126 | 2126 | ||
| 2127 | if (adapter->algo->smbus_xfer) { | 2127 | if (adapter->algo->smbus_xfer) { |
| 2128 | i2c_lock_adapter(adapter); | 2128 | i2c_lock_adapter(adapter); |
| @@ -2140,11 +2140,17 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
| 2140 | break; | 2140 | break; |
| 2141 | } | 2141 | } |
| 2142 | i2c_unlock_adapter(adapter); | 2142 | i2c_unlock_adapter(adapter); |
| 2143 | } else | ||
| 2144 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | ||
| 2145 | command, protocol, data); | ||
| 2146 | 2143 | ||
| 2147 | return res; | 2144 | if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) |
| 2145 | return res; | ||
| 2146 | /* | ||
| 2147 | * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't | ||
| 2148 | * implement native support for the SMBus operation. | ||
| 2149 | */ | ||
| 2150 | } | ||
| 2151 | |||
| 2152 | return i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | ||
| 2153 | command, protocol, data); | ||
| 2148 | } | 2154 | } |
| 2149 | EXPORT_SYMBOL(i2c_smbus_xfer); | 2155 | EXPORT_SYMBOL(i2c_smbus_xfer); |
| 2150 | 2156 | ||
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 9836d08f7a77..df3e0bf31eb3 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c | |||
| @@ -245,18 +245,7 @@ int i2c_handle_smbus_alert(struct i2c_client *ara) | |||
| 245 | } | 245 | } |
| 246 | EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert); | 246 | EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert); |
| 247 | 247 | ||
| 248 | static int __init i2c_smbus_init(void) | 248 | module_i2c_driver(smbalert_driver); |
| 249 | { | ||
| 250 | return i2c_add_driver(&smbalert_driver); | ||
| 251 | } | ||
| 252 | |||
| 253 | static void __exit i2c_smbus_exit(void) | ||
| 254 | { | ||
| 255 | i2c_del_driver(&smbalert_driver); | ||
| 256 | } | ||
| 257 | |||
| 258 | module_init(i2c_smbus_init); | ||
| 259 | module_exit(i2c_smbus_exit); | ||
| 260 | 249 | ||
| 261 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | 250 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); |
| 262 | MODULE_DESCRIPTION("SMBus protocol extensions support"); | 251 | MODULE_DESCRIPTION("SMBus protocol extensions support"); |
diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index 8aacde1516ac..f8f72f39e0b5 100644 --- a/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c | |||
| @@ -396,6 +396,6 @@ static struct i2c_driver pca9541_driver = { | |||
| 396 | 396 | ||
| 397 | module_i2c_driver(pca9541_driver); | 397 | module_i2c_driver(pca9541_driver); |
| 398 | 398 | ||
| 399 | MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); | 399 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
| 400 | MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); | 400 | MODULE_DESCRIPTION("PCA9541 I2C master selector driver"); |
| 401 | MODULE_LICENSE("GPL v2"); | 401 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/staging/media/go7007/wis-i2c.h b/drivers/staging/media/go7007/wis-i2c.h index 3c2b9be455df..6d09c06c8560 100644 --- a/drivers/staging/media/go7007/wis-i2c.h +++ b/drivers/staging/media/go7007/wis-i2c.h | |||
| @@ -25,11 +25,6 @@ | |||
| 25 | #define I2C_DRIVERID_WIS_TW2804 0xf0f6 | 25 | #define I2C_DRIVERID_WIS_TW2804 0xf0f6 |
| 26 | #define I2C_DRIVERID_S2250 0xf0f7 | 26 | #define I2C_DRIVERID_S2250 0xf0f7 |
| 27 | 27 | ||
| 28 | /* Flag to indicate that the client needs to be accessed with SCCB semantics */ | ||
| 29 | /* We re-use the I2C_M_TEN value so the flag passes through the masks in the | ||
| 30 | * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */ | ||
| 31 | #define I2C_CLIENT_SCCB 0x10 | ||
| 32 | |||
| 33 | /* Definitions for new video decoder commands */ | 28 | /* Definitions for new video decoder commands */ |
| 34 | 29 | ||
| 35 | struct video_decoder_resolution { | 30 | struct video_decoder_resolution { |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index ddfa04108baf..1d0fe4877b1f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
| @@ -425,6 +425,8 @@ void i2c_unlock_adapter(struct i2c_adapter *); | |||
| 425 | #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ | 425 | #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ |
| 426 | /* Must equal I2C_M_TEN below */ | 426 | /* Must equal I2C_M_TEN below */ |
| 427 | #define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */ | 427 | #define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */ |
| 428 | #define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */ | ||
| 429 | /* Must match I2C_M_STOP|IGNORE_NAK */ | ||
| 428 | 430 | ||
| 429 | /* i2c adapter classes (bitmask) */ | 431 | /* i2c adapter classes (bitmask) */ |
| 430 | #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ | 432 | #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ |
| @@ -541,6 +543,7 @@ struct i2c_msg { | |||
| 541 | __u16 flags; | 543 | __u16 flags; |
| 542 | #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ | 544 | #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ |
| 543 | #define I2C_M_RD 0x0001 /* read data, from slave to master */ | 545 | #define I2C_M_RD 0x0001 /* read data, from slave to master */ |
| 546 | #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */ | ||
| 544 | #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */ | 547 | #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */ |
| 545 | #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ | 548 | #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ |
| 546 | #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ | 549 | #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ |
