Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pinctrl: eyeq5: Use match data

Instead of using the pin descriptions, pin functions and register offsets
of the EyeQ5 directly, access those via a pointer to a newly introduced
struct eq5p_match_data.

This structure contains, in addition to the pin descriptions and pin
functions, an array of pin banks. Each bank holds the number of pins
and the register offsets.

All functions accessing a pin now use a pointer to a bank structure and
an offset inside that bank. The conversion from a pin number to a bank
and an offset is done in the new function eq5p_pin_to_bank_offset(),
which replace eq5p_pin_to_bank() and eq5p_pin_to_offset().

All the data related to the EyeQ5 is declared with the eq5p_eyeq5_
prefix to distinguish it from the common code.

During the probe, we use the parent OF node to get the match data.
We cannot directly use an OF node since pinctrl-eyeq5 is an auxiliary
device of clk-eyeq.

Signed-off-by: Benoît Monin <benoit.monin@bootlin.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

authored by

Benoît Monin and committed by
Thomas Bogendoerfer
7cfa9474 36cab4bd

+213 -129
+213 -129
drivers/pinctrl/pinctrl-eyeq5.c
··· 26 26 #include <linux/errno.h> 27 27 #include <linux/io.h> 28 28 #include <linux/mod_devicetable.h> 29 + #include <linux/of.h> 29 30 #include <linux/seq_file.h> 30 31 #include <linux/slab.h> 31 32 #include <linux/types.h> ··· 39 38 #include "core.h" 40 39 #include "pinctrl-utils.h" 41 40 42 - struct eq5p_pinctrl { 43 - struct pinctrl_desc desc; 44 - void __iomem *base; 45 - }; 46 - 47 - enum eq5p_bank { 48 - EQ5P_BANK_A, 49 - EQ5P_BANK_B, 50 - 51 - EQ5P_BANK_COUNT, 52 - }; 53 - 54 41 enum eq5p_regs { 55 42 EQ5P_PD, 56 43 EQ5P_PU, ··· 49 60 EQ5P_REG_COUNT, 50 61 }; 51 62 52 - static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = { 53 - [EQ5P_BANK_A] = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0}, 54 - [EQ5P_BANK_B] = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4}, 63 + struct eq5p_bank { 64 + const unsigned int npins; 65 + const unsigned int regs[EQ5P_REG_COUNT]; 66 + }; 67 + 68 + struct eq5p_match_data { 69 + const unsigned int npins; 70 + const unsigned int nfunctions; 71 + const unsigned int nbanks; 72 + const struct pinctrl_pin_desc *pins; 73 + const struct pinfunction *functions; 74 + const struct eq5p_bank *banks; 75 + }; 76 + 77 + struct eq5p_pinctrl { 78 + struct pinctrl_desc desc; 79 + void __iomem *base; 80 + const struct eq5p_match_data *data; 55 81 }; 56 82 57 83 /* ··· 75 71 #define EQ5P_DS_MASK GENMASK(1, 0) 76 72 77 73 /* 74 + * The GPIO function is always the first function 75 + */ 76 + #define EQ5P_GPIO_FUNC_SELECTOR 0 77 + 78 + /* Helper to declare pinfunction */ 79 + #define EQ5P_PINFUNCTION(func, groups) PINCTRL_PINFUNCTION(func, groups, ARRAY_SIZE(groups)) 80 + 81 + /* 78 82 * Comments to the right of each pin are the "signal name" in the datasheet. 79 83 */ 80 - static const struct pinctrl_pin_desc eq5p_pins[] = { 84 + static const struct pinctrl_pin_desc eq5p_eyeq5_pins[] = { 81 85 /* Bank A */ 82 86 PINCTRL_PIN(0, "PA0"), /* A0_TIMER0_CK */ 83 87 PINCTRL_PIN(1, "PA1"), /* A1_TIMER0_EOC */ ··· 117 105 PINCTRL_PIN(27, "PA27"), /* A27_SPI_1_CS1 */ 118 106 PINCTRL_PIN(28, "PA28"), /* A28_REF_CLK0 */ 119 107 120 - #define EQ5P_PIN_OFFSET_BANK_B 29 108 + #define EQ5P_EYEQ5_PIN_OFFSET_BANK_B 29 121 109 122 110 /* Bank B */ 123 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */ 124 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */ 125 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */ 126 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */ 127 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */ 128 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */ 129 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */ 130 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */ 131 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */ 132 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */ 133 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */ 134 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */ 135 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */ 136 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */ 137 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */ 138 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */ 139 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */ 140 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */ 141 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */ 142 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */ 143 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */ 144 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */ 145 - PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */ 111 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */ 112 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */ 113 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */ 114 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */ 115 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */ 116 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */ 117 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */ 118 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */ 119 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */ 120 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */ 121 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */ 122 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */ 123 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */ 124 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */ 125 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */ 126 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */ 127 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */ 128 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */ 129 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */ 130 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */ 131 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */ 132 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */ 133 + PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */ 146 134 }; 147 135 148 - static const char * const gpio_groups[] = { 136 + static const char * const eq5p_eyeq5_gpio_groups[] = { 149 137 /* Bank A */ 150 138 "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", 151 139 "PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15", ··· 159 147 }; 160 148 161 149 /* Groups of functions on bank A */ 162 - static const char * const timer0_groups[] = { "PA0", "PA1" }; 163 - static const char * const timer1_groups[] = { "PA2", "PA3" }; 164 - static const char * const timer2_groups[] = { "PA4", "PA5" }; 165 - static const char * const timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" }; 166 - static const char * const uart0_groups[] = { "PA10", "PA11" }; 167 - static const char * const uart1_groups[] = { "PA12", "PA13" }; 168 - static const char * const can0_groups[] = { "PA14", "PA15" }; 169 - static const char * const can1_groups[] = { "PA16", "PA17" }; 170 - static const char * const spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" }; 171 - static const char * const spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" }; 172 - static const char * const refclk0_groups[] = { "PA28" }; 150 + static const char * const eq5p_eyeq5_timer0_groups[] = { "PA0", "PA1" }; 151 + static const char * const eq5p_eyeq5_timer1_groups[] = { "PA2", "PA3" }; 152 + static const char * const eq5p_eyeq5_timer2_groups[] = { "PA4", "PA5" }; 153 + static const char * const eq5p_eyeq5_timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" }; 154 + static const char * const eq5p_eyeq5_uart0_groups[] = { "PA10", "PA11" }; 155 + static const char * const eq5p_eyeq5_uart1_groups[] = { "PA12", "PA13" }; 156 + static const char * const eq5p_eyeq5_can0_groups[] = { "PA14", "PA15" }; 157 + static const char * const eq5p_eyeq5_can1_groups[] = { "PA16", "PA17" }; 158 + static const char * const eq5p_eyeq5_spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" }; 159 + static const char * const eq5p_eyeq5_spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" }; 160 + static const char * const eq5p_eyeq5_refclk0_groups[] = { "PA28" }; 173 161 174 162 /* Groups of functions on bank B */ 175 - static const char * const timer3_groups[] = { "PB0", "PB1" }; 176 - static const char * const timer4_groups[] = { "PB2", "PB3" }; 177 - static const char * const timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" }; 178 - static const char * const uart2_groups[] = { "PB8", "PB9" }; 179 - static const char * const can2_groups[] = { "PB10", "PB11" }; 180 - static const char * const spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" }; 181 - static const char * const spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" }; 182 - static const char * const mclk0_groups[] = { "PB22" }; 163 + static const char * const eq5p_eyeq5_timer3_groups[] = { "PB0", "PB1" }; 164 + static const char * const eq5p_eyeq5_timer4_groups[] = { "PB2", "PB3" }; 165 + static const char * const eq5p_eyeq5_timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" }; 166 + static const char * const eq5p_eyeq5_uart2_groups[] = { "PB8", "PB9" }; 167 + static const char * const eq5p_eyeq5_can2_groups[] = { "PB10", "PB11" }; 168 + static const char * const eq5p_eyeq5_spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" }; 169 + static const char * const eq5p_eyeq5_spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" }; 170 + static const char * const eq5p_eyeq5_mclk0_groups[] = { "PB22" }; 183 171 184 - static const struct pinfunction eq5p_functions[] = { 185 - /* GPIO having a fixed index is depended upon, see GPIO_FUNC_SELECTOR. */ 186 - PINCTRL_PINFUNCTION("gpio", gpio_groups, ARRAY_SIZE(gpio_groups)), 187 - #define GPIO_FUNC_SELECTOR 0 172 + static const struct pinfunction eq5p_eyeq5_functions[] = { 173 + /* GPIO having a fixed index is depended upon, see EQ5P_GPIO_FUNC_SELECTOR. */ 174 + EQ5P_PINFUNCTION("gpio", eq5p_eyeq5_gpio_groups), 188 175 189 176 /* Bank A functions */ 190 - PINCTRL_PINFUNCTION("timer0", timer0_groups, ARRAY_SIZE(timer0_groups)), 191 - PINCTRL_PINFUNCTION("timer1", timer1_groups, ARRAY_SIZE(timer1_groups)), 192 - PINCTRL_PINFUNCTION("timer2", timer2_groups, ARRAY_SIZE(timer2_groups)), 193 - PINCTRL_PINFUNCTION("timer5", timer5_groups, ARRAY_SIZE(timer5_groups)), 194 - PINCTRL_PINFUNCTION("uart0", uart0_groups, ARRAY_SIZE(uart0_groups)), 195 - PINCTRL_PINFUNCTION("uart1", uart1_groups, ARRAY_SIZE(uart1_groups)), 196 - PINCTRL_PINFUNCTION("can0", can0_groups, ARRAY_SIZE(can0_groups)), 197 - PINCTRL_PINFUNCTION("can1", can1_groups, ARRAY_SIZE(can1_groups)), 198 - PINCTRL_PINFUNCTION("spi0", spi0_groups, ARRAY_SIZE(spi0_groups)), 199 - PINCTRL_PINFUNCTION("spi1", spi1_groups, ARRAY_SIZE(spi1_groups)), 200 - PINCTRL_PINFUNCTION("refclk0", refclk0_groups, ARRAY_SIZE(refclk0_groups)), 177 + EQ5P_PINFUNCTION("timer0", eq5p_eyeq5_timer0_groups), 178 + EQ5P_PINFUNCTION("timer1", eq5p_eyeq5_timer1_groups), 179 + EQ5P_PINFUNCTION("timer2", eq5p_eyeq5_timer2_groups), 180 + EQ5P_PINFUNCTION("timer5", eq5p_eyeq5_timer5_groups), 181 + EQ5P_PINFUNCTION("uart0", eq5p_eyeq5_uart0_groups), 182 + EQ5P_PINFUNCTION("uart1", eq5p_eyeq5_uart1_groups), 183 + EQ5P_PINFUNCTION("can0", eq5p_eyeq5_can0_groups), 184 + EQ5P_PINFUNCTION("can1", eq5p_eyeq5_can1_groups), 185 + EQ5P_PINFUNCTION("spi0", eq5p_eyeq5_spi0_groups), 186 + EQ5P_PINFUNCTION("spi1", eq5p_eyeq5_spi1_groups), 187 + EQ5P_PINFUNCTION("refclk0", eq5p_eyeq5_refclk0_groups), 201 188 202 189 /* Bank B functions */ 203 - PINCTRL_PINFUNCTION("timer3", timer3_groups, ARRAY_SIZE(timer3_groups)), 204 - PINCTRL_PINFUNCTION("timer4", timer4_groups, ARRAY_SIZE(timer4_groups)), 205 - PINCTRL_PINFUNCTION("timer6", timer6_groups, ARRAY_SIZE(timer6_groups)), 206 - PINCTRL_PINFUNCTION("uart2", uart2_groups, ARRAY_SIZE(uart2_groups)), 207 - PINCTRL_PINFUNCTION("can2", can2_groups, ARRAY_SIZE(can2_groups)), 208 - PINCTRL_PINFUNCTION("spi2", spi2_groups, ARRAY_SIZE(spi2_groups)), 209 - PINCTRL_PINFUNCTION("spi3", spi3_groups, ARRAY_SIZE(spi3_groups)), 210 - PINCTRL_PINFUNCTION("mclk0", mclk0_groups, ARRAY_SIZE(mclk0_groups)), 190 + EQ5P_PINFUNCTION("timer3", eq5p_eyeq5_timer3_groups), 191 + EQ5P_PINFUNCTION("timer4", eq5p_eyeq5_timer4_groups), 192 + EQ5P_PINFUNCTION("timer6", eq5p_eyeq5_timer6_groups), 193 + EQ5P_PINFUNCTION("uart2", eq5p_eyeq5_uart2_groups), 194 + EQ5P_PINFUNCTION("can2", eq5p_eyeq5_can2_groups), 195 + EQ5P_PINFUNCTION("spi2", eq5p_eyeq5_spi2_groups), 196 + EQ5P_PINFUNCTION("spi3", eq5p_eyeq5_spi3_groups), 197 + EQ5P_PINFUNCTION("mclk0", eq5p_eyeq5_mclk0_groups), 198 + }; 199 + 200 + static const struct eq5p_bank eq5p_eyeq5_banks[] = { 201 + { 202 + .npins = EQ5P_EYEQ5_PIN_OFFSET_BANK_B, 203 + .regs = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0}, 204 + }, 205 + { 206 + .npins = ARRAY_SIZE(eq5p_eyeq5_pins) - EQ5P_EYEQ5_PIN_OFFSET_BANK_B, 207 + .regs = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4}, 208 + }, 209 + }; 210 + 211 + static const struct eq5p_match_data eq5p_eyeq5_data = { 212 + .npins = ARRAY_SIZE(eq5p_eyeq5_pins), 213 + .nfunctions = ARRAY_SIZE(eq5p_eyeq5_functions), 214 + .nbanks = ARRAY_SIZE(eq5p_eyeq5_banks), 215 + .pins = eq5p_eyeq5_pins, 216 + .functions = eq5p_eyeq5_functions, 217 + .banks = eq5p_eyeq5_banks, 211 218 }; 212 219 213 220 static void eq5p_update_bits(const struct eq5p_pinctrl *pctrl, 214 - enum eq5p_bank bank, enum eq5p_regs reg, 215 - u32 mask, u32 val) 221 + const struct eq5p_bank *bank, 222 + enum eq5p_regs reg, u32 mask, u32 val) 216 223 { 217 - void __iomem *ptr = pctrl->base + eq5p_regs[bank][reg]; 224 + void __iomem *ptr = pctrl->base + bank->regs[reg]; 218 225 219 226 writel((readl(ptr) & ~mask) | (val & mask), ptr); 220 227 } 221 228 222 229 static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl, 223 - enum eq5p_bank bank, enum eq5p_regs reg, int offset) 230 + const struct eq5p_bank *bank, 231 + enum eq5p_regs reg, int offset) 224 232 { 225 - u32 val = readl(pctrl->base + eq5p_regs[bank][reg]); 233 + u32 val = readl(pctrl->base + bank->regs[reg]); 226 234 227 235 if (WARN_ON(offset > 31)) 228 236 return false; ··· 250 218 return (val & BIT(offset)) != 0; 251 219 } 252 220 253 - static enum eq5p_bank eq5p_pin_to_bank(unsigned int pin) 221 + static int eq5p_pin_to_bank_offset(const struct eq5p_pinctrl *pctrl, unsigned int pin, 222 + const struct eq5p_bank **bank, unsigned int *offset) 254 223 { 255 - if (pin < EQ5P_PIN_OFFSET_BANK_B) 256 - return EQ5P_BANK_A; 257 - else 258 - return EQ5P_BANK_B; 259 - } 224 + for (unsigned int i = 0; i < pctrl->data->nbanks; i++) { 225 + const struct eq5p_bank *_bank = &pctrl->data->banks[i]; 226 + unsigned int npins = _bank->npins; 260 227 261 - static unsigned int eq5p_pin_to_offset(unsigned int pin) 262 - { 263 - if (pin < EQ5P_PIN_OFFSET_BANK_B) 264 - return pin; 265 - else 266 - return pin - EQ5P_PIN_OFFSET_BANK_B; 228 + if (pin < npins) { 229 + *bank = _bank; 230 + *offset = pin; 231 + return 0; 232 + } 233 + pin -= npins; 234 + } 235 + 236 + return -EINVAL; 267 237 } 268 238 269 239 static int eq5p_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) 270 240 { 271 - return ARRAY_SIZE(eq5p_pins); 241 + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 242 + 243 + return pctrl->data->npins; 272 244 } 273 245 274 246 static const char *eq5p_pinctrl_get_group_name(struct pinctrl_dev *pctldev, ··· 296 260 { 297 261 enum pin_config_param param = pinconf_to_config_param(*config); 298 262 struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 299 - unsigned int offset = eq5p_pin_to_offset(pin); 300 - enum eq5p_bank bank = eq5p_pin_to_bank(pin); 263 + const struct eq5p_bank *bank; 264 + unsigned int offset; 301 265 u32 val_ds, arg; 302 266 bool pd, pu; 267 + int ret; 268 + 269 + ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset); 270 + if (ret) 271 + return ret; 303 272 304 273 pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset); 305 274 pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset); ··· 322 281 case PIN_CONFIG_DRIVE_STRENGTH: 323 282 offset *= 2; /* two bits per pin */ 324 283 if (offset >= 32) { 325 - val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_HIGH]); 284 + val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_HIGH]); 326 285 offset -= 32; 327 286 } else { 328 - val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_LOW]); 287 + val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_LOW]); 329 288 } 330 289 arg = (val_ds >> offset) & EQ5P_DS_MASK; 331 290 break; ··· 343 302 { 344 303 struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 345 304 const char *pin_name = pctrl->desc.pins[pin].name; 346 - unsigned int offset = eq5p_pin_to_offset(pin); 347 - enum eq5p_bank bank = eq5p_pin_to_bank(pin); 305 + const struct eq5p_bank *bank; 348 306 const char *func_name, *bias; 349 307 unsigned long ds_config; 308 + unsigned int offset; 350 309 u32 drive_strength; 351 310 bool pd, pu; 352 311 int i, j; 312 + 313 + if (eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset)) { 314 + seq_puts(s, "unknown pin"); 315 + return; 316 + } 353 317 354 318 /* 355 319 * First, let's get the function name. All pins have only two functions: ··· 362 316 */ 363 317 if (eq5p_test_bit(pctrl, bank, EQ5P_IOCR, offset)) { 364 318 func_name = NULL; 365 - for (i = 0; i < ARRAY_SIZE(eq5p_functions); i++) { 366 - if (i == GPIO_FUNC_SELECTOR) 319 + for (i = 0; i < pctrl->data->nfunctions; i++) { 320 + if (i == EQ5P_GPIO_FUNC_SELECTOR) 367 321 continue; 368 322 369 - for (j = 0; j < eq5p_functions[i].ngroups; j++) { 323 + for (j = 0; j < pctrl->data->functions[i].ngroups; j++) { 370 324 /* Groups and pins are the same thing for us. */ 371 - const char *x = eq5p_functions[i].groups[j]; 325 + const char *x = pctrl->data->functions[i].groups[j]; 372 326 373 327 if (strcmp(x, pin_name) == 0) { 374 - func_name = eq5p_functions[i].name; 328 + func_name = pctrl->data->functions[i].name; 375 329 break; 376 330 } 377 331 } ··· 387 341 if (!func_name) 388 342 func_name = "unknown"; 389 343 } else { 390 - func_name = eq5p_functions[GPIO_FUNC_SELECTOR].name; 344 + func_name = pctrl->data->functions[EQ5P_GPIO_FUNC_SELECTOR].name; 391 345 } 392 346 393 347 /* Second, we retrieve the bias. */ ··· 422 376 423 377 static int eq5p_pinmux_get_functions_count(struct pinctrl_dev *pctldev) 424 378 { 425 - return ARRAY_SIZE(eq5p_functions); 379 + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 380 + 381 + return pctrl->data->nfunctions; 426 382 } 427 383 428 384 static const char *eq5p_pinmux_get_function_name(struct pinctrl_dev *pctldev, 429 385 unsigned int selector) 430 386 { 431 - return eq5p_functions[selector].name; 387 + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 388 + 389 + return pctrl->data->functions[selector].name; 432 390 } 433 391 434 392 static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev, ··· 440 390 const char * const **groups, 441 391 unsigned int *num_groups) 442 392 { 443 - *groups = eq5p_functions[selector].groups; 444 - *num_groups = eq5p_functions[selector].ngroups; 393 + struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 394 + 395 + *groups = pctrl->data->functions[selector].groups; 396 + *num_groups = pctrl->data->functions[selector].ngroups; 445 397 return 0; 446 398 } 447 399 ··· 451 399 unsigned int func_selector, unsigned int pin) 452 400 { 453 401 struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 454 - const char *func_name = eq5p_functions[func_selector].name; 402 + const char *func_name = pctrl->data->functions[func_selector].name; 455 403 const char *group_name = pctldev->desc->pins[pin].name; 456 - bool is_gpio = func_selector == GPIO_FUNC_SELECTOR; 457 - unsigned int offset = eq5p_pin_to_offset(pin); 458 - enum eq5p_bank bank = eq5p_pin_to_bank(pin); 404 + bool is_gpio = func_selector == EQ5P_GPIO_FUNC_SELECTOR; 405 + const struct eq5p_bank *bank; 406 + unsigned int offset; 459 407 u32 mask, val; 408 + int ret; 409 + 410 + ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset); 411 + if (ret) 412 + return ret; 460 413 461 414 dev_dbg(pctldev->dev, "func=%s group=%s\n", func_name, group_name); 462 415 ··· 476 419 unsigned int pin) 477 420 { 478 421 /* Pin numbers and group selectors are the same thing in our case. */ 479 - return eq5p_pinmux_set_mux(pctldev, GPIO_FUNC_SELECTOR, pin); 422 + return eq5p_pinmux_set_mux(pctldev, EQ5P_GPIO_FUNC_SELECTOR, pin); 480 423 } 481 424 482 425 static const struct pinmux_ops eq5p_pinmux_ops = { ··· 492 435 unsigned int pin, u32 arg) 493 436 { 494 437 struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 495 - unsigned int offset = eq5p_pin_to_offset(pin); 496 - enum eq5p_bank bank = eq5p_pin_to_bank(pin); 438 + const struct eq5p_bank *bank; 439 + unsigned int offset; 497 440 unsigned int reg; 498 441 u32 mask, val; 442 + int ret; 443 + 444 + ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset); 445 + if (ret) 446 + return ret; 499 447 500 448 if (arg & ~EQ5P_DS_MASK) { 501 449 dev_err(pctldev->dev, "Unsupported drive strength: %u\n", arg); ··· 527 465 { 528 466 struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 529 467 const char *pin_name = pctldev->desc->pins[pin].name; 530 - unsigned int offset = eq5p_pin_to_offset(pin); 531 - enum eq5p_bank bank = eq5p_pin_to_bank(pin); 532 468 struct device *dev = pctldev->dev; 533 - u32 val = BIT(offset); 469 + const struct eq5p_bank *bank; 470 + unsigned int offset; 534 471 unsigned int i; 472 + u32 val; 473 + int ret; 535 474 475 + ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset); 476 + if (ret) 477 + return ret; 478 + 479 + val = BIT(offset); 536 480 for (i = 0; i < num_configs; i++) { 537 481 enum pin_config_param param = pinconf_to_config_param(configs[i]); 538 482 u32 arg = pinconf_to_config_argument(configs[i]); ··· 601 533 static int eq5p_probe(struct auxiliary_device *adev, 602 534 const struct auxiliary_device_id *id) 603 535 { 536 + const struct of_device_id *match; 604 537 struct device *dev = &adev->dev; 605 538 struct pinctrl_dev *pctldev; 606 539 struct eq5p_pinctrl *pctrl; 607 540 int ret; 541 + 542 + /* Get match data based on parent OF node set in clk-eyeq */ 543 + match = of_match_node(dev->driver->of_match_table, dev->of_node); 544 + if (!match || !match->data) 545 + return -ENODEV; 608 546 609 547 pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); 610 548 if (!pctrl) 611 549 return -ENOMEM; 612 550 613 551 pctrl->base = (void __iomem *)dev_get_platdata(dev); 552 + pctrl->data = match->data; 614 553 pctrl->desc.name = dev_name(dev); 615 - pctrl->desc.pins = eq5p_pins; 616 - pctrl->desc.npins = ARRAY_SIZE(eq5p_pins); 554 + pctrl->desc.pins = pctrl->data->pins; 555 + pctrl->desc.npins = pctrl->data->npins; 617 556 pctrl->desc.pctlops = &eq5p_pinctrl_ops; 618 557 pctrl->desc.pmxops = &eq5p_pinmux_ops; 619 558 pctrl->desc.confops = &eq5p_pinconf_ops; ··· 637 562 return 0; 638 563 } 639 564 565 + static const struct of_device_id eq5p_match_table[] = { 566 + { .compatible = "mobileye,eyeq5-olb", .data = &eq5p_eyeq5_data }, 567 + {} 568 + }; 569 + MODULE_DEVICE_TABLE(of, eq5p_match_table); 570 + 640 571 static const struct auxiliary_device_id eq5p_id_table[] = { 641 572 { .name = "clk_eyeq.pinctrl" }, 642 573 {} ··· 652 571 static struct auxiliary_driver eq5p_driver = { 653 572 .probe = eq5p_probe, 654 573 .id_table = eq5p_id_table, 574 + .driver = { 575 + .of_match_table = eq5p_match_table, 576 + } 655 577 }; 656 578 module_auxiliary_driver(eq5p_driver);