bool acpi_device_always_present(struct acpi_device *adev) { bool ret = false; unsigned int i; for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) { if (acpi_match_device_ids(adev, always_present_ids[i].hid)) continue; if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, always_present_ids[i].uid)) continue; if (!x86_match_cpu(always_present_ids[i].cpu_ids)) continue; if (always_present_ids[i].dmi_ids[0].matches[0].slot && !dmi_check_system(always_present_ids[i].dmi_ids)) continue; ret = true; break; } return ret; }
/** * acpi_create_platform_device - Create platform device for ACPI device node * @adev: ACPI device node to create a platform device for. * * Check if the given @adev can be represented as a platform device and, if * that's the case, create and register a platform device, populate its common * resources and returns a pointer to it. Otherwise, return %NULL. * * Name of the platform device will be the same as @adev's. */ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) { struct platform_device *pdev = NULL; struct acpi_device *acpi_parent; struct platform_device_info pdevinfo; struct resource_entry *rentry; struct list_head resource_list; struct resource *resources = NULL; int count; /* If the ACPI node already has a physical device attached, skip it. */ if (adev->physical_node_count) return NULL; if (!acpi_match_device_ids(adev, forbidden_id_list)) return ERR_PTR(-EINVAL); INIT_LIST_HEAD(&resource_list); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); if (count < 0) { return NULL; } else if (count > 0) { resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); if (!resources) { dev_err(&adev->dev, "No memory for resources\n"); acpi_dev_free_resource_list(&resource_list); return ERR_PTR(-ENOMEM); } count = 0; list_for_each_entry(rentry, &resource_list, node) resources[count++] = *rentry->res; acpi_dev_free_resource_list(&resource_list); } memset(&pdevinfo, 0, sizeof(pdevinfo)); /* * If the ACPI node has a parent and that parent has a physical device * attached to it, that physical device should be the parent of the * platform device we are about to create. */ pdevinfo.parent = NULL; acpi_parent = adev->parent; if (acpi_parent) { struct acpi_device_physical_node *entry; struct list_head *list; mutex_lock(&acpi_parent->physical_node_lock); list = &acpi_parent->physical_node_list; if (!list_empty(list)) { entry = list_first_entry(list, struct acpi_device_physical_node, node); pdevinfo.parent = entry->dev; } mutex_unlock(&acpi_parent->physical_node_lock); }
/* * For CMOS RTC devices, the PNP ACPI scan handler does not work, because * there is a CMOS RTC ACPI scan handler installed already, so we need to * check those devices and enumerate them to the PNP bus directly. */ static int is_cmos_rtc_device(struct acpi_device *adev) { struct acpi_device_id ids[] = { { "PNP0B00" }, { "PNP0B01" }, { "PNP0B02" }, {""}, }; return !acpi_match_device_ids(adev, ids); }
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) { struct acpi_pci_root *root; struct acpi_device *device; if (acpi_bus_get_device(handle, &device) || acpi_match_device_ids(device, root_device_ids)) return NULL; root = acpi_driver_data(device); return root; }
static int __init match_acpi_dev(struct device *dev, void *data) { struct acpi_hid_uid hid_uid = *(struct acpi_hid_uid *)data; struct acpi_device *adev = to_acpi_device(dev); if (acpi_match_device_ids(adev, hid_uid.hid)) return 0; if (adev->pnp.unique_id) return !strcmp(adev->pnp.unique_id, hid_uid.uid); else return !strcmp("0", hid_uid.uid); }
/** * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge * @handle - the ACPI CA node in question. * * Note: we could make this API take a struct acpi_device * instead, but * for now, it's more convenient to operate on an acpi_handle. */ int acpi_is_root_bridge(acpi_handle handle) { int ret; struct acpi_device *device; ret = acpi_bus_get_device(handle, &device); if (ret) return 0; ret = acpi_match_device_ids(device, root_device_ids); if (ret) return 0; else return 1; }
/* * Unfortunately, some laptops provide a _HID="INT33D5" device with * _CID="PNP0C02". This causes the pnpacpi scan driver to claim the * ACPI node, so no platform device will be created. The pnpacpi * driver rejects this device in subsequent processing, so no physical * node is created at all. * * As a workaround until the ACPI core figures out how to handle * this corner case, manually ask the ACPI platform device code to * claim the ACPI node. */ static acpi_status __init check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv) { const struct acpi_device_id *ids = context; struct acpi_device *dev; if (acpi_bus_get_device(handle, &dev) != 0) return AE_OK; if (acpi_match_device_ids(dev, ids) == 0) if (acpi_create_platform_device(dev, NULL)) dev_info(&dev->dev, "intel-hid: created platform device\n"); return AE_OK; }
static acpi_status find_video(acpi_handle handle, u32 lvl, void *context, void **rv) { long *cap = context; struct pci_dev *dev; struct acpi_device *acpi_dev; static const struct acpi_device_id video_ids[] = { {ACPI_VIDEO_HID, 0}, {"", 0}, }; if (acpi_bus_get_device(handle, &acpi_dev)) return AE_OK; if (!acpi_match_device_ids(acpi_dev, video_ids)) { dev = acpi_get_pci_dev(handle); if (!dev) return AE_OK; pci_dev_put(dev); *cap |= acpi_is_video_device(handle); } return AE_OK; }
static inline int __init is_exclusive_device(struct acpi_device *dev) { return (!acpi_match_device_ids(dev, excluded_id_list)); }
/** * acpi_create_platform_device - Create platform device for ACPI device node * @adev: ACPI device node to create a platform device for. * * Check if the given @adev can be represented as a platform device and, if * that's the case, create and register a platform device, populate its common * resources and returns a pointer to it. Otherwise, return %NULL. * * Name of the platform device will be the same as @adev's. */ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) { struct platform_device *pdev = NULL; struct platform_device_info pdevinfo; struct resource_entry *rentry; struct list_head resource_list; struct resource *resources = NULL; int count; /* If the ACPI node already has a physical device attached, skip it. */ if (adev->physical_node_count) return NULL; if (!acpi_match_device_ids(adev, forbidden_id_list)) return ERR_PTR(-EINVAL); INIT_LIST_HEAD(&resource_list); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); if (count < 0) { return NULL; } else if (count > 0) { resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); if (!resources) { dev_err(&adev->dev, "No memory for resources\n"); acpi_dev_free_resource_list(&resource_list); return ERR_PTR(-ENOMEM); } count = 0; list_for_each_entry(rentry, &resource_list, node) resources[count++] = *rentry->res; acpi_dev_free_resource_list(&resource_list); } memset(&pdevinfo, 0, sizeof(pdevinfo)); /* * If the ACPI node has a parent and that parent has a physical device * attached to it, that physical device should be the parent of the * platform device we are about to create. */ pdevinfo.parent = adev->parent ? acpi_get_first_physical_node(adev->parent) : NULL; pdevinfo.name = dev_name(&adev->dev); pdevinfo.id = -1; pdevinfo.res = resources; pdevinfo.num_res = count; pdevinfo.fwnode = acpi_fwnode_handle(adev); if (acpi_dma_supported(adev)) pdevinfo.dma_mask = DMA_BIT_MASK(32); else pdevinfo.dma_mask = 0; pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) dev_err(&adev->dev, "platform device creation failed: %ld\n", PTR_ERR(pdev)); else dev_dbg(&adev->dev, "created platform device %s\n", dev_name(&pdev->dev)); kfree(resources); return pdev; }