From: Yuanjie Yang Date: Tue, 24 Jun 2025 09:06:00 +0000 (+0800) Subject: pinctrl: qcom: add multi TLMM region option parameter X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56ffb63749f4a1e88c282b763c458f3ed73d8c27;p=thirdparty%2Fkernel%2Flinux.git pinctrl: qcom: add multi TLMM region option parameter Add support for selecting multiple TLMM regions using the tlmm-test tool. The current implementation only selects the TLMM Node region 0, which can lead to incorrect region selection. QCS 615 TLMM Node dts reg: tlmm: pinctrl@3100000 { compatible = "qcom,qcs615-tlmm"; reg = <0x0 0x03100000 0x0 0x300000>, <0x0 0x03500000 0x0 0x300000>, <0x0 0x03d00000 0x0 0x300000>; reg-names = "east", "west", "south"; QCS615 gpio57 is in the south region with an offset of 0x39000, and its address is 0x3d39000. However, the default region selection is region 0 (east region), resulting in a wrong calculated address of 0x3139000. Add a tlmm option parameter named tlmm_reg_name to select the region. If the user does not input the parameter, the default region is 0. Signed-off-by: Yuanjie Yang Link: https://lore.kernel.org/20250624090600.91063-1-quic_yuanjiey@quicinc.com Signed-off-by: Linus Walleij --- diff --git a/drivers/pinctrl/qcom/tlmm-test.c b/drivers/pinctrl/qcom/tlmm-test.c index 7b99e89e0f670..7d7fff538755a 100644 --- a/drivers/pinctrl/qcom/tlmm-test.c +++ b/drivers/pinctrl/qcom/tlmm-test.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * This TLMM test module serves the purpose of validating that the TLMM driver @@ -38,7 +39,10 @@ #define TLMM_REG_SIZE 0x1000 static int tlmm_test_gpio = -1; +static char *tlmm_reg_name = "default_region"; + module_param_named(gpio, tlmm_test_gpio, int, 0600); +module_param_named(name, tlmm_reg_name, charp, 0600); static struct { void __iomem *base; @@ -570,6 +574,47 @@ static const struct of_device_id tlmm_of_match[] = { {} }; +static int tlmm_reg_base(struct device_node *tlmm, struct resource *res) +{ + const char **reg_names; + int count; + int ret; + int i; + + count = of_property_count_strings(tlmm, "reg-names"); + if (count <= 0) { + pr_err("failed to find tlmm reg name\n"); + return count; + } + + reg_names = kcalloc(count, sizeof(char *), GFP_KERNEL); + if (!reg_names) + return -ENOMEM; + + ret = of_property_read_string_array(tlmm, "reg-names", reg_names, count); + if (ret != count) { + kfree(reg_names); + return -EINVAL; + } + + if (!strcmp(tlmm_reg_name, "default_region")) { + ret = of_address_to_resource(tlmm, 0, res); + } else { + for (i = 0; i < count; i++) { + if (!strcmp(reg_names[i], tlmm_reg_name)) { + ret = of_address_to_resource(tlmm, i, res); + break; + } + } + if (i == count) + ret = -EINVAL; + } + + kfree(reg_names); + + return ret; +} + static int tlmm_test_init_suite(struct kunit_suite *suite) { struct of_phandle_args args = {}; @@ -588,7 +633,7 @@ static int tlmm_test_init_suite(struct kunit_suite *suite) return -EINVAL; } - ret = of_address_to_resource(tlmm, 0, &res); + ret = tlmm_reg_base(tlmm, &res); if (ret < 0) return ret;