From: "zhichang.yuan" <[email protected]>

Based on the provious patches, this patch supports the ACPI LPC host on
Hip06/Hip07.

Signed-off-by: zhichang.yuan <[email protected]>
Signed-off-by: John Garry <[email protected]>
Signed-off-by: Gabriele Paoloni <[email protected]>
Tested-by: dann frazier <[email protected]>
---
 drivers/acpi/arm64/acpi_indirect_pio.c |  3 ++
 drivers/bus/hisi_lpc.c                 | 71 ++++++++++++++++++++++++++++++++--
 include/acpi/acpi_indirect_pio.h       |  4 ++
 3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/arm64/acpi_indirect_pio.c 
b/drivers/acpi/arm64/acpi_indirect_pio.c
index 7813f73..3a5ba7a 100644
--- a/drivers/acpi/arm64/acpi_indirect_pio.c
+++ b/drivers/acpi/arm64/acpi_indirect_pio.c
@@ -261,6 +261,9 @@ int acpi_set_logic_pio_resource(struct device *child,
 
 /* All the host devices which apply indirect-PIO can be listed here. */
 static const struct acpi_device_id acpi_indirect_host_id[] = {
+#ifdef CONFIG_HISILICON_LPC
+       {"HISI0191", INDIRECT_PIO_INFO(lpc_host_desc)},
+#endif
        {""},
 };
 
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
index 4f3bf76..05a0a84 100644
--- a/drivers/bus/hisi_lpc.c
+++ b/drivers/bus/hisi_lpc.c
@@ -467,7 +467,9 @@ static int hisilpc_probe(struct platform_device *pdev)
        }
 
        /* register the LPC host PIO resources */
-       if (!has_acpi_companion(dev)) {
+       if (has_acpi_companion(dev)) {
+               lpcdev->io_host = find_io_range_by_fwnode(dev->fwnode);
+       } else {
                struct logic_pio_hwaddr *range;
 
                range = kzalloc(sizeof(*range), GFP_KERNEL);
@@ -481,13 +483,14 @@ static int hisilpc_probe(struct platform_device *pdev)
                ret = logic_pio_register_range(range);
                if (ret) {
                        kfree(range);
-                       dev_err(dev, "OF: register IO range FAIL!\n");
+                       dev_err(dev, "OF: logic_pio_register_range returned 
%d!\n",
+                                       ret);
                        return -ret;
                }
                lpcdev->io_host = range;
        }
        if (!lpcdev->io_host) {
-               dev_err(dev, "Hisilpc IO hasn't registered!\n");
+               dev_err(dev, "HiSi LPC IO hasn't been registered!\n");
                return -EFAULT;
        }
 
@@ -533,10 +536,72 @@ static const struct of_device_id hisilpc_of_match[] = {
        {},
 };
 
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_indirect_pio.h>
+
+struct lpc_private_data {
+       resource_size_t io_size;
+       resource_size_t io_start;
+};
+
+static struct lpc_private_data lpc_data = {
+       .io_size = LPC_BUS_IO_SIZE,
+       .io_start = LPC_MIN_BUS_RANGE,
+};
+
+static int lpc_host_io_setup(struct acpi_device *adev, void *pdata)
+{
+       int ret = 0;
+       struct logic_pio_hwaddr *range;
+       struct lpc_private_data *lpc_private;
+       struct acpi_device *child;
+
+       lpc_private = (struct lpc_private_data *)pdata;
+       range = kzalloc(sizeof(*range), GFP_KERNEL);
+       if (!range)
+               return -ENOMEM;
+       range->fwnode = &adev->fwnode;
+       range->flags = PIO_INDIRECT;
+       range->size = lpc_private->io_size;
+       range->hw_start = lpc_private->io_start;
+
+       ret = logic_pio_register_range(range);
+       if (ret) {
+               kfree(range);
+               return ret;
+       }
+
+       /* In HiSilicon lpc, only care about the children of the host. */
+       list_for_each_entry(child, &adev->children, node) {
+               ret = acpi_set_logic_pio_resource(&child->dev, &adev->dev);
+               if (ret) {
+                       dev_err(&child->dev,
+                                       "acpi_set_logic_pio_resource() returned 
%d\n",
+                                       ret);
+                       return ret;
+               }
+       }
+
+       return ret;
+}
+
+static const struct acpi_device_id hisilpc_acpi_match[] = {
+       {"HISI0191", },
+       {},
+};
+
+const struct indirect_pio_device_desc lpc_host_desc = {
+       .pdata = &lpc_data,
+       .pre_setup = lpc_host_io_setup,
+};
+
+#endif
+
 static struct platform_driver hisilpc_driver = {
        .driver = {
                .name           = "hisi_lpc",
                .of_match_table = hisilpc_of_match,
+               .acpi_match_table = ACPI_PTR(hisilpc_acpi_match),
        },
        .probe = hisilpc_probe,
 };
diff --git a/include/acpi/acpi_indirect_pio.h b/include/acpi/acpi_indirect_pio.h
index efc5c43..7a8d26b 100644
--- a/include/acpi/acpi_indirect_pio.h
+++ b/include/acpi/acpi_indirect_pio.h
@@ -18,6 +18,10 @@ struct indirect_pio_device_desc {
        int (*pre_setup)(struct acpi_device *adev, void *pdata);
 };
 
+#ifdef CONFIG_HISILICON_LPC
+extern const struct indirect_pio_device_desc lpc_host_desc;
+#endif
+
 int acpi_set_logic_pio_resource(struct device *child,
                struct device *hostdev);
 
-- 
2.7.4


Reply via email to