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 now get a reference to the parent OF node if we
don't already have it and use that 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>
---
drivers/pinctrl/pinctrl-eyeq5.c | 367 ++++++++++++++++++++++++++--------------
1 file changed, 239 insertions(+), 128 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-eyeq5.c b/drivers/pinctrl/pinctrl-eyeq5.c
index 5f6af934a516..e48add1d965d 100644
--- a/drivers/pinctrl/pinctrl-eyeq5.c
+++ b/drivers/pinctrl/pinctrl-eyeq5.c
@@ -26,6 +26,7 @@
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
+#include <linux/of.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -38,18 +39,6 @@
#include "core.h"
#include "pinctrl-utils.h"
-struct eq5p_pinctrl {
- struct pinctrl_desc desc;
- void __iomem *base;
-};
-
-enum eq5p_bank {
- EQ5P_BANK_A,
- EQ5P_BANK_B,
-
- EQ5P_BANK_COUNT,
-};
-
enum eq5p_regs {
EQ5P_PD,
EQ5P_PU,
@@ -60,9 +49,24 @@ enum eq5p_regs {
EQ5P_REG_COUNT,
};
-static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = {
- [EQ5P_BANK_A] = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
- [EQ5P_BANK_B] = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4},
+struct eq5p_bank {
+ const unsigned int npins;
+ const unsigned int regs[EQ5P_REG_COUNT];
+};
+
+struct eq5p_match_data {
+ const unsigned int npins;
+ const unsigned int nfunctions;
+ const unsigned int nbanks;
+ const struct pinctrl_pin_desc *pins;
+ const struct pinfunction *functions;
+ const struct eq5p_bank *banks;
+};
+
+struct eq5p_pinctrl {
+ struct pinctrl_desc desc;
+ void __iomem *base;
+ const struct eq5p_match_data *data;
};
/*
@@ -70,10 +74,18 @@ static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = {
*/
#define EQ5P_DS_MASK GENMASK(1, 0)
+/*
+ * The GPIO function is always the first function
+ */
+#define EQ5P_GPIO_FUNC_SELECTOR 0
+
+/* Helper to declare pinfunction */
+#define EQ5P_PINFUNCTION(func, groups) PINCTRL_PINFUNCTION(func, groups, ARRAY_SIZE(groups))
+
/*
* Comments to the right of each pin are the "signal name" in the datasheet.
*/
-static const struct pinctrl_pin_desc eq5p_pins[] = {
+static const struct pinctrl_pin_desc eq5p_eyeq5_pins[] = {
/* Bank A */
PINCTRL_PIN(0, "PA0"), /* A0_TIMER0_CK */
PINCTRL_PIN(1, "PA1"), /* A1_TIMER0_EOC */
@@ -105,35 +117,35 @@ static const struct pinctrl_pin_desc eq5p_pins[] = {
PINCTRL_PIN(27, "PA27"), /* A27_SPI_1_CS1 */
PINCTRL_PIN(28, "PA28"), /* A28_REF_CLK0 */
-#define EQ5P_PIN_OFFSET_BANK_B 29
+#define EQ5P_EYEQ5_PIN_OFFSET_BANK_B 29
/* Bank B */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */
- PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */
+ PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */
};
-static const char * const gpio_groups[] = {
+static const char * const eq5p_eyeq5_gpio_groups[] = {
/* Bank A */
"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
"PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
@@ -147,70 +159,90 @@ static const char * const gpio_groups[] = {
};
/* Groups of functions on bank A */
-static const char * const timer0_groups[] = { "PA0", "PA1" };
-static const char * const timer1_groups[] = { "PA2", "PA3" };
-static const char * const timer2_groups[] = { "PA4", "PA5" };
-static const char * const timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" };
-static const char * const uart0_groups[] = { "PA10", "PA11" };
-static const char * const uart1_groups[] = { "PA12", "PA13" };
-static const char * const can0_groups[] = { "PA14", "PA15" };
-static const char * const can1_groups[] = { "PA16", "PA17" };
-static const char * const spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" };
-static const char * const spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" };
-static const char * const refclk0_groups[] = { "PA28" };
+static const char * const eq5p_eyeq5_timer0_groups[] = { "PA0", "PA1" };
+static const char * const eq5p_eyeq5_timer1_groups[] = { "PA2", "PA3" };
+static const char * const eq5p_eyeq5_timer2_groups[] = { "PA4", "PA5" };
+static const char * const eq5p_eyeq5_timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" };
+static const char * const eq5p_eyeq5_uart0_groups[] = { "PA10", "PA11" };
+static const char * const eq5p_eyeq5_uart1_groups[] = { "PA12", "PA13" };
+static const char * const eq5p_eyeq5_can0_groups[] = { "PA14", "PA15" };
+static const char * const eq5p_eyeq5_can1_groups[] = { "PA16", "PA17" };
+static const char * const eq5p_eyeq5_spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" };
+static const char * const eq5p_eyeq5_spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" };
+static const char * const eq5p_eyeq5_refclk0_groups[] = { "PA28" };
/* Groups of functions on bank B */
-static const char * const timer3_groups[] = { "PB0", "PB1" };
-static const char * const timer4_groups[] = { "PB2", "PB3" };
-static const char * const timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" };
-static const char * const uart2_groups[] = { "PB8", "PB9" };
-static const char * const can2_groups[] = { "PB10", "PB11" };
-static const char * const spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" };
-static const char * const spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" };
-static const char * const mclk0_groups[] = { "PB22" };
+static const char * const eq5p_eyeq5_timer3_groups[] = { "PB0", "PB1" };
+static const char * const eq5p_eyeq5_timer4_groups[] = { "PB2", "PB3" };
+static const char * const eq5p_eyeq5_timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" };
+static const char * const eq5p_eyeq5_uart2_groups[] = { "PB8", "PB9" };
+static const char * const eq5p_eyeq5_can2_groups[] = { "PB10", "PB11" };
+static const char * const eq5p_eyeq5_spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" };
+static const char * const eq5p_eyeq5_spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" };
+static const char * const eq5p_eyeq5_mclk0_groups[] = { "PB22" };
-static const struct pinfunction eq5p_functions[] = {
- /* GPIO having a fixed index is depended upon, see GPIO_FUNC_SELECTOR. */
- PINCTRL_PINFUNCTION("gpio", gpio_groups, ARRAY_SIZE(gpio_groups)),
-#define GPIO_FUNC_SELECTOR 0
+static const struct pinfunction eq5p_eyeq5_functions[] = {
+ /* GPIO having a fixed index is depended upon, see EQ5P_GPIO_FUNC_SELECTOR. */
+ EQ5P_PINFUNCTION("gpio", eq5p_eyeq5_gpio_groups),
/* Bank A functions */
- PINCTRL_PINFUNCTION("timer0", timer0_groups, ARRAY_SIZE(timer0_groups)),
- PINCTRL_PINFUNCTION("timer1", timer1_groups, ARRAY_SIZE(timer1_groups)),
- PINCTRL_PINFUNCTION("timer2", timer2_groups, ARRAY_SIZE(timer2_groups)),
- PINCTRL_PINFUNCTION("timer5", timer5_groups, ARRAY_SIZE(timer5_groups)),
- PINCTRL_PINFUNCTION("uart0", uart0_groups, ARRAY_SIZE(uart0_groups)),
- PINCTRL_PINFUNCTION("uart1", uart1_groups, ARRAY_SIZE(uart1_groups)),
- PINCTRL_PINFUNCTION("can0", can0_groups, ARRAY_SIZE(can0_groups)),
- PINCTRL_PINFUNCTION("can1", can1_groups, ARRAY_SIZE(can1_groups)),
- PINCTRL_PINFUNCTION("spi0", spi0_groups, ARRAY_SIZE(spi0_groups)),
- PINCTRL_PINFUNCTION("spi1", spi1_groups, ARRAY_SIZE(spi1_groups)),
- PINCTRL_PINFUNCTION("refclk0", refclk0_groups, ARRAY_SIZE(refclk0_groups)),
+ EQ5P_PINFUNCTION("timer0", eq5p_eyeq5_timer0_groups),
+ EQ5P_PINFUNCTION("timer1", eq5p_eyeq5_timer1_groups),
+ EQ5P_PINFUNCTION("timer2", eq5p_eyeq5_timer2_groups),
+ EQ5P_PINFUNCTION("timer5", eq5p_eyeq5_timer5_groups),
+ EQ5P_PINFUNCTION("uart0", eq5p_eyeq5_uart0_groups),
+ EQ5P_PINFUNCTION("uart1", eq5p_eyeq5_uart1_groups),
+ EQ5P_PINFUNCTION("can0", eq5p_eyeq5_can0_groups),
+ EQ5P_PINFUNCTION("can1", eq5p_eyeq5_can1_groups),
+ EQ5P_PINFUNCTION("spi0", eq5p_eyeq5_spi0_groups),
+ EQ5P_PINFUNCTION("spi1", eq5p_eyeq5_spi1_groups),
+ EQ5P_PINFUNCTION("refclk0", eq5p_eyeq5_refclk0_groups),
/* Bank B functions */
- PINCTRL_PINFUNCTION("timer3", timer3_groups, ARRAY_SIZE(timer3_groups)),
- PINCTRL_PINFUNCTION("timer4", timer4_groups, ARRAY_SIZE(timer4_groups)),
- PINCTRL_PINFUNCTION("timer6", timer6_groups, ARRAY_SIZE(timer6_groups)),
- PINCTRL_PINFUNCTION("uart2", uart2_groups, ARRAY_SIZE(uart2_groups)),
- PINCTRL_PINFUNCTION("can2", can2_groups, ARRAY_SIZE(can2_groups)),
- PINCTRL_PINFUNCTION("spi2", spi2_groups, ARRAY_SIZE(spi2_groups)),
- PINCTRL_PINFUNCTION("spi3", spi3_groups, ARRAY_SIZE(spi3_groups)),
- PINCTRL_PINFUNCTION("mclk0", mclk0_groups, ARRAY_SIZE(mclk0_groups)),
+ EQ5P_PINFUNCTION("timer3", eq5p_eyeq5_timer3_groups),
+ EQ5P_PINFUNCTION("timer4", eq5p_eyeq5_timer4_groups),
+ EQ5P_PINFUNCTION("timer6", eq5p_eyeq5_timer6_groups),
+ EQ5P_PINFUNCTION("uart2", eq5p_eyeq5_uart2_groups),
+ EQ5P_PINFUNCTION("can2", eq5p_eyeq5_can2_groups),
+ EQ5P_PINFUNCTION("spi2", eq5p_eyeq5_spi2_groups),
+ EQ5P_PINFUNCTION("spi3", eq5p_eyeq5_spi3_groups),
+ EQ5P_PINFUNCTION("mclk0", eq5p_eyeq5_mclk0_groups),
+};
+
+static const struct eq5p_bank eq5p_eyeq5_banks[] = {
+ {
+ .npins = EQ5P_EYEQ5_PIN_OFFSET_BANK_B,
+ .regs = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
+ },
+ {
+ .npins = ARRAY_SIZE(eq5p_eyeq5_pins) - EQ5P_EYEQ5_PIN_OFFSET_BANK_B,
+ .regs = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4},
+ },
+};
+
+static const struct eq5p_match_data eq5p_eyeq5_data = {
+ .npins = ARRAY_SIZE(eq5p_eyeq5_pins),
+ .nfunctions = ARRAY_SIZE(eq5p_eyeq5_functions),
+ .nbanks = ARRAY_SIZE(eq5p_eyeq5_banks),
+ .pins = eq5p_eyeq5_pins,
+ .functions = eq5p_eyeq5_functions,
+ .banks = eq5p_eyeq5_banks,
};
static void eq5p_update_bits(const struct eq5p_pinctrl *pctrl,
- enum eq5p_bank bank, enum eq5p_regs reg,
- u32 mask, u32 val)
+ const struct eq5p_bank *bank,
+ enum eq5p_regs reg, u32 mask, u32 val)
{
- void __iomem *ptr = pctrl->base + eq5p_regs[bank][reg];
+ void __iomem *ptr = pctrl->base + bank->regs[reg];
writel((readl(ptr) & ~mask) | (val & mask), ptr);
}
static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl,
- enum eq5p_bank bank, enum eq5p_regs reg, int offset)
+ const struct eq5p_bank *bank,
+ enum eq5p_regs reg, int offset)
{
- u32 val = readl(pctrl->base + eq5p_regs[bank][reg]);
+ u32 val = readl(pctrl->base + bank->regs[reg]);
if (WARN_ON(offset > 31))
return false;
@@ -218,25 +250,29 @@ static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl,
return (val & BIT(offset)) != 0;
}
-static enum eq5p_bank eq5p_pin_to_bank(unsigned int pin)
+static int eq5p_pin_to_bank_offset(const struct eq5p_pinctrl *pctrl, unsigned int pin,
+ const struct eq5p_bank **bank, unsigned int *offset)
{
- if (pin < EQ5P_PIN_OFFSET_BANK_B)
- return EQ5P_BANK_A;
- else
- return EQ5P_BANK_B;
-}
+ for (unsigned int i = 0; i < pctrl->data->nbanks; i++) {
+ const struct eq5p_bank *_bank = &pctrl->data->banks[i];
+ unsigned int npins = _bank->npins;
-static unsigned int eq5p_pin_to_offset(unsigned int pin)
-{
- if (pin < EQ5P_PIN_OFFSET_BANK_B)
- return pin;
- else
- return pin - EQ5P_PIN_OFFSET_BANK_B;
+ if (pin < npins) {
+ *bank = _bank;
+ *offset = pin;
+ return 0;
+ }
+ pin -= npins;
+ }
+
+ return -EINVAL;
}
static int eq5p_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
- return ARRAY_SIZE(eq5p_pins);
+ struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->data->npins;
}
static const char *eq5p_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
@@ -260,10 +296,15 @@ static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
{
enum pin_config_param param = pinconf_to_config_param(*config);
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- unsigned int offset = eq5p_pin_to_offset(pin);
- enum eq5p_bank bank = eq5p_pin_to_bank(pin);
+ const struct eq5p_bank *bank;
+ unsigned int offset;
u32 val_ds, arg;
bool pd, pu;
+ int ret;
+
+ ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
+ if (ret)
+ return ret;
pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset);
pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset);
@@ -281,10 +322,10 @@ static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
case PIN_CONFIG_DRIVE_STRENGTH:
offset *= 2; /* two bits per pin */
if (offset >= 32) {
- val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_HIGH]);
+ val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_HIGH]);
offset -= 32;
} else {
- val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_LOW]);
+ val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_LOW]);
}
arg = (val_ds >> offset) & EQ5P_DS_MASK;
break;
@@ -302,30 +343,35 @@ static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const char *pin_name = pctrl->desc.pins[pin].name;
- unsigned int offset = eq5p_pin_to_offset(pin);
- enum eq5p_bank bank = eq5p_pin_to_bank(pin);
+ const struct eq5p_bank *bank;
const char *func_name, *bias;
unsigned long ds_config;
+ unsigned int offset;
u32 drive_strength;
bool pd, pu;
int i, j;
+ if (eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset)) {
+ seq_puts(s, "unknown pin");
+ return;
+ }
+
/*
* First, let's get the function name. All pins have only two functions:
* GPIO (IOCR == 0) and something else (IOCR == 1).
*/
if (eq5p_test_bit(pctrl, bank, EQ5P_IOCR, offset)) {
func_name = NULL;
- for (i = 0; i < ARRAY_SIZE(eq5p_functions); i++) {
- if (i == GPIO_FUNC_SELECTOR)
+ for (i = 0; i < pctrl->data->nfunctions; i++) {
+ if (i == EQ5P_GPIO_FUNC_SELECTOR)
continue;
- for (j = 0; j < eq5p_functions[i].ngroups; j++) {
+ for (j = 0; j < pctrl->data->functions[i].ngroups; j++) {
/* Groups and pins are the same thing for us. */
- const char *x = eq5p_functions[i].groups[j];
+ const char *x = pctrl->data->functions[i].groups[j];
if (strcmp(x, pin_name) == 0) {
- func_name = eq5p_functions[i].name;
+ func_name = pctrl->data->functions[i].name;
break;
}
}
@@ -341,7 +387,7 @@ static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
if (!func_name)
func_name = "unknown";
} else {
- func_name = eq5p_functions[GPIO_FUNC_SELECTOR].name;
+ func_name = pctrl->data->functions[EQ5P_GPIO_FUNC_SELECTOR].name;
}
/* Second, we retrieve the bias. */
@@ -376,13 +422,17 @@ static const struct pinctrl_ops eq5p_pinctrl_ops = {
static int eq5p_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
{
- return ARRAY_SIZE(eq5p_functions);
+ struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->data->nfunctions;
}
static const char *eq5p_pinmux_get_function_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
- return eq5p_functions[selector].name;
+ struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctrl->data->functions[selector].name;
}
static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
@@ -390,8 +440,10 @@ static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
const char * const **groups,
unsigned int *num_groups)
{
- *groups = eq5p_functions[selector].groups;
- *num_groups = eq5p_functions[selector].ngroups;
+ struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pctrl->data->functions[selector].groups;
+ *num_groups = pctrl->data->functions[selector].ngroups;
return 0;
}
@@ -399,12 +451,17 @@ static int eq5p_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int func_selector, unsigned int pin)
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- const char *func_name = eq5p_functions[func_selector].name;
+ const char *func_name = pctrl->data->functions[func_selector].name;
const char *group_name = pctldev->desc->pins[pin].name;
- bool is_gpio = func_selector == GPIO_FUNC_SELECTOR;
- unsigned int offset = eq5p_pin_to_offset(pin);
- enum eq5p_bank bank = eq5p_pin_to_bank(pin);
+ bool is_gpio = func_selector == EQ5P_GPIO_FUNC_SELECTOR;
+ const struct eq5p_bank *bank;
+ unsigned int offset;
u32 mask, val;
+ int ret;
+
+ ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
+ if (ret)
+ return ret;
dev_dbg(pctldev->dev, "func=%s group=%s\n", func_name, group_name);
@@ -419,7 +476,7 @@ static int eq5p_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
unsigned int pin)
{
/* Pin numbers and group selectors are the same thing in our case. */
- return eq5p_pinmux_set_mux(pctldev, GPIO_FUNC_SELECTOR, pin);
+ return eq5p_pinmux_set_mux(pctldev, EQ5P_GPIO_FUNC_SELECTOR, pin);
}
static const struct pinmux_ops eq5p_pinmux_ops = {
@@ -435,10 +492,15 @@ static int eq5p_pinconf_set_drive_strength(struct pinctrl_dev *pctldev,
unsigned int pin, u32 arg)
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- unsigned int offset = eq5p_pin_to_offset(pin);
- enum eq5p_bank bank = eq5p_pin_to_bank(pin);
+ const struct eq5p_bank *bank;
+ unsigned int offset;
unsigned int reg;
u32 mask, val;
+ int ret;
+
+ ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
+ if (ret)
+ return ret;
if (arg & ~EQ5P_DS_MASK) {
dev_err(pctldev->dev, "Unsupported drive strength: %u\n", arg);
@@ -465,11 +527,16 @@ static int eq5p_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const char *pin_name = pctldev->desc->pins[pin].name;
- unsigned int offset = eq5p_pin_to_offset(pin);
- enum eq5p_bank bank = eq5p_pin_to_bank(pin);
struct device *dev = pctldev->dev;
+ const struct eq5p_bank *bank;
+ unsigned int offset;
u32 val = BIT(offset);
unsigned int i;
+ int ret;
+
+ ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
+ if (ret)
+ return ret;
for (i = 0; i < num_configs; i++) {
enum pin_config_param param = pinconf_to_config_param(configs[i]);
@@ -530,22 +597,57 @@ static const struct pinconf_ops eq5p_pinconf_ops = {
.pin_config_group_set = eq5p_pinconf_set,
};
+static void eq5p_of_node_put(void *_dev)
+{
+ struct device *dev = _dev;
+
+ of_node_put(dev->of_node);
+}
+
static int eq5p_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
+ const struct of_device_id *match;
struct device *dev = &adev->dev;
struct pinctrl_dev *pctldev;
struct eq5p_pinctrl *pctrl;
+ bool need_of_put = false;
int ret;
+ /*
+ * We are an auxiliary device of clk-eyeq. We do not have an OF node by
+ * default; let's reuse our parent's OF node if not already set.
+ */
+ if (!dev->of_node) {
+ device_set_of_node_from_dev(dev, dev->parent);
+ need_of_put = true;
+ }
+ if (!dev->of_node)
+ return -ENODEV;
+
+ if (need_of_put) {
+ ret = devm_add_action_or_reset(dev, eq5p_of_node_put, dev);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Using our newfound OF node, we can get match data. We cannot use
+ * device_get_match_data() because it does not match reused OF nodes.
+ */
+ match = of_match_node(dev->driver->of_match_table, dev->of_node);
+ if (!match || !match->data)
+ return -ENODEV;
+
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
pctrl->base = (void __iomem *)dev_get_platdata(dev);
+ pctrl->data = match->data;
pctrl->desc.name = dev_name(dev);
- pctrl->desc.pins = eq5p_pins;
- pctrl->desc.npins = ARRAY_SIZE(eq5p_pins);
+ pctrl->desc.pins = pctrl->data->pins;
+ pctrl->desc.npins = pctrl->data->npins;
pctrl->desc.pctlops = &eq5p_pinctrl_ops;
pctrl->desc.pmxops = &eq5p_pinmux_ops;
pctrl->desc.confops = &eq5p_pinconf_ops;
@@ -562,6 +664,12 @@ static int eq5p_probe(struct auxiliary_device *adev,
return 0;
}
+static const struct of_device_id eq5p_match_table[] = {
+ { .compatible = "mobileye,eyeq5-olb", .data = &eq5p_eyeq5_data },
+ {}
+};
+MODULE_DEVICE_TABLE(of, eq5p_match_table);
+
static const struct auxiliary_device_id eq5p_id_table[] = {
{ .name = "clk_eyeq.pinctrl" },
{}
@@ -571,5 +679,8 @@ MODULE_DEVICE_TABLE(auxiliary, eq5p_id_table);
static struct auxiliary_driver eq5p_driver = {
.probe = eq5p_probe,
.id_table = eq5p_id_table,
+ .driver = {
+ .of_match_table = eq5p_match_table,
+ }
};
module_auxiliary_driver(eq5p_driver);
--
2.52.0
Hi Benoît,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]
url: https://github.com/intel-lab-lkp/linux/commits/Beno-t-Monin/dt-bindings-mips-Add-Mobileye-EyeQ6Lplus-SoC/20251217-214926
base: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link: https://lore.kernel.org/r/20251217-eyeq6lplus-v1-5-e9cdbd3af4c2%40bootlin.com
patch subject: [PATCH 05/13] pinctrl: eyeq5: Use match data
config: parisc-randconfig-r051-20251218 (https://download.01.org/0day-ci/archive/20251220/202512202102.TqCsNdqY-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512202102.TqCsNdqY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512202102.TqCsNdqY-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/bits.h:5,
from include/linux/ratelimit_types.h:5,
from include/linux/ratelimit.h:5,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/auxiliary_bus.h:11,
from drivers/pinctrl/pinctrl-eyeq5.c:21:
drivers/pinctrl/pinctrl-eyeq5.c: In function 'eq5p_pinconf_set':
>> include/vdso/bits.h:7:40: warning: 'offset' is used uninitialized [-Wuninitialized]
7 | #define BIT(nr) (UL(1) << (nr))
| ~~~~~~~^~~~~~~~
drivers/pinctrl/pinctrl-eyeq5.c:533:19: note: in expansion of macro 'BIT'
533 | u32 val = BIT(offset);
| ^~~
drivers/pinctrl/pinctrl-eyeq5.c:532:22: note: 'offset' declared here
532 | unsigned int offset;
| ^~~~~~
vim +/offset +7 include/vdso/bits.h
3945ff37d2f48d Vincenzo Frascino 2020-03-20 6
3945ff37d2f48d Vincenzo Frascino 2020-03-20 @7 #define BIT(nr) (UL(1) << (nr))
cbdb1f163af2bb Andy Shevchenko 2022-11-28 8 #define BIT_ULL(nr) (ULL(1) << (nr))
3945ff37d2f48d Vincenzo Frascino 2020-03-20 9
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Benoît,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]
url: https://github.com/intel-lab-lkp/linux/commits/Beno-t-Monin/dt-bindings-mips-Add-Mobileye-EyeQ6Lplus-SoC/20251217-214926
base: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link: https://lore.kernel.org/r/20251217-eyeq6lplus-v1-5-e9cdbd3af4c2%40bootlin.com
patch subject: [PATCH 05/13] pinctrl: eyeq5: Use match data
config: parisc-allyesconfig (https://download.01.org/0day-ci/archive/20251220/202512202142.StvDXvbg-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512202142.StvDXvbg-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512202142.StvDXvbg-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/pinctrl/pinctrl-eyeq5.c: In function 'eq5p_pinconf_set':
>> drivers/pinctrl/pinctrl-eyeq5.c:533:13: warning: 'offset' is used uninitialized [-Wuninitialized]
533 | u32 val = BIT(offset);
| ^~~
drivers/pinctrl/pinctrl-eyeq5.c:532:22: note: 'offset' was declared here
532 | unsigned int offset;
| ^~~~~~
vim +/offset +533 drivers/pinctrl/pinctrl-eyeq5.c
41795aa1f56a6e Théo Lebrun 2024-07-30 524
41795aa1f56a6e Théo Lebrun 2024-07-30 525 static int eq5p_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
41795aa1f56a6e Théo Lebrun 2024-07-30 526 unsigned long *configs, unsigned int num_configs)
41795aa1f56a6e Théo Lebrun 2024-07-30 527 {
41795aa1f56a6e Théo Lebrun 2024-07-30 528 struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
41795aa1f56a6e Théo Lebrun 2024-07-30 529 const char *pin_name = pctldev->desc->pins[pin].name;
41795aa1f56a6e Théo Lebrun 2024-07-30 530 struct device *dev = pctldev->dev;
e3ba56038b97ee Benoît Monin 2025-12-17 531 const struct eq5p_bank *bank;
e3ba56038b97ee Benoît Monin 2025-12-17 532 unsigned int offset;
41795aa1f56a6e Théo Lebrun 2024-07-30 @533 u32 val = BIT(offset);
41795aa1f56a6e Théo Lebrun 2024-07-30 534 unsigned int i;
e3ba56038b97ee Benoît Monin 2025-12-17 535 int ret;
e3ba56038b97ee Benoît Monin 2025-12-17 536
e3ba56038b97ee Benoît Monin 2025-12-17 537 ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
e3ba56038b97ee Benoît Monin 2025-12-17 538 if (ret)
e3ba56038b97ee Benoît Monin 2025-12-17 539 return ret;
41795aa1f56a6e Théo Lebrun 2024-07-30 540
41795aa1f56a6e Théo Lebrun 2024-07-30 541 for (i = 0; i < num_configs; i++) {
41795aa1f56a6e Théo Lebrun 2024-07-30 542 enum pin_config_param param = pinconf_to_config_param(configs[i]);
41795aa1f56a6e Théo Lebrun 2024-07-30 543 u32 arg = pinconf_to_config_argument(configs[i]);
41795aa1f56a6e Théo Lebrun 2024-07-30 544
41795aa1f56a6e Théo Lebrun 2024-07-30 545 switch (param) {
41795aa1f56a6e Théo Lebrun 2024-07-30 546 case PIN_CONFIG_BIAS_DISABLE:
41795aa1f56a6e Théo Lebrun 2024-07-30 547 dev_dbg(dev, "pin=%s bias_disable\n", pin_name);
41795aa1f56a6e Théo Lebrun 2024-07-30 548
41795aa1f56a6e Théo Lebrun 2024-07-30 549 eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0);
41795aa1f56a6e Théo Lebrun 2024-07-30 550 eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0);
41795aa1f56a6e Théo Lebrun 2024-07-30 551 break;
41795aa1f56a6e Théo Lebrun 2024-07-30 552
41795aa1f56a6e Théo Lebrun 2024-07-30 553 case PIN_CONFIG_BIAS_PULL_DOWN:
41795aa1f56a6e Théo Lebrun 2024-07-30 554 dev_dbg(dev, "pin=%s bias_pull_down arg=%u\n",
41795aa1f56a6e Théo Lebrun 2024-07-30 555 pin_name, arg);
41795aa1f56a6e Théo Lebrun 2024-07-30 556
41795aa1f56a6e Théo Lebrun 2024-07-30 557 if (arg == 0) /* cannot connect to GND */
41795aa1f56a6e Théo Lebrun 2024-07-30 558 return -ENOTSUPP;
41795aa1f56a6e Théo Lebrun 2024-07-30 559
41795aa1f56a6e Théo Lebrun 2024-07-30 560 eq5p_update_bits(pctrl, bank, EQ5P_PD, val, val);
41795aa1f56a6e Théo Lebrun 2024-07-30 561 eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0);
41795aa1f56a6e Théo Lebrun 2024-07-30 562 break;
41795aa1f56a6e Théo Lebrun 2024-07-30 563
41795aa1f56a6e Théo Lebrun 2024-07-30 564 case PIN_CONFIG_BIAS_PULL_UP:
41795aa1f56a6e Théo Lebrun 2024-07-30 565 dev_dbg(dev, "pin=%s bias_pull_up arg=%u\n",
41795aa1f56a6e Théo Lebrun 2024-07-30 566 pin_name, arg);
41795aa1f56a6e Théo Lebrun 2024-07-30 567
41795aa1f56a6e Théo Lebrun 2024-07-30 568 if (arg == 0) /* cannot connect to VDD */
41795aa1f56a6e Théo Lebrun 2024-07-30 569 return -ENOTSUPP;
41795aa1f56a6e Théo Lebrun 2024-07-30 570
41795aa1f56a6e Théo Lebrun 2024-07-30 571 eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0);
41795aa1f56a6e Théo Lebrun 2024-07-30 572 eq5p_update_bits(pctrl, bank, EQ5P_PU, val, val);
41795aa1f56a6e Théo Lebrun 2024-07-30 573 break;
41795aa1f56a6e Théo Lebrun 2024-07-30 574
41795aa1f56a6e Théo Lebrun 2024-07-30 575 case PIN_CONFIG_DRIVE_STRENGTH:
41795aa1f56a6e Théo Lebrun 2024-07-30 576 dev_dbg(dev, "pin=%s drive_strength arg=%u\n",
41795aa1f56a6e Théo Lebrun 2024-07-30 577 pin_name, arg);
41795aa1f56a6e Théo Lebrun 2024-07-30 578
41795aa1f56a6e Théo Lebrun 2024-07-30 579 eq5p_pinconf_set_drive_strength(pctldev, pin, arg);
41795aa1f56a6e Théo Lebrun 2024-07-30 580 break;
41795aa1f56a6e Théo Lebrun 2024-07-30 581
41795aa1f56a6e Théo Lebrun 2024-07-30 582 default:
41795aa1f56a6e Théo Lebrun 2024-07-30 583 dev_err(dev, "Unsupported pinconf %u\n", param);
41795aa1f56a6e Théo Lebrun 2024-07-30 584 return -ENOTSUPP;
41795aa1f56a6e Théo Lebrun 2024-07-30 585 }
41795aa1f56a6e Théo Lebrun 2024-07-30 586 }
41795aa1f56a6e Théo Lebrun 2024-07-30 587
41795aa1f56a6e Théo Lebrun 2024-07-30 588 return 0;
41795aa1f56a6e Théo Lebrun 2024-07-30 589 }
41795aa1f56a6e Théo Lebrun 2024-07-30 590
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.