#include <linux/pnp.h>
#include <linux/mod_devicetable.h>
#include <acpi/acpi_bus.h>
-#include <acpi/actypes.h>
+#include "../base.h"
#include "pnpacpi.h"
static int num = 0;
* have irqs (PIC, Timer) because we call acpi_register_gsi.
* Finally, only devices that have a CRS method need to be in this list.
*/
-static struct __initdata acpi_device_id excluded_id_list[] = {
+static struct acpi_device_id excluded_id_list[] __initdata = {
{"PNP0C09", 0}, /* EC */
{"PNP0C0F", 0}, /* Link device */
{"PNP0000", 0}, /* PIC */
{"", 0},
};
-static inline int is_exclusive_device(struct acpi_device *dev)
+static inline int __init is_exclusive_device(struct acpi_device *dev)
{
return (!acpi_match_device_ids(dev, excluded_id_list));
}
return 1;
}
-static void __init pnpidacpi_to_pnpid(char *id, char *str)
+static int pnpacpi_get_resources(struct pnp_dev *dev)
{
- str[0] = id[0];
- str[1] = id[1];
- str[2] = id[2];
- str[3] = tolower(id[3]);
- str[4] = tolower(id[4]);
- str[5] = tolower(id[5]);
- str[6] = tolower(id[6]);
- str[7] = '\0';
+ pnp_dbg(&dev->dev, "get resources\n");
+ return pnpacpi_parse_allocated_resource(dev);
}
-static int pnpacpi_get_resources(struct pnp_dev *dev,
- struct pnp_resource_table *res)
+static int pnpacpi_set_resources(struct pnp_dev *dev)
{
- acpi_status status;
-
- status = pnpacpi_parse_allocated_resource((acpi_handle) dev->data,
- &dev->res);
- return ACPI_FAILURE(status) ? -ENODEV : 0;
-}
-
-static int pnpacpi_set_resources(struct pnp_dev *dev,
- struct pnp_resource_table *res)
-{
- acpi_handle handle = dev->data;
+ struct acpi_device *acpi_dev = dev->data;
+ acpi_handle handle = acpi_dev->handle;
struct acpi_buffer buffer;
- int ret = 0;
- acpi_status status;
+ int ret;
- ret = pnpacpi_build_resource_template(handle, &buffer);
+ pnp_dbg(&dev->dev, "set resources\n");
+ ret = pnpacpi_build_resource_template(dev, &buffer);
if (ret)
return ret;
- ret = pnpacpi_encode_resources(res, &buffer);
+ ret = pnpacpi_encode_resources(dev, &buffer);
if (ret) {
kfree(buffer.pointer);
return ret;
}
- status = acpi_set_current_resources(handle, &buffer);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
ret = -EINVAL;
+ else if (acpi_bus_power_manageable(handle))
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
kfree(buffer.pointer);
return ret;
}
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
- acpi_status status;
+ struct acpi_device *acpi_dev = dev->data;
+ acpi_handle handle = acpi_dev->handle;
+ int ret;
+
+ dev_dbg(&dev->dev, "disable resources\n");
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle) dev->data,
- "_DIS", NULL, NULL);
- return ACPI_FAILURE(status) ? -ENODEV : 0;
+ ret = 0;
+ if (acpi_bus_power_manageable(handle))
+ acpi_bus_set_power(handle, ACPI_STATE_D3);
+ /* continue even if acpi_bus_set_power() fails */
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+ ret = -ENODEV;
+ return ret;
}
#ifdef CONFIG_ACPI_SLEEP
static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{
+ struct acpi_device *acpi_dev = dev->data;
+ acpi_handle handle = acpi_dev->handle;
int power_state;
- power_state = acpi_pm_device_sleep_state(&dev->dev,
- device_may_wakeup(&dev->dev),
- NULL);
+ power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
if (power_state < 0)
power_state = (state.event == PM_EVENT_ON) ?
ACPI_STATE_D0 : ACPI_STATE_D3;
- return acpi_bus_set_power((acpi_handle) dev->data, power_state);
+ return acpi_bus_set_power(handle, power_state);
}
static int pnpacpi_resume(struct pnp_dev *dev)
{
- return acpi_bus_set_power((acpi_handle) dev->data, ACPI_STATE_D0);
+ struct acpi_device *acpi_dev = dev->data;
+ acpi_handle handle = acpi_dev->handle;
+
+ return acpi_bus_set_power(handle, ACPI_STATE_D0);
}
#endif
-static struct pnp_protocol pnpacpi_protocol = {
+struct pnp_protocol pnpacpi_protocol = {
.name = "Plug and Play ACPI",
.get = pnpacpi_get_resources,
.set = pnpacpi_set_resources,
.resume = pnpacpi_resume,
#endif
};
+EXPORT_SYMBOL(pnpacpi_protocol);
static int __init pnpacpi_add_device(struct acpi_device *device)
{
acpi_handle temp = NULL;
acpi_status status;
- struct pnp_id *dev_id;
struct pnp_dev *dev;
+ struct acpi_hardware_id *id;
+ /*
+ * If a PnPacpi device is not present , the device
+ * driver should not be loaded.
+ */
status = acpi_get_handle(device->handle, "_CRS", &temp);
if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
- is_exclusive_device(device))
+ is_exclusive_device(device) || (!device->status.present))
return 0;
- dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
- if (!dev) {
- pnp_err("Out of memory");
+ dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
+ if (!dev)
return -ENOMEM;
- }
- dev->data = device->handle;
+
+ dev->data = device;
/* .enabled means the device can decode the resources */
dev->active = device->status.enabled;
status = acpi_get_handle(device->handle, "_SRS", &temp);
if (ACPI_SUCCESS(status))
dev->capabilities |= PNP_CONFIGURABLE;
dev->capabilities |= PNP_READ;
- if (device->flags.dynamic_status)
+ if (device->flags.dynamic_status && (dev->capabilities & PNP_CONFIGURABLE))
dev->capabilities |= PNP_WRITE;
if (device->flags.removable)
dev->capabilities |= PNP_REMOVABLE;
if (ACPI_SUCCESS(status))
dev->capabilities |= PNP_DISABLE;
- dev->protocol = &pnpacpi_protocol;
-
if (strlen(acpi_device_name(device)))
strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
else
strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
- dev->number = num;
-
- /* set the initial values for the PnP device */
- dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
- if (!dev_id)
- goto err;
- pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
- pnp_add_id(dev_id, dev);
-
- if (dev->active) {
- /* parse allocated resource */
- status = pnpacpi_parse_allocated_resource(device->handle,
- &dev->res);
- if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
- pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s",
- dev_id->id);
- goto err1;
- }
- }
+ if (dev->active)
+ pnpacpi_parse_allocated_resource(dev);
- if (dev->capabilities & PNP_CONFIGURABLE) {
- status = pnpacpi_parse_resource_option_data(device->handle,
- dev);
- if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
- pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s",
- dev_id->id);
- goto err1;
- }
- }
+ if (dev->capabilities & PNP_CONFIGURABLE)
+ pnpacpi_parse_resource_option_data(dev);
- /* parse compatible ids */
- if (device->flags.compatible_ids) {
- struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
- int i;
-
- for (i = 0; i < cid_list->count; i++) {
- if (!ispnpidacpi(cid_list->id[i].value))
- continue;
- dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
- if (!dev_id)
- continue;
-
- pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);
- pnp_add_id(dev_id, dev);
- }
+ list_for_each_entry(id, &device->pnp.ids, list) {
+ if (!strcmp(id->id, acpi_device_hid(device)))
+ continue;
+ if (!ispnpidacpi(id->id))
+ continue;
+ pnp_add_id(dev, id->id);
}
/* clear out the damaged flags */
if (!dev->active)
- pnp_init_resource_table(&dev->res);
+ pnp_init_resources(dev);
pnp_add_device(dev);
num++;
return AE_OK;
-err1:
- kfree(dev_id);
-err:
- kfree(dev);
- return -EINVAL;
}
static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
struct pnp_dev *pnp = _pnp;
/* true means it matched */
- return acpi->flags.hardware_id
- && !acpi_get_physical_device(acpi->handle)
- && compare_pnp_id(pnp->id, acpi->pnp.hardware_id);
+ return !acpi_get_physical_device(acpi->handle)
+ && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
}
static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle)
static int __init pnpacpi_init(void)
{
if (acpi_disabled || pnpacpi_disabled) {
- pnp_info("PnP ACPI: disabled");
+ printk(KERN_INFO "pnp: PnP ACPI: disabled\n");
return 0;
}
- pnp_info("PnP ACPI init");
+ printk(KERN_INFO "pnp: PnP ACPI init\n");
pnp_register_protocol(&pnpacpi_protocol);
register_acpi_bus_type(&acpi_pnp_bus);
acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
- pnp_info("PnP ACPI: found %d devices", num);
+ printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num);
unregister_acpi_bus_type(&acpi_pnp_bus);
pnp_platform_devices = 1;
return 0;
}
-subsys_initcall(pnpacpi_init);
+fs_initcall(pnpacpi_init);
static int __init pnpacpi_setup(char *str)
{