diff options
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/memory.c | 1 | ||||
| -rw-r--r-- | drivers/base/platform.c | 2 | ||||
| -rw-r--r-- | drivers/base/power/clock_ops.c | 4 | ||||
| -rw-r--r-- | drivers/base/power/main.c | 28 | ||||
| -rw-r--r-- | drivers/base/syscore.c | 8 |
5 files changed, 32 insertions, 11 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 9f9b2359f718..45d7c8fc73bd 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | static DEFINE_MUTEX(mem_sysfs_mutex); | 30 | static DEFINE_MUTEX(mem_sysfs_mutex); |
| 31 | 31 | ||
| 32 | #define MEMORY_CLASS_NAME "memory" | 32 | #define MEMORY_CLASS_NAME "memory" |
| 33 | #define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) | ||
| 34 | 33 | ||
| 35 | static int sections_per_block; | 34 | static int sections_per_block; |
| 36 | 35 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 1c291af637b3..6040717b62bb 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); | |||
| 367 | * | 367 | * |
| 368 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | 368 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. |
| 369 | */ | 369 | */ |
| 370 | struct platform_device *__init_or_module platform_device_register_resndata( | 370 | struct platform_device *platform_device_register_resndata( |
| 371 | struct device *parent, | 371 | struct device *parent, |
| 372 | const char *name, int id, | 372 | const char *name, int id, |
| 373 | const struct resource *res, unsigned int num, | 373 | const struct resource *res, unsigned int num, |
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index eaa8a854af03..ad367c4139b1 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
| @@ -387,7 +387,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, | |||
| 387 | clknb = container_of(nb, struct pm_clk_notifier_block, nb); | 387 | clknb = container_of(nb, struct pm_clk_notifier_block, nb); |
| 388 | 388 | ||
| 389 | switch (action) { | 389 | switch (action) { |
| 390 | case BUS_NOTIFY_ADD_DEVICE: | 390 | case BUS_NOTIFY_BIND_DRIVER: |
| 391 | if (clknb->con_ids[0]) { | 391 | if (clknb->con_ids[0]) { |
| 392 | for (con_id = clknb->con_ids; *con_id; con_id++) | 392 | for (con_id = clknb->con_ids; *con_id; con_id++) |
| 393 | enable_clock(dev, *con_id); | 393 | enable_clock(dev, *con_id); |
| @@ -395,7 +395,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, | |||
| 395 | enable_clock(dev, NULL); | 395 | enable_clock(dev, NULL); |
| 396 | } | 396 | } |
| 397 | break; | 397 | break; |
| 398 | case BUS_NOTIFY_DEL_DEVICE: | 398 | case BUS_NOTIFY_UNBOUND_DRIVER: |
| 399 | if (clknb->con_ids[0]) { | 399 | if (clknb->con_ids[0]) { |
| 400 | for (con_id = clknb->con_ids; *con_id; con_id++) | 400 | for (con_id = clknb->con_ids; *con_id; con_id++) |
| 401 | disable_clock(dev, *con_id); | 401 | disable_clock(dev, *con_id); |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index aa6320207745..06f09bf89cb2 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
| @@ -57,7 +57,8 @@ static int async_error; | |||
| 57 | */ | 57 | */ |
| 58 | void device_pm_init(struct device *dev) | 58 | void device_pm_init(struct device *dev) |
| 59 | { | 59 | { |
| 60 | dev->power.in_suspend = false; | 60 | dev->power.is_prepared = false; |
| 61 | dev->power.is_suspended = false; | ||
| 61 | init_completion(&dev->power.completion); | 62 | init_completion(&dev->power.completion); |
| 62 | complete_all(&dev->power.completion); | 63 | complete_all(&dev->power.completion); |
| 63 | dev->power.wakeup = NULL; | 64 | dev->power.wakeup = NULL; |
| @@ -91,7 +92,7 @@ void device_pm_add(struct device *dev) | |||
| 91 | pr_debug("PM: Adding info for %s:%s\n", | 92 | pr_debug("PM: Adding info for %s:%s\n", |
| 92 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); | 93 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
| 93 | mutex_lock(&dpm_list_mtx); | 94 | mutex_lock(&dpm_list_mtx); |
| 94 | if (dev->parent && dev->parent->power.in_suspend) | 95 | if (dev->parent && dev->parent->power.is_prepared) |
| 95 | dev_warn(dev, "parent %s should not be sleeping\n", | 96 | dev_warn(dev, "parent %s should not be sleeping\n", |
| 96 | dev_name(dev->parent)); | 97 | dev_name(dev->parent)); |
| 97 | list_add_tail(&dev->power.entry, &dpm_list); | 98 | list_add_tail(&dev->power.entry, &dpm_list); |
| @@ -511,7 +512,14 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
| 511 | dpm_wait(dev->parent, async); | 512 | dpm_wait(dev->parent, async); |
| 512 | device_lock(dev); | 513 | device_lock(dev); |
| 513 | 514 | ||
| 514 | dev->power.in_suspend = false; | 515 | /* |
| 516 | * This is a fib. But we'll allow new children to be added below | ||
| 517 | * a resumed device, even if the device hasn't been completed yet. | ||
| 518 | */ | ||
| 519 | dev->power.is_prepared = false; | ||
| 520 | |||
| 521 | if (!dev->power.is_suspended) | ||
| 522 | goto Unlock; | ||
| 515 | 523 | ||
| 516 | if (dev->pwr_domain) { | 524 | if (dev->pwr_domain) { |
| 517 | pm_dev_dbg(dev, state, "power domain "); | 525 | pm_dev_dbg(dev, state, "power domain "); |
| @@ -548,6 +556,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
| 548 | } | 556 | } |
| 549 | 557 | ||
| 550 | End: | 558 | End: |
| 559 | dev->power.is_suspended = false; | ||
| 560 | |||
| 561 | Unlock: | ||
| 551 | device_unlock(dev); | 562 | device_unlock(dev); |
| 552 | complete_all(&dev->power.completion); | 563 | complete_all(&dev->power.completion); |
| 553 | 564 | ||
| @@ -670,7 +681,7 @@ void dpm_complete(pm_message_t state) | |||
| 670 | struct device *dev = to_device(dpm_prepared_list.prev); | 681 | struct device *dev = to_device(dpm_prepared_list.prev); |
| 671 | 682 | ||
| 672 | get_device(dev); | 683 | get_device(dev); |
| 673 | dev->power.in_suspend = false; | 684 | dev->power.is_prepared = false; |
| 674 | list_move(&dev->power.entry, &list); | 685 | list_move(&dev->power.entry, &list); |
| 675 | mutex_unlock(&dpm_list_mtx); | 686 | mutex_unlock(&dpm_list_mtx); |
| 676 | 687 | ||
| @@ -835,11 +846,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
| 835 | device_lock(dev); | 846 | device_lock(dev); |
| 836 | 847 | ||
| 837 | if (async_error) | 848 | if (async_error) |
| 838 | goto End; | 849 | goto Unlock; |
| 839 | 850 | ||
| 840 | if (pm_wakeup_pending()) { | 851 | if (pm_wakeup_pending()) { |
| 841 | async_error = -EBUSY; | 852 | async_error = -EBUSY; |
| 842 | goto End; | 853 | goto Unlock; |
| 843 | } | 854 | } |
| 844 | 855 | ||
| 845 | if (dev->pwr_domain) { | 856 | if (dev->pwr_domain) { |
| @@ -877,6 +888,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
| 877 | } | 888 | } |
| 878 | 889 | ||
| 879 | End: | 890 | End: |
| 891 | dev->power.is_suspended = !error; | ||
| 892 | |||
| 893 | Unlock: | ||
| 880 | device_unlock(dev); | 894 | device_unlock(dev); |
| 881 | complete_all(&dev->power.completion); | 895 | complete_all(&dev->power.completion); |
| 882 | 896 | ||
| @@ -1042,7 +1056,7 @@ int dpm_prepare(pm_message_t state) | |||
| 1042 | put_device(dev); | 1056 | put_device(dev); |
| 1043 | break; | 1057 | break; |
| 1044 | } | 1058 | } |
| 1045 | dev->power.in_suspend = true; | 1059 | dev->power.is_prepared = true; |
| 1046 | if (!list_empty(&dev->power.entry)) | 1060 | if (!list_empty(&dev->power.entry)) |
| 1047 | list_move_tail(&dev->power.entry, &dpm_prepared_list); | 1061 | list_move_tail(&dev->power.entry, &dpm_prepared_list); |
| 1048 | put_device(dev); | 1062 | put_device(dev); |
diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index c126db3cb7d1..e8d11b6630ee 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <linux/syscore_ops.h> | 9 | #include <linux/syscore_ops.h> |
| 10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/interrupt.h> | ||
| 12 | 13 | ||
| 13 | static LIST_HEAD(syscore_ops_list); | 14 | static LIST_HEAD(syscore_ops_list); |
| 14 | static DEFINE_MUTEX(syscore_ops_lock); | 15 | static DEFINE_MUTEX(syscore_ops_lock); |
| @@ -48,6 +49,13 @@ int syscore_suspend(void) | |||
| 48 | struct syscore_ops *ops; | 49 | struct syscore_ops *ops; |
| 49 | int ret = 0; | 50 | int ret = 0; |
| 50 | 51 | ||
| 52 | pr_debug("Checking wakeup interrupts\n"); | ||
| 53 | |||
| 54 | /* Return error code if there are any wakeup interrupts pending. */ | ||
| 55 | ret = check_wakeup_irqs(); | ||
| 56 | if (ret) | ||
| 57 | return ret; | ||
| 58 | |||
| 51 | WARN_ONCE(!irqs_disabled(), | 59 | WARN_ONCE(!irqs_disabled(), |
| 52 | "Interrupts enabled before system core suspend.\n"); | 60 | "Interrupts enabled before system core suspend.\n"); |
| 53 | 61 | ||
