Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f752ceaf authored by Anant Goel's avatar Anant Goel Committed by Gerrit - the friendly Code Review server
Browse files

drivers: pinctrl: Add custom GPIO to PDC pin mapping list support



Add feature support where a user can provide a custom list of TLMM
GPIOs associated with PDC pins for direct connect interrupt support.
This feature is needed because the TLMM GPIO PDC map is fixed per target
which is restrictive for a usecase where a custom list of direct connect
interrupts for GPIOs is needed.

Change-Id: Idc6e07a3405c7900445f25e60d08570f7b350fcc
Signed-off-by: default avatarAnant Goel <anantg@codeaurora.org>
parent eca62752
Loading
Loading
Loading
Loading
+48 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -2270,8 +2270,55 @@ static struct msm_pinctrl_soc_data sdmshrike_pinctrl = {
	.dir_conn = sdmshrike_dir_conn,
};

static int sdmshrike_pinctrl_gpio_irq_map_probe(struct platform_device *pdev)
{
	int ret, n, gpio_irq_map_count;
	struct device_node *np = pdev->dev.of_node;
	struct msm_gpio_wakeirq_map *gpio_irq_map;

	n = of_property_count_elems_of_size(np, "qcom,gpio-irq-map",
					sizeof(u32));
	if (n <= 0 || n % 2)
		return -EINVAL;

	gpio_irq_map_count = n / 2;
	gpio_irq_map = devm_kcalloc(&pdev->dev, gpio_irq_map_count,
				sizeof(*gpio_irq_map), GFP_KERNEL);
	if (!gpio_irq_map)
		return -ENOMEM;

	for (n = 0; n < gpio_irq_map_count; n++) {
		ret = of_property_read_u32_index(np, "qcom,gpio-irq-map",
						n * 2 + 0,
						&gpio_irq_map[n].gpio);
		if (ret)
			return ret;
		ret = of_property_read_u32_index(np, "qcom,gpio-irq-map",
						n * 2 + 1,
						&gpio_irq_map[n].wakeirq);
		if (ret)
			return ret;
	}

	sdmshrike_pinctrl.wakeirq_map = gpio_irq_map;
	sdmshrike_pinctrl.nwakeirq_map = gpio_irq_map_count;

	return 0;
}

static int sdmshrike_pinctrl_probe(struct platform_device *pdev)
{
	int len, ret;

	if (of_find_property(pdev->dev.of_node, "qcom,gpio-irq-map", &len)) {
		ret = sdmshrike_pinctrl_gpio_irq_map_probe(pdev);
		if (ret) {
			dev_err(&pdev->dev,
				"Unable to parse GPIO IRQ map\n");
			return ret;
		}
	}

	return msm_pinctrl_probe(pdev, &sdmshrike_pinctrl);
}

+47 −0
Original line number Diff line number Diff line
@@ -1614,8 +1614,55 @@ static struct msm_pinctrl_soc_data sm6150_pinctrl = {
#endif
};

static int sm6150_pinctrl_gpio_irq_map_probe(struct platform_device *pdev)
{
	int ret, n, gpio_irq_map_count;
	struct device_node *np = pdev->dev.of_node;
	struct msm_gpio_wakeirq_map *gpio_irq_map;

	n = of_property_count_elems_of_size(np, "qcom,gpio-irq-map",
					sizeof(u32));
	if (n <= 0 || n % 2)
		return -EINVAL;

	gpio_irq_map_count = n / 2;
	gpio_irq_map = devm_kcalloc(&pdev->dev, gpio_irq_map_count,
				sizeof(*gpio_irq_map), GFP_KERNEL);
	if (!gpio_irq_map)
		return -ENOMEM;

	for (n = 0; n < gpio_irq_map_count; n++) {
		ret = of_property_read_u32_index(np, "qcom,gpio-irq-map",
						n * 2 + 0,
						&gpio_irq_map[n].gpio);
		if (ret)
			return ret;
		ret = of_property_read_u32_index(np, "qcom,gpio-irq-map",
						n * 2 + 1,
						&gpio_irq_map[n].wakeirq);
		if (ret)
			return ret;
	}

	sm6150_pinctrl.wakeirq_map = gpio_irq_map;
	sm6150_pinctrl.nwakeirq_map = gpio_irq_map_count;

	return 0;
}

static int sm6150_pinctrl_probe(struct platform_device *pdev)
{
	int len, ret;

	if (of_find_property(pdev->dev.of_node, "qcom,gpio-irq-map", &len)) {
		ret = sm6150_pinctrl_gpio_irq_map_probe(pdev);
		if (ret) {
			dev_err(&pdev->dev,
				"Unable to parse GPIO IRQ map\n");
			return ret;
		}
	}

	return msm_pinctrl_probe(pdev, &sm6150_pinctrl);
}

+49 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
// Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.

#include <linux/module.h>
#include <linux/of.h>
@@ -1532,7 +1532,7 @@ static struct msm_dir_conn sm8150_dir_conn[] = {
	  {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}
};

static const struct msm_pinctrl_soc_data sm8150_pinctrl = {
static struct msm_pinctrl_soc_data sm8150_pinctrl = {
	.pins = sm8150_pins,
	.npins = ARRAY_SIZE(sm8150_pins),
	.functions = sm8150_functions,
@@ -1547,8 +1547,55 @@ static const struct msm_pinctrl_soc_data sm8150_pinctrl = {
	.dir_conn = sm8150_dir_conn,
};

static int sm8150_pinctrl_gpio_irq_map_probe(struct platform_device *pdev)
{
	int ret, n, gpio_irq_map_count;
	struct device_node *np = pdev->dev.of_node;
	struct msm_gpio_wakeirq_map *gpio_irq_map;

	n = of_property_count_elems_of_size(np, "qcom,gpio-irq-map",
					sizeof(u32));
	if (n <= 0 || n % 2)
		return -EINVAL;

	gpio_irq_map_count = n / 2;
	gpio_irq_map = devm_kcalloc(&pdev->dev, gpio_irq_map_count,
				sizeof(*gpio_irq_map), GFP_KERNEL);
	if (!gpio_irq_map)
		return -ENOMEM;

	for (n = 0; n < gpio_irq_map_count; n++) {
		ret = of_property_read_u32_index(np, "qcom,gpio-irq-map",
						n * 2 + 0,
						&gpio_irq_map[n].gpio);
		if (ret)
			return ret;
		ret = of_property_read_u32_index(np, "qcom,gpio-irq-map",
						n * 2 + 1,
						&gpio_irq_map[n].wakeirq);
		if (ret)
			return ret;
	}

	sm8150_pinctrl.wakeirq_map = gpio_irq_map;
	sm8150_pinctrl.nwakeirq_map = gpio_irq_map_count;

	return 0;
}

static int sm8150_pinctrl_probe(struct platform_device *pdev)
{
	int len, ret;

	if (of_find_property(pdev->dev.of_node, "qcom,gpio-irq-map", &len)) {
		ret = sm8150_pinctrl_gpio_irq_map_probe(pdev);
		if (ret) {
			dev_err(&pdev->dev,
				"Unable to parse GPIO IRQ map\n");
			return ret;
		}
	}

	return msm_pinctrl_probe(pdev, &sm8150_pinctrl);
}