* [PATCH]libata-acpi: add ACPI _PSx method
@ 2007-09-14 2:45 Shaohua Li
2007-09-14 3:21 ` Jeff Garzik
2007-09-20 22:00 ` Jeff Garzik
0 siblings, 2 replies; 16+ messages in thread
From: Shaohua Li @ 2007-09-14 2:45 UTC (permalink / raw)
To: linux-ide, linux acpi; +Cc: jgarzik, Len Brown
ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx
methods. As recently most PATA drivers use libata, this patch adds _PSx
method support in libata. ACPI spec doesn't mention if SATA requires the
same _PSx method, but executing _PSx for SATA should be ok I think.
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
---
drivers/ata/libata-acpi.c | 34 ++++++++++++++++++++++++++++++++++
drivers/ata/libata-eh.c | 3 +++
drivers/ata/libata.h | 2 ++
3 files changed, 39 insertions(+)
Index: linux/drivers/ata/libata-acpi.c
===================================================================
--- linux.orig/drivers/ata/libata-acpi.c 2007-07-17 15:00:32.000000000 +0800
+++ linux/drivers/ata/libata-acpi.c 2007-09-14 10:23:01.000000000 +0800
@@ -523,6 +523,40 @@ void ata_acpi_on_resume(struct ata_port
}
/**
+ * ata_acpi_set_state - set the port power state
+ * @ap: target ATA port
+ * @state: state, on/off
+ *
+ * This function executes the _PS0/_PS3 ACPI method to set the power state.
+ * ACPI spec requires _PS0 when IDE power on and _PS3 when power off
+ */
+void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
+{
+ int max_devices = 1, i;
+
+ if (!ap->acpi_handle)
+ return;
+
+ /* channel first and then drives for power on and verse versa for power off */
+ if (state.event == PM_EVENT_ON)
+ acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);
+
+ if (ap->flags & ATA_FLAG_SLAVE_POSS)
+ max_devices++;
+
+ for (i = 0; i < max_devices; ++i) {
+ struct ata_device *dev = &ap->device[i];
+
+ if (dev->acpi_handle)
+ acpi_bus_set_power(dev->acpi_handle,
+ state.event == PM_EVENT_ON ?
+ ACPI_STATE_D0: ACPI_STATE_D3);
+ }
+ if (state.event != PM_EVENT_ON)
+ acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3);
+}
+
+/**
* ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
* @dev: target ATA device
*
Index: linux/drivers/ata/libata-eh.c
===================================================================
--- linux.orig/drivers/ata/libata-eh.c 2007-09-12 11:16:16.000000000 +0800
+++ linux/drivers/ata/libata-eh.c 2007-09-14 08:58:44.000000000 +0800
@@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s
if (ap->ops->port_suspend)
rc = ap->ops->port_suspend(ap, ap->pm_mesg);
+ ata_acpi_set_state(ap, PMSG_SUSPEND);
out:
/* report result */
spin_lock_irqsave(ap->lock, flags);
@@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st
WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
+ ata_acpi_set_state(ap, PMSG_ON);
+
if (ap->ops->port_resume)
rc = ap->ops->port_resume(ap);
Index: linux/drivers/ata/libata.h
===================================================================
--- linux.orig/drivers/ata/libata.h 2007-07-25 09:14:32.000000000 +0800
+++ linux/drivers/ata/libata.h 2007-09-14 08:57:46.000000000 +0800
@@ -102,11 +102,13 @@ extern void ata_acpi_associate(struct at
extern int ata_acpi_on_suspend(struct ata_port *ap);
extern void ata_acpi_on_resume(struct ata_port *ap);
extern int ata_acpi_on_devcfg(struct ata_device *adev);
+extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state);
#else
static inline void ata_acpi_associate(struct ata_host *host) { }
static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
static inline void ata_acpi_on_resume(struct ata_port *ap) { }
static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; }
+static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { }
#endif
/* libata-scsi.c */
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-14 2:45 [PATCH]libata-acpi: add ACPI _PSx method Shaohua Li @ 2007-09-14 3:21 ` Jeff Garzik 2007-09-14 3:11 ` Shaohua Li 2007-09-20 22:00 ` Jeff Garzik 1 sibling, 1 reply; 16+ messages in thread From: Jeff Garzik @ 2007-09-14 3:21 UTC (permalink / raw) To: Shaohua Li; +Cc: linux-ide, linux acpi, Len Brown Shaohua Li wrote: > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > methods. As recently most PATA drivers use libata, this patch adds _PSx > method support in libata. ACPI spec doesn't mention if SATA requires the > same _PSx method, but executing _PSx for SATA should be ok I think. > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> Where/how can a need for this change be produced? Jeff ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-14 3:21 ` Jeff Garzik @ 2007-09-14 3:11 ` Shaohua Li 0 siblings, 0 replies; 16+ messages in thread From: Shaohua Li @ 2007-09-14 3:11 UTC (permalink / raw) To: Jeff Garzik; +Cc: linux-ide, linux acpi, Len Brown On Thu, 2007-09-13 at 23:21 -0400, Jeff Garzik wrote: > Shaohua Li wrote: > > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > > methods. As recently most PATA drivers use libata, this patch adds _PSx > > method support in libata. ACPI spec doesn't mention if SATA requires the > > same _PSx method, but executing _PSx for SATA should be ok I think. > > > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> > > Where/how can a need for this change be produced? I run suspend/resume test in a Thinkpad R40 laptop, which implements _PSx method in IDE devices. But I'd say I didn't see visible difference in the suspend/resume circle w/wo the patch in the test laptop. This is just to make Linux match with ACPI spec. Maybe this changes other laptops. Thanks, Shaohua ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-14 2:45 [PATCH]libata-acpi: add ACPI _PSx method Shaohua Li 2007-09-14 3:21 ` Jeff Garzik @ 2007-09-20 22:00 ` Jeff Garzik 2007-09-21 1:16 ` Shaohua Li 1 sibling, 1 reply; 16+ messages in thread From: Jeff Garzik @ 2007-09-20 22:00 UTC (permalink / raw) To: Shaohua Li; +Cc: linux-ide, linux acpi, Len Brown, Andrew Morton, Tejun Heo Shaohua Li wrote: > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > methods. As recently most PATA drivers use libata, this patch adds _PSx > method support in libata. ACPI spec doesn't mention if SATA requires the > same _PSx method, but executing _PSx for SATA should be ok I think. > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> ahci and sata_sil24 directly power off components, so it seems quite unwise for "modern" SATA controllers. ISTR Tejun, when he cleaned up libata-acpi, finally figured out a good way to distinguish ACPI's idea of "IDE" -- which sometimes includes the legacy programming mode of SATA controllers, and a controller running a modern programming mode. Your best bet is to use a similar test when deciding when to execute _PSx. Or, you could simply be conservative and only do it for PATA. outside of those issues, the rest of the patch looks ok. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-20 22:00 ` Jeff Garzik @ 2007-09-21 1:16 ` Shaohua Li 2007-09-21 2:20 ` Tejun Heo 0 siblings, 1 reply; 16+ messages in thread From: Shaohua Li @ 2007-09-21 1:16 UTC (permalink / raw) To: Jeff Garzik; +Cc: linux-ide, linux acpi, Len Brown, Andrew Morton, Tejun Heo On Thu, 2007-09-20 at 18:00 -0400, Jeff Garzik wrote: > Shaohua Li wrote: > > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > > methods. As recently most PATA drivers use libata, this patch adds _PSx > > method support in libata. ACPI spec doesn't mention if SATA requires the > > same _PSx method, but executing _PSx for SATA should be ok I think. > > > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> > > ahci and sata_sil24 directly power off components, so it seems quite > unwise for "modern" SATA controllers. > > ISTR Tejun, when he cleaned up libata-acpi, finally figured out a good > way to distinguish ACPI's idea of "IDE" -- which sometimes includes the > legacy programming mode of SATA controllers, and a controller running a > modern programming mode. > > Your best bet is to use a similar test when deciding when to execute > _PSx. Or, you could simply be conservative and only do it for PATA. > > outside of those issues, the rest of the patch looks ok. Then how about this one? I added a check in ata_acpi_set_state to skip SATA device, assume this is what you are talking about. Thanks, Shaohua --- drivers/ata/libata-acpi.c | 34 ++++++++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 3 +++ drivers/ata/libata.h | 2 ++ 3 files changed, 39 insertions(+) Index: linux/drivers/ata/libata-acpi.c =================================================================== --- linux.orig/drivers/ata/libata-acpi.c 2007-09-14 10:28:25.000000000 +0800 +++ linux/drivers/ata/libata-acpi.c 2007-09-21 08:58:18.000000000 +0800 @@ -523,6 +523,40 @@ void ata_acpi_on_resume(struct ata_port } /** + * ata_acpi_set_state - set the port power state + * @ap: target ATA port + * @state: state, on/off + * + * This function executes the _PS0/_PS3 ACPI method to set the power state. + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off + */ +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) +{ + int max_devices = 1, i; + + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) + return; + + /* channel first and then drives for power on and verse versa for power off */ + if (state.event == PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); + + if (ap->flags & ATA_FLAG_SLAVE_POSS) + max_devices++; + + for (i = 0; i < max_devices; ++i) { + struct ata_device *dev = &ap->device[i]; + + if (dev->acpi_handle) + acpi_bus_set_power(dev->acpi_handle, + state.event == PM_EVENT_ON ? + ACPI_STATE_D0: ACPI_STATE_D3); + } + if (state.event != PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); +} + +/** * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration * @dev: target ATA device * Index: linux/drivers/ata/libata-eh.c =================================================================== --- linux.orig/drivers/ata/libata-eh.c 2007-09-14 10:28:25.000000000 +0800 +++ linux/drivers/ata/libata-eh.c 2007-09-21 08:56:40.000000000 +0800 @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); + ata_acpi_set_state(ap, PMSG_SUSPEND); out: /* report result */ spin_lock_irqsave(ap->lock, flags); @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); + ata_acpi_set_state(ap, PMSG_ON); + if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); Index: linux/drivers/ata/libata.h =================================================================== --- linux.orig/drivers/ata/libata.h 2007-09-14 10:28:25.000000000 +0800 +++ linux/drivers/ata/libata.h 2007-09-21 08:56:40.000000000 +0800 @@ -102,11 +102,13 @@ extern void ata_acpi_associate(struct at extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *adev); +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); #else static inline void ata_acpi_associate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } #endif /* libata-scsi.c */ ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-21 1:16 ` Shaohua Li @ 2007-09-21 2:20 ` Tejun Heo 2007-09-21 2:17 ` Shaohua Li 0 siblings, 1 reply; 16+ messages in thread From: Tejun Heo @ 2007-09-21 2:20 UTC (permalink / raw) To: Shaohua Li; +Cc: Jeff Garzik, linux-ide, linux acpi, Len Brown, Andrew Morton Hello, Shaohua Li wrote: > + /* channel first and then drives for power on and verse versa for power off */ > + if (state.event == PM_EVENT_ON) > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > + > + if (ap->flags & ATA_FLAG_SLAVE_POSS) > + max_devices++; ata_port_max_devices()? > Index: linux/drivers/ata/libata-eh.c > =================================================================== > --- linux.orig/drivers/ata/libata-eh.c 2007-09-14 10:28:25.000000000 +0800 > +++ linux/drivers/ata/libata-eh.c 2007-09-21 08:56:40.000000000 +0800 > @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s > if (ap->ops->port_suspend) > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > out: > /* report result */ > spin_lock_irqsave(ap->lock, flags); > @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > + ata_acpi_set_state(ap, PMSG_ON); > + > if (ap->ops->port_resume) > rc = ap->ops->port_resume(ap); Can these be moved into ata_acpi_on_suspend() and ata_acpi_on_resume()? Or do they have to be placed on the other side of ->port_suspend/resume callbacks? Thanks. -- tejun ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-21 2:20 ` Tejun Heo @ 2007-09-21 2:17 ` Shaohua Li 2007-10-31 2:27 ` Len Brown 0 siblings, 1 reply; 16+ messages in thread From: Shaohua Li @ 2007-09-21 2:17 UTC (permalink / raw) To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, linux acpi, Len Brown, Andrew Morton On Fri, 2007-09-21 at 11:20 +0900, Tejun Heo wrote: > Hello, > > Shaohua Li wrote: > > + /* channel first and then drives for power on and verse versa for power off */ > > + if (state.event == PM_EVENT_ON) > > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > > + > > + if (ap->flags & ATA_FLAG_SLAVE_POSS) > > + max_devices++; > > ata_port_max_devices()? ok, fixed. > > > Index: linux/drivers/ata/libata-eh.c > > =================================================================== > > --- linux.orig/drivers/ata/libata-eh.c 2007-09-14 10:28:25.000000000 +0800 > > +++ linux/drivers/ata/libata-eh.c 2007-09-21 08:56:40.000000000 +0800 > > @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s > > if (ap->ops->port_suspend) > > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > > out: > > /* report result */ > > spin_lock_irqsave(ap->lock, flags); > > @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st > > > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > > > + ata_acpi_set_state(ap, PMSG_ON); > > + > > if (ap->ops->port_resume) > > rc = ap->ops->port_resume(ap); > > Can these be moved into ata_acpi_on_suspend() and ata_acpi_on_resume()? > Or do they have to be placed on the other side of ->port_suspend/resume > callbacks? I suppose _PSx will shutdown ports. So I want to do PS3 as later as possible in suspend, and vice versa in resume. Thanks, Shaohua --- drivers/ata/libata-acpi.c | 34 ++++++++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 3 +++ drivers/ata/libata.h | 2 ++ 3 files changed, 39 insertions(+) Index: linux/drivers/ata/libata-acpi.c =================================================================== --- linux.orig/drivers/ata/libata-acpi.c 2007-09-21 09:23:13.000000000 +0800 +++ linux/drivers/ata/libata-acpi.c 2007-09-21 10:13:32.000000000 +0800 @@ -523,6 +523,39 @@ void ata_acpi_on_resume(struct ata_port } /** + * ata_acpi_set_state - set the port power state + * @ap: target ATA port + * @state: state, on/off + * + * This function executes the _PS0/_PS3 ACPI method to set the power state. + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off + */ +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) +{ + int max_devices, i; + + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) + return; + + /* channel first and then drives for power on and verse versa for power off */ + if (state.event == PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); + + max_devices = ata_port_max_devices(ap); + + for (i = 0; i < max_devices; ++i) { + struct ata_device *dev = &ap->device[i]; + + if (dev->acpi_handle) + acpi_bus_set_power(dev->acpi_handle, + state.event == PM_EVENT_ON ? + ACPI_STATE_D0: ACPI_STATE_D3); + } + if (state.event != PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); +} + +/** * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration * @dev: target ATA device * Index: linux/drivers/ata/libata-eh.c =================================================================== --- linux.orig/drivers/ata/libata-eh.c 2007-09-21 09:23:13.000000000 +0800 +++ linux/drivers/ata/libata-eh.c 2007-09-21 10:09:10.000000000 +0800 @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); + ata_acpi_set_state(ap, PMSG_SUSPEND); out: /* report result */ spin_lock_irqsave(ap->lock, flags); @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); + ata_acpi_set_state(ap, PMSG_ON); + if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); Index: linux/drivers/ata/libata.h =================================================================== --- linux.orig/drivers/ata/libata.h 2007-09-21 09:23:13.000000000 +0800 +++ linux/drivers/ata/libata.h 2007-09-21 10:09:10.000000000 +0800 @@ -102,11 +102,13 @@ extern void ata_acpi_associate(struct at extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *adev); +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); #else static inline void ata_acpi_associate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } #endif /* libata-scsi.c */ ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-09-21 2:17 ` Shaohua Li @ 2007-10-31 2:27 ` Len Brown 2007-10-31 13:26 ` Rafael J. Wysocki 0 siblings, 1 reply; 16+ messages in thread From: Len Brown @ 2007-10-31 2:27 UTC (permalink / raw) To: Shaohua Li; +Cc: Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton It would be interseting if any of the folks having power consumption problems when suspended see an improvement with this patch. Are there plans to refresh this patch and get it upstream? Acked-by: Len Brown <len.brown@intel.com> thanks, -Len On Thursday 20 September 2007 22:17, Shaohua Li wrote: > On Fri, 2007-09-21 at 11:20 +0900, Tejun Heo wrote: > > Hello, > > > > Shaohua Li wrote: > > > + /* channel first and then drives for power on and verse versa for power off */ > > > + if (state.event == PM_EVENT_ON) > > > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > > > + > > > + if (ap->flags & ATA_FLAG_SLAVE_POSS) > > > + max_devices++; > > > > ata_port_max_devices()? > ok, fixed. > > > > > Index: linux/drivers/ata/libata-eh.c > > > =================================================================== > > > --- linux.orig/drivers/ata/libata-eh.c 2007-09-14 10:28:25.000000000 +0800 > > > +++ linux/drivers/ata/libata-eh.c 2007-09-21 08:56:40.000000000 +0800 > > > @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s > > > if (ap->ops->port_suspend) > > > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > > > > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > > > out: > > > /* report result */ > > > spin_lock_irqsave(ap->lock, flags); > > > @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st > > > > > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > > > > > + ata_acpi_set_state(ap, PMSG_ON); > > > + > > > if (ap->ops->port_resume) > > > rc = ap->ops->port_resume(ap); > > > > Can these be moved into ata_acpi_on_suspend() and ata_acpi_on_resume()? > > Or do they have to be placed on the other side of ->port_suspend/resume > > callbacks? > I suppose _PSx will shutdown ports. So I want to do PS3 as later as > possible in suspend, and vice versa in resume. > > Thanks, > Shaohua > > > --- > drivers/ata/libata-acpi.c | 34 ++++++++++++++++++++++++++++++++++ > drivers/ata/libata-eh.c | 3 +++ > drivers/ata/libata.h | 2 ++ > 3 files changed, 39 insertions(+) > > Index: linux/drivers/ata/libata-acpi.c > =================================================================== > --- linux.orig/drivers/ata/libata-acpi.c 2007-09-21 09:23:13.000000000 +0800 > +++ linux/drivers/ata/libata-acpi.c 2007-09-21 10:13:32.000000000 +0800 > @@ -523,6 +523,39 @@ void ata_acpi_on_resume(struct ata_port > } > > /** > + * ata_acpi_set_state - set the port power state > + * @ap: target ATA port > + * @state: state, on/off > + * > + * This function executes the _PS0/_PS3 ACPI method to set the power state. > + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off > + */ > +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) > +{ > + int max_devices, i; > + > + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) > + return; > + > + /* channel first and then drives for power on and verse versa for power off */ > + if (state.event == PM_EVENT_ON) > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > + > + max_devices = ata_port_max_devices(ap); > + > + for (i = 0; i < max_devices; ++i) { > + struct ata_device *dev = &ap->device[i]; > + > + if (dev->acpi_handle) > + acpi_bus_set_power(dev->acpi_handle, > + state.event == PM_EVENT_ON ? > + ACPI_STATE_D0: ACPI_STATE_D3); > + } > + if (state.event != PM_EVENT_ON) > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); > +} > + > +/** > * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration > * @dev: target ATA device > * > Index: linux/drivers/ata/libata-eh.c > =================================================================== > --- linux.orig/drivers/ata/libata-eh.c 2007-09-21 09:23:13.000000000 +0800 > +++ linux/drivers/ata/libata-eh.c 2007-09-21 10:09:10.000000000 +0800 > @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s > if (ap->ops->port_suspend) > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > out: > /* report result */ > spin_lock_irqsave(ap->lock, flags); > @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > + ata_acpi_set_state(ap, PMSG_ON); > + > if (ap->ops->port_resume) > rc = ap->ops->port_resume(ap); > > Index: linux/drivers/ata/libata.h > =================================================================== > --- linux.orig/drivers/ata/libata.h 2007-09-21 09:23:13.000000000 +0800 > +++ linux/drivers/ata/libata.h 2007-09-21 10:09:10.000000000 +0800 > @@ -102,11 +102,13 @@ extern void ata_acpi_associate(struct at > extern int ata_acpi_on_suspend(struct ata_port *ap); > extern void ata_acpi_on_resume(struct ata_port *ap); > extern int ata_acpi_on_devcfg(struct ata_device *adev); > +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); > #else > static inline void ata_acpi_associate(struct ata_host *host) { } > static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } > static inline void ata_acpi_on_resume(struct ata_port *ap) { } > static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } > +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } > #endif > > /* libata-scsi.c */ > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-10-31 2:27 ` Len Brown @ 2007-10-31 13:26 ` Rafael J. Wysocki 2007-11-01 2:50 ` Shaohua Li 0 siblings, 1 reply; 16+ messages in thread From: Rafael J. Wysocki @ 2007-10-31 13:26 UTC (permalink / raw) To: Len Brown Cc: Shaohua Li, Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton On Wednesday, 31 October 2007 03:27, Len Brown wrote: > It would be interseting if any of the folks having power consumption > problems when suspended see an improvement with this patch. > > Are there plans to refresh this patch and get it upstream? > > Acked-by: Len Brown <len.brown@intel.com> There was a discussion regarding this patch, IIRC, and it was argued that _PSx are only applicable to IDE/PATA devices. I wonder if this has been addressed. Greetings, Rafael > On Thursday 20 September 2007 22:17, Shaohua Li wrote: > > On Fri, 2007-09-21 at 11:20 +0900, Tejun Heo wrote: > > > Hello, > > > > > > Shaohua Li wrote: > > > > + /* channel first and then drives for power on and verse versa for power off */ > > > > + if (state.event == PM_EVENT_ON) > > > > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > > > > + > > > > + if (ap->flags & ATA_FLAG_SLAVE_POSS) > > > > + max_devices++; > > > > > > ata_port_max_devices()? > > ok, fixed. > > > > > > > Index: linux/drivers/ata/libata-eh.c > > > > =================================================================== > > > > --- linux.orig/drivers/ata/libata-eh.c 2007-09-14 10:28:25.000000000 +0800 > > > > +++ linux/drivers/ata/libata-eh.c 2007-09-21 08:56:40.000000000 +0800 > > > > @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s > > > > if (ap->ops->port_suspend) > > > > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > > > > > > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > > > > out: > > > > /* report result */ > > > > spin_lock_irqsave(ap->lock, flags); > > > > @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st > > > > > > > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > > > > > > > + ata_acpi_set_state(ap, PMSG_ON); > > > > + > > > > if (ap->ops->port_resume) > > > > rc = ap->ops->port_resume(ap); > > > > > > Can these be moved into ata_acpi_on_suspend() and ata_acpi_on_resume()? > > > Or do they have to be placed on the other side of ->port_suspend/resume > > > callbacks? > > I suppose _PSx will shutdown ports. So I want to do PS3 as later as > > possible in suspend, and vice versa in resume. > > > > Thanks, > > Shaohua > > > > > > --- > > drivers/ata/libata-acpi.c | 34 ++++++++++++++++++++++++++++++++++ > > drivers/ata/libata-eh.c | 3 +++ > > drivers/ata/libata.h | 2 ++ > > 3 files changed, 39 insertions(+) > > > > Index: linux/drivers/ata/libata-acpi.c > > =================================================================== > > --- linux.orig/drivers/ata/libata-acpi.c 2007-09-21 09:23:13.000000000 +0800 > > +++ linux/drivers/ata/libata-acpi.c 2007-09-21 10:13:32.000000000 +0800 > > @@ -523,6 +523,39 @@ void ata_acpi_on_resume(struct ata_port > > } > > > > /** > > + * ata_acpi_set_state - set the port power state > > + * @ap: target ATA port > > + * @state: state, on/off > > + * > > + * This function executes the _PS0/_PS3 ACPI method to set the power state. > > + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off > > + */ > > +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) > > +{ > > + int max_devices, i; > > + > > + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) > > + return; > > + > > + /* channel first and then drives for power on and verse versa for power off */ > > + if (state.event == PM_EVENT_ON) > > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > > + > > + max_devices = ata_port_max_devices(ap); > > + > > + for (i = 0; i < max_devices; ++i) { > > + struct ata_device *dev = &ap->device[i]; > > + > > + if (dev->acpi_handle) > > + acpi_bus_set_power(dev->acpi_handle, > > + state.event == PM_EVENT_ON ? > > + ACPI_STATE_D0: ACPI_STATE_D3); > > + } > > + if (state.event != PM_EVENT_ON) > > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); > > +} > > + > > +/** > > * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration > > * @dev: target ATA device > > * > > Index: linux/drivers/ata/libata-eh.c > > =================================================================== > > --- linux.orig/drivers/ata/libata-eh.c 2007-09-21 09:23:13.000000000 +0800 > > +++ linux/drivers/ata/libata-eh.c 2007-09-21 10:09:10.000000000 +0800 > > @@ -2349,6 +2349,7 @@ static void ata_eh_handle_port_suspend(s > > if (ap->ops->port_suspend) > > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > > out: > > /* report result */ > > spin_lock_irqsave(ap->lock, flags); > > @@ -2394,6 +2395,8 @@ static void ata_eh_handle_port_resume(st > > > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > > > + ata_acpi_set_state(ap, PMSG_ON); > > + > > if (ap->ops->port_resume) > > rc = ap->ops->port_resume(ap); > > > > Index: linux/drivers/ata/libata.h > > =================================================================== > > --- linux.orig/drivers/ata/libata.h 2007-09-21 09:23:13.000000000 +0800 > > +++ linux/drivers/ata/libata.h 2007-09-21 10:09:10.000000000 +0800 > > @@ -102,11 +102,13 @@ extern void ata_acpi_associate(struct at > > extern int ata_acpi_on_suspend(struct ata_port *ap); > > extern void ata_acpi_on_resume(struct ata_port *ap); > > extern int ata_acpi_on_devcfg(struct ata_device *adev); > > +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); > > #else > > static inline void ata_acpi_associate(struct ata_host *host) { } > > static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } > > static inline void ata_acpi_on_resume(struct ata_port *ap) { } > > static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } > > +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } > > #endif > > > > /* libata-scsi.c */ > > > - > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- "Premature optimization is the root of all evil." - Donald Knuth ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-10-31 13:26 ` Rafael J. Wysocki @ 2007-11-01 2:50 ` Shaohua Li 2007-11-01 10:04 ` Alan Cox 0 siblings, 1 reply; 16+ messages in thread From: Shaohua Li @ 2007-11-01 2:50 UTC (permalink / raw) To: Rafael J. Wysocki Cc: Len Brown, Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton On Wed, 2007-10-31 at 14:26 +0100, Rafael J. Wysocki wrote: > On Wednesday, 31 October 2007 03:27, Len Brown wrote: > > It would be interseting if any of the folks having power consumption > > problems when suspended see an improvement with this patch. > > > > Are there plans to refresh this patch and get it upstream? > > > > Acked-by: Len Brown <len.brown@intel.com> > > There was a discussion regarding this patch, IIRC, and it was argued that > _PSx are only applicable to IDE/PATA devices. > > I wonder if this has been addressed. Sure, there is a check for PATA. I refreshed the patch to against latest git tree. ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx methods. As recently most PATA drivers use libata, this patch adds _PSx method support in libata. ACPI spec doesn't mention if SATA requires the same _PSx method. Signed-off-by: Shaohua Li <shaohua.li@intel.com> Acked-by: Len Brown <len.brown@intel.com> --- drivers/ata/libata-acpi.c | 33 +++++++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 3 +++ drivers/ata/libata.h | 2 ++ 3 files changed, 38 insertions(+) Index: linux/drivers/ata/libata-acpi.c =================================================================== --- linux.orig/drivers/ata/libata-acpi.c 2007-10-26 08:49:07.000000000 +0800 +++ linux/drivers/ata/libata-acpi.c 2007-11-01 09:17:12.000000000 +0800 @@ -652,6 +652,39 @@ void ata_acpi_on_resume(struct ata_port } /** + * ata_acpi_set_state - set the port power state + * @ap: target ATA port + * @state: state, on/off + * + * This function executes the _PS0/_PS3 ACPI method to set the power state. + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off + */ +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) +{ + int max_devices, i; + + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) + return; + + /* channel first and then drives for power on and verse versa for power off */ + if (state.event == PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); + + max_devices = ata_link_max_devices(&ap->link); + + for (i = 0; i < max_devices; ++i) { + struct ata_device *dev = &ap->link.device[i]; + + if (dev->acpi_handle) + acpi_bus_set_power(dev->acpi_handle, + state.event == PM_EVENT_ON ? + ACPI_STATE_D0: ACPI_STATE_D3); + } + if (state.event != PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); +} + +/** * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration * @dev: target ATA device * Index: linux/drivers/ata/libata-eh.c =================================================================== --- linux.orig/drivers/ata/libata-eh.c 2007-10-31 09:14:06.000000000 +0800 +++ linux/drivers/ata/libata-eh.c 2007-11-01 08:55:05.000000000 +0800 @@ -2796,6 +2796,7 @@ static void ata_eh_handle_port_suspend(s if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); + ata_acpi_set_state(ap, PMSG_SUSPEND); out: /* report result */ spin_lock_irqsave(ap->lock, flags); @@ -2841,6 +2842,8 @@ static void ata_eh_handle_port_resume(st WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); + ata_acpi_set_state(ap, PMSG_ON); + if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); Index: linux/drivers/ata/libata.h =================================================================== --- linux.orig/drivers/ata/libata.h 2007-10-30 14:17:14.000000000 +0800 +++ linux/drivers/ata/libata.h 2007-11-01 08:55:05.000000000 +0800 @@ -111,12 +111,14 @@ extern void ata_acpi_associate(struct at extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *adev); +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); #else static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } static inline void ata_acpi_associate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } #endif /* libata-scsi.c */ ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-11-01 2:50 ` Shaohua Li @ 2007-11-01 10:04 ` Alan Cox 2007-11-02 1:32 ` Shaohua Li 0 siblings, 1 reply; 16+ messages in thread From: Alan Cox @ 2007-11-01 10:04 UTC (permalink / raw) To: Shaohua Li Cc: Rafael J. Wysocki, Len Brown, Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton > + max_devices = ata_link_max_devices(&ap->link); > + > + for (i = 0; i < max_devices; ++i) { > + struct ata_device *dev = &ap->link.device[i]; Better to use: ata_link_for_each_dev(dev, &ap->link) { > + > + if (dev->acpi_handle) > + acpi_bus_set_power(dev->acpi_handle, > + state.event == PM_EVENT_ON ? > + ACPI_STATE_D0: ACPI_STATE_D3); > + } Also should you not check ata_dev_enabled(dev) ? Alan ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-11-01 10:04 ` Alan Cox @ 2007-11-02 1:32 ` Shaohua Li 2007-11-02 11:16 ` Rafael J. Wysocki 2007-11-03 13:00 ` Jeff Garzik 0 siblings, 2 replies; 16+ messages in thread From: Shaohua Li @ 2007-11-02 1:32 UTC (permalink / raw) To: Alan Cox Cc: Rafael J. Wysocki, Len Brown, Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton On Thu, 2007-11-01 at 10:04 +0000, Alan Cox wrote: > > + max_devices = ata_link_max_devices(&ap->link); > > + > > + for (i = 0; i < max_devices; ++i) { > > + struct ata_device *dev = &ap->link.device[i]; > > Better to use: ok. > ata_link_for_each_dev(dev, &ap->link) { > > > + > > + if (dev->acpi_handle) > > + acpi_bus_set_power(dev->acpi_handle, > > + state.event == PM_EVENT_ON ? > > + ACPI_STATE_D0: ACPI_STATE_D3); > > + } > > Also should you not check ata_dev_enabled(dev) ? Not sure, this is just to call a BIOS routine, but a check should be safer. Thanks! ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx methods. As recently most PATA drivers use libata, this patch adds _PSx method support in libata. ACPI spec doesn't mention if SATA requires the same _PSx method. Signed-off-by: Shaohua Li <shaohua.li@intel.com> Acked-by: Len Brown <len.brown@intel.com> --- drivers/ata/libata-acpi.c | 29 +++++++++++++++++++++++++++++ drivers/ata/libata-eh.c | 3 +++ drivers/ata/libata.h | 2 ++ 3 files changed, 34 insertions(+) Index: linux/drivers/ata/libata-acpi.c =================================================================== --- linux.orig/drivers/ata/libata-acpi.c 2007-11-01 10:54:25.000000000 +0800 +++ linux/drivers/ata/libata-acpi.c 2007-11-02 09:14:12.000000000 +0800 @@ -652,6 +652,35 @@ void ata_acpi_on_resume(struct ata_port } /** + * ata_acpi_set_state - set the port power state + * @ap: target ATA port + * @state: state, on/off + * + * This function executes the _PS0/_PS3 ACPI method to set the power state. + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off + */ +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) +{ + struct ata_device *dev; + + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) + return; + + /* channel first and then drives for power on and verse versa for power off */ + if (state.event == PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); + + ata_link_for_each_dev(dev, &ap->link) { + if (dev->acpi_handle && ata_dev_enabled(dev)) + acpi_bus_set_power(dev->acpi_handle, + state.event == PM_EVENT_ON ? + ACPI_STATE_D0: ACPI_STATE_D3); + } + if (state.event != PM_EVENT_ON) + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); +} + +/** * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration * @dev: target ATA device * Index: linux/drivers/ata/libata-eh.c =================================================================== --- linux.orig/drivers/ata/libata-eh.c 2007-11-01 10:54:25.000000000 +0800 +++ linux/drivers/ata/libata-eh.c 2007-11-02 09:01:41.000000000 +0800 @@ -2796,6 +2796,7 @@ static void ata_eh_handle_port_suspend(s if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); + ata_acpi_set_state(ap, PMSG_SUSPEND); out: /* report result */ spin_lock_irqsave(ap->lock, flags); @@ -2841,6 +2842,8 @@ static void ata_eh_handle_port_resume(st WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); + ata_acpi_set_state(ap, PMSG_ON); + if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); Index: linux/drivers/ata/libata.h =================================================================== --- linux.orig/drivers/ata/libata.h 2007-11-01 10:54:25.000000000 +0800 +++ linux/drivers/ata/libata.h 2007-11-02 09:01:41.000000000 +0800 @@ -111,12 +111,14 @@ extern void ata_acpi_associate(struct at extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *adev); +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); #else static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } static inline void ata_acpi_associate(struct ata_host *host) { } static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } #endif /* libata-scsi.c */ ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-11-02 1:32 ` Shaohua Li @ 2007-11-02 11:16 ` Rafael J. Wysocki 2007-11-05 1:26 ` Shaohua Li 2007-11-03 13:00 ` Jeff Garzik 1 sibling, 1 reply; 16+ messages in thread From: Rafael J. Wysocki @ 2007-11-02 11:16 UTC (permalink / raw) To: Shaohua Li Cc: Alan Cox, Len Brown, Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton On Friday, 2 November 2007 02:32, Shaohua Li wrote: > On Thu, 2007-11-01 at 10:04 +0000, Alan Cox wrote: > > > + max_devices = ata_link_max_devices(&ap->link); > > > + > > > + for (i = 0; i < max_devices; ++i) { > > > + struct ata_device *dev = &ap->link.device[i]; > > > > Better to use: > ok. > > ata_link_for_each_dev(dev, &ap->link) { > > > > > + > > > + if (dev->acpi_handle) > > > + acpi_bus_set_power(dev->acpi_handle, > > > + state.event == PM_EVENT_ON ? > > > + ACPI_STATE_D0: ACPI_STATE_D3); > > > + } > > > > Also should you not check ata_dev_enabled(dev) ? > Not sure, this is just to call a BIOS routine, but a check should be > safer. Thanks! > > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > methods. As recently most PATA drivers use libata, this patch adds _PSx > method support in libata. ACPI spec doesn't mention if SATA requires the > same _PSx method. > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> > Acked-by: Len Brown <len.brown@intel.com> > --- > drivers/ata/libata-acpi.c | 29 +++++++++++++++++++++++++++++ > drivers/ata/libata-eh.c | 3 +++ > drivers/ata/libata.h | 2 ++ > 3 files changed, 34 insertions(+) > > Index: linux/drivers/ata/libata-acpi.c > =================================================================== > --- linux.orig/drivers/ata/libata-acpi.c 2007-11-01 10:54:25.000000000 +0800 > +++ linux/drivers/ata/libata-acpi.c 2007-11-02 09:14:12.000000000 +0800 > @@ -652,6 +652,35 @@ void ata_acpi_on_resume(struct ata_port > } > > /** > + * ata_acpi_set_state - set the port power state > + * @ap: target ATA port > + * @state: state, on/off > + * > + * This function executes the _PS0/_PS3 ACPI method to set the power state. > + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off > + */ > +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) I wouldn't use pm_message_t here. We're seriously considering removing it in the future and the caller passes constants explicitly anyway. IMO, it might be cleaner to define two separate functions, one for switching to D0 and one for switching to D3, and call them as appropriate. Then, you could get rid of some conditionals below. > +{ > + struct ata_device *dev; > + > + if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA)) > + return; > + > + /* channel first and then drives for power on and verse versa for power off */ > + if (state.event == PM_EVENT_ON) > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0); > + > + ata_link_for_each_dev(dev, &ap->link) { > + if (dev->acpi_handle && ata_dev_enabled(dev)) > + acpi_bus_set_power(dev->acpi_handle, > + state.event == PM_EVENT_ON ? > + ACPI_STATE_D0: ACPI_STATE_D3); > + } > + if (state.event != PM_EVENT_ON) > + acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3); > +} > + > +/** > * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration > * @dev: target ATA device > * > Index: linux/drivers/ata/libata-eh.c > =================================================================== > --- linux.orig/drivers/ata/libata-eh.c 2007-11-01 10:54:25.000000000 +0800 > +++ linux/drivers/ata/libata-eh.c 2007-11-02 09:01:41.000000000 +0800 > @@ -2796,6 +2796,7 @@ static void ata_eh_handle_port_suspend(s > if (ap->ops->port_suspend) > rc = ap->ops->port_suspend(ap, ap->pm_mesg); > > + ata_acpi_set_state(ap, PMSG_SUSPEND); > out: > /* report result */ > spin_lock_irqsave(ap->lock, flags); > @@ -2841,6 +2842,8 @@ static void ata_eh_handle_port_resume(st > > WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > + ata_acpi_set_state(ap, PMSG_ON); > + > if (ap->ops->port_resume) > rc = ap->ops->port_resume(ap); > > Index: linux/drivers/ata/libata.h > =================================================================== > --- linux.orig/drivers/ata/libata.h 2007-11-01 10:54:25.000000000 +0800 > +++ linux/drivers/ata/libata.h 2007-11-02 09:01:41.000000000 +0800 > @@ -111,12 +111,14 @@ extern void ata_acpi_associate(struct at > extern int ata_acpi_on_suspend(struct ata_port *ap); > extern void ata_acpi_on_resume(struct ata_port *ap); > extern int ata_acpi_on_devcfg(struct ata_device *adev); > +extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); > #else > static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { } > static inline void ata_acpi_associate(struct ata_host *host) { } > static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } > static inline void ata_acpi_on_resume(struct ata_port *ap) { } > static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } > +static inline void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) { } > #endif > > /* libata-scsi.c */ > - > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > Greetings, Rafael ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-11-02 11:16 ` Rafael J. Wysocki @ 2007-11-05 1:26 ` Shaohua Li 0 siblings, 0 replies; 16+ messages in thread From: Shaohua Li @ 2007-11-05 1:26 UTC (permalink / raw) To: Rafael J. Wysocki Cc: Alan Cox, Len Brown, Tejun Heo, Jeff Garzik, linux-ide, linux acpi, Andrew Morton On Fri, 2007-11-02 at 12:16 +0100, Rafael J. Wysocki wrote: > > > > Index: linux/drivers/ata/libata-acpi.c > > =================================================================== > > --- linux.orig/drivers/ata/libata-acpi.c 2007-11-01 10:54:25.000000000 +0800 > > +++ linux/drivers/ata/libata-acpi.c 2007-11-02 09:14:12.000000000 +0800 > > @@ -652,6 +652,35 @@ void ata_acpi_on_resume(struct ata_port > > } > > > > /** > > + * ata_acpi_set_state - set the port power state > > + * @ap: target ATA port > > + * @state: state, on/off > > + * > > + * This function executes the _PS0/_PS3 ACPI method to set the power state. > > + * ACPI spec requires _PS0 when IDE power on and _PS3 when power off > > + */ > > +void ata_acpi_set_state(struct ata_port *ap, pm_message_t state) > > I wouldn't use pm_message_t here. > > We're seriously considering removing it in the future and the caller passes > constants explicitly anyway. > > IMO, it might be cleaner to define two separate functions, one for switching > to D0 and one for switching to D3, and call them as appropriate. Then, you > could get rid of some conditionals below. It doesn't make sense to add a new one just for ata_acpi and we don't misuse pm_message_t here. If you will remove it, lets clean up it then. Thanks, Shaohua ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-11-02 1:32 ` Shaohua Li 2007-11-02 11:16 ` Rafael J. Wysocki @ 2007-11-03 13:00 ` Jeff Garzik 2007-11-05 1:12 ` Shaohua Li 1 sibling, 1 reply; 16+ messages in thread From: Jeff Garzik @ 2007-11-03 13:00 UTC (permalink / raw) To: Shaohua Li Cc: Alan Cox, Rafael J. Wysocki, Len Brown, Tejun Heo, linux-ide, linux acpi, Andrew Morton Shaohua Li wrote: > Not sure, this is just to call a BIOS routine, but a check should be > safer. Thanks! > > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > methods. As recently most PATA drivers use libata, this patch adds _PSx > method support in libata. ACPI spec doesn't mention if SATA requires the > same _PSx method. > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> > Acked-by: Len Brown <len.brown@intel.com> What is the safety factor on this patch? :) Since we are into 2.6.24-rc, my preference would be to let this get some testing in -mm, and push it upstream for 2.6.25. Comments? Jeff ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH]libata-acpi: add ACPI _PSx method 2007-11-03 13:00 ` Jeff Garzik @ 2007-11-05 1:12 ` Shaohua Li 0 siblings, 0 replies; 16+ messages in thread From: Shaohua Li @ 2007-11-05 1:12 UTC (permalink / raw) To: Jeff Garzik Cc: Alan Cox, Rafael J. Wysocki, Len Brown, Tejun Heo, linux-ide, linux acpi, Andrew Morton On Sat, 2007-11-03 at 09:00 -0400, Jeff Garzik wrote: > Shaohua Li wrote: > > Not sure, this is just to call a BIOS routine, but a check should be > > safer. Thanks! > > > > ACPI spec (ver 3.0a, p289) requires IDE power on/off executes ACPI _PSx > > methods. As recently most PATA drivers use libata, this patch adds _PSx > > method support in libata. ACPI spec doesn't mention if SATA requires the > > same _PSx method. > > > > Signed-off-by: Shaohua Li <shaohua.li@intel.com> > > Acked-by: Len Brown <len.brown@intel.com> > > > What is the safety factor on this patch? :) Not sure, but it depends on BIOS, I just guess ignoring disabled device might be safe :) > Since we are into 2.6.24-rc, my preference would be to let this get some > testing in -mm, and push it upstream for 2.6.25. Comments? Sure, Thanks, taking either this patch or previous patch is ok to me. Thanks, Shaohua ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2007-11-05 1:32 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-09-14 2:45 [PATCH]libata-acpi: add ACPI _PSx method Shaohua Li 2007-09-14 3:21 ` Jeff Garzik 2007-09-14 3:11 ` Shaohua Li 2007-09-20 22:00 ` Jeff Garzik 2007-09-21 1:16 ` Shaohua Li 2007-09-21 2:20 ` Tejun Heo 2007-09-21 2:17 ` Shaohua Li 2007-10-31 2:27 ` Len Brown 2007-10-31 13:26 ` Rafael J. Wysocki 2007-11-01 2:50 ` Shaohua Li 2007-11-01 10:04 ` Alan Cox 2007-11-02 1:32 ` Shaohua Li 2007-11-02 11:16 ` Rafael J. Wysocki 2007-11-05 1:26 ` Shaohua Li 2007-11-03 13:00 ` Jeff Garzik 2007-11-05 1:12 ` Shaohua Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).