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

Commit 95f04359 authored by Anant Goel's avatar Anant Goel
Browse files

drivers: msm: pinctrl: Add custom TLMM direct connect list feature support



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

Change-Id: I9b4eb8005a7c0230940a59337352bb3eaaa51ceb
Signed-off-by: default avatarAnant Goel <anantg@codeaurora.org>
parent e8d900e1
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -47,6 +47,13 @@ SM8150 platform.
	Definition: must be 2. Specifying the pin number and flags, as defined
		    in <dt-bindings/gpio/gpio.h>

- dirconn-list:
	Usage: optional
	Value type: <prop-encoded-array>
	Definition: a 3-tuple list which contains mapping of GPIO pin to
		    hardware IRQ, and a boolean for enabling the TLMM direct
		    connect interrupt for the pin.

Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.

+52 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1939,7 +1939,7 @@ static struct msm_dir_conn sm8150_dir_conn[] = {
	{-1, 209},
};

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,
@@ -1952,8 +1952,58 @@ static const struct msm_pinctrl_soc_data sm8150_pinctrl = {
	.dir_conn_irq_base = 216,
};

static int sm8150_pinctrl_dir_conn_probe(struct platform_device *pdev)
{
	const __be32 *prop;
	struct msm_dir_conn *dir_conn_list;
	uint32_t dir_conn_length, iterator = 0;
	int i, length, *dir_conn_entries, num_dir_conns;

	prop = of_get_property(pdev->dev.of_node, "dirconn-list",
			&length);

	dir_conn_length = length / sizeof(u32);

	dir_conn_entries = devm_kzalloc(&pdev->dev,
				dir_conn_length*sizeof(uint32_t), GFP_KERNEL);
	if (!dir_conn_entries)
		return -ENOMEM;

	for (i = 0; i < dir_conn_length; i++)
		dir_conn_entries[i] = be32_to_cpu(prop[i]);

	num_dir_conns = (dir_conn_length / 3);

	dir_conn_list = devm_kzalloc(&pdev->dev,
			num_dir_conns * sizeof(*dir_conn_list), GFP_KERNEL);
	if (!dir_conn_list)
		return -ENOMEM;

	for (i = 0; i < num_dir_conns; i++) {
		dir_conn_list[i].gpio = dir_conn_entries[iterator++];
		dir_conn_list[i].hwirq = dir_conn_entries[iterator++];
		dir_conn_list[i].tlmm_dc = dir_conn_entries[iterator++];
	}

	sm8150_pinctrl.dir_conn = dir_conn_list;
	sm8150_pinctrl.n_dir_conns = num_dir_conns;

	return 0;
}

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

	if (of_find_property(pdev->dev.of_node, "dirconn-list", &len)) {
		ret = sm8150_pinctrl_dir_conn_probe(pdev);
		if (ret) {
			dev_err(&pdev->dev,
				"Unable to parse TLMM direct connects\n");
			return ret;
		}
	}

	return msm_pinctrl_probe(pdev, &sm8150_pinctrl);
}