18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0 OR MIT)
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Microsemi SoCs pinctrl driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Author: <alexandre.belloni@free-electrons.com>
68c2ecf20Sopenharmony_ci * License: Dual MIT/GPL
78c2ecf20Sopenharmony_ci * Copyright (c) 2017 Microsemi Corporation
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/gpio/driver.h>
118c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
128c2ecf20Sopenharmony_ci#include <linux/io.h>
138c2ecf20Sopenharmony_ci#include <linux/of_device.h>
148c2ecf20Sopenharmony_ci#include <linux/of_irq.h>
158c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
168c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
178c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinmux.h>
188c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf.h>
198c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h>
208c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
218c2ecf20Sopenharmony_ci#include <linux/regmap.h>
228c2ecf20Sopenharmony_ci#include <linux/slab.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include "core.h"
258c2ecf20Sopenharmony_ci#include "pinconf.h"
268c2ecf20Sopenharmony_ci#include "pinmux.h"
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#define ocelot_clrsetbits(addr, clear, set) \
298c2ecf20Sopenharmony_ci	writel((readl(addr) & ~(clear)) | (set), (addr))
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* PINCONFIG bits (sparx5 only) */
328c2ecf20Sopenharmony_cienum {
338c2ecf20Sopenharmony_ci	PINCONF_BIAS,
348c2ecf20Sopenharmony_ci	PINCONF_SCHMITT,
358c2ecf20Sopenharmony_ci	PINCONF_DRIVE_STRENGTH,
368c2ecf20Sopenharmony_ci};
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define BIAS_PD_BIT BIT(4)
398c2ecf20Sopenharmony_ci#define BIAS_PU_BIT BIT(3)
408c2ecf20Sopenharmony_ci#define BIAS_BITS   (BIAS_PD_BIT|BIAS_PU_BIT)
418c2ecf20Sopenharmony_ci#define SCHMITT_BIT BIT(2)
428c2ecf20Sopenharmony_ci#define DRIVE_BITS  GENMASK(1, 0)
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci/* GPIO standard registers */
458c2ecf20Sopenharmony_ci#define OCELOT_GPIO_OUT_SET	0x0
468c2ecf20Sopenharmony_ci#define OCELOT_GPIO_OUT_CLR	0x4
478c2ecf20Sopenharmony_ci#define OCELOT_GPIO_OUT		0x8
488c2ecf20Sopenharmony_ci#define OCELOT_GPIO_IN		0xc
498c2ecf20Sopenharmony_ci#define OCELOT_GPIO_OE		0x10
508c2ecf20Sopenharmony_ci#define OCELOT_GPIO_INTR	0x14
518c2ecf20Sopenharmony_ci#define OCELOT_GPIO_INTR_ENA	0x18
528c2ecf20Sopenharmony_ci#define OCELOT_GPIO_INTR_IDENT	0x1c
538c2ecf20Sopenharmony_ci#define OCELOT_GPIO_ALT0	0x20
548c2ecf20Sopenharmony_ci#define OCELOT_GPIO_ALT1	0x24
558c2ecf20Sopenharmony_ci#define OCELOT_GPIO_SD_MAP	0x28
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#define OCELOT_FUNC_PER_PIN	4
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cienum {
608c2ecf20Sopenharmony_ci	FUNC_NONE,
618c2ecf20Sopenharmony_ci	FUNC_GPIO,
628c2ecf20Sopenharmony_ci	FUNC_IRQ0,
638c2ecf20Sopenharmony_ci	FUNC_IRQ0_IN,
648c2ecf20Sopenharmony_ci	FUNC_IRQ0_OUT,
658c2ecf20Sopenharmony_ci	FUNC_IRQ1,
668c2ecf20Sopenharmony_ci	FUNC_IRQ1_IN,
678c2ecf20Sopenharmony_ci	FUNC_IRQ1_OUT,
688c2ecf20Sopenharmony_ci	FUNC_EXT_IRQ,
698c2ecf20Sopenharmony_ci	FUNC_MIIM,
708c2ecf20Sopenharmony_ci	FUNC_PHY_LED,
718c2ecf20Sopenharmony_ci	FUNC_PCI_WAKE,
728c2ecf20Sopenharmony_ci	FUNC_MD,
738c2ecf20Sopenharmony_ci	FUNC_PTP0,
748c2ecf20Sopenharmony_ci	FUNC_PTP1,
758c2ecf20Sopenharmony_ci	FUNC_PTP2,
768c2ecf20Sopenharmony_ci	FUNC_PTP3,
778c2ecf20Sopenharmony_ci	FUNC_PWM,
788c2ecf20Sopenharmony_ci	FUNC_RECO_CLK,
798c2ecf20Sopenharmony_ci	FUNC_SFP,
808c2ecf20Sopenharmony_ci	FUNC_SG0,
818c2ecf20Sopenharmony_ci	FUNC_SG1,
828c2ecf20Sopenharmony_ci	FUNC_SG2,
838c2ecf20Sopenharmony_ci	FUNC_SI,
848c2ecf20Sopenharmony_ci	FUNC_SI2,
858c2ecf20Sopenharmony_ci	FUNC_TACHO,
868c2ecf20Sopenharmony_ci	FUNC_TWI,
878c2ecf20Sopenharmony_ci	FUNC_TWI2,
888c2ecf20Sopenharmony_ci	FUNC_TWI3,
898c2ecf20Sopenharmony_ci	FUNC_TWI_SCL_M,
908c2ecf20Sopenharmony_ci	FUNC_UART,
918c2ecf20Sopenharmony_ci	FUNC_UART2,
928c2ecf20Sopenharmony_ci	FUNC_UART3,
938c2ecf20Sopenharmony_ci	FUNC_PLL_STAT,
948c2ecf20Sopenharmony_ci	FUNC_EMMC,
958c2ecf20Sopenharmony_ci	FUNC_REF_CLK,
968c2ecf20Sopenharmony_ci	FUNC_RCVRD_CLK,
978c2ecf20Sopenharmony_ci	FUNC_MAX
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic const char *const ocelot_function_names[] = {
1018c2ecf20Sopenharmony_ci	[FUNC_NONE]		= "none",
1028c2ecf20Sopenharmony_ci	[FUNC_GPIO]		= "gpio",
1038c2ecf20Sopenharmony_ci	[FUNC_IRQ0]		= "irq0",
1048c2ecf20Sopenharmony_ci	[FUNC_IRQ0_IN]		= "irq0_in",
1058c2ecf20Sopenharmony_ci	[FUNC_IRQ0_OUT]		= "irq0_out",
1068c2ecf20Sopenharmony_ci	[FUNC_IRQ1]		= "irq1",
1078c2ecf20Sopenharmony_ci	[FUNC_IRQ1_IN]		= "irq1_in",
1088c2ecf20Sopenharmony_ci	[FUNC_IRQ1_OUT]		= "irq1_out",
1098c2ecf20Sopenharmony_ci	[FUNC_EXT_IRQ]		= "ext_irq",
1108c2ecf20Sopenharmony_ci	[FUNC_MIIM]		= "miim",
1118c2ecf20Sopenharmony_ci	[FUNC_PHY_LED]		= "phy_led",
1128c2ecf20Sopenharmony_ci	[FUNC_PCI_WAKE]		= "pci_wake",
1138c2ecf20Sopenharmony_ci	[FUNC_MD]		= "md",
1148c2ecf20Sopenharmony_ci	[FUNC_PTP0]		= "ptp0",
1158c2ecf20Sopenharmony_ci	[FUNC_PTP1]		= "ptp1",
1168c2ecf20Sopenharmony_ci	[FUNC_PTP2]		= "ptp2",
1178c2ecf20Sopenharmony_ci	[FUNC_PTP3]		= "ptp3",
1188c2ecf20Sopenharmony_ci	[FUNC_PWM]		= "pwm",
1198c2ecf20Sopenharmony_ci	[FUNC_RECO_CLK]		= "reco_clk",
1208c2ecf20Sopenharmony_ci	[FUNC_SFP]		= "sfp",
1218c2ecf20Sopenharmony_ci	[FUNC_SG0]		= "sg0",
1228c2ecf20Sopenharmony_ci	[FUNC_SG1]		= "sg1",
1238c2ecf20Sopenharmony_ci	[FUNC_SG2]		= "sg2",
1248c2ecf20Sopenharmony_ci	[FUNC_SI]		= "si",
1258c2ecf20Sopenharmony_ci	[FUNC_SI2]		= "si2",
1268c2ecf20Sopenharmony_ci	[FUNC_TACHO]		= "tacho",
1278c2ecf20Sopenharmony_ci	[FUNC_TWI]		= "twi",
1288c2ecf20Sopenharmony_ci	[FUNC_TWI2]		= "twi2",
1298c2ecf20Sopenharmony_ci	[FUNC_TWI3]		= "twi3",
1308c2ecf20Sopenharmony_ci	[FUNC_TWI_SCL_M]	= "twi_scl_m",
1318c2ecf20Sopenharmony_ci	[FUNC_UART]		= "uart",
1328c2ecf20Sopenharmony_ci	[FUNC_UART2]		= "uart2",
1338c2ecf20Sopenharmony_ci	[FUNC_UART3]		= "uart3",
1348c2ecf20Sopenharmony_ci	[FUNC_PLL_STAT]		= "pll_stat",
1358c2ecf20Sopenharmony_ci	[FUNC_EMMC]		= "emmc",
1368c2ecf20Sopenharmony_ci	[FUNC_REF_CLK]		= "ref_clk",
1378c2ecf20Sopenharmony_ci	[FUNC_RCVRD_CLK]	= "rcvrd_clk",
1388c2ecf20Sopenharmony_ci};
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistruct ocelot_pmx_func {
1418c2ecf20Sopenharmony_ci	const char **groups;
1428c2ecf20Sopenharmony_ci	unsigned int ngroups;
1438c2ecf20Sopenharmony_ci};
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistruct ocelot_pin_caps {
1468c2ecf20Sopenharmony_ci	unsigned int pin;
1478c2ecf20Sopenharmony_ci	unsigned char functions[OCELOT_FUNC_PER_PIN];
1488c2ecf20Sopenharmony_ci};
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistruct ocelot_pinctrl {
1518c2ecf20Sopenharmony_ci	struct device *dev;
1528c2ecf20Sopenharmony_ci	struct pinctrl_dev *pctl;
1538c2ecf20Sopenharmony_ci	struct gpio_chip gpio_chip;
1548c2ecf20Sopenharmony_ci	struct regmap *map;
1558c2ecf20Sopenharmony_ci	void __iomem *pincfg;
1568c2ecf20Sopenharmony_ci	struct pinctrl_desc *desc;
1578c2ecf20Sopenharmony_ci	struct ocelot_pmx_func func[FUNC_MAX];
1588c2ecf20Sopenharmony_ci	u8 stride;
1598c2ecf20Sopenharmony_ci};
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci#define OCELOT_P(p, f0, f1, f2)						\
1628c2ecf20Sopenharmony_cistatic struct ocelot_pin_caps ocelot_pin_##p = {			\
1638c2ecf20Sopenharmony_ci	.pin = p,							\
1648c2ecf20Sopenharmony_ci	.functions = {							\
1658c2ecf20Sopenharmony_ci			FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2,	\
1668c2ecf20Sopenharmony_ci	},								\
1678c2ecf20Sopenharmony_ci}
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ciOCELOT_P(0,  SG0,       NONE,      NONE);
1708c2ecf20Sopenharmony_ciOCELOT_P(1,  SG0,       NONE,      NONE);
1718c2ecf20Sopenharmony_ciOCELOT_P(2,  SG0,       NONE,      NONE);
1728c2ecf20Sopenharmony_ciOCELOT_P(3,  SG0,       NONE,      NONE);
1738c2ecf20Sopenharmony_ciOCELOT_P(4,  IRQ0_IN,   IRQ0_OUT,  TWI_SCL_M);
1748c2ecf20Sopenharmony_ciOCELOT_P(5,  IRQ1_IN,   IRQ1_OUT,  PCI_WAKE);
1758c2ecf20Sopenharmony_ciOCELOT_P(6,  UART,      TWI_SCL_M, NONE);
1768c2ecf20Sopenharmony_ciOCELOT_P(7,  UART,      TWI_SCL_M, NONE);
1778c2ecf20Sopenharmony_ciOCELOT_P(8,  SI,        TWI_SCL_M, IRQ0_OUT);
1788c2ecf20Sopenharmony_ciOCELOT_P(9,  SI,        TWI_SCL_M, IRQ1_OUT);
1798c2ecf20Sopenharmony_ciOCELOT_P(10, PTP2,      TWI_SCL_M, SFP);
1808c2ecf20Sopenharmony_ciOCELOT_P(11, PTP3,      TWI_SCL_M, SFP);
1818c2ecf20Sopenharmony_ciOCELOT_P(12, UART2,     TWI_SCL_M, SFP);
1828c2ecf20Sopenharmony_ciOCELOT_P(13, UART2,     TWI_SCL_M, SFP);
1838c2ecf20Sopenharmony_ciOCELOT_P(14, MIIM,      TWI_SCL_M, SFP);
1848c2ecf20Sopenharmony_ciOCELOT_P(15, MIIM,      TWI_SCL_M, SFP);
1858c2ecf20Sopenharmony_ciOCELOT_P(16, TWI,       NONE,      SI);
1868c2ecf20Sopenharmony_ciOCELOT_P(17, TWI,       TWI_SCL_M, SI);
1878c2ecf20Sopenharmony_ciOCELOT_P(18, PTP0,      TWI_SCL_M, NONE);
1888c2ecf20Sopenharmony_ciOCELOT_P(19, PTP1,      TWI_SCL_M, NONE);
1898c2ecf20Sopenharmony_ciOCELOT_P(20, RECO_CLK,  TACHO,     TWI_SCL_M);
1908c2ecf20Sopenharmony_ciOCELOT_P(21, RECO_CLK,  PWM,       TWI_SCL_M);
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci#define OCELOT_PIN(n) {						\
1938c2ecf20Sopenharmony_ci	.number = n,						\
1948c2ecf20Sopenharmony_ci	.name = "GPIO_"#n,					\
1958c2ecf20Sopenharmony_ci	.drv_data = &ocelot_pin_##n				\
1968c2ecf20Sopenharmony_ci}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc ocelot_pins[] = {
1998c2ecf20Sopenharmony_ci	OCELOT_PIN(0),
2008c2ecf20Sopenharmony_ci	OCELOT_PIN(1),
2018c2ecf20Sopenharmony_ci	OCELOT_PIN(2),
2028c2ecf20Sopenharmony_ci	OCELOT_PIN(3),
2038c2ecf20Sopenharmony_ci	OCELOT_PIN(4),
2048c2ecf20Sopenharmony_ci	OCELOT_PIN(5),
2058c2ecf20Sopenharmony_ci	OCELOT_PIN(6),
2068c2ecf20Sopenharmony_ci	OCELOT_PIN(7),
2078c2ecf20Sopenharmony_ci	OCELOT_PIN(8),
2088c2ecf20Sopenharmony_ci	OCELOT_PIN(9),
2098c2ecf20Sopenharmony_ci	OCELOT_PIN(10),
2108c2ecf20Sopenharmony_ci	OCELOT_PIN(11),
2118c2ecf20Sopenharmony_ci	OCELOT_PIN(12),
2128c2ecf20Sopenharmony_ci	OCELOT_PIN(13),
2138c2ecf20Sopenharmony_ci	OCELOT_PIN(14),
2148c2ecf20Sopenharmony_ci	OCELOT_PIN(15),
2158c2ecf20Sopenharmony_ci	OCELOT_PIN(16),
2168c2ecf20Sopenharmony_ci	OCELOT_PIN(17),
2178c2ecf20Sopenharmony_ci	OCELOT_PIN(18),
2188c2ecf20Sopenharmony_ci	OCELOT_PIN(19),
2198c2ecf20Sopenharmony_ci	OCELOT_PIN(20),
2208c2ecf20Sopenharmony_ci	OCELOT_PIN(21),
2218c2ecf20Sopenharmony_ci};
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci#define JAGUAR2_P(p, f0, f1)						\
2248c2ecf20Sopenharmony_cistatic struct ocelot_pin_caps jaguar2_pin_##p = {			\
2258c2ecf20Sopenharmony_ci	.pin = p,							\
2268c2ecf20Sopenharmony_ci	.functions = {							\
2278c2ecf20Sopenharmony_ci			FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_NONE	\
2288c2ecf20Sopenharmony_ci	},								\
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ciJAGUAR2_P(0,  SG0,       NONE);
2328c2ecf20Sopenharmony_ciJAGUAR2_P(1,  SG0,       NONE);
2338c2ecf20Sopenharmony_ciJAGUAR2_P(2,  SG0,       NONE);
2348c2ecf20Sopenharmony_ciJAGUAR2_P(3,  SG0,       NONE);
2358c2ecf20Sopenharmony_ciJAGUAR2_P(4,  SG1,       NONE);
2368c2ecf20Sopenharmony_ciJAGUAR2_P(5,  SG1,       NONE);
2378c2ecf20Sopenharmony_ciJAGUAR2_P(6,  IRQ0_IN,   IRQ0_OUT);
2388c2ecf20Sopenharmony_ciJAGUAR2_P(7,  IRQ1_IN,   IRQ1_OUT);
2398c2ecf20Sopenharmony_ciJAGUAR2_P(8,  PTP0,      NONE);
2408c2ecf20Sopenharmony_ciJAGUAR2_P(9,  PTP1,      NONE);
2418c2ecf20Sopenharmony_ciJAGUAR2_P(10, UART,      NONE);
2428c2ecf20Sopenharmony_ciJAGUAR2_P(11, UART,      NONE);
2438c2ecf20Sopenharmony_ciJAGUAR2_P(12, SG1,       NONE);
2448c2ecf20Sopenharmony_ciJAGUAR2_P(13, SG1,       NONE);
2458c2ecf20Sopenharmony_ciJAGUAR2_P(14, TWI,       TWI_SCL_M);
2468c2ecf20Sopenharmony_ciJAGUAR2_P(15, TWI,       NONE);
2478c2ecf20Sopenharmony_ciJAGUAR2_P(16, SI,        TWI_SCL_M);
2488c2ecf20Sopenharmony_ciJAGUAR2_P(17, SI,        TWI_SCL_M);
2498c2ecf20Sopenharmony_ciJAGUAR2_P(18, SI,        TWI_SCL_M);
2508c2ecf20Sopenharmony_ciJAGUAR2_P(19, PCI_WAKE,  NONE);
2518c2ecf20Sopenharmony_ciJAGUAR2_P(20, IRQ0_OUT,  TWI_SCL_M);
2528c2ecf20Sopenharmony_ciJAGUAR2_P(21, IRQ1_OUT,  TWI_SCL_M);
2538c2ecf20Sopenharmony_ciJAGUAR2_P(22, TACHO,     NONE);
2548c2ecf20Sopenharmony_ciJAGUAR2_P(23, PWM,       NONE);
2558c2ecf20Sopenharmony_ciJAGUAR2_P(24, UART2,     NONE);
2568c2ecf20Sopenharmony_ciJAGUAR2_P(25, UART2,     SI);
2578c2ecf20Sopenharmony_ciJAGUAR2_P(26, PTP2,      SI);
2588c2ecf20Sopenharmony_ciJAGUAR2_P(27, PTP3,      SI);
2598c2ecf20Sopenharmony_ciJAGUAR2_P(28, TWI2,      SI);
2608c2ecf20Sopenharmony_ciJAGUAR2_P(29, TWI2,      SI);
2618c2ecf20Sopenharmony_ciJAGUAR2_P(30, SG2,       SI);
2628c2ecf20Sopenharmony_ciJAGUAR2_P(31, SG2,       SI);
2638c2ecf20Sopenharmony_ciJAGUAR2_P(32, SG2,       SI);
2648c2ecf20Sopenharmony_ciJAGUAR2_P(33, SG2,       SI);
2658c2ecf20Sopenharmony_ciJAGUAR2_P(34, NONE,      TWI_SCL_M);
2668c2ecf20Sopenharmony_ciJAGUAR2_P(35, NONE,      TWI_SCL_M);
2678c2ecf20Sopenharmony_ciJAGUAR2_P(36, NONE,      TWI_SCL_M);
2688c2ecf20Sopenharmony_ciJAGUAR2_P(37, NONE,      TWI_SCL_M);
2698c2ecf20Sopenharmony_ciJAGUAR2_P(38, NONE,      TWI_SCL_M);
2708c2ecf20Sopenharmony_ciJAGUAR2_P(39, NONE,      TWI_SCL_M);
2718c2ecf20Sopenharmony_ciJAGUAR2_P(40, NONE,      TWI_SCL_M);
2728c2ecf20Sopenharmony_ciJAGUAR2_P(41, NONE,      TWI_SCL_M);
2738c2ecf20Sopenharmony_ciJAGUAR2_P(42, NONE,      TWI_SCL_M);
2748c2ecf20Sopenharmony_ciJAGUAR2_P(43, NONE,      TWI_SCL_M);
2758c2ecf20Sopenharmony_ciJAGUAR2_P(44, NONE,      SFP);
2768c2ecf20Sopenharmony_ciJAGUAR2_P(45, NONE,      SFP);
2778c2ecf20Sopenharmony_ciJAGUAR2_P(46, NONE,      SFP);
2788c2ecf20Sopenharmony_ciJAGUAR2_P(47, NONE,      SFP);
2798c2ecf20Sopenharmony_ciJAGUAR2_P(48, SFP,       NONE);
2808c2ecf20Sopenharmony_ciJAGUAR2_P(49, SFP,       SI);
2818c2ecf20Sopenharmony_ciJAGUAR2_P(50, SFP,       SI);
2828c2ecf20Sopenharmony_ciJAGUAR2_P(51, SFP,       SI);
2838c2ecf20Sopenharmony_ciJAGUAR2_P(52, SFP,       NONE);
2848c2ecf20Sopenharmony_ciJAGUAR2_P(53, SFP,       NONE);
2858c2ecf20Sopenharmony_ciJAGUAR2_P(54, SFP,       NONE);
2868c2ecf20Sopenharmony_ciJAGUAR2_P(55, SFP,       NONE);
2878c2ecf20Sopenharmony_ciJAGUAR2_P(56, MIIM,      SFP);
2888c2ecf20Sopenharmony_ciJAGUAR2_P(57, MIIM,      SFP);
2898c2ecf20Sopenharmony_ciJAGUAR2_P(58, MIIM,      SFP);
2908c2ecf20Sopenharmony_ciJAGUAR2_P(59, MIIM,      SFP);
2918c2ecf20Sopenharmony_ciJAGUAR2_P(60, NONE,      NONE);
2928c2ecf20Sopenharmony_ciJAGUAR2_P(61, NONE,      NONE);
2938c2ecf20Sopenharmony_ciJAGUAR2_P(62, NONE,      NONE);
2948c2ecf20Sopenharmony_ciJAGUAR2_P(63, NONE,      NONE);
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci#define JAGUAR2_PIN(n) {					\
2978c2ecf20Sopenharmony_ci	.number = n,						\
2988c2ecf20Sopenharmony_ci	.name = "GPIO_"#n,					\
2998c2ecf20Sopenharmony_ci	.drv_data = &jaguar2_pin_##n				\
3008c2ecf20Sopenharmony_ci}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc jaguar2_pins[] = {
3038c2ecf20Sopenharmony_ci	JAGUAR2_PIN(0),
3048c2ecf20Sopenharmony_ci	JAGUAR2_PIN(1),
3058c2ecf20Sopenharmony_ci	JAGUAR2_PIN(2),
3068c2ecf20Sopenharmony_ci	JAGUAR2_PIN(3),
3078c2ecf20Sopenharmony_ci	JAGUAR2_PIN(4),
3088c2ecf20Sopenharmony_ci	JAGUAR2_PIN(5),
3098c2ecf20Sopenharmony_ci	JAGUAR2_PIN(6),
3108c2ecf20Sopenharmony_ci	JAGUAR2_PIN(7),
3118c2ecf20Sopenharmony_ci	JAGUAR2_PIN(8),
3128c2ecf20Sopenharmony_ci	JAGUAR2_PIN(9),
3138c2ecf20Sopenharmony_ci	JAGUAR2_PIN(10),
3148c2ecf20Sopenharmony_ci	JAGUAR2_PIN(11),
3158c2ecf20Sopenharmony_ci	JAGUAR2_PIN(12),
3168c2ecf20Sopenharmony_ci	JAGUAR2_PIN(13),
3178c2ecf20Sopenharmony_ci	JAGUAR2_PIN(14),
3188c2ecf20Sopenharmony_ci	JAGUAR2_PIN(15),
3198c2ecf20Sopenharmony_ci	JAGUAR2_PIN(16),
3208c2ecf20Sopenharmony_ci	JAGUAR2_PIN(17),
3218c2ecf20Sopenharmony_ci	JAGUAR2_PIN(18),
3228c2ecf20Sopenharmony_ci	JAGUAR2_PIN(19),
3238c2ecf20Sopenharmony_ci	JAGUAR2_PIN(20),
3248c2ecf20Sopenharmony_ci	JAGUAR2_PIN(21),
3258c2ecf20Sopenharmony_ci	JAGUAR2_PIN(22),
3268c2ecf20Sopenharmony_ci	JAGUAR2_PIN(23),
3278c2ecf20Sopenharmony_ci	JAGUAR2_PIN(24),
3288c2ecf20Sopenharmony_ci	JAGUAR2_PIN(25),
3298c2ecf20Sopenharmony_ci	JAGUAR2_PIN(26),
3308c2ecf20Sopenharmony_ci	JAGUAR2_PIN(27),
3318c2ecf20Sopenharmony_ci	JAGUAR2_PIN(28),
3328c2ecf20Sopenharmony_ci	JAGUAR2_PIN(29),
3338c2ecf20Sopenharmony_ci	JAGUAR2_PIN(30),
3348c2ecf20Sopenharmony_ci	JAGUAR2_PIN(31),
3358c2ecf20Sopenharmony_ci	JAGUAR2_PIN(32),
3368c2ecf20Sopenharmony_ci	JAGUAR2_PIN(33),
3378c2ecf20Sopenharmony_ci	JAGUAR2_PIN(34),
3388c2ecf20Sopenharmony_ci	JAGUAR2_PIN(35),
3398c2ecf20Sopenharmony_ci	JAGUAR2_PIN(36),
3408c2ecf20Sopenharmony_ci	JAGUAR2_PIN(37),
3418c2ecf20Sopenharmony_ci	JAGUAR2_PIN(38),
3428c2ecf20Sopenharmony_ci	JAGUAR2_PIN(39),
3438c2ecf20Sopenharmony_ci	JAGUAR2_PIN(40),
3448c2ecf20Sopenharmony_ci	JAGUAR2_PIN(41),
3458c2ecf20Sopenharmony_ci	JAGUAR2_PIN(42),
3468c2ecf20Sopenharmony_ci	JAGUAR2_PIN(43),
3478c2ecf20Sopenharmony_ci	JAGUAR2_PIN(44),
3488c2ecf20Sopenharmony_ci	JAGUAR2_PIN(45),
3498c2ecf20Sopenharmony_ci	JAGUAR2_PIN(46),
3508c2ecf20Sopenharmony_ci	JAGUAR2_PIN(47),
3518c2ecf20Sopenharmony_ci	JAGUAR2_PIN(48),
3528c2ecf20Sopenharmony_ci	JAGUAR2_PIN(49),
3538c2ecf20Sopenharmony_ci	JAGUAR2_PIN(50),
3548c2ecf20Sopenharmony_ci	JAGUAR2_PIN(51),
3558c2ecf20Sopenharmony_ci	JAGUAR2_PIN(52),
3568c2ecf20Sopenharmony_ci	JAGUAR2_PIN(53),
3578c2ecf20Sopenharmony_ci	JAGUAR2_PIN(54),
3588c2ecf20Sopenharmony_ci	JAGUAR2_PIN(55),
3598c2ecf20Sopenharmony_ci	JAGUAR2_PIN(56),
3608c2ecf20Sopenharmony_ci	JAGUAR2_PIN(57),
3618c2ecf20Sopenharmony_ci	JAGUAR2_PIN(58),
3628c2ecf20Sopenharmony_ci	JAGUAR2_PIN(59),
3638c2ecf20Sopenharmony_ci	JAGUAR2_PIN(60),
3648c2ecf20Sopenharmony_ci	JAGUAR2_PIN(61),
3658c2ecf20Sopenharmony_ci	JAGUAR2_PIN(62),
3668c2ecf20Sopenharmony_ci	JAGUAR2_PIN(63),
3678c2ecf20Sopenharmony_ci};
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci#define SPARX5_P(p, f0, f1, f2)					\
3708c2ecf20Sopenharmony_cistatic struct ocelot_pin_caps sparx5_pin_##p = {			\
3718c2ecf20Sopenharmony_ci	.pin = p,							\
3728c2ecf20Sopenharmony_ci	.functions = {							\
3738c2ecf20Sopenharmony_ci		FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2		\
3748c2ecf20Sopenharmony_ci	},								\
3758c2ecf20Sopenharmony_ci}
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ciSPARX5_P(0,  SG0,       PLL_STAT,  NONE);
3788c2ecf20Sopenharmony_ciSPARX5_P(1,  SG0,       NONE,      NONE);
3798c2ecf20Sopenharmony_ciSPARX5_P(2,  SG0,       NONE,      NONE);
3808c2ecf20Sopenharmony_ciSPARX5_P(3,  SG0,       NONE,      NONE);
3818c2ecf20Sopenharmony_ciSPARX5_P(4,  SG1,       NONE,      NONE);
3828c2ecf20Sopenharmony_ciSPARX5_P(5,  SG1,       NONE,      NONE);
3838c2ecf20Sopenharmony_ciSPARX5_P(6,  IRQ0_IN,   IRQ0_OUT,  SFP);
3848c2ecf20Sopenharmony_ciSPARX5_P(7,  IRQ1_IN,   IRQ1_OUT,  SFP);
3858c2ecf20Sopenharmony_ciSPARX5_P(8,  PTP0,      NONE,      SFP);
3868c2ecf20Sopenharmony_ciSPARX5_P(9,  PTP1,      SFP,       TWI_SCL_M);
3878c2ecf20Sopenharmony_ciSPARX5_P(10, UART,      NONE,      NONE);
3888c2ecf20Sopenharmony_ciSPARX5_P(11, UART,      NONE,      NONE);
3898c2ecf20Sopenharmony_ciSPARX5_P(12, SG1,       NONE,      NONE);
3908c2ecf20Sopenharmony_ciSPARX5_P(13, SG1,       NONE,      NONE);
3918c2ecf20Sopenharmony_ciSPARX5_P(14, TWI,       TWI_SCL_M, NONE);
3928c2ecf20Sopenharmony_ciSPARX5_P(15, TWI,       NONE,      NONE);
3938c2ecf20Sopenharmony_ciSPARX5_P(16, SI,        TWI_SCL_M, SFP);
3948c2ecf20Sopenharmony_ciSPARX5_P(17, SI,        TWI_SCL_M, SFP);
3958c2ecf20Sopenharmony_ciSPARX5_P(18, SI,        TWI_SCL_M, SFP);
3968c2ecf20Sopenharmony_ciSPARX5_P(19, PCI_WAKE,  TWI_SCL_M, SFP);
3978c2ecf20Sopenharmony_ciSPARX5_P(20, IRQ0_OUT,  TWI_SCL_M, SFP);
3988c2ecf20Sopenharmony_ciSPARX5_P(21, IRQ1_OUT,  TACHO,     SFP);
3998c2ecf20Sopenharmony_ciSPARX5_P(22, TACHO,     IRQ0_OUT,  TWI_SCL_M);
4008c2ecf20Sopenharmony_ciSPARX5_P(23, PWM,       UART3,     TWI_SCL_M);
4018c2ecf20Sopenharmony_ciSPARX5_P(24, PTP2,      UART3,     TWI_SCL_M);
4028c2ecf20Sopenharmony_ciSPARX5_P(25, PTP3,      SI,        TWI_SCL_M);
4038c2ecf20Sopenharmony_ciSPARX5_P(26, UART2,     SI,        TWI_SCL_M);
4048c2ecf20Sopenharmony_ciSPARX5_P(27, UART2,     SI,        TWI_SCL_M);
4058c2ecf20Sopenharmony_ciSPARX5_P(28, TWI2,      SI,        SFP);
4068c2ecf20Sopenharmony_ciSPARX5_P(29, TWI2,      SI,        SFP);
4078c2ecf20Sopenharmony_ciSPARX5_P(30, SG2,       SI,        PWM);
4088c2ecf20Sopenharmony_ciSPARX5_P(31, SG2,       SI,        TWI_SCL_M);
4098c2ecf20Sopenharmony_ciSPARX5_P(32, SG2,       SI,        TWI_SCL_M);
4108c2ecf20Sopenharmony_ciSPARX5_P(33, SG2,       SI,        SFP);
4118c2ecf20Sopenharmony_ciSPARX5_P(34, NONE,      TWI_SCL_M, EMMC);
4128c2ecf20Sopenharmony_ciSPARX5_P(35, SFP,       TWI_SCL_M, EMMC);
4138c2ecf20Sopenharmony_ciSPARX5_P(36, SFP,       TWI_SCL_M, EMMC);
4148c2ecf20Sopenharmony_ciSPARX5_P(37, SFP,       NONE,      EMMC);
4158c2ecf20Sopenharmony_ciSPARX5_P(38, NONE,      TWI_SCL_M, EMMC);
4168c2ecf20Sopenharmony_ciSPARX5_P(39, SI2,       TWI_SCL_M, EMMC);
4178c2ecf20Sopenharmony_ciSPARX5_P(40, SI2,       TWI_SCL_M, EMMC);
4188c2ecf20Sopenharmony_ciSPARX5_P(41, SI2,       TWI_SCL_M, EMMC);
4198c2ecf20Sopenharmony_ciSPARX5_P(42, SI2,       TWI_SCL_M, EMMC);
4208c2ecf20Sopenharmony_ciSPARX5_P(43, SI2,       TWI_SCL_M, EMMC);
4218c2ecf20Sopenharmony_ciSPARX5_P(44, SI,        SFP,       EMMC);
4228c2ecf20Sopenharmony_ciSPARX5_P(45, SI,        SFP,       EMMC);
4238c2ecf20Sopenharmony_ciSPARX5_P(46, NONE,      SFP,       EMMC);
4248c2ecf20Sopenharmony_ciSPARX5_P(47, NONE,      SFP,       EMMC);
4258c2ecf20Sopenharmony_ciSPARX5_P(48, TWI3,      SI,        SFP);
4268c2ecf20Sopenharmony_ciSPARX5_P(49, TWI3,      NONE,      SFP);
4278c2ecf20Sopenharmony_ciSPARX5_P(50, SFP,       NONE,      TWI_SCL_M);
4288c2ecf20Sopenharmony_ciSPARX5_P(51, SFP,       SI,        TWI_SCL_M);
4298c2ecf20Sopenharmony_ciSPARX5_P(52, SFP,       MIIM,      TWI_SCL_M);
4308c2ecf20Sopenharmony_ciSPARX5_P(53, SFP,       MIIM,      TWI_SCL_M);
4318c2ecf20Sopenharmony_ciSPARX5_P(54, SFP,       PTP2,      TWI_SCL_M);
4328c2ecf20Sopenharmony_ciSPARX5_P(55, SFP,       PTP3,      PCI_WAKE);
4338c2ecf20Sopenharmony_ciSPARX5_P(56, MIIM,      SFP,       TWI_SCL_M);
4348c2ecf20Sopenharmony_ciSPARX5_P(57, MIIM,      SFP,       TWI_SCL_M);
4358c2ecf20Sopenharmony_ciSPARX5_P(58, MIIM,      SFP,       TWI_SCL_M);
4368c2ecf20Sopenharmony_ciSPARX5_P(59, MIIM,      SFP,       NONE);
4378c2ecf20Sopenharmony_ciSPARX5_P(60, RECO_CLK,  NONE,      NONE);
4388c2ecf20Sopenharmony_ciSPARX5_P(61, RECO_CLK,  NONE,      NONE);
4398c2ecf20Sopenharmony_ciSPARX5_P(62, RECO_CLK,  PLL_STAT,  NONE);
4408c2ecf20Sopenharmony_ciSPARX5_P(63, RECO_CLK,  NONE,      NONE);
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci#define SPARX5_PIN(n) {					\
4438c2ecf20Sopenharmony_ci	.number = n,						\
4448c2ecf20Sopenharmony_ci	.name = "GPIO_"#n,					\
4458c2ecf20Sopenharmony_ci	.drv_data = &sparx5_pin_##n				\
4468c2ecf20Sopenharmony_ci}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc sparx5_pins[] = {
4498c2ecf20Sopenharmony_ci	SPARX5_PIN(0),
4508c2ecf20Sopenharmony_ci	SPARX5_PIN(1),
4518c2ecf20Sopenharmony_ci	SPARX5_PIN(2),
4528c2ecf20Sopenharmony_ci	SPARX5_PIN(3),
4538c2ecf20Sopenharmony_ci	SPARX5_PIN(4),
4548c2ecf20Sopenharmony_ci	SPARX5_PIN(5),
4558c2ecf20Sopenharmony_ci	SPARX5_PIN(6),
4568c2ecf20Sopenharmony_ci	SPARX5_PIN(7),
4578c2ecf20Sopenharmony_ci	SPARX5_PIN(8),
4588c2ecf20Sopenharmony_ci	SPARX5_PIN(9),
4598c2ecf20Sopenharmony_ci	SPARX5_PIN(10),
4608c2ecf20Sopenharmony_ci	SPARX5_PIN(11),
4618c2ecf20Sopenharmony_ci	SPARX5_PIN(12),
4628c2ecf20Sopenharmony_ci	SPARX5_PIN(13),
4638c2ecf20Sopenharmony_ci	SPARX5_PIN(14),
4648c2ecf20Sopenharmony_ci	SPARX5_PIN(15),
4658c2ecf20Sopenharmony_ci	SPARX5_PIN(16),
4668c2ecf20Sopenharmony_ci	SPARX5_PIN(17),
4678c2ecf20Sopenharmony_ci	SPARX5_PIN(18),
4688c2ecf20Sopenharmony_ci	SPARX5_PIN(19),
4698c2ecf20Sopenharmony_ci	SPARX5_PIN(20),
4708c2ecf20Sopenharmony_ci	SPARX5_PIN(21),
4718c2ecf20Sopenharmony_ci	SPARX5_PIN(22),
4728c2ecf20Sopenharmony_ci	SPARX5_PIN(23),
4738c2ecf20Sopenharmony_ci	SPARX5_PIN(24),
4748c2ecf20Sopenharmony_ci	SPARX5_PIN(25),
4758c2ecf20Sopenharmony_ci	SPARX5_PIN(26),
4768c2ecf20Sopenharmony_ci	SPARX5_PIN(27),
4778c2ecf20Sopenharmony_ci	SPARX5_PIN(28),
4788c2ecf20Sopenharmony_ci	SPARX5_PIN(29),
4798c2ecf20Sopenharmony_ci	SPARX5_PIN(30),
4808c2ecf20Sopenharmony_ci	SPARX5_PIN(31),
4818c2ecf20Sopenharmony_ci	SPARX5_PIN(32),
4828c2ecf20Sopenharmony_ci	SPARX5_PIN(33),
4838c2ecf20Sopenharmony_ci	SPARX5_PIN(34),
4848c2ecf20Sopenharmony_ci	SPARX5_PIN(35),
4858c2ecf20Sopenharmony_ci	SPARX5_PIN(36),
4868c2ecf20Sopenharmony_ci	SPARX5_PIN(37),
4878c2ecf20Sopenharmony_ci	SPARX5_PIN(38),
4888c2ecf20Sopenharmony_ci	SPARX5_PIN(39),
4898c2ecf20Sopenharmony_ci	SPARX5_PIN(40),
4908c2ecf20Sopenharmony_ci	SPARX5_PIN(41),
4918c2ecf20Sopenharmony_ci	SPARX5_PIN(42),
4928c2ecf20Sopenharmony_ci	SPARX5_PIN(43),
4938c2ecf20Sopenharmony_ci	SPARX5_PIN(44),
4948c2ecf20Sopenharmony_ci	SPARX5_PIN(45),
4958c2ecf20Sopenharmony_ci	SPARX5_PIN(46),
4968c2ecf20Sopenharmony_ci	SPARX5_PIN(47),
4978c2ecf20Sopenharmony_ci	SPARX5_PIN(48),
4988c2ecf20Sopenharmony_ci	SPARX5_PIN(49),
4998c2ecf20Sopenharmony_ci	SPARX5_PIN(50),
5008c2ecf20Sopenharmony_ci	SPARX5_PIN(51),
5018c2ecf20Sopenharmony_ci	SPARX5_PIN(52),
5028c2ecf20Sopenharmony_ci	SPARX5_PIN(53),
5038c2ecf20Sopenharmony_ci	SPARX5_PIN(54),
5048c2ecf20Sopenharmony_ci	SPARX5_PIN(55),
5058c2ecf20Sopenharmony_ci	SPARX5_PIN(56),
5068c2ecf20Sopenharmony_ci	SPARX5_PIN(57),
5078c2ecf20Sopenharmony_ci	SPARX5_PIN(58),
5088c2ecf20Sopenharmony_ci	SPARX5_PIN(59),
5098c2ecf20Sopenharmony_ci	SPARX5_PIN(60),
5108c2ecf20Sopenharmony_ci	SPARX5_PIN(61),
5118c2ecf20Sopenharmony_ci	SPARX5_PIN(62),
5128c2ecf20Sopenharmony_ci	SPARX5_PIN(63),
5138c2ecf20Sopenharmony_ci};
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_cistatic int ocelot_get_functions_count(struct pinctrl_dev *pctldev)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci	return ARRAY_SIZE(ocelot_function_names);
5188c2ecf20Sopenharmony_ci}
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_cistatic const char *ocelot_get_function_name(struct pinctrl_dev *pctldev,
5218c2ecf20Sopenharmony_ci					    unsigned int function)
5228c2ecf20Sopenharmony_ci{
5238c2ecf20Sopenharmony_ci	return ocelot_function_names[function];
5248c2ecf20Sopenharmony_ci}
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_cistatic int ocelot_get_function_groups(struct pinctrl_dev *pctldev,
5278c2ecf20Sopenharmony_ci				      unsigned int function,
5288c2ecf20Sopenharmony_ci				      const char *const **groups,
5298c2ecf20Sopenharmony_ci				      unsigned *const num_groups)
5308c2ecf20Sopenharmony_ci{
5318c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	*groups  = info->func[function].groups;
5348c2ecf20Sopenharmony_ci	*num_groups = info->func[function].ngroups;
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci	return 0;
5378c2ecf20Sopenharmony_ci}
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_cistatic int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
5408c2ecf20Sopenharmony_ci				   unsigned int pin, unsigned int function)
5418c2ecf20Sopenharmony_ci{
5428c2ecf20Sopenharmony_ci	struct ocelot_pin_caps *p = info->desc->pins[pin].drv_data;
5438c2ecf20Sopenharmony_ci	int i;
5448c2ecf20Sopenharmony_ci
5458c2ecf20Sopenharmony_ci	for (i = 0; i < OCELOT_FUNC_PER_PIN; i++) {
5468c2ecf20Sopenharmony_ci		if (function == p->functions[i])
5478c2ecf20Sopenharmony_ci			return i;
5488c2ecf20Sopenharmony_ci	}
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci	return -1;
5518c2ecf20Sopenharmony_ci}
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ci#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32))))
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_cistatic int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
5568c2ecf20Sopenharmony_ci				 unsigned int selector, unsigned int group)
5578c2ecf20Sopenharmony_ci{
5588c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
5598c2ecf20Sopenharmony_ci	struct ocelot_pin_caps *pin = info->desc->pins[group].drv_data;
5608c2ecf20Sopenharmony_ci	unsigned int p = pin->pin % 32;
5618c2ecf20Sopenharmony_ci	int f;
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	f = ocelot_pin_function_idx(info, group, selector);
5648c2ecf20Sopenharmony_ci	if (f < 0)
5658c2ecf20Sopenharmony_ci		return -EINVAL;
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_ci	/*
5688c2ecf20Sopenharmony_ci	 * f is encoded on two bits.
5698c2ecf20Sopenharmony_ci	 * bit 0 of f goes in BIT(pin) of ALT[0], bit 1 of f goes in BIT(pin) of
5708c2ecf20Sopenharmony_ci	 * ALT[1]
5718c2ecf20Sopenharmony_ci	 * This is racy because both registers can't be updated at the same time
5728c2ecf20Sopenharmony_ci	 * but it doesn't matter much for now.
5738c2ecf20Sopenharmony_ci	 * Note: ALT0/ALT1 are organized specially for 64 gpio targets
5748c2ecf20Sopenharmony_ci	 */
5758c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG_ALT(0, info, pin->pin),
5768c2ecf20Sopenharmony_ci			   BIT(p), f << p);
5778c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG_ALT(1, info, pin->pin),
5788c2ecf20Sopenharmony_ci			   BIT(p), (f >> 1) << p);
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci	return 0;
5818c2ecf20Sopenharmony_ci}
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci#define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32)))
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_cistatic int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev,
5868c2ecf20Sopenharmony_ci				     struct pinctrl_gpio_range *range,
5878c2ecf20Sopenharmony_ci				     unsigned int pin, bool input)
5888c2ecf20Sopenharmony_ci{
5898c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
5908c2ecf20Sopenharmony_ci	unsigned int p = pin % 32;
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG(OCELOT_GPIO_OE, info, pin), BIT(p),
5938c2ecf20Sopenharmony_ci			   input ? 0 : BIT(p));
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	return 0;
5968c2ecf20Sopenharmony_ci}
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_cistatic int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev,
5998c2ecf20Sopenharmony_ci				      struct pinctrl_gpio_range *range,
6008c2ecf20Sopenharmony_ci				      unsigned int offset)
6018c2ecf20Sopenharmony_ci{
6028c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
6038c2ecf20Sopenharmony_ci	unsigned int p = offset % 32;
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG_ALT(0, info, offset),
6068c2ecf20Sopenharmony_ci			   BIT(p), 0);
6078c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG_ALT(1, info, offset),
6088c2ecf20Sopenharmony_ci			   BIT(p), 0);
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_ci	return 0;
6118c2ecf20Sopenharmony_ci}
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_cistatic const struct pinmux_ops ocelot_pmx_ops = {
6148c2ecf20Sopenharmony_ci	.get_functions_count = ocelot_get_functions_count,
6158c2ecf20Sopenharmony_ci	.get_function_name = ocelot_get_function_name,
6168c2ecf20Sopenharmony_ci	.get_function_groups = ocelot_get_function_groups,
6178c2ecf20Sopenharmony_ci	.set_mux = ocelot_pinmux_set_mux,
6188c2ecf20Sopenharmony_ci	.gpio_set_direction = ocelot_gpio_set_direction,
6198c2ecf20Sopenharmony_ci	.gpio_request_enable = ocelot_gpio_request_enable,
6208c2ecf20Sopenharmony_ci};
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_cistatic int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev)
6238c2ecf20Sopenharmony_ci{
6248c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci	return info->desc->npins;
6278c2ecf20Sopenharmony_ci}
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_cistatic const char *ocelot_pctl_get_group_name(struct pinctrl_dev *pctldev,
6308c2ecf20Sopenharmony_ci					      unsigned int group)
6318c2ecf20Sopenharmony_ci{
6328c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci	return info->desc->pins[group].name;
6358c2ecf20Sopenharmony_ci}
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_cistatic int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev,
6388c2ecf20Sopenharmony_ci				      unsigned int group,
6398c2ecf20Sopenharmony_ci				      const unsigned int **pins,
6408c2ecf20Sopenharmony_ci				      unsigned int *num_pins)
6418c2ecf20Sopenharmony_ci{
6428c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci	*pins = &info->desc->pins[group].number;
6458c2ecf20Sopenharmony_ci	*num_pins = 1;
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci	return 0;
6488c2ecf20Sopenharmony_ci}
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_cistatic int ocelot_hw_get_value(struct ocelot_pinctrl *info,
6518c2ecf20Sopenharmony_ci			       unsigned int pin,
6528c2ecf20Sopenharmony_ci			       unsigned int reg,
6538c2ecf20Sopenharmony_ci			       int *val)
6548c2ecf20Sopenharmony_ci{
6558c2ecf20Sopenharmony_ci	int ret = -EOPNOTSUPP;
6568c2ecf20Sopenharmony_ci
6578c2ecf20Sopenharmony_ci	if (info->pincfg) {
6588c2ecf20Sopenharmony_ci		u32 regcfg = readl(info->pincfg + (pin * sizeof(u32)));
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_ci		ret = 0;
6618c2ecf20Sopenharmony_ci		switch (reg) {
6628c2ecf20Sopenharmony_ci		case PINCONF_BIAS:
6638c2ecf20Sopenharmony_ci			*val = regcfg & BIAS_BITS;
6648c2ecf20Sopenharmony_ci			break;
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci		case PINCONF_SCHMITT:
6678c2ecf20Sopenharmony_ci			*val = regcfg & SCHMITT_BIT;
6688c2ecf20Sopenharmony_ci			break;
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci		case PINCONF_DRIVE_STRENGTH:
6718c2ecf20Sopenharmony_ci			*val = regcfg & DRIVE_BITS;
6728c2ecf20Sopenharmony_ci			break;
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci		default:
6758c2ecf20Sopenharmony_ci			ret = -EOPNOTSUPP;
6768c2ecf20Sopenharmony_ci			break;
6778c2ecf20Sopenharmony_ci		}
6788c2ecf20Sopenharmony_ci	}
6798c2ecf20Sopenharmony_ci	return ret;
6808c2ecf20Sopenharmony_ci}
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_cistatic int ocelot_hw_set_value(struct ocelot_pinctrl *info,
6838c2ecf20Sopenharmony_ci			       unsigned int pin,
6848c2ecf20Sopenharmony_ci			       unsigned int reg,
6858c2ecf20Sopenharmony_ci			       int val)
6868c2ecf20Sopenharmony_ci{
6878c2ecf20Sopenharmony_ci	int ret = -EOPNOTSUPP;
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci	if (info->pincfg) {
6908c2ecf20Sopenharmony_ci		void __iomem *regaddr = info->pincfg + (pin * sizeof(u32));
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci		ret = 0;
6938c2ecf20Sopenharmony_ci		switch (reg) {
6948c2ecf20Sopenharmony_ci		case PINCONF_BIAS:
6958c2ecf20Sopenharmony_ci			ocelot_clrsetbits(regaddr, BIAS_BITS, val);
6968c2ecf20Sopenharmony_ci			break;
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci		case PINCONF_SCHMITT:
6998c2ecf20Sopenharmony_ci			ocelot_clrsetbits(regaddr, SCHMITT_BIT, val);
7008c2ecf20Sopenharmony_ci			break;
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci		case PINCONF_DRIVE_STRENGTH:
7038c2ecf20Sopenharmony_ci			if (val <= 3)
7048c2ecf20Sopenharmony_ci				ocelot_clrsetbits(regaddr, DRIVE_BITS, val);
7058c2ecf20Sopenharmony_ci			else
7068c2ecf20Sopenharmony_ci				ret = -EINVAL;
7078c2ecf20Sopenharmony_ci			break;
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci		default:
7108c2ecf20Sopenharmony_ci			ret = -EOPNOTSUPP;
7118c2ecf20Sopenharmony_ci			break;
7128c2ecf20Sopenharmony_ci		}
7138c2ecf20Sopenharmony_ci	}
7148c2ecf20Sopenharmony_ci	return ret;
7158c2ecf20Sopenharmony_ci}
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_cistatic int ocelot_pinconf_get(struct pinctrl_dev *pctldev,
7188c2ecf20Sopenharmony_ci			      unsigned int pin, unsigned long *config)
7198c2ecf20Sopenharmony_ci{
7208c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
7218c2ecf20Sopenharmony_ci	u32 param = pinconf_to_config_param(*config);
7228c2ecf20Sopenharmony_ci	int val, err;
7238c2ecf20Sopenharmony_ci
7248c2ecf20Sopenharmony_ci	switch (param) {
7258c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_DISABLE:
7268c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_PULL_UP:
7278c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_PULL_DOWN:
7288c2ecf20Sopenharmony_ci		err = ocelot_hw_get_value(info, pin, PINCONF_BIAS, &val);
7298c2ecf20Sopenharmony_ci		if (err)
7308c2ecf20Sopenharmony_ci			return err;
7318c2ecf20Sopenharmony_ci		if (param == PIN_CONFIG_BIAS_DISABLE)
7328c2ecf20Sopenharmony_ci			val = (val == 0 ? true : false);
7338c2ecf20Sopenharmony_ci		else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
7348c2ecf20Sopenharmony_ci			val = (val & BIAS_PD_BIT ? true : false);
7358c2ecf20Sopenharmony_ci		else    /* PIN_CONFIG_BIAS_PULL_UP */
7368c2ecf20Sopenharmony_ci			val = (val & BIAS_PU_BIT ? true : false);
7378c2ecf20Sopenharmony_ci		break;
7388c2ecf20Sopenharmony_ci
7398c2ecf20Sopenharmony_ci	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
7408c2ecf20Sopenharmony_ci		err = ocelot_hw_get_value(info, pin, PINCONF_SCHMITT, &val);
7418c2ecf20Sopenharmony_ci		if (err)
7428c2ecf20Sopenharmony_ci			return err;
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_ci		val = (val & SCHMITT_BIT ? true : false);
7458c2ecf20Sopenharmony_ci		break;
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ci	case PIN_CONFIG_DRIVE_STRENGTH:
7488c2ecf20Sopenharmony_ci		err = ocelot_hw_get_value(info, pin, PINCONF_DRIVE_STRENGTH,
7498c2ecf20Sopenharmony_ci					  &val);
7508c2ecf20Sopenharmony_ci		if (err)
7518c2ecf20Sopenharmony_ci			return err;
7528c2ecf20Sopenharmony_ci		break;
7538c2ecf20Sopenharmony_ci
7548c2ecf20Sopenharmony_ci	case PIN_CONFIG_OUTPUT:
7558c2ecf20Sopenharmony_ci		err = regmap_read(info->map, REG(OCELOT_GPIO_OUT, info, pin),
7568c2ecf20Sopenharmony_ci				  &val);
7578c2ecf20Sopenharmony_ci		if (err)
7588c2ecf20Sopenharmony_ci			return err;
7598c2ecf20Sopenharmony_ci		val = !!(val & BIT(pin % 32));
7608c2ecf20Sopenharmony_ci		break;
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci	case PIN_CONFIG_INPUT_ENABLE:
7638c2ecf20Sopenharmony_ci	case PIN_CONFIG_OUTPUT_ENABLE:
7648c2ecf20Sopenharmony_ci		err = regmap_read(info->map, REG(OCELOT_GPIO_OE, info, pin),
7658c2ecf20Sopenharmony_ci				  &val);
7668c2ecf20Sopenharmony_ci		if (err)
7678c2ecf20Sopenharmony_ci			return err;
7688c2ecf20Sopenharmony_ci		val = val & BIT(pin % 32);
7698c2ecf20Sopenharmony_ci		if (param == PIN_CONFIG_OUTPUT_ENABLE)
7708c2ecf20Sopenharmony_ci			val = !!val;
7718c2ecf20Sopenharmony_ci		else
7728c2ecf20Sopenharmony_ci			val = !val;
7738c2ecf20Sopenharmony_ci		break;
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_ci	default:
7768c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
7778c2ecf20Sopenharmony_ci	}
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	*config = pinconf_to_config_packed(param, val);
7808c2ecf20Sopenharmony_ci
7818c2ecf20Sopenharmony_ci	return 0;
7828c2ecf20Sopenharmony_ci}
7838c2ecf20Sopenharmony_ci
7848c2ecf20Sopenharmony_cistatic int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
7858c2ecf20Sopenharmony_ci			      unsigned long *configs, unsigned int num_configs)
7868c2ecf20Sopenharmony_ci{
7878c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
7888c2ecf20Sopenharmony_ci	u32 param, arg, p;
7898c2ecf20Sopenharmony_ci	int cfg, err = 0;
7908c2ecf20Sopenharmony_ci
7918c2ecf20Sopenharmony_ci	for (cfg = 0; cfg < num_configs; cfg++) {
7928c2ecf20Sopenharmony_ci		param = pinconf_to_config_param(configs[cfg]);
7938c2ecf20Sopenharmony_ci		arg = pinconf_to_config_argument(configs[cfg]);
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci		switch (param) {
7968c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_DISABLE:
7978c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_PULL_UP:
7988c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_PULL_DOWN:
7998c2ecf20Sopenharmony_ci			arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
8008c2ecf20Sopenharmony_ci			(param == PIN_CONFIG_BIAS_PULL_UP) ? BIAS_PU_BIT :
8018c2ecf20Sopenharmony_ci			BIAS_PD_BIT;
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_ci			err = ocelot_hw_set_value(info, pin, PINCONF_BIAS, arg);
8048c2ecf20Sopenharmony_ci			if (err)
8058c2ecf20Sopenharmony_ci				goto err;
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci			break;
8088c2ecf20Sopenharmony_ci
8098c2ecf20Sopenharmony_ci		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
8108c2ecf20Sopenharmony_ci			arg = arg ? SCHMITT_BIT : 0;
8118c2ecf20Sopenharmony_ci			err = ocelot_hw_set_value(info, pin, PINCONF_SCHMITT,
8128c2ecf20Sopenharmony_ci						  arg);
8138c2ecf20Sopenharmony_ci			if (err)
8148c2ecf20Sopenharmony_ci				goto err;
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci			break;
8178c2ecf20Sopenharmony_ci
8188c2ecf20Sopenharmony_ci		case PIN_CONFIG_DRIVE_STRENGTH:
8198c2ecf20Sopenharmony_ci			err = ocelot_hw_set_value(info, pin,
8208c2ecf20Sopenharmony_ci						  PINCONF_DRIVE_STRENGTH,
8218c2ecf20Sopenharmony_ci						  arg);
8228c2ecf20Sopenharmony_ci			if (err)
8238c2ecf20Sopenharmony_ci				goto err;
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci			break;
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci		case PIN_CONFIG_OUTPUT_ENABLE:
8288c2ecf20Sopenharmony_ci		case PIN_CONFIG_INPUT_ENABLE:
8298c2ecf20Sopenharmony_ci		case PIN_CONFIG_OUTPUT:
8308c2ecf20Sopenharmony_ci			p = pin % 32;
8318c2ecf20Sopenharmony_ci			if (arg)
8328c2ecf20Sopenharmony_ci				regmap_write(info->map,
8338c2ecf20Sopenharmony_ci					     REG(OCELOT_GPIO_OUT_SET, info,
8348c2ecf20Sopenharmony_ci						 pin),
8358c2ecf20Sopenharmony_ci					     BIT(p));
8368c2ecf20Sopenharmony_ci			else
8378c2ecf20Sopenharmony_ci				regmap_write(info->map,
8388c2ecf20Sopenharmony_ci					     REG(OCELOT_GPIO_OUT_CLR, info,
8398c2ecf20Sopenharmony_ci						 pin),
8408c2ecf20Sopenharmony_ci					     BIT(p));
8418c2ecf20Sopenharmony_ci			regmap_update_bits(info->map,
8428c2ecf20Sopenharmony_ci					   REG(OCELOT_GPIO_OE, info, pin),
8438c2ecf20Sopenharmony_ci					   BIT(p),
8448c2ecf20Sopenharmony_ci					   param == PIN_CONFIG_INPUT_ENABLE ?
8458c2ecf20Sopenharmony_ci					   0 : BIT(p));
8468c2ecf20Sopenharmony_ci			break;
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci		default:
8498c2ecf20Sopenharmony_ci			err = -EOPNOTSUPP;
8508c2ecf20Sopenharmony_ci		}
8518c2ecf20Sopenharmony_ci	}
8528c2ecf20Sopenharmony_cierr:
8538c2ecf20Sopenharmony_ci	return err;
8548c2ecf20Sopenharmony_ci}
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_cistatic const struct pinconf_ops ocelot_confops = {
8578c2ecf20Sopenharmony_ci	.is_generic = true,
8588c2ecf20Sopenharmony_ci	.pin_config_get = ocelot_pinconf_get,
8598c2ecf20Sopenharmony_ci	.pin_config_set = ocelot_pinconf_set,
8608c2ecf20Sopenharmony_ci	.pin_config_config_dbg_show = pinconf_generic_dump_config,
8618c2ecf20Sopenharmony_ci};
8628c2ecf20Sopenharmony_ci
8638c2ecf20Sopenharmony_cistatic const struct pinctrl_ops ocelot_pctl_ops = {
8648c2ecf20Sopenharmony_ci	.get_groups_count = ocelot_pctl_get_groups_count,
8658c2ecf20Sopenharmony_ci	.get_group_name = ocelot_pctl_get_group_name,
8668c2ecf20Sopenharmony_ci	.get_group_pins = ocelot_pctl_get_group_pins,
8678c2ecf20Sopenharmony_ci	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
8688c2ecf20Sopenharmony_ci	.dt_free_map = pinconf_generic_dt_free_map,
8698c2ecf20Sopenharmony_ci};
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_cistatic struct pinctrl_desc ocelot_desc = {
8728c2ecf20Sopenharmony_ci	.name = "ocelot-pinctrl",
8738c2ecf20Sopenharmony_ci	.pins = ocelot_pins,
8748c2ecf20Sopenharmony_ci	.npins = ARRAY_SIZE(ocelot_pins),
8758c2ecf20Sopenharmony_ci	.pctlops = &ocelot_pctl_ops,
8768c2ecf20Sopenharmony_ci	.pmxops = &ocelot_pmx_ops,
8778c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
8788c2ecf20Sopenharmony_ci};
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_cistatic struct pinctrl_desc jaguar2_desc = {
8818c2ecf20Sopenharmony_ci	.name = "jaguar2-pinctrl",
8828c2ecf20Sopenharmony_ci	.pins = jaguar2_pins,
8838c2ecf20Sopenharmony_ci	.npins = ARRAY_SIZE(jaguar2_pins),
8848c2ecf20Sopenharmony_ci	.pctlops = &ocelot_pctl_ops,
8858c2ecf20Sopenharmony_ci	.pmxops = &ocelot_pmx_ops,
8868c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
8878c2ecf20Sopenharmony_ci};
8888c2ecf20Sopenharmony_ci
8898c2ecf20Sopenharmony_cistatic struct pinctrl_desc sparx5_desc = {
8908c2ecf20Sopenharmony_ci	.name = "sparx5-pinctrl",
8918c2ecf20Sopenharmony_ci	.pins = sparx5_pins,
8928c2ecf20Sopenharmony_ci	.npins = ARRAY_SIZE(sparx5_pins),
8938c2ecf20Sopenharmony_ci	.pctlops = &ocelot_pctl_ops,
8948c2ecf20Sopenharmony_ci	.pmxops = &ocelot_pmx_ops,
8958c2ecf20Sopenharmony_ci	.confops = &ocelot_confops,
8968c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
8978c2ecf20Sopenharmony_ci};
8988c2ecf20Sopenharmony_ci
8998c2ecf20Sopenharmony_cistatic int ocelot_create_group_func_map(struct device *dev,
9008c2ecf20Sopenharmony_ci					struct ocelot_pinctrl *info)
9018c2ecf20Sopenharmony_ci{
9028c2ecf20Sopenharmony_ci	int f, npins, i;
9038c2ecf20Sopenharmony_ci	u8 *pins = kcalloc(info->desc->npins, sizeof(u8), GFP_KERNEL);
9048c2ecf20Sopenharmony_ci
9058c2ecf20Sopenharmony_ci	if (!pins)
9068c2ecf20Sopenharmony_ci		return -ENOMEM;
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci	for (f = 0; f < FUNC_MAX; f++) {
9098c2ecf20Sopenharmony_ci		for (npins = 0, i = 0; i < info->desc->npins; i++) {
9108c2ecf20Sopenharmony_ci			if (ocelot_pin_function_idx(info, i, f) >= 0)
9118c2ecf20Sopenharmony_ci				pins[npins++] = i;
9128c2ecf20Sopenharmony_ci		}
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci		if (!npins)
9158c2ecf20Sopenharmony_ci			continue;
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci		info->func[f].ngroups = npins;
9188c2ecf20Sopenharmony_ci		info->func[f].groups = devm_kcalloc(dev, npins, sizeof(char *),
9198c2ecf20Sopenharmony_ci						    GFP_KERNEL);
9208c2ecf20Sopenharmony_ci		if (!info->func[f].groups) {
9218c2ecf20Sopenharmony_ci			kfree(pins);
9228c2ecf20Sopenharmony_ci			return -ENOMEM;
9238c2ecf20Sopenharmony_ci		}
9248c2ecf20Sopenharmony_ci
9258c2ecf20Sopenharmony_ci		for (i = 0; i < npins; i++)
9268c2ecf20Sopenharmony_ci			info->func[f].groups[i] =
9278c2ecf20Sopenharmony_ci				info->desc->pins[pins[i]].name;
9288c2ecf20Sopenharmony_ci	}
9298c2ecf20Sopenharmony_ci
9308c2ecf20Sopenharmony_ci	kfree(pins);
9318c2ecf20Sopenharmony_ci
9328c2ecf20Sopenharmony_ci	return 0;
9338c2ecf20Sopenharmony_ci}
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_cistatic int ocelot_pinctrl_register(struct platform_device *pdev,
9368c2ecf20Sopenharmony_ci				   struct ocelot_pinctrl *info)
9378c2ecf20Sopenharmony_ci{
9388c2ecf20Sopenharmony_ci	int ret;
9398c2ecf20Sopenharmony_ci
9408c2ecf20Sopenharmony_ci	ret = ocelot_create_group_func_map(&pdev->dev, info);
9418c2ecf20Sopenharmony_ci	if (ret) {
9428c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Unable to create group func map.\n");
9438c2ecf20Sopenharmony_ci		return ret;
9448c2ecf20Sopenharmony_ci	}
9458c2ecf20Sopenharmony_ci
9468c2ecf20Sopenharmony_ci	info->pctl = devm_pinctrl_register(&pdev->dev, info->desc, info);
9478c2ecf20Sopenharmony_ci	if (IS_ERR(info->pctl)) {
9488c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Failed to register pinctrl\n");
9498c2ecf20Sopenharmony_ci		return PTR_ERR(info->pctl);
9508c2ecf20Sopenharmony_ci	}
9518c2ecf20Sopenharmony_ci
9528c2ecf20Sopenharmony_ci	return 0;
9538c2ecf20Sopenharmony_ci}
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_cistatic int ocelot_gpio_get(struct gpio_chip *chip, unsigned int offset)
9568c2ecf20Sopenharmony_ci{
9578c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
9588c2ecf20Sopenharmony_ci	unsigned int val;
9598c2ecf20Sopenharmony_ci
9608c2ecf20Sopenharmony_ci	regmap_read(info->map, REG(OCELOT_GPIO_IN, info, offset), &val);
9618c2ecf20Sopenharmony_ci
9628c2ecf20Sopenharmony_ci	return !!(val & BIT(offset % 32));
9638c2ecf20Sopenharmony_ci}
9648c2ecf20Sopenharmony_ci
9658c2ecf20Sopenharmony_cistatic void ocelot_gpio_set(struct gpio_chip *chip, unsigned int offset,
9668c2ecf20Sopenharmony_ci			    int value)
9678c2ecf20Sopenharmony_ci{
9688c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_ci	if (value)
9718c2ecf20Sopenharmony_ci		regmap_write(info->map, REG(OCELOT_GPIO_OUT_SET, info, offset),
9728c2ecf20Sopenharmony_ci			     BIT(offset % 32));
9738c2ecf20Sopenharmony_ci	else
9748c2ecf20Sopenharmony_ci		regmap_write(info->map, REG(OCELOT_GPIO_OUT_CLR, info, offset),
9758c2ecf20Sopenharmony_ci			     BIT(offset % 32));
9768c2ecf20Sopenharmony_ci}
9778c2ecf20Sopenharmony_ci
9788c2ecf20Sopenharmony_cistatic int ocelot_gpio_get_direction(struct gpio_chip *chip,
9798c2ecf20Sopenharmony_ci				     unsigned int offset)
9808c2ecf20Sopenharmony_ci{
9818c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
9828c2ecf20Sopenharmony_ci	unsigned int val;
9838c2ecf20Sopenharmony_ci
9848c2ecf20Sopenharmony_ci	regmap_read(info->map, REG(OCELOT_GPIO_OE, info, offset), &val);
9858c2ecf20Sopenharmony_ci
9868c2ecf20Sopenharmony_ci	if (val & BIT(offset % 32))
9878c2ecf20Sopenharmony_ci		return GPIO_LINE_DIRECTION_OUT;
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_ci	return GPIO_LINE_DIRECTION_IN;
9908c2ecf20Sopenharmony_ci}
9918c2ecf20Sopenharmony_ci
9928c2ecf20Sopenharmony_cistatic int ocelot_gpio_direction_input(struct gpio_chip *chip,
9938c2ecf20Sopenharmony_ci				       unsigned int offset)
9948c2ecf20Sopenharmony_ci{
9958c2ecf20Sopenharmony_ci	return pinctrl_gpio_direction_input(chip->base + offset);
9968c2ecf20Sopenharmony_ci}
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_cistatic int ocelot_gpio_direction_output(struct gpio_chip *chip,
9998c2ecf20Sopenharmony_ci					unsigned int offset, int value)
10008c2ecf20Sopenharmony_ci{
10018c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
10028c2ecf20Sopenharmony_ci	unsigned int pin = BIT(offset % 32);
10038c2ecf20Sopenharmony_ci
10048c2ecf20Sopenharmony_ci	if (value)
10058c2ecf20Sopenharmony_ci		regmap_write(info->map, REG(OCELOT_GPIO_OUT_SET, info, offset),
10068c2ecf20Sopenharmony_ci			     pin);
10078c2ecf20Sopenharmony_ci	else
10088c2ecf20Sopenharmony_ci		regmap_write(info->map, REG(OCELOT_GPIO_OUT_CLR, info, offset),
10098c2ecf20Sopenharmony_ci			     pin);
10108c2ecf20Sopenharmony_ci
10118c2ecf20Sopenharmony_ci	return pinctrl_gpio_direction_output(chip->base + offset);
10128c2ecf20Sopenharmony_ci}
10138c2ecf20Sopenharmony_ci
10148c2ecf20Sopenharmony_cistatic const struct gpio_chip ocelot_gpiolib_chip = {
10158c2ecf20Sopenharmony_ci	.request = gpiochip_generic_request,
10168c2ecf20Sopenharmony_ci	.free = gpiochip_generic_free,
10178c2ecf20Sopenharmony_ci	.set = ocelot_gpio_set,
10188c2ecf20Sopenharmony_ci	.get = ocelot_gpio_get,
10198c2ecf20Sopenharmony_ci	.get_direction = ocelot_gpio_get_direction,
10208c2ecf20Sopenharmony_ci	.direction_input = ocelot_gpio_direction_input,
10218c2ecf20Sopenharmony_ci	.direction_output = ocelot_gpio_direction_output,
10228c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
10238c2ecf20Sopenharmony_ci};
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_cistatic void ocelot_irq_mask(struct irq_data *data)
10268c2ecf20Sopenharmony_ci{
10278c2ecf20Sopenharmony_ci	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
10288c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
10298c2ecf20Sopenharmony_ci	unsigned int gpio = irqd_to_hwirq(data);
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio),
10328c2ecf20Sopenharmony_ci			   BIT(gpio % 32), 0);
10338c2ecf20Sopenharmony_ci}
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_cistatic void ocelot_irq_unmask(struct irq_data *data)
10368c2ecf20Sopenharmony_ci{
10378c2ecf20Sopenharmony_ci	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
10388c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
10398c2ecf20Sopenharmony_ci	unsigned int gpio = irqd_to_hwirq(data);
10408c2ecf20Sopenharmony_ci
10418c2ecf20Sopenharmony_ci	regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio),
10428c2ecf20Sopenharmony_ci			   BIT(gpio % 32), BIT(gpio % 32));
10438c2ecf20Sopenharmony_ci}
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_cistatic void ocelot_irq_ack(struct irq_data *data)
10468c2ecf20Sopenharmony_ci{
10478c2ecf20Sopenharmony_ci	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
10488c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
10498c2ecf20Sopenharmony_ci	unsigned int gpio = irqd_to_hwirq(data);
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_ci	regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio),
10528c2ecf20Sopenharmony_ci			  BIT(gpio % 32), BIT(gpio % 32));
10538c2ecf20Sopenharmony_ci}
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_cistatic int ocelot_irq_set_type(struct irq_data *data, unsigned int type);
10568c2ecf20Sopenharmony_ci
10578c2ecf20Sopenharmony_cistatic struct irq_chip ocelot_eoi_irqchip = {
10588c2ecf20Sopenharmony_ci	.name		= "gpio",
10598c2ecf20Sopenharmony_ci	.irq_mask	= ocelot_irq_mask,
10608c2ecf20Sopenharmony_ci	.irq_eoi	= ocelot_irq_ack,
10618c2ecf20Sopenharmony_ci	.irq_unmask	= ocelot_irq_unmask,
10628c2ecf20Sopenharmony_ci	.flags          = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED,
10638c2ecf20Sopenharmony_ci	.irq_set_type	= ocelot_irq_set_type,
10648c2ecf20Sopenharmony_ci};
10658c2ecf20Sopenharmony_ci
10668c2ecf20Sopenharmony_cistatic struct irq_chip ocelot_irqchip = {
10678c2ecf20Sopenharmony_ci	.name		= "gpio",
10688c2ecf20Sopenharmony_ci	.irq_mask	= ocelot_irq_mask,
10698c2ecf20Sopenharmony_ci	.irq_ack	= ocelot_irq_ack,
10708c2ecf20Sopenharmony_ci	.irq_unmask	= ocelot_irq_unmask,
10718c2ecf20Sopenharmony_ci	.irq_set_type	= ocelot_irq_set_type,
10728c2ecf20Sopenharmony_ci};
10738c2ecf20Sopenharmony_ci
10748c2ecf20Sopenharmony_cistatic int ocelot_irq_set_type(struct irq_data *data, unsigned int type)
10758c2ecf20Sopenharmony_ci{
10768c2ecf20Sopenharmony_ci	type &= IRQ_TYPE_SENSE_MASK;
10778c2ecf20Sopenharmony_ci
10788c2ecf20Sopenharmony_ci	if (!(type & (IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_HIGH)))
10798c2ecf20Sopenharmony_ci		return -EINVAL;
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci	if (type & IRQ_TYPE_LEVEL_HIGH)
10828c2ecf20Sopenharmony_ci		irq_set_chip_handler_name_locked(data, &ocelot_eoi_irqchip,
10838c2ecf20Sopenharmony_ci						 handle_fasteoi_irq, NULL);
10848c2ecf20Sopenharmony_ci	if (type & IRQ_TYPE_EDGE_BOTH)
10858c2ecf20Sopenharmony_ci		irq_set_chip_handler_name_locked(data, &ocelot_irqchip,
10868c2ecf20Sopenharmony_ci						 handle_edge_irq, NULL);
10878c2ecf20Sopenharmony_ci
10888c2ecf20Sopenharmony_ci	return 0;
10898c2ecf20Sopenharmony_ci}
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_cistatic void ocelot_irq_handler(struct irq_desc *desc)
10928c2ecf20Sopenharmony_ci{
10938c2ecf20Sopenharmony_ci	struct irq_chip *parent_chip = irq_desc_get_chip(desc);
10948c2ecf20Sopenharmony_ci	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
10958c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info = gpiochip_get_data(chip);
10968c2ecf20Sopenharmony_ci	unsigned int id_reg = OCELOT_GPIO_INTR_IDENT * info->stride;
10978c2ecf20Sopenharmony_ci	unsigned int reg = 0, irq, i;
10988c2ecf20Sopenharmony_ci	unsigned long irqs;
10998c2ecf20Sopenharmony_ci
11008c2ecf20Sopenharmony_ci	for (i = 0; i < info->stride; i++) {
11018c2ecf20Sopenharmony_ci		regmap_read(info->map, id_reg + 4 * i, &reg);
11028c2ecf20Sopenharmony_ci		if (!reg)
11038c2ecf20Sopenharmony_ci			continue;
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_ci		chained_irq_enter(parent_chip, desc);
11068c2ecf20Sopenharmony_ci
11078c2ecf20Sopenharmony_ci		irqs = reg;
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci		for_each_set_bit(irq, &irqs,
11108c2ecf20Sopenharmony_ci				 min(32U, info->desc->npins - 32 * i))
11118c2ecf20Sopenharmony_ci			generic_handle_irq(irq_linear_revmap(chip->irq.domain,
11128c2ecf20Sopenharmony_ci							     irq + 32 * i));
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_ci		chained_irq_exit(parent_chip, desc);
11158c2ecf20Sopenharmony_ci	}
11168c2ecf20Sopenharmony_ci}
11178c2ecf20Sopenharmony_ci
11188c2ecf20Sopenharmony_cistatic int ocelot_gpiochip_register(struct platform_device *pdev,
11198c2ecf20Sopenharmony_ci				    struct ocelot_pinctrl *info)
11208c2ecf20Sopenharmony_ci{
11218c2ecf20Sopenharmony_ci	struct gpio_chip *gc;
11228c2ecf20Sopenharmony_ci	struct gpio_irq_chip *girq;
11238c2ecf20Sopenharmony_ci	int irq;
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_ci	info->gpio_chip = ocelot_gpiolib_chip;
11268c2ecf20Sopenharmony_ci
11278c2ecf20Sopenharmony_ci	gc = &info->gpio_chip;
11288c2ecf20Sopenharmony_ci	gc->ngpio = info->desc->npins;
11298c2ecf20Sopenharmony_ci	gc->parent = &pdev->dev;
11308c2ecf20Sopenharmony_ci	gc->base = 0;
11318c2ecf20Sopenharmony_ci	gc->of_node = info->dev->of_node;
11328c2ecf20Sopenharmony_ci	gc->label = "ocelot-gpio";
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_ci	irq = irq_of_parse_and_map(gc->of_node, 0);
11358c2ecf20Sopenharmony_ci	if (irq) {
11368c2ecf20Sopenharmony_ci		girq = &gc->irq;
11378c2ecf20Sopenharmony_ci		girq->chip = &ocelot_irqchip;
11388c2ecf20Sopenharmony_ci		girq->parent_handler = ocelot_irq_handler;
11398c2ecf20Sopenharmony_ci		girq->num_parents = 1;
11408c2ecf20Sopenharmony_ci		girq->parents = devm_kcalloc(&pdev->dev, 1,
11418c2ecf20Sopenharmony_ci					     sizeof(*girq->parents),
11428c2ecf20Sopenharmony_ci					     GFP_KERNEL);
11438c2ecf20Sopenharmony_ci		if (!girq->parents)
11448c2ecf20Sopenharmony_ci			return -ENOMEM;
11458c2ecf20Sopenharmony_ci		girq->parents[0] = irq;
11468c2ecf20Sopenharmony_ci		girq->default_type = IRQ_TYPE_NONE;
11478c2ecf20Sopenharmony_ci		girq->handler = handle_edge_irq;
11488c2ecf20Sopenharmony_ci	}
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_ci	return devm_gpiochip_add_data(&pdev->dev, gc, info);
11518c2ecf20Sopenharmony_ci}
11528c2ecf20Sopenharmony_ci
11538c2ecf20Sopenharmony_cistatic const struct of_device_id ocelot_pinctrl_of_match[] = {
11548c2ecf20Sopenharmony_ci	{ .compatible = "mscc,ocelot-pinctrl", .data = &ocelot_desc },
11558c2ecf20Sopenharmony_ci	{ .compatible = "mscc,jaguar2-pinctrl", .data = &jaguar2_desc },
11568c2ecf20Sopenharmony_ci	{ .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc },
11578c2ecf20Sopenharmony_ci	{},
11588c2ecf20Sopenharmony_ci};
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_cistatic int ocelot_pinctrl_probe(struct platform_device *pdev)
11618c2ecf20Sopenharmony_ci{
11628c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
11638c2ecf20Sopenharmony_ci	struct ocelot_pinctrl *info;
11648c2ecf20Sopenharmony_ci	void __iomem *base;
11658c2ecf20Sopenharmony_ci	struct resource *res;
11668c2ecf20Sopenharmony_ci	int ret;
11678c2ecf20Sopenharmony_ci	struct regmap_config regmap_config = {
11688c2ecf20Sopenharmony_ci		.reg_bits = 32,
11698c2ecf20Sopenharmony_ci		.val_bits = 32,
11708c2ecf20Sopenharmony_ci		.reg_stride = 4,
11718c2ecf20Sopenharmony_ci	};
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_ci	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
11748c2ecf20Sopenharmony_ci	if (!info)
11758c2ecf20Sopenharmony_ci		return -ENOMEM;
11768c2ecf20Sopenharmony_ci
11778c2ecf20Sopenharmony_ci	info->desc = (struct pinctrl_desc *)device_get_match_data(dev);
11788c2ecf20Sopenharmony_ci
11798c2ecf20Sopenharmony_ci	base = devm_ioremap_resource(dev,
11808c2ecf20Sopenharmony_ci			platform_get_resource(pdev, IORESOURCE_MEM, 0));
11818c2ecf20Sopenharmony_ci	if (IS_ERR(base)) {
11828c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to ioremap registers\n");
11838c2ecf20Sopenharmony_ci		return PTR_ERR(base);
11848c2ecf20Sopenharmony_ci	}
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_ci	info->stride = 1 + (info->desc->npins - 1) / 32;
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_ci	regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;
11898c2ecf20Sopenharmony_ci
11908c2ecf20Sopenharmony_ci	info->map = devm_regmap_init_mmio(dev, base, &regmap_config);
11918c2ecf20Sopenharmony_ci	if (IS_ERR(info->map)) {
11928c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to create regmap\n");
11938c2ecf20Sopenharmony_ci		return PTR_ERR(info->map);
11948c2ecf20Sopenharmony_ci	}
11958c2ecf20Sopenharmony_ci	dev_set_drvdata(dev, info->map);
11968c2ecf20Sopenharmony_ci	info->dev = dev;
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci	/* Pinconf registers */
11998c2ecf20Sopenharmony_ci	if (info->desc->confops) {
12008c2ecf20Sopenharmony_ci		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
12018c2ecf20Sopenharmony_ci		base = devm_ioremap_resource(dev, res);
12028c2ecf20Sopenharmony_ci		if (IS_ERR(base))
12038c2ecf20Sopenharmony_ci			dev_dbg(dev, "Failed to ioremap config registers (no extended pinconf)\n");
12048c2ecf20Sopenharmony_ci		else
12058c2ecf20Sopenharmony_ci			info->pincfg = base;
12068c2ecf20Sopenharmony_ci	}
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci	ret = ocelot_pinctrl_register(pdev, info);
12098c2ecf20Sopenharmony_ci	if (ret)
12108c2ecf20Sopenharmony_ci		return ret;
12118c2ecf20Sopenharmony_ci
12128c2ecf20Sopenharmony_ci	ret = ocelot_gpiochip_register(pdev, info);
12138c2ecf20Sopenharmony_ci	if (ret)
12148c2ecf20Sopenharmony_ci		return ret;
12158c2ecf20Sopenharmony_ci
12168c2ecf20Sopenharmony_ci	dev_info(dev, "driver registered\n");
12178c2ecf20Sopenharmony_ci
12188c2ecf20Sopenharmony_ci	return 0;
12198c2ecf20Sopenharmony_ci}
12208c2ecf20Sopenharmony_ci
12218c2ecf20Sopenharmony_cistatic struct platform_driver ocelot_pinctrl_driver = {
12228c2ecf20Sopenharmony_ci	.driver = {
12238c2ecf20Sopenharmony_ci		.name = "pinctrl-ocelot",
12248c2ecf20Sopenharmony_ci		.of_match_table = of_match_ptr(ocelot_pinctrl_of_match),
12258c2ecf20Sopenharmony_ci		.suppress_bind_attrs = true,
12268c2ecf20Sopenharmony_ci	},
12278c2ecf20Sopenharmony_ci	.probe = ocelot_pinctrl_probe,
12288c2ecf20Sopenharmony_ci};
12298c2ecf20Sopenharmony_cibuiltin_platform_driver(ocelot_pinctrl_driver);
1230