#include "internal.h"
static const struct acpi_device_id forbidden_id_list[] = {
+++ {"ACPI0009", 0}, /* IOxAPIC */
+++ {"ACPI000A", 0}, /* IOAPIC */
{"PNP0000", 0}, /* PIC */
{"PNP0100", 0}, /* Timer */
{"PNP0200", 0}, /* AT DMA Controller */
--- {"ACPI0009", 0}, /* IOxAPIC */
--- {"ACPI000A", 0}, /* IOAPIC */
{"SMB0001", 0}, /* ACPI SMBUS virtual device */
--- {"", 0},
+++ { }
};
static struct platform_device *acpi_platform_device_find_by_companion(struct acpi_device *adev)
* If the device has parent we need to take its resources into
* account as well because this device might consume part of those.
*/
--- parent = acpi_get_first_physical_node(adev->parent);
+++ parent = acpi_get_first_physical_node(acpi_dev_parent(adev));
if (parent && dev_is_pci(parent))
dest->parent = pci_find_resource(to_pci_dev(parent), dest);
}
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
const struct property_entry *properties)
{
+++ struct acpi_device *parent = acpi_dev_parent(adev);
struct platform_device *pdev = NULL;
struct platform_device_info pdevinfo;
struct resource_entry *rentry;
INIT_LIST_HEAD(&resource_list);
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
--- if (count < 0) {
+++ if (count < 0)
return NULL;
--- } else if (count > 0) {
--- resources = kcalloc(count, sizeof(struct resource),
--- GFP_KERNEL);
+++ if (count > 0) {
+++ resources = kcalloc(count, sizeof(*resources), GFP_KERNEL);
if (!resources) {
--- dev_err(&adev->dev, "No memory for resources\n");
acpi_dev_free_resource_list(&resource_list);
return ERR_PTR(-ENOMEM);
}
* 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.parent = parent ? acpi_get_first_physical_node(parent) : NULL;
pdevinfo.name = dev_name(&adev->dev);
--- pdevinfo.id = -1;
+++ pdevinfo.id = PLATFORM_DEVID_NONE;
pdevinfo.res = resources;
pdevinfo.num_res = count;
pdevinfo.fwnode = acpi_fwnode_handle(adev);
Notification Handling
-------------------------------------------------------------------------- */
-- -/**
++ +/*
* acpi_bus_notify
* ---------------
* Callback for all 'system-level' device notifications (values 0x00-0x7F).
break;
}
--- adev = acpi_bus_get_acpi_device(handle);
+++ adev = acpi_get_acpi_dev(handle);
if (!adev)
goto err;
}
if (!hotplug_event) {
--- acpi_bus_put_acpi_device(adev);
+++ acpi_put_acpi_dev(adev);
return;
}
if (ACPI_SUCCESS(acpi_hotplug_schedule(adev, type)))
return;
--- acpi_bus_put_acpi_device(adev);
+++ acpi_put_acpi_dev(adev);
err:
acpi_evaluate_ost(handle, type, ost_code, NULL);
const void *acpi_device_get_match_data(const struct device *dev)
{
++ + const struct acpi_device_id *acpi_ids = dev->driver->acpi_match_table;
const struct acpi_device_id *match;
-- - if (!dev->driver->acpi_match_table)
++ + if (!acpi_ids)
return acpi_of_device_get_match_data(dev);
-- - match = acpi_match_device(dev->driver->acpi_match_table, dev);
++ + match = acpi_match_device(acpi_ids, dev);
if (!match)
return NULL;
bool acpi_driver_match_device(struct device *dev,
const struct device_driver *drv)
{
-- - if (!drv->acpi_match_table)
-- - return acpi_of_match_device(ACPI_COMPANION(dev),
-- - drv->of_match_table,
-- - NULL);
++ + const struct acpi_device_id *acpi_ids = drv->acpi_match_table;
++ + const struct of_device_id *of_ids = drv->of_match_table;
-- - return __acpi_match_device(acpi_companion_match(dev),
-- - drv->acpi_match_table, drv->of_match_table,
-- - NULL, NULL);
++ + if (!acpi_ids)
++ + return acpi_of_match_device(ACPI_COMPANION(dev), of_ids, NULL);
++ +
++ + return __acpi_match_device(acpi_companion_match(dev), acpi_ids, of_ids, NULL, NULL);
}
EXPORT_SYMBOL_GPL(acpi_driver_match_device);
*/
int acpi_bus_register_driver(struct acpi_driver *driver)
{
-- - int ret;
-- -
if (acpi_disabled)
return -ENODEV;
driver->drv.name = driver->name;
driver->drv.bus = &acpi_bus_type;
driver->drv.owner = driver->owner;
-- - ret = driver_register(&driver->drv);
-- - return ret;
++ + return driver_register(&driver->drv);
}
EXPORT_SYMBOL(acpi_bus_register_driver);
#include <linux/platform_data/x86/apple.h>
#include <linux/pgtable.h>
#include <linux/crc32.h>
+ ++#include <linux/dma-direct.h>
#include "internal.h"
#define ACPI_BUS_HID "LNXSYBUS"
#define ACPI_BUS_DEVICE_NAME "System Bus"
---#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
---
#define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page)
static const char *dummy_hid = "device";
acpi_evaluate_ost(adev->handle, src, ost_code, NULL);
out:
--- acpi_bus_put_acpi_device(adev);
+++ acpi_put_acpi_dev(adev);
mutex_unlock(&acpi_scan_lock);
unlock_device_hotplug();
}
acpi_dev_get(dev);
}
---struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle)
+++/**
+++ * acpi_get_acpi_dev - Retrieve ACPI device object and reference count it.
+++ * @handle: ACPI handle associated with the requested ACPI device object.
+++ *
+++ * Return a pointer to the ACPI device object associated with @handle and bump
+++ * up that object's reference counter (under the ACPI Namespace lock), if
+++ * present, or return NULL otherwise.
+++ *
+++ * The ACPI device object reference acquired by this function needs to be
+++ * dropped via acpi_dev_put().
+++ */
+++struct acpi_device *acpi_get_acpi_dev(acpi_handle handle)
{
return handle_to_device(handle, get_acpi_device);
}
---EXPORT_SYMBOL_GPL(acpi_bus_get_acpi_device);
+++EXPORT_SYMBOL_GPL(acpi_get_acpi_dev);
static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
{
return 0;
}
---static int acpi_tie_acpi_dev(struct acpi_device *adev)
+++int acpi_tie_acpi_dev(struct acpi_device *adev)
{
acpi_handle handle = adev->handle;
acpi_status status;
ACPI_FREE(pld);
}
---static int __acpi_device_add(struct acpi_device *device,
--- void (*release)(struct device *))
+++int acpi_device_add(struct acpi_device *device)
{
struct acpi_device_bus_id *acpi_device_bus_id;
int result;
mutex_unlock(&acpi_device_lock);
--- if (device->parent)
--- device->dev.parent = &device->parent->dev;
---
--- device->dev.bus = &acpi_bus_type;
--- device->dev.release = release;
result = device_add(&device->dev);
if (result) {
dev_err(&device->dev, "Error registering device\n");
return result;
}
---int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *))
---{
--- int ret;
---
--- ret = acpi_tie_acpi_dev(adev);
--- if (ret)
--- return ret;
---
--- return __acpi_device_add(adev, release);
---}
---
/* --------------------------------------------------------------------------
Device Enumeration
-------------------------------------------------------------------------- */
NULL
};
---static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
+++static struct acpi_device *acpi_find_parent_acpi_dev(acpi_handle handle)
{
--- struct acpi_device *device;
--- acpi_status status;
+++ struct acpi_device *adev;
/*
* Fixed hardware devices do not appear in the namespace and do not
return acpi_root;
do {
+++ acpi_status status;
+++
status = acpi_get_parent(handle, &handle);
--- if (ACPI_FAILURE(status))
--- return status == AE_NULL_ENTRY ? NULL : acpi_root;
+++ if (ACPI_FAILURE(status)) {
+++ if (status != AE_NULL_ENTRY)
+++ return acpi_root;
--- device = acpi_fetch_acpi_dev(handle);
--- } while (!device);
--- return device;
+++ return NULL;
+++ }
+++ adev = acpi_fetch_acpi_dev(handle);
+++ } while (!adev);
+++ return adev;
}
acpi_status
* The device's Bus ID is simply the object name.
* TBD: Shouldn't this value be unique (within the ACPI namespace)?
*/
--- if (ACPI_IS_ROOT_DEVICE(device)) {
+++ if (!acpi_dev_parent(device)) {
strcpy(device->pnp.bus_id, "ACPI");
return;
}
* acpi_dma_get_range() - Get device DMA parameters.
*
* @dev: device to configure
- -- * @dma_addr: pointer device DMA address result
- -- * @offset: pointer to the DMA offset result
- -- * @size: pointer to DMA range size result
+ ++ * @map: pointer to DMA ranges result
*
- -- * Evaluate DMA regions and return respectively DMA region start, offset
- -- * and size in dma_addr, offset and size on parsing success; it does not
- -- * update the passed in values on failure.
+ ++ * Evaluate DMA regions and return pointer to DMA regions on
+ ++ * parsing success; it does not update the passed in values on failure.
*
* Return 0 on success, < 0 on failure.
*/
- --int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
- -- u64 *size)
+ ++int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
{
struct acpi_device *adev;
LIST_HEAD(list);
struct resource_entry *rentry;
int ret;
struct device *dma_dev = dev;
- -- u64 len, dma_start = U64_MAX, dma_end = 0, dma_offset = 0;
+ ++ struct bus_dma_region *r;
/*
* Walk the device tree chasing an ACPI companion with a _DMA
ret = acpi_dev_get_dma_resources(adev, &list);
if (ret > 0) {
+ ++ r = kcalloc(ret + 1, sizeof(*r), GFP_KERNEL);
+ ++ if (!r) {
+ ++ ret = -ENOMEM;
+ ++ goto out;
+ ++ }
+ ++
list_for_each_entry(rentry, &list, node) {
- -- if (dma_offset && rentry->offset != dma_offset) {
+ ++ if (rentry->res->start >= rentry->res->end) {
+ ++ kfree(r);
ret = -EINVAL;
- -- dev_warn(dma_dev, "Can't handle multiple windows with different offsets\n");
+ ++ dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
goto out;
}
- -- dma_offset = rentry->offset;
- -- /* Take lower and upper limits */
- -- if (rentry->res->start < dma_start)
- -- dma_start = rentry->res->start;
- -- if (rentry->res->end > dma_end)
- -- dma_end = rentry->res->end;
- -- }
- --
- -- if (dma_start >= dma_end) {
- -- ret = -EINVAL;
- -- dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
- -- goto out;
+ ++ r->cpu_start = rentry->res->start;
+ ++ r->dma_start = rentry->res->start - rentry->offset;
+ ++ r->size = resource_size(rentry->res);
+ ++ r->offset = rentry->offset;
+ ++ r++;
}
- -- *dma_addr = dma_start - dma_offset;
- -- len = dma_end - dma_start;
- -- *size = max(len, len + 1);
- -- *offset = dma_offset;
+ ++ *map = r;
}
out:
acpi_dev_free_resource_list(&list);
const u32 *input_id)
{
const struct iommu_ops *iommu;
- -- u64 dma_addr = 0, size = 0;
if (attr == DEV_DMA_NOT_SUPPORTED) {
set_dma_ops(dev, &dma_dummy_ops);
return 0;
}
- -- acpi_arch_dma_setup(dev, &dma_addr, &size);
+ ++ acpi_arch_dma_setup(dev);
iommu = acpi_iommu_configure_id(dev, input_id);
if (PTR_ERR(iommu) == -EPROBE_DEFER)
return -EPROBE_DEFER;
- -- arch_setup_dma_ops(dev, dma_addr, size,
+ ++ arch_setup_dma_ops(dev, 0, U64_MAX,
iommu, attr == DEV_DMA_COHERENT);
return 0;
{
unsigned long long cca = 0;
acpi_status status;
--- struct acpi_device *parent = adev->parent;
+++ struct acpi_device *parent = acpi_dev_parent(adev);
if (parent && parent->flags.cca_seen) {
/*
static bool acpi_is_indirect_io_slave(struct acpi_device *device)
{
--- struct acpi_device *parent = device->parent;
+++ struct acpi_device *parent = acpi_dev_parent(device);
static const struct acpi_device_id indirect_io_hosts[] = {
{"HISI0191", 0},
{}
}
void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
--- int type)
+++ int type, void (*release)(struct device *))
{
+++ struct acpi_device *parent = acpi_find_parent_acpi_dev(handle);
+++
INIT_LIST_HEAD(&device->pnp.ids);
device->device_type = type;
device->handle = handle;
--- device->parent = acpi_bus_get_parent(handle);
+++ device->dev.parent = parent ? &parent->dev : NULL;
+++ device->dev.release = release;
+++ device->dev.bus = &acpi_bus_type;
fwnode_init(&device->fwnode, &acpi_device_fwnode_ops);
acpi_set_device_status(device, ACPI_STA_DEFAULT);
acpi_device_get_busid(device);
if (!device)
return -ENOMEM;
--- acpi_init_device_object(device, handle, type);
+++ acpi_init_device_object(device, handle, type, acpi_device_release);
/*
* Getting the status is delayed till here so that we can call
* acpi_bus_get_status() and use its quirk handling. Note that
mutex_unlock(&acpi_dep_list_lock);
if (!result)
--- result = __acpi_device_add(device, acpi_device_release);
+++ result = acpi_device_add(device);
if (result) {
acpi_device_release(&device->dev);
acpi_device_add_finalize(device);
acpi_handle_debug(handle, "Added as %s, parent %s\n",
--- dev_name(&device->dev), device->parent ?
--- dev_name(&device->parent->dev) : "(null)");
+++ dev_name(&device->dev), device->dev.parent ?
+++ dev_name(device->dev.parent) : "(null)");
*child = device;
return 0;
return 0;
}
---static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
+++static int acpi_dev_get_next_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
{
--- struct acpi_device *adev;
+++ struct acpi_device **adev_p = data;
+++ struct acpi_device *adev = *adev_p;
+
-- adev = acpi_bus_get_acpi_device(dep->consumer);
+++ /*
+++ * If we're passed a 'previous' consumer device then we need to skip
+++ * any consumers until we meet the previous one, and then NULL @data
+++ * so the next one can be returned.
+++ */
+++ if (adev) {
+++ if (dep->consumer == adev->handle)
+++ *adev_p = NULL;
+++
+++ return 0;
+++ }
++
- adev = acpi_bus_get_acpi_device(dep->consumer);
+++ adev = acpi_get_acpi_dev(dep->consumer);
if (adev) {
*(struct acpi_device **)data = adev;
return 1;
static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
{
--- struct acpi_device *adev = acpi_bus_get_acpi_device(dep->consumer);
+++ struct acpi_device *adev = acpi_get_acpi_dev(dep->consumer);
if (adev) {
adev->dep_unmet--;
EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
/**
--- * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
+++ * acpi_dev_get_next_consumer_dev - Return the next adev dependent on @supplier
* @supplier: Pointer to the dependee device
+++ * @start: Pointer to the current dependent device
*
--- * Returns the first &struct acpi_device which declares itself dependent on
+++ * Returns the next &struct acpi_device which declares itself dependent on
* @supplier via the _DEP buffer, parsed from the acpi_dep_list.
*
--- * The caller is responsible for putting the reference to adev when it is no
--- * longer needed.
+++ * If the returned adev is not passed as @start to this function, the caller is
+++ * responsible for putting the reference to adev when it is no longer needed.
*/
---struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
+++struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
+++ struct acpi_device *start)
{
--- struct acpi_device *adev = NULL;
+++ struct acpi_device *adev = start;
acpi_walk_dep_device_list(supplier->handle,
--- acpi_dev_get_first_consumer_dev_cb, &adev);
+++ acpi_dev_get_next_consumer_dev_cb, &adev);
+++
+++ acpi_dev_put(start);
+++
+++ if (adev == start)
+++ return NULL;
return adev;
}
---EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
+++EXPORT_SYMBOL_GPL(acpi_dev_get_next_consumer_dev);
/**
* acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
int device_type;
acpi_handle handle; /* no handle for fixed hardware */
struct fwnode_handle fwnode;
--- struct acpi_device *parent;
struct list_head wakeup_list;
struct list_head del_list;
struct acpi_device_status status;
#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
+++static inline struct acpi_device *acpi_dev_parent(struct acpi_device *adev)
+++{
+++ if (adev->dev.parent)
+++ return to_acpi_device(adev->dev.parent);
+++
+++ return NULL;
+++}
+++
static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
{
*((u32 *)&adev->status) = sta;
* External Functions
*/
---struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle);
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
unsigned long long *sta);
int acpi_bus_get_status(struct acpi_device *device);
int acpi_iommu_fwspec_init(struct device *dev, u32 id,
struct fwnode_handle *fwnode,
const struct iommu_ops *ops);
- --int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
- -- u64 *size);
+ ++int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
const u32 *input_id);
static inline int acpi_dma_configure(struct device *dev,
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
---struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
+++struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
+++ struct acpi_device *start);
+++
+++/**
+++ * for_each_acpi_consumer_dev - iterate over the consumer ACPI devices for a
+++ * given supplier
+++ * @supplier: Pointer to the supplier's ACPI device
+++ * @consumer: Pointer to &struct acpi_device to hold the consumer, initially NULL
+++ */
+++#define for_each_acpi_consumer_dev(supplier, consumer) \
+++ for (consumer = acpi_dev_get_next_consumer_dev(supplier, NULL); \
+++ consumer; \
+++ consumer = acpi_dev_get_next_consumer_dev(supplier, consumer))
+++
struct acpi_device *
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
struct acpi_device *
put_device(&adev->dev);
}
---struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
+++struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle);
+++struct acpi_device *acpi_get_acpi_dev(acpi_handle handle);
---static inline void acpi_bus_put_acpi_device(struct acpi_device *adev)
+++static inline void acpi_put_acpi_dev(struct acpi_device *adev)
{
acpi_dev_put(adev);
}