aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-acpi.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-21 18:48:31 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-21 18:48:31 -0500
commit5d5132059a1f652de9dc2d62a8ff15561e648d11 (patch)
tree50b8d40bcdc23aa66a64db90c733160a0e565867 /drivers/ata/libata-acpi.c
parentbe27b3dcb02335ec093b81053fc8c84b32d3106e (diff)
ACPI / ATA: Add hotplug contexts to ACPI companions of SATA devices
Modify the SATA subsystem to add hotplug contexts to ACPI companions of SATA devices and ports instead of registering special ACPI dock operations using register_hotplug_dock_device(). That change will allow the entire code handling those special ACPI dock operations to be dropped in the next commit. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Aaron Lu <aaron.lu@intel.com> Acked-by: Tejun Heo <tj@kernel.org>
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 9e69a5308693..acb95dffdb6a 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/**