summaryrefslogtreecommitdiff
path: root/drivers/bus/hisi_lpc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-02 11:12:25 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-02 11:12:25 -0700
commit8fa0db3a9b8ef310eb40cf91481141ece084f584 (patch)
treed78fe991dc58ca33a755d37ae1b753322817e99d /drivers/bus/hisi_lpc.c
parent64ae88ff48cb5b3cc7b7aea97241a3e940085bf7 (diff)
parent6352f3478a95cc413ecfee4fdb3300009fd3679a (diff)
Merge tag 'acpi-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki: "These rework the handling of ACPI device objects to use the driver core facilities for managing child ones instead of some questionable home-grown ways without the requisite locking and reference counting, clean up the EC driver, improve suspend-to-idle handling on x86, add some systems to the ACPI backlight quirk list, fix some assorted issues, clean up code and improve documentation. Specifics: - Use 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). - Prepare the CPPC library for handling backwards-compatible future _CPC return package formats gracefully (Rafael Wysocki). - Clean up the ACPI EC driver after previous changes in it (Hans de Goede). - Drop leftover acpi_processor_get_limit_info() declaration (Riwen Lu). - Split out thermal initialization from ACPI PSS (Riwen Lu). - Annotate more functions in the ACPI CPU idle driver to live in the cpuidle section (Guilherme G. Piccoli). - Fix _EINJ vs "special purpose" EFI memory regions (Dan Williams). - Implement a better fix to avoid spamming the console with old error logs (Tony Luck). - Fix typo in a comment in the APEI code (Xiang wangx). - Save NVS memory during transitions into S3 on Lenovo G40-45 (Manyi Li). - Add support for upcoming AMD uPEP device ID AMDI008 to the ACPI suspend-to-idle driver for x86 platforms (Shyam Sundar S K). - Clean up checks related to the ACPI_FADT_LOW_POWER_S0 platform flag in the LPIT table driver and the suspend-to-idle driver for x86 platforms (Rafael Wysocki). - Print information messages regarding declared LPS0 idle support in the platform firmware (Rafael Wysocki). - Fix missing check in register_device_clock() in the ACPI driver for Intel SoCs (huhai). - Fix ACS setup in the VIOT table parser (Eric Auger). - Skip IRQ override on AMD Zen platforms where it's harmful (Chuanhong Guo). - Use native backlight on Dell Inspiron N4010 (Hans de Goede). - Use native backlight on some TongFang devices (Werner Sembach). - Drop X86 dependency from the ACPI backlight driver Kconfig (Riwen Lu). - Shorten the quirk list in the ACPI backlight driver by identifying Clevo by board_name only (Werner Sembach). - Remove useless NULL pointer checks from 2 ACPI PCI link management functions (Andrey Strachuk). - Fix obsolete example in the ACPI EINJ documentation (Qifu Zhang). - Update links and references to _DSD-related documents (Sudeep Holla)" * tag 'acpi-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (46 commits) ACPI/PCI: Remove useless NULL pointer checks ACPI: CPPC: Do not prevent CPPC from working in the future ACPI: PM: x86: Print messages regarding LPS0 idle support ACPI: resource: skip IRQ override on AMD Zen platforms Documentation: ACPI: EINJ: Fix obsolete example ACPI: video: Use native backlight on Dell Inspiron N4010 ACPI: PM: s2idle: Use LPS0 idle if ACPI_FADT_LOW_POWER_S0 is unset Revert "ACPI / PM: LPIT: Register sysfs attributes based on FADT" ACPI: video: Shortening quirk list by identifying Clevo by board_name only ACPI: video: Force backlight native for some TongFang devices ACPI: PM: s2idle: Add support for upcoming AMD uPEP HID AMDI008 ACPI: VIOT: Fix ACS setup 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() ACPI: APEI: Fix _EINJ vs EFI_MEMORY_SP ACPI: LPSS: Fix missing check in register_device_clock() ACPI: APEI: Better fix to avoid spamming the console with old error logs ...
Diffstat (limited to 'drivers/bus/hisi_lpc.c')
-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;
}