cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pinctrl-tb10x.c (26830B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Abilis Systems TB10x pin control driver
      4 *
      5 * Copyright (C) Abilis Systems 2012
      6 *
      7 * Author: Christian Ruppert <christian.ruppert@abilis.com>
      8 */
      9
     10#include <linux/stringify.h>
     11#include <linux/pinctrl/pinctrl.h>
     12#include <linux/pinctrl/pinmux.h>
     13#include <linux/pinctrl/machine.h>
     14#include <linux/platform_device.h>
     15#include <linux/module.h>
     16#include <linux/mutex.h>
     17#include <linux/err.h>
     18#include <linux/io.h>
     19#include <linux/of.h>
     20#include <linux/slab.h>
     21
     22#include "pinctrl-utils.h"
     23
     24#define TB10X_PORT1 (0)
     25#define TB10X_PORT2 (16)
     26#define TB10X_PORT3 (32)
     27#define TB10X_PORT4 (48)
     28#define TB10X_PORT5 (128)
     29#define TB10X_PORT6 (64)
     30#define TB10X_PORT7 (80)
     31#define TB10X_PORT8 (96)
     32#define TB10X_PORT9 (112)
     33#define TB10X_GPIOS (256)
     34
     35#define PCFG_PORT_BITWIDTH (2)
     36#define PCFG_PORT_MASK(PORT) \
     37	(((1 << PCFG_PORT_BITWIDTH) - 1) << (PCFG_PORT_BITWIDTH * (PORT)))
     38
     39static const struct pinctrl_pin_desc tb10x_pins[] = {
     40	/* Port 1 */
     41	PINCTRL_PIN(TB10X_PORT1 +  0, "MICLK_S0"),
     42	PINCTRL_PIN(TB10X_PORT1 +  1, "MISTRT_S0"),
     43	PINCTRL_PIN(TB10X_PORT1 +  2, "MIVAL_S0"),
     44	PINCTRL_PIN(TB10X_PORT1 +  3, "MDI_S0"),
     45	PINCTRL_PIN(TB10X_PORT1 +  4, "GPIOA0"),
     46	PINCTRL_PIN(TB10X_PORT1 +  5, "GPIOA1"),
     47	PINCTRL_PIN(TB10X_PORT1 +  6, "GPIOA2"),
     48	PINCTRL_PIN(TB10X_PORT1 +  7, "MDI_S1"),
     49	PINCTRL_PIN(TB10X_PORT1 +  8, "MIVAL_S1"),
     50	PINCTRL_PIN(TB10X_PORT1 +  9, "MISTRT_S1"),
     51	PINCTRL_PIN(TB10X_PORT1 + 10, "MICLK_S1"),
     52	/* Port 2 */
     53	PINCTRL_PIN(TB10X_PORT2 +  0, "MICLK_S2"),
     54	PINCTRL_PIN(TB10X_PORT2 +  1, "MISTRT_S2"),
     55	PINCTRL_PIN(TB10X_PORT2 +  2, "MIVAL_S2"),
     56	PINCTRL_PIN(TB10X_PORT2 +  3, "MDI_S2"),
     57	PINCTRL_PIN(TB10X_PORT2 +  4, "GPIOC0"),
     58	PINCTRL_PIN(TB10X_PORT2 +  5, "GPIOC1"),
     59	PINCTRL_PIN(TB10X_PORT2 +  6, "GPIOC2"),
     60	PINCTRL_PIN(TB10X_PORT2 +  7, "MDI_S3"),
     61	PINCTRL_PIN(TB10X_PORT2 +  8, "MIVAL_S3"),
     62	PINCTRL_PIN(TB10X_PORT2 +  9, "MISTRT_S3"),
     63	PINCTRL_PIN(TB10X_PORT2 + 10, "MICLK_S3"),
     64	/* Port 3 */
     65	PINCTRL_PIN(TB10X_PORT3 +  0, "MICLK_S4"),
     66	PINCTRL_PIN(TB10X_PORT3 +  1, "MISTRT_S4"),
     67	PINCTRL_PIN(TB10X_PORT3 +  2, "MIVAL_S4"),
     68	PINCTRL_PIN(TB10X_PORT3 +  3, "MDI_S4"),
     69	PINCTRL_PIN(TB10X_PORT3 +  4, "GPIOE0"),
     70	PINCTRL_PIN(TB10X_PORT3 +  5, "GPIOE1"),
     71	PINCTRL_PIN(TB10X_PORT3 +  6, "GPIOE2"),
     72	PINCTRL_PIN(TB10X_PORT3 +  7, "MDI_S5"),
     73	PINCTRL_PIN(TB10X_PORT3 +  8, "MIVAL_S5"),
     74	PINCTRL_PIN(TB10X_PORT3 +  9, "MISTRT_S5"),
     75	PINCTRL_PIN(TB10X_PORT3 + 10, "MICLK_S5"),
     76	/* Port 4 */
     77	PINCTRL_PIN(TB10X_PORT4 +  0, "MICLK_S6"),
     78	PINCTRL_PIN(TB10X_PORT4 +  1, "MISTRT_S6"),
     79	PINCTRL_PIN(TB10X_PORT4 +  2, "MIVAL_S6"),
     80	PINCTRL_PIN(TB10X_PORT4 +  3, "MDI_S6"),
     81	PINCTRL_PIN(TB10X_PORT4 +  4, "GPIOG0"),
     82	PINCTRL_PIN(TB10X_PORT4 +  5, "GPIOG1"),
     83	PINCTRL_PIN(TB10X_PORT4 +  6, "GPIOG2"),
     84	PINCTRL_PIN(TB10X_PORT4 +  7, "MDI_S7"),
     85	PINCTRL_PIN(TB10X_PORT4 +  8, "MIVAL_S7"),
     86	PINCTRL_PIN(TB10X_PORT4 +  9, "MISTRT_S7"),
     87	PINCTRL_PIN(TB10X_PORT4 + 10, "MICLK_S7"),
     88	/* Port 5 */
     89	PINCTRL_PIN(TB10X_PORT5 +  0, "PC_CE1N"),
     90	PINCTRL_PIN(TB10X_PORT5 +  1, "PC_CE2N"),
     91	PINCTRL_PIN(TB10X_PORT5 +  2, "PC_REGN"),
     92	PINCTRL_PIN(TB10X_PORT5 +  3, "PC_INPACKN"),
     93	PINCTRL_PIN(TB10X_PORT5 +  4, "PC_OEN"),
     94	PINCTRL_PIN(TB10X_PORT5 +  5, "PC_WEN"),
     95	PINCTRL_PIN(TB10X_PORT5 +  6, "PC_IORDN"),
     96	PINCTRL_PIN(TB10X_PORT5 +  7, "PC_IOWRN"),
     97	PINCTRL_PIN(TB10X_PORT5 +  8, "PC_RDYIRQN"),
     98	PINCTRL_PIN(TB10X_PORT5 +  9, "PC_WAITN"),
     99	PINCTRL_PIN(TB10X_PORT5 + 10, "PC_A0"),
    100	PINCTRL_PIN(TB10X_PORT5 + 11, "PC_A1"),
    101	PINCTRL_PIN(TB10X_PORT5 + 12, "PC_A2"),
    102	PINCTRL_PIN(TB10X_PORT5 + 13, "PC_A3"),
    103	PINCTRL_PIN(TB10X_PORT5 + 14, "PC_A4"),
    104	PINCTRL_PIN(TB10X_PORT5 + 15, "PC_A5"),
    105	PINCTRL_PIN(TB10X_PORT5 + 16, "PC_A6"),
    106	PINCTRL_PIN(TB10X_PORT5 + 17, "PC_A7"),
    107	PINCTRL_PIN(TB10X_PORT5 + 18, "PC_A8"),
    108	PINCTRL_PIN(TB10X_PORT5 + 19, "PC_A9"),
    109	PINCTRL_PIN(TB10X_PORT5 + 20, "PC_A10"),
    110	PINCTRL_PIN(TB10X_PORT5 + 21, "PC_A11"),
    111	PINCTRL_PIN(TB10X_PORT5 + 22, "PC_A12"),
    112	PINCTRL_PIN(TB10X_PORT5 + 23, "PC_A13"),
    113	PINCTRL_PIN(TB10X_PORT5 + 24, "PC_A14"),
    114	PINCTRL_PIN(TB10X_PORT5 + 25, "PC_D0"),
    115	PINCTRL_PIN(TB10X_PORT5 + 26, "PC_D1"),
    116	PINCTRL_PIN(TB10X_PORT5 + 27, "PC_D2"),
    117	PINCTRL_PIN(TB10X_PORT5 + 28, "PC_D3"),
    118	PINCTRL_PIN(TB10X_PORT5 + 29, "PC_D4"),
    119	PINCTRL_PIN(TB10X_PORT5 + 30, "PC_D5"),
    120	PINCTRL_PIN(TB10X_PORT5 + 31, "PC_D6"),
    121	PINCTRL_PIN(TB10X_PORT5 + 32, "PC_D7"),
    122	PINCTRL_PIN(TB10X_PORT5 + 33, "PC_MOSTRT"),
    123	PINCTRL_PIN(TB10X_PORT5 + 34, "PC_MOVAL"),
    124	PINCTRL_PIN(TB10X_PORT5 + 35, "PC_MDO0"),
    125	PINCTRL_PIN(TB10X_PORT5 + 36, "PC_MDO1"),
    126	PINCTRL_PIN(TB10X_PORT5 + 37, "PC_MDO2"),
    127	PINCTRL_PIN(TB10X_PORT5 + 38, "PC_MDO3"),
    128	PINCTRL_PIN(TB10X_PORT5 + 39, "PC_MDO4"),
    129	PINCTRL_PIN(TB10X_PORT5 + 40, "PC_MDO5"),
    130	PINCTRL_PIN(TB10X_PORT5 + 41, "PC_MDO6"),
    131	PINCTRL_PIN(TB10X_PORT5 + 42, "PC_MDO7"),
    132	PINCTRL_PIN(TB10X_PORT5 + 43, "PC_MISTRT"),
    133	PINCTRL_PIN(TB10X_PORT5 + 44, "PC_MIVAL"),
    134	PINCTRL_PIN(TB10X_PORT5 + 45, "PC_MDI0"),
    135	PINCTRL_PIN(TB10X_PORT5 + 46, "PC_MDI1"),
    136	PINCTRL_PIN(TB10X_PORT5 + 47, "PC_MDI2"),
    137	PINCTRL_PIN(TB10X_PORT5 + 48, "PC_MDI3"),
    138	PINCTRL_PIN(TB10X_PORT5 + 49, "PC_MDI4"),
    139	PINCTRL_PIN(TB10X_PORT5 + 50, "PC_MDI5"),
    140	PINCTRL_PIN(TB10X_PORT5 + 51, "PC_MDI6"),
    141	PINCTRL_PIN(TB10X_PORT5 + 52, "PC_MDI7"),
    142	PINCTRL_PIN(TB10X_PORT5 + 53, "PC_MICLK"),
    143	/* Port 6 */
    144	PINCTRL_PIN(TB10X_PORT6 + 0, "T_MOSTRT_S0"),
    145	PINCTRL_PIN(TB10X_PORT6 + 1, "T_MOVAL_S0"),
    146	PINCTRL_PIN(TB10X_PORT6 + 2, "T_MDO_S0"),
    147	PINCTRL_PIN(TB10X_PORT6 + 3, "T_MOSTRT_S1"),
    148	PINCTRL_PIN(TB10X_PORT6 + 4, "T_MOVAL_S1"),
    149	PINCTRL_PIN(TB10X_PORT6 + 5, "T_MDO_S1"),
    150	PINCTRL_PIN(TB10X_PORT6 + 6, "T_MOSTRT_S2"),
    151	PINCTRL_PIN(TB10X_PORT6 + 7, "T_MOVAL_S2"),
    152	PINCTRL_PIN(TB10X_PORT6 + 8, "T_MDO_S2"),
    153	PINCTRL_PIN(TB10X_PORT6 + 9, "T_MOSTRT_S3"),
    154	/* Port 7 */
    155	PINCTRL_PIN(TB10X_PORT7 + 0, "UART0_TXD"),
    156	PINCTRL_PIN(TB10X_PORT7 + 1, "UART0_RXD"),
    157	PINCTRL_PIN(TB10X_PORT7 + 2, "UART0_CTS"),
    158	PINCTRL_PIN(TB10X_PORT7 + 3, "UART0_RTS"),
    159	PINCTRL_PIN(TB10X_PORT7 + 4, "UART1_TXD"),
    160	PINCTRL_PIN(TB10X_PORT7 + 5, "UART1_RXD"),
    161	PINCTRL_PIN(TB10X_PORT7 + 6, "UART1_CTS"),
    162	PINCTRL_PIN(TB10X_PORT7 + 7, "UART1_RTS"),
    163	/* Port 8 */
    164	PINCTRL_PIN(TB10X_PORT8 + 0, "SPI3_CLK"),
    165	PINCTRL_PIN(TB10X_PORT8 + 1, "SPI3_MISO"),
    166	PINCTRL_PIN(TB10X_PORT8 + 2, "SPI3_MOSI"),
    167	PINCTRL_PIN(TB10X_PORT8 + 3, "SPI3_SSN"),
    168	/* Port 9 */
    169	PINCTRL_PIN(TB10X_PORT9 + 0, "SPI1_CLK"),
    170	PINCTRL_PIN(TB10X_PORT9 + 1, "SPI1_MISO"),
    171	PINCTRL_PIN(TB10X_PORT9 + 2, "SPI1_MOSI"),
    172	PINCTRL_PIN(TB10X_PORT9 + 3, "SPI1_SSN0"),
    173	PINCTRL_PIN(TB10X_PORT9 + 4, "SPI1_SSN1"),
    174	/* Unmuxed GPIOs */
    175	PINCTRL_PIN(TB10X_GPIOS +  0, "GPIOB0"),
    176	PINCTRL_PIN(TB10X_GPIOS +  1, "GPIOB1"),
    177
    178	PINCTRL_PIN(TB10X_GPIOS +  2, "GPIOD0"),
    179	PINCTRL_PIN(TB10X_GPIOS +  3, "GPIOD1"),
    180
    181	PINCTRL_PIN(TB10X_GPIOS +  4, "GPIOF0"),
    182	PINCTRL_PIN(TB10X_GPIOS +  5, "GPIOF1"),
    183
    184	PINCTRL_PIN(TB10X_GPIOS +  6, "GPIOH0"),
    185	PINCTRL_PIN(TB10X_GPIOS +  7, "GPIOH1"),
    186
    187	PINCTRL_PIN(TB10X_GPIOS +  8, "GPIOI0"),
    188	PINCTRL_PIN(TB10X_GPIOS +  9, "GPIOI1"),
    189	PINCTRL_PIN(TB10X_GPIOS + 10, "GPIOI2"),
    190	PINCTRL_PIN(TB10X_GPIOS + 11, "GPIOI3"),
    191	PINCTRL_PIN(TB10X_GPIOS + 12, "GPIOI4"),
    192	PINCTRL_PIN(TB10X_GPIOS + 13, "GPIOI5"),
    193	PINCTRL_PIN(TB10X_GPIOS + 14, "GPIOI6"),
    194	PINCTRL_PIN(TB10X_GPIOS + 15, "GPIOI7"),
    195	PINCTRL_PIN(TB10X_GPIOS + 16, "GPIOI8"),
    196	PINCTRL_PIN(TB10X_GPIOS + 17, "GPIOI9"),
    197	PINCTRL_PIN(TB10X_GPIOS + 18, "GPIOI10"),
    198	PINCTRL_PIN(TB10X_GPIOS + 19, "GPIOI11"),
    199
    200	PINCTRL_PIN(TB10X_GPIOS + 20, "GPION0"),
    201	PINCTRL_PIN(TB10X_GPIOS + 21, "GPION1"),
    202	PINCTRL_PIN(TB10X_GPIOS + 22, "GPION2"),
    203	PINCTRL_PIN(TB10X_GPIOS + 23, "GPION3"),
    204#define MAX_PIN (TB10X_GPIOS + 24)
    205	PINCTRL_PIN(MAX_PIN,  "GPION4"),
    206};
    207
    208
    209/* Port 1 */
    210static const unsigned mis0_pins[]  = {	TB10X_PORT1 + 0, TB10X_PORT1 + 1,
    211					TB10X_PORT1 + 2, TB10X_PORT1 + 3};
    212static const unsigned gpioa_pins[] = {	TB10X_PORT1 + 4, TB10X_PORT1 + 5,
    213					TB10X_PORT1 + 6};
    214static const unsigned mis1_pins[]  = {	TB10X_PORT1 + 7, TB10X_PORT1 + 8,
    215					TB10X_PORT1 + 9, TB10X_PORT1 + 10};
    216static const unsigned mip1_pins[]  = {	TB10X_PORT1 + 0, TB10X_PORT1 + 1,
    217					TB10X_PORT1 + 2, TB10X_PORT1 + 3,
    218					TB10X_PORT1 + 4, TB10X_PORT1 + 5,
    219					TB10X_PORT1 + 6, TB10X_PORT1 + 7,
    220					TB10X_PORT1 + 8, TB10X_PORT1 + 9,
    221					TB10X_PORT1 + 10};
    222
    223/* Port 2 */
    224static const unsigned mis2_pins[]  = {	TB10X_PORT2 + 0, TB10X_PORT2 + 1,
    225					TB10X_PORT2 + 2, TB10X_PORT2 + 3};
    226static const unsigned gpioc_pins[] = {	TB10X_PORT2 + 4, TB10X_PORT2 + 5,
    227					TB10X_PORT2 + 6};
    228static const unsigned mis3_pins[]  = {	TB10X_PORT2 + 7, TB10X_PORT2 + 8,
    229					TB10X_PORT2 + 9, TB10X_PORT2 + 10};
    230static const unsigned mip3_pins[]  = {	TB10X_PORT2 + 0, TB10X_PORT2 + 1,
    231					TB10X_PORT2 + 2, TB10X_PORT2 + 3,
    232					TB10X_PORT2 + 4, TB10X_PORT2 + 5,
    233					TB10X_PORT2 + 6, TB10X_PORT2 + 7,
    234					TB10X_PORT2 + 8, TB10X_PORT2 + 9,
    235					TB10X_PORT2 + 10};
    236
    237/* Port 3 */
    238static const unsigned mis4_pins[]  = {	TB10X_PORT3 + 0, TB10X_PORT3 + 1,
    239					TB10X_PORT3 + 2, TB10X_PORT3 + 3};
    240static const unsigned gpioe_pins[] = {	TB10X_PORT3 + 4, TB10X_PORT3 + 5,
    241					TB10X_PORT3 + 6};
    242static const unsigned mis5_pins[]  = {	TB10X_PORT3 + 7, TB10X_PORT3 + 8,
    243					TB10X_PORT3 + 9, TB10X_PORT3 + 10};
    244static const unsigned mip5_pins[]  = {	TB10X_PORT3 + 0, TB10X_PORT3 + 1,
    245					TB10X_PORT3 + 2, TB10X_PORT3 + 3,
    246					TB10X_PORT3 + 4, TB10X_PORT3 + 5,
    247					TB10X_PORT3 + 6, TB10X_PORT3 + 7,
    248					TB10X_PORT3 + 8, TB10X_PORT3 + 9,
    249					TB10X_PORT3 + 10};
    250
    251/* Port 4 */
    252static const unsigned mis6_pins[]  = {	TB10X_PORT4 + 0, TB10X_PORT4 + 1,
    253					TB10X_PORT4 + 2, TB10X_PORT4 + 3};
    254static const unsigned gpiog_pins[] = {	TB10X_PORT4 + 4, TB10X_PORT4 + 5,
    255					TB10X_PORT4 + 6};
    256static const unsigned mis7_pins[]  = {	TB10X_PORT4 + 7, TB10X_PORT4 + 8,
    257					TB10X_PORT4 + 9, TB10X_PORT4 + 10};
    258static const unsigned mip7_pins[]  = {	TB10X_PORT4 + 0, TB10X_PORT4 + 1,
    259					TB10X_PORT4 + 2, TB10X_PORT4 + 3,
    260					TB10X_PORT4 + 4, TB10X_PORT4 + 5,
    261					TB10X_PORT4 + 6, TB10X_PORT4 + 7,
    262					TB10X_PORT4 + 8, TB10X_PORT4 + 9,
    263					TB10X_PORT4 + 10};
    264
    265/* Port 6 */
    266static const unsigned mop_pins[] = {	TB10X_PORT6 + 0, TB10X_PORT6 + 1,
    267					TB10X_PORT6 + 2, TB10X_PORT6 + 3,
    268					TB10X_PORT6 + 4, TB10X_PORT6 + 5,
    269					TB10X_PORT6 + 6, TB10X_PORT6 + 7,
    270					TB10X_PORT6 + 8, TB10X_PORT6 + 9};
    271static const unsigned mos0_pins[] = {	TB10X_PORT6 + 0, TB10X_PORT6 + 1,
    272					TB10X_PORT6 + 2};
    273static const unsigned mos1_pins[] = {	TB10X_PORT6 + 3, TB10X_PORT6 + 4,
    274					TB10X_PORT6 + 5};
    275static const unsigned mos2_pins[] = {	TB10X_PORT6 + 6, TB10X_PORT6 + 7,
    276					TB10X_PORT6 + 8};
    277static const unsigned mos3_pins[] = {	TB10X_PORT6 + 9};
    278
    279/* Port 7 */
    280static const unsigned uart0_pins[] = {	TB10X_PORT7 + 0, TB10X_PORT7 + 1,
    281					TB10X_PORT7 + 2, TB10X_PORT7 + 3};
    282static const unsigned uart1_pins[] = {	TB10X_PORT7 + 4, TB10X_PORT7 + 5,
    283					TB10X_PORT7 + 6, TB10X_PORT7 + 7};
    284static const unsigned gpiol_pins[] = {	TB10X_PORT7 + 0, TB10X_PORT7 + 1,
    285					TB10X_PORT7 + 2, TB10X_PORT7 + 3};
    286static const unsigned gpiom_pins[] = {	TB10X_PORT7 + 4, TB10X_PORT7 + 5,
    287					TB10X_PORT7 + 6, TB10X_PORT7 + 7};
    288
    289/* Port 8 */
    290static const unsigned spi3_pins[] = {	TB10X_PORT8 + 0, TB10X_PORT8 + 1,
    291					TB10X_PORT8 + 2, TB10X_PORT8 + 3};
    292static const unsigned jtag_pins[] = {	TB10X_PORT8 + 0, TB10X_PORT8 + 1,
    293					TB10X_PORT8 + 2, TB10X_PORT8 + 3};
    294
    295/* Port 9 */
    296static const unsigned spi1_pins[] = {	TB10X_PORT9 + 0, TB10X_PORT9 + 1,
    297					TB10X_PORT9 + 2, TB10X_PORT9 + 3,
    298					TB10X_PORT9 + 4};
    299static const unsigned gpion_pins[] = {	TB10X_PORT9 + 0, TB10X_PORT9 + 1,
    300					TB10X_PORT9 + 2, TB10X_PORT9 + 3,
    301					TB10X_PORT9 + 4};
    302
    303/* Port 5 */
    304static const unsigned gpioj_pins[] = {	TB10X_PORT5 + 0, TB10X_PORT5 + 1,
    305					TB10X_PORT5 + 2, TB10X_PORT5 + 3,
    306					TB10X_PORT5 + 4, TB10X_PORT5 + 5,
    307					TB10X_PORT5 + 6, TB10X_PORT5 + 7,
    308					TB10X_PORT5 + 8, TB10X_PORT5 + 9,
    309					TB10X_PORT5 + 10, TB10X_PORT5 + 11,
    310					TB10X_PORT5 + 12, TB10X_PORT5 + 13,
    311					TB10X_PORT5 + 14, TB10X_PORT5 + 15,
    312					TB10X_PORT5 + 16, TB10X_PORT5 + 17,
    313					TB10X_PORT5 + 18, TB10X_PORT5 + 19,
    314					TB10X_PORT5 + 20, TB10X_PORT5 + 21,
    315					TB10X_PORT5 + 22, TB10X_PORT5 + 23,
    316					TB10X_PORT5 + 24, TB10X_PORT5 + 25,
    317					TB10X_PORT5 + 26, TB10X_PORT5 + 27,
    318					TB10X_PORT5 + 28, TB10X_PORT5 + 29,
    319					TB10X_PORT5 + 30, TB10X_PORT5 + 31};
    320static const unsigned gpiok_pins[] = {	TB10X_PORT5 + 32, TB10X_PORT5 + 33,
    321					TB10X_PORT5 + 34, TB10X_PORT5 + 35,
    322					TB10X_PORT5 + 36, TB10X_PORT5 + 37,
    323					TB10X_PORT5 + 38, TB10X_PORT5 + 39,
    324					TB10X_PORT5 + 40, TB10X_PORT5 + 41,
    325					TB10X_PORT5 + 42, TB10X_PORT5 + 43,
    326					TB10X_PORT5 + 44, TB10X_PORT5 + 45,
    327					TB10X_PORT5 + 46, TB10X_PORT5 + 47,
    328					TB10X_PORT5 + 48, TB10X_PORT5 + 49,
    329					TB10X_PORT5 + 50, TB10X_PORT5 + 51,
    330					TB10X_PORT5 + 52, TB10X_PORT5 + 53};
    331static const unsigned ciplus_pins[] = {	TB10X_PORT5 + 0, TB10X_PORT5 + 1,
    332					TB10X_PORT5 + 2, TB10X_PORT5 + 3,
    333					TB10X_PORT5 + 4, TB10X_PORT5 + 5,
    334					TB10X_PORT5 + 6, TB10X_PORT5 + 7,
    335					TB10X_PORT5 + 8, TB10X_PORT5 + 9,
    336					TB10X_PORT5 + 10, TB10X_PORT5 + 11,
    337					TB10X_PORT5 + 12, TB10X_PORT5 + 13,
    338					TB10X_PORT5 + 14, TB10X_PORT5 + 15,
    339					TB10X_PORT5 + 16, TB10X_PORT5 + 17,
    340					TB10X_PORT5 + 18, TB10X_PORT5 + 19,
    341					TB10X_PORT5 + 20, TB10X_PORT5 + 21,
    342					TB10X_PORT5 + 22, TB10X_PORT5 + 23,
    343					TB10X_PORT5 + 24, TB10X_PORT5 + 25,
    344					TB10X_PORT5 + 26, TB10X_PORT5 + 27,
    345					TB10X_PORT5 + 28, TB10X_PORT5 + 29,
    346					TB10X_PORT5 + 30, TB10X_PORT5 + 31,
    347					TB10X_PORT5 + 32, TB10X_PORT5 + 33,
    348					TB10X_PORT5 + 34, TB10X_PORT5 + 35,
    349					TB10X_PORT5 + 36, TB10X_PORT5 + 37,
    350					TB10X_PORT5 + 38, TB10X_PORT5 + 39,
    351					TB10X_PORT5 + 40, TB10X_PORT5 + 41,
    352					TB10X_PORT5 + 42, TB10X_PORT5 + 43,
    353					TB10X_PORT5 + 44, TB10X_PORT5 + 45,
    354					TB10X_PORT5 + 46, TB10X_PORT5 + 47,
    355					TB10X_PORT5 + 48, TB10X_PORT5 + 49,
    356					TB10X_PORT5 + 50, TB10X_PORT5 + 51,
    357					TB10X_PORT5 + 52, TB10X_PORT5 + 53};
    358static const unsigned mcard_pins[] = {	TB10X_PORT5 + 3, TB10X_PORT5 + 10,
    359					TB10X_PORT5 + 11, TB10X_PORT5 + 12,
    360					TB10X_PORT5 + 22, TB10X_PORT5 + 23,
    361					TB10X_PORT5 + 33, TB10X_PORT5 + 35,
    362					TB10X_PORT5 + 36, TB10X_PORT5 + 37,
    363					TB10X_PORT5 + 38, TB10X_PORT5 + 39,
    364					TB10X_PORT5 + 40, TB10X_PORT5 + 41,
    365					TB10X_PORT5 + 42, TB10X_PORT5 + 43,
    366					TB10X_PORT5 + 45, TB10X_PORT5 + 46,
    367					TB10X_PORT5 + 47, TB10X_PORT5 + 48,
    368					TB10X_PORT5 + 49, TB10X_PORT5 + 50,
    369					TB10X_PORT5 + 51, TB10X_PORT5 + 52,
    370					TB10X_PORT5 + 53};
    371static const unsigned stc0_pins[] = {	TB10X_PORT5 + 34, TB10X_PORT5 + 35,
    372					TB10X_PORT5 + 36, TB10X_PORT5 + 37,
    373					TB10X_PORT5 + 38, TB10X_PORT5 + 39,
    374					TB10X_PORT5 + 40};
    375static const unsigned stc1_pins[] = {	TB10X_PORT5 + 25, TB10X_PORT5 + 26,
    376					TB10X_PORT5 + 27, TB10X_PORT5 + 28,
    377					TB10X_PORT5 + 29, TB10X_PORT5 + 30,
    378					TB10X_PORT5 + 44};
    379
    380/* Unmuxed GPIOs */
    381static const unsigned gpiob_pins[] = {	TB10X_GPIOS + 0, TB10X_GPIOS + 1};
    382static const unsigned gpiod_pins[] = {	TB10X_GPIOS + 2, TB10X_GPIOS + 3};
    383static const unsigned gpiof_pins[] = {	TB10X_GPIOS + 4, TB10X_GPIOS + 5};
    384static const unsigned gpioh_pins[] = {	TB10X_GPIOS + 6, TB10X_GPIOS + 7};
    385static const unsigned gpioi_pins[] = {	TB10X_GPIOS + 8, TB10X_GPIOS + 9,
    386					TB10X_GPIOS + 10, TB10X_GPIOS + 11,
    387					TB10X_GPIOS + 12, TB10X_GPIOS + 13,
    388					TB10X_GPIOS + 14, TB10X_GPIOS + 15,
    389					TB10X_GPIOS + 16, TB10X_GPIOS + 17,
    390					TB10X_GPIOS + 18, TB10X_GPIOS + 19};
    391
    392struct tb10x_pinfuncgrp {
    393	const char *name;
    394	const unsigned int *pins;
    395	const unsigned int pincnt;
    396	const int port;
    397	const unsigned int mode;
    398	const int isgpio;
    399};
    400#define DEFPINFUNCGRP(NAME, PORT, MODE, ISGPIO) { \
    401		.name = __stringify(NAME), \
    402		.pins = NAME##_pins, .pincnt = ARRAY_SIZE(NAME##_pins), \
    403		.port = (PORT), .mode = (MODE), \
    404		.isgpio = (ISGPIO), \
    405	}
    406static const struct tb10x_pinfuncgrp tb10x_pingroups[] = {
    407	DEFPINFUNCGRP(mis0,   0, 0, 0),
    408	DEFPINFUNCGRP(gpioa,  0, 0, 1),
    409	DEFPINFUNCGRP(mis1,   0, 0, 0),
    410	DEFPINFUNCGRP(mip1,   0, 1, 0),
    411	DEFPINFUNCGRP(mis2,   1, 0, 0),
    412	DEFPINFUNCGRP(gpioc,  1, 0, 1),
    413	DEFPINFUNCGRP(mis3,   1, 0, 0),
    414	DEFPINFUNCGRP(mip3,   1, 1, 0),
    415	DEFPINFUNCGRP(mis4,   2, 0, 0),
    416	DEFPINFUNCGRP(gpioe,  2, 0, 1),
    417	DEFPINFUNCGRP(mis5,   2, 0, 0),
    418	DEFPINFUNCGRP(mip5,   2, 1, 0),
    419	DEFPINFUNCGRP(mis6,   3, 0, 0),
    420	DEFPINFUNCGRP(gpiog,  3, 0, 1),
    421	DEFPINFUNCGRP(mis7,   3, 0, 0),
    422	DEFPINFUNCGRP(mip7,   3, 1, 0),
    423	DEFPINFUNCGRP(gpioj,  4, 0, 1),
    424	DEFPINFUNCGRP(gpiok,  4, 0, 1),
    425	DEFPINFUNCGRP(ciplus, 4, 1, 0),
    426	DEFPINFUNCGRP(mcard,  4, 2, 0),
    427	DEFPINFUNCGRP(stc0,   4, 3, 0),
    428	DEFPINFUNCGRP(stc1,   4, 3, 0),
    429	DEFPINFUNCGRP(mop,    5, 0, 0),
    430	DEFPINFUNCGRP(mos0,   5, 1, 0),
    431	DEFPINFUNCGRP(mos1,   5, 1, 0),
    432	DEFPINFUNCGRP(mos2,   5, 1, 0),
    433	DEFPINFUNCGRP(mos3,   5, 1, 0),
    434	DEFPINFUNCGRP(uart0,  6, 0, 0),
    435	DEFPINFUNCGRP(uart1,  6, 0, 0),
    436	DEFPINFUNCGRP(gpiol,  6, 1, 1),
    437	DEFPINFUNCGRP(gpiom,  6, 1, 1),
    438	DEFPINFUNCGRP(spi3,   7, 0, 0),
    439	DEFPINFUNCGRP(jtag,   7, 1, 0),
    440	DEFPINFUNCGRP(spi1,   8, 0, 0),
    441	DEFPINFUNCGRP(gpion,  8, 1, 1),
    442	DEFPINFUNCGRP(gpiob, -1, 0, 1),
    443	DEFPINFUNCGRP(gpiod, -1, 0, 1),
    444	DEFPINFUNCGRP(gpiof, -1, 0, 1),
    445	DEFPINFUNCGRP(gpioh, -1, 0, 1),
    446	DEFPINFUNCGRP(gpioi, -1, 0, 1),
    447};
    448#undef DEFPINFUNCGRP
    449
    450struct tb10x_of_pinfunc {
    451	const char *name;
    452	const char *group;
    453};
    454
    455#define TB10X_PORTS (9)
    456
    457/**
    458 * struct tb10x_port - state of an I/O port
    459 * @mode: Node this port is currently in.
    460 * @count: Number of enabled functions which require this port to be
    461 *         configured in @mode.
    462 */
    463struct tb10x_port {
    464	unsigned int mode;
    465	unsigned int count;
    466};
    467
    468/**
    469 * struct tb10x_pinctrl - TB10x pin controller internal state
    470 * @pctl: pointer to the pinctrl_dev structure of this pin controller.
    471 * @base: register set base address.
    472 * @pingroups: pointer to an array of the pin groups this driver manages.
    473 * @pinfuncgrpcnt: number of pingroups in @pingroups.
    474 * @pinfuncnt: number of pin functions in @pinfuncs.
    475 * @mutex: mutex for exclusive access to a pin controller's state.
    476 * @ports: current state of each port.
    477 * @gpios: Indicates if a given pin is currently used as GPIO (1) or not (0).
    478 * @pinfuncs: flexible array of pin functions this driver manages.
    479 */
    480struct tb10x_pinctrl {
    481	struct pinctrl_dev *pctl;
    482	void *base;
    483	const struct tb10x_pinfuncgrp *pingroups;
    484	unsigned int pinfuncgrpcnt;
    485	unsigned int pinfuncnt;
    486	struct mutex mutex;
    487	struct tb10x_port ports[TB10X_PORTS];
    488	DECLARE_BITMAP(gpios, MAX_PIN + 1);
    489	struct tb10x_of_pinfunc pinfuncs[];
    490};
    491
    492static inline void tb10x_pinctrl_set_config(struct tb10x_pinctrl *state,
    493				unsigned int port, unsigned int mode)
    494{
    495	u32 pcfg;
    496
    497	if (state->ports[port].count)
    498		return;
    499
    500	state->ports[port].mode = mode;
    501
    502	pcfg = ioread32(state->base) & ~(PCFG_PORT_MASK(port));
    503	pcfg |= (mode << (PCFG_PORT_BITWIDTH * port)) & PCFG_PORT_MASK(port);
    504	iowrite32(pcfg, state->base);
    505}
    506
    507static inline unsigned int tb10x_pinctrl_get_config(
    508				struct tb10x_pinctrl *state,
    509				unsigned int port)
    510{
    511	return (ioread32(state->base) & PCFG_PORT_MASK(port))
    512		>> (PCFG_PORT_BITWIDTH * port);
    513}
    514
    515static int tb10x_get_groups_count(struct pinctrl_dev *pctl)
    516{
    517	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    518	return state->pinfuncgrpcnt;
    519}
    520
    521static const char *tb10x_get_group_name(struct pinctrl_dev *pctl, unsigned n)
    522{
    523	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    524	return state->pingroups[n].name;
    525}
    526
    527static int tb10x_get_group_pins(struct pinctrl_dev *pctl, unsigned n,
    528				unsigned const **pins,
    529				unsigned * const num_pins)
    530{
    531	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    532
    533	*pins = state->pingroups[n].pins;
    534	*num_pins = state->pingroups[n].pincnt;
    535
    536	return 0;
    537}
    538
    539static int tb10x_dt_node_to_map(struct pinctrl_dev *pctl,
    540				struct device_node *np_config,
    541				struct pinctrl_map **map, unsigned *num_maps)
    542{
    543	const char *string;
    544	unsigned reserved_maps = 0;
    545	int ret = 0;
    546
    547	if (of_property_read_string(np_config, "abilis,function", &string)) {
    548		pr_err("%pOF: No abilis,function property in device tree.\n",
    549			np_config);
    550		return -EINVAL;
    551	}
    552
    553	*map = NULL;
    554	*num_maps = 0;
    555
    556	ret = pinctrl_utils_reserve_map(pctl, map, &reserved_maps,
    557					num_maps, 1);
    558	if (ret)
    559		goto out;
    560
    561	ret = pinctrl_utils_add_map_mux(pctl, map, &reserved_maps,
    562					num_maps, string, np_config->name);
    563
    564out:
    565	return ret;
    566}
    567
    568static const struct pinctrl_ops tb10x_pinctrl_ops = {
    569	.get_groups_count = tb10x_get_groups_count,
    570	.get_group_name   = tb10x_get_group_name,
    571	.get_group_pins   = tb10x_get_group_pins,
    572	.dt_node_to_map   = tb10x_dt_node_to_map,
    573	.dt_free_map      = pinctrl_utils_free_map,
    574};
    575
    576static int tb10x_get_functions_count(struct pinctrl_dev *pctl)
    577{
    578	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    579	return state->pinfuncnt;
    580}
    581
    582static const char *tb10x_get_function_name(struct pinctrl_dev *pctl,
    583					unsigned n)
    584{
    585	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    586	return state->pinfuncs[n].name;
    587}
    588
    589static int tb10x_get_function_groups(struct pinctrl_dev *pctl,
    590				unsigned n, const char * const **groups,
    591				unsigned * const num_groups)
    592{
    593	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    594
    595	*groups = &state->pinfuncs[n].group;
    596	*num_groups = 1;
    597
    598	return 0;
    599}
    600
    601static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
    602					struct pinctrl_gpio_range *range,
    603					unsigned pin)
    604{
    605	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    606	int muxport = -1;
    607	int muxmode = -1;
    608	int i;
    609
    610	mutex_lock(&state->mutex);
    611
    612	/*
    613	 * Figure out to which port the requested GPIO belongs and how to
    614	 * configure that port.
    615	 * This loop also checks for pin conflicts between GPIOs and other
    616	 * functions.
    617	 */
    618	for (i = 0; i < state->pinfuncgrpcnt; i++) {
    619		const struct tb10x_pinfuncgrp *pfg = &state->pingroups[i];
    620		unsigned int mode = pfg->mode;
    621		int j, port = pfg->port;
    622
    623		/*
    624		 * Skip pin groups which are always mapped and don't need
    625		 * to be configured.
    626		 */
    627		if (port < 0)
    628			continue;
    629
    630		for (j = 0; j < pfg->pincnt; j++) {
    631			if (pin == pfg->pins[j]) {
    632				if (pfg->isgpio) {
    633					/*
    634					 * Remember the GPIO-only setting of
    635					 * the port this pin belongs to.
    636					 */
    637					muxport = port;
    638					muxmode = mode;
    639				} else if (state->ports[port].count
    640					&& (state->ports[port].mode == mode)) {
    641					/*
    642					 * Error: The requested pin is already
    643					 * used for something else.
    644					 */
    645					mutex_unlock(&state->mutex);
    646					return -EBUSY;
    647				}
    648				break;
    649			}
    650		}
    651	}
    652
    653	/*
    654	 * If we haven't returned an error at this point, the GPIO pin is not
    655	 * used by another function and the GPIO request can be granted:
    656	 * Register pin as being used as GPIO so we don't allocate it to
    657	 * another function later.
    658	 */
    659	set_bit(pin, state->gpios);
    660
    661	/*
    662	 * Potential conflicts between GPIOs and pin functions were caught
    663	 * earlier in this function and tb10x_pinctrl_set_config will do the
    664	 * Right Thing, either configure the port in GPIO only mode or leave
    665	 * another mode compatible with this GPIO request untouched.
    666	 */
    667	if (muxport >= 0)
    668		tb10x_pinctrl_set_config(state, muxport, muxmode);
    669
    670	mutex_unlock(&state->mutex);
    671
    672	return 0;
    673}
    674
    675static void tb10x_gpio_disable_free(struct pinctrl_dev *pctl,
    676					struct pinctrl_gpio_range *range,
    677					unsigned pin)
    678{
    679	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    680
    681	mutex_lock(&state->mutex);
    682
    683	clear_bit(pin, state->gpios);
    684
    685	mutex_unlock(&state->mutex);
    686}
    687
    688static int tb10x_pctl_set_mux(struct pinctrl_dev *pctl,
    689			unsigned func_selector, unsigned group_selector)
    690{
    691	struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
    692	const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
    693	int i;
    694
    695	if (grp->port < 0)
    696		return 0;
    697
    698	mutex_lock(&state->mutex);
    699
    700	/*
    701	 * Check if the requested function is compatible with previously
    702	 * requested functions.
    703	 */
    704	if (state->ports[grp->port].count
    705			&& (state->ports[grp->port].mode != grp->mode)) {
    706		mutex_unlock(&state->mutex);
    707		return -EBUSY;
    708	}
    709
    710	/*
    711	 * Check if the requested function is compatible with previously
    712	 * requested GPIOs.
    713	 */
    714	for (i = 0; i < grp->pincnt; i++)
    715		if (test_bit(grp->pins[i], state->gpios)) {
    716			mutex_unlock(&state->mutex);
    717			return -EBUSY;
    718		}
    719
    720	tb10x_pinctrl_set_config(state, grp->port, grp->mode);
    721
    722	state->ports[grp->port].count++;
    723
    724	mutex_unlock(&state->mutex);
    725
    726	return 0;
    727}
    728
    729static const struct pinmux_ops tb10x_pinmux_ops = {
    730	.get_functions_count = tb10x_get_functions_count,
    731	.get_function_name = tb10x_get_function_name,
    732	.get_function_groups = tb10x_get_function_groups,
    733	.gpio_request_enable = tb10x_gpio_request_enable,
    734	.gpio_disable_free = tb10x_gpio_disable_free,
    735	.set_mux = tb10x_pctl_set_mux,
    736};
    737
    738static struct pinctrl_desc tb10x_pindesc = {
    739	.name = "TB10x",
    740	.pins = tb10x_pins,
    741	.npins = ARRAY_SIZE(tb10x_pins),
    742	.owner = THIS_MODULE,
    743	.pctlops = &tb10x_pinctrl_ops,
    744	.pmxops  = &tb10x_pinmux_ops,
    745};
    746
    747static int tb10x_pinctrl_probe(struct platform_device *pdev)
    748{
    749	int ret = -EINVAL;
    750	struct device *dev = &pdev->dev;
    751	struct device_node *of_node = dev->of_node;
    752	struct device_node *child;
    753	struct tb10x_pinctrl *state;
    754	int i;
    755
    756	if (!of_node) {
    757		dev_err(dev, "No device tree node found.\n");
    758		return -EINVAL;
    759	}
    760
    761	state = devm_kzalloc(dev, struct_size(state, pinfuncs,
    762					      of_get_child_count(of_node)),
    763			     GFP_KERNEL);
    764	if (!state)
    765		return -ENOMEM;
    766
    767	platform_set_drvdata(pdev, state);
    768	mutex_init(&state->mutex);
    769
    770	state->base = devm_platform_ioremap_resource(pdev, 0);
    771	if (IS_ERR(state->base)) {
    772		ret = PTR_ERR(state->base);
    773		goto fail;
    774	}
    775
    776	state->pingroups = tb10x_pingroups;
    777	state->pinfuncgrpcnt = ARRAY_SIZE(tb10x_pingroups);
    778
    779	for (i = 0; i < TB10X_PORTS; i++)
    780		state->ports[i].mode = tb10x_pinctrl_get_config(state, i);
    781
    782	for_each_child_of_node(of_node, child) {
    783		const char *name;
    784
    785		if (!of_property_read_string(child, "abilis,function",
    786						&name)) {
    787			state->pinfuncs[state->pinfuncnt].name = child->name;
    788			state->pinfuncs[state->pinfuncnt].group = name;
    789			state->pinfuncnt++;
    790		}
    791	}
    792
    793	state->pctl = devm_pinctrl_register(dev, &tb10x_pindesc, state);
    794	if (IS_ERR(state->pctl)) {
    795		dev_err(dev, "could not register TB10x pin driver\n");
    796		ret = PTR_ERR(state->pctl);
    797		goto fail;
    798	}
    799
    800	return 0;
    801
    802fail:
    803	mutex_destroy(&state->mutex);
    804	return ret;
    805}
    806
    807static int tb10x_pinctrl_remove(struct platform_device *pdev)
    808{
    809	struct tb10x_pinctrl *state = platform_get_drvdata(pdev);
    810
    811	mutex_destroy(&state->mutex);
    812
    813	return 0;
    814}
    815
    816
    817static const struct of_device_id tb10x_pinctrl_dt_ids[] = {
    818	{ .compatible = "abilis,tb10x-iomux" },
    819	{ }
    820};
    821MODULE_DEVICE_TABLE(of, tb10x_pinctrl_dt_ids);
    822
    823static struct platform_driver tb10x_pinctrl_pdrv = {
    824	.probe   = tb10x_pinctrl_probe,
    825	.remove  = tb10x_pinctrl_remove,
    826	.driver  = {
    827		.name  = "tb10x_pinctrl",
    828		.of_match_table = of_match_ptr(tb10x_pinctrl_dt_ids),
    829	}
    830};
    831
    832module_platform_driver(tb10x_pinctrl_pdrv);
    833
    834MODULE_AUTHOR("Christian Ruppert <christian.ruppert@abilis.com>");
    835MODULE_LICENSE("GPL");