mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
pinctrl: s32cc: implement GPIO functionality
The updated SIUL2 block groups pinctrl, GPIO data access and interrupt control within the same hardware unit. The SIUL2 driver is therefore structured as a monolithic pinctrl/GPIO driver. GPIO data access and direction handling are implemented using the gpio-regmap library backed by a virtual regmap. The virtual regmap translates the gpio-regmap register model to the underlying SIUL2 registers: MSCR for direction, PGPDI for input values and PGPDO for output values. The existing pinctrl GPIO callbacks are used for the request/free path: they switch the pad to GPIO mode on request and restore the previous MSCR configuration when the GPIO is released. This change came as a result of upstream review in the following series: https://lore.kernel.org/linux-gpio/20260120115923.3463866-4-khristineandreea.barbulescu@oss.nxp.com/T/#m543c9edbdde74bdc68b6a2364e8b975356c33043 https://lore.kernel.org/all/20260504131148.3622697-7-khristineandreea.barbulescu@oss.nxp.com/ Support both SIUL2 DT layouts: - legacy pinctrl-only binding - extended pinctrl/GPIO/irqchip binding Reviewed-by: Linus Walleij <linusw@kernel.org> Signed-off-by: Andrei Stefanescu <andrei.stefanescu@oss.nxp.com> Signed-off-by: Khristine Andreea Barbulescu <khristineandreea.barbulescu@oss.nxp.com> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Link: https://lore.kernel.org/linux-gpio/20260120115923.3463866-4-khristineandreea.barbulescu@oss.nxp.com/T/#m543c9edbdde74bdc68b6a2364e8b975356c33043 Link: https://lore.kernel.org/all/20260504131148.3622697-7-khristineandreea.barbulescu@oss.nxp.com/ Signed-off-by: Linus Walleij <linusw@kernel.org>
This commit is contained in:
committed by
Linus Walleij
parent
e91152802f
commit
94cb9e8f27
@@ -1,10 +1,11 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config PINCTRL_S32CC
|
||||
bool
|
||||
depends on ARCH_S32 && OF
|
||||
depends on ARCH_S32 && OF && GPIOLIB
|
||||
select GENERIC_PINCTRL_GROUPS
|
||||
select GENERIC_PINMUX_FUNCTIONS
|
||||
select GENERIC_PINCONF
|
||||
select GPIO_REGMAP
|
||||
select REGMAP_MMIO
|
||||
|
||||
config PINCTRL_S32G2
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* S32 pinmux core definitions
|
||||
*
|
||||
* Copyright 2016-2020, 2022 NXP
|
||||
* Copyright 2016-2020, 2022, 2026 NXP
|
||||
* Copyright (C) 2022 SUSE LLC
|
||||
* Copyright 2015-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright (C) 2012 Linaro Ltd.
|
||||
@@ -34,11 +34,42 @@ struct s32_pin_range {
|
||||
unsigned int end;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct s32_gpio_range - contiguous GPIO pin range within a SIUL2 module
|
||||
* @gpio_base: first GPIO line offset in the GPIO range
|
||||
* @pin_base: first pinctrl pin number mapped by this GPIO range
|
||||
* @gpio_num: number of consecutive GPIO pins in the range
|
||||
* @sparse: true if the PGPD layout is non-linear (resolved via pad map only);
|
||||
* pins not found in the pad map are invalid for this range
|
||||
*/
|
||||
struct s32_gpio_range {
|
||||
unsigned int gpio_base;
|
||||
unsigned int pin_base;
|
||||
unsigned int gpio_num;
|
||||
bool sparse;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct s32_gpio_pad_map - mapping between GPIO ranges and PGPD pads
|
||||
* @gpio_start: first GPIO line offset in the range
|
||||
* @gpio_end: last GPIO line offset in the range
|
||||
* @pad: PGPD pad number serving the range
|
||||
*/
|
||||
struct s32_gpio_pad_map {
|
||||
unsigned int gpio_start;
|
||||
unsigned int gpio_end;
|
||||
unsigned int pad;
|
||||
};
|
||||
|
||||
struct s32_pinctrl_soc_data {
|
||||
const struct pinctrl_pin_desc *pins;
|
||||
unsigned int npins;
|
||||
const struct s32_pin_range *mem_pin_ranges;
|
||||
unsigned int mem_regions;
|
||||
const struct s32_gpio_range *gpio_ranges;
|
||||
unsigned int num_gpio_ranges;
|
||||
const struct s32_gpio_pad_map *gpio_pad_maps;
|
||||
unsigned int num_gpio_pad_maps;
|
||||
};
|
||||
|
||||
struct s32_pinctrl_soc_info {
|
||||
@@ -53,6 +84,8 @@ struct s32_pinctrl_soc_info {
|
||||
|
||||
#define S32_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
|
||||
#define S32_PIN_RANGE(_start, _end) { .start = _start, .end = _end }
|
||||
#define S32_GPIO_RANGE(gpio, pin, num) \
|
||||
{ .gpio_base = gpio, .pin_base = pin, .gpio_num = num }
|
||||
|
||||
int s32_pinctrl_probe(struct platform_device *pdev,
|
||||
const struct s32_pinctrl_soc_data *soc_data);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
* NXP S32G pinctrl driver
|
||||
*
|
||||
* Copyright 2015-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017-2018, 2020-2022 NXP
|
||||
* Copyright 2017-2018, 2020-2022, 2025-2026 NXP
|
||||
* Copyright (C) 2022 SUSE LLC
|
||||
*/
|
||||
|
||||
@@ -773,17 +773,48 @@ static const struct s32_pin_range s32_pin_ranges_siul2[] = {
|
||||
S32_PIN_RANGE(942, 1007),
|
||||
};
|
||||
|
||||
static const struct s32_pinctrl_soc_data s32_pinctrl_data = {
|
||||
static const struct s32_gpio_range s32_gpio_ranges_siul2[] = {
|
||||
S32_GPIO_RANGE(0, 0, 102),
|
||||
/* SIUL2_1: sparse layout, PGPD mapping required for all pins */
|
||||
{ .gpio_base = 112, .pin_base = 112, .gpio_num = 79, .sparse = true },
|
||||
};
|
||||
|
||||
/*
|
||||
* SIUL2_1 GPIO ranges mapped to sparse PGPD pads.
|
||||
*
|
||||
* SIUL2_1 does not expose GPIO data registers as a linear pad
|
||||
* sequence. Each entry describes a contiguous GPIO offset range
|
||||
* and the PGPD pad servicing that range.
|
||||
*/
|
||||
static const struct s32_gpio_pad_map s32g_gpio_pad_maps[] = {
|
||||
{ 112, 122, 7 }, /* PH_00 .. PH_10 -> PGPD7 */
|
||||
{ 144, 159, 9 }, /* PJ_00 .. PJ_15 -> PGPD9 */
|
||||
{ 160, 175, 10 }, /* PK_00 .. PK_15 -> PGPD10 */
|
||||
{ 176, 190, 11 }, /* PL_00 .. PL_14 -> PGPD11 */
|
||||
};
|
||||
|
||||
/* Legacy data for old DT bindings without GPIO support */
|
||||
static const struct s32_pinctrl_soc_data legacy_s32g_pinctrl_data = {
|
||||
.pins = s32_pinctrl_pads_siul2,
|
||||
.npins = ARRAY_SIZE(s32_pinctrl_pads_siul2),
|
||||
.mem_pin_ranges = s32_pin_ranges_siul2,
|
||||
.mem_regions = ARRAY_SIZE(s32_pin_ranges_siul2),
|
||||
};
|
||||
|
||||
static const struct s32_pinctrl_soc_data s32g_pinctrl_data = {
|
||||
.pins = s32_pinctrl_pads_siul2,
|
||||
.npins = ARRAY_SIZE(s32_pinctrl_pads_siul2),
|
||||
.mem_pin_ranges = s32_pin_ranges_siul2,
|
||||
.mem_regions = ARRAY_SIZE(s32_pin_ranges_siul2),
|
||||
.gpio_ranges = s32_gpio_ranges_siul2,
|
||||
.num_gpio_ranges = ARRAY_SIZE(s32_gpio_ranges_siul2),
|
||||
.gpio_pad_maps = s32g_gpio_pad_maps,
|
||||
.num_gpio_pad_maps = ARRAY_SIZE(s32g_gpio_pad_maps),
|
||||
};
|
||||
|
||||
static const struct of_device_id s32_pinctrl_of_match[] = {
|
||||
{
|
||||
.compatible = "nxp,s32g2-siul2-pinctrl",
|
||||
.data = &s32_pinctrl_data,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
@@ -792,8 +823,16 @@ MODULE_DEVICE_TABLE(of, s32_pinctrl_of_match);
|
||||
static int s32g_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct s32_pinctrl_soc_data *soc_data;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
soc_data = of_device_get_match_data(&pdev->dev);
|
||||
/*
|
||||
* Legacy DTs only describe the pinctrl resources.
|
||||
* New DT changes extend the same node with GPIO resources.
|
||||
*/
|
||||
if (of_property_present(np, "gpio-controller"))
|
||||
soc_data = &s32g_pinctrl_data;
|
||||
else
|
||||
soc_data = &legacy_s32g_pinctrl_data;
|
||||
|
||||
return s32_pinctrl_probe(pdev, soc_data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user