aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-acpi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 15:48:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 15:48:54 -0400
commit4dedde7c7a18f55180574f934dbc1be84ca0400b (patch)
treed7cc511e8ba8ffceadf3f45b9a63395c4e4183c5 /drivers/ata/libata-acpi.c
parent683b6c6f82a60fabf47012581c2cfbf1b037ab95 (diff)
parent0ecfe310f4517d7505599be738158087c165be7c (diff)
Merge tag 'pm+acpi-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki: "The majority of this material spent some time in linux-next, some of it even several weeks. There are a few relatively fresh commits in it, but they are mostly fixes and simple cleanups. ACPI took the lead this time, both in terms of the number of commits and the number of modified lines of code, cpufreq follows and there are a few changes in the PM core and in cpuidle too. A new feature that already got some LWN.net's attention is the device PM QoS extension allowing latency tolerance requirements to be propagated from leaf devices to their ancestors with hardware interfaces for specifying latency tolerance. That should help systems with hardware-driven power management to avoid going too far with it in cases when there are latency tolerance constraints. There also are some significant changes in the ACPI core related to the way in which hotplug notifications are handled. They affect PCI hotplug (ACPIPHP) and the ACPI dock station code too. The bottom line is that all those notification now go through the root notify handler and are propagated to the interested subsystems by means of callbacks instead of having to install a notify handler for each device object that we can potentially get hotplug notifications for. In addition to that ACPICA will now advertise "Windows 2013" compatibility for _OSI, because some systems out there don't work correctly if that is not done (some of them don't even boot). On the system suspend side of things, all of the device suspend and resume callbacks, except for ->prepare() and ->complete(), are now going to be executed asynchronously as that turns out to speed up system suspend and resume on some platforms quite significantly and we have a few more optimizations in that area. Apart from that, there are some new device IDs and fixes and cleanups all over. In particular, the system suspend and resume handling by cpufreq should be improved and the cpuidle menu governor should be a bit more robust now. Specifics: - Device PM QoS support for latency tolerance constraints on systems with hardware interfaces allowing such constraints to be specified. That is necessary to prevent hardware-driven power management from becoming overly aggressive on some systems and to prevent power management features leading to excessive latencies from being used in some cases. - Consolidation of the handling of ACPI hotplug notifications for device objects. This causes all device hotplug notifications to go through the root notify handler (that was executed for all of them anyway before) that propagates them to individual subsystems, if necessary, by executing callbacks provided by those subsystems (those callbacks are associated with struct acpi_device objects during device enumeration). As a result, the code in question becomes both smaller in size and more straightforward and all of those changes should not affect users. - ACPICA update, including fixes related to the handling of _PRT in cases when it is broken and the addition of "Windows 2013" to the list of supported "features" for _OSI (which is necessary to support systems that work incorrectly or don't even boot without it). Changes from Bob Moore and Lv Zheng. - Consolidation of ACPI _OST handling from Jiang Liu. - ACPI battery and AC fixes allowing unusual system configurations to be handled by that code from Alexander Mezin. - New device IDs for the ACPI LPSS driver from Chiau Ee Chew. - ACPI fan and thermal optimizations related to system suspend and resume from Aaron Lu. - Cleanups related to ACPI video from Jean Delvare. - Assorted ACPI fixes and cleanups from Al Stone, Hanjun Guo, Lan Tianyu, Paul Bolle, Tomasz Nowicki. - Intel RAPL (Running Average Power Limits) driver cleanups from Jacob Pan. - intel_pstate fixes and cleanups from Dirk Brandewie. - cpufreq fixes related to system suspend/resume handling from Viresh Kumar. - cpufreq core fixes and cleanups from Viresh Kumar, Stratos Karafotis, Saravana Kannan, Rashika Kheria, Joe Perches. - cpufreq drivers updates from Viresh Kumar, Zhuoyu Zhang, Rob Herring. - cpuidle fixes related to the menu governor from Tuukka Tikkanen. - cpuidle fix related to coupled CPUs handling from Paul Burton. - Asynchronous execution of all device suspend and resume callbacks, except for ->prepare and ->complete, during system suspend and resume from Chuansheng Liu. - Delayed resuming of runtime-suspended devices during system suspend for the PCI bus type and ACPI PM domain. - New set of PM helper routines to allow device runtime PM callbacks to be used during system suspend and resume more easily from Ulf Hansson. - Assorted fixes and cleanups in the PM core from Geert Uytterhoeven, Prabhakar Lad, Philipp Zabel, Rashika Kheria, Sebastian Capella. - devfreq fix from Saravana Kannan" * tag 'pm+acpi-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (162 commits) PM / devfreq: Rewrite devfreq_update_status() to fix multiple bugs PM / sleep: Correct whitespace errors in <linux/pm.h> intel_pstate: Set core to min P state during core offline cpufreq: Add stop CPU callback to cpufreq_driver interface cpufreq: Remove unnecessary braces cpufreq: Fix checkpatch errors and warnings cpufreq: powerpc: add cpufreq transition latency for FSL e500mc SoCs MAINTAINERS: Reorder maintainer addresses for PM and ACPI PM / Runtime: Update runtime_idle() documentation for return value meaning video / output: Drop display output class support fujitsu-laptop: Drop unneeded include acer-wmi: Stop selecting VIDEO_OUTPUT_CONTROL ACPI / gpu / drm: Stop selecting VIDEO_OUTPUT_CONTROL ACPI / video: fix ACPI_VIDEO dependencies cpufreq: remove unused notifier: CPUFREQ_{SUSPENDCHANGE|RESUMECHANGE} cpufreq: Do not allow ->setpolicy drivers to provide ->target cpufreq: arm_big_little: set 'physical_cluster' for each CPU cpufreq: arm_big_little: make vexpress driver depend on bL core driver ACPI / button: Add ACPI Button event via netlink routine ACPI: Remove duplicate definitions of PREFIX ...
Diffstat (limited to 'drivers/ata/libata-acpi.c')
-rw-r--r--drivers/ata/libata-acpi.c72
1 files changed, 45 insertions, 27 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index b4f7cc2522d9..97a14fe47de1 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -38,6 +38,16 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
38 dev->gtf_cache = NULL; 38 dev->gtf_cache = NULL;
39} 39}
40 40
41struct ata_acpi_hotplug_context {
42 struct acpi_hotplug_context hp;
43 union {
44 struct ata_port *ap;
45 struct ata_device *dev;
46 } data;
47};
48
49#define ata_hotplug_data(context) (container_of((context), struct ata_acpi_hotplug_context, hp)->data)
50
41/** 51/**
42 * ata_dev_acpi_handle - provide the acpi_handle for an ata_device 52 * ata_dev_acpi_handle - provide the acpi_handle for an ata_device
43 * @dev: the acpi_handle returned will correspond to this device 53 * @dev: the acpi_handle returned will correspond to this device
@@ -121,18 +131,17 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
121 ata_port_wait_eh(ap); 131 ata_port_wait_eh(ap);
122} 132}
123 133
124static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) 134static int ata_acpi_dev_notify_dock(struct acpi_device *adev, u32 event)
125{ 135{
126 struct ata_device *dev = data; 136 struct ata_device *dev = ata_hotplug_data(adev->hp).dev;
127
128 ata_acpi_handle_hotplug(dev->link->ap, dev, event); 137 ata_acpi_handle_hotplug(dev->link->ap, dev, event);
138 return 0;
129} 139}
130 140
131static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) 141static int ata_acpi_ap_notify_dock(struct acpi_device *adev, u32 event)
132{ 142{
133 struct ata_port *ap = data; 143 ata_acpi_handle_hotplug(ata_hotplug_data(adev->hp).ap, NULL, event);
134 144 return 0;
135 ata_acpi_handle_hotplug(ap, NULL, event);
136} 145}
137 146
138static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev, 147static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
@@ -154,31 +163,23 @@ static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
154 } 163 }
155} 164}
156 165
157static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data) 166static void ata_acpi_ap_uevent(struct acpi_device *adev, u32 event)
158{ 167{
159 ata_acpi_uevent(data, NULL, event); 168 ata_acpi_uevent(ata_hotplug_data(adev->hp).ap, NULL, event);
160} 169}
161 170
162static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data) 171static void ata_acpi_dev_uevent(struct acpi_device *adev, u32 event)
163{ 172{
164 struct ata_device *dev = data; 173 struct ata_device *dev = ata_hotplug_data(adev->hp).dev;
165 ata_acpi_uevent(dev->link->ap, dev, event); 174 ata_acpi_uevent(dev->link->ap, dev, event);
166} 175}
167 176
168static const struct acpi_dock_ops ata_acpi_dev_dock_ops = {
169 .handler = ata_acpi_dev_notify_dock,
170 .uevent = ata_acpi_dev_uevent,
171};
172
173static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
174 .handler = ata_acpi_ap_notify_dock,
175 .uevent = ata_acpi_ap_uevent,
176};
177
178/* bind acpi handle to pata port */ 177/* bind acpi handle to pata port */
179void ata_acpi_bind_port(struct ata_port *ap) 178void ata_acpi_bind_port(struct ata_port *ap)
180{ 179{
181 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); 180 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
181 struct acpi_device *adev;
182 struct ata_acpi_hotplug_context *context;
182 183
183 if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion) 184 if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion)
184 return; 185 return;
@@ -188,9 +189,17 @@ void ata_acpi_bind_port(struct ata_port *ap)
188 if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) 189 if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
189 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; 190 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
190 191
191 /* we might be on a docking station */ 192 adev = ACPI_COMPANION(&ap->tdev);
192 register_hotplug_dock_device(ACPI_HANDLE(&ap->tdev), 193 if (!adev || adev->hp)
193 &ata_acpi_ap_dock_ops, ap, NULL, NULL); 194 return;
195
196 context = kzalloc(sizeof(*context), GFP_KERNEL);
197 if (!context)
198 return;
199
200 context->data.ap = ap;
201 acpi_initialize_hp_context(adev, &context->hp, ata_acpi_ap_notify_dock,
202 ata_acpi_ap_uevent);
194} 203}
195 204
196void ata_acpi_bind_dev(struct ata_device *dev) 205void ata_acpi_bind_dev(struct ata_device *dev)
@@ -198,7 +207,8 @@ void ata_acpi_bind_dev(struct ata_device *dev)
198 struct ata_port *ap = dev->link->ap; 207 struct ata_port *ap = dev->link->ap;
199 struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev); 208 struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev);
200 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); 209 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
201 struct acpi_device *parent; 210 struct acpi_device *parent, *adev;
211 struct ata_acpi_hotplug_context *context;
202 u64 adr; 212 u64 adr;
203 213
204 /* 214 /*
@@ -221,9 +231,17 @@ void ata_acpi_bind_dev(struct ata_device *dev)
221 } 231 }
222 232
223 acpi_preset_companion(&dev->tdev, parent, adr); 233 acpi_preset_companion(&dev->tdev, parent, adr);
234 adev = ACPI_COMPANION(&dev->tdev);
235 if (!adev || adev->hp)
236 return;
237
238 context = kzalloc(sizeof(*context), GFP_KERNEL);
239 if (!context)
240 return;
224 241
225 register_hotplug_dock_device(ata_dev_acpi_handle(dev), 242 context->data.dev = dev;
226 &ata_acpi_dev_dock_ops, dev, NULL, NULL); 243 acpi_initialize_hp_context(adev, &context->hp, ata_acpi_dev_notify_dock,
244 ata_acpi_dev_uevent);
227} 245}
228 246
229/** 247/**