diff options
author | David Brownell <david-b@pacbell.net> | 2007-05-08 03:28:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:08 -0400 |
commit | 55955aad7c09e4d93029d0cf2d360b41891f2fe4 (patch) | |
tree | 7d7bbb9d1e06c833fcc8d110db1f278b026aae80 /drivers/pnp/pnpacpi | |
parent | 98701d1b0fe98b477b53df89114e6862547f8107 (diff) |
PNPACPI sets pnpdev->dev.archdata
Teach PNPACPI how to hook up its devices to their ACPI nodes, so that
pnpdev->dev.archdata points to the parallel acpi device node. Previously
this only worked for PCI, leaving a notable hole.
Export "acpi_bus_type" so this can work.
Remove some extraneous whitespace.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Adam Belay <ambx1@neo.rr.com>
Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/pnp/pnpacpi')
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 62eda5d5902..7eb8275185b 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> | 4 | * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> |
5 | * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> | 5 | * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
9 | * Free Software Foundation; either version 2, or (at your option) any | 9 | * Free Software Foundation; either version 2, or (at your option) any |
@@ -18,7 +18,7 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/acpi.h> | 22 | #include <linux/acpi.h> |
23 | #include <linux/pnp.h> | 23 | #include <linux/pnp.h> |
24 | #include <acpi/acpi_bus.h> | 24 | #include <acpi/acpi_bus.h> |
@@ -82,7 +82,7 @@ static void __init pnpidacpi_to_pnpid(char *id, char *str) | |||
82 | static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res) | 82 | static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res) |
83 | { | 83 | { |
84 | acpi_status status; | 84 | acpi_status status; |
85 | status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, | 85 | status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, |
86 | &dev->res); | 86 | &dev->res); |
87 | return ACPI_FAILURE(status) ? -ENODEV : 0; | 87 | return ACPI_FAILURE(status) ? -ENODEV : 0; |
88 | } | 88 | } |
@@ -112,9 +112,9 @@ static int pnpacpi_set_resources(struct pnp_dev * dev, struct pnp_resource_table | |||
112 | static int pnpacpi_disable_resources(struct pnp_dev *dev) | 112 | static int pnpacpi_disable_resources(struct pnp_dev *dev) |
113 | { | 113 | { |
114 | acpi_status status; | 114 | acpi_status status; |
115 | 115 | ||
116 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ | 116 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ |
117 | status = acpi_evaluate_object((acpi_handle)dev->data, | 117 | status = acpi_evaluate_object((acpi_handle)dev->data, |
118 | "_DIS", NULL, NULL); | 118 | "_DIS", NULL, NULL); |
119 | return ACPI_FAILURE(status) ? -ENODEV : 0; | 119 | return ACPI_FAILURE(status) ? -ENODEV : 0; |
120 | } | 120 | } |
@@ -167,7 +167,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
167 | strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); | 167 | strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); |
168 | 168 | ||
169 | dev->number = num; | 169 | dev->number = num; |
170 | 170 | ||
171 | /* set the initial values for the PnP device */ | 171 | /* set the initial values for the PnP device */ |
172 | dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); | 172 | dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); |
173 | if (!dev_id) | 173 | if (!dev_id) |
@@ -185,14 +185,14 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | if(dev->capabilities & PNP_CONFIGURABLE) { | 187 | if(dev->capabilities & PNP_CONFIGURABLE) { |
188 | status = pnpacpi_parse_resource_option_data(device->handle, | 188 | status = pnpacpi_parse_resource_option_data(device->handle, |
189 | dev); | 189 | dev); |
190 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { | 190 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { |
191 | pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id); | 191 | pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id); |
192 | goto err1; | 192 | goto err1; |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | /* parse compatible ids */ | 196 | /* parse compatible ids */ |
197 | if (device->flags.compatible_ids) { | 197 | if (device->flags.compatible_ids) { |
198 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 198 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; |
@@ -236,6 +236,42 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, | |||
236 | return AE_OK; | 236 | return AE_OK; |
237 | } | 237 | } |
238 | 238 | ||
239 | static int __init acpi_pnp_match(struct device *dev, void *_pnp) | ||
240 | { | ||
241 | struct acpi_device *acpi = to_acpi_device(dev); | ||
242 | struct pnp_dev *pnp = _pnp; | ||
243 | |||
244 | /* true means it matched */ | ||
245 | return acpi->flags.hardware_id | ||
246 | && !acpi_get_physical_device(acpi->handle) | ||
247 | && compare_pnp_id(pnp->id, acpi->pnp.hardware_id); | ||
248 | } | ||
249 | |||
250 | static int __init acpi_pnp_find_device(struct device *dev, acpi_handle *handle) | ||
251 | { | ||
252 | struct device *adev; | ||
253 | struct acpi_device *acpi; | ||
254 | |||
255 | adev = bus_find_device(&acpi_bus_type, NULL, | ||
256 | to_pnp_dev(dev), | ||
257 | acpi_pnp_match); | ||
258 | if (!adev) | ||
259 | return -ENODEV; | ||
260 | |||
261 | acpi = to_acpi_device(adev); | ||
262 | *handle = acpi->handle; | ||
263 | put_device(adev); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* complete initialization of a PNPACPI device includes having | ||
268 | * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. | ||
269 | */ | ||
270 | static struct acpi_bus_type __initdata acpi_pnp_bus = { | ||
271 | .bus = &pnp_bus_type, | ||
272 | .find_device = acpi_pnp_find_device, | ||
273 | }; | ||
274 | |||
239 | int pnpacpi_disabled __initdata; | 275 | int pnpacpi_disabled __initdata; |
240 | static int __init pnpacpi_init(void) | 276 | static int __init pnpacpi_init(void) |
241 | { | 277 | { |
@@ -245,8 +281,10 @@ static int __init pnpacpi_init(void) | |||
245 | } | 281 | } |
246 | pnp_info("PnP ACPI init"); | 282 | pnp_info("PnP ACPI init"); |
247 | pnp_register_protocol(&pnpacpi_protocol); | 283 | pnp_register_protocol(&pnpacpi_protocol); |
284 | register_acpi_bus_type(&acpi_pnp_bus); | ||
248 | acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); | 285 | acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); |
249 | pnp_info("PnP ACPI: found %d devices", num); | 286 | pnp_info("PnP ACPI: found %d devices", num); |
287 | unregister_acpi_bus_type(&acpi_pnp_bus); | ||
250 | return 0; | 288 | return 0; |
251 | } | 289 | } |
252 | subsys_initcall(pnpacpi_init); | 290 | subsys_initcall(pnpacpi_init); |