diff options
257 files changed, 4683 insertions, 2836 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 03641a08e275..8906648f962b 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
| @@ -268,10 +268,6 @@ | |||
| 268 | !Finclude/net/mac80211.h ieee80211_ops | 268 | !Finclude/net/mac80211.h ieee80211_ops |
| 269 | !Finclude/net/mac80211.h ieee80211_alloc_hw | 269 | !Finclude/net/mac80211.h ieee80211_alloc_hw |
| 270 | !Finclude/net/mac80211.h ieee80211_register_hw | 270 | !Finclude/net/mac80211.h ieee80211_register_hw |
| 271 | !Finclude/net/mac80211.h ieee80211_get_tx_led_name | ||
| 272 | !Finclude/net/mac80211.h ieee80211_get_rx_led_name | ||
| 273 | !Finclude/net/mac80211.h ieee80211_get_assoc_led_name | ||
| 274 | !Finclude/net/mac80211.h ieee80211_get_radio_led_name | ||
| 275 | !Finclude/net/mac80211.h ieee80211_unregister_hw | 271 | !Finclude/net/mac80211.h ieee80211_unregister_hw |
| 276 | !Finclude/net/mac80211.h ieee80211_free_hw | 272 | !Finclude/net/mac80211.h ieee80211_free_hw |
| 277 | </chapter> | 273 | </chapter> |
| @@ -382,6 +378,23 @@ | |||
| 382 | </para> | 378 | </para> |
| 383 | </partintro> | 379 | </partintro> |
| 384 | 380 | ||
| 381 | <chapter id="led-support"> | ||
| 382 | <title>LED support</title> | ||
| 383 | <para> | ||
| 384 | Mac80211 supports various ways of blinking LEDs. Wherever possible, | ||
| 385 | device LEDs should be exposed as LED class devices and hooked up to | ||
| 386 | the appropriate trigger, which will then be triggered appropriately | ||
| 387 | by mac80211. | ||
| 388 | </para> | ||
| 389 | !Finclude/net/mac80211.h ieee80211_get_tx_led_name | ||
| 390 | !Finclude/net/mac80211.h ieee80211_get_rx_led_name | ||
| 391 | !Finclude/net/mac80211.h ieee80211_get_assoc_led_name | ||
| 392 | !Finclude/net/mac80211.h ieee80211_get_radio_led_name | ||
| 393 | !Finclude/net/mac80211.h ieee80211_tpt_blink | ||
| 394 | !Finclude/net/mac80211.h ieee80211_tpt_led_trigger_flags | ||
| 395 | !Finclude/net/mac80211.h ieee80211_create_tpt_led_trigger | ||
| 396 | </chapter> | ||
| 397 | |||
| 385 | <chapter id="hardware-crypto-offload"> | 398 | <chapter id="hardware-crypto-offload"> |
| 386 | <title>Hardware crypto acceleration</title> | 399 | <title>Hardware crypto acceleration</title> |
| 387 | !Pinclude/net/mac80211.h Hardware crypto acceleration | 400 | !Pinclude/net/mac80211.h Hardware crypto acceleration |
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index bac328c232f5..7781857dc940 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt | |||
| @@ -385,10 +385,6 @@ mapped_file - # of bytes of mapped file (includes tmpfs/shmem) | |||
| 385 | pgpgin - # of pages paged in (equivalent to # of charging events). | 385 | pgpgin - # of pages paged in (equivalent to # of charging events). |
| 386 | pgpgout - # of pages paged out (equivalent to # of uncharging events). | 386 | pgpgout - # of pages paged out (equivalent to # of uncharging events). |
| 387 | swap - # of bytes of swap usage | 387 | swap - # of bytes of swap usage |
| 388 | dirty - # of bytes that are waiting to get written back to the disk. | ||
| 389 | writeback - # of bytes that are actively being written back to the disk. | ||
| 390 | nfs_unstable - # of bytes sent to the NFS server, but not yet committed to | ||
| 391 | the actual storage. | ||
| 392 | inactive_anon - # of bytes of anonymous memory and swap cache memory on | 388 | inactive_anon - # of bytes of anonymous memory and swap cache memory on |
| 393 | LRU list. | 389 | LRU list. |
| 394 | active_anon - # of bytes of anonymous and swap cache memory on active | 390 | active_anon - # of bytes of anonymous and swap cache memory on active |
| @@ -410,9 +406,6 @@ total_mapped_file - sum of all children's "cache" | |||
| 410 | total_pgpgin - sum of all children's "pgpgin" | 406 | total_pgpgin - sum of all children's "pgpgin" |
| 411 | total_pgpgout - sum of all children's "pgpgout" | 407 | total_pgpgout - sum of all children's "pgpgout" |
| 412 | total_swap - sum of all children's "swap" | 408 | total_swap - sum of all children's "swap" |
| 413 | total_dirty - sum of all children's "dirty" | ||
| 414 | total_writeback - sum of all children's "writeback" | ||
| 415 | total_nfs_unstable - sum of all children's "nfs_unstable" | ||
| 416 | total_inactive_anon - sum of all children's "inactive_anon" | 409 | total_inactive_anon - sum of all children's "inactive_anon" |
| 417 | total_active_anon - sum of all children's "active_anon" | 410 | total_active_anon - sum of all children's "active_anon" |
| 418 | total_inactive_file - sum of all children's "inactive_file" | 411 | total_inactive_file - sum of all children's "inactive_file" |
| @@ -460,73 +453,6 @@ memory under it will be reclaimed. | |||
| 460 | You can reset failcnt by writing 0 to failcnt file. | 453 | You can reset failcnt by writing 0 to failcnt file. |
| 461 | # echo 0 > .../memory.failcnt | 454 | # echo 0 > .../memory.failcnt |
| 462 | 455 | ||
| 463 | 5.5 dirty memory | ||
| 464 | |||
| 465 | Control the maximum amount of dirty pages a cgroup can have at any given time. | ||
| 466 | |||
| 467 | Limiting dirty memory is like fixing the max amount of dirty (hard to reclaim) | ||
| 468 | page cache used by a cgroup. So, in case of multiple cgroup writers, they will | ||
| 469 | not be able to consume more than their designated share of dirty pages and will | ||
| 470 | be forced to perform write-out if they cross that limit. | ||
| 471 | |||
| 472 | The interface is equivalent to the procfs interface: /proc/sys/vm/dirty_*. It | ||
| 473 | is possible to configure a limit to trigger both a direct writeback or a | ||
| 474 | background writeback performed by per-bdi flusher threads. The root cgroup | ||
| 475 | memory.dirty_* control files are read-only and match the contents of | ||
| 476 | the /proc/sys/vm/dirty_* files. | ||
| 477 | |||
| 478 | Per-cgroup dirty limits can be set using the following files in the cgroupfs: | ||
| 479 | |||
| 480 | - memory.dirty_ratio: the amount of dirty memory (expressed as a percentage of | ||
| 481 | cgroup memory) at which a process generating dirty pages will itself start | ||
| 482 | writing out dirty data. | ||
| 483 | |||
| 484 | - memory.dirty_limit_in_bytes: the amount of dirty memory (expressed in bytes) | ||
| 485 | in the cgroup at which a process generating dirty pages will start itself | ||
| 486 | writing out dirty data. Suffix (k, K, m, M, g, or G) can be used to indicate | ||
| 487 | that value is kilo, mega or gigabytes. | ||
| 488 | |||
| 489 | Note: memory.dirty_limit_in_bytes is the counterpart of memory.dirty_ratio. | ||
| 490 | Only one of them may be specified at a time. When one is written it is | ||
| 491 | immediately taken into account to evaluate the dirty memory limits and the | ||
| 492 | other appears as 0 when read. | ||
| 493 | |||
| 494 | - memory.dirty_background_ratio: the amount of dirty memory of the cgroup | ||
| 495 | (expressed as a percentage of cgroup memory) at which background writeback | ||
| 496 | kernel threads will start writing out dirty data. | ||
| 497 | |||
| 498 | - memory.dirty_background_limit_in_bytes: the amount of dirty memory (expressed | ||
| 499 | in bytes) in the cgroup at which background writeback kernel threads will | ||
| 500 | start writing out dirty data. Suffix (k, K, m, M, g, or G) can be used to | ||
| 501 | indicate that value is kilo, mega or gigabytes. | ||
| 502 | |||
| 503 | Note: memory.dirty_background_limit_in_bytes is the counterpart of | ||
| 504 | memory.dirty_background_ratio. Only one of them may be specified at a time. | ||
| 505 | When one is written it is immediately taken into account to evaluate the dirty | ||
| 506 | memory limits and the other appears as 0 when read. | ||
| 507 | |||
| 508 | A cgroup may contain more dirty memory than its dirty limit. This is possible | ||
| 509 | because of the principle that the first cgroup to touch a page is charged for | ||
| 510 | it. Subsequent page counting events (dirty, writeback, nfs_unstable) are also | ||
| 511 | counted to the originally charged cgroup. | ||
| 512 | |||
| 513 | Example: If page is allocated by a cgroup A task, then the page is charged to | ||
| 514 | cgroup A. If the page is later dirtied by a task in cgroup B, then the cgroup A | ||
| 515 | dirty count will be incremented. If cgroup A is over its dirty limit but cgroup | ||
| 516 | B is not, then dirtying a cgroup A page from a cgroup B task may push cgroup A | ||
| 517 | over its dirty limit without throttling the dirtying cgroup B task. | ||
| 518 | |||
| 519 | When use_hierarchy=0, each cgroup has dirty memory usage and limits. | ||
| 520 | System-wide dirty limits are also consulted. Dirty memory consumption is | ||
| 521 | checked against both system-wide and per-cgroup dirty limits. | ||
| 522 | |||
| 523 | The current implementation does not enforce per-cgroup dirty limits when | ||
| 524 | use_hierarchy=1. System-wide dirty limits are used for processes in such | ||
| 525 | cgroups. Attempts to read memory.dirty_* files return the system-wide | ||
| 526 | values. Writes to the memory.dirty_* files return error. An enhanced | ||
| 527 | implementation is needed to check the chain of parents to ensure that no | ||
| 528 | dirty limit is exceeded. | ||
| 529 | |||
| 530 | 6. Hierarchy support | 456 | 6. Hierarchy support |
| 531 | 457 | ||
| 532 | The memory controller supports a deep hierarchy and hierarchical accounting. | 458 | The memory controller supports a deep hierarchy and hierarchical accounting. |
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 977d8919cc69..ef9349a4b5d1 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
| @@ -343,7 +343,6 @@ prototypes: | |||
| 343 | int (*fl_grant)(struct file_lock *, struct file_lock *, int); | 343 | int (*fl_grant)(struct file_lock *, struct file_lock *, int); |
| 344 | void (*fl_release_private)(struct file_lock *); | 344 | void (*fl_release_private)(struct file_lock *); |
| 345 | void (*fl_break)(struct file_lock *); /* break_lease callback */ | 345 | void (*fl_break)(struct file_lock *); /* break_lease callback */ |
| 346 | int (*fl_mylease)(struct file_lock *, struct file_lock *); | ||
| 347 | int (*fl_change)(struct file_lock **, int); | 346 | int (*fl_change)(struct file_lock **, int); |
| 348 | 347 | ||
| 349 | locking rules: | 348 | locking rules: |
| @@ -353,7 +352,6 @@ fl_notify: yes no | |||
| 353 | fl_grant: no no | 352 | fl_grant: no no |
| 354 | fl_release_private: maybe no | 353 | fl_release_private: maybe no |
| 355 | fl_break: yes no | 354 | fl_break: yes no |
| 356 | fl_mylease: yes no | ||
| 357 | fl_change yes no | 355 | fl_change yes no |
| 358 | 356 | ||
| 359 | --------------------------- buffer_head ----------------------------------- | 357 | --------------------------- buffer_head ----------------------------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index af656ded404e..89e4d4b145bb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -5272,8 +5272,7 @@ S: Supported | |||
| 5272 | F: drivers/s390/net/ | 5272 | F: drivers/s390/net/ |
| 5273 | 5273 | ||
| 5274 | S390 ZCRYPT DRIVER | 5274 | S390 ZCRYPT DRIVER |
| 5275 | M: Felix Beck <felix.beck@de.ibm.com> | 5275 | M: Holger Dengler <hd@linux.vnet.ibm.com> |
| 5276 | M: Ralph Wuerthner <ralph.wuerthner@de.ibm.com> | ||
| 5277 | M: linux390@de.ibm.com | 5276 | M: linux390@de.ibm.com |
| 5278 | L: linux-s390@vger.kernel.org | 5277 | L: linux-s390@vger.kernel.org |
| 5279 | W: http://www.ibm.com/developerworks/linux/linux390/ | 5278 | W: http://www.ibm.com/developerworks/linux/linux390/ |
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index a70bdf28e2bc..07d1b20b1148 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
| @@ -554,6 +554,7 @@ static void __init omap_sfh7741prox_init(void) | |||
| 554 | 554 | ||
| 555 | #ifdef CONFIG_OMAP_MUX | 555 | #ifdef CONFIG_OMAP_MUX |
| 556 | static struct omap_board_mux board_mux[] __initdata = { | 556 | static struct omap_board_mux board_mux[] __initdata = { |
| 557 | OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), | ||
| 557 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 558 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
| 558 | }; | 559 | }; |
| 559 | #else | 560 | #else |
| @@ -576,11 +577,12 @@ static void __init omap_4430sdp_init(void) | |||
| 576 | omap4_twl6030_hsmmc_init(mmc); | 577 | omap4_twl6030_hsmmc_init(mmc); |
| 577 | 578 | ||
| 578 | /* Power on the ULPI PHY */ | 579 | /* Power on the ULPI PHY */ |
| 579 | if (gpio_is_valid(OMAP4SDP_MDM_PWR_EN_GPIO)) { | 580 | status = gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3"); |
| 580 | /* FIXME: Assumes pad is already muxed for GPIO mode */ | 581 | if (status) |
| 581 | gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3"); | 582 | pr_err("%s: Could not get USBB1 PHY GPIO\n", __func__); |
| 583 | else | ||
| 582 | gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); | 584 | gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); |
| 583 | } | 585 | |
| 584 | usb_ehci_init(&ehci_pdata); | 586 | usb_ehci_init(&ehci_pdata); |
| 585 | usb_musb_init(&musb_board_data); | 587 | usb_musb_init(&musb_board_data); |
| 586 | 588 | ||
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index ebaa230e67ed..3be85a1f55f4 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/input.h> | ||
| 20 | 21 | ||
| 21 | #include <linux/regulator/machine.h> | 22 | #include <linux/regulator/machine.h> |
| 22 | #include <linux/regulator/fixed.h> | 23 | #include <linux/regulator/fixed.h> |
| @@ -541,6 +542,37 @@ static struct twl4030_codec_data igep2_codec_data = { | |||
| 541 | .audio = &igep2_audio_data, | 542 | .audio = &igep2_audio_data, |
| 542 | }; | 543 | }; |
| 543 | 544 | ||
| 545 | static int igep2_keymap[] = { | ||
| 546 | KEY(0, 0, KEY_LEFT), | ||
| 547 | KEY(0, 1, KEY_RIGHT), | ||
| 548 | KEY(0, 2, KEY_A), | ||
| 549 | KEY(0, 3, KEY_B), | ||
| 550 | KEY(1, 0, KEY_DOWN), | ||
| 551 | KEY(1, 1, KEY_UP), | ||
| 552 | KEY(1, 2, KEY_E), | ||
| 553 | KEY(1, 3, KEY_F), | ||
| 554 | KEY(2, 0, KEY_ENTER), | ||
| 555 | KEY(2, 1, KEY_I), | ||
| 556 | KEY(2, 2, KEY_J), | ||
| 557 | KEY(2, 3, KEY_K), | ||
| 558 | KEY(3, 0, KEY_M), | ||
| 559 | KEY(3, 1, KEY_N), | ||
| 560 | KEY(3, 2, KEY_O), | ||
| 561 | KEY(3, 3, KEY_P) | ||
| 562 | }; | ||
| 563 | |||
| 564 | static struct matrix_keymap_data igep2_keymap_data = { | ||
| 565 | .keymap = igep2_keymap, | ||
| 566 | .keymap_size = ARRAY_SIZE(igep2_keymap), | ||
| 567 | }; | ||
| 568 | |||
| 569 | static struct twl4030_keypad_data igep2_keypad_pdata = { | ||
| 570 | .keymap_data = &igep2_keymap_data, | ||
| 571 | .rows = 4, | ||
| 572 | .cols = 4, | ||
| 573 | .rep = 1, | ||
| 574 | }; | ||
| 575 | |||
| 544 | static struct twl4030_platform_data igep2_twldata = { | 576 | static struct twl4030_platform_data igep2_twldata = { |
| 545 | .irq_base = TWL4030_IRQ_BASE, | 577 | .irq_base = TWL4030_IRQ_BASE, |
| 546 | .irq_end = TWL4030_IRQ_END, | 578 | .irq_end = TWL4030_IRQ_END, |
| @@ -549,6 +581,7 @@ static struct twl4030_platform_data igep2_twldata = { | |||
| 549 | .usb = &igep2_usb_data, | 581 | .usb = &igep2_usb_data, |
| 550 | .codec = &igep2_codec_data, | 582 | .codec = &igep2_codec_data, |
| 551 | .gpio = &igep2_twl4030_gpio_pdata, | 583 | .gpio = &igep2_twl4030_gpio_pdata, |
| 584 | .keypad = &igep2_keypad_pdata, | ||
| 552 | .vmmc1 = &igep2_vmmc1, | 585 | .vmmc1 = &igep2_vmmc1, |
| 553 | .vpll2 = &igep2_vpll2, | 586 | .vpll2 = &igep2_vpll2, |
| 554 | .vio = &igep2_vio, | 587 | .vio = &igep2_vio, |
diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c index bcccd68f1856..4dc62a9b9cb2 100644 --- a/arch/arm/mach-omap2/board-igep0030.c +++ b/arch/arm/mach-omap2/board-igep0030.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | 20 | ||
| 21 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
| 22 | #include <linux/regulator/fixed.h> | ||
| 22 | #include <linux/i2c/twl.h> | 23 | #include <linux/i2c/twl.h> |
| 23 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
| 24 | 25 | ||
| @@ -43,7 +44,7 @@ | |||
| 43 | #define IGEP3_GPIO_WIFI_NRESET 139 | 44 | #define IGEP3_GPIO_WIFI_NRESET 139 |
| 44 | #define IGEP3_GPIO_BT_NRESET 137 | 45 | #define IGEP3_GPIO_BT_NRESET 137 |
| 45 | 46 | ||
| 46 | #define IGEP3_GPIO_USBH_NRESET 115 | 47 | #define IGEP3_GPIO_USBH_NRESET 183 |
| 47 | 48 | ||
| 48 | 49 | ||
| 49 | #if defined(CONFIG_MTD_ONENAND_OMAP2) || \ | 50 | #if defined(CONFIG_MTD_ONENAND_OMAP2) || \ |
| @@ -103,7 +104,7 @@ static struct platform_device igep3_onenand_device = { | |||
| 103 | }, | 104 | }, |
| 104 | }; | 105 | }; |
| 105 | 106 | ||
| 106 | void __init igep3_flash_init(void) | 107 | static void __init igep3_flash_init(void) |
| 107 | { | 108 | { |
| 108 | u8 cs = 0; | 109 | u8 cs = 0; |
| 109 | u8 onenandcs = GPMC_CS_NUM + 1; | 110 | u8 onenandcs = GPMC_CS_NUM + 1; |
| @@ -137,12 +138,11 @@ void __init igep3_flash_init(void) | |||
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | #else | 140 | #else |
| 140 | void __init igep3_flash_init(void) {} | 141 | static void __init igep3_flash_init(void) {} |
| 141 | #endif | 142 | #endif |
| 142 | 143 | ||
| 143 | static struct regulator_consumer_supply igep3_vmmc1_supply = { | 144 | static struct regulator_consumer_supply igep3_vmmc1_supply = |
| 144 | .supply = "vmmc", | 145 | REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"); |
| 145 | }; | ||
| 146 | 146 | ||
| 147 | /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ | 147 | /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ |
| 148 | static struct regulator_init_data igep3_vmmc1 = { | 148 | static struct regulator_init_data igep3_vmmc1 = { |
| @@ -159,6 +159,52 @@ static struct regulator_init_data igep3_vmmc1 = { | |||
| 159 | .consumer_supplies = &igep3_vmmc1_supply, | 159 | .consumer_supplies = &igep3_vmmc1_supply, |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static struct regulator_consumer_supply igep3_vio_supply = | ||
| 163 | REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1"); | ||
| 164 | |||
| 165 | static struct regulator_init_data igep3_vio = { | ||
| 166 | .constraints = { | ||
| 167 | .min_uV = 1800000, | ||
| 168 | .max_uV = 1800000, | ||
| 169 | .apply_uV = 1, | ||
| 170 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
| 171 | | REGULATOR_MODE_STANDBY, | ||
| 172 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
| 173 | | REGULATOR_CHANGE_MODE | ||
| 174 | | REGULATOR_CHANGE_STATUS, | ||
| 175 | }, | ||
| 176 | .num_consumer_supplies = 1, | ||
| 177 | .consumer_supplies = &igep3_vio_supply, | ||
| 178 | }; | ||
| 179 | |||
| 180 | static struct regulator_consumer_supply igep3_vmmc2_supply = | ||
| 181 | REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"); | ||
| 182 | |||
| 183 | static struct regulator_init_data igep3_vmmc2 = { | ||
| 184 | .constraints = { | ||
| 185 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
| 186 | .always_on = 1, | ||
| 187 | }, | ||
| 188 | .num_consumer_supplies = 1, | ||
| 189 | .consumer_supplies = &igep3_vmmc2_supply, | ||
| 190 | }; | ||
| 191 | |||
| 192 | static struct fixed_voltage_config igep3_vwlan = { | ||
| 193 | .supply_name = "vwlan", | ||
| 194 | .microvolts = 3300000, | ||
| 195 | .gpio = -EINVAL, | ||
| 196 | .enabled_at_boot = 1, | ||
| 197 | .init_data = &igep3_vmmc2, | ||
| 198 | }; | ||
| 199 | |||
| 200 | static struct platform_device igep3_vwlan_device = { | ||
| 201 | .name = "reg-fixed-voltage", | ||
| 202 | .id = 0, | ||
| 203 | .dev = { | ||
| 204 | .platform_data = &igep3_vwlan, | ||
| 205 | }, | ||
| 206 | }; | ||
| 207 | |||
| 162 | static struct omap2_hsmmc_info mmc[] = { | 208 | static struct omap2_hsmmc_info mmc[] = { |
| 163 | [0] = { | 209 | [0] = { |
| 164 | .mmc = 1, | 210 | .mmc = 1, |
| @@ -254,12 +300,6 @@ static int igep3_twl4030_gpio_setup(struct device *dev, | |||
| 254 | mmc[0].gpio_cd = gpio + 0; | 300 | mmc[0].gpio_cd = gpio + 0; |
| 255 | omap2_hsmmc_init(mmc); | 301 | omap2_hsmmc_init(mmc); |
| 256 | 302 | ||
| 257 | /* | ||
| 258 | * link regulators to MMC adapters ... we "know" the | ||
| 259 | * regulators will be set up only *after* we return. | ||
| 260 | */ | ||
| 261 | igep3_vmmc1_supply.dev = mmc[0].dev; | ||
| 262 | |||
| 263 | /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ | 303 | /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ |
| 264 | #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) | 304 | #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) |
| 265 | if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0) | 305 | if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0) |
| @@ -287,6 +327,10 @@ static struct twl4030_usb_data igep3_twl4030_usb_data = { | |||
| 287 | .usb_mode = T2_USB_MODE_ULPI, | 327 | .usb_mode = T2_USB_MODE_ULPI, |
| 288 | }; | 328 | }; |
| 289 | 329 | ||
| 330 | static struct platform_device *igep3_devices[] __initdata = { | ||
| 331 | &igep3_vwlan_device, | ||
| 332 | }; | ||
| 333 | |||
| 290 | static void __init igep3_init_irq(void) | 334 | static void __init igep3_init_irq(void) |
| 291 | { | 335 | { |
| 292 | omap2_init_common_infrastructure(); | 336 | omap2_init_common_infrastructure(); |
| @@ -303,6 +347,7 @@ static struct twl4030_platform_data igep3_twl4030_pdata = { | |||
| 303 | .usb = &igep3_twl4030_usb_data, | 347 | .usb = &igep3_twl4030_usb_data, |
| 304 | .gpio = &igep3_twl4030_gpio_pdata, | 348 | .gpio = &igep3_twl4030_gpio_pdata, |
| 305 | .vmmc1 = &igep3_vmmc1, | 349 | .vmmc1 = &igep3_vmmc1, |
| 350 | .vio = &igep3_vio, | ||
| 306 | }; | 351 | }; |
| 307 | 352 | ||
| 308 | static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = { | 353 | static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = { |
| @@ -363,8 +408,20 @@ static void __init igep3_wifi_bt_init(void) | |||
| 363 | void __init igep3_wifi_bt_init(void) {} | 408 | void __init igep3_wifi_bt_init(void) {} |
| 364 | #endif | 409 | #endif |
| 365 | 410 | ||
| 411 | static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { | ||
| 412 | .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, | ||
| 413 | .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, | ||
| 414 | .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, | ||
| 415 | |||
| 416 | .phy_reset = true, | ||
| 417 | .reset_gpio_port[0] = -EINVAL, | ||
| 418 | .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET, | ||
| 419 | .reset_gpio_port[2] = -EINVAL, | ||
| 420 | }; | ||
| 421 | |||
| 366 | #ifdef CONFIG_OMAP_MUX | 422 | #ifdef CONFIG_OMAP_MUX |
| 367 | static struct omap_board_mux board_mux[] __initdata = { | 423 | static struct omap_board_mux board_mux[] __initdata = { |
| 424 | OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), | ||
| 368 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 425 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
| 369 | }; | 426 | }; |
| 370 | #endif | 427 | #endif |
| @@ -375,9 +432,10 @@ static void __init igep3_init(void) | |||
| 375 | 432 | ||
| 376 | /* Register I2C busses and drivers */ | 433 | /* Register I2C busses and drivers */ |
| 377 | igep3_i2c_init(); | 434 | igep3_i2c_init(); |
| 378 | 435 | platform_add_devices(igep3_devices, ARRAY_SIZE(igep3_devices)); | |
| 379 | omap_serial_init(); | 436 | omap_serial_init(); |
| 380 | usb_musb_init(&musb_board_data); | 437 | usb_musb_init(&musb_board_data); |
| 438 | usb_ehci_init(&ehci_pdata); | ||
| 381 | 439 | ||
| 382 | igep3_flash_init(); | 440 | igep3_flash_init(); |
| 383 | igep3_leds_init(); | 441 | igep3_leds_init(); |
| @@ -392,6 +450,7 @@ static void __init igep3_init(void) | |||
| 392 | 450 | ||
| 393 | MACHINE_START(IGEP0030, "IGEP OMAP3 module") | 451 | MACHINE_START(IGEP0030, "IGEP OMAP3 module") |
| 394 | .boot_params = 0x80000100, | 452 | .boot_params = 0x80000100, |
| 453 | .reserve = omap_reserve, | ||
| 395 | .map_io = omap3_map_io, | 454 | .map_io = omap3_map_io, |
| 396 | .init_irq = igep3_init_irq, | 455 | .init_irq = igep3_init_irq, |
| 397 | .init_machine = igep3_init, | 456 | .init_machine = igep3_init, |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index a4fe8e1ee1bd..46d814ab5656 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
| @@ -207,7 +207,7 @@ static struct omap_dss_device beagle_dvi_device = { | |||
| 207 | .driver_name = "generic_dpi_panel", | 207 | .driver_name = "generic_dpi_panel", |
| 208 | .data = &dvi_panel, | 208 | .data = &dvi_panel, |
| 209 | .phy.dpi.data_lines = 24, | 209 | .phy.dpi.data_lines = 24, |
| 210 | .reset_gpio = 170, | 210 | .reset_gpio = -EINVAL, |
| 211 | }; | 211 | }; |
| 212 | 212 | ||
| 213 | static struct omap_dss_device beagle_tv_device = { | 213 | static struct omap_dss_device beagle_tv_device = { |
| @@ -279,6 +279,8 @@ static struct gpio_led gpio_leds[]; | |||
| 279 | static int beagle_twl_gpio_setup(struct device *dev, | 279 | static int beagle_twl_gpio_setup(struct device *dev, |
| 280 | unsigned gpio, unsigned ngpio) | 280 | unsigned gpio, unsigned ngpio) |
| 281 | { | 281 | { |
| 282 | int r; | ||
| 283 | |||
| 282 | if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { | 284 | if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { |
| 283 | mmc[0].gpio_wp = -EINVAL; | 285 | mmc[0].gpio_wp = -EINVAL; |
| 284 | } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) || | 286 | } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) || |
| @@ -299,17 +301,63 @@ static int beagle_twl_gpio_setup(struct device *dev, | |||
| 299 | /* REVISIT: need ehci-omap hooks for external VBUS | 301 | /* REVISIT: need ehci-omap hooks for external VBUS |
| 300 | * power switch and overcurrent detect | 302 | * power switch and overcurrent detect |
| 301 | */ | 303 | */ |
| 304 | if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) { | ||
| 305 | r = gpio_request(gpio + 1, "EHCI_nOC"); | ||
| 306 | if (!r) { | ||
| 307 | r = gpio_direction_input(gpio + 1); | ||
| 308 | if (r) | ||
| 309 | gpio_free(gpio + 1); | ||
| 310 | } | ||
| 311 | if (r) | ||
| 312 | pr_err("%s: unable to configure EHCI_nOC\n", __func__); | ||
| 313 | } | ||
| 302 | 314 | ||
| 303 | gpio_request(gpio + 1, "EHCI_nOC"); | 315 | /* |
| 304 | gpio_direction_input(gpio + 1); | 316 | * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active |
| 305 | 317 | * high / others active low) | |
| 306 | /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ | 318 | */ |
| 307 | gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); | 319 | gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); |
| 308 | gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); | 320 | if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) |
| 321 | gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); | ||
| 322 | else | ||
| 323 | gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); | ||
| 324 | |||
| 325 | /* DVI reset GPIO is different between beagle revisions */ | ||
| 326 | if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) | ||
| 327 | beagle_dvi_device.reset_gpio = 129; | ||
| 328 | else | ||
| 329 | beagle_dvi_device.reset_gpio = 170; | ||
| 309 | 330 | ||
| 310 | /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ | 331 | /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ |
| 311 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; | 332 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; |
| 312 | 333 | ||
| 334 | /* | ||
| 335 | * gpio + 1 on Xm controls the TFP410's enable line (active low) | ||
| 336 | * gpio + 2 control varies depending on the board rev as follows: | ||
| 337 | * P7/P8 revisions(prototype): Camera EN | ||
| 338 | * A2+ revisions (production): LDO (supplies DVI, serial, led blocks) | ||
| 339 | */ | ||
| 340 | if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { | ||
| 341 | r = gpio_request(gpio + 1, "nDVI_PWR_EN"); | ||
| 342 | if (!r) { | ||
| 343 | r = gpio_direction_output(gpio + 1, 0); | ||
| 344 | if (r) | ||
| 345 | gpio_free(gpio + 1); | ||
| 346 | } | ||
| 347 | if (r) | ||
| 348 | pr_err("%s: unable to configure nDVI_PWR_EN\n", | ||
| 349 | __func__); | ||
| 350 | r = gpio_request(gpio + 2, "DVI_LDO_EN"); | ||
| 351 | if (!r) { | ||
| 352 | r = gpio_direction_output(gpio + 2, 1); | ||
| 353 | if (r) | ||
| 354 | gpio_free(gpio + 2); | ||
| 355 | } | ||
| 356 | if (r) | ||
| 357 | pr_err("%s: unable to configure DVI_LDO_EN\n", | ||
| 358 | __func__); | ||
| 359 | } | ||
| 360 | |||
| 313 | return 0; | 361 | return 0; |
| 314 | } | 362 | } |
| 315 | 363 | ||
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 3094e2007844..e001a048dc0c 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/clk.h> | ||
| 22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 23 | #include <linux/leds.h> | 24 | #include <linux/leds.h> |
| 24 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
| @@ -95,7 +96,16 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { | |||
| 95 | static void __init omap4_ehci_init(void) | 96 | static void __init omap4_ehci_init(void) |
| 96 | { | 97 | { |
| 97 | int ret; | 98 | int ret; |
| 99 | struct clk *phy_ref_clk; | ||
| 98 | 100 | ||
| 101 | /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ | ||
| 102 | phy_ref_clk = clk_get(NULL, "auxclk3_ck"); | ||
| 103 | if (IS_ERR(phy_ref_clk)) { | ||
| 104 | pr_err("Cannot request auxclk3\n"); | ||
| 105 | goto error1; | ||
| 106 | } | ||
| 107 | clk_set_rate(phy_ref_clk, 19200000); | ||
| 108 | clk_enable(phy_ref_clk); | ||
| 99 | 109 | ||
| 100 | /* disable the power to the usb hub prior to init */ | 110 | /* disable the power to the usb hub prior to init */ |
| 101 | ret = gpio_request(GPIO_HUB_POWER, "hub_power"); | 111 | ret = gpio_request(GPIO_HUB_POWER, "hub_power"); |
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 14d95afa3f0d..e0e040f34c68 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c | |||
| @@ -192,7 +192,7 @@ static struct platform_device omap_vwlan_device = { | |||
| 192 | }, | 192 | }, |
| 193 | }; | 193 | }; |
| 194 | 194 | ||
| 195 | struct wl12xx_platform_data omap_zoom_wlan_data __initdata = { | 195 | static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = { |
| 196 | .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO), | 196 | .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO), |
| 197 | /* ZOOM ref clock is 26 MHz */ | 197 | /* ZOOM ref clock is 26 MHz */ |
| 198 | .board_ref_clock = 1, | 198 | .board_ref_clock = 1, |
| @@ -286,7 +286,7 @@ static int zoom_twl_gpio_setup(struct device *dev, | |||
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | /* EXTMUTE callback function */ | 288 | /* EXTMUTE callback function */ |
| 289 | void zoom2_set_hs_extmute(int mute) | 289 | static void zoom2_set_hs_extmute(int mute) |
| 290 | { | 290 | { |
| 291 | gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute); | 291 | gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute); |
| 292 | } | 292 | } |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index d3ab1c9e50b0..403a4a1d3f9c 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
| @@ -3286,7 +3286,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
| 3286 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3286 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3287 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3287 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3288 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3288 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3289 | CLK("ehci-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX), | 3289 | CLK("ehci-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
| 3290 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), | 3290 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), |
| 3291 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), | 3291 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), |
| 3292 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), | 3292 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), |
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index de3faa20b46b..9b459c26fb85 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h | |||
| @@ -103,9 +103,7 @@ struct clockdomain { | |||
| 103 | const char *name; | 103 | const char *name; |
| 104 | struct powerdomain *ptr; | 104 | struct powerdomain *ptr; |
| 105 | } pwrdm; | 105 | } pwrdm; |
| 106 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
| 107 | const u16 clktrctrl_mask; | 106 | const u16 clktrctrl_mask; |
| 108 | #endif | ||
| 109 | const u8 flags; | 107 | const u8 flags; |
| 110 | const u8 dep_bit; | 108 | const u8 dep_bit; |
| 111 | const u8 prcm_partition; | 109 | const u8 prcm_partition; |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 381f4eb92352..2c9c912f2c42 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
| @@ -978,7 +978,7 @@ static int __init omap2_init_devices(void) | |||
| 978 | arch_initcall(omap2_init_devices); | 978 | arch_initcall(omap2_init_devices); |
| 979 | 979 | ||
| 980 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) | 980 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) |
| 981 | struct omap_device_pm_latency omap_wdt_latency[] = { | 981 | static struct omap_device_pm_latency omap_wdt_latency[] = { |
| 982 | [0] = { | 982 | [0] = { |
| 983 | .deactivate_func = omap_device_idle_hwmods, | 983 | .deactivate_func = omap_device_idle_hwmods, |
| 984 | .activate_func = omap_device_enable_hwmods, | 984 | .activate_func = omap_device_enable_hwmods, |
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 17bd6394d224..df8d2f2872c6 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
| @@ -893,7 +893,7 @@ static struct omap_mux * __init omap_mux_list_add( | |||
| 893 | return NULL; | 893 | return NULL; |
| 894 | 894 | ||
| 895 | m = &entry->mux; | 895 | m = &entry->mux; |
| 896 | memcpy(m, src, sizeof(struct omap_mux_entry)); | 896 | entry->mux = *src; |
| 897 | 897 | ||
| 898 | #ifdef CONFIG_OMAP_MUX | 898 | #ifdef CONFIG_OMAP_MUX |
| 899 | if (omap_mux_copy_names(src, m)) { | 899 | if (omap_mux_copy_names(src, m)) { |
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c index 440c98e9a510..17f80e4ab162 100644 --- a/arch/arm/mach-omap2/mux34xx.c +++ b/arch/arm/mach-omap2/mux34xx.c | |||
| @@ -703,7 +703,7 @@ static struct omap_mux __initdata omap3_muxmodes[] = { | |||
| 703 | * Signals different on CBC package compared to the superset | 703 | * Signals different on CBC package compared to the superset |
| 704 | */ | 704 | */ |
| 705 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC) | 705 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC) |
| 706 | struct omap_mux __initdata omap3_cbc_subset[] = { | 706 | static struct omap_mux __initdata omap3_cbc_subset[] = { |
| 707 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 707 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
| 708 | }; | 708 | }; |
| 709 | #else | 709 | #else |
| @@ -721,7 +721,7 @@ struct omap_mux __initdata omap3_cbc_subset[] = { | |||
| 721 | */ | 721 | */ |
| 722 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ | 722 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ |
| 723 | && defined(CONFIG_OMAP_PACKAGE_CBC) | 723 | && defined(CONFIG_OMAP_PACKAGE_CBC) |
| 724 | struct omap_ball __initdata omap3_cbc_ball[] = { | 724 | static struct omap_ball __initdata omap3_cbc_ball[] = { |
| 725 | _OMAP3_BALLENTRY(CAM_D0, "ae16", NULL), | 725 | _OMAP3_BALLENTRY(CAM_D0, "ae16", NULL), |
| 726 | _OMAP3_BALLENTRY(CAM_D1, "ae15", NULL), | 726 | _OMAP3_BALLENTRY(CAM_D1, "ae15", NULL), |
| 727 | _OMAP3_BALLENTRY(CAM_D10, "d25", NULL), | 727 | _OMAP3_BALLENTRY(CAM_D10, "d25", NULL), |
diff --git a/arch/arm/mach-omap2/mux44xx.c b/arch/arm/mach-omap2/mux44xx.c index 980f11d45c79..c322e7bdaa17 100644 --- a/arch/arm/mach-omap2/mux44xx.c +++ b/arch/arm/mach-omap2/mux44xx.c | |||
| @@ -544,7 +544,7 @@ static struct omap_mux __initdata omap4_core_muxmodes[] = { | |||
| 544 | */ | 544 | */ |
| 545 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ | 545 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ |
| 546 | && defined(CONFIG_OMAP_PACKAGE_CBL) | 546 | && defined(CONFIG_OMAP_PACKAGE_CBL) |
| 547 | struct omap_ball __initdata omap4_core_cbl_ball[] = { | 547 | static struct omap_ball __initdata omap4_core_cbl_ball[] = { |
| 548 | _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL), | 548 | _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL), |
| 549 | _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL), | 549 | _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL), |
| 550 | _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL), | 550 | _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL), |
| @@ -1262,7 +1262,7 @@ static struct omap_mux __initdata omap4_es2_core_muxmodes[] = { | |||
| 1262 | */ | 1262 | */ |
| 1263 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ | 1263 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ |
| 1264 | && defined(CONFIG_OMAP_PACKAGE_CBS) | 1264 | && defined(CONFIG_OMAP_PACKAGE_CBS) |
| 1265 | struct omap_ball __initdata omap4_core_cbs_ball[] = { | 1265 | static struct omap_ball __initdata omap4_core_cbs_ball[] = { |
| 1266 | _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL), | 1266 | _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL), |
| 1267 | _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL), | 1267 | _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL), |
| 1268 | _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL), | 1268 | _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL), |
| @@ -1546,7 +1546,7 @@ static struct omap_mux __initdata omap4_wkup_muxmodes[] = { | |||
| 1546 | */ | 1546 | */ |
| 1547 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ | 1547 | #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \ |
| 1548 | && defined(CONFIG_OMAP_PACKAGE_CBL) | 1548 | && defined(CONFIG_OMAP_PACKAGE_CBL) |
| 1549 | struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = { | 1549 | static struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = { |
| 1550 | _OMAP4_BALLENTRY(SIM_IO, "h4", NULL), | 1550 | _OMAP4_BALLENTRY(SIM_IO, "h4", NULL), |
| 1551 | _OMAP4_BALLENTRY(SIM_CLK, "j2", NULL), | 1551 | _OMAP4_BALLENTRY(SIM_CLK, "j2", NULL), |
| 1552 | _OMAP4_BALLENTRY(SIM_RESET, "g2", NULL), | 1552 | _OMAP4_BALLENTRY(SIM_RESET, "g2", NULL), |
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 15f8c6c1bb0f..00e1d2b53683 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | #include <plat/voltage.h> | 21 | #include <plat/voltage.h> |
| 22 | 22 | ||
| 23 | #include "pm.h" | ||
| 24 | |||
| 23 | #define OMAP3_SRI2C_SLAVE_ADDR 0x12 | 25 | #define OMAP3_SRI2C_SLAVE_ADDR 0x12 |
| 24 | #define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00 | 26 | #define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00 |
| 25 | #define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01 | 27 | #define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01 |
| @@ -60,17 +62,17 @@ static u8 smps_offset; | |||
| 60 | 62 | ||
| 61 | #define REG_SMPS_OFFSET 0xE0 | 63 | #define REG_SMPS_OFFSET 0xE0 |
| 62 | 64 | ||
| 63 | unsigned long twl4030_vsel_to_uv(const u8 vsel) | 65 | static unsigned long twl4030_vsel_to_uv(const u8 vsel) |
| 64 | { | 66 | { |
| 65 | return (((vsel * 125) + 6000)) * 100; | 67 | return (((vsel * 125) + 6000)) * 100; |
| 66 | } | 68 | } |
| 67 | 69 | ||
| 68 | u8 twl4030_uv_to_vsel(unsigned long uv) | 70 | static u8 twl4030_uv_to_vsel(unsigned long uv) |
| 69 | { | 71 | { |
| 70 | return DIV_ROUND_UP(uv - 600000, 12500); | 72 | return DIV_ROUND_UP(uv - 600000, 12500); |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | unsigned long twl6030_vsel_to_uv(const u8 vsel) | 75 | static unsigned long twl6030_vsel_to_uv(const u8 vsel) |
| 74 | { | 76 | { |
| 75 | /* | 77 | /* |
| 76 | * In TWL6030 depending on the value of SMPS_OFFSET | 78 | * In TWL6030 depending on the value of SMPS_OFFSET |
| @@ -102,7 +104,7 @@ unsigned long twl6030_vsel_to_uv(const u8 vsel) | |||
| 102 | return ((((vsel - 1) * 125) + 6000)) * 100; | 104 | return ((((vsel - 1) * 125) + 6000)) * 100; |
| 103 | } | 105 | } |
| 104 | 106 | ||
| 105 | u8 twl6030_uv_to_vsel(unsigned long uv) | 107 | static u8 twl6030_uv_to_vsel(unsigned long uv) |
| 106 | { | 108 | { |
| 107 | /* | 109 | /* |
| 108 | * In TWL6030 depending on the value of SMPS_OFFSET | 110 | * In TWL6030 depending on the value of SMPS_OFFSET |
diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c index 784989f8f2f5..5acd2ab298b1 100644 --- a/arch/arm/mach-omap2/pm_bus.c +++ b/arch/arm/mach-omap2/pm_bus.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <plat/omap-pm.h> | 20 | #include <plat/omap-pm.h> |
| 21 | 21 | ||
| 22 | #ifdef CONFIG_PM_RUNTIME | 22 | #ifdef CONFIG_PM_RUNTIME |
| 23 | int omap_pm_runtime_suspend(struct device *dev) | 23 | static int omap_pm_runtime_suspend(struct device *dev) |
| 24 | { | 24 | { |
| 25 | struct platform_device *pdev = to_platform_device(dev); | 25 | struct platform_device *pdev = to_platform_device(dev); |
| 26 | int r, ret = 0; | 26 | int r, ret = 0; |
| @@ -37,7 +37,7 @@ int omap_pm_runtime_suspend(struct device *dev) | |||
| 37 | return ret; | 37 | return ret; |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | int omap_pm_runtime_resume(struct device *dev) | 40 | static int omap_pm_runtime_resume(struct device *dev) |
| 41 | { | 41 | { |
| 42 | struct platform_device *pdev = to_platform_device(dev); | 42 | struct platform_device *pdev = to_platform_device(dev); |
| 43 | int r; | 43 | int r; |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 53d44f6e3736..49654c8d18f5 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h | |||
| @@ -228,7 +228,67 @@ | |||
| 228 | 228 | ||
| 229 | 229 | ||
| 230 | #ifndef __ASSEMBLER__ | 230 | #ifndef __ASSEMBLER__ |
| 231 | 231 | /* | |
| 232 | * Stub omap2xxx/omap3xxx functions so that common files | ||
| 233 | * continue to build when custom builds are used | ||
| 234 | */ | ||
| 235 | #if defined(CONFIG_ARCH_OMAP4) && !(defined(CONFIG_ARCH_OMAP2) || \ | ||
| 236 | defined(CONFIG_ARCH_OMAP3)) | ||
| 237 | static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) | ||
| 238 | { | ||
| 239 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 240 | "not suppose to be used on omap4\n"); | ||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) | ||
| 244 | { | ||
| 245 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 246 | "not suppose to be used on omap4\n"); | ||
| 247 | } | ||
| 248 | static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, | ||
| 249 | s16 module, s16 idx) | ||
| 250 | { | ||
| 251 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 252 | "not suppose to be used on omap4\n"); | ||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | ||
| 256 | { | ||
| 257 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 258 | "not suppose to be used on omap4\n"); | ||
| 259 | return 0; | ||
| 260 | } | ||
| 261 | static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) | ||
| 262 | { | ||
| 263 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 264 | "not suppose to be used on omap4\n"); | ||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) | ||
| 268 | { | ||
| 269 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 270 | "not suppose to be used on omap4\n"); | ||
| 271 | return 0; | ||
| 272 | } | ||
| 273 | static inline int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) | ||
| 274 | { | ||
| 275 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 276 | "not suppose to be used on omap4\n"); | ||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) | ||
| 280 | { | ||
| 281 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 282 | "not suppose to be used on omap4\n"); | ||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift) | ||
| 286 | { | ||
| 287 | WARN(1, "prm: omap2xxx/omap3xxx specific function and " | ||
| 288 | "not suppose to be used on omap4\n"); | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | #else | ||
| 232 | /* Power/reset management domain register get/set */ | 292 | /* Power/reset management domain register get/set */ |
| 233 | extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx); | 293 | extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx); |
| 234 | extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx); | 294 | extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx); |
| @@ -242,6 +302,7 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); | |||
| 242 | extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); | 302 | extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); |
| 243 | extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift); | 303 | extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift); |
| 244 | 304 | ||
| 305 | #endif /* CONFIG_ARCH_OMAP4 */ | ||
| 245 | #endif | 306 | #endif |
| 246 | 307 | ||
| 247 | /* | 308 | /* |
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 786d685c09a9..b1e0af18a26a 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <plat/voltage.h> | 27 | #include <plat/voltage.h> |
| 28 | 28 | ||
| 29 | #include "control.h" | 29 | #include "control.h" |
| 30 | #include "pm.h" | ||
| 30 | 31 | ||
| 31 | static bool sr_enable_on_init; | 32 | static bool sr_enable_on_init; |
| 32 | 33 | ||
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index b0c4907ab3ca..4067669d96c4 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | #include <plat/omap_hwmod.h> | 14 | #include <plat/omap_hwmod.h> |
| 15 | 15 | ||
| 16 | #include "wd_timer.h" | ||
| 17 | |||
| 16 | /* | 18 | /* |
| 17 | * In order to avoid any assumptions from bootloader regarding WDT | 19 | * In order to avoid any assumptions from bootloader regarding WDT |
| 18 | * settings, WDT module is reset during init. This enables the watchdog | 20 | * settings, WDT module is reset during init. This enables the watchdog |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index fcc1e628e050..9d30c6f804b9 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -644,7 +644,7 @@ config ARM_THUMBEE | |||
| 644 | 644 | ||
| 645 | config SWP_EMULATE | 645 | config SWP_EMULATE |
| 646 | bool "Emulate SWP/SWPB instructions" | 646 | bool "Emulate SWP/SWPB instructions" |
| 647 | depends on CPU_V7 | 647 | depends on CPU_V7 && !CPU_V6 |
| 648 | select HAVE_PROC_CPU if PROC_FS | 648 | select HAVE_PROC_CPU if PROC_FS |
| 649 | default y if SMP | 649 | default y if SMP |
| 650 | help | 650 | help |
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 1f98e0b94847..ccf2660f4151 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
| @@ -718,7 +718,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) | |||
| 718 | case METHOD_GPIO_24XX: | 718 | case METHOD_GPIO_24XX: |
| 719 | case METHOD_GPIO_44XX: | 719 | case METHOD_GPIO_44XX: |
| 720 | set_24xx_gpio_triggering(bank, gpio, trigger); | 720 | set_24xx_gpio_triggering(bank, gpio, trigger); |
| 721 | break; | 721 | return 0; |
| 722 | #endif | 722 | #endif |
| 723 | default: | 723 | default: |
| 724 | goto bad; | 724 | goto bad; |
| @@ -756,8 +756,10 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
| 756 | spin_lock_irqsave(&bank->lock, flags); | 756 | spin_lock_irqsave(&bank->lock, flags); |
| 757 | retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); | 757 | retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); |
| 758 | if (retval == 0) { | 758 | if (retval == 0) { |
| 759 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; | 759 | struct irq_desc *d = irq_to_desc(irq); |
| 760 | irq_desc[irq].status |= type; | 760 | |
| 761 | d->status &= ~IRQ_TYPE_SENSE_MASK; | ||
| 762 | d->status |= type; | ||
| 761 | } | 763 | } |
| 762 | spin_unlock_irqrestore(&bank->lock, flags); | 764 | spin_unlock_irqrestore(&bank->lock, flags); |
| 763 | 765 | ||
| @@ -1671,7 +1673,9 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank) | |||
| 1671 | 1673 | ||
| 1672 | for (j = bank->virtual_irq_start; | 1674 | for (j = bank->virtual_irq_start; |
| 1673 | j < bank->virtual_irq_start + bank_width; j++) { | 1675 | j < bank->virtual_irq_start + bank_width; j++) { |
| 1674 | lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); | 1676 | struct irq_desc *d = irq_to_desc(j); |
| 1677 | |||
| 1678 | lockdep_set_class(&d->lock, &gpio_lock_class); | ||
| 1675 | set_irq_chip_data(j, bank); | 1679 | set_irq_chip_data(j, bank); |
| 1676 | if (bank_is_mpuio(bank)) | 1680 | if (bank_is_mpuio(bank)) |
| 1677 | set_irq_chip(j, &mpuio_irq_chip); | 1681 | set_irq_chip(j, &mpuio_irq_chip); |
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h index 0ff123399f3b..5bd204e55c32 100644 --- a/arch/arm/plat-omap/include/plat/voltage.h +++ b/arch/arm/plat-omap/include/plat/voltage.h | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | #ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H | 14 | #ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H |
| 15 | #define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H | 15 | #define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H |
| 16 | 16 | ||
| 17 | #include <linux/err.h> | ||
| 18 | |||
| 17 | #define VOLTSCALE_VPFORCEUPDATE 1 | 19 | #define VOLTSCALE_VPFORCEUPDATE 1 |
| 18 | #define VOLTSCALE_VCBYPASS 2 | 20 | #define VOLTSCALE_VCBYPASS 2 |
| 19 | 21 | ||
| @@ -65,9 +67,6 @@ struct voltagedomain { | |||
| 65 | char *name; | 67 | char *name; |
| 66 | }; | 68 | }; |
| 67 | 69 | ||
| 68 | /* API to get the voltagedomain pointer */ | ||
| 69 | struct voltagedomain *omap_voltage_domain_lookup(char *name); | ||
| 70 | |||
| 71 | /** | 70 | /** |
| 72 | * struct omap_volt_data - Omap voltage specific data. | 71 | * struct omap_volt_data - Omap voltage specific data. |
| 73 | * @voltage_nominal: The possible voltage value in uV | 72 | * @voltage_nominal: The possible voltage value in uV |
| @@ -131,16 +130,26 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm, | |||
| 131 | struct omap_volt_pmic_info *pmic_info); | 130 | struct omap_volt_pmic_info *pmic_info); |
| 132 | void omap_change_voltscale_method(struct voltagedomain *voltdm, | 131 | void omap_change_voltscale_method(struct voltagedomain *voltdm, |
| 133 | int voltscale_method); | 132 | int voltscale_method); |
| 133 | /* API to get the voltagedomain pointer */ | ||
| 134 | struct voltagedomain *omap_voltage_domain_lookup(char *name); | ||
| 135 | |||
| 134 | int omap_voltage_late_init(void); | 136 | int omap_voltage_late_init(void); |
| 135 | #else | 137 | #else |
| 136 | static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm, | 138 | static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm, |
| 137 | struct omap_volt_pmic_info *pmic_info) {} | 139 | struct omap_volt_pmic_info *pmic_info) |
| 140 | { | ||
| 141 | return -EINVAL; | ||
| 142 | } | ||
| 138 | static inline void omap_change_voltscale_method(struct voltagedomain *voltdm, | 143 | static inline void omap_change_voltscale_method(struct voltagedomain *voltdm, |
| 139 | int voltscale_method) {} | 144 | int voltscale_method) {} |
| 140 | static inline int omap_voltage_late_init(void) | 145 | static inline int omap_voltage_late_init(void) |
| 141 | { | 146 | { |
| 142 | return -EINVAL; | 147 | return -EINVAL; |
| 143 | } | 148 | } |
| 149 | static inline struct voltagedomain *omap_voltage_domain_lookup(char *name) | ||
| 150 | { | ||
| 151 | return ERR_PTR(-EINVAL); | ||
| 152 | } | ||
| 144 | #endif | 153 | #endif |
| 145 | 154 | ||
| 146 | #endif | 155 | #endif |
diff --git a/arch/ia64/include/asm/page.h b/arch/ia64/include/asm/page.h index 41b6d31110fd..961a16f43e6b 100644 --- a/arch/ia64/include/asm/page.h +++ b/arch/ia64/include/asm/page.h | |||
| @@ -189,6 +189,7 @@ get_order (unsigned long size) | |||
| 189 | # define pgprot_val(x) ((x).pgprot) | 189 | # define pgprot_val(x) ((x).pgprot) |
| 190 | 190 | ||
| 191 | # define __pte(x) ((pte_t) { (x) } ) | 191 | # define __pte(x) ((pte_t) { (x) } ) |
| 192 | # define __pmd(x) ((pmd_t) { (x) } ) | ||
| 192 | # define __pgprot(x) ((pgprot_t) { (x) } ) | 193 | # define __pgprot(x) ((pgprot_t) { (x) } ) |
| 193 | 194 | ||
| 194 | #else /* !STRICT_MM_TYPECHECKS */ | 195 | #else /* !STRICT_MM_TYPECHECKS */ |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index d79697157ac0..29c82c640a88 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
| @@ -5,10 +5,21 @@ CONFIG_AUDIT=y | |||
| 5 | CONFIG_RCU_TRACE=y | 5 | CONFIG_RCU_TRACE=y |
| 6 | CONFIG_IKCONFIG=y | 6 | CONFIG_IKCONFIG=y |
| 7 | CONFIG_IKCONFIG_PROC=y | 7 | CONFIG_IKCONFIG_PROC=y |
| 8 | CONFIG_CGROUPS=y | ||
| 9 | CONFIG_CPUSETS=y | ||
| 10 | CONFIG_CGROUP_CPUACCT=y | ||
| 11 | CONFIG_RESOURCE_COUNTERS=y | ||
| 12 | CONFIG_CGROUP_MEM_RES_CTLR=y | ||
| 13 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | ||
| 14 | CONFIG_CGROUP_SCHED=y | ||
| 15 | CONFIG_RT_GROUP_SCHED=y | ||
| 16 | CONFIG_BLK_CGROUP=y | ||
| 8 | CONFIG_BLK_DEV_INITRD=y | 17 | CONFIG_BLK_DEV_INITRD=y |
| 9 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 18 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
| 10 | CONFIG_PERF_EVENTS=y | 19 | # CONFIG_COMPAT_BRK is not set |
| 11 | CONFIG_SLAB=y | 20 | CONFIG_SLAB=y |
| 21 | CONFIG_PROFILING=y | ||
| 22 | CONFIG_OPROFILE=y | ||
| 12 | CONFIG_KPROBES=y | 23 | CONFIG_KPROBES=y |
| 13 | CONFIG_MODULES=y | 24 | CONFIG_MODULES=y |
| 14 | CONFIG_MODULE_UNLOAD=y | 25 | CONFIG_MODULE_UNLOAD=y |
| @@ -19,7 +30,9 @@ CONFIG_HIGH_RES_TIMERS=y | |||
| 19 | CONFIG_PREEMPT=y | 30 | CONFIG_PREEMPT=y |
| 20 | CONFIG_MEMORY_HOTPLUG=y | 31 | CONFIG_MEMORY_HOTPLUG=y |
| 21 | CONFIG_MEMORY_HOTREMOVE=y | 32 | CONFIG_MEMORY_HOTREMOVE=y |
| 33 | CONFIG_KSM=y | ||
| 22 | CONFIG_BINFMT_MISC=m | 34 | CONFIG_BINFMT_MISC=m |
| 35 | CONFIG_CMM=m | ||
| 23 | CONFIG_HZ_100=y | 36 | CONFIG_HZ_100=y |
| 24 | CONFIG_KEXEC=y | 37 | CONFIG_KEXEC=y |
| 25 | CONFIG_PM=y | 38 | CONFIG_PM=y |
| @@ -105,6 +118,7 @@ CONFIG_DEBUG_LIST=y | |||
| 105 | CONFIG_DEBUG_NOTIFIERS=y | 118 | CONFIG_DEBUG_NOTIFIERS=y |
| 106 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 119 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
| 107 | CONFIG_KPROBES_SANITY_TEST=y | 120 | CONFIG_KPROBES_SANITY_TEST=y |
| 121 | CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y | ||
| 108 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m | 122 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m |
| 109 | CONFIG_LATENCYTOP=y | 123 | CONFIG_LATENCYTOP=y |
| 110 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 124 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a875c2f542e1..da359ca6fe55 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
| @@ -169,7 +169,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
| 169 | 169 | ||
| 170 | static inline int is_compat_task(void) | 170 | static inline int is_compat_task(void) |
| 171 | { | 171 | { |
| 172 | return test_thread_flag(TIF_31BIT); | 172 | return is_32bit_task(); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | #else | 175 | #else |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 354d42616c7e..10c029cfcc7d 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
| @@ -161,7 +161,9 @@ extern unsigned int vdso_enabled; | |||
| 161 | use of this is to invoke "./ld.so someprog" to test out a new version of | 161 | use of this is to invoke "./ld.so someprog" to test out a new version of |
| 162 | the loader. We need to make sure that it is out of the way of the program | 162 | the loader. We need to make sure that it is out of the way of the program |
| 163 | that it will "exec", and that there is sufficient room for the brk. */ | 163 | that it will "exec", and that there is sufficient room for the brk. */ |
| 164 | #define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) | 164 | |
| 165 | extern unsigned long randomize_et_dyn(unsigned long base); | ||
| 166 | #define ELF_ET_DYN_BASE (randomize_et_dyn(STACK_TOP / 3 * 2)) | ||
| 165 | 167 | ||
| 166 | /* This yields a mask that user programs can use to figure out what | 168 | /* This yields a mask that user programs can use to figure out what |
| 167 | instruction set this CPU supports. */ | 169 | instruction set this CPU supports. */ |
| @@ -206,6 +208,8 @@ do { \ | |||
| 206 | current->mm->context.noexec == 0; \ | 208 | current->mm->context.noexec == 0; \ |
| 207 | }) | 209 | }) |
| 208 | 210 | ||
| 211 | #define STACK_RND_MASK 0x7ffUL | ||
| 212 | |||
| 209 | #define ARCH_DLINFO \ | 213 | #define ARCH_DLINFO \ |
| 210 | do { \ | 214 | do { \ |
| 211 | if (vdso_enabled) \ | 215 | if (vdso_enabled) \ |
| @@ -218,4 +222,7 @@ struct linux_binprm; | |||
| 218 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | 222 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 |
| 219 | int arch_setup_additional_pages(struct linux_binprm *, int); | 223 | int arch_setup_additional_pages(struct linux_binprm *, int); |
| 220 | 224 | ||
| 225 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | ||
| 226 | #define arch_randomize_brk arch_randomize_brk | ||
| 227 | |||
| 221 | #endif | 228 | #endif |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 6710b0eac165..8f8d759f6a7b 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
| @@ -449,7 +449,7 @@ extern void (*_machine_restart)(char *command); | |||
| 449 | extern void (*_machine_halt)(void); | 449 | extern void (*_machine_halt)(void); |
| 450 | extern void (*_machine_power_off)(void); | 450 | extern void (*_machine_power_off)(void); |
| 451 | 451 | ||
| 452 | #define arch_align_stack(x) (x) | 452 | extern unsigned long arch_align_stack(unsigned long sp); |
| 453 | 453 | ||
| 454 | static inline int tprot(unsigned long addr) | 454 | static inline int tprot(unsigned long addr) |
| 455 | { | 455 | { |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ebc77091466f..ad1382f7932e 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
| @@ -118,6 +118,12 @@ static inline struct thread_info *current_thread_info(void) | |||
| 118 | #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) | 118 | #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) |
| 119 | #define _TIF_FREEZE (1<<TIF_FREEZE) | 119 | #define _TIF_FREEZE (1<<TIF_FREEZE) |
| 120 | 120 | ||
| 121 | #ifdef CONFIG_64BIT | ||
| 122 | #define is_32bit_task() (test_thread_flag(TIF_31BIT)) | ||
| 123 | #else | ||
| 124 | #define is_32bit_task() (1) | ||
| 125 | #endif | ||
| 126 | |||
| 121 | #endif /* __KERNEL__ */ | 127 | #endif /* __KERNEL__ */ |
| 122 | 128 | ||
| 123 | #define PREEMPT_ACTIVE 0x4000000 | 129 | #define PREEMPT_ACTIVE 0x4000000 |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 6ba42222b542..a895e69379f7 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
| @@ -30,9 +30,11 @@ | |||
| 30 | #include <linux/tick.h> | 30 | #include <linux/tick.h> |
| 31 | #include <linux/elfcore.h> | 31 | #include <linux/elfcore.h> |
| 32 | #include <linux/kernel_stat.h> | 32 | #include <linux/kernel_stat.h> |
| 33 | #include <linux/personality.h> | ||
| 33 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
| 34 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
| 35 | #include <linux/kprobes.h> | 36 | #include <linux/kprobes.h> |
| 37 | #include <linux/random.h> | ||
| 36 | #include <asm/compat.h> | 38 | #include <asm/compat.h> |
| 37 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
| 38 | #include <asm/pgtable.h> | 40 | #include <asm/pgtable.h> |
| @@ -332,3 +334,39 @@ unsigned long get_wchan(struct task_struct *p) | |||
| 332 | } | 334 | } |
| 333 | return 0; | 335 | return 0; |
| 334 | } | 336 | } |
| 337 | |||
| 338 | unsigned long arch_align_stack(unsigned long sp) | ||
| 339 | { | ||
| 340 | if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) | ||
| 341 | sp -= get_random_int() & ~PAGE_MASK; | ||
| 342 | return sp & ~0xf; | ||
| 343 | } | ||
| 344 | |||
| 345 | static inline unsigned long brk_rnd(void) | ||
| 346 | { | ||
| 347 | /* 8MB for 32bit, 1GB for 64bit */ | ||
| 348 | if (is_32bit_task()) | ||
| 349 | return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; | ||
| 350 | else | ||
| 351 | return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT; | ||
| 352 | } | ||
| 353 | |||
| 354 | unsigned long arch_randomize_brk(struct mm_struct *mm) | ||
| 355 | { | ||
| 356 | unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); | ||
| 357 | |||
| 358 | if (ret < mm->brk) | ||
| 359 | return mm->brk; | ||
| 360 | return ret; | ||
| 361 | } | ||
| 362 | |||
| 363 | unsigned long randomize_et_dyn(unsigned long base) | ||
| 364 | { | ||
| 365 | unsigned long ret = PAGE_ALIGN(base + brk_rnd()); | ||
| 366 | |||
| 367 | if (!(current->flags & PF_RANDOMIZE)) | ||
| 368 | return base; | ||
| 369 | if (ret < base) | ||
| 370 | return base; | ||
| 371 | return ret; | ||
| 372 | } | ||
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index e3150dd2fe74..f438d74dedbd 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
| @@ -203,7 +203,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
| 203 | if (!uses_interp) | 203 | if (!uses_interp) |
| 204 | return 0; | 204 | return 0; |
| 205 | 205 | ||
| 206 | vdso_base = mm->mmap_base; | ||
| 207 | #ifdef CONFIG_64BIT | 206 | #ifdef CONFIG_64BIT |
| 208 | vdso_pagelist = vdso64_pagelist; | 207 | vdso_pagelist = vdso64_pagelist; |
| 209 | vdso_pages = vdso64_pages; | 208 | vdso_pages = vdso64_pages; |
| @@ -233,8 +232,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
| 233 | * fail and end up putting it elsewhere. | 232 | * fail and end up putting it elsewhere. |
| 234 | */ | 233 | */ |
| 235 | down_write(&mm->mmap_sem); | 234 | down_write(&mm->mmap_sem); |
| 236 | vdso_base = get_unmapped_area(NULL, vdso_base, | 235 | vdso_base = get_unmapped_area(NULL, 0, vdso_pages << PAGE_SHIFT, 0, 0); |
| 237 | vdso_pages << PAGE_SHIFT, 0, 0); | ||
| 238 | if (IS_ERR_VALUE(vdso_base)) { | 236 | if (IS_ERR_VALUE(vdso_base)) { |
| 239 | rc = vdso_base; | 237 | rc = vdso_base; |
| 240 | goto out_up; | 238 | goto out_up; |
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 869efbaed3ea..c9a9f7f18188 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
| @@ -27,17 +27,44 @@ | |||
| 27 | #include <linux/personality.h> | 27 | #include <linux/personality.h> |
| 28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/random.h> | ||
| 30 | #include <asm/pgalloc.h> | 31 | #include <asm/pgalloc.h> |
| 31 | #include <asm/compat.h> | 32 | #include <asm/compat.h> |
| 32 | 33 | ||
| 34 | static unsigned long stack_maxrandom_size(void) | ||
| 35 | { | ||
| 36 | if (!(current->flags & PF_RANDOMIZE)) | ||
| 37 | return 0; | ||
| 38 | if (current->personality & ADDR_NO_RANDOMIZE) | ||
| 39 | return 0; | ||
| 40 | return STACK_RND_MASK << PAGE_SHIFT; | ||
| 41 | } | ||
| 42 | |||
| 33 | /* | 43 | /* |
| 34 | * Top of mmap area (just below the process stack). | 44 | * Top of mmap area (just below the process stack). |
| 35 | * | 45 | * |
| 36 | * Leave an at least ~128 MB hole. | 46 | * Leave at least a ~32 MB hole. |
| 37 | */ | 47 | */ |
| 38 | #define MIN_GAP (128*1024*1024) | 48 | #define MIN_GAP (32*1024*1024) |
| 39 | #define MAX_GAP (STACK_TOP/6*5) | 49 | #define MAX_GAP (STACK_TOP/6*5) |
| 40 | 50 | ||
| 51 | static inline int mmap_is_legacy(void) | ||
| 52 | { | ||
| 53 | if (current->personality & ADDR_COMPAT_LAYOUT) | ||
| 54 | return 1; | ||
| 55 | if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) | ||
| 56 | return 1; | ||
| 57 | return sysctl_legacy_va_layout; | ||
| 58 | } | ||
| 59 | |||
| 60 | static unsigned long mmap_rnd(void) | ||
| 61 | { | ||
| 62 | if (!(current->flags & PF_RANDOMIZE)) | ||
| 63 | return 0; | ||
| 64 | /* 8MB randomization for mmap_base */ | ||
| 65 | return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; | ||
| 66 | } | ||
| 67 | |||
| 41 | static inline unsigned long mmap_base(void) | 68 | static inline unsigned long mmap_base(void) |
| 42 | { | 69 | { |
| 43 | unsigned long gap = rlimit(RLIMIT_STACK); | 70 | unsigned long gap = rlimit(RLIMIT_STACK); |
| @@ -46,22 +73,8 @@ static inline unsigned long mmap_base(void) | |||
| 46 | gap = MIN_GAP; | 73 | gap = MIN_GAP; |
| 47 | else if (gap > MAX_GAP) | 74 | else if (gap > MAX_GAP) |
| 48 | gap = MAX_GAP; | 75 | gap = MAX_GAP; |
| 49 | 76 | gap &= PAGE_MASK; | |
| 50 | return STACK_TOP - (gap & PAGE_MASK); | 77 | return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; |
| 51 | } | ||
| 52 | |||
| 53 | static inline int mmap_is_legacy(void) | ||
| 54 | { | ||
| 55 | #ifdef CONFIG_64BIT | ||
| 56 | /* | ||
| 57 | * Force standard allocation for 64 bit programs. | ||
| 58 | */ | ||
| 59 | if (!is_compat_task()) | ||
| 60 | return 1; | ||
| 61 | #endif | ||
| 62 | return sysctl_legacy_va_layout || | ||
| 63 | (current->personality & ADDR_COMPAT_LAYOUT) || | ||
| 64 | rlimit(RLIMIT_STACK) == RLIM_INFINITY; | ||
| 65 | } | 78 | } |
| 66 | 79 | ||
| 67 | #ifndef CONFIG_64BIT | 80 | #ifndef CONFIG_64BIT |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 36ed2e2c896b..47ae4a751a59 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -1934,13 +1934,19 @@ config PCI_MMCONFIG | |||
| 1934 | depends on X86_64 && PCI && ACPI | 1934 | depends on X86_64 && PCI && ACPI |
| 1935 | 1935 | ||
| 1936 | config PCI_CNB20LE_QUIRK | 1936 | config PCI_CNB20LE_QUIRK |
| 1937 | bool "Read CNB20LE Host Bridge Windows" | 1937 | bool "Read CNB20LE Host Bridge Windows" if EMBEDDED |
| 1938 | depends on PCI | 1938 | default n |
| 1939 | depends on PCI && EXPERIMENTAL | ||
| 1939 | help | 1940 | help |
| 1940 | Read the PCI windows out of the CNB20LE host bridge. This allows | 1941 | Read the PCI windows out of the CNB20LE host bridge. This allows |
| 1941 | PCI hotplug to work on systems with the CNB20LE chipset which do | 1942 | PCI hotplug to work on systems with the CNB20LE chipset which do |
| 1942 | not have ACPI. | 1943 | not have ACPI. |
| 1943 | 1944 | ||
| 1945 | There's no public spec for this chipset, and this functionality | ||
| 1946 | is known to be incomplete. | ||
| 1947 | |||
| 1948 | You should say N unless you know you need this. | ||
| 1949 | |||
| 1944 | config DMAR | 1950 | config DMAR |
| 1945 | bool "Support for DMA Remapping Devices (EXPERIMENTAL)" | 1951 | bool "Support for DMA Remapping Devices (EXPERIMENTAL)" |
| 1946 | depends on PCI_MSI && ACPI && EXPERIMENTAL | 1952 | depends on PCI_MSI && ACPI && EXPERIMENTAL |
| @@ -2068,7 +2074,7 @@ config OLPC | |||
| 2068 | 2074 | ||
| 2069 | config OLPC_XO1 | 2075 | config OLPC_XO1 |
| 2070 | tristate "OLPC XO-1 support" | 2076 | tristate "OLPC XO-1 support" |
| 2071 | depends on OLPC && PCI | 2077 | depends on OLPC && MFD_CS5535 |
| 2072 | ---help--- | 2078 | ---help--- |
| 2073 | Add support for non-essential features of the OLPC XO-1 laptop. | 2079 | Add support for non-essential features of the OLPC XO-1 laptop. |
| 2074 | 2080 | ||
diff --git a/arch/x86/pci/broadcom_bus.c b/arch/x86/pci/broadcom_bus.c index 0846a5bbbfbd..ab8269b0da29 100644 --- a/arch/x86/pci/broadcom_bus.c +++ b/arch/x86/pci/broadcom_bus.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * option) any later version. | 9 | * option) any later version. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/acpi.h> | ||
| 12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 13 | #include <linux/dmi.h> | 14 | #include <linux/dmi.h> |
| 14 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
| @@ -25,12 +26,14 @@ static void __devinit cnb20le_res(struct pci_dev *dev) | |||
| 25 | u8 fbus, lbus; | 26 | u8 fbus, lbus; |
| 26 | int i; | 27 | int i; |
| 27 | 28 | ||
| 29 | #ifdef CONFIG_ACPI | ||
| 28 | /* | 30 | /* |
| 29 | * The x86_pci_root_bus_res_quirks() function already refuses to use | 31 | * We should get host bridge information from ACPI unless the BIOS |
| 30 | * this information if ACPI _CRS was used. Therefore, we don't bother | 32 | * doesn't support it. |
| 31 | * checking if ACPI is enabled, and just generate the information | ||
| 32 | * for both the ACPI _CRS and no ACPI cases. | ||
| 33 | */ | 33 | */ |
| 34 | if (acpi_os_get_root_pointer()) | ||
| 35 | return; | ||
| 36 | #endif | ||
| 34 | 37 | ||
| 35 | info = &pci_root_info[pci_root_num]; | 38 | info = &pci_root_info[pci_root_num]; |
| 36 | pci_root_num++; | 39 | pci_root_num++; |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index f7c8a399978c..5fe75026ecc2 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -22,6 +22,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | |||
| 22 | 22 | ||
| 23 | unsigned int pci_early_dump_regs; | 23 | unsigned int pci_early_dump_regs; |
| 24 | static int pci_bf_sort; | 24 | static int pci_bf_sort; |
| 25 | static int smbios_type_b1_flag; | ||
| 25 | int pci_routeirq; | 26 | int pci_routeirq; |
| 26 | int noioapicquirk; | 27 | int noioapicquirk; |
| 27 | #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS | 28 | #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS |
| @@ -185,6 +186,39 @@ static int __devinit set_bf_sort(const struct dmi_system_id *d) | |||
| 185 | return 0; | 186 | return 0; |
| 186 | } | 187 | } |
| 187 | 188 | ||
| 189 | static void __devinit read_dmi_type_b1(const struct dmi_header *dm, | ||
| 190 | void *private_data) | ||
| 191 | { | ||
| 192 | u8 *d = (u8 *)dm + 4; | ||
| 193 | |||
| 194 | if (dm->type != 0xB1) | ||
| 195 | return; | ||
| 196 | switch (((*(u32 *)d) >> 9) & 0x03) { | ||
| 197 | case 0x00: | ||
| 198 | printk(KERN_INFO "dmi type 0xB1 record - unknown flag\n"); | ||
| 199 | break; | ||
| 200 | case 0x01: /* set pci=bfsort */ | ||
| 201 | smbios_type_b1_flag = 1; | ||
| 202 | break; | ||
| 203 | case 0x02: /* do not set pci=bfsort */ | ||
| 204 | smbios_type_b1_flag = 2; | ||
| 205 | break; | ||
| 206 | default: | ||
| 207 | break; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | static int __devinit find_sort_method(const struct dmi_system_id *d) | ||
| 212 | { | ||
| 213 | dmi_walk(read_dmi_type_b1, NULL); | ||
| 214 | |||
| 215 | if (smbios_type_b1_flag == 1) { | ||
| 216 | set_bf_sort(d); | ||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | return -1; | ||
| 220 | } | ||
| 221 | |||
| 188 | /* | 222 | /* |
| 189 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) | 223 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) |
| 190 | */ | 224 | */ |
| @@ -213,6 +247,13 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { | |||
| 213 | }, | 247 | }, |
| 214 | #endif /* __i386__ */ | 248 | #endif /* __i386__ */ |
| 215 | { | 249 | { |
| 250 | .callback = find_sort_method, | ||
| 251 | .ident = "Dell System", | ||
| 252 | .matches = { | ||
| 253 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | ||
| 254 | }, | ||
| 255 | }, | ||
| 256 | { | ||
| 216 | .callback = set_bf_sort, | 257 | .callback = set_bf_sort, |
| 217 | .ident = "Dell PowerEdge 1950", | 258 | .ident = "Dell PowerEdge 1950", |
| 218 | .matches = { | 259 | .matches = { |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 9f9bfb705cf9..87e6c8323117 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
| @@ -589,7 +589,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
| 589 | case PCI_DEVICE_ID_INTEL_ICH10_1: | 589 | case PCI_DEVICE_ID_INTEL_ICH10_1: |
| 590 | case PCI_DEVICE_ID_INTEL_ICH10_2: | 590 | case PCI_DEVICE_ID_INTEL_ICH10_2: |
| 591 | case PCI_DEVICE_ID_INTEL_ICH10_3: | 591 | case PCI_DEVICE_ID_INTEL_ICH10_3: |
| 592 | case PCI_DEVICE_ID_INTEL_PATSBURG_LPC: | 592 | case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0: |
| 593 | case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1: | ||
| 593 | r->name = "PIIX/ICH"; | 594 | r->name = "PIIX/ICH"; |
| 594 | r->get = pirq_piix_get; | 595 | r->get = pirq_piix_get; |
| 595 | r->set = pirq_piix_set; | 596 | r->set = pirq_piix_set; |
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c index f5442c03abc3..127775696d6c 100644 --- a/arch/x86/platform/olpc/olpc-xo1.c +++ b/arch/x86/platform/olpc/olpc-xo1.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for features of the OLPC XO-1 laptop | 2 | * Support for features of the OLPC XO-1 laptop |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2010 Andres Salomon <dilinger@queued.net> | ||
| 4 | * Copyright (C) 2010 One Laptop per Child | 5 | * Copyright (C) 2010 One Laptop per Child |
| 5 | * Copyright (C) 2006 Red Hat, Inc. | 6 | * Copyright (C) 2006 Red Hat, Inc. |
| 6 | * Copyright (C) 2006 Advanced Micro Devices, Inc. | 7 | * Copyright (C) 2006 Advanced Micro Devices, Inc. |
| @@ -12,8 +13,6 @@ | |||
| 12 | */ | 13 | */ |
| 13 | 14 | ||
| 14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 15 | #include <linux/pci.h> | ||
| 16 | #include <linux/pci_ids.h> | ||
| 17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 18 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
| 19 | 18 | ||
| @@ -22,9 +21,6 @@ | |||
| 22 | 21 | ||
| 23 | #define DRV_NAME "olpc-xo1" | 22 | #define DRV_NAME "olpc-xo1" |
| 24 | 23 | ||
| 25 | #define PMS_BAR 4 | ||
| 26 | #define ACPI_BAR 5 | ||
| 27 | |||
| 28 | /* PMC registers (PMS block) */ | 24 | /* PMC registers (PMS block) */ |
| 29 | #define PM_SCLK 0x10 | 25 | #define PM_SCLK 0x10 |
| 30 | #define PM_IN_SLPCTL 0x20 | 26 | #define PM_IN_SLPCTL 0x20 |
| @@ -57,65 +53,67 @@ static void xo1_power_off(void) | |||
| 57 | outl(0x00002000, acpi_base + PM1_CNT); | 53 | outl(0x00002000, acpi_base + PM1_CNT); |
| 58 | } | 54 | } |
| 59 | 55 | ||
| 60 | /* Read the base addresses from the PCI BAR info */ | 56 | static int __devinit olpc_xo1_probe(struct platform_device *pdev) |
| 61 | static int __devinit setup_bases(struct pci_dev *pdev) | ||
| 62 | { | 57 | { |
| 63 | int r; | 58 | struct resource *res; |
| 64 | 59 | ||
| 65 | r = pci_enable_device_io(pdev); | 60 | /* don't run on non-XOs */ |
| 66 | if (r) { | 61 | if (!machine_is_olpc()) |
| 67 | dev_err(&pdev->dev, "can't enable device IO\n"); | 62 | return -ENODEV; |
| 68 | return r; | ||
| 69 | } | ||
| 70 | 63 | ||
| 71 | r = pci_request_region(pdev, ACPI_BAR, DRV_NAME); | 64 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 72 | if (r) { | 65 | if (!res) { |
| 73 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR); | 66 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 74 | return r; | 67 | return -EIO; |
| 75 | } | 68 | } |
| 76 | 69 | ||
| 77 | r = pci_request_region(pdev, PMS_BAR, DRV_NAME); | 70 | if (!request_region(res->start, resource_size(res), DRV_NAME)) { |
| 78 | if (r) { | 71 | dev_err(&pdev->dev, "can't request region\n"); |
| 79 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR); | 72 | return -EIO; |
| 80 | pci_release_region(pdev, ACPI_BAR); | ||
| 81 | return r; | ||
| 82 | } | 73 | } |
| 83 | 74 | ||
| 84 | acpi_base = pci_resource_start(pdev, ACPI_BAR); | 75 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
| 85 | pms_base = pci_resource_start(pdev, PMS_BAR); | 76 | pms_base = res->start; |
| 77 | else if (strcmp(pdev->name, "cs5535-acpi") == 0) | ||
| 78 | acpi_base = res->start; | ||
| 79 | |||
| 80 | /* If we have both addresses, we can override the poweroff hook */ | ||
| 81 | if (pms_base && acpi_base) { | ||
| 82 | pm_power_off = xo1_power_off; | ||
| 83 | printk(KERN_INFO "OLPC XO-1 support registered\n"); | ||
| 84 | } | ||
| 86 | 85 | ||
| 87 | return 0; | 86 | return 0; |
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | static int __devinit olpc_xo1_probe(struct platform_device *pdev) | 89 | static int __devexit olpc_xo1_remove(struct platform_device *pdev) |
| 91 | { | 90 | { |
| 92 | struct pci_dev *pcidev; | 91 | struct resource *r; |
| 93 | int r; | ||
| 94 | |||
| 95 | pcidev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, | ||
| 96 | NULL); | ||
| 97 | if (!pdev) | ||
| 98 | return -ENODEV; | ||
| 99 | |||
| 100 | r = setup_bases(pcidev); | ||
| 101 | if (r) | ||
| 102 | return r; | ||
| 103 | 92 | ||
| 104 | pm_power_off = xo1_power_off; | 93 | r = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 94 | release_region(r->start, resource_size(r)); | ||
| 105 | 95 | ||
| 106 | printk(KERN_INFO "OLPC XO-1 support registered\n"); | 96 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
| 107 | return 0; | 97 | pms_base = 0; |
| 108 | } | 98 | else if (strcmp(pdev->name, "cs5535-acpi") == 0) |
| 99 | acpi_base = 0; | ||
| 109 | 100 | ||
| 110 | static int __devexit olpc_xo1_remove(struct platform_device *pdev) | ||
| 111 | { | ||
| 112 | pm_power_off = NULL; | 101 | pm_power_off = NULL; |
| 113 | return 0; | 102 | return 0; |
| 114 | } | 103 | } |
| 115 | 104 | ||
| 116 | static struct platform_driver olpc_xo1_driver = { | 105 | static struct platform_driver cs5535_pms_drv = { |
| 106 | .driver = { | ||
| 107 | .name = "cs5535-pms", | ||
| 108 | .owner = THIS_MODULE, | ||
| 109 | }, | ||
| 110 | .probe = olpc_xo1_probe, | ||
| 111 | .remove = __devexit_p(olpc_xo1_remove), | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct platform_driver cs5535_acpi_drv = { | ||
| 117 | .driver = { | 115 | .driver = { |
| 118 | .name = DRV_NAME, | 116 | .name = "cs5535-acpi", |
| 119 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
| 120 | }, | 118 | }, |
| 121 | .probe = olpc_xo1_probe, | 119 | .probe = olpc_xo1_probe, |
| @@ -124,12 +122,23 @@ static struct platform_driver olpc_xo1_driver = { | |||
| 124 | 122 | ||
| 125 | static int __init olpc_xo1_init(void) | 123 | static int __init olpc_xo1_init(void) |
| 126 | { | 124 | { |
| 127 | return platform_driver_register(&olpc_xo1_driver); | 125 | int r; |
| 126 | |||
| 127 | r = platform_driver_register(&cs5535_pms_drv); | ||
| 128 | if (r) | ||
| 129 | return r; | ||
| 130 | |||
| 131 | r = platform_driver_register(&cs5535_acpi_drv); | ||
| 132 | if (r) | ||
| 133 | platform_driver_unregister(&cs5535_pms_drv); | ||
| 134 | |||
| 135 | return r; | ||
| 128 | } | 136 | } |
| 129 | 137 | ||
| 130 | static void __exit olpc_xo1_exit(void) | 138 | static void __exit olpc_xo1_exit(void) |
| 131 | { | 139 | { |
| 132 | platform_driver_unregister(&olpc_xo1_driver); | 140 | platform_driver_unregister(&cs5535_acpi_drv); |
| 141 | platform_driver_unregister(&cs5535_pms_drv); | ||
| 133 | } | 142 | } |
| 134 | 143 | ||
| 135 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); | 144 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); |
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index daa7bc63f1d4..4ee58e72b730 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
| @@ -195,24 +195,24 @@ static int __init setup_hest_disable(char *str) | |||
| 195 | 195 | ||
| 196 | __setup("hest_disable", setup_hest_disable); | 196 | __setup("hest_disable", setup_hest_disable); |
| 197 | 197 | ||
| 198 | static int __init hest_init(void) | 198 | void __init acpi_hest_init(void) |
| 199 | { | 199 | { |
| 200 | acpi_status status; | 200 | acpi_status status; |
| 201 | int rc = -ENODEV; | 201 | int rc = -ENODEV; |
| 202 | unsigned int ghes_count = 0; | 202 | unsigned int ghes_count = 0; |
| 203 | 203 | ||
| 204 | if (acpi_disabled) | 204 | if (acpi_disabled) |
| 205 | goto err; | 205 | return; |
| 206 | 206 | ||
| 207 | if (hest_disable) { | 207 | if (hest_disable) { |
| 208 | pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); | 208 | pr_info(HEST_PFX "Table parsing disabled.\n"); |
| 209 | goto err; | 209 | return; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | status = acpi_get_table(ACPI_SIG_HEST, 0, | 212 | status = acpi_get_table(ACPI_SIG_HEST, 0, |
| 213 | (struct acpi_table_header **)&hest_tab); | 213 | (struct acpi_table_header **)&hest_tab); |
| 214 | if (status == AE_NOT_FOUND) { | 214 | if (status == AE_NOT_FOUND) { |
| 215 | pr_info(HEST_PFX "Table is not found!\n"); | 215 | pr_info(HEST_PFX "Table not found.\n"); |
| 216 | goto err; | 216 | goto err; |
| 217 | } else if (ACPI_FAILURE(status)) { | 217 | } else if (ACPI_FAILURE(status)) { |
| 218 | const char *msg = acpi_format_exception(status); | 218 | const char *msg = acpi_format_exception(status); |
| @@ -226,15 +226,11 @@ static int __init hest_init(void) | |||
| 226 | goto err; | 226 | goto err; |
| 227 | 227 | ||
| 228 | rc = hest_ghes_dev_register(ghes_count); | 228 | rc = hest_ghes_dev_register(ghes_count); |
| 229 | if (rc) | 229 | if (!rc) { |
| 230 | goto err; | 230 | pr_info(HEST_PFX "Table parsing has been initialized.\n"); |
| 231 | 231 | return; | |
| 232 | pr_info(HEST_PFX "HEST table parsing is initialized.\n"); | 232 | } |
| 233 | 233 | ||
| 234 | return 0; | ||
| 235 | err: | 234 | err: |
| 236 | hest_disable = 1; | 235 | hest_disable = 1; |
| 237 | return rc; | ||
| 238 | } | 236 | } |
| 239 | |||
| 240 | subsys_initcall(hest_init); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 96668ad09622..d9766797cd98 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 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 | #include <acpi/apei.h> | ||
| 39 | 40 | ||
| 40 | #define PREFIX "ACPI: " | 41 | #define PREFIX "ACPI: " |
| 41 | 42 | ||
| @@ -47,6 +48,11 @@ static int acpi_pci_root_add(struct acpi_device *device); | |||
| 47 | static int acpi_pci_root_remove(struct acpi_device *device, int type); | 48 | static int acpi_pci_root_remove(struct acpi_device *device, int type); |
| 48 | static int acpi_pci_root_start(struct acpi_device *device); | 49 | static int acpi_pci_root_start(struct acpi_device *device); |
| 49 | 50 | ||
| 51 | #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | ||
| 52 | | OSC_ACTIVE_STATE_PWR_SUPPORT \ | ||
| 53 | | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \ | ||
| 54 | | OSC_MSI_SUPPORT) | ||
| 55 | |||
| 50 | static const struct acpi_device_id root_device_ids[] = { | 56 | static const struct acpi_device_id root_device_ids[] = { |
| 51 | {"PNP0A03", 0}, | 57 | {"PNP0A03", 0}, |
| 52 | {"", 0}, | 58 | {"", 0}, |
| @@ -566,6 +572,33 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 566 | if (flags != base_flags) | 572 | if (flags != base_flags) |
| 567 | acpi_pci_osc_support(root, flags); | 573 | acpi_pci_osc_support(root, flags); |
| 568 | 574 | ||
| 575 | if (!pcie_ports_disabled | ||
| 576 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | ||
| 577 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
| 578 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
| 579 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
| 580 | |||
| 581 | if (pci_aer_available()) { | ||
| 582 | if (aer_acpi_firmware_first()) | ||
| 583 | dev_dbg(root->bus->bridge, | ||
| 584 | "PCIe errors handled by BIOS.\n"); | ||
| 585 | else | ||
| 586 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
| 587 | } | ||
| 588 | |||
| 589 | dev_info(root->bus->bridge, | ||
| 590 | "Requesting ACPI _OSC control (0x%02x)\n", flags); | ||
| 591 | |||
| 592 | status = acpi_pci_osc_control_set(device->handle, &flags, | ||
| 593 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
| 594 | if (ACPI_SUCCESS(status)) | ||
| 595 | dev_info(root->bus->bridge, | ||
| 596 | "ACPI _OSC control (0x%02x) granted\n", flags); | ||
| 597 | else | ||
| 598 | dev_dbg(root->bus->bridge, | ||
| 599 | "ACPI _OSC request failed (code %d)\n", status); | ||
| 600 | } | ||
| 601 | |||
| 569 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 602 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
| 570 | if (device->wakeup.flags.run_wake) | 603 | if (device->wakeup.flags.run_wake) |
| 571 | device_set_run_wake(root->bus->bridge, true); | 604 | device_set_run_wake(root->bus->bridge, true); |
| @@ -603,6 +636,8 @@ static int __init acpi_pci_root_init(void) | |||
| 603 | if (acpi_pci_disabled) | 636 | if (acpi_pci_disabled) |
| 604 | return 0; | 637 | return 0; |
| 605 | 638 | ||
| 639 | acpi_hest_init(); | ||
| 640 | |||
| 606 | pci_acpi_crs_quirks(); | 641 | pci_acpi_crs_quirks(); |
| 607 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) | 642 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) |
| 608 | return -ENODEV; | 643 | return -ENODEV; |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 07e9796fead7..857df10c0428 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
| @@ -717,8 +717,8 @@ static const struct intel_agp_driver_description { | |||
| 717 | { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver }, | 717 | { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver }, |
| 718 | { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver }, | 718 | { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver }, |
| 719 | { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver }, | 719 | { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver }, |
| 720 | { PCI_DEVICE_ID_INTEL_82845_HB, "845G", &intel_845_driver }, | 720 | { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver }, |
| 721 | { PCI_DEVICE_ID_INTEL_82845G_HB, "830M", &intel_845_driver }, | 721 | { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver }, |
| 722 | { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver }, | 722 | { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver }, |
| 723 | { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver }, | 723 | { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver }, |
| 724 | { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver }, | 724 | { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver }, |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index e921b693412b..826ab0939a12 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
| @@ -1361,7 +1361,7 @@ static const struct intel_gtt_driver_description { | |||
| 1361 | &i81x_gtt_driver}, | 1361 | &i81x_gtt_driver}, |
| 1362 | { PCI_DEVICE_ID_INTEL_82830_CGC, "830M", | 1362 | { PCI_DEVICE_ID_INTEL_82830_CGC, "830M", |
| 1363 | &i8xx_gtt_driver}, | 1363 | &i8xx_gtt_driver}, |
| 1364 | { PCI_DEVICE_ID_INTEL_82845G_IG, "830M", | 1364 | { PCI_DEVICE_ID_INTEL_82845G_IG, "845G", |
| 1365 | &i8xx_gtt_driver}, | 1365 | &i8xx_gtt_driver}, |
| 1366 | { PCI_DEVICE_ID_INTEL_82854_IG, "854", | 1366 | { PCI_DEVICE_ID_INTEL_82854_IG, "854", |
| 1367 | &i8xx_gtt_driver}, | 1367 | &i8xx_gtt_driver}, |
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 815d98b2c1ba..0d05ea7d499b 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c | |||
| @@ -11,14 +11,13 @@ | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/pci.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/cs5535.h> | 17 | #include <linux/cs5535.h> |
| 18 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
| 19 | 19 | ||
| 20 | #define DRV_NAME "cs5535-gpio" | 20 | #define DRV_NAME "cs5535-gpio" |
| 21 | #define GPIO_BAR 1 | ||
| 22 | 21 | ||
| 23 | /* | 22 | /* |
| 24 | * Some GPIO pins | 23 | * Some GPIO pins |
| @@ -47,7 +46,7 @@ static struct cs5535_gpio_chip { | |||
| 47 | struct gpio_chip chip; | 46 | struct gpio_chip chip; |
| 48 | resource_size_t base; | 47 | resource_size_t base; |
| 49 | 48 | ||
| 50 | struct pci_dev *pdev; | 49 | struct platform_device *pdev; |
| 51 | spinlock_t lock; | 50 | spinlock_t lock; |
| 52 | } cs5535_gpio_chip; | 51 | } cs5535_gpio_chip; |
| 53 | 52 | ||
| @@ -301,10 +300,10 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = { | |||
| 301 | }, | 300 | }, |
| 302 | }; | 301 | }; |
| 303 | 302 | ||
| 304 | static int __init cs5535_gpio_probe(struct pci_dev *pdev, | 303 | static int __devinit cs5535_gpio_probe(struct platform_device *pdev) |
| 305 | const struct pci_device_id *pci_id) | ||
| 306 | { | 304 | { |
| 307 | int err; | 305 | struct resource *res; |
| 306 | int err = -EIO; | ||
| 308 | ulong mask_orig = mask; | 307 | ulong mask_orig = mask; |
| 309 | 308 | ||
| 310 | /* There are two ways to get the GPIO base address; one is by | 309 | /* There are two ways to get the GPIO base address; one is by |
| @@ -314,25 +313,23 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev, | |||
| 314 | * it turns out to be unreliable in the face of crappy BIOSes, we | 313 | * it turns out to be unreliable in the face of crappy BIOSes, we |
| 315 | * can always go back to using MSRs.. */ | 314 | * can always go back to using MSRs.. */ |
| 316 | 315 | ||
| 317 | err = pci_enable_device_io(pdev); | 316 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 318 | if (err) { | 317 | if (!res) { |
| 319 | dev_err(&pdev->dev, "can't enable device IO\n"); | 318 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 320 | goto done; | 319 | goto done; |
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | err = pci_request_region(pdev, GPIO_BAR, DRV_NAME); | 322 | if (!request_region(res->start, resource_size(res), pdev->name)) { |
| 324 | if (err) { | 323 | dev_err(&pdev->dev, "can't request region\n"); |
| 325 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); | ||
| 326 | goto done; | 324 | goto done; |
| 327 | } | 325 | } |
| 328 | 326 | ||
| 329 | /* set up the driver-specific struct */ | 327 | /* set up the driver-specific struct */ |
| 330 | cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR); | 328 | cs5535_gpio_chip.base = res->start; |
| 331 | cs5535_gpio_chip.pdev = pdev; | 329 | cs5535_gpio_chip.pdev = pdev; |
| 332 | spin_lock_init(&cs5535_gpio_chip.lock); | 330 | spin_lock_init(&cs5535_gpio_chip.lock); |
| 333 | 331 | ||
| 334 | dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR, | 332 | dev_info(&pdev->dev, "reserved resource region %pR\n", res); |
| 335 | (unsigned long long) cs5535_gpio_chip.base); | ||
| 336 | 333 | ||
| 337 | /* mask out reserved pins */ | 334 | /* mask out reserved pins */ |
| 338 | mask &= 0x1F7FFFFF; | 335 | mask &= 0x1F7FFFFF; |
| @@ -350,78 +347,49 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev, | |||
| 350 | if (err) | 347 | if (err) |
| 351 | goto release_region; | 348 | goto release_region; |
| 352 | 349 | ||
| 353 | dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n"); | 350 | dev_info(&pdev->dev, "GPIO support successfully loaded.\n"); |
| 354 | return 0; | 351 | return 0; |
| 355 | 352 | ||
| 356 | release_region: | 353 | release_region: |
| 357 | pci_release_region(pdev, GPIO_BAR); | 354 | release_region(res->start, resource_size(res)); |
| 358 | done: | 355 | done: |
| 359 | return err; | 356 | return err; |
| 360 | } | 357 | } |
| 361 | 358 | ||
| 362 | static void __exit cs5535_gpio_remove(struct pci_dev *pdev) | 359 | static int __devexit cs5535_gpio_remove(struct platform_device *pdev) |
| 363 | { | 360 | { |
| 361 | struct resource *r; | ||
| 364 | int err; | 362 | int err; |
| 365 | 363 | ||
| 366 | err = gpiochip_remove(&cs5535_gpio_chip.chip); | 364 | err = gpiochip_remove(&cs5535_gpio_chip.chip); |
| 367 | if (err) { | 365 | if (err) { |
| 368 | /* uhh? */ | 366 | /* uhh? */ |
| 369 | dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); | 367 | dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); |
| 368 | return err; | ||
| 370 | } | 369 | } |
| 371 | pci_release_region(pdev, GPIO_BAR); | ||
| 372 | } | ||
| 373 | |||
| 374 | static struct pci_device_id cs5535_gpio_pci_tbl[] = { | ||
| 375 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
| 376 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
| 377 | { 0, }, | ||
| 378 | }; | ||
| 379 | MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl); | ||
| 380 | 370 | ||
| 381 | /* | 371 | r = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 382 | * We can't use the standard PCI driver registration stuff here, since | 372 | release_region(r->start, resource_size(r)); |
| 383 | * that allows only one driver to bind to each PCI device (and we want | 373 | return 0; |
| 384 | * multiple drivers to be able to bind to the device). Instead, manually | ||
| 385 | * scan for the PCI device, request a single region, and keep track of the | ||
| 386 | * devices that we're using. | ||
| 387 | */ | ||
| 388 | |||
| 389 | static int __init cs5535_gpio_scan_pci(void) | ||
| 390 | { | ||
| 391 | struct pci_dev *pdev; | ||
| 392 | int err = -ENODEV; | ||
| 393 | int i; | ||
| 394 | |||
| 395 | for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) { | ||
| 396 | pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor, | ||
| 397 | cs5535_gpio_pci_tbl[i].device, NULL); | ||
| 398 | if (pdev) { | ||
| 399 | err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]); | ||
| 400 | if (err) | ||
| 401 | pci_dev_put(pdev); | ||
| 402 | |||
| 403 | /* we only support a single CS5535/6 southbridge */ | ||
| 404 | break; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | return err; | ||
| 409 | } | 374 | } |
| 410 | 375 | ||
| 411 | static void __exit cs5535_gpio_free_pci(void) | 376 | static struct platform_driver cs5535_gpio_drv = { |
| 412 | { | 377 | .driver = { |
| 413 | cs5535_gpio_remove(cs5535_gpio_chip.pdev); | 378 | .name = DRV_NAME, |
| 414 | pci_dev_put(cs5535_gpio_chip.pdev); | 379 | .owner = THIS_MODULE, |
| 415 | } | 380 | }, |
| 381 | .probe = cs5535_gpio_probe, | ||
| 382 | .remove = __devexit_p(cs5535_gpio_remove), | ||
| 383 | }; | ||
| 416 | 384 | ||
| 417 | static int __init cs5535_gpio_init(void) | 385 | static int __init cs5535_gpio_init(void) |
| 418 | { | 386 | { |
| 419 | return cs5535_gpio_scan_pci(); | 387 | return platform_driver_register(&cs5535_gpio_drv); |
| 420 | } | 388 | } |
| 421 | 389 | ||
| 422 | static void __exit cs5535_gpio_exit(void) | 390 | static void __exit cs5535_gpio_exit(void) |
| 423 | { | 391 | { |
| 424 | cs5535_gpio_free_pci(); | 392 | platform_driver_unregister(&cs5535_gpio_drv); |
| 425 | } | 393 | } |
| 426 | 394 | ||
| 427 | module_init(cs5535_gpio_init); | 395 | module_init(cs5535_gpio_init); |
| @@ -430,3 +398,4 @@ module_exit(cs5535_gpio_exit); | |||
| 430 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | 398 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); |
| 431 | MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver"); | 399 | MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver"); |
| 432 | MODULE_LICENSE("GPL"); | 400 | MODULE_LICENSE("GPL"); |
| 401 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c index 349131eb1ce0..58c8f30352dd 100644 --- a/drivers/gpio/timbgpio.c +++ b/drivers/gpio/timbgpio.c | |||
| @@ -193,13 +193,13 @@ out: | |||
| 193 | return ret; | 193 | return ret; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static void timbgpio_irq(struct irq_data *d, struct irq_desc *desc) | 196 | static void timbgpio_irq(unsigned int irq, struct irq_desc *desc) |
| 197 | { | 197 | { |
| 198 | struct timbgpio *tgpio = irq_data_get_irq_data(d); | 198 | struct timbgpio *tgpio = get_irq_data(irq); |
| 199 | unsigned long ipr; | 199 | unsigned long ipr; |
| 200 | int offset; | 200 | int offset; |
| 201 | 201 | ||
| 202 | desc->irq_data.chip->ack(irq_get_irq_data(d)); | 202 | desc->irq_data.chip->irq_ack(irq_get_irq_data(irq)); |
| 203 | ipr = ioread32(tgpio->membase + TGPIO_IPR); | 203 | ipr = ioread32(tgpio->membase + TGPIO_IPR); |
| 204 | iowrite32(ipr, tgpio->membase + TGPIO_ICR); | 204 | iowrite32(ipr, tgpio->membase + TGPIO_ICR); |
| 205 | 205 | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 19a3d58044dd..3601466c5502 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -703,7 +703,7 @@ static void print_error_buffers(struct seq_file *m, | |||
| 703 | seq_printf(m, "%s [%d]:\n", name, count); | 703 | seq_printf(m, "%s [%d]:\n", name, count); |
| 704 | 704 | ||
| 705 | while (count--) { | 705 | while (count--) { |
| 706 | seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s%s", | 706 | seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s", |
| 707 | err->gtt_offset, | 707 | err->gtt_offset, |
| 708 | err->size, | 708 | err->size, |
| 709 | err->read_domains, | 709 | err->read_domains, |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0de75a23f8e7..72fea2bcfc4f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -49,6 +49,9 @@ module_param_named(powersave, i915_powersave, int, 0600); | |||
| 49 | unsigned int i915_lvds_downclock = 0; | 49 | unsigned int i915_lvds_downclock = 0; |
| 50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); | 50 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); |
| 51 | 51 | ||
| 52 | unsigned int i915_panel_use_ssc = 1; | ||
| 53 | module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); | ||
| 54 | |||
| 52 | bool i915_try_reset = true; | 55 | bool i915_try_reset = true; |
| 53 | module_param_named(reset, i915_try_reset, bool, 0600); | 56 | module_param_named(reset, i915_try_reset, bool, 0600); |
| 54 | 57 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 385fc7ec39d3..5969f46ac2d6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -954,6 +954,7 @@ extern int i915_max_ioctl; | |||
| 954 | extern unsigned int i915_fbpercrtc; | 954 | extern unsigned int i915_fbpercrtc; |
| 955 | extern unsigned int i915_powersave; | 955 | extern unsigned int i915_powersave; |
| 956 | extern unsigned int i915_lvds_downclock; | 956 | extern unsigned int i915_lvds_downclock; |
| 957 | extern unsigned int i915_panel_use_ssc; | ||
| 957 | 958 | ||
| 958 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 959 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
| 959 | extern int i915_resume(struct drm_device *dev); | 960 | extern int i915_resume(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e69834341ef0..dcfdf4151b6d 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -464,8 +464,6 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, | |||
| 464 | int ret; | 464 | int ret; |
| 465 | 465 | ||
| 466 | list_for_each_entry(obj, objects, exec_list) { | 466 | list_for_each_entry(obj, objects, exec_list) { |
| 467 | obj->base.pending_read_domains = 0; | ||
| 468 | obj->base.pending_write_domain = 0; | ||
| 469 | ret = i915_gem_execbuffer_relocate_object(obj, eb); | 467 | ret = i915_gem_execbuffer_relocate_object(obj, eb); |
| 470 | if (ret) | 468 | if (ret) |
| 471 | return ret; | 469 | return ret; |
| @@ -505,6 +503,9 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
| 505 | list_move(&obj->exec_list, &ordered_objects); | 503 | list_move(&obj->exec_list, &ordered_objects); |
| 506 | else | 504 | else |
| 507 | list_move_tail(&obj->exec_list, &ordered_objects); | 505 | list_move_tail(&obj->exec_list, &ordered_objects); |
| 506 | |||
| 507 | obj->base.pending_read_domains = 0; | ||
| 508 | obj->base.pending_write_domain = 0; | ||
| 508 | } | 509 | } |
| 509 | list_splice(&ordered_objects, objects); | 510 | list_splice(&ordered_objects, objects); |
| 510 | 511 | ||
| @@ -636,6 +637,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
| 636 | { | 637 | { |
| 637 | struct drm_i915_gem_relocation_entry *reloc; | 638 | struct drm_i915_gem_relocation_entry *reloc; |
| 638 | struct drm_i915_gem_object *obj; | 639 | struct drm_i915_gem_object *obj; |
| 640 | int *reloc_offset; | ||
| 639 | int i, total, ret; | 641 | int i, total, ret; |
| 640 | 642 | ||
| 641 | /* We may process another execbuffer during the unlock... */ | 643 | /* We may process another execbuffer during the unlock... */ |
| @@ -653,8 +655,11 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
| 653 | for (i = 0; i < count; i++) | 655 | for (i = 0; i < count; i++) |
| 654 | total += exec[i].relocation_count; | 656 | total += exec[i].relocation_count; |
| 655 | 657 | ||
| 658 | reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset)); | ||
| 656 | reloc = drm_malloc_ab(total, sizeof(*reloc)); | 659 | reloc = drm_malloc_ab(total, sizeof(*reloc)); |
| 657 | if (reloc == NULL) { | 660 | if (reloc == NULL || reloc_offset == NULL) { |
| 661 | drm_free_large(reloc); | ||
| 662 | drm_free_large(reloc_offset); | ||
| 658 | mutex_lock(&dev->struct_mutex); | 663 | mutex_lock(&dev->struct_mutex); |
| 659 | return -ENOMEM; | 664 | return -ENOMEM; |
| 660 | } | 665 | } |
| @@ -672,6 +677,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
| 672 | goto err; | 677 | goto err; |
| 673 | } | 678 | } |
| 674 | 679 | ||
| 680 | reloc_offset[i] = total; | ||
| 675 | total += exec[i].relocation_count; | 681 | total += exec[i].relocation_count; |
| 676 | } | 682 | } |
| 677 | 683 | ||
| @@ -705,17 +711,12 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
| 705 | if (ret) | 711 | if (ret) |
| 706 | goto err; | 712 | goto err; |
| 707 | 713 | ||
| 708 | total = 0; | ||
| 709 | list_for_each_entry(obj, objects, exec_list) { | 714 | list_for_each_entry(obj, objects, exec_list) { |
| 710 | obj->base.pending_read_domains = 0; | 715 | int offset = obj->exec_entry - exec; |
| 711 | obj->base.pending_write_domain = 0; | ||
| 712 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, | 716 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, |
| 713 | reloc + total); | 717 | reloc + reloc_offset[offset]); |
| 714 | if (ret) | 718 | if (ret) |
| 715 | goto err; | 719 | goto err; |
| 716 | |||
| 717 | total += exec->relocation_count; | ||
| 718 | exec++; | ||
| 719 | } | 720 | } |
| 720 | 721 | ||
| 721 | /* Leave the user relocations as are, this is the painfully slow path, | 722 | /* Leave the user relocations as are, this is the painfully slow path, |
| @@ -726,6 +727,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
| 726 | 727 | ||
| 727 | err: | 728 | err: |
| 728 | drm_free_large(reloc); | 729 | drm_free_large(reloc); |
| 730 | drm_free_large(reloc_offset); | ||
| 729 | return ret; | 731 | return ret; |
| 730 | } | 732 | } |
| 731 | 733 | ||
| @@ -770,7 +772,8 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, | |||
| 770 | if (from == NULL || to == from) | 772 | if (from == NULL || to == from) |
| 771 | return 0; | 773 | return 0; |
| 772 | 774 | ||
| 773 | if (INTEL_INFO(obj->base.dev)->gen < 6) | 775 | /* XXX gpu semaphores are currently causing hard hangs on SNB mobile */ |
| 776 | if (INTEL_INFO(obj->base.dev)->gen < 6 || IS_MOBILE(obj->base.dev)) | ||
| 774 | return i915_gem_object_wait_rendering(obj, true); | 777 | return i915_gem_object_wait_rendering(obj, true); |
| 775 | 778 | ||
| 776 | idx = intel_ring_sync_index(from, to); | 779 | idx = intel_ring_sync_index(from, to); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e418e8bb61e6..b8e509ae065e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -720,7 +720,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, | |||
| 720 | if (obj->ring != ring) | 720 | if (obj->ring != ring) |
| 721 | continue; | 721 | continue; |
| 722 | 722 | ||
| 723 | if (!i915_seqno_passed(obj->last_rendering_seqno, seqno)) | 723 | if (i915_seqno_passed(seqno, obj->last_rendering_seqno)) |
| 724 | continue; | 724 | continue; |
| 725 | 725 | ||
| 726 | if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) | 726 | if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b0b1200ed650..0b44956c336b 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
| @@ -264,17 +264,12 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
| 264 | dev_priv->int_crt_support = general->int_crt_support; | 264 | dev_priv->int_crt_support = general->int_crt_support; |
| 265 | dev_priv->lvds_use_ssc = general->enable_ssc; | 265 | dev_priv->lvds_use_ssc = general->enable_ssc; |
| 266 | 266 | ||
| 267 | if (dev_priv->lvds_use_ssc) { | 267 | if (IS_I85X(dev)) |
| 268 | if (IS_I85X(dev)) | 268 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; |
| 269 | dev_priv->lvds_ssc_freq = | 269 | else if (IS_GEN5(dev) || IS_GEN6(dev)) |
| 270 | general->ssc_freq ? 66 : 48; | 270 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 120; |
| 271 | else if (IS_GEN5(dev) || IS_GEN6(dev)) | 271 | else |
| 272 | dev_priv->lvds_ssc_freq = | 272 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; |
| 273 | general->ssc_freq ? 100 : 120; | ||
| 274 | else | ||
| 275 | dev_priv->lvds_ssc_freq = | ||
| 276 | general->ssc_freq ? 100 : 96; | ||
| 277 | } | ||
| 278 | } | 273 | } |
| 279 | } | 274 | } |
| 280 | 275 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 25d96889d7d2..98967f3b7724 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -3822,6 +3822,11 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
| 3822 | sr_hdisplay, sr_htotal, pixel_size); | 3822 | sr_hdisplay, sr_htotal, pixel_size); |
| 3823 | } | 3823 | } |
| 3824 | 3824 | ||
| 3825 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | ||
| 3826 | { | ||
| 3827 | return dev_priv->lvds_use_ssc && i915_panel_use_ssc; | ||
| 3828 | } | ||
| 3829 | |||
| 3825 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 3830 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
| 3826 | struct drm_display_mode *mode, | 3831 | struct drm_display_mode *mode, |
| 3827 | struct drm_display_mode *adjusted_mode, | 3832 | struct drm_display_mode *adjusted_mode, |
| @@ -3884,7 +3889,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3884 | num_connectors++; | 3889 | num_connectors++; |
| 3885 | } | 3890 | } |
| 3886 | 3891 | ||
| 3887 | if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { | 3892 | if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { |
| 3888 | refclk = dev_priv->lvds_ssc_freq * 1000; | 3893 | refclk = dev_priv->lvds_ssc_freq * 1000; |
| 3889 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", | 3894 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", |
| 3890 | refclk / 1000); | 3895 | refclk / 1000); |
| @@ -4059,7 +4064,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4059 | udelay(200); | 4064 | udelay(200); |
| 4060 | 4065 | ||
| 4061 | if (has_edp_encoder) { | 4066 | if (has_edp_encoder) { |
| 4062 | if (dev_priv->lvds_use_ssc) { | 4067 | if (intel_panel_use_ssc(dev_priv)) { |
| 4063 | temp |= DREF_SSC1_ENABLE; | 4068 | temp |= DREF_SSC1_ENABLE; |
| 4064 | I915_WRITE(PCH_DREF_CONTROL, temp); | 4069 | I915_WRITE(PCH_DREF_CONTROL, temp); |
| 4065 | 4070 | ||
| @@ -4070,13 +4075,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4070 | 4075 | ||
| 4071 | /* Enable CPU source on CPU attached eDP */ | 4076 | /* Enable CPU source on CPU attached eDP */ |
| 4072 | if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | 4077 | if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
| 4073 | if (dev_priv->lvds_use_ssc) | 4078 | if (intel_panel_use_ssc(dev_priv)) |
| 4074 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; | 4079 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; |
| 4075 | else | 4080 | else |
| 4076 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | 4081 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; |
| 4077 | } else { | 4082 | } else { |
| 4078 | /* Enable SSC on PCH eDP if needed */ | 4083 | /* Enable SSC on PCH eDP if needed */ |
| 4079 | if (dev_priv->lvds_use_ssc) { | 4084 | if (intel_panel_use_ssc(dev_priv)) { |
| 4080 | DRM_ERROR("enabling SSC on PCH\n"); | 4085 | DRM_ERROR("enabling SSC on PCH\n"); |
| 4081 | temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; | 4086 | temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; |
| 4082 | } | 4087 | } |
| @@ -4104,7 +4109,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4104 | int factor = 21; | 4109 | int factor = 21; |
| 4105 | 4110 | ||
| 4106 | if (is_lvds) { | 4111 | if (is_lvds) { |
| 4107 | if ((dev_priv->lvds_use_ssc && | 4112 | if ((intel_panel_use_ssc(dev_priv) && |
| 4108 | dev_priv->lvds_ssc_freq == 100) || | 4113 | dev_priv->lvds_ssc_freq == 100) || |
| 4109 | (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) | 4114 | (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) |
| 4110 | factor = 25; | 4115 | factor = 25; |
| @@ -4183,7 +4188,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4183 | /* XXX: just matching BIOS for now */ | 4188 | /* XXX: just matching BIOS for now */ |
| 4184 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ | 4189 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
| 4185 | dpll |= 3; | 4190 | dpll |= 3; |
| 4186 | else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) | 4191 | else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) |
| 4187 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; | 4192 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
| 4188 | else | 4193 | else |
| 4189 | dpll |= PLL_REF_INPUT_DREFCLK; | 4194 | dpll |= PLL_REF_INPUT_DREFCLK; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 8f4f6bd33ee9..ace8d5d30dd2 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -704,6 +704,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 704 | }, | 704 | }, |
| 705 | { | 705 | { |
| 706 | .callback = intel_no_lvds_dmi_callback, | 706 | .callback = intel_no_lvds_dmi_callback, |
| 707 | .ident = "AOpen i915GMm-HFS", | ||
| 708 | .matches = { | ||
| 709 | DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), | ||
| 710 | DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), | ||
| 711 | }, | ||
| 712 | }, | ||
| 713 | { | ||
| 714 | .callback = intel_no_lvds_dmi_callback, | ||
| 707 | .ident = "Aopen i945GTt-VFA", | 715 | .ident = "Aopen i945GTt-VFA", |
| 708 | .matches = { | 716 | .matches = { |
| 709 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 717 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e00d200df3db..c65992df458d 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -278,6 +278,6 @@ void intel_panel_setup_backlight(struct drm_device *dev) | |||
| 278 | { | 278 | { |
| 279 | struct drm_i915_private *dev_priv = dev->dev_private; | 279 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 280 | 280 | ||
| 281 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | 281 | dev_priv->backlight_level = intel_panel_get_backlight(dev); |
| 282 | dev_priv->backlight_enabled = dev_priv->backlight_level != 0; | 282 | dev_priv->backlight_enabled = dev_priv->backlight_level != 0; |
| 283 | } | 283 | } |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 53fab518b3da..986e5f62debe 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
| 31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 32 | #include <linux/platform_device.h> | ||
| 32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
| 33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| @@ -40,6 +41,7 @@ | |||
| 40 | 41 | ||
| 41 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); | 42 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); |
| 42 | MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); | 43 | MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); |
| 44 | MODULE_ALIAS("platform:cs5535-smb"); | ||
| 43 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
| 44 | 46 | ||
| 45 | #define MAX_DEVICES 4 | 47 | #define MAX_DEVICES 4 |
| @@ -84,10 +86,6 @@ struct scx200_acb_iface { | |||
| 84 | u8 *ptr; | 86 | u8 *ptr; |
| 85 | char needs_reset; | 87 | char needs_reset; |
| 86 | unsigned len; | 88 | unsigned len; |
| 87 | |||
| 88 | /* PCI device info */ | ||
| 89 | struct pci_dev *pdev; | ||
| 90 | int bar; | ||
| 91 | }; | 89 | }; |
| 92 | 90 | ||
| 93 | /* Register Definitions */ | 91 | /* Register Definitions */ |
| @@ -391,7 +389,7 @@ static const struct i2c_algorithm scx200_acb_algorithm = { | |||
| 391 | static struct scx200_acb_iface *scx200_acb_list; | 389 | static struct scx200_acb_iface *scx200_acb_list; |
| 392 | static DEFINE_MUTEX(scx200_acb_list_mutex); | 390 | static DEFINE_MUTEX(scx200_acb_list_mutex); |
| 393 | 391 | ||
| 394 | static __init int scx200_acb_probe(struct scx200_acb_iface *iface) | 392 | static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) |
| 395 | { | 393 | { |
| 396 | u8 val; | 394 | u8 val; |
| 397 | 395 | ||
| @@ -427,7 +425,7 @@ static __init int scx200_acb_probe(struct scx200_acb_iface *iface) | |||
| 427 | return 0; | 425 | return 0; |
| 428 | } | 426 | } |
| 429 | 427 | ||
| 430 | static __init struct scx200_acb_iface *scx200_create_iface(const char *text, | 428 | static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text, |
| 431 | struct device *dev, int index) | 429 | struct device *dev, int index) |
| 432 | { | 430 | { |
| 433 | struct scx200_acb_iface *iface; | 431 | struct scx200_acb_iface *iface; |
| @@ -452,7 +450,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text, | |||
| 452 | return iface; | 450 | return iface; |
| 453 | } | 451 | } |
| 454 | 452 | ||
| 455 | static int __init scx200_acb_create(struct scx200_acb_iface *iface) | 453 | static int __devinit scx200_acb_create(struct scx200_acb_iface *iface) |
| 456 | { | 454 | { |
| 457 | struct i2c_adapter *adapter; | 455 | struct i2c_adapter *adapter; |
| 458 | int rc; | 456 | int rc; |
| @@ -472,183 +470,145 @@ static int __init scx200_acb_create(struct scx200_acb_iface *iface) | |||
| 472 | return -ENODEV; | 470 | return -ENODEV; |
| 473 | } | 471 | } |
| 474 | 472 | ||
| 475 | mutex_lock(&scx200_acb_list_mutex); | 473 | if (!adapter->dev.parent) { |
| 476 | iface->next = scx200_acb_list; | 474 | /* If there's no dev, we're tracking (ISA) ifaces manually */ |
| 477 | scx200_acb_list = iface; | 475 | mutex_lock(&scx200_acb_list_mutex); |
| 478 | mutex_unlock(&scx200_acb_list_mutex); | 476 | iface->next = scx200_acb_list; |
| 477 | scx200_acb_list = iface; | ||
| 478 | mutex_unlock(&scx200_acb_list_mutex); | ||
| 479 | } | ||
| 479 | 480 | ||
| 480 | return 0; | 481 | return 0; |
| 481 | } | 482 | } |
| 482 | 483 | ||
| 483 | static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, | 484 | static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text, |
| 484 | int bar) | 485 | unsigned long base, int index, struct device *dev) |
| 485 | { | 486 | { |
| 486 | struct scx200_acb_iface *iface; | 487 | struct scx200_acb_iface *iface; |
| 487 | int rc; | 488 | int rc; |
| 488 | 489 | ||
| 489 | iface = scx200_create_iface(text, &pdev->dev, 0); | 490 | iface = scx200_create_iface(text, dev, index); |
| 490 | 491 | ||
| 491 | if (iface == NULL) | 492 | if (iface == NULL) |
| 492 | return -ENOMEM; | 493 | return NULL; |
| 493 | |||
| 494 | iface->pdev = pdev; | ||
| 495 | iface->bar = bar; | ||
| 496 | |||
| 497 | rc = pci_enable_device_io(iface->pdev); | ||
| 498 | if (rc) | ||
| 499 | goto errout_free; | ||
| 500 | 494 | ||
| 501 | rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); | 495 | if (!request_region(base, 8, iface->adapter.name)) { |
| 502 | if (rc) { | 496 | printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", |
| 503 | printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", | 497 | base, base + 8 - 1); |
| 504 | iface->bar); | ||
| 505 | goto errout_free; | 498 | goto errout_free; |
| 506 | } | 499 | } |
| 507 | 500 | ||
| 508 | iface->base = pci_resource_start(iface->pdev, iface->bar); | 501 | iface->base = base; |
| 509 | rc = scx200_acb_create(iface); | 502 | rc = scx200_acb_create(iface); |
| 510 | 503 | ||
| 511 | if (rc == 0) | 504 | if (rc == 0) |
| 512 | return 0; | 505 | return iface; |
| 513 | 506 | ||
| 514 | pci_release_region(iface->pdev, iface->bar); | 507 | release_region(base, 8); |
| 515 | pci_dev_put(iface->pdev); | ||
| 516 | errout_free: | 508 | errout_free: |
| 517 | kfree(iface); | 509 | kfree(iface); |
| 518 | return rc; | 510 | return NULL; |
| 519 | } | 511 | } |
| 520 | 512 | ||
| 521 | static int __init scx200_create_isa(const char *text, unsigned long base, | 513 | static int __devinit scx200_probe(struct platform_device *pdev) |
| 522 | int index) | ||
| 523 | { | 514 | { |
| 524 | struct scx200_acb_iface *iface; | 515 | struct scx200_acb_iface *iface; |
| 525 | int rc; | 516 | struct resource *res; |
| 526 | |||
| 527 | iface = scx200_create_iface(text, NULL, index); | ||
| 528 | |||
| 529 | if (iface == NULL) | ||
| 530 | return -ENOMEM; | ||
| 531 | 517 | ||
| 532 | if (!request_region(base, 8, iface->adapter.name)) { | 518 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 533 | printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", | 519 | if (!res) { |
| 534 | base, base + 8 - 1); | 520 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 535 | rc = -EBUSY; | 521 | return -ENODEV; |
| 536 | goto errout_free; | ||
| 537 | } | 522 | } |
| 538 | 523 | ||
| 539 | iface->base = base; | 524 | iface = scx200_create_dev("CS5535", res->start, 0, &pdev->dev); |
| 540 | rc = scx200_acb_create(iface); | 525 | if (!iface) |
| 526 | return -EIO; | ||
| 541 | 527 | ||
| 542 | if (rc == 0) | 528 | dev_info(&pdev->dev, "SCx200 device '%s' registered\n", |
| 543 | return 0; | 529 | iface->adapter.name); |
| 530 | platform_set_drvdata(pdev, iface); | ||
| 544 | 531 | ||
| 545 | release_region(base, 8); | 532 | return 0; |
| 546 | errout_free: | ||
| 547 | kfree(iface); | ||
| 548 | return rc; | ||
| 549 | } | 533 | } |
| 550 | 534 | ||
| 551 | /* Driver data is an index into the scx200_data array that indicates | 535 | static void __devexit scx200_cleanup_iface(struct scx200_acb_iface *iface) |
| 552 | * the name and the BAR where the I/O address resource is located. ISA | 536 | { |
| 553 | * devices are flagged with a bar value of -1 */ | 537 | i2c_del_adapter(&iface->adapter); |
| 554 | 538 | release_region(iface->base, 8); | |
| 555 | static const struct pci_device_id scx200_pci[] __initconst = { | 539 | kfree(iface); |
| 556 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE), | 540 | } |
| 557 | .driver_data = 0 }, | ||
| 558 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE), | ||
| 559 | .driver_data = 0 }, | ||
| 560 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA), | ||
| 561 | .driver_data = 1 }, | ||
| 562 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA), | ||
| 563 | .driver_data = 2 }, | ||
| 564 | { 0, } | ||
| 565 | }; | ||
| 566 | |||
| 567 | static struct { | ||
| 568 | const char *name; | ||
| 569 | int bar; | ||
| 570 | } scx200_data[] = { | ||
| 571 | { "SCx200", -1 }, | ||
| 572 | { "CS5535", 0 }, | ||
| 573 | { "CS5536", 0 } | ||
| 574 | }; | ||
| 575 | 541 | ||
| 576 | static __init int scx200_scan_pci(void) | 542 | static int __devexit scx200_remove(struct platform_device *pdev) |
| 577 | { | 543 | { |
| 578 | int data, dev; | 544 | struct scx200_acb_iface *iface; |
| 579 | int rc = -ENODEV; | ||
| 580 | struct pci_dev *pdev; | ||
| 581 | 545 | ||
| 582 | for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) { | 546 | iface = platform_get_drvdata(pdev); |
| 583 | pdev = pci_get_device(scx200_pci[dev].vendor, | 547 | platform_set_drvdata(pdev, NULL); |
| 584 | scx200_pci[dev].device, NULL); | 548 | scx200_cleanup_iface(iface); |
| 585 | 549 | ||
| 586 | if (pdev == NULL) | 550 | return 0; |
| 587 | continue; | 551 | } |
| 588 | 552 | ||
| 589 | data = scx200_pci[dev].driver_data; | 553 | static struct platform_driver scx200_pci_drv = { |
| 554 | .driver = { | ||
| 555 | .name = "cs5535-smb", | ||
| 556 | .owner = THIS_MODULE, | ||
| 557 | }, | ||
| 558 | .probe = scx200_probe, | ||
| 559 | .remove = __devexit_p(scx200_remove), | ||
| 560 | }; | ||
| 590 | 561 | ||
| 591 | /* if .bar is greater or equal to zero, this is a | 562 | static const struct pci_device_id scx200_isa[] __initconst = { |
| 592 | * PCI device - otherwise, we assume | 563 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, |
| 593 | that the ports are ISA based | 564 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, |
| 594 | */ | 565 | { 0, } |
| 566 | }; | ||
| 595 | 567 | ||
| 596 | if (scx200_data[data].bar >= 0) | 568 | static __init void scx200_scan_isa(void) |
| 597 | rc = scx200_create_pci(scx200_data[data].name, pdev, | 569 | { |
| 598 | scx200_data[data].bar); | 570 | int i; |
| 599 | else { | ||
| 600 | int i; | ||
| 601 | 571 | ||
| 602 | pci_dev_put(pdev); | 572 | if (!pci_dev_present(scx200_isa)) |
| 603 | for (i = 0; i < MAX_DEVICES; ++i) { | 573 | return; |
| 604 | if (base[i] == 0) | ||
| 605 | continue; | ||
| 606 | 574 | ||
| 607 | rc = scx200_create_isa(scx200_data[data].name, | 575 | for (i = 0; i < MAX_DEVICES; ++i) { |
| 608 | base[i], | 576 | if (base[i] == 0) |
| 609 | i); | 577 | continue; |
| 610 | } | ||
| 611 | } | ||
| 612 | 578 | ||
| 613 | break; | 579 | /* XXX: should we care about failures? */ |
| 580 | scx200_create_dev("SCx200", base[i], i, NULL); | ||
| 614 | } | 581 | } |
| 615 | |||
| 616 | return rc; | ||
| 617 | } | 582 | } |
| 618 | 583 | ||
| 619 | static int __init scx200_acb_init(void) | 584 | static int __init scx200_acb_init(void) |
| 620 | { | 585 | { |
| 621 | int rc; | ||
| 622 | |||
| 623 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); | 586 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); |
| 624 | 587 | ||
| 625 | rc = scx200_scan_pci(); | 588 | /* First scan for ISA-based devices */ |
| 589 | scx200_scan_isa(); /* XXX: should we care about errors? */ | ||
| 626 | 590 | ||
| 627 | /* If at least one bus was created, init must succeed */ | 591 | /* If at least one bus was created, init must succeed */ |
| 628 | if (scx200_acb_list) | 592 | if (scx200_acb_list) |
| 629 | return 0; | 593 | return 0; |
| 630 | return rc; | 594 | |
| 595 | /* No ISA devices; register the platform driver for PCI-based devices */ | ||
| 596 | return platform_driver_register(&scx200_pci_drv); | ||
| 631 | } | 597 | } |
| 632 | 598 | ||
| 633 | static void __exit scx200_acb_cleanup(void) | 599 | static void __exit scx200_acb_cleanup(void) |
| 634 | { | 600 | { |
| 635 | struct scx200_acb_iface *iface; | 601 | struct scx200_acb_iface *iface; |
| 636 | 602 | ||
| 603 | platform_driver_unregister(&scx200_pci_drv); | ||
| 604 | |||
| 637 | mutex_lock(&scx200_acb_list_mutex); | 605 | mutex_lock(&scx200_acb_list_mutex); |
| 638 | while ((iface = scx200_acb_list) != NULL) { | 606 | while ((iface = scx200_acb_list) != NULL) { |
| 639 | scx200_acb_list = iface->next; | 607 | scx200_acb_list = iface->next; |
| 640 | mutex_unlock(&scx200_acb_list_mutex); | 608 | mutex_unlock(&scx200_acb_list_mutex); |
| 641 | 609 | ||
| 642 | i2c_del_adapter(&iface->adapter); | 610 | scx200_cleanup_iface(iface); |
| 643 | |||
| 644 | if (iface->pdev) { | ||
| 645 | pci_release_region(iface->pdev, iface->bar); | ||
| 646 | pci_dev_put(iface->pdev); | ||
| 647 | } | ||
| 648 | else | ||
| 649 | release_region(iface->base, 8); | ||
| 650 | 611 | ||
| 651 | kfree(iface); | ||
| 652 | mutex_lock(&scx200_acb_list_mutex); | 612 | mutex_lock(&scx200_acb_list_mutex); |
| 653 | } | 613 | } |
| 654 | mutex_unlock(&scx200_acb_list_mutex); | 614 | mutex_unlock(&scx200_acb_list_mutex); |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 789087cd6a9c..49f1b8f1418e 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
| @@ -2184,9 +2184,7 @@ static int cafe_pci_resume(struct pci_dev *pdev) | |||
| 2184 | struct cafe_camera *cam = to_cam(v4l2_dev); | 2184 | struct cafe_camera *cam = to_cam(v4l2_dev); |
| 2185 | int ret = 0; | 2185 | int ret = 0; |
| 2186 | 2186 | ||
| 2187 | ret = pci_restore_state(pdev); | 2187 | pci_restore_state(pdev); |
| 2188 | if (ret) | ||
| 2189 | return ret; | ||
| 2190 | ret = pci_enable_device(pdev); | 2188 | ret = pci_enable_device(pdev); |
| 2191 | 2189 | ||
| 2192 | if (ret) { | 2190 | if (ret) { |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 20895e7a99c9..793300c554b4 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
| @@ -361,12 +361,6 @@ static struct pm860x_irq_data pm860x_irqs[] = { | |||
| 361 | }, | 361 | }, |
| 362 | }; | 362 | }; |
| 363 | 363 | ||
| 364 | static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip, | ||
| 365 | int irq) | ||
| 366 | { | ||
| 367 | return &pm860x_irqs[irq - chip->irq_base]; | ||
| 368 | } | ||
| 369 | |||
| 370 | static irqreturn_t pm860x_irq(int irq, void *data) | 364 | static irqreturn_t pm860x_irq(int irq, void *data) |
| 371 | { | 365 | { |
| 372 | struct pm860x_chip *chip = data; | 366 | struct pm860x_chip *chip = data; |
| @@ -388,16 +382,16 @@ static irqreturn_t pm860x_irq(int irq, void *data) | |||
| 388 | return IRQ_HANDLED; | 382 | return IRQ_HANDLED; |
| 389 | } | 383 | } |
| 390 | 384 | ||
| 391 | static void pm860x_irq_lock(unsigned int irq) | 385 | static void pm860x_irq_lock(struct irq_data *data) |
| 392 | { | 386 | { |
| 393 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 387 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 394 | 388 | ||
| 395 | mutex_lock(&chip->irq_lock); | 389 | mutex_lock(&chip->irq_lock); |
| 396 | } | 390 | } |
| 397 | 391 | ||
| 398 | static void pm860x_irq_sync_unlock(unsigned int irq) | 392 | static void pm860x_irq_sync_unlock(struct irq_data *data) |
| 399 | { | 393 | { |
| 400 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 394 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 401 | struct pm860x_irq_data *irq_data; | 395 | struct pm860x_irq_data *irq_data; |
| 402 | struct i2c_client *i2c; | 396 | struct i2c_client *i2c; |
| 403 | static unsigned char cached[3] = {0x0, 0x0, 0x0}; | 397 | static unsigned char cached[3] = {0x0, 0x0, 0x0}; |
| @@ -439,25 +433,25 @@ static void pm860x_irq_sync_unlock(unsigned int irq) | |||
| 439 | mutex_unlock(&chip->irq_lock); | 433 | mutex_unlock(&chip->irq_lock); |
| 440 | } | 434 | } |
| 441 | 435 | ||
| 442 | static void pm860x_irq_enable(unsigned int irq) | 436 | static void pm860x_irq_enable(struct irq_data *data) |
| 443 | { | 437 | { |
| 444 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 438 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 445 | pm860x_irqs[irq - chip->irq_base].enable | 439 | pm860x_irqs[data->irq - chip->irq_base].enable |
| 446 | = pm860x_irqs[irq - chip->irq_base].offs; | 440 | = pm860x_irqs[data->irq - chip->irq_base].offs; |
| 447 | } | 441 | } |
| 448 | 442 | ||
| 449 | static void pm860x_irq_disable(unsigned int irq) | 443 | static void pm860x_irq_disable(struct irq_data *data) |
| 450 | { | 444 | { |
| 451 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 445 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 452 | pm860x_irqs[irq - chip->irq_base].enable = 0; | 446 | pm860x_irqs[data->irq - chip->irq_base].enable = 0; |
| 453 | } | 447 | } |
| 454 | 448 | ||
| 455 | static struct irq_chip pm860x_irq_chip = { | 449 | static struct irq_chip pm860x_irq_chip = { |
| 456 | .name = "88pm860x", | 450 | .name = "88pm860x", |
| 457 | .bus_lock = pm860x_irq_lock, | 451 | .irq_bus_lock = pm860x_irq_lock, |
| 458 | .bus_sync_unlock = pm860x_irq_sync_unlock, | 452 | .irq_bus_sync_unlock = pm860x_irq_sync_unlock, |
| 459 | .enable = pm860x_irq_enable, | 453 | .irq_enable = pm860x_irq_enable, |
| 460 | .disable = pm860x_irq_disable, | 454 | .irq_disable = pm860x_irq_disable, |
| 461 | }; | 455 | }; |
| 462 | 456 | ||
| 463 | static int __devinit device_gpadc_init(struct pm860x_chip *chip, | 457 | static int __devinit device_gpadc_init(struct pm860x_chip *chip, |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index da9d2971102e..fd018366d670 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
| @@ -496,13 +496,13 @@ config EZX_PCAP | |||
| 496 | 496 | ||
| 497 | config AB8500_CORE | 497 | config AB8500_CORE |
| 498 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" | 498 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" |
| 499 | depends on GENERIC_HARDIRQS && ABX500_CORE && SPI_MASTER && ARCH_U8500 | 499 | depends on GENERIC_HARDIRQS && ABX500_CORE |
| 500 | select MFD_CORE | 500 | select MFD_CORE |
| 501 | help | 501 | help |
| 502 | Select this option to enable access to AB8500 power management | 502 | Select this option to enable access to AB8500 power management |
| 503 | chip. This connects to U8500 either on the SSP/SPI bus | 503 | chip. This connects to U8500 either on the SSP/SPI bus (deprecated |
| 504 | or the I2C bus via PRCMU. It also adds the irq_chip | 504 | since hardware version v1.0) or the I2C bus via PRCMU. It also adds |
| 505 | parts for handling the Mixed Signal chip events. | 505 | the irq_chip parts for handling the Mixed Signal chip events. |
| 506 | This chip embeds various other multimedia funtionalities as well. | 506 | This chip embeds various other multimedia funtionalities as well. |
| 507 | 507 | ||
| 508 | config AB8500_I2C_CORE | 508 | config AB8500_I2C_CORE |
| @@ -537,6 +537,14 @@ config AB3550_CORE | |||
| 537 | LEDs, vibrator, system power and temperature, power management | 537 | LEDs, vibrator, system power and temperature, power management |
| 538 | and ALSA sound. | 538 | and ALSA sound. |
| 539 | 539 | ||
| 540 | config MFD_CS5535 | ||
| 541 | tristate "Support for CS5535 and CS5536 southbridge core functions" | ||
| 542 | select MFD_CORE | ||
| 543 | depends on PCI | ||
| 544 | ---help--- | ||
| 545 | This is the core driver for CS5535/CS5536 MFD functions. This is | ||
| 546 | necessary for using the board's GPIO and MFGPT functionality. | ||
| 547 | |||
| 540 | config MFD_TIMBERDALE | 548 | config MFD_TIMBERDALE |
| 541 | tristate "Support for the Timberdale FPGA" | 549 | tristate "Support for the Timberdale FPGA" |
| 542 | select MFD_CORE | 550 | select MFD_CORE |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 848e7eac75aa..a54e2c7c6a1c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
| @@ -70,7 +70,7 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o | |||
| 70 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o | 70 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o |
| 71 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o | 71 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o |
| 72 | obj-$(CONFIG_AB3550_CORE) += ab3550-core.o | 72 | obj-$(CONFIG_AB3550_CORE) += ab3550-core.o |
| 73 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o | 73 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o |
| 74 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o | 74 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o |
| 75 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o | 75 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o |
| 76 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o | 76 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o |
| @@ -82,3 +82,4 @@ obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o | |||
| 82 | obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o | 82 | obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o |
| 83 | obj-$(CONFIG_MFD_VX855) += vx855.o | 83 | obj-$(CONFIG_MFD_VX855) += vx855.o |
| 84 | obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o | 84 | obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o |
| 85 | obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o | ||
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c index 8a98739e6d9c..5fbca346b998 100644 --- a/drivers/mfd/ab3550-core.c +++ b/drivers/mfd/ab3550-core.c | |||
| @@ -1159,15 +1159,16 @@ static void ab3550_mask_work(struct work_struct *work) | |||
| 1159 | } | 1159 | } |
| 1160 | } | 1160 | } |
| 1161 | 1161 | ||
| 1162 | static void ab3550_mask(unsigned int irq) | 1162 | static void ab3550_mask(struct irq_data *data) |
| 1163 | { | 1163 | { |
| 1164 | unsigned long flags; | 1164 | unsigned long flags; |
| 1165 | struct ab3550 *ab; | 1165 | struct ab3550 *ab; |
| 1166 | struct ab3550_platform_data *plf_data; | 1166 | struct ab3550_platform_data *plf_data; |
| 1167 | int irq; | ||
| 1167 | 1168 | ||
| 1168 | ab = get_irq_chip_data(irq); | 1169 | ab = irq_data_get_irq_chip_data(data); |
| 1169 | plf_data = ab->i2c_client[0]->dev.platform_data; | 1170 | plf_data = ab->i2c_client[0]->dev.platform_data; |
| 1170 | irq -= plf_data->irq.base; | 1171 | irq = data->irq - plf_data->irq.base; |
| 1171 | 1172 | ||
| 1172 | spin_lock_irqsave(&ab->event_lock, flags); | 1173 | spin_lock_irqsave(&ab->event_lock, flags); |
| 1173 | ab->event_mask[irq / 8] |= BIT(irq % 8); | 1174 | ab->event_mask[irq / 8] |= BIT(irq % 8); |
| @@ -1176,15 +1177,16 @@ static void ab3550_mask(unsigned int irq) | |||
| 1176 | schedule_work(&ab->mask_work); | 1177 | schedule_work(&ab->mask_work); |
| 1177 | } | 1178 | } |
| 1178 | 1179 | ||
| 1179 | static void ab3550_unmask(unsigned int irq) | 1180 | static void ab3550_unmask(struct irq_data *data) |
| 1180 | { | 1181 | { |
| 1181 | unsigned long flags; | 1182 | unsigned long flags; |
| 1182 | struct ab3550 *ab; | 1183 | struct ab3550 *ab; |
| 1183 | struct ab3550_platform_data *plf_data; | 1184 | struct ab3550_platform_data *plf_data; |
| 1185 | int irq; | ||
| 1184 | 1186 | ||
| 1185 | ab = get_irq_chip_data(irq); | 1187 | ab = irq_data_get_irq_chip_data(data); |
| 1186 | plf_data = ab->i2c_client[0]->dev.platform_data; | 1188 | plf_data = ab->i2c_client[0]->dev.platform_data; |
| 1187 | irq -= plf_data->irq.base; | 1189 | irq = data->irq - plf_data->irq.base; |
| 1188 | 1190 | ||
| 1189 | spin_lock_irqsave(&ab->event_lock, flags); | 1191 | spin_lock_irqsave(&ab->event_lock, flags); |
| 1190 | ab->event_mask[irq / 8] &= ~BIT(irq % 8); | 1192 | ab->event_mask[irq / 8] &= ~BIT(irq % 8); |
| @@ -1193,20 +1195,16 @@ static void ab3550_unmask(unsigned int irq) | |||
| 1193 | schedule_work(&ab->mask_work); | 1195 | schedule_work(&ab->mask_work); |
| 1194 | } | 1196 | } |
| 1195 | 1197 | ||
| 1196 | static void noop(unsigned int irq) | 1198 | static void noop(struct irq_data *data) |
| 1197 | { | 1199 | { |
| 1198 | } | 1200 | } |
| 1199 | 1201 | ||
| 1200 | static struct irq_chip ab3550_irq_chip = { | 1202 | static struct irq_chip ab3550_irq_chip = { |
| 1201 | .name = "ab3550-core", /* Keep the same name as the request */ | 1203 | .name = "ab3550-core", /* Keep the same name as the request */ |
| 1202 | .startup = NULL, /* defaults to enable */ | 1204 | .irq_disable = ab3550_mask, /* No default to mask in chip.c */ |
| 1203 | .shutdown = NULL, /* defaults to disable */ | 1205 | .irq_ack = noop, |
| 1204 | .enable = NULL, /* defaults to unmask */ | 1206 | .irq_mask = ab3550_mask, |
| 1205 | .disable = ab3550_mask, /* No default to mask in chip.c */ | 1207 | .irq_unmask = ab3550_unmask, |
| 1206 | .ack = noop, | ||
| 1207 | .mask = ab3550_mask, | ||
| 1208 | .unmask = ab3550_unmask, | ||
| 1209 | .end = NULL, | ||
| 1210 | }; | 1208 | }; |
| 1211 | 1209 | ||
| 1212 | struct ab_family_id { | 1210 | struct ab_family_id { |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index d9640a623ff4..b6887014d687 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #define AB8500_IT_LATCH8_REG 0x27 | 52 | #define AB8500_IT_LATCH8_REG 0x27 |
| 53 | #define AB8500_IT_LATCH9_REG 0x28 | 53 | #define AB8500_IT_LATCH9_REG 0x28 |
| 54 | #define AB8500_IT_LATCH10_REG 0x29 | 54 | #define AB8500_IT_LATCH10_REG 0x29 |
| 55 | #define AB8500_IT_LATCH12_REG 0x2B | ||
| 55 | #define AB8500_IT_LATCH19_REG 0x32 | 56 | #define AB8500_IT_LATCH19_REG 0x32 |
| 56 | #define AB8500_IT_LATCH20_REG 0x33 | 57 | #define AB8500_IT_LATCH20_REG 0x33 |
| 57 | #define AB8500_IT_LATCH21_REG 0x34 | 58 | #define AB8500_IT_LATCH21_REG 0x34 |
| @@ -98,13 +99,17 @@ | |||
| 98 | * offset 0. | 99 | * offset 0. |
| 99 | */ | 100 | */ |
| 100 | static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { | 101 | static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { |
| 101 | 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, | 102 | 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | static int ab8500_get_chip_id(struct device *dev) | 105 | static int ab8500_get_chip_id(struct device *dev) |
| 105 | { | 106 | { |
| 106 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 107 | struct ab8500 *ab8500; |
| 107 | return (int)ab8500->chip_id; | 108 | |
| 109 | if (!dev) | ||
| 110 | return -EINVAL; | ||
| 111 | ab8500 = dev_get_drvdata(dev->parent); | ||
| 112 | return ab8500 ? (int)ab8500->chip_id : -EINVAL; | ||
| 108 | } | 113 | } |
| 109 | 114 | ||
| 110 | static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, | 115 | static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, |
| @@ -228,16 +233,16 @@ static struct abx500_ops ab8500_ops = { | |||
| 228 | .startup_irq_enabled = NULL, | 233 | .startup_irq_enabled = NULL, |
| 229 | }; | 234 | }; |
| 230 | 235 | ||
| 231 | static void ab8500_irq_lock(unsigned int irq) | 236 | static void ab8500_irq_lock(struct irq_data *data) |
| 232 | { | 237 | { |
| 233 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 238 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 234 | 239 | ||
| 235 | mutex_lock(&ab8500->irq_lock); | 240 | mutex_lock(&ab8500->irq_lock); |
| 236 | } | 241 | } |
| 237 | 242 | ||
| 238 | static void ab8500_irq_sync_unlock(unsigned int irq) | 243 | static void ab8500_irq_sync_unlock(struct irq_data *data) |
| 239 | { | 244 | { |
| 240 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 245 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 241 | int i; | 246 | int i; |
| 242 | 247 | ||
| 243 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { | 248 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { |
| @@ -248,6 +253,10 @@ static void ab8500_irq_sync_unlock(unsigned int irq) | |||
| 248 | if (new == old) | 253 | if (new == old) |
| 249 | continue; | 254 | continue; |
| 250 | 255 | ||
| 256 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ | ||
| 257 | if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) | ||
| 258 | continue; | ||
| 259 | |||
| 251 | ab8500->oldmask[i] = new; | 260 | ab8500->oldmask[i] = new; |
| 252 | 261 | ||
| 253 | reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; | 262 | reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; |
| @@ -257,20 +266,20 @@ static void ab8500_irq_sync_unlock(unsigned int irq) | |||
| 257 | mutex_unlock(&ab8500->irq_lock); | 266 | mutex_unlock(&ab8500->irq_lock); |
| 258 | } | 267 | } |
| 259 | 268 | ||
| 260 | static void ab8500_irq_mask(unsigned int irq) | 269 | static void ab8500_irq_mask(struct irq_data *data) |
| 261 | { | 270 | { |
| 262 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 271 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 263 | int offset = irq - ab8500->irq_base; | 272 | int offset = data->irq - ab8500->irq_base; |
| 264 | int index = offset / 8; | 273 | int index = offset / 8; |
| 265 | int mask = 1 << (offset % 8); | 274 | int mask = 1 << (offset % 8); |
| 266 | 275 | ||
| 267 | ab8500->mask[index] |= mask; | 276 | ab8500->mask[index] |= mask; |
| 268 | } | 277 | } |
| 269 | 278 | ||
| 270 | static void ab8500_irq_unmask(unsigned int irq) | 279 | static void ab8500_irq_unmask(struct irq_data *data) |
| 271 | { | 280 | { |
| 272 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 281 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 273 | int offset = irq - ab8500->irq_base; | 282 | int offset = data->irq - ab8500->irq_base; |
| 274 | int index = offset / 8; | 283 | int index = offset / 8; |
| 275 | int mask = 1 << (offset % 8); | 284 | int mask = 1 << (offset % 8); |
| 276 | 285 | ||
| @@ -279,10 +288,10 @@ static void ab8500_irq_unmask(unsigned int irq) | |||
| 279 | 288 | ||
| 280 | static struct irq_chip ab8500_irq_chip = { | 289 | static struct irq_chip ab8500_irq_chip = { |
| 281 | .name = "ab8500", | 290 | .name = "ab8500", |
| 282 | .bus_lock = ab8500_irq_lock, | 291 | .irq_bus_lock = ab8500_irq_lock, |
| 283 | .bus_sync_unlock = ab8500_irq_sync_unlock, | 292 | .irq_bus_sync_unlock = ab8500_irq_sync_unlock, |
| 284 | .mask = ab8500_irq_mask, | 293 | .irq_mask = ab8500_irq_mask, |
| 285 | .unmask = ab8500_irq_unmask, | 294 | .irq_unmask = ab8500_irq_unmask, |
| 286 | }; | 295 | }; |
| 287 | 296 | ||
| 288 | static irqreturn_t ab8500_irq(int irq, void *dev) | 297 | static irqreturn_t ab8500_irq(int irq, void *dev) |
| @@ -297,6 +306,10 @@ static irqreturn_t ab8500_irq(int irq, void *dev) | |||
| 297 | int status; | 306 | int status; |
| 298 | u8 value; | 307 | u8 value; |
| 299 | 308 | ||
| 309 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ | ||
| 310 | if (regoffset == 11 && ab8500->chip_id < 0x20) | ||
| 311 | continue; | ||
| 312 | |||
| 300 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, | 313 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, |
| 301 | AB8500_IT_LATCH1_REG + regoffset, &value); | 314 | AB8500_IT_LATCH1_REG + regoffset, &value); |
| 302 | if (status < 0 || value == 0) | 315 | if (status < 0 || value == 0) |
| @@ -393,13 +406,195 @@ static struct resource ab8500_poweronkey_db_resources[] = { | |||
| 393 | }, | 406 | }, |
| 394 | }; | 407 | }; |
| 395 | 408 | ||
| 409 | static struct resource ab8500_bm_resources[] = { | ||
| 410 | { | ||
| 411 | .name = "MAIN_EXT_CH_NOT_OK", | ||
| 412 | .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 413 | .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 414 | .flags = IORESOURCE_IRQ, | ||
| 415 | }, | ||
| 416 | { | ||
| 417 | .name = "BATT_OVV", | ||
| 418 | .start = AB8500_INT_BATT_OVV, | ||
| 419 | .end = AB8500_INT_BATT_OVV, | ||
| 420 | .flags = IORESOURCE_IRQ, | ||
| 421 | }, | ||
| 422 | { | ||
| 423 | .name = "MAIN_CH_UNPLUG_DET", | ||
| 424 | .start = AB8500_INT_MAIN_CH_UNPLUG_DET, | ||
| 425 | .end = AB8500_INT_MAIN_CH_UNPLUG_DET, | ||
| 426 | .flags = IORESOURCE_IRQ, | ||
| 427 | }, | ||
| 428 | { | ||
| 429 | .name = "MAIN_CHARGE_PLUG_DET", | ||
| 430 | .start = AB8500_INT_MAIN_CH_PLUG_DET, | ||
| 431 | .end = AB8500_INT_MAIN_CH_PLUG_DET, | ||
| 432 | .flags = IORESOURCE_IRQ, | ||
| 433 | }, | ||
| 434 | { | ||
| 435 | .name = "VBUS_DET_F", | ||
| 436 | .start = AB8500_INT_VBUS_DET_F, | ||
| 437 | .end = AB8500_INT_VBUS_DET_F, | ||
| 438 | .flags = IORESOURCE_IRQ, | ||
| 439 | }, | ||
| 440 | { | ||
| 441 | .name = "VBUS_DET_R", | ||
| 442 | .start = AB8500_INT_VBUS_DET_R, | ||
| 443 | .end = AB8500_INT_VBUS_DET_R, | ||
| 444 | .flags = IORESOURCE_IRQ, | ||
| 445 | }, | ||
| 446 | { | ||
| 447 | .name = "BAT_CTRL_INDB", | ||
| 448 | .start = AB8500_INT_BAT_CTRL_INDB, | ||
| 449 | .end = AB8500_INT_BAT_CTRL_INDB, | ||
| 450 | .flags = IORESOURCE_IRQ, | ||
| 451 | }, | ||
| 452 | { | ||
| 453 | .name = "CH_WD_EXP", | ||
| 454 | .start = AB8500_INT_CH_WD_EXP, | ||
| 455 | .end = AB8500_INT_CH_WD_EXP, | ||
| 456 | .flags = IORESOURCE_IRQ, | ||
| 457 | }, | ||
| 458 | { | ||
| 459 | .name = "VBUS_OVV", | ||
| 460 | .start = AB8500_INT_VBUS_OVV, | ||
| 461 | .end = AB8500_INT_VBUS_OVV, | ||
| 462 | .flags = IORESOURCE_IRQ, | ||
| 463 | }, | ||
| 464 | { | ||
| 465 | .name = "NCONV_ACCU", | ||
| 466 | .start = AB8500_INT_CCN_CONV_ACC, | ||
| 467 | .end = AB8500_INT_CCN_CONV_ACC, | ||
| 468 | .flags = IORESOURCE_IRQ, | ||
| 469 | }, | ||
| 470 | { | ||
| 471 | .name = "LOW_BAT_F", | ||
| 472 | .start = AB8500_INT_LOW_BAT_F, | ||
| 473 | .end = AB8500_INT_LOW_BAT_F, | ||
| 474 | .flags = IORESOURCE_IRQ, | ||
| 475 | }, | ||
| 476 | { | ||
| 477 | .name = "LOW_BAT_R", | ||
| 478 | .start = AB8500_INT_LOW_BAT_R, | ||
| 479 | .end = AB8500_INT_LOW_BAT_R, | ||
| 480 | .flags = IORESOURCE_IRQ, | ||
| 481 | }, | ||
| 482 | { | ||
| 483 | .name = "BTEMP_LOW", | ||
| 484 | .start = AB8500_INT_BTEMP_LOW, | ||
| 485 | .end = AB8500_INT_BTEMP_LOW, | ||
| 486 | .flags = IORESOURCE_IRQ, | ||
| 487 | }, | ||
| 488 | { | ||
| 489 | .name = "BTEMP_HIGH", | ||
| 490 | .start = AB8500_INT_BTEMP_HIGH, | ||
| 491 | .end = AB8500_INT_BTEMP_HIGH, | ||
| 492 | .flags = IORESOURCE_IRQ, | ||
| 493 | }, | ||
| 494 | { | ||
| 495 | .name = "USB_CHARGER_NOT_OKR", | ||
| 496 | .start = AB8500_INT_USB_CHARGER_NOT_OK, | ||
| 497 | .end = AB8500_INT_USB_CHARGER_NOT_OK, | ||
| 498 | .flags = IORESOURCE_IRQ, | ||
| 499 | }, | ||
| 500 | { | ||
| 501 | .name = "USB_CHARGE_DET_DONE", | ||
| 502 | .start = AB8500_INT_USB_CHG_DET_DONE, | ||
| 503 | .end = AB8500_INT_USB_CHG_DET_DONE, | ||
| 504 | .flags = IORESOURCE_IRQ, | ||
| 505 | }, | ||
| 506 | { | ||
| 507 | .name = "USB_CH_TH_PROT_R", | ||
| 508 | .start = AB8500_INT_USB_CH_TH_PROT_R, | ||
| 509 | .end = AB8500_INT_USB_CH_TH_PROT_R, | ||
| 510 | .flags = IORESOURCE_IRQ, | ||
| 511 | }, | ||
| 512 | { | ||
| 513 | .name = "MAIN_CH_TH_PROT_R", | ||
| 514 | .start = AB8500_INT_MAIN_CH_TH_PROT_R, | ||
| 515 | .end = AB8500_INT_MAIN_CH_TH_PROT_R, | ||
| 516 | .flags = IORESOURCE_IRQ, | ||
| 517 | }, | ||
| 518 | { | ||
| 519 | .name = "USB_CHARGER_NOT_OKF", | ||
| 520 | .start = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 521 | .end = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 522 | .flags = IORESOURCE_IRQ, | ||
| 523 | }, | ||
| 524 | }; | ||
| 525 | |||
| 526 | static struct resource ab8500_debug_resources[] = { | ||
| 527 | { | ||
| 528 | .name = "IRQ_FIRST", | ||
| 529 | .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 530 | .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 531 | .flags = IORESOURCE_IRQ, | ||
| 532 | }, | ||
| 533 | { | ||
| 534 | .name = "IRQ_LAST", | ||
| 535 | .start = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 536 | .end = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 537 | .flags = IORESOURCE_IRQ, | ||
| 538 | }, | ||
| 539 | }; | ||
| 540 | |||
| 541 | static struct resource ab8500_usb_resources[] = { | ||
| 542 | { | ||
| 543 | .name = "ID_WAKEUP_R", | ||
| 544 | .start = AB8500_INT_ID_WAKEUP_R, | ||
| 545 | .end = AB8500_INT_ID_WAKEUP_R, | ||
| 546 | .flags = IORESOURCE_IRQ, | ||
| 547 | }, | ||
| 548 | { | ||
| 549 | .name = "ID_WAKEUP_F", | ||
| 550 | .start = AB8500_INT_ID_WAKEUP_F, | ||
| 551 | .end = AB8500_INT_ID_WAKEUP_F, | ||
| 552 | .flags = IORESOURCE_IRQ, | ||
| 553 | }, | ||
| 554 | { | ||
| 555 | .name = "VBUS_DET_F", | ||
| 556 | .start = AB8500_INT_VBUS_DET_F, | ||
| 557 | .end = AB8500_INT_VBUS_DET_F, | ||
| 558 | .flags = IORESOURCE_IRQ, | ||
| 559 | }, | ||
| 560 | { | ||
| 561 | .name = "VBUS_DET_R", | ||
| 562 | .start = AB8500_INT_VBUS_DET_R, | ||
| 563 | .end = AB8500_INT_VBUS_DET_R, | ||
| 564 | .flags = IORESOURCE_IRQ, | ||
| 565 | }, | ||
| 566 | { | ||
| 567 | .name = "USB_LINK_STATUS", | ||
| 568 | .start = AB8500_INT_USB_LINK_STATUS, | ||
| 569 | .end = AB8500_INT_USB_LINK_STATUS, | ||
| 570 | .flags = IORESOURCE_IRQ, | ||
| 571 | }, | ||
| 572 | }; | ||
| 573 | |||
| 574 | static struct resource ab8500_temp_resources[] = { | ||
| 575 | { | ||
| 576 | .name = "AB8500_TEMP_WARM", | ||
| 577 | .start = AB8500_INT_TEMP_WARM, | ||
| 578 | .end = AB8500_INT_TEMP_WARM, | ||
| 579 | .flags = IORESOURCE_IRQ, | ||
| 580 | }, | ||
| 581 | }; | ||
| 582 | |||
| 396 | static struct mfd_cell ab8500_devs[] = { | 583 | static struct mfd_cell ab8500_devs[] = { |
| 397 | #ifdef CONFIG_DEBUG_FS | 584 | #ifdef CONFIG_DEBUG_FS |
| 398 | { | 585 | { |
| 399 | .name = "ab8500-debug", | 586 | .name = "ab8500-debug", |
| 587 | .num_resources = ARRAY_SIZE(ab8500_debug_resources), | ||
| 588 | .resources = ab8500_debug_resources, | ||
| 400 | }, | 589 | }, |
| 401 | #endif | 590 | #endif |
| 402 | { | 591 | { |
| 592 | .name = "ab8500-sysctrl", | ||
| 593 | }, | ||
| 594 | { | ||
| 595 | .name = "ab8500-regulator", | ||
| 596 | }, | ||
| 597 | { | ||
| 403 | .name = "ab8500-gpadc", | 598 | .name = "ab8500-gpadc", |
| 404 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), | 599 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), |
| 405 | .resources = ab8500_gpadc_resources, | 600 | .resources = ab8500_gpadc_resources, |
| @@ -410,6 +605,22 @@ static struct mfd_cell ab8500_devs[] = { | |||
| 410 | .resources = ab8500_rtc_resources, | 605 | .resources = ab8500_rtc_resources, |
| 411 | }, | 606 | }, |
| 412 | { | 607 | { |
| 608 | .name = "ab8500-bm", | ||
| 609 | .num_resources = ARRAY_SIZE(ab8500_bm_resources), | ||
| 610 | .resources = ab8500_bm_resources, | ||
| 611 | }, | ||
| 612 | { .name = "ab8500-codec", }, | ||
| 613 | { | ||
| 614 | .name = "ab8500-usb", | ||
| 615 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), | ||
| 616 | .resources = ab8500_usb_resources, | ||
| 617 | }, | ||
| 618 | { | ||
| 619 | .name = "ab8500-poweron-key", | ||
| 620 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), | ||
| 621 | .resources = ab8500_poweronkey_db_resources, | ||
| 622 | }, | ||
| 623 | { | ||
| 413 | .name = "ab8500-pwm", | 624 | .name = "ab8500-pwm", |
| 414 | .id = 1, | 625 | .id = 1, |
| 415 | }, | 626 | }, |
| @@ -421,17 +632,37 @@ static struct mfd_cell ab8500_devs[] = { | |||
| 421 | .name = "ab8500-pwm", | 632 | .name = "ab8500-pwm", |
| 422 | .id = 3, | 633 | .id = 3, |
| 423 | }, | 634 | }, |
| 424 | { .name = "ab8500-charger", }, | 635 | { .name = "ab8500-leds", }, |
| 425 | { .name = "ab8500-audio", }, | ||
| 426 | { .name = "ab8500-usb", }, | ||
| 427 | { .name = "ab8500-regulator", }, | ||
| 428 | { | 636 | { |
| 429 | .name = "ab8500-poweron-key", | 637 | .name = "ab8500-denc", |
| 430 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), | 638 | }, |
| 431 | .resources = ab8500_poweronkey_db_resources, | 639 | { |
| 640 | .name = "ab8500-temp", | ||
| 641 | .num_resources = ARRAY_SIZE(ab8500_temp_resources), | ||
| 642 | .resources = ab8500_temp_resources, | ||
| 432 | }, | 643 | }, |
| 433 | }; | 644 | }; |
| 434 | 645 | ||
| 646 | static ssize_t show_chip_id(struct device *dev, | ||
| 647 | struct device_attribute *attr, char *buf) | ||
| 648 | { | ||
| 649 | struct ab8500 *ab8500; | ||
| 650 | |||
| 651 | ab8500 = dev_get_drvdata(dev); | ||
| 652 | return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); | ||
| 653 | } | ||
| 654 | |||
| 655 | static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); | ||
| 656 | |||
| 657 | static struct attribute *ab8500_sysfs_entries[] = { | ||
| 658 | &dev_attr_chip_id.attr, | ||
| 659 | NULL, | ||
| 660 | }; | ||
| 661 | |||
| 662 | static struct attribute_group ab8500_attr_group = { | ||
| 663 | .attrs = ab8500_sysfs_entries, | ||
| 664 | }; | ||
| 665 | |||
| 435 | int __devinit ab8500_init(struct ab8500 *ab8500) | 666 | int __devinit ab8500_init(struct ab8500 *ab8500) |
| 436 | { | 667 | { |
| 437 | struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); | 668 | struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); |
| @@ -454,8 +685,9 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 454 | * 0x0 - Early Drop | 685 | * 0x0 - Early Drop |
| 455 | * 0x10 - Cut 1.0 | 686 | * 0x10 - Cut 1.0 |
| 456 | * 0x11 - Cut 1.1 | 687 | * 0x11 - Cut 1.1 |
| 688 | * 0x20 - Cut 2.0 | ||
| 457 | */ | 689 | */ |
| 458 | if (value == 0x0 || value == 0x10 || value == 0x11) { | 690 | if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { |
| 459 | ab8500->revision = value; | 691 | ab8500->revision = value; |
| 460 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); | 692 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); |
| 461 | } else { | 693 | } else { |
| @@ -468,18 +700,16 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 468 | plat->init(ab8500); | 700 | plat->init(ab8500); |
| 469 | 701 | ||
| 470 | /* Clear and mask all interrupts */ | 702 | /* Clear and mask all interrupts */ |
| 471 | for (i = 0; i < 10; i++) { | 703 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { |
| 472 | get_register_interruptible(ab8500, AB8500_INTERRUPT, | 704 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ |
| 473 | AB8500_IT_LATCH1_REG + i, &value); | 705 | if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) |
| 474 | set_register_interruptible(ab8500, AB8500_INTERRUPT, | 706 | continue; |
| 475 | AB8500_IT_MASK1_REG + i, 0xff); | ||
| 476 | } | ||
| 477 | 707 | ||
| 478 | for (i = 18; i < 24; i++) { | ||
| 479 | get_register_interruptible(ab8500, AB8500_INTERRUPT, | 708 | get_register_interruptible(ab8500, AB8500_INTERRUPT, |
| 480 | AB8500_IT_LATCH1_REG + i, &value); | 709 | AB8500_IT_LATCH1_REG + ab8500_irq_regoffset[i], |
| 710 | &value); | ||
| 481 | set_register_interruptible(ab8500, AB8500_INTERRUPT, | 711 | set_register_interruptible(ab8500, AB8500_INTERRUPT, |
| 482 | AB8500_IT_MASK1_REG + i, 0xff); | 712 | AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i], 0xff); |
| 483 | } | 713 | } |
| 484 | 714 | ||
| 485 | ret = abx500_register_ops(ab8500->dev, &ab8500_ops); | 715 | ret = abx500_register_ops(ab8500->dev, &ab8500_ops); |
| @@ -495,7 +725,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 495 | return ret; | 725 | return ret; |
| 496 | 726 | ||
| 497 | ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, | 727 | ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, |
| 498 | IRQF_ONESHOT, "ab8500", ab8500); | 728 | IRQF_ONESHOT | IRQF_NO_SUSPEND, |
| 729 | "ab8500", ab8500); | ||
| 499 | if (ret) | 730 | if (ret) |
| 500 | goto out_removeirq; | 731 | goto out_removeirq; |
| 501 | } | 732 | } |
| @@ -506,6 +737,10 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 506 | if (ret) | 737 | if (ret) |
| 507 | goto out_freeirq; | 738 | goto out_freeirq; |
| 508 | 739 | ||
| 740 | ret = sysfs_create_group(&ab8500->dev->kobj, &ab8500_attr_group); | ||
| 741 | if (ret) | ||
| 742 | dev_err(ab8500->dev, "error creating sysfs entries\n"); | ||
| 743 | |||
| 509 | return ret; | 744 | return ret; |
| 510 | 745 | ||
| 511 | out_freeirq: | 746 | out_freeirq: |
| @@ -519,6 +754,7 @@ out_removeirq: | |||
| 519 | 754 | ||
| 520 | int __devexit ab8500_exit(struct ab8500 *ab8500) | 755 | int __devexit ab8500_exit(struct ab8500 *ab8500) |
| 521 | { | 756 | { |
| 757 | sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); | ||
| 522 | mfd_remove_devices(ab8500->dev); | 758 | mfd_remove_devices(ab8500->dev); |
| 523 | if (ab8500->irq_base) { | 759 | if (ab8500->irq_base) { |
| 524 | free_irq(ab8500->irq, ab8500); | 760 | free_irq(ab8500->irq, ab8500); |
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 8d1e05a39815..3c1541ae7223 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c | |||
| @@ -24,9 +24,9 @@ static u32 debug_address; | |||
| 24 | * @perm: access permissions for the range | 24 | * @perm: access permissions for the range |
| 25 | */ | 25 | */ |
| 26 | struct ab8500_reg_range { | 26 | struct ab8500_reg_range { |
| 27 | u8 first; | 27 | u8 first; |
| 28 | u8 last; | 28 | u8 last; |
| 29 | u8 perm; | 29 | u8 perm; |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| @@ -36,9 +36,9 @@ struct ab8500_reg_range { | |||
| 36 | * @range: the list of register ranges | 36 | * @range: the list of register ranges |
| 37 | */ | 37 | */ |
| 38 | struct ab8500_i2c_ranges { | 38 | struct ab8500_i2c_ranges { |
| 39 | u8 num_ranges; | 39 | u8 num_ranges; |
| 40 | u8 bankid; | 40 | u8 bankid; |
| 41 | const struct ab8500_reg_range *range; | 41 | const struct ab8500_reg_range *range; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | #define AB8500_NAME_STRING "ab8500" | 44 | #define AB8500_NAME_STRING "ab8500" |
| @@ -47,521 +47,521 @@ struct ab8500_i2c_ranges { | |||
| 47 | #define AB8500_REV_REG 0x80 | 47 | #define AB8500_REV_REG 0x80 |
| 48 | 48 | ||
| 49 | static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = { | 49 | static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = { |
| 50 | [0x0] = { | 50 | [0x0] = { |
| 51 | .num_ranges = 0, | 51 | .num_ranges = 0, |
| 52 | .range = 0, | 52 | .range = 0, |
| 53 | }, | 53 | }, |
| 54 | [AB8500_SYS_CTRL1_BLOCK] = { | 54 | [AB8500_SYS_CTRL1_BLOCK] = { |
| 55 | .num_ranges = 3, | 55 | .num_ranges = 3, |
| 56 | .range = (struct ab8500_reg_range[]) { | 56 | .range = (struct ab8500_reg_range[]) { |
| 57 | { | 57 | { |
| 58 | .first = 0x00, | 58 | .first = 0x00, |
| 59 | .last = 0x02, | 59 | .last = 0x02, |
| 60 | }, | 60 | }, |
| 61 | { | 61 | { |
| 62 | .first = 0x42, | 62 | .first = 0x42, |
| 63 | .last = 0x42, | 63 | .last = 0x42, |
| 64 | }, | 64 | }, |
| 65 | { | 65 | { |
| 66 | .first = 0x80, | 66 | .first = 0x80, |
| 67 | .last = 0x81, | 67 | .last = 0x81, |
| 68 | }, | 68 | }, |
| 69 | }, | 69 | }, |
| 70 | }, | 70 | }, |
| 71 | [AB8500_SYS_CTRL2_BLOCK] = { | 71 | [AB8500_SYS_CTRL2_BLOCK] = { |
| 72 | .num_ranges = 4, | 72 | .num_ranges = 4, |
| 73 | .range = (struct ab8500_reg_range[]) { | 73 | .range = (struct ab8500_reg_range[]) { |
| 74 | { | 74 | { |
| 75 | .first = 0x00, | 75 | .first = 0x00, |
| 76 | .last = 0x0D, | 76 | .last = 0x0D, |
| 77 | }, | 77 | }, |
| 78 | { | 78 | { |
| 79 | .first = 0x0F, | 79 | .first = 0x0F, |
| 80 | .last = 0x17, | 80 | .last = 0x17, |
| 81 | }, | 81 | }, |
| 82 | { | 82 | { |
| 83 | .first = 0x30, | 83 | .first = 0x30, |
| 84 | .last = 0x30, | 84 | .last = 0x30, |
| 85 | }, | 85 | }, |
| 86 | { | 86 | { |
| 87 | .first = 0x32, | 87 | .first = 0x32, |
| 88 | .last = 0x33, | 88 | .last = 0x33, |
| 89 | }, | 89 | }, |
| 90 | }, | 90 | }, |
| 91 | }, | 91 | }, |
| 92 | [AB8500_REGU_CTRL1] = { | 92 | [AB8500_REGU_CTRL1] = { |
| 93 | .num_ranges = 3, | 93 | .num_ranges = 3, |
| 94 | .range = (struct ab8500_reg_range[]) { | 94 | .range = (struct ab8500_reg_range[]) { |
| 95 | { | 95 | { |
| 96 | .first = 0x00, | 96 | .first = 0x00, |
| 97 | .last = 0x00, | 97 | .last = 0x00, |
| 98 | }, | 98 | }, |
| 99 | { | 99 | { |
| 100 | .first = 0x03, | 100 | .first = 0x03, |
| 101 | .last = 0x10, | 101 | .last = 0x10, |
| 102 | }, | 102 | }, |
| 103 | { | 103 | { |
| 104 | .first = 0x80, | 104 | .first = 0x80, |
| 105 | .last = 0x84, | 105 | .last = 0x84, |
| 106 | }, | 106 | }, |
| 107 | }, | 107 | }, |
| 108 | }, | 108 | }, |
| 109 | [AB8500_REGU_CTRL2] = { | 109 | [AB8500_REGU_CTRL2] = { |
| 110 | .num_ranges = 5, | 110 | .num_ranges = 5, |
| 111 | .range = (struct ab8500_reg_range[]) { | 111 | .range = (struct ab8500_reg_range[]) { |
| 112 | { | 112 | { |
| 113 | .first = 0x00, | 113 | .first = 0x00, |
| 114 | .last = 0x15, | 114 | .last = 0x15, |
| 115 | }, | 115 | }, |
| 116 | { | 116 | { |
| 117 | .first = 0x17, | 117 | .first = 0x17, |
| 118 | .last = 0x19, | 118 | .last = 0x19, |
| 119 | }, | 119 | }, |
| 120 | { | 120 | { |
| 121 | .first = 0x1B, | 121 | .first = 0x1B, |
| 122 | .last = 0x1D, | 122 | .last = 0x1D, |
| 123 | }, | 123 | }, |
| 124 | { | 124 | { |
| 125 | .first = 0x1F, | 125 | .first = 0x1F, |
| 126 | .last = 0x22, | 126 | .last = 0x22, |
| 127 | }, | 127 | }, |
| 128 | { | 128 | { |
| 129 | .first = 0x40, | 129 | .first = 0x40, |
| 130 | .last = 0x44, | 130 | .last = 0x44, |
| 131 | }, | 131 | }, |
| 132 | /* 0x80-0x8B is SIM registers and should | 132 | /* 0x80-0x8B is SIM registers and should |
| 133 | * not be accessed from here */ | 133 | * not be accessed from here */ |
| 134 | }, | 134 | }, |
| 135 | }, | 135 | }, |
| 136 | [AB8500_USB] = { | 136 | [AB8500_USB] = { |
| 137 | .num_ranges = 2, | 137 | .num_ranges = 2, |
| 138 | .range = (struct ab8500_reg_range[]) { | 138 | .range = (struct ab8500_reg_range[]) { |
| 139 | { | 139 | { |
| 140 | .first = 0x80, | 140 | .first = 0x80, |
| 141 | .last = 0x83, | 141 | .last = 0x83, |
| 142 | }, | 142 | }, |
| 143 | { | 143 | { |
| 144 | .first = 0x87, | 144 | .first = 0x87, |
| 145 | .last = 0x8A, | 145 | .last = 0x8A, |
| 146 | }, | 146 | }, |
| 147 | }, | 147 | }, |
| 148 | }, | 148 | }, |
| 149 | [AB8500_TVOUT] = { | 149 | [AB8500_TVOUT] = { |
| 150 | .num_ranges = 9, | 150 | .num_ranges = 9, |
| 151 | .range = (struct ab8500_reg_range[]) { | 151 | .range = (struct ab8500_reg_range[]) { |
| 152 | { | 152 | { |
| 153 | .first = 0x00, | 153 | .first = 0x00, |
| 154 | .last = 0x12, | 154 | .last = 0x12, |
| 155 | }, | 155 | }, |
| 156 | { | 156 | { |
| 157 | .first = 0x15, | 157 | .first = 0x15, |
| 158 | .last = 0x17, | 158 | .last = 0x17, |
| 159 | }, | 159 | }, |
| 160 | { | 160 | { |
| 161 | .first = 0x19, | 161 | .first = 0x19, |
| 162 | .last = 0x21, | 162 | .last = 0x21, |
| 163 | }, | 163 | }, |
| 164 | { | 164 | { |
| 165 | .first = 0x27, | 165 | .first = 0x27, |
| 166 | .last = 0x2C, | 166 | .last = 0x2C, |
| 167 | }, | 167 | }, |
| 168 | { | 168 | { |
| 169 | .first = 0x41, | 169 | .first = 0x41, |
| 170 | .last = 0x41, | 170 | .last = 0x41, |
| 171 | }, | 171 | }, |
| 172 | { | 172 | { |
| 173 | .first = 0x45, | 173 | .first = 0x45, |
| 174 | .last = 0x5B, | 174 | .last = 0x5B, |
| 175 | }, | 175 | }, |
| 176 | { | 176 | { |
| 177 | .first = 0x5D, | 177 | .first = 0x5D, |
| 178 | .last = 0x5D, | 178 | .last = 0x5D, |
| 179 | }, | 179 | }, |
| 180 | { | 180 | { |
| 181 | .first = 0x69, | 181 | .first = 0x69, |
| 182 | .last = 0x69, | 182 | .last = 0x69, |
| 183 | }, | 183 | }, |
| 184 | { | 184 | { |
| 185 | .first = 0x80, | 185 | .first = 0x80, |
| 186 | .last = 0x81, | 186 | .last = 0x81, |
| 187 | }, | 187 | }, |
| 188 | }, | 188 | }, |
| 189 | }, | 189 | }, |
| 190 | [AB8500_DBI] = { | 190 | [AB8500_DBI] = { |
| 191 | .num_ranges = 0, | 191 | .num_ranges = 0, |
| 192 | .range = 0, | 192 | .range = NULL, |
| 193 | }, | 193 | }, |
| 194 | [AB8500_ECI_AV_ACC] = { | 194 | [AB8500_ECI_AV_ACC] = { |
| 195 | .num_ranges = 1, | 195 | .num_ranges = 1, |
| 196 | .range = (struct ab8500_reg_range[]) { | 196 | .range = (struct ab8500_reg_range[]) { |
| 197 | { | 197 | { |
| 198 | .first = 0x80, | 198 | .first = 0x80, |
| 199 | .last = 0x82, | 199 | .last = 0x82, |
| 200 | }, | 200 | }, |
| 201 | }, | 201 | }, |
| 202 | }, | 202 | }, |
| 203 | [0x9] = { | 203 | [0x9] = { |
| 204 | .num_ranges = 0, | 204 | .num_ranges = 0, |
| 205 | .range = 0, | 205 | .range = NULL, |
| 206 | }, | 206 | }, |
| 207 | [AB8500_GPADC] = { | 207 | [AB8500_GPADC] = { |
| 208 | .num_ranges = 1, | 208 | .num_ranges = 1, |
| 209 | .range = (struct ab8500_reg_range[]) { | 209 | .range = (struct ab8500_reg_range[]) { |
| 210 | { | 210 | { |
| 211 | .first = 0x00, | 211 | .first = 0x00, |
| 212 | .last = 0x08, | 212 | .last = 0x08, |
| 213 | }, | 213 | }, |
| 214 | }, | 214 | }, |
| 215 | }, | 215 | }, |
| 216 | [AB8500_CHARGER] = { | 216 | [AB8500_CHARGER] = { |
| 217 | .num_ranges = 8, | 217 | .num_ranges = 8, |
| 218 | .range = (struct ab8500_reg_range[]) { | 218 | .range = (struct ab8500_reg_range[]) { |
| 219 | { | 219 | { |
| 220 | .first = 0x00, | 220 | .first = 0x00, |
| 221 | .last = 0x03, | 221 | .last = 0x03, |
| 222 | }, | 222 | }, |
| 223 | { | 223 | { |
| 224 | .first = 0x05, | 224 | .first = 0x05, |
| 225 | .last = 0x05, | 225 | .last = 0x05, |
| 226 | }, | 226 | }, |
| 227 | { | 227 | { |
| 228 | .first = 0x40, | 228 | .first = 0x40, |
| 229 | .last = 0x40, | 229 | .last = 0x40, |
| 230 | }, | 230 | }, |
| 231 | { | 231 | { |
| 232 | .first = 0x42, | 232 | .first = 0x42, |
| 233 | .last = 0x42, | 233 | .last = 0x42, |
| 234 | }, | 234 | }, |
| 235 | { | 235 | { |
| 236 | .first = 0x44, | 236 | .first = 0x44, |
| 237 | .last = 0x44, | 237 | .last = 0x44, |
| 238 | }, | 238 | }, |
| 239 | { | 239 | { |
| 240 | .first = 0x50, | 240 | .first = 0x50, |
| 241 | .last = 0x55, | 241 | .last = 0x55, |
| 242 | }, | 242 | }, |
| 243 | { | 243 | { |
| 244 | .first = 0x80, | 244 | .first = 0x80, |
| 245 | .last = 0x82, | 245 | .last = 0x82, |
| 246 | }, | 246 | }, |
| 247 | { | 247 | { |
| 248 | .first = 0xC0, | 248 | .first = 0xC0, |
| 249 | .last = 0xC2, | 249 | .last = 0xC2, |
| 250 | }, | 250 | }, |
| 251 | }, | 251 | }, |
| 252 | }, | 252 | }, |
| 253 | [AB8500_GAS_GAUGE] = { | 253 | [AB8500_GAS_GAUGE] = { |
| 254 | .num_ranges = 3, | 254 | .num_ranges = 3, |
| 255 | .range = (struct ab8500_reg_range[]) { | 255 | .range = (struct ab8500_reg_range[]) { |
| 256 | { | 256 | { |
| 257 | .first = 0x00, | 257 | .first = 0x00, |
| 258 | .last = 0x00, | 258 | .last = 0x00, |
| 259 | }, | 259 | }, |
| 260 | { | 260 | { |
| 261 | .first = 0x07, | 261 | .first = 0x07, |
| 262 | .last = 0x0A, | 262 | .last = 0x0A, |
| 263 | }, | 263 | }, |
| 264 | { | 264 | { |
| 265 | .first = 0x10, | 265 | .first = 0x10, |
| 266 | .last = 0x14, | 266 | .last = 0x14, |
| 267 | }, | 267 | }, |
| 268 | }, | 268 | }, |
| 269 | }, | 269 | }, |
| 270 | [AB8500_AUDIO] = { | 270 | [AB8500_AUDIO] = { |
| 271 | .num_ranges = 1, | 271 | .num_ranges = 1, |
| 272 | .range = (struct ab8500_reg_range[]) { | 272 | .range = (struct ab8500_reg_range[]) { |
| 273 | { | 273 | { |
| 274 | .first = 0x00, | 274 | .first = 0x00, |
| 275 | .last = 0x6F, | 275 | .last = 0x6F, |
| 276 | }, | 276 | }, |
| 277 | }, | 277 | }, |
| 278 | }, | 278 | }, |
| 279 | [AB8500_INTERRUPT] = { | 279 | [AB8500_INTERRUPT] = { |
| 280 | .num_ranges = 0, | 280 | .num_ranges = 0, |
| 281 | .range = 0, | 281 | .range = NULL, |
| 282 | }, | 282 | }, |
| 283 | [AB8500_RTC] = { | 283 | [AB8500_RTC] = { |
| 284 | .num_ranges = 1, | 284 | .num_ranges = 1, |
| 285 | .range = (struct ab8500_reg_range[]) { | 285 | .range = (struct ab8500_reg_range[]) { |
| 286 | { | 286 | { |
| 287 | .first = 0x00, | 287 | .first = 0x00, |
| 288 | .last = 0x0F, | 288 | .last = 0x0F, |
| 289 | }, | 289 | }, |
| 290 | }, | 290 | }, |
| 291 | }, | 291 | }, |
| 292 | [AB8500_MISC] = { | 292 | [AB8500_MISC] = { |
| 293 | .num_ranges = 8, | 293 | .num_ranges = 8, |
| 294 | .range = (struct ab8500_reg_range[]) { | 294 | .range = (struct ab8500_reg_range[]) { |
| 295 | { | 295 | { |
| 296 | .first = 0x00, | 296 | .first = 0x00, |
| 297 | .last = 0x05, | 297 | .last = 0x05, |
| 298 | }, | 298 | }, |
| 299 | { | 299 | { |
| 300 | .first = 0x10, | 300 | .first = 0x10, |
| 301 | .last = 0x15, | 301 | .last = 0x15, |
| 302 | }, | 302 | }, |
| 303 | { | 303 | { |
| 304 | .first = 0x20, | 304 | .first = 0x20, |
| 305 | .last = 0x25, | 305 | .last = 0x25, |
| 306 | }, | 306 | }, |
| 307 | { | 307 | { |
| 308 | .first = 0x30, | 308 | .first = 0x30, |
| 309 | .last = 0x35, | 309 | .last = 0x35, |
| 310 | }, | 310 | }, |
| 311 | { | 311 | { |
| 312 | .first = 0x40, | 312 | .first = 0x40, |
| 313 | .last = 0x45, | 313 | .last = 0x45, |
| 314 | }, | 314 | }, |
| 315 | { | 315 | { |
| 316 | .first = 0x50, | 316 | .first = 0x50, |
| 317 | .last = 0x50, | 317 | .last = 0x50, |
| 318 | }, | 318 | }, |
| 319 | { | 319 | { |
| 320 | .first = 0x60, | 320 | .first = 0x60, |
| 321 | .last = 0x67, | 321 | .last = 0x67, |
| 322 | }, | 322 | }, |
| 323 | { | 323 | { |
| 324 | .first = 0x80, | 324 | .first = 0x80, |
| 325 | .last = 0x80, | 325 | .last = 0x80, |
| 326 | }, | 326 | }, |
| 327 | }, | 327 | }, |
| 328 | }, | 328 | }, |
| 329 | [0x11] = { | 329 | [0x11] = { |
| 330 | .num_ranges = 0, | 330 | .num_ranges = 0, |
| 331 | .range = 0, | 331 | .range = NULL, |
| 332 | }, | 332 | }, |
| 333 | [0x12] = { | 333 | [0x12] = { |
| 334 | .num_ranges = 0, | 334 | .num_ranges = 0, |
| 335 | .range = 0, | 335 | .range = NULL, |
| 336 | }, | 336 | }, |
| 337 | [0x13] = { | 337 | [0x13] = { |
| 338 | .num_ranges = 0, | 338 | .num_ranges = 0, |
| 339 | .range = 0, | 339 | .range = NULL, |
| 340 | }, | 340 | }, |
| 341 | [0x14] = { | 341 | [0x14] = { |
| 342 | .num_ranges = 0, | 342 | .num_ranges = 0, |
| 343 | .range = 0, | 343 | .range = NULL, |
| 344 | }, | 344 | }, |
| 345 | [AB8500_OTP_EMUL] = { | 345 | [AB8500_OTP_EMUL] = { |
| 346 | .num_ranges = 1, | 346 | .num_ranges = 1, |
| 347 | .range = (struct ab8500_reg_range[]) { | 347 | .range = (struct ab8500_reg_range[]) { |
| 348 | { | 348 | { |
| 349 | .first = 0x01, | 349 | .first = 0x01, |
| 350 | .last = 0x0F, | 350 | .last = 0x0F, |
| 351 | }, | 351 | }, |
| 352 | }, | 352 | }, |
| 353 | }, | 353 | }, |
| 354 | }; | 354 | }; |
| 355 | 355 | ||
| 356 | static int ab8500_registers_print(struct seq_file *s, void *p) | 356 | static int ab8500_registers_print(struct seq_file *s, void *p) |
| 357 | { | 357 | { |
| 358 | struct device *dev = s->private; | 358 | struct device *dev = s->private; |
| 359 | unsigned int i; | 359 | unsigned int i; |
| 360 | u32 bank = debug_bank; | 360 | u32 bank = debug_bank; |
| 361 | 361 | ||
| 362 | seq_printf(s, AB8500_NAME_STRING " register values:\n"); | 362 | seq_printf(s, AB8500_NAME_STRING " register values:\n"); |
| 363 | 363 | ||
| 364 | seq_printf(s, " bank %u:\n", bank); | 364 | seq_printf(s, " bank %u:\n", bank); |
| 365 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { | 365 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { |
| 366 | u32 reg; | 366 | u32 reg; |
| 367 | 367 | ||
| 368 | for (reg = debug_ranges[bank].range[i].first; | 368 | for (reg = debug_ranges[bank].range[i].first; |
| 369 | reg <= debug_ranges[bank].range[i].last; | 369 | reg <= debug_ranges[bank].range[i].last; |
| 370 | reg++) { | 370 | reg++) { |
| 371 | u8 value; | 371 | u8 value; |
| 372 | int err; | 372 | int err; |
| 373 | 373 | ||
| 374 | err = abx500_get_register_interruptible(dev, | 374 | err = abx500_get_register_interruptible(dev, |
| 375 | (u8)bank, (u8)reg, &value); | 375 | (u8)bank, (u8)reg, &value); |
| 376 | if (err < 0) { | 376 | if (err < 0) { |
| 377 | dev_err(dev, "ab->read fail %d\n", err); | 377 | dev_err(dev, "ab->read fail %d\n", err); |
| 378 | return err; | 378 | return err; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, | 381 | err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, |
| 382 | reg, value); | 382 | reg, value); |
| 383 | if (err < 0) { | 383 | if (err < 0) { |
| 384 | dev_err(dev, "seq_printf overflow\n"); | 384 | dev_err(dev, "seq_printf overflow\n"); |
| 385 | /* Error is not returned here since | 385 | /* Error is not returned here since |
| 386 | * the output is wanted in any case */ | 386 | * the output is wanted in any case */ |
| 387 | return 0; | 387 | return 0; |
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | } | 390 | } |
| 391 | return 0; | 391 | return 0; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | static int ab8500_registers_open(struct inode *inode, struct file *file) | 394 | static int ab8500_registers_open(struct inode *inode, struct file *file) |
| 395 | { | 395 | { |
| 396 | return single_open(file, ab8500_registers_print, inode->i_private); | 396 | return single_open(file, ab8500_registers_print, inode->i_private); |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | static const struct file_operations ab8500_registers_fops = { | 399 | static const struct file_operations ab8500_registers_fops = { |
| 400 | .open = ab8500_registers_open, | 400 | .open = ab8500_registers_open, |
| 401 | .read = seq_read, | 401 | .read = seq_read, |
| 402 | .llseek = seq_lseek, | 402 | .llseek = seq_lseek, |
| 403 | .release = single_release, | 403 | .release = single_release, |
| 404 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
| 405 | }; | 405 | }; |
| 406 | 406 | ||
| 407 | static int ab8500_bank_print(struct seq_file *s, void *p) | 407 | static int ab8500_bank_print(struct seq_file *s, void *p) |
| 408 | { | 408 | { |
| 409 | return seq_printf(s, "%d\n", debug_bank); | 409 | return seq_printf(s, "%d\n", debug_bank); |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | static int ab8500_bank_open(struct inode *inode, struct file *file) | 412 | static int ab8500_bank_open(struct inode *inode, struct file *file) |
| 413 | { | 413 | { |
| 414 | return single_open(file, ab8500_bank_print, inode->i_private); | 414 | return single_open(file, ab8500_bank_print, inode->i_private); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | static ssize_t ab8500_bank_write(struct file *file, | 417 | static ssize_t ab8500_bank_write(struct file *file, |
| 418 | const char __user *user_buf, | 418 | const char __user *user_buf, |
| 419 | size_t count, loff_t *ppos) | 419 | size_t count, loff_t *ppos) |
| 420 | { | 420 | { |
| 421 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | 421 | struct device *dev = ((struct seq_file *)(file->private_data))->private; |
| 422 | char buf[32]; | 422 | char buf[32]; |
| 423 | int buf_size; | 423 | int buf_size; |
| 424 | unsigned long user_bank; | 424 | unsigned long user_bank; |
| 425 | int err; | 425 | int err; |
| 426 | 426 | ||
| 427 | /* Get userspace string and assure termination */ | 427 | /* Get userspace string and assure termination */ |
| 428 | buf_size = min(count, (sizeof(buf) - 1)); | 428 | buf_size = min(count, (sizeof(buf) - 1)); |
| 429 | if (copy_from_user(buf, user_buf, buf_size)) | 429 | if (copy_from_user(buf, user_buf, buf_size)) |
| 430 | return -EFAULT; | 430 | return -EFAULT; |
| 431 | buf[buf_size] = 0; | 431 | buf[buf_size] = 0; |
| 432 | 432 | ||
| 433 | err = strict_strtoul(buf, 0, &user_bank); | 433 | err = strict_strtoul(buf, 0, &user_bank); |
| 434 | if (err) | 434 | if (err) |
| 435 | return -EINVAL; | 435 | return -EINVAL; |
| 436 | 436 | ||
| 437 | if (user_bank >= AB8500_NUM_BANKS) { | 437 | if (user_bank >= AB8500_NUM_BANKS) { |
| 438 | dev_err(dev, "debugfs error input > number of banks\n"); | 438 | dev_err(dev, "debugfs error input > number of banks\n"); |
| 439 | return -EINVAL; | 439 | return -EINVAL; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | debug_bank = user_bank; | 442 | debug_bank = user_bank; |
| 443 | 443 | ||
| 444 | return buf_size; | 444 | return buf_size; |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static int ab8500_address_print(struct seq_file *s, void *p) | 447 | static int ab8500_address_print(struct seq_file *s, void *p) |
| 448 | { | 448 | { |
| 449 | return seq_printf(s, "0x%02X\n", debug_address); | 449 | return seq_printf(s, "0x%02X\n", debug_address); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | static int ab8500_address_open(struct inode *inode, struct file *file) | 452 | static int ab8500_address_open(struct inode *inode, struct file *file) |
| 453 | { | 453 | { |
| 454 | return single_open(file, ab8500_address_print, inode->i_private); | 454 | return single_open(file, ab8500_address_print, inode->i_private); |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | static ssize_t ab8500_address_write(struct file *file, | 457 | static ssize_t ab8500_address_write(struct file *file, |
| 458 | const char __user *user_buf, | 458 | const char __user *user_buf, |
| 459 | size_t count, loff_t *ppos) | 459 | size_t count, loff_t *ppos) |
| 460 | { | 460 | { |
| 461 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | 461 | struct device *dev = ((struct seq_file *)(file->private_data))->private; |
| 462 | char buf[32]; | 462 | char buf[32]; |
| 463 | int buf_size; | 463 | int buf_size; |
| 464 | unsigned long user_address; | 464 | unsigned long user_address; |
| 465 | int err; | 465 | int err; |
| 466 | 466 | ||
| 467 | /* Get userspace string and assure termination */ | 467 | /* Get userspace string and assure termination */ |
| 468 | buf_size = min(count, (sizeof(buf) - 1)); | 468 | buf_size = min(count, (sizeof(buf) - 1)); |
| 469 | if (copy_from_user(buf, user_buf, buf_size)) | 469 | if (copy_from_user(buf, user_buf, buf_size)) |
| 470 | return -EFAULT; | 470 | return -EFAULT; |
| 471 | buf[buf_size] = 0; | 471 | buf[buf_size] = 0; |
| 472 | 472 | ||
| 473 | err = strict_strtoul(buf, 0, &user_address); | 473 | err = strict_strtoul(buf, 0, &user_address); |
| 474 | if (err) | 474 | if (err) |
| 475 | return -EINVAL; | 475 | return -EINVAL; |
| 476 | if (user_address > 0xff) { | 476 | if (user_address > 0xff) { |
| 477 | dev_err(dev, "debugfs error input > 0xff\n"); | 477 | dev_err(dev, "debugfs error input > 0xff\n"); |
| 478 | return -EINVAL; | 478 | return -EINVAL; |
| 479 | } | 479 | } |
| 480 | debug_address = user_address; | 480 | debug_address = user_address; |
| 481 | return buf_size; | 481 | return buf_size; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static int ab8500_val_print(struct seq_file *s, void *p) | 484 | static int ab8500_val_print(struct seq_file *s, void *p) |
| 485 | { | 485 | { |
| 486 | struct device *dev = s->private; | 486 | struct device *dev = s->private; |
| 487 | int ret; | 487 | int ret; |
| 488 | u8 regvalue; | 488 | u8 regvalue; |
| 489 | 489 | ||
| 490 | ret = abx500_get_register_interruptible(dev, | 490 | ret = abx500_get_register_interruptible(dev, |
| 491 | (u8)debug_bank, (u8)debug_address, ®value); | 491 | (u8)debug_bank, (u8)debug_address, ®value); |
| 492 | if (ret < 0) { | 492 | if (ret < 0) { |
| 493 | dev_err(dev, "abx500_get_reg fail %d, %d\n", | 493 | dev_err(dev, "abx500_get_reg fail %d, %d\n", |
| 494 | ret, __LINE__); | 494 | ret, __LINE__); |
| 495 | return -EINVAL; | 495 | return -EINVAL; |
| 496 | } | 496 | } |
| 497 | seq_printf(s, "0x%02X\n", regvalue); | 497 | seq_printf(s, "0x%02X\n", regvalue); |
| 498 | 498 | ||
| 499 | return 0; | 499 | return 0; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | static int ab8500_val_open(struct inode *inode, struct file *file) | 502 | static int ab8500_val_open(struct inode *inode, struct file *file) |
| 503 | { | 503 | { |
| 504 | return single_open(file, ab8500_val_print, inode->i_private); | 504 | return single_open(file, ab8500_val_print, inode->i_private); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | static ssize_t ab8500_val_write(struct file *file, | 507 | static ssize_t ab8500_val_write(struct file *file, |
| 508 | const char __user *user_buf, | 508 | const char __user *user_buf, |
| 509 | size_t count, loff_t *ppos) | 509 | size_t count, loff_t *ppos) |
| 510 | { | 510 | { |
| 511 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | 511 | struct device *dev = ((struct seq_file *)(file->private_data))->private; |
| 512 | char buf[32]; | 512 | char buf[32]; |
| 513 | int buf_size; | 513 | int buf_size; |
| 514 | unsigned long user_val; | 514 | unsigned long user_val; |
| 515 | int err; | 515 | int err; |
| 516 | 516 | ||
| 517 | /* Get userspace string and assure termination */ | 517 | /* Get userspace string and assure termination */ |
| 518 | buf_size = min(count, (sizeof(buf)-1)); | 518 | buf_size = min(count, (sizeof(buf)-1)); |
| 519 | if (copy_from_user(buf, user_buf, buf_size)) | 519 | if (copy_from_user(buf, user_buf, buf_size)) |
| 520 | return -EFAULT; | 520 | return -EFAULT; |
| 521 | buf[buf_size] = 0; | 521 | buf[buf_size] = 0; |
| 522 | 522 | ||
| 523 | err = strict_strtoul(buf, 0, &user_val); | 523 | err = strict_strtoul(buf, 0, &user_val); |
| 524 | if (err) | 524 | if (err) |
| 525 | return -EINVAL; | 525 | return -EINVAL; |
| 526 | if (user_val > 0xff) { | 526 | if (user_val > 0xff) { |
| 527 | dev_err(dev, "debugfs error input > 0xff\n"); | 527 | dev_err(dev, "debugfs error input > 0xff\n"); |
| 528 | return -EINVAL; | 528 | return -EINVAL; |
| 529 | } | 529 | } |
| 530 | err = abx500_set_register_interruptible(dev, | 530 | err = abx500_set_register_interruptible(dev, |
| 531 | (u8)debug_bank, debug_address, (u8)user_val); | 531 | (u8)debug_bank, debug_address, (u8)user_val); |
| 532 | if (err < 0) { | 532 | if (err < 0) { |
| 533 | printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); | 533 | printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); |
| 534 | return -EINVAL; | 534 | return -EINVAL; |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | return buf_size; | 537 | return buf_size; |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | static const struct file_operations ab8500_bank_fops = { | 540 | static const struct file_operations ab8500_bank_fops = { |
| 541 | .open = ab8500_bank_open, | 541 | .open = ab8500_bank_open, |
| 542 | .write = ab8500_bank_write, | 542 | .write = ab8500_bank_write, |
| 543 | .read = seq_read, | 543 | .read = seq_read, |
| 544 | .llseek = seq_lseek, | 544 | .llseek = seq_lseek, |
| 545 | .release = single_release, | 545 | .release = single_release, |
| 546 | .owner = THIS_MODULE, | 546 | .owner = THIS_MODULE, |
| 547 | }; | 547 | }; |
| 548 | 548 | ||
| 549 | static const struct file_operations ab8500_address_fops = { | 549 | static const struct file_operations ab8500_address_fops = { |
| 550 | .open = ab8500_address_open, | 550 | .open = ab8500_address_open, |
| 551 | .write = ab8500_address_write, | 551 | .write = ab8500_address_write, |
| 552 | .read = seq_read, | 552 | .read = seq_read, |
| 553 | .llseek = seq_lseek, | 553 | .llseek = seq_lseek, |
| 554 | .release = single_release, | 554 | .release = single_release, |
| 555 | .owner = THIS_MODULE, | 555 | .owner = THIS_MODULE, |
| 556 | }; | 556 | }; |
| 557 | 557 | ||
| 558 | static const struct file_operations ab8500_val_fops = { | 558 | static const struct file_operations ab8500_val_fops = { |
| 559 | .open = ab8500_val_open, | 559 | .open = ab8500_val_open, |
| 560 | .write = ab8500_val_write, | 560 | .write = ab8500_val_write, |
| 561 | .read = seq_read, | 561 | .read = seq_read, |
| 562 | .llseek = seq_lseek, | 562 | .llseek = seq_lseek, |
| 563 | .release = single_release, | 563 | .release = single_release, |
| 564 | .owner = THIS_MODULE, | 564 | .owner = THIS_MODULE, |
| 565 | }; | 565 | }; |
| 566 | 566 | ||
| 567 | static struct dentry *ab8500_dir; | 567 | static struct dentry *ab8500_dir; |
| @@ -572,77 +572,77 @@ static struct dentry *ab8500_val_file; | |||
| 572 | 572 | ||
| 573 | static int __devinit ab8500_debug_probe(struct platform_device *plf) | 573 | static int __devinit ab8500_debug_probe(struct platform_device *plf) |
| 574 | { | 574 | { |
| 575 | debug_bank = AB8500_MISC; | 575 | debug_bank = AB8500_MISC; |
| 576 | debug_address = AB8500_REV_REG & 0x00FF; | 576 | debug_address = AB8500_REV_REG & 0x00FF; |
| 577 | 577 | ||
| 578 | ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); | 578 | ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); |
| 579 | if (!ab8500_dir) | 579 | if (!ab8500_dir) |
| 580 | goto exit_no_debugfs; | 580 | goto exit_no_debugfs; |
| 581 | 581 | ||
| 582 | ab8500_reg_file = debugfs_create_file("all-bank-registers", | 582 | ab8500_reg_file = debugfs_create_file("all-bank-registers", |
| 583 | S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); | 583 | S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); |
| 584 | if (!ab8500_reg_file) | 584 | if (!ab8500_reg_file) |
| 585 | goto exit_destroy_dir; | 585 | goto exit_destroy_dir; |
| 586 | 586 | ||
| 587 | ab8500_bank_file = debugfs_create_file("register-bank", | 587 | ab8500_bank_file = debugfs_create_file("register-bank", |
| 588 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); | 588 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); |
| 589 | if (!ab8500_bank_file) | 589 | if (!ab8500_bank_file) |
| 590 | goto exit_destroy_reg; | 590 | goto exit_destroy_reg; |
| 591 | 591 | ||
| 592 | ab8500_address_file = debugfs_create_file("register-address", | 592 | ab8500_address_file = debugfs_create_file("register-address", |
| 593 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, | 593 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, |
| 594 | &ab8500_address_fops); | 594 | &ab8500_address_fops); |
| 595 | if (!ab8500_address_file) | 595 | if (!ab8500_address_file) |
| 596 | goto exit_destroy_bank; | 596 | goto exit_destroy_bank; |
| 597 | 597 | ||
| 598 | ab8500_val_file = debugfs_create_file("register-value", | 598 | ab8500_val_file = debugfs_create_file("register-value", |
| 599 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); | 599 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); |
| 600 | if (!ab8500_val_file) | 600 | if (!ab8500_val_file) |
| 601 | goto exit_destroy_address; | 601 | goto exit_destroy_address; |
| 602 | 602 | ||
| 603 | return 0; | 603 | return 0; |
| 604 | 604 | ||
| 605 | exit_destroy_address: | 605 | exit_destroy_address: |
| 606 | debugfs_remove(ab8500_address_file); | 606 | debugfs_remove(ab8500_address_file); |
| 607 | exit_destroy_bank: | 607 | exit_destroy_bank: |
| 608 | debugfs_remove(ab8500_bank_file); | 608 | debugfs_remove(ab8500_bank_file); |
| 609 | exit_destroy_reg: | 609 | exit_destroy_reg: |
| 610 | debugfs_remove(ab8500_reg_file); | 610 | debugfs_remove(ab8500_reg_file); |
| 611 | exit_destroy_dir: | 611 | exit_destroy_dir: |
| 612 | debugfs_remove(ab8500_dir); | 612 | debugfs_remove(ab8500_dir); |
| 613 | exit_no_debugfs: | 613 | exit_no_debugfs: |
| 614 | dev_err(&plf->dev, "failed to create debugfs entries.\n"); | 614 | dev_err(&plf->dev, "failed to create debugfs entries.\n"); |
| 615 | return -ENOMEM; | 615 | return -ENOMEM; |
| 616 | } | 616 | } |
| 617 | 617 | ||
| 618 | static int __devexit ab8500_debug_remove(struct platform_device *plf) | 618 | static int __devexit ab8500_debug_remove(struct platform_device *plf) |
| 619 | { | 619 | { |
| 620 | debugfs_remove(ab8500_val_file); | 620 | debugfs_remove(ab8500_val_file); |
| 621 | debugfs_remove(ab8500_address_file); | 621 | debugfs_remove(ab8500_address_file); |
| 622 | debugfs_remove(ab8500_bank_file); | 622 | debugfs_remove(ab8500_bank_file); |
| 623 | debugfs_remove(ab8500_reg_file); | 623 | debugfs_remove(ab8500_reg_file); |
| 624 | debugfs_remove(ab8500_dir); | 624 | debugfs_remove(ab8500_dir); |
| 625 | 625 | ||
| 626 | return 0; | 626 | return 0; |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | static struct platform_driver ab8500_debug_driver = { | 629 | static struct platform_driver ab8500_debug_driver = { |
| 630 | .driver = { | 630 | .driver = { |
| 631 | .name = "ab8500-debug", | 631 | .name = "ab8500-debug", |
| 632 | .owner = THIS_MODULE, | 632 | .owner = THIS_MODULE, |
| 633 | }, | 633 | }, |
| 634 | .probe = ab8500_debug_probe, | 634 | .probe = ab8500_debug_probe, |
| 635 | .remove = __devexit_p(ab8500_debug_remove) | 635 | .remove = __devexit_p(ab8500_debug_remove) |
| 636 | }; | 636 | }; |
| 637 | 637 | ||
| 638 | static int __init ab8500_debug_init(void) | 638 | static int __init ab8500_debug_init(void) |
| 639 | { | 639 | { |
| 640 | return platform_driver_register(&ab8500_debug_driver); | 640 | return platform_driver_register(&ab8500_debug_driver); |
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | static void __exit ab8500_debug_exit(void) | 643 | static void __exit ab8500_debug_exit(void) |
| 644 | { | 644 | { |
| 645 | platform_driver_unregister(&ab8500_debug_driver); | 645 | platform_driver_unregister(&ab8500_debug_driver); |
| 646 | } | 646 | } |
| 647 | subsys_initcall(ab8500_debug_init); | 647 | subsys_initcall(ab8500_debug_init); |
| 648 | module_exit(ab8500_debug_exit); | 648 | module_exit(ab8500_debug_exit); |
diff --git a/drivers/mfd/ab8500-spi.c b/drivers/mfd/ab8500-spi.c deleted file mode 100644 index b1653421edb5..000000000000 --- a/drivers/mfd/ab8500-spi.c +++ /dev/null | |||
| @@ -1,143 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * License Terms: GNU General Public License v2 | ||
| 5 | * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/slab.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/spi/spi.h> | ||
| 14 | #include <linux/mfd/ab8500.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * This funtion writes to any AB8500 registers using | ||
| 18 | * SPI protocol & before it writes it packs the data | ||
| 19 | * in the below 24 bit frame format | ||
| 20 | * | ||
| 21 | * *|------------------------------------| | ||
| 22 | * *| 23|22...18|17.......10|9|8|7......0| | ||
| 23 | * *| r/w bank adr data | | ||
| 24 | * * ------------------------------------ | ||
| 25 | * | ||
| 26 | * This function shouldn't be called from interrupt | ||
| 27 | * context | ||
| 28 | */ | ||
| 29 | static int ab8500_spi_write(struct ab8500 *ab8500, u16 addr, u8 data) | ||
| 30 | { | ||
| 31 | struct spi_device *spi = container_of(ab8500->dev, struct spi_device, | ||
| 32 | dev); | ||
| 33 | unsigned long spi_data = addr << 10 | data; | ||
| 34 | struct spi_transfer xfer; | ||
| 35 | struct spi_message msg; | ||
| 36 | |||
| 37 | ab8500->tx_buf[0] = spi_data; | ||
| 38 | ab8500->rx_buf[0] = 0; | ||
| 39 | |||
| 40 | xfer.tx_buf = ab8500->tx_buf; | ||
| 41 | xfer.rx_buf = NULL; | ||
| 42 | xfer.len = sizeof(unsigned long); | ||
| 43 | |||
| 44 | spi_message_init(&msg); | ||
| 45 | spi_message_add_tail(&xfer, &msg); | ||
| 46 | |||
| 47 | return spi_sync(spi, &msg); | ||
| 48 | } | ||
| 49 | |||
| 50 | static int ab8500_spi_read(struct ab8500 *ab8500, u16 addr) | ||
| 51 | { | ||
| 52 | struct spi_device *spi = container_of(ab8500->dev, struct spi_device, | ||
| 53 | dev); | ||
| 54 | unsigned long spi_data = 1 << 23 | addr << 10; | ||
| 55 | struct spi_transfer xfer; | ||
| 56 | struct spi_message msg; | ||
| 57 | int ret; | ||
| 58 | |||
| 59 | ab8500->tx_buf[0] = spi_data; | ||
| 60 | ab8500->rx_buf[0] = 0; | ||
| 61 | |||
| 62 | xfer.tx_buf = ab8500->tx_buf; | ||
| 63 | xfer.rx_buf = ab8500->rx_buf; | ||
| 64 | xfer.len = sizeof(unsigned long); | ||
| 65 | |||
| 66 | spi_message_init(&msg); | ||
| 67 | spi_message_add_tail(&xfer, &msg); | ||
| 68 | |||
| 69 | ret = spi_sync(spi, &msg); | ||
| 70 | if (!ret) | ||
| 71 | /* | ||
| 72 | * Only the 8 lowermost bytes are | ||
| 73 | * defined with value, the rest may | ||
| 74 | * vary depending on chip/board noise. | ||
| 75 | */ | ||
| 76 | ret = ab8500->rx_buf[0] & 0xFFU; | ||
| 77 | |||
| 78 | return ret; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int __devinit ab8500_spi_probe(struct spi_device *spi) | ||
| 82 | { | ||
| 83 | struct ab8500 *ab8500; | ||
| 84 | int ret; | ||
| 85 | |||
| 86 | spi->bits_per_word = 24; | ||
| 87 | ret = spi_setup(spi); | ||
| 88 | if (ret < 0) | ||
| 89 | return ret; | ||
| 90 | |||
| 91 | ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); | ||
| 92 | if (!ab8500) | ||
| 93 | return -ENOMEM; | ||
| 94 | |||
| 95 | ab8500->dev = &spi->dev; | ||
| 96 | ab8500->irq = spi->irq; | ||
| 97 | |||
| 98 | ab8500->read = ab8500_spi_read; | ||
| 99 | ab8500->write = ab8500_spi_write; | ||
| 100 | |||
| 101 | spi_set_drvdata(spi, ab8500); | ||
| 102 | |||
| 103 | ret = ab8500_init(ab8500); | ||
| 104 | if (ret) | ||
| 105 | kfree(ab8500); | ||
| 106 | |||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int __devexit ab8500_spi_remove(struct spi_device *spi) | ||
| 111 | { | ||
| 112 | struct ab8500 *ab8500 = spi_get_drvdata(spi); | ||
| 113 | |||
| 114 | ab8500_exit(ab8500); | ||
| 115 | kfree(ab8500); | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static struct spi_driver ab8500_spi_driver = { | ||
| 121 | .driver = { | ||
| 122 | .name = "ab8500-spi", | ||
| 123 | .owner = THIS_MODULE, | ||
| 124 | }, | ||
| 125 | .probe = ab8500_spi_probe, | ||
| 126 | .remove = __devexit_p(ab8500_spi_remove) | ||
| 127 | }; | ||
| 128 | |||
| 129 | static int __init ab8500_spi_init(void) | ||
| 130 | { | ||
| 131 | return spi_register_driver(&ab8500_spi_driver); | ||
| 132 | } | ||
| 133 | subsys_initcall(ab8500_spi_init); | ||
| 134 | |||
| 135 | static void __exit ab8500_spi_exit(void) | ||
| 136 | { | ||
| 137 | spi_unregister_driver(&ab8500_spi_driver); | ||
| 138 | } | ||
| 139 | module_exit(ab8500_spi_exit); | ||
| 140 | |||
| 141 | MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com"); | ||
| 142 | MODULE_DESCRIPTION("AB8500 SPI"); | ||
| 143 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 7de708d15d72..6a1f94042612 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
| @@ -57,7 +57,7 @@ struct asic3_clk { | |||
| 57 | .rate = _rate, \ | 57 | .rate = _rate, \ |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | struct asic3_clk asic3_clk_init[] __initdata = { | 60 | static struct asic3_clk asic3_clk_init[] __initdata = { |
| 61 | INIT_CDEX(SPI, 0), | 61 | INIT_CDEX(SPI, 0), |
| 62 | INIT_CDEX(OWM, 5000000), | 62 | INIT_CDEX(OWM, 5000000), |
| 63 | INIT_CDEX(PWM0, 0), | 63 | INIT_CDEX(PWM0, 0), |
| @@ -102,7 +102,7 @@ static inline u32 asic3_read_register(struct asic3 *asic, | |||
| 102 | (reg >> asic->bus_shift)); | 102 | (reg >> asic->bus_shift)); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) | 105 | static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) |
| 106 | { | 106 | { |
| 107 | unsigned long flags; | 107 | unsigned long flags; |
| 108 | u32 val; | 108 | u32 val; |
| @@ -226,14 +226,14 @@ static inline int asic3_irq_to_index(struct asic3 *asic, int irq) | |||
| 226 | return (irq - asic->irq_base) & 0xf; | 226 | return (irq - asic->irq_base) & 0xf; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | static void asic3_mask_gpio_irq(unsigned int irq) | 229 | static void asic3_mask_gpio_irq(struct irq_data *data) |
| 230 | { | 230 | { |
| 231 | struct asic3 *asic = get_irq_chip_data(irq); | 231 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 232 | u32 val, bank, index; | 232 | u32 val, bank, index; |
| 233 | unsigned long flags; | 233 | unsigned long flags; |
| 234 | 234 | ||
| 235 | bank = asic3_irq_to_bank(asic, irq); | 235 | bank = asic3_irq_to_bank(asic, data->irq); |
| 236 | index = asic3_irq_to_index(asic, irq); | 236 | index = asic3_irq_to_index(asic, data->irq); |
| 237 | 237 | ||
| 238 | spin_lock_irqsave(&asic->lock, flags); | 238 | spin_lock_irqsave(&asic->lock, flags); |
| 239 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); | 239 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); |
| @@ -242,9 +242,9 @@ static void asic3_mask_gpio_irq(unsigned int irq) | |||
| 242 | spin_unlock_irqrestore(&asic->lock, flags); | 242 | spin_unlock_irqrestore(&asic->lock, flags); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | static void asic3_mask_irq(unsigned int irq) | 245 | static void asic3_mask_irq(struct irq_data *data) |
| 246 | { | 246 | { |
| 247 | struct asic3 *asic = get_irq_chip_data(irq); | 247 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 248 | int regval; | 248 | int regval; |
| 249 | unsigned long flags; | 249 | unsigned long flags; |
| 250 | 250 | ||
| @@ -254,7 +254,7 @@ static void asic3_mask_irq(unsigned int irq) | |||
| 254 | ASIC3_INTR_INT_MASK); | 254 | ASIC3_INTR_INT_MASK); |
| 255 | 255 | ||
| 256 | regval &= ~(ASIC3_INTMASK_MASK0 << | 256 | regval &= ~(ASIC3_INTMASK_MASK0 << |
| 257 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); | 257 | (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); |
| 258 | 258 | ||
| 259 | asic3_write_register(asic, | 259 | asic3_write_register(asic, |
| 260 | ASIC3_INTR_BASE + | 260 | ASIC3_INTR_BASE + |
| @@ -263,14 +263,14 @@ static void asic3_mask_irq(unsigned int irq) | |||
| 263 | spin_unlock_irqrestore(&asic->lock, flags); | 263 | spin_unlock_irqrestore(&asic->lock, flags); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static void asic3_unmask_gpio_irq(unsigned int irq) | 266 | static void asic3_unmask_gpio_irq(struct irq_data *data) |
| 267 | { | 267 | { |
| 268 | struct asic3 *asic = get_irq_chip_data(irq); | 268 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 269 | u32 val, bank, index; | 269 | u32 val, bank, index; |
| 270 | unsigned long flags; | 270 | unsigned long flags; |
| 271 | 271 | ||
| 272 | bank = asic3_irq_to_bank(asic, irq); | 272 | bank = asic3_irq_to_bank(asic, data->irq); |
| 273 | index = asic3_irq_to_index(asic, irq); | 273 | index = asic3_irq_to_index(asic, data->irq); |
| 274 | 274 | ||
| 275 | spin_lock_irqsave(&asic->lock, flags); | 275 | spin_lock_irqsave(&asic->lock, flags); |
| 276 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); | 276 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); |
| @@ -279,9 +279,9 @@ static void asic3_unmask_gpio_irq(unsigned int irq) | |||
| 279 | spin_unlock_irqrestore(&asic->lock, flags); | 279 | spin_unlock_irqrestore(&asic->lock, flags); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void asic3_unmask_irq(unsigned int irq) | 282 | static void asic3_unmask_irq(struct irq_data *data) |
| 283 | { | 283 | { |
| 284 | struct asic3 *asic = get_irq_chip_data(irq); | 284 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 285 | int regval; | 285 | int regval; |
| 286 | unsigned long flags; | 286 | unsigned long flags; |
| 287 | 287 | ||
| @@ -291,7 +291,7 @@ static void asic3_unmask_irq(unsigned int irq) | |||
| 291 | ASIC3_INTR_INT_MASK); | 291 | ASIC3_INTR_INT_MASK); |
| 292 | 292 | ||
| 293 | regval |= (ASIC3_INTMASK_MASK0 << | 293 | regval |= (ASIC3_INTMASK_MASK0 << |
| 294 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); | 294 | (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); |
| 295 | 295 | ||
| 296 | asic3_write_register(asic, | 296 | asic3_write_register(asic, |
| 297 | ASIC3_INTR_BASE + | 297 | ASIC3_INTR_BASE + |
| @@ -300,15 +300,15 @@ static void asic3_unmask_irq(unsigned int irq) | |||
| 300 | spin_unlock_irqrestore(&asic->lock, flags); | 300 | spin_unlock_irqrestore(&asic->lock, flags); |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | 303 | static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) |
| 304 | { | 304 | { |
| 305 | struct asic3 *asic = get_irq_chip_data(irq); | 305 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 306 | u32 bank, index; | 306 | u32 bank, index; |
| 307 | u16 trigger, level, edge, bit; | 307 | u16 trigger, level, edge, bit; |
| 308 | unsigned long flags; | 308 | unsigned long flags; |
| 309 | 309 | ||
| 310 | bank = asic3_irq_to_bank(asic, irq); | 310 | bank = asic3_irq_to_bank(asic, data->irq); |
| 311 | index = asic3_irq_to_index(asic, irq); | 311 | index = asic3_irq_to_index(asic, data->irq); |
| 312 | bit = 1<<index; | 312 | bit = 1<<index; |
| 313 | 313 | ||
| 314 | spin_lock_irqsave(&asic->lock, flags); | 314 | spin_lock_irqsave(&asic->lock, flags); |
| @@ -318,7 +318,7 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
| 318 | bank + ASIC3_GPIO_EDGE_TRIGGER); | 318 | bank + ASIC3_GPIO_EDGE_TRIGGER); |
| 319 | trigger = asic3_read_register(asic, | 319 | trigger = asic3_read_register(asic, |
| 320 | bank + ASIC3_GPIO_TRIGGER_TYPE); | 320 | bank + ASIC3_GPIO_TRIGGER_TYPE); |
| 321 | asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; | 321 | asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] &= ~bit; |
| 322 | 322 | ||
| 323 | if (type == IRQ_TYPE_EDGE_RISING) { | 323 | if (type == IRQ_TYPE_EDGE_RISING) { |
| 324 | trigger |= bit; | 324 | trigger |= bit; |
| @@ -328,11 +328,11 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
| 328 | edge &= ~bit; | 328 | edge &= ~bit; |
| 329 | } else if (type == IRQ_TYPE_EDGE_BOTH) { | 329 | } else if (type == IRQ_TYPE_EDGE_BOTH) { |
| 330 | trigger |= bit; | 330 | trigger |= bit; |
| 331 | if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base)) | 331 | if (asic3_gpio_get(&asic->gpio, data->irq - asic->irq_base)) |
| 332 | edge &= ~bit; | 332 | edge &= ~bit; |
| 333 | else | 333 | else |
| 334 | edge |= bit; | 334 | edge |= bit; |
| 335 | asic->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit; | 335 | asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] |= bit; |
| 336 | } else if (type == IRQ_TYPE_LEVEL_LOW) { | 336 | } else if (type == IRQ_TYPE_LEVEL_LOW) { |
| 337 | trigger &= ~bit; | 337 | trigger &= ~bit; |
| 338 | level &= ~bit; | 338 | level &= ~bit; |
| @@ -359,17 +359,17 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
| 359 | 359 | ||
| 360 | static struct irq_chip asic3_gpio_irq_chip = { | 360 | static struct irq_chip asic3_gpio_irq_chip = { |
| 361 | .name = "ASIC3-GPIO", | 361 | .name = "ASIC3-GPIO", |
| 362 | .ack = asic3_mask_gpio_irq, | 362 | .irq_ack = asic3_mask_gpio_irq, |
| 363 | .mask = asic3_mask_gpio_irq, | 363 | .irq_mask = asic3_mask_gpio_irq, |
| 364 | .unmask = asic3_unmask_gpio_irq, | 364 | .irq_unmask = asic3_unmask_gpio_irq, |
| 365 | .set_type = asic3_gpio_irq_type, | 365 | .irq_set_type = asic3_gpio_irq_type, |
| 366 | }; | 366 | }; |
| 367 | 367 | ||
| 368 | static struct irq_chip asic3_irq_chip = { | 368 | static struct irq_chip asic3_irq_chip = { |
| 369 | .name = "ASIC3", | 369 | .name = "ASIC3", |
| 370 | .ack = asic3_mask_irq, | 370 | .irq_ack = asic3_mask_irq, |
| 371 | .mask = asic3_mask_irq, | 371 | .irq_mask = asic3_mask_irq, |
| 372 | .unmask = asic3_unmask_irq, | 372 | .irq_unmask = asic3_unmask_irq, |
| 373 | }; | 373 | }; |
| 374 | 374 | ||
| 375 | static int __init asic3_irq_probe(struct platform_device *pdev) | 375 | static int __init asic3_irq_probe(struct platform_device *pdev) |
| @@ -635,7 +635,7 @@ static struct resource ds1wm_resources[] = { | |||
| 635 | }, | 635 | }, |
| 636 | { | 636 | { |
| 637 | .start = ASIC3_IRQ_OWM, | 637 | .start = ASIC3_IRQ_OWM, |
| 638 | .start = ASIC3_IRQ_OWM, | 638 | .end = ASIC3_IRQ_OWM, |
| 639 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | 639 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, |
| 640 | }, | 640 | }, |
| 641 | }; | 641 | }; |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c new file mode 100644 index 000000000000..59ca6f151e78 --- /dev/null +++ b/drivers/mfd/cs5535-mfd.c | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | /* | ||
| 2 | * cs5535-mfd.c - core MFD driver for CS5535/CS5536 southbridges | ||
| 3 | * | ||
| 4 | * The CS5535 and CS5536 has an ISA bridge on the PCI bus that is | ||
| 5 | * used for accessing GPIOs, MFGPTs, ACPI, etc. Each subdevice has | ||
| 6 | * an IO range that's specified in a single BAR. The BAR order is | ||
| 7 | * hardcoded in the CS553x specifications. | ||
| 8 | * | ||
| 9 | * Copyright (c) 2010 Andres Salomon <dilinger@queued.net> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/mfd/core.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/pci.h> | ||
| 30 | |||
| 31 | #define DRV_NAME "cs5535-mfd" | ||
| 32 | |||
| 33 | enum cs5535_mfd_bars { | ||
| 34 | SMB_BAR = 0, | ||
| 35 | GPIO_BAR = 1, | ||
| 36 | MFGPT_BAR = 2, | ||
| 37 | PMS_BAR = 4, | ||
| 38 | ACPI_BAR = 5, | ||
| 39 | NR_BARS, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; | ||
| 43 | |||
| 44 | static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { | ||
| 45 | { | ||
| 46 | .id = SMB_BAR, | ||
| 47 | .name = "cs5535-smb", | ||
| 48 | .num_resources = 1, | ||
| 49 | .resources = &cs5535_mfd_resources[SMB_BAR], | ||
| 50 | }, | ||
| 51 | { | ||
| 52 | .id = GPIO_BAR, | ||
| 53 | .name = "cs5535-gpio", | ||
| 54 | .num_resources = 1, | ||
| 55 | .resources = &cs5535_mfd_resources[GPIO_BAR], | ||
| 56 | }, | ||
| 57 | { | ||
| 58 | .id = MFGPT_BAR, | ||
| 59 | .name = "cs5535-mfgpt", | ||
| 60 | .num_resources = 1, | ||
| 61 | .resources = &cs5535_mfd_resources[MFGPT_BAR], | ||
| 62 | }, | ||
| 63 | { | ||
| 64 | .id = PMS_BAR, | ||
| 65 | .name = "cs5535-pms", | ||
| 66 | .num_resources = 1, | ||
| 67 | .resources = &cs5535_mfd_resources[PMS_BAR], | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | .id = ACPI_BAR, | ||
| 71 | .name = "cs5535-acpi", | ||
| 72 | .num_resources = 1, | ||
| 73 | .resources = &cs5535_mfd_resources[ACPI_BAR], | ||
| 74 | }, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | ||
| 78 | const struct pci_device_id *id) | ||
| 79 | { | ||
| 80 | int err, i; | ||
| 81 | |||
| 82 | err = pci_enable_device(pdev); | ||
| 83 | if (err) | ||
| 84 | return err; | ||
| 85 | |||
| 86 | /* fill in IO range for each cell; subdrivers handle the region */ | ||
| 87 | for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) { | ||
| 88 | int bar = cs5535_mfd_cells[i].id; | ||
| 89 | struct resource *r = &cs5535_mfd_resources[bar]; | ||
| 90 | |||
| 91 | r->flags = IORESOURCE_IO; | ||
| 92 | r->start = pci_resource_start(pdev, bar); | ||
| 93 | r->end = pci_resource_end(pdev, bar); | ||
| 94 | |||
| 95 | /* id is used for temporarily storing BAR; unset it now */ | ||
| 96 | cs5535_mfd_cells[i].id = 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, | ||
| 100 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); | ||
| 101 | if (err) { | ||
| 102 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); | ||
| 103 | goto err_disable; | ||
| 104 | } | ||
| 105 | |||
| 106 | dev_info(&pdev->dev, "%zu devices registered.\n", | ||
| 107 | ARRAY_SIZE(cs5535_mfd_cells)); | ||
| 108 | |||
| 109 | return 0; | ||
| 110 | |||
| 111 | err_disable: | ||
| 112 | pci_disable_device(pdev); | ||
| 113 | return err; | ||
| 114 | } | ||
| 115 | |||
| 116 | static void __devexit cs5535_mfd_remove(struct pci_dev *pdev) | ||
| 117 | { | ||
| 118 | mfd_remove_devices(&pdev->dev); | ||
| 119 | pci_disable_device(pdev); | ||
| 120 | } | ||
| 121 | |||
| 122 | static struct pci_device_id cs5535_mfd_pci_tbl[] = { | ||
| 123 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
| 124 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
| 125 | { 0, } | ||
| 126 | }; | ||
| 127 | MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); | ||
| 128 | |||
| 129 | static struct pci_driver cs5535_mfd_drv = { | ||
| 130 | .name = DRV_NAME, | ||
| 131 | .id_table = cs5535_mfd_pci_tbl, | ||
| 132 | .probe = cs5535_mfd_probe, | ||
| 133 | .remove = __devexit_p(cs5535_mfd_remove), | ||
| 134 | }; | ||
| 135 | |||
| 136 | static int __init cs5535_mfd_init(void) | ||
| 137 | { | ||
| 138 | return pci_register_driver(&cs5535_mfd_drv); | ||
| 139 | } | ||
| 140 | |||
| 141 | static void __exit cs5535_mfd_exit(void) | ||
| 142 | { | ||
| 143 | pci_unregister_driver(&cs5535_mfd_drv); | ||
| 144 | } | ||
| 145 | |||
| 146 | module_init(cs5535_mfd_init); | ||
| 147 | module_exit(cs5535_mfd_exit); | ||
| 148 | |||
| 149 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | ||
| 150 | MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); | ||
| 151 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index c2b698d69a93..9e2d8dd5f9e5 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
| @@ -144,26 +144,26 @@ int pcap_to_irq(struct pcap_chip *pcap, int irq) | |||
| 144 | } | 144 | } |
| 145 | EXPORT_SYMBOL_GPL(pcap_to_irq); | 145 | EXPORT_SYMBOL_GPL(pcap_to_irq); |
| 146 | 146 | ||
| 147 | static void pcap_mask_irq(unsigned int irq) | 147 | static void pcap_mask_irq(struct irq_data *d) |
| 148 | { | 148 | { |
| 149 | struct pcap_chip *pcap = get_irq_chip_data(irq); | 149 | struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); |
| 150 | 150 | ||
| 151 | pcap->msr |= 1 << irq_to_pcap(pcap, irq); | 151 | pcap->msr |= 1 << irq_to_pcap(pcap, d->irq); |
| 152 | queue_work(pcap->workqueue, &pcap->msr_work); | 152 | queue_work(pcap->workqueue, &pcap->msr_work); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static void pcap_unmask_irq(unsigned int irq) | 155 | static void pcap_unmask_irq(struct irq_data *d) |
| 156 | { | 156 | { |
| 157 | struct pcap_chip *pcap = get_irq_chip_data(irq); | 157 | struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); |
| 158 | 158 | ||
| 159 | pcap->msr &= ~(1 << irq_to_pcap(pcap, irq)); | 159 | pcap->msr &= ~(1 << irq_to_pcap(pcap, d->irq)); |
| 160 | queue_work(pcap->workqueue, &pcap->msr_work); | 160 | queue_work(pcap->workqueue, &pcap->msr_work); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | static struct irq_chip pcap_irq_chip = { | 163 | static struct irq_chip pcap_irq_chip = { |
| 164 | .name = "pcap", | 164 | .name = "pcap", |
| 165 | .mask = pcap_mask_irq, | 165 | .irq_mask = pcap_mask_irq, |
| 166 | .unmask = pcap_unmask_irq, | 166 | .irq_unmask = pcap_unmask_irq, |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
| 169 | static void pcap_msr_work(struct work_struct *work) | 169 | static void pcap_msr_work(struct work_struct *work) |
| @@ -199,8 +199,7 @@ static void pcap_isr_work(struct work_struct *work) | |||
| 199 | if (service & 1) { | 199 | if (service & 1) { |
| 200 | struct irq_desc *desc = irq_to_desc(irq); | 200 | struct irq_desc *desc = irq_to_desc(irq); |
| 201 | 201 | ||
| 202 | if (WARN(!desc, KERN_WARNING | 202 | if (WARN(!desc, "Invalid PCAP IRQ %d\n", irq)) |
| 203 | "Invalid PCAP IRQ %d\n", irq)) | ||
| 204 | break; | 203 | break; |
| 205 | 204 | ||
| 206 | if (desc->status & IRQ_DISABLED) | 205 | if (desc->status & IRQ_DISABLED) |
| @@ -218,7 +217,7 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 218 | { | 217 | { |
| 219 | struct pcap_chip *pcap = get_irq_data(irq); | 218 | struct pcap_chip *pcap = get_irq_data(irq); |
| 220 | 219 | ||
| 221 | desc->chip->ack(irq); | 220 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
| 222 | queue_work(pcap->workqueue, &pcap->isr_work); | 221 | queue_work(pcap->workqueue, &pcap->isr_work); |
| 223 | return; | 222 | return; |
| 224 | } | 223 | } |
| @@ -282,7 +281,7 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) | |||
| 282 | mutex_lock(&pcap->adc_mutex); | 281 | mutex_lock(&pcap->adc_mutex); |
| 283 | req = pcap->adc_queue[pcap->adc_head]; | 282 | req = pcap->adc_queue[pcap->adc_head]; |
| 284 | 283 | ||
| 285 | if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) { | 284 | if (WARN(!req, "adc irq without pending request\n")) { |
| 286 | mutex_unlock(&pcap->adc_mutex); | 285 | mutex_unlock(&pcap->adc_mutex); |
| 287 | return IRQ_HANDLED; | 286 | return IRQ_HANDLED; |
| 288 | } | 287 | } |
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index d3e74f8585e0..d00b6d1a69e5 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
| @@ -70,31 +70,32 @@ static inline void ack_irqs(struct egpio_info *ei) | |||
| 70 | ei->ack_write, ei->ack_register << ei->bus_shift); | 70 | ei->ack_write, ei->ack_register << ei->bus_shift); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static void egpio_ack(unsigned int irq) | 73 | static void egpio_ack(struct irq_data *data) |
| 74 | { | 74 | { |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | /* There does not appear to be a way to proactively mask interrupts | 77 | /* There does not appear to be a way to proactively mask interrupts |
| 78 | * on the egpio chip itself. So, we simply ignore interrupts that | 78 | * on the egpio chip itself. So, we simply ignore interrupts that |
| 79 | * aren't desired. */ | 79 | * aren't desired. */ |
| 80 | static void egpio_mask(unsigned int irq) | 80 | static void egpio_mask(struct irq_data *data) |
| 81 | { | 81 | { |
| 82 | struct egpio_info *ei = get_irq_chip_data(irq); | 82 | struct egpio_info *ei = irq_data_get_irq_chip_data(data); |
| 83 | ei->irqs_enabled &= ~(1 << (irq - ei->irq_start)); | 83 | ei->irqs_enabled &= ~(1 << (data->irq - ei->irq_start)); |
| 84 | pr_debug("EGPIO mask %d %04x\n", irq, ei->irqs_enabled); | 84 | pr_debug("EGPIO mask %d %04x\n", data->irq, ei->irqs_enabled); |
| 85 | } | 85 | } |
| 86 | static void egpio_unmask(unsigned int irq) | 86 | |
| 87 | static void egpio_unmask(struct irq_data *data) | ||
| 87 | { | 88 | { |
| 88 | struct egpio_info *ei = get_irq_chip_data(irq); | 89 | struct egpio_info *ei = irq_data_get_irq_chip_data(data); |
| 89 | ei->irqs_enabled |= 1 << (irq - ei->irq_start); | 90 | ei->irqs_enabled |= 1 << (data->irq - ei->irq_start); |
| 90 | pr_debug("EGPIO unmask %d %04x\n", irq, ei->irqs_enabled); | 91 | pr_debug("EGPIO unmask %d %04x\n", data->irq, ei->irqs_enabled); |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | static struct irq_chip egpio_muxed_chip = { | 94 | static struct irq_chip egpio_muxed_chip = { |
| 94 | .name = "htc-egpio", | 95 | .name = "htc-egpio", |
| 95 | .ack = egpio_ack, | 96 | .irq_ack = egpio_ack, |
| 96 | .mask = egpio_mask, | 97 | .irq_mask = egpio_mask, |
| 97 | .unmask = egpio_unmask, | 98 | .irq_unmask = egpio_unmask, |
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | static void egpio_handler(unsigned int irq, struct irq_desc *desc) | 101 | static void egpio_handler(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 594c9a8e25e1..296ad1562f69 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
| @@ -82,25 +82,25 @@ struct htcpld_data { | |||
| 82 | /* There does not appear to be a way to proactively mask interrupts | 82 | /* There does not appear to be a way to proactively mask interrupts |
| 83 | * on the htcpld chip itself. So, we simply ignore interrupts that | 83 | * on the htcpld chip itself. So, we simply ignore interrupts that |
| 84 | * aren't desired. */ | 84 | * aren't desired. */ |
| 85 | static void htcpld_mask(unsigned int irq) | 85 | static void htcpld_mask(struct irq_data *data) |
| 86 | { | 86 | { |
| 87 | struct htcpld_chip *chip = get_irq_chip_data(irq); | 87 | struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); |
| 88 | chip->irqs_enabled &= ~(1 << (irq - chip->irq_start)); | 88 | chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start)); |
| 89 | pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled); | 89 | pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled); |
| 90 | } | 90 | } |
| 91 | static void htcpld_unmask(unsigned int irq) | 91 | static void htcpld_unmask(struct irq_data *data) |
| 92 | { | 92 | { |
| 93 | struct htcpld_chip *chip = get_irq_chip_data(irq); | 93 | struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); |
| 94 | chip->irqs_enabled |= 1 << (irq - chip->irq_start); | 94 | chip->irqs_enabled |= 1 << (data->irq - chip->irq_start); |
| 95 | pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled); | 95 | pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static int htcpld_set_type(unsigned int irq, unsigned int flags) | 98 | static int htcpld_set_type(struct irq_data *data, unsigned int flags) |
| 99 | { | 99 | { |
| 100 | struct irq_desc *d = irq_to_desc(irq); | 100 | struct irq_desc *d = irq_to_desc(data->irq); |
| 101 | 101 | ||
| 102 | if (!d) { | 102 | if (!d) { |
| 103 | pr_err("HTCPLD invalid IRQ: %d\n", irq); | 103 | pr_err("HTCPLD invalid IRQ: %d\n", data->irq); |
| 104 | return -EINVAL; | 104 | return -EINVAL; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| @@ -118,10 +118,10 @@ static int htcpld_set_type(unsigned int irq, unsigned int flags) | |||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static struct irq_chip htcpld_muxed_chip = { | 120 | static struct irq_chip htcpld_muxed_chip = { |
| 121 | .name = "htcpld", | 121 | .name = "htcpld", |
| 122 | .mask = htcpld_mask, | 122 | .irq_mask = htcpld_mask, |
| 123 | .unmask = htcpld_unmask, | 123 | .irq_unmask = htcpld_unmask, |
| 124 | .set_type = htcpld_set_type, | 124 | .irq_set_type = htcpld_set_type, |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | /* To properly dispatch IRQ events, we need to read from the | 127 | /* To properly dispatch IRQ events, we need to read from the |
| @@ -235,7 +235,7 @@ static irqreturn_t htcpld_handler(int irq, void *dev) | |||
| 235 | * and that work is scheduled in the set routine. The kernel can then run | 235 | * and that work is scheduled in the set routine. The kernel can then run |
| 236 | * the I2C functions, which will sleep, in process context. | 236 | * the I2C functions, which will sleep, in process context. |
| 237 | */ | 237 | */ |
| 238 | void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) | 238 | static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) |
| 239 | { | 239 | { |
| 240 | struct i2c_client *client; | 240 | struct i2c_client *client; |
| 241 | struct htcpld_chip *chip_data; | 241 | struct htcpld_chip *chip_data; |
| @@ -259,7 +259,7 @@ void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) | |||
| 259 | schedule_work(&(chip_data->set_val_work)); | 259 | schedule_work(&(chip_data->set_val_work)); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | void htcpld_chip_set_ni(struct work_struct *work) | 262 | static void htcpld_chip_set_ni(struct work_struct *work) |
| 263 | { | 263 | { |
| 264 | struct htcpld_chip *chip_data; | 264 | struct htcpld_chip *chip_data; |
| 265 | struct i2c_client *client; | 265 | struct i2c_client *client; |
| @@ -269,7 +269,7 @@ void htcpld_chip_set_ni(struct work_struct *work) | |||
| 269 | i2c_smbus_read_byte_data(client, chip_data->cache_out); | 269 | i2c_smbus_read_byte_data(client, chip_data->cache_out); |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) | 272 | static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) |
| 273 | { | 273 | { |
| 274 | struct htcpld_chip *chip_data; | 274 | struct htcpld_chip *chip_data; |
| 275 | int val = 0; | 275 | int val = 0; |
| @@ -316,7 +316,7 @@ static int htcpld_direction_input(struct gpio_chip *chip, | |||
| 316 | return (offset < chip->ngpio) ? 0 : -EINVAL; | 316 | return (offset < chip->ngpio) ? 0 : -EINVAL; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) | 319 | static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) |
| 320 | { | 320 | { |
| 321 | struct htcpld_chip *chip_data; | 321 | struct htcpld_chip *chip_data; |
| 322 | 322 | ||
| @@ -328,7 +328,7 @@ int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 328 | return -EINVAL; | 328 | return -EINVAL; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | void htcpld_chip_reset(struct i2c_client *client) | 331 | static void htcpld_chip_reset(struct i2c_client *client) |
| 332 | { | 332 | { |
| 333 | struct htcpld_chip *chip_data = i2c_get_clientdata(client); | 333 | struct htcpld_chip *chip_data = i2c_get_clientdata(client); |
| 334 | if (!chip_data) | 334 | if (!chip_data) |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 9dd1b33f2275..0cc59795f600 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
| @@ -84,31 +84,30 @@ static inline void jz4740_adc_irq_set_masked(struct jz4740_adc *adc, int irq, | |||
| 84 | spin_unlock_irqrestore(&adc->lock, flags); | 84 | spin_unlock_irqrestore(&adc->lock, flags); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static void jz4740_adc_irq_mask(unsigned int irq) | 87 | static void jz4740_adc_irq_mask(struct irq_data *data) |
| 88 | { | 88 | { |
| 89 | struct jz4740_adc *adc = get_irq_chip_data(irq); | 89 | struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); |
| 90 | jz4740_adc_irq_set_masked(adc, irq, true); | 90 | jz4740_adc_irq_set_masked(adc, data->irq, true); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static void jz4740_adc_irq_unmask(unsigned int irq) | 93 | static void jz4740_adc_irq_unmask(struct irq_data *data) |
| 94 | { | 94 | { |
| 95 | struct jz4740_adc *adc = get_irq_chip_data(irq); | 95 | struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); |
| 96 | jz4740_adc_irq_set_masked(adc, irq, false); | 96 | jz4740_adc_irq_set_masked(adc, data->irq, false); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void jz4740_adc_irq_ack(unsigned int irq) | 99 | static void jz4740_adc_irq_ack(struct irq_data *data) |
| 100 | { | 100 | { |
| 101 | struct jz4740_adc *adc = get_irq_chip_data(irq); | 101 | struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); |
| 102 | 102 | unsigned int irq = data->irq - adc->irq_base; | |
| 103 | irq -= adc->irq_base; | ||
| 104 | writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS); | 103 | writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS); |
| 105 | } | 104 | } |
| 106 | 105 | ||
| 107 | static struct irq_chip jz4740_adc_irq_chip = { | 106 | static struct irq_chip jz4740_adc_irq_chip = { |
| 108 | .name = "jz4740-adc", | 107 | .name = "jz4740-adc", |
| 109 | .mask = jz4740_adc_irq_mask, | 108 | .irq_mask = jz4740_adc_irq_mask, |
| 110 | .unmask = jz4740_adc_irq_unmask, | 109 | .irq_unmask = jz4740_adc_irq_unmask, |
| 111 | .ack = jz4740_adc_irq_ack, | 110 | .irq_ack = jz4740_adc_irq_ack, |
| 112 | }; | 111 | }; |
| 113 | 112 | ||
| 114 | static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) | 113 | static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 44695f5a1800..0e998dc4e7d8 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
| @@ -407,16 +407,16 @@ static irqreturn_t max8925_tsc_irq(int irq, void *data) | |||
| 407 | return IRQ_HANDLED; | 407 | return IRQ_HANDLED; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | static void max8925_irq_lock(unsigned int irq) | 410 | static void max8925_irq_lock(struct irq_data *data) |
| 411 | { | 411 | { |
| 412 | struct max8925_chip *chip = get_irq_chip_data(irq); | 412 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 413 | 413 | ||
| 414 | mutex_lock(&chip->irq_lock); | 414 | mutex_lock(&chip->irq_lock); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | static void max8925_irq_sync_unlock(unsigned int irq) | 417 | static void max8925_irq_sync_unlock(struct irq_data *data) |
| 418 | { | 418 | { |
| 419 | struct max8925_chip *chip = get_irq_chip_data(irq); | 419 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 420 | struct max8925_irq_data *irq_data; | 420 | struct max8925_irq_data *irq_data; |
| 421 | static unsigned char cache_chg[2] = {0xff, 0xff}; | 421 | static unsigned char cache_chg[2] = {0xff, 0xff}; |
| 422 | static unsigned char cache_on[2] = {0xff, 0xff}; | 422 | static unsigned char cache_on[2] = {0xff, 0xff}; |
| @@ -492,25 +492,25 @@ static void max8925_irq_sync_unlock(unsigned int irq) | |||
| 492 | mutex_unlock(&chip->irq_lock); | 492 | mutex_unlock(&chip->irq_lock); |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | static void max8925_irq_enable(unsigned int irq) | 495 | static void max8925_irq_enable(struct irq_data *data) |
| 496 | { | 496 | { |
| 497 | struct max8925_chip *chip = get_irq_chip_data(irq); | 497 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 498 | max8925_irqs[irq - chip->irq_base].enable | 498 | max8925_irqs[data->irq - chip->irq_base].enable |
| 499 | = max8925_irqs[irq - chip->irq_base].offs; | 499 | = max8925_irqs[data->irq - chip->irq_base].offs; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | static void max8925_irq_disable(unsigned int irq) | 502 | static void max8925_irq_disable(struct irq_data *data) |
| 503 | { | 503 | { |
| 504 | struct max8925_chip *chip = get_irq_chip_data(irq); | 504 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 505 | max8925_irqs[irq - chip->irq_base].enable = 0; | 505 | max8925_irqs[data->irq - chip->irq_base].enable = 0; |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | static struct irq_chip max8925_irq_chip = { | 508 | static struct irq_chip max8925_irq_chip = { |
| 509 | .name = "max8925", | 509 | .name = "max8925", |
| 510 | .bus_lock = max8925_irq_lock, | 510 | .irq_bus_lock = max8925_irq_lock, |
| 511 | .bus_sync_unlock = max8925_irq_sync_unlock, | 511 | .irq_bus_sync_unlock = max8925_irq_sync_unlock, |
| 512 | .enable = max8925_irq_enable, | 512 | .irq_enable = max8925_irq_enable, |
| 513 | .disable = max8925_irq_disable, | 513 | .irq_disable = max8925_irq_disable, |
| 514 | }; | 514 | }; |
| 515 | 515 | ||
| 516 | static int max8925_irq_init(struct max8925_chip *chip, int irq, | 516 | static int max8925_irq_init(struct max8925_chip *chip, int irq, |
diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c index 45bfe77b639b..3903e1fbb334 100644 --- a/drivers/mfd/max8998-irq.c +++ b/drivers/mfd/max8998-irq.c | |||
| @@ -102,16 +102,16 @@ irq_to_max8998_irq(struct max8998_dev *max8998, int irq) | |||
| 102 | return &max8998_irqs[irq - max8998->irq_base]; | 102 | return &max8998_irqs[irq - max8998->irq_base]; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static void max8998_irq_lock(unsigned int irq) | 105 | static void max8998_irq_lock(struct irq_data *data) |
| 106 | { | 106 | { |
| 107 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 107 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 108 | 108 | ||
| 109 | mutex_lock(&max8998->irqlock); | 109 | mutex_lock(&max8998->irqlock); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static void max8998_irq_sync_unlock(unsigned int irq) | 112 | static void max8998_irq_sync_unlock(struct irq_data *data) |
| 113 | { | 113 | { |
| 114 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 114 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 115 | int i; | 115 | int i; |
| 116 | 116 | ||
| 117 | for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { | 117 | for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { |
| @@ -129,28 +129,30 @@ static void max8998_irq_sync_unlock(unsigned int irq) | |||
| 129 | mutex_unlock(&max8998->irqlock); | 129 | mutex_unlock(&max8998->irqlock); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static void max8998_irq_unmask(unsigned int irq) | 132 | static void max8998_irq_unmask(struct irq_data *data) |
| 133 | { | 133 | { |
| 134 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 134 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 135 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq); | 135 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, |
| 136 | data->irq); | ||
| 136 | 137 | ||
| 137 | max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 138 | max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 140 | static void max8998_irq_mask(unsigned int irq) | 141 | static void max8998_irq_mask(struct irq_data *data) |
| 141 | { | 142 | { |
| 142 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 143 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 143 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq); | 144 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, |
| 145 | data->irq); | ||
| 144 | 146 | ||
| 145 | max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 147 | max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | static struct irq_chip max8998_irq_chip = { | 150 | static struct irq_chip max8998_irq_chip = { |
| 149 | .name = "max8998", | 151 | .name = "max8998", |
| 150 | .bus_lock = max8998_irq_lock, | 152 | .irq_bus_lock = max8998_irq_lock, |
| 151 | .bus_sync_unlock = max8998_irq_sync_unlock, | 153 | .irq_bus_sync_unlock = max8998_irq_sync_unlock, |
| 152 | .mask = max8998_irq_mask, | 154 | .irq_mask = max8998_irq_mask, |
| 153 | .unmask = max8998_irq_unmask, | 155 | .irq_unmask = max8998_irq_unmask, |
| 154 | }; | 156 | }; |
| 155 | 157 | ||
| 156 | static irqreturn_t max8998_irq_thread(int irq, void *data) | 158 | static irqreturn_t max8998_irq_thread(int irq, void *data) |
| @@ -181,6 +183,13 @@ static irqreturn_t max8998_irq_thread(int irq, void *data) | |||
| 181 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
| 182 | } | 184 | } |
| 183 | 185 | ||
| 186 | int max8998_irq_resume(struct max8998_dev *max8998) | ||
| 187 | { | ||
| 188 | if (max8998->irq && max8998->irq_base) | ||
| 189 | max8998_irq_thread(max8998->irq_base, max8998); | ||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 184 | int max8998_irq_init(struct max8998_dev *max8998) | 193 | int max8998_irq_init(struct max8998_dev *max8998) |
| 185 | { | 194 | { |
| 186 | int i; | 195 | int i; |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index bb9977bebe78..bbfe86732602 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
| 28 | #include <linux/interrupt.h> | ||
| 29 | #include <linux/pm_runtime.h> | ||
| 28 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
| 29 | #include <linux/mfd/core.h> | 31 | #include <linux/mfd/core.h> |
| 30 | #include <linux/mfd/max8998.h> | 32 | #include <linux/mfd/max8998.h> |
| @@ -40,6 +42,14 @@ static struct mfd_cell max8998_devs[] = { | |||
| 40 | }, | 42 | }, |
| 41 | }; | 43 | }; |
| 42 | 44 | ||
| 45 | static struct mfd_cell lp3974_devs[] = { | ||
| 46 | { | ||
| 47 | .name = "lp3974-pmic", | ||
| 48 | }, { | ||
| 49 | .name = "lp3974-rtc", | ||
| 50 | }, | ||
| 51 | }; | ||
| 52 | |||
| 43 | int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) | 53 | int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) |
| 44 | { | 54 | { |
| 45 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | 55 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
| @@ -135,6 +145,7 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
| 135 | if (pdata) { | 145 | if (pdata) { |
| 136 | max8998->ono = pdata->ono; | 146 | max8998->ono = pdata->ono; |
| 137 | max8998->irq_base = pdata->irq_base; | 147 | max8998->irq_base = pdata->irq_base; |
| 148 | max8998->wakeup = pdata->wakeup; | ||
| 138 | } | 149 | } |
| 139 | mutex_init(&max8998->iolock); | 150 | mutex_init(&max8998->iolock); |
| 140 | 151 | ||
| @@ -143,9 +154,23 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
| 143 | 154 | ||
| 144 | max8998_irq_init(max8998); | 155 | max8998_irq_init(max8998); |
| 145 | 156 | ||
| 146 | ret = mfd_add_devices(max8998->dev, -1, | 157 | pm_runtime_set_active(max8998->dev); |
| 147 | max8998_devs, ARRAY_SIZE(max8998_devs), | 158 | |
| 148 | NULL, 0); | 159 | switch (id->driver_data) { |
| 160 | case TYPE_LP3974: | ||
| 161 | ret = mfd_add_devices(max8998->dev, -1, | ||
| 162 | lp3974_devs, ARRAY_SIZE(lp3974_devs), | ||
| 163 | NULL, 0); | ||
| 164 | break; | ||
| 165 | case TYPE_MAX8998: | ||
| 166 | ret = mfd_add_devices(max8998->dev, -1, | ||
| 167 | max8998_devs, ARRAY_SIZE(max8998_devs), | ||
| 168 | NULL, 0); | ||
| 169 | break; | ||
| 170 | default: | ||
| 171 | ret = -EINVAL; | ||
| 172 | } | ||
| 173 | |||
| 149 | if (ret < 0) | 174 | if (ret < 0) |
| 150 | goto err; | 175 | goto err; |
| 151 | 176 | ||
| @@ -178,10 +203,113 @@ static const struct i2c_device_id max8998_i2c_id[] = { | |||
| 178 | }; | 203 | }; |
| 179 | MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); | 204 | MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); |
| 180 | 205 | ||
| 206 | static int max8998_suspend(struct device *dev) | ||
| 207 | { | ||
| 208 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 209 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | ||
| 210 | |||
| 211 | if (max8998->wakeup) | ||
| 212 | set_irq_wake(max8998->irq, 1); | ||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int max8998_resume(struct device *dev) | ||
| 217 | { | ||
| 218 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 219 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | ||
| 220 | |||
| 221 | if (max8998->wakeup) | ||
| 222 | set_irq_wake(max8998->irq, 0); | ||
| 223 | /* | ||
| 224 | * In LP3974, if IRQ registers are not "read & clear" | ||
| 225 | * when it's set during sleep, the interrupt becomes | ||
| 226 | * disabled. | ||
| 227 | */ | ||
| 228 | return max8998_irq_resume(i2c_get_clientdata(i2c)); | ||
| 229 | } | ||
| 230 | |||
| 231 | struct max8998_reg_dump { | ||
| 232 | u8 addr; | ||
| 233 | u8 val; | ||
| 234 | }; | ||
| 235 | #define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } | ||
| 236 | struct max8998_reg_dump max8998_dump[] = { | ||
| 237 | SAVE_ITEM(MAX8998_REG_IRQM1), | ||
| 238 | SAVE_ITEM(MAX8998_REG_IRQM2), | ||
| 239 | SAVE_ITEM(MAX8998_REG_IRQM3), | ||
| 240 | SAVE_ITEM(MAX8998_REG_IRQM4), | ||
| 241 | SAVE_ITEM(MAX8998_REG_STATUSM1), | ||
| 242 | SAVE_ITEM(MAX8998_REG_STATUSM2), | ||
| 243 | SAVE_ITEM(MAX8998_REG_CHGR1), | ||
| 244 | SAVE_ITEM(MAX8998_REG_CHGR2), | ||
| 245 | SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), | ||
| 246 | SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), | ||
| 247 | SAVE_ITEM(MAX8998_REG_BUCK_ACTIVE_DISCHARGE3), | ||
| 248 | SAVE_ITEM(MAX8998_REG_ONOFF1), | ||
| 249 | SAVE_ITEM(MAX8998_REG_ONOFF2), | ||
| 250 | SAVE_ITEM(MAX8998_REG_ONOFF3), | ||
| 251 | SAVE_ITEM(MAX8998_REG_ONOFF4), | ||
| 252 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE1), | ||
| 253 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE2), | ||
| 254 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE3), | ||
| 255 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE4), | ||
| 256 | SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE1), | ||
| 257 | SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE2), | ||
| 258 | SAVE_ITEM(MAX8998_REG_LDO2_LDO3), | ||
| 259 | SAVE_ITEM(MAX8998_REG_LDO4), | ||
| 260 | SAVE_ITEM(MAX8998_REG_LDO5), | ||
| 261 | SAVE_ITEM(MAX8998_REG_LDO6), | ||
| 262 | SAVE_ITEM(MAX8998_REG_LDO7), | ||
| 263 | SAVE_ITEM(MAX8998_REG_LDO8_LDO9), | ||
| 264 | SAVE_ITEM(MAX8998_REG_LDO10_LDO11), | ||
| 265 | SAVE_ITEM(MAX8998_REG_LDO12), | ||
| 266 | SAVE_ITEM(MAX8998_REG_LDO13), | ||
| 267 | SAVE_ITEM(MAX8998_REG_LDO14), | ||
| 268 | SAVE_ITEM(MAX8998_REG_LDO15), | ||
| 269 | SAVE_ITEM(MAX8998_REG_LDO16), | ||
| 270 | SAVE_ITEM(MAX8998_REG_LDO17), | ||
| 271 | SAVE_ITEM(MAX8998_REG_BKCHR), | ||
| 272 | SAVE_ITEM(MAX8998_REG_LBCNFG1), | ||
| 273 | SAVE_ITEM(MAX8998_REG_LBCNFG2), | ||
| 274 | }; | ||
| 275 | /* Save registers before hibernation */ | ||
| 276 | static int max8998_freeze(struct device *dev) | ||
| 277 | { | ||
| 278 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 279 | int i; | ||
| 280 | |||
| 281 | for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) | ||
| 282 | max8998_read_reg(i2c, max8998_dump[i].addr, | ||
| 283 | &max8998_dump[i].val); | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Restore registers after hibernation */ | ||
| 289 | static int max8998_restore(struct device *dev) | ||
| 290 | { | ||
| 291 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 292 | int i; | ||
| 293 | |||
| 294 | for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) | ||
| 295 | max8998_write_reg(i2c, max8998_dump[i].addr, | ||
| 296 | max8998_dump[i].val); | ||
| 297 | |||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | const struct dev_pm_ops max8998_pm = { | ||
| 302 | .suspend = max8998_suspend, | ||
| 303 | .resume = max8998_resume, | ||
| 304 | .freeze = max8998_freeze, | ||
| 305 | .restore = max8998_restore, | ||
| 306 | }; | ||
| 307 | |||
| 181 | static struct i2c_driver max8998_i2c_driver = { | 308 | static struct i2c_driver max8998_i2c_driver = { |
| 182 | .driver = { | 309 | .driver = { |
| 183 | .name = "max8998", | 310 | .name = "max8998", |
| 184 | .owner = THIS_MODULE, | 311 | .owner = THIS_MODULE, |
| 312 | .pm = &max8998_pm, | ||
| 185 | }, | 313 | }, |
| 186 | .probe = max8998_i2c_probe, | 314 | .probe = max8998_i2c_probe, |
| 187 | .remove = max8998_i2c_remove, | 315 | .remove = max8998_i2c_remove, |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index a2ac2ed6d64c..b9fcaf0004da 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
| @@ -749,7 +749,7 @@ static int mc13xxx_probe(struct spi_device *spi) | |||
| 749 | if (ret) { | 749 | if (ret) { |
| 750 | err_mask: | 750 | err_mask: |
| 751 | err_revision: | 751 | err_revision: |
| 752 | mutex_unlock(&mc13xxx->lock); | 752 | mc13xxx_unlock(mc13xxx); |
| 753 | dev_set_drvdata(&spi->dev, NULL); | 753 | dev_set_drvdata(&spi->dev, NULL); |
| 754 | kfree(mc13xxx); | 754 | kfree(mc13xxx); |
| 755 | return ret; | 755 | return ret; |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index ec99f681e773..d83ad0f141af 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
| 17 | #include <linux/mfd/core.h> | 17 | #include <linux/mfd/core.h> |
| 18 | #include <linux/pm_runtime.h> | ||
| 18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 19 | 20 | ||
| 20 | static int mfd_add_device(struct device *parent, int id, | 21 | static int mfd_add_device(struct device *parent, int id, |
| @@ -82,6 +83,9 @@ static int mfd_add_device(struct device *parent, int id, | |||
| 82 | if (ret) | 83 | if (ret) |
| 83 | goto fail_res; | 84 | goto fail_res; |
| 84 | 85 | ||
| 86 | if (cell->pm_runtime_no_callbacks) | ||
| 87 | pm_runtime_no_callbacks(&pdev->dev); | ||
| 88 | |||
| 85 | kfree(res); | 89 | kfree(res); |
| 86 | 90 | ||
| 87 | return 0; | 91 | return 0; |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index bc9275c12133..5de3a760ea1e 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/sm501-regs.h> | 26 | #include <linux/sm501-regs.h> |
| 27 | #include <linux/serial_8250.h> | 27 | #include <linux/serial_8250.h> |
| 28 | 28 | ||
| 29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
| 30 | 30 | ||
| 31 | struct sm501_device { | 31 | struct sm501_device { |
| 32 | struct list_head list; | 32 | struct list_head list; |
| @@ -745,11 +745,8 @@ static int sm501_register_device(struct sm501_devdata *sm, | |||
| 745 | int ret; | 745 | int ret; |
| 746 | 746 | ||
| 747 | for (ptr = 0; ptr < pdev->num_resources; ptr++) { | 747 | for (ptr = 0; ptr < pdev->num_resources; ptr++) { |
| 748 | printk(KERN_DEBUG "%s[%d] flags %08lx: %08llx..%08llx\n", | 748 | printk(KERN_DEBUG "%s[%d] %pR\n", |
| 749 | pdev->name, ptr, | 749 | pdev->name, ptr, &pdev->resource[ptr]); |
| 750 | pdev->resource[ptr].flags, | ||
| 751 | (unsigned long long)pdev->resource[ptr].start, | ||
| 752 | (unsigned long long)pdev->resource[ptr].end); | ||
| 753 | } | 750 | } |
| 754 | 751 | ||
| 755 | ret = platform_device_register(pdev); | 752 | ret = platform_device_register(pdev); |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index b11487f1e1cb..3e5732b58c49 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
| @@ -699,16 +699,16 @@ static irqreturn_t stmpe_irq(int irq, void *data) | |||
| 699 | return IRQ_HANDLED; | 699 | return IRQ_HANDLED; |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | static void stmpe_irq_lock(unsigned int irq) | 702 | static void stmpe_irq_lock(struct irq_data *data) |
| 703 | { | 703 | { |
| 704 | struct stmpe *stmpe = get_irq_chip_data(irq); | 704 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 705 | 705 | ||
| 706 | mutex_lock(&stmpe->irq_lock); | 706 | mutex_lock(&stmpe->irq_lock); |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | static void stmpe_irq_sync_unlock(unsigned int irq) | 709 | static void stmpe_irq_sync_unlock(struct irq_data *data) |
| 710 | { | 710 | { |
| 711 | struct stmpe *stmpe = get_irq_chip_data(irq); | 711 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 712 | struct stmpe_variant_info *variant = stmpe->variant; | 712 | struct stmpe_variant_info *variant = stmpe->variant; |
| 713 | int num = DIV_ROUND_UP(variant->num_irqs, 8); | 713 | int num = DIV_ROUND_UP(variant->num_irqs, 8); |
| 714 | int i; | 714 | int i; |
| @@ -727,20 +727,20 @@ static void stmpe_irq_sync_unlock(unsigned int irq) | |||
| 727 | mutex_unlock(&stmpe->irq_lock); | 727 | mutex_unlock(&stmpe->irq_lock); |
| 728 | } | 728 | } |
| 729 | 729 | ||
| 730 | static void stmpe_irq_mask(unsigned int irq) | 730 | static void stmpe_irq_mask(struct irq_data *data) |
| 731 | { | 731 | { |
| 732 | struct stmpe *stmpe = get_irq_chip_data(irq); | 732 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 733 | int offset = irq - stmpe->irq_base; | 733 | int offset = data->irq - stmpe->irq_base; |
| 734 | int regoffset = offset / 8; | 734 | int regoffset = offset / 8; |
| 735 | int mask = 1 << (offset % 8); | 735 | int mask = 1 << (offset % 8); |
| 736 | 736 | ||
| 737 | stmpe->ier[regoffset] &= ~mask; | 737 | stmpe->ier[regoffset] &= ~mask; |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | static void stmpe_irq_unmask(unsigned int irq) | 740 | static void stmpe_irq_unmask(struct irq_data *data) |
| 741 | { | 741 | { |
| 742 | struct stmpe *stmpe = get_irq_chip_data(irq); | 742 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 743 | int offset = irq - stmpe->irq_base; | 743 | int offset = data->irq - stmpe->irq_base; |
| 744 | int regoffset = offset / 8; | 744 | int regoffset = offset / 8; |
| 745 | int mask = 1 << (offset % 8); | 745 | int mask = 1 << (offset % 8); |
| 746 | 746 | ||
| @@ -749,10 +749,10 @@ static void stmpe_irq_unmask(unsigned int irq) | |||
| 749 | 749 | ||
| 750 | static struct irq_chip stmpe_irq_chip = { | 750 | static struct irq_chip stmpe_irq_chip = { |
| 751 | .name = "stmpe", | 751 | .name = "stmpe", |
| 752 | .bus_lock = stmpe_irq_lock, | 752 | .irq_bus_lock = stmpe_irq_lock, |
| 753 | .bus_sync_unlock = stmpe_irq_sync_unlock, | 753 | .irq_bus_sync_unlock = stmpe_irq_sync_unlock, |
| 754 | .mask = stmpe_irq_mask, | 754 | .irq_mask = stmpe_irq_mask, |
| 755 | .unmask = stmpe_irq_unmask, | 755 | .irq_unmask = stmpe_irq_unmask, |
| 756 | }; | 756 | }; |
| 757 | 757 | ||
| 758 | static int __devinit stmpe_irq_init(struct stmpe *stmpe) | 758 | static int __devinit stmpe_irq_init(struct stmpe *stmpe) |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 006c121f3f0d..9caeb4ac6ea6 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
| @@ -199,37 +199,37 @@ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) | |||
| 199 | generic_handle_irq(irq_base + i); | 199 | generic_handle_irq(irq_base + i); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static void t7l66xb_irq_mask(unsigned int irq) | 202 | static void t7l66xb_irq_mask(struct irq_data *data) |
| 203 | { | 203 | { |
| 204 | struct t7l66xb *t7l66xb = get_irq_chip_data(irq); | 204 | struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); |
| 205 | unsigned long flags; | 205 | unsigned long flags; |
| 206 | u8 imr; | 206 | u8 imr; |
| 207 | 207 | ||
| 208 | spin_lock_irqsave(&t7l66xb->lock, flags); | 208 | spin_lock_irqsave(&t7l66xb->lock, flags); |
| 209 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); | 209 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); |
| 210 | imr |= 1 << (irq - t7l66xb->irq_base); | 210 | imr |= 1 << (data->irq - t7l66xb->irq_base); |
| 211 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); | 211 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); |
| 212 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 212 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | static void t7l66xb_irq_unmask(unsigned int irq) | 215 | static void t7l66xb_irq_unmask(struct irq_data *data) |
| 216 | { | 216 | { |
| 217 | struct t7l66xb *t7l66xb = get_irq_chip_data(irq); | 217 | struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); |
| 218 | unsigned long flags; | 218 | unsigned long flags; |
| 219 | u8 imr; | 219 | u8 imr; |
| 220 | 220 | ||
| 221 | spin_lock_irqsave(&t7l66xb->lock, flags); | 221 | spin_lock_irqsave(&t7l66xb->lock, flags); |
| 222 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); | 222 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); |
| 223 | imr &= ~(1 << (irq - t7l66xb->irq_base)); | 223 | imr &= ~(1 << (data->irq - t7l66xb->irq_base)); |
| 224 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); | 224 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); |
| 225 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 225 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | static struct irq_chip t7l66xb_chip = { | 228 | static struct irq_chip t7l66xb_chip = { |
| 229 | .name = "t7l66xb", | 229 | .name = "t7l66xb", |
| 230 | .ack = t7l66xb_irq_mask, | 230 | .irq_ack = t7l66xb_irq_mask, |
| 231 | .mask = t7l66xb_irq_mask, | 231 | .irq_mask = t7l66xb_irq_mask, |
| 232 | .unmask = t7l66xb_irq_unmask, | 232 | .irq_unmask = t7l66xb_irq_unmask, |
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| 235 | /*--------------------------------------------------------------------------*/ | 235 | /*--------------------------------------------------------------------------*/ |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 1ea80d8ad915..9a238633a54d 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
| @@ -527,41 +527,41 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc) | |||
| 527 | } | 527 | } |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | static void tc6393xb_irq_ack(unsigned int irq) | 530 | static void tc6393xb_irq_ack(struct irq_data *data) |
| 531 | { | 531 | { |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | static void tc6393xb_irq_mask(unsigned int irq) | 534 | static void tc6393xb_irq_mask(struct irq_data *data) |
| 535 | { | 535 | { |
| 536 | struct tc6393xb *tc6393xb = get_irq_chip_data(irq); | 536 | struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); |
| 537 | unsigned long flags; | 537 | unsigned long flags; |
| 538 | u8 imr; | 538 | u8 imr; |
| 539 | 539 | ||
| 540 | spin_lock_irqsave(&tc6393xb->lock, flags); | 540 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 541 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); | 541 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 542 | imr |= 1 << (irq - tc6393xb->irq_base); | 542 | imr |= 1 << (data->irq - tc6393xb->irq_base); |
| 543 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); | 543 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 544 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 544 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | static void tc6393xb_irq_unmask(unsigned int irq) | 547 | static void tc6393xb_irq_unmask(struct irq_data *data) |
| 548 | { | 548 | { |
| 549 | struct tc6393xb *tc6393xb = get_irq_chip_data(irq); | 549 | struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); |
| 550 | unsigned long flags; | 550 | unsigned long flags; |
| 551 | u8 imr; | 551 | u8 imr; |
| 552 | 552 | ||
| 553 | spin_lock_irqsave(&tc6393xb->lock, flags); | 553 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 554 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); | 554 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 555 | imr &= ~(1 << (irq - tc6393xb->irq_base)); | 555 | imr &= ~(1 << (data->irq - tc6393xb->irq_base)); |
| 556 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); | 556 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 557 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 557 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | static struct irq_chip tc6393xb_chip = { | 560 | static struct irq_chip tc6393xb_chip = { |
| 561 | .name = "tc6393xb", | 561 | .name = "tc6393xb", |
| 562 | .ack = tc6393xb_irq_ack, | 562 | .irq_ack = tc6393xb_irq_ack, |
| 563 | .mask = tc6393xb_irq_mask, | 563 | .irq_mask = tc6393xb_irq_mask, |
| 564 | .unmask = tc6393xb_irq_unmask, | 564 | .irq_unmask = tc6393xb_irq_unmask, |
| 565 | }; | 565 | }; |
| 566 | 566 | ||
| 567 | static void tc6393xb_attach_irq(struct platform_device *dev) | 567 | static void tc6393xb_attach_irq(struct platform_device *dev) |
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index 90187fe33e04..93d5fdf020c7 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include <linux/i2c/tps65010.h> | 35 | #include <linux/i2c/tps65010.h> |
| 36 | 36 | ||
| 37 | #include <asm/gpio.h> | 37 | #include <linux/gpio.h> |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /*-------------------------------------------------------------------------*/ | 40 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index b4931ab34929..627cf577b16d 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
| @@ -46,8 +46,6 @@ | |||
| 46 | 46 | ||
| 47 | /* device id */ | 47 | /* device id */ |
| 48 | #define TPS6586X_VERSIONCRC 0xcd | 48 | #define TPS6586X_VERSIONCRC 0xcd |
| 49 | #define TPS658621A_VERSIONCRC 0x15 | ||
| 50 | #define TPS658621C_VERSIONCRC 0x2c | ||
| 51 | 49 | ||
| 52 | struct tps6586x_irq_data { | 50 | struct tps6586x_irq_data { |
| 53 | u8 mask_reg; | 51 | u8 mask_reg; |
| @@ -325,37 +323,37 @@ static int tps6586x_remove_subdevs(struct tps6586x *tps6586x) | |||
| 325 | return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); | 323 | return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); |
| 326 | } | 324 | } |
| 327 | 325 | ||
| 328 | static void tps6586x_irq_lock(unsigned int irq) | 326 | static void tps6586x_irq_lock(struct irq_data *data) |
| 329 | { | 327 | { |
| 330 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 328 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); |
| 331 | 329 | ||
| 332 | mutex_lock(&tps6586x->irq_lock); | 330 | mutex_lock(&tps6586x->irq_lock); |
| 333 | } | 331 | } |
| 334 | 332 | ||
| 335 | static void tps6586x_irq_enable(unsigned int irq) | 333 | static void tps6586x_irq_enable(struct irq_data *irq_data) |
| 336 | { | 334 | { |
| 337 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 335 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); |
| 338 | unsigned int __irq = irq - tps6586x->irq_base; | 336 | unsigned int __irq = irq_data->irq - tps6586x->irq_base; |
| 339 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; | 337 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; |
| 340 | 338 | ||
| 341 | tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; | 339 | tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; |
| 342 | tps6586x->irq_en |= (1 << __irq); | 340 | tps6586x->irq_en |= (1 << __irq); |
| 343 | } | 341 | } |
| 344 | 342 | ||
| 345 | static void tps6586x_irq_disable(unsigned int irq) | 343 | static void tps6586x_irq_disable(struct irq_data *irq_data) |
| 346 | { | 344 | { |
| 347 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 345 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); |
| 348 | 346 | ||
| 349 | unsigned int __irq = irq - tps6586x->irq_base; | 347 | unsigned int __irq = irq_data->irq - tps6586x->irq_base; |
| 350 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; | 348 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; |
| 351 | 349 | ||
| 352 | tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; | 350 | tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; |
| 353 | tps6586x->irq_en &= ~(1 << __irq); | 351 | tps6586x->irq_en &= ~(1 << __irq); |
| 354 | } | 352 | } |
| 355 | 353 | ||
| 356 | static void tps6586x_irq_sync_unlock(unsigned int irq) | 354 | static void tps6586x_irq_sync_unlock(struct irq_data *data) |
| 357 | { | 355 | { |
| 358 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 356 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); |
| 359 | int i; | 357 | int i; |
| 360 | 358 | ||
| 361 | for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { | 359 | for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { |
| @@ -421,10 +419,10 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, | |||
| 421 | tps6586x->irq_base = irq_base; | 419 | tps6586x->irq_base = irq_base; |
| 422 | 420 | ||
| 423 | tps6586x->irq_chip.name = "tps6586x"; | 421 | tps6586x->irq_chip.name = "tps6586x"; |
| 424 | tps6586x->irq_chip.enable = tps6586x_irq_enable; | 422 | tps6586x->irq_chip.irq_enable = tps6586x_irq_enable; |
| 425 | tps6586x->irq_chip.disable = tps6586x_irq_disable; | 423 | tps6586x->irq_chip.irq_disable = tps6586x_irq_disable; |
| 426 | tps6586x->irq_chip.bus_lock = tps6586x_irq_lock; | 424 | tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock; |
| 427 | tps6586x->irq_chip.bus_sync_unlock = tps6586x_irq_sync_unlock; | 425 | tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock; |
| 428 | 426 | ||
| 429 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { | 427 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { |
| 430 | int __irq = i + tps6586x->irq_base; | 428 | int __irq = i + tps6586x->irq_base; |
| @@ -498,11 +496,7 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
| 498 | return -EIO; | 496 | return -EIO; |
| 499 | } | 497 | } |
| 500 | 498 | ||
| 501 | if ((ret != TPS658621A_VERSIONCRC) && | 499 | dev_info(&client->dev, "VERSIONCRC is %02x\n", ret); |
| 502 | (ret != TPS658621C_VERSIONCRC)) { | ||
| 503 | dev_err(&client->dev, "Unsupported chip ID: %x\n", ret); | ||
| 504 | return -ENODEV; | ||
| 505 | } | ||
| 506 | 500 | ||
| 507 | tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); | 501 | tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); |
| 508 | if (tps6586x == NULL) | 502 | if (tps6586x == NULL) |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 12abd5b924b3..a35fa7dcbf53 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
| @@ -1003,7 +1003,7 @@ static int twl_remove(struct i2c_client *client) | |||
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ | 1005 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ |
| 1006 | static int __init | 1006 | static int __devinit |
| 1007 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1007 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) |
| 1008 | { | 1008 | { |
| 1009 | int status; | 1009 | int status; |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 5d3a1478004b..63a30e88908f 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
| @@ -599,38 +599,38 @@ static void twl4030_sih_do_edge(struct work_struct *work) | |||
| 599 | * completion, potentially including some re-ordering, of these requests. | 599 | * completion, potentially including some re-ordering, of these requests. |
| 600 | */ | 600 | */ |
| 601 | 601 | ||
| 602 | static void twl4030_sih_mask(unsigned irq) | 602 | static void twl4030_sih_mask(struct irq_data *data) |
| 603 | { | 603 | { |
| 604 | struct sih_agent *sih = get_irq_chip_data(irq); | 604 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
| 605 | unsigned long flags; | 605 | unsigned long flags; |
| 606 | 606 | ||
| 607 | spin_lock_irqsave(&sih_agent_lock, flags); | 607 | spin_lock_irqsave(&sih_agent_lock, flags); |
| 608 | sih->imr |= BIT(irq - sih->irq_base); | 608 | sih->imr |= BIT(data->irq - sih->irq_base); |
| 609 | sih->imr_change_pending = true; | 609 | sih->imr_change_pending = true; |
| 610 | queue_work(wq, &sih->mask_work); | 610 | queue_work(wq, &sih->mask_work); |
| 611 | spin_unlock_irqrestore(&sih_agent_lock, flags); | 611 | spin_unlock_irqrestore(&sih_agent_lock, flags); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | static void twl4030_sih_unmask(unsigned irq) | 614 | static void twl4030_sih_unmask(struct irq_data *data) |
| 615 | { | 615 | { |
| 616 | struct sih_agent *sih = get_irq_chip_data(irq); | 616 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
| 617 | unsigned long flags; | 617 | unsigned long flags; |
| 618 | 618 | ||
| 619 | spin_lock_irqsave(&sih_agent_lock, flags); | 619 | spin_lock_irqsave(&sih_agent_lock, flags); |
| 620 | sih->imr &= ~BIT(irq - sih->irq_base); | 620 | sih->imr &= ~BIT(data->irq - sih->irq_base); |
| 621 | sih->imr_change_pending = true; | 621 | sih->imr_change_pending = true; |
| 622 | queue_work(wq, &sih->mask_work); | 622 | queue_work(wq, &sih->mask_work); |
| 623 | spin_unlock_irqrestore(&sih_agent_lock, flags); | 623 | spin_unlock_irqrestore(&sih_agent_lock, flags); |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | static int twl4030_sih_set_type(unsigned irq, unsigned trigger) | 626 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) |
| 627 | { | 627 | { |
| 628 | struct sih_agent *sih = get_irq_chip_data(irq); | 628 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
| 629 | struct irq_desc *desc = irq_to_desc(irq); | 629 | struct irq_desc *desc = irq_to_desc(data->irq); |
| 630 | unsigned long flags; | 630 | unsigned long flags; |
| 631 | 631 | ||
| 632 | if (!desc) { | 632 | if (!desc) { |
| 633 | pr_err("twl4030: Invalid IRQ: %d\n", irq); | 633 | pr_err("twl4030: Invalid IRQ: %d\n", data->irq); |
| 634 | return -EINVAL; | 634 | return -EINVAL; |
| 635 | } | 635 | } |
| 636 | 636 | ||
| @@ -641,7 +641,7 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) | |||
| 641 | if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { | 641 | if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { |
| 642 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | 642 | desc->status &= ~IRQ_TYPE_SENSE_MASK; |
| 643 | desc->status |= trigger; | 643 | desc->status |= trigger; |
| 644 | sih->edge_change |= BIT(irq - sih->irq_base); | 644 | sih->edge_change |= BIT(data->irq - sih->irq_base); |
| 645 | queue_work(wq, &sih->edge_work); | 645 | queue_work(wq, &sih->edge_work); |
| 646 | } | 646 | } |
| 647 | spin_unlock_irqrestore(&sih_agent_lock, flags); | 647 | spin_unlock_irqrestore(&sih_agent_lock, flags); |
| @@ -650,9 +650,9 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) | |||
| 650 | 650 | ||
| 651 | static struct irq_chip twl4030_sih_irq_chip = { | 651 | static struct irq_chip twl4030_sih_irq_chip = { |
| 652 | .name = "twl4030", | 652 | .name = "twl4030", |
| 653 | .mask = twl4030_sih_mask, | 653 | .irq_mask = twl4030_sih_mask, |
| 654 | .unmask = twl4030_sih_unmask, | 654 | .irq_unmask = twl4030_sih_unmask, |
| 655 | .set_type = twl4030_sih_set_type, | 655 | .irq_set_type = twl4030_sih_set_type, |
| 656 | }; | 656 | }; |
| 657 | 657 | ||
| 658 | /*----------------------------------------------------------------------*/ | 658 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 06c8955907e9..4082ed73613f 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
| @@ -332,7 +332,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
| 332 | */ | 332 | */ |
| 333 | twl6030_irq_chip = dummy_irq_chip; | 333 | twl6030_irq_chip = dummy_irq_chip; |
| 334 | twl6030_irq_chip.name = "twl6030"; | 334 | twl6030_irq_chip.name = "twl6030"; |
| 335 | twl6030_irq_chip.set_type = NULL; | 335 | twl6030_irq_chip.irq_set_type = NULL; |
| 336 | 336 | ||
| 337 | for (i = irq_base; i < irq_end; i++) { | 337 | for (i = irq_base; i < irq_end; i++) { |
| 338 | set_irq_chip_and_handler(i, &twl6030_irq_chip, | 338 | set_irq_chip_and_handler(i, &twl6030_irq_chip, |
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index ebb059765edd..348052aa5dbf 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
| @@ -112,7 +112,7 @@ out: | |||
| 112 | return ret; | 112 | return ret; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static void vx855_remove(struct pci_dev *pdev) | 115 | static void __devexit vx855_remove(struct pci_dev *pdev) |
| 116 | { | 116 | { |
| 117 | mfd_remove_devices(&pdev->dev); | 117 | mfd_remove_devices(&pdev->dev); |
| 118 | pci_disable_device(pdev); | 118 | pci_disable_device(pdev); |
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 76cadcf3b1fe..3fe9a58fe6c7 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
| @@ -1541,6 +1541,12 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
| 1541 | dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); | 1541 | dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); |
| 1542 | break; | 1542 | break; |
| 1543 | 1543 | ||
| 1544 | case WM8326: | ||
| 1545 | parent = WM8326; | ||
| 1546 | wm831x->num_gpio = 12; | ||
| 1547 | dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev); | ||
| 1548 | break; | ||
| 1549 | |||
| 1544 | default: | 1550 | default: |
| 1545 | dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); | 1551 | dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); |
| 1546 | ret = -EINVAL; | 1552 | ret = -EINVAL; |
| @@ -1610,18 +1616,9 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
| 1610 | break; | 1616 | break; |
| 1611 | 1617 | ||
| 1612 | case WM8320: | 1618 | case WM8320: |
| 1613 | ret = mfd_add_devices(wm831x->dev, -1, | ||
| 1614 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | ||
| 1615 | NULL, 0); | ||
| 1616 | break; | ||
| 1617 | |||
| 1618 | case WM8321: | 1619 | case WM8321: |
| 1619 | ret = mfd_add_devices(wm831x->dev, -1, | ||
| 1620 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | ||
| 1621 | NULL, 0); | ||
| 1622 | break; | ||
| 1623 | |||
| 1624 | case WM8325: | 1620 | case WM8325: |
| 1621 | case WM8326: | ||
| 1625 | ret = mfd_add_devices(wm831x->dev, -1, | 1622 | ret = mfd_add_devices(wm831x->dev, -1, |
| 1626 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1623 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
| 1627 | NULL, wm831x->irq_base); | 1624 | NULL, wm831x->irq_base); |
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 156b19859e81..3853fa8e7cc2 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c | |||
| @@ -94,9 +94,9 @@ static int wm831x_i2c_remove(struct i2c_client *i2c) | |||
| 94 | return 0; | 94 | return 0; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) | 97 | static int wm831x_i2c_suspend(struct device *dev) |
| 98 | { | 98 | { |
| 99 | struct wm831x *wm831x = i2c_get_clientdata(i2c); | 99 | struct wm831x *wm831x = dev_get_drvdata(dev); |
| 100 | 100 | ||
| 101 | return wm831x_device_suspend(wm831x); | 101 | return wm831x_device_suspend(wm831x); |
| 102 | } | 102 | } |
| @@ -108,19 +108,23 @@ static const struct i2c_device_id wm831x_i2c_id[] = { | |||
| 108 | { "wm8320", WM8320 }, | 108 | { "wm8320", WM8320 }, |
| 109 | { "wm8321", WM8321 }, | 109 | { "wm8321", WM8321 }, |
| 110 | { "wm8325", WM8325 }, | 110 | { "wm8325", WM8325 }, |
| 111 | { "wm8326", WM8326 }, | ||
| 111 | { } | 112 | { } |
| 112 | }; | 113 | }; |
| 113 | MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); | 114 | MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); |
| 114 | 115 | ||
| 116 | static const struct dev_pm_ops wm831x_pm_ops = { | ||
| 117 | .suspend = wm831x_i2c_suspend, | ||
| 118 | }; | ||
| 115 | 119 | ||
| 116 | static struct i2c_driver wm831x_i2c_driver = { | 120 | static struct i2c_driver wm831x_i2c_driver = { |
| 117 | .driver = { | 121 | .driver = { |
| 118 | .name = "wm831x", | 122 | .name = "wm831x", |
| 119 | .owner = THIS_MODULE, | 123 | .owner = THIS_MODULE, |
| 124 | .pm = &wm831x_pm_ops, | ||
| 120 | }, | 125 | }, |
| 121 | .probe = wm831x_i2c_probe, | 126 | .probe = wm831x_i2c_probe, |
| 122 | .remove = wm831x_i2c_remove, | 127 | .remove = wm831x_i2c_remove, |
| 123 | .suspend = wm831x_i2c_suspend, | ||
| 124 | .id_table = wm831x_i2c_id, | 128 | .id_table = wm831x_i2c_id, |
| 125 | }; | 129 | }; |
| 126 | 130 | ||
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 294183b6260b..f7192d438aab 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
| @@ -345,16 +345,16 @@ static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, | |||
| 345 | return &wm831x_irqs[irq - wm831x->irq_base]; | 345 | return &wm831x_irqs[irq - wm831x->irq_base]; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static void wm831x_irq_lock(unsigned int irq) | 348 | static void wm831x_irq_lock(struct irq_data *data) |
| 349 | { | 349 | { |
| 350 | struct wm831x *wm831x = get_irq_chip_data(irq); | 350 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 351 | 351 | ||
| 352 | mutex_lock(&wm831x->irq_lock); | 352 | mutex_lock(&wm831x->irq_lock); |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | static void wm831x_irq_sync_unlock(unsigned int irq) | 355 | static void wm831x_irq_sync_unlock(struct irq_data *data) |
| 356 | { | 356 | { |
| 357 | struct wm831x *wm831x = get_irq_chip_data(irq); | 357 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 358 | int i; | 358 | int i; |
| 359 | 359 | ||
| 360 | for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { | 360 | for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { |
| @@ -371,28 +371,30 @@ static void wm831x_irq_sync_unlock(unsigned int irq) | |||
| 371 | mutex_unlock(&wm831x->irq_lock); | 371 | mutex_unlock(&wm831x->irq_lock); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | static void wm831x_irq_unmask(unsigned int irq) | 374 | static void wm831x_irq_unmask(struct irq_data *data) |
| 375 | { | 375 | { |
| 376 | struct wm831x *wm831x = get_irq_chip_data(irq); | 376 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 377 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); | 377 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, |
| 378 | data->irq); | ||
| 378 | 379 | ||
| 379 | wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 380 | wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
| 380 | } | 381 | } |
| 381 | 382 | ||
| 382 | static void wm831x_irq_mask(unsigned int irq) | 383 | static void wm831x_irq_mask(struct irq_data *data) |
| 383 | { | 384 | { |
| 384 | struct wm831x *wm831x = get_irq_chip_data(irq); | 385 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 385 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); | 386 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, |
| 387 | data->irq); | ||
| 386 | 388 | ||
| 387 | wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 389 | wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
| 388 | } | 390 | } |
| 389 | 391 | ||
| 390 | static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | 392 | static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) |
| 391 | { | 393 | { |
| 392 | struct wm831x *wm831x = get_irq_chip_data(irq); | 394 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 393 | int val; | 395 | int val, irq; |
| 394 | 396 | ||
| 395 | irq = irq - wm831x->irq_base; | 397 | irq = data->irq - wm831x->irq_base; |
| 396 | 398 | ||
| 397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { | 399 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { |
| 398 | /* Ignore internal-only IRQs */ | 400 | /* Ignore internal-only IRQs */ |
| @@ -421,12 +423,12 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | |||
| 421 | } | 423 | } |
| 422 | 424 | ||
| 423 | static struct irq_chip wm831x_irq_chip = { | 425 | static struct irq_chip wm831x_irq_chip = { |
| 424 | .name = "wm831x", | 426 | .name = "wm831x", |
| 425 | .bus_lock = wm831x_irq_lock, | 427 | .irq_bus_lock = wm831x_irq_lock, |
| 426 | .bus_sync_unlock = wm831x_irq_sync_unlock, | 428 | .irq_bus_sync_unlock = wm831x_irq_sync_unlock, |
| 427 | .mask = wm831x_irq_mask, | 429 | .irq_mask = wm831x_irq_mask, |
| 428 | .unmask = wm831x_irq_unmask, | 430 | .irq_unmask = wm831x_irq_unmask, |
| 429 | .set_type = wm831x_irq_set_type, | 431 | .irq_set_type = wm831x_irq_set_type, |
| 430 | }; | 432 | }; |
| 431 | 433 | ||
| 432 | /* The processing of the primary interrupt occurs in a thread so that | 434 | /* The processing of the primary interrupt occurs in a thread so that |
| @@ -515,6 +517,17 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) | |||
| 515 | return 0; | 517 | return 0; |
| 516 | } | 518 | } |
| 517 | 519 | ||
| 520 | /* Try to flag /IRQ as a wake source; there are a number of | ||
| 521 | * unconditional wake sources in the PMIC so this isn't | ||
| 522 | * conditional but we don't actually care *too* much if it | ||
| 523 | * fails. | ||
| 524 | */ | ||
| 525 | ret = enable_irq_wake(irq); | ||
| 526 | if (ret != 0) { | ||
| 527 | dev_warn(wm831x->dev, "Can't enable IRQ as wake source: %d\n", | ||
| 528 | ret); | ||
| 529 | } | ||
| 530 | |||
| 518 | wm831x->irq = irq; | 531 | wm831x->irq = irq; |
| 519 | wm831x->irq_base = pdata->irq_base; | 532 | wm831x->irq_base = pdata->irq_base; |
| 520 | 533 | ||
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index 2789b151b0f9..0a8f772be88c 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c | |||
| @@ -81,6 +81,8 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) | |||
| 81 | type = WM8321; | 81 | type = WM8321; |
| 82 | else if (strcmp(spi->modalias, "wm8325") == 0) | 82 | else if (strcmp(spi->modalias, "wm8325") == 0) |
| 83 | type = WM8325; | 83 | type = WM8325; |
| 84 | else if (strcmp(spi->modalias, "wm8326") == 0) | ||
| 85 | type = WM8326; | ||
| 84 | else { | 86 | else { |
| 85 | dev_err(&spi->dev, "Unknown device type\n"); | 87 | dev_err(&spi->dev, "Unknown device type\n"); |
| 86 | return -EINVAL; | 88 | return -EINVAL; |
| @@ -184,6 +186,17 @@ static struct spi_driver wm8325_spi_driver = { | |||
| 184 | .suspend = wm831x_spi_suspend, | 186 | .suspend = wm831x_spi_suspend, |
| 185 | }; | 187 | }; |
| 186 | 188 | ||
| 189 | static struct spi_driver wm8326_spi_driver = { | ||
| 190 | .driver = { | ||
| 191 | .name = "wm8326", | ||
| 192 | .bus = &spi_bus_type, | ||
| 193 | .owner = THIS_MODULE, | ||
| 194 | }, | ||
| 195 | .probe = wm831x_spi_probe, | ||
| 196 | .remove = __devexit_p(wm831x_spi_remove), | ||
| 197 | .suspend = wm831x_spi_suspend, | ||
| 198 | }; | ||
| 199 | |||
| 187 | static int __init wm831x_spi_init(void) | 200 | static int __init wm831x_spi_init(void) |
| 188 | { | 201 | { |
| 189 | int ret; | 202 | int ret; |
| @@ -212,12 +225,17 @@ static int __init wm831x_spi_init(void) | |||
| 212 | if (ret != 0) | 225 | if (ret != 0) |
| 213 | pr_err("Failed to register WM8325 SPI driver: %d\n", ret); | 226 | pr_err("Failed to register WM8325 SPI driver: %d\n", ret); |
| 214 | 227 | ||
| 228 | ret = spi_register_driver(&wm8326_spi_driver); | ||
| 229 | if (ret != 0) | ||
| 230 | pr_err("Failed to register WM8326 SPI driver: %d\n", ret); | ||
| 231 | |||
| 215 | return 0; | 232 | return 0; |
| 216 | } | 233 | } |
| 217 | subsys_initcall(wm831x_spi_init); | 234 | subsys_initcall(wm831x_spi_init); |
| 218 | 235 | ||
| 219 | static void __exit wm831x_spi_exit(void) | 236 | static void __exit wm831x_spi_exit(void) |
| 220 | { | 237 | { |
| 238 | spi_unregister_driver(&wm8326_spi_driver); | ||
| 221 | spi_unregister_driver(&wm8325_spi_driver); | 239 | spi_unregister_driver(&wm8325_spi_driver); |
| 222 | spi_unregister_driver(&wm8321_spi_driver); | 240 | spi_unregister_driver(&wm8321_spi_driver); |
| 223 | spi_unregister_driver(&wm8320_spi_driver); | 241 | spi_unregister_driver(&wm8320_spi_driver); |
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index f56c9adf9493..5839966ebd85 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
| @@ -417,16 +417,16 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data) | |||
| 417 | return IRQ_HANDLED; | 417 | return IRQ_HANDLED; |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | static void wm8350_irq_lock(unsigned int irq) | 420 | static void wm8350_irq_lock(struct irq_data *data) |
| 421 | { | 421 | { |
| 422 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 422 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 423 | 423 | ||
| 424 | mutex_lock(&wm8350->irq_lock); | 424 | mutex_lock(&wm8350->irq_lock); |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static void wm8350_irq_sync_unlock(unsigned int irq) | 427 | static void wm8350_irq_sync_unlock(struct irq_data *data) |
| 428 | { | 428 | { |
| 429 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 429 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 430 | int i; | 430 | int i; |
| 431 | 431 | ||
| 432 | for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { | 432 | for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { |
| @@ -442,28 +442,30 @@ static void wm8350_irq_sync_unlock(unsigned int irq) | |||
| 442 | mutex_unlock(&wm8350->irq_lock); | 442 | mutex_unlock(&wm8350->irq_lock); |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | static void wm8350_irq_enable(unsigned int irq) | 445 | static void wm8350_irq_enable(struct irq_data *data) |
| 446 | { | 446 | { |
| 447 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 447 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 448 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); | 448 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, |
| 449 | data->irq); | ||
| 449 | 450 | ||
| 450 | wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; | 451 | wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; |
| 451 | } | 452 | } |
| 452 | 453 | ||
| 453 | static void wm8350_irq_disable(unsigned int irq) | 454 | static void wm8350_irq_disable(struct irq_data *data) |
| 454 | { | 455 | { |
| 455 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 456 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 456 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); | 457 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, |
| 458 | data->irq); | ||
| 457 | 459 | ||
| 458 | wm8350->irq_masks[irq_data->reg] |= irq_data->mask; | 460 | wm8350->irq_masks[irq_data->reg] |= irq_data->mask; |
| 459 | } | 461 | } |
| 460 | 462 | ||
| 461 | static struct irq_chip wm8350_irq_chip = { | 463 | static struct irq_chip wm8350_irq_chip = { |
| 462 | .name = "wm8350", | 464 | .name = "wm8350", |
| 463 | .bus_lock = wm8350_irq_lock, | 465 | .irq_bus_lock = wm8350_irq_lock, |
| 464 | .bus_sync_unlock = wm8350_irq_sync_unlock, | 466 | .irq_bus_sync_unlock = wm8350_irq_sync_unlock, |
| 465 | .disable = wm8350_irq_disable, | 467 | .irq_disable = wm8350_irq_disable, |
| 466 | .enable = wm8350_irq_enable, | 468 | .irq_enable = wm8350_irq_enable, |
| 467 | }; | 469 | }; |
| 468 | 470 | ||
| 469 | int wm8350_irq_init(struct wm8350 *wm8350, int irq, | 471 | int wm8350_irq_init(struct wm8350 *wm8350, int irq, |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 8d221ba5e38d..41233c7fa581 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
| 19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 20 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
| 21 | #include <linux/pm_runtime.h> | ||
| 21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
| 22 | #include <linux/regulator/machine.h> | 23 | #include <linux/regulator/machine.h> |
| 23 | 24 | ||
| @@ -169,8 +170,16 @@ out: | |||
| 169 | EXPORT_SYMBOL_GPL(wm8994_set_bits); | 170 | EXPORT_SYMBOL_GPL(wm8994_set_bits); |
| 170 | 171 | ||
| 171 | static struct mfd_cell wm8994_regulator_devs[] = { | 172 | static struct mfd_cell wm8994_regulator_devs[] = { |
| 172 | { .name = "wm8994-ldo", .id = 1 }, | 173 | { |
| 173 | { .name = "wm8994-ldo", .id = 2 }, | 174 | .name = "wm8994-ldo", |
| 175 | .id = 1, | ||
| 176 | .pm_runtime_no_callbacks = true, | ||
| 177 | }, | ||
| 178 | { | ||
| 179 | .name = "wm8994-ldo", | ||
| 180 | .id = 2, | ||
| 181 | .pm_runtime_no_callbacks = true, | ||
| 182 | }, | ||
| 174 | }; | 183 | }; |
| 175 | 184 | ||
| 176 | static struct resource wm8994_codec_resources[] = { | 185 | static struct resource wm8994_codec_resources[] = { |
| @@ -200,6 +209,7 @@ static struct mfd_cell wm8994_devs[] = { | |||
| 200 | .name = "wm8994-gpio", | 209 | .name = "wm8994-gpio", |
| 201 | .num_resources = ARRAY_SIZE(wm8994_gpio_resources), | 210 | .num_resources = ARRAY_SIZE(wm8994_gpio_resources), |
| 202 | .resources = wm8994_gpio_resources, | 211 | .resources = wm8994_gpio_resources, |
| 212 | .pm_runtime_no_callbacks = true, | ||
| 203 | }, | 213 | }, |
| 204 | }; | 214 | }; |
| 205 | 215 | ||
| @@ -231,7 +241,7 @@ static const char *wm8958_main_supplies[] = { | |||
| 231 | }; | 241 | }; |
| 232 | 242 | ||
| 233 | #ifdef CONFIG_PM | 243 | #ifdef CONFIG_PM |
| 234 | static int wm8994_device_suspend(struct device *dev) | 244 | static int wm8994_suspend(struct device *dev) |
| 235 | { | 245 | { |
| 236 | struct wm8994 *wm8994 = dev_get_drvdata(dev); | 246 | struct wm8994 *wm8994 = dev_get_drvdata(dev); |
| 237 | int ret; | 247 | int ret; |
| @@ -261,7 +271,7 @@ static int wm8994_device_suspend(struct device *dev) | |||
| 261 | return 0; | 271 | return 0; |
| 262 | } | 272 | } |
| 263 | 273 | ||
| 264 | static int wm8994_device_resume(struct device *dev) | 274 | static int wm8994_resume(struct device *dev) |
| 265 | { | 275 | { |
| 266 | struct wm8994 *wm8994 = dev_get_drvdata(dev); | 276 | struct wm8994 *wm8994 = dev_get_drvdata(dev); |
| 267 | int ret; | 277 | int ret; |
| @@ -471,6 +481,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
| 471 | goto err_irq; | 481 | goto err_irq; |
| 472 | } | 482 | } |
| 473 | 483 | ||
| 484 | pm_runtime_enable(wm8994->dev); | ||
| 485 | pm_runtime_resume(wm8994->dev); | ||
| 486 | |||
| 474 | return 0; | 487 | return 0; |
| 475 | 488 | ||
| 476 | err_irq: | 489 | err_irq: |
| @@ -490,6 +503,7 @@ err: | |||
| 490 | 503 | ||
| 491 | static void wm8994_device_exit(struct wm8994 *wm8994) | 504 | static void wm8994_device_exit(struct wm8994 *wm8994) |
| 492 | { | 505 | { |
| 506 | pm_runtime_disable(wm8994->dev); | ||
| 493 | mfd_remove_devices(wm8994->dev); | 507 | mfd_remove_devices(wm8994->dev); |
| 494 | wm8994_irq_exit(wm8994); | 508 | wm8994_irq_exit(wm8994); |
| 495 | regulator_bulk_disable(wm8994->num_supplies, | 509 | regulator_bulk_disable(wm8994->num_supplies, |
| @@ -573,21 +587,6 @@ static int wm8994_i2c_remove(struct i2c_client *i2c) | |||
| 573 | return 0; | 587 | return 0; |
| 574 | } | 588 | } |
| 575 | 589 | ||
| 576 | #ifdef CONFIG_PM | ||
| 577 | static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state) | ||
| 578 | { | ||
| 579 | return wm8994_device_suspend(&i2c->dev); | ||
| 580 | } | ||
| 581 | |||
| 582 | static int wm8994_i2c_resume(struct i2c_client *i2c) | ||
| 583 | { | ||
| 584 | return wm8994_device_resume(&i2c->dev); | ||
| 585 | } | ||
| 586 | #else | ||
| 587 | #define wm8994_i2c_suspend NULL | ||
| 588 | #define wm8994_i2c_resume NULL | ||
| 589 | #endif | ||
| 590 | |||
| 591 | static const struct i2c_device_id wm8994_i2c_id[] = { | 590 | static const struct i2c_device_id wm8994_i2c_id[] = { |
| 592 | { "wm8994", WM8994 }, | 591 | { "wm8994", WM8994 }, |
| 593 | { "wm8958", WM8958 }, | 592 | { "wm8958", WM8958 }, |
| @@ -595,15 +594,16 @@ static const struct i2c_device_id wm8994_i2c_id[] = { | |||
| 595 | }; | 594 | }; |
| 596 | MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); | 595 | MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); |
| 597 | 596 | ||
| 597 | UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); | ||
| 598 | |||
| 598 | static struct i2c_driver wm8994_i2c_driver = { | 599 | static struct i2c_driver wm8994_i2c_driver = { |
| 599 | .driver = { | 600 | .driver = { |
| 600 | .name = "wm8994", | 601 | .name = "wm8994", |
| 601 | .owner = THIS_MODULE, | 602 | .owner = THIS_MODULE, |
| 603 | .pm = &wm8994_pm_ops, | ||
| 602 | }, | 604 | }, |
| 603 | .probe = wm8994_i2c_probe, | 605 | .probe = wm8994_i2c_probe, |
| 604 | .remove = wm8994_i2c_remove, | 606 | .remove = wm8994_i2c_remove, |
| 605 | .suspend = wm8994_i2c_suspend, | ||
| 606 | .resume = wm8994_i2c_resume, | ||
| 607 | .id_table = wm8994_i2c_id, | 607 | .id_table = wm8994_i2c_id, |
| 608 | }; | 608 | }; |
| 609 | 609 | ||
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c index 8400eb1ee5db..29e8faf9c01c 100644 --- a/drivers/mfd/wm8994-irq.c +++ b/drivers/mfd/wm8994-irq.c | |||
| @@ -156,16 +156,16 @@ static inline struct wm8994_irq_data *irq_to_wm8994_irq(struct wm8994 *wm8994, | |||
| 156 | return &wm8994_irqs[irq - wm8994->irq_base]; | 156 | return &wm8994_irqs[irq - wm8994->irq_base]; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static void wm8994_irq_lock(unsigned int irq) | 159 | static void wm8994_irq_lock(struct irq_data *data) |
| 160 | { | 160 | { |
| 161 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 161 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 162 | 162 | ||
| 163 | mutex_lock(&wm8994->irq_lock); | 163 | mutex_lock(&wm8994->irq_lock); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static void wm8994_irq_sync_unlock(unsigned int irq) | 166 | static void wm8994_irq_sync_unlock(struct irq_data *data) |
| 167 | { | 167 | { |
| 168 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 168 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 169 | int i; | 169 | int i; |
| 170 | 170 | ||
| 171 | for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { | 171 | for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { |
| @@ -182,28 +182,30 @@ static void wm8994_irq_sync_unlock(unsigned int irq) | |||
| 182 | mutex_unlock(&wm8994->irq_lock); | 182 | mutex_unlock(&wm8994->irq_lock); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | static void wm8994_irq_unmask(unsigned int irq) | 185 | static void wm8994_irq_unmask(struct irq_data *data) |
| 186 | { | 186 | { |
| 187 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 187 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 188 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq); | 188 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, |
| 189 | data->irq); | ||
| 189 | 190 | ||
| 190 | wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 191 | wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
| 191 | } | 192 | } |
| 192 | 193 | ||
| 193 | static void wm8994_irq_mask(unsigned int irq) | 194 | static void wm8994_irq_mask(struct irq_data *data) |
| 194 | { | 195 | { |
| 195 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 196 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 196 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq); | 197 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, |
| 198 | data->irq); | ||
| 197 | 199 | ||
| 198 | wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 200 | wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | static struct irq_chip wm8994_irq_chip = { | 203 | static struct irq_chip wm8994_irq_chip = { |
| 202 | .name = "wm8994", | 204 | .name = "wm8994", |
| 203 | .bus_lock = wm8994_irq_lock, | 205 | .irq_bus_lock = wm8994_irq_lock, |
| 204 | .bus_sync_unlock = wm8994_irq_sync_unlock, | 206 | .irq_bus_sync_unlock = wm8994_irq_sync_unlock, |
| 205 | .mask = wm8994_irq_mask, | 207 | .irq_mask = wm8994_irq_mask, |
| 206 | .unmask = wm8994_irq_unmask, | 208 | .irq_unmask = wm8994_irq_unmask, |
| 207 | }; | 209 | }; |
| 208 | 210 | ||
| 209 | /* The processing of the primary interrupt occurs in a thread so that | 211 | /* The processing of the primary interrupt occurs in a thread so that |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1e1a4be8eb6c..cc8e49db45fe 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -64,7 +64,7 @@ config ATMEL_PWM | |||
| 64 | 64 | ||
| 65 | config AB8500_PWM | 65 | config AB8500_PWM |
| 66 | bool "AB8500 PWM support" | 66 | bool "AB8500 PWM support" |
| 67 | depends on AB8500_CORE | 67 | depends on AB8500_CORE && ARCH_U8500 |
| 68 | select HAVE_PWM | 68 | select HAVE_PWM |
| 69 | help | 69 | help |
| 70 | This driver exports functions to enable/disble/config/free Pulse | 70 | This driver exports functions to enable/disble/config/free Pulse |
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 6f6218061b0d..d02d302ee6d5 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c | |||
| @@ -16,12 +16,11 @@ | |||
| 16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/pci.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/cs5535.h> | 20 | #include <linux/cs5535.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | 22 | ||
| 23 | #define DRV_NAME "cs5535-mfgpt" | 23 | #define DRV_NAME "cs5535-mfgpt" |
| 24 | #define MFGPT_BAR 2 | ||
| 25 | 24 | ||
| 26 | static int mfgpt_reset_timers; | 25 | static int mfgpt_reset_timers; |
| 27 | module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); | 26 | module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); |
| @@ -37,7 +36,7 @@ static struct cs5535_mfgpt_chip { | |||
| 37 | DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); | 36 | DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); |
| 38 | resource_size_t base; | 37 | resource_size_t base; |
| 39 | 38 | ||
| 40 | struct pci_dev *pdev; | 39 | struct platform_device *pdev; |
| 41 | spinlock_t lock; | 40 | spinlock_t lock; |
| 42 | int initialized; | 41 | int initialized; |
| 43 | } cs5535_mfgpt_chip; | 42 | } cs5535_mfgpt_chip; |
| @@ -290,10 +289,10 @@ static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt) | |||
| 290 | return timers; | 289 | return timers; |
| 291 | } | 290 | } |
| 292 | 291 | ||
| 293 | static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, | 292 | static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) |
| 294 | const struct pci_device_id *pci_id) | ||
| 295 | { | 293 | { |
| 296 | int err, t; | 294 | struct resource *res; |
| 295 | int err = -EIO, t; | ||
| 297 | 296 | ||
| 298 | /* There are two ways to get the MFGPT base address; one is by | 297 | /* There are two ways to get the MFGPT base address; one is by |
| 299 | * fetching it from MSR_LBAR_MFGPT, the other is by reading the | 298 | * fetching it from MSR_LBAR_MFGPT, the other is by reading the |
| @@ -302,29 +301,27 @@ static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, | |||
| 302 | * it turns out to be unreliable in the face of crappy BIOSes, we | 301 | * it turns out to be unreliable in the face of crappy BIOSes, we |
| 303 | * can always go back to using MSRs.. */ | 302 | * can always go back to using MSRs.. */ |
| 304 | 303 | ||
| 305 | err = pci_enable_device_io(pdev); | 304 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 306 | if (err) { | 305 | if (!res) { |
| 307 | dev_err(&pdev->dev, "can't enable device IO\n"); | 306 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 308 | goto done; | 307 | goto done; |
| 309 | } | 308 | } |
| 310 | 309 | ||
| 311 | err = pci_request_region(pdev, MFGPT_BAR, DRV_NAME); | 310 | if (!request_region(res->start, resource_size(res), pdev->name)) { |
| 312 | if (err) { | 311 | dev_err(&pdev->dev, "can't request region\n"); |
| 313 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", MFGPT_BAR); | ||
| 314 | goto done; | 312 | goto done; |
| 315 | } | 313 | } |
| 316 | 314 | ||
| 317 | /* set up the driver-specific struct */ | 315 | /* set up the driver-specific struct */ |
| 318 | cs5535_mfgpt_chip.base = pci_resource_start(pdev, MFGPT_BAR); | 316 | cs5535_mfgpt_chip.base = res->start; |
| 319 | cs5535_mfgpt_chip.pdev = pdev; | 317 | cs5535_mfgpt_chip.pdev = pdev; |
| 320 | spin_lock_init(&cs5535_mfgpt_chip.lock); | 318 | spin_lock_init(&cs5535_mfgpt_chip.lock); |
| 321 | 319 | ||
| 322 | dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", MFGPT_BAR, | 320 | dev_info(&pdev->dev, "reserved resource region %pR\n", res); |
| 323 | (unsigned long long) cs5535_mfgpt_chip.base); | ||
| 324 | 321 | ||
| 325 | /* detect the available timers */ | 322 | /* detect the available timers */ |
| 326 | t = scan_timers(&cs5535_mfgpt_chip); | 323 | t = scan_timers(&cs5535_mfgpt_chip); |
| 327 | dev_info(&pdev->dev, DRV_NAME ": %d MFGPT timers available\n", t); | 324 | dev_info(&pdev->dev, "%d MFGPT timers available\n", t); |
| 328 | cs5535_mfgpt_chip.initialized = 1; | 325 | cs5535_mfgpt_chip.initialized = 1; |
| 329 | return 0; | 326 | return 0; |
| 330 | 327 | ||
| @@ -332,47 +329,18 @@ done: | |||
| 332 | return err; | 329 | return err; |
| 333 | } | 330 | } |
| 334 | 331 | ||
| 335 | static struct pci_device_id cs5535_mfgpt_pci_tbl[] = { | 332 | static struct platform_driver cs5535_mfgpt_drv = { |
| 336 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | 333 | .driver = { |
| 337 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 334 | .name = DRV_NAME, |
| 338 | { 0, }, | 335 | .owner = THIS_MODULE, |
| 336 | }, | ||
| 337 | .probe = cs5535_mfgpt_probe, | ||
| 339 | }; | 338 | }; |
| 340 | MODULE_DEVICE_TABLE(pci, cs5535_mfgpt_pci_tbl); | ||
| 341 | 339 | ||
| 342 | /* | ||
| 343 | * Just like with the cs5535-gpio driver, we can't use the standard PCI driver | ||
| 344 | * registration stuff. It only allows only one driver to bind to each PCI | ||
| 345 | * device, and we want the GPIO and MFGPT drivers to be able to share a PCI | ||
| 346 | * device. Instead, we manually scan for the PCI device, request a single | ||
| 347 | * region, and keep track of the devices that we're using. | ||
| 348 | */ | ||
| 349 | |||
| 350 | static int __init cs5535_mfgpt_scan_pci(void) | ||
| 351 | { | ||
| 352 | struct pci_dev *pdev; | ||
| 353 | int err = -ENODEV; | ||
| 354 | int i; | ||
| 355 | |||
| 356 | for (i = 0; i < ARRAY_SIZE(cs5535_mfgpt_pci_tbl); i++) { | ||
| 357 | pdev = pci_get_device(cs5535_mfgpt_pci_tbl[i].vendor, | ||
| 358 | cs5535_mfgpt_pci_tbl[i].device, NULL); | ||
| 359 | if (pdev) { | ||
| 360 | err = cs5535_mfgpt_probe(pdev, | ||
| 361 | &cs5535_mfgpt_pci_tbl[i]); | ||
| 362 | if (err) | ||
| 363 | pci_dev_put(pdev); | ||
| 364 | |||
| 365 | /* we only support a single CS5535/6 southbridge */ | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | } | ||
| 369 | |||
| 370 | return err; | ||
| 371 | } | ||
| 372 | 340 | ||
| 373 | static int __init cs5535_mfgpt_init(void) | 341 | static int __init cs5535_mfgpt_init(void) |
| 374 | { | 342 | { |
| 375 | return cs5535_mfgpt_scan_pci(); | 343 | return platform_driver_register(&cs5535_mfgpt_drv); |
| 376 | } | 344 | } |
| 377 | 345 | ||
| 378 | module_init(cs5535_mfgpt_init); | 346 | module_init(cs5535_mfgpt_init); |
| @@ -380,3 +348,4 @@ module_init(cs5535_mfgpt_init); | |||
| 380 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | 348 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); |
| 381 | MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver"); | 349 | MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver"); |
| 382 | MODULE_LICENSE("GPL"); | 350 | MODULE_LICENSE("GPL"); |
| 351 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 54c6d849cf25..62d6f88cbab5 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
| @@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value) | |||
| 854 | } | 854 | } |
| 855 | 855 | ||
| 856 | /** | 856 | /** |
| 857 | * ks8695_get_settings - Get device-specific settings. | 857 | * ks8695_wan_get_settings - Get device-specific settings. |
| 858 | * @ndev: The network device to read settings from | 858 | * @ndev: The network device to read settings from |
| 859 | * @cmd: The ethtool structure to read into | 859 | * @cmd: The ethtool structure to read into |
| 860 | */ | 860 | */ |
| 861 | static int | 861 | static int |
| 862 | ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | 862 | ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) |
| 863 | { | 863 | { |
| 864 | struct ks8695_priv *ksp = netdev_priv(ndev); | 864 | struct ks8695_priv *ksp = netdev_priv(ndev); |
| 865 | u32 ctrl; | 865 | u32 ctrl; |
| @@ -870,69 +870,50 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | |||
| 870 | SUPPORTED_TP | SUPPORTED_MII); | 870 | SUPPORTED_TP | SUPPORTED_MII); |
| 871 | cmd->transceiver = XCVR_INTERNAL; | 871 | cmd->transceiver = XCVR_INTERNAL; |
| 872 | 872 | ||
| 873 | /* Port specific extras */ | 873 | cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; |
| 874 | switch (ksp->dtype) { | 874 | cmd->port = PORT_MII; |
| 875 | case KS8695_DTYPE_HPNA: | 875 | cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); |
| 876 | cmd->phy_address = 0; | 876 | cmd->phy_address = 0; |
| 877 | /* not supported for HPNA */ | ||
| 878 | cmd->autoneg = AUTONEG_DISABLE; | ||
| 879 | 877 | ||
| 880 | /* BUG: Erm, dtype hpna implies no phy regs */ | 878 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
| 881 | /* | 879 | if ((ctrl & WMC_WAND) == 0) { |
| 882 | ctrl = readl(KS8695_MISC_VA + KS8695_HMC); | 880 | /* auto-negotiation is enabled */ |
| 883 | cmd->speed = (ctrl & HMC_HSS) ? SPEED_100 : SPEED_10; | 881 | cmd->advertising |= ADVERTISED_Autoneg; |
| 884 | cmd->duplex = (ctrl & HMC_HDS) ? DUPLEX_FULL : DUPLEX_HALF; | 882 | if (ctrl & WMC_WANA100F) |
| 885 | */ | 883 | cmd->advertising |= ADVERTISED_100baseT_Full; |
| 886 | return -EOPNOTSUPP; | 884 | if (ctrl & WMC_WANA100H) |
| 887 | case KS8695_DTYPE_WAN: | 885 | cmd->advertising |= ADVERTISED_100baseT_Half; |
| 888 | cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; | 886 | if (ctrl & WMC_WANA10F) |
| 889 | cmd->port = PORT_MII; | 887 | cmd->advertising |= ADVERTISED_10baseT_Full; |
| 890 | cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); | 888 | if (ctrl & WMC_WANA10H) |
| 891 | cmd->phy_address = 0; | 889 | cmd->advertising |= ADVERTISED_10baseT_Half; |
| 890 | if (ctrl & WMC_WANAP) | ||
| 891 | cmd->advertising |= ADVERTISED_Pause; | ||
| 892 | cmd->autoneg = AUTONEG_ENABLE; | ||
| 893 | |||
| 894 | cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10; | ||
| 895 | cmd->duplex = (ctrl & WMC_WDS) ? | ||
| 896 | DUPLEX_FULL : DUPLEX_HALF; | ||
| 897 | } else { | ||
| 898 | /* auto-negotiation is disabled */ | ||
| 899 | cmd->autoneg = AUTONEG_DISABLE; | ||
| 892 | 900 | ||
| 893 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | 901 | cmd->speed = (ctrl & WMC_WANF100) ? |
| 894 | if ((ctrl & WMC_WAND) == 0) { | 902 | SPEED_100 : SPEED_10; |
| 895 | /* auto-negotiation is enabled */ | 903 | cmd->duplex = (ctrl & WMC_WANFF) ? |
| 896 | cmd->advertising |= ADVERTISED_Autoneg; | 904 | DUPLEX_FULL : DUPLEX_HALF; |
| 897 | if (ctrl & WMC_WANA100F) | ||
| 898 | cmd->advertising |= ADVERTISED_100baseT_Full; | ||
| 899 | if (ctrl & WMC_WANA100H) | ||
| 900 | cmd->advertising |= ADVERTISED_100baseT_Half; | ||
| 901 | if (ctrl & WMC_WANA10F) | ||
| 902 | cmd->advertising |= ADVERTISED_10baseT_Full; | ||
| 903 | if (ctrl & WMC_WANA10H) | ||
| 904 | cmd->advertising |= ADVERTISED_10baseT_Half; | ||
| 905 | if (ctrl & WMC_WANAP) | ||
| 906 | cmd->advertising |= ADVERTISED_Pause; | ||
| 907 | cmd->autoneg = AUTONEG_ENABLE; | ||
| 908 | |||
| 909 | cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10; | ||
| 910 | cmd->duplex = (ctrl & WMC_WDS) ? | ||
| 911 | DUPLEX_FULL : DUPLEX_HALF; | ||
| 912 | } else { | ||
| 913 | /* auto-negotiation is disabled */ | ||
| 914 | cmd->autoneg = AUTONEG_DISABLE; | ||
| 915 | |||
| 916 | cmd->speed = (ctrl & WMC_WANF100) ? | ||
| 917 | SPEED_100 : SPEED_10; | ||
| 918 | cmd->duplex = (ctrl & WMC_WANFF) ? | ||
| 919 | DUPLEX_FULL : DUPLEX_HALF; | ||
| 920 | } | ||
| 921 | break; | ||
| 922 | case KS8695_DTYPE_LAN: | ||
| 923 | return -EOPNOTSUPP; | ||
| 924 | } | 905 | } |
| 925 | 906 | ||
| 926 | return 0; | 907 | return 0; |
| 927 | } | 908 | } |
| 928 | 909 | ||
| 929 | /** | 910 | /** |
| 930 | * ks8695_set_settings - Set device-specific settings. | 911 | * ks8695_wan_set_settings - Set device-specific settings. |
| 931 | * @ndev: The network device to configure | 912 | * @ndev: The network device to configure |
| 932 | * @cmd: The settings to configure | 913 | * @cmd: The settings to configure |
| 933 | */ | 914 | */ |
| 934 | static int | 915 | static int |
| 935 | ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | 916 | ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) |
| 936 | { | 917 | { |
| 937 | struct ks8695_priv *ksp = netdev_priv(ndev); | 918 | struct ks8695_priv *ksp = netdev_priv(ndev); |
| 938 | u32 ctrl; | 919 | u32 ctrl; |
| @@ -956,171 +937,85 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) | |||
| 956 | ADVERTISED_100baseT_Full)) == 0) | 937 | ADVERTISED_100baseT_Full)) == 0) |
| 957 | return -EINVAL; | 938 | return -EINVAL; |
| 958 | 939 | ||
| 959 | switch (ksp->dtype) { | 940 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
| 960 | case KS8695_DTYPE_HPNA: | ||
| 961 | /* HPNA does not support auto-negotiation. */ | ||
| 962 | return -EINVAL; | ||
| 963 | case KS8695_DTYPE_WAN: | ||
| 964 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
| 965 | |||
| 966 | ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | | ||
| 967 | WMC_WANA10F | WMC_WANA10H); | ||
| 968 | if (cmd->advertising & ADVERTISED_100baseT_Full) | ||
| 969 | ctrl |= WMC_WANA100F; | ||
| 970 | if (cmd->advertising & ADVERTISED_100baseT_Half) | ||
| 971 | ctrl |= WMC_WANA100H; | ||
| 972 | if (cmd->advertising & ADVERTISED_10baseT_Full) | ||
| 973 | ctrl |= WMC_WANA10F; | ||
| 974 | if (cmd->advertising & ADVERTISED_10baseT_Half) | ||
| 975 | ctrl |= WMC_WANA10H; | ||
| 976 | |||
| 977 | /* force a re-negotiation */ | ||
| 978 | ctrl |= WMC_WANR; | ||
| 979 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | ||
| 980 | break; | ||
| 981 | case KS8695_DTYPE_LAN: | ||
| 982 | return -EOPNOTSUPP; | ||
| 983 | } | ||
| 984 | 941 | ||
| 942 | ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | | ||
| 943 | WMC_WANA10F | WMC_WANA10H); | ||
| 944 | if (cmd->advertising & ADVERTISED_100baseT_Full) | ||
| 945 | ctrl |= WMC_WANA100F; | ||
| 946 | if (cmd->advertising & ADVERTISED_100baseT_Half) | ||
| 947 | ctrl |= WMC_WANA100H; | ||
| 948 | if (cmd->advertising & ADVERTISED_10baseT_Full) | ||
| 949 | ctrl |= WMC_WANA10F; | ||
| 950 | if (cmd->advertising & ADVERTISED_10baseT_Half) | ||
| 951 | ctrl |= WMC_WANA10H; | ||
| 952 | |||
| 953 | /* force a re-negotiation */ | ||
| 954 | ctrl |= WMC_WANR; | ||
| 955 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | ||
| 985 | } else { | 956 | } else { |
| 986 | switch (ksp->dtype) { | 957 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
| 987 | case KS8695_DTYPE_HPNA: | 958 | |
| 988 | /* BUG: dtype_hpna implies no phy registers */ | 959 | /* disable auto-negotiation */ |
| 989 | /* | 960 | ctrl |= WMC_WAND; |
| 990 | ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC); | 961 | ctrl &= ~(WMC_WANF100 | WMC_WANFF); |
| 991 | 962 | ||
| 992 | ctrl &= ~(HMC_HSS | HMC_HDS); | 963 | if (cmd->speed == SPEED_100) |
| 993 | if (cmd->speed == SPEED_100) | 964 | ctrl |= WMC_WANF100; |
| 994 | ctrl |= HMC_HSS; | 965 | if (cmd->duplex == DUPLEX_FULL) |
| 995 | if (cmd->duplex == DUPLEX_FULL) | 966 | ctrl |= WMC_WANFF; |
| 996 | ctrl |= HMC_HDS; | 967 | |
| 997 | 968 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | |
| 998 | __raw_writel(ctrl, KS8695_MISC_VA + KS8695_HMC); | ||
| 999 | */ | ||
| 1000 | return -EOPNOTSUPP; | ||
| 1001 | case KS8695_DTYPE_WAN: | ||
| 1002 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
| 1003 | |||
| 1004 | /* disable auto-negotiation */ | ||
| 1005 | ctrl |= WMC_WAND; | ||
| 1006 | ctrl &= ~(WMC_WANF100 | WMC_WANFF); | ||
| 1007 | |||
| 1008 | if (cmd->speed == SPEED_100) | ||
| 1009 | ctrl |= WMC_WANF100; | ||
| 1010 | if (cmd->duplex == DUPLEX_FULL) | ||
| 1011 | ctrl |= WMC_WANFF; | ||
| 1012 | |||
| 1013 | writel(ctrl, ksp->phyiface_regs + KS8695_WMC); | ||
| 1014 | break; | ||
| 1015 | case KS8695_DTYPE_LAN: | ||
| 1016 | return -EOPNOTSUPP; | ||
| 1017 | } | ||
| 1018 | } | 969 | } |
| 1019 | 970 | ||
| 1020 | return 0; | 971 | return 0; |
| 1021 | } | 972 | } |
| 1022 | 973 | ||
| 1023 | /** | 974 | /** |
| 1024 | * ks8695_nwayreset - Restart the autonegotiation on the port. | 975 | * ks8695_wan_nwayreset - Restart the autonegotiation on the port. |
| 1025 | * @ndev: The network device to restart autoneotiation on | 976 | * @ndev: The network device to restart autoneotiation on |
| 1026 | */ | 977 | */ |
| 1027 | static int | 978 | static int |
| 1028 | ks8695_nwayreset(struct net_device *ndev) | 979 | ks8695_wan_nwayreset(struct net_device *ndev) |
| 1029 | { | 980 | { |
| 1030 | struct ks8695_priv *ksp = netdev_priv(ndev); | 981 | struct ks8695_priv *ksp = netdev_priv(ndev); |
| 1031 | u32 ctrl; | 982 | u32 ctrl; |
| 1032 | 983 | ||
| 1033 | switch (ksp->dtype) { | 984 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
| 1034 | case KS8695_DTYPE_HPNA: | ||
| 1035 | /* No phy means no autonegotiation on hpna */ | ||
| 1036 | return -EINVAL; | ||
| 1037 | case KS8695_DTYPE_WAN: | ||
| 1038 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
| 1039 | |||
| 1040 | if ((ctrl & WMC_WAND) == 0) | ||
| 1041 | writel(ctrl | WMC_WANR, | ||
| 1042 | ksp->phyiface_regs + KS8695_WMC); | ||
| 1043 | else | ||
| 1044 | /* auto-negotiation not enabled */ | ||
| 1045 | return -EINVAL; | ||
| 1046 | break; | ||
| 1047 | case KS8695_DTYPE_LAN: | ||
| 1048 | return -EOPNOTSUPP; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | return 0; | ||
| 1052 | } | ||
| 1053 | 985 | ||
| 1054 | /** | 986 | if ((ctrl & WMC_WAND) == 0) |
| 1055 | * ks8695_get_link - Retrieve link status of network interface | 987 | writel(ctrl | WMC_WANR, |
| 1056 | * @ndev: The network interface to retrive the link status of. | 988 | ksp->phyiface_regs + KS8695_WMC); |
| 1057 | */ | 989 | else |
| 1058 | static u32 | 990 | /* auto-negotiation not enabled */ |
| 1059 | ks8695_get_link(struct net_device *ndev) | 991 | return -EINVAL; |
| 1060 | { | ||
| 1061 | struct ks8695_priv *ksp = netdev_priv(ndev); | ||
| 1062 | u32 ctrl; | ||
| 1063 | 992 | ||
| 1064 | switch (ksp->dtype) { | ||
| 1065 | case KS8695_DTYPE_HPNA: | ||
| 1066 | /* HPNA always has link */ | ||
| 1067 | return 1; | ||
| 1068 | case KS8695_DTYPE_WAN: | ||
| 1069 | /* WAN we can read the PHY for */ | ||
| 1070 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
| 1071 | return ctrl & WMC_WLS; | ||
| 1072 | case KS8695_DTYPE_LAN: | ||
| 1073 | return -EOPNOTSUPP; | ||
| 1074 | } | ||
| 1075 | return 0; | 993 | return 0; |
| 1076 | } | 994 | } |
| 1077 | 995 | ||
| 1078 | /** | 996 | /** |
| 1079 | * ks8695_get_pause - Retrieve network pause/flow-control advertising | 997 | * ks8695_wan_get_pause - Retrieve network pause/flow-control advertising |
| 1080 | * @ndev: The device to retrieve settings from | 998 | * @ndev: The device to retrieve settings from |
| 1081 | * @param: The structure to fill out with the information | 999 | * @param: The structure to fill out with the information |
| 1082 | */ | 1000 | */ |
| 1083 | static void | 1001 | static void |
| 1084 | ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) | 1002 | ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) |
| 1085 | { | 1003 | { |
| 1086 | struct ks8695_priv *ksp = netdev_priv(ndev); | 1004 | struct ks8695_priv *ksp = netdev_priv(ndev); |
| 1087 | u32 ctrl; | 1005 | u32 ctrl; |
| 1088 | 1006 | ||
| 1089 | switch (ksp->dtype) { | 1007 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); |
| 1090 | case KS8695_DTYPE_HPNA: | ||
| 1091 | /* No phy link on hpna to configure */ | ||
| 1092 | return; | ||
| 1093 | case KS8695_DTYPE_WAN: | ||
| 1094 | ctrl = readl(ksp->phyiface_regs + KS8695_WMC); | ||
| 1095 | |||
| 1096 | /* advertise Pause */ | ||
| 1097 | param->autoneg = (ctrl & WMC_WANAP); | ||
| 1098 | 1008 | ||
| 1099 | /* current Rx Flow-control */ | 1009 | /* advertise Pause */ |
| 1100 | ctrl = ks8695_readreg(ksp, KS8695_DRXC); | 1010 | param->autoneg = (ctrl & WMC_WANAP); |
| 1101 | param->rx_pause = (ctrl & DRXC_RFCE); | ||
| 1102 | 1011 | ||
| 1103 | /* current Tx Flow-control */ | 1012 | /* current Rx Flow-control */ |
| 1104 | ctrl = ks8695_readreg(ksp, KS8695_DTXC); | 1013 | ctrl = ks8695_readreg(ksp, KS8695_DRXC); |
| 1105 | param->tx_pause = (ctrl & DTXC_TFCE); | 1014 | param->rx_pause = (ctrl & DRXC_RFCE); |
| 1106 | break; | ||
| 1107 | case KS8695_DTYPE_LAN: | ||
| 1108 | /* The LAN's "phy" is a direct-attached switch */ | ||
| 1109 | return; | ||
| 1110 | } | ||
| 1111 | } | ||
| 1112 | 1015 | ||
| 1113 | /** | 1016 | /* current Tx Flow-control */ |
| 1114 | * ks8695_set_pause - Configure pause/flow-control | 1017 | ctrl = ks8695_readreg(ksp, KS8695_DTXC); |
| 1115 | * @ndev: The device to configure | 1018 | param->tx_pause = (ctrl & DTXC_TFCE); |
| 1116 | * @param: The pause parameters to set | ||
| 1117 | * | ||
| 1118 | * TODO: Implement this | ||
| 1119 | */ | ||
| 1120 | static int | ||
| 1121 | ks8695_set_pause(struct net_device *ndev, struct ethtool_pauseparam *param) | ||
| 1122 | { | ||
| 1123 | return -EOPNOTSUPP; | ||
| 1124 | } | 1019 | } |
| 1125 | 1020 | ||
| 1126 | /** | 1021 | /** |
| @@ -1140,12 +1035,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) | |||
| 1140 | static const struct ethtool_ops ks8695_ethtool_ops = { | 1035 | static const struct ethtool_ops ks8695_ethtool_ops = { |
| 1141 | .get_msglevel = ks8695_get_msglevel, | 1036 | .get_msglevel = ks8695_get_msglevel, |
| 1142 | .set_msglevel = ks8695_set_msglevel, | 1037 | .set_msglevel = ks8695_set_msglevel, |
| 1143 | .get_settings = ks8695_get_settings, | 1038 | .get_drvinfo = ks8695_get_drvinfo, |
| 1144 | .set_settings = ks8695_set_settings, | 1039 | }; |
| 1145 | .nway_reset = ks8695_nwayreset, | 1040 | |
| 1146 | .get_link = ks8695_get_link, | 1041 | static const struct ethtool_ops ks8695_wan_ethtool_ops = { |
| 1147 | .get_pauseparam = ks8695_get_pause, | 1042 | .get_msglevel = ks8695_get_msglevel, |
| 1148 | .set_pauseparam = ks8695_set_pause, | 1043 | .set_msglevel = ks8695_set_msglevel, |
| 1044 | .get_settings = ks8695_wan_get_settings, | ||
| 1045 | .set_settings = ks8695_wan_set_settings, | ||
| 1046 | .nway_reset = ks8695_wan_nwayreset, | ||
| 1047 | .get_link = ethtool_op_get_link, | ||
| 1048 | .get_pauseparam = ks8695_wan_get_pause, | ||
| 1149 | .get_drvinfo = ks8695_get_drvinfo, | 1049 | .get_drvinfo = ks8695_get_drvinfo, |
| 1150 | }; | 1050 | }; |
| 1151 | 1051 | ||
| @@ -1541,7 +1441,6 @@ ks8695_probe(struct platform_device *pdev) | |||
| 1541 | 1441 | ||
| 1542 | /* driver system setup */ | 1442 | /* driver system setup */ |
| 1543 | ndev->netdev_ops = &ks8695_netdev_ops; | 1443 | ndev->netdev_ops = &ks8695_netdev_ops; |
| 1544 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | ||
| 1545 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); | 1444 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); |
| 1546 | 1445 | ||
| 1547 | netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); | 1446 | netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); |
| @@ -1608,12 +1507,15 @@ ks8695_probe(struct platform_device *pdev) | |||
| 1608 | if (ksp->phyiface_regs && ksp->link_irq == -1) { | 1507 | if (ksp->phyiface_regs && ksp->link_irq == -1) { |
| 1609 | ks8695_init_switch(ksp); | 1508 | ks8695_init_switch(ksp); |
| 1610 | ksp->dtype = KS8695_DTYPE_LAN; | 1509 | ksp->dtype = KS8695_DTYPE_LAN; |
| 1510 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | ||
| 1611 | } else if (ksp->phyiface_regs && ksp->link_irq != -1) { | 1511 | } else if (ksp->phyiface_regs && ksp->link_irq != -1) { |
| 1612 | ks8695_init_wan_phy(ksp); | 1512 | ks8695_init_wan_phy(ksp); |
| 1613 | ksp->dtype = KS8695_DTYPE_WAN; | 1513 | ksp->dtype = KS8695_DTYPE_WAN; |
| 1514 | SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops); | ||
| 1614 | } else { | 1515 | } else { |
| 1615 | /* No initialisation since HPNA does not have a PHY */ | 1516 | /* No initialisation since HPNA does not have a PHY */ |
| 1616 | ksp->dtype = KS8695_DTYPE_HPNA; | 1517 | ksp->dtype = KS8695_DTYPE_HPNA; |
| 1518 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | ||
| 1617 | } | 1519 | } |
| 1618 | 1520 | ||
| 1619 | /* And bring up the net_device with the net core */ | 1521 | /* And bring up the net_device with the net core */ |
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 0b9fc5173aef..22abfb39d813 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
| @@ -1284,19 +1284,12 @@ static void bfin_mac_multicast_hash(struct net_device *dev) | |||
| 1284 | { | 1284 | { |
| 1285 | u32 emac_hashhi, emac_hashlo; | 1285 | u32 emac_hashhi, emac_hashlo; |
| 1286 | struct netdev_hw_addr *ha; | 1286 | struct netdev_hw_addr *ha; |
| 1287 | char *addrs; | ||
| 1288 | u32 crc; | 1287 | u32 crc; |
| 1289 | 1288 | ||
| 1290 | emac_hashhi = emac_hashlo = 0; | 1289 | emac_hashhi = emac_hashlo = 0; |
| 1291 | 1290 | ||
| 1292 | netdev_for_each_mc_addr(ha, dev) { | 1291 | netdev_for_each_mc_addr(ha, dev) { |
| 1293 | addrs = ha->addr; | 1292 | crc = ether_crc(ETH_ALEN, ha->addr); |
| 1294 | |||
| 1295 | /* skip non-multicast addresses */ | ||
| 1296 | if (!(*addrs & 1)) | ||
| 1297 | continue; | ||
| 1298 | |||
| 1299 | crc = ether_crc(ETH_ALEN, addrs); | ||
| 1300 | crc >>= 26; | 1293 | crc >>= 26; |
| 1301 | 1294 | ||
| 1302 | if (crc & 0x20) | 1295 | if (crc & 0x20) |
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index 99be5ae91991..142d6047da27 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c | |||
| @@ -275,7 +275,6 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | |||
| 275 | 275 | ||
| 276 | ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); | 276 | ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); |
| 277 | if (ioc_attr) { | 277 | if (ioc_attr) { |
| 278 | memset(ioc_attr, 0, sizeof(*ioc_attr)); | ||
| 279 | spin_lock_irqsave(&bnad->bna_lock, flags); | 278 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| 280 | bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr); | 279 | bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr); |
| 281 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | 280 | spin_unlock_irqrestore(&bnad->bna_lock, flags); |
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7206ab2cbbf8..3437613f0454 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
| @@ -3203,7 +3203,7 @@ static int cas_get_vpd_info(struct cas *cp, unsigned char *dev_addr, | |||
| 3203 | int phy_type = CAS_PHY_MII_MDIO0; /* default phy type */ | 3203 | int phy_type = CAS_PHY_MII_MDIO0; /* default phy type */ |
| 3204 | int mac_off = 0; | 3204 | int mac_off = 0; |
| 3205 | 3205 | ||
| 3206 | #if defined(CONFIG_OF) | 3206 | #if defined(CONFIG_SPARC) |
| 3207 | const unsigned char *addr; | 3207 | const unsigned char *addr; |
| 3208 | #endif | 3208 | #endif |
| 3209 | 3209 | ||
| @@ -3354,7 +3354,7 @@ use_random_mac_addr: | |||
| 3354 | if (found & VPD_FOUND_MAC) | 3354 | if (found & VPD_FOUND_MAC) |
| 3355 | goto done; | 3355 | goto done; |
| 3356 | 3356 | ||
| 3357 | #if defined(CONFIG_OF) | 3357 | #if defined(CONFIG_SPARC) |
| 3358 | addr = of_get_property(cp->of_node, "local-mac-address", NULL); | 3358 | addr = of_get_property(cp->of_node, "local-mac-address", NULL); |
| 3359 | if (addr != NULL) { | 3359 | if (addr != NULL) { |
| 3360 | memcpy(dev_addr, addr, 6); | 3360 | memcpy(dev_addr, addr, 6); |
| @@ -5031,7 +5031,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, | |||
| 5031 | cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE : | 5031 | cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE : |
| 5032 | cassini_debug; | 5032 | cassini_debug; |
| 5033 | 5033 | ||
| 5034 | #if defined(CONFIG_OF) | 5034 | #if defined(CONFIG_SPARC) |
| 5035 | cp->of_node = pci_device_to_OF_node(pdev); | 5035 | cp->of_node = pci_device_to_OF_node(pdev); |
| 5036 | #endif | 5036 | #endif |
| 5037 | 5037 | ||
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index de69c54301c1..bfab14092d2c 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -3478,9 +3478,17 @@ static irqreturn_t e1000_intr(int irq, void *data) | |||
| 3478 | struct e1000_hw *hw = &adapter->hw; | 3478 | struct e1000_hw *hw = &adapter->hw; |
| 3479 | u32 icr = er32(ICR); | 3479 | u32 icr = er32(ICR); |
| 3480 | 3480 | ||
| 3481 | if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags))) | 3481 | if (unlikely((!icr))) |
| 3482 | return IRQ_NONE; /* Not our interrupt */ | 3482 | return IRQ_NONE; /* Not our interrupt */ |
| 3483 | 3483 | ||
| 3484 | /* | ||
| 3485 | * we might have caused the interrupt, but the above | ||
| 3486 | * read cleared it, and just in case the driver is | ||
| 3487 | * down there is nothing to do so return handled | ||
| 3488 | */ | ||
| 3489 | if (unlikely(test_bit(__E1000_DOWN, &adapter->flags))) | ||
| 3490 | return IRQ_HANDLED; | ||
| 3491 | |||
| 3484 | if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { | 3492 | if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { |
| 3485 | hw->get_link_status = 1; | 3493 | hw->get_link_status = 1; |
| 3486 | /* guard against interrupt when we're going down */ | 3494 | /* guard against interrupt when we're going down */ |
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 1397da118f0d..89a69035e538 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
| @@ -1310,7 +1310,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) | |||
| 1310 | * apply workaround for hardware errata documented in errata | 1310 | * apply workaround for hardware errata documented in errata |
| 1311 | * docs Fixes issue where some error prone or unreliable PCIe | 1311 | * docs Fixes issue where some error prone or unreliable PCIe |
| 1312 | * completions are occurring, particularly with ASPM enabled. | 1312 | * completions are occurring, particularly with ASPM enabled. |
| 1313 | * Without fix, issue can cause tx timeouts. | 1313 | * Without fix, issue can cause Tx timeouts. |
| 1314 | */ | 1314 | */ |
| 1315 | reg = er32(GCR2); | 1315 | reg = er32(GCR2); |
| 1316 | reg |= 1; | 1316 | reg |= 1; |
diff --git a/drivers/net/e1000e/Makefile b/drivers/net/e1000e/Makefile index 360c91369f35..28519acacd2d 100644 --- a/drivers/net/e1000e/Makefile +++ b/drivers/net/e1000e/Makefile | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ################################################################################ | 1 | ################################################################################ |
| 2 | # | 2 | # |
| 3 | # Intel PRO/1000 Linux driver | 3 | # Intel PRO/1000 Linux driver |
| 4 | # Copyright(c) 1999 - 2008 Intel Corporation. | 4 | # Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | # | 5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify it | 6 | # This program is free software; you can redistribute it and/or modify it |
| 7 | # under the terms and conditions of the GNU General Public License, | 7 | # under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 7245dc2e0b7c..13149983d07e 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 5255be753746..e610e1369053 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index e45a61c8930a..2fefa820302b 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index f8ed03dab9b1..fa08b6336cfb 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index e774380c7cec..bc0860a598c9 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
| @@ -102,7 +102,7 @@ enum e1e_registers { | |||
| 102 | E1000_RDTR = 0x02820, /* Rx Delay Timer - RW */ | 102 | E1000_RDTR = 0x02820, /* Rx Delay Timer - RW */ |
| 103 | E1000_RXDCTL_BASE = 0x02828, /* Rx Descriptor Control - RW */ | 103 | E1000_RXDCTL_BASE = 0x02828, /* Rx Descriptor Control - RW */ |
| 104 | #define E1000_RXDCTL(_n) (E1000_RXDCTL_BASE + (_n << 8)) | 104 | #define E1000_RXDCTL(_n) (E1000_RXDCTL_BASE + (_n << 8)) |
| 105 | E1000_RADV = 0x0282C, /* RX Interrupt Absolute Delay Timer - RW */ | 105 | E1000_RADV = 0x0282C, /* Rx Interrupt Absolute Delay Timer - RW */ |
| 106 | 106 | ||
| 107 | /* Convenience macros | 107 | /* Convenience macros |
| 108 | * | 108 | * |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 5bb65b7382db..fb46974cfec1 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index ff2872153b21..68aa1749bf66 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
| @@ -533,7 +533,7 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) | |||
| 533 | mac->autoneg_failed = 1; | 533 | mac->autoneg_failed = 1; |
| 534 | return 0; | 534 | return 0; |
| 535 | } | 535 | } |
| 536 | e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n"); | 536 | e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); |
| 537 | 537 | ||
| 538 | /* Disable auto-negotiation in the TXCW register */ | 538 | /* Disable auto-negotiation in the TXCW register */ |
| 539 | ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); | 539 | ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); |
| @@ -556,7 +556,7 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) | |||
| 556 | * and disable forced link in the Device Control register | 556 | * and disable forced link in the Device Control register |
| 557 | * in an attempt to auto-negotiate with our link partner. | 557 | * in an attempt to auto-negotiate with our link partner. |
| 558 | */ | 558 | */ |
| 559 | e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n"); | 559 | e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); |
| 560 | ew32(TXCW, mac->txcw); | 560 | ew32(TXCW, mac->txcw); |
| 561 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); | 561 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); |
| 562 | 562 | ||
| @@ -598,7 +598,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) | |||
| 598 | mac->autoneg_failed = 1; | 598 | mac->autoneg_failed = 1; |
| 599 | return 0; | 599 | return 0; |
| 600 | } | 600 | } |
| 601 | e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n"); | 601 | e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); |
| 602 | 602 | ||
| 603 | /* Disable auto-negotiation in the TXCW register */ | 603 | /* Disable auto-negotiation in the TXCW register */ |
| 604 | ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); | 604 | ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); |
| @@ -621,7 +621,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) | |||
| 621 | * and disable forced link in the Device Control register | 621 | * and disable forced link in the Device Control register |
| 622 | * in an attempt to auto-negotiate with our link partner. | 622 | * in an attempt to auto-negotiate with our link partner. |
| 623 | */ | 623 | */ |
| 624 | e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n"); | 624 | e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); |
| 625 | ew32(TXCW, mac->txcw); | 625 | ew32(TXCW, mac->txcw); |
| 626 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); | 626 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); |
| 627 | 627 | ||
| @@ -800,9 +800,9 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) | |||
| 800 | * The possible values of the "fc" parameter are: | 800 | * The possible values of the "fc" parameter are: |
| 801 | * 0: Flow control is completely disabled | 801 | * 0: Flow control is completely disabled |
| 802 | * 1: Rx flow control is enabled (we can receive pause frames, | 802 | * 1: Rx flow control is enabled (we can receive pause frames, |
| 803 | * but not send pause frames). | 803 | * but not send pause frames). |
| 804 | * 2: Tx flow control is enabled (we can send pause frames but we | 804 | * 2: Tx flow control is enabled (we can send pause frames but we |
| 805 | * do not support receiving pause frames). | 805 | * do not support receiving pause frames). |
| 806 | * 3: Both Rx and Tx flow control (symmetric) are enabled. | 806 | * 3: Both Rx and Tx flow control (symmetric) are enabled. |
| 807 | */ | 807 | */ |
| 808 | switch (hw->fc.current_mode) { | 808 | switch (hw->fc.current_mode) { |
| @@ -1031,9 +1031,9 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw) | |||
| 1031 | * The possible values of the "fc" parameter are: | 1031 | * The possible values of the "fc" parameter are: |
| 1032 | * 0: Flow control is completely disabled | 1032 | * 0: Flow control is completely disabled |
| 1033 | * 1: Rx flow control is enabled (we can receive pause | 1033 | * 1: Rx flow control is enabled (we can receive pause |
| 1034 | * frames but not send pause frames). | 1034 | * frames but not send pause frames). |
| 1035 | * 2: Tx flow control is enabled (we can send pause frames | 1035 | * 2: Tx flow control is enabled (we can send pause frames |
| 1036 | * frames but we do not receive pause frames). | 1036 | * frames but we do not receive pause frames). |
| 1037 | * 3: Both Rx and Tx flow control (symmetric) is enabled. | 1037 | * 3: Both Rx and Tx flow control (symmetric) is enabled. |
| 1038 | * other: No other values should be possible at this point. | 1038 | * other: No other values should be possible at this point. |
| 1039 | */ | 1039 | */ |
| @@ -1189,7 +1189,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) | |||
| 1189 | } else { | 1189 | } else { |
| 1190 | hw->fc.current_mode = e1000_fc_rx_pause; | 1190 | hw->fc.current_mode = e1000_fc_rx_pause; |
| 1191 | e_dbg("Flow Control = " | 1191 | e_dbg("Flow Control = " |
| 1192 | "RX PAUSE frames only.\r\n"); | 1192 | "Rx PAUSE frames only.\r\n"); |
| 1193 | } | 1193 | } |
| 1194 | } | 1194 | } |
| 1195 | /* | 1195 | /* |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index fa5b60452547..1c18f26b0812 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
| @@ -77,17 +77,17 @@ struct e1000_reg_info { | |||
| 77 | char *name; | 77 | char *name; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | #define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */ | 80 | #define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */ |
| 81 | #define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */ | 81 | #define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */ |
| 82 | #define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */ | 82 | #define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */ |
| 83 | #define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */ | 83 | #define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */ |
| 84 | #define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */ | 84 | #define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */ |
| 85 | 85 | ||
| 86 | #define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */ | 86 | #define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */ |
| 87 | #define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */ | 87 | #define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */ |
| 88 | #define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */ | 88 | #define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */ |
| 89 | #define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */ | 89 | #define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */ |
| 90 | #define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */ | 90 | #define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */ |
| 91 | 91 | ||
| 92 | static const struct e1000_reg_info e1000_reg_info_tbl[] = { | 92 | static const struct e1000_reg_info e1000_reg_info_tbl[] = { |
| 93 | 93 | ||
| @@ -99,7 +99,7 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = { | |||
| 99 | /* Interrupt Registers */ | 99 | /* Interrupt Registers */ |
| 100 | {E1000_ICR, "ICR"}, | 100 | {E1000_ICR, "ICR"}, |
| 101 | 101 | ||
| 102 | /* RX Registers */ | 102 | /* Rx Registers */ |
| 103 | {E1000_RCTL, "RCTL"}, | 103 | {E1000_RCTL, "RCTL"}, |
| 104 | {E1000_RDLEN, "RDLEN"}, | 104 | {E1000_RDLEN, "RDLEN"}, |
| 105 | {E1000_RDH, "RDH"}, | 105 | {E1000_RDH, "RDH"}, |
| @@ -115,7 +115,7 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = { | |||
| 115 | {E1000_RDFTS, "RDFTS"}, | 115 | {E1000_RDFTS, "RDFTS"}, |
| 116 | {E1000_RDFPC, "RDFPC"}, | 116 | {E1000_RDFPC, "RDFPC"}, |
| 117 | 117 | ||
| 118 | /* TX Registers */ | 118 | /* Tx Registers */ |
| 119 | {E1000_TCTL, "TCTL"}, | 119 | {E1000_TCTL, "TCTL"}, |
| 120 | {E1000_TDBAL, "TDBAL"}, | 120 | {E1000_TDBAL, "TDBAL"}, |
| 121 | {E1000_TDBAH, "TDBAH"}, | 121 | {E1000_TDBAH, "TDBAH"}, |
| @@ -160,7 +160,7 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) | |||
| 160 | break; | 160 | break; |
| 161 | default: | 161 | default: |
| 162 | printk(KERN_INFO "%-15s %08x\n", | 162 | printk(KERN_INFO "%-15s %08x\n", |
| 163 | reginfo->name, __er32(hw, reginfo->ofs)); | 163 | reginfo->name, __er32(hw, reginfo->ofs)); |
| 164 | return; | 164 | return; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| @@ -171,9 +171,8 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) | |||
| 171 | printk(KERN_CONT "\n"); | 171 | printk(KERN_CONT "\n"); |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | |||
| 175 | /* | 174 | /* |
| 176 | * e1000e_dump - Print registers, tx-ring and rx-ring | 175 | * e1000e_dump - Print registers, Tx-ring and Rx-ring |
| 177 | */ | 176 | */ |
| 178 | static void e1000e_dump(struct e1000_adapter *adapter) | 177 | static void e1000e_dump(struct e1000_adapter *adapter) |
| 179 | { | 178 | { |
| @@ -182,12 +181,20 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
| 182 | struct e1000_reg_info *reginfo; | 181 | struct e1000_reg_info *reginfo; |
| 183 | struct e1000_ring *tx_ring = adapter->tx_ring; | 182 | struct e1000_ring *tx_ring = adapter->tx_ring; |
| 184 | struct e1000_tx_desc *tx_desc; | 183 | struct e1000_tx_desc *tx_desc; |
| 185 | struct my_u0 { u64 a; u64 b; } *u0; | 184 | struct my_u0 { |
| 185 | u64 a; | ||
| 186 | u64 b; | ||
| 187 | } *u0; | ||
| 186 | struct e1000_buffer *buffer_info; | 188 | struct e1000_buffer *buffer_info; |
| 187 | struct e1000_ring *rx_ring = adapter->rx_ring; | 189 | struct e1000_ring *rx_ring = adapter->rx_ring; |
| 188 | union e1000_rx_desc_packet_split *rx_desc_ps; | 190 | union e1000_rx_desc_packet_split *rx_desc_ps; |
| 189 | struct e1000_rx_desc *rx_desc; | 191 | struct e1000_rx_desc *rx_desc; |
| 190 | struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1; | 192 | struct my_u1 { |
| 193 | u64 a; | ||
| 194 | u64 b; | ||
| 195 | u64 c; | ||
| 196 | u64 d; | ||
| 197 | } *u1; | ||
| 191 | u32 staterr; | 198 | u32 staterr; |
| 192 | int i = 0; | 199 | int i = 0; |
| 193 | 200 | ||
| @@ -198,12 +205,10 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
| 198 | if (netdev) { | 205 | if (netdev) { |
| 199 | dev_info(&adapter->pdev->dev, "Net device Info\n"); | 206 | dev_info(&adapter->pdev->dev, "Net device Info\n"); |
| 200 | printk(KERN_INFO "Device Name state " | 207 | printk(KERN_INFO "Device Name state " |
| 201 | "trans_start last_rx\n"); | 208 | "trans_start last_rx\n"); |
| 202 | printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", | 209 | printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", |
| 203 | netdev->name, | 210 | netdev->name, netdev->state, netdev->trans_start, |
| 204 | netdev->state, | 211 | netdev->last_rx); |
| 205 | netdev->trans_start, | ||
| 206 | netdev->last_rx); | ||
| 207 | } | 212 | } |
| 208 | 213 | ||
| 209 | /* Print Registers */ | 214 | /* Print Registers */ |
| @@ -214,26 +219,26 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
| 214 | e1000_regdump(hw, reginfo); | 219 | e1000_regdump(hw, reginfo); |
| 215 | } | 220 | } |
| 216 | 221 | ||
| 217 | /* Print TX Ring Summary */ | 222 | /* Print Tx Ring Summary */ |
| 218 | if (!netdev || !netif_running(netdev)) | 223 | if (!netdev || !netif_running(netdev)) |
| 219 | goto exit; | 224 | goto exit; |
| 220 | 225 | ||
| 221 | dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); | 226 | dev_info(&adapter->pdev->dev, "Tx Ring Summary\n"); |
| 222 | printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]" | 227 | printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]" |
| 223 | " leng ntw timestamp\n"); | 228 | " leng ntw timestamp\n"); |
| 224 | buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; | 229 | buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; |
| 225 | printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", | 230 | printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", |
| 226 | 0, tx_ring->next_to_use, tx_ring->next_to_clean, | 231 | 0, tx_ring->next_to_use, tx_ring->next_to_clean, |
| 227 | (unsigned long long)buffer_info->dma, | 232 | (unsigned long long)buffer_info->dma, |
| 228 | buffer_info->length, | 233 | buffer_info->length, |
| 229 | buffer_info->next_to_watch, | 234 | buffer_info->next_to_watch, |
| 230 | (unsigned long long)buffer_info->time_stamp); | 235 | (unsigned long long)buffer_info->time_stamp); |
| 231 | 236 | ||
| 232 | /* Print TX Rings */ | 237 | /* Print Tx Ring */ |
| 233 | if (!netif_msg_tx_done(adapter)) | 238 | if (!netif_msg_tx_done(adapter)) |
| 234 | goto rx_ring_summary; | 239 | goto rx_ring_summary; |
| 235 | 240 | ||
| 236 | dev_info(&adapter->pdev->dev, "TX Rings Dump\n"); | 241 | dev_info(&adapter->pdev->dev, "Tx Ring Dump\n"); |
| 237 | 242 | ||
| 238 | /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended) | 243 | /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended) |
| 239 | * | 244 | * |
| @@ -263,22 +268,22 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
| 263 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 | 268 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 |
| 264 | */ | 269 | */ |
| 265 | printk(KERN_INFO "Tl[desc] [address 63:0 ] [SpeCssSCmCsLen]" | 270 | printk(KERN_INFO "Tl[desc] [address 63:0 ] [SpeCssSCmCsLen]" |
| 266 | " [bi->dma ] leng ntw timestamp bi->skb " | 271 | " [bi->dma ] leng ntw timestamp bi->skb " |
| 267 | "<-- Legacy format\n"); | 272 | "<-- Legacy format\n"); |
| 268 | printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen]" | 273 | printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen]" |
| 269 | " [bi->dma ] leng ntw timestamp bi->skb " | 274 | " [bi->dma ] leng ntw timestamp bi->skb " |
| 270 | "<-- Ext Context format\n"); | 275 | "<-- Ext Context format\n"); |
| 271 | printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen]" | 276 | printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen]" |
| 272 | " [bi->dma ] leng ntw timestamp bi->skb " | 277 | " [bi->dma ] leng ntw timestamp bi->skb " |
| 273 | "<-- Ext Data format\n"); | 278 | "<-- Ext Data format\n"); |
| 274 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { | 279 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { |
| 275 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 280 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
| 276 | buffer_info = &tx_ring->buffer_info[i]; | 281 | buffer_info = &tx_ring->buffer_info[i]; |
| 277 | u0 = (struct my_u0 *)tx_desc; | 282 | u0 = (struct my_u0 *)tx_desc; |
| 278 | printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX " | 283 | printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX " |
| 279 | "%04X %3X %016llX %p", | 284 | "%04X %3X %016llX %p", |
| 280 | (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' : | 285 | (!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' : |
| 281 | ((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i, | 286 | ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')), i, |
| 282 | (unsigned long long)le64_to_cpu(u0->a), | 287 | (unsigned long long)le64_to_cpu(u0->a), |
| 283 | (unsigned long long)le64_to_cpu(u0->b), | 288 | (unsigned long long)le64_to_cpu(u0->b), |
| 284 | (unsigned long long)buffer_info->dma, | 289 | (unsigned long long)buffer_info->dma, |
| @@ -296,22 +301,22 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
| 296 | 301 | ||
| 297 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 302 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) |
| 298 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | 303 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, |
| 299 | 16, 1, phys_to_virt(buffer_info->dma), | 304 | 16, 1, phys_to_virt(buffer_info->dma), |
| 300 | buffer_info->length, true); | 305 | buffer_info->length, true); |
| 301 | } | 306 | } |
| 302 | 307 | ||
| 303 | /* Print RX Rings Summary */ | 308 | /* Print Rx Ring Summary */ |
| 304 | rx_ring_summary: | 309 | rx_ring_summary: |
| 305 | dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); | 310 | dev_info(&adapter->pdev->dev, "Rx Ring Summary\n"); |
| 306 | printk(KERN_INFO "Queue [NTU] [NTC]\n"); | 311 | printk(KERN_INFO "Queue [NTU] [NTC]\n"); |
| 307 | printk(KERN_INFO " %5d %5X %5X\n", 0, | 312 | printk(KERN_INFO " %5d %5X %5X\n", 0, |
| 308 | rx_ring->next_to_use, rx_ring->next_to_clean); | 313 | rx_ring->next_to_use, rx_ring->next_to_clean); |
| 309 | 314 | ||
| 310 | /* Print RX Rings */ | 315 | /* Print Rx Ring */ |
| 311 | if (!netif_msg_rx_status(adapter)) | 316 | if (!netif_msg_rx_status(adapter)) |
| 312 | goto exit; | 317 | goto exit; |
| 313 | 318 | ||
| 314 | dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); | 319 | dev_info(&adapter->pdev->dev, "Rx Ring Dump\n"); |
| 315 | switch (adapter->rx_ps_pages) { | 320 | switch (adapter->rx_ps_pages) { |
| 316 | case 1: | 321 | case 1: |
| 317 | case 2: | 322 | case 2: |
| @@ -329,7 +334,7 @@ rx_ring_summary: | |||
| 329 | * +-----------------------------------------------------+ | 334 | * +-----------------------------------------------------+ |
| 330 | */ | 335 | */ |
| 331 | printk(KERN_INFO "R [desc] [buffer 0 63:0 ] " | 336 | printk(KERN_INFO "R [desc] [buffer 0 63:0 ] " |
| 332 | "[buffer 1 63:0 ] " | 337 | "[buffer 1 63:0 ] " |
| 333 | "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] " | 338 | "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] " |
| 334 | "[bi->skb] <-- Ext Pkt Split format\n"); | 339 | "[bi->skb] <-- Ext Pkt Split format\n"); |
| 335 | /* [Extended] Receive Descriptor (Write-Back) Format | 340 | /* [Extended] Receive Descriptor (Write-Back) Format |
| @@ -344,7 +349,7 @@ rx_ring_summary: | |||
| 344 | * 63 48 47 32 31 20 19 0 | 349 | * 63 48 47 32 31 20 19 0 |
| 345 | */ | 350 | */ |
| 346 | printk(KERN_INFO "RWB[desc] [ck ipid mrqhsh] " | 351 | printk(KERN_INFO "RWB[desc] [ck ipid mrqhsh] " |
| 347 | "[vl l0 ee es] " | 352 | "[vl l0 ee es] " |
| 348 | "[ l3 l2 l1 hs] [reserved ] ---------------- " | 353 | "[ l3 l2 l1 hs] [reserved ] ---------------- " |
| 349 | "[bi->skb] <-- Ext Rx Write-Back format\n"); | 354 | "[bi->skb] <-- Ext Rx Write-Back format\n"); |
| 350 | for (i = 0; i < rx_ring->count; i++) { | 355 | for (i = 0; i < rx_ring->count; i++) { |
| @@ -352,26 +357,26 @@ rx_ring_summary: | |||
| 352 | rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i); | 357 | rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i); |
| 353 | u1 = (struct my_u1 *)rx_desc_ps; | 358 | u1 = (struct my_u1 *)rx_desc_ps; |
| 354 | staterr = | 359 | staterr = |
| 355 | le32_to_cpu(rx_desc_ps->wb.middle.status_error); | 360 | le32_to_cpu(rx_desc_ps->wb.middle.status_error); |
| 356 | if (staterr & E1000_RXD_STAT_DD) { | 361 | if (staterr & E1000_RXD_STAT_DD) { |
| 357 | /* Descriptor Done */ | 362 | /* Descriptor Done */ |
| 358 | printk(KERN_INFO "RWB[0x%03X] %016llX " | 363 | printk(KERN_INFO "RWB[0x%03X] %016llX " |
| 359 | "%016llX %016llX %016llX " | 364 | "%016llX %016llX %016llX " |
| 360 | "---------------- %p", i, | 365 | "---------------- %p", i, |
| 361 | (unsigned long long)le64_to_cpu(u1->a), | 366 | (unsigned long long)le64_to_cpu(u1->a), |
| 362 | (unsigned long long)le64_to_cpu(u1->b), | 367 | (unsigned long long)le64_to_cpu(u1->b), |
| 363 | (unsigned long long)le64_to_cpu(u1->c), | 368 | (unsigned long long)le64_to_cpu(u1->c), |
| 364 | (unsigned long long)le64_to_cpu(u1->d), | 369 | (unsigned long long)le64_to_cpu(u1->d), |
| 365 | buffer_info->skb); | 370 | buffer_info->skb); |
| 366 | } else { | 371 | } else { |
| 367 | printk(KERN_INFO "R [0x%03X] %016llX " | 372 | printk(KERN_INFO "R [0x%03X] %016llX " |
| 368 | "%016llX %016llX %016llX %016llX %p", i, | 373 | "%016llX %016llX %016llX %016llX %p", i, |
| 369 | (unsigned long long)le64_to_cpu(u1->a), | 374 | (unsigned long long)le64_to_cpu(u1->a), |
| 370 | (unsigned long long)le64_to_cpu(u1->b), | 375 | (unsigned long long)le64_to_cpu(u1->b), |
| 371 | (unsigned long long)le64_to_cpu(u1->c), | 376 | (unsigned long long)le64_to_cpu(u1->c), |
| 372 | (unsigned long long)le64_to_cpu(u1->d), | 377 | (unsigned long long)le64_to_cpu(u1->d), |
| 373 | (unsigned long long)buffer_info->dma, | 378 | (unsigned long long)buffer_info->dma, |
| 374 | buffer_info->skb); | 379 | buffer_info->skb); |
| 375 | 380 | ||
| 376 | if (netif_msg_pktdata(adapter)) | 381 | if (netif_msg_pktdata(adapter)) |
| 377 | print_hex_dump(KERN_INFO, "", | 382 | print_hex_dump(KERN_INFO, "", |
| @@ -400,18 +405,18 @@ rx_ring_summary: | |||
| 400 | * 63 48 47 40 39 32 31 16 15 0 | 405 | * 63 48 47 40 39 32 31 16 15 0 |
| 401 | */ | 406 | */ |
| 402 | printk(KERN_INFO "Rl[desc] [address 63:0 ] " | 407 | printk(KERN_INFO "Rl[desc] [address 63:0 ] " |
| 403 | "[vl er S cks ln] [bi->dma ] [bi->skb] " | 408 | "[vl er S cks ln] [bi->dma ] [bi->skb] " |
| 404 | "<-- Legacy format\n"); | 409 | "<-- Legacy format\n"); |
| 405 | for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { | 410 | for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { |
| 406 | rx_desc = E1000_RX_DESC(*rx_ring, i); | 411 | rx_desc = E1000_RX_DESC(*rx_ring, i); |
| 407 | buffer_info = &rx_ring->buffer_info[i]; | 412 | buffer_info = &rx_ring->buffer_info[i]; |
| 408 | u0 = (struct my_u0 *)rx_desc; | 413 | u0 = (struct my_u0 *)rx_desc; |
| 409 | printk(KERN_INFO "Rl[0x%03X] %016llX %016llX " | 414 | printk(KERN_INFO "Rl[0x%03X] %016llX %016llX " |
| 410 | "%016llX %p", i, | 415 | "%016llX %p", i, |
| 411 | (unsigned long long)le64_to_cpu(u0->a), | 416 | (unsigned long long)le64_to_cpu(u0->a), |
| 412 | (unsigned long long)le64_to_cpu(u0->b), | 417 | (unsigned long long)le64_to_cpu(u0->b), |
| 413 | (unsigned long long)buffer_info->dma, | 418 | (unsigned long long)buffer_info->dma, |
| 414 | buffer_info->skb); | 419 | buffer_info->skb); |
| 415 | if (i == rx_ring->next_to_use) | 420 | if (i == rx_ring->next_to_use) |
| 416 | printk(KERN_CONT " NTU\n"); | 421 | printk(KERN_CONT " NTU\n"); |
| 417 | else if (i == rx_ring->next_to_clean) | 422 | else if (i == rx_ring->next_to_clean) |
| @@ -421,9 +426,10 @@ rx_ring_summary: | |||
| 421 | 426 | ||
| 422 | if (netif_msg_pktdata(adapter)) | 427 | if (netif_msg_pktdata(adapter)) |
| 423 | print_hex_dump(KERN_INFO, "", | 428 | print_hex_dump(KERN_INFO, "", |
| 424 | DUMP_PREFIX_ADDRESS, | 429 | DUMP_PREFIX_ADDRESS, |
| 425 | 16, 1, phys_to_virt(buffer_info->dma), | 430 | 16, 1, |
| 426 | adapter->rx_buffer_len, true); | 431 | phys_to_virt(buffer_info->dma), |
| 432 | adapter->rx_buffer_len, true); | ||
| 427 | } | 433 | } |
| 428 | } | 434 | } |
| 429 | 435 | ||
| @@ -450,8 +456,7 @@ static int e1000_desc_unused(struct e1000_ring *ring) | |||
| 450 | * @skb: pointer to sk_buff to be indicated to stack | 456 | * @skb: pointer to sk_buff to be indicated to stack |
| 451 | **/ | 457 | **/ |
| 452 | static void e1000_receive_skb(struct e1000_adapter *adapter, | 458 | static void e1000_receive_skb(struct e1000_adapter *adapter, |
| 453 | struct net_device *netdev, | 459 | struct net_device *netdev, struct sk_buff *skb, |
| 454 | struct sk_buff *skb, | ||
| 455 | u8 status, __le16 vlan) | 460 | u8 status, __le16 vlan) |
| 456 | { | 461 | { |
| 457 | skb->protocol = eth_type_trans(skb, netdev); | 462 | skb->protocol = eth_type_trans(skb, netdev); |
| @@ -464,7 +469,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, | |||
| 464 | } | 469 | } |
| 465 | 470 | ||
| 466 | /** | 471 | /** |
| 467 | * e1000_rx_checksum - Receive Checksum Offload for 82543 | 472 | * e1000_rx_checksum - Receive Checksum Offload |
| 468 | * @adapter: board private structure | 473 | * @adapter: board private structure |
| 469 | * @status_err: receive descriptor status and error fields | 474 | * @status_err: receive descriptor status and error fields |
| 470 | * @csum: receive descriptor csum field | 475 | * @csum: receive descriptor csum field |
| @@ -548,7 +553,7 @@ map_skb: | |||
| 548 | adapter->rx_buffer_len, | 553 | adapter->rx_buffer_len, |
| 549 | DMA_FROM_DEVICE); | 554 | DMA_FROM_DEVICE); |
| 550 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { | 555 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { |
| 551 | dev_err(&pdev->dev, "RX DMA map failed\n"); | 556 | dev_err(&pdev->dev, "Rx DMA map failed\n"); |
| 552 | adapter->rx_dma_failed++; | 557 | adapter->rx_dma_failed++; |
| 553 | break; | 558 | break; |
| 554 | } | 559 | } |
| @@ -601,7 +606,8 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, | |||
| 601 | ps_page = &buffer_info->ps_pages[j]; | 606 | ps_page = &buffer_info->ps_pages[j]; |
| 602 | if (j >= adapter->rx_ps_pages) { | 607 | if (j >= adapter->rx_ps_pages) { |
| 603 | /* all unused desc entries get hw null ptr */ | 608 | /* all unused desc entries get hw null ptr */ |
| 604 | rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0); | 609 | rx_desc->read.buffer_addr[j + 1] = |
| 610 | ~cpu_to_le64(0); | ||
| 605 | continue; | 611 | continue; |
| 606 | } | 612 | } |
| 607 | if (!ps_page->page) { | 613 | if (!ps_page->page) { |
| @@ -617,7 +623,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, | |||
| 617 | if (dma_mapping_error(&pdev->dev, | 623 | if (dma_mapping_error(&pdev->dev, |
| 618 | ps_page->dma)) { | 624 | ps_page->dma)) { |
| 619 | dev_err(&adapter->pdev->dev, | 625 | dev_err(&adapter->pdev->dev, |
| 620 | "RX DMA page map failed\n"); | 626 | "Rx DMA page map failed\n"); |
| 621 | adapter->rx_dma_failed++; | 627 | adapter->rx_dma_failed++; |
| 622 | goto no_buffers; | 628 | goto no_buffers; |
| 623 | } | 629 | } |
| @@ -627,8 +633,8 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, | |||
| 627 | * didn't change because each write-back | 633 | * didn't change because each write-back |
| 628 | * erases this info. | 634 | * erases this info. |
| 629 | */ | 635 | */ |
| 630 | rx_desc->read.buffer_addr[j+1] = | 636 | rx_desc->read.buffer_addr[j + 1] = |
| 631 | cpu_to_le64(ps_page->dma); | 637 | cpu_to_le64(ps_page->dma); |
| 632 | } | 638 | } |
| 633 | 639 | ||
| 634 | skb = netdev_alloc_skb_ip_align(netdev, | 640 | skb = netdev_alloc_skb_ip_align(netdev, |
| @@ -644,7 +650,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, | |||
| 644 | adapter->rx_ps_bsize0, | 650 | adapter->rx_ps_bsize0, |
| 645 | DMA_FROM_DEVICE); | 651 | DMA_FROM_DEVICE); |
| 646 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { | 652 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { |
| 647 | dev_err(&pdev->dev, "RX DMA map failed\n"); | 653 | dev_err(&pdev->dev, "Rx DMA map failed\n"); |
| 648 | adapter->rx_dma_failed++; | 654 | adapter->rx_dma_failed++; |
| 649 | /* cleanup skb */ | 655 | /* cleanup skb */ |
| 650 | dev_kfree_skb_any(skb); | 656 | dev_kfree_skb_any(skb); |
| @@ -662,7 +668,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, | |||
| 662 | * such as IA-64). | 668 | * such as IA-64). |
| 663 | */ | 669 | */ |
| 664 | wmb(); | 670 | wmb(); |
| 665 | writel(i<<1, adapter->hw.hw_addr + rx_ring->tail); | 671 | writel(i << 1, adapter->hw.hw_addr + rx_ring->tail); |
| 666 | } | 672 | } |
| 667 | 673 | ||
| 668 | i++; | 674 | i++; |
| @@ -1106,11 +1112,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
| 1106 | cleaned = 1; | 1112 | cleaned = 1; |
| 1107 | cleaned_count++; | 1113 | cleaned_count++; |
| 1108 | dma_unmap_single(&pdev->dev, buffer_info->dma, | 1114 | dma_unmap_single(&pdev->dev, buffer_info->dma, |
| 1109 | adapter->rx_ps_bsize0, | 1115 | adapter->rx_ps_bsize0, DMA_FROM_DEVICE); |
| 1110 | DMA_FROM_DEVICE); | ||
| 1111 | buffer_info->dma = 0; | 1116 | buffer_info->dma = 0; |
| 1112 | 1117 | ||
| 1113 | /* see !EOP comment in other rx routine */ | 1118 | /* see !EOP comment in other Rx routine */ |
| 1114 | if (!(staterr & E1000_RXD_STAT_EOP)) | 1119 | if (!(staterr & E1000_RXD_STAT_EOP)) |
| 1115 | adapter->flags2 |= FLAG2_IS_DISCARDING; | 1120 | adapter->flags2 |= FLAG2_IS_DISCARDING; |
| 1116 | 1121 | ||
| @@ -2610,7 +2615,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter) | |||
| 2610 | } | 2615 | } |
| 2611 | 2616 | ||
| 2612 | /** | 2617 | /** |
| 2613 | * e1000_configure_tx - Configure 8254x Transmit Unit after Reset | 2618 | * e1000_configure_tx - Configure Transmit Unit after Reset |
| 2614 | * @adapter: board private structure | 2619 | * @adapter: board private structure |
| 2615 | * | 2620 | * |
| 2616 | * Configure the Tx unit of the MAC after a reset. | 2621 | * Configure the Tx unit of the MAC after a reset. |
| @@ -2663,7 +2668,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) | |||
| 2663 | * hthresh = 1 ==> prefetch when one or more available | 2668 | * hthresh = 1 ==> prefetch when one or more available |
| 2664 | * pthresh = 0x1f ==> prefetch if internal cache 31 or less | 2669 | * pthresh = 0x1f ==> prefetch if internal cache 31 or less |
| 2665 | * BEWARE: this seems to work but should be considered first if | 2670 | * BEWARE: this seems to work but should be considered first if |
| 2666 | * there are tx hangs or other tx related bugs | 2671 | * there are Tx hangs or other Tx related bugs |
| 2667 | */ | 2672 | */ |
| 2668 | txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE; | 2673 | txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE; |
| 2669 | ew32(TXDCTL(0), txdctl); | 2674 | ew32(TXDCTL(0), txdctl); |
| @@ -2877,7 +2882,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
| 2877 | if (adapter->rx_ps_pages) { | 2882 | if (adapter->rx_ps_pages) { |
| 2878 | /* this is a 32 byte descriptor */ | 2883 | /* this is a 32 byte descriptor */ |
| 2879 | rdlen = rx_ring->count * | 2884 | rdlen = rx_ring->count * |
| 2880 | sizeof(union e1000_rx_desc_packet_split); | 2885 | sizeof(union e1000_rx_desc_packet_split); |
| 2881 | adapter->clean_rx = e1000_clean_rx_irq_ps; | 2886 | adapter->clean_rx = e1000_clean_rx_irq_ps; |
| 2882 | adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; | 2887 | adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; |
| 2883 | } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) { | 2888 | } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) { |
| @@ -2900,7 +2905,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
| 2900 | /* | 2905 | /* |
| 2901 | * set the writeback threshold (only takes effect if the RDTR | 2906 | * set the writeback threshold (only takes effect if the RDTR |
| 2902 | * is set). set GRAN=1 and write back up to 0x4 worth, and | 2907 | * is set). set GRAN=1 and write back up to 0x4 worth, and |
| 2903 | * enable prefetching of 0x20 rx descriptors | 2908 | * enable prefetching of 0x20 Rx descriptors |
| 2904 | * granularity = 01 | 2909 | * granularity = 01 |
| 2905 | * wthresh = 04, | 2910 | * wthresh = 04, |
| 2906 | * hthresh = 04, | 2911 | * hthresh = 04, |
| @@ -2981,12 +2986,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
| 2981 | * excessive C-state transition latencies result in | 2986 | * excessive C-state transition latencies result in |
| 2982 | * dropped transactions. | 2987 | * dropped transactions. |
| 2983 | */ | 2988 | */ |
| 2984 | pm_qos_update_request( | 2989 | pm_qos_update_request(&adapter->netdev->pm_qos_req, 55); |
| 2985 | &adapter->netdev->pm_qos_req, 55); | ||
| 2986 | } else { | 2990 | } else { |
| 2987 | pm_qos_update_request( | 2991 | pm_qos_update_request(&adapter->netdev->pm_qos_req, |
| 2988 | &adapter->netdev->pm_qos_req, | 2992 | PM_QOS_DEFAULT_VALUE); |
| 2989 | PM_QOS_DEFAULT_VALUE); | ||
| 2990 | } | 2993 | } |
| 2991 | } | 2994 | } |
| 2992 | 2995 | ||
| @@ -3152,7 +3155,7 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
| 3152 | /* lower 16 bits has Rx packet buffer allocation size in KB */ | 3155 | /* lower 16 bits has Rx packet buffer allocation size in KB */ |
| 3153 | pba &= 0xffff; | 3156 | pba &= 0xffff; |
| 3154 | /* | 3157 | /* |
| 3155 | * the Tx fifo also stores 16 bytes of information about the tx | 3158 | * the Tx fifo also stores 16 bytes of information about the Tx |
| 3156 | * but don't include ethernet FCS because hardware appends it | 3159 | * but don't include ethernet FCS because hardware appends it |
| 3157 | */ | 3160 | */ |
| 3158 | min_tx_space = (adapter->max_frame_size + | 3161 | min_tx_space = (adapter->max_frame_size + |
| @@ -3175,7 +3178,7 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
| 3175 | pba -= min_tx_space - tx_space; | 3178 | pba -= min_tx_space - tx_space; |
| 3176 | 3179 | ||
| 3177 | /* | 3180 | /* |
| 3178 | * if short on Rx space, Rx wins and must trump tx | 3181 | * if short on Rx space, Rx wins and must trump Tx |
| 3179 | * adjustment or use Early Receive if available | 3182 | * adjustment or use Early Receive if available |
| 3180 | */ | 3183 | */ |
| 3181 | if ((pba < min_rx_space) && | 3184 | if ((pba < min_rx_space) && |
| @@ -4039,11 +4042,11 @@ static void e1000_print_link_info(struct e1000_adapter *adapter) | |||
| 4039 | adapter->netdev->name, | 4042 | adapter->netdev->name, |
| 4040 | adapter->link_speed, | 4043 | adapter->link_speed, |
| 4041 | (adapter->link_duplex == FULL_DUPLEX) ? | 4044 | (adapter->link_duplex == FULL_DUPLEX) ? |
| 4042 | "Full Duplex" : "Half Duplex", | 4045 | "Full Duplex" : "Half Duplex", |
| 4043 | ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? | 4046 | ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? |
| 4044 | "RX/TX" : | 4047 | "Rx/Tx" : |
| 4045 | ((ctrl & E1000_CTRL_RFCE) ? "RX" : | 4048 | ((ctrl & E1000_CTRL_RFCE) ? "Rx" : |
| 4046 | ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" ))); | 4049 | ((ctrl & E1000_CTRL_TFCE) ? "Tx" : "None"))); |
| 4047 | } | 4050 | } |
| 4048 | 4051 | ||
| 4049 | static bool e1000e_has_link(struct e1000_adapter *adapter) | 4052 | static bool e1000e_has_link(struct e1000_adapter *adapter) |
| @@ -4338,7 +4341,7 @@ link_up: | |||
| 4338 | /* Force detection of hung controller every watchdog period */ | 4341 | /* Force detection of hung controller every watchdog period */ |
| 4339 | adapter->detect_tx_hung = 1; | 4342 | adapter->detect_tx_hung = 1; |
| 4340 | 4343 | ||
| 4341 | /* flush partial descriptors to memory before detecting tx hang */ | 4344 | /* flush partial descriptors to memory before detecting Tx hang */ |
| 4342 | if (adapter->flags2 & FLAG2_DMA_BURST) { | 4345 | if (adapter->flags2 & FLAG2_DMA_BURST) { |
| 4343 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | 4346 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); |
| 4344 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | 4347 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); |
| @@ -4529,7 +4532,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
| 4529 | buffer_info->next_to_watch = i; | 4532 | buffer_info->next_to_watch = i; |
| 4530 | buffer_info->dma = dma_map_single(&pdev->dev, | 4533 | buffer_info->dma = dma_map_single(&pdev->dev, |
| 4531 | skb->data + offset, | 4534 | skb->data + offset, |
| 4532 | size, DMA_TO_DEVICE); | 4535 | size, DMA_TO_DEVICE); |
| 4533 | buffer_info->mapped_as_page = false; | 4536 | buffer_info->mapped_as_page = false; |
| 4534 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) | 4537 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) |
| 4535 | goto dma_error; | 4538 | goto dma_error; |
| @@ -4576,7 +4579,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
| 4576 | } | 4579 | } |
| 4577 | } | 4580 | } |
| 4578 | 4581 | ||
| 4579 | segs = skb_shinfo(skb)->gso_segs ?: 1; | 4582 | segs = skb_shinfo(skb)->gso_segs ? : 1; |
| 4580 | /* multiply data chunks by size of headers */ | 4583 | /* multiply data chunks by size of headers */ |
| 4581 | bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len; | 4584 | bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len; |
| 4582 | 4585 | ||
| @@ -4588,13 +4591,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
| 4588 | return count; | 4591 | return count; |
| 4589 | 4592 | ||
| 4590 | dma_error: | 4593 | dma_error: |
| 4591 | dev_err(&pdev->dev, "TX DMA map failed\n"); | 4594 | dev_err(&pdev->dev, "Tx DMA map failed\n"); |
| 4592 | buffer_info->dma = 0; | 4595 | buffer_info->dma = 0; |
| 4593 | if (count) | 4596 | if (count) |
| 4594 | count--; | 4597 | count--; |
| 4595 | 4598 | ||
| 4596 | while (count--) { | 4599 | while (count--) { |
| 4597 | if (i==0) | 4600 | if (i == 0) |
| 4598 | i += tx_ring->count; | 4601 | i += tx_ring->count; |
| 4599 | i--; | 4602 | i--; |
| 4600 | buffer_info = &tx_ring->buffer_info[i]; | 4603 | buffer_info = &tx_ring->buffer_info[i]; |
| @@ -6193,7 +6196,7 @@ static int __init e1000_init_module(void) | |||
| 6193 | int ret; | 6196 | int ret; |
| 6194 | pr_info("Intel(R) PRO/1000 Network Driver - %s\n", | 6197 | pr_info("Intel(R) PRO/1000 Network Driver - %s\n", |
| 6195 | e1000e_driver_version); | 6198 | e1000e_driver_version); |
| 6196 | pr_info("Copyright (c) 1999 - 2010 Intel Corporation.\n"); | 6199 | pr_info("Copyright(c) 1999 - 2011 Intel Corporation.\n"); |
| 6197 | ret = pci_register_driver(&e1000_driver); | 6200 | ret = pci_register_driver(&e1000_driver); |
| 6198 | 6201 | ||
| 6199 | return ret; | 6202 | return ret; |
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index a9612b0e4bca..4dd9b63273f6 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
| @@ -62,10 +62,9 @@ MODULE_PARM_DESC(copybreak, | |||
| 62 | module_param_array_named(X, X, int, &num_##X, 0); \ | 62 | module_param_array_named(X, X, int, &num_##X, 0); \ |
| 63 | MODULE_PARM_DESC(X, desc); | 63 | MODULE_PARM_DESC(X, desc); |
| 64 | 64 | ||
| 65 | |||
| 66 | /* | 65 | /* |
| 67 | * Transmit Interrupt Delay in units of 1.024 microseconds | 66 | * Transmit Interrupt Delay in units of 1.024 microseconds |
| 68 | * Tx interrupt delay needs to typically be set to something non zero | 67 | * Tx interrupt delay needs to typically be set to something non-zero |
| 69 | * | 68 | * |
| 70 | * Valid Range: 0-65535 | 69 | * Valid Range: 0-65535 |
| 71 | */ | 70 | */ |
| @@ -112,6 +111,7 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); | |||
| 112 | #define DEFAULT_ITR 3 | 111 | #define DEFAULT_ITR 3 |
| 113 | #define MAX_ITR 100000 | 112 | #define MAX_ITR 100000 |
| 114 | #define MIN_ITR 100 | 113 | #define MIN_ITR 100 |
| 114 | |||
| 115 | /* IntMode (Interrupt Mode) | 115 | /* IntMode (Interrupt Mode) |
| 116 | * | 116 | * |
| 117 | * Valid Range: 0 - 2 | 117 | * Valid Range: 0 - 2 |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 00f89e8a9fa0..6bea051b134b 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | 2 | ||
| 3 | Intel PRO/1000 Linux driver | 3 | Intel PRO/1000 Linux driver |
| 4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
| 5 | 5 | ||
| 6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
| 7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
| @@ -640,7 +640,7 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) | |||
| 640 | s32 ret_val; | 640 | s32 ret_val; |
| 641 | u16 phy_data; | 641 | u16 phy_data; |
| 642 | 642 | ||
| 643 | /* Enable CRS on TX. This must be set for half-duplex operation. */ | 643 | /* Enable CRS on Tx. This must be set for half-duplex operation. */ |
| 644 | ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data); | 644 | ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data); |
| 645 | if (ret_val) | 645 | if (ret_val) |
| 646 | goto out; | 646 | goto out; |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6de4675016b5..119aa2000c24 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
| @@ -434,7 +434,6 @@ static void gfar_init_mac(struct net_device *ndev) | |||
| 434 | static struct net_device_stats *gfar_get_stats(struct net_device *dev) | 434 | static struct net_device_stats *gfar_get_stats(struct net_device *dev) |
| 435 | { | 435 | { |
| 436 | struct gfar_private *priv = netdev_priv(dev); | 436 | struct gfar_private *priv = netdev_priv(dev); |
| 437 | struct netdev_queue *txq; | ||
| 438 | unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; | 437 | unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; |
| 439 | unsigned long tx_packets = 0, tx_bytes = 0; | 438 | unsigned long tx_packets = 0, tx_bytes = 0; |
| 440 | int i = 0; | 439 | int i = 0; |
| @@ -450,9 +449,8 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev) | |||
| 450 | dev->stats.rx_dropped = rx_dropped; | 449 | dev->stats.rx_dropped = rx_dropped; |
| 451 | 450 | ||
| 452 | for (i = 0; i < priv->num_tx_queues; i++) { | 451 | for (i = 0; i < priv->num_tx_queues; i++) { |
| 453 | txq = netdev_get_tx_queue(dev, i); | 452 | tx_bytes += priv->tx_queue[i]->stats.tx_bytes; |
| 454 | tx_bytes += txq->tx_bytes; | 453 | tx_packets += priv->tx_queue[i]->stats.tx_packets; |
| 455 | tx_packets += txq->tx_packets; | ||
| 456 | } | 454 | } |
| 457 | 455 | ||
| 458 | dev->stats.tx_bytes = tx_bytes; | 456 | dev->stats.tx_bytes = tx_bytes; |
| @@ -2109,8 +2107,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 2109 | } | 2107 | } |
| 2110 | 2108 | ||
| 2111 | /* Update transmit stats */ | 2109 | /* Update transmit stats */ |
| 2112 | txq->tx_bytes += skb->len; | 2110 | tx_queue->stats.tx_bytes += skb->len; |
| 2113 | txq->tx_packets ++; | 2111 | tx_queue->stats.tx_packets++; |
| 2114 | 2112 | ||
| 2115 | txbdp = txbdp_start = tx_queue->cur_tx; | 2113 | txbdp = txbdp_start = tx_queue->cur_tx; |
| 2116 | lstatus = txbdp->lstatus; | 2114 | lstatus = txbdp->lstatus; |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 68984eb88ae0..54de4135e932 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
| @@ -907,12 +907,21 @@ enum { | |||
| 907 | MQ_MG_MODE | 907 | MQ_MG_MODE |
| 908 | }; | 908 | }; |
| 909 | 909 | ||
| 910 | /* | ||
| 911 | * Per TX queue stats | ||
| 912 | */ | ||
| 913 | struct tx_q_stats { | ||
| 914 | unsigned long tx_packets; | ||
| 915 | unsigned long tx_bytes; | ||
| 916 | }; | ||
| 917 | |||
| 910 | /** | 918 | /** |
| 911 | * struct gfar_priv_tx_q - per tx queue structure | 919 | * struct gfar_priv_tx_q - per tx queue structure |
| 912 | * @txlock: per queue tx spin lock | 920 | * @txlock: per queue tx spin lock |
| 913 | * @tx_skbuff:skb pointers | 921 | * @tx_skbuff:skb pointers |
| 914 | * @skb_curtx: to be used skb pointer | 922 | * @skb_curtx: to be used skb pointer |
| 915 | * @skb_dirtytx:the last used skb pointer | 923 | * @skb_dirtytx:the last used skb pointer |
| 924 | * @stats: bytes/packets stats | ||
| 916 | * @qindex: index of this queue | 925 | * @qindex: index of this queue |
| 917 | * @dev: back pointer to the dev structure | 926 | * @dev: back pointer to the dev structure |
| 918 | * @grp: back pointer to the group to which this queue belongs | 927 | * @grp: back pointer to the group to which this queue belongs |
| @@ -934,6 +943,7 @@ struct gfar_priv_tx_q { | |||
| 934 | struct txbd8 *tx_bd_base; | 943 | struct txbd8 *tx_bd_base; |
| 935 | struct txbd8 *cur_tx; | 944 | struct txbd8 *cur_tx; |
| 936 | struct txbd8 *dirty_tx; | 945 | struct txbd8 *dirty_tx; |
| 946 | struct tx_q_stats stats; | ||
| 937 | struct net_device *dev; | 947 | struct net_device *dev; |
| 938 | struct gfar_priv_grp *grp; | 948 | struct gfar_priv_grp *grp; |
| 939 | u16 skb_curtx; | 949 | u16 skb_curtx; |
diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 27d6960ce09e..fdb0333f5cb6 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC. | 2 | * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC. |
| 3 | * | 3 | * |
| 4 | * 2005-2009 (c) Aeroflex Gaisler AB | 4 | * 2005-2010 (c) Aeroflex Gaisler AB |
| 5 | * | 5 | * |
| 6 | * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs | 6 | * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs |
| 7 | * available in the GRLIB VHDL IP core library. | 7 | * available in the GRLIB VHDL IP core library. |
| @@ -356,6 +356,8 @@ static int greth_open(struct net_device *dev) | |||
| 356 | dev_dbg(&dev->dev, " starting queue\n"); | 356 | dev_dbg(&dev->dev, " starting queue\n"); |
| 357 | netif_start_queue(dev); | 357 | netif_start_queue(dev); |
| 358 | 358 | ||
| 359 | GRETH_REGSAVE(greth->regs->status, 0xFF); | ||
| 360 | |||
| 359 | napi_enable(&greth->napi); | 361 | napi_enable(&greth->napi); |
| 360 | 362 | ||
| 361 | greth_enable_irqs(greth); | 363 | greth_enable_irqs(greth); |
| @@ -371,7 +373,9 @@ static int greth_close(struct net_device *dev) | |||
| 371 | 373 | ||
| 372 | napi_disable(&greth->napi); | 374 | napi_disable(&greth->napi); |
| 373 | 375 | ||
| 376 | greth_disable_irqs(greth); | ||
| 374 | greth_disable_tx(greth); | 377 | greth_disable_tx(greth); |
| 378 | greth_disable_rx(greth); | ||
| 375 | 379 | ||
| 376 | netif_stop_queue(dev); | 380 | netif_stop_queue(dev); |
| 377 | 381 | ||
| @@ -388,12 +392,20 @@ greth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 388 | struct greth_private *greth = netdev_priv(dev); | 392 | struct greth_private *greth = netdev_priv(dev); |
| 389 | struct greth_bd *bdp; | 393 | struct greth_bd *bdp; |
| 390 | int err = NETDEV_TX_OK; | 394 | int err = NETDEV_TX_OK; |
| 391 | u32 status, dma_addr; | 395 | u32 status, dma_addr, ctrl; |
| 396 | unsigned long flags; | ||
| 392 | 397 | ||
| 393 | bdp = greth->tx_bd_base + greth->tx_next; | 398 | /* Clean TX Ring */ |
| 399 | greth_clean_tx(greth->netdev); | ||
| 394 | 400 | ||
| 395 | if (unlikely(greth->tx_free <= 0)) { | 401 | if (unlikely(greth->tx_free <= 0)) { |
| 402 | spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/ | ||
| 403 | ctrl = GRETH_REGLOAD(greth->regs->control); | ||
| 404 | /* Enable TX IRQ only if not already in poll() routine */ | ||
| 405 | if (ctrl & GRETH_RXI) | ||
| 406 | GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI); | ||
| 396 | netif_stop_queue(dev); | 407 | netif_stop_queue(dev); |
| 408 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 397 | return NETDEV_TX_BUSY; | 409 | return NETDEV_TX_BUSY; |
| 398 | } | 410 | } |
| 399 | 411 | ||
| @@ -406,13 +418,14 @@ greth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 406 | goto out; | 418 | goto out; |
| 407 | } | 419 | } |
| 408 | 420 | ||
| 421 | bdp = greth->tx_bd_base + greth->tx_next; | ||
| 409 | dma_addr = greth_read_bd(&bdp->addr); | 422 | dma_addr = greth_read_bd(&bdp->addr); |
| 410 | 423 | ||
| 411 | memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len); | 424 | memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len); |
| 412 | 425 | ||
| 413 | dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE); | 426 | dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE); |
| 414 | 427 | ||
| 415 | status = GRETH_BD_EN | (skb->len & GRETH_BD_LEN); | 428 | status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN); |
| 416 | 429 | ||
| 417 | /* Wrap around descriptor ring */ | 430 | /* Wrap around descriptor ring */ |
| 418 | if (greth->tx_next == GRETH_TXBD_NUM_MASK) { | 431 | if (greth->tx_next == GRETH_TXBD_NUM_MASK) { |
| @@ -422,22 +435,11 @@ greth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 422 | greth->tx_next = NEXT_TX(greth->tx_next); | 435 | greth->tx_next = NEXT_TX(greth->tx_next); |
| 423 | greth->tx_free--; | 436 | greth->tx_free--; |
| 424 | 437 | ||
| 425 | /* No more descriptors */ | ||
| 426 | if (unlikely(greth->tx_free == 0)) { | ||
| 427 | |||
| 428 | /* Free transmitted descriptors */ | ||
| 429 | greth_clean_tx(dev); | ||
| 430 | |||
| 431 | /* If nothing was cleaned, stop queue & wait for irq */ | ||
| 432 | if (unlikely(greth->tx_free == 0)) { | ||
| 433 | status |= GRETH_BD_IE; | ||
| 434 | netif_stop_queue(dev); | ||
| 435 | } | ||
| 436 | } | ||
| 437 | |||
| 438 | /* Write descriptor control word and enable transmission */ | 438 | /* Write descriptor control word and enable transmission */ |
| 439 | greth_write_bd(&bdp->stat, status); | 439 | greth_write_bd(&bdp->stat, status); |
| 440 | spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/ | ||
| 440 | greth_enable_tx(greth); | 441 | greth_enable_tx(greth); |
| 442 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 441 | 443 | ||
| 442 | out: | 444 | out: |
| 443 | dev_kfree_skb(skb); | 445 | dev_kfree_skb(skb); |
| @@ -450,13 +452,23 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | |||
| 450 | { | 452 | { |
| 451 | struct greth_private *greth = netdev_priv(dev); | 453 | struct greth_private *greth = netdev_priv(dev); |
| 452 | struct greth_bd *bdp; | 454 | struct greth_bd *bdp; |
| 453 | u32 status = 0, dma_addr; | 455 | u32 status = 0, dma_addr, ctrl; |
| 454 | int curr_tx, nr_frags, i, err = NETDEV_TX_OK; | 456 | int curr_tx, nr_frags, i, err = NETDEV_TX_OK; |
| 457 | unsigned long flags; | ||
| 455 | 458 | ||
| 456 | nr_frags = skb_shinfo(skb)->nr_frags; | 459 | nr_frags = skb_shinfo(skb)->nr_frags; |
| 457 | 460 | ||
| 461 | /* Clean TX Ring */ | ||
| 462 | greth_clean_tx_gbit(dev); | ||
| 463 | |||
| 458 | if (greth->tx_free < nr_frags + 1) { | 464 | if (greth->tx_free < nr_frags + 1) { |
| 465 | spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/ | ||
| 466 | ctrl = GRETH_REGLOAD(greth->regs->control); | ||
| 467 | /* Enable TX IRQ only if not already in poll() routine */ | ||
| 468 | if (ctrl & GRETH_RXI) | ||
| 469 | GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI); | ||
| 459 | netif_stop_queue(dev); | 470 | netif_stop_queue(dev); |
| 471 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 460 | err = NETDEV_TX_BUSY; | 472 | err = NETDEV_TX_BUSY; |
| 461 | goto out; | 473 | goto out; |
| 462 | } | 474 | } |
| @@ -499,7 +511,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | |||
| 499 | greth->tx_skbuff[curr_tx] = NULL; | 511 | greth->tx_skbuff[curr_tx] = NULL; |
| 500 | bdp = greth->tx_bd_base + curr_tx; | 512 | bdp = greth->tx_bd_base + curr_tx; |
| 501 | 513 | ||
| 502 | status = GRETH_TXBD_CSALL; | 514 | status = GRETH_TXBD_CSALL | GRETH_BD_EN; |
| 503 | status |= frag->size & GRETH_BD_LEN; | 515 | status |= frag->size & GRETH_BD_LEN; |
| 504 | 516 | ||
| 505 | /* Wrap around descriptor ring */ | 517 | /* Wrap around descriptor ring */ |
| @@ -509,14 +521,8 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | |||
| 509 | /* More fragments left */ | 521 | /* More fragments left */ |
| 510 | if (i < nr_frags - 1) | 522 | if (i < nr_frags - 1) |
| 511 | status |= GRETH_TXBD_MORE; | 523 | status |= GRETH_TXBD_MORE; |
| 512 | 524 | else | |
| 513 | /* ... last fragment, check if out of descriptors */ | 525 | status |= GRETH_BD_IE; /* enable IRQ on last fragment */ |
| 514 | else if (greth->tx_free - nr_frags - 1 < (MAX_SKB_FRAGS + 1)) { | ||
| 515 | |||
| 516 | /* Enable interrupts and stop queue */ | ||
| 517 | status |= GRETH_BD_IE; | ||
| 518 | netif_stop_queue(dev); | ||
| 519 | } | ||
| 520 | 526 | ||
| 521 | greth_write_bd(&bdp->stat, status); | 527 | greth_write_bd(&bdp->stat, status); |
| 522 | 528 | ||
| @@ -536,26 +542,29 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) | |||
| 536 | 542 | ||
| 537 | wmb(); | 543 | wmb(); |
| 538 | 544 | ||
| 539 | /* Enable the descriptors that we configured ... */ | 545 | /* Enable the descriptor chain by enabling the first descriptor */ |
| 540 | for (i = 0; i < nr_frags + 1; i++) { | 546 | bdp = greth->tx_bd_base + greth->tx_next; |
| 541 | bdp = greth->tx_bd_base + greth->tx_next; | 547 | greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN); |
| 542 | greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN); | 548 | greth->tx_next = curr_tx; |
| 543 | greth->tx_next = NEXT_TX(greth->tx_next); | 549 | greth->tx_free -= nr_frags + 1; |
| 544 | greth->tx_free--; | ||
| 545 | } | ||
| 546 | 550 | ||
| 551 | wmb(); | ||
| 552 | |||
| 553 | spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/ | ||
| 547 | greth_enable_tx(greth); | 554 | greth_enable_tx(greth); |
| 555 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 548 | 556 | ||
| 549 | return NETDEV_TX_OK; | 557 | return NETDEV_TX_OK; |
| 550 | 558 | ||
| 551 | frag_map_error: | 559 | frag_map_error: |
| 552 | /* Unmap SKB mappings that succeeded */ | 560 | /* Unmap SKB mappings that succeeded and disable descriptor */ |
| 553 | for (i = 0; greth->tx_next + i != curr_tx; i++) { | 561 | for (i = 0; greth->tx_next + i != curr_tx; i++) { |
| 554 | bdp = greth->tx_bd_base + greth->tx_next + i; | 562 | bdp = greth->tx_bd_base + greth->tx_next + i; |
| 555 | dma_unmap_single(greth->dev, | 563 | dma_unmap_single(greth->dev, |
| 556 | greth_read_bd(&bdp->addr), | 564 | greth_read_bd(&bdp->addr), |
| 557 | greth_read_bd(&bdp->stat) & GRETH_BD_LEN, | 565 | greth_read_bd(&bdp->stat) & GRETH_BD_LEN, |
| 558 | DMA_TO_DEVICE); | 566 | DMA_TO_DEVICE); |
| 567 | greth_write_bd(&bdp->stat, 0); | ||
| 559 | } | 568 | } |
| 560 | map_error: | 569 | map_error: |
| 561 | if (net_ratelimit()) | 570 | if (net_ratelimit()) |
| @@ -565,12 +574,11 @@ out: | |||
| 565 | return err; | 574 | return err; |
| 566 | } | 575 | } |
| 567 | 576 | ||
| 568 | |||
| 569 | static irqreturn_t greth_interrupt(int irq, void *dev_id) | 577 | static irqreturn_t greth_interrupt(int irq, void *dev_id) |
| 570 | { | 578 | { |
| 571 | struct net_device *dev = dev_id; | 579 | struct net_device *dev = dev_id; |
| 572 | struct greth_private *greth; | 580 | struct greth_private *greth; |
| 573 | u32 status; | 581 | u32 status, ctrl; |
| 574 | irqreturn_t retval = IRQ_NONE; | 582 | irqreturn_t retval = IRQ_NONE; |
| 575 | 583 | ||
| 576 | greth = netdev_priv(dev); | 584 | greth = netdev_priv(dev); |
| @@ -580,13 +588,15 @@ static irqreturn_t greth_interrupt(int irq, void *dev_id) | |||
| 580 | /* Get the interrupt events that caused us to be here. */ | 588 | /* Get the interrupt events that caused us to be here. */ |
| 581 | status = GRETH_REGLOAD(greth->regs->status); | 589 | status = GRETH_REGLOAD(greth->regs->status); |
| 582 | 590 | ||
| 583 | /* Handle rx and tx interrupts through poll */ | 591 | /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be |
| 584 | if (status & (GRETH_INT_RX | GRETH_INT_TX)) { | 592 | * set regardless of whether IRQ is enabled or not. Especially |
| 585 | 593 | * important when shared IRQ. | |
| 586 | /* Clear interrupt status */ | 594 | */ |
| 587 | GRETH_REGORIN(greth->regs->status, | 595 | ctrl = GRETH_REGLOAD(greth->regs->control); |
| 588 | status & (GRETH_INT_RX | GRETH_INT_TX)); | ||
| 589 | 596 | ||
| 597 | /* Handle rx and tx interrupts through poll */ | ||
| 598 | if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) || | ||
| 599 | ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) { | ||
| 590 | retval = IRQ_HANDLED; | 600 | retval = IRQ_HANDLED; |
| 591 | 601 | ||
| 592 | /* Disable interrupts and schedule poll() */ | 602 | /* Disable interrupts and schedule poll() */ |
| @@ -610,6 +620,8 @@ static void greth_clean_tx(struct net_device *dev) | |||
| 610 | 620 | ||
| 611 | while (1) { | 621 | while (1) { |
| 612 | bdp = greth->tx_bd_base + greth->tx_last; | 622 | bdp = greth->tx_bd_base + greth->tx_last; |
| 623 | GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); | ||
| 624 | mb(); | ||
| 613 | stat = greth_read_bd(&bdp->stat); | 625 | stat = greth_read_bd(&bdp->stat); |
| 614 | 626 | ||
| 615 | if (unlikely(stat & GRETH_BD_EN)) | 627 | if (unlikely(stat & GRETH_BD_EN)) |
| @@ -670,7 +682,10 @@ static void greth_clean_tx_gbit(struct net_device *dev) | |||
| 670 | 682 | ||
| 671 | /* We only clean fully completed SKBs */ | 683 | /* We only clean fully completed SKBs */ |
| 672 | bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags); | 684 | bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags); |
| 673 | stat = bdp_last_frag->stat; | 685 | |
| 686 | GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); | ||
| 687 | mb(); | ||
| 688 | stat = greth_read_bd(&bdp_last_frag->stat); | ||
| 674 | 689 | ||
| 675 | if (stat & GRETH_BD_EN) | 690 | if (stat & GRETH_BD_EN) |
| 676 | break; | 691 | break; |
| @@ -702,21 +717,9 @@ static void greth_clean_tx_gbit(struct net_device *dev) | |||
| 702 | greth->tx_free += nr_frags+1; | 717 | greth->tx_free += nr_frags+1; |
| 703 | dev_kfree_skb(skb); | 718 | dev_kfree_skb(skb); |
| 704 | } | 719 | } |
| 705 | if (greth->tx_free > (MAX_SKB_FRAGS + 1)) { | ||
| 706 | netif_wake_queue(dev); | ||
| 707 | } | ||
| 708 | } | ||
| 709 | 720 | ||
| 710 | static int greth_pending_packets(struct greth_private *greth) | 721 | if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1))) |
| 711 | { | 722 | netif_wake_queue(dev); |
| 712 | struct greth_bd *bdp; | ||
| 713 | u32 status; | ||
| 714 | bdp = greth->rx_bd_base + greth->rx_cur; | ||
| 715 | status = greth_read_bd(&bdp->stat); | ||
| 716 | if (status & GRETH_BD_EN) | ||
| 717 | return 0; | ||
| 718 | else | ||
| 719 | return 1; | ||
| 720 | } | 723 | } |
| 721 | 724 | ||
| 722 | static int greth_rx(struct net_device *dev, int limit) | 725 | static int greth_rx(struct net_device *dev, int limit) |
| @@ -727,20 +730,24 @@ static int greth_rx(struct net_device *dev, int limit) | |||
| 727 | int pkt_len; | 730 | int pkt_len; |
| 728 | int bad, count; | 731 | int bad, count; |
| 729 | u32 status, dma_addr; | 732 | u32 status, dma_addr; |
| 733 | unsigned long flags; | ||
| 730 | 734 | ||
| 731 | greth = netdev_priv(dev); | 735 | greth = netdev_priv(dev); |
| 732 | 736 | ||
| 733 | for (count = 0; count < limit; ++count) { | 737 | for (count = 0; count < limit; ++count) { |
| 734 | 738 | ||
| 735 | bdp = greth->rx_bd_base + greth->rx_cur; | 739 | bdp = greth->rx_bd_base + greth->rx_cur; |
| 740 | GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX); | ||
| 741 | mb(); | ||
| 736 | status = greth_read_bd(&bdp->stat); | 742 | status = greth_read_bd(&bdp->stat); |
| 737 | dma_addr = greth_read_bd(&bdp->addr); | ||
| 738 | bad = 0; | ||
| 739 | 743 | ||
| 740 | if (unlikely(status & GRETH_BD_EN)) { | 744 | if (unlikely(status & GRETH_BD_EN)) { |
| 741 | break; | 745 | break; |
| 742 | } | 746 | } |
| 743 | 747 | ||
| 748 | dma_addr = greth_read_bd(&bdp->addr); | ||
| 749 | bad = 0; | ||
| 750 | |||
| 744 | /* Check status for errors. */ | 751 | /* Check status for errors. */ |
| 745 | if (unlikely(status & GRETH_RXBD_STATUS)) { | 752 | if (unlikely(status & GRETH_RXBD_STATUS)) { |
| 746 | if (status & GRETH_RXBD_ERR_FT) { | 753 | if (status & GRETH_RXBD_ERR_FT) { |
| @@ -802,7 +809,9 @@ static int greth_rx(struct net_device *dev, int limit) | |||
| 802 | 809 | ||
| 803 | dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); | 810 | dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); |
| 804 | 811 | ||
| 812 | spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */ | ||
| 805 | greth_enable_rx(greth); | 813 | greth_enable_rx(greth); |
| 814 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 806 | 815 | ||
| 807 | greth->rx_cur = NEXT_RX(greth->rx_cur); | 816 | greth->rx_cur = NEXT_RX(greth->rx_cur); |
| 808 | } | 817 | } |
| @@ -836,6 +845,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit) | |||
| 836 | int pkt_len; | 845 | int pkt_len; |
| 837 | int bad, count = 0; | 846 | int bad, count = 0; |
| 838 | u32 status, dma_addr; | 847 | u32 status, dma_addr; |
| 848 | unsigned long flags; | ||
| 839 | 849 | ||
| 840 | greth = netdev_priv(dev); | 850 | greth = netdev_priv(dev); |
| 841 | 851 | ||
| @@ -843,6 +853,8 @@ static int greth_rx_gbit(struct net_device *dev, int limit) | |||
| 843 | 853 | ||
| 844 | bdp = greth->rx_bd_base + greth->rx_cur; | 854 | bdp = greth->rx_bd_base + greth->rx_cur; |
| 845 | skb = greth->rx_skbuff[greth->rx_cur]; | 855 | skb = greth->rx_skbuff[greth->rx_cur]; |
| 856 | GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX); | ||
| 857 | mb(); | ||
| 846 | status = greth_read_bd(&bdp->stat); | 858 | status = greth_read_bd(&bdp->stat); |
| 847 | bad = 0; | 859 | bad = 0; |
| 848 | 860 | ||
| @@ -865,10 +877,9 @@ static int greth_rx_gbit(struct net_device *dev, int limit) | |||
| 865 | } | 877 | } |
| 866 | } | 878 | } |
| 867 | 879 | ||
| 868 | /* Allocate new skb to replace current */ | 880 | /* Allocate new skb to replace current, not needed if the |
| 869 | newskb = netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN); | 881 | * current skb can be reused */ |
| 870 | 882 | if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) { | |
| 871 | if (!bad && newskb) { | ||
| 872 | skb_reserve(newskb, NET_IP_ALIGN); | 883 | skb_reserve(newskb, NET_IP_ALIGN); |
| 873 | 884 | ||
| 874 | dma_addr = dma_map_single(greth->dev, | 885 | dma_addr = dma_map_single(greth->dev, |
| @@ -905,11 +916,22 @@ static int greth_rx_gbit(struct net_device *dev, int limit) | |||
| 905 | if (net_ratelimit()) | 916 | if (net_ratelimit()) |
| 906 | dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n"); | 917 | dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n"); |
| 907 | dev_kfree_skb(newskb); | 918 | dev_kfree_skb(newskb); |
| 919 | /* reusing current skb, so it is a drop */ | ||
| 908 | dev->stats.rx_dropped++; | 920 | dev->stats.rx_dropped++; |
| 909 | } | 921 | } |
| 922 | } else if (bad) { | ||
| 923 | /* Bad Frame transfer, the skb is reused */ | ||
| 924 | dev->stats.rx_dropped++; | ||
| 910 | } else { | 925 | } else { |
| 926 | /* Failed Allocating a new skb. This is rather stupid | ||
| 927 | * but the current "filled" skb is reused, as if | ||
| 928 | * transfer failure. One could argue that RX descriptor | ||
| 929 | * table handling should be divided into cleaning and | ||
| 930 | * filling as the TX part of the driver | ||
| 931 | */ | ||
| 911 | if (net_ratelimit()) | 932 | if (net_ratelimit()) |
| 912 | dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n"); | 933 | dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n"); |
| 934 | /* reusing current skb, so it is a drop */ | ||
| 913 | dev->stats.rx_dropped++; | 935 | dev->stats.rx_dropped++; |
| 914 | } | 936 | } |
| 915 | 937 | ||
| @@ -920,7 +942,9 @@ static int greth_rx_gbit(struct net_device *dev, int limit) | |||
| 920 | 942 | ||
| 921 | wmb(); | 943 | wmb(); |
| 922 | greth_write_bd(&bdp->stat, status); | 944 | greth_write_bd(&bdp->stat, status); |
| 945 | spin_lock_irqsave(&greth->devlock, flags); | ||
| 923 | greth_enable_rx(greth); | 946 | greth_enable_rx(greth); |
| 947 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 924 | greth->rx_cur = NEXT_RX(greth->rx_cur); | 948 | greth->rx_cur = NEXT_RX(greth->rx_cur); |
| 925 | } | 949 | } |
| 926 | 950 | ||
| @@ -932,15 +956,18 @@ static int greth_poll(struct napi_struct *napi, int budget) | |||
| 932 | { | 956 | { |
| 933 | struct greth_private *greth; | 957 | struct greth_private *greth; |
| 934 | int work_done = 0; | 958 | int work_done = 0; |
| 959 | unsigned long flags; | ||
| 960 | u32 mask, ctrl; | ||
| 935 | greth = container_of(napi, struct greth_private, napi); | 961 | greth = container_of(napi, struct greth_private, napi); |
| 936 | 962 | ||
| 937 | if (greth->gbit_mac) { | 963 | restart_txrx_poll: |
| 938 | greth_clean_tx_gbit(greth->netdev); | 964 | if (netif_queue_stopped(greth->netdev)) { |
| 939 | } else { | 965 | if (greth->gbit_mac) |
| 940 | greth_clean_tx(greth->netdev); | 966 | greth_clean_tx_gbit(greth->netdev); |
| 967 | else | ||
| 968 | greth_clean_tx(greth->netdev); | ||
| 941 | } | 969 | } |
| 942 | 970 | ||
| 943 | restart_poll: | ||
| 944 | if (greth->gbit_mac) { | 971 | if (greth->gbit_mac) { |
| 945 | work_done += greth_rx_gbit(greth->netdev, budget - work_done); | 972 | work_done += greth_rx_gbit(greth->netdev, budget - work_done); |
| 946 | } else { | 973 | } else { |
| @@ -949,15 +976,29 @@ restart_poll: | |||
| 949 | 976 | ||
| 950 | if (work_done < budget) { | 977 | if (work_done < budget) { |
| 951 | 978 | ||
| 952 | napi_complete(napi); | 979 | spin_lock_irqsave(&greth->devlock, flags); |
| 980 | |||
| 981 | ctrl = GRETH_REGLOAD(greth->regs->control); | ||
| 982 | if (netif_queue_stopped(greth->netdev)) { | ||
| 983 | GRETH_REGSAVE(greth->regs->control, | ||
| 984 | ctrl | GRETH_TXI | GRETH_RXI); | ||
| 985 | mask = GRETH_INT_RX | GRETH_INT_RE | | ||
| 986 | GRETH_INT_TX | GRETH_INT_TE; | ||
| 987 | } else { | ||
| 988 | GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI); | ||
| 989 | mask = GRETH_INT_RX | GRETH_INT_RE; | ||
| 990 | } | ||
| 953 | 991 | ||
| 954 | if (greth_pending_packets(greth)) { | 992 | if (GRETH_REGLOAD(greth->regs->status) & mask) { |
| 955 | napi_reschedule(napi); | 993 | GRETH_REGSAVE(greth->regs->control, ctrl); |
| 956 | goto restart_poll; | 994 | spin_unlock_irqrestore(&greth->devlock, flags); |
| 995 | goto restart_txrx_poll; | ||
| 996 | } else { | ||
| 997 | __napi_complete(napi); | ||
| 998 | spin_unlock_irqrestore(&greth->devlock, flags); | ||
| 957 | } | 999 | } |
| 958 | } | 1000 | } |
| 959 | 1001 | ||
| 960 | greth_enable_irqs(greth); | ||
| 961 | return work_done; | 1002 | return work_done; |
| 962 | } | 1003 | } |
| 963 | 1004 | ||
| @@ -1152,11 +1193,11 @@ static const struct ethtool_ops greth_ethtool_ops = { | |||
| 1152 | }; | 1193 | }; |
| 1153 | 1194 | ||
| 1154 | static struct net_device_ops greth_netdev_ops = { | 1195 | static struct net_device_ops greth_netdev_ops = { |
| 1155 | .ndo_open = greth_open, | 1196 | .ndo_open = greth_open, |
| 1156 | .ndo_stop = greth_close, | 1197 | .ndo_stop = greth_close, |
| 1157 | .ndo_start_xmit = greth_start_xmit, | 1198 | .ndo_start_xmit = greth_start_xmit, |
| 1158 | .ndo_set_mac_address = greth_set_mac_add, | 1199 | .ndo_set_mac_address = greth_set_mac_add, |
| 1159 | .ndo_validate_addr = eth_validate_addr, | 1200 | .ndo_validate_addr = eth_validate_addr, |
| 1160 | }; | 1201 | }; |
| 1161 | 1202 | ||
| 1162 | static inline int wait_for_mdio(struct greth_private *greth) | 1203 | static inline int wait_for_mdio(struct greth_private *greth) |
| @@ -1217,29 +1258,26 @@ static void greth_link_change(struct net_device *dev) | |||
| 1217 | struct greth_private *greth = netdev_priv(dev); | 1258 | struct greth_private *greth = netdev_priv(dev); |
| 1218 | struct phy_device *phydev = greth->phy; | 1259 | struct phy_device *phydev = greth->phy; |
| 1219 | unsigned long flags; | 1260 | unsigned long flags; |
| 1220 | |||
| 1221 | int status_change = 0; | 1261 | int status_change = 0; |
| 1262 | u32 ctrl; | ||
| 1222 | 1263 | ||
| 1223 | spin_lock_irqsave(&greth->devlock, flags); | 1264 | spin_lock_irqsave(&greth->devlock, flags); |
| 1224 | 1265 | ||
| 1225 | if (phydev->link) { | 1266 | if (phydev->link) { |
| 1226 | 1267 | ||
| 1227 | if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) { | 1268 | if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) { |
| 1228 | 1269 | ctrl = GRETH_REGLOAD(greth->regs->control) & | |
| 1229 | GRETH_REGANDIN(greth->regs->control, | 1270 | ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB); |
| 1230 | ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB)); | ||
| 1231 | 1271 | ||
| 1232 | if (phydev->duplex) | 1272 | if (phydev->duplex) |
| 1233 | GRETH_REGORIN(greth->regs->control, GRETH_CTRL_FD); | 1273 | ctrl |= GRETH_CTRL_FD; |
| 1234 | |||
| 1235 | if (phydev->speed == SPEED_100) { | ||
| 1236 | |||
| 1237 | GRETH_REGORIN(greth->regs->control, GRETH_CTRL_SP); | ||
| 1238 | } | ||
| 1239 | 1274 | ||
| 1275 | if (phydev->speed == SPEED_100) | ||
| 1276 | ctrl |= GRETH_CTRL_SP; | ||
| 1240 | else if (phydev->speed == SPEED_1000) | 1277 | else if (phydev->speed == SPEED_1000) |
| 1241 | GRETH_REGORIN(greth->regs->control, GRETH_CTRL_GB); | 1278 | ctrl |= GRETH_CTRL_GB; |
| 1242 | 1279 | ||
| 1280 | GRETH_REGSAVE(greth->regs->control, ctrl); | ||
| 1243 | greth->speed = phydev->speed; | 1281 | greth->speed = phydev->speed; |
| 1244 | greth->duplex = phydev->duplex; | 1282 | greth->duplex = phydev->duplex; |
| 1245 | status_change = 1; | 1283 | status_change = 1; |
| @@ -1600,6 +1638,9 @@ static struct of_device_id greth_of_match[] = { | |||
| 1600 | { | 1638 | { |
| 1601 | .name = "GAISLER_ETHMAC", | 1639 | .name = "GAISLER_ETHMAC", |
| 1602 | }, | 1640 | }, |
| 1641 | { | ||
| 1642 | .name = "01_01d", | ||
| 1643 | }, | ||
| 1603 | {}, | 1644 | {}, |
| 1604 | }; | 1645 | }; |
| 1605 | 1646 | ||
diff --git a/drivers/net/greth.h b/drivers/net/greth.h index 03ad903cd676..be0f2062bd14 100644 --- a/drivers/net/greth.h +++ b/drivers/net/greth.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #define GRETH_BD_LEN 0x7FF | 23 | #define GRETH_BD_LEN 0x7FF |
| 24 | 24 | ||
| 25 | #define GRETH_TXEN 0x1 | 25 | #define GRETH_TXEN 0x1 |
| 26 | #define GRETH_INT_TE 0x2 | ||
| 26 | #define GRETH_INT_TX 0x8 | 27 | #define GRETH_INT_TX 0x8 |
| 27 | #define GRETH_TXI 0x4 | 28 | #define GRETH_TXI 0x4 |
| 28 | #define GRETH_TXBD_STATUS 0x0001C000 | 29 | #define GRETH_TXBD_STATUS 0x0001C000 |
| @@ -35,6 +36,7 @@ | |||
| 35 | #define GRETH_TXBD_ERR_UE 0x4000 | 36 | #define GRETH_TXBD_ERR_UE 0x4000 |
| 36 | #define GRETH_TXBD_ERR_AL 0x8000 | 37 | #define GRETH_TXBD_ERR_AL 0x8000 |
| 37 | 38 | ||
| 39 | #define GRETH_INT_RE 0x1 | ||
| 38 | #define GRETH_INT_RX 0x4 | 40 | #define GRETH_INT_RX 0x4 |
| 39 | #define GRETH_RXEN 0x2 | 41 | #define GRETH_RXEN 0x2 |
| 40 | #define GRETH_RXI 0x8 | 42 | #define GRETH_RXI 0x8 |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a060610a42db..602078b84892 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -6667,8 +6667,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, | |||
| 6667 | struct ixgbe_adapter *adapter, | 6667 | struct ixgbe_adapter *adapter, |
| 6668 | struct ixgbe_ring *tx_ring) | 6668 | struct ixgbe_ring *tx_ring) |
| 6669 | { | 6669 | { |
| 6670 | struct net_device *netdev = tx_ring->netdev; | ||
| 6671 | struct netdev_queue *txq; | ||
| 6672 | unsigned int first; | 6670 | unsigned int first; |
| 6673 | unsigned int tx_flags = 0; | 6671 | unsigned int tx_flags = 0; |
| 6674 | u8 hdr_len = 0; | 6672 | u8 hdr_len = 0; |
| @@ -6765,9 +6763,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, | |||
| 6765 | /* add the ATR filter if ATR is on */ | 6763 | /* add the ATR filter if ATR is on */ |
| 6766 | if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state)) | 6764 | if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state)) |
| 6767 | ixgbe_atr(tx_ring, skb, tx_flags, protocol); | 6765 | ixgbe_atr(tx_ring, skb, tx_flags, protocol); |
| 6768 | txq = netdev_get_tx_queue(netdev, tx_ring->queue_index); | ||
| 6769 | txq->tx_bytes += skb->len; | ||
| 6770 | txq->tx_packets++; | ||
| 6771 | ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len); | 6766 | ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len); |
| 6772 | ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); | 6767 | ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); |
| 6773 | 6768 | ||
| @@ -6925,8 +6920,6 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, | |||
| 6925 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 6920 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
| 6926 | int i; | 6921 | int i; |
| 6927 | 6922 | ||
| 6928 | /* accurate rx/tx bytes/packets stats */ | ||
| 6929 | dev_txq_stats_fold(netdev, stats); | ||
| 6930 | rcu_read_lock(); | 6923 | rcu_read_lock(); |
| 6931 | for (i = 0; i < adapter->num_rx_queues; i++) { | 6924 | for (i = 0; i < adapter->num_rx_queues; i++) { |
| 6932 | struct ixgbe_ring *ring = ACCESS_ONCE(adapter->rx_ring[i]); | 6925 | struct ixgbe_ring *ring = ACCESS_ONCE(adapter->rx_ring[i]); |
| @@ -6943,6 +6936,22 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, | |||
| 6943 | stats->rx_bytes += bytes; | 6936 | stats->rx_bytes += bytes; |
| 6944 | } | 6937 | } |
| 6945 | } | 6938 | } |
| 6939 | |||
| 6940 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
| 6941 | struct ixgbe_ring *ring = ACCESS_ONCE(adapter->tx_ring[i]); | ||
| 6942 | u64 bytes, packets; | ||
| 6943 | unsigned int start; | ||
| 6944 | |||
| 6945 | if (ring) { | ||
| 6946 | do { | ||
| 6947 | start = u64_stats_fetch_begin_bh(&ring->syncp); | ||
| 6948 | packets = ring->stats.packets; | ||
| 6949 | bytes = ring->stats.bytes; | ||
| 6950 | } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); | ||
| 6951 | stats->tx_packets += packets; | ||
| 6952 | stats->tx_bytes += bytes; | ||
| 6953 | } | ||
| 6954 | } | ||
| 6946 | rcu_read_unlock(); | 6955 | rcu_read_unlock(); |
| 6947 | /* following stats updated by ixgbe_watchdog_task() */ | 6956 | /* following stats updated by ixgbe_watchdog_task() */ |
| 6948 | stats->multicast = netdev->stats.multicast; | 6957 | stats->multicast = netdev->stats.multicast; |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 21845affea13..5933621ac3ff 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
| @@ -585,7 +585,7 @@ err: | |||
| 585 | rcu_read_lock_bh(); | 585 | rcu_read_lock_bh(); |
| 586 | vlan = rcu_dereference(q->vlan); | 586 | vlan = rcu_dereference(q->vlan); |
| 587 | if (vlan) | 587 | if (vlan) |
| 588 | netdev_get_tx_queue(vlan->dev, 0)->tx_dropped++; | 588 | vlan->dev->stats.tx_dropped++; |
| 589 | rcu_read_unlock_bh(); | 589 | rcu_read_unlock_bh(); |
| 590 | 590 | ||
| 591 | return err; | 591 | return err; |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index a37fcf11ab36..ea5cfe2c3a04 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
| @@ -3403,9 +3403,7 @@ static int myri10ge_resume(struct pci_dev *pdev) | |||
| 3403 | return -EIO; | 3403 | return -EIO; |
| 3404 | } | 3404 | } |
| 3405 | 3405 | ||
| 3406 | status = pci_restore_state(pdev); | 3406 | pci_restore_state(pdev); |
| 3407 | if (status) | ||
| 3408 | return status; | ||
| 3409 | 3407 | ||
| 3410 | status = pci_enable_device(pdev); | 3408 | status = pci_enable_device(pdev); |
| 3411 | if (status) { | 3409 | if (status) { |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bb8645ab247c..bde7d61f1930 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -554,6 +554,8 @@ struct rtl8169_private { | |||
| 554 | struct mii_if_info mii; | 554 | struct mii_if_info mii; |
| 555 | struct rtl8169_counters counters; | 555 | struct rtl8169_counters counters; |
| 556 | u32 saved_wolopts; | 556 | u32 saved_wolopts; |
| 557 | |||
| 558 | const struct firmware *fw; | ||
| 557 | }; | 559 | }; |
| 558 | 560 | ||
| 559 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 561 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
| @@ -1766,6 +1768,29 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) | |||
| 1766 | } | 1768 | } |
| 1767 | } | 1769 | } |
| 1768 | 1770 | ||
| 1771 | static void rtl_release_firmware(struct rtl8169_private *tp) | ||
| 1772 | { | ||
| 1773 | release_firmware(tp->fw); | ||
| 1774 | tp->fw = NULL; | ||
| 1775 | } | ||
| 1776 | |||
| 1777 | static int rtl_apply_firmware(struct rtl8169_private *tp, const char *fw_name) | ||
| 1778 | { | ||
| 1779 | const struct firmware **fw = &tp->fw; | ||
| 1780 | int rc = !*fw; | ||
| 1781 | |||
| 1782 | if (rc) { | ||
| 1783 | rc = request_firmware(fw, fw_name, &tp->pci_dev->dev); | ||
| 1784 | if (rc < 0) | ||
| 1785 | goto out; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | /* TODO: release firmware once rtl_phy_write_fw signals failures. */ | ||
| 1789 | rtl_phy_write_fw(tp, *fw); | ||
| 1790 | out: | ||
| 1791 | return rc; | ||
| 1792 | } | ||
| 1793 | |||
| 1769 | static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) | 1794 | static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) |
| 1770 | { | 1795 | { |
| 1771 | static const struct phy_reg phy_reg_init[] = { | 1796 | static const struct phy_reg phy_reg_init[] = { |
| @@ -2139,7 +2164,6 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) | |||
| 2139 | { 0x0d, 0xf880 } | 2164 | { 0x0d, 0xf880 } |
| 2140 | }; | 2165 | }; |
| 2141 | void __iomem *ioaddr = tp->mmio_addr; | 2166 | void __iomem *ioaddr = tp->mmio_addr; |
| 2142 | const struct firmware *fw; | ||
| 2143 | 2167 | ||
| 2144 | rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); | 2168 | rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); |
| 2145 | 2169 | ||
| @@ -2203,11 +2227,8 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) | |||
| 2203 | 2227 | ||
| 2204 | rtl_writephy(tp, 0x1f, 0x0005); | 2228 | rtl_writephy(tp, 0x1f, 0x0005); |
| 2205 | rtl_writephy(tp, 0x05, 0x001b); | 2229 | rtl_writephy(tp, 0x05, 0x001b); |
| 2206 | if (rtl_readphy(tp, 0x06) == 0xbf00 && | 2230 | if ((rtl_readphy(tp, 0x06) != 0xbf00) || |
| 2207 | request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) { | 2231 | (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) { |
| 2208 | rtl_phy_write_fw(tp, fw); | ||
| 2209 | release_firmware(fw); | ||
| 2210 | } else { | ||
| 2211 | netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); | 2232 | netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); |
| 2212 | } | 2233 | } |
| 2213 | 2234 | ||
| @@ -2257,7 +2278,6 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) | |||
| 2257 | { 0x0d, 0xf880 } | 2278 | { 0x0d, 0xf880 } |
| 2258 | }; | 2279 | }; |
| 2259 | void __iomem *ioaddr = tp->mmio_addr; | 2280 | void __iomem *ioaddr = tp->mmio_addr; |
| 2260 | const struct firmware *fw; | ||
| 2261 | 2281 | ||
| 2262 | rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); | 2282 | rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); |
| 2263 | 2283 | ||
| @@ -2312,11 +2332,8 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) | |||
| 2312 | 2332 | ||
| 2313 | rtl_writephy(tp, 0x1f, 0x0005); | 2333 | rtl_writephy(tp, 0x1f, 0x0005); |
| 2314 | rtl_writephy(tp, 0x05, 0x001b); | 2334 | rtl_writephy(tp, 0x05, 0x001b); |
| 2315 | if (rtl_readphy(tp, 0x06) == 0xb300 && | 2335 | if ((rtl_readphy(tp, 0x06) != 0xb300) || |
| 2316 | request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) { | 2336 | (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) { |
| 2317 | rtl_phy_write_fw(tp, fw); | ||
| 2318 | release_firmware(fw); | ||
| 2319 | } else { | ||
| 2320 | netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); | 2337 | netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); |
| 2321 | } | 2338 | } |
| 2322 | 2339 | ||
| @@ -3200,6 +3217,8 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
| 3200 | 3217 | ||
| 3201 | cancel_delayed_work_sync(&tp->task); | 3218 | cancel_delayed_work_sync(&tp->task); |
| 3202 | 3219 | ||
| 3220 | rtl_release_firmware(tp); | ||
| 3221 | |||
| 3203 | unregister_netdev(dev); | 3222 | unregister_netdev(dev); |
| 3204 | 3223 | ||
| 3205 | if (pci_dev_run_wake(pdev)) | 3224 | if (pci_dev_run_wake(pdev)) |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 711449c6e675..002bac743843 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
| @@ -1153,6 +1153,9 @@ static int efx_wanted_channels(void) | |||
| 1153 | int count; | 1153 | int count; |
| 1154 | int cpu; | 1154 | int cpu; |
| 1155 | 1155 | ||
| 1156 | if (rss_cpus) | ||
| 1157 | return rss_cpus; | ||
| 1158 | |||
| 1156 | if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) { | 1159 | if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) { |
| 1157 | printk(KERN_WARNING | 1160 | printk(KERN_WARNING |
| 1158 | "sfc: RSS disabled due to allocation failure\n"); | 1161 | "sfc: RSS disabled due to allocation failure\n"); |
| @@ -1266,27 +1269,18 @@ static void efx_remove_interrupts(struct efx_nic *efx) | |||
| 1266 | efx->legacy_irq = 0; | 1269 | efx->legacy_irq = 0; |
| 1267 | } | 1270 | } |
| 1268 | 1271 | ||
| 1269 | struct efx_tx_queue * | ||
| 1270 | efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) | ||
| 1271 | { | ||
| 1272 | unsigned tx_channel_offset = | ||
| 1273 | separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; | ||
| 1274 | EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || | ||
| 1275 | type >= EFX_TXQ_TYPES); | ||
| 1276 | return &efx->channel[tx_channel_offset + index]->tx_queue[type]; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | static void efx_set_channels(struct efx_nic *efx) | 1272 | static void efx_set_channels(struct efx_nic *efx) |
| 1280 | { | 1273 | { |
| 1281 | struct efx_channel *channel; | 1274 | struct efx_channel *channel; |
| 1282 | struct efx_tx_queue *tx_queue; | 1275 | struct efx_tx_queue *tx_queue; |
| 1283 | unsigned tx_channel_offset = | 1276 | |
| 1277 | efx->tx_channel_offset = | ||
| 1284 | separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; | 1278 | separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; |
| 1285 | 1279 | ||
| 1286 | /* Channel pointers were set in efx_init_struct() but we now | 1280 | /* Channel pointers were set in efx_init_struct() but we now |
| 1287 | * need to clear them for TX queues in any RX-only channels. */ | 1281 | * need to clear them for TX queues in any RX-only channels. */ |
| 1288 | efx_for_each_channel(channel, efx) { | 1282 | efx_for_each_channel(channel, efx) { |
| 1289 | if (channel->channel - tx_channel_offset >= | 1283 | if (channel->channel - efx->tx_channel_offset >= |
| 1290 | efx->n_tx_channels) { | 1284 | efx->n_tx_channels) { |
| 1291 | efx_for_each_channel_tx_queue(tx_queue, channel) | 1285 | efx_for_each_channel_tx_queue(tx_queue, channel) |
| 1292 | tx_queue->channel = NULL; | 1286 | tx_queue->channel = NULL; |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 70e4f7dcce81..61ddd2c6e750 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
| @@ -1107,22 +1107,9 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) | |||
| 1107 | 1107 | ||
| 1108 | /* Restore PCI configuration if needed */ | 1108 | /* Restore PCI configuration if needed */ |
| 1109 | if (method == RESET_TYPE_WORLD) { | 1109 | if (method == RESET_TYPE_WORLD) { |
| 1110 | if (efx_nic_is_dual_func(efx)) { | 1110 | if (efx_nic_is_dual_func(efx)) |
| 1111 | rc = pci_restore_state(nic_data->pci_dev2); | 1111 | pci_restore_state(nic_data->pci_dev2); |
| 1112 | if (rc) { | 1112 | pci_restore_state(efx->pci_dev); |
| 1113 | netif_err(efx, drv, efx->net_dev, | ||
| 1114 | "failed to restore PCI config for " | ||
| 1115 | "the secondary function\n"); | ||
| 1116 | goto fail3; | ||
| 1117 | } | ||
| 1118 | } | ||
| 1119 | rc = pci_restore_state(efx->pci_dev); | ||
| 1120 | if (rc) { | ||
| 1121 | netif_err(efx, drv, efx->net_dev, | ||
| 1122 | "failed to restore PCI config for the " | ||
| 1123 | "primary function\n"); | ||
| 1124 | goto fail4; | ||
| 1125 | } | ||
| 1126 | netif_dbg(efx, drv, efx->net_dev, | 1113 | netif_dbg(efx, drv, efx->net_dev, |
| 1127 | "successfully restored PCI config\n"); | 1114 | "successfully restored PCI config\n"); |
| 1128 | } | 1115 | } |
| @@ -1133,7 +1120,7 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) | |||
| 1133 | rc = -ETIMEDOUT; | 1120 | rc = -ETIMEDOUT; |
| 1134 | netif_err(efx, hw, efx->net_dev, | 1121 | netif_err(efx, hw, efx->net_dev, |
| 1135 | "timed out waiting for hardware reset\n"); | 1122 | "timed out waiting for hardware reset\n"); |
| 1136 | goto fail5; | 1123 | goto fail3; |
| 1137 | } | 1124 | } |
| 1138 | netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n"); | 1125 | netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n"); |
| 1139 | 1126 | ||
| @@ -1141,11 +1128,9 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) | |||
| 1141 | 1128 | ||
| 1142 | /* pci_save_state() and pci_restore_state() MUST be called in pairs */ | 1129 | /* pci_save_state() and pci_restore_state() MUST be called in pairs */ |
| 1143 | fail2: | 1130 | fail2: |
| 1144 | fail3: | ||
| 1145 | pci_restore_state(efx->pci_dev); | 1131 | pci_restore_state(efx->pci_dev); |
| 1146 | fail1: | 1132 | fail1: |
| 1147 | fail4: | 1133 | fail3: |
| 1148 | fail5: | ||
| 1149 | return rc; | 1134 | return rc; |
| 1150 | } | 1135 | } |
| 1151 | 1136 | ||
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index bdce66ddf93a..28df8665256a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
| @@ -735,6 +735,7 @@ struct efx_nic { | |||
| 735 | unsigned next_buffer_table; | 735 | unsigned next_buffer_table; |
| 736 | unsigned n_channels; | 736 | unsigned n_channels; |
| 737 | unsigned n_rx_channels; | 737 | unsigned n_rx_channels; |
| 738 | unsigned tx_channel_offset; | ||
| 738 | unsigned n_tx_channels; | 739 | unsigned n_tx_channels; |
| 739 | unsigned int rx_buffer_len; | 740 | unsigned int rx_buffer_len; |
| 740 | unsigned int rx_buffer_order; | 741 | unsigned int rx_buffer_order; |
| @@ -929,8 +930,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index) | |||
| 929 | _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ | 930 | _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ |
| 930 | (_efx)->channel[_channel->channel + 1] : NULL) | 931 | (_efx)->channel[_channel->channel + 1] : NULL) |
| 931 | 932 | ||
| 932 | extern struct efx_tx_queue * | 933 | static inline struct efx_tx_queue * |
| 933 | efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type); | 934 | efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) |
| 935 | { | ||
| 936 | EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || | ||
| 937 | type >= EFX_TXQ_TYPES); | ||
| 938 | return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type]; | ||
| 939 | } | ||
| 934 | 940 | ||
| 935 | static inline struct efx_tx_queue * | 941 | static inline struct efx_tx_queue * |
| 936 | efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) | 942 | efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) |
diff --git a/drivers/net/tile/tilepro.c b/drivers/net/tile/tilepro.c index 0e6bac5ec65b..7cb301da7474 100644 --- a/drivers/net/tile/tilepro.c +++ b/drivers/net/tile/tilepro.c | |||
| @@ -142,14 +142,6 @@ | |||
| 142 | MODULE_AUTHOR("Tilera"); | 142 | MODULE_AUTHOR("Tilera"); |
| 143 | MODULE_LICENSE("GPL"); | 143 | MODULE_LICENSE("GPL"); |
| 144 | 144 | ||
| 145 | |||
| 146 | #define IS_MULTICAST(mac_addr) \ | ||
| 147 | (((u8 *)(mac_addr))[0] & 0x01) | ||
| 148 | |||
| 149 | #define IS_BROADCAST(mac_addr) \ | ||
| 150 | (((u16 *)(mac_addr))[0] == 0xffff) | ||
| 151 | |||
| 152 | |||
| 153 | /* | 145 | /* |
| 154 | * Queue of incoming packets for a specific cpu and device. | 146 | * Queue of incoming packets for a specific cpu and device. |
| 155 | * | 147 | * |
| @@ -795,7 +787,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) | |||
| 795 | /* | 787 | /* |
| 796 | * FIXME: Implement HW multicast filter. | 788 | * FIXME: Implement HW multicast filter. |
| 797 | */ | 789 | */ |
| 798 | if (!IS_MULTICAST(buf) && !IS_BROADCAST(buf)) { | 790 | if (is_unicast_ether_addr(buf)) { |
| 799 | /* Filter packets not for our address. */ | 791 | /* Filter packets not for our address. */ |
| 800 | const u8 *mine = dev->dev_addr; | 792 | const u8 *mine = dev->dev_addr; |
| 801 | filter = compare_ether_addr(mine, buf); | 793 | filter = compare_ether_addr(mine, buf); |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 73a3e0d93237..715e7b47e7e9 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
| @@ -2032,7 +2032,7 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
| 2032 | netdev_for_each_mc_addr(ha, dev) { | 2032 | netdev_for_each_mc_addr(ha, dev) { |
| 2033 | /* Only support group multicast for now. | 2033 | /* Only support group multicast for now. |
| 2034 | */ | 2034 | */ |
| 2035 | if (!(ha->addr[0] & 1)) | 2035 | if (!is_multicast_ether_addr(ha->addr)) |
| 2036 | continue; | 2036 | continue; |
| 2037 | 2037 | ||
| 2038 | /* Ask CPM to run CRC and set bit in | 2038 | /* Ask CPM to run CRC and set bit in |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 593c104ab199..d776c4a8d3c1 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
| @@ -1021,13 +1021,15 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
| 1021 | (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { | 1021 | (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { |
| 1022 | pr_debug("invalid frame detected (ignored)" | 1022 | pr_debug("invalid frame detected (ignored)" |
| 1023 | "offset[%u]=%u, length=%u, skb=%p\n", | 1023 | "offset[%u]=%u, length=%u, skb=%p\n", |
| 1024 | x, offset, temp, skb); | 1024 | x, offset, temp, skb_in); |
| 1025 | if (!x) | 1025 | if (!x) |
| 1026 | goto error; | 1026 | goto error; |
| 1027 | break; | 1027 | break; |
| 1028 | 1028 | ||
| 1029 | } else { | 1029 | } else { |
| 1030 | skb = skb_clone(skb_in, GFP_ATOMIC); | 1030 | skb = skb_clone(skb_in, GFP_ATOMIC); |
| 1031 | if (!skb) | ||
| 1032 | goto error; | ||
| 1031 | skb->len = temp; | 1033 | skb->len = temp; |
| 1032 | skb->data = ((u8 *)skb_in->data) + offset; | 1034 | skb->data = ((u8 *)skb_in->data) + offset; |
| 1033 | skb_set_tail_pointer(skb, temp); | 1035 | skb_set_tail_pointer(skb, temp); |
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 1ac9b568f1b0..c81a6512c683 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
| @@ -4120,6 +4120,7 @@ int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override) | |||
| 4120 | "hotplug event.\n"); | 4120 | "hotplug event.\n"); |
| 4121 | 4121 | ||
| 4122 | out: | 4122 | out: |
| 4123 | release_firmware(fw); | ||
| 4123 | return ret; | 4124 | return ret; |
| 4124 | } | 4125 | } |
| 4125 | 4126 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 01880aa13e36..ea2e7d714bda 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
| @@ -954,6 +954,9 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah) | |||
| 954 | &adc_dc_cal_multi_sample; | 954 | &adc_dc_cal_multi_sample; |
| 955 | } | 955 | } |
| 956 | ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; | 956 | ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; |
| 957 | |||
| 958 | if (AR_SREV_9287(ah)) | ||
| 959 | ah->supp_cals &= ~ADC_GAIN_CAL; | ||
| 957 | } | 960 | } |
| 958 | } | 961 | } |
| 959 | 962 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 088f141f2006..749a93608664 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
| @@ -226,6 +226,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
| 226 | eep->baseEepHeader.pwdclkind == 0) | 226 | eep->baseEepHeader.pwdclkind == 0) |
| 227 | ah->need_an_top2_fixup = 1; | 227 | ah->need_an_top2_fixup = 1; |
| 228 | 228 | ||
| 229 | if ((common->bus_ops->ath_bus_type == ATH_USB) && | ||
| 230 | (AR_SREV_9280(ah))) | ||
| 231 | eep->modalHeader[0].xpaBiasLvl = 0; | ||
| 232 | |||
| 229 | return 0; | 233 | return 0; |
| 230 | } | 234 | } |
| 231 | 235 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index a099b3e87ed3..1ce506f23110 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
| @@ -433,6 +433,7 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, | |||
| 433 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | 433 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, |
| 434 | enum htc_endpoint_id ep_id, bool txok); | 434 | enum htc_endpoint_id ep_id, bool txok); |
| 435 | 435 | ||
| 436 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); | ||
| 436 | void ath9k_htc_station_work(struct work_struct *work); | 437 | void ath9k_htc_station_work(struct work_struct *work); |
| 437 | void ath9k_htc_aggr_work(struct work_struct *work); | 438 | void ath9k_htc_aggr_work(struct work_struct *work); |
| 438 | void ath9k_ani_work(struct work_struct *work);; | 439 | void ath9k_ani_work(struct work_struct *work);; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 845b4c938d16..f4d576bc3ccd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -301,6 +301,16 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
| 301 | 301 | ||
| 302 | priv->nstations++; | 302 | priv->nstations++; |
| 303 | 303 | ||
| 304 | /* | ||
| 305 | * Set chainmask etc. on the target. | ||
| 306 | */ | ||
| 307 | ret = ath9k_htc_update_cap_target(priv); | ||
| 308 | if (ret) | ||
| 309 | ath_dbg(common, ATH_DBG_CONFIG, | ||
| 310 | "Failed to update capability in target\n"); | ||
| 311 | |||
| 312 | priv->ah->is_monitoring = true; | ||
| 313 | |||
| 304 | return 0; | 314 | return 0; |
| 305 | 315 | ||
| 306 | err_vif: | 316 | err_vif: |
| @@ -328,6 +338,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) | |||
| 328 | } | 338 | } |
| 329 | 339 | ||
| 330 | priv->nstations--; | 340 | priv->nstations--; |
| 341 | priv->ah->is_monitoring = false; | ||
| 331 | 342 | ||
| 332 | return 0; | 343 | return 0; |
| 333 | } | 344 | } |
| @@ -419,7 +430,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, | |||
| 419 | return 0; | 430 | return 0; |
| 420 | } | 431 | } |
| 421 | 432 | ||
| 422 | static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | 433 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) |
| 423 | { | 434 | { |
| 424 | struct ath9k_htc_cap_target tcap; | 435 | struct ath9k_htc_cap_target tcap; |
| 425 | int ret; | 436 | int ret; |
| @@ -1186,6 +1197,20 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1186 | } | 1197 | } |
| 1187 | } | 1198 | } |
| 1188 | 1199 | ||
| 1200 | /* | ||
| 1201 | * Monitor interface should be added before | ||
| 1202 | * IEEE80211_CONF_CHANGE_CHANNEL is handled. | ||
| 1203 | */ | ||
| 1204 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
| 1205 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
| 1206 | if (ath9k_htc_add_monitor_interface(priv)) | ||
| 1207 | ath_err(common, "Failed to set monitor mode\n"); | ||
| 1208 | else | ||
| 1209 | ath_dbg(common, ATH_DBG_CONFIG, | ||
| 1210 | "HW opmode set to Monitor mode\n"); | ||
| 1211 | } | ||
| 1212 | } | ||
| 1213 | |||
| 1189 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1214 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 1190 | struct ieee80211_channel *curchan = hw->conf.channel; | 1215 | struct ieee80211_channel *curchan = hw->conf.channel; |
| 1191 | int pos = curchan->hw_value; | 1216 | int pos = curchan->hw_value; |
| @@ -1221,16 +1246,6 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1221 | ath_update_txpow(priv); | 1246 | ath_update_txpow(priv); |
| 1222 | } | 1247 | } |
| 1223 | 1248 | ||
| 1224 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
| 1225 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
| 1226 | if (ath9k_htc_add_monitor_interface(priv)) | ||
| 1227 | ath_err(common, "Failed to set monitor mode\n"); | ||
| 1228 | else | ||
| 1229 | ath_dbg(common, ATH_DBG_CONFIG, | ||
| 1230 | "HW opmode set to Monitor mode\n"); | ||
| 1231 | } | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 1249 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
| 1235 | mutex_lock(&priv->htc_pm_lock); | 1250 | mutex_lock(&priv->htc_pm_lock); |
| 1236 | if (!priv->ps_idle) { | 1251 | if (!priv->ps_idle) { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fde978665e07..1afb8bb85756 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -436,9 +436,10 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah) | |||
| 436 | 436 | ||
| 437 | static int ath9k_hw_post_init(struct ath_hw *ah) | 437 | static int ath9k_hw_post_init(struct ath_hw *ah) |
| 438 | { | 438 | { |
| 439 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 439 | int ecode; | 440 | int ecode; |
| 440 | 441 | ||
| 441 | if (!AR_SREV_9271(ah)) { | 442 | if (common->bus_ops->ath_bus_type != ATH_USB) { |
| 442 | if (!ath9k_hw_chip_test(ah)) | 443 | if (!ath9k_hw_chip_test(ah)) |
| 443 | return -ENODEV; | 444 | return -ENODEV; |
| 444 | } | 445 | } |
| @@ -1213,7 +1214,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
| 1213 | ah->txchainmask = common->tx_chainmask; | 1214 | ah->txchainmask = common->tx_chainmask; |
| 1214 | ah->rxchainmask = common->rx_chainmask; | 1215 | ah->rxchainmask = common->rx_chainmask; |
| 1215 | 1216 | ||
| 1216 | if (!ah->chip_fullsleep) { | 1217 | if ((common->bus_ops->ath_bus_type != ATH_USB) && !ah->chip_fullsleep) { |
| 1217 | ath9k_hw_abortpcurecv(ah); | 1218 | ath9k_hw_abortpcurecv(ah); |
| 1218 | if (!ath9k_hw_stopdmarecv(ah)) { | 1219 | if (!ath9k_hw_stopdmarecv(ah)) { |
| 1219 | ath_dbg(common, ATH_DBG_XMIT, | 1220 | ath_dbg(common, ATH_DBG_XMIT, |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index bd8a4134edeb..2176edede39b 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
| @@ -518,22 +518,21 @@ static int prism2_config(struct pcmcia_device *link) | |||
| 518 | hw_priv->link = link; | 518 | hw_priv->link = link; |
| 519 | 519 | ||
| 520 | /* | 520 | /* |
| 521 | * Make sure the IRQ handler cannot proceed until at least | 521 | * We enable IRQ here, but IRQ handler will not proceed |
| 522 | * dev->base_addr is initialized. | 522 | * until dev->base_addr is set below. This protect us from |
| 523 | * receive interrupts when driver is not initialized. | ||
| 523 | */ | 524 | */ |
| 524 | spin_lock_irqsave(&local->irq_init_lock, flags); | ||
| 525 | |||
| 526 | ret = pcmcia_request_irq(link, prism2_interrupt); | 525 | ret = pcmcia_request_irq(link, prism2_interrupt); |
| 527 | if (ret) | 526 | if (ret) |
| 528 | goto failed_unlock; | 527 | goto failed; |
| 529 | 528 | ||
| 530 | ret = pcmcia_enable_device(link); | 529 | ret = pcmcia_enable_device(link); |
| 531 | if (ret) | 530 | if (ret) |
| 532 | goto failed_unlock; | 531 | goto failed; |
| 533 | 532 | ||
| 533 | spin_lock_irqsave(&local->irq_init_lock, flags); | ||
| 534 | dev->irq = link->irq; | 534 | dev->irq = link->irq; |
| 535 | dev->base_addr = link->resource[0]->start; | 535 | dev->base_addr = link->resource[0]->start; |
| 536 | |||
| 537 | spin_unlock_irqrestore(&local->irq_init_lock, flags); | 536 | spin_unlock_irqrestore(&local->irq_init_lock, flags); |
| 538 | 537 | ||
| 539 | local->shutdown = 0; | 538 | local->shutdown = 0; |
| @@ -546,8 +545,6 @@ static int prism2_config(struct pcmcia_device *link) | |||
| 546 | 545 | ||
| 547 | return ret; | 546 | return ret; |
| 548 | 547 | ||
| 549 | failed_unlock: | ||
| 550 | spin_unlock_irqrestore(&local->irq_init_lock, flags); | ||
| 551 | failed: | 548 | failed: |
| 552 | kfree(hw_priv); | 549 | kfree(hw_priv); |
| 553 | prism2_release((u_long)link); | 550 | prism2_release((u_long)link); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 8d6ed5f6f46f..ae438ed80c2f 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
| @@ -1973,6 +1973,13 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 1973 | 1973 | ||
| 1974 | inta = ipw_read32(priv, IPW_INTA_RW); | 1974 | inta = ipw_read32(priv, IPW_INTA_RW); |
| 1975 | inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); | 1975 | inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); |
| 1976 | |||
| 1977 | if (inta == 0xFFFFFFFF) { | ||
| 1978 | /* Hardware disappeared */ | ||
| 1979 | IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n"); | ||
| 1980 | /* Only handle the cached INTA values */ | ||
| 1981 | inta = 0; | ||
| 1982 | } | ||
| 1976 | inta &= (IPW_INTA_MASK_ALL & inta_mask); | 1983 | inta &= (IPW_INTA_MASK_ALL & inta_mask); |
| 1977 | 1984 | ||
| 1978 | /* Add any cached INTA values that need to be handled */ | 1985 | /* Add any cached INTA values that need to be handled */ |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 76b2318a7dc7..f618b9623e5a 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
| @@ -618,7 +618,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb, | |||
| 618 | else | 618 | else |
| 619 | *burst_possible = false; | 619 | *burst_possible = false; |
| 620 | 620 | ||
| 621 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | 621 | if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) |
| 622 | *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR; | 622 | *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR; |
| 623 | 623 | ||
| 624 | if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE) | 624 | if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 73631c6fbb30..ace0b668c04e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
| @@ -363,12 +363,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) | |||
| 363 | struct rt2x00_dev *rt2x00dev = hw->priv; | 363 | struct rt2x00_dev *rt2x00dev = hw->priv; |
| 364 | 364 | ||
| 365 | if (pci_set_power_state(pci_dev, PCI_D0) || | 365 | if (pci_set_power_state(pci_dev, PCI_D0) || |
| 366 | pci_enable_device(pci_dev) || | 366 | pci_enable_device(pci_dev)) { |
| 367 | pci_restore_state(pci_dev)) { | ||
| 368 | ERROR(rt2x00dev, "Failed to resume device.\n"); | 367 | ERROR(rt2x00dev, "Failed to resume device.\n"); |
| 369 | return -EIO; | 368 | return -EIO; |
| 370 | } | 369 | } |
| 371 | 370 | ||
| 371 | pci_restore_state(pci_dev); | ||
| 372 | return rt2x00lib_resume(rt2x00dev); | 372 | return rt2x00lib_resume(rt2x00dev); |
| 373 | } | 373 | } |
| 374 | EXPORT_SYMBOL_GPL(rt2x00pci_resume); | 374 | EXPORT_SYMBOL_GPL(rt2x00pci_resume); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7c24dcef2989..44b0aeee83e5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -168,8 +168,9 @@ static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag) | |||
| 168 | u32 mask_bits = desc->masked; | 168 | u32 mask_bits = desc->masked; |
| 169 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | 169 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + |
| 170 | PCI_MSIX_ENTRY_VECTOR_CTRL; | 170 | PCI_MSIX_ENTRY_VECTOR_CTRL; |
| 171 | mask_bits &= ~1; | 171 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; |
| 172 | mask_bits |= flag; | 172 | if (flag) |
| 173 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; | ||
| 173 | writel(mask_bits, desc->mask_base + offset); | 174 | writel(mask_bits, desc->mask_base + offset); |
| 174 | 175 | ||
| 175 | return mask_bits; | 176 | return mask_bits; |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index feff3bee6fe5..65c42f80f23e 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
| @@ -6,12 +6,6 @@ | |||
| 6 | #ifndef MSI_H | 6 | #ifndef MSI_H |
| 7 | #define MSI_H | 7 | #define MSI_H |
| 8 | 8 | ||
| 9 | #define PCI_MSIX_ENTRY_SIZE 16 | ||
| 10 | #define PCI_MSIX_ENTRY_LOWER_ADDR 0 | ||
| 11 | #define PCI_MSIX_ENTRY_UPPER_ADDR 4 | ||
| 12 | #define PCI_MSIX_ENTRY_DATA 8 | ||
| 13 | #define PCI_MSIX_ENTRY_VECTOR_CTRL 12 | ||
| 14 | |||
| 15 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | 9 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) |
| 16 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) | 10 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) |
| 17 | #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) | 11 | #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 24e19c594e57..6fe0772e0e7d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -46,9 +46,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | |||
| 46 | struct pci_dev *pci_dev = context; | 46 | struct pci_dev *pci_dev = context; |
| 47 | 47 | ||
| 48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | 48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { |
| 49 | pci_wakeup_event(pci_dev); | ||
| 49 | pci_check_pme_status(pci_dev); | 50 | pci_check_pme_status(pci_dev); |
| 50 | pm_runtime_resume(&pci_dev->dev); | 51 | pm_runtime_resume(&pci_dev->dev); |
| 51 | pci_wakeup_event(pci_dev); | ||
| 52 | if (pci_dev->subordinate) | 52 | if (pci_dev->subordinate) |
| 53 | pci_pme_wakeup_bus(pci_dev->subordinate); | 53 | pci_pme_wakeup_bus(pci_dev->subordinate); |
| 54 | } | 54 | } |
| @@ -399,6 +399,7 @@ static int __init acpi_pci_init(void) | |||
| 399 | 399 | ||
| 400 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | 400 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { |
| 401 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); | 401 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); |
| 402 | pcie_clear_aspm(); | ||
| 402 | pcie_no_aspm(); | 403 | pcie_no_aspm(); |
| 403 | } | 404 | } |
| 404 | 405 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8a6f797de8e5..88246dd46452 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -338,7 +338,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | |||
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | /** | 340 | /** |
| 341 | * __pci_device_probe() | 341 | * __pci_device_probe - check if a driver wants to claim a specific PCI device |
| 342 | * @drv: driver to call to check if it wants the PCI device | 342 | * @drv: driver to call to check if it wants the PCI device |
| 343 | * @pci_dev: PCI device being probed | 343 | * @pci_dev: PCI device being probed |
| 344 | * | 344 | * |
| @@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) | |||
| 449 | return error; | 449 | return error; |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | return pci_restore_state(pci_dev); | 452 | pci_restore_state(pci_dev); |
| 453 | return 0; | ||
| 453 | } | 454 | } |
| 454 | 455 | ||
| 455 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) | 456 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) |
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c index f7b68ca6cc98..775e933c2225 100644 --- a/drivers/pci/pci-stub.c +++ b/drivers/pci/pci-stub.c | |||
| @@ -47,6 +47,10 @@ static int __init pci_stub_init(void) | |||
| 47 | if (rc) | 47 | if (rc) |
| 48 | return rc; | 48 | return rc; |
| 49 | 49 | ||
| 50 | /* no ids passed actually */ | ||
| 51 | if (ids[0] == '\0') | ||
| 52 | return 0; | ||
| 53 | |||
| 50 | /* add ids specified in the module parameter */ | 54 | /* add ids specified in the module parameter */ |
| 51 | p = ids; | 55 | p = ids; |
| 52 | while ((id = strsep(&p, ","))) { | 56 | while ((id = strsep(&p, ","))) { |
| @@ -54,6 +58,9 @@ static int __init pci_stub_init(void) | |||
| 54 | subdevice = PCI_ANY_ID, class=0, class_mask=0; | 58 | subdevice = PCI_ANY_ID, class=0, class_mask=0; |
| 55 | int fields; | 59 | int fields; |
| 56 | 60 | ||
| 61 | if (!strlen(id)) | ||
| 62 | continue; | ||
| 63 | |||
| 57 | fields = sscanf(id, "%x:%x:%x:%x:%x:%x", | 64 | fields = sscanf(id, "%x:%x:%x:%x:%x:%x", |
| 58 | &vendor, &device, &subvendor, &subdevice, | 65 | &vendor, &device, &subvendor, &subdevice, |
| 59 | &class, &class_mask); | 66 | &class, &class_mask); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 63d5042f2079..8ecaac983923 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -1149,7 +1149,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
| 1149 | sysfs_bin_attr_init(attr); | 1149 | sysfs_bin_attr_init(attr); |
| 1150 | attr->size = rom_size; | 1150 | attr->size = rom_size; |
| 1151 | attr->attr.name = "rom"; | 1151 | attr->attr.name = "rom"; |
| 1152 | attr->attr.mode = S_IRUSR; | 1152 | attr->attr.mode = S_IRUSR | S_IWUSR; |
| 1153 | attr->read = pci_read_rom; | 1153 | attr->read = pci_read_rom; |
| 1154 | attr->write = pci_write_rom; | 1154 | attr->write = pci_write_rom; |
| 1155 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); | 1155 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 710c8a29be0d..b714d787bddd 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev) | |||
| 937 | * pci_restore_state - Restore the saved state of a PCI device | 937 | * pci_restore_state - Restore the saved state of a PCI device |
| 938 | * @dev: - PCI device that we're dealing with | 938 | * @dev: - PCI device that we're dealing with |
| 939 | */ | 939 | */ |
| 940 | int | 940 | void pci_restore_state(struct pci_dev *dev) |
| 941 | pci_restore_state(struct pci_dev *dev) | ||
| 942 | { | 941 | { |
| 943 | int i; | 942 | int i; |
| 944 | u32 val; | 943 | u32 val; |
| 945 | 944 | ||
| 946 | if (!dev->state_saved) | 945 | if (!dev->state_saved) |
| 947 | return 0; | 946 | return; |
| 948 | 947 | ||
| 949 | /* PCI Express register must be restored first */ | 948 | /* PCI Express register must be restored first */ |
| 950 | pci_restore_pcie_state(dev); | 949 | pci_restore_pcie_state(dev); |
| @@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev) | |||
| 968 | pci_restore_iov_state(dev); | 967 | pci_restore_iov_state(dev); |
| 969 | 968 | ||
| 970 | dev->state_saved = false; | 969 | dev->state_saved = false; |
| 971 | |||
| 972 | return 0; | ||
| 973 | } | 970 | } |
| 974 | 971 | ||
| 975 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 972 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
| @@ -1300,22 +1297,6 @@ bool pci_check_pme_status(struct pci_dev *dev) | |||
| 1300 | return ret; | 1297 | return ret; |
| 1301 | } | 1298 | } |
| 1302 | 1299 | ||
| 1303 | /* | ||
| 1304 | * Time to wait before the system can be put into a sleep state after reporting | ||
| 1305 | * a wakeup event signaled by a PCI device. | ||
| 1306 | */ | ||
| 1307 | #define PCI_WAKEUP_COOLDOWN 100 | ||
| 1308 | |||
| 1309 | /** | ||
| 1310 | * pci_wakeup_event - Report a wakeup event related to a given PCI device. | ||
| 1311 | * @dev: Device to report the wakeup event for. | ||
| 1312 | */ | ||
| 1313 | void pci_wakeup_event(struct pci_dev *dev) | ||
| 1314 | { | ||
| 1315 | if (device_may_wakeup(&dev->dev)) | ||
| 1316 | pm_wakeup_event(&dev->dev, PCI_WAKEUP_COOLDOWN); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | /** | 1300 | /** |
| 1320 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | 1301 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. |
| 1321 | * @dev: Device to handle. | 1302 | * @dev: Device to handle. |
| @@ -1327,8 +1308,8 @@ void pci_wakeup_event(struct pci_dev *dev) | |||
| 1327 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | 1308 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) |
| 1328 | { | 1309 | { |
| 1329 | if (pci_check_pme_status(dev)) { | 1310 | if (pci_check_pme_status(dev)) { |
| 1330 | pm_request_resume(&dev->dev); | ||
| 1331 | pci_wakeup_event(dev); | 1311 | pci_wakeup_event(dev); |
| 1312 | pm_request_resume(&dev->dev); | ||
| 1332 | } | 1313 | } |
| 1333 | return 0; | 1314 | return 0; |
| 1334 | } | 1315 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 7d33f6673868..f69d6e0fda75 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -74,6 +74,12 @@ extern void pci_pm_init(struct pci_dev *dev); | |||
| 74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
| 75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
| 76 | 76 | ||
| 77 | static inline void pci_wakeup_event(struct pci_dev *dev) | ||
| 78 | { | ||
| 79 | /* Wait 100 ms before the system can be put into a sleep state. */ | ||
| 80 | pm_wakeup_event(&dev->dev, 100); | ||
| 81 | } | ||
| 82 | |||
| 77 | static inline bool pci_is_bridge(struct pci_dev *pci_dev) | 83 | static inline bool pci_is_bridge(struct pci_dev *pci_dev) |
| 78 | { | 84 | { |
| 79 | return !!(pci_dev->subordinate); | 85 | return !!(pci_dev->subordinate); |
| @@ -140,14 +146,6 @@ static inline void pci_no_msi(void) { } | |||
| 140 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 146 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
| 141 | #endif | 147 | #endif |
| 142 | 148 | ||
| 143 | #ifdef CONFIG_PCIEAER | ||
| 144 | void pci_no_aer(void); | ||
| 145 | bool pci_aer_available(void); | ||
| 146 | #else | ||
| 147 | static inline void pci_no_aer(void) { } | ||
| 148 | static inline bool pci_aer_available(void) { return false; } | ||
| 149 | #endif | ||
| 150 | |||
| 151 | static inline int pci_no_d1d2(struct pci_dev *dev) | 149 | static inline int pci_no_d1d2(struct pci_dev *dev) |
| 152 | { | 150 | { |
| 153 | unsigned int parent_dstates = 0; | 151 | unsigned int parent_dstates = 0; |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 2b2b6508efde..58ad7917553c 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
| 20 | #include <linux/pci-acpi.h> | ||
| 20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 22 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 9656e3060412..80c11d131499 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
| @@ -132,7 +132,6 @@ static inline int aer_osc_setup(struct pcie_device *pciedev) | |||
| 132 | 132 | ||
| 133 | #ifdef CONFIG_ACPI_APEI | 133 | #ifdef CONFIG_ACPI_APEI |
| 134 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); | 134 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); |
| 135 | extern bool aer_acpi_firmware_first(void); | ||
| 136 | #else | 135 | #else |
| 137 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | 136 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) |
| 138 | { | 137 | { |
| @@ -140,8 +139,6 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | |||
| 140 | return pci_dev->__aer_firmware_first; | 139 | return pci_dev->__aer_firmware_first; |
| 141 | return 0; | 140 | return 0; |
| 142 | } | 141 | } |
| 143 | |||
| 144 | static inline bool aer_acpi_firmware_first(void) { return false; } | ||
| 145 | #endif | 142 | #endif |
| 146 | 143 | ||
| 147 | static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, | 144 | static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 71222814c1ec..3188cd96b338 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -68,7 +68,7 @@ struct pcie_link_state { | |||
| 68 | struct aspm_latency acceptable[8]; | 68 | struct aspm_latency acceptable[8]; |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | static int aspm_disabled, aspm_force; | 71 | static int aspm_disabled, aspm_force, aspm_clear_state; |
| 72 | static DEFINE_MUTEX(aspm_lock); | 72 | static DEFINE_MUTEX(aspm_lock); |
| 73 | static LIST_HEAD(link_list); | 73 | static LIST_HEAD(link_list); |
| 74 | 74 | ||
| @@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) | |||
| 139 | { | 139 | { |
| 140 | /* Don't enable Clock PM if the link is not Clock PM capable */ | 140 | /* Don't enable Clock PM if the link is not Clock PM capable */ |
| 141 | if (!link->clkpm_capable && enable) | 141 | if (!link->clkpm_capable && enable) |
| 142 | return; | 142 | enable = 0; |
| 143 | /* Need nothing if the specified equals to current state */ | 143 | /* Need nothing if the specified equals to current state */ |
| 144 | if (link->clkpm_enabled == enable) | 144 | if (link->clkpm_enabled == enable) |
| 145 | return; | 145 | return; |
| @@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
| 498 | struct pci_dev *child; | 498 | struct pci_dev *child; |
| 499 | int pos; | 499 | int pos; |
| 500 | u32 reg32; | 500 | u32 reg32; |
| 501 | |||
| 502 | if (aspm_clear_state) | ||
| 503 | return -EINVAL; | ||
| 504 | |||
| 501 | /* | 505 | /* |
| 502 | * Some functions in a slot might not all be PCIe functions, | 506 | * Some functions in a slot might not all be PCIe functions, |
| 503 | * very strange. Disable ASPM for the whole slot | 507 | * very strange. Disable ASPM for the whole slot |
| @@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
| 563 | struct pcie_link_state *link; | 567 | struct pcie_link_state *link; |
| 564 | int blacklist = !!pcie_aspm_sanity_check(pdev); | 568 | int blacklist = !!pcie_aspm_sanity_check(pdev); |
| 565 | 569 | ||
| 566 | if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) | 570 | if (!pci_is_pcie(pdev) || pdev->link_state) |
| 567 | return; | 571 | return; |
| 568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 572 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
| 569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 573 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
| 570 | return; | 574 | return; |
| 571 | 575 | ||
| 576 | if (aspm_disabled && !aspm_clear_state) | ||
| 577 | return; | ||
| 578 | |||
| 572 | /* VIA has a strange chipset, root port is under a bridge */ | 579 | /* VIA has a strange chipset, root port is under a bridge */ |
| 573 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && | 580 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && |
| 574 | pdev->bus->self) | 581 | pdev->bus->self) |
| @@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
| 641 | struct pci_dev *parent = pdev->bus->self; | 648 | struct pci_dev *parent = pdev->bus->self; |
| 642 | struct pcie_link_state *link, *root, *parent_link; | 649 | struct pcie_link_state *link, *root, *parent_link; |
| 643 | 650 | ||
| 644 | if (aspm_disabled || !pci_is_pcie(pdev) || | 651 | if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || |
| 645 | !parent || !parent->link_state) | 652 | !parent || !parent->link_state) |
| 646 | return; | 653 | return; |
| 647 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 654 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
| @@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str) | |||
| 899 | 906 | ||
| 900 | __setup("pcie_aspm=", pcie_aspm_disable); | 907 | __setup("pcie_aspm=", pcie_aspm_disable); |
| 901 | 908 | ||
| 909 | void pcie_clear_aspm(void) | ||
| 910 | { | ||
| 911 | if (!aspm_force) | ||
| 912 | aspm_clear_state = 1; | ||
| 913 | } | ||
| 914 | |||
| 902 | void pcie_no_aspm(void) | 915 | void pcie_no_aspm(void) |
| 903 | { | 916 | { |
| 904 | if (!aspm_force) | 917 | if (!aspm_force) |
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 2f3c90407227..0057344a3fcb 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
| @@ -26,9 +26,6 @@ | |||
| 26 | #include "../pci.h" | 26 | #include "../pci.h" |
| 27 | #include "portdrv.h" | 27 | #include "portdrv.h" |
| 28 | 28 | ||
| 29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | ||
| 30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | ||
| 31 | |||
| 32 | /* | 29 | /* |
| 33 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | 30 | * If this switch is set, MSI will not be used for PCIe PME signaling. This |
| 34 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | 31 | * causes the PCIe port driver to use INTx interrupts only, but it turns out |
| @@ -74,22 +71,6 @@ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) | |||
| 74 | } | 71 | } |
| 75 | 72 | ||
| 76 | /** | 73 | /** |
| 77 | * pcie_pme_clear_status - Clear root port PME interrupt status. | ||
| 78 | * @dev: PCIe root port or event collector. | ||
| 79 | */ | ||
| 80 | static void pcie_pme_clear_status(struct pci_dev *dev) | ||
| 81 | { | ||
| 82 | int rtsta_pos; | ||
| 83 | u32 rtsta; | ||
| 84 | |||
| 85 | rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; | ||
| 86 | |||
| 87 | pci_read_config_dword(dev, rtsta_pos, &rtsta); | ||
| 88 | rtsta |= PCI_EXP_RTSTA_PME; | ||
| 89 | pci_write_config_dword(dev, rtsta_pos, rtsta); | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. | 74 | * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. |
| 94 | * @bus: PCI bus to scan. | 75 | * @bus: PCI bus to scan. |
| 95 | * | 76 | * |
| @@ -103,8 +84,8 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus) | |||
| 103 | list_for_each_entry(dev, &bus->devices, bus_list) { | 84 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 104 | /* Skip PCIe devices in case we started from a root port. */ | 85 | /* Skip PCIe devices in case we started from a root port. */ |
| 105 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { | 86 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { |
| 106 | pm_request_resume(&dev->dev); | ||
| 107 | pci_wakeup_event(dev); | 87 | pci_wakeup_event(dev); |
| 88 | pm_request_resume(&dev->dev); | ||
| 108 | ret = true; | 89 | ret = true; |
| 109 | } | 90 | } |
| 110 | 91 | ||
| @@ -206,8 +187,8 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) | |||
| 206 | /* The device is there, but we have to check its PME status. */ | 187 | /* The device is there, but we have to check its PME status. */ |
| 207 | found = pci_check_pme_status(dev); | 188 | found = pci_check_pme_status(dev); |
| 208 | if (found) { | 189 | if (found) { |
| 209 | pm_request_resume(&dev->dev); | ||
| 210 | pci_wakeup_event(dev); | 190 | pci_wakeup_event(dev); |
| 191 | pm_request_resume(&dev->dev); | ||
| 211 | } | 192 | } |
| 212 | pci_dev_put(dev); | 193 | pci_dev_put(dev); |
| 213 | } else if (devfn) { | 194 | } else if (devfn) { |
| @@ -253,7 +234,7 @@ static void pcie_pme_work_fn(struct work_struct *work) | |||
| 253 | * Clear PME status of the port. If there are other | 234 | * Clear PME status of the port. If there are other |
| 254 | * pending PMEs, the status will be set again. | 235 | * pending PMEs, the status will be set again. |
| 255 | */ | 236 | */ |
| 256 | pcie_pme_clear_status(port); | 237 | pcie_clear_root_pme_status(port); |
| 257 | 238 | ||
| 258 | spin_unlock_irq(&data->lock); | 239 | spin_unlock_irq(&data->lock); |
| 259 | pcie_pme_handle_request(port, rtsta & 0xffff); | 240 | pcie_pme_handle_request(port, rtsta & 0xffff); |
| @@ -378,7 +359,7 @@ static int pcie_pme_probe(struct pcie_device *srv) | |||
| 378 | 359 | ||
| 379 | port = srv->port; | 360 | port = srv->port; |
| 380 | pcie_pme_interrupt_enable(port, false); | 361 | pcie_pme_interrupt_enable(port, false); |
| 381 | pcie_pme_clear_status(port); | 362 | pcie_clear_root_pme_status(port); |
| 382 | 363 | ||
| 383 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); | 364 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); |
| 384 | if (ret) { | 365 | if (ret) { |
| @@ -402,7 +383,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) | |||
| 402 | 383 | ||
| 403 | spin_lock_irq(&data->lock); | 384 | spin_lock_irq(&data->lock); |
| 404 | pcie_pme_interrupt_enable(port, false); | 385 | pcie_pme_interrupt_enable(port, false); |
| 405 | pcie_pme_clear_status(port); | 386 | pcie_clear_root_pme_status(port); |
| 406 | data->noirq = true; | 387 | data->noirq = true; |
| 407 | spin_unlock_irq(&data->lock); | 388 | spin_unlock_irq(&data->lock); |
| 408 | 389 | ||
| @@ -422,7 +403,7 @@ static int pcie_pme_resume(struct pcie_device *srv) | |||
| 422 | 403 | ||
| 423 | spin_lock_irq(&data->lock); | 404 | spin_lock_irq(&data->lock); |
| 424 | data->noirq = false; | 405 | data->noirq = false; |
| 425 | pcie_pme_clear_status(port); | 406 | pcie_clear_root_pme_status(port); |
| 426 | pcie_pme_interrupt_enable(port, true); | 407 | pcie_pme_interrupt_enable(port, true); |
| 427 | spin_unlock_irq(&data->lock); | 408 | spin_unlock_irq(&data->lock); |
| 428 | 409 | ||
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 7b5aba0a3291..bd00a01aef14 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
| @@ -20,9 +20,6 @@ | |||
| 20 | 20 | ||
| 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
| 22 | 22 | ||
| 23 | extern bool pcie_ports_disabled; | ||
| 24 | extern bool pcie_ports_auto; | ||
| 25 | |||
| 26 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
| 27 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | extern int pcie_port_device_register(struct pci_dev *dev); |
| 28 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
| @@ -35,6 +32,8 @@ extern void pcie_port_bus_unregister(void); | |||
| 35 | 32 | ||
| 36 | struct pci_dev; | 33 | struct pci_dev; |
| 37 | 34 | ||
| 35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); | ||
| 36 | |||
| 38 | #ifdef CONFIG_PCIE_PME | 37 | #ifdef CONFIG_PCIE_PME |
| 39 | extern bool pcie_pme_msi_disabled; | 38 | extern bool pcie_pme_msi_disabled; |
| 40 | 39 | ||
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c index 5982b6a63b89..a86b56e5f2f2 100644 --- a/drivers/pci/pcie/portdrv_acpi.c +++ b/drivers/pci/pcie/portdrv_acpi.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | */ | 33 | */ |
| 34 | int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) | 34 | int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) |
| 35 | { | 35 | { |
| 36 | acpi_status status; | 36 | struct acpi_pci_root *root; |
| 37 | acpi_handle handle; | 37 | acpi_handle handle; |
| 38 | u32 flags; | 38 | u32 flags; |
| 39 | 39 | ||
| @@ -44,26 +44,11 @@ int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) | |||
| 44 | if (!handle) | 44 | if (!handle) |
| 45 | return -EINVAL; | 45 | return -EINVAL; |
| 46 | 46 | ||
| 47 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | 47 | root = acpi_pci_find_root(handle); |
| 48 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | 48 | if (!root) |
| 49 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
| 50 | |||
| 51 | if (pci_aer_available()) { | ||
| 52 | if (aer_acpi_firmware_first()) | ||
| 53 | dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); | ||
| 54 | else | ||
| 55 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
| 56 | } | ||
| 57 | |||
| 58 | status = acpi_pci_osc_control_set(handle, &flags, | ||
| 59 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
| 60 | if (ACPI_FAILURE(status)) { | ||
| 61 | dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n", | ||
| 62 | status); | ||
| 63 | return -ENODEV; | 49 | return -ENODEV; |
| 64 | } | ||
| 65 | 50 | ||
| 66 | dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags); | 51 | flags = root->osc_control_set; |
| 67 | 52 | ||
| 68 | *srv_mask = PCIE_PORT_SERVICE_VC; | 53 | *srv_mask = PCIE_PORT_SERVICE_VC; |
| 69 | if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | 54 | if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index a9c222d79ebc..5130d0d22390 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
| @@ -241,17 +241,17 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
| 241 | int cap_mask; | 241 | int cap_mask; |
| 242 | int err; | 242 | int err; |
| 243 | 243 | ||
| 244 | if (pcie_ports_disabled) | ||
| 245 | return 0; | ||
| 246 | |||
| 244 | err = pcie_port_platform_notify(dev, &cap_mask); | 247 | err = pcie_port_platform_notify(dev, &cap_mask); |
| 245 | if (pcie_ports_auto) { | 248 | if (!pcie_ports_auto) { |
| 246 | if (err) { | ||
| 247 | pcie_no_aspm(); | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | } else { | ||
| 251 | cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | 249 | cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |
| 252 | | PCIE_PORT_SERVICE_VC; | 250 | | PCIE_PORT_SERVICE_VC; |
| 253 | if (pci_aer_available()) | 251 | if (pci_aer_available()) |
| 254 | cap_mask |= PCIE_PORT_SERVICE_AER; | 252 | cap_mask |= PCIE_PORT_SERVICE_AER; |
| 253 | } else if (err) { | ||
| 254 | return 0; | ||
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | pos = pci_pcie_cap(dev); | 257 | pos = pci_pcie_cap(dev); |
| @@ -349,15 +349,18 @@ int pcie_port_device_register(struct pci_dev *dev) | |||
| 349 | int status, capabilities, i, nr_service; | 349 | int status, capabilities, i, nr_service; |
| 350 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; | 350 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; |
| 351 | 351 | ||
| 352 | /* Get and check PCI Express port services */ | ||
| 353 | capabilities = get_port_device_capability(dev); | ||
| 354 | if (!capabilities) | ||
| 355 | return -ENODEV; | ||
| 356 | |||
| 357 | /* Enable PCI Express port device */ | 352 | /* Enable PCI Express port device */ |
| 358 | status = pci_enable_device(dev); | 353 | status = pci_enable_device(dev); |
| 359 | if (status) | 354 | if (status) |
| 360 | return status; | 355 | return status; |
| 356 | |||
| 357 | /* Get and check PCI Express port services */ | ||
| 358 | capabilities = get_port_device_capability(dev); | ||
| 359 | if (!capabilities) { | ||
| 360 | pcie_no_aspm(); | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 361 | pci_set_master(dev); | 364 | pci_set_master(dev); |
| 362 | /* | 365 | /* |
| 363 | * Initialize service irqs. Don't use service devices that | 366 | * Initialize service irqs. Don't use service devices that |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f9033e190fb6..e0610bda1dea 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -57,6 +57,22 @@ __setup("pcie_ports=", pcie_port_setup); | |||
| 57 | 57 | ||
| 58 | /* global data */ | 58 | /* global data */ |
| 59 | 59 | ||
| 60 | /** | ||
| 61 | * pcie_clear_root_pme_status - Clear root port PME interrupt status. | ||
| 62 | * @dev: PCIe root port or event collector. | ||
| 63 | */ | ||
| 64 | void pcie_clear_root_pme_status(struct pci_dev *dev) | ||
| 65 | { | ||
| 66 | int rtsta_pos; | ||
| 67 | u32 rtsta; | ||
| 68 | |||
| 69 | rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; | ||
| 70 | |||
| 71 | pci_read_config_dword(dev, rtsta_pos, &rtsta); | ||
| 72 | rtsta |= PCI_EXP_RTSTA_PME; | ||
| 73 | pci_write_config_dword(dev, rtsta_pos, rtsta); | ||
| 74 | } | ||
| 75 | |||
| 60 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | 76 | static int pcie_portdrv_restore_config(struct pci_dev *dev) |
| 61 | { | 77 | { |
| 62 | int retval; | 78 | int retval; |
| @@ -69,6 +85,20 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
| 69 | } | 85 | } |
| 70 | 86 | ||
| 71 | #ifdef CONFIG_PM | 87 | #ifdef CONFIG_PM |
| 88 | static int pcie_port_resume_noirq(struct device *dev) | ||
| 89 | { | ||
| 90 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Some BIOSes forget to clear Root PME Status bits after system wakeup | ||
| 94 | * which breaks ACPI-based runtime wakeup on PCI Express, so clear those | ||
| 95 | * bits now just in case (shouldn't hurt). | ||
| 96 | */ | ||
| 97 | if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | ||
| 98 | pcie_clear_root_pme_status(pdev); | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 72 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 102 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
| 73 | .suspend = pcie_port_device_suspend, | 103 | .suspend = pcie_port_device_suspend, |
| 74 | .resume = pcie_port_device_resume, | 104 | .resume = pcie_port_device_resume, |
| @@ -76,6 +106,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
| 76 | .thaw = pcie_port_device_resume, | 106 | .thaw = pcie_port_device_resume, |
| 77 | .poweroff = pcie_port_device_suspend, | 107 | .poweroff = pcie_port_device_suspend, |
| 78 | .restore = pcie_port_device_resume, | 108 | .restore = pcie_port_device_resume, |
| 109 | .resume_noirq = pcie_port_resume_noirq, | ||
| 79 | }; | 110 | }; |
| 80 | 111 | ||
| 81 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 112 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
| @@ -327,10 +358,8 @@ static int __init pcie_portdrv_init(void) | |||
| 327 | { | 358 | { |
| 328 | int retval; | 359 | int retval; |
| 329 | 360 | ||
| 330 | if (pcie_ports_disabled) { | 361 | if (pcie_ports_disabled) |
| 331 | pcie_no_aspm(); | 362 | return pci_register_driver(&pcie_portdriver); |
| 332 | return -EACCES; | ||
| 333 | } | ||
| 334 | 363 | ||
| 335 | dmi_check_system(pcie_portdrv_dmi_table); | 364 | dmi_check_system(pcie_portdrv_dmi_table); |
| 336 | 365 | ||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 60d83d983a36..61bf5d724139 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
| @@ -136,6 +136,16 @@ config BATTERY_MAX17040 | |||
| 136 | in handheld and portable equipment. The MAX17040 is configured | 136 | in handheld and portable equipment. The MAX17040 is configured |
| 137 | to operate with a single lithium cell | 137 | to operate with a single lithium cell |
| 138 | 138 | ||
| 139 | config BATTERY_MAX17042 | ||
| 140 | tristate "Maxim MAX17042/8997/8966 Fuel Gauge" | ||
| 141 | depends on I2C | ||
| 142 | help | ||
| 143 | MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries | ||
| 144 | in handheld and portable equipment. The MAX17042 is configured | ||
| 145 | to operate with a single lithium cell. MAX8997 and MAX8966 are | ||
| 146 | multi-function devices that include fuel gauages that are compatible | ||
| 147 | with MAX17042. | ||
| 148 | |||
| 139 | config BATTERY_Z2 | 149 | config BATTERY_Z2 |
| 140 | tristate "Z2 battery driver" | 150 | tristate "Z2 battery driver" |
| 141 | depends on I2C && MACH_ZIPIT2 | 151 | depends on I2C && MACH_ZIPIT2 |
| @@ -185,4 +195,14 @@ config CHARGER_TWL4030 | |||
| 185 | help | 195 | help |
| 186 | Say Y here to enable support for TWL4030 Battery Charge Interface. | 196 | Say Y here to enable support for TWL4030 Battery Charge Interface. |
| 187 | 197 | ||
| 198 | config CHARGER_GPIO | ||
| 199 | tristate "GPIO charger" | ||
| 200 | depends on GPIOLIB | ||
| 201 | help | ||
| 202 | Say Y to include support for chargers which report their online status | ||
| 203 | through a GPIO pin. | ||
| 204 | |||
| 205 | This driver can be build as a module. If so, the module will be | ||
| 206 | called gpio-charger. | ||
| 207 | |||
| 188 | endif # POWER_SUPPLY | 208 | endif # POWER_SUPPLY |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index c75772eb157c..8385bfae8728 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
| @@ -25,6 +25,7 @@ obj-$(CONFIG_BATTERY_BQ20Z75) += bq20z75.o | |||
| 25 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o | 25 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o |
| 26 | obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o | 26 | obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o |
| 27 | obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o | 27 | obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o |
| 28 | obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o | ||
| 28 | obj-$(CONFIG_BATTERY_Z2) += z2_battery.o | 29 | obj-$(CONFIG_BATTERY_Z2) += z2_battery.o |
| 29 | obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o | 30 | obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o |
| 30 | obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o | 31 | obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o |
| @@ -32,3 +33,4 @@ obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o | |||
| 32 | obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o | 33 | obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o |
| 33 | obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o | 34 | obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o |
| 34 | obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o | 35 | obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o |
| 36 | obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o | ||
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c index 039f41ae217d..548d263b1ad0 100644 --- a/drivers/power/collie_battery.c +++ b/drivers/power/collie_battery.c | |||
| @@ -295,7 +295,7 @@ static struct { | |||
| 295 | static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state) | 295 | static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state) |
| 296 | { | 296 | { |
| 297 | /* flush all pending status updates */ | 297 | /* flush all pending status updates */ |
| 298 | flush_scheduled_work(); | 298 | flush_work_sync(&bat_work); |
| 299 | return 0; | 299 | return 0; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| @@ -362,7 +362,7 @@ err_psy_reg_bu: | |||
| 362 | err_psy_reg_main: | 362 | err_psy_reg_main: |
| 363 | 363 | ||
| 364 | /* see comment in collie_bat_remove */ | 364 | /* see comment in collie_bat_remove */ |
| 365 | flush_scheduled_work(); | 365 | cancel_work_sync(&bat_work); |
| 366 | 366 | ||
| 367 | i--; | 367 | i--; |
| 368 | err_gpio: | 368 | err_gpio: |
| @@ -382,12 +382,11 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) | |||
| 382 | power_supply_unregister(&collie_bat_main.psy); | 382 | power_supply_unregister(&collie_bat_main.psy); |
| 383 | 383 | ||
| 384 | /* | 384 | /* |
| 385 | * now flush all pending work. | 385 | * Now cancel the bat_work. We won't get any more schedules, |
| 386 | * we won't get any more schedules, since all | 386 | * since all sources (isr and external_power_changed) are |
| 387 | * sources (isr and external_power_changed) | 387 | * unregistered now. |
| 388 | * are unregistered now. | ||
| 389 | */ | 388 | */ |
| 390 | flush_scheduled_work(); | 389 | cancel_work_sync(&bat_work); |
| 391 | 390 | ||
| 392 | for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) | 391 | for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) |
| 393 | gpio_free(gpios[i].gpio); | 392 | gpio_free(gpios[i].gpio); |
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index e7f89785beef..e534290f3256 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c | |||
| @@ -212,7 +212,7 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di) | |||
| 212 | if (di->rem_capacity > 100) | 212 | if (di->rem_capacity > 100) |
| 213 | di->rem_capacity = 100; | 213 | di->rem_capacity = 100; |
| 214 | 214 | ||
| 215 | if (di->current_uA >= 100L) | 215 | if (di->current_uA < -100L) |
| 216 | di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L) | 216 | di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L) |
| 217 | / (di->current_uA / 100L); | 217 | / (di->current_uA / 100L); |
| 218 | else | 218 | else |
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c new file mode 100644 index 000000000000..25b88ac1d44c --- /dev/null +++ b/drivers/power/gpio-charger.c | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
| 3 | * Driver for chargers which report their online status through a GPIO pin | ||
| 4 | * | ||
| 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 | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | * | ||
| 10 | * You should have received a copy of the GNU General Public License along | ||
| 11 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 12 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/gpio.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/power_supply.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | |||
| 26 | #include <linux/power/gpio-charger.h> | ||
| 27 | |||
| 28 | struct gpio_charger { | ||
| 29 | const struct gpio_charger_platform_data *pdata; | ||
| 30 | unsigned int irq; | ||
| 31 | |||
| 32 | struct power_supply charger; | ||
| 33 | }; | ||
| 34 | |||
| 35 | static irqreturn_t gpio_charger_irq(int irq, void *devid) | ||
| 36 | { | ||
| 37 | struct power_supply *charger = devid; | ||
| 38 | |||
| 39 | power_supply_changed(charger); | ||
| 40 | |||
| 41 | return IRQ_HANDLED; | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) | ||
| 45 | { | ||
| 46 | return container_of(psy, struct gpio_charger, charger); | ||
| 47 | } | ||
| 48 | |||
| 49 | static int gpio_charger_get_property(struct power_supply *psy, | ||
| 50 | enum power_supply_property psp, union power_supply_propval *val) | ||
| 51 | { | ||
| 52 | struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy); | ||
| 53 | const struct gpio_charger_platform_data *pdata = gpio_charger->pdata; | ||
| 54 | |||
| 55 | switch (psp) { | ||
| 56 | case POWER_SUPPLY_PROP_ONLINE: | ||
| 57 | val->intval = gpio_get_value(pdata->gpio); | ||
| 58 | val->intval ^= pdata->gpio_active_low; | ||
| 59 | break; | ||
| 60 | default: | ||
| 61 | return -EINVAL; | ||
| 62 | } | ||
| 63 | |||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | static enum power_supply_property gpio_charger_properties[] = { | ||
| 68 | POWER_SUPPLY_PROP_ONLINE, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static int __devinit gpio_charger_probe(struct platform_device *pdev) | ||
| 72 | { | ||
| 73 | const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; | ||
| 74 | struct gpio_charger *gpio_charger; | ||
| 75 | struct power_supply *charger; | ||
| 76 | int ret; | ||
| 77 | int irq; | ||
| 78 | |||
| 79 | if (!pdata) { | ||
| 80 | dev_err(&pdev->dev, "No platform data\n"); | ||
| 81 | return -EINVAL; | ||
| 82 | } | ||
| 83 | |||
| 84 | if (!gpio_is_valid(pdata->gpio)) { | ||
| 85 | dev_err(&pdev->dev, "Invalid gpio pin\n"); | ||
| 86 | return -EINVAL; | ||
| 87 | } | ||
| 88 | |||
| 89 | gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL); | ||
| 90 | if (!gpio_charger) { | ||
| 91 | dev_err(&pdev->dev, "Failed to alloc driver structure\n"); | ||
| 92 | return -ENOMEM; | ||
| 93 | } | ||
| 94 | |||
| 95 | charger = &gpio_charger->charger; | ||
| 96 | |||
| 97 | charger->name = pdata->name ? pdata->name : "gpio-charger"; | ||
| 98 | charger->type = pdata->type; | ||
| 99 | charger->properties = gpio_charger_properties; | ||
| 100 | charger->num_properties = ARRAY_SIZE(gpio_charger_properties); | ||
| 101 | charger->get_property = gpio_charger_get_property; | ||
| 102 | charger->supplied_to = pdata->supplied_to; | ||
| 103 | charger->num_supplicants = pdata->num_supplicants; | ||
| 104 | |||
| 105 | ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); | ||
| 106 | if (ret) { | ||
| 107 | dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret); | ||
| 108 | goto err_free; | ||
| 109 | } | ||
| 110 | ret = gpio_direction_input(pdata->gpio); | ||
| 111 | if (ret) { | ||
| 112 | dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret); | ||
| 113 | goto err_gpio_free; | ||
| 114 | } | ||
| 115 | |||
| 116 | gpio_charger->pdata = pdata; | ||
| 117 | |||
| 118 | ret = power_supply_register(&pdev->dev, charger); | ||
| 119 | if (ret < 0) { | ||
| 120 | dev_err(&pdev->dev, "Failed to register power supply: %d\n", | ||
| 121 | ret); | ||
| 122 | goto err_gpio_free; | ||
| 123 | } | ||
| 124 | |||
| 125 | irq = gpio_to_irq(pdata->gpio); | ||
| 126 | if (irq > 0) { | ||
| 127 | ret = request_any_context_irq(irq, gpio_charger_irq, | ||
| 128 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
| 129 | dev_name(&pdev->dev), charger); | ||
| 130 | if (ret) | ||
| 131 | dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); | ||
| 132 | else | ||
| 133 | gpio_charger->irq = irq; | ||
| 134 | } | ||
| 135 | |||
| 136 | platform_set_drvdata(pdev, gpio_charger); | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | |||
| 140 | err_gpio_free: | ||
| 141 | gpio_free(pdata->gpio); | ||
| 142 | err_free: | ||
| 143 | kfree(gpio_charger); | ||
| 144 | return ret; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int __devexit gpio_charger_remove(struct platform_device *pdev) | ||
| 148 | { | ||
| 149 | struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); | ||
| 150 | |||
| 151 | if (gpio_charger->irq) | ||
| 152 | free_irq(gpio_charger->irq, &gpio_charger->charger); | ||
| 153 | |||
| 154 | power_supply_unregister(&gpio_charger->charger); | ||
| 155 | |||
| 156 | gpio_free(gpio_charger->pdata->gpio); | ||
| 157 | |||
| 158 | platform_set_drvdata(pdev, NULL); | ||
| 159 | kfree(gpio_charger); | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static struct platform_driver gpio_charger_driver = { | ||
| 165 | .probe = gpio_charger_probe, | ||
| 166 | .remove = __devexit_p(gpio_charger_remove), | ||
| 167 | .driver = { | ||
| 168 | .name = "gpio-charger", | ||
| 169 | .owner = THIS_MODULE, | ||
| 170 | }, | ||
| 171 | }; | ||
| 172 | |||
| 173 | static int __init gpio_charger_init(void) | ||
| 174 | { | ||
| 175 | return platform_driver_register(&gpio_charger_driver); | ||
| 176 | } | ||
| 177 | module_init(gpio_charger_init); | ||
| 178 | |||
| 179 | static void __exit gpio_charger_exit(void) | ||
| 180 | { | ||
| 181 | platform_driver_unregister(&gpio_charger_driver); | ||
| 182 | } | ||
| 183 | module_exit(gpio_charger_exit); | ||
| 184 | |||
| 185 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
| 186 | MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO"); | ||
| 187 | MODULE_LICENSE("GPL"); | ||
| 188 | MODULE_ALIAS("platform:gpio-charger"); | ||
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index 36cf402c0677..bce3a01da2f0 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c | |||
| @@ -765,7 +765,7 @@ static int __devexit platform_pmic_battery_remove(struct platform_device *pdev) | |||
| 765 | power_supply_unregister(&pbi->usb); | 765 | power_supply_unregister(&pbi->usb); |
| 766 | power_supply_unregister(&pbi->batt); | 766 | power_supply_unregister(&pbi->batt); |
| 767 | 767 | ||
| 768 | flush_scheduled_work(); | 768 | cancel_work_sync(&pbi->handler); |
| 769 | kfree(pbi); | 769 | kfree(pbi); |
| 770 | return 0; | 770 | return 0; |
| 771 | } | 771 | } |
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 72512185f3e2..2ad9b14a5ce3 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c | |||
| @@ -59,11 +59,61 @@ struct isp1704_charger { | |||
| 59 | struct notifier_block nb; | 59 | struct notifier_block nb; |
| 60 | struct work_struct work; | 60 | struct work_struct work; |
| 61 | 61 | ||
| 62 | char model[7]; | 62 | /* properties */ |
| 63 | char model[8]; | ||
| 63 | unsigned present:1; | 64 | unsigned present:1; |
| 65 | unsigned online:1; | ||
| 66 | unsigned current_max; | ||
| 67 | |||
| 68 | /* temp storage variables */ | ||
| 69 | unsigned long event; | ||
| 70 | unsigned max_power; | ||
| 64 | }; | 71 | }; |
| 65 | 72 | ||
| 66 | /* | 73 | /* |
| 74 | * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB | ||
| 75 | * chargers). | ||
| 76 | * | ||
| 77 | * REVISIT: The method is defined in Battery Charging Specification and is | ||
| 78 | * applicable to any ULPI transceiver. Nothing isp170x specific here. | ||
| 79 | */ | ||
| 80 | static inline int isp1704_charger_type(struct isp1704_charger *isp) | ||
| 81 | { | ||
| 82 | u8 reg; | ||
| 83 | u8 func_ctrl; | ||
| 84 | u8 otg_ctrl; | ||
| 85 | int type = POWER_SUPPLY_TYPE_USB_DCP; | ||
| 86 | |||
| 87 | func_ctrl = otg_io_read(isp->otg, ULPI_FUNC_CTRL); | ||
| 88 | otg_ctrl = otg_io_read(isp->otg, ULPI_OTG_CTRL); | ||
| 89 | |||
| 90 | /* disable pulldowns */ | ||
| 91 | reg = ULPI_OTG_CTRL_DM_PULLDOWN | ULPI_OTG_CTRL_DP_PULLDOWN; | ||
| 92 | otg_io_write(isp->otg, ULPI_CLR(ULPI_OTG_CTRL), reg); | ||
| 93 | |||
| 94 | /* full speed */ | ||
| 95 | otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL), | ||
| 96 | ULPI_FUNC_CTRL_XCVRSEL_MASK); | ||
| 97 | otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), | ||
| 98 | ULPI_FUNC_CTRL_FULL_SPEED); | ||
| 99 | |||
| 100 | /* Enable strong pull-up on DP (1.5K) and reset */ | ||
| 101 | reg = ULPI_FUNC_CTRL_TERMSELECT | ULPI_FUNC_CTRL_RESET; | ||
| 102 | otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), reg); | ||
| 103 | usleep_range(1000, 2000); | ||
| 104 | |||
| 105 | reg = otg_io_read(isp->otg, ULPI_DEBUG); | ||
| 106 | if ((reg & 3) != 3) | ||
| 107 | type = POWER_SUPPLY_TYPE_USB_CDP; | ||
| 108 | |||
| 109 | /* recover original state */ | ||
| 110 | otg_io_write(isp->otg, ULPI_FUNC_CTRL, func_ctrl); | ||
| 111 | otg_io_write(isp->otg, ULPI_OTG_CTRL, otg_ctrl); | ||
| 112 | |||
| 113 | return type; | ||
| 114 | } | ||
| 115 | |||
| 116 | /* | ||
| 67 | * ISP1704 detects PS/2 adapters as charger. To make sure the detected charger | 117 | * ISP1704 detects PS/2 adapters as charger. To make sure the detected charger |
| 68 | * is actually a dedicated charger, the following steps need to be taken. | 118 | * is actually a dedicated charger, the following steps need to be taken. |
| 69 | */ | 119 | */ |
| @@ -127,16 +177,19 @@ static inline int isp1704_charger_verify(struct isp1704_charger *isp) | |||
| 127 | static inline int isp1704_charger_detect(struct isp1704_charger *isp) | 177 | static inline int isp1704_charger_detect(struct isp1704_charger *isp) |
| 128 | { | 178 | { |
| 129 | unsigned long timeout; | 179 | unsigned long timeout; |
| 130 | u8 r; | 180 | u8 pwr_ctrl; |
| 131 | int ret = 0; | 181 | int ret = 0; |
| 132 | 182 | ||
| 183 | pwr_ctrl = otg_io_read(isp->otg, ISP1704_PWR_CTRL); | ||
| 184 | |||
| 133 | /* set SW control bit in PWR_CTRL register */ | 185 | /* set SW control bit in PWR_CTRL register */ |
| 134 | otg_io_write(isp->otg, ISP1704_PWR_CTRL, | 186 | otg_io_write(isp->otg, ISP1704_PWR_CTRL, |
| 135 | ISP1704_PWR_CTRL_SWCTRL); | 187 | ISP1704_PWR_CTRL_SWCTRL); |
| 136 | 188 | ||
| 137 | /* enable manual charger detection */ | 189 | /* enable manual charger detection */ |
| 138 | r = (ISP1704_PWR_CTRL_SWCTRL | ISP1704_PWR_CTRL_DPVSRC_EN); | 190 | otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), |
| 139 | otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), r); | 191 | ISP1704_PWR_CTRL_SWCTRL |
| 192 | | ISP1704_PWR_CTRL_DPVSRC_EN); | ||
| 140 | usleep_range(1000, 2000); | 193 | usleep_range(1000, 2000); |
| 141 | 194 | ||
| 142 | timeout = jiffies + msecs_to_jiffies(300); | 195 | timeout = jiffies + msecs_to_jiffies(300); |
| @@ -147,7 +200,10 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) | |||
| 147 | ret = isp1704_charger_verify(isp); | 200 | ret = isp1704_charger_verify(isp); |
| 148 | break; | 201 | break; |
| 149 | } | 202 | } |
| 150 | } while (!time_after(jiffies, timeout)); | 203 | } while (!time_after(jiffies, timeout) && isp->online); |
| 204 | |||
| 205 | /* recover original state */ | ||
| 206 | otg_io_write(isp->otg, ISP1704_PWR_CTRL, pwr_ctrl); | ||
| 151 | 207 | ||
| 152 | return ret; | 208 | return ret; |
| 153 | } | 209 | } |
| @@ -155,52 +211,92 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) | |||
| 155 | static void isp1704_charger_work(struct work_struct *data) | 211 | static void isp1704_charger_work(struct work_struct *data) |
| 156 | { | 212 | { |
| 157 | int detect; | 213 | int detect; |
| 214 | unsigned long event; | ||
| 215 | unsigned power; | ||
| 158 | struct isp1704_charger *isp = | 216 | struct isp1704_charger *isp = |
| 159 | container_of(data, struct isp1704_charger, work); | 217 | container_of(data, struct isp1704_charger, work); |
| 218 | static DEFINE_MUTEX(lock); | ||
| 160 | 219 | ||
| 161 | /* | 220 | event = isp->event; |
| 162 | * FIXME Only supporting dedicated chargers even though isp1704 can | 221 | power = isp->max_power; |
| 163 | * detect HUB and HOST chargers. If the device has already been | ||
| 164 | * enumerated, the detection will break the connection. | ||
| 165 | */ | ||
| 166 | if (isp->otg->state != OTG_STATE_B_IDLE) | ||
| 167 | return; | ||
| 168 | 222 | ||
| 169 | /* disable data pullups */ | 223 | mutex_lock(&lock); |
| 170 | if (isp->otg->gadget) | 224 | |
| 171 | usb_gadget_disconnect(isp->otg->gadget); | 225 | switch (event) { |
| 226 | case USB_EVENT_VBUS: | ||
| 227 | isp->online = true; | ||
| 228 | |||
| 229 | /* detect charger */ | ||
| 230 | detect = isp1704_charger_detect(isp); | ||
| 231 | |||
| 232 | if (detect) { | ||
| 233 | isp->present = detect; | ||
| 234 | isp->psy.type = isp1704_charger_type(isp); | ||
| 235 | } | ||
| 172 | 236 | ||
| 173 | /* detect charger */ | 237 | switch (isp->psy.type) { |
| 174 | detect = isp1704_charger_detect(isp); | 238 | case POWER_SUPPLY_TYPE_USB_DCP: |
| 175 | if (detect) { | 239 | isp->current_max = 1800; |
| 176 | isp->present = detect; | 240 | break; |
| 177 | power_supply_changed(&isp->psy); | 241 | case POWER_SUPPLY_TYPE_USB_CDP: |
| 242 | /* | ||
| 243 | * Only 500mA here or high speed chirp | ||
| 244 | * handshaking may break | ||
| 245 | */ | ||
| 246 | isp->current_max = 500; | ||
| 247 | /* FALLTHROUGH */ | ||
| 248 | case POWER_SUPPLY_TYPE_USB: | ||
| 249 | default: | ||
| 250 | /* enable data pullups */ | ||
| 251 | if (isp->otg->gadget) | ||
| 252 | usb_gadget_connect(isp->otg->gadget); | ||
| 253 | } | ||
| 254 | break; | ||
| 255 | case USB_EVENT_NONE: | ||
| 256 | isp->online = false; | ||
| 257 | isp->current_max = 0; | ||
| 258 | isp->present = 0; | ||
| 259 | isp->current_max = 0; | ||
| 260 | isp->psy.type = POWER_SUPPLY_TYPE_USB; | ||
| 261 | |||
| 262 | /* | ||
| 263 | * Disable data pullups. We need to prevent the controller from | ||
| 264 | * enumerating. | ||
| 265 | * | ||
| 266 | * FIXME: This is here to allow charger detection with Host/HUB | ||
| 267 | * chargers. The pullups may be enabled elsewhere, so this can | ||
| 268 | * not be the final solution. | ||
| 269 | */ | ||
| 270 | if (isp->otg->gadget) | ||
| 271 | usb_gadget_disconnect(isp->otg->gadget); | ||
| 272 | break; | ||
| 273 | case USB_EVENT_ENUMERATED: | ||
| 274 | if (isp->present) | ||
| 275 | isp->current_max = 1800; | ||
| 276 | else | ||
| 277 | isp->current_max = power; | ||
| 278 | break; | ||
| 279 | default: | ||
| 280 | goto out; | ||
| 178 | } | 281 | } |
| 179 | 282 | ||
| 180 | /* enable data pullups */ | 283 | power_supply_changed(&isp->psy); |
| 181 | if (isp->otg->gadget) | 284 | out: |
| 182 | usb_gadget_connect(isp->otg->gadget); | 285 | mutex_unlock(&lock); |
| 183 | } | 286 | } |
| 184 | 287 | ||
| 185 | static int isp1704_notifier_call(struct notifier_block *nb, | 288 | static int isp1704_notifier_call(struct notifier_block *nb, |
| 186 | unsigned long event, void *unused) | 289 | unsigned long event, void *power) |
| 187 | { | 290 | { |
| 188 | struct isp1704_charger *isp = | 291 | struct isp1704_charger *isp = |
| 189 | container_of(nb, struct isp1704_charger, nb); | 292 | container_of(nb, struct isp1704_charger, nb); |
| 190 | 293 | ||
| 191 | switch (event) { | 294 | isp->event = event; |
| 192 | case USB_EVENT_VBUS: | 295 | |
| 193 | schedule_work(&isp->work); | 296 | if (power) |
| 194 | break; | 297 | isp->max_power = *((unsigned *)power); |
| 195 | case USB_EVENT_NONE: | 298 | |
| 196 | if (isp->present) { | 299 | schedule_work(&isp->work); |
| 197 | isp->present = 0; | ||
| 198 | power_supply_changed(&isp->psy); | ||
| 199 | } | ||
| 200 | break; | ||
| 201 | default: | ||
| 202 | return NOTIFY_DONE; | ||
| 203 | } | ||
| 204 | 300 | ||
| 205 | return NOTIFY_OK; | 301 | return NOTIFY_OK; |
| 206 | } | 302 | } |
| @@ -216,6 +312,12 @@ static int isp1704_charger_get_property(struct power_supply *psy, | |||
| 216 | case POWER_SUPPLY_PROP_PRESENT: | 312 | case POWER_SUPPLY_PROP_PRESENT: |
| 217 | val->intval = isp->present; | 313 | val->intval = isp->present; |
| 218 | break; | 314 | break; |
| 315 | case POWER_SUPPLY_PROP_ONLINE: | ||
| 316 | val->intval = isp->online; | ||
| 317 | break; | ||
| 318 | case POWER_SUPPLY_PROP_CURRENT_MAX: | ||
| 319 | val->intval = isp->current_max; | ||
| 320 | break; | ||
| 219 | case POWER_SUPPLY_PROP_MODEL_NAME: | 321 | case POWER_SUPPLY_PROP_MODEL_NAME: |
| 220 | val->strval = isp->model; | 322 | val->strval = isp->model; |
| 221 | break; | 323 | break; |
| @@ -230,6 +332,8 @@ static int isp1704_charger_get_property(struct power_supply *psy, | |||
| 230 | 332 | ||
| 231 | static enum power_supply_property power_props[] = { | 333 | static enum power_supply_property power_props[] = { |
| 232 | POWER_SUPPLY_PROP_PRESENT, | 334 | POWER_SUPPLY_PROP_PRESENT, |
| 335 | POWER_SUPPLY_PROP_ONLINE, | ||
| 336 | POWER_SUPPLY_PROP_CURRENT_MAX, | ||
| 233 | POWER_SUPPLY_PROP_MODEL_NAME, | 337 | POWER_SUPPLY_PROP_MODEL_NAME, |
| 234 | POWER_SUPPLY_PROP_MANUFACTURER, | 338 | POWER_SUPPLY_PROP_MANUFACTURER, |
| 235 | }; | 339 | }; |
| @@ -287,13 +391,13 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) | |||
| 287 | if (!isp->otg) | 391 | if (!isp->otg) |
| 288 | goto fail0; | 392 | goto fail0; |
| 289 | 393 | ||
| 394 | isp->dev = &pdev->dev; | ||
| 395 | platform_set_drvdata(pdev, isp); | ||
| 396 | |||
| 290 | ret = isp1704_test_ulpi(isp); | 397 | ret = isp1704_test_ulpi(isp); |
| 291 | if (ret < 0) | 398 | if (ret < 0) |
| 292 | goto fail1; | 399 | goto fail1; |
| 293 | 400 | ||
| 294 | isp->dev = &pdev->dev; | ||
| 295 | platform_set_drvdata(pdev, isp); | ||
| 296 | |||
| 297 | isp->psy.name = "isp1704"; | 401 | isp->psy.name = "isp1704"; |
| 298 | isp->psy.type = POWER_SUPPLY_TYPE_USB; | 402 | isp->psy.type = POWER_SUPPLY_TYPE_USB; |
| 299 | isp->psy.properties = power_props; | 403 | isp->psy.properties = power_props; |
| @@ -318,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) | |||
| 318 | 422 | ||
| 319 | dev_info(isp->dev, "registered with product id %s\n", isp->model); | 423 | dev_info(isp->dev, "registered with product id %s\n", isp->model); |
| 320 | 424 | ||
| 425 | /* | ||
| 426 | * Taking over the D+ pullup. | ||
| 427 | * | ||
| 428 | * FIXME: The device will be disconnected if it was already | ||
| 429 | * enumerated. The charger driver should be always loaded before any | ||
| 430 | * gadget is loaded. | ||
| 431 | */ | ||
| 432 | if (isp->otg->gadget) | ||
| 433 | usb_gadget_disconnect(isp->otg->gadget); | ||
| 434 | |||
| 435 | /* Detect charger if VBUS is valid (the cable was already plugged). */ | ||
| 436 | ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); | ||
| 437 | if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { | ||
| 438 | isp->event = USB_EVENT_VBUS; | ||
| 439 | schedule_work(&isp->work); | ||
| 440 | } | ||
| 441 | |||
| 321 | return 0; | 442 | return 0; |
| 322 | fail2: | 443 | fail2: |
| 323 | power_supply_unregister(&isp->psy); | 444 | power_supply_unregister(&isp->psy); |
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index a8108a73593e..02414db6a94c 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/io.h> | ||
| 22 | 23 | ||
| 23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 24 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
| @@ -47,6 +48,8 @@ struct jz_battery { | |||
| 47 | 48 | ||
| 48 | struct power_supply battery; | 49 | struct power_supply battery; |
| 49 | struct delayed_work work; | 50 | struct delayed_work work; |
| 51 | |||
| 52 | struct mutex lock; | ||
| 50 | }; | 53 | }; |
| 51 | 54 | ||
| 52 | static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) | 55 | static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) |
| @@ -68,6 +71,8 @@ static long jz_battery_read_voltage(struct jz_battery *battery) | |||
| 68 | unsigned long val; | 71 | unsigned long val; |
| 69 | long voltage; | 72 | long voltage; |
| 70 | 73 | ||
| 74 | mutex_lock(&battery->lock); | ||
| 75 | |||
| 71 | INIT_COMPLETION(battery->read_completion); | 76 | INIT_COMPLETION(battery->read_completion); |
| 72 | 77 | ||
| 73 | enable_irq(battery->irq); | 78 | enable_irq(battery->irq); |
| @@ -91,6 +96,8 @@ static long jz_battery_read_voltage(struct jz_battery *battery) | |||
| 91 | battery->cell->disable(battery->pdev); | 96 | battery->cell->disable(battery->pdev); |
| 92 | disable_irq(battery->irq); | 97 | disable_irq(battery->irq); |
| 93 | 98 | ||
| 99 | mutex_unlock(&battery->lock); | ||
| 100 | |||
| 94 | return voltage; | 101 | return voltage; |
| 95 | } | 102 | } |
| 96 | 103 | ||
| @@ -240,6 +247,11 @@ static int __devinit jz_battery_probe(struct platform_device *pdev) | |||
| 240 | struct jz_battery *jz_battery; | 247 | struct jz_battery *jz_battery; |
| 241 | struct power_supply *battery; | 248 | struct power_supply *battery; |
| 242 | 249 | ||
| 250 | if (!pdata) { | ||
| 251 | dev_err(&pdev->dev, "No platform_data supplied\n"); | ||
| 252 | return -ENXIO; | ||
| 253 | } | ||
| 254 | |||
| 243 | jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL); | 255 | jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL); |
| 244 | if (!jz_battery) { | 256 | if (!jz_battery) { |
| 245 | dev_err(&pdev->dev, "Failed to allocate driver structure\n"); | 257 | dev_err(&pdev->dev, "Failed to allocate driver structure\n"); |
| @@ -291,6 +303,7 @@ static int __devinit jz_battery_probe(struct platform_device *pdev) | |||
| 291 | jz_battery->pdev = pdev; | 303 | jz_battery->pdev = pdev; |
| 292 | 304 | ||
| 293 | init_completion(&jz_battery->read_completion); | 305 | init_completion(&jz_battery->read_completion); |
| 306 | mutex_init(&jz_battery->lock); | ||
| 294 | 307 | ||
| 295 | INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work); | 308 | INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work); |
| 296 | 309 | ||
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c new file mode 100644 index 000000000000..c5c8805156cb --- /dev/null +++ b/drivers/power/max17042_battery.c | |||
| @@ -0,0 +1,239 @@ | |||
| 1 | /* | ||
| 2 | * Fuel gauge driver for Maxim 17042 / 8966 / 8997 | ||
| 3 | * Note that Maxim 8966 and 8997 are mfd and this is its subdevice. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2011 Samsung Electronics | ||
| 6 | * MyungJoo Ham <myungjoo.ham@samsung.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | * | ||
| 22 | * This driver is based on max17040_battery.c | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/slab.h> | ||
| 27 | #include <linux/i2c.h> | ||
| 28 | #include <linux/mod_devicetable.h> | ||
| 29 | #include <linux/power_supply.h> | ||
| 30 | #include <linux/power/max17042_battery.h> | ||
| 31 | |||
| 32 | enum max17042_register { | ||
| 33 | MAX17042_STATUS = 0x00, | ||
| 34 | MAX17042_VALRT_Th = 0x01, | ||
| 35 | MAX17042_TALRT_Th = 0x02, | ||
| 36 | MAX17042_SALRT_Th = 0x03, | ||
| 37 | MAX17042_AtRate = 0x04, | ||
| 38 | MAX17042_RepCap = 0x05, | ||
| 39 | MAX17042_RepSOC = 0x06, | ||
| 40 | MAX17042_Age = 0x07, | ||
| 41 | MAX17042_TEMP = 0x08, | ||
| 42 | MAX17042_VCELL = 0x09, | ||
| 43 | MAX17042_Current = 0x0A, | ||
| 44 | MAX17042_AvgCurrent = 0x0B, | ||
| 45 | MAX17042_Qresidual = 0x0C, | ||
| 46 | MAX17042_SOC = 0x0D, | ||
| 47 | MAX17042_AvSOC = 0x0E, | ||
| 48 | MAX17042_RemCap = 0x0F, | ||
| 49 | MAX17402_FullCAP = 0x10, | ||
| 50 | MAX17042_TTE = 0x11, | ||
| 51 | MAX17042_V_empty = 0x12, | ||
| 52 | |||
| 53 | MAX17042_RSLOW = 0x14, | ||
| 54 | |||
| 55 | MAX17042_AvgTA = 0x16, | ||
| 56 | MAX17042_Cycles = 0x17, | ||
| 57 | MAX17042_DesignCap = 0x18, | ||
| 58 | MAX17042_AvgVCELL = 0x19, | ||
| 59 | MAX17042_MinMaxTemp = 0x1A, | ||
| 60 | MAX17042_MinMaxVolt = 0x1B, | ||
| 61 | MAX17042_MinMaxCurr = 0x1C, | ||
| 62 | MAX17042_CONFIG = 0x1D, | ||
| 63 | MAX17042_ICHGTerm = 0x1E, | ||
| 64 | MAX17042_AvCap = 0x1F, | ||
| 65 | MAX17042_ManName = 0x20, | ||
| 66 | MAX17042_DevName = 0x21, | ||
| 67 | MAX17042_DevChem = 0x22, | ||
| 68 | |||
| 69 | MAX17042_TempNom = 0x24, | ||
| 70 | MAX17042_TempCold = 0x25, | ||
| 71 | MAX17042_TempHot = 0x26, | ||
| 72 | MAX17042_AIN = 0x27, | ||
| 73 | MAX17042_LearnCFG = 0x28, | ||
| 74 | MAX17042_SHFTCFG = 0x29, | ||
| 75 | MAX17042_RelaxCFG = 0x2A, | ||
| 76 | MAX17042_MiscCFG = 0x2B, | ||
| 77 | MAX17042_TGAIN = 0x2C, | ||
| 78 | MAx17042_TOFF = 0x2D, | ||
| 79 | MAX17042_CGAIN = 0x2E, | ||
| 80 | MAX17042_COFF = 0x2F, | ||
| 81 | |||
| 82 | MAX17042_Q_empty = 0x33, | ||
| 83 | MAX17042_T_empty = 0x34, | ||
| 84 | |||
| 85 | MAX17042_RCOMP0 = 0x38, | ||
| 86 | MAX17042_TempCo = 0x39, | ||
| 87 | MAX17042_Rx = 0x3A, | ||
| 88 | MAX17042_T_empty0 = 0x3B, | ||
| 89 | MAX17042_TaskPeriod = 0x3C, | ||
| 90 | MAX17042_FSTAT = 0x3D, | ||
| 91 | |||
| 92 | MAX17042_SHDNTIMER = 0x3F, | ||
| 93 | |||
| 94 | MAX17042_VFRemCap = 0x4A, | ||
| 95 | |||
| 96 | MAX17042_QH = 0x4D, | ||
| 97 | MAX17042_QL = 0x4E, | ||
| 98 | }; | ||
| 99 | |||
| 100 | struct max17042_chip { | ||
| 101 | struct i2c_client *client; | ||
| 102 | struct power_supply battery; | ||
| 103 | struct max17042_platform_data *pdata; | ||
| 104 | }; | ||
| 105 | |||
| 106 | static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value) | ||
| 107 | { | ||
| 108 | int ret = i2c_smbus_write_word_data(client, reg, value); | ||
| 109 | |||
| 110 | if (ret < 0) | ||
| 111 | dev_err(&client->dev, "%s: err %d\n", __func__, ret); | ||
| 112 | |||
| 113 | return ret; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int max17042_read_reg(struct i2c_client *client, u8 reg) | ||
| 117 | { | ||
| 118 | int ret = i2c_smbus_read_word_data(client, reg); | ||
| 119 | |||
| 120 | if (ret < 0) | ||
| 121 | dev_err(&client->dev, "%s: err %d\n", __func__, ret); | ||
| 122 | |||
| 123 | return ret; | ||
| 124 | } | ||
| 125 | |||
| 126 | static enum power_supply_property max17042_battery_props[] = { | ||
| 127 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 128 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | ||
| 129 | POWER_SUPPLY_PROP_CAPACITY, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static int max17042_get_property(struct power_supply *psy, | ||
| 133 | enum power_supply_property psp, | ||
| 134 | union power_supply_propval *val) | ||
| 135 | { | ||
| 136 | struct max17042_chip *chip = container_of(psy, | ||
| 137 | struct max17042_chip, battery); | ||
| 138 | |||
| 139 | switch (psp) { | ||
| 140 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
| 141 | val->intval = max17042_read_reg(chip->client, | ||
| 142 | MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */ | ||
| 143 | break; | ||
| 144 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | ||
| 145 | val->intval = max17042_read_reg(chip->client, | ||
| 146 | MAX17042_AvgVCELL) * 83; | ||
| 147 | break; | ||
| 148 | case POWER_SUPPLY_PROP_CAPACITY: | ||
| 149 | val->intval = max17042_read_reg(chip->client, | ||
| 150 | MAX17042_SOC) / 256; | ||
| 151 | break; | ||
| 152 | default: | ||
| 153 | return -EINVAL; | ||
| 154 | } | ||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static int __devinit max17042_probe(struct i2c_client *client, | ||
| 159 | const struct i2c_device_id *id) | ||
| 160 | { | ||
| 161 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
| 162 | struct max17042_chip *chip; | ||
| 163 | int ret; | ||
| 164 | |||
| 165 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) | ||
| 166 | return -EIO; | ||
| 167 | |||
| 168 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
| 169 | if (!chip) | ||
| 170 | return -ENOMEM; | ||
| 171 | |||
| 172 | chip->client = client; | ||
| 173 | chip->pdata = client->dev.platform_data; | ||
| 174 | |||
| 175 | i2c_set_clientdata(client, chip); | ||
| 176 | |||
| 177 | chip->battery.name = "max17042_battery"; | ||
| 178 | chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 179 | chip->battery.get_property = max17042_get_property; | ||
| 180 | chip->battery.properties = max17042_battery_props; | ||
| 181 | chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props); | ||
| 182 | |||
| 183 | ret = power_supply_register(&client->dev, &chip->battery); | ||
| 184 | if (ret) { | ||
| 185 | dev_err(&client->dev, "failed: power supply register\n"); | ||
| 186 | i2c_set_clientdata(client, NULL); | ||
| 187 | kfree(chip); | ||
| 188 | return ret; | ||
| 189 | } | ||
| 190 | |||
| 191 | if (!chip->pdata->enable_current_sense) { | ||
| 192 | max17042_write_reg(client, MAX17042_CGAIN, 0x0000); | ||
| 193 | max17042_write_reg(client, MAX17042_MiscCFG, 0x0003); | ||
| 194 | max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); | ||
| 195 | } | ||
| 196 | |||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int __devexit max17042_remove(struct i2c_client *client) | ||
| 201 | { | ||
| 202 | struct max17042_chip *chip = i2c_get_clientdata(client); | ||
| 203 | |||
| 204 | power_supply_unregister(&chip->battery); | ||
| 205 | i2c_set_clientdata(client, NULL); | ||
| 206 | kfree(chip); | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | static const struct i2c_device_id max17042_id[] = { | ||
| 211 | { "max17042", 0 }, | ||
| 212 | { } | ||
| 213 | }; | ||
| 214 | MODULE_DEVICE_TABLE(i2c, max17042_id); | ||
| 215 | |||
| 216 | static struct i2c_driver max17042_i2c_driver = { | ||
| 217 | .driver = { | ||
| 218 | .name = "max17042", | ||
| 219 | }, | ||
| 220 | .probe = max17042_probe, | ||
| 221 | .remove = __devexit_p(max17042_remove), | ||
| 222 | .id_table = max17042_id, | ||
| 223 | }; | ||
| 224 | |||
| 225 | static int __init max17042_init(void) | ||
| 226 | { | ||
| 227 | return i2c_add_driver(&max17042_i2c_driver); | ||
| 228 | } | ||
| 229 | module_init(max17042_init); | ||
| 230 | |||
| 231 | static void __exit max17042_exit(void) | ||
| 232 | { | ||
| 233 | i2c_del_driver(&max17042_i2c_driver); | ||
| 234 | } | ||
| 235 | module_exit(max17042_exit); | ||
| 236 | |||
| 237 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | ||
| 238 | MODULE_DESCRIPTION("MAX17042 Fuel Gauge"); | ||
| 239 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 5bc1dcf7785e..0b0ff3a936a6 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c | |||
| @@ -201,6 +201,72 @@ static int olpc_bat_get_tech(union power_supply_propval *val) | |||
| 201 | return ret; | 201 | return ret; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static int olpc_bat_get_charge_full_design(union power_supply_propval *val) | ||
| 205 | { | ||
| 206 | uint8_t ec_byte; | ||
| 207 | union power_supply_propval tech; | ||
| 208 | int ret, mfr; | ||
| 209 | |||
| 210 | ret = olpc_bat_get_tech(&tech); | ||
| 211 | if (ret) | ||
| 212 | return ret; | ||
| 213 | |||
| 214 | ec_byte = BAT_ADDR_MFR_TYPE; | ||
| 215 | ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1); | ||
| 216 | if (ret) | ||
| 217 | return ret; | ||
| 218 | |||
| 219 | mfr = ec_byte >> 4; | ||
| 220 | |||
| 221 | switch (tech.intval) { | ||
| 222 | case POWER_SUPPLY_TECHNOLOGY_NiMH: | ||
| 223 | switch (mfr) { | ||
| 224 | case 1: /* Gold Peak */ | ||
| 225 | val->intval = 3000000*.8; | ||
| 226 | break; | ||
| 227 | default: | ||
| 228 | return -EIO; | ||
| 229 | } | ||
| 230 | break; | ||
| 231 | |||
| 232 | case POWER_SUPPLY_TECHNOLOGY_LiFe: | ||
| 233 | switch (mfr) { | ||
| 234 | case 1: /* Gold Peak */ | ||
| 235 | val->intval = 2800000; | ||
| 236 | break; | ||
| 237 | case 2: /* BYD */ | ||
| 238 | val->intval = 3100000; | ||
| 239 | break; | ||
| 240 | default: | ||
| 241 | return -EIO; | ||
| 242 | } | ||
| 243 | break; | ||
| 244 | |||
| 245 | default: | ||
| 246 | return -EIO; | ||
| 247 | } | ||
| 248 | |||
| 249 | return ret; | ||
| 250 | } | ||
| 251 | |||
| 252 | static int olpc_bat_get_charge_now(union power_supply_propval *val) | ||
| 253 | { | ||
| 254 | uint8_t soc; | ||
| 255 | union power_supply_propval full; | ||
| 256 | int ret; | ||
| 257 | |||
| 258 | ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &soc, 1); | ||
| 259 | if (ret) | ||
| 260 | return ret; | ||
| 261 | |||
| 262 | ret = olpc_bat_get_charge_full_design(&full); | ||
| 263 | if (ret) | ||
| 264 | return ret; | ||
| 265 | |||
| 266 | val->intval = soc * (full.intval / 100); | ||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | |||
| 204 | /********************************************************************* | 270 | /********************************************************************* |
| 205 | * Battery properties | 271 | * Battery properties |
| 206 | *********************************************************************/ | 272 | *********************************************************************/ |
| @@ -267,6 +333,7 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
| 267 | return ret; | 333 | return ret; |
| 268 | break; | 334 | break; |
| 269 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | 335 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: |
| 336 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
| 270 | ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); | 337 | ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); |
| 271 | if (ret) | 338 | if (ret) |
| 272 | return ret; | 339 | return ret; |
| @@ -274,6 +341,7 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
| 274 | val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32; | 341 | val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32; |
| 275 | break; | 342 | break; |
| 276 | case POWER_SUPPLY_PROP_CURRENT_AVG: | 343 | case POWER_SUPPLY_PROP_CURRENT_AVG: |
| 344 | case POWER_SUPPLY_PROP_CURRENT_NOW: | ||
| 277 | ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); | 345 | ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); |
| 278 | if (ret) | 346 | if (ret) |
| 279 | return ret; | 347 | return ret; |
| @@ -294,6 +362,16 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
| 294 | else | 362 | else |
| 295 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; | 363 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; |
| 296 | break; | 364 | break; |
| 365 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | ||
| 366 | ret = olpc_bat_get_charge_full_design(val); | ||
| 367 | if (ret) | ||
| 368 | return ret; | ||
| 369 | break; | ||
| 370 | case POWER_SUPPLY_PROP_CHARGE_NOW: | ||
| 371 | ret = olpc_bat_get_charge_now(val); | ||
| 372 | if (ret) | ||
| 373 | return ret; | ||
| 374 | break; | ||
| 297 | case POWER_SUPPLY_PROP_TEMP: | 375 | case POWER_SUPPLY_PROP_TEMP: |
| 298 | ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); | 376 | ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); |
| 299 | if (ret) | 377 | if (ret) |
| @@ -331,16 +409,20 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
| 331 | return ret; | 409 | return ret; |
| 332 | } | 410 | } |
| 333 | 411 | ||
| 334 | static enum power_supply_property olpc_bat_props[] = { | 412 | static enum power_supply_property olpc_xo1_bat_props[] = { |
| 335 | POWER_SUPPLY_PROP_STATUS, | 413 | POWER_SUPPLY_PROP_STATUS, |
| 336 | POWER_SUPPLY_PROP_CHARGE_TYPE, | 414 | POWER_SUPPLY_PROP_CHARGE_TYPE, |
| 337 | POWER_SUPPLY_PROP_PRESENT, | 415 | POWER_SUPPLY_PROP_PRESENT, |
| 338 | POWER_SUPPLY_PROP_HEALTH, | 416 | POWER_SUPPLY_PROP_HEALTH, |
| 339 | POWER_SUPPLY_PROP_TECHNOLOGY, | 417 | POWER_SUPPLY_PROP_TECHNOLOGY, |
| 340 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | 418 | POWER_SUPPLY_PROP_VOLTAGE_AVG, |
| 419 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 341 | POWER_SUPPLY_PROP_CURRENT_AVG, | 420 | POWER_SUPPLY_PROP_CURRENT_AVG, |
| 421 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
| 342 | POWER_SUPPLY_PROP_CAPACITY, | 422 | POWER_SUPPLY_PROP_CAPACITY, |
| 343 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | 423 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, |
| 424 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | ||
| 425 | POWER_SUPPLY_PROP_CHARGE_NOW, | ||
| 344 | POWER_SUPPLY_PROP_TEMP, | 426 | POWER_SUPPLY_PROP_TEMP, |
| 345 | POWER_SUPPLY_PROP_TEMP_AMBIENT, | 427 | POWER_SUPPLY_PROP_TEMP_AMBIENT, |
| 346 | POWER_SUPPLY_PROP_MANUFACTURER, | 428 | POWER_SUPPLY_PROP_MANUFACTURER, |
| @@ -348,6 +430,27 @@ static enum power_supply_property olpc_bat_props[] = { | |||
| 348 | POWER_SUPPLY_PROP_CHARGE_COUNTER, | 430 | POWER_SUPPLY_PROP_CHARGE_COUNTER, |
| 349 | }; | 431 | }; |
| 350 | 432 | ||
| 433 | /* XO-1.5 does not have ambient temperature property */ | ||
| 434 | static enum power_supply_property olpc_xo15_bat_props[] = { | ||
| 435 | POWER_SUPPLY_PROP_STATUS, | ||
| 436 | POWER_SUPPLY_PROP_CHARGE_TYPE, | ||
| 437 | POWER_SUPPLY_PROP_PRESENT, | ||
| 438 | POWER_SUPPLY_PROP_HEALTH, | ||
| 439 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 440 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | ||
| 441 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 442 | POWER_SUPPLY_PROP_CURRENT_AVG, | ||
| 443 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
| 444 | POWER_SUPPLY_PROP_CAPACITY, | ||
| 445 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | ||
| 446 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | ||
| 447 | POWER_SUPPLY_PROP_CHARGE_NOW, | ||
| 448 | POWER_SUPPLY_PROP_TEMP, | ||
| 449 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
| 450 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | ||
| 451 | POWER_SUPPLY_PROP_CHARGE_COUNTER, | ||
| 452 | }; | ||
| 453 | |||
| 351 | /* EEPROM reading goes completely around the power_supply API, sadly */ | 454 | /* EEPROM reading goes completely around the power_supply API, sadly */ |
| 352 | 455 | ||
| 353 | #define EEPROM_START 0x20 | 456 | #define EEPROM_START 0x20 |
| @@ -419,8 +522,6 @@ static struct device_attribute olpc_bat_error = { | |||
| 419 | static struct platform_device *bat_pdev; | 522 | static struct platform_device *bat_pdev; |
| 420 | 523 | ||
| 421 | static struct power_supply olpc_bat = { | 524 | static struct power_supply olpc_bat = { |
| 422 | .properties = olpc_bat_props, | ||
| 423 | .num_properties = ARRAY_SIZE(olpc_bat_props), | ||
| 424 | .get_property = olpc_bat_get_property, | 525 | .get_property = olpc_bat_get_property, |
| 425 | .use_for_apm = 1, | 526 | .use_for_apm = 1, |
| 426 | }; | 527 | }; |
| @@ -466,6 +567,13 @@ static int __init olpc_bat_init(void) | |||
| 466 | goto ac_failed; | 567 | goto ac_failed; |
| 467 | 568 | ||
| 468 | olpc_bat.name = bat_pdev->name; | 569 | olpc_bat.name = bat_pdev->name; |
| 570 | if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ | ||
| 571 | olpc_bat.properties = olpc_xo15_bat_props; | ||
| 572 | olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); | ||
| 573 | } else { /* XO-1 */ | ||
| 574 | olpc_bat.properties = olpc_xo1_bat_props; | ||
| 575 | olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); | ||
| 576 | } | ||
| 469 | 577 | ||
| 470 | ret = power_supply_register(&bat_pdev->dev, &olpc_bat); | 578 | ret = power_supply_register(&bat_pdev->dev, &olpc_bat); |
| 471 | if (ret) | 579 | if (ret) |
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 91606bb55318..970f7335d3a7 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
| @@ -190,10 +190,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy) | |||
| 190 | goto success; | 190 | goto success; |
| 191 | 191 | ||
| 192 | create_triggers_failed: | 192 | create_triggers_failed: |
| 193 | device_unregister(psy->dev); | 193 | device_del(dev); |
| 194 | kobject_set_name_failed: | 194 | kobject_set_name_failed: |
| 195 | device_add_failed: | 195 | device_add_failed: |
| 196 | kfree(dev); | 196 | put_device(dev); |
| 197 | success: | 197 | success: |
| 198 | return rc; | 198 | return rc; |
| 199 | } | 199 | } |
| @@ -201,7 +201,7 @@ EXPORT_SYMBOL_GPL(power_supply_register); | |||
| 201 | 201 | ||
| 202 | void power_supply_unregister(struct power_supply *psy) | 202 | void power_supply_unregister(struct power_supply *psy) |
| 203 | { | 203 | { |
| 204 | flush_scheduled_work(); | 204 | cancel_work_sync(&psy->changed_work); |
| 205 | power_supply_remove_triggers(psy); | 205 | power_supply_remove_triggers(psy); |
| 206 | device_unregister(psy->dev); | 206 | device_unregister(psy->dev); |
| 207 | } | 207 | } |
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index 4a8ae3935b3b..4255f2358b13 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c | |||
| @@ -112,6 +112,13 @@ static int calc_full_volt(int volt_val, int cur_val, int impedance) | |||
| 112 | return volt_val + cur_val * impedance / 1000; | 112 | return volt_val + cur_val * impedance / 1000; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static int charge_finished(struct s3c_adc_bat *bat) | ||
| 116 | { | ||
| 117 | return bat->pdata->gpio_inverted ? | ||
| 118 | !gpio_get_value(bat->pdata->gpio_charge_finished) : | ||
| 119 | gpio_get_value(bat->pdata->gpio_charge_finished); | ||
| 120 | } | ||
| 121 | |||
| 115 | static int s3c_adc_bat_get_property(struct power_supply *psy, | 122 | static int s3c_adc_bat_get_property(struct power_supply *psy, |
| 116 | enum power_supply_property psp, | 123 | enum power_supply_property psp, |
| 117 | union power_supply_propval *val) | 124 | union power_supply_propval *val) |
| @@ -140,7 +147,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, | |||
| 140 | 147 | ||
| 141 | if (bat->cable_plugged && | 148 | if (bat->cable_plugged && |
| 142 | ((bat->pdata->gpio_charge_finished < 0) || | 149 | ((bat->pdata->gpio_charge_finished < 0) || |
| 143 | !gpio_get_value(bat->pdata->gpio_charge_finished))) { | 150 | !charge_finished(bat))) { |
| 144 | lut = bat->pdata->lut_acin; | 151 | lut = bat->pdata->lut_acin; |
| 145 | lut_size = bat->pdata->lut_acin_cnt; | 152 | lut_size = bat->pdata->lut_acin_cnt; |
| 146 | } | 153 | } |
| @@ -236,8 +243,7 @@ static void s3c_adc_bat_work(struct work_struct *work) | |||
| 236 | } | 243 | } |
| 237 | } else { | 244 | } else { |
| 238 | if ((bat->pdata->gpio_charge_finished >= 0) && is_plugged) { | 245 | if ((bat->pdata->gpio_charge_finished >= 0) && is_plugged) { |
| 239 | is_charged = gpio_get_value( | 246 | is_charged = charge_finished(&main_bat); |
| 240 | main_bat.pdata->gpio_charge_finished); | ||
| 241 | if (is_charged) { | 247 | if (is_charged) { |
| 242 | if (bat->pdata->disable_charger) | 248 | if (bat->pdata->disable_charger) |
| 243 | bat->pdata->disable_charger(); | 249 | bat->pdata->disable_charger(); |
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c index ee04936b2db5..53f0d3524fcd 100644 --- a/drivers/power/tosa_battery.c +++ b/drivers/power/tosa_battery.c | |||
| @@ -332,7 +332,7 @@ static struct { | |||
| 332 | static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state) | 332 | static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state) |
| 333 | { | 333 | { |
| 334 | /* flush all pending status updates */ | 334 | /* flush all pending status updates */ |
| 335 | flush_scheduled_work(); | 335 | flush_work_sync(&bat_work); |
| 336 | return 0; | 336 | return 0; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| @@ -422,7 +422,7 @@ err_psy_reg_jacket: | |||
| 422 | err_psy_reg_main: | 422 | err_psy_reg_main: |
| 423 | 423 | ||
| 424 | /* see comment in tosa_bat_remove */ | 424 | /* see comment in tosa_bat_remove */ |
| 425 | flush_scheduled_work(); | 425 | cancel_work_sync(&bat_work); |
| 426 | 426 | ||
| 427 | i--; | 427 | i--; |
| 428 | err_gpio: | 428 | err_gpio: |
| @@ -445,12 +445,11 @@ static int __devexit tosa_bat_remove(struct platform_device *dev) | |||
| 445 | power_supply_unregister(&tosa_bat_main.psy); | 445 | power_supply_unregister(&tosa_bat_main.psy); |
| 446 | 446 | ||
| 447 | /* | 447 | /* |
| 448 | * now flush all pending work. | 448 | * Now cancel the bat_work. We won't get any more schedules, |
| 449 | * we won't get any more schedules, since all | 449 | * since all sources (isr and external_power_changed) are |
| 450 | * sources (isr and external_power_changed) | 450 | * unregistered now. |
| 451 | * are unregistered now. | ||
| 452 | */ | 451 | */ |
| 453 | flush_scheduled_work(); | 452 | cancel_work_sync(&bat_work); |
| 454 | 453 | ||
| 455 | for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) | 454 | for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) |
| 456 | gpio_free(gpios[i].gpio); | 455 | gpio_free(gpios[i].gpio); |
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 5071d85ec12d..156559e56fa5 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c | |||
| @@ -147,7 +147,7 @@ static irqreturn_t wm97xx_chrg_irq(int irq, void *data) | |||
| 147 | #ifdef CONFIG_PM | 147 | #ifdef CONFIG_PM |
| 148 | static int wm97xx_bat_suspend(struct device *dev) | 148 | static int wm97xx_bat_suspend(struct device *dev) |
| 149 | { | 149 | { |
| 150 | flush_scheduled_work(); | 150 | flush_work_sync(&bat_work); |
| 151 | return 0; | 151 | return 0; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| @@ -273,7 +273,7 @@ static int __devexit wm97xx_bat_remove(struct platform_device *dev) | |||
| 273 | free_irq(gpio_to_irq(pdata->charge_gpio), dev); | 273 | free_irq(gpio_to_irq(pdata->charge_gpio), dev); |
| 274 | gpio_free(pdata->charge_gpio); | 274 | gpio_free(pdata->charge_gpio); |
| 275 | } | 275 | } |
| 276 | flush_scheduled_work(); | 276 | cancel_work_sync(&bat_work); |
| 277 | power_supply_unregister(&bat_ps); | 277 | power_supply_unregister(&bat_ps); |
| 278 | kfree(prop); | 278 | kfree(prop); |
| 279 | return 0; | 279 | return 0; |
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c index 85064a9f649e..e5ed52d71937 100644 --- a/drivers/power/z2_battery.c +++ b/drivers/power/z2_battery.c | |||
| @@ -254,7 +254,7 @@ static int __devexit z2_batt_remove(struct i2c_client *client) | |||
| 254 | struct z2_charger *charger = i2c_get_clientdata(client); | 254 | struct z2_charger *charger = i2c_get_clientdata(client); |
| 255 | struct z2_battery_info *info = charger->info; | 255 | struct z2_battery_info *info = charger->info; |
| 256 | 256 | ||
| 257 | flush_scheduled_work(); | 257 | cancel_work_sync(&charger->bat_work); |
| 258 | power_supply_unregister(&charger->batt_ps); | 258 | power_supply_unregister(&charger->batt_ps); |
| 259 | 259 | ||
| 260 | kfree(charger->batt_ps.properties); | 260 | kfree(charger->batt_ps.properties); |
| @@ -271,7 +271,9 @@ static int __devexit z2_batt_remove(struct i2c_client *client) | |||
| 271 | #ifdef CONFIG_PM | 271 | #ifdef CONFIG_PM |
| 272 | static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) | 272 | static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) |
| 273 | { | 273 | { |
| 274 | flush_scheduled_work(); | 274 | struct z2_charger *charger = i2c_get_clientdata(client); |
| 275 | |||
| 276 | flush_work_sync(&charger->bat_work); | ||
| 275 | return 0; | 277 | return 0; |
| 276 | } | 278 | } |
| 277 | 279 | ||
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 7568df6122ab..0ec49ca527a8 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
| @@ -424,6 +424,9 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, | |||
| 424 | } | 424 | } |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | if (pdata->buck_voltage_lock) | ||
| 428 | return -EINVAL; | ||
| 429 | |||
| 427 | /* no predefine regulator found */ | 430 | /* no predefine regulator found */ |
| 428 | max8998->buck1_idx = (buck1_last_val % 2) + 2; | 431 | max8998->buck1_idx = (buck1_last_val % 2) + 2; |
| 429 | dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", | 432 | dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", |
| @@ -451,18 +454,26 @@ buck1_exit: | |||
| 451 | "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" | 454 | "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" |
| 452 | , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); | 455 | , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); |
| 453 | if (gpio_is_valid(pdata->buck2_set3)) { | 456 | if (gpio_is_valid(pdata->buck2_set3)) { |
| 454 | if (max8998->buck2_vol[0] == i) { | 457 | |
| 455 | max8998->buck1_idx = 0; | 458 | /* check if requested voltage */ |
| 456 | buck2_gpio_set(pdata->buck2_set3, 0); | 459 | /* value is already defined */ |
| 457 | } else { | 460 | for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) { |
| 458 | max8998->buck1_idx = 1; | 461 | if (max8998->buck2_vol[j] == i) { |
| 459 | ret = max8998_get_voltage_register(rdev, ®, | 462 | max8998->buck2_idx = j; |
| 460 | &shift, | 463 | buck2_gpio_set(pdata->buck2_set3, j); |
| 461 | &mask); | 464 | goto buck2_exit; |
| 462 | ret = max8998_write_reg(i2c, reg, i); | 465 | } |
| 463 | max8998->buck2_vol[1] = i; | ||
| 464 | buck2_gpio_set(pdata->buck2_set3, 1); | ||
| 465 | } | 466 | } |
| 467 | |||
| 468 | if (pdata->buck_voltage_lock) | ||
| 469 | return -EINVAL; | ||
| 470 | |||
| 471 | max8998_get_voltage_register(rdev, | ||
| 472 | ®, &shift, &mask); | ||
| 473 | ret = max8998_write_reg(i2c, reg, i); | ||
| 474 | max8998->buck2_vol[max8998->buck2_idx] = i; | ||
| 475 | buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx); | ||
| 476 | buck2_exit: | ||
| 466 | dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, | 477 | dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, |
| 467 | gpio_get_value(pdata->buck2_set3)); | 478 | gpio_get_value(pdata->buck2_set3)); |
| 468 | } else { | 479 | } else { |
| @@ -707,6 +718,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
| 707 | platform_set_drvdata(pdev, max8998); | 718 | platform_set_drvdata(pdev, max8998); |
| 708 | i2c = max8998->iodev->i2c; | 719 | i2c = max8998->iodev->i2c; |
| 709 | 720 | ||
| 721 | max8998->buck1_idx = pdata->buck1_default_idx; | ||
| 722 | max8998->buck2_idx = pdata->buck2_default_idx; | ||
| 723 | |||
| 710 | /* NOTE: */ | 724 | /* NOTE: */ |
| 711 | /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ | 725 | /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ |
| 712 | /* will be displayed */ | 726 | /* will be displayed */ |
| @@ -739,23 +753,46 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
| 739 | i = 0; | 753 | i = 0; |
| 740 | while (buck12_voltage_map_desc.min + | 754 | while (buck12_voltage_map_desc.min + |
| 741 | buck12_voltage_map_desc.step*i | 755 | buck12_voltage_map_desc.step*i |
| 742 | != (pdata->buck1_max_voltage1 / 1000)) | 756 | < (pdata->buck1_voltage1 / 1000)) |
| 743 | i++; | 757 | i++; |
| 744 | printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); | ||
| 745 | max8998->buck1_vol[0] = i; | 758 | max8998->buck1_vol[0] = i; |
| 746 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); | 759 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); |
| 760 | if (ret) | ||
| 761 | return ret; | ||
| 747 | 762 | ||
| 748 | /* Set predefined value for BUCK1 register 2 */ | 763 | /* Set predefined value for BUCK1 register 2 */ |
| 749 | i = 0; | 764 | i = 0; |
| 750 | while (buck12_voltage_map_desc.min + | 765 | while (buck12_voltage_map_desc.min + |
| 751 | buck12_voltage_map_desc.step*i | 766 | buck12_voltage_map_desc.step*i |
| 752 | != (pdata->buck1_max_voltage2 / 1000)) | 767 | < (pdata->buck1_voltage2 / 1000)) |
| 753 | i++; | 768 | i++; |
| 754 | 769 | ||
| 755 | max8998->buck1_vol[1] = i; | 770 | max8998->buck1_vol[1] = i; |
| 756 | printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); | 771 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); |
| 757 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i) | 772 | if (ret) |
| 758 | + ret; | 773 | return ret; |
| 774 | |||
| 775 | /* Set predefined value for BUCK1 register 3 */ | ||
| 776 | i = 0; | ||
| 777 | while (buck12_voltage_map_desc.min + | ||
| 778 | buck12_voltage_map_desc.step*i | ||
| 779 | < (pdata->buck1_voltage3 / 1000)) | ||
| 780 | i++; | ||
| 781 | |||
| 782 | max8998->buck1_vol[2] = i; | ||
| 783 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); | ||
| 784 | if (ret) | ||
| 785 | return ret; | ||
| 786 | |||
| 787 | /* Set predefined value for BUCK1 register 4 */ | ||
| 788 | i = 0; | ||
| 789 | while (buck12_voltage_map_desc.min + | ||
| 790 | buck12_voltage_map_desc.step*i | ||
| 791 | < (pdata->buck1_voltage4 / 1000)) | ||
| 792 | i++; | ||
| 793 | |||
| 794 | max8998->buck1_vol[3] = i; | ||
| 795 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); | ||
| 759 | if (ret) | 796 | if (ret) |
| 760 | return ret; | 797 | return ret; |
| 761 | 798 | ||
| @@ -772,18 +809,28 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
| 772 | gpio_direction_output(pdata->buck2_set3, | 809 | gpio_direction_output(pdata->buck2_set3, |
| 773 | max8998->buck2_idx & 0x1); | 810 | max8998->buck2_idx & 0x1); |
| 774 | 811 | ||
| 775 | /* BUCK2 - set preset default voltage value to buck2_vol[0] */ | 812 | /* BUCK2 register 1 */ |
| 776 | i = 0; | 813 | i = 0; |
| 777 | while (buck12_voltage_map_desc.min + | 814 | while (buck12_voltage_map_desc.min + |
| 778 | buck12_voltage_map_desc.step*i | 815 | buck12_voltage_map_desc.step*i |
| 779 | != (pdata->buck2_max_voltage / 1000)) | 816 | < (pdata->buck2_voltage1 / 1000)) |
| 780 | i++; | 817 | i++; |
| 781 | printk(KERN_ERR "i:%d, buck2_idx:%d\n", i, max8998->buck2_idx); | ||
| 782 | max8998->buck2_vol[0] = i; | 818 | max8998->buck2_vol[0] = i; |
| 783 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); | 819 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); |
| 784 | if (ret) | 820 | if (ret) |
| 785 | return ret; | 821 | return ret; |
| 786 | 822 | ||
| 823 | /* BUCK2 register 2 */ | ||
| 824 | i = 0; | ||
| 825 | while (buck12_voltage_map_desc.min + | ||
| 826 | buck12_voltage_map_desc.step*i | ||
| 827 | < (pdata->buck2_voltage2 / 1000)) | ||
| 828 | i++; | ||
| 829 | printk(KERN_ERR "i2:%d, buck2_idx:%d\n", i, max8998->buck2_idx); | ||
| 830 | max8998->buck2_vol[1] = i; | ||
| 831 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); | ||
| 832 | if (ret) | ||
| 833 | return ret; | ||
| 787 | } | 834 | } |
| 788 | 835 | ||
| 789 | for (i = 0; i < pdata->num_regulators; i++) { | 836 | for (i = 0; i < pdata->num_regulators; i++) { |
| @@ -835,6 +882,12 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) | |||
| 835 | return 0; | 882 | return 0; |
| 836 | } | 883 | } |
| 837 | 884 | ||
| 885 | static const struct platform_device_id max8998_pmic_id[] = { | ||
| 886 | { "max8998-pmic", TYPE_MAX8998 }, | ||
| 887 | { "lp3974-pmic", TYPE_LP3974 }, | ||
| 888 | { } | ||
| 889 | }; | ||
| 890 | |||
| 838 | static struct platform_driver max8998_pmic_driver = { | 891 | static struct platform_driver max8998_pmic_driver = { |
| 839 | .driver = { | 892 | .driver = { |
| 840 | .name = "max8998-pmic", | 893 | .name = "max8998-pmic", |
| @@ -842,6 +895,7 @@ static struct platform_driver max8998_pmic_driver = { | |||
| 842 | }, | 895 | }, |
| 843 | .probe = max8998_pmic_probe, | 896 | .probe = max8998_pmic_probe, |
| 844 | .remove = __devexit_p(max8998_pmic_remove), | 897 | .remove = __devexit_p(max8998_pmic_remove), |
| 898 | .id_table = max8998_pmic_id, | ||
| 845 | }; | 899 | }; |
| 846 | 900 | ||
| 847 | static int __init max8998_pmic_init(void) | 901 | static int __init max8998_pmic_init(void) |
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index f22dee35f330..3f7bc6b9fefa 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/mfd/max8998.h> | 21 | #include <linux/mfd/max8998.h> |
| 22 | #include <linux/mfd/max8998-private.h> | 22 | #include <linux/mfd/max8998-private.h> |
| 23 | #include <linux/delay.h> | ||
| 23 | 24 | ||
| 24 | #define MAX8998_RTC_SEC 0x00 | 25 | #define MAX8998_RTC_SEC 0x00 |
| 25 | #define MAX8998_RTC_MIN 0x01 | 26 | #define MAX8998_RTC_MIN 0x01 |
| @@ -73,6 +74,7 @@ struct max8998_rtc_info { | |||
| 73 | struct i2c_client *rtc; | 74 | struct i2c_client *rtc; |
| 74 | struct rtc_device *rtc_dev; | 75 | struct rtc_device *rtc_dev; |
| 75 | int irq; | 76 | int irq; |
| 77 | bool lp3974_bug_workaround; | ||
| 76 | }; | 78 | }; |
| 77 | 79 | ||
| 78 | static void max8998_data_to_tm(u8 *data, struct rtc_time *tm) | 80 | static void max8998_data_to_tm(u8 *data, struct rtc_time *tm) |
| @@ -124,10 +126,16 @@ static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 124 | { | 126 | { |
| 125 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | 127 | struct max8998_rtc_info *info = dev_get_drvdata(dev); |
| 126 | u8 data[8]; | 128 | u8 data[8]; |
| 129 | int ret; | ||
| 127 | 130 | ||
| 128 | max8998_tm_to_data(tm, data); | 131 | max8998_tm_to_data(tm, data); |
| 129 | 132 | ||
| 130 | return max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); | 133 | ret = max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); |
| 134 | |||
| 135 | if (info->lp3974_bug_workaround) | ||
| 136 | msleep(2000); | ||
| 137 | |||
| 138 | return ret; | ||
| 131 | } | 139 | } |
| 132 | 140 | ||
| 133 | static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 141 | static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| @@ -163,12 +171,29 @@ static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 163 | 171 | ||
| 164 | static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info) | 172 | static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info) |
| 165 | { | 173 | { |
| 166 | return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); | 174 | int ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); |
| 175 | |||
| 176 | if (info->lp3974_bug_workaround) | ||
| 177 | msleep(2000); | ||
| 178 | |||
| 179 | return ret; | ||
| 167 | } | 180 | } |
| 168 | 181 | ||
| 169 | static int max8998_rtc_start_alarm(struct max8998_rtc_info *info) | 182 | static int max8998_rtc_start_alarm(struct max8998_rtc_info *info) |
| 170 | { | 183 | { |
| 171 | return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0x77); | 184 | int ret; |
| 185 | u8 alarm0_conf = 0x77; | ||
| 186 | |||
| 187 | /* LP3974 with delay bug chips has rtc alarm bugs with "MONTH" field */ | ||
| 188 | if (info->lp3974_bug_workaround) | ||
| 189 | alarm0_conf = 0x57; | ||
| 190 | |||
| 191 | ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, alarm0_conf); | ||
| 192 | |||
| 193 | if (info->lp3974_bug_workaround) | ||
| 194 | msleep(2000); | ||
| 195 | |||
| 196 | return ret; | ||
| 172 | } | 197 | } |
| 173 | 198 | ||
| 174 | static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 199 | static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| @@ -187,10 +212,13 @@ static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 187 | if (ret < 0) | 212 | if (ret < 0) |
| 188 | return ret; | 213 | return ret; |
| 189 | 214 | ||
| 215 | if (info->lp3974_bug_workaround) | ||
| 216 | msleep(2000); | ||
| 217 | |||
| 190 | if (alrm->enabled) | 218 | if (alrm->enabled) |
| 191 | return max8998_rtc_start_alarm(info); | 219 | ret = max8998_rtc_start_alarm(info); |
| 192 | 220 | ||
| 193 | return 0; | 221 | return ret; |
| 194 | } | 222 | } |
| 195 | 223 | ||
| 196 | static int max8998_rtc_alarm_irq_enable(struct device *dev, | 224 | static int max8998_rtc_alarm_irq_enable(struct device *dev, |
| @@ -224,6 +252,7 @@ static const struct rtc_class_ops max8998_rtc_ops = { | |||
| 224 | static int __devinit max8998_rtc_probe(struct platform_device *pdev) | 252 | static int __devinit max8998_rtc_probe(struct platform_device *pdev) |
| 225 | { | 253 | { |
| 226 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); | 254 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); |
| 255 | struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev); | ||
| 227 | struct max8998_rtc_info *info; | 256 | struct max8998_rtc_info *info; |
| 228 | int ret; | 257 | int ret; |
| 229 | 258 | ||
| @@ -249,10 +278,18 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) | |||
| 249 | 278 | ||
| 250 | ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, | 279 | ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, |
| 251 | "rtc-alarm0", info); | 280 | "rtc-alarm0", info); |
| 281 | |||
| 252 | if (ret < 0) | 282 | if (ret < 0) |
| 253 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | 283 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", |
| 254 | info->irq, ret); | 284 | info->irq, ret); |
| 255 | 285 | ||
| 286 | dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); | ||
| 287 | if (pdata->rtc_delay) { | ||
| 288 | info->lp3974_bug_workaround = true; | ||
| 289 | dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." | ||
| 290 | " RTC updates will be extremely slow.\n"); | ||
| 291 | } | ||
| 292 | |||
| 256 | return 0; | 293 | return 0; |
| 257 | 294 | ||
| 258 | out_rtc: | 295 | out_rtc: |
| @@ -273,6 +310,12 @@ static int __devexit max8998_rtc_remove(struct platform_device *pdev) | |||
| 273 | return 0; | 310 | return 0; |
| 274 | } | 311 | } |
| 275 | 312 | ||
| 313 | static const struct platform_device_id max8998_rtc_id[] = { | ||
| 314 | { "max8998-rtc", TYPE_MAX8998 }, | ||
| 315 | { "lp3974-rtc", TYPE_LP3974 }, | ||
| 316 | { } | ||
| 317 | }; | ||
| 318 | |||
| 276 | static struct platform_driver max8998_rtc_driver = { | 319 | static struct platform_driver max8998_rtc_driver = { |
| 277 | .driver = { | 320 | .driver = { |
| 278 | .name = "max8998-rtc", | 321 | .name = "max8998-rtc", |
| @@ -280,6 +323,7 @@ static struct platform_driver max8998_rtc_driver = { | |||
| 280 | }, | 323 | }, |
| 281 | .probe = max8998_rtc_probe, | 324 | .probe = max8998_rtc_probe, |
| 282 | .remove = __devexit_p(max8998_rtc_remove), | 325 | .remove = __devexit_p(max8998_rtc_remove), |
| 326 | .id_table = max8998_rtc_id, | ||
| 283 | }; | 327 | }; |
| 284 | 328 | ||
| 285 | static int __init max8998_rtc_init(void) | 329 | static int __init max8998_rtc_init(void) |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index e8391b89eff4..b7eaff9ca19e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -1835,6 +1835,7 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev) | |||
| 1835 | * available again. Kick re-detection. | 1835 | * available again. Kick re-detection. |
| 1836 | */ | 1836 | */ |
| 1837 | cdev->private->flags.resuming = 1; | 1837 | cdev->private->flags.resuming = 1; |
| 1838 | cdev->private->path_new_mask = LPM_ANYPATH; | ||
| 1838 | css_schedule_eval(sch->schid); | 1839 | css_schedule_eval(sch->schid); |
| 1839 | spin_unlock_irq(sch->lock); | 1840 | spin_unlock_irq(sch->lock); |
| 1840 | css_complete_work(); | 1841 | css_complete_work(); |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index d3c5905b22ec..9c5c8be72231 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
| @@ -7515,16 +7515,10 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) | |||
| 7515 | { | 7515 | { |
| 7516 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 7516 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 7517 | volatile u32 int_reg; | 7517 | volatile u32 int_reg; |
| 7518 | int rc; | ||
| 7519 | 7518 | ||
| 7520 | ENTER; | 7519 | ENTER; |
| 7521 | ioa_cfg->pdev->state_saved = true; | 7520 | ioa_cfg->pdev->state_saved = true; |
| 7522 | rc = pci_restore_state(ioa_cfg->pdev); | 7521 | pci_restore_state(ioa_cfg->pdev); |
| 7523 | |||
| 7524 | if (rc != PCIBIOS_SUCCESSFUL) { | ||
| 7525 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); | ||
| 7526 | return IPR_RC_JOB_CONTINUE; | ||
| 7527 | } | ||
| 7528 | 7522 | ||
| 7529 | if (ipr_set_pcix_cmd_reg(ioa_cfg)) { | 7523 | if (ipr_set_pcix_cmd_reg(ioa_cfg)) { |
| 7530 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); | 7524 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); |
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 300d59f389da..321cf3ae8630 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
| @@ -2228,12 +2228,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd) | |||
| 2228 | /* Once either bist or pci reset is done, restore PCI config | 2228 | /* Once either bist or pci reset is done, restore PCI config |
| 2229 | * space. If this fails, proceed with hard reset again | 2229 | * space. If this fails, proceed with hard reset again |
| 2230 | */ | 2230 | */ |
| 2231 | if (pci_restore_state(pinstance->pdev)) { | 2231 | pci_restore_state(pinstance->pdev); |
| 2232 | pmcraid_info("config-space error resetting again\n"); | ||
| 2233 | pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; | ||
| 2234 | pmcraid_reset_alert(cmd); | ||
| 2235 | break; | ||
| 2236 | } | ||
| 2237 | 2232 | ||
| 2238 | /* fail all pending commands */ | 2233 | /* fail all pending commands */ |
| 2239 | pmcraid_fail_outstanding_cmds(pinstance); | 2234 | pmcraid_fail_outstanding_cmds(pinstance); |
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 5a0985d4ce15..29884c00c4d5 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c | |||
| @@ -420,6 +420,16 @@ int ssb_bus_scan(struct ssb_bus *bus, | |||
| 420 | bus->pcicore.dev = dev; | 420 | bus->pcicore.dev = dev; |
| 421 | #endif /* CONFIG_SSB_DRIVER_PCICORE */ | 421 | #endif /* CONFIG_SSB_DRIVER_PCICORE */ |
| 422 | break; | 422 | break; |
| 423 | case SSB_DEV_ETHERNET: | ||
| 424 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
| 425 | if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM && | ||
| 426 | (bus->host_pci->device & 0xFF00) == 0x4300) { | ||
| 427 | /* This is a dangling ethernet core on a | ||
| 428 | * wireless device. Ignore it. */ | ||
| 429 | continue; | ||
| 430 | } | ||
| 431 | } | ||
| 432 | break; | ||
| 423 | default: | 433 | default: |
| 424 | break; | 434 | break; |
| 425 | } | 435 | } |
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index f4b163f7338a..0bc113c44d39 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c | |||
| @@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) | |||
| 1071 | /* when resuming, restore pci data and fb cursor */ | 1071 | /* when resuming, restore pci data and fb cursor */ |
| 1072 | if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { | 1072 | if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { |
| 1073 | retv = pci_set_power_state(pdev, PCI_D0); | 1073 | retv = pci_set_power_state(pdev, PCI_D0); |
| 1074 | retv = pci_restore_state(pdev); | 1074 | pci_restore_state(pdev); |
| 1075 | if (pci_enable_device(pdev)) | 1075 | if (pci_enable_device(pdev)) |
| 1076 | return -1; | 1076 | return -1; |
| 1077 | pci_set_master(pdev); | 1077 | pci_set_master(pdev); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 38244f59cdd9..ade0568c07a4 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
| @@ -97,22 +97,26 @@ void vhost_poll_stop(struct vhost_poll *poll) | |||
| 97 | remove_wait_queue(poll->wqh, &poll->wait); | 97 | remove_wait_queue(poll->wqh, &poll->wait); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, | ||
| 101 | unsigned seq) | ||
| 102 | { | ||
| 103 | int left; | ||
| 104 | spin_lock_irq(&dev->work_lock); | ||
| 105 | left = seq - work->done_seq; | ||
| 106 | spin_unlock_irq(&dev->work_lock); | ||
| 107 | return left <= 0; | ||
| 108 | } | ||
| 109 | |||
| 100 | static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) | 110 | static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) |
| 101 | { | 111 | { |
| 102 | unsigned seq; | 112 | unsigned seq; |
| 103 | int left; | ||
| 104 | int flushing; | 113 | int flushing; |
| 105 | 114 | ||
| 106 | spin_lock_irq(&dev->work_lock); | 115 | spin_lock_irq(&dev->work_lock); |
| 107 | seq = work->queue_seq; | 116 | seq = work->queue_seq; |
| 108 | work->flushing++; | 117 | work->flushing++; |
| 109 | spin_unlock_irq(&dev->work_lock); | 118 | spin_unlock_irq(&dev->work_lock); |
| 110 | wait_event(work->done, ({ | 119 | wait_event(work->done, vhost_work_seq_done(dev, work, seq)); |
| 111 | spin_lock_irq(&dev->work_lock); | ||
| 112 | left = seq - work->done_seq <= 0; | ||
| 113 | spin_unlock_irq(&dev->work_lock); | ||
| 114 | left; | ||
| 115 | })); | ||
| 116 | spin_lock_irq(&dev->work_lock); | 120 | spin_lock_irq(&dev->work_lock); |
| 117 | flushing = --work->flushing; | 121 | flushing = --work->flushing; |
| 118 | spin_unlock_irq(&dev->work_lock); | 122 | spin_unlock_irq(&dev->work_lock); |
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index a3bcec75c54a..1c8c6cc6de30 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
| @@ -289,7 +289,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, | |||
| 289 | call->server = server; | 289 | call->server = server; |
| 290 | 290 | ||
| 291 | INIT_WORK(&call->work, SRXAFSCB_CallBack); | 291 | INIT_WORK(&call->work, SRXAFSCB_CallBack); |
| 292 | schedule_work(&call->work); | 292 | queue_work(afs_wq, &call->work); |
| 293 | return 0; | 293 | return 0; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| @@ -336,7 +336,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call, | |||
| 336 | call->server = server; | 336 | call->server = server; |
| 337 | 337 | ||
| 338 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); | 338 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); |
| 339 | schedule_work(&call->work); | 339 | queue_work(afs_wq, &call->work); |
| 340 | return 0; | 340 | return 0; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| @@ -367,7 +367,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call, | |||
| 367 | call->server = server; | 367 | call->server = server; |
| 368 | 368 | ||
| 369 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); | 369 | INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); |
| 370 | schedule_work(&call->work); | 370 | queue_work(afs_wq, &call->work); |
| 371 | return 0; | 371 | return 0; |
| 372 | } | 372 | } |
| 373 | 373 | ||
| @@ -400,7 +400,7 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb, | |||
| 400 | call->state = AFS_CALL_REPLYING; | 400 | call->state = AFS_CALL_REPLYING; |
| 401 | 401 | ||
| 402 | INIT_WORK(&call->work, SRXAFSCB_Probe); | 402 | INIT_WORK(&call->work, SRXAFSCB_Probe); |
| 403 | schedule_work(&call->work); | 403 | queue_work(afs_wq, &call->work); |
| 404 | return 0; | 404 | return 0; |
| 405 | } | 405 | } |
| 406 | 406 | ||
| @@ -496,7 +496,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb, | |||
| 496 | call->state = AFS_CALL_REPLYING; | 496 | call->state = AFS_CALL_REPLYING; |
| 497 | 497 | ||
| 498 | INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); | 498 | INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); |
| 499 | schedule_work(&call->work); | 499 | queue_work(afs_wq, &call->work); |
| 500 | return 0; | 500 | return 0; |
| 501 | } | 501 | } |
| 502 | 502 | ||
| @@ -580,6 +580,6 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call, | |||
| 580 | call->state = AFS_CALL_REPLYING; | 580 | call->state = AFS_CALL_REPLYING; |
| 581 | 581 | ||
| 582 | INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); | 582 | INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); |
| 583 | schedule_work(&call->work); | 583 | queue_work(afs_wq, &call->work); |
| 584 | return 0; | 584 | return 0; |
| 585 | } | 585 | } |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index ab6db5abaf53..58c633b80246 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -577,6 +577,7 @@ extern int afs_drop_inode(struct inode *); | |||
| 577 | /* | 577 | /* |
| 578 | * main.c | 578 | * main.c |
| 579 | */ | 579 | */ |
| 580 | extern struct workqueue_struct *afs_wq; | ||
| 580 | extern struct afs_uuid afs_uuid; | 581 | extern struct afs_uuid afs_uuid; |
| 581 | 582 | ||
| 582 | /* | 583 | /* |
diff --git a/fs/afs/main.c b/fs/afs/main.c index cfd1cbe25b22..42dd2e499ed8 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c | |||
| @@ -30,6 +30,7 @@ module_param(rootcell, charp, 0); | |||
| 30 | MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); | 30 | MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); |
| 31 | 31 | ||
| 32 | struct afs_uuid afs_uuid; | 32 | struct afs_uuid afs_uuid; |
| 33 | struct workqueue_struct *afs_wq; | ||
| 33 | 34 | ||
| 34 | /* | 35 | /* |
| 35 | * get a client UUID | 36 | * get a client UUID |
| @@ -87,10 +88,16 @@ static int __init afs_init(void) | |||
| 87 | if (ret < 0) | 88 | if (ret < 0) |
| 88 | return ret; | 89 | return ret; |
| 89 | 90 | ||
| 91 | /* create workqueue */ | ||
| 92 | ret = -ENOMEM; | ||
| 93 | afs_wq = alloc_workqueue("afs", 0, 0); | ||
| 94 | if (!afs_wq) | ||
| 95 | return ret; | ||
| 96 | |||
| 90 | /* register the /proc stuff */ | 97 | /* register the /proc stuff */ |
| 91 | ret = afs_proc_init(); | 98 | ret = afs_proc_init(); |
| 92 | if (ret < 0) | 99 | if (ret < 0) |
| 93 | return ret; | 100 | goto error_proc; |
| 94 | 101 | ||
| 95 | #ifdef CONFIG_AFS_FSCACHE | 102 | #ifdef CONFIG_AFS_FSCACHE |
| 96 | /* we want to be able to cache */ | 103 | /* we want to be able to cache */ |
| @@ -140,6 +147,8 @@ error_cell_init: | |||
| 140 | error_cache: | 147 | error_cache: |
| 141 | #endif | 148 | #endif |
| 142 | afs_proc_cleanup(); | 149 | afs_proc_cleanup(); |
| 150 | error_proc: | ||
| 151 | destroy_workqueue(afs_wq); | ||
| 143 | rcu_barrier(); | 152 | rcu_barrier(); |
| 144 | printk(KERN_ERR "kAFS: failed to register: %d\n", ret); | 153 | printk(KERN_ERR "kAFS: failed to register: %d\n", ret); |
| 145 | return ret; | 154 | return ret; |
| @@ -163,7 +172,7 @@ static void __exit afs_exit(void) | |||
| 163 | afs_purge_servers(); | 172 | afs_purge_servers(); |
| 164 | afs_callback_update_kill(); | 173 | afs_callback_update_kill(); |
| 165 | afs_vlocation_purge(); | 174 | afs_vlocation_purge(); |
| 166 | flush_scheduled_work(); | 175 | destroy_workqueue(afs_wq); |
| 167 | afs_cell_purge(); | 176 | afs_cell_purge(); |
| 168 | #ifdef CONFIG_AFS_FSCACHE | 177 | #ifdef CONFIG_AFS_FSCACHE |
| 169 | fscache_unregister_netfs(&afs_cache_netfs); | 178 | fscache_unregister_netfs(&afs_cache_netfs); |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 6153417caf57..e83c0336e7b5 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
| @@ -268,8 +268,8 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
| 268 | path_put(&nd->path); | 268 | path_put(&nd->path); |
| 269 | nd->path.mnt = newmnt; | 269 | nd->path.mnt = newmnt; |
| 270 | nd->path.dentry = dget(newmnt->mnt_root); | 270 | nd->path.dentry = dget(newmnt->mnt_root); |
| 271 | schedule_delayed_work(&afs_mntpt_expiry_timer, | 271 | queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, |
| 272 | afs_mntpt_expiry_timeout * HZ); | 272 | afs_mntpt_expiry_timeout * HZ); |
| 273 | break; | 273 | break; |
| 274 | case -EBUSY: | 274 | case -EBUSY: |
| 275 | /* someone else made a mount here whilst we were busy */ | 275 | /* someone else made a mount here whilst we were busy */ |
| @@ -295,8 +295,8 @@ static void afs_mntpt_expiry_timed_out(struct work_struct *work) | |||
| 295 | 295 | ||
| 296 | if (!list_empty(&afs_vfsmounts)) { | 296 | if (!list_empty(&afs_vfsmounts)) { |
| 297 | mark_mounts_for_expiry(&afs_vfsmounts); | 297 | mark_mounts_for_expiry(&afs_vfsmounts); |
| 298 | schedule_delayed_work(&afs_mntpt_expiry_timer, | 298 | queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, |
| 299 | afs_mntpt_expiry_timeout * HZ); | 299 | afs_mntpt_expiry_timeout * HZ); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | _leave(""); | 302 | _leave(""); |
| @@ -310,6 +310,5 @@ void afs_mntpt_kill_timer(void) | |||
| 310 | _enter(""); | 310 | _enter(""); |
| 311 | 311 | ||
| 312 | ASSERT(list_empty(&afs_vfsmounts)); | 312 | ASSERT(list_empty(&afs_vfsmounts)); |
| 313 | cancel_delayed_work(&afs_mntpt_expiry_timer); | 313 | cancel_delayed_work_sync(&afs_mntpt_expiry_timer); |
| 314 | flush_scheduled_work(); | ||
| 315 | } | 314 | } |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 654d8fdbf01f..e45a323aebb4 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
| @@ -410,7 +410,7 @@ static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID, | |||
| 410 | if (!call) { | 410 | if (!call) { |
| 411 | /* its an incoming call for our callback service */ | 411 | /* its an incoming call for our callback service */ |
| 412 | skb_queue_tail(&afs_incoming_calls, skb); | 412 | skb_queue_tail(&afs_incoming_calls, skb); |
| 413 | schedule_work(&afs_collect_incoming_call_work); | 413 | queue_work(afs_wq, &afs_collect_incoming_call_work); |
| 414 | } else { | 414 | } else { |
| 415 | /* route the messages directly to the appropriate call */ | 415 | /* route the messages directly to the appropriate call */ |
| 416 | skb_queue_tail(&call->rx_queue, skb); | 416 | skb_queue_tail(&call->rx_queue, skb); |
diff --git a/fs/afs/server.c b/fs/afs/server.c index 9fdc7fe3a7bc..d59b7516e943 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
| @@ -238,8 +238,8 @@ void afs_put_server(struct afs_server *server) | |||
| 238 | if (atomic_read(&server->usage) == 0) { | 238 | if (atomic_read(&server->usage) == 0) { |
| 239 | list_move_tail(&server->grave, &afs_server_graveyard); | 239 | list_move_tail(&server->grave, &afs_server_graveyard); |
| 240 | server->time_of_death = get_seconds(); | 240 | server->time_of_death = get_seconds(); |
| 241 | schedule_delayed_work(&afs_server_reaper, | 241 | queue_delayed_work(afs_wq, &afs_server_reaper, |
| 242 | afs_server_timeout * HZ); | 242 | afs_server_timeout * HZ); |
| 243 | } | 243 | } |
| 244 | spin_unlock(&afs_server_graveyard_lock); | 244 | spin_unlock(&afs_server_graveyard_lock); |
| 245 | _leave(" [dead]"); | 245 | _leave(" [dead]"); |
| @@ -285,10 +285,11 @@ static void afs_reap_server(struct work_struct *work) | |||
| 285 | expiry = server->time_of_death + afs_server_timeout; | 285 | expiry = server->time_of_death + afs_server_timeout; |
| 286 | if (expiry > now) { | 286 | if (expiry > now) { |
| 287 | delay = (expiry - now) * HZ; | 287 | delay = (expiry - now) * HZ; |
| 288 | if (!schedule_delayed_work(&afs_server_reaper, delay)) { | 288 | if (!queue_delayed_work(afs_wq, &afs_server_reaper, |
| 289 | delay)) { | ||
| 289 | cancel_delayed_work(&afs_server_reaper); | 290 | cancel_delayed_work(&afs_server_reaper); |
| 290 | schedule_delayed_work(&afs_server_reaper, | 291 | queue_delayed_work(afs_wq, &afs_server_reaper, |
| 291 | delay); | 292 | delay); |
| 292 | } | 293 | } |
| 293 | break; | 294 | break; |
| 294 | } | 295 | } |
| @@ -323,5 +324,5 @@ void __exit afs_purge_servers(void) | |||
| 323 | { | 324 | { |
| 324 | afs_server_timeout = 0; | 325 | afs_server_timeout = 0; |
| 325 | cancel_delayed_work(&afs_server_reaper); | 326 | cancel_delayed_work(&afs_server_reaper); |
| 326 | schedule_delayed_work(&afs_server_reaper, 0); | 327 | queue_delayed_work(afs_wq, &afs_server_reaper, 0); |
| 327 | } | 328 | } |
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 9ac260d1361d..431984d2e372 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c | |||
| @@ -507,8 +507,8 @@ void afs_put_vlocation(struct afs_vlocation *vl) | |||
| 507 | _debug("buried"); | 507 | _debug("buried"); |
| 508 | list_move_tail(&vl->grave, &afs_vlocation_graveyard); | 508 | list_move_tail(&vl->grave, &afs_vlocation_graveyard); |
| 509 | vl->time_of_death = get_seconds(); | 509 | vl->time_of_death = get_seconds(); |
| 510 | schedule_delayed_work(&afs_vlocation_reap, | 510 | queue_delayed_work(afs_wq, &afs_vlocation_reap, |
| 511 | afs_vlocation_timeout * HZ); | 511 | afs_vlocation_timeout * HZ); |
| 512 | 512 | ||
| 513 | /* suspend updates on this record */ | 513 | /* suspend updates on this record */ |
| 514 | if (!list_empty(&vl->update)) { | 514 | if (!list_empty(&vl->update)) { |
| @@ -561,11 +561,11 @@ static void afs_vlocation_reaper(struct work_struct *work) | |||
| 561 | if (expiry > now) { | 561 | if (expiry > now) { |
| 562 | delay = (expiry - now) * HZ; | 562 | delay = (expiry - now) * HZ; |
| 563 | _debug("delay %lu", delay); | 563 | _debug("delay %lu", delay); |
| 564 | if (!schedule_delayed_work(&afs_vlocation_reap, | 564 | if (!queue_delayed_work(afs_wq, &afs_vlocation_reap, |
| 565 | delay)) { | 565 | delay)) { |
| 566 | cancel_delayed_work(&afs_vlocation_reap); | 566 | cancel_delayed_work(&afs_vlocation_reap); |
| 567 | schedule_delayed_work(&afs_vlocation_reap, | 567 | queue_delayed_work(afs_wq, &afs_vlocation_reap, |
| 568 | delay); | 568 | delay); |
| 569 | } | 569 | } |
| 570 | break; | 570 | break; |
| 571 | } | 571 | } |
| @@ -620,7 +620,7 @@ void afs_vlocation_purge(void) | |||
| 620 | destroy_workqueue(afs_vlocation_update_worker); | 620 | destroy_workqueue(afs_vlocation_update_worker); |
| 621 | 621 | ||
| 622 | cancel_delayed_work(&afs_vlocation_reap); | 622 | cancel_delayed_work(&afs_vlocation_reap); |
| 623 | schedule_delayed_work(&afs_vlocation_reap, 0); | 623 | queue_delayed_work(afs_wq, &afs_vlocation_reap, 0); |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | /* | 626 | /* |
diff --git a/fs/dcache.c b/fs/dcache.c index 0c6d5c549d84..274a22250380 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -1357,8 +1357,8 @@ EXPORT_SYMBOL(d_alloc_name); | |||
| 1357 | 1357 | ||
| 1358 | void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) | 1358 | void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) |
| 1359 | { | 1359 | { |
| 1360 | BUG_ON(dentry->d_op); | 1360 | WARN_ON_ONCE(dentry->d_op); |
| 1361 | BUG_ON(dentry->d_flags & (DCACHE_OP_HASH | | 1361 | WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH | |
| 1362 | DCACHE_OP_COMPARE | | 1362 | DCACHE_OP_COMPARE | |
| 1363 | DCACHE_OP_REVALIDATE | | 1363 | DCACHE_OP_REVALIDATE | |
| 1364 | DCACHE_OP_DELETE )); | 1364 | DCACHE_OP_DELETE )); |
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index b9f34eaede09..48a18f184d50 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c | |||
| @@ -101,7 +101,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object, | |||
| 101 | object->n_ops++; | 101 | object->n_ops++; |
| 102 | object->n_exclusive++; /* reads and writes must wait */ | 102 | object->n_exclusive++; /* reads and writes must wait */ |
| 103 | 103 | ||
| 104 | if (object->n_ops > 0) { | 104 | if (object->n_ops > 1) { |
| 105 | atomic_inc(&op->usage); | 105 | atomic_inc(&op->usage); |
| 106 | list_add_tail(&op->pend_link, &object->pending_ops); | 106 | list_add_tail(&op->pend_link, &object->pending_ops); |
| 107 | fscache_stat(&fscache_n_op_pend); | 107 | fscache_stat(&fscache_n_op_pend); |
diff --git a/fs/locks.c b/fs/locks.c index 08415b2a6d36..0f3998291f78 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -444,15 +444,9 @@ static void lease_release_private_callback(struct file_lock *fl) | |||
| 444 | fl->fl_file->f_owner.signum = 0; | 444 | fl->fl_file->f_owner.signum = 0; |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static int lease_mylease_callback(struct file_lock *fl, struct file_lock *try) | ||
| 448 | { | ||
| 449 | return fl->fl_file == try->fl_file; | ||
| 450 | } | ||
| 451 | |||
| 452 | static const struct lock_manager_operations lease_manager_ops = { | 447 | static const struct lock_manager_operations lease_manager_ops = { |
| 453 | .fl_break = lease_break_callback, | 448 | .fl_break = lease_break_callback, |
| 454 | .fl_release_private = lease_release_private_callback, | 449 | .fl_release_private = lease_release_private_callback, |
| 455 | .fl_mylease = lease_mylease_callback, | ||
| 456 | .fl_change = lease_modify, | 450 | .fl_change = lease_modify, |
| 457 | }; | 451 | }; |
| 458 | 452 | ||
| @@ -1405,7 +1399,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | |||
| 1405 | for (before = &inode->i_flock; | 1399 | for (before = &inode->i_flock; |
| 1406 | ((fl = *before) != NULL) && IS_LEASE(fl); | 1400 | ((fl = *before) != NULL) && IS_LEASE(fl); |
| 1407 | before = &fl->fl_next) { | 1401 | before = &fl->fl_next) { |
| 1408 | if (lease->fl_lmops->fl_mylease(fl, lease)) | 1402 | if (fl->fl_file == filp) |
| 1409 | my_before = before; | 1403 | my_before = before; |
| 1410 | else if (fl->fl_type == (F_INPROGRESS | F_UNLCK)) | 1404 | else if (fl->fl_type == (F_INPROGRESS | F_UNLCK)) |
| 1411 | /* | 1405 | /* |
diff --git a/fs/namei.c b/fs/namei.c index 86643302079e..8df7a78ace58 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -779,7 +779,8 @@ static void path_put_conditional(struct path *path, struct nameidata *nd) | |||
| 779 | mntput(path->mnt); | 779 | mntput(path->mnt); |
| 780 | } | 780 | } |
| 781 | 781 | ||
| 782 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | 782 | static inline void path_to_nameidata(const struct path *path, |
| 783 | struct nameidata *nd) | ||
| 783 | { | 784 | { |
| 784 | if (!(nd->flags & LOOKUP_RCU)) { | 785 | if (!(nd->flags & LOOKUP_RCU)) { |
| 785 | dput(nd->path.dentry); | 786 | dput(nd->path.dentry); |
| @@ -791,20 +792,20 @@ static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | |||
| 791 | } | 792 | } |
| 792 | 793 | ||
| 793 | static __always_inline int | 794 | static __always_inline int |
| 794 | __do_follow_link(struct path *path, struct nameidata *nd, void **p) | 795 | __do_follow_link(const struct path *link, struct nameidata *nd, void **p) |
| 795 | { | 796 | { |
| 796 | int error; | 797 | int error; |
| 797 | struct dentry *dentry = path->dentry; | 798 | struct dentry *dentry = link->dentry; |
| 798 | 799 | ||
| 799 | touch_atime(path->mnt, dentry); | 800 | touch_atime(link->mnt, dentry); |
| 800 | nd_set_link(nd, NULL); | 801 | nd_set_link(nd, NULL); |
| 801 | 802 | ||
| 802 | if (path->mnt != nd->path.mnt) { | 803 | if (link->mnt != nd->path.mnt) { |
| 803 | path_to_nameidata(path, nd); | 804 | path_to_nameidata(link, nd); |
| 804 | nd->inode = nd->path.dentry->d_inode; | 805 | nd->inode = nd->path.dentry->d_inode; |
| 805 | dget(dentry); | 806 | dget(dentry); |
| 806 | } | 807 | } |
| 807 | mntget(path->mnt); | 808 | mntget(link->mnt); |
| 808 | 809 | ||
| 809 | nd->last_type = LAST_BIND; | 810 | nd->last_type = LAST_BIND; |
| 810 | *p = dentry->d_inode->i_op->follow_link(dentry, nd); | 811 | *p = dentry->d_inode->i_op->follow_link(dentry, nd); |
| @@ -2348,11 +2349,12 @@ reval: | |||
| 2348 | nd.flags = flags; | 2349 | nd.flags = flags; |
| 2349 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); | 2350 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); |
| 2350 | while (unlikely(!filp)) { /* trailing symlink */ | 2351 | while (unlikely(!filp)) { /* trailing symlink */ |
| 2351 | struct path holder; | 2352 | struct path link = path; |
| 2353 | struct inode *linki = link.dentry->d_inode; | ||
| 2352 | void *cookie; | 2354 | void *cookie; |
| 2353 | error = -ELOOP; | 2355 | error = -ELOOP; |
| 2354 | /* S_ISDIR part is a temporary automount kludge */ | 2356 | /* S_ISDIR part is a temporary automount kludge */ |
| 2355 | if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(nd.inode->i_mode)) | 2357 | if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(linki->i_mode)) |
| 2356 | goto exit_dput; | 2358 | goto exit_dput; |
| 2357 | if (count++ == 32) | 2359 | if (count++ == 32) |
| 2358 | goto exit_dput; | 2360 | goto exit_dput; |
| @@ -2368,23 +2370,22 @@ reval: | |||
| 2368 | * just set LAST_BIND. | 2370 | * just set LAST_BIND. |
| 2369 | */ | 2371 | */ |
| 2370 | nd.flags |= LOOKUP_PARENT; | 2372 | nd.flags |= LOOKUP_PARENT; |
| 2371 | error = security_inode_follow_link(path.dentry, &nd); | 2373 | error = security_inode_follow_link(link.dentry, &nd); |
| 2372 | if (error) | 2374 | if (error) |
| 2373 | goto exit_dput; | 2375 | goto exit_dput; |
| 2374 | error = __do_follow_link(&path, &nd, &cookie); | 2376 | error = __do_follow_link(&link, &nd, &cookie); |
| 2375 | if (unlikely(error)) { | 2377 | if (unlikely(error)) { |
| 2376 | if (!IS_ERR(cookie) && nd.inode->i_op->put_link) | 2378 | if (!IS_ERR(cookie) && linki->i_op->put_link) |
| 2377 | nd.inode->i_op->put_link(path.dentry, &nd, cookie); | 2379 | linki->i_op->put_link(link.dentry, &nd, cookie); |
| 2378 | /* nd.path had been dropped */ | 2380 | /* nd.path had been dropped */ |
| 2379 | nd.path = path; | 2381 | nd.path = link; |
| 2380 | goto out_path; | 2382 | goto out_path; |
| 2381 | } | 2383 | } |
| 2382 | holder = path; | ||
| 2383 | nd.flags &= ~LOOKUP_PARENT; | 2384 | nd.flags &= ~LOOKUP_PARENT; |
| 2384 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); | 2385 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); |
| 2385 | if (nd.inode->i_op->put_link) | 2386 | if (linki->i_op->put_link) |
| 2386 | nd.inode->i_op->put_link(holder.dentry, &nd, cookie); | 2387 | linki->i_op->put_link(link.dentry, &nd, cookie); |
| 2387 | path_put(&holder); | 2388 | path_put(&link); |
| 2388 | } | 2389 | } |
| 2389 | out: | 2390 | out: |
| 2390 | if (nd.root.mnt) | 2391 | if (nd.root.mnt) |
diff --git a/include/linux/nfs4_acl.h b/fs/nfsd/acl.h index c9c05a78e9bb..34e5c40af5ef 100644 --- a/include/linux/nfs4_acl.h +++ b/fs/nfsd/acl.h | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/linux/nfs4_acl.c | ||
| 3 | * | ||
| 4 | * Common NFSv4 ACL handling definitions. | 2 | * Common NFSv4 ACL handling definitions. |
| 5 | * | 3 | * |
| 6 | * Copyright (c) 2002 The Regents of the University of Michigan. | 4 | * Copyright (c) 2002 The Regents of the University of Michigan. |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index c0fcb7ab7f6d..8b31e5f8795d 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | #define MSNFS /* HACK HACK */ | ||
| 2 | /* | 1 | /* |
| 3 | * NFS exporting and validation. | 2 | * NFS exporting and validation. |
| 4 | * | 3 | * |
| @@ -1444,9 +1443,6 @@ static struct flags { | |||
| 1444 | { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, | 1443 | { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, |
| 1445 | { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, | 1444 | { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, |
| 1446 | { NFSEXP_V4ROOT, {"v4root", ""}}, | 1445 | { NFSEXP_V4ROOT, {"v4root", ""}}, |
| 1447 | #ifdef MSNFS | ||
| 1448 | { NFSEXP_MSNFS, {"msnfs", ""}}, | ||
| 1449 | #endif | ||
| 1450 | { 0, {"", ""}} | 1446 | { 0, {"", ""}} |
| 1451 | }; | 1447 | }; |
| 1452 | 1448 | ||
diff --git a/include/linux/nfsd_idmap.h b/fs/nfsd/idmap.h index d4a2ac18bd4c..2f3be1321534 100644 --- a/include/linux/nfsd_idmap.h +++ b/fs/nfsd/idmap.h | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/linux/nfsd_idmap.h | ||
| 3 | * | ||
| 4 | * Mapping of UID to name and vice versa. | 2 | * Mapping of UID to name and vice versa. |
| 5 | * | 3 | * |
| 6 | * Copyright (c) 2002, 2003 The Regents of the University of | 4 | * Copyright (c) 2002, 2003 The Regents of the University of |
| @@ -56,8 +54,8 @@ static inline void nfsd_idmap_shutdown(void) | |||
| 56 | } | 54 | } |
| 57 | #endif | 55 | #endif |
| 58 | 56 | ||
| 59 | int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); | 57 | __be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); |
| 60 | int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *); | 58 | __be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *); |
| 61 | int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *); | 59 | int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *); |
| 62 | int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *); | 60 | int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *); |
| 63 | 61 | ||
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 5b7e3021e06b..2247fc91d5e9 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
| @@ -151,10 +151,10 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, | |||
| 151 | __be32 nfserr; | 151 | __be32 nfserr; |
| 152 | u32 max_blocksize = svc_max_payload(rqstp); | 152 | u32 max_blocksize = svc_max_payload(rqstp); |
| 153 | 153 | ||
| 154 | dprintk("nfsd: READ(3) %s %lu bytes at %lu\n", | 154 | dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n", |
| 155 | SVCFH_fmt(&argp->fh), | 155 | SVCFH_fmt(&argp->fh), |
| 156 | (unsigned long) argp->count, | 156 | (unsigned long) argp->count, |
| 157 | (unsigned long) argp->offset); | 157 | (unsigned long long) argp->offset); |
| 158 | 158 | ||
| 159 | /* Obtain buffer pointer for payload. | 159 | /* Obtain buffer pointer for payload. |
| 160 | * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) | 160 | * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) |
| @@ -191,10 +191,10 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, | |||
| 191 | __be32 nfserr; | 191 | __be32 nfserr; |
| 192 | unsigned long cnt = argp->len; | 192 | unsigned long cnt = argp->len; |
| 193 | 193 | ||
| 194 | dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n", | 194 | dprintk("nfsd: WRITE(3) %s %d bytes at %Lu%s\n", |
| 195 | SVCFH_fmt(&argp->fh), | 195 | SVCFH_fmt(&argp->fh), |
| 196 | argp->len, | 196 | argp->len, |
| 197 | (unsigned long) argp->offset, | 197 | (unsigned long long) argp->offset, |
| 198 | argp->stable? " stable" : ""); | 198 | argp->stable? " stable" : ""); |
| 199 | 199 | ||
| 200 | fh_copy(&resp->fh, &argp->fh); | 200 | fh_copy(&resp->fh, &argp->fh); |
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index e48052615159..ad88f1c0a4c3 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
| 38 | #include <linux/nfs_fs.h> | 38 | #include <linux/nfs_fs.h> |
| 39 | #include <linux/nfs4_acl.h> | 39 | #include "acl.h" |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | /* mode bit translations: */ | 42 | /* mode bit translations: */ |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 21a63da305ff..3be975e18919 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -628,10 +628,8 @@ static int max_cb_time(void) | |||
| 628 | return max(nfsd4_lease/10, (time_t)1) * HZ; | 628 | return max(nfsd4_lease/10, (time_t)1) * HZ; |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | /* Reference counting, callback cleanup, etc., all look racy as heck. | ||
| 632 | * And why is cl_cb_set an atomic? */ | ||
| 633 | 631 | ||
| 634 | int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn) | 632 | static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) |
| 635 | { | 633 | { |
| 636 | struct rpc_timeout timeparms = { | 634 | struct rpc_timeout timeparms = { |
| 637 | .to_initval = max_cb_time(), | 635 | .to_initval = max_cb_time(), |
| @@ -641,6 +639,7 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn) | |||
| 641 | .net = &init_net, | 639 | .net = &init_net, |
| 642 | .address = (struct sockaddr *) &conn->cb_addr, | 640 | .address = (struct sockaddr *) &conn->cb_addr, |
| 643 | .addrsize = conn->cb_addrlen, | 641 | .addrsize = conn->cb_addrlen, |
| 642 | .saddress = (struct sockaddr *) &conn->cb_saddr, | ||
| 644 | .timeout = &timeparms, | 643 | .timeout = &timeparms, |
| 645 | .program = &cb_program, | 644 | .program = &cb_program, |
| 646 | .version = 0, | 645 | .version = 0, |
| @@ -657,6 +656,10 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn) | |||
| 657 | args.protocol = XPRT_TRANSPORT_TCP; | 656 | args.protocol = XPRT_TRANSPORT_TCP; |
| 658 | clp->cl_cb_ident = conn->cb_ident; | 657 | clp->cl_cb_ident = conn->cb_ident; |
| 659 | } else { | 658 | } else { |
| 659 | if (!conn->cb_xprt) | ||
| 660 | return -EINVAL; | ||
| 661 | clp->cl_cb_conn.cb_xprt = conn->cb_xprt; | ||
| 662 | clp->cl_cb_session = ses; | ||
| 660 | args.bc_xprt = conn->cb_xprt; | 663 | args.bc_xprt = conn->cb_xprt; |
| 661 | args.prognumber = clp->cl_cb_session->se_cb_prog; | 664 | args.prognumber = clp->cl_cb_session->se_cb_prog; |
| 662 | args.protocol = XPRT_TRANSPORT_BC_TCP; | 665 | args.protocol = XPRT_TRANSPORT_BC_TCP; |
| @@ -679,14 +682,20 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason) | |||
| 679 | (int)clp->cl_name.len, clp->cl_name.data, reason); | 682 | (int)clp->cl_name.len, clp->cl_name.data, reason); |
| 680 | } | 683 | } |
| 681 | 684 | ||
| 685 | static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason) | ||
| 686 | { | ||
| 687 | clp->cl_cb_state = NFSD4_CB_DOWN; | ||
| 688 | warn_no_callback_path(clp, reason); | ||
| 689 | } | ||
| 690 | |||
| 682 | static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) | 691 | static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) |
| 683 | { | 692 | { |
| 684 | struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null); | 693 | struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null); |
| 685 | 694 | ||
| 686 | if (task->tk_status) | 695 | if (task->tk_status) |
| 687 | warn_no_callback_path(clp, task->tk_status); | 696 | nfsd4_mark_cb_down(clp, task->tk_status); |
| 688 | else | 697 | else |
| 689 | atomic_set(&clp->cl_cb_set, 1); | 698 | clp->cl_cb_state = NFSD4_CB_UP; |
| 690 | } | 699 | } |
| 691 | 700 | ||
| 692 | static const struct rpc_call_ops nfsd4_cb_probe_ops = { | 701 | static const struct rpc_call_ops nfsd4_cb_probe_ops = { |
| @@ -709,6 +718,11 @@ int set_callback_cred(void) | |||
| 709 | 718 | ||
| 710 | static struct workqueue_struct *callback_wq; | 719 | static struct workqueue_struct *callback_wq; |
| 711 | 720 | ||
| 721 | static void run_nfsd4_cb(struct nfsd4_callback *cb) | ||
| 722 | { | ||
| 723 | queue_work(callback_wq, &cb->cb_work); | ||
| 724 | } | ||
| 725 | |||
| 712 | static void do_probe_callback(struct nfs4_client *clp) | 726 | static void do_probe_callback(struct nfs4_client *clp) |
| 713 | { | 727 | { |
| 714 | struct nfsd4_callback *cb = &clp->cl_cb_null; | 728 | struct nfsd4_callback *cb = &clp->cl_cb_null; |
| @@ -723,7 +737,7 @@ static void do_probe_callback(struct nfs4_client *clp) | |||
| 723 | 737 | ||
| 724 | cb->cb_ops = &nfsd4_cb_probe_ops; | 738 | cb->cb_ops = &nfsd4_cb_probe_ops; |
| 725 | 739 | ||
| 726 | queue_work(callback_wq, &cb->cb_work); | 740 | run_nfsd4_cb(cb); |
| 727 | } | 741 | } |
| 728 | 742 | ||
| 729 | /* | 743 | /* |
| @@ -732,14 +746,21 @@ static void do_probe_callback(struct nfs4_client *clp) | |||
| 732 | */ | 746 | */ |
| 733 | void nfsd4_probe_callback(struct nfs4_client *clp) | 747 | void nfsd4_probe_callback(struct nfs4_client *clp) |
| 734 | { | 748 | { |
| 749 | /* XXX: atomicity? Also, should we be using cl_cb_flags? */ | ||
| 750 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | ||
| 735 | set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); | 751 | set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); |
| 736 | do_probe_callback(clp); | 752 | do_probe_callback(clp); |
| 737 | } | 753 | } |
| 738 | 754 | ||
| 739 | void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn) | 755 | void nfsd4_probe_callback_sync(struct nfs4_client *clp) |
| 740 | { | 756 | { |
| 741 | BUG_ON(atomic_read(&clp->cl_cb_set)); | 757 | nfsd4_probe_callback(clp); |
| 758 | flush_workqueue(callback_wq); | ||
| 759 | } | ||
| 742 | 760 | ||
| 761 | void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn) | ||
| 762 | { | ||
| 763 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | ||
| 743 | spin_lock(&clp->cl_lock); | 764 | spin_lock(&clp->cl_lock); |
| 744 | memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn)); | 765 | memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn)); |
| 745 | spin_unlock(&clp->cl_lock); | 766 | spin_unlock(&clp->cl_lock); |
| @@ -750,24 +771,14 @@ void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn) | |||
| 750 | * If the slot is available, then mark it busy. Otherwise, set the | 771 | * If the slot is available, then mark it busy. Otherwise, set the |
| 751 | * thread for sleeping on the callback RPC wait queue. | 772 | * thread for sleeping on the callback RPC wait queue. |
| 752 | */ | 773 | */ |
| 753 | static int nfsd41_cb_setup_sequence(struct nfs4_client *clp, | 774 | static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task) |
| 754 | struct rpc_task *task) | ||
| 755 | { | 775 | { |
| 756 | u32 *ptr = (u32 *)clp->cl_cb_session->se_sessionid.data; | ||
| 757 | int status = 0; | ||
| 758 | |||
| 759 | dprintk("%s: %u:%u:%u:%u\n", __func__, | ||
| 760 | ptr[0], ptr[1], ptr[2], ptr[3]); | ||
| 761 | |||
| 762 | if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { | 776 | if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) { |
| 763 | rpc_sleep_on(&clp->cl_cb_waitq, task, NULL); | 777 | rpc_sleep_on(&clp->cl_cb_waitq, task, NULL); |
| 764 | dprintk("%s slot is busy\n", __func__); | 778 | dprintk("%s slot is busy\n", __func__); |
| 765 | status = -EAGAIN; | 779 | return false; |
| 766 | goto out; | ||
| 767 | } | 780 | } |
| 768 | out: | 781 | return true; |
| 769 | dprintk("%s status=%d\n", __func__, status); | ||
| 770 | return status; | ||
| 771 | } | 782 | } |
| 772 | 783 | ||
| 773 | /* | 784 | /* |
| @@ -780,20 +791,19 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) | |||
| 780 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); | 791 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); |
| 781 | struct nfs4_client *clp = dp->dl_client; | 792 | struct nfs4_client *clp = dp->dl_client; |
| 782 | u32 minorversion = clp->cl_minorversion; | 793 | u32 minorversion = clp->cl_minorversion; |
| 783 | int status = 0; | ||
| 784 | 794 | ||
| 785 | cb->cb_minorversion = minorversion; | 795 | cb->cb_minorversion = minorversion; |
| 786 | if (minorversion) { | 796 | if (minorversion) { |
| 787 | status = nfsd41_cb_setup_sequence(clp, task); | 797 | if (!nfsd41_cb_get_slot(clp, task)) |
| 788 | if (status) { | ||
| 789 | if (status != -EAGAIN) { | ||
| 790 | /* terminate rpc task */ | ||
| 791 | task->tk_status = status; | ||
| 792 | task->tk_action = NULL; | ||
| 793 | } | ||
| 794 | return; | 798 | return; |
| 795 | } | ||
| 796 | } | 799 | } |
| 800 | spin_lock(&clp->cl_lock); | ||
| 801 | if (list_empty(&cb->cb_per_client)) { | ||
| 802 | /* This is the first call, not a restart */ | ||
| 803 | cb->cb_done = false; | ||
| 804 | list_add(&cb->cb_per_client, &clp->cl_callbacks); | ||
| 805 | } | ||
| 806 | spin_unlock(&clp->cl_lock); | ||
| 797 | rpc_call_start(task); | 807 | rpc_call_start(task); |
| 798 | } | 808 | } |
| 799 | 809 | ||
| @@ -829,15 +839,18 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) | |||
| 829 | 839 | ||
| 830 | nfsd4_cb_done(task, calldata); | 840 | nfsd4_cb_done(task, calldata); |
| 831 | 841 | ||
| 832 | if (current_rpc_client == NULL) { | 842 | if (current_rpc_client != task->tk_client) { |
| 833 | /* We're shutting down; give up. */ | 843 | /* We're shutting down or changing cl_cb_client; leave |
| 834 | /* XXX: err, or is it ok just to fall through | 844 | * it to nfsd4_process_cb_update to restart the call if |
| 835 | * and rpc_restart_call? */ | 845 | * necessary. */ |
| 836 | return; | 846 | return; |
| 837 | } | 847 | } |
| 838 | 848 | ||
| 849 | if (cb->cb_done) | ||
| 850 | return; | ||
| 839 | switch (task->tk_status) { | 851 | switch (task->tk_status) { |
| 840 | case 0: | 852 | case 0: |
| 853 | cb->cb_done = true; | ||
| 841 | return; | 854 | return; |
| 842 | case -EBADHANDLE: | 855 | case -EBADHANDLE: |
| 843 | case -NFS4ERR_BAD_STATEID: | 856 | case -NFS4ERR_BAD_STATEID: |
| @@ -846,32 +859,30 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) | |||
| 846 | break; | 859 | break; |
| 847 | default: | 860 | default: |
| 848 | /* Network partition? */ | 861 | /* Network partition? */ |
| 849 | atomic_set(&clp->cl_cb_set, 0); | 862 | nfsd4_mark_cb_down(clp, task->tk_status); |
| 850 | warn_no_callback_path(clp, task->tk_status); | ||
| 851 | if (current_rpc_client != task->tk_client) { | ||
| 852 | /* queue a callback on the new connection: */ | ||
| 853 | atomic_inc(&dp->dl_count); | ||
| 854 | nfsd4_cb_recall(dp); | ||
| 855 | return; | ||
| 856 | } | ||
| 857 | } | 863 | } |
| 858 | if (dp->dl_retries--) { | 864 | if (dp->dl_retries--) { |
| 859 | rpc_delay(task, 2*HZ); | 865 | rpc_delay(task, 2*HZ); |
| 860 | task->tk_status = 0; | 866 | task->tk_status = 0; |
| 861 | rpc_restart_call_prepare(task); | 867 | rpc_restart_call_prepare(task); |
| 862 | return; | 868 | return; |
| 863 | } else { | ||
| 864 | atomic_set(&clp->cl_cb_set, 0); | ||
| 865 | warn_no_callback_path(clp, task->tk_status); | ||
| 866 | } | 869 | } |
| 870 | nfsd4_mark_cb_down(clp, task->tk_status); | ||
| 871 | cb->cb_done = true; | ||
| 867 | } | 872 | } |
| 868 | 873 | ||
| 869 | static void nfsd4_cb_recall_release(void *calldata) | 874 | static void nfsd4_cb_recall_release(void *calldata) |
| 870 | { | 875 | { |
| 871 | struct nfsd4_callback *cb = calldata; | 876 | struct nfsd4_callback *cb = calldata; |
| 877 | struct nfs4_client *clp = cb->cb_clp; | ||
| 872 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); | 878 | struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); |
| 873 | 879 | ||
| 874 | nfs4_put_delegation(dp); | 880 | if (cb->cb_done) { |
| 881 | spin_lock(&clp->cl_lock); | ||
| 882 | list_del(&cb->cb_per_client); | ||
| 883 | spin_unlock(&clp->cl_lock); | ||
| 884 | nfs4_put_delegation(dp); | ||
| 885 | } | ||
| 875 | } | 886 | } |
| 876 | 887 | ||
| 877 | static const struct rpc_call_ops nfsd4_cb_recall_ops = { | 888 | static const struct rpc_call_ops nfsd4_cb_recall_ops = { |
| @@ -906,16 +917,33 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp) | |||
| 906 | flush_workqueue(callback_wq); | 917 | flush_workqueue(callback_wq); |
| 907 | } | 918 | } |
| 908 | 919 | ||
| 909 | void nfsd4_release_cb(struct nfsd4_callback *cb) | 920 | static void nfsd4_release_cb(struct nfsd4_callback *cb) |
| 910 | { | 921 | { |
| 911 | if (cb->cb_ops->rpc_release) | 922 | if (cb->cb_ops->rpc_release) |
| 912 | cb->cb_ops->rpc_release(cb); | 923 | cb->cb_ops->rpc_release(cb); |
| 913 | } | 924 | } |
| 914 | 925 | ||
| 915 | void nfsd4_process_cb_update(struct nfsd4_callback *cb) | 926 | /* requires cl_lock: */ |
| 927 | static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp) | ||
| 928 | { | ||
| 929 | struct nfsd4_session *s; | ||
| 930 | struct nfsd4_conn *c; | ||
| 931 | |||
| 932 | list_for_each_entry(s, &clp->cl_sessions, se_perclnt) { | ||
| 933 | list_for_each_entry(c, &s->se_conns, cn_persession) { | ||
| 934 | if (c->cn_flags & NFS4_CDFC4_BACK) | ||
| 935 | return c; | ||
| 936 | } | ||
| 937 | } | ||
| 938 | return NULL; | ||
| 939 | } | ||
| 940 | |||
| 941 | static void nfsd4_process_cb_update(struct nfsd4_callback *cb) | ||
| 916 | { | 942 | { |
| 917 | struct nfs4_cb_conn conn; | 943 | struct nfs4_cb_conn conn; |
| 918 | struct nfs4_client *clp = cb->cb_clp; | 944 | struct nfs4_client *clp = cb->cb_clp; |
| 945 | struct nfsd4_session *ses = NULL; | ||
| 946 | struct nfsd4_conn *c; | ||
| 919 | int err; | 947 | int err; |
| 920 | 948 | ||
| 921 | /* | 949 | /* |
| @@ -926,6 +954,10 @@ void nfsd4_process_cb_update(struct nfsd4_callback *cb) | |||
| 926 | rpc_shutdown_client(clp->cl_cb_client); | 954 | rpc_shutdown_client(clp->cl_cb_client); |
| 927 | clp->cl_cb_client = NULL; | 955 | clp->cl_cb_client = NULL; |
| 928 | } | 956 | } |
| 957 | if (clp->cl_cb_conn.cb_xprt) { | ||
| 958 | svc_xprt_put(clp->cl_cb_conn.cb_xprt); | ||
| 959 | clp->cl_cb_conn.cb_xprt = NULL; | ||
| 960 | } | ||
| 929 | if (test_bit(NFSD4_CLIENT_KILL, &clp->cl_cb_flags)) | 961 | if (test_bit(NFSD4_CLIENT_KILL, &clp->cl_cb_flags)) |
| 930 | return; | 962 | return; |
| 931 | spin_lock(&clp->cl_lock); | 963 | spin_lock(&clp->cl_lock); |
| @@ -936,11 +968,22 @@ void nfsd4_process_cb_update(struct nfsd4_callback *cb) | |||
| 936 | BUG_ON(!clp->cl_cb_flags); | 968 | BUG_ON(!clp->cl_cb_flags); |
| 937 | clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); | 969 | clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); |
| 938 | memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn)); | 970 | memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn)); |
| 971 | c = __nfsd4_find_backchannel(clp); | ||
| 972 | if (c) { | ||
| 973 | svc_xprt_get(c->cn_xprt); | ||
| 974 | conn.cb_xprt = c->cn_xprt; | ||
| 975 | ses = c->cn_session; | ||
| 976 | } | ||
| 939 | spin_unlock(&clp->cl_lock); | 977 | spin_unlock(&clp->cl_lock); |
| 940 | 978 | ||
| 941 | err = setup_callback_client(clp, &conn); | 979 | err = setup_callback_client(clp, &conn, ses); |
| 942 | if (err) | 980 | if (err) { |
| 943 | warn_no_callback_path(clp, err); | 981 | warn_no_callback_path(clp, err); |
| 982 | return; | ||
| 983 | } | ||
| 984 | /* Yay, the callback channel's back! Restart any callbacks: */ | ||
| 985 | list_for_each_entry(cb, &clp->cl_callbacks, cb_per_client) | ||
| 986 | run_nfsd4_cb(cb); | ||
| 944 | } | 987 | } |
| 945 | 988 | ||
| 946 | void nfsd4_do_callback_rpc(struct work_struct *w) | 989 | void nfsd4_do_callback_rpc(struct work_struct *w) |
| @@ -965,10 +1008,11 @@ void nfsd4_do_callback_rpc(struct work_struct *w) | |||
| 965 | void nfsd4_cb_recall(struct nfs4_delegation *dp) | 1008 | void nfsd4_cb_recall(struct nfs4_delegation *dp) |
| 966 | { | 1009 | { |
| 967 | struct nfsd4_callback *cb = &dp->dl_recall; | 1010 | struct nfsd4_callback *cb = &dp->dl_recall; |
| 1011 | struct nfs4_client *clp = dp->dl_client; | ||
| 968 | 1012 | ||
| 969 | dp->dl_retries = 1; | 1013 | dp->dl_retries = 1; |
| 970 | cb->cb_op = dp; | 1014 | cb->cb_op = dp; |
| 971 | cb->cb_clp = dp->dl_client; | 1015 | cb->cb_clp = clp; |
| 972 | cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL]; | 1016 | cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL]; |
| 973 | cb->cb_msg.rpc_argp = cb; | 1017 | cb->cb_msg.rpc_argp = cb; |
| 974 | cb->cb_msg.rpc_resp = cb; | 1018 | cb->cb_msg.rpc_resp = cb; |
| @@ -977,5 +1021,8 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp) | |||
| 977 | cb->cb_ops = &nfsd4_cb_recall_ops; | 1021 | cb->cb_ops = &nfsd4_cb_recall_ops; |
| 978 | dp->dl_retries = 1; | 1022 | dp->dl_retries = 1; |
| 979 | 1023 | ||
| 980 | queue_work(callback_wq, &dp->dl_recall.cb_work); | 1024 | INIT_LIST_HEAD(&cb->cb_per_client); |
| 1025 | cb->cb_done = true; | ||
| 1026 | |||
| 1027 | run_nfsd4_cb(&dp->dl_recall); | ||
| 981 | } | 1028 | } |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index f0695e815f0e..6d2c397d458b 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
| @@ -33,10 +33,11 @@ | |||
| 33 | */ | 33 | */ |
| 34 | 34 | ||
| 35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
| 36 | #include <linux/nfsd_idmap.h> | ||
| 37 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
| 38 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
| 39 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include "idmap.h" | ||
| 40 | #include "nfsd.h" | ||
| 40 | 41 | ||
| 41 | /* | 42 | /* |
| 42 | * Cache entry | 43 | * Cache entry |
| @@ -514,7 +515,7 @@ rqst_authname(struct svc_rqst *rqstp) | |||
| 514 | return clp->name; | 515 | return clp->name; |
| 515 | } | 516 | } |
| 516 | 517 | ||
| 517 | static int | 518 | static __be32 |
| 518 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, | 519 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, |
| 519 | uid_t *id) | 520 | uid_t *id) |
| 520 | { | 521 | { |
| @@ -524,15 +525,15 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen | |||
| 524 | int ret; | 525 | int ret; |
| 525 | 526 | ||
| 526 | if (namelen + 1 > sizeof(key.name)) | 527 | if (namelen + 1 > sizeof(key.name)) |
| 527 | return -EINVAL; | 528 | return nfserr_badowner; |
| 528 | memcpy(key.name, name, namelen); | 529 | memcpy(key.name, name, namelen); |
| 529 | key.name[namelen] = '\0'; | 530 | key.name[namelen] = '\0'; |
| 530 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); | 531 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); |
| 531 | ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); | 532 | ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); |
| 532 | if (ret == -ENOENT) | 533 | if (ret == -ENOENT) |
| 533 | ret = -ESRCH; /* nfserr_badname */ | 534 | return nfserr_badowner; |
| 534 | if (ret) | 535 | if (ret) |
| 535 | return ret; | 536 | return nfserrno(ret); |
| 536 | *id = item->id; | 537 | *id = item->id; |
| 537 | cache_put(&item->h, &nametoid_cache); | 538 | cache_put(&item->h, &nametoid_cache); |
| 538 | return 0; | 539 | return 0; |
| @@ -560,14 +561,14 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
| 560 | return ret; | 561 | return ret; |
| 561 | } | 562 | } |
| 562 | 563 | ||
| 563 | int | 564 | __be32 |
| 564 | nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, | 565 | nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, |
| 565 | __u32 *id) | 566 | __u32 *id) |
| 566 | { | 567 | { |
| 567 | return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); | 568 | return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); |
| 568 | } | 569 | } |
| 569 | 570 | ||
| 570 | int | 571 | __be32 |
| 571 | nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, | 572 | nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, |
| 572 | __u32 *id) | 573 | __u32 *id) |
| 573 | { | 574 | { |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0cdfd022bb7b..db52546143d1 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
| @@ -604,9 +604,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 604 | return status; | 604 | return status; |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | static __be32 | 607 | static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) |
| 608 | nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
| 609 | void *arg) | ||
| 610 | { | 608 | { |
| 611 | struct svc_fh tmp_fh; | 609 | struct svc_fh tmp_fh; |
| 612 | __be32 ret; | 610 | __be32 ret; |
| @@ -615,13 +613,19 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 615 | ret = exp_pseudoroot(rqstp, &tmp_fh); | 613 | ret = exp_pseudoroot(rqstp, &tmp_fh); |
| 616 | if (ret) | 614 | if (ret) |
| 617 | return ret; | 615 | return ret; |
| 618 | if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { | 616 | if (tmp_fh.fh_dentry == fh->fh_dentry) { |
| 619 | fh_put(&tmp_fh); | 617 | fh_put(&tmp_fh); |
| 620 | return nfserr_noent; | 618 | return nfserr_noent; |
| 621 | } | 619 | } |
| 622 | fh_put(&tmp_fh); | 620 | fh_put(&tmp_fh); |
| 623 | return nfsd_lookup(rqstp, &cstate->current_fh, | 621 | return nfsd_lookup(rqstp, fh, "..", 2, fh); |
| 624 | "..", 2, &cstate->current_fh); | 622 | } |
| 623 | |||
| 624 | static __be32 | ||
| 625 | nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
| 626 | void *arg) | ||
| 627 | { | ||
| 628 | return nfsd4_do_lookupp(rqstp, &cstate->current_fh); | ||
| 625 | } | 629 | } |
| 626 | 630 | ||
| 627 | static __be32 | 631 | static __be32 |
| @@ -769,10 +773,36 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 769 | } else | 773 | } else |
| 770 | secinfo->si_exp = exp; | 774 | secinfo->si_exp = exp; |
| 771 | dput(dentry); | 775 | dput(dentry); |
| 776 | if (cstate->minorversion) | ||
| 777 | /* See rfc 5661 section 2.6.3.1.1.8 */ | ||
| 778 | fh_put(&cstate->current_fh); | ||
| 772 | return err; | 779 | return err; |
| 773 | } | 780 | } |
| 774 | 781 | ||
| 775 | static __be32 | 782 | static __be32 |
| 783 | nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
| 784 | struct nfsd4_secinfo_no_name *sin) | ||
| 785 | { | ||
| 786 | __be32 err; | ||
| 787 | |||
| 788 | switch (sin->sin_style) { | ||
| 789 | case NFS4_SECINFO_STYLE4_CURRENT_FH: | ||
| 790 | break; | ||
| 791 | case NFS4_SECINFO_STYLE4_PARENT: | ||
| 792 | err = nfsd4_do_lookupp(rqstp, &cstate->current_fh); | ||
| 793 | if (err) | ||
| 794 | return err; | ||
| 795 | break; | ||
| 796 | default: | ||
| 797 | return nfserr_inval; | ||
| 798 | } | ||
| 799 | exp_get(cstate->current_fh.fh_export); | ||
| 800 | sin->sin_exp = cstate->current_fh.fh_export; | ||
| 801 | fh_put(&cstate->current_fh); | ||
| 802 | return nfs_ok; | ||
| 803 | } | ||
| 804 | |||
| 805 | static __be32 | ||
| 776 | nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 806 | nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
| 777 | struct nfsd4_setattr *setattr) | 807 | struct nfsd4_setattr *setattr) |
| 778 | { | 808 | { |
| @@ -974,8 +1004,8 @@ static const char *nfsd4_op_name(unsigned opnum); | |||
| 974 | * Also note, enforced elsewhere: | 1004 | * Also note, enforced elsewhere: |
| 975 | * - SEQUENCE other than as first op results in | 1005 | * - SEQUENCE other than as first op results in |
| 976 | * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().) | 1006 | * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().) |
| 977 | * - BIND_CONN_TO_SESSION must be the only op in its compound | 1007 | * - BIND_CONN_TO_SESSION must be the only op in its compound. |
| 978 | * (Will be enforced in nfsd4_bind_conn_to_session().) | 1008 | * (Enforced in nfsd4_bind_conn_to_session().) |
| 979 | * - DESTROY_SESSION must be the final operation in a compound, if | 1009 | * - DESTROY_SESSION must be the final operation in a compound, if |
| 980 | * sessionid's in SEQUENCE and DESTROY_SESSION are the same. | 1010 | * sessionid's in SEQUENCE and DESTROY_SESSION are the same. |
| 981 | * (Enforced in nfsd4_destroy_session().) | 1011 | * (Enforced in nfsd4_destroy_session().) |
| @@ -1126,10 +1156,6 @@ encode_op: | |||
| 1126 | 1156 | ||
| 1127 | nfsd4_increment_op_stats(op->opnum); | 1157 | nfsd4_increment_op_stats(op->opnum); |
| 1128 | } | 1158 | } |
| 1129 | if (!rqstp->rq_usedeferral && status == nfserr_dropit) { | ||
| 1130 | dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__); | ||
| 1131 | status = nfserr_jukebox; | ||
| 1132 | } | ||
| 1133 | 1159 | ||
| 1134 | resp->cstate.status = status; | 1160 | resp->cstate.status = status; |
| 1135 | fh_put(&resp->cstate.current_fh); | 1161 | fh_put(&resp->cstate.current_fh); |
| @@ -1300,6 +1326,11 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
| 1300 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, | 1326 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, |
| 1301 | .op_name = "OP_EXCHANGE_ID", | 1327 | .op_name = "OP_EXCHANGE_ID", |
| 1302 | }, | 1328 | }, |
| 1329 | [OP_BIND_CONN_TO_SESSION] = { | ||
| 1330 | .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, | ||
| 1331 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, | ||
| 1332 | .op_name = "OP_BIND_CONN_TO_SESSION", | ||
| 1333 | }, | ||
| 1303 | [OP_CREATE_SESSION] = { | 1334 | [OP_CREATE_SESSION] = { |
| 1304 | .op_func = (nfsd4op_func)nfsd4_create_session, | 1335 | .op_func = (nfsd4op_func)nfsd4_create_session, |
| 1305 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, | 1336 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, |
| @@ -1320,6 +1351,10 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
| 1320 | .op_flags = ALLOWED_WITHOUT_FH, | 1351 | .op_flags = ALLOWED_WITHOUT_FH, |
| 1321 | .op_name = "OP_RECLAIM_COMPLETE", | 1352 | .op_name = "OP_RECLAIM_COMPLETE", |
| 1322 | }, | 1353 | }, |
| 1354 | [OP_SECINFO_NO_NAME] = { | ||
| 1355 | .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, | ||
| 1356 | .op_name = "OP_SECINFO_NO_NAME", | ||
| 1357 | }, | ||
| 1323 | }; | 1358 | }; |
| 1324 | 1359 | ||
| 1325 | static const char *nfsd4_op_name(unsigned opnum) | 1360 | static const char *nfsd4_op_name(unsigned opnum) |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 7e26caab2a26..ffb59ef6f82f 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
| @@ -302,7 +302,6 @@ purge_old(struct dentry *parent, struct dentry *child) | |||
| 302 | { | 302 | { |
| 303 | int status; | 303 | int status; |
| 304 | 304 | ||
| 305 | /* note: we currently use this path only for minorversion 0 */ | ||
| 306 | if (nfs4_has_reclaimed_state(child->d_name.name, false)) | 305 | if (nfs4_has_reclaimed_state(child->d_name.name, false)) |
| 307 | return 0; | 306 | return 0; |
| 308 | 307 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fbd18c3074bb..d98d0213285d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -230,7 +230,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f | |||
| 230 | dp->dl_client = clp; | 230 | dp->dl_client = clp; |
| 231 | get_nfs4_file(fp); | 231 | get_nfs4_file(fp); |
| 232 | dp->dl_file = fp; | 232 | dp->dl_file = fp; |
| 233 | nfs4_file_get_access(fp, O_RDONLY); | 233 | dp->dl_vfs_file = find_readable_file(fp); |
| 234 | get_file(dp->dl_vfs_file); | ||
| 234 | dp->dl_flock = NULL; | 235 | dp->dl_flock = NULL; |
| 235 | dp->dl_type = type; | 236 | dp->dl_type = type; |
| 236 | dp->dl_stateid.si_boot = boot_time; | 237 | dp->dl_stateid.si_boot = boot_time; |
| @@ -252,6 +253,7 @@ nfs4_put_delegation(struct nfs4_delegation *dp) | |||
| 252 | if (atomic_dec_and_test(&dp->dl_count)) { | 253 | if (atomic_dec_and_test(&dp->dl_count)) { |
| 253 | dprintk("NFSD: freeing dp %p\n",dp); | 254 | dprintk("NFSD: freeing dp %p\n",dp); |
| 254 | put_nfs4_file(dp->dl_file); | 255 | put_nfs4_file(dp->dl_file); |
| 256 | fput(dp->dl_vfs_file); | ||
| 255 | kmem_cache_free(deleg_slab, dp); | 257 | kmem_cache_free(deleg_slab, dp); |
| 256 | num_delegations--; | 258 | num_delegations--; |
| 257 | } | 259 | } |
| @@ -265,12 +267,10 @@ nfs4_put_delegation(struct nfs4_delegation *dp) | |||
| 265 | static void | 267 | static void |
| 266 | nfs4_close_delegation(struct nfs4_delegation *dp) | 268 | nfs4_close_delegation(struct nfs4_delegation *dp) |
| 267 | { | 269 | { |
| 268 | struct file *filp = find_readable_file(dp->dl_file); | ||
| 269 | |||
| 270 | dprintk("NFSD: close_delegation dp %p\n",dp); | 270 | dprintk("NFSD: close_delegation dp %p\n",dp); |
| 271 | /* XXX: do we even need this check?: */ | ||
| 271 | if (dp->dl_flock) | 272 | if (dp->dl_flock) |
| 272 | vfs_setlease(filp, F_UNLCK, &dp->dl_flock); | 273 | vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock); |
| 273 | nfs4_file_put_access(dp->dl_file, O_RDONLY); | ||
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | /* Called under the state lock. */ | 276 | /* Called under the state lock. */ |
| @@ -642,6 +642,7 @@ static void nfsd4_conn_lost(struct svc_xpt_user *u) | |||
| 642 | free_conn(c); | 642 | free_conn(c); |
| 643 | } | 643 | } |
| 644 | spin_unlock(&clp->cl_lock); | 644 | spin_unlock(&clp->cl_lock); |
| 645 | nfsd4_probe_callback(clp); | ||
| 645 | } | 646 | } |
| 646 | 647 | ||
| 647 | static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags) | 648 | static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags) |
| @@ -679,15 +680,12 @@ static int nfsd4_register_conn(struct nfsd4_conn *conn) | |||
| 679 | return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); | 680 | return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); |
| 680 | } | 681 | } |
| 681 | 682 | ||
| 682 | static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) | 683 | static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir) |
| 683 | { | 684 | { |
| 684 | struct nfsd4_conn *conn; | 685 | struct nfsd4_conn *conn; |
| 685 | u32 flags = NFS4_CDFC4_FORE; | ||
| 686 | int ret; | 686 | int ret; |
| 687 | 687 | ||
| 688 | if (ses->se_flags & SESSION4_BACK_CHAN) | 688 | conn = alloc_conn(rqstp, dir); |
| 689 | flags |= NFS4_CDFC4_BACK; | ||
| 690 | conn = alloc_conn(rqstp, flags); | ||
| 691 | if (!conn) | 689 | if (!conn) |
| 692 | return nfserr_jukebox; | 690 | return nfserr_jukebox; |
| 693 | nfsd4_hash_conn(conn, ses); | 691 | nfsd4_hash_conn(conn, ses); |
| @@ -698,6 +696,17 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) | |||
| 698 | return nfs_ok; | 696 | return nfs_ok; |
| 699 | } | 697 | } |
| 700 | 698 | ||
| 699 | static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses) | ||
| 700 | { | ||
| 701 | u32 dir = NFS4_CDFC4_FORE; | ||
| 702 | |||
| 703 | if (ses->se_flags & SESSION4_BACK_CHAN) | ||
| 704 | dir |= NFS4_CDFC4_BACK; | ||
| 705 | |||
| 706 | return nfsd4_new_conn(rqstp, ses, dir); | ||
| 707 | } | ||
| 708 | |||
| 709 | /* must be called under client_lock */ | ||
| 701 | static void nfsd4_del_conns(struct nfsd4_session *s) | 710 | static void nfsd4_del_conns(struct nfsd4_session *s) |
| 702 | { | 711 | { |
| 703 | struct nfs4_client *clp = s->se_client; | 712 | struct nfs4_client *clp = s->se_client; |
| @@ -749,6 +758,8 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n | |||
| 749 | */ | 758 | */ |
| 750 | slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached); | 759 | slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached); |
| 751 | numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs); | 760 | numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs); |
| 761 | if (numslots < 1) | ||
| 762 | return NULL; | ||
| 752 | 763 | ||
| 753 | new = alloc_session(slotsize, numslots); | 764 | new = alloc_session(slotsize, numslots); |
| 754 | if (!new) { | 765 | if (!new) { |
| @@ -769,25 +780,30 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n | |||
| 769 | idx = hash_sessionid(&new->se_sessionid); | 780 | idx = hash_sessionid(&new->se_sessionid); |
| 770 | spin_lock(&client_lock); | 781 | spin_lock(&client_lock); |
| 771 | list_add(&new->se_hash, &sessionid_hashtbl[idx]); | 782 | list_add(&new->se_hash, &sessionid_hashtbl[idx]); |
| 783 | spin_lock(&clp->cl_lock); | ||
| 772 | list_add(&new->se_perclnt, &clp->cl_sessions); | 784 | list_add(&new->se_perclnt, &clp->cl_sessions); |
| 785 | spin_unlock(&clp->cl_lock); | ||
| 773 | spin_unlock(&client_lock); | 786 | spin_unlock(&client_lock); |
| 774 | 787 | ||
| 775 | status = nfsd4_new_conn(rqstp, new); | 788 | status = nfsd4_new_conn_from_crses(rqstp, new); |
| 776 | /* whoops: benny points out, status is ignored! (err, or bogus) */ | 789 | /* whoops: benny points out, status is ignored! (err, or bogus) */ |
| 777 | if (status) { | 790 | if (status) { |
| 778 | free_session(&new->se_ref); | 791 | free_session(&new->se_ref); |
| 779 | return NULL; | 792 | return NULL; |
| 780 | } | 793 | } |
| 781 | if (!clp->cl_cb_session && (cses->flags & SESSION4_BACK_CHAN)) { | 794 | if (cses->flags & SESSION4_BACK_CHAN) { |
| 782 | struct sockaddr *sa = svc_addr(rqstp); | 795 | struct sockaddr *sa = svc_addr(rqstp); |
| 783 | 796 | /* | |
| 784 | clp->cl_cb_session = new; | 797 | * This is a little silly; with sessions there's no real |
| 785 | clp->cl_cb_conn.cb_xprt = rqstp->rq_xprt; | 798 | * use for the callback address. Use the peer address |
| 786 | svc_xprt_get(rqstp->rq_xprt); | 799 | * as a reasonable default for now, but consider fixing |
| 800 | * the rpc client not to require an address in the | ||
| 801 | * future: | ||
| 802 | */ | ||
| 787 | rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa); | 803 | rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa); |
| 788 | clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa); | 804 | clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa); |
| 789 | nfsd4_probe_callback(clp); | ||
| 790 | } | 805 | } |
| 806 | nfsd4_probe_callback(clp); | ||
| 791 | return new; | 807 | return new; |
| 792 | } | 808 | } |
| 793 | 809 | ||
| @@ -817,7 +833,9 @@ static void | |||
| 817 | unhash_session(struct nfsd4_session *ses) | 833 | unhash_session(struct nfsd4_session *ses) |
| 818 | { | 834 | { |
| 819 | list_del(&ses->se_hash); | 835 | list_del(&ses->se_hash); |
| 836 | spin_lock(&ses->se_client->cl_lock); | ||
| 820 | list_del(&ses->se_perclnt); | 837 | list_del(&ses->se_perclnt); |
| 838 | spin_unlock(&ses->se_client->cl_lock); | ||
| 821 | } | 839 | } |
| 822 | 840 | ||
| 823 | /* must be called under the client_lock */ | 841 | /* must be called under the client_lock */ |
| @@ -923,8 +941,10 @@ unhash_client_locked(struct nfs4_client *clp) | |||
| 923 | 941 | ||
| 924 | mark_client_expired(clp); | 942 | mark_client_expired(clp); |
| 925 | list_del(&clp->cl_lru); | 943 | list_del(&clp->cl_lru); |
| 944 | spin_lock(&clp->cl_lock); | ||
| 926 | list_for_each_entry(ses, &clp->cl_sessions, se_perclnt) | 945 | list_for_each_entry(ses, &clp->cl_sessions, se_perclnt) |
| 927 | list_del_init(&ses->se_hash); | 946 | list_del_init(&ses->se_hash); |
| 947 | spin_unlock(&clp->cl_lock); | ||
| 928 | } | 948 | } |
| 929 | 949 | ||
| 930 | static void | 950 | static void |
| @@ -1051,12 +1071,13 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, | |||
| 1051 | 1071 | ||
| 1052 | memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); | 1072 | memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); |
| 1053 | atomic_set(&clp->cl_refcount, 0); | 1073 | atomic_set(&clp->cl_refcount, 0); |
| 1054 | atomic_set(&clp->cl_cb_set, 0); | 1074 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; |
| 1055 | INIT_LIST_HEAD(&clp->cl_idhash); | 1075 | INIT_LIST_HEAD(&clp->cl_idhash); |
| 1056 | INIT_LIST_HEAD(&clp->cl_strhash); | 1076 | INIT_LIST_HEAD(&clp->cl_strhash); |
| 1057 | INIT_LIST_HEAD(&clp->cl_openowners); | 1077 | INIT_LIST_HEAD(&clp->cl_openowners); |
| 1058 | INIT_LIST_HEAD(&clp->cl_delegations); | 1078 | INIT_LIST_HEAD(&clp->cl_delegations); |
| 1059 | INIT_LIST_HEAD(&clp->cl_lru); | 1079 | INIT_LIST_HEAD(&clp->cl_lru); |
| 1080 | INIT_LIST_HEAD(&clp->cl_callbacks); | ||
| 1060 | spin_lock_init(&clp->cl_lock); | 1081 | spin_lock_init(&clp->cl_lock); |
| 1061 | INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); | 1082 | INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc); |
| 1062 | clp->cl_time = get_seconds(); | 1083 | clp->cl_time = get_seconds(); |
| @@ -1132,54 +1153,55 @@ find_unconfirmed_client(clientid_t *clid) | |||
| 1132 | return NULL; | 1153 | return NULL; |
| 1133 | } | 1154 | } |
| 1134 | 1155 | ||
| 1135 | /* | 1156 | static bool clp_used_exchangeid(struct nfs4_client *clp) |
| 1136 | * Return 1 iff clp's clientid establishment method matches the use_exchange_id | ||
| 1137 | * parameter. Matching is based on the fact the at least one of the | ||
| 1138 | * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1 | ||
| 1139 | * | ||
| 1140 | * FIXME: we need to unify the clientid namespaces for nfsv4.x | ||
| 1141 | * and correctly deal with client upgrade/downgrade in EXCHANGE_ID | ||
| 1142 | * and SET_CLIENTID{,_CONFIRM} | ||
| 1143 | */ | ||
| 1144 | static inline int | ||
| 1145 | match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id) | ||
| 1146 | { | 1157 | { |
| 1147 | bool has_exchange_flags = (clp->cl_exchange_flags != 0); | 1158 | return clp->cl_exchange_flags != 0; |
| 1148 | return use_exchange_id == has_exchange_flags; | 1159 | } |
| 1149 | } | ||
| 1150 | 1160 | ||
| 1151 | static struct nfs4_client * | 1161 | static struct nfs4_client * |
| 1152 | find_confirmed_client_by_str(const char *dname, unsigned int hashval, | 1162 | find_confirmed_client_by_str(const char *dname, unsigned int hashval) |
| 1153 | bool use_exchange_id) | ||
| 1154 | { | 1163 | { |
| 1155 | struct nfs4_client *clp; | 1164 | struct nfs4_client *clp; |
| 1156 | 1165 | ||
| 1157 | list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { | 1166 | list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { |
| 1158 | if (same_name(clp->cl_recdir, dname) && | 1167 | if (same_name(clp->cl_recdir, dname)) |
| 1159 | match_clientid_establishment(clp, use_exchange_id)) | ||
| 1160 | return clp; | 1168 | return clp; |
| 1161 | } | 1169 | } |
| 1162 | return NULL; | 1170 | return NULL; |
| 1163 | } | 1171 | } |
| 1164 | 1172 | ||
| 1165 | static struct nfs4_client * | 1173 | static struct nfs4_client * |
| 1166 | find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, | 1174 | find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) |
| 1167 | bool use_exchange_id) | ||
| 1168 | { | 1175 | { |
| 1169 | struct nfs4_client *clp; | 1176 | struct nfs4_client *clp; |
| 1170 | 1177 | ||
| 1171 | list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { | 1178 | list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { |
| 1172 | if (same_name(clp->cl_recdir, dname) && | 1179 | if (same_name(clp->cl_recdir, dname)) |
| 1173 | match_clientid_establishment(clp, use_exchange_id)) | ||
| 1174 | return clp; | 1180 | return clp; |
| 1175 | } | 1181 | } |
| 1176 | return NULL; | 1182 | return NULL; |
| 1177 | } | 1183 | } |
| 1178 | 1184 | ||
| 1185 | static void rpc_svcaddr2sockaddr(struct sockaddr *sa, unsigned short family, union svc_addr_u *svcaddr) | ||
| 1186 | { | ||
| 1187 | switch (family) { | ||
| 1188 | case AF_INET: | ||
| 1189 | ((struct sockaddr_in *)sa)->sin_family = AF_INET; | ||
| 1190 | ((struct sockaddr_in *)sa)->sin_addr = svcaddr->addr; | ||
| 1191 | return; | ||
| 1192 | case AF_INET6: | ||
| 1193 | ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6; | ||
| 1194 | ((struct sockaddr_in6 *)sa)->sin6_addr = svcaddr->addr6; | ||
| 1195 | return; | ||
| 1196 | } | ||
| 1197 | } | ||
| 1198 | |||
| 1179 | static void | 1199 | static void |
| 1180 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid) | 1200 | gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp) |
| 1181 | { | 1201 | { |
| 1182 | struct nfs4_cb_conn *conn = &clp->cl_cb_conn; | 1202 | struct nfs4_cb_conn *conn = &clp->cl_cb_conn; |
| 1203 | struct sockaddr *sa = svc_addr(rqstp); | ||
| 1204 | u32 scopeid = rpc_get_scope_id(sa); | ||
| 1183 | unsigned short expected_family; | 1205 | unsigned short expected_family; |
| 1184 | 1206 | ||
| 1185 | /* Currently, we only support tcp and tcp6 for the callback channel */ | 1207 | /* Currently, we only support tcp and tcp6 for the callback channel */ |
| @@ -1205,6 +1227,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid) | |||
| 1205 | 1227 | ||
| 1206 | conn->cb_prog = se->se_callback_prog; | 1228 | conn->cb_prog = se->se_callback_prog; |
| 1207 | conn->cb_ident = se->se_callback_ident; | 1229 | conn->cb_ident = se->se_callback_ident; |
| 1230 | rpc_svcaddr2sockaddr((struct sockaddr *)&conn->cb_saddr, expected_family, &rqstp->rq_daddr); | ||
| 1208 | return; | 1231 | return; |
| 1209 | out_err: | 1232 | out_err: |
| 1210 | conn->cb_addr.ss_family = AF_UNSPEC; | 1233 | conn->cb_addr.ss_family = AF_UNSPEC; |
| @@ -1344,7 +1367,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
| 1344 | case SP4_NONE: | 1367 | case SP4_NONE: |
| 1345 | break; | 1368 | break; |
| 1346 | case SP4_SSV: | 1369 | case SP4_SSV: |
| 1347 | return nfserr_encr_alg_unsupp; | 1370 | return nfserr_serverfault; |
| 1348 | default: | 1371 | default: |
| 1349 | BUG(); /* checked by xdr code */ | 1372 | BUG(); /* checked by xdr code */ |
| 1350 | case SP4_MACH_CRED: | 1373 | case SP4_MACH_CRED: |
| @@ -1361,8 +1384,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
| 1361 | nfs4_lock_state(); | 1384 | nfs4_lock_state(); |
| 1362 | status = nfs_ok; | 1385 | status = nfs_ok; |
| 1363 | 1386 | ||
| 1364 | conf = find_confirmed_client_by_str(dname, strhashval, true); | 1387 | conf = find_confirmed_client_by_str(dname, strhashval); |
| 1365 | if (conf) { | 1388 | if (conf) { |
| 1389 | if (!clp_used_exchangeid(conf)) { | ||
| 1390 | status = nfserr_clid_inuse; /* XXX: ? */ | ||
| 1391 | goto out; | ||
| 1392 | } | ||
| 1366 | if (!same_verf(&verf, &conf->cl_verifier)) { | 1393 | if (!same_verf(&verf, &conf->cl_verifier)) { |
| 1367 | /* 18.35.4 case 8 */ | 1394 | /* 18.35.4 case 8 */ |
| 1368 | if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { | 1395 | if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { |
| @@ -1403,7 +1430,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
| 1403 | goto out; | 1430 | goto out; |
| 1404 | } | 1431 | } |
| 1405 | 1432 | ||
| 1406 | unconf = find_unconfirmed_client_by_str(dname, strhashval, true); | 1433 | unconf = find_unconfirmed_client_by_str(dname, strhashval); |
| 1407 | if (unconf) { | 1434 | if (unconf) { |
| 1408 | /* | 1435 | /* |
| 1409 | * Possible retry or client restart. Per 18.35.4 case 4, | 1436 | * Possible retry or client restart. Per 18.35.4 case 4, |
| @@ -1560,6 +1587,8 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
| 1560 | status = nfs_ok; | 1587 | status = nfs_ok; |
| 1561 | memcpy(cr_ses->sessionid.data, new->se_sessionid.data, | 1588 | memcpy(cr_ses->sessionid.data, new->se_sessionid.data, |
| 1562 | NFS4_MAX_SESSIONID_LEN); | 1589 | NFS4_MAX_SESSIONID_LEN); |
| 1590 | memcpy(&cr_ses->fore_channel, &new->se_fchannel, | ||
| 1591 | sizeof(struct nfsd4_channel_attrs)); | ||
| 1563 | cs_slot->sl_seqid++; | 1592 | cs_slot->sl_seqid++; |
| 1564 | cr_ses->seqid = cs_slot->sl_seqid; | 1593 | cr_ses->seqid = cs_slot->sl_seqid; |
| 1565 | 1594 | ||
| @@ -1581,6 +1610,45 @@ static bool nfsd4_last_compound_op(struct svc_rqst *rqstp) | |||
| 1581 | return argp->opcnt == resp->opcnt; | 1610 | return argp->opcnt == resp->opcnt; |
| 1582 | } | 1611 | } |
| 1583 | 1612 | ||
| 1613 | static __be32 nfsd4_map_bcts_dir(u32 *dir) | ||
| 1614 | { | ||
| 1615 | switch (*dir) { | ||
| 1616 | case NFS4_CDFC4_FORE: | ||
| 1617 | case NFS4_CDFC4_BACK: | ||
| 1618 | return nfs_ok; | ||
| 1619 | case NFS4_CDFC4_FORE_OR_BOTH: | ||
| 1620 | case NFS4_CDFC4_BACK_OR_BOTH: | ||
| 1621 | *dir = NFS4_CDFC4_BOTH; | ||
| 1622 | return nfs_ok; | ||
| 1623 | }; | ||
| 1624 | return nfserr_inval; | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, | ||
| 1628 | struct nfsd4_compound_state *cstate, | ||
| 1629 | struct nfsd4_bind_conn_to_session *bcts) | ||
| 1630 | { | ||
| 1631 | __be32 status; | ||
| 1632 | |||
| 1633 | if (!nfsd4_last_compound_op(rqstp)) | ||
| 1634 | return nfserr_not_only_op; | ||
| 1635 | spin_lock(&client_lock); | ||
| 1636 | cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid); | ||
| 1637 | /* Sorta weird: we only need the refcnt'ing because new_conn acquires | ||
| 1638 | * client_lock iself: */ | ||
| 1639 | if (cstate->session) { | ||
| 1640 | nfsd4_get_session(cstate->session); | ||
| 1641 | atomic_inc(&cstate->session->se_client->cl_refcount); | ||
| 1642 | } | ||
| 1643 | spin_unlock(&client_lock); | ||
| 1644 | if (!cstate->session) | ||
| 1645 | return nfserr_badsession; | ||
| 1646 | |||
| 1647 | status = nfsd4_map_bcts_dir(&bcts->dir); | ||
| 1648 | nfsd4_new_conn(rqstp, cstate->session, bcts->dir); | ||
| 1649 | return nfs_ok; | ||
| 1650 | } | ||
| 1651 | |||
| 1584 | static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) | 1652 | static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) |
| 1585 | { | 1653 | { |
| 1586 | if (!session) | 1654 | if (!session) |
| @@ -1619,8 +1687,7 @@ nfsd4_destroy_session(struct svc_rqst *r, | |||
| 1619 | spin_unlock(&client_lock); | 1687 | spin_unlock(&client_lock); |
| 1620 | 1688 | ||
| 1621 | nfs4_lock_state(); | 1689 | nfs4_lock_state(); |
| 1622 | /* wait for callbacks */ | 1690 | nfsd4_probe_callback_sync(ses->se_client); |
| 1623 | nfsd4_shutdown_callback(ses->se_client); | ||
| 1624 | nfs4_unlock_state(); | 1691 | nfs4_unlock_state(); |
| 1625 | 1692 | ||
| 1626 | nfsd4_del_conns(ses); | 1693 | nfsd4_del_conns(ses); |
| @@ -1733,8 +1800,12 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
| 1733 | out: | 1800 | out: |
| 1734 | /* Hold a session reference until done processing the compound. */ | 1801 | /* Hold a session reference until done processing the compound. */ |
| 1735 | if (cstate->session) { | 1802 | if (cstate->session) { |
| 1803 | struct nfs4_client *clp = session->se_client; | ||
| 1804 | |||
| 1736 | nfsd4_get_session(cstate->session); | 1805 | nfsd4_get_session(cstate->session); |
| 1737 | atomic_inc(&session->se_client->cl_refcount); | 1806 | atomic_inc(&clp->cl_refcount); |
| 1807 | if (clp->cl_cb_state == NFSD4_CB_DOWN) | ||
| 1808 | seq->status_flags |= SEQ4_STATUS_CB_PATH_DOWN; | ||
| 1738 | } | 1809 | } |
| 1739 | kfree(conn); | 1810 | kfree(conn); |
| 1740 | spin_unlock(&client_lock); | 1811 | spin_unlock(&client_lock); |
| @@ -1775,7 +1846,6 @@ __be32 | |||
| 1775 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 1846 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
| 1776 | struct nfsd4_setclientid *setclid) | 1847 | struct nfsd4_setclientid *setclid) |
| 1777 | { | 1848 | { |
| 1778 | struct sockaddr *sa = svc_addr(rqstp); | ||
| 1779 | struct xdr_netobj clname = { | 1849 | struct xdr_netobj clname = { |
| 1780 | .len = setclid->se_namelen, | 1850 | .len = setclid->se_namelen, |
| 1781 | .data = setclid->se_name, | 1851 | .data = setclid->se_name, |
| @@ -1801,10 +1871,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1801 | strhashval = clientstr_hashval(dname); | 1871 | strhashval = clientstr_hashval(dname); |
| 1802 | 1872 | ||
| 1803 | nfs4_lock_state(); | 1873 | nfs4_lock_state(); |
| 1804 | conf = find_confirmed_client_by_str(dname, strhashval, false); | 1874 | conf = find_confirmed_client_by_str(dname, strhashval); |
| 1805 | if (conf) { | 1875 | if (conf) { |
| 1806 | /* RFC 3530 14.2.33 CASE 0: */ | 1876 | /* RFC 3530 14.2.33 CASE 0: */ |
| 1807 | status = nfserr_clid_inuse; | 1877 | status = nfserr_clid_inuse; |
| 1878 | if (clp_used_exchangeid(conf)) | ||
| 1879 | goto out; | ||
| 1808 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { | 1880 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { |
| 1809 | char addr_str[INET6_ADDRSTRLEN]; | 1881 | char addr_str[INET6_ADDRSTRLEN]; |
| 1810 | rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str, | 1882 | rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str, |
| @@ -1819,7 +1891,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1819 | * has a description of SETCLIENTID request processing consisting | 1891 | * has a description of SETCLIENTID request processing consisting |
| 1820 | * of 5 bullet points, labeled as CASE0 - CASE4 below. | 1892 | * of 5 bullet points, labeled as CASE0 - CASE4 below. |
| 1821 | */ | 1893 | */ |
| 1822 | unconf = find_unconfirmed_client_by_str(dname, strhashval, false); | 1894 | unconf = find_unconfirmed_client_by_str(dname, strhashval); |
| 1823 | status = nfserr_resource; | 1895 | status = nfserr_resource; |
| 1824 | if (!conf) { | 1896 | if (!conf) { |
| 1825 | /* | 1897 | /* |
| @@ -1876,7 +1948,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 1876 | * for consistent minorversion use throughout: | 1948 | * for consistent minorversion use throughout: |
| 1877 | */ | 1949 | */ |
| 1878 | new->cl_minorversion = 0; | 1950 | new->cl_minorversion = 0; |
| 1879 | gen_callback(new, setclid, rpc_get_scope_id(sa)); | 1951 | gen_callback(new, setclid, rqstp); |
| 1880 | add_to_unconfirmed(new, strhashval); | 1952 | add_to_unconfirmed(new, strhashval); |
| 1881 | setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; | 1953 | setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; |
| 1882 | setclid->se_clientid.cl_id = new->cl_clientid.cl_id; | 1954 | setclid->se_clientid.cl_id = new->cl_clientid.cl_id; |
| @@ -1935,7 +2007,6 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
| 1935 | if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) | 2007 | if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) |
| 1936 | status = nfserr_clid_inuse; | 2008 | status = nfserr_clid_inuse; |
| 1937 | else { | 2009 | else { |
| 1938 | atomic_set(&conf->cl_cb_set, 0); | ||
| 1939 | nfsd4_change_callback(conf, &unconf->cl_cb_conn); | 2010 | nfsd4_change_callback(conf, &unconf->cl_cb_conn); |
| 1940 | nfsd4_probe_callback(conf); | 2011 | nfsd4_probe_callback(conf); |
| 1941 | expire_client(unconf); | 2012 | expire_client(unconf); |
| @@ -1964,7 +2035,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
| 1964 | unsigned int hash = | 2035 | unsigned int hash = |
| 1965 | clientstr_hashval(unconf->cl_recdir); | 2036 | clientstr_hashval(unconf->cl_recdir); |
| 1966 | conf = find_confirmed_client_by_str(unconf->cl_recdir, | 2037 | conf = find_confirmed_client_by_str(unconf->cl_recdir, |
| 1967 | hash, false); | 2038 | hash); |
| 1968 | if (conf) { | 2039 | if (conf) { |
| 1969 | nfsd4_remove_clid_dir(conf); | 2040 | nfsd4_remove_clid_dir(conf); |
| 1970 | expire_client(conf); | 2041 | expire_client(conf); |
| @@ -2300,41 +2371,6 @@ void nfsd_break_deleg_cb(struct file_lock *fl) | |||
| 2300 | nfsd4_cb_recall(dp); | 2371 | nfsd4_cb_recall(dp); |
| 2301 | } | 2372 | } |
| 2302 | 2373 | ||
| 2303 | /* | ||
| 2304 | * The file_lock is being reapd. | ||
| 2305 | * | ||
| 2306 | * Called by locks_free_lock() with lock_flocks() held. | ||
| 2307 | */ | ||
| 2308 | static | ||
| 2309 | void nfsd_release_deleg_cb(struct file_lock *fl) | ||
| 2310 | { | ||
| 2311 | struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner; | ||
| 2312 | |||
| 2313 | dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d\n", fl,dp, atomic_read(&dp->dl_count)); | ||
| 2314 | |||
| 2315 | if (!(fl->fl_flags & FL_LEASE) || !dp) | ||
| 2316 | return; | ||
| 2317 | dp->dl_flock = NULL; | ||
| 2318 | } | ||
| 2319 | |||
| 2320 | /* | ||
| 2321 | * Called from setlease() with lock_flocks() held | ||
| 2322 | */ | ||
| 2323 | static | ||
| 2324 | int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) | ||
| 2325 | { | ||
| 2326 | struct nfs4_delegation *onlistd = | ||
| 2327 | (struct nfs4_delegation *)onlist->fl_owner; | ||
| 2328 | struct nfs4_delegation *tryd = | ||
| 2329 | (struct nfs4_delegation *)try->fl_owner; | ||
| 2330 | |||
| 2331 | if (onlist->fl_lmops != try->fl_lmops) | ||
| 2332 | return 0; | ||
| 2333 | |||
| 2334 | return onlistd->dl_client == tryd->dl_client; | ||
| 2335 | } | ||
| 2336 | |||
| 2337 | |||
| 2338 | static | 2374 | static |
| 2339 | int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) | 2375 | int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) |
| 2340 | { | 2376 | { |
| @@ -2346,8 +2382,6 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) | |||
| 2346 | 2382 | ||
| 2347 | static const struct lock_manager_operations nfsd_lease_mng_ops = { | 2383 | static const struct lock_manager_operations nfsd_lease_mng_ops = { |
| 2348 | .fl_break = nfsd_break_deleg_cb, | 2384 | .fl_break = nfsd_break_deleg_cb, |
| 2349 | .fl_release_private = nfsd_release_deleg_cb, | ||
| 2350 | .fl_mylease = nfsd_same_client_deleg_cb, | ||
| 2351 | .fl_change = nfsd_change_deleg_cb, | 2385 | .fl_change = nfsd_change_deleg_cb, |
| 2352 | }; | 2386 | }; |
| 2353 | 2387 | ||
| @@ -2514,8 +2548,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file | |||
| 2514 | if (!fp->fi_fds[oflag]) { | 2548 | if (!fp->fi_fds[oflag]) { |
| 2515 | status = nfsd_open(rqstp, cur_fh, S_IFREG, access, | 2549 | status = nfsd_open(rqstp, cur_fh, S_IFREG, access, |
| 2516 | &fp->fi_fds[oflag]); | 2550 | &fp->fi_fds[oflag]); |
| 2517 | if (status == nfserr_dropit) | ||
| 2518 | status = nfserr_jukebox; | ||
| 2519 | if (status) | 2551 | if (status) |
| 2520 | return status; | 2552 | return status; |
| 2521 | } | 2553 | } |
| @@ -2596,6 +2628,19 @@ nfs4_set_claim_prev(struct nfsd4_open *open) | |||
| 2596 | open->op_stateowner->so_client->cl_firststate = 1; | 2628 | open->op_stateowner->so_client->cl_firststate = 1; |
| 2597 | } | 2629 | } |
| 2598 | 2630 | ||
| 2631 | /* Should we give out recallable state?: */ | ||
| 2632 | static bool nfsd4_cb_channel_good(struct nfs4_client *clp) | ||
| 2633 | { | ||
| 2634 | if (clp->cl_cb_state == NFSD4_CB_UP) | ||
| 2635 | return true; | ||
| 2636 | /* | ||
| 2637 | * In the sessions case, since we don't have to establish a | ||
| 2638 | * separate connection for callbacks, we assume it's OK | ||
| 2639 | * until we hear otherwise: | ||
| 2640 | */ | ||
| 2641 | return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN; | ||
| 2642 | } | ||
| 2643 | |||
| 2599 | /* | 2644 | /* |
| 2600 | * Attempt to hand out a delegation. | 2645 | * Attempt to hand out a delegation. |
| 2601 | */ | 2646 | */ |
| @@ -2604,10 +2649,11 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
| 2604 | { | 2649 | { |
| 2605 | struct nfs4_delegation *dp; | 2650 | struct nfs4_delegation *dp; |
| 2606 | struct nfs4_stateowner *sop = stp->st_stateowner; | 2651 | struct nfs4_stateowner *sop = stp->st_stateowner; |
| 2607 | int cb_up = atomic_read(&sop->so_client->cl_cb_set); | 2652 | int cb_up; |
| 2608 | struct file_lock *fl; | 2653 | struct file_lock *fl; |
| 2609 | int status, flag = 0; | 2654 | int status, flag = 0; |
| 2610 | 2655 | ||
| 2656 | cb_up = nfsd4_cb_channel_good(sop->so_client); | ||
| 2611 | flag = NFS4_OPEN_DELEGATE_NONE; | 2657 | flag = NFS4_OPEN_DELEGATE_NONE; |
| 2612 | open->op_recall = 0; | 2658 | open->op_recall = 0; |
| 2613 | switch (open->op_claim_type) { | 2659 | switch (open->op_claim_type) { |
| @@ -2655,7 +2701,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
| 2655 | dp->dl_flock = fl; | 2701 | dp->dl_flock = fl; |
| 2656 | 2702 | ||
| 2657 | /* vfs_setlease checks to see if delegation should be handed out. | 2703 | /* vfs_setlease checks to see if delegation should be handed out. |
| 2658 | * the lock_manager callbacks fl_mylease and fl_change are used | 2704 | * the lock_manager callback fl_change is used |
| 2659 | */ | 2705 | */ |
| 2660 | if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { | 2706 | if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { |
| 2661 | dprintk("NFSD: setlease failed [%d], no delegation\n", status); | 2707 | dprintk("NFSD: setlease failed [%d], no delegation\n", status); |
| @@ -2794,7 +2840,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 2794 | renew_client(clp); | 2840 | renew_client(clp); |
| 2795 | status = nfserr_cb_path_down; | 2841 | status = nfserr_cb_path_down; |
| 2796 | if (!list_empty(&clp->cl_delegations) | 2842 | if (!list_empty(&clp->cl_delegations) |
| 2797 | && !atomic_read(&clp->cl_cb_set)) | 2843 | && clp->cl_cb_state != NFSD4_CB_UP) |
| 2798 | goto out; | 2844 | goto out; |
| 2799 | status = nfs_ok; | 2845 | status = nfs_ok; |
| 2800 | out: | 2846 | out: |
| @@ -3081,9 +3127,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | |||
| 3081 | if (status) | 3127 | if (status) |
| 3082 | goto out; | 3128 | goto out; |
| 3083 | renew_client(dp->dl_client); | 3129 | renew_client(dp->dl_client); |
| 3084 | if (filpp) | 3130 | if (filpp) { |
| 3085 | *filpp = find_readable_file(dp->dl_file); | 3131 | *filpp = find_readable_file(dp->dl_file); |
| 3086 | BUG_ON(!*filpp); | 3132 | BUG_ON(!*filpp); |
| 3133 | } | ||
| 3087 | } else { /* open or lock stateid */ | 3134 | } else { /* open or lock stateid */ |
| 3088 | stp = find_stateid(stateid, flags); | 3135 | stp = find_stateid(stateid, flags); |
| 3089 | if (!stp) | 3136 | if (!stp) |
| @@ -4107,7 +4154,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id) | |||
| 4107 | unsigned int strhashval = clientstr_hashval(name); | 4154 | unsigned int strhashval = clientstr_hashval(name); |
| 4108 | struct nfs4_client *clp; | 4155 | struct nfs4_client *clp; |
| 4109 | 4156 | ||
| 4110 | clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id); | 4157 | clp = find_confirmed_client_by_str(name, strhashval); |
| 4111 | return clp ? 1 : 0; | 4158 | return clp ? 1 : 0; |
| 4112 | } | 4159 | } |
| 4113 | 4160 | ||
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f35a94a04026..956629b9cdc9 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -44,13 +44,14 @@ | |||
| 44 | #include <linux/namei.h> | 44 | #include <linux/namei.h> |
| 45 | #include <linux/statfs.h> | 45 | #include <linux/statfs.h> |
| 46 | #include <linux/utsname.h> | 46 | #include <linux/utsname.h> |
| 47 | #include <linux/nfsd_idmap.h> | ||
| 48 | #include <linux/nfs4_acl.h> | ||
| 49 | #include <linux/sunrpc/svcauth_gss.h> | 47 | #include <linux/sunrpc/svcauth_gss.h> |
| 50 | 48 | ||
| 49 | #include "idmap.h" | ||
| 50 | #include "acl.h" | ||
| 51 | #include "xdr4.h" | 51 | #include "xdr4.h" |
| 52 | #include "vfs.h" | 52 | #include "vfs.h" |
| 53 | 53 | ||
| 54 | |||
| 54 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 55 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
| 55 | 56 | ||
| 56 | /* | 57 | /* |
| @@ -288,17 +289,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, | |||
| 288 | len += XDR_QUADLEN(dummy32) << 2; | 289 | len += XDR_QUADLEN(dummy32) << 2; |
| 289 | READMEM(buf, dummy32); | 290 | READMEM(buf, dummy32); |
| 290 | ace->whotype = nfs4_acl_get_whotype(buf, dummy32); | 291 | ace->whotype = nfs4_acl_get_whotype(buf, dummy32); |
| 291 | host_err = 0; | 292 | status = nfs_ok; |
| 292 | if (ace->whotype != NFS4_ACL_WHO_NAMED) | 293 | if (ace->whotype != NFS4_ACL_WHO_NAMED) |
| 293 | ace->who = 0; | 294 | ace->who = 0; |
| 294 | else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) | 295 | else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) |
| 295 | host_err = nfsd_map_name_to_gid(argp->rqstp, | 296 | status = nfsd_map_name_to_gid(argp->rqstp, |
| 296 | buf, dummy32, &ace->who); | 297 | buf, dummy32, &ace->who); |
| 297 | else | 298 | else |
| 298 | host_err = nfsd_map_name_to_uid(argp->rqstp, | 299 | status = nfsd_map_name_to_uid(argp->rqstp, |
| 299 | buf, dummy32, &ace->who); | 300 | buf, dummy32, &ace->who); |
| 300 | if (host_err) | 301 | if (status) |
| 301 | goto out_nfserr; | 302 | return status; |
| 302 | } | 303 | } |
| 303 | } else | 304 | } else |
| 304 | *acl = NULL; | 305 | *acl = NULL; |
| @@ -420,6 +421,21 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access | |||
| 420 | DECODE_TAIL; | 421 | DECODE_TAIL; |
| 421 | } | 422 | } |
| 422 | 423 | ||
| 424 | static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) | ||
| 425 | { | ||
| 426 | DECODE_HEAD; | ||
| 427 | u32 dummy; | ||
| 428 | |||
| 429 | READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); | ||
| 430 | COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); | ||
| 431 | READ32(bcts->dir); | ||
| 432 | /* XXX: Perhaps Tom Tucker could help us figure out how we | ||
| 433 | * should be using ctsa_use_conn_in_rdma_mode: */ | ||
| 434 | READ32(dummy); | ||
| 435 | |||
| 436 | DECODE_TAIL; | ||
| 437 | } | ||
| 438 | |||
| 423 | static __be32 | 439 | static __be32 |
| 424 | nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) | 440 | nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) |
| 425 | { | 441 | { |
| @@ -847,6 +863,17 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, | |||
| 847 | } | 863 | } |
| 848 | 864 | ||
| 849 | static __be32 | 865 | static __be32 |
| 866 | nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp, | ||
| 867 | struct nfsd4_secinfo_no_name *sin) | ||
| 868 | { | ||
| 869 | DECODE_HEAD; | ||
| 870 | |||
| 871 | READ_BUF(4); | ||
| 872 | READ32(sin->sin_style); | ||
| 873 | DECODE_TAIL; | ||
| 874 | } | ||
| 875 | |||
| 876 | static __be32 | ||
| 850 | nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) | 877 | nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) |
| 851 | { | 878 | { |
| 852 | __be32 status; | 879 | __be32 status; |
| @@ -1005,7 +1032,7 @@ static __be32 | |||
| 1005 | nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, | 1032 | nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, |
| 1006 | struct nfsd4_exchange_id *exid) | 1033 | struct nfsd4_exchange_id *exid) |
| 1007 | { | 1034 | { |
| 1008 | int dummy; | 1035 | int dummy, tmp; |
| 1009 | DECODE_HEAD; | 1036 | DECODE_HEAD; |
| 1010 | 1037 | ||
| 1011 | READ_BUF(NFS4_VERIFIER_SIZE); | 1038 | READ_BUF(NFS4_VERIFIER_SIZE); |
| @@ -1053,15 +1080,23 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, | |||
| 1053 | 1080 | ||
| 1054 | /* ssp_hash_algs<> */ | 1081 | /* ssp_hash_algs<> */ |
| 1055 | READ_BUF(4); | 1082 | READ_BUF(4); |
| 1056 | READ32(dummy); | 1083 | READ32(tmp); |
| 1057 | READ_BUF(dummy); | 1084 | while (tmp--) { |
| 1058 | p += XDR_QUADLEN(dummy); | 1085 | READ_BUF(4); |
| 1086 | READ32(dummy); | ||
| 1087 | READ_BUF(dummy); | ||
| 1088 | p += XDR_QUADLEN(dummy); | ||
| 1089 | } | ||
| 1059 | 1090 | ||
| 1060 | /* ssp_encr_algs<> */ | 1091 | /* ssp_encr_algs<> */ |
| 1061 | READ_BUF(4); | 1092 | READ_BUF(4); |
| 1062 | READ32(dummy); | 1093 | READ32(tmp); |
| 1063 | READ_BUF(dummy); | 1094 | while (tmp--) { |
| 1064 | p += XDR_QUADLEN(dummy); | 1095 | READ_BUF(4); |
| 1096 | READ32(dummy); | ||
| 1097 | READ_BUF(dummy); | ||
| 1098 | p += XDR_QUADLEN(dummy); | ||
| 1099 | } | ||
| 1065 | 1100 | ||
| 1066 | /* ssp_window and ssp_num_gss_handles */ | 1101 | /* ssp_window and ssp_num_gss_handles */ |
| 1067 | READ_BUF(8); | 1102 | READ_BUF(8); |
| @@ -1339,7 +1374,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { | |||
| 1339 | 1374 | ||
| 1340 | /* new operations for NFSv4.1 */ | 1375 | /* new operations for NFSv4.1 */ |
| 1341 | [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, | 1376 | [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, |
| 1342 | [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_notsupp, | 1377 | [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, |
| 1343 | [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, | 1378 | [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, |
| 1344 | [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, | 1379 | [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, |
| 1345 | [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, | 1380 | [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, |
| @@ -1350,7 +1385,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { | |||
| 1350 | [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, | 1385 | [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, |
| 1351 | [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, | 1386 | [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, |
| 1352 | [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, | 1387 | [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, |
| 1353 | [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_notsupp, | 1388 | [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name, |
| 1354 | [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, | 1389 | [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, |
| 1355 | [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, | 1390 | [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, |
| 1356 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, | 1391 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, |
| @@ -2309,8 +2344,6 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
| 2309 | case nfserr_resource: | 2344 | case nfserr_resource: |
| 2310 | nfserr = nfserr_toosmall; | 2345 | nfserr = nfserr_toosmall; |
| 2311 | goto fail; | 2346 | goto fail; |
| 2312 | case nfserr_dropit: | ||
| 2313 | goto fail; | ||
| 2314 | case nfserr_noent: | 2347 | case nfserr_noent: |
| 2315 | goto skip_entry; | 2348 | goto skip_entry; |
| 2316 | default: | 2349 | default: |
| @@ -2365,6 +2398,21 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ | |||
| 2365 | return nfserr; | 2398 | return nfserr; |
| 2366 | } | 2399 | } |
| 2367 | 2400 | ||
| 2401 | static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) | ||
| 2402 | { | ||
| 2403 | __be32 *p; | ||
| 2404 | |||
| 2405 | if (!nfserr) { | ||
| 2406 | RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8); | ||
| 2407 | WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); | ||
| 2408 | WRITE32(bcts->dir); | ||
| 2409 | /* XXX: ? */ | ||
| 2410 | WRITE32(0); | ||
| 2411 | ADJUST_ARGS(); | ||
| 2412 | } | ||
| 2413 | return nfserr; | ||
| 2414 | } | ||
| 2415 | |||
| 2368 | static __be32 | 2416 | static __be32 |
| 2369 | nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) | 2417 | nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) |
| 2370 | { | 2418 | { |
| @@ -2826,11 +2874,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ | |||
| 2826 | } | 2874 | } |
| 2827 | 2875 | ||
| 2828 | static __be32 | 2876 | static __be32 |
| 2829 | nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, | 2877 | nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, |
| 2830 | struct nfsd4_secinfo *secinfo) | 2878 | __be32 nfserr,struct svc_export *exp) |
| 2831 | { | 2879 | { |
| 2832 | int i = 0; | 2880 | int i = 0; |
| 2833 | struct svc_export *exp = secinfo->si_exp; | ||
| 2834 | u32 nflavs; | 2881 | u32 nflavs; |
| 2835 | struct exp_flavor_info *flavs; | 2882 | struct exp_flavor_info *flavs; |
| 2836 | struct exp_flavor_info def_flavs[2]; | 2883 | struct exp_flavor_info def_flavs[2]; |
| @@ -2892,6 +2939,20 @@ out: | |||
| 2892 | return nfserr; | 2939 | return nfserr; |
| 2893 | } | 2940 | } |
| 2894 | 2941 | ||
| 2942 | static __be32 | ||
| 2943 | nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, | ||
| 2944 | struct nfsd4_secinfo *secinfo) | ||
| 2945 | { | ||
| 2946 | return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp); | ||
| 2947 | } | ||
| 2948 | |||
| 2949 | static __be32 | ||
| 2950 | nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, | ||
| 2951 | struct nfsd4_secinfo_no_name *secinfo) | ||
| 2952 | { | ||
| 2953 | return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp); | ||
| 2954 | } | ||
| 2955 | |||
| 2895 | /* | 2956 | /* |
| 2896 | * The SETATTR encode routine is special -- it always encodes a bitmap, | 2957 | * The SETATTR encode routine is special -- it always encodes a bitmap, |
| 2897 | * regardless of the error status. | 2958 | * regardless of the error status. |
| @@ -3076,13 +3137,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, | |||
| 3076 | WRITE32(seq->seqid); | 3137 | WRITE32(seq->seqid); |
| 3077 | WRITE32(seq->slotid); | 3138 | WRITE32(seq->slotid); |
| 3078 | WRITE32(seq->maxslots); | 3139 | WRITE32(seq->maxslots); |
| 3079 | /* | 3140 | /* For now: target_maxslots = maxslots */ |
| 3080 | * FIXME: for now: | ||
| 3081 | * target_maxslots = maxslots | ||
| 3082 | * status_flags = 0 | ||
| 3083 | */ | ||
| 3084 | WRITE32(seq->maxslots); | 3141 | WRITE32(seq->maxslots); |
| 3085 | WRITE32(0); | 3142 | WRITE32(seq->status_flags); |
| 3086 | 3143 | ||
| 3087 | ADJUST_ARGS(); | 3144 | ADJUST_ARGS(); |
| 3088 | resp->cstate.datap = p; /* DRC cache data pointer */ | 3145 | resp->cstate.datap = p; /* DRC cache data pointer */ |
| @@ -3143,7 +3200,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { | |||
| 3143 | 3200 | ||
| 3144 | /* NFSv4.1 operations */ | 3201 | /* NFSv4.1 operations */ |
| 3145 | [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, | 3202 | [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, |
| 3146 | [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop, | 3203 | [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session, |
| 3147 | [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, | 3204 | [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, |
| 3148 | [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, | 3205 | [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, |
| 3149 | [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, | 3206 | [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, |
| @@ -3154,7 +3211,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { | |||
| 3154 | [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, | 3211 | [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, |
| 3155 | [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, | 3212 | [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, |
| 3156 | [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, | 3213 | [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, |
| 3157 | [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop, | 3214 | [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name, |
| 3158 | [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, | 3215 | [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, |
| 3159 | [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, | 3216 | [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, |
| 3160 | [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, | 3217 | [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 4514ebbee4d6..33b3e2b06779 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
| @@ -8,12 +8,12 @@ | |||
| 8 | #include <linux/namei.h> | 8 | #include <linux/namei.h> |
| 9 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
| 10 | 10 | ||
| 11 | #include <linux/nfsd_idmap.h> | ||
| 12 | #include <linux/sunrpc/svcsock.h> | 11 | #include <linux/sunrpc/svcsock.h> |
| 13 | #include <linux/nfsd/syscall.h> | 12 | #include <linux/nfsd/syscall.h> |
| 14 | #include <linux/lockd/lockd.h> | 13 | #include <linux/lockd/lockd.h> |
| 15 | #include <linux/sunrpc/clnt.h> | 14 | #include <linux/sunrpc/clnt.h> |
| 16 | 15 | ||
| 16 | #include "idmap.h" | ||
| 17 | #include "nfsd.h" | 17 | #include "nfsd.h" |
| 18 | #include "cache.h" | 18 | #include "cache.h" |
| 19 | 19 | ||
| @@ -127,6 +127,7 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu | |||
| 127 | 127 | ||
| 128 | static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) | 128 | static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) |
| 129 | { | 129 | { |
| 130 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 130 | static int warned; | 131 | static int warned; |
| 131 | if (file->f_dentry->d_name.name[0] == '.' && !warned) { | 132 | if (file->f_dentry->d_name.name[0] == '.' && !warned) { |
| 132 | printk(KERN_INFO | 133 | printk(KERN_INFO |
| @@ -135,6 +136,7 @@ static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size | |||
| 135 | current->comm, file->f_dentry->d_name.name); | 136 | current->comm, file->f_dentry->d_name.name); |
| 136 | warned = 1; | 137 | warned = 1; |
| 137 | } | 138 | } |
| 139 | #endif | ||
| 138 | if (! file->private_data) { | 140 | if (! file->private_data) { |
| 139 | /* An attempt to read a transaction file without writing | 141 | /* An attempt to read a transaction file without writing |
| 140 | * causes a 0-byte write so that the file can return | 142 | * causes a 0-byte write so that the file can return |
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 6b641cf2c19a..7ecfa2420307 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h | |||
| @@ -158,6 +158,7 @@ void nfsd_lockd_shutdown(void); | |||
| 158 | #define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) | 158 | #define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) |
| 159 | #define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) | 159 | #define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) |
| 160 | #define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) | 160 | #define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) |
| 161 | #define nfserr_badowner cpu_to_be32(NFSERR_BADOWNER) | ||
| 161 | #define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) | 162 | #define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) |
| 162 | #define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) | 163 | #define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) |
| 163 | #define nfserr_grace cpu_to_be32(NFSERR_GRACE) | 164 | #define nfserr_grace cpu_to_be32(NFSERR_GRACE) |
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 08e17264784b..e15dc45fc5ec 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c | |||
| @@ -735,9 +735,9 @@ nfserrno (int errno) | |||
| 735 | { nfserr_stale, -ESTALE }, | 735 | { nfserr_stale, -ESTALE }, |
| 736 | { nfserr_jukebox, -ETIMEDOUT }, | 736 | { nfserr_jukebox, -ETIMEDOUT }, |
| 737 | { nfserr_jukebox, -ERESTARTSYS }, | 737 | { nfserr_jukebox, -ERESTARTSYS }, |
| 738 | { nfserr_dropit, -EAGAIN }, | 738 | { nfserr_jukebox, -EAGAIN }, |
| 739 | { nfserr_dropit, -ENOMEM }, | 739 | { nfserr_jukebox, -EWOULDBLOCK }, |
| 740 | { nfserr_badname, -ESRCH }, | 740 | { nfserr_jukebox, -ENOMEM }, |
| 741 | { nfserr_io, -ETXTBSY }, | 741 | { nfserr_io, -ETXTBSY }, |
| 742 | { nfserr_notsupp, -EOPNOTSUPP }, | 742 | { nfserr_notsupp, -EOPNOTSUPP }, |
| 743 | { nfserr_toosmall, -ETOOSMALL }, | 743 | { nfserr_toosmall, -ETOOSMALL }, |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 2bae1d86f5f2..18743c4d8bca 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
| @@ -608,7 +608,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) | |||
| 608 | /* Now call the procedure handler, and encode NFS status. */ | 608 | /* Now call the procedure handler, and encode NFS status. */ |
| 609 | nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); | 609 | nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); |
| 610 | nfserr = map_new_errors(rqstp->rq_vers, nfserr); | 610 | nfserr = map_new_errors(rqstp->rq_vers, nfserr); |
| 611 | if (nfserr == nfserr_dropit) { | 611 | if (nfserr == nfserr_dropit || rqstp->rq_dropme) { |
| 612 | dprintk("nfsd: Dropping request; may be revisited later\n"); | 612 | dprintk("nfsd: Dropping request; may be revisited later\n"); |
| 613 | nfsd_cache_update(rqstp, RC_NOCACHE, NULL); | 613 | nfsd_cache_update(rqstp, RC_NOCACHE, NULL); |
| 614 | return 0; | 614 | return 0; |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 39adc27b0685..3074656ba7bf 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
| @@ -68,10 +68,12 @@ typedef struct { | |||
| 68 | struct nfsd4_callback { | 68 | struct nfsd4_callback { |
| 69 | void *cb_op; | 69 | void *cb_op; |
| 70 | struct nfs4_client *cb_clp; | 70 | struct nfs4_client *cb_clp; |
| 71 | struct list_head cb_per_client; | ||
| 71 | u32 cb_minorversion; | 72 | u32 cb_minorversion; |
| 72 | struct rpc_message cb_msg; | 73 | struct rpc_message cb_msg; |
| 73 | const struct rpc_call_ops *cb_ops; | 74 | const struct rpc_call_ops *cb_ops; |
| 74 | struct work_struct cb_work; | 75 | struct work_struct cb_work; |
| 76 | bool cb_done; | ||
| 75 | }; | 77 | }; |
| 76 | 78 | ||
| 77 | struct nfs4_delegation { | 79 | struct nfs4_delegation { |
| @@ -81,6 +83,7 @@ struct nfs4_delegation { | |||
| 81 | atomic_t dl_count; /* ref count */ | 83 | atomic_t dl_count; /* ref count */ |
| 82 | struct nfs4_client *dl_client; | 84 | struct nfs4_client *dl_client; |
| 83 | struct nfs4_file *dl_file; | 85 | struct nfs4_file *dl_file; |
| 86 | struct file *dl_vfs_file; | ||
| 84 | struct file_lock *dl_flock; | 87 | struct file_lock *dl_flock; |
| 85 | u32 dl_type; | 88 | u32 dl_type; |
| 86 | time_t dl_time; | 89 | time_t dl_time; |
| @@ -95,6 +98,7 @@ struct nfs4_delegation { | |||
| 95 | struct nfs4_cb_conn { | 98 | struct nfs4_cb_conn { |
| 96 | /* SETCLIENTID info */ | 99 | /* SETCLIENTID info */ |
| 97 | struct sockaddr_storage cb_addr; | 100 | struct sockaddr_storage cb_addr; |
| 101 | struct sockaddr_storage cb_saddr; | ||
| 98 | size_t cb_addrlen; | 102 | size_t cb_addrlen; |
| 99 | u32 cb_prog; /* used only in 4.0 case; | 103 | u32 cb_prog; /* used only in 4.0 case; |
| 100 | per-session otherwise */ | 104 | per-session otherwise */ |
| @@ -146,6 +150,11 @@ struct nfsd4_create_session { | |||
| 146 | u32 gid; | 150 | u32 gid; |
| 147 | }; | 151 | }; |
| 148 | 152 | ||
| 153 | struct nfsd4_bind_conn_to_session { | ||
| 154 | struct nfs4_sessionid sessionid; | ||
| 155 | u32 dir; | ||
| 156 | }; | ||
| 157 | |||
| 149 | /* The single slot clientid cache structure */ | 158 | /* The single slot clientid cache structure */ |
| 150 | struct nfsd4_clid_slot { | 159 | struct nfsd4_clid_slot { |
| 151 | u32 sl_seqid; | 160 | u32 sl_seqid; |
| @@ -235,9 +244,13 @@ struct nfs4_client { | |||
| 235 | unsigned long cl_cb_flags; | 244 | unsigned long cl_cb_flags; |
| 236 | struct rpc_clnt *cl_cb_client; | 245 | struct rpc_clnt *cl_cb_client; |
| 237 | u32 cl_cb_ident; | 246 | u32 cl_cb_ident; |
| 238 | atomic_t cl_cb_set; | 247 | #define NFSD4_CB_UP 0 |
| 248 | #define NFSD4_CB_UNKNOWN 1 | ||
| 249 | #define NFSD4_CB_DOWN 2 | ||
| 250 | int cl_cb_state; | ||
| 239 | struct nfsd4_callback cl_cb_null; | 251 | struct nfsd4_callback cl_cb_null; |
| 240 | struct nfsd4_session *cl_cb_session; | 252 | struct nfsd4_session *cl_cb_session; |
| 253 | struct list_head cl_callbacks; /* list of in-progress callbacks */ | ||
| 241 | 254 | ||
| 242 | /* for all client information that callback code might need: */ | 255 | /* for all client information that callback code might need: */ |
| 243 | spinlock_t cl_lock; | 256 | spinlock_t cl_lock; |
| @@ -454,6 +467,7 @@ extern __be32 nfs4_check_open_reclaim(clientid_t *clid); | |||
| 454 | extern void nfs4_free_stateowner(struct kref *kref); | 467 | extern void nfs4_free_stateowner(struct kref *kref); |
| 455 | extern int set_callback_cred(void); | 468 | extern int set_callback_cred(void); |
| 456 | extern void nfsd4_probe_callback(struct nfs4_client *clp); | 469 | extern void nfsd4_probe_callback(struct nfs4_client *clp); |
| 470 | extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); | ||
| 457 | extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); | 471 | extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); |
| 458 | extern void nfsd4_do_callback_rpc(struct work_struct *); | 472 | extern void nfsd4_do_callback_rpc(struct work_struct *); |
| 459 | extern void nfsd4_cb_recall(struct nfs4_delegation *dp); | 473 | extern void nfsd4_cb_recall(struct nfs4_delegation *dp); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 230b79fbf005..a3c7f701395a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | #define MSNFS /* HACK HACK */ | ||
| 2 | /* | 1 | /* |
| 3 | * File operations used by nfsd. Some of these have been ripped from | 2 | * File operations used by nfsd. Some of these have been ripped from |
| 4 | * other parts of the kernel because they weren't exported, others | 3 | * other parts of the kernel because they weren't exported, others |
| @@ -35,8 +34,8 @@ | |||
| 35 | #endif /* CONFIG_NFSD_V3 */ | 34 | #endif /* CONFIG_NFSD_V3 */ |
| 36 | 35 | ||
| 37 | #ifdef CONFIG_NFSD_V4 | 36 | #ifdef CONFIG_NFSD_V4 |
| 38 | #include <linux/nfs4_acl.h> | 37 | #include "acl.h" |
| 39 | #include <linux/nfsd_idmap.h> | 38 | #include "idmap.h" |
| 40 | #endif /* CONFIG_NFSD_V4 */ | 39 | #endif /* CONFIG_NFSD_V4 */ |
| 41 | 40 | ||
| 42 | #include "nfsd.h" | 41 | #include "nfsd.h" |
| @@ -273,6 +272,13 @@ out: | |||
| 273 | return err; | 272 | return err; |
| 274 | } | 273 | } |
| 275 | 274 | ||
| 275 | static int nfsd_break_lease(struct inode *inode) | ||
| 276 | { | ||
| 277 | if (!S_ISREG(inode->i_mode)) | ||
| 278 | return 0; | ||
| 279 | return break_lease(inode, O_WRONLY | O_NONBLOCK); | ||
| 280 | } | ||
| 281 | |||
| 276 | /* | 282 | /* |
| 277 | * Commit metadata changes to stable storage. | 283 | * Commit metadata changes to stable storage. |
| 278 | */ | 284 | */ |
| @@ -375,16 +381,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
| 375 | goto out; | 381 | goto out; |
| 376 | } | 382 | } |
| 377 | 383 | ||
| 378 | /* | ||
| 379 | * If we are changing the size of the file, then | ||
| 380 | * we need to break all leases. | ||
| 381 | */ | ||
| 382 | host_err = break_lease(inode, O_WRONLY | O_NONBLOCK); | ||
| 383 | if (host_err == -EWOULDBLOCK) | ||
| 384 | host_err = -ETIMEDOUT; | ||
| 385 | if (host_err) /* ENOMEM or EWOULDBLOCK */ | ||
| 386 | goto out_nfserr; | ||
| 387 | |||
| 388 | host_err = get_write_access(inode); | 384 | host_err = get_write_access(inode); |
| 389 | if (host_err) | 385 | if (host_err) |
| 390 | goto out_nfserr; | 386 | goto out_nfserr; |
| @@ -425,7 +421,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
| 425 | 421 | ||
| 426 | err = nfserr_notsync; | 422 | err = nfserr_notsync; |
| 427 | if (!check_guard || guardtime == inode->i_ctime.tv_sec) { | 423 | if (!check_guard || guardtime == inode->i_ctime.tv_sec) { |
| 424 | host_err = nfsd_break_lease(inode); | ||
| 425 | if (host_err) | ||
| 426 | goto out_nfserr; | ||
| 428 | fh_lock(fhp); | 427 | fh_lock(fhp); |
| 428 | |||
| 429 | host_err = notify_change(dentry, iap); | 429 | host_err = notify_change(dentry, iap); |
| 430 | err = nfserrno(host_err); | 430 | err = nfserrno(host_err); |
| 431 | fh_unlock(fhp); | 431 | fh_unlock(fhp); |
| @@ -752,8 +752,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
| 752 | */ | 752 | */ |
| 753 | if (!(access & NFSD_MAY_NOT_BREAK_LEASE)) | 753 | if (!(access & NFSD_MAY_NOT_BREAK_LEASE)) |
| 754 | host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0)); | 754 | host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0)); |
| 755 | if (host_err == -EWOULDBLOCK) | ||
| 756 | host_err = -ETIMEDOUT; | ||
| 757 | if (host_err) /* NOMEM or WOULDBLOCK */ | 755 | if (host_err) /* NOMEM or WOULDBLOCK */ |
| 758 | goto out_nfserr; | 756 | goto out_nfserr; |
| 759 | 757 | ||
| @@ -874,15 +872,6 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe, | |||
| 874 | return __splice_from_pipe(pipe, sd, nfsd_splice_actor); | 872 | return __splice_from_pipe(pipe, sd, nfsd_splice_actor); |
| 875 | } | 873 | } |
| 876 | 874 | ||
| 877 | static inline int svc_msnfs(struct svc_fh *ffhp) | ||
| 878 | { | ||
| 879 | #ifdef MSNFS | ||
| 880 | return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS); | ||
| 881 | #else | ||
| 882 | return 0; | ||
| 883 | #endif | ||
| 884 | } | ||
| 885 | |||
| 886 | static __be32 | 875 | static __be32 |
| 887 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 876 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, |
| 888 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) | 877 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) |
| @@ -895,9 +884,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
| 895 | err = nfserr_perm; | 884 | err = nfserr_perm; |
| 896 | inode = file->f_path.dentry->d_inode; | 885 | inode = file->f_path.dentry->d_inode; |
| 897 | 886 | ||
| 898 | if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count)) | ||
| 899 | goto out; | ||
| 900 | |||
| 901 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { | 887 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { |
| 902 | struct splice_desc sd = { | 888 | struct splice_desc sd = { |
| 903 | .len = 0, | 889 | .len = 0, |
| @@ -922,7 +908,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
| 922 | fsnotify_access(file); | 908 | fsnotify_access(file); |
| 923 | } else | 909 | } else |
| 924 | err = nfserrno(host_err); | 910 | err = nfserrno(host_err); |
| 925 | out: | ||
| 926 | return err; | 911 | return err; |
| 927 | } | 912 | } |
| 928 | 913 | ||
| @@ -987,14 +972,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
| 987 | int stable = *stablep; | 972 | int stable = *stablep; |
| 988 | int use_wgather; | 973 | int use_wgather; |
| 989 | 974 | ||
| 990 | #ifdef MSNFS | ||
| 991 | err = nfserr_perm; | ||
| 992 | |||
| 993 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && | ||
| 994 | (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt))) | ||
| 995 | goto out; | ||
| 996 | #endif | ||
| 997 | |||
| 998 | dentry = file->f_path.dentry; | 975 | dentry = file->f_path.dentry; |
| 999 | inode = dentry->d_inode; | 976 | inode = dentry->d_inode; |
| 1000 | exp = fhp->fh_export; | 977 | exp = fhp->fh_export; |
| @@ -1045,7 +1022,6 @@ out_nfserr: | |||
| 1045 | err = 0; | 1022 | err = 0; |
| 1046 | else | 1023 | else |
| 1047 | err = nfserrno(host_err); | 1024 | err = nfserrno(host_err); |
| 1048 | out: | ||
| 1049 | return err; | 1025 | return err; |
| 1050 | } | 1026 | } |
| 1051 | 1027 | ||
| @@ -1665,6 +1641,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
| 1665 | err = nfserrno(host_err); | 1641 | err = nfserrno(host_err); |
| 1666 | goto out_dput; | 1642 | goto out_dput; |
| 1667 | } | 1643 | } |
| 1644 | err = nfserr_noent; | ||
| 1645 | if (!dold->d_inode) | ||
| 1646 | goto out_drop_write; | ||
| 1647 | host_err = nfsd_break_lease(dold->d_inode); | ||
| 1648 | if (host_err) | ||
| 1649 | goto out_drop_write; | ||
| 1668 | host_err = vfs_link(dold, dirp, dnew); | 1650 | host_err = vfs_link(dold, dirp, dnew); |
| 1669 | if (!host_err) { | 1651 | if (!host_err) { |
| 1670 | err = nfserrno(commit_metadata(ffhp)); | 1652 | err = nfserrno(commit_metadata(ffhp)); |
| @@ -1676,6 +1658,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
| 1676 | else | 1658 | else |
| 1677 | err = nfserrno(host_err); | 1659 | err = nfserrno(host_err); |
| 1678 | } | 1660 | } |
| 1661 | out_drop_write: | ||
| 1679 | mnt_drop_write(tfhp->fh_export->ex_path.mnt); | 1662 | mnt_drop_write(tfhp->fh_export->ex_path.mnt); |
| 1680 | out_dput: | 1663 | out_dput: |
| 1681 | dput(dnew); | 1664 | dput(dnew); |
| @@ -1750,12 +1733,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
| 1750 | if (ndentry == trap) | 1733 | if (ndentry == trap) |
| 1751 | goto out_dput_new; | 1734 | goto out_dput_new; |
| 1752 | 1735 | ||
| 1753 | if (svc_msnfs(ffhp) && | ||
| 1754 | ((odentry->d_count > 1) || (ndentry->d_count > 1))) { | ||
| 1755 | host_err = -EPERM; | ||
| 1756 | goto out_dput_new; | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | host_err = -EXDEV; | 1736 | host_err = -EXDEV; |
| 1760 | if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) | 1737 | if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) |
| 1761 | goto out_dput_new; | 1738 | goto out_dput_new; |
| @@ -1763,15 +1740,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
| 1763 | if (host_err) | 1740 | if (host_err) |
| 1764 | goto out_dput_new; | 1741 | goto out_dput_new; |
| 1765 | 1742 | ||
| 1743 | host_err = nfsd_break_lease(odentry->d_inode); | ||
| 1744 | if (host_err) | ||
| 1745 | goto out_drop_write; | ||
| 1766 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); | 1746 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); |
| 1767 | if (!host_err) { | 1747 | if (!host_err) { |
| 1768 | host_err = commit_metadata(tfhp); | 1748 | host_err = commit_metadata(tfhp); |
| 1769 | if (!host_err) | 1749 | if (!host_err) |
| 1770 | host_err = commit_metadata(ffhp); | 1750 | host_err = commit_metadata(ffhp); |
| 1771 | } | 1751 | } |
| 1772 | 1752 | out_drop_write: | |
| 1773 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); | 1753 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); |
| 1774 | |||
| 1775 | out_dput_new: | 1754 | out_dput_new: |
| 1776 | dput(ndentry); | 1755 | dput(ndentry); |
| 1777 | out_dput_old: | 1756 | out_dput_old: |
| @@ -1834,18 +1813,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
| 1834 | if (host_err) | 1813 | if (host_err) |
| 1835 | goto out_nfserr; | 1814 | goto out_nfserr; |
| 1836 | 1815 | ||
| 1837 | if (type != S_IFDIR) { /* It's UNLINK */ | 1816 | host_err = nfsd_break_lease(rdentry->d_inode); |
| 1838 | #ifdef MSNFS | 1817 | if (host_err) |
| 1839 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && | 1818 | goto out_put; |
| 1840 | (rdentry->d_count > 1)) { | 1819 | if (type != S_IFDIR) |
| 1841 | host_err = -EPERM; | ||
| 1842 | } else | ||
| 1843 | #endif | ||
| 1844 | host_err = vfs_unlink(dirp, rdentry); | 1820 | host_err = vfs_unlink(dirp, rdentry); |
| 1845 | } else { /* It's RMDIR */ | 1821 | else |
| 1846 | host_err = vfs_rmdir(dirp, rdentry); | 1822 | host_err = vfs_rmdir(dirp, rdentry); |
| 1847 | } | 1823 | out_put: |
| 1848 | |||
| 1849 | dput(rdentry); | 1824 | dput(rdentry); |
| 1850 | 1825 | ||
| 1851 | if (!host_err) | 1826 | if (!host_err) |
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 60fce3dc5cb5..366401e1a536 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
| @@ -311,6 +311,11 @@ struct nfsd4_secinfo { | |||
| 311 | struct svc_export *si_exp; /* response */ | 311 | struct svc_export *si_exp; /* response */ |
| 312 | }; | 312 | }; |
| 313 | 313 | ||
| 314 | struct nfsd4_secinfo_no_name { | ||
| 315 | u32 sin_style; /* request */ | ||
| 316 | struct svc_export *sin_exp; /* response */ | ||
| 317 | }; | ||
| 318 | |||
| 314 | struct nfsd4_setattr { | 319 | struct nfsd4_setattr { |
| 315 | stateid_t sa_stateid; /* request */ | 320 | stateid_t sa_stateid; /* request */ |
| 316 | u32 sa_bmval[3]; /* request */ | 321 | u32 sa_bmval[3]; /* request */ |
| @@ -373,8 +378,8 @@ struct nfsd4_sequence { | |||
| 373 | u32 cachethis; /* request */ | 378 | u32 cachethis; /* request */ |
| 374 | #if 0 | 379 | #if 0 |
| 375 | u32 target_maxslots; /* response */ | 380 | u32 target_maxslots; /* response */ |
| 376 | u32 status_flags; /* response */ | ||
| 377 | #endif /* not yet */ | 381 | #endif /* not yet */ |
| 382 | u32 status_flags; /* response */ | ||
| 378 | }; | 383 | }; |
| 379 | 384 | ||
| 380 | struct nfsd4_destroy_session { | 385 | struct nfsd4_destroy_session { |
| @@ -422,6 +427,7 @@ struct nfsd4_op { | |||
| 422 | 427 | ||
| 423 | /* NFSv4.1 */ | 428 | /* NFSv4.1 */ |
| 424 | struct nfsd4_exchange_id exchange_id; | 429 | struct nfsd4_exchange_id exchange_id; |
| 430 | struct nfsd4_bind_conn_to_session bind_conn_to_session; | ||
| 425 | struct nfsd4_create_session create_session; | 431 | struct nfsd4_create_session create_session; |
| 426 | struct nfsd4_destroy_session destroy_session; | 432 | struct nfsd4_destroy_session destroy_session; |
| 427 | struct nfsd4_sequence sequence; | 433 | struct nfsd4_sequence sequence; |
| @@ -518,6 +524,7 @@ extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, | |||
| 518 | struct nfsd4_sequence *seq); | 524 | struct nfsd4_sequence *seq); |
| 519 | extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, | 525 | extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, |
| 520 | struct nfsd4_compound_state *, struct nfsd4_exchange_id *); | 526 | struct nfsd4_compound_state *, struct nfsd4_exchange_id *); |
| 527 | extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *); | ||
| 521 | extern __be32 nfsd4_create_session(struct svc_rqst *, | 528 | extern __be32 nfsd4_create_session(struct svc_rqst *, |
| 522 | struct nfsd4_compound_state *, | 529 | struct nfsd4_compound_state *, |
| 523 | struct nfsd4_create_session *); | 530 | struct nfsd4_create_session *); |
diff --git a/include/acpi/apei.h b/include/acpi/apei.h index b3365025ff8d..c4dbb132d902 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h | |||
| @@ -19,6 +19,12 @@ | |||
| 19 | extern int hest_disable; | 19 | extern int hest_disable; |
| 20 | extern int erst_disable; | 20 | extern int erst_disable; |
| 21 | 21 | ||
| 22 | #ifdef CONFIG_ACPI_APEI | ||
| 23 | void __init acpi_hest_init(void); | ||
| 24 | #else | ||
| 25 | static inline void acpi_hest_init(void) { return; } | ||
| 26 | #endif | ||
| 27 | |||
| 22 | typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); | 28 | typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); |
| 23 | int apei_hest_parse(apei_hest_func_t func, void *data); | 29 | int apei_hest_parse(apei_hest_func_t func, void *data); |
| 24 | 30 | ||
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index bec8b82889bf..ab68f785fd19 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
| @@ -99,6 +99,17 @@ static inline int is_broadcast_ether_addr(const u8 *addr) | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | /** | 101 | /** |
| 102 | * is_unicast_ether_addr - Determine if the Ethernet address is unicast | ||
| 103 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
| 104 | * | ||
| 105 | * Return true if the address is a unicast address. | ||
| 106 | */ | ||
| 107 | static inline int is_unicast_ether_addr(const u8 *addr) | ||
| 108 | { | ||
| 109 | return !is_multicast_ether_addr(addr); | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 102 | * is_valid_ether_addr - Determine if the given Ethernet address is valid | 113 | * is_valid_ether_addr - Determine if the given Ethernet address is valid |
| 103 | * @addr: Pointer to a six-byte array containing the Ethernet address | 114 | * @addr: Pointer to a six-byte array containing the Ethernet address |
| 104 | * | 115 | * |
diff --git a/include/linux/fs.h b/include/linux/fs.h index fb2190349cdf..08824e0ef381 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1066,7 +1066,6 @@ struct lock_manager_operations { | |||
| 1066 | int (*fl_grant)(struct file_lock *, struct file_lock *, int); | 1066 | int (*fl_grant)(struct file_lock *, struct file_lock *, int); |
| 1067 | void (*fl_release_private)(struct file_lock *); | 1067 | void (*fl_release_private)(struct file_lock *); |
| 1068 | void (*fl_break)(struct file_lock *); | 1068 | void (*fl_break)(struct file_lock *); |
| 1069 | int (*fl_mylease)(struct file_lock *, struct file_lock *); | ||
| 1070 | int (*fl_change)(struct file_lock **, int); | 1069 | int (*fl_change)(struct file_lock **, int); |
| 1071 | }; | 1070 | }; |
| 1072 | 1071 | ||
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 4b47ed96f131..32720baf70f1 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
| @@ -35,13 +35,13 @@ static inline int gpio_request(unsigned gpio, const char *label) | |||
| 35 | return -ENOSYS; | 35 | return -ENOSYS; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | static inline int __must_check gpio_request_one(unsigned gpio, | 38 | static inline int gpio_request_one(unsigned gpio, |
| 39 | unsigned long flags, const char *label) | 39 | unsigned long flags, const char *label) |
| 40 | { | 40 | { |
| 41 | return -ENOSYS; | 41 | return -ENOSYS; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | static inline int __must_check gpio_request_array(struct gpio *array, size_t num) | 44 | static inline int gpio_request_array(struct gpio *array, size_t num) |
| 45 | { | 45 | { |
| 46 | return -ENOSYS; | 46 | return -ENOSYS; |
| 47 | } | 47 | } |
diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h index b2adbb4b2f73..5bad17d1acde 100644 --- a/include/linux/list_bl.h +++ b/include/linux/list_bl.h | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | * some fast and compact auxiliary data. | 16 | * some fast and compact auxiliary data. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #if defined(CONFIG_SMP) | 19 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
| 20 | #define LIST_BL_LOCKMASK 1UL | 20 | #define LIST_BL_LOCKMASK 1UL |
| 21 | #else | 21 | #else |
| 22 | #define LIST_BL_LOCKMASK 0UL | 22 | #define LIST_BL_LOCKMASK 0UL |
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index 85cf2c28fac6..37f56b7c4c15 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h | |||
| @@ -74,30 +74,37 @@ | |||
| 74 | #define AB8500_INT_ACC_DETECT_21DB_F 37 | 74 | #define AB8500_INT_ACC_DETECT_21DB_F 37 |
| 75 | #define AB8500_INT_ACC_DETECT_21DB_R 38 | 75 | #define AB8500_INT_ACC_DETECT_21DB_R 38 |
| 76 | #define AB8500_INT_GP_SW_ADC_CONV_END 39 | 76 | #define AB8500_INT_GP_SW_ADC_CONV_END 39 |
| 77 | #define AB8500_INT_BTEMP_LOW 72 | 77 | #define AB8500_INT_ADP_SOURCE_ERROR 72 |
| 78 | #define AB8500_INT_BTEMP_LOW_MEDIUM 73 | 78 | #define AB8500_INT_ADP_SINK_ERROR 73 |
| 79 | #define AB8500_INT_BTEMP_MEDIUM_HIGH 74 | 79 | #define AB8500_INT_ADP_PROBE_PLUG 74 |
| 80 | #define AB8500_INT_BTEMP_HIGH 75 | 80 | #define AB8500_INT_ADP_PROBE_UNPLUG 75 |
| 81 | #define AB8500_INT_USB_CHARGER_NOT_OK 81 | 81 | #define AB8500_INT_ADP_SENSE_OFF 76 |
| 82 | #define AB8500_INT_ID_WAKEUP_R 82 | 82 | #define AB8500_INT_USB_PHY_POWER_ERR 78 |
| 83 | #define AB8500_INT_ID_DET_R1R 84 | 83 | #define AB8500_INT_USB_LINK_STATUS 79 |
| 84 | #define AB8500_INT_ID_DET_R2R 85 | 84 | #define AB8500_INT_BTEMP_LOW 80 |
| 85 | #define AB8500_INT_ID_DET_R3R 86 | 85 | #define AB8500_INT_BTEMP_LOW_MEDIUM 81 |
| 86 | #define AB8500_INT_ID_DET_R4R 87 | 86 | #define AB8500_INT_BTEMP_MEDIUM_HIGH 82 |
| 87 | #define AB8500_INT_ID_WAKEUP_F 88 | 87 | #define AB8500_INT_BTEMP_HIGH 83 |
| 88 | #define AB8500_INT_ID_DET_R1F 90 | 88 | #define AB8500_INT_USB_CHARGER_NOT_OK 89 |
| 89 | #define AB8500_INT_ID_DET_R2F 91 | 89 | #define AB8500_INT_ID_WAKEUP_R 90 |
| 90 | #define AB8500_INT_ID_DET_R3F 92 | 90 | #define AB8500_INT_ID_DET_R1R 92 |
| 91 | #define AB8500_INT_ID_DET_R4F 93 | 91 | #define AB8500_INT_ID_DET_R2R 93 |
| 92 | #define AB8500_INT_USB_CHG_DET_DONE 94 | 92 | #define AB8500_INT_ID_DET_R3R 94 |
| 93 | #define AB8500_INT_USB_CH_TH_PROT_F 96 | 93 | #define AB8500_INT_ID_DET_R4R 95 |
| 94 | #define AB8500_INT_USB_CH_TH_PROP_R 97 | 94 | #define AB8500_INT_ID_WAKEUP_F 96 |
| 95 | #define AB8500_INT_MAIN_CH_TH_PROP_F 98 | 95 | #define AB8500_INT_ID_DET_R1F 98 |
| 96 | #define AB8500_INT_MAIN_CH_TH_PROT_R 99 | 96 | #define AB8500_INT_ID_DET_R2F 99 |
| 97 | #define AB8500_INT_USB_CHARGER_NOT_OKF 103 | 97 | #define AB8500_INT_ID_DET_R3F 100 |
| 98 | #define AB8500_INT_ID_DET_R4F 101 | ||
| 99 | #define AB8500_INT_USB_CHG_DET_DONE 102 | ||
| 100 | #define AB8500_INT_USB_CH_TH_PROT_F 104 | ||
| 101 | #define AB8500_INT_USB_CH_TH_PROT_R 105 | ||
| 102 | #define AB8500_INT_MAIN_CH_TH_PROT_F 106 | ||
| 103 | #define AB8500_INT_MAIN_CH_TH_PROT_R 107 | ||
| 104 | #define AB8500_INT_USB_CHARGER_NOT_OKF 111 | ||
| 98 | 105 | ||
| 99 | #define AB8500_NR_IRQS 104 | 106 | #define AB8500_NR_IRQS 112 |
| 100 | #define AB8500_NUM_IRQ_REGS 13 | 107 | #define AB8500_NUM_IRQ_REGS 14 |
| 101 | 108 | ||
| 102 | /** | 109 | /** |
| 103 | * struct ab8500 - ab8500 internal structure | 110 | * struct ab8500 - ab8500 internal structure |
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 5582ab3d3e48..835996e167e1 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h | |||
| @@ -47,6 +47,12 @@ struct mfd_cell { | |||
| 47 | 47 | ||
| 48 | /* don't check for resource conflicts */ | 48 | /* don't check for resource conflicts */ |
| 49 | bool ignore_resource_conflicts; | 49 | bool ignore_resource_conflicts; |
| 50 | |||
| 51 | /* | ||
| 52 | * Disable runtime PM callbacks for this subdevice - see | ||
| 53 | * pm_runtime_no_callbacks(). | ||
| 54 | */ | ||
| 55 | bool pm_runtime_no_callbacks; | ||
| 50 | }; | 56 | }; |
| 51 | 57 | ||
| 52 | extern int mfd_add_devices(struct device *parent, int id, | 58 | extern int mfd_add_devices(struct device *parent, int id, |
diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h index 7363dea6bbcd..effa5d3b96ae 100644 --- a/include/linux/mfd/max8998-private.h +++ b/include/linux/mfd/max8998-private.h | |||
| @@ -159,10 +159,12 @@ struct max8998_dev { | |||
| 159 | u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; | 159 | u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; |
| 160 | u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; | 160 | u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; |
| 161 | int type; | 161 | int type; |
| 162 | bool wakeup; | ||
| 162 | }; | 163 | }; |
| 163 | 164 | ||
| 164 | int max8998_irq_init(struct max8998_dev *max8998); | 165 | int max8998_irq_init(struct max8998_dev *max8998); |
| 165 | void max8998_irq_exit(struct max8998_dev *max8998); | 166 | void max8998_irq_exit(struct max8998_dev *max8998); |
| 167 | int max8998_irq_resume(struct max8998_dev *max8998); | ||
| 166 | 168 | ||
| 167 | extern int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); | 169 | extern int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); |
| 168 | extern int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, | 170 | extern int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, |
diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h index f8c9f884aff2..61daa167b576 100644 --- a/include/linux/mfd/max8998.h +++ b/include/linux/mfd/max8998.h | |||
| @@ -70,24 +70,43 @@ struct max8998_regulator_data { | |||
| 70 | * @num_regulators: number of regultors used | 70 | * @num_regulators: number of regultors used |
| 71 | * @irq_base: base IRQ number for max8998, required for IRQs | 71 | * @irq_base: base IRQ number for max8998, required for IRQs |
| 72 | * @ono: power onoff IRQ number for max8998 | 72 | * @ono: power onoff IRQ number for max8998 |
| 73 | * @buck1_max_voltage1: BUCK1 maximum alowed voltage register 1 | 73 | * @buck_voltage_lock: Do NOT change the values of the following six |
| 74 | * @buck1_max_voltage2: BUCK1 maximum alowed voltage register 2 | 74 | * registers set by buck?_voltage?. The voltage of BUCK1/2 cannot |
| 75 | * @buck2_max_voltage: BUCK2 maximum alowed voltage | 75 | * be other than the preset values. |
| 76 | * @buck1_voltage1: BUCK1 DVS mode 1 voltage register | ||
| 77 | * @buck1_voltage2: BUCK1 DVS mode 2 voltage register | ||
| 78 | * @buck1_voltage3: BUCK1 DVS mode 3 voltage register | ||
| 79 | * @buck1_voltage4: BUCK1 DVS mode 4 voltage register | ||
| 80 | * @buck2_voltage1: BUCK2 DVS mode 1 voltage register | ||
| 81 | * @buck2_voltage2: BUCK2 DVS mode 2 voltage register | ||
| 76 | * @buck1_set1: BUCK1 gpio pin 1 to set output voltage | 82 | * @buck1_set1: BUCK1 gpio pin 1 to set output voltage |
| 77 | * @buck1_set2: BUCK1 gpio pin 2 to set output voltage | 83 | * @buck1_set2: BUCK1 gpio pin 2 to set output voltage |
| 84 | * @buck1_default_idx: Default for BUCK1 gpio pin 1, 2 | ||
| 78 | * @buck2_set3: BUCK2 gpio pin to set output voltage | 85 | * @buck2_set3: BUCK2 gpio pin to set output voltage |
| 86 | * @buck2_default_idx: Default for BUCK2 gpio pin. | ||
| 87 | * @wakeup: Allow to wake up from suspend | ||
| 88 | * @rtc_delay: LP3974 RTC chip bug that requires delay after a register | ||
| 89 | * write before reading it. | ||
| 79 | */ | 90 | */ |
| 80 | struct max8998_platform_data { | 91 | struct max8998_platform_data { |
| 81 | struct max8998_regulator_data *regulators; | 92 | struct max8998_regulator_data *regulators; |
| 82 | int num_regulators; | 93 | int num_regulators; |
| 83 | int irq_base; | 94 | int irq_base; |
| 84 | int ono; | 95 | int ono; |
| 85 | int buck1_max_voltage1; | 96 | bool buck_voltage_lock; |
| 86 | int buck1_max_voltage2; | 97 | int buck1_voltage1; |
| 87 | int buck2_max_voltage; | 98 | int buck1_voltage2; |
| 99 | int buck1_voltage3; | ||
| 100 | int buck1_voltage4; | ||
| 101 | int buck2_voltage1; | ||
| 102 | int buck2_voltage2; | ||
| 88 | int buck1_set1; | 103 | int buck1_set1; |
| 89 | int buck1_set2; | 104 | int buck1_set2; |
| 105 | int buck1_default_idx; | ||
| 90 | int buck2_set3; | 106 | int buck2_set3; |
| 107 | int buck2_default_idx; | ||
| 108 | bool wakeup; | ||
| 109 | bool rtc_delay; | ||
| 91 | }; | 110 | }; |
| 92 | 111 | ||
| 93 | #endif /* __LINUX_MFD_MAX8998_H */ | 112 | #endif /* __LINUX_MFD_MAX8998_H */ |
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index a1239c48b41a..903280d21866 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h | |||
| @@ -245,6 +245,7 @@ enum wm831x_parent { | |||
| 245 | WM8320 = 0x8320, | 245 | WM8320 = 0x8320, |
| 246 | WM8321 = 0x8321, | 246 | WM8321 = 0x8321, |
| 247 | WM8325 = 0x8325, | 247 | WM8325 = 0x8325, |
| 248 | WM8326 = 0x8326, | ||
| 248 | }; | 249 | }; |
| 249 | 250 | ||
| 250 | struct wm831x { | 251 | struct wm831x { |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index be4957cf6511..d971346b0340 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -520,9 +520,6 @@ struct netdev_queue { | |||
| 520 | * please use this field instead of dev->trans_start | 520 | * please use this field instead of dev->trans_start |
| 521 | */ | 521 | */ |
| 522 | unsigned long trans_start; | 522 | unsigned long trans_start; |
| 523 | u64 tx_bytes; | ||
| 524 | u64 tx_packets; | ||
| 525 | u64 tx_dropped; | ||
| 526 | } ____cacheline_aligned_in_smp; | 523 | } ____cacheline_aligned_in_smp; |
| 527 | 524 | ||
| 528 | static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) | 525 | static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) |
| @@ -2265,8 +2262,6 @@ extern void dev_load(struct net *net, const char *name); | |||
| 2265 | extern void dev_mcast_init(void); | 2262 | extern void dev_mcast_init(void); |
| 2266 | extern struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, | 2263 | extern struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, |
| 2267 | struct rtnl_link_stats64 *storage); | 2264 | struct rtnl_link_stats64 *storage); |
| 2268 | extern void dev_txq_stats_fold(const struct net_device *dev, | ||
| 2269 | struct rtnl_link_stats64 *stats); | ||
| 2270 | 2265 | ||
| 2271 | extern int netdev_max_backlog; | 2266 | extern int netdev_max_backlog; |
| 2272 | extern int netdev_tstamp_prequeue; | 2267 | extern int netdev_tstamp_prequeue; |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 9b46300b4305..134716e5e350 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
| @@ -65,6 +65,9 @@ | |||
| 65 | 65 | ||
| 66 | #define NFS4_CDFC4_FORE 0x1 | 66 | #define NFS4_CDFC4_FORE 0x1 |
| 67 | #define NFS4_CDFC4_BACK 0x2 | 67 | #define NFS4_CDFC4_BACK 0x2 |
| 68 | #define NFS4_CDFC4_BOTH 0x3 | ||
| 69 | #define NFS4_CDFC4_FORE_OR_BOTH 0x3 | ||
| 70 | #define NFS4_CDFC4_BACK_OR_BOTH 0x7 | ||
| 68 | 71 | ||
| 69 | #define NFS4_SET_TO_SERVER_TIME 0 | 72 | #define NFS4_SET_TO_SERVER_TIME 0 |
| 70 | #define NFS4_SET_TO_CLIENT_TIME 1 | 73 | #define NFS4_SET_TO_CLIENT_TIME 1 |
| @@ -140,6 +143,9 @@ | |||
| 140 | #define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200 | 143 | #define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200 |
| 141 | #define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400 | 144 | #define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400 |
| 142 | 145 | ||
| 146 | #define NFS4_SECINFO_STYLE4_CURRENT_FH 0 | ||
| 147 | #define NFS4_SECINFO_STYLE4_PARENT 1 | ||
| 148 | |||
| 143 | #define NFS4_MAX_UINT64 (~(u64)0) | 149 | #define NFS4_MAX_UINT64 (~(u64)0) |
| 144 | 150 | ||
| 145 | /* An NFS4 sessions server must support at least NFS4_MAX_OPS operations. | 151 | /* An NFS4 sessions server must support at least NFS4_MAX_OPS operations. |
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index 8ae78a61eea4..bd316159278c 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | #define NFSEXP_NOHIDE 0x0200 | 35 | #define NFSEXP_NOHIDE 0x0200 |
| 36 | #define NFSEXP_NOSUBTREECHECK 0x0400 | 36 | #define NFSEXP_NOSUBTREECHECK 0x0400 |
| 37 | #define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */ | 37 | #define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */ |
| 38 | #define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect */ | 38 | #define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect; no longer supported */ |
| 39 | #define NFSEXP_FSID 0x2000 | 39 | #define NFSEXP_FSID 0x2000 |
| 40 | #define NFSEXP_CROSSMOUNT 0x4000 | 40 | #define NFSEXP_CROSSMOUNT 0x4000 |
| 41 | #define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */ | 41 | #define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */ |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 2b89b712565b..821ffb954f14 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
| @@ -148,6 +148,10 @@ | |||
| 148 | * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to | 148 | * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to |
| 149 | * destination %NL80211_ATTR_MAC on the interface identified by | 149 | * destination %NL80211_ATTR_MAC on the interface identified by |
| 150 | * %NL80211_ATTR_IFINDEX. | 150 | * %NL80211_ATTR_IFINDEX. |
| 151 | * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by | ||
| 152 | * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP. | ||
| 153 | * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by | ||
| 154 | * %NL80211_ATTR_MAC. | ||
| 151 | * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the | 155 | * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the |
| 152 | * the interface identified by %NL80211_ATTR_IFINDEX. | 156 | * the interface identified by %NL80211_ATTR_IFINDEX. |
| 153 | * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC | 157 | * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC |
| @@ -612,7 +616,7 @@ enum nl80211_commands { | |||
| 612 | * consisting of a nested array. | 616 | * consisting of a nested array. |
| 613 | * | 617 | * |
| 614 | * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). | 618 | * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). |
| 615 | * @NL80211_ATTR_PLINK_ACTION: action to perform on the mesh peer link. | 619 | * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link. |
| 616 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. | 620 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. |
| 617 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path | 621 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path |
| 618 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at | 622 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at |
| @@ -879,7 +883,9 @@ enum nl80211_commands { | |||
| 879 | * See &enum nl80211_key_default_types. | 883 | * See &enum nl80211_key_default_types. |
| 880 | * | 884 | * |
| 881 | * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be | 885 | * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be |
| 882 | * changed once the mesh is active. | 886 | * changed once the mesh is active. |
| 887 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute | ||
| 888 | * containing attributes from &enum nl80211_meshconf_params. | ||
| 883 | * | 889 | * |
| 884 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 890 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
| 885 | * @__NL80211_ATTR_AFTER_LAST: internal use | 891 | * @__NL80211_ATTR_AFTER_LAST: internal use |
| @@ -1225,8 +1231,6 @@ enum nl80211_rate_info { | |||
| 1225 | * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) | 1231 | * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) |
| 1226 | * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) | 1232 | * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) |
| 1227 | * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) | 1233 | * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) |
| 1228 | * @__NL80211_STA_INFO_AFTER_LAST: internal | ||
| 1229 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | ||
| 1230 | * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) | 1234 | * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) |
| 1231 | * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute | 1235 | * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute |
| 1232 | * containing info as possible, see &enum nl80211_sta_info_txrate. | 1236 | * containing info as possible, see &enum nl80211_sta_info_txrate. |
| @@ -1236,6 +1240,11 @@ enum nl80211_rate_info { | |||
| 1236 | * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) | 1240 | * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) |
| 1237 | * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) | 1241 | * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) |
| 1238 | * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) | 1242 | * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) |
| 1243 | * @NL80211_STA_INFO_LLID: the station's mesh LLID | ||
| 1244 | * @NL80211_STA_INFO_PLID: the station's mesh PLID | ||
| 1245 | * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station | ||
| 1246 | * @__NL80211_STA_INFO_AFTER_LAST: internal | ||
| 1247 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | ||
| 1239 | */ | 1248 | */ |
| 1240 | enum nl80211_sta_info { | 1249 | enum nl80211_sta_info { |
| 1241 | __NL80211_STA_INFO_INVALID, | 1250 | __NL80211_STA_INFO_INVALID, |
| @@ -1626,7 +1635,7 @@ enum nl80211_mntr_flags { | |||
| 1626 | * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) | 1635 | * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) |
| 1627 | * that it takes for an HWMP information element to propagate across the mesh | 1636 | * that it takes for an HWMP information element to propagate across the mesh |
| 1628 | * | 1637 | * |
| 1629 | * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not | 1638 | * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not |
| 1630 | * | 1639 | * |
| 1631 | * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a | 1640 | * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a |
| 1632 | * source mesh point for path selection elements. | 1641 | * source mesh point for path selection elements. |
| @@ -1678,6 +1687,7 @@ enum nl80211_meshconf_params { | |||
| 1678 | * element that vendors will use to identify the path selection methods and | 1687 | * element that vendors will use to identify the path selection methods and |
| 1679 | * metrics in use. | 1688 | * metrics in use. |
| 1680 | * | 1689 | * |
| 1690 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number | ||
| 1681 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use | 1691 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use |
| 1682 | */ | 1692 | */ |
| 1683 | enum nl80211_mesh_setup_params { | 1693 | enum nl80211_mesh_setup_params { |
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h index 5b0c971d7cae..6d6cb7a57bb3 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h | |||
| @@ -42,9 +42,6 @@ enum { | |||
| 42 | /* flags for mem_cgroup and file and I/O status */ | 42 | /* flags for mem_cgroup and file and I/O status */ |
| 43 | PCG_MOVE_LOCK, /* For race between move_account v.s. following bits */ | 43 | PCG_MOVE_LOCK, /* For race between move_account v.s. following bits */ |
| 44 | PCG_FILE_MAPPED, /* page is accounted as "mapped" */ | 44 | PCG_FILE_MAPPED, /* page is accounted as "mapped" */ |
| 45 | PCG_FILE_DIRTY, /* page is dirty */ | ||
| 46 | PCG_FILE_WRITEBACK, /* page is under writeback */ | ||
| 47 | PCG_FILE_UNSTABLE_NFS, /* page is NFS unstable */ | ||
| 48 | /* No lock in page_cgroup */ | 45 | /* No lock in page_cgroup */ |
| 49 | PCG_ACCT_LRU, /* page has been accounted for (under lru_lock) */ | 46 | PCG_ACCT_LRU, /* page has been accounted for (under lru_lock) */ |
| 50 | }; | 47 | }; |
| @@ -65,10 +62,6 @@ static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \ | |||
| 65 | static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ | 62 | static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ |
| 66 | { return test_and_clear_bit(PCG_##lname, &pc->flags); } | 63 | { return test_and_clear_bit(PCG_##lname, &pc->flags); } |
| 67 | 64 | ||
| 68 | #define TESTSETPCGFLAG(uname, lname) \ | ||
| 69 | static inline int TestSetPageCgroup##uname(struct page_cgroup *pc) \ | ||
| 70 | { return test_and_set_bit(PCG_##lname, &pc->flags); } | ||
| 71 | |||
| 72 | /* Cache flag is set only once (at allocation) */ | 65 | /* Cache flag is set only once (at allocation) */ |
| 73 | TESTPCGFLAG(Cache, CACHE) | 66 | TESTPCGFLAG(Cache, CACHE) |
| 74 | CLEARPCGFLAG(Cache, CACHE) | 67 | CLEARPCGFLAG(Cache, CACHE) |
| @@ -88,22 +81,6 @@ SETPCGFLAG(FileMapped, FILE_MAPPED) | |||
| 88 | CLEARPCGFLAG(FileMapped, FILE_MAPPED) | 81 | CLEARPCGFLAG(FileMapped, FILE_MAPPED) |
| 89 | TESTPCGFLAG(FileMapped, FILE_MAPPED) | 82 | TESTPCGFLAG(FileMapped, FILE_MAPPED) |
| 90 | 83 | ||
| 91 | SETPCGFLAG(FileDirty, FILE_DIRTY) | ||
| 92 | CLEARPCGFLAG(FileDirty, FILE_DIRTY) | ||
| 93 | TESTPCGFLAG(FileDirty, FILE_DIRTY) | ||
| 94 | TESTCLEARPCGFLAG(FileDirty, FILE_DIRTY) | ||
| 95 | TESTSETPCGFLAG(FileDirty, FILE_DIRTY) | ||
| 96 | |||
| 97 | SETPCGFLAG(FileWriteback, FILE_WRITEBACK) | ||
| 98 | CLEARPCGFLAG(FileWriteback, FILE_WRITEBACK) | ||
| 99 | TESTPCGFLAG(FileWriteback, FILE_WRITEBACK) | ||
| 100 | |||
| 101 | SETPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) | ||
| 102 | CLEARPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) | ||
| 103 | TESTPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) | ||
| 104 | TESTCLEARPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) | ||
| 105 | TESTSETPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) | ||
| 106 | |||
| 107 | SETPCGFLAG(Migration, MIGRATION) | 84 | SETPCGFLAG(Migration, MIGRATION) |
| 108 | CLEARPCGFLAG(Migration, MIGRATION) | 85 | CLEARPCGFLAG(Migration, MIGRATION) |
| 109 | TESTPCGFLAG(Migration, MIGRATION) | 86 | TESTPCGFLAG(Migration, MIGRATION) |
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index c8b6473c5f42..479d9bb88e11 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h | |||
| @@ -40,4 +40,10 @@ static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) | |||
| 40 | { return NULL; } | 40 | { return NULL; } |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #ifdef CONFIG_ACPI_APEI | ||
| 44 | extern bool aer_acpi_firmware_first(void); | ||
| 45 | #else | ||
| 46 | static inline bool aer_acpi_firmware_first(void) { return false; } | ||
| 47 | #endif | ||
| 48 | |||
| 43 | #endif /* _PCI_ACPI_H_ */ | 49 | #endif /* _PCI_ACPI_H_ */ |
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h index 91ba0b338b47..ce6810512c66 100644 --- a/include/linux/pci-aspm.h +++ b/include/linux/pci-aspm.h | |||
| @@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev); | |||
| 27 | extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); | 27 | extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); |
| 28 | extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); | 28 | extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); |
| 29 | extern void pci_disable_link_state(struct pci_dev *pdev, int state); | 29 | extern void pci_disable_link_state(struct pci_dev *pdev, int state); |
| 30 | extern void pcie_clear_aspm(void); | ||
| 30 | extern void pcie_no_aspm(void); | 31 | extern void pcie_no_aspm(void); |
| 31 | #else | 32 | #else |
| 32 | static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) | 33 | static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) |
| @@ -41,7 +42,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) | |||
| 41 | static inline void pci_disable_link_state(struct pci_dev *pdev, int state) | 42 | static inline void pci_disable_link_state(struct pci_dev *pdev, int state) |
| 42 | { | 43 | { |
| 43 | } | 44 | } |
| 44 | 45 | static inline void pcie_clear_aspm(void) | |
| 46 | { | ||
| 47 | } | ||
| 45 | static inline void pcie_no_aspm(void) | 48 | static inline void pcie_no_aspm(void) |
| 46 | { | 49 | { |
| 47 | } | 50 | } |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7454408c41b6..9e67dcd054c4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); | |||
| 806 | 806 | ||
| 807 | /* Power management related routines */ | 807 | /* Power management related routines */ |
| 808 | int pci_save_state(struct pci_dev *dev); | 808 | int pci_save_state(struct pci_dev *dev); |
| 809 | int pci_restore_state(struct pci_dev *dev); | 809 | void pci_restore_state(struct pci_dev *dev); |
| 810 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state); | 810 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state); |
| 811 | int pci_set_power_state(struct pci_dev *dev, pci_power_t state); | 811 | int pci_set_power_state(struct pci_dev *dev, pci_power_t state); |
| 812 | pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); | 812 | pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); |
| @@ -820,7 +820,6 @@ int pci_prepare_to_sleep(struct pci_dev *dev); | |||
| 820 | int pci_back_from_sleep(struct pci_dev *dev); | 820 | int pci_back_from_sleep(struct pci_dev *dev); |
| 821 | bool pci_dev_run_wake(struct pci_dev *dev); | 821 | bool pci_dev_run_wake(struct pci_dev *dev); |
| 822 | bool pci_check_pme_status(struct pci_dev *dev); | 822 | bool pci_check_pme_status(struct pci_dev *dev); |
| 823 | void pci_wakeup_event(struct pci_dev *dev); | ||
| 824 | void pci_pme_wakeup_bus(struct pci_bus *bus); | 823 | void pci_pme_wakeup_bus(struct pci_bus *bus); |
| 825 | 824 | ||
| 826 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, | 825 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, |
| @@ -994,6 +993,9 @@ extern void pci_restore_msi_state(struct pci_dev *dev); | |||
| 994 | extern int pci_msi_enabled(void); | 993 | extern int pci_msi_enabled(void); |
| 995 | #endif | 994 | #endif |
| 996 | 995 | ||
| 996 | extern bool pcie_ports_disabled; | ||
| 997 | extern bool pcie_ports_auto; | ||
| 998 | |||
| 997 | #ifndef CONFIG_PCIEASPM | 999 | #ifndef CONFIG_PCIEASPM |
| 998 | static inline int pcie_aspm_enabled(void) | 1000 | static inline int pcie_aspm_enabled(void) |
| 999 | { | 1001 | { |
| @@ -1003,6 +1005,14 @@ static inline int pcie_aspm_enabled(void) | |||
| 1003 | extern int pcie_aspm_enabled(void); | 1005 | extern int pcie_aspm_enabled(void); |
| 1004 | #endif | 1006 | #endif |
| 1005 | 1007 | ||
| 1008 | #ifdef CONFIG_PCIEAER | ||
| 1009 | void pci_no_aer(void); | ||
| 1010 | bool pci_aer_available(void); | ||
| 1011 | #else | ||
| 1012 | static inline void pci_no_aer(void) { } | ||
| 1013 | static inline bool pci_aer_available(void) { return false; } | ||
| 1014 | #endif | ||
| 1015 | |||
| 1006 | #ifndef CONFIG_PCIE_ECRC | 1016 | #ifndef CONFIG_PCIE_ECRC |
| 1007 | static inline void pcie_set_ecrc_checking(struct pci_dev *dev) | 1017 | static inline void pcie_set_ecrc_checking(struct pci_dev *dev) |
| 1008 | { | 1018 | { |
| @@ -1168,10 +1178,8 @@ static inline int pci_save_state(struct pci_dev *dev) | |||
| 1168 | return 0; | 1178 | return 0; |
| 1169 | } | 1179 | } |
| 1170 | 1180 | ||
| 1171 | static inline int pci_restore_state(struct pci_dev *dev) | 1181 | static inline void pci_restore_state(struct pci_dev *dev) |
| 1172 | { | 1182 | { } |
| 1173 | return 0; | ||
| 1174 | } | ||
| 1175 | 1183 | ||
| 1176 | static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | 1184 | static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) |
| 1177 | { | 1185 | { |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ae0dc453e3e2..3adb06ebf841 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2478,7 +2478,8 @@ | |||
| 2478 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 | 2478 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 |
| 2479 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f | 2479 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f |
| 2480 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 | 2480 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 |
| 2481 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40 | 2481 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 |
| 2482 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 | ||
| 2482 | #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 | 2483 | #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 |
| 2483 | #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 | 2484 | #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 |
| 2484 | #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 | 2485 | #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 |
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index af83076c31a6..5b7e6b1ba54f 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h | |||
| @@ -309,6 +309,14 @@ | |||
| 309 | #define PCI_MSIX_PBA 8 | 309 | #define PCI_MSIX_PBA 8 |
| 310 | #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) | 310 | #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) |
| 311 | 311 | ||
| 312 | /* MSI-X entry's format */ | ||
| 313 | #define PCI_MSIX_ENTRY_SIZE 16 | ||
| 314 | #define PCI_MSIX_ENTRY_LOWER_ADDR 0 | ||
| 315 | #define PCI_MSIX_ENTRY_UPPER_ADDR 4 | ||
| 316 | #define PCI_MSIX_ENTRY_DATA 8 | ||
| 317 | #define PCI_MSIX_ENTRY_VECTOR_CTRL 12 | ||
| 318 | #define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 | ||
| 319 | |||
| 312 | /* CompactPCI Hotswap Register */ | 320 | /* CompactPCI Hotswap Register */ |
| 313 | 321 | ||
| 314 | #define PCI_CHSWP_CSR 2 /* Control and Status Register */ | 322 | #define PCI_CHSWP_CSR 2 /* Control and Status Register */ |
| @@ -496,6 +504,8 @@ | |||
| 496 | #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ | 504 | #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ |
| 497 | #define PCI_EXP_RTCAP 30 /* Root Capabilities */ | 505 | #define PCI_EXP_RTCAP 30 /* Root Capabilities */ |
| 498 | #define PCI_EXP_RTSTA 32 /* Root Status */ | 506 | #define PCI_EXP_RTSTA 32 /* Root Status */ |
| 507 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | ||
| 508 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | ||
| 499 | #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ | 509 | #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ |
| 500 | #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ | 510 | #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ |
| 501 | #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ | 511 | #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ |
diff --git a/include/linux/power/gpio-charger.h b/include/linux/power/gpio-charger.h new file mode 100644 index 000000000000..de1dfe09a03d --- /dev/null +++ b/include/linux/power/gpio-charger.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * You should have received a copy of the GNU General Public License along | ||
| 10 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 11 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __LINUX_POWER_GPIO_CHARGER_H__ | ||
| 16 | #define __LINUX_POWER_GPIO_CHARGER_H__ | ||
| 17 | |||
| 18 | #include <linux/power_supply.h> | ||
| 19 | #include <linux/types.h> | ||
| 20 | |||
| 21 | /** | ||
| 22 | * struct gpio_charger_platform_data - platform_data for gpio_charger devices | ||
| 23 | * @name: Name for the chargers power_supply device | ||
| 24 | * @type: Type of the charger | ||
| 25 | * @gpio: GPIO which is used to indicate the chargers status | ||
| 26 | * @gpio_active_low: Should be set to 1 if the GPIO is active low otherwise 0 | ||
| 27 | * @supplied_to: Array of battery names to which this chargers supplies power | ||
| 28 | * @num_supplicants: Number of entries in the supplied_to array | ||
| 29 | */ | ||
| 30 | struct gpio_charger_platform_data { | ||
| 31 | const char *name; | ||
| 32 | enum power_supply_type type; | ||
| 33 | |||
| 34 | int gpio; | ||
| 35 | int gpio_active_low; | ||
| 36 | |||
| 37 | char **supplied_to; | ||
| 38 | size_t num_supplicants; | ||
| 39 | }; | ||
| 40 | |||
| 41 | #endif | ||
diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h new file mode 100644 index 000000000000..7995deb8bfc1 --- /dev/null +++ b/include/linux/power/max17042_battery.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * Fuel gauge driver for Maxim 17042 / 8966 / 8997 | ||
| 3 | * Note that Maxim 8966 and 8997 are mfd and this is its subdevice. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2011 Samsung Electronics | ||
| 6 | * MyungJoo Ham <myungjoo.ham@samsung.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef __MAX17042_BATTERY_H_ | ||
| 24 | #define __MAX17042_BATTERY_H_ | ||
| 25 | |||
| 26 | struct max17042_platform_data { | ||
| 27 | bool enable_current_sense; | ||
| 28 | }; | ||
| 29 | |||
| 30 | #endif /* __MAX17042_BATTERY_H_ */ | ||
diff --git a/include/linux/s3c_adc_battery.h b/include/linux/s3c_adc_battery.h index dbce22faa660..fbe58b7e63eb 100644 --- a/include/linux/s3c_adc_battery.h +++ b/include/linux/s3c_adc_battery.h | |||
| @@ -14,6 +14,7 @@ struct s3c_adc_bat_pdata { | |||
| 14 | void (*disable_charger)(void); | 14 | void (*disable_charger)(void); |
| 15 | 15 | ||
| 16 | int gpio_charge_finished; | 16 | int gpio_charge_finished; |
| 17 | int gpio_inverted; | ||
| 17 | 18 | ||
| 18 | const struct s3c_adc_bat_thresh *lut_noac; | 19 | const struct s3c_adc_bat_thresh *lut_noac; |
| 19 | unsigned int lut_noac_cnt; | 20 | unsigned int lut_noac_cnt; |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 20ec0a64cb9f..bf221d65d9ad 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -255,6 +255,11 @@ typedef unsigned int sk_buff_data_t; | |||
| 255 | typedef unsigned char *sk_buff_data_t; | 255 | typedef unsigned char *sk_buff_data_t; |
| 256 | #endif | 256 | #endif |
| 257 | 257 | ||
| 258 | #if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \ | ||
| 259 | defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE) | ||
| 260 | #define NET_SKBUFF_NF_DEFRAG_NEEDED 1 | ||
| 261 | #endif | ||
| 262 | |||
| 258 | /** | 263 | /** |
| 259 | * struct sk_buff - socket buffer | 264 | * struct sk_buff - socket buffer |
| 260 | * @next: Next buffer in list | 265 | * @next: Next buffer in list |
| @@ -362,6 +367,8 @@ struct sk_buff { | |||
| 362 | void (*destructor)(struct sk_buff *skb); | 367 | void (*destructor)(struct sk_buff *skb); |
| 363 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 368 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
| 364 | struct nf_conntrack *nfct; | 369 | struct nf_conntrack *nfct; |
| 370 | #endif | ||
| 371 | #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED | ||
| 365 | struct sk_buff *nfct_reasm; | 372 | struct sk_buff *nfct_reasm; |
| 366 | #endif | 373 | #endif |
| 367 | #ifdef CONFIG_BRIDGE_NETFILTER | 374 | #ifdef CONFIG_BRIDGE_NETFILTER |
| @@ -2057,6 +2064,8 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct) | |||
| 2057 | if (nfct) | 2064 | if (nfct) |
| 2058 | atomic_inc(&nfct->use); | 2065 | atomic_inc(&nfct->use); |
| 2059 | } | 2066 | } |
| 2067 | #endif | ||
| 2068 | #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED | ||
| 2060 | static inline void nf_conntrack_get_reasm(struct sk_buff *skb) | 2069 | static inline void nf_conntrack_get_reasm(struct sk_buff *skb) |
| 2061 | { | 2070 | { |
| 2062 | if (skb) | 2071 | if (skb) |
| @@ -2085,6 +2094,8 @@ static inline void nf_reset(struct sk_buff *skb) | |||
| 2085 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 2094 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
| 2086 | nf_conntrack_put(skb->nfct); | 2095 | nf_conntrack_put(skb->nfct); |
| 2087 | skb->nfct = NULL; | 2096 | skb->nfct = NULL; |
| 2097 | #endif | ||
| 2098 | #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED | ||
| 2088 | nf_conntrack_put_reasm(skb->nfct_reasm); | 2099 | nf_conntrack_put_reasm(skb->nfct_reasm); |
| 2089 | skb->nfct_reasm = NULL; | 2100 | skb->nfct_reasm = NULL; |
| 2090 | #endif | 2101 | #endif |
| @@ -2101,6 +2112,8 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src) | |||
| 2101 | dst->nfct = src->nfct; | 2112 | dst->nfct = src->nfct; |
| 2102 | nf_conntrack_get(src->nfct); | 2113 | nf_conntrack_get(src->nfct); |
| 2103 | dst->nfctinfo = src->nfctinfo; | 2114 | dst->nfctinfo = src->nfctinfo; |
| 2115 | #endif | ||
| 2116 | #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED | ||
| 2104 | dst->nfct_reasm = src->nfct_reasm; | 2117 | dst->nfct_reasm = src->nfct_reasm; |
| 2105 | nf_conntrack_get_reasm(src->nfct_reasm); | 2118 | nf_conntrack_get_reasm(src->nfct_reasm); |
| 2106 | #endif | 2119 | #endif |
| @@ -2114,6 +2127,8 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src) | |||
| 2114 | { | 2127 | { |
| 2115 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 2128 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
| 2116 | nf_conntrack_put(dst->nfct); | 2129 | nf_conntrack_put(dst->nfct); |
| 2130 | #endif | ||
| 2131 | #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED | ||
| 2117 | nf_conntrack_put_reasm(dst->nfct_reasm); | 2132 | nf_conntrack_put_reasm(dst->nfct_reasm); |
| 2118 | #endif | 2133 | #endif |
| 2119 | #ifdef CONFIG_BRIDGE_NETFILTER | 2134 | #ifdef CONFIG_BRIDGE_NETFILTER |
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 78aa104250b7..7898ea13de70 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h | |||
| @@ -256,10 +256,13 @@ static inline time_t get_expiry(char **bpp) | |||
| 256 | return rv - boot.tv_sec; | 256 | return rv - boot.tv_sec; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 259 | static inline void sunrpc_invalidate(struct cache_head *h, | 260 | static inline void sunrpc_invalidate(struct cache_head *h, |
| 260 | struct cache_detail *detail) | 261 | struct cache_detail *detail) |
| 261 | { | 262 | { |
| 262 | h->expiry_time = seconds_since_boot() - 1; | 263 | h->expiry_time = seconds_since_boot() - 1; |
| 263 | detail->nextcheck = seconds_since_boot(); | 264 | detail->nextcheck = seconds_since_boot(); |
| 264 | } | 265 | } |
| 266 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 267 | |||
| 265 | #endif /* _LINUX_SUNRPC_CACHE_H_ */ | 268 | #endif /* _LINUX_SUNRPC_CACHE_H_ */ |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index c81d4d8be3a9..ea29330b78bd 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
| @@ -269,6 +269,7 @@ struct svc_rqst { | |||
| 269 | struct cache_req rq_chandle; /* handle passed to caches for | 269 | struct cache_req rq_chandle; /* handle passed to caches for |
| 270 | * request delaying | 270 | * request delaying |
| 271 | */ | 271 | */ |
| 272 | bool rq_dropme; | ||
| 272 | /* Catering to nfsd */ | 273 | /* Catering to nfsd */ |
| 273 | struct auth_domain * rq_client; /* RPC peer info */ | 274 | struct auth_domain * rq_client; /* RPC peer info */ |
| 274 | struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ | 275 | struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ |
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 357da5e0daa3..059877b4d85b 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h | |||
| @@ -63,7 +63,6 @@ struct svc_xprt { | |||
| 63 | #define XPT_LISTENER 11 /* listening endpoint */ | 63 | #define XPT_LISTENER 11 /* listening endpoint */ |
| 64 | #define XPT_CACHE_AUTH 12 /* cache auth info */ | 64 | #define XPT_CACHE_AUTH 12 /* cache auth info */ |
| 65 | 65 | ||
| 66 | struct svc_pool *xpt_pool; /* current pool iff queued */ | ||
| 67 | struct svc_serv *xpt_server; /* service for transport */ | 66 | struct svc_serv *xpt_server; /* service for transport */ |
| 68 | atomic_t xpt_reserved; /* space on outq that is rsvd */ | 67 | atomic_t xpt_reserved; /* space on outq that is rsvd */ |
| 69 | struct mutex xpt_mutex; /* to serialize sending data */ | 68 | struct mutex xpt_mutex; /* to serialize sending data */ |
| @@ -81,6 +80,7 @@ struct svc_xprt { | |||
| 81 | void *xpt_bc_sid; /* back channel session ID */ | 80 | void *xpt_bc_sid; /* back channel session ID */ |
| 82 | 81 | ||
| 83 | struct net *xpt_net; | 82 | struct net *xpt_net; |
| 83 | struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */ | ||
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) | 86 | static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) |
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 1b353a76c304..04dba23c59f2 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h | |||
| @@ -28,7 +28,6 @@ struct svc_sock { | |||
| 28 | /* private TCP part */ | 28 | /* private TCP part */ |
| 29 | u32 sk_reclen; /* length of record */ | 29 | u32 sk_reclen; /* length of record */ |
| 30 | u32 sk_tcplen; /* current read length */ | 30 | u32 sk_tcplen; /* current read length */ |
| 31 | struct rpc_xprt *sk_bc_xprt; /* NFSv4.1 backchannel xprt */ | ||
| 32 | }; | 31 | }; |
| 33 | 32 | ||
| 34 | /* | 33 | /* |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 89d10d279a20..bef0f535f746 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
| @@ -321,6 +321,7 @@ void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie); | |||
| 321 | #define XPRT_CLOSING (6) | 321 | #define XPRT_CLOSING (6) |
| 322 | #define XPRT_CONNECTION_ABORT (7) | 322 | #define XPRT_CONNECTION_ABORT (7) |
| 323 | #define XPRT_CONNECTION_CLOSE (8) | 323 | #define XPRT_CONNECTION_CLOSE (8) |
| 324 | #define XPRT_INITIALIZED (9) | ||
| 324 | 325 | ||
| 325 | static inline void xprt_set_connected(struct rpc_xprt *xprt) | 326 | static inline void xprt_set_connected(struct rpc_xprt *xprt) |
| 326 | { | 327 | { |
diff --git a/include/net/ah.h b/include/net/ah.h index be7798dea6f4..ca95b98969dd 100644 --- a/include/net/ah.h +++ b/include/net/ah.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include <linux/skbuff.h> | 4 | #include <linux/skbuff.h> |
| 5 | 5 | ||
| 6 | /* This is the maximum truncated ICV length that we know of. */ | 6 | /* This is the maximum truncated ICV length that we know of. */ |
| 7 | #define MAX_AH_AUTH_LEN 16 | 7 | #define MAX_AH_AUTH_LEN 64 |
| 8 | 8 | ||
| 9 | struct crypto_ahash; | 9 | struct crypto_ahash; |
| 10 | 10 | ||
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index bcc9f448ec4e..1322695beb52 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
| @@ -1103,6 +1103,8 @@ struct cfg80211_pmksa { | |||
| 1103 | * @change_mpath: change a given mesh path | 1103 | * @change_mpath: change a given mesh path |
| 1104 | * @get_mpath: get a mesh path for the given parameters | 1104 | * @get_mpath: get a mesh path for the given parameters |
| 1105 | * @dump_mpath: dump mesh path callback -- resume dump at index @idx | 1105 | * @dump_mpath: dump mesh path callback -- resume dump at index @idx |
| 1106 | * @join_mesh: join the mesh network with the specified parameters | ||
| 1107 | * @leave_mesh: leave the current mesh network | ||
| 1106 | * | 1108 | * |
| 1107 | * @get_mesh_config: Get the current mesh configuration | 1109 | * @get_mesh_config: Get the current mesh configuration |
| 1108 | * | 1110 | * |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5b3fd5add7a4..62c0ce2d1dc8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -337,6 +337,10 @@ struct ieee80211_bss_conf { | |||
| 337 | * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame | 337 | * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame |
| 338 | * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this | 338 | * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this |
| 339 | * frame and selects the maximum number of streams that it can use. | 339 | * frame and selects the maximum number of streams that it can use. |
| 340 | * @IEEE80211_TX_CTL_TX_OFFCHAN: Marks this packet to be transmitted on | ||
| 341 | * the off-channel channel when a remain-on-channel offload is done | ||
| 342 | * in hardware -- normal packets still flow and are expected to be | ||
| 343 | * handled properly by the device. | ||
| 340 | * | 344 | * |
| 341 | * Note: If you have to add new flags to the enumeration, then don't | 345 | * Note: If you have to add new flags to the enumeration, then don't |
| 342 | * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. | 346 | * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. |
| @@ -1753,6 +1757,16 @@ enum ieee80211_ampdu_mlme_action { | |||
| 1753 | * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX). | 1757 | * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX). |
| 1754 | * | 1758 | * |
| 1755 | * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). | 1759 | * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). |
| 1760 | * | ||
| 1761 | * @remain_on_channel: Starts an off-channel period on the given channel, must | ||
| 1762 | * call back to ieee80211_ready_on_channel() when on that channel. Note | ||
| 1763 | * that normal channel traffic is not stopped as this is intended for hw | ||
| 1764 | * offload. Frames to transmit on the off-channel channel are transmitted | ||
| 1765 | * normally except for the %IEEE80211_TX_CTL_TX_OFFCHAN flag. When the | ||
| 1766 | * duration (which will always be non-zero) expires, the driver must call | ||
| 1767 | * ieee80211_remain_on_channel_expired(). This callback may sleep. | ||
| 1768 | * @cancel_remain_on_channel: Requests that an ongoing off-channel period is | ||
| 1769 | * aborted before it expires. This callback may sleep. | ||
| 1756 | */ | 1770 | */ |
| 1757 | struct ieee80211_ops { | 1771 | struct ieee80211_ops { |
| 1758 | int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); | 1772 | int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); |
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h index 1ee717eb5b09..a4c993685795 100644 --- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h | |||
| @@ -7,16 +7,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; | |||
| 7 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; | 7 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; |
| 8 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; | 8 | extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; |
| 9 | 9 | ||
| 10 | extern int nf_ct_frag6_init(void); | ||
| 11 | extern void nf_ct_frag6_cleanup(void); | ||
| 12 | extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user); | ||
| 13 | extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, | ||
| 14 | struct net_device *in, | ||
| 15 | struct net_device *out, | ||
| 16 | int (*okfn)(struct sk_buff *)); | ||
| 17 | |||
| 18 | struct inet_frags_ctl; | ||
| 19 | |||
| 20 | #include <linux/sysctl.h> | 10 | #include <linux/sysctl.h> |
| 21 | extern struct ctl_table nf_ct_ipv6_sysctl_table[]; | 11 | extern struct ctl_table nf_ct_ipv6_sysctl_table[]; |
| 22 | 12 | ||
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h index 94dd54d76b48..fd79c9a1779d 100644 --- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h | |||
| @@ -3,4 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | extern void nf_defrag_ipv6_enable(void); | 4 | extern void nf_defrag_ipv6_enable(void); |
| 5 | 5 | ||
| 6 | extern int nf_ct_frag6_init(void); | ||
| 7 | extern void nf_ct_frag6_cleanup(void); | ||
| 8 | extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user); | ||
| 9 | extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, | ||
| 10 | struct net_device *in, | ||
| 11 | struct net_device *out, | ||
| 12 | int (*okfn)(struct sk_buff *)); | ||
| 13 | |||
| 14 | struct inet_frags_ctl; | ||
| 15 | |||
| 6 | #endif /* _NF_DEFRAG_IPV6_H */ | 16 | #endif /* _NF_DEFRAG_IPV6_H */ |
diff --git a/include/net/red.h b/include/net/red.h index 995108e54d9f..3319f16b3beb 100644 --- a/include/net/red.h +++ b/include/net/red.h | |||
| @@ -97,7 +97,6 @@ struct red_stats { | |||
| 97 | u32 forced_mark; /* Forced marks, qavg > max_thresh */ | 97 | u32 forced_mark; /* Forced marks, qavg > max_thresh */ |
| 98 | u32 pdrop; /* Drops due to queue limits */ | 98 | u32 pdrop; /* Drops due to queue limits */ |
| 99 | u32 other; /* Drops due to drop() calls */ | 99 | u32 other; /* Drops due to drop() calls */ |
| 100 | u32 backlog; | ||
| 101 | }; | 100 | }; |
| 102 | 101 | ||
| 103 | struct red_parms { | 102 | struct red_parms { |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 5c5f4cc2e99a..b24d7027b83c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -764,6 +764,7 @@ EXPORT_SYMBOL_GPL(cgroup_unlock); | |||
| 764 | */ | 764 | */ |
| 765 | 765 | ||
| 766 | static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); | 766 | static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); |
| 767 | static struct dentry *cgroup_lookup(struct inode *, struct dentry *, struct nameidata *); | ||
| 767 | static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); | 768 | static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); |
| 768 | static int cgroup_populate_dir(struct cgroup *cgrp); | 769 | static int cgroup_populate_dir(struct cgroup *cgrp); |
| 769 | static const struct inode_operations cgroup_dir_inode_operations; | 770 | static const struct inode_operations cgroup_dir_inode_operations; |
| @@ -860,6 +861,11 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
| 860 | iput(inode); | 861 | iput(inode); |
| 861 | } | 862 | } |
| 862 | 863 | ||
| 864 | static int cgroup_delete(const struct dentry *d) | ||
| 865 | { | ||
| 866 | return 1; | ||
| 867 | } | ||
| 868 | |||
| 863 | static void remove_dir(struct dentry *d) | 869 | static void remove_dir(struct dentry *d) |
| 864 | { | 870 | { |
| 865 | struct dentry *parent = dget(d->d_parent); | 871 | struct dentry *parent = dget(d->d_parent); |
| @@ -910,7 +916,7 @@ static void cgroup_d_remove_dir(struct dentry *dentry) | |||
| 910 | 916 | ||
| 911 | parent = dentry->d_parent; | 917 | parent = dentry->d_parent; |
| 912 | spin_lock(&parent->d_lock); | 918 | spin_lock(&parent->d_lock); |
| 913 | spin_lock(&dentry->d_lock); | 919 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
| 914 | list_del_init(&dentry->d_u.d_child); | 920 | list_del_init(&dentry->d_u.d_child); |
| 915 | spin_unlock(&dentry->d_lock); | 921 | spin_unlock(&dentry->d_lock); |
| 916 | spin_unlock(&parent->d_lock); | 922 | spin_unlock(&parent->d_lock); |
| @@ -1451,6 +1457,7 @@ static int cgroup_get_rootdir(struct super_block *sb) | |||
| 1451 | { | 1457 | { |
| 1452 | static const struct dentry_operations cgroup_dops = { | 1458 | static const struct dentry_operations cgroup_dops = { |
| 1453 | .d_iput = cgroup_diput, | 1459 | .d_iput = cgroup_diput, |
| 1460 | .d_delete = cgroup_delete, | ||
| 1454 | }; | 1461 | }; |
| 1455 | 1462 | ||
| 1456 | struct inode *inode = | 1463 | struct inode *inode = |
| @@ -2195,12 +2202,20 @@ static const struct file_operations cgroup_file_operations = { | |||
| 2195 | }; | 2202 | }; |
| 2196 | 2203 | ||
| 2197 | static const struct inode_operations cgroup_dir_inode_operations = { | 2204 | static const struct inode_operations cgroup_dir_inode_operations = { |
| 2198 | .lookup = simple_lookup, | 2205 | .lookup = cgroup_lookup, |
| 2199 | .mkdir = cgroup_mkdir, | 2206 | .mkdir = cgroup_mkdir, |
| 2200 | .rmdir = cgroup_rmdir, | 2207 | .rmdir = cgroup_rmdir, |
| 2201 | .rename = cgroup_rename, | 2208 | .rename = cgroup_rename, |
| 2202 | }; | 2209 | }; |
| 2203 | 2210 | ||
| 2211 | static struct dentry *cgroup_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | ||
| 2212 | { | ||
| 2213 | if (dentry->d_name.len > NAME_MAX) | ||
| 2214 | return ERR_PTR(-ENAMETOOLONG); | ||
| 2215 | d_add(dentry, NULL); | ||
| 2216 | return NULL; | ||
| 2217 | } | ||
| 2218 | |||
| 2204 | /* | 2219 | /* |
| 2205 | * Check if a file is a control file | 2220 | * Check if a file is a control file |
| 2206 | */ | 2221 | */ |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index bb86d2932394..6da5daeebab7 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
| @@ -1392,7 +1392,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 1392 | ax25_cb *ax25; | 1392 | ax25_cb *ax25; |
| 1393 | int err = 0; | 1393 | int err = 0; |
| 1394 | 1394 | ||
| 1395 | memset(fsa, 0, sizeof(fsa)); | 1395 | memset(fsa, 0, sizeof(*fsa)); |
| 1396 | lock_sock(sk); | 1396 | lock_sock(sk); |
| 1397 | ax25 = ax25_sk(sk); | 1397 | ax25 = ax25_sk(sk); |
| 1398 | 1398 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 06d0e7b25385..54277df0f735 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -5523,34 +5523,6 @@ void netdev_run_todo(void) | |||
| 5523 | } | 5523 | } |
| 5524 | } | 5524 | } |
| 5525 | 5525 | ||
| 5526 | /** | ||
| 5527 | * dev_txq_stats_fold - fold tx_queues stats | ||
| 5528 | * @dev: device to get statistics from | ||
| 5529 | * @stats: struct rtnl_link_stats64 to hold results | ||
| 5530 | */ | ||
| 5531 | void dev_txq_stats_fold(const struct net_device *dev, | ||
| 5532 | struct rtnl_link_stats64 *stats) | ||
| 5533 | { | ||
| 5534 | u64 tx_bytes = 0, tx_packets = 0, tx_dropped = 0; | ||
| 5535 | unsigned int i; | ||
| 5536 | struct netdev_queue *txq; | ||
| 5537 | |||
| 5538 | for (i = 0; i < dev->num_tx_queues; i++) { | ||
| 5539 | txq = netdev_get_tx_queue(dev, i); | ||
| 5540 | spin_lock_bh(&txq->_xmit_lock); | ||
| 5541 | tx_bytes += txq->tx_bytes; | ||
| 5542 | tx_packets += txq->tx_packets; | ||
| 5543 | tx_dropped += txq->tx_dropped; | ||
| 5544 | spin_unlock_bh(&txq->_xmit_lock); | ||
| 5545 | } | ||
| 5546 | if (tx_bytes || tx_packets || tx_dropped) { | ||
| 5547 | stats->tx_bytes = tx_bytes; | ||
| 5548 | stats->tx_packets = tx_packets; | ||
| 5549 | stats->tx_dropped = tx_dropped; | ||
| 5550 | } | ||
| 5551 | } | ||
| 5552 | EXPORT_SYMBOL(dev_txq_stats_fold); | ||
| 5553 | |||
| 5554 | /* Convert net_device_stats to rtnl_link_stats64. They have the same | 5526 | /* Convert net_device_stats to rtnl_link_stats64. They have the same |
| 5555 | * fields in the same order, with only the type differing. | 5527 | * fields in the same order, with only the type differing. |
| 5556 | */ | 5528 | */ |
| @@ -5594,7 +5566,6 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, | |||
| 5594 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); | 5566 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); |
| 5595 | } else { | 5567 | } else { |
| 5596 | netdev_stats_to_stats64(storage, &dev->stats); | 5568 | netdev_stats_to_stats64(storage, &dev->stats); |
| 5597 | dev_txq_stats_fold(dev, storage); | ||
| 5598 | } | 5569 | } |
| 5599 | storage->rx_dropped += atomic_long_read(&dev->rx_dropped); | 5570 | storage->rx_dropped += atomic_long_read(&dev->rx_dropped); |
| 5600 | return storage; | 5571 | return storage; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 19d6c21220fd..d31bb36ae0dc 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -380,6 +380,8 @@ static void skb_release_head_state(struct sk_buff *skb) | |||
| 380 | } | 380 | } |
| 381 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 381 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
| 382 | nf_conntrack_put(skb->nfct); | 382 | nf_conntrack_put(skb->nfct); |
| 383 | #endif | ||
| 384 | #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED | ||
| 383 | nf_conntrack_put_reasm(skb->nfct_reasm); | 385 | nf_conntrack_put_reasm(skb->nfct_reasm); |
| 384 | #endif | 386 | #endif |
| 385 | #ifdef CONFIG_BRIDGE_NETFILTER | 387 | #ifdef CONFIG_BRIDGE_NETFILTER |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index f9d7ac924f15..44d2b42fda56 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
| @@ -351,7 +351,7 @@ EXPORT_SYMBOL(ether_setup); | |||
| 351 | * @sizeof_priv: Size of additional driver-private structure to be allocated | 351 | * @sizeof_priv: Size of additional driver-private structure to be allocated |
| 352 | * for this Ethernet device | 352 | * for this Ethernet device |
| 353 | * @txqs: The number of TX queues this device has. | 353 | * @txqs: The number of TX queues this device has. |
| 354 | * @txqs: The number of RX queues this device has. | 354 | * @rxqs: The number of RX queues this device has. |
| 355 | * | 355 | * |
| 356 | * Fill in the fields of the device structure with Ethernet-generic | 356 | * Fill in the fields of the device structure with Ethernet-generic |
| 357 | * values. Basically does everything except registering the device. | 357 | * values. Basically does everything except registering the device. |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 94b5bf132b2e..5f8d242be3f3 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -401,6 +401,9 @@ int ip6_forward(struct sk_buff *skb) | |||
| 401 | goto drop; | 401 | goto drop; |
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | if (skb->pkt_type != PACKET_HOST) | ||
| 405 | goto drop; | ||
| 406 | |||
| 404 | skb_forward_csum(skb); | 407 | skb_forward_csum(skb); |
| 405 | 408 | ||
| 406 | /* | 409 | /* |
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index 99abfb53bab9..97c5b21b9674 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | |||
| @@ -19,13 +19,15 @@ | |||
| 19 | 19 | ||
| 20 | #include <linux/netfilter_ipv6.h> | 20 | #include <linux/netfilter_ipv6.h> |
| 21 | #include <linux/netfilter_bridge.h> | 21 | #include <linux/netfilter_bridge.h> |
| 22 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 22 | #include <net/netfilter/nf_conntrack.h> | 23 | #include <net/netfilter/nf_conntrack.h> |
| 23 | #include <net/netfilter/nf_conntrack_helper.h> | 24 | #include <net/netfilter/nf_conntrack_helper.h> |
| 24 | #include <net/netfilter/nf_conntrack_l4proto.h> | 25 | #include <net/netfilter/nf_conntrack_l4proto.h> |
| 25 | #include <net/netfilter/nf_conntrack_l3proto.h> | 26 | #include <net/netfilter/nf_conntrack_l3proto.h> |
| 26 | #include <net/netfilter/nf_conntrack_core.h> | 27 | #include <net/netfilter/nf_conntrack_core.h> |
| 27 | #include <net/netfilter/nf_conntrack_zones.h> | ||
| 28 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> | 28 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> |
| 29 | #endif | ||
| 30 | #include <net/netfilter/nf_conntrack_zones.h> | ||
| 29 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> | 31 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> |
| 30 | 32 | ||
| 31 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | 33 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, |
| @@ -33,8 +35,10 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | |||
| 33 | { | 35 | { |
| 34 | u16 zone = NF_CT_DEFAULT_ZONE; | 36 | u16 zone = NF_CT_DEFAULT_ZONE; |
| 35 | 37 | ||
| 38 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 36 | if (skb->nfct) | 39 | if (skb->nfct) |
| 37 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); | 40 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); |
| 41 | #endif | ||
| 38 | 42 | ||
| 39 | #ifdef CONFIG_BRIDGE_NETFILTER | 43 | #ifdef CONFIG_BRIDGE_NETFILTER |
| 40 | if (skb->nf_bridge && | 44 | if (skb->nf_bridge && |
| @@ -56,9 +60,11 @@ static unsigned int ipv6_defrag(unsigned int hooknum, | |||
| 56 | { | 60 | { |
| 57 | struct sk_buff *reasm; | 61 | struct sk_buff *reasm; |
| 58 | 62 | ||
| 63 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 59 | /* Previously seen (loopback)? */ | 64 | /* Previously seen (loopback)? */ |
| 60 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) | 65 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) |
| 61 | return NF_ACCEPT; | 66 | return NF_ACCEPT; |
| 67 | #endif | ||
| 62 | 68 | ||
| 63 | reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); | 69 | reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); |
| 64 | /* queued */ | 70 | /* queued */ |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 5cb8d3027b18..2b7eef37875c 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -972,7 +972,8 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 972 | free: | 972 | free: |
| 973 | kfree_skb(skb2); | 973 | kfree_skb(skb2); |
| 974 | out: | 974 | out: |
| 975 | return err; | 975 | /* this avoids a loop in nfnetlink. */ |
| 976 | return err == -EAGAIN ? -ENOBUFS : err; | ||
| 976 | } | 977 | } |
| 977 | 978 | ||
| 978 | #ifdef CONFIG_NF_NAT_NEEDED | 979 | #ifdef CONFIG_NF_NAT_NEEDED |
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 0b9bb2085ce4..74c064c0dfdd 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
| @@ -808,7 +808,7 @@ static int __init af_rxrpc_init(void) | |||
| 808 | goto error_call_jar; | 808 | goto error_call_jar; |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | rxrpc_workqueue = create_workqueue("krxrpcd"); | 811 | rxrpc_workqueue = alloc_workqueue("krxrpcd", 0, 1); |
| 812 | if (!rxrpc_workqueue) { | 812 | if (!rxrpc_workqueue) { |
| 813 | printk(KERN_NOTICE "RxRPC: Failed to allocate work queue\n"); | 813 | printk(KERN_NOTICE "RxRPC: Failed to allocate work queue\n"); |
| 814 | goto error_work_queue; | 814 | goto error_work_queue; |
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index af9360d1f6eb..84ce48eadff4 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
| @@ -59,6 +59,10 @@ struct teql_master | |||
| 59 | struct net_device *dev; | 59 | struct net_device *dev; |
| 60 | struct Qdisc *slaves; | 60 | struct Qdisc *slaves; |
| 61 | struct list_head master_list; | 61 | struct list_head master_list; |
| 62 | unsigned long tx_bytes; | ||
| 63 | unsigned long tx_packets; | ||
| 64 | unsigned long tx_errors; | ||
| 65 | unsigned long tx_dropped; | ||
| 62 | }; | 66 | }; |
| 63 | 67 | ||
| 64 | struct teql_sched_data | 68 | struct teql_sched_data |
| @@ -274,7 +278,6 @@ static inline int teql_resolve(struct sk_buff *skb, | |||
| 274 | static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev) | 278 | static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev) |
| 275 | { | 279 | { |
| 276 | struct teql_master *master = netdev_priv(dev); | 280 | struct teql_master *master = netdev_priv(dev); |
| 277 | struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); | ||
| 278 | struct Qdisc *start, *q; | 281 | struct Qdisc *start, *q; |
| 279 | int busy; | 282 | int busy; |
| 280 | int nores; | 283 | int nores; |
| @@ -314,8 +317,8 @@ restart: | |||
| 314 | __netif_tx_unlock(slave_txq); | 317 | __netif_tx_unlock(slave_txq); |
| 315 | master->slaves = NEXT_SLAVE(q); | 318 | master->slaves = NEXT_SLAVE(q); |
| 316 | netif_wake_queue(dev); | 319 | netif_wake_queue(dev); |
| 317 | txq->tx_packets++; | 320 | master->tx_packets++; |
| 318 | txq->tx_bytes += length; | 321 | master->tx_bytes += length; |
| 319 | return NETDEV_TX_OK; | 322 | return NETDEV_TX_OK; |
| 320 | } | 323 | } |
| 321 | __netif_tx_unlock(slave_txq); | 324 | __netif_tx_unlock(slave_txq); |
| @@ -342,10 +345,10 @@ restart: | |||
| 342 | netif_stop_queue(dev); | 345 | netif_stop_queue(dev); |
| 343 | return NETDEV_TX_BUSY; | 346 | return NETDEV_TX_BUSY; |
| 344 | } | 347 | } |
| 345 | dev->stats.tx_errors++; | 348 | master->tx_errors++; |
| 346 | 349 | ||
| 347 | drop: | 350 | drop: |
| 348 | txq->tx_dropped++; | 351 | master->tx_dropped++; |
| 349 | dev_kfree_skb(skb); | 352 | dev_kfree_skb(skb); |
| 350 | return NETDEV_TX_OK; | 353 | return NETDEV_TX_OK; |
| 351 | } | 354 | } |
| @@ -398,6 +401,18 @@ static int teql_master_close(struct net_device *dev) | |||
| 398 | return 0; | 401 | return 0; |
| 399 | } | 402 | } |
| 400 | 403 | ||
| 404 | static struct rtnl_link_stats64 *teql_master_stats64(struct net_device *dev, | ||
| 405 | struct rtnl_link_stats64 *stats) | ||
| 406 | { | ||
| 407 | struct teql_master *m = netdev_priv(dev); | ||
| 408 | |||
| 409 | stats->tx_packets = m->tx_packets; | ||
| 410 | stats->tx_bytes = m->tx_bytes; | ||
| 411 | stats->tx_errors = m->tx_errors; | ||
| 412 | stats->tx_dropped = m->tx_dropped; | ||
| 413 | return stats; | ||
| 414 | } | ||
| 415 | |||
| 401 | static int teql_master_mtu(struct net_device *dev, int new_mtu) | 416 | static int teql_master_mtu(struct net_device *dev, int new_mtu) |
| 402 | { | 417 | { |
| 403 | struct teql_master *m = netdev_priv(dev); | 418 | struct teql_master *m = netdev_priv(dev); |
| @@ -422,6 +437,7 @@ static const struct net_device_ops teql_netdev_ops = { | |||
| 422 | .ndo_open = teql_master_open, | 437 | .ndo_open = teql_master_open, |
| 423 | .ndo_stop = teql_master_close, | 438 | .ndo_stop = teql_master_close, |
| 424 | .ndo_start_xmit = teql_master_xmit, | 439 | .ndo_start_xmit = teql_master_xmit, |
| 440 | .ndo_get_stats64 = teql_master_stats64, | ||
| 425 | .ndo_change_mtu = teql_master_mtu, | 441 | .ndo_change_mtu = teql_master_mtu, |
| 426 | }; | 442 | }; |
| 427 | 443 | ||
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 75ee993ea057..9576f35ab701 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
| @@ -137,7 +137,7 @@ arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4]) | |||
| 137 | ms_usage = 13; | 137 | ms_usage = 13; |
| 138 | break; | 138 | break; |
| 139 | default: | 139 | default: |
| 140 | return EINVAL;; | 140 | return -EINVAL; |
| 141 | } | 141 | } |
| 142 | salt[0] = (ms_usage >> 0) & 0xff; | 142 | salt[0] = (ms_usage >> 0) & 0xff; |
| 143 | salt[1] = (ms_usage >> 8) & 0xff; | 143 | salt[1] = (ms_usage >> 8) & 0xff; |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index dec2a6fc7c12..bcdae78fdfc6 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -67,7 +67,6 @@ static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b) | |||
| 67 | 67 | ||
| 68 | #define RSI_HASHBITS 6 | 68 | #define RSI_HASHBITS 6 |
| 69 | #define RSI_HASHMAX (1<<RSI_HASHBITS) | 69 | #define RSI_HASHMAX (1<<RSI_HASHBITS) |
| 70 | #define RSI_HASHMASK (RSI_HASHMAX-1) | ||
| 71 | 70 | ||
| 72 | struct rsi { | 71 | struct rsi { |
| 73 | struct cache_head h; | 72 | struct cache_head h; |
| @@ -319,7 +318,6 @@ static struct rsi *rsi_update(struct rsi *new, struct rsi *old) | |||
| 319 | 318 | ||
| 320 | #define RSC_HASHBITS 10 | 319 | #define RSC_HASHBITS 10 |
| 321 | #define RSC_HASHMAX (1<<RSC_HASHBITS) | 320 | #define RSC_HASHMAX (1<<RSC_HASHBITS) |
| 322 | #define RSC_HASHMASK (RSC_HASHMAX-1) | ||
| 323 | 321 | ||
| 324 | #define GSS_SEQ_WIN 128 | 322 | #define GSS_SEQ_WIN 128 |
| 325 | 323 | ||
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index e433e7580e27..72ad836e4fe0 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #define RPCDBG_FACILITY RPCDBG_CACHE | 38 | #define RPCDBG_FACILITY RPCDBG_CACHE |
| 39 | 39 | ||
| 40 | static void cache_defer_req(struct cache_req *req, struct cache_head *item); | 40 | static bool cache_defer_req(struct cache_req *req, struct cache_head *item); |
| 41 | static void cache_revisit_request(struct cache_head *item); | 41 | static void cache_revisit_request(struct cache_head *item); |
| 42 | 42 | ||
| 43 | static void cache_init(struct cache_head *h) | 43 | static void cache_init(struct cache_head *h) |
| @@ -128,6 +128,7 @@ static void cache_fresh_locked(struct cache_head *head, time_t expiry) | |||
| 128 | { | 128 | { |
| 129 | head->expiry_time = expiry; | 129 | head->expiry_time = expiry; |
| 130 | head->last_refresh = seconds_since_boot(); | 130 | head->last_refresh = seconds_since_boot(); |
| 131 | smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */ | ||
| 131 | set_bit(CACHE_VALID, &head->flags); | 132 | set_bit(CACHE_VALID, &head->flags); |
| 132 | } | 133 | } |
| 133 | 134 | ||
| @@ -208,11 +209,36 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head | |||
| 208 | /* entry is valid */ | 209 | /* entry is valid */ |
| 209 | if (test_bit(CACHE_NEGATIVE, &h->flags)) | 210 | if (test_bit(CACHE_NEGATIVE, &h->flags)) |
| 210 | return -ENOENT; | 211 | return -ENOENT; |
| 211 | else | 212 | else { |
| 213 | /* | ||
| 214 | * In combination with write barrier in | ||
| 215 | * sunrpc_cache_update, ensures that anyone | ||
| 216 | * using the cache entry after this sees the | ||
| 217 | * updated contents: | ||
| 218 | */ | ||
| 219 | smp_rmb(); | ||
| 212 | return 0; | 220 | return 0; |
| 221 | } | ||
| 213 | } | 222 | } |
| 214 | } | 223 | } |
| 215 | 224 | ||
| 225 | static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h) | ||
| 226 | { | ||
| 227 | int rv; | ||
| 228 | |||
| 229 | write_lock(&detail->hash_lock); | ||
| 230 | rv = cache_is_valid(detail, h); | ||
| 231 | if (rv != -EAGAIN) { | ||
| 232 | write_unlock(&detail->hash_lock); | ||
| 233 | return rv; | ||
| 234 | } | ||
| 235 | set_bit(CACHE_NEGATIVE, &h->flags); | ||
| 236 | cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); | ||
| 237 | write_unlock(&detail->hash_lock); | ||
| 238 | cache_fresh_unlocked(h, detail); | ||
| 239 | return -ENOENT; | ||
| 240 | } | ||
| 241 | |||
| 216 | /* | 242 | /* |
| 217 | * This is the generic cache management routine for all | 243 | * This is the generic cache management routine for all |
| 218 | * the authentication caches. | 244 | * the authentication caches. |
| @@ -251,14 +277,8 @@ int cache_check(struct cache_detail *detail, | |||
| 251 | case -EINVAL: | 277 | case -EINVAL: |
| 252 | clear_bit(CACHE_PENDING, &h->flags); | 278 | clear_bit(CACHE_PENDING, &h->flags); |
| 253 | cache_revisit_request(h); | 279 | cache_revisit_request(h); |
| 254 | if (rv == -EAGAIN) { | 280 | rv = try_to_negate_entry(detail, h); |
| 255 | set_bit(CACHE_NEGATIVE, &h->flags); | ||
| 256 | cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); | ||
| 257 | cache_fresh_unlocked(h, detail); | ||
| 258 | rv = -ENOENT; | ||
| 259 | } | ||
| 260 | break; | 281 | break; |
| 261 | |||
| 262 | case -EAGAIN: | 282 | case -EAGAIN: |
| 263 | clear_bit(CACHE_PENDING, &h->flags); | 283 | clear_bit(CACHE_PENDING, &h->flags); |
| 264 | cache_revisit_request(h); | 284 | cache_revisit_request(h); |
| @@ -268,9 +288,11 @@ int cache_check(struct cache_detail *detail, | |||
| 268 | } | 288 | } |
| 269 | 289 | ||
| 270 | if (rv == -EAGAIN) { | 290 | if (rv == -EAGAIN) { |
| 271 | cache_defer_req(rqstp, h); | 291 | if (!cache_defer_req(rqstp, h)) { |
| 272 | if (!test_bit(CACHE_PENDING, &h->flags)) { | 292 | /* |
| 273 | /* Request is not deferred */ | 293 | * Request was not deferred; handle it as best |
| 294 | * we can ourselves: | ||
| 295 | */ | ||
| 274 | rv = cache_is_valid(detail, h); | 296 | rv = cache_is_valid(detail, h); |
| 275 | if (rv == -EAGAIN) | 297 | if (rv == -EAGAIN) |
| 276 | rv = -ETIMEDOUT; | 298 | rv = -ETIMEDOUT; |
| @@ -618,18 +640,19 @@ static void cache_limit_defers(void) | |||
| 618 | discard->revisit(discard, 1); | 640 | discard->revisit(discard, 1); |
| 619 | } | 641 | } |
| 620 | 642 | ||
| 621 | static void cache_defer_req(struct cache_req *req, struct cache_head *item) | 643 | /* Return true if and only if a deferred request is queued. */ |
| 644 | static bool cache_defer_req(struct cache_req *req, struct cache_head *item) | ||
| 622 | { | 645 | { |
| 623 | struct cache_deferred_req *dreq; | 646 | struct cache_deferred_req *dreq; |
| 624 | 647 | ||
| 625 | if (req->thread_wait) { | 648 | if (req->thread_wait) { |
| 626 | cache_wait_req(req, item); | 649 | cache_wait_req(req, item); |
| 627 | if (!test_bit(CACHE_PENDING, &item->flags)) | 650 | if (!test_bit(CACHE_PENDING, &item->flags)) |
| 628 | return; | 651 | return false; |
| 629 | } | 652 | } |
| 630 | dreq = req->defer(req); | 653 | dreq = req->defer(req); |
| 631 | if (dreq == NULL) | 654 | if (dreq == NULL) |
| 632 | return; | 655 | return false; |
| 633 | setup_deferral(dreq, item, 1); | 656 | setup_deferral(dreq, item, 1); |
| 634 | if (!test_bit(CACHE_PENDING, &item->flags)) | 657 | if (!test_bit(CACHE_PENDING, &item->flags)) |
| 635 | /* Bit could have been cleared before we managed to | 658 | /* Bit could have been cleared before we managed to |
| @@ -638,6 +661,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item) | |||
| 638 | cache_revisit_request(item); | 661 | cache_revisit_request(item); |
| 639 | 662 | ||
| 640 | cache_limit_defers(); | 663 | cache_limit_defers(); |
| 664 | return true; | ||
| 641 | } | 665 | } |
| 642 | 666 | ||
| 643 | static void cache_revisit_request(struct cache_head *item) | 667 | static void cache_revisit_request(struct cache_head *item) |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 0e659c665a8d..08e05a8ce025 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -1001,6 +1001,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
| 1001 | rqstp->rq_splice_ok = 1; | 1001 | rqstp->rq_splice_ok = 1; |
| 1002 | /* Will be turned off only when NFSv4 Sessions are used */ | 1002 | /* Will be turned off only when NFSv4 Sessions are used */ |
| 1003 | rqstp->rq_usedeferral = 1; | 1003 | rqstp->rq_usedeferral = 1; |
| 1004 | rqstp->rq_dropme = false; | ||
| 1004 | 1005 | ||
| 1005 | /* Setup reply header */ | 1006 | /* Setup reply header */ |
| 1006 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); | 1007 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); |
| @@ -1102,7 +1103,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
| 1102 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); | 1103 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); |
| 1103 | 1104 | ||
| 1104 | /* Encode reply */ | 1105 | /* Encode reply */ |
| 1105 | if (*statp == rpc_drop_reply) { | 1106 | if (rqstp->rq_dropme) { |
| 1106 | if (procp->pc_release) | 1107 | if (procp->pc_release) |
| 1107 | procp->pc_release(rqstp, NULL, rqstp->rq_resp); | 1108 | procp->pc_release(rqstp, NULL, rqstp->rq_resp); |
| 1108 | goto dropit; | 1109 | goto dropit; |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 3f2c5559ca1a..ab86b7927f84 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/sunrpc/stats.h> | 13 | #include <linux/sunrpc/stats.h> |
| 14 | #include <linux/sunrpc/svc_xprt.h> | 14 | #include <linux/sunrpc/svc_xprt.h> |
| 15 | #include <linux/sunrpc/svcsock.h> | 15 | #include <linux/sunrpc/svcsock.h> |
| 16 | #include <linux/sunrpc/xprt.h> | ||
| 16 | 17 | ||
| 17 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 18 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
| 18 | 19 | ||
| @@ -128,6 +129,9 @@ static void svc_xprt_free(struct kref *kref) | |||
| 128 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) | 129 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) |
| 129 | svcauth_unix_info_release(xprt); | 130 | svcauth_unix_info_release(xprt); |
| 130 | put_net(xprt->xpt_net); | 131 | put_net(xprt->xpt_net); |
| 132 | /* See comment on corresponding get in xs_setup_bc_tcp(): */ | ||
| 133 | if (xprt->xpt_bc_xprt) | ||
| 134 | xprt_put(xprt->xpt_bc_xprt); | ||
| 131 | xprt->xpt_ops->xpo_free(xprt); | 135 | xprt->xpt_ops->xpo_free(xprt); |
| 132 | module_put(owner); | 136 | module_put(owner); |
| 133 | } | 137 | } |
| @@ -303,6 +307,15 @@ static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) | |||
| 303 | list_del(&rqstp->rq_list); | 307 | list_del(&rqstp->rq_list); |
| 304 | } | 308 | } |
| 305 | 309 | ||
| 310 | static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt) | ||
| 311 | { | ||
| 312 | if (xprt->xpt_flags & ((1<<XPT_CONN)|(1<<XPT_CLOSE))) | ||
| 313 | return true; | ||
| 314 | if (xprt->xpt_flags & ((1<<XPT_DATA)|(1<<XPT_DEFERRED))) | ||
| 315 | return xprt->xpt_ops->xpo_has_wspace(xprt); | ||
| 316 | return false; | ||
| 317 | } | ||
| 318 | |||
| 306 | /* | 319 | /* |
| 307 | * Queue up a transport with data pending. If there are idle nfsd | 320 | * Queue up a transport with data pending. If there are idle nfsd |
| 308 | * processes, wake 'em up. | 321 | * processes, wake 'em up. |
| @@ -315,8 +328,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
| 315 | struct svc_rqst *rqstp; | 328 | struct svc_rqst *rqstp; |
| 316 | int cpu; | 329 | int cpu; |
| 317 | 330 | ||
| 318 | if (!(xprt->xpt_flags & | 331 | if (!svc_xprt_has_something_to_do(xprt)) |
| 319 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) | ||
| 320 | return; | 332 | return; |
| 321 | 333 | ||
| 322 | cpu = get_cpu(); | 334 | cpu = get_cpu(); |
| @@ -343,28 +355,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
| 343 | dprintk("svc: transport %p busy, not enqueued\n", xprt); | 355 | dprintk("svc: transport %p busy, not enqueued\n", xprt); |
| 344 | goto out_unlock; | 356 | goto out_unlock; |
| 345 | } | 357 | } |
| 346 | BUG_ON(xprt->xpt_pool != NULL); | ||
| 347 | xprt->xpt_pool = pool; | ||
| 348 | |||
| 349 | /* Handle pending connection */ | ||
| 350 | if (test_bit(XPT_CONN, &xprt->xpt_flags)) | ||
| 351 | goto process; | ||
| 352 | |||
| 353 | /* Handle close in-progress */ | ||
| 354 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
| 355 | goto process; | ||
| 356 | |||
| 357 | /* Check if we have space to reply to a request */ | ||
| 358 | if (!xprt->xpt_ops->xpo_has_wspace(xprt)) { | ||
| 359 | /* Don't enqueue while not enough space for reply */ | ||
| 360 | dprintk("svc: no write space, transport %p not enqueued\n", | ||
| 361 | xprt); | ||
| 362 | xprt->xpt_pool = NULL; | ||
| 363 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
| 364 | goto out_unlock; | ||
| 365 | } | ||
| 366 | 358 | ||
| 367 | process: | ||
| 368 | if (!list_empty(&pool->sp_threads)) { | 359 | if (!list_empty(&pool->sp_threads)) { |
| 369 | rqstp = list_entry(pool->sp_threads.next, | 360 | rqstp = list_entry(pool->sp_threads.next, |
| 370 | struct svc_rqst, | 361 | struct svc_rqst, |
| @@ -381,13 +372,11 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
| 381 | rqstp->rq_reserved = serv->sv_max_mesg; | 372 | rqstp->rq_reserved = serv->sv_max_mesg; |
| 382 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | 373 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); |
| 383 | pool->sp_stats.threads_woken++; | 374 | pool->sp_stats.threads_woken++; |
| 384 | BUG_ON(xprt->xpt_pool != pool); | ||
| 385 | wake_up(&rqstp->rq_wait); | 375 | wake_up(&rqstp->rq_wait); |
| 386 | } else { | 376 | } else { |
| 387 | dprintk("svc: transport %p put into queue\n", xprt); | 377 | dprintk("svc: transport %p put into queue\n", xprt); |
| 388 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); | 378 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); |
| 389 | pool->sp_stats.sockets_queued++; | 379 | pool->sp_stats.sockets_queued++; |
| 390 | BUG_ON(xprt->xpt_pool != pool); | ||
| 391 | } | 380 | } |
| 392 | 381 | ||
| 393 | out_unlock: | 382 | out_unlock: |
| @@ -426,7 +415,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | |||
| 426 | void svc_xprt_received(struct svc_xprt *xprt) | 415 | void svc_xprt_received(struct svc_xprt *xprt) |
| 427 | { | 416 | { |
| 428 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | 417 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); |
| 429 | xprt->xpt_pool = NULL; | ||
| 430 | /* As soon as we clear busy, the xprt could be closed and | 418 | /* As soon as we clear busy, the xprt could be closed and |
| 431 | * 'put', so we need a reference to call svc_xprt_enqueue with: | 419 | * 'put', so we need a reference to call svc_xprt_enqueue with: |
| 432 | */ | 420 | */ |
| @@ -722,7 +710,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 722 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 710 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
| 723 | dprintk("svc_recv: found XPT_CLOSE\n"); | 711 | dprintk("svc_recv: found XPT_CLOSE\n"); |
| 724 | svc_delete_xprt(xprt); | 712 | svc_delete_xprt(xprt); |
| 725 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | 713 | /* Leave XPT_BUSY set on the dead xprt: */ |
| 714 | goto out; | ||
| 715 | } | ||
| 716 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
| 726 | struct svc_xprt *newxpt; | 717 | struct svc_xprt *newxpt; |
| 727 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 718 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
| 728 | if (newxpt) { | 719 | if (newxpt) { |
| @@ -747,28 +738,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 747 | spin_unlock_bh(&serv->sv_lock); | 738 | spin_unlock_bh(&serv->sv_lock); |
| 748 | svc_xprt_received(newxpt); | 739 | svc_xprt_received(newxpt); |
| 749 | } | 740 | } |
| 750 | svc_xprt_received(xprt); | 741 | } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { |
| 751 | } else { | ||
| 752 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 742 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
| 753 | rqstp, pool->sp_id, xprt, | 743 | rqstp, pool->sp_id, xprt, |
| 754 | atomic_read(&xprt->xpt_ref.refcount)); | 744 | atomic_read(&xprt->xpt_ref.refcount)); |
| 755 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | 745 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); |
| 756 | if (rqstp->rq_deferred) { | 746 | if (rqstp->rq_deferred) |
| 757 | svc_xprt_received(xprt); | ||
| 758 | len = svc_deferred_recv(rqstp); | 747 | len = svc_deferred_recv(rqstp); |
| 759 | } else { | 748 | else |
| 760 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | 749 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); |
| 761 | svc_xprt_received(xprt); | ||
| 762 | } | ||
| 763 | dprintk("svc: got len=%d\n", len); | 750 | dprintk("svc: got len=%d\n", len); |
| 764 | } | 751 | } |
| 752 | svc_xprt_received(xprt); | ||
| 765 | 753 | ||
| 766 | /* No data, incomplete (TCP) read, or accept() */ | 754 | /* No data, incomplete (TCP) read, or accept() */ |
| 767 | if (len == 0 || len == -EAGAIN) { | 755 | if (len == 0 || len == -EAGAIN) |
| 768 | rqstp->rq_res.len = 0; | 756 | goto out; |
| 769 | svc_xprt_release(rqstp); | 757 | |
| 770 | return -EAGAIN; | ||
| 771 | } | ||
| 772 | clear_bit(XPT_OLD, &xprt->xpt_flags); | 758 | clear_bit(XPT_OLD, &xprt->xpt_flags); |
| 773 | 759 | ||
| 774 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | 760 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); |
| @@ -777,6 +763,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 777 | if (serv->sv_stats) | 763 | if (serv->sv_stats) |
| 778 | serv->sv_stats->netcnt++; | 764 | serv->sv_stats->netcnt++; |
| 779 | return len; | 765 | return len; |
| 766 | out: | ||
| 767 | rqstp->rq_res.len = 0; | ||
| 768 | svc_xprt_release(rqstp); | ||
| 769 | return -EAGAIN; | ||
| 780 | } | 770 | } |
| 781 | EXPORT_SYMBOL_GPL(svc_recv); | 771 | EXPORT_SYMBOL_GPL(svc_recv); |
| 782 | 772 | ||
| @@ -935,7 +925,12 @@ void svc_close_xprt(struct svc_xprt *xprt) | |||
| 935 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) | 925 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) |
| 936 | /* someone else will have to effect the close */ | 926 | /* someone else will have to effect the close */ |
| 937 | return; | 927 | return; |
| 938 | 928 | /* | |
| 929 | * We expect svc_close_xprt() to work even when no threads are | ||
| 930 | * running (e.g., while configuring the server before starting | ||
| 931 | * any threads), so if the transport isn't busy, we delete | ||
| 932 | * it ourself: | ||
| 933 | */ | ||
| 939 | svc_delete_xprt(xprt); | 934 | svc_delete_xprt(xprt); |
| 940 | } | 935 | } |
| 941 | EXPORT_SYMBOL_GPL(svc_close_xprt); | 936 | EXPORT_SYMBOL_GPL(svc_close_xprt); |
| @@ -945,16 +940,16 @@ void svc_close_all(struct list_head *xprt_list) | |||
| 945 | struct svc_xprt *xprt; | 940 | struct svc_xprt *xprt; |
| 946 | struct svc_xprt *tmp; | 941 | struct svc_xprt *tmp; |
| 947 | 942 | ||
| 943 | /* | ||
| 944 | * The server is shutting down, and no more threads are running. | ||
| 945 | * svc_xprt_enqueue() might still be running, but at worst it | ||
| 946 | * will re-add the xprt to sp_sockets, which will soon get | ||
| 947 | * freed. So we don't bother with any more locking, and don't | ||
| 948 | * leave the close to the (nonexistent) server threads: | ||
| 949 | */ | ||
| 948 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | 950 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { |
| 949 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | 951 | set_bit(XPT_CLOSE, &xprt->xpt_flags); |
| 950 | if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { | 952 | svc_delete_xprt(xprt); |
| 951 | /* Waiting to be processed, but no threads left, | ||
| 952 | * So just remove it from the waiting list | ||
| 953 | */ | ||
| 954 | list_del_init(&xprt->xpt_ready); | ||
| 955 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
| 956 | } | ||
| 957 | svc_close_xprt(xprt); | ||
| 958 | } | 953 | } |
| 959 | } | 954 | } |
| 960 | 955 | ||
| @@ -1028,6 +1023,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req) | |||
| 1028 | } | 1023 | } |
| 1029 | svc_xprt_get(rqstp->rq_xprt); | 1024 | svc_xprt_get(rqstp->rq_xprt); |
| 1030 | dr->xprt = rqstp->rq_xprt; | 1025 | dr->xprt = rqstp->rq_xprt; |
| 1026 | rqstp->rq_dropme = true; | ||
| 1031 | 1027 | ||
| 1032 | dr->handle.revisit = svc_revisit; | 1028 | dr->handle.revisit = svc_revisit; |
| 1033 | return &dr->handle; | 1029 | return &dr->handle; |
| @@ -1065,14 +1061,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | |||
| 1065 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) | 1061 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) |
| 1066 | return NULL; | 1062 | return NULL; |
| 1067 | spin_lock(&xprt->xpt_lock); | 1063 | spin_lock(&xprt->xpt_lock); |
| 1068 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
| 1069 | if (!list_empty(&xprt->xpt_deferred)) { | 1064 | if (!list_empty(&xprt->xpt_deferred)) { |
| 1070 | dr = list_entry(xprt->xpt_deferred.next, | 1065 | dr = list_entry(xprt->xpt_deferred.next, |
| 1071 | struct svc_deferred_req, | 1066 | struct svc_deferred_req, |
| 1072 | handle.recent); | 1067 | handle.recent); |
| 1073 | list_del_init(&dr->handle.recent); | 1068 | list_del_init(&dr->handle.recent); |
| 1074 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | 1069 | } else |
| 1075 | } | 1070 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); |
| 1076 | spin_unlock(&xprt->xpt_lock); | 1071 | spin_unlock(&xprt->xpt_lock); |
| 1077 | return dr; | 1072 | return dr; |
| 1078 | } | 1073 | } |
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 4e9393c24687..7963569fc04f 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
| @@ -118,7 +118,6 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister); | |||
| 118 | 118 | ||
| 119 | #define DN_HASHBITS 6 | 119 | #define DN_HASHBITS 6 |
| 120 | #define DN_HASHMAX (1<<DN_HASHBITS) | 120 | #define DN_HASHMAX (1<<DN_HASHBITS) |
| 121 | #define DN_HASHMASK (DN_HASHMAX-1) | ||
| 122 | 121 | ||
| 123 | static struct hlist_head auth_domain_table[DN_HASHMAX]; | 122 | static struct hlist_head auth_domain_table[DN_HASHMAX]; |
| 124 | static spinlock_t auth_domain_lock = | 123 | static spinlock_t auth_domain_lock = |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 560677d187f1..30916b06c12b 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
| @@ -30,7 +30,9 @@ | |||
| 30 | 30 | ||
| 31 | struct unix_domain { | 31 | struct unix_domain { |
| 32 | struct auth_domain h; | 32 | struct auth_domain h; |
| 33 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 33 | int addr_changes; | 34 | int addr_changes; |
| 35 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 34 | /* other stuff later */ | 36 | /* other stuff later */ |
| 35 | }; | 37 | }; |
| 36 | 38 | ||
| @@ -64,7 +66,9 @@ struct auth_domain *unix_domain_find(char *name) | |||
| 64 | return NULL; | 66 | return NULL; |
| 65 | } | 67 | } |
| 66 | new->h.flavour = &svcauth_unix; | 68 | new->h.flavour = &svcauth_unix; |
| 69 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 67 | new->addr_changes = 0; | 70 | new->addr_changes = 0; |
| 71 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 68 | rv = auth_domain_lookup(name, &new->h); | 72 | rv = auth_domain_lookup(name, &new->h); |
| 69 | } | 73 | } |
| 70 | } | 74 | } |
| @@ -85,14 +89,15 @@ static void svcauth_unix_domain_release(struct auth_domain *dom) | |||
| 85 | */ | 89 | */ |
| 86 | #define IP_HASHBITS 8 | 90 | #define IP_HASHBITS 8 |
| 87 | #define IP_HASHMAX (1<<IP_HASHBITS) | 91 | #define IP_HASHMAX (1<<IP_HASHBITS) |
| 88 | #define IP_HASHMASK (IP_HASHMAX-1) | ||
| 89 | 92 | ||
| 90 | struct ip_map { | 93 | struct ip_map { |
| 91 | struct cache_head h; | 94 | struct cache_head h; |
| 92 | char m_class[8]; /* e.g. "nfsd" */ | 95 | char m_class[8]; /* e.g. "nfsd" */ |
| 93 | struct in6_addr m_addr; | 96 | struct in6_addr m_addr; |
| 94 | struct unix_domain *m_client; | 97 | struct unix_domain *m_client; |
| 98 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 95 | int m_add_change; | 99 | int m_add_change; |
| 100 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 96 | }; | 101 | }; |
| 97 | 102 | ||
| 98 | static void ip_map_put(struct kref *kref) | 103 | static void ip_map_put(struct kref *kref) |
| @@ -146,7 +151,9 @@ static void update(struct cache_head *cnew, struct cache_head *citem) | |||
| 146 | 151 | ||
| 147 | kref_get(&item->m_client->h.ref); | 152 | kref_get(&item->m_client->h.ref); |
| 148 | new->m_client = item->m_client; | 153 | new->m_client = item->m_client; |
| 154 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 149 | new->m_add_change = item->m_add_change; | 155 | new->m_add_change = item->m_add_change; |
| 156 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 150 | } | 157 | } |
| 151 | static struct cache_head *ip_map_alloc(void) | 158 | static struct cache_head *ip_map_alloc(void) |
| 152 | { | 159 | { |
| @@ -331,6 +338,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, | |||
| 331 | ip.h.flags = 0; | 338 | ip.h.flags = 0; |
| 332 | if (!udom) | 339 | if (!udom) |
| 333 | set_bit(CACHE_NEGATIVE, &ip.h.flags); | 340 | set_bit(CACHE_NEGATIVE, &ip.h.flags); |
| 341 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 334 | else { | 342 | else { |
| 335 | ip.m_add_change = udom->addr_changes; | 343 | ip.m_add_change = udom->addr_changes; |
| 336 | /* if this is from the legacy set_client system call, | 344 | /* if this is from the legacy set_client system call, |
| @@ -339,6 +347,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, | |||
| 339 | if (expiry == NEVER) | 347 | if (expiry == NEVER) |
| 340 | ip.m_add_change++; | 348 | ip.m_add_change++; |
| 341 | } | 349 | } |
| 350 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 342 | ip.h.expiry_time = expiry; | 351 | ip.h.expiry_time = expiry; |
| 343 | ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, | 352 | ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, |
| 344 | hash_str(ipm->m_class, IP_HASHBITS) ^ | 353 | hash_str(ipm->m_class, IP_HASHBITS) ^ |
| @@ -358,6 +367,7 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm, | |||
| 358 | return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); | 367 | return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); |
| 359 | } | 368 | } |
| 360 | 369 | ||
| 370 | #ifdef CONFIG_NFSD_DEPRECATED | ||
| 361 | int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) | 371 | int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) |
| 362 | { | 372 | { |
| 363 | struct unix_domain *udom; | 373 | struct unix_domain *udom; |
| @@ -402,8 +412,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) | |||
| 402 | return NULL; | 412 | return NULL; |
| 403 | 413 | ||
| 404 | if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { | 414 | if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { |
| 405 | if (test_and_set_bit(CACHE_NEGATIVE, &ipm->h.flags) == 0) | 415 | sunrpc_invalidate(&ipm->h, sn->ip_map_cache); |
| 406 | auth_domain_put(&ipm->m_client->h); | ||
| 407 | rv = NULL; | 416 | rv = NULL; |
| 408 | } else { | 417 | } else { |
| 409 | rv = &ipm->m_client->h; | 418 | rv = &ipm->m_client->h; |
| @@ -413,6 +422,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) | |||
| 413 | return rv; | 422 | return rv; |
| 414 | } | 423 | } |
| 415 | EXPORT_SYMBOL_GPL(auth_unix_lookup); | 424 | EXPORT_SYMBOL_GPL(auth_unix_lookup); |
| 425 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
| 416 | 426 | ||
| 417 | void svcauth_unix_purge(void) | 427 | void svcauth_unix_purge(void) |
| 418 | { | 428 | { |
| @@ -497,7 +507,6 @@ svcauth_unix_info_release(struct svc_xprt *xpt) | |||
| 497 | */ | 507 | */ |
| 498 | #define GID_HASHBITS 8 | 508 | #define GID_HASHBITS 8 |
| 499 | #define GID_HASHMAX (1<<GID_HASHBITS) | 509 | #define GID_HASHMAX (1<<GID_HASHBITS) |
| 500 | #define GID_HASHMASK (GID_HASHMAX - 1) | ||
| 501 | 510 | ||
| 502 | struct unix_gid { | 511 | struct unix_gid { |
| 503 | struct cache_head h; | 512 | struct cache_head h; |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index d265aa700bb3..7bd3bbba4710 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -331,19 +331,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen, | |||
| 331 | len = onelen; | 331 | len = onelen; |
| 332 | break; | 332 | break; |
| 333 | } | 333 | } |
| 334 | if (toclose && strcmp(toclose, buf + len) == 0) | 334 | if (toclose && strcmp(toclose, buf + len) == 0) { |
| 335 | closesk = svsk; | 335 | closesk = svsk; |
| 336 | else | 336 | svc_xprt_get(&closesk->sk_xprt); |
| 337 | } else | ||
| 337 | len += onelen; | 338 | len += onelen; |
| 338 | } | 339 | } |
| 339 | spin_unlock_bh(&serv->sv_lock); | 340 | spin_unlock_bh(&serv->sv_lock); |
| 340 | 341 | ||
| 341 | if (closesk) | 342 | if (closesk) { |
| 342 | /* Should unregister with portmap, but you cannot | 343 | /* Should unregister with portmap, but you cannot |
| 343 | * unregister just one protocol... | 344 | * unregister just one protocol... |
| 344 | */ | 345 | */ |
| 345 | svc_close_xprt(&closesk->sk_xprt); | 346 | svc_close_xprt(&closesk->sk_xprt); |
| 346 | else if (toclose) | 347 | svc_xprt_put(&closesk->sk_xprt); |
| 348 | } else if (toclose) | ||
| 347 | return -ENOENT; | 349 | return -ENOENT; |
| 348 | return len; | 350 | return len; |
| 349 | } | 351 | } |
| @@ -992,15 +994,17 @@ static int svc_process_calldir(struct svc_sock *svsk, struct svc_rqst *rqstp, | |||
| 992 | vec[0] = rqstp->rq_arg.head[0]; | 994 | vec[0] = rqstp->rq_arg.head[0]; |
| 993 | } else { | 995 | } else { |
| 994 | /* REPLY */ | 996 | /* REPLY */ |
| 995 | if (svsk->sk_bc_xprt) | 997 | struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt; |
| 996 | req = xprt_lookup_rqst(svsk->sk_bc_xprt, xid); | 998 | |
| 999 | if (bc_xprt) | ||
| 1000 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
| 997 | 1001 | ||
| 998 | if (!req) { | 1002 | if (!req) { |
| 999 | printk(KERN_NOTICE | 1003 | printk(KERN_NOTICE |
| 1000 | "%s: Got unrecognized reply: " | 1004 | "%s: Got unrecognized reply: " |
| 1001 | "calldir 0x%x sk_bc_xprt %p xid %08x\n", | 1005 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", |
| 1002 | __func__, ntohl(calldir), | 1006 | __func__, ntohl(calldir), |
| 1003 | svsk->sk_bc_xprt, xid); | 1007 | bc_xprt, xid); |
| 1004 | vec[0] = rqstp->rq_arg.head[0]; | 1008 | vec[0] = rqstp->rq_arg.head[0]; |
| 1005 | goto out; | 1009 | goto out; |
| 1006 | } | 1010 | } |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 4c8f18aff7c3..856274d7e85c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
| @@ -965,6 +965,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req) | |||
| 965 | xprt = kzalloc(size, GFP_KERNEL); | 965 | xprt = kzalloc(size, GFP_KERNEL); |
| 966 | if (xprt == NULL) | 966 | if (xprt == NULL) |
| 967 | goto out; | 967 | goto out; |
| 968 | kref_init(&xprt->kref); | ||
| 968 | 969 | ||
| 969 | xprt->max_reqs = max_req; | 970 | xprt->max_reqs = max_req; |
| 970 | xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); | 971 | xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); |
| @@ -1101,8 +1102,10 @@ found: | |||
| 1101 | -PTR_ERR(xprt)); | 1102 | -PTR_ERR(xprt)); |
| 1102 | return xprt; | 1103 | return xprt; |
| 1103 | } | 1104 | } |
| 1105 | if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state)) | ||
| 1106 | /* ->setup returned a pre-initialized xprt: */ | ||
| 1107 | return xprt; | ||
| 1104 | 1108 | ||
| 1105 | kref_init(&xprt->kref); | ||
| 1106 | spin_lock_init(&xprt->transport_lock); | 1109 | spin_lock_init(&xprt->transport_lock); |
| 1107 | spin_lock_init(&xprt->reserve_lock); | 1110 | spin_lock_init(&xprt->reserve_lock); |
| 1108 | 1111 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 96549df836ee..c431f5a57960 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -2359,6 +2359,15 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
| 2359 | struct svc_sock *bc_sock; | 2359 | struct svc_sock *bc_sock; |
| 2360 | struct rpc_xprt *ret; | 2360 | struct rpc_xprt *ret; |
| 2361 | 2361 | ||
| 2362 | if (args->bc_xprt->xpt_bc_xprt) { | ||
| 2363 | /* | ||
| 2364 | * This server connection already has a backchannel | ||
| 2365 | * export; we can't create a new one, as we wouldn't be | ||
| 2366 | * able to match replies based on xid any more. So, | ||
| 2367 | * reuse the already-existing one: | ||
| 2368 | */ | ||
| 2369 | return args->bc_xprt->xpt_bc_xprt; | ||
| 2370 | } | ||
| 2362 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2371 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); |
| 2363 | if (IS_ERR(xprt)) | 2372 | if (IS_ERR(xprt)) |
| 2364 | return xprt; | 2373 | return xprt; |
| @@ -2375,16 +2384,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
| 2375 | xprt->reestablish_timeout = 0; | 2384 | xprt->reestablish_timeout = 0; |
| 2376 | xprt->idle_timeout = 0; | 2385 | xprt->idle_timeout = 0; |
| 2377 | 2386 | ||
| 2378 | /* | ||
| 2379 | * The backchannel uses the same socket connection as the | ||
| 2380 | * forechannel | ||
| 2381 | */ | ||
| 2382 | xprt->bc_xprt = args->bc_xprt; | ||
| 2383 | bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt); | ||
| 2384 | bc_sock->sk_bc_xprt = xprt; | ||
| 2385 | transport->sock = bc_sock->sk_sock; | ||
| 2386 | transport->inet = bc_sock->sk_sk; | ||
| 2387 | |||
| 2388 | xprt->ops = &bc_tcp_ops; | 2387 | xprt->ops = &bc_tcp_ops; |
| 2389 | 2388 | ||
| 2390 | switch (addr->sa_family) { | 2389 | switch (addr->sa_family) { |
| @@ -2407,6 +2406,20 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
| 2407 | xprt->address_strings[RPC_DISPLAY_PROTO]); | 2406 | xprt->address_strings[RPC_DISPLAY_PROTO]); |
| 2408 | 2407 | ||
| 2409 | /* | 2408 | /* |
| 2409 | * Once we've associated a backchannel xprt with a connection, | ||
| 2410 | * we want to keep it around as long as long as the connection | ||
| 2411 | * lasts, in case we need to start using it for a backchannel | ||
| 2412 | * again; this reference won't be dropped until bc_xprt is | ||
| 2413 | * destroyed. | ||
| 2414 | */ | ||
| 2415 | xprt_get(xprt); | ||
| 2416 | args->bc_xprt->xpt_bc_xprt = xprt; | ||
| 2417 | xprt->bc_xprt = args->bc_xprt; | ||
| 2418 | bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt); | ||
| 2419 | transport->sock = bc_sock->sk_sock; | ||
| 2420 | transport->inet = bc_sock->sk_sk; | ||
| 2421 | |||
| 2422 | /* | ||
| 2410 | * Since we don't want connections for the backchannel, we set | 2423 | * Since we don't want connections for the backchannel, we set |
| 2411 | * the xprt status to connected | 2424 | * the xprt status to connected |
| 2412 | */ | 2425 | */ |
| @@ -2415,6 +2428,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
| 2415 | 2428 | ||
| 2416 | if (try_module_get(THIS_MODULE)) | 2429 | if (try_module_get(THIS_MODULE)) |
| 2417 | return xprt; | 2430 | return xprt; |
| 2431 | xprt_put(xprt); | ||
| 2418 | ret = ERR_PTR(-EINVAL); | 2432 | ret = ERR_PTR(-EINVAL); |
| 2419 | out_err: | 2433 | out_err: |
| 2420 | xprt_free(xprt); | 2434 | xprt_free(xprt); |
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index a3301cc4ab82..185b00088320 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c | |||
| @@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci) | |||
| 90 | int i; | 90 | int i; |
| 91 | 91 | ||
| 92 | pci_set_power_state(pci, PCI_D0); | 92 | pci_set_power_state(pci, PCI_D0); |
| 93 | if (pci_restore_state(pci) < 0) { | 93 | pci_restore_state(pci); |
| 94 | printk(KERN_ERR "cs5535audio: pci_restore_state failed, " | ||
| 95 | "disabling device\n"); | ||
| 96 | snd_card_disconnect(card); | ||
| 97 | return -EIO; | ||
| 98 | } | ||
| 99 | if (pci_enable_device(pci) < 0) { | 94 | if (pci_enable_device(pci) < 0) { |
| 100 | printk(KERN_ERR "cs5535audio: pci_enable_device failed, " | 95 | printk(KERN_ERR "cs5535audio: pci_enable_device failed, " |
| 101 | "disabling device\n"); | 96 | "disabling device\n"); |
