Presently there is no way to change pinmux configuration runtime. Hence add IOMUX details which can be used to configure IOMUX gpio pins runtime to different functionalities. Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@xxxxxxx> --- drivers/pinctrl/pinctrl-amd.c | 65 +++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-amd.h | 1 + 2 files changed, 66 insertions(+) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 1a7d686494ff..3058b6d35e47 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -32,6 +32,8 @@ #include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinconf-generic.h> +#include "../acpi/acpica/accommon.h" + #include "core.h" #include "pinctrl-utils.h" #include "pinctrl-amd.h" @@ -958,6 +960,68 @@ static struct pinctrl_desc amd_pinctrl_desc = { .owner = THIS_MODULE, }; +static acpi_status acpi_get_iomux_region(acpi_handle handle, u32 level, + void *ctx, void **return_value) +{ + struct acpi_namespace_node *node = handle; + union acpi_operand_object *region_obj; + struct amd_gpio *gpio_dev = ctx; + + /* Already mapped the IOMUX base */ + if (gpio_dev->iomux_base) + return AE_OK; + + /* Valid object */ + if (!node || !node->object) + return AE_OK; + + /* Valid operand or namespace node*/ + if ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND) && + (ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_NAMED)) + return AE_OK; + + /* Valid object type*/ + if (node->object->common.type == ACPI_TYPE_LOCAL_DATA) + return AE_OK; + + region_obj = node->object; + if (!region_obj->region.handler) + return AE_OK; + + if (region_obj->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) + return AE_OK; + + if (strncmp("IOMX", region_obj->region.node->name.ascii, strlen("IOMX"))) + return AE_OK; + + gpio_dev->iomux_base = devm_ioremap(&gpio_dev->pdev->dev, + region_obj->region.address, + region_obj->region.length); + if (!gpio_dev->iomux_base) + dev_err(&gpio_dev->pdev->dev, "failed to devm_ioremap() iomux_base\n"); + + return AE_OK; +} + +static void amd_update_iomux_info(struct amd_gpio *gpio_dev) +{ + acpi_handle sys_bus_handle; + int status = acpi_get_handle(NULL, "\\_SB", &sys_bus_handle); + + if (ACPI_FAILURE(status)) { + dev_err(&gpio_dev->pdev->dev, "Failed to get SB handle\n"); + return; + } + + status = acpi_walk_namespace(ACPI_TYPE_REGION, sys_bus_handle, ACPI_UINT32_MAX, + acpi_get_iomux_region, NULL, gpio_dev, NULL); + + if (ACPI_FAILURE(status)) { + dev_err(&gpio_dev->pdev->dev, "Failed to get acpi_get_iomux_region\n"); + return; + } +} + static int amd_gpio_probe(struct platform_device *pdev) { int ret = 0; @@ -1052,6 +1116,7 @@ static int amd_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpio_dev); acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev); + amd_update_iomux_info(gpio_dev); dev_dbg(&pdev->dev, "amd gpio driver loaded\n"); return ret; diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h index de2bc9dddc9c..8296426f4c81 100644 --- a/drivers/pinctrl/pinctrl-amd.h +++ b/drivers/pinctrl/pinctrl-amd.h @@ -89,6 +89,7 @@ struct amd_function { struct amd_gpio { raw_spinlock_t lock; void __iomem *base; + void __iomem *iomux_base; const struct amd_pingroup *groups; u32 ngroups; -- 2.25.1