Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Intel Thunder Bay SOC pinctrl/GPIO driver
0004  *
0005  * Copyright (C) 2021 Intel Corporation
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/err.h>
0010 #include <linux/gpio/driver.h>
0011 #include <linux/init.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/irq.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/of_irq.h>
0018 
0019 #include <linux/pinctrl/pinconf.h>
0020 #include <linux/pinctrl/pinconf-generic.h>
0021 #include <linux/pinctrl/pinctrl.h>
0022 #include <linux/pinctrl/pinmux.h>
0023 
0024 #include <linux/platform_device.h>
0025 #include <linux/slab.h>
0026 #include <linux/spinlock.h>
0027 
0028 #include "core.h"
0029 #include "pinconf.h"
0030 #include "pinctrl-utils.h"
0031 #include "pinmux.h"
0032 
0033 /* Bit 0:2 and 4:6 should be used for mode selection */
0034 #define THB_GPIO_PINMUX_MODE_0          0x00
0035 #define THB_GPIO_PINMUX_MODE_1          0x11
0036 #define THB_GPIO_PINMUX_MODE_2          0x22
0037 #define THB_GPIO_PINMUX_MODE_3          0x33
0038 #define THB_GPIO_PINMUX_MODE_4          0x44
0039 
0040 #define THB_GPIO_PORT_SELECT_MASK       BIT(8)
0041 #define THB_GPIO_PAD_DIRECTION_MASK     BIT(10)
0042 #define THB_GPIO_SPU_MASK           BIT(11)
0043 #define THB_GPIO_PULL_ENABLE_MASK       BIT(12)
0044 #define THB_GPIO_PULL_UP_MASK           BIT(13)
0045 #define THB_GPIO_PULL_DOWN_MASK         BIT(14)
0046 #define THB_GPIO_ENAQ_MASK          BIT(15)
0047 /* bit 16-19: Drive Strength for the Pad */
0048 #define THB_GPIO_DRIVE_STRENGTH_MASK        (0xF0000)
0049 #define THB_GPIO_SLEW_RATE_MASK         BIT(20)
0050 #define THB_GPIO_SCHMITT_TRIGGER_MASK       BIT(21)
0051 
0052 #define THB_GPIO_REG_OFFSET(pin_num)            ((pin_num) * (0x4))
0053 #define THB_MAX_MODE_SUPPORTED              (5u)
0054 #define THB_MAX_NPINS_SUPPORTED             (67u)
0055 
0056 /* store Pin status */
0057 static u32 thb_pinx_status[THB_MAX_NPINS_SUPPORTED];
0058 
0059 struct thunderbay_mux_desc {
0060     u8 mode;
0061     const char *name;
0062 };
0063 
0064 #define THUNDERBAY_PIN_DESC(pin_number, pin_name, ...) {        \
0065     .number = pin_number,                           \
0066     .name = pin_name,                               \
0067     .drv_data = &(struct thunderbay_mux_desc[]) {   \
0068             __VA_ARGS__, { } },             \
0069 }
0070 
0071 #define THUNDERBAY_MUX(pin_mode, pin_function) {                \
0072     .mode = pin_mode,                               \
0073     .name = pin_function,                           \
0074 }
0075 
0076 struct thunderbay_pin_soc {
0077     const struct pinctrl_pin_desc           *pins;
0078     unsigned int                            npins;
0079 };
0080 
0081 /**
0082  * struct thunderbay_pinctrl - Intel Thunderbay pinctrl structure
0083  * @pctrl: Pointer to the pin controller device
0084  * @base0: First register base address
0085  * @dev: Pointer to the device structure
0086  * @chip: GPIO chip used by this pin controller
0087  * @soc: Pin control configuration data based on SoC
0088  * @ngroups: Number of pin groups available
0089  * @nfuncs: Number of pin functions available
0090  */
0091 struct thunderbay_pinctrl {
0092     struct pinctrl_dev              *pctrl;
0093     void __iomem                    *base0;
0094     struct device                   *dev;
0095     struct gpio_chip                chip;
0096     const struct thunderbay_pin_soc *soc;
0097     unsigned int                    ngroups;
0098     unsigned int                    nfuncs;
0099 };
0100 
0101 static const struct pinctrl_pin_desc thunderbay_pins[] = {
0102     THUNDERBAY_PIN_DESC(0, "GPIO0",
0103                 THUNDERBAY_MUX(0X0, "I2C0_M0"),
0104                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0105                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0106                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0107                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0108     THUNDERBAY_PIN_DESC(1, "GPIO1",
0109                 THUNDERBAY_MUX(0X0, "I2C0_M0"),
0110                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0111                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0112                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0113                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0114     THUNDERBAY_PIN_DESC(2, "GPIO2",
0115                 THUNDERBAY_MUX(0X0, "I2C1_M0"),
0116                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0117                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0118                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0119                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0120     THUNDERBAY_PIN_DESC(3, "GPIO3",
0121                 THUNDERBAY_MUX(0X0, "I2C1_M0"),
0122                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0123                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0124                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0125                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0126     THUNDERBAY_PIN_DESC(4, "GPIO4",
0127                 THUNDERBAY_MUX(0X0, "I2C2_M0"),
0128                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0129                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0130                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0131                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0132     THUNDERBAY_PIN_DESC(5, "GPIO5",
0133                 THUNDERBAY_MUX(0X0, "I2C2_M0"),
0134                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0135                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0136                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0137                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0138     THUNDERBAY_PIN_DESC(6, "GPIO6",
0139                 THUNDERBAY_MUX(0X0, "I2C3_M0"),
0140                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0141                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0142                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0143                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0144     THUNDERBAY_PIN_DESC(7, "GPIO7",
0145                 THUNDERBAY_MUX(0X0, "I2C3_M0"),
0146                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0147                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0148                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0149                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0150     THUNDERBAY_PIN_DESC(8, "GPIO8",
0151                 THUNDERBAY_MUX(0X0, "I2C4_M0"),
0152                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0153                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0154                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0155                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0156     THUNDERBAY_PIN_DESC(9, "GPIO9",
0157                 THUNDERBAY_MUX(0X0, "I2C4_M0"),
0158                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0159                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0160                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0161                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0162     THUNDERBAY_PIN_DESC(10, "GPIO10",
0163                 THUNDERBAY_MUX(0X0, "UART0_M0"),
0164                 THUNDERBAY_MUX(0X1, "RT0_DSU_M1"),
0165                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0166                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0167                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0168     THUNDERBAY_PIN_DESC(11, "GPIO11",
0169                 THUNDERBAY_MUX(0X0, "UART0_M0"),
0170                 THUNDERBAY_MUX(0X1, "RT0_DSU_M1"),
0171                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0172                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0173                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0174     THUNDERBAY_PIN_DESC(12, "GPIO12",
0175                 THUNDERBAY_MUX(0X0, "UART0_M0"),
0176                 THUNDERBAY_MUX(0X1, "RT1_DSU_M1"),
0177                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0178                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0179                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0180     THUNDERBAY_PIN_DESC(13, "GPIO13",
0181                 THUNDERBAY_MUX(0X0, "UART0_M0"),
0182                 THUNDERBAY_MUX(0X1, "RT1_DSU_M1"),
0183                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0184                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0185                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0186     THUNDERBAY_PIN_DESC(14, "GPIO14",
0187                 THUNDERBAY_MUX(0X0, "UART1_M0"),
0188                 THUNDERBAY_MUX(0X1, "RT2_DSU_M1"),
0189                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0190                 THUNDERBAY_MUX(0X3, "TRIGGER_M3"),
0191                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0192     THUNDERBAY_PIN_DESC(15, "GPIO15",
0193                 THUNDERBAY_MUX(0X0, "UART1_M0"),
0194                 THUNDERBAY_MUX(0X1, "RT2_DSU_M1"),
0195                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0196                 THUNDERBAY_MUX(0X3, "TRIGGER_M3"),
0197                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0198     THUNDERBAY_PIN_DESC(16, "GPIO16",
0199                 THUNDERBAY_MUX(0X0, "UART1_M0"),
0200                 THUNDERBAY_MUX(0X1, "RT3_DSU_M1"),
0201                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0202                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0203                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0204     THUNDERBAY_PIN_DESC(17, "GPIO17",
0205                 THUNDERBAY_MUX(0X0, "UART1_M0"),
0206                 THUNDERBAY_MUX(0X1, "RT3_DSU_M1"),
0207                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0208                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0209                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0210     THUNDERBAY_PIN_DESC(18, "GPIO18",
0211                 THUNDERBAY_MUX(0X0, "SPI0_M0"),
0212                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0213                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0214                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0215                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0216     THUNDERBAY_PIN_DESC(19, "GPIO19",
0217                 THUNDERBAY_MUX(0X0, "SPI0_M0"),
0218                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0219                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0220                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0221                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0222     THUNDERBAY_PIN_DESC(20, "GPIO20",
0223                 THUNDERBAY_MUX(0X0, "SPI0_M0"),
0224                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0225                 THUNDERBAY_MUX(0X2, "TPIU_TRACE_M2"),
0226                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0227                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0228     THUNDERBAY_PIN_DESC(21, "GPIO21",
0229                 THUNDERBAY_MUX(0X0, "SPI0_M0"),
0230                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0231                 THUNDERBAY_MUX(0X2, "TPIU_TRACE_M2"),
0232                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0233                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0234     THUNDERBAY_PIN_DESC(22, "GPIO22",
0235                 THUNDERBAY_MUX(0X0, "SPI1_M0"),
0236                 THUNDERBAY_MUX(0X1, "EMPTY_M0"),
0237                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0238                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0239                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0240     THUNDERBAY_PIN_DESC(23, "GPIO23",
0241                 THUNDERBAY_MUX(0X0, "SPI1_M0"),
0242                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0243                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0244                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0245                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0246     THUNDERBAY_PIN_DESC(24, "GPIO24",
0247                 THUNDERBAY_MUX(0X0, "SPI1_M0"),
0248                 THUNDERBAY_MUX(0X1, "TPIU_TRACE_M1"),
0249                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0250                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0251                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0252     THUNDERBAY_PIN_DESC(25, "GPIO25",
0253                 THUNDERBAY_MUX(0X0, "SPI1_M0"),
0254                 THUNDERBAY_MUX(0X1, "TPIU_TRACE_M1"),
0255                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0256                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0257                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0258     THUNDERBAY_PIN_DESC(26, "GPIO26",
0259                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0260                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0261                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0262                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0263                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0264     THUNDERBAY_PIN_DESC(27, "GPIO27",
0265                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0266                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0267                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0268                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0269                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0270     THUNDERBAY_PIN_DESC(28, "GPIO28",
0271                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0272                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0273                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0274                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0275                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0276     THUNDERBAY_PIN_DESC(29, "GPIO29",
0277                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0278                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0279                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0280                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0281                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0282     THUNDERBAY_PIN_DESC(30, "GPIO30",
0283                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0284                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0285                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0286                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0287                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0288     THUNDERBAY_PIN_DESC(31, "GPIO31",
0289                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0290                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0291                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0292                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0293                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0294     THUNDERBAY_PIN_DESC(32, "GPIO32",
0295                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0296                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0297                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0298                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0299                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0300     THUNDERBAY_PIN_DESC(33, "GPIO33",
0301                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0302                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0303                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0304                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0305                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0306     THUNDERBAY_PIN_DESC(34, "GPIO34",
0307                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0308                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0309                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0310                 THUNDERBAY_MUX(0X3, "DIG_VIEW_0"),
0311                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0312     THUNDERBAY_PIN_DESC(35, "GPIO35",
0313                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0314                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0315                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0316                 THUNDERBAY_MUX(0X3, "DIG_VIEW_1"),
0317                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0318     THUNDERBAY_PIN_DESC(36, "GPIO36",
0319                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0320                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0321                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0322                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_0"),
0323                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0324     THUNDERBAY_PIN_DESC(37, "GPIO37",
0325                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0326                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0327                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0328                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_1"),
0329                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0330     THUNDERBAY_PIN_DESC(38, "GPIO38",
0331                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0332                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0333                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0334                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_2"),
0335                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0336     THUNDERBAY_PIN_DESC(39, "GPIO39",
0337                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0338                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0339                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0340                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_3"),
0341                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0342     THUNDERBAY_PIN_DESC(40, "GPIO40",
0343                 THUNDERBAY_MUX(0X0, "ETHER0_M0"),
0344                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0345                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0346                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0347                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0348     THUNDERBAY_PIN_DESC(41, "GPIO41",
0349                 THUNDERBAY_MUX(0X0, "POWER_INTERRUPT_MAX_PLATFORM_POWER_M0"),
0350                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0351                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0352                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0353                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0354     THUNDERBAY_PIN_DESC(42, "GPIO42",
0355                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0356                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0357                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0358                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0359                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0360     THUNDERBAY_PIN_DESC(43, "GPIO43",
0361                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0362                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0363                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0364                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0365                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0366     THUNDERBAY_PIN_DESC(44, "GPIO44",
0367                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0368                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0369                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0370                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0371                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0372     THUNDERBAY_PIN_DESC(45, "GPIO45",
0373                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0374                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0375                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0376                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0377                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0378     THUNDERBAY_PIN_DESC(46, "GPIO46",
0379                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0380                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0381                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0382                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0383                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0384     THUNDERBAY_PIN_DESC(47, "GPIO47",
0385                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0386                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0387                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0388                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0389                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0390     THUNDERBAY_PIN_DESC(48, "GPIO48",
0391                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0392                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0393                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0394                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0395                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0396     THUNDERBAY_PIN_DESC(49, "GPIO49",
0397                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0398                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0399                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0400                 THUNDERBAY_MUX(0X3, "DEBUG_M3"),
0401                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0402     THUNDERBAY_PIN_DESC(50, "GPIO50",
0403                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0404                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0405                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0406                 THUNDERBAY_MUX(0X3, "DIG_VIEW_0"),
0407                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0408     THUNDERBAY_PIN_DESC(51, "GPIO51",
0409                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0410                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0411                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0412                 THUNDERBAY_MUX(0X3, "DIG_VIEW_1"),
0413                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0414     THUNDERBAY_PIN_DESC(52, "GPIO52",
0415                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0416                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0417                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0418                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_0"),
0419                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0420     THUNDERBAY_PIN_DESC(53, "GPIO53",
0421                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0422                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0423                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0424                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_1"),
0425                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0426     THUNDERBAY_PIN_DESC(54, "GPIO54",
0427                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0428                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0429                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0430                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_2"),
0431                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0432     THUNDERBAY_PIN_DESC(55, "GPIO55",
0433                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0434                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0435                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0436                 THUNDERBAY_MUX(0X3, "CPR_IO_OUT_CLK_3"),
0437                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0438     THUNDERBAY_PIN_DESC(56, "GPIO56",
0439                 THUNDERBAY_MUX(0X0, "ETHER1_M0"),
0440                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0441                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0442                 THUNDERBAY_MUX(0X3, "POWER_INTERRUPT_ICCMAX_VDDD_M3"),
0443                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0444     THUNDERBAY_PIN_DESC(57, "GPIO57",
0445                 THUNDERBAY_MUX(0X0, "POWER_INTERRUPT_ICCMAX_VPU_M0"),
0446                 THUNDERBAY_MUX(0X1, "TPIU_DATA_M1"),
0447                 THUNDERBAY_MUX(0X2, "TPIU_DATA_M2"),
0448                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0449                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0450     THUNDERBAY_PIN_DESC(58, "GPIO58",
0451                 THUNDERBAY_MUX(0X0, "THERMTRIP_M0"),
0452                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0453                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0454                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0455                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0456     THUNDERBAY_PIN_DESC(59, "GPIO59",
0457                 THUNDERBAY_MUX(0X0, "THERMTRIP_M0"),
0458                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0459                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0460                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0461                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0462     THUNDERBAY_PIN_DESC(60, "GPIO60",
0463                 THUNDERBAY_MUX(0X0, "SMBUS_M0"),
0464                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0465                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0466                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0467                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0468     THUNDERBAY_PIN_DESC(61, "GPIO61",
0469                 THUNDERBAY_MUX(0X0, "SMBUS_M0"),
0470                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0471                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0472                 THUNDERBAY_MUX(0X3, "POWER_INTERRUPT_ICCMAX_VDDD_M3"),
0473                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0474     THUNDERBAY_PIN_DESC(62, "GPIO62",
0475                 THUNDERBAY_MUX(0X0, "PLATFORM_RESET_M0"),
0476                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0477                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0478                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0479                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0480     THUNDERBAY_PIN_DESC(63, "GPIO63",
0481                 THUNDERBAY_MUX(0X0, "PLATFORM_RESET_M0"),
0482                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0483                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0484                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0485                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0486     THUNDERBAY_PIN_DESC(64, "GPIO64",
0487                 THUNDERBAY_MUX(0X0, "PLATFORM_SHUTDOWN_M0"),
0488                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0489                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0490                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0491                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0492     THUNDERBAY_PIN_DESC(65, "GPIO65",
0493                 THUNDERBAY_MUX(0X0, "PLATFORM_SHUTDOWN_M0"),
0494                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0495                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0496                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0497                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0498     THUNDERBAY_PIN_DESC(66, "GPIO66",
0499                 THUNDERBAY_MUX(0X0, "POWER_INTERRUPT_ICCMAX_MEDIA_M0"),
0500                 THUNDERBAY_MUX(0X1, "EMPTY_M1"),
0501                 THUNDERBAY_MUX(0X2, "EMPTY_M2"),
0502                 THUNDERBAY_MUX(0X3, "EMPTY_M3"),
0503                 THUNDERBAY_MUX(0X4, "GPIO_M4")),
0504 };
0505 
0506 static const struct thunderbay_pin_soc thunderbay_data = {
0507     .pins   = thunderbay_pins,
0508     .npins  = ARRAY_SIZE(thunderbay_pins),
0509 };
0510 
0511 static u32 thb_gpio_read_reg(struct gpio_chip *chip, unsigned int pinnr)
0512 {
0513     struct thunderbay_pinctrl *tpc = gpiochip_get_data(chip);
0514 
0515     return readl(tpc->base0 + THB_GPIO_REG_OFFSET(pinnr));
0516 }
0517 
0518 static u32 thb_gpio_write_reg(struct gpio_chip *chip, unsigned int pinnr, u32 value)
0519 {
0520     struct thunderbay_pinctrl *tpc = gpiochip_get_data(chip);
0521 
0522     writel(value, (tpc->base0 + THB_GPIO_REG_OFFSET(pinnr)));
0523     return 0;
0524 }
0525 
0526 static int thb_read_gpio_data(struct gpio_chip *chip, unsigned int offset, unsigned int pad_dir)
0527 {
0528     int data_offset;
0529     u32 data_reg;
0530 
0531     /* as per GPIO Spec = pad_dir 0:input, 1:output */
0532     data_offset = 0x2000u + (offset / 32);
0533     if (!pad_dir)
0534         data_offset += 4;
0535     data_reg = thb_gpio_read_reg(chip, data_offset);
0536 
0537     return data_reg & BIT(offset % 32);
0538 }
0539 
0540 static int thb_write_gpio_data(struct gpio_chip *chip, unsigned int offset, unsigned int value)
0541 {
0542     int data_offset;
0543     u32 data_reg;
0544 
0545     data_offset = 0x2000u + (offset / 32);
0546 
0547     data_reg = thb_gpio_read_reg(chip, data_offset);
0548 
0549     if (value > 0)
0550         data_reg |= BIT(offset % 32);
0551     else
0552         data_reg &= ~BIT(offset % 32);
0553 
0554     return thb_gpio_write_reg(chip, data_offset, data_reg);
0555 }
0556 
0557 static int thunderbay_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
0558 {
0559     u32 reg = thb_gpio_read_reg(chip, offset);
0560 
0561     /* Return direction only if configured as GPIO else negative error */
0562     if (reg & THB_GPIO_PORT_SELECT_MASK)
0563         return !(reg & THB_GPIO_PAD_DIRECTION_MASK);
0564     return -EINVAL;
0565 }
0566 
0567 static int thunderbay_gpio_set_direction_input(struct gpio_chip *chip, unsigned int offset)
0568 {
0569     u32 reg = thb_gpio_read_reg(chip, offset);
0570 
0571     /* set pin as input only if it is GPIO else error */
0572     if (reg & THB_GPIO_PORT_SELECT_MASK) {
0573         reg &= (~THB_GPIO_PAD_DIRECTION_MASK);
0574         thb_gpio_write_reg(chip, offset, reg);
0575         return 0;
0576     }
0577     return -EINVAL;
0578 }
0579 
0580 static void thunderbay_gpio_set_value(struct gpio_chip *chip, unsigned int offset, int value)
0581 {
0582     u32 reg = thb_gpio_read_reg(chip, offset);
0583 
0584     /* update pin value only if it is GPIO-output else error */
0585     if ((reg & THB_GPIO_PORT_SELECT_MASK) && (reg & THB_GPIO_PAD_DIRECTION_MASK))
0586         thb_write_gpio_data(chip, offset, value);
0587 }
0588 
0589 static int thunderbay_gpio_set_direction_output(struct gpio_chip *chip,
0590                         unsigned int offset, int value)
0591 {
0592     u32 reg = thb_gpio_read_reg(chip, offset);
0593 
0594     /* set pin as output only if it is GPIO else error */
0595     if (reg & THB_GPIO_PORT_SELECT_MASK) {
0596         reg |= THB_GPIO_PAD_DIRECTION_MASK;
0597         thb_gpio_write_reg(chip, offset, reg);
0598         thunderbay_gpio_set_value(chip, offset, value);
0599         return 0;
0600     }
0601     return -EINVAL;
0602 }
0603 
0604 static int thunderbay_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
0605 {
0606     u32 reg = thb_gpio_read_reg(chip, offset);
0607     int gpio_dir = 0;
0608 
0609     /* Read pin value only if it is GPIO else error */
0610     if (reg & THB_GPIO_PORT_SELECT_MASK) {
0611         /* 0=in, 1=out */
0612         gpio_dir = (reg & THB_GPIO_PAD_DIRECTION_MASK) > 0;
0613 
0614         /* Returns negative value when pin is configured as PORT */
0615         return thb_read_gpio_data(chip, offset, gpio_dir);
0616     }
0617     return -EINVAL;
0618 }
0619 
0620 static int thunderbay_gpiochip_probe(struct thunderbay_pinctrl *tpc)
0621 {
0622     struct gpio_chip *chip = &tpc->chip;
0623     int ret;
0624 
0625     chip->label     = dev_name(tpc->dev);
0626     chip->parent        = tpc->dev;
0627     chip->request       = gpiochip_generic_request;
0628     chip->free      = gpiochip_generic_free;
0629     chip->get_direction = thunderbay_gpio_get_direction;
0630     chip->direction_input   = thunderbay_gpio_set_direction_input;
0631     chip->direction_output  = thunderbay_gpio_set_direction_output;
0632     chip->get       = thunderbay_gpio_get_value;
0633     chip->set               = thunderbay_gpio_set_value;
0634     chip->set_config    = gpiochip_generic_config;
0635     /* identifies the first GPIO number handled by this chip; or,
0636      * if negative during registration, requests dynamic ID allocation.
0637      * Please pass -1 as base to let gpiolib select the chip base in all possible cases.
0638      * We want to get rid of the static GPIO number space in the long run.
0639      */
0640     chip->base      = -1;
0641     /* Number of GPIOs handled by this controller; the last GPIO handled is (base + ngpio - 1)*/
0642     chip->ngpio     = THB_MAX_NPINS_SUPPORTED;
0643 
0644     /* Register/add Thunder Bay GPIO chip with Linux framework */
0645     ret = gpiochip_add_data(chip, tpc);
0646     if (ret)
0647         dev_err(tpc->dev, "Failed to add gpiochip\n");
0648     return ret;
0649 }
0650 
0651 static int thunderbay_request_gpio(struct pinctrl_dev *pctldev,
0652                    struct pinctrl_gpio_range *range,
0653                    unsigned int pin)
0654 {
0655     struct thunderbay_pinctrl *tpc = pinctrl_dev_get_drvdata(pctldev);
0656     struct gpio_chip *chip = &tpc->chip;
0657     u32 reg = 0;
0658 
0659     if (thb_pinx_status[pin] == 0u) {
0660         reg = thb_gpio_read_reg(chip, pin);
0661         /* Updates PIN configuration as GPIO and sets GPIO to MODE-4*/
0662         reg |= (THB_GPIO_PORT_SELECT_MASK | THB_GPIO_PINMUX_MODE_4);
0663         thb_gpio_write_reg(chip, pin, reg);
0664 
0665         /* update pin status as busy */
0666         thb_pinx_status[pin] = 1u;
0667 
0668         return 0;
0669     }
0670     return -EINVAL;
0671 }
0672 
0673 static void thunderbay_free_gpio(struct pinctrl_dev *pctldev,
0674                  struct pinctrl_gpio_range *range,
0675                  unsigned int pin)
0676 {
0677     struct thunderbay_pinctrl *tpc = pinctrl_dev_get_drvdata(pctldev);
0678     struct gpio_chip *chip = &tpc->chip;
0679     u32 reg = 0;
0680 
0681     if (thb_pinx_status[pin] == 1u) {
0682         reg = thb_gpio_read_reg(chip, pin);
0683 
0684         /* Updates PIN configuration from GPIO to PORT */
0685         reg &= (~THB_GPIO_PORT_SELECT_MASK);
0686 
0687         /* Change Port/gpio mode to default mode-0 */
0688         reg &= (~THB_GPIO_PINMUX_MODE_4);
0689 
0690         thb_gpio_write_reg(chip, pin, reg);
0691 
0692         /* update pin status as free */
0693         thb_pinx_status[pin] = 0u;
0694     }
0695 }
0696 
0697 static int thb_pinctrl_set_mux(struct pinctrl_dev *pctldev,
0698                    unsigned int func_select, unsigned int group_select)
0699 {
0700     struct thunderbay_pinctrl *tpc = pinctrl_dev_get_drvdata(pctldev);
0701     struct gpio_chip *chip = &tpc->chip;
0702     struct function_desc *function;
0703     unsigned int i, pin_mode;
0704     struct group_desc *group;
0705     int ret = -EINVAL;
0706     u32 reg = 0u;
0707 
0708     group = pinctrl_generic_get_group(pctldev, group_select);
0709     if (!group)
0710         return -EINVAL;
0711 
0712     function = pinmux_generic_get_function(pctldev, func_select);
0713     if (!function)
0714         return -EINVAL;
0715 
0716     pin_mode = *(unsigned int *)(function->data);
0717 
0718     /* Change modes for pins in the selected group */
0719     for (i = 0; i < group->num_pins; i++) {
0720         reg = thb_gpio_read_reg(chip, group->pins[i]);
0721 
0722         switch (pin_mode) {
0723         case 0u:
0724             reg |= THB_GPIO_PINMUX_MODE_0;
0725             break;
0726         case 1u:
0727             reg |= THB_GPIO_PINMUX_MODE_1;
0728             break;
0729         case 2u:
0730             reg |= THB_GPIO_PINMUX_MODE_2;
0731             break;
0732         case 3u:
0733             reg |= THB_GPIO_PINMUX_MODE_3;
0734             break;
0735         case 4u:
0736             reg |= THB_GPIO_PINMUX_MODE_4;
0737             break;
0738         default:
0739             return -EINVAL;
0740         }
0741 
0742         ret = thb_gpio_write_reg(chip, group->pins[i], reg);
0743         if (~ret) {
0744             /* update pin status as busy */
0745             thb_pinx_status[group->pins[i]] = 1u;
0746         }
0747     }
0748     return ret;
0749 }
0750 
0751 static int thunderbay_build_groups(struct thunderbay_pinctrl *tpc)
0752 {
0753     struct group_desc *thunderbay_groups;
0754     int i;
0755 
0756     tpc->ngroups = tpc->soc->npins;
0757     thunderbay_groups = devm_kcalloc(tpc->dev, tpc->ngroups,
0758                      sizeof(*thunderbay_groups), GFP_KERNEL);
0759     if (!thunderbay_groups)
0760         return -ENOMEM;
0761 
0762     for (i = 0; i < tpc->ngroups; i++) {
0763         struct group_desc *group = thunderbay_groups + i;
0764         const struct pinctrl_pin_desc *pin_info = thunderbay_pins + i;
0765 
0766         group->name = pin_info->name;
0767         group->pins = (int *)&pin_info->number;
0768         pinctrl_generic_add_group(tpc->pctrl, group->name,
0769                       group->pins, 1, NULL);
0770     }
0771     return 0;
0772 }
0773 
0774 static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct function_desc *funcs)
0775 {
0776     int i;
0777 
0778     /* Assign the groups for each function */
0779     for (i = 0; i < tpc->nfuncs; i++) {
0780         struct function_desc *func = &funcs[i];
0781         const char **group_names;
0782         unsigned int grp_idx = 0;
0783         int j;
0784 
0785         group_names = devm_kcalloc(tpc->dev, func->num_group_names,
0786                        sizeof(*group_names), GFP_KERNEL);
0787         if (!group_names)
0788             return -ENOMEM;
0789 
0790         for (j = 0; j < tpc->soc->npins; j++) {
0791             const struct pinctrl_pin_desc *pin_info = &thunderbay_pins[j];
0792             struct thunderbay_mux_desc *pin_mux;
0793 
0794             for (pin_mux = pin_info->drv_data; pin_mux->name; pin_mux++) {
0795                 if (!strcmp(pin_mux->name, func->name))
0796                     group_names[grp_idx++] = pin_info->name;
0797             }
0798         }
0799 
0800         func->group_names = group_names;
0801     }
0802 
0803     /* Add all functions */
0804     for (i = 0; i < tpc->nfuncs; i++) {
0805         pinmux_generic_add_function(tpc->pctrl,
0806                         funcs[i].name,
0807                         funcs[i].group_names,
0808                         funcs[i].num_group_names,
0809                         funcs[i].data);
0810     }
0811     kfree(funcs);
0812     return 0;
0813 }
0814 
0815 static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
0816 {
0817     struct function_desc *thunderbay_funcs;
0818     void *ptr;
0819     int pin;
0820 
0821     /*
0822      * Allocate maximum possible number of functions. Assume every pin
0823      * being part of 8 (hw maximum) globally unique muxes.
0824      */
0825     tpc->nfuncs = 0;
0826     thunderbay_funcs = kcalloc(tpc->soc->npins * 8,
0827                    sizeof(*thunderbay_funcs), GFP_KERNEL);
0828     if (!thunderbay_funcs)
0829         return -ENOMEM;
0830 
0831     /* Setup 1 function for each unique mux */
0832     for (pin = 0; pin < tpc->soc->npins; pin++) {
0833         const struct pinctrl_pin_desc *pin_info = thunderbay_pins + pin;
0834         struct thunderbay_mux_desc *pin_mux;
0835 
0836         for (pin_mux = pin_info->drv_data; pin_mux->name; pin_mux++) {
0837             struct function_desc *func;
0838 
0839             /* Check if we already have function for this mux */
0840             for (func = thunderbay_funcs; func->name; func++) {
0841                 if (!strcmp(pin_mux->name, func->name)) {
0842                     func->num_group_names++;
0843                     break;
0844                 }
0845             }
0846 
0847             if (!func->name) {
0848                 func->name = pin_mux->name;
0849                 func->num_group_names = 1;
0850                 func->data = (int *)&pin_mux->mode;
0851                 tpc->nfuncs++;
0852             }
0853         }
0854     }
0855 
0856     /* Reallocate memory based on actual number of functions */
0857     ptr = krealloc(thunderbay_funcs,
0858                tpc->nfuncs * sizeof(*thunderbay_funcs), GFP_KERNEL);
0859     if (!ptr)
0860         return -ENOMEM;
0861 
0862     thunderbay_funcs = ptr;
0863     return thunderbay_add_functions(tpc, thunderbay_funcs);
0864 }
0865 
0866 static int thunderbay_pinconf_set_tristate(struct thunderbay_pinctrl *tpc,
0867                        unsigned int pin, u32 config)
0868 {
0869     struct gpio_chip *chip = &tpc->chip;
0870     u32 reg;
0871 
0872     reg = thb_gpio_read_reg(chip, pin);
0873     if (config > 0)
0874         reg |= THB_GPIO_ENAQ_MASK;
0875     else
0876         reg &= ~THB_GPIO_ENAQ_MASK;
0877 
0878     return thb_gpio_write_reg(chip, pin, reg);
0879 }
0880 
0881 static int thunderbay_pinconf_get_tristate(struct thunderbay_pinctrl *tpc,
0882                        unsigned int pin, u32 *config)
0883 {
0884     struct gpio_chip *chip = &tpc->chip;
0885     u32 reg;
0886 
0887     reg = thb_gpio_read_reg(chip, pin);
0888     *config = (reg & THB_GPIO_ENAQ_MASK) > 0;
0889 
0890     return 0;
0891 }
0892 
0893 static int thunderbay_pinconf_set_pulldown(struct thunderbay_pinctrl *tpc,
0894                        unsigned int pin, u32 config)
0895 {
0896     struct gpio_chip *chip = &tpc->chip;
0897     u32 reg;
0898 
0899     reg = thb_gpio_read_reg(chip, pin);
0900     if (config > 0)
0901         reg |= THB_GPIO_PULL_DOWN_MASK;
0902     else
0903         reg &= ~THB_GPIO_PULL_DOWN_MASK;
0904 
0905     return thb_gpio_write_reg(chip, pin, reg);
0906 }
0907 
0908 static int thunderbay_pinconf_get_pulldown(struct thunderbay_pinctrl *tpc,
0909                        unsigned int pin, u32 *config)
0910 {
0911     struct gpio_chip *chip = &tpc->chip;
0912     u32 reg = 0;
0913 
0914     reg = thb_gpio_read_reg(chip, pin);
0915     *config = ((reg & THB_GPIO_PULL_DOWN_MASK) > 0) ? 1 : 0;
0916 
0917     return 0;
0918 }
0919 
0920 static int thunderbay_pinconf_set_pullup(struct thunderbay_pinctrl *tpc,
0921                      unsigned int pin, u32 config)
0922 {
0923     struct gpio_chip *chip = &tpc->chip;
0924     u32 reg;
0925 
0926     reg = thb_gpio_read_reg(chip, pin);
0927     if (config > 0)
0928         reg &= ~THB_GPIO_PULL_UP_MASK;
0929     else
0930         reg |= THB_GPIO_PULL_UP_MASK;
0931 
0932     return thb_gpio_write_reg(chip, pin, reg);
0933 }
0934 
0935 static int thunderbay_pinconf_get_pullup(struct thunderbay_pinctrl *tpc,
0936                      unsigned int pin, u32 *config)
0937 {
0938     struct gpio_chip *chip = &tpc->chip;
0939     u32 reg;
0940 
0941     reg = thb_gpio_read_reg(chip, pin);
0942     *config = ((reg & THB_GPIO_PULL_UP_MASK) == 0) ? 1 : 0;
0943 
0944     return 0;
0945 }
0946 
0947 static int thunderbay_pinconf_set_opendrain(struct thunderbay_pinctrl *tpc,
0948                         unsigned int pin, u32 config)
0949 {
0950     struct gpio_chip *chip = &tpc->chip;
0951     u32 reg;
0952 
0953     reg = thb_gpio_read_reg(chip, pin);
0954     if (config > 0)
0955         reg &= ~THB_GPIO_PULL_ENABLE_MASK;
0956     else
0957         reg |= THB_GPIO_PULL_ENABLE_MASK;
0958 
0959     return thb_gpio_write_reg(chip, pin, reg);
0960 }
0961 
0962 static int thunderbay_pinconf_get_opendrain(struct thunderbay_pinctrl *tpc,
0963                         unsigned int pin, u32 *config)
0964 {
0965     struct gpio_chip *chip = &tpc->chip;
0966     u32 reg;
0967 
0968     reg = thb_gpio_read_reg(chip, pin);
0969     *config = ((reg & THB_GPIO_PULL_ENABLE_MASK) == 0) ? 1 : 0;
0970 
0971     return 0;
0972 }
0973 
0974 static int thunderbay_pinconf_set_pushpull(struct thunderbay_pinctrl *tpc,
0975                        unsigned int pin, u32 config)
0976 {
0977     struct gpio_chip *chip = &tpc->chip;
0978     u32 reg;
0979 
0980     reg = thb_gpio_read_reg(chip, pin);
0981     if (config > 0)
0982         reg |= THB_GPIO_PULL_ENABLE_MASK;
0983     else
0984         reg &= ~THB_GPIO_PULL_ENABLE_MASK;
0985 
0986     return thb_gpio_write_reg(chip, pin, reg);
0987 }
0988 
0989 static int thunderbay_pinconf_get_pushpull(struct thunderbay_pinctrl *tpc,
0990                        unsigned int pin, u32 *config)
0991 {
0992     struct gpio_chip *chip = &tpc->chip;
0993     u32 reg;
0994 
0995     reg = thb_gpio_read_reg(chip, pin);
0996     *config = ((reg & THB_GPIO_PULL_ENABLE_MASK) > 0) ? 1 : 0;
0997 
0998     return 0;
0999 }
1000 
1001 static int thunderbay_pinconf_set_drivestrength(struct thunderbay_pinctrl *tpc,
1002                         unsigned int pin, u32 config)
1003 {
1004     struct gpio_chip *chip = &tpc->chip;
1005     u32 reg;
1006 
1007     reg = thb_gpio_read_reg(chip, pin);
1008 
1009     /* Drive Strength: 0x0 to 0xF */
1010     if (config <= 0xF) {
1011         reg = (reg | config);
1012         return thb_gpio_write_reg(chip, pin, reg);
1013     }
1014 
1015     return -EINVAL;
1016 }
1017 
1018 static int thunderbay_pinconf_get_drivestrength(struct thunderbay_pinctrl *tpc,
1019                         unsigned int pin, u32 *config)
1020 {
1021     struct gpio_chip *chip = &tpc->chip;
1022     u32 reg;
1023 
1024     reg = thb_gpio_read_reg(chip, pin);
1025     reg = (reg & THB_GPIO_DRIVE_STRENGTH_MASK) >> 16;
1026     *config = (reg > 0) ? reg : 0;
1027 
1028     return 0;
1029 }
1030 
1031 static int thunderbay_pinconf_set_schmitt(struct thunderbay_pinctrl *tpc,
1032                       unsigned int pin, u32 config)
1033 {
1034     struct gpio_chip *chip = &tpc->chip;
1035     u32 reg;
1036 
1037     reg = thb_gpio_read_reg(chip, pin);
1038     if (config > 0)
1039         reg |= THB_GPIO_SCHMITT_TRIGGER_MASK;
1040     else
1041         reg &= ~THB_GPIO_SCHMITT_TRIGGER_MASK;
1042 
1043     return thb_gpio_write_reg(chip, pin, reg);
1044 }
1045 
1046 static int thunderbay_pinconf_get_schmitt(struct thunderbay_pinctrl *tpc,
1047                       unsigned int pin, u32 *config)
1048 {
1049     struct gpio_chip *chip = &tpc->chip;
1050     u32 reg;
1051 
1052     reg = thb_gpio_read_reg(chip, pin);
1053     *config = ((reg & THB_GPIO_SCHMITT_TRIGGER_MASK) > 0) ? 1 : 0;
1054 
1055     return 0;
1056 }
1057 
1058 static int thunderbay_pinconf_set_slew_rate(struct thunderbay_pinctrl *tpc,
1059                         unsigned int pin, u32 config)
1060 {
1061     struct gpio_chip *chip = &tpc->chip;
1062     u32 reg = 0;
1063 
1064     reg = thb_gpio_read_reg(chip, pin);
1065     if (config > 0)
1066         reg |= THB_GPIO_SLEW_RATE_MASK;
1067     else
1068         reg &= ~THB_GPIO_SLEW_RATE_MASK;
1069 
1070     return thb_gpio_write_reg(chip, pin, reg);
1071 }
1072 
1073 static int thunderbay_pinconf_get_slew_rate(struct thunderbay_pinctrl *tpc,
1074                         unsigned int pin, u32 *config)
1075 {
1076     struct gpio_chip *chip = &tpc->chip;
1077     u32 reg;
1078 
1079     reg = thb_gpio_read_reg(chip, pin);
1080     *config = ((reg & THB_GPIO_SLEW_RATE_MASK) > 0) ? 1 : 0;
1081 
1082     return 0;
1083 }
1084 
1085 static int thunderbay_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
1086                   unsigned long *config)
1087 {
1088     struct thunderbay_pinctrl *tpc = pinctrl_dev_get_drvdata(pctldev);
1089     enum pin_config_param param = pinconf_to_config_param(*config);
1090     u32 arg;
1091     int ret;
1092 
1093     switch (param) {
1094     case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
1095         ret = thunderbay_pinconf_get_tristate(tpc, pin, &arg);
1096         break;
1097 
1098     case PIN_CONFIG_BIAS_PULL_DOWN:
1099         ret = thunderbay_pinconf_get_pulldown(tpc, pin, &arg);
1100         break;
1101 
1102     case PIN_CONFIG_BIAS_PULL_UP:
1103         ret = thunderbay_pinconf_get_pullup(tpc, pin, &arg);
1104         break;
1105 
1106     case PIN_CONFIG_DRIVE_OPEN_DRAIN:
1107         ret = thunderbay_pinconf_get_opendrain(tpc, pin, &arg);
1108         break;
1109 
1110     case PIN_CONFIG_DRIVE_PUSH_PULL:
1111         ret = thunderbay_pinconf_get_pushpull(tpc, pin, &arg);
1112         break;
1113 
1114     case PIN_CONFIG_DRIVE_STRENGTH:
1115         ret = thunderbay_pinconf_get_drivestrength(tpc, pin, &arg);
1116         break;
1117 
1118     case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
1119         ret = thunderbay_pinconf_get_schmitt(tpc, pin, &arg);
1120         break;
1121 
1122     case PIN_CONFIG_SLEW_RATE:
1123         ret = thunderbay_pinconf_get_slew_rate(tpc, pin, &arg);
1124         break;
1125 
1126     default:
1127         return -ENOTSUPP;
1128     }
1129 
1130     *config = pinconf_to_config_packed(param, arg);
1131 
1132     return ret;
1133 }
1134 
1135 static int thunderbay_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
1136                   unsigned long *configs, unsigned int num_configs)
1137 {
1138     struct thunderbay_pinctrl *tpc = pinctrl_dev_get_drvdata(pctldev);
1139     enum pin_config_param param;
1140     unsigned int pinconf;
1141     int ret = 0;
1142     u32 arg;
1143 
1144     for (pinconf = 0; pinconf < num_configs; pinconf++) {
1145         param = pinconf_to_config_param(configs[pinconf]);
1146         arg = pinconf_to_config_argument(configs[pinconf]);
1147 
1148         switch (param) {
1149         case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
1150             ret = thunderbay_pinconf_set_tristate(tpc, pin, arg);
1151             break;
1152 
1153         case PIN_CONFIG_BIAS_PULL_DOWN:
1154             ret = thunderbay_pinconf_set_pulldown(tpc, pin, arg);
1155             break;
1156 
1157         case PIN_CONFIG_BIAS_PULL_UP:
1158             ret = thunderbay_pinconf_set_pullup(tpc, pin, arg);
1159             break;
1160 
1161         case PIN_CONFIG_DRIVE_OPEN_DRAIN:
1162             ret = thunderbay_pinconf_set_opendrain(tpc, pin, arg);
1163             break;
1164 
1165         case PIN_CONFIG_DRIVE_PUSH_PULL:
1166             ret = thunderbay_pinconf_set_pushpull(tpc, pin, arg);
1167             break;
1168 
1169         case PIN_CONFIG_DRIVE_STRENGTH:
1170             ret = thunderbay_pinconf_set_drivestrength(tpc, pin, arg);
1171             break;
1172 
1173         case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
1174             ret = thunderbay_pinconf_set_schmitt(tpc, pin, arg);
1175             break;
1176 
1177         case PIN_CONFIG_SLEW_RATE:
1178             ret = thunderbay_pinconf_set_slew_rate(tpc, pin, arg);
1179             break;
1180 
1181         default:
1182             return -ENOTSUPP;
1183         }
1184     }
1185     return ret;
1186 }
1187 
1188 static const struct pinctrl_ops thunderbay_pctlops = {
1189     .get_groups_count = pinctrl_generic_get_group_count,
1190     .get_group_name   = pinctrl_generic_get_group_name,
1191     .get_group_pins   = pinctrl_generic_get_group_pins,
1192     .dt_node_to_map   = pinconf_generic_dt_node_to_map_all,
1193     .dt_free_map      = pinconf_generic_dt_free_map,
1194 };
1195 
1196 static const struct pinmux_ops thunderbay_pmxops = {
1197     .get_functions_count    = pinmux_generic_get_function_count,
1198     .get_function_name  = pinmux_generic_get_function_name,
1199     .get_function_groups    = pinmux_generic_get_function_groups,
1200     .set_mux        = thb_pinctrl_set_mux,
1201     .gpio_request_enable    = thunderbay_request_gpio,
1202     .gpio_disable_free  = thunderbay_free_gpio,
1203 };
1204 
1205 static const struct pinconf_ops thunderbay_confops = {
1206     .is_generic     = true,
1207     .pin_config_get     = thunderbay_pinconf_get,
1208     .pin_config_set     = thunderbay_pinconf_set,
1209 };
1210 
1211 static struct pinctrl_desc thunderbay_pinctrl_desc = {
1212     .name       = "thunderbay-pinmux",
1213     .pctlops    = &thunderbay_pctlops,
1214     .pmxops     = &thunderbay_pmxops,
1215     .confops    = &thunderbay_confops,
1216     .owner      = THIS_MODULE,
1217 };
1218 
1219 static const struct of_device_id thunderbay_pinctrl_match[] = {
1220     {
1221         .compatible = "intel,thunderbay-pinctrl",
1222         .data = &thunderbay_data
1223     },
1224     {}
1225 };
1226 
1227 static int thunderbay_pinctrl_probe(struct platform_device *pdev)
1228 {
1229     const struct of_device_id *of_id;
1230     struct device *dev = &pdev->dev;
1231     struct thunderbay_pinctrl *tpc;
1232     int ret;
1233 
1234     of_id = of_match_node(thunderbay_pinctrl_match, pdev->dev.of_node);
1235     if (!of_id)
1236         return -ENODEV;
1237 
1238     tpc = devm_kzalloc(dev, sizeof(*tpc), GFP_KERNEL);
1239     if (!tpc)
1240         return -ENOMEM;
1241 
1242     tpc->dev = dev;
1243     tpc->soc = of_id->data;
1244 
1245     tpc->base0 = devm_platform_ioremap_resource(pdev, 0);
1246     if (IS_ERR(tpc->base0))
1247         return PTR_ERR(tpc->base0);
1248 
1249     thunderbay_pinctrl_desc.pins = tpc->soc->pins;
1250     thunderbay_pinctrl_desc.npins = tpc->soc->npins;
1251 
1252     /* Register pinctrl */
1253     tpc->pctrl = devm_pinctrl_register(dev, &thunderbay_pinctrl_desc, tpc);
1254     if (IS_ERR(tpc->pctrl))
1255         return PTR_ERR(tpc->pctrl);
1256 
1257     /* Setup pinmux groups */
1258     ret = thunderbay_build_groups(tpc);
1259     if (ret)
1260         return ret;
1261 
1262     /* Setup pinmux functions */
1263     ret = thunderbay_build_functions(tpc);
1264     if (ret)
1265         return ret;
1266 
1267     /* Setup GPIO */
1268     ret = thunderbay_gpiochip_probe(tpc);
1269     if (ret < 0)
1270         return ret;
1271 
1272     platform_set_drvdata(pdev, tpc);
1273 
1274     return 0;
1275 }
1276 
1277 static int thunderbay_pinctrl_remove(struct platform_device *pdev)
1278 {
1279     /* thunderbay_pinctrl_remove function to clear the assigned memory */
1280     return 0;
1281 }
1282 
1283 static struct platform_driver thunderbay_pinctrl_driver = {
1284     .driver = {
1285         .name = "thunderbay-pinctrl",
1286         .of_match_table = thunderbay_pinctrl_match,
1287     },
1288     .probe = thunderbay_pinctrl_probe,
1289     .remove = thunderbay_pinctrl_remove,
1290 };
1291 
1292 builtin_platform_driver(thunderbay_pinctrl_driver);
1293 
1294 MODULE_AUTHOR("Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>");
1295 MODULE_AUTHOR("Kiran Kumar S <kiran.kumar1.s@intel.com>");
1296 MODULE_DESCRIPTION("Intel Thunder Bay Pinctrl/GPIO Driver");
1297 MODULE_LICENSE("GPL v2");