aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAaron Lu <aaron.lu@intel.com>2013-01-25 01:29:35 -0500
committerJeff Garzik <jgarzik@redhat.com>2013-01-25 15:33:33 -0500
commita7ff60dbe0858496531c75b1544666c099a2b200 (patch)
tree2bb707b6682c398fbe35db8d3b775272561ddab0 /drivers/ata
parente175435ed281d06ffd56d4edc8a2dd56f8672f07 (diff)
[libata] pm: differentiate system and runtime pm for ata port
We need to do different things for system PM and runtime PM, e.g. we do not need to enable runtime wake for ZPODD when we are doing system suspend, etc. Currently, we use PMSG_SUSPEND for both system suspend and runtime suspend and PMSG_ON for both system resume and runtime resume. Change this by using PMSG_AUTO_SUSPEND for runtime suspend and PMSG_AUTO_RESUME for runtime resume. And since PMSG_ON means no transition, it is changed to PMSG_RESUME for ata port's system resume. The ata_acpi_set_state is modified accordingly, and the sata case and pata case is seperated for easy reading. Signed-off-by: Aaron Lu <aaron.lu@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-acpi.c76
-rw-r--r--drivers/ata/libata-core.c29
-rw-r--r--drivers/ata/libata-eh.c17
3 files changed, 83 insertions, 39 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 97094496127e..dfd529a30c20 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -836,9 +836,11 @@ void ata_acpi_on_resume(struct ata_port *ap)
836 } 836 }
837} 837}
838 838
839static int ata_acpi_choose_suspend_state(struct ata_device *dev) 839static int ata_acpi_choose_suspend_state(struct ata_device *dev, bool runtime)
840{ 840{
841 int d_max_in = ACPI_STATE_D3_COLD; 841 int d_max_in = ACPI_STATE_D3_COLD;
842 if (!runtime)
843 goto out;
842 844
843 /* 845 /*
844 * For ATAPI, runtime D3 cold is only allowed 846 * For ATAPI, runtime D3 cold is only allowed
@@ -848,53 +850,81 @@ static int ata_acpi_choose_suspend_state(struct ata_device *dev)
848 !(zpodd_dev_enabled(dev) && zpodd_zpready(dev))) 850 !(zpodd_dev_enabled(dev) && zpodd_zpready(dev)))
849 d_max_in = ACPI_STATE_D3_HOT; 851 d_max_in = ACPI_STATE_D3_HOT;
850 852
853out:
851 return acpi_pm_device_sleep_state(&dev->sdev->sdev_gendev, 854 return acpi_pm_device_sleep_state(&dev->sdev->sdev_gendev,
852 NULL, d_max_in); 855 NULL, d_max_in);
853} 856}
854 857
855/** 858static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state)
856 * ata_acpi_set_state - set the port power state
857 * @ap: target ATA port
858 * @state: state, on/off
859 *
860 * This function executes the _PS0/_PS3 ACPI method to set the power state.
861 * ACPI spec requires _PS0 when IDE power on and _PS3 when power off
862 */
863void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
864{ 859{
860 bool runtime = PMSG_IS_AUTO(state);
865 struct ata_device *dev; 861 struct ata_device *dev;
866 acpi_handle handle; 862 acpi_handle handle;
867 int acpi_state; 863 int acpi_state;
868 864
869 /* channel first and then drives for power on and vica versa
870 for power off */
871 handle = ata_ap_acpi_handle(ap);
872 if (handle && state.event == PM_EVENT_ON)
873 acpi_bus_set_power(handle, ACPI_STATE_D0);
874
875 ata_for_each_dev(dev, &ap->link, ENABLED) { 865 ata_for_each_dev(dev, &ap->link, ENABLED) {
876 handle = ata_dev_acpi_handle(dev); 866 handle = ata_dev_acpi_handle(dev);
877 if (!handle) 867 if (!handle)
878 continue; 868 continue;
879 869
880 if (state.event != PM_EVENT_ON) { 870 if (!(state.event & PM_EVENT_RESUME)) {
881 acpi_state = ata_acpi_choose_suspend_state(dev); 871 acpi_state = ata_acpi_choose_suspend_state(dev, runtime);
882 if (acpi_state == ACPI_STATE_D0) 872 if (acpi_state == ACPI_STATE_D0)
883 continue; 873 continue;
884 if (zpodd_dev_enabled(dev) && 874 if (runtime && zpodd_dev_enabled(dev) &&
885 acpi_state == ACPI_STATE_D3_COLD) 875 acpi_state == ACPI_STATE_D3_COLD)
886 zpodd_enable_run_wake(dev); 876 zpodd_enable_run_wake(dev);
887 acpi_bus_set_power(handle, acpi_state); 877 acpi_bus_set_power(handle, acpi_state);
888 } else { 878 } else {
889 if (zpodd_dev_enabled(dev)) 879 if (runtime && zpodd_dev_enabled(dev))
890 zpodd_disable_run_wake(dev); 880 zpodd_disable_run_wake(dev);
891 acpi_bus_set_power(handle, ACPI_STATE_D0); 881 acpi_bus_set_power(handle, ACPI_STATE_D0);
892 } 882 }
893 } 883 }
884}
885
886/* ACPI spec requires _PS0 when IDE power on and _PS3 when power off */
887static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
888{
889 struct ata_device *dev;
890 acpi_handle port_handle;
891
892 port_handle = ata_ap_acpi_handle(ap);
893 if (!port_handle)
894 return;
895
896 /* channel first and then drives for power on and vica versa
897 for power off */
898 if (state.event & PM_EVENT_RESUME)
899 acpi_bus_set_power(port_handle, ACPI_STATE_D0);
900
901 ata_for_each_dev(dev, &ap->link, ENABLED) {
902 acpi_handle dev_handle = ata_dev_acpi_handle(dev);
903 if (!dev_handle)
904 continue;
905
906 acpi_bus_set_power(dev_handle, state.event & PM_EVENT_RESUME ?
907 ACPI_STATE_D0 : ACPI_STATE_D3);
908 }
909
910 if (!(state.event & PM_EVENT_RESUME))
911 acpi_bus_set_power(port_handle, ACPI_STATE_D3);
912}
894 913
895 handle = ata_ap_acpi_handle(ap); 914/**
896 if (handle && state.event != PM_EVENT_ON) 915 * ata_acpi_set_state - set the port power state
897 acpi_bus_set_power(handle, ACPI_STATE_D3); 916 * @ap: target ATA port
917 * @state: state, on/off
918 *
919 * This function sets a proper ACPI D state for the device on
920 * system and runtime PM operations.
921 */
922void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
923{
924 if (ap->flags & ATA_FLAG_ACPI_SATA)
925 sata_acpi_set_state(ap, state);
926 else
927 pata_acpi_set_state(ap, state);
898} 928}
899 929
900/** 930/**
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 4b6fb48eb831..b7c972dc8b9b 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5344,7 +5344,7 @@ static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int
5344 * 5344 *
5345 * http://thread.gmane.org/gmane.linux.ide/46764 5345 * http://thread.gmane.org/gmane.linux.ide/46764
5346 */ 5346 */
5347 if (mesg.event == PM_EVENT_SUSPEND) 5347 if (mesg.event & PM_EVENT_SUSPEND)
5348 ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; 5348 ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
5349 5349
5350 rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, async); 5350 rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, async);
@@ -5382,27 +5382,28 @@ static int ata_port_poweroff(struct device *dev)
5382 return ata_port_suspend_common(dev, PMSG_HIBERNATE); 5382 return ata_port_suspend_common(dev, PMSG_HIBERNATE);
5383} 5383}
5384 5384
5385static int __ata_port_resume_common(struct ata_port *ap, int *async) 5385static int __ata_port_resume_common(struct ata_port *ap, pm_message_t mesg,
5386 int *async)
5386{ 5387{
5387 int rc; 5388 int rc;
5388 5389
5389 rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET, 5390 rc = ata_port_request_pm(ap, mesg, ATA_EH_RESET,
5390 ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async); 5391 ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async);
5391 return rc; 5392 return rc;
5392} 5393}
5393 5394
5394static int ata_port_resume_common(struct device *dev) 5395static int ata_port_resume_common(struct device *dev, pm_message_t mesg)
5395{ 5396{
5396 struct ata_port *ap = to_ata_port(dev); 5397 struct ata_port *ap = to_ata_port(dev);
5397 5398
5398 return __ata_port_resume_common(ap, NULL); 5399 return __ata_port_resume_common(ap, mesg, NULL);
5399} 5400}
5400 5401
5401static int ata_port_resume(struct device *dev) 5402static int ata_port_resume(struct device *dev)
5402{ 5403{
5403 int rc; 5404 int rc;
5404 5405
5405 rc = ata_port_resume_common(dev); 5406 rc = ata_port_resume_common(dev, PMSG_RESUME);
5406 if (!rc) { 5407 if (!rc) {
5407 pm_runtime_disable(dev); 5408 pm_runtime_disable(dev);
5408 pm_runtime_set_active(dev); 5409 pm_runtime_set_active(dev);
@@ -5436,6 +5437,16 @@ static int ata_port_runtime_idle(struct device *dev)
5436 return pm_runtime_suspend(dev); 5437 return pm_runtime_suspend(dev);
5437} 5438}
5438 5439
5440static int ata_port_runtime_suspend(struct device *dev)
5441{
5442 return ata_port_suspend_common(dev, PMSG_AUTO_SUSPEND);
5443}
5444
5445static int ata_port_runtime_resume(struct device *dev)
5446{
5447 return ata_port_resume_common(dev, PMSG_AUTO_RESUME);
5448}
5449
5439static const struct dev_pm_ops ata_port_pm_ops = { 5450static const struct dev_pm_ops ata_port_pm_ops = {
5440 .suspend = ata_port_suspend, 5451 .suspend = ata_port_suspend,
5441 .resume = ata_port_resume, 5452 .resume = ata_port_resume,
@@ -5444,8 +5455,8 @@ static const struct dev_pm_ops ata_port_pm_ops = {
5444 .poweroff = ata_port_poweroff, 5455 .poweroff = ata_port_poweroff,
5445 .restore = ata_port_resume, 5456 .restore = ata_port_resume,
5446 5457
5447 .runtime_suspend = ata_port_suspend, 5458 .runtime_suspend = ata_port_runtime_suspend,
5448 .runtime_resume = ata_port_resume_common, 5459 .runtime_resume = ata_port_runtime_resume,
5449 .runtime_idle = ata_port_runtime_idle, 5460 .runtime_idle = ata_port_runtime_idle,
5450}; 5461};
5451 5462
@@ -5462,7 +5473,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend);
5462 5473
5463int ata_sas_port_async_resume(struct ata_port *ap, int *async) 5474int ata_sas_port_async_resume(struct ata_port *ap, int *async)
5464{ 5475{
5465 return __ata_port_resume_common(ap, async); 5476 return __ata_port_resume_common(ap, PMSG_RESUME, async);
5466} 5477}
5467EXPORT_SYMBOL_GPL(ata_sas_port_async_resume); 5478EXPORT_SYMBOL_GPL(ata_sas_port_async_resume);
5468 5479
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 50f3ef04809d..f9476fb3ac43 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -4029,7 +4029,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
4029 /* are we suspending? */ 4029 /* are we suspending? */
4030 spin_lock_irqsave(ap->lock, flags); 4030 spin_lock_irqsave(ap->lock, flags);
4031 if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || 4031 if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
4032 ap->pm_mesg.event == PM_EVENT_ON) { 4032 ap->pm_mesg.event & PM_EVENT_RESUME) {
4033 spin_unlock_irqrestore(ap->lock, flags); 4033 spin_unlock_irqrestore(ap->lock, flags);
4034 return; 4034 return;
4035 } 4035 }
@@ -4040,10 +4040,13 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
4040 /* 4040 /*
4041 * If we have a ZPODD attached, check its zero 4041 * If we have a ZPODD attached, check its zero
4042 * power ready status before the port is frozen. 4042 * power ready status before the port is frozen.
4043 * Only needed for runtime suspend.
4043 */ 4044 */
4044 ata_for_each_dev(dev, &ap->link, ENABLED) { 4045 if (PMSG_IS_AUTO(ap->pm_mesg)) {
4045 if (zpodd_dev_enabled(dev)) 4046 ata_for_each_dev(dev, &ap->link, ENABLED) {
4046 zpodd_on_suspend(dev); 4047 if (zpodd_dev_enabled(dev))
4048 zpodd_on_suspend(dev);
4049 }
4047 } 4050 }
4048 4051
4049 /* tell ACPI we're suspending */ 4052 /* tell ACPI we're suspending */
@@ -4057,7 +4060,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
4057 if (ap->ops->port_suspend) 4060 if (ap->ops->port_suspend)
4058 rc = ap->ops->port_suspend(ap, ap->pm_mesg); 4061 rc = ap->ops->port_suspend(ap, ap->pm_mesg);
4059 4062
4060 ata_acpi_set_state(ap, PMSG_SUSPEND); 4063 ata_acpi_set_state(ap, ap->pm_mesg);
4061 out: 4064 out:
4062 /* report result */ 4065 /* report result */
4063 spin_lock_irqsave(ap->lock, flags); 4066 spin_lock_irqsave(ap->lock, flags);
@@ -4097,7 +4100,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
4097 /* are we resuming? */ 4100 /* are we resuming? */
4098 spin_lock_irqsave(ap->lock, flags); 4101 spin_lock_irqsave(ap->lock, flags);
4099 if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || 4102 if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
4100 ap->pm_mesg.event != PM_EVENT_ON) { 4103 !(ap->pm_mesg.event & PM_EVENT_RESUME)) {
4101 spin_unlock_irqrestore(ap->lock, flags); 4104 spin_unlock_irqrestore(ap->lock, flags);
4102 return; 4105 return;
4103 } 4106 }
@@ -4116,7 +4119,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
4116 ata_for_each_dev(dev, link, ALL) 4119 ata_for_each_dev(dev, link, ALL)
4117 ata_ering_clear(&dev->ering); 4120 ata_ering_clear(&dev->ering);
4118 4121
4119 ata_acpi_set_state(ap, PMSG_ON); 4122 ata_acpi_set_state(ap, ap->pm_mesg);
4120 4123
4121 if (ap->ops->port_resume) 4124 if (ap->ops->port_resume)
4122 rc = ap->ops->port_resume(ap); 4125 rc = ap->ops->port_resume(ap);