[PATCH v9 6/7] LPC: Add the ACPI LPC support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "zhichang.yuan" <yuanzhichang@xxxxxxxxxxxxx>

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

Signed-off-by: zhichang.yuan <yuanzhichang@xxxxxxxxxxxxx>
Signed-off-by: John Garry <john.garry@xxxxxxxxxx>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@xxxxxxxxxx>
Tested-by: dann frazier <dann.frazier@xxxxxxxxxxxxx>
---
 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





[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux