aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bus
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2022-07-29 19:58:52 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2022-07-29 19:58:52 +0200
commitd60b6b0bc00365ab338804213437785d269f777b (patch)
treee3a56a9fc3e2cd3ebc2301bdd9058a0bc2679270 /drivers/bus
parentACPI: CPPC: Do not prevent CPPC from working in the future (diff)
parentACPI: bus: Drop unused list heads from struct acpi_device (diff)
downloadlinux-dev-d60b6b0bc00365ab338804213437785d269f777b.tar.xz
linux-dev-d60b6b0bc00365ab338804213437785d269f777b.zip
Merge branch 'acpi-bus'
Merge ACPI device object management changes for v5.20-rc1. - Use the facilities provided by the driver core and some additional helpers to handle the children of a given ACPI device object in multiple places instead of using the children and node list heads in struct acpi_device which is error prone (Rafael Wysocki). - Fix ACPI-related device reference counting issue in the hisi_lpc bus driver (Yang Yingliang). - Drop the children and node list heads that are not needed any more from struct acpi_device (Rafael Wysocki). - Drop driver member from struct acpi_device (Uwe Kleine-König). - Drop redundant check from acpi_device_remove() (Uwe Kleine-König). * acpi-bus: ACPI: bus: Drop unused list heads from struct acpi_device hisi_lpc: Use acpi_dev_for_each_child() bus: hisi_lpc: fix missing platform_device_put() in hisi_lpc_acpi_probe() ACPI: bus: Drop driver member of struct acpi_device ACPI: bus: Drop redundant check in acpi_device_remove() mfd: core: Use acpi_dev_for_each_child() ACPI / MMC: PM: Unify fixing up device power soundwire: Use acpi_dev_for_each_child() platform/x86/thinkpad_acpi: Use acpi_dev_for_each_child() ACPI: scan: Walk ACPI device's children using driver core ACPI: bus: Introduce acpi_dev_for_each_child_reverse() ACPI: video: Use acpi_dev_for_each_child() ACPI: bus: Export acpi_dev_for_each_child() to modules ACPI: property: Use acpi_dev_for_each_child() for child lookup ACPI: container: Use acpi_dev_for_each_child() USB: ACPI: Replace usb_acpi_find_port() with acpi_find_child_by_adr() thunderbolt: ACPI: Replace tb_acpi_find_port() with acpi_find_child_by_adr() ACPI: glue: Introduce acpi_find_child_by_adr() ACPI: glue: Introduce acpi_dev_has_children() ACPI: glue: Use acpi_dev_for_each_child()
Diffstat (limited to 'drivers/bus')
-rw-r--r--drivers/bus/hisi_lpc.c204
1 files changed, 101 insertions, 103 deletions
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
index 378f5d62a991..2e564803e786 100644
--- a/drivers/bus/hisi_lpc.c
+++ b/drivers/bus/hisi_lpc.c
@@ -379,7 +379,7 @@ static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev,
/*
* hisi_lpc_acpi_set_io_res - set the resources for a child
- * @child: the device node to be updated the I/O resource
+ * @adev: ACPI companion of the device node to be updated the I/O resource
* @hostdev: the device node associated with host controller
* @res: double pointer to be set to the address of translated resources
* @num_res: pointer to variable to hold the number of translated resources
@@ -390,31 +390,24 @@ static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev,
* host-relative address resource. This function will return the translated
* logical PIO addresses for each child devices resources.
*/
-static int hisi_lpc_acpi_set_io_res(struct device *child,
+static int hisi_lpc_acpi_set_io_res(struct acpi_device *adev,
struct device *hostdev,
const struct resource **res, int *num_res)
{
- struct acpi_device *adev;
- struct acpi_device *host;
+ struct acpi_device *host = to_acpi_device(adev->dev.parent);
struct resource_entry *rentry;
LIST_HEAD(resource_list);
struct resource *resources;
int count;
int i;
- if (!child || !hostdev)
- return -EINVAL;
-
- host = to_acpi_device(hostdev);
- adev = to_acpi_device(child);
-
if (!adev->status.present) {
- dev_dbg(child, "device is not present\n");
+ dev_dbg(&adev->dev, "device is not present\n");
return -EIO;
}
if (acpi_device_enumerated(adev)) {
- dev_dbg(child, "has been enumerated\n");
+ dev_dbg(&adev->dev, "has been enumerated\n");
return -EIO;
}
@@ -425,7 +418,7 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
*/
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
if (count <= 0) {
- dev_dbg(child, "failed to get resources\n");
+ dev_dbg(&adev->dev, "failed to get resources\n");
return count ? count : -EIO;
}
@@ -454,7 +447,7 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
continue;
ret = hisi_lpc_acpi_xlat_io_res(adev, host, &resources[i]);
if (ret) {
- dev_err(child, "translate IO range %pR failed (%d)\n",
+ dev_err(&adev->dev, "translate IO range %pR failed (%d)\n",
&resources[i], ret);
return ret;
}
@@ -471,6 +464,12 @@ static int hisi_lpc_acpi_remove_subdev(struct device *dev, void *unused)
return 0;
}
+static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_used)
+{
+ acpi_device_clear_enumerated(adev);
+ return 0;
+}
+
struct hisi_lpc_acpi_cell {
const char *hid;
const char *name;
@@ -480,115 +479,114 @@ struct hisi_lpc_acpi_cell {
static void hisi_lpc_acpi_remove(struct device *hostdev)
{
- struct acpi_device *adev = ACPI_COMPANION(hostdev);
- struct acpi_device *child;
-
device_for_each_child(hostdev, NULL, hisi_lpc_acpi_remove_subdev);
-
- list_for_each_entry(child, &adev->children, node)
- acpi_device_clear_enumerated(child);
+ acpi_dev_for_each_child(ACPI_COMPANION(hostdev),
+ hisi_lpc_acpi_clear_enumerated, NULL);
}
-/*
- * hisi_lpc_acpi_probe - probe children for ACPI FW
- * @hostdev: LPC host device pointer
- *
- * Returns 0 when successful, and a negative value for failure.
- *
- * Create a platform device per child, fixing up the resources
- * from bus addresses to Logical PIO addresses.
- *
- */
-static int hisi_lpc_acpi_probe(struct device *hostdev)
+static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data)
{
- struct acpi_device *adev = ACPI_COMPANION(hostdev);
- struct acpi_device *child;
+ const char *hid = acpi_device_hid(child);
+ struct device *hostdev = data;
+ const struct hisi_lpc_acpi_cell *cell;
+ struct platform_device *pdev;
+ const struct resource *res;
+ bool found = false;
+ int num_res;
int ret;
- /* Only consider the children of the host */
- list_for_each_entry(child, &adev->children, node) {
- const char *hid = acpi_device_hid(child);
- const struct hisi_lpc_acpi_cell *cell;
- struct platform_device *pdev;
- const struct resource *res;
- bool found = false;
- int num_res;
-
- ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev, &res,
- &num_res);
- if (ret) {
- dev_warn(hostdev, "set resource fail (%d)\n", ret);
- goto fail;
- }
+ ret = hisi_lpc_acpi_set_io_res(child, hostdev, &res, &num_res);
+ if (ret) {
+ dev_warn(hostdev, "set resource fail (%d)\n", ret);
+ return ret;
+ }
- cell = (struct hisi_lpc_acpi_cell []){
- /* ipmi */
- {
- .hid = "IPI0001",
- .name = "hisi-lpc-ipmi",
- },
- /* 8250-compatible uart */
- {
- .hid = "HISI1031",
- .name = "serial8250",
- .pdata = (struct plat_serial8250_port []) {
- {
- .iobase = res->start,
- .uartclk = 1843200,
- .iotype = UPIO_PORT,
- .flags = UPF_BOOT_AUTOCONF,
- },
- {}
+ cell = (struct hisi_lpc_acpi_cell []){
+ /* ipmi */
+ {
+ .hid = "IPI0001",
+ .name = "hisi-lpc-ipmi",
+ },
+ /* 8250-compatible uart */
+ {
+ .hid = "HISI1031",
+ .name = "serial8250",
+ .pdata = (struct plat_serial8250_port []) {
+ {
+ .iobase = res->start,
+ .uartclk = 1843200,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF,
},
- .pdata_size = 2 *
- sizeof(struct plat_serial8250_port),
+ {}
},
- {}
- };
-
- for (; cell && cell->name; cell++) {
- if (!strcmp(cell->hid, hid)) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- dev_warn(hostdev,
- "could not find cell for child device (%s), discarding\n",
- hid);
- continue;
+ .pdata_size = 2 *
+ sizeof(struct plat_serial8250_port),
+ },
+ {}
+ };
+
+ for (; cell && cell->name; cell++) {
+ if (!strcmp(cell->hid, hid)) {
+ found = true;
+ break;
}
+ }
- pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO);
- if (!pdev) {
- ret = -ENOMEM;
- goto fail;
- }
+ if (!found) {
+ dev_warn(hostdev,
+ "could not find cell for child device (%s), discarding\n",
+ hid);
+ return 0;
+ }
- pdev->dev.parent = hostdev;
- ACPI_COMPANION_SET(&pdev->dev, child);
+ pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO);
+ if (!pdev)
+ return -ENOMEM;
- ret = platform_device_add_resources(pdev, res, num_res);
- if (ret)
- goto fail;
+ pdev->dev.parent = hostdev;
+ ACPI_COMPANION_SET(&pdev->dev, child);
- ret = platform_device_add_data(pdev, cell->pdata,
- cell->pdata_size);
- if (ret)
- goto fail;
+ ret = platform_device_add_resources(pdev, res, num_res);
+ if (ret)
+ goto fail;
- ret = platform_device_add(pdev);
- if (ret)
- goto fail;
+ ret = platform_device_add_data(pdev, cell->pdata, cell->pdata_size);
+ if (ret)
+ goto fail;
- acpi_device_set_enumerated(child);
- }
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto fail;
+ acpi_device_set_enumerated(child);
return 0;
fail:
- hisi_lpc_acpi_remove(hostdev);
+ platform_device_put(pdev);
+ return ret;
+}
+
+/*
+ * hisi_lpc_acpi_probe - probe children for ACPI FW
+ * @hostdev: LPC host device pointer
+ *
+ * Returns 0 when successful, and a negative value for failure.
+ *
+ * Create a platform device per child, fixing up the resources
+ * from bus addresses to Logical PIO addresses.
+ *
+ */
+static int hisi_lpc_acpi_probe(struct device *hostdev)
+{
+ int ret;
+
+ /* Only consider the children of the host */
+ ret = acpi_dev_for_each_child(ACPI_COMPANION(hostdev),
+ hisi_lpc_acpi_add_child, hostdev);
+ if (ret)
+ hisi_lpc_acpi_remove(hostdev);
+
return ret;
}