From 645ec714545bca2a0ed13d7ac5b97d95e09da853 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Jun 2014 15:26:00 +0200 Subject: [PATCH 01/61] pinctrl: sunxi: Remove irq_mask_ack and use irq_ack instead If irq_mask_ack is not defined, mask_ack_irq will call irq_mask and then irq_ack. In order to avoid code duplication, between irq_mask_ack and irq_mask, just declare irq_ack. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index f1ca75e6d7b1..657c4b21cda8 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -573,26 +573,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, return 0; } -static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d) +static void sunxi_pinctrl_irq_ack(struct irq_data *d) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); - u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq); - u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq); u32 status_reg = sunxi_irq_status_reg(d->hwirq); u8 status_idx = sunxi_irq_status_offset(d->hwirq); - unsigned long flags; - u32 val; - - spin_lock_irqsave(&pctl->lock, flags); - - /* Mask the IRQ */ - val = readl(pctl->membase + ctrl_reg); - writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg); /* Clear the IRQ */ writel(1 << status_idx, pctl->membase + status_reg); - - spin_unlock_irqrestore(&pctl->lock, flags); } static void sunxi_pinctrl_irq_mask(struct irq_data *d) @@ -638,8 +626,8 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d) } static struct irq_chip sunxi_pinctrl_irq_chip = { + .irq_ack = sunxi_pinctrl_irq_ack, .irq_mask = sunxi_pinctrl_irq_mask, - .irq_mask_ack = sunxi_pinctrl_irq_mask_ack, .irq_unmask = sunxi_pinctrl_irq_unmask, .irq_set_type = sunxi_pinctrl_irq_set_type, }; From 6e1c30239fe31aae6b415088c39ede7fa62b190c Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Jun 2014 15:26:01 +0200 Subject: [PATCH 02/61] pinctrl: sunxi: Add macro definition for pinctrl with more than one interrupt The A31 and A23, unlike the other Allwinner SoCs, have several interrupts banks and parent interrupts, while the other only have up to 32 interrupts in a single bank and a single parent interrupt. Start supporting it by introducing a function macro to declare irq functions and their banks. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index 8169ba598876..cb87e15b1b3c 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h @@ -77,6 +77,7 @@ struct sunxi_desc_function { const char *name; u8 muxval; + u8 irqbank; u8 irqnum; }; @@ -139,6 +140,14 @@ struct sunxi_pinctrl { .irqnum = _irq, \ } +#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \ + { \ + .name = "irq", \ + .muxval = _val, \ + .irqbank = _bank, \ + .irqnum = _irq, \ + } + /* * The sunXi PIO registers are organized as is: * 0x00 - 0x0c Muxing values. From 8966ada2d40790214444c193be4902924e7ef02e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Jun 2014 15:26:02 +0200 Subject: [PATCH 03/61] pinctrl: sunxi: Declare the number of interrupt banks in the descriptor Declare in the description structure associated to the compatible the number of interrupt banks the device has. For now, we're not doing anything with it. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 1 + drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c | 1 + drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c | 1 + drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c | 1 + drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c | 1 + drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c | 1 + drivers/pinctrl/sunxi/pinctrl-sunxi.h | 1 + 7 files changed, 7 insertions(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c index fa1ff7c7e357..86b608bedca6 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c @@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = { static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = { .pins = sun4i_a10_pins, .npins = ARRAY_SIZE(sun4i_a10_pins), + .irq_banks = 1, }; static int sun4i_a10_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c index 164d743f526c..2fa7430cabaf 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c @@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = { static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = { .pins = sun5i_a10s_pins, .npins = ARRAY_SIZE(sun5i_a10s_pins), + .irq_banks = 1, }; static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c index 1188a2b7b988..29c734a60b51 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c @@ -382,6 +382,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = { .pins = sun5i_a13_pins, .npins = ARRAY_SIZE(sun5i_a13_pins), + .irq_banks = 1, }; static int sun5i_a13_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c index 8fcba48e0a42..9a2517b65113 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c @@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = { .pins = sun6i_a31_r_pins, .npins = ARRAY_SIZE(sun6i_a31_r_pins), .pin_base = PL_BASE, + .irq_banks = 2, }; static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c index 8dea5856458b..7adc4888eb27 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c @@ -836,6 +836,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = { .pins = sun6i_a31_pins, .npins = ARRAY_SIZE(sun6i_a31_pins), + .irq_banks = 4, }; static int sun6i_a31_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c index d8577ce5f1a4..dac99e02bfdb 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c @@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = { static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = { .pins = sun7i_a20_pins, .npins = ARRAY_SIZE(sun7i_a20_pins), + .irq_banks = 1, }; static int sun7i_a20_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index cb87e15b1b3c..7ddcce0f3c27 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h @@ -90,6 +90,7 @@ struct sunxi_pinctrl_desc { const struct sunxi_desc_pin *pins; int npins; unsigned pin_base; + unsigned irq_banks; }; struct sunxi_pinctrl_function { From c11a33c15ebc7c516551fef624efd9927da8cd81 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Jun 2014 15:26:03 +0200 Subject: [PATCH 04/61] pinctrl: sunxi: Declare the interrupt function for the A31 The primary pinctrl device has 4 interrupt banks. As usual, to be able to generate interrupts, the pins supporting it need to be muxed to a special function. Declare these functions in the pins array. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c | 216 ++++++++++++++-------- 1 file changed, 144 insertions(+), 72 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c index 7adc4888eb27..a2b4b85c5ad5 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c @@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D0 */ - SUNXI_FUNCTION(0x4, "uart1")), /* DTR */ + SUNXI_FUNCTION(0x4, "uart1"), /* DTR */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD1 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D1 */ - SUNXI_FUNCTION(0x4, "uart1")), /* DSR */ + SUNXI_FUNCTION(0x4, "uart1"), /* DSR */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D2 */ - SUNXI_FUNCTION(0x4, "uart1")), /* DCD */ + SUNXI_FUNCTION(0x4, "uart1"), /* DCD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D3 */ - SUNXI_FUNCTION(0x4, "uart1")), /* RING */ + SUNXI_FUNCTION(0x4, "uart1"), /* RING */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD4 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D4 */ - SUNXI_FUNCTION(0x4, "uart1")), /* TX */ + SUNXI_FUNCTION(0x4, "uart1"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD5 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D5 */ - SUNXI_FUNCTION(0x4, "uart1")), /* RX */ + SUNXI_FUNCTION(0x4, "uart1"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD6 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D6 */ - SUNXI_FUNCTION(0x4, "uart1")), /* RTS */ + SUNXI_FUNCTION(0x4, "uart1"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXD7 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D7 */ - SUNXI_FUNCTION(0x4, "uart1")), /* CTS */ + SUNXI_FUNCTION(0x4, "uart1"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXCLK */ - SUNXI_FUNCTION(0x3, "lcd1")), /* D8 */ + SUNXI_FUNCTION(0x3, "lcd1"), /* D8 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */ SUNXI_FUNCTION(0x3, "lcd1"), /* D9 */ SUNXI_FUNCTION(0x4, "mmc3"), /* CMD */ - SUNXI_FUNCTION(0x5, "mmc2")), /* CMD */ + SUNXI_FUNCTION(0x5, "mmc2"), /* CMD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* GTXCLK */ SUNXI_FUNCTION(0x3, "lcd1"), /* D10 */ SUNXI_FUNCTION(0x4, "mmc3"), /* CLK */ - SUNXI_FUNCTION(0x5, "mmc2")), /* CLK */ + SUNXI_FUNCTION(0x5, "mmc2"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D11 */ SUNXI_FUNCTION(0x4, "mmc3"), /* D0 */ - SUNXI_FUNCTION(0x5, "mmc2")), /* D0 */ + SUNXI_FUNCTION(0x5, "mmc2"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D12 */ SUNXI_FUNCTION(0x4, "mmc3"), /* D1 */ - SUNXI_FUNCTION(0x5, "mmc2")), /* D1 */ + SUNXI_FUNCTION(0x5, "mmc2"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D13 */ SUNXI_FUNCTION(0x4, "mmc3"), /* D2 */ - SUNXI_FUNCTION(0x5, "mmc2")), /* D2 */ + SUNXI_FUNCTION(0x5, "mmc2"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */ SUNXI_FUNCTION(0x3, "lcd1"), /* D14 */ SUNXI_FUNCTION(0x4, "mmc3"), /* D3 */ - SUNXI_FUNCTION(0x5, "mmc2")), /* D3 */ + SUNXI_FUNCTION(0x5, "mmc2"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD4 */ - SUNXI_FUNCTION(0x3, "lcd1")), /* D15 */ + SUNXI_FUNCTION(0x3, "lcd1"), /* D15 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD5 */ - SUNXI_FUNCTION(0x3, "lcd1")), /* D16 */ + SUNXI_FUNCTION(0x3, "lcd1"), /* D16 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD6 */ - SUNXI_FUNCTION(0x3, "lcd1")), /* D17 */ + SUNXI_FUNCTION(0x3, "lcd1"), /* D17 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXD7 */ - SUNXI_FUNCTION(0x3, "lcd1")), /* D18 */ + SUNXI_FUNCTION(0x3, "lcd1"), /* D18 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXDV */ SUNXI_FUNCTION(0x3, "lcd1"), /* D19 */ - SUNXI_FUNCTION(0x4, "pwm3")), /* Positive */ + SUNXI_FUNCTION(0x4, "pwm3"), /* Positive */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXCLK */ SUNXI_FUNCTION(0x3, "lcd1"), /* D20 */ - SUNXI_FUNCTION(0x4, "pwm3")), /* Negative */ + SUNXI_FUNCTION(0x4, "pwm3"), /* Negative */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* TXERR */ SUNXI_FUNCTION(0x3, "lcd1"), /* D21 */ - SUNXI_FUNCTION(0x4, "spi3")), /* CS0 */ + SUNXI_FUNCTION(0x4, "spi3"), /* CS0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 22), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */ SUNXI_FUNCTION(0x3, "lcd1"), /* D22 */ - SUNXI_FUNCTION(0x4, "spi3")), /* CLK */ + SUNXI_FUNCTION(0x4, "spi3"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 22)), /* PA_EINT22 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 23), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* COL */ SUNXI_FUNCTION(0x3, "lcd1"), /* D23 */ - SUNXI_FUNCTION(0x4, "spi3")), /* MOSI */ + SUNXI_FUNCTION(0x4, "spi3"), /* MOSI */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 23)), /* PA_EINT23 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 24), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* CRS */ SUNXI_FUNCTION(0x3, "lcd1"), /* CLK */ - SUNXI_FUNCTION(0x4, "spi3")), /* MISO */ + SUNXI_FUNCTION(0x4, "spi3"), /* MISO */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 24)), /* PA_EINT24 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 25), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* CLKIN */ SUNXI_FUNCTION(0x3, "lcd1"), /* DE */ - SUNXI_FUNCTION(0x4, "spi3")), /* CS1 */ + SUNXI_FUNCTION(0x4, "spi3"), /* CS1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 25)), /* PA_EINT25 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 26), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* MDC */ - SUNXI_FUNCTION(0x3, "lcd1")), /* HSYNC */ + SUNXI_FUNCTION(0x3, "lcd1"), /* HSYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 26)), /* PA_EINT26 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 27), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "gmac"), /* MDIO */ - SUNXI_FUNCTION(0x3, "lcd1")), /* VSYNC */ + SUNXI_FUNCTION(0x3, "lcd1"), /* VSYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 27)), /* PA_EINT27 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */ SUNXI_FUNCTION(0x3, "uart3"), /* CTS */ - SUNXI_FUNCTION(0x4, "csi")), /* MCLK1 */ + SUNXI_FUNCTION(0x4, "csi"), /* MCLK1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PB_EINT0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s0")), /* BCLK */ + SUNXI_FUNCTION(0x2, "i2s0"), /* BCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PB_EINT1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s0")), /* LRCK */ + SUNXI_FUNCTION(0x2, "i2s0"), /* LRCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PB_EINT2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "i2s0")), /* DO0 */ + SUNXI_FUNCTION(0x2, "i2s0"), /* DO0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PB_EINT3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "i2s0"), /* DO1 */ - SUNXI_FUNCTION(0x3, "uart3")), /* RTS */ + SUNXI_FUNCTION(0x3, "uart3"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PB_EINT4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "i2s0"), /* DO2 */ SUNXI_FUNCTION(0x3, "uart3"), /* TX */ - SUNXI_FUNCTION(0x4, "i2c3")), /* SCK */ + SUNXI_FUNCTION(0x4, "i2c3"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "i2s0"), /* DO3 */ SUNXI_FUNCTION(0x3, "uart3"), /* RX */ - SUNXI_FUNCTION(0x4, "i2c3")), /* SDA */ + SUNXI_FUNCTION(0x4, "i2c3"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x3, "i2s0")), /* DI */ + SUNXI_FUNCTION(0x3, "i2s0"), /* DI */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)), /* PB_EINT7 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), SUNXI_FUNCTION(0x0, "gpio_in"), @@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* PCLK */ - SUNXI_FUNCTION(0x3, "ts")), /* CLK */ + SUNXI_FUNCTION(0x3, "ts"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* MCLK */ - SUNXI_FUNCTION(0x3, "ts")), /* ERR */ + SUNXI_FUNCTION(0x3, "ts"), /* ERR */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */ - SUNXI_FUNCTION(0x3, "ts")), /* SYNC */ + SUNXI_FUNCTION(0x3, "ts"), /* SYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */ - SUNXI_FUNCTION(0x3, "ts")), /* DVLD */ + SUNXI_FUNCTION(0x3, "ts"), /* DVLD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D0 */ - SUNXI_FUNCTION(0x3, "uart5")), /* TX */ + SUNXI_FUNCTION(0x3, "uart5"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D1 */ - SUNXI_FUNCTION(0x3, "uart5")), /* RX */ + SUNXI_FUNCTION(0x3, "uart5"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D2 */ - SUNXI_FUNCTION(0x3, "uart5")), /* RTS */ + SUNXI_FUNCTION(0x3, "uart5"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D3 */ - SUNXI_FUNCTION(0x3, "uart5")), /* CTS */ + SUNXI_FUNCTION(0x3, "uart5"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D4 */ - SUNXI_FUNCTION(0x3, "ts")), /* D0 */ + SUNXI_FUNCTION(0x3, "ts"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D5 */ - SUNXI_FUNCTION(0x3, "ts")), /* D1 */ + SUNXI_FUNCTION(0x3, "ts"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D6 */ - SUNXI_FUNCTION(0x3, "ts")), /* D2 */ + SUNXI_FUNCTION(0x3, "ts"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D7 */ - SUNXI_FUNCTION(0x3, "ts")), /* D3 */ + SUNXI_FUNCTION(0x3, "ts"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D8 */ - SUNXI_FUNCTION(0x3, "ts")), /* D4 */ + SUNXI_FUNCTION(0x3, "ts"), /* D4 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D9 */ - SUNXI_FUNCTION(0x3, "ts")), /* D5 */ + SUNXI_FUNCTION(0x3, "ts"), /* D5 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D10 */ - SUNXI_FUNCTION(0x3, "ts")), /* D6 */ + SUNXI_FUNCTION(0x3, "ts"), /* D6 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "csi"), /* D11 */ - SUNXI_FUNCTION(0x3, "ts")), /* D7 */ + SUNXI_FUNCTION(0x3, "ts"), /* D7 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "csi")), /* MIPI CSI MCLK */ + SUNXI_FUNCTION(0x2, "csi"), /* MIPI CSI MCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), SUNXI_FUNCTION(0x0, "gpio_in"), @@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1")), /* CLK */ + SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1")), /* CMD */ + SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1")), /* D0 */ + SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1")), /* D1 */ + SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1")), /* D2 */ + SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "mmc1")), /* D3 */ + SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart2")), /* TX */ + SUNXI_FUNCTION(0x2, "uart2"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart2")), /* RX */ + SUNXI_FUNCTION(0x2, "uart2"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart2")), /* RTS */ + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart2")), /* CTS */ + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */ - SUNXI_FUNCTION(0x3, "usb")), /* DP3 */ + SUNXI_FUNCTION(0x3, "usb"), /* DP3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */ - SUNXI_FUNCTION(0x3, "usb")), /* DM3 */ + SUNXI_FUNCTION(0x3, "usb"), /* DM3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */ - SUNXI_FUNCTION(0x3, "i2s1")), /* MCLK */ + SUNXI_FUNCTION(0x3, "i2s1"), /* MCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */ - SUNXI_FUNCTION(0x3, "i2s1")), /* BCLK */ + SUNXI_FUNCTION(0x3, "i2s1"), /* BCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ - SUNXI_FUNCTION(0x3, "i2s1")), /* LRCK */ + SUNXI_FUNCTION(0x3, "i2s1"), /* LRCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ - SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */ + SUNXI_FUNCTION(0x3, "i2s1"), /* DIN */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ - SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */ + SUNXI_FUNCTION(0x3, "i2s1"), /* DOUT */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 16)), /* PG_EINT16 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 17), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart4")), /* TX */ + SUNXI_FUNCTION(0x2, "uart4"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 17)), /* PG_EINT17 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 18), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "uart4")), /* RX */ + SUNXI_FUNCTION(0x2, "uart4"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 18)), /* PG_EINT18 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), SUNXI_FUNCTION(0x0, "gpio_in"), From aebdc8abc9db86e2bd33070fc2f961012fff74b4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 5 Jun 2014 15:26:04 +0200 Subject: [PATCH 05/61] pinctrl: sunxi: Implement multiple interrupt banks support The A23 and A31 support multiple interrupt banks. Support it by adding a linear domain covering all the banks. It's trickier than it should because there's an interrupt per bank, so we have multiple interrupts using the same domain. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 65 +++++++++++++++++++++------ drivers/pinctrl/sunxi/pinctrl-sunxi.h | 34 ++++++++++---- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 657c4b21cda8..d989a10f7b10 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -636,17 +636,28 @@ static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); struct sunxi_pinctrl *pctl = irq_get_handler_data(irq); - const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG); + unsigned long bank, reg, val; + + for (bank = 0; bank < pctl->desc->irq_banks; bank++) + if (irq == pctl->irq[bank]) + break; + + if (bank == pctl->desc->irq_banks) + return; + + reg = sunxi_irq_status_reg_from_bank(bank); + val = readl(pctl->membase + reg); /* Clear all interrupts */ - writel(reg, pctl->membase + IRQ_STATUS_REG); + writel(val, pctl->membase + reg); - if (reg) { + if (val) { int irqoffset; chained_irq_enter(chip, desc); - for_each_set_bit(irqoffset, ®, SUNXI_IRQ_NUMBER) { - int pin_irq = irq_find_mapping(pctl->domain, irqoffset); + for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) { + int pin_irq = irq_find_mapping(pctl->domain, + bank * IRQ_PER_BANK + irqoffset); generic_handle_irq(pin_irq); } chained_irq_exit(chip, desc); @@ -714,8 +725,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) while (func->name) { /* Create interrupt mapping while we're at it */ - if (!strcmp(func->name, "irq")) - pctl->irq_array[func->irqnum] = pin->pin.number; + if (!strcmp(func->name, "irq")) { + int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK; + pctl->irq_array[irqnum] = pin->pin.number; + } + sunxi_pinctrl_add_function(pctl, func->name); func++; } @@ -785,6 +799,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev, pctl->dev = &pdev->dev; pctl->desc = desc; + pctl->irq_array = devm_kcalloc(&pdev->dev, + IRQ_PER_BANK * pctl->desc->irq_banks, + sizeof(*pctl->irq_array), + GFP_KERNEL); + if (!pctl->irq_array) + return -ENOMEM; + ret = sunxi_pinctrl_build_state(pdev); if (ret) { dev_err(&pdev->dev, "dt probe failed: %d\n", ret); @@ -869,21 +890,34 @@ int sunxi_pinctrl_init(struct platform_device *pdev, if (ret) goto gpiochip_error; - pctl->irq = irq_of_parse_and_map(node, 0); + pctl->irq = devm_kcalloc(&pdev->dev, + pctl->desc->irq_banks, + sizeof(*pctl->irq), + GFP_KERNEL); if (!pctl->irq) { - ret = -EINVAL; + ret = -ENOMEM; goto clk_error; } - pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER, - &irq_domain_simple_ops, NULL); + for (i = 0; i < pctl->desc->irq_banks; i++) { + pctl->irq[i] = platform_get_irq(pdev, i); + if (pctl->irq[i] < 0) { + ret = pctl->irq[i]; + goto clk_error; + } + } + + pctl->domain = irq_domain_add_linear(node, + pctl->desc->irq_banks * IRQ_PER_BANK, + &irq_domain_simple_ops, + NULL); if (!pctl->domain) { dev_err(&pdev->dev, "Couldn't register IRQ domain\n"); ret = -ENOMEM; goto clk_error; } - for (i = 0; i < SUNXI_IRQ_NUMBER; i++) { + for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) { int irqno = irq_create_mapping(pctl->domain, i); irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip, @@ -891,8 +925,11 @@ int sunxi_pinctrl_init(struct platform_device *pdev, irq_set_chip_data(irqno, pctl); }; - irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler); - irq_set_handler_data(pctl->irq, pctl); + for (i = 0; i < pctl->desc->irq_banks; i++) { + irq_set_chained_handler(pctl->irq[i], + sunxi_pinctrl_irq_handler); + irq_set_handler_data(pctl->irq[i], pctl); + } dev_info(&pdev->dev, "initialized sunXi PIO driver\n"); diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index 7ddcce0f3c27..4245b96c7996 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h @@ -53,7 +53,7 @@ #define PULL_PINS_BITS 2 #define PULL_PINS_MASK 0x03 -#define SUNXI_IRQ_NUMBER 32 +#define IRQ_PER_BANK 32 #define IRQ_CFG_REG 0x200 #define IRQ_CFG_IRQ_PER_REG 8 @@ -68,6 +68,8 @@ #define IRQ_STATUS_IRQ_BITS 1 #define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1) +#define IRQ_MEM_SIZE 0x20 + #define IRQ_EDGE_RISING 0x00 #define IRQ_EDGE_FALLING 0x01 #define IRQ_LEVEL_HIGH 0x02 @@ -115,8 +117,8 @@ struct sunxi_pinctrl { unsigned nfunctions; struct sunxi_pinctrl_group *groups; unsigned ngroups; - int irq; - int irq_array[SUNXI_IRQ_NUMBER]; + int *irq; + unsigned *irq_array; spinlock_t lock; struct pinctrl_dev *pctl_dev; }; @@ -228,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin) static inline u32 sunxi_irq_cfg_reg(u16 irq) { - u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04; - return reg + IRQ_CFG_REG; + u8 bank = irq / IRQ_PER_BANK; + u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04; + + return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg; } static inline u32 sunxi_irq_cfg_offset(u16 irq) @@ -238,10 +242,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq) return irq_num * IRQ_CFG_IRQ_BITS; } +static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank) +{ + return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE; +} + static inline u32 sunxi_irq_ctrl_reg(u16 irq) { - u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04; - return reg + IRQ_CTRL_REG; + u8 bank = irq / IRQ_PER_BANK; + + return sunxi_irq_ctrl_reg_from_bank(bank); } static inline u32 sunxi_irq_ctrl_offset(u16 irq) @@ -250,10 +260,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq) return irq_num * IRQ_CTRL_IRQ_BITS; } +static inline u32 sunxi_irq_status_reg_from_bank(u8 bank) +{ + return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE; +} + static inline u32 sunxi_irq_status_reg(u16 irq) { - u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04; - return reg + IRQ_STATUS_REG; + u8 bank = irq / IRQ_PER_BANK; + + return sunxi_irq_status_reg_from_bank(bank); } static inline u32 sunxi_irq_status_offset(u16 irq) From 22763bf527446fe1f25ac365d846b02fd040e19c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 29 May 2014 11:18:48 +0200 Subject: [PATCH 06/61] pinctrl: spear: switch plgpio to irqchip helpers This switches the SPEAr PLGPIO driver over to using the irqchip helpers. As part of this effort, also get rid of the strange irq_base calculation and failure to use d->hwirq for obtaining a local irqchip offset. Cc: Viresh Kumar Cc: Shiraz Hashim Cc: spear-devel@list.st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/Kconfig | 1 + drivers/pinctrl/spear/pinctrl-plgpio.c | 81 ++++++++++---------------- 2 files changed, 31 insertions(+), 51 deletions(-) diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig index 04d93e602674..9ef18eb958e1 100644 --- a/drivers/pinctrl/spear/Kconfig +++ b/drivers/pinctrl/spear/Kconfig @@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340 config PINCTRL_SPEAR_PLGPIO bool "SPEAr SoC PLGPIO Controller" depends on GPIOLIB && PINCTRL_SPEAR + select GPIOLIB_IRQCHIP help Say yes here to support PLGPIO controller on ST Microelectronics SPEAr SoCs. diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index ff2940e9f2a7..3a20cdc65810 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -11,12 +11,11 @@ #include #include -#include +#include #include -#include -#include -#include #include +#include +#include #include #include #include @@ -54,7 +53,6 @@ struct plgpio_regs { * * lock: lock for guarding gpio registers * base: base address of plgpio block - * irq_base: irq number of plgpio0 * chip: gpio framework specific chip information structure * p2o: function ptr for pin to offset conversion. This is required only for * machines where mapping b/w pin and offset is not 1-to-1. @@ -68,8 +66,6 @@ struct plgpio { spinlock_t lock; void __iomem *base; struct clk *clk; - unsigned irq_base; - struct irq_domain *irq_domain; struct gpio_chip chip; int (*p2o)(int pin); /* pin_to_offset */ int (*o2p)(int offset); /* offset_to_pin */ @@ -280,21 +276,12 @@ disable_clk: pinctrl_free_gpio(gpio); } -static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct plgpio *plgpio = container_of(chip, struct plgpio, chip); - - if (IS_ERR_VALUE(plgpio->irq_base)) - return -EINVAL; - - return irq_find_mapping(plgpio->irq_domain, offset); -} - /* PLGPIO IRQ */ static void plgpio_irq_disable(struct irq_data *d) { - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); + int offset = d->hwirq; unsigned long flags; /* get correct offset for "offset" pin */ @@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d) static void plgpio_irq_enable(struct irq_data *d) { - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); + int offset = d->hwirq; unsigned long flags; /* get correct offset for "offset" pin */ @@ -329,8 +317,9 @@ static void plgpio_irq_enable(struct irq_data *d) static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger) { - struct plgpio *plgpio = irq_data_get_irq_chip_data(d); - int offset = d->irq - plgpio->irq_base; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); + int offset = d->hwirq; void __iomem *reg_off; unsigned int supported_type = 0, val; @@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = { static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) { - struct plgpio *plgpio = irq_get_handler_data(irq); + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct plgpio *plgpio = container_of(gc, struct plgpio, chip); struct irq_chip *irqchip = irq_desc_get_chip(desc); int regs_count, count, pin, offset, i = 0; unsigned long pending; @@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) /* get correct irq line number */ pin = i * MAX_GPIO_PER_REG + pin; - generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin)); + generic_handle_irq( + irq_find_mapping(gc->irqdomain, pin)); } } chained_irq_exit(irqchip, desc); @@ -523,10 +514,9 @@ end: } static int plgpio_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct plgpio *plgpio; struct resource *res; - int ret, irq, i; + int ret, irq; plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); if (!plgpio) { @@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, plgpio); spin_lock_init(&plgpio->lock); - plgpio->irq_base = -1; plgpio->chip.base = -1; plgpio->chip.request = plgpio_request; plgpio->chip.free = plgpio_free; @@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev) plgpio->chip.direction_output = plgpio_direction_output; plgpio->chip.get = plgpio_get_value; plgpio->chip.set = plgpio_set_value; - plgpio->chip.to_irq = plgpio_to_irq; plgpio->chip.label = dev_name(&pdev->dev); plgpio->chip.dev = &pdev->dev; plgpio->chip.owner = THIS_MODULE; + plgpio->chip.of_node = pdev->dev.of_node; if (!IS_ERR(plgpio->clk)) { ret = clk_prepare(plgpio->clk); @@ -592,35 +581,25 @@ static int plgpio_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_info(&pdev->dev, "irqs not supported\n"); + dev_info(&pdev->dev, "PLGPIO registered without IRQs\n"); return 0; } - plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0); - if (IS_ERR_VALUE(plgpio->irq_base)) { - /* we would not support irq for gpio */ - dev_warn(&pdev->dev, "couldn't allocate irq base\n"); - return 0; - } - - plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, - plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); - if (WARN_ON(!plgpio->irq_domain)) { - dev_err(&pdev->dev, "irq domain init failed\n"); - irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); - ret = -ENXIO; + ret = gpiochip_irqchip_add(&plgpio->chip, + &plgpio_irqchip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n"); goto remove_gpiochip; } - irq_set_chained_handler(irq, plgpio_irq_handler); - for (i = 0; i < plgpio->chip.ngpio; i++) { - irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, - handle_simple_irq); - set_irq_flags(i + plgpio->irq_base, IRQF_VALID); - irq_set_chip_data(i + plgpio->irq_base, plgpio); - } + gpiochip_set_chained_irqchip(&plgpio->chip, + &plgpio_irqchip, + irq, + plgpio_irq_handler); - irq_set_handler_data(irq, plgpio); dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); return 0; From 244e95a7ad6a34278aa9c21677785093188d3fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 3 Jun 2014 10:02:36 +0200 Subject: [PATCH 07/61] pinctrl: hide CONFIG_PINMUX and CONFIG_PINCONF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These symbols are supposed to be selected by the drivers actually needing them. The only situation where it would make sense to enable them without a driver selecting them is when an out-of-tree pinctrl driver is used or for compile testing. Signed-off-by: Uwe Kleine-König Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 0042ccb46b9a..4af9e3519388 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -11,10 +11,10 @@ menu "Pin controllers" depends on PINCTRL config PINMUX - bool "Support pin multiplexing controllers" + bool "Support pin multiplexing controllers" if COMPILE_TEST config PINCONF - bool "Support pin configuration controllers" + bool "Support pin configuration controllers" if COMPILE_TEST config GENERIC_PINCONF bool From 7d98fd3218b282d879101a92eb04f8db9505590b Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 10 Jun 2014 11:37:15 +0900 Subject: [PATCH 08/61] pinctrl: sh-pfc: r8a7791: Add HSCIF pin support Signed-off-by: Nobuhiro Iwamatsu Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 250 +++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 2e688dc4a3c8..394b234488cc 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c @@ -1867,6 +1867,192 @@ static const unsigned int eth_rmii_mux[] = { ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK, ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REFCLK_MARK, }; + +/* - HSCIF0 ----------------------------------------------------------------- */ +static const unsigned int hscif0_data_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(7, 3), RCAR_GP_PIN(7, 4), +}; +static const unsigned int hscif0_data_mux[] = { + HRX0_MARK, HTX0_MARK, +}; +static const unsigned int hscif0_clk_pins[] = { + /* SCK */ + RCAR_GP_PIN(7, 2), +}; +static const unsigned int hscif0_clk_mux[] = { + HSCK0_MARK, +}; +static const unsigned int hscif0_ctrl_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(7, 1), RCAR_GP_PIN(7, 0), +}; +static const unsigned int hscif0_ctrl_mux[] = { + HRTS0_N_MARK, HCTS0_N_MARK, +}; +static const unsigned int hscif0_data_b_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 15), +}; +static const unsigned int hscif0_data_b_mux[] = { + HRX0_B_MARK, HTX0_B_MARK, +}; +static const unsigned int hscif0_ctrl_b_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13), +}; +static const unsigned int hscif0_ctrl_b_mux[] = { + HRTS0_N_B_MARK, HCTS0_N_B_MARK, +}; +static const unsigned int hscif0_data_c_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), +}; +static const unsigned int hscif0_data_c_mux[] = { + HRX0_C_MARK, HTX0_C_MARK, +}; +static const unsigned int hscif0_clk_c_pins[] = { + /* SCK */ + RCAR_GP_PIN(5, 31), +}; +static const unsigned int hscif0_clk_c_mux[] = { + HSCK0_C_MARK, +}; +/* - HSCIF1 ----------------------------------------------------------------- */ +static const unsigned int hscif1_data_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(7, 5), RCAR_GP_PIN(7, 6), +}; +static const unsigned int hscif1_data_mux[] = { + HRX1_MARK, HTX1_MARK, +}; +static const unsigned int hscif1_clk_pins[] = { + /* SCK */ + RCAR_GP_PIN(7, 7), +}; +static const unsigned int hscif1_clk_mux[] = { + HSCK1_MARK, +}; +static const unsigned int hscif1_ctrl_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(7, 9), RCAR_GP_PIN(7, 8), +}; +static const unsigned int hscif1_ctrl_mux[] = { + HRTS1_N_MARK, HCTS1_N_MARK, +}; +static const unsigned int hscif1_data_b_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18), +}; +static const unsigned int hscif1_data_b_mux[] = { + HRX1_B_MARK, HTX1_B_MARK, +}; +static const unsigned int hscif1_data_c_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15), +}; +static const unsigned int hscif1_data_c_mux[] = { + HRX1_C_MARK, HTX1_C_MARK, +}; +static const unsigned int hscif1_clk_c_pins[] = { + /* SCK */ + RCAR_GP_PIN(7, 16), +}; +static const unsigned int hscif1_clk_c_mux[] = { + HSCK1_C_MARK, +}; +static const unsigned int hscif1_ctrl_c_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(7, 18), RCAR_GP_PIN(7, 17), +}; +static const unsigned int hscif1_ctrl_c_mux[] = { + HRTS1_N_C_MARK, HCTS1_N_C_MARK, +}; +static const unsigned int hscif1_data_d_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 18), +}; +static const unsigned int hscif1_data_d_mux[] = { + HRX1_D_MARK, HTX1_D_MARK, +}; +static const unsigned int hscif1_data_e_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15), +}; +static const unsigned int hscif1_data_e_mux[] = { + HRX1_C_MARK, HTX1_C_MARK, +}; +static const unsigned int hscif1_clk_e_pins[] = { + /* SCK */ + RCAR_GP_PIN(2, 6), +}; +static const unsigned int hscif1_clk_e_mux[] = { + HSCK1_E_MARK, +}; +static const unsigned int hscif1_ctrl_e_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 7), +}; +static const unsigned int hscif1_ctrl_e_mux[] = { + HRTS1_N_E_MARK, HCTS1_N_E_MARK, +}; +/* - HSCIF2 ----------------------------------------------------------------- */ +static const unsigned int hscif2_data_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17), +}; +static const unsigned int hscif2_data_mux[] = { + HRX2_MARK, HTX2_MARK, +}; +static const unsigned int hscif2_clk_pins[] = { + /* SCK */ + RCAR_GP_PIN(4, 15), +}; +static const unsigned int hscif2_clk_mux[] = { + HSCK2_MARK, +}; +static const unsigned int hscif2_ctrl_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13), +}; +static const unsigned int hscif2_ctrl_mux[] = { + HRTS2_N_MARK, HCTS2_N_MARK, +}; +static const unsigned int hscif2_data_b_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 22), +}; +static const unsigned int hscif2_data_b_mux[] = { + HRX2_B_MARK, HTX2_B_MARK, +}; +static const unsigned int hscif2_ctrl_b_pins[] = { + /* RTS, CTS */ + RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 21), +}; +static const unsigned int hscif2_ctrl_b_mux[] = { + HRTS2_N_B_MARK, HCTS2_N_B_MARK, +}; +static const unsigned int hscif2_data_c_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), +}; +static const unsigned int hscif2_data_c_mux[] = { + HRX2_C_MARK, HTX2_C_MARK, +}; +static const unsigned int hscif2_clk_c_pins[] = { + /* SCK */ + RCAR_GP_PIN(5, 31), +}; +static const unsigned int hscif2_clk_c_mux[] = { + HSCK2_C_MARK, +}; +static const unsigned int hscif2_data_d_pins[] = { + /* RX, TX */ + RCAR_GP_PIN(1, 20), RCAR_GP_PIN(5, 31), +}; +static const unsigned int hscif2_data_d_mux[] = { + HRX2_B_MARK, HTX2_D_MARK, +}; /* - I2C0 ------------------------------------------------------------------- */ static const unsigned int i2c0_pins[] = { /* SCL, SDA */ @@ -3885,6 +4071,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(eth_magic), SH_PFC_PIN_GROUP(eth_mdio), SH_PFC_PIN_GROUP(eth_rmii), + SH_PFC_PIN_GROUP(hscif0_data), + SH_PFC_PIN_GROUP(hscif0_clk), + SH_PFC_PIN_GROUP(hscif0_ctrl), + SH_PFC_PIN_GROUP(hscif0_data_b), + SH_PFC_PIN_GROUP(hscif0_ctrl_b), + SH_PFC_PIN_GROUP(hscif0_data_c), + SH_PFC_PIN_GROUP(hscif0_clk_c), + SH_PFC_PIN_GROUP(hscif1_data), + SH_PFC_PIN_GROUP(hscif1_clk), + SH_PFC_PIN_GROUP(hscif1_ctrl), + SH_PFC_PIN_GROUP(hscif1_data_b), + SH_PFC_PIN_GROUP(hscif1_data_c), + SH_PFC_PIN_GROUP(hscif1_clk_c), + SH_PFC_PIN_GROUP(hscif1_ctrl_c), + SH_PFC_PIN_GROUP(hscif1_data_d), + SH_PFC_PIN_GROUP(hscif1_data_e), + SH_PFC_PIN_GROUP(hscif1_clk_e), + SH_PFC_PIN_GROUP(hscif1_ctrl_e), + SH_PFC_PIN_GROUP(hscif2_data), + SH_PFC_PIN_GROUP(hscif2_clk), + SH_PFC_PIN_GROUP(hscif2_ctrl), + SH_PFC_PIN_GROUP(hscif2_data_b), + SH_PFC_PIN_GROUP(hscif2_ctrl_b), + SH_PFC_PIN_GROUP(hscif2_data_c), + SH_PFC_PIN_GROUP(hscif2_clk_c), + SH_PFC_PIN_GROUP(hscif2_data_d), SH_PFC_PIN_GROUP(i2c0), SH_PFC_PIN_GROUP(i2c0_b), SH_PFC_PIN_GROUP(i2c0_c), @@ -4183,6 +4395,41 @@ static const char * const eth_groups[] = { "eth_rmii", }; +static const char * const hscif0_groups[] = { + "hscif0_data", + "hscif0_clk", + "hscif0_ctrl", + "hscif0_data_b", + "hscif0_ctrl_b", + "hscif0_data_c", + "hscif0_clk_c", +}; + +static const char * const hscif1_groups[] = { + "hscif1_data", + "hscif1_clk", + "hscif1_ctrl", + "hscif1_data_b", + "hscif1_data_c", + "hscif1_clk_c", + "hscif1_ctrl_c", + "hscif1_data_d", + "hscif1_data_e", + "hscif1_clk_e", + "hscif1_ctrl_e", +}; + +static const char * const hscif2_groups[] = { + "hscif2_data", + "hscif2_clk", + "hscif2_ctrl", + "hscif2_data_b", + "hscif2_ctrl_b", + "hscif2_data_c", + "hscif2_clk_c", + "hscif2_data_d", +}; + static const char * const i2c0_groups[] = { "i2c0", "i2c0_b", @@ -4547,6 +4794,9 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), SH_PFC_FUNCTION(eth), + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), + SH_PFC_FUNCTION(hscif2), SH_PFC_FUNCTION(i2c0), SH_PFC_FUNCTION(i2c1), SH_PFC_FUNCTION(i2c2), From 578c0a8721278770b851ecd23c5873ceda598ae8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 29 Jun 2014 16:10:59 +0200 Subject: [PATCH 09/61] pinctrl: sunxi: Add IRQCHIP_SKIP_SET_WAKE flag for pinctrl irq chip The sunxi pinctrl irq chip driver does not support wakeup at the moment. Adding IRQCHIP_SKIP_SET_WAKE lets the irqs work with drivers using wakeup. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index d989a10f7b10..c19933737fa5 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -630,6 +630,7 @@ static struct irq_chip sunxi_pinctrl_irq_chip = { .irq_mask = sunxi_pinctrl_irq_mask, .irq_unmask = sunxi_pinctrl_irq_unmask, .irq_set_type = sunxi_pinctrl_irq_set_type, + .flags = IRQCHIP_SKIP_SET_WAKE, }; static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) From fea6d8efd023a2438c848c049480ea67ea0bca16 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 29 Jun 2014 16:11:00 +0200 Subject: [PATCH 10/61] pinctrl: sunxi: Move setting of mux to irq type With level triggered interrupt mask / unmask will get called for each interrupt, doing the somewhat expensive mux setting on each unmask thus is not a good idea. Instead add a request_resources callback and do it there. Signed-off-by: Hans de Goede Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index c19933737fa5..8bdd65b924ca 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -531,6 +531,21 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) return irq_find_mapping(pctl->domain, desc->irqnum); } +static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) +{ + struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); + struct sunxi_desc_function *func; + + func = sunxi_pinctrl_desc_find_function_by_pin(pctl, + pctl->irq_array[d->hwirq], "irq"); + if (!func) + return -EINVAL; + + /* Change muxing to INT mode */ + sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); + + return 0; +} static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) @@ -603,19 +618,11 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d) static void sunxi_pinctrl_irq_unmask(struct irq_data *d) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); - struct sunxi_desc_function *func; u32 reg = sunxi_irq_ctrl_reg(d->hwirq); u8 idx = sunxi_irq_ctrl_offset(d->hwirq); unsigned long flags; u32 val; - func = sunxi_pinctrl_desc_find_function_by_pin(pctl, - pctl->irq_array[d->hwirq], - "irq"); - - /* Change muxing to INT mode */ - sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); - spin_lock_irqsave(&pctl->lock, flags); /* Unmask the IRQ */ @@ -629,6 +636,7 @@ static struct irq_chip sunxi_pinctrl_irq_chip = { .irq_ack = sunxi_pinctrl_irq_ack, .irq_mask = sunxi_pinctrl_irq_mask, .irq_unmask = sunxi_pinctrl_irq_unmask, + .irq_request_resources = sunxi_pinctrl_irq_request_resources, .irq_set_type = sunxi_pinctrl_irq_set_type, .flags = IRQCHIP_SKIP_SET_WAKE, }; From f4c51c103b6a7373186dd6dc80759bc707bffdb4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 29 Jun 2014 16:11:01 +0200 Subject: [PATCH 11/61] pinctrl: sunxi: Properly handle level triggered gpio interrupts For level triggered gpio interrupts we need to use handle_fasteoi_irq, like we do with the irq-sunxi-nmi driver. This is necessary to give threaded interrupt handlers a chance to actuall clear the source of the interrupt (which may involve sleeping waiting for i2c / spi / mmc transfers), before acknowledging the interrupt. Signed-off-by: Hans de Goede Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 39 +++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 8bdd65b924ca..c1f053014dd6 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -31,6 +31,9 @@ #include "../core.h" #include "pinctrl-sunxi.h" +static struct irq_chip sunxi_pinctrl_edge_irq_chip; +static struct irq_chip sunxi_pinctrl_level_irq_chip; + static struct sunxi_pinctrl_group * sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group) { @@ -547,10 +550,10 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) return 0; } -static int sunxi_pinctrl_irq_set_type(struct irq_data *d, - unsigned int type) +static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); + struct irq_desc *desc = container_of(d, struct irq_desc, irq_data); u32 reg = sunxi_irq_cfg_reg(d->hwirq); u8 index = sunxi_irq_cfg_offset(d->hwirq); unsigned long flags; @@ -577,6 +580,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, return -EINVAL; } + if (type & IRQ_TYPE_LEVEL_MASK) { + d->chip = &sunxi_pinctrl_level_irq_chip; + desc->handle_irq = handle_fasteoi_irq; + } else { + d->chip = &sunxi_pinctrl_edge_irq_chip; + desc->handle_irq = handle_edge_irq; + } + spin_lock_irqsave(&pctl->lock, flags); regval = readl(pctl->membase + reg); @@ -632,7 +643,7 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d) spin_unlock_irqrestore(&pctl->lock, flags); } -static struct irq_chip sunxi_pinctrl_irq_chip = { +static struct irq_chip sunxi_pinctrl_edge_irq_chip = { .irq_ack = sunxi_pinctrl_irq_ack, .irq_mask = sunxi_pinctrl_irq_mask, .irq_unmask = sunxi_pinctrl_irq_unmask, @@ -641,6 +652,16 @@ static struct irq_chip sunxi_pinctrl_irq_chip = { .flags = IRQCHIP_SKIP_SET_WAKE, }; +static struct irq_chip sunxi_pinctrl_level_irq_chip = { + .irq_eoi = sunxi_pinctrl_irq_ack, + .irq_mask = sunxi_pinctrl_irq_mask, + .irq_unmask = sunxi_pinctrl_irq_unmask, + .irq_request_resources = sunxi_pinctrl_irq_request_resources, + .irq_set_type = sunxi_pinctrl_irq_set_type, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED | + IRQCHIP_EOI_IF_HANDLED, +}; + static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); @@ -657,9 +678,6 @@ static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) reg = sunxi_irq_status_reg_from_bank(bank); val = readl(pctl->membase + reg); - /* Clear all interrupts */ - writel(val, pctl->membase + reg); - if (val) { int irqoffset; @@ -929,12 +947,17 @@ int sunxi_pinctrl_init(struct platform_device *pdev, for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) { int irqno = irq_create_mapping(pctl->domain, i); - irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip, - handle_simple_irq); + irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip, + handle_edge_irq); irq_set_chip_data(irqno, pctl); }; for (i = 0; i < pctl->desc->irq_banks; i++) { + /* Mask and clear all IRQs before registering a handler */ + writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i)); + writel(0xffffffff, + pctl->membase + sunxi_irq_status_reg_from_bank(i)); + irq_set_chained_handler(pctl->irq[i], sunxi_pinctrl_irq_handler); irq_set_handler_data(pctl->irq[i], pctl); From d61e23e5250e2d189f6bcdac71abf3e997398714 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 29 Jun 2014 16:11:02 +0200 Subject: [PATCH 12/61] pinctrl: sunxi: Define enable / disable irq callbacks Some drivers use disable_irq / enable_irq and do the work clearing the source in another thread instead of using a threaded interrupt handler. The irqchip used not having irq_disable and irq_enable callbacks in this case, will lead to unnecessary spurious interrupts: On a disable_irq in a chip without a handler for this, the irq core will remember the disable, but not actually call into the irqchip. With a level triggered interrupt (where the source has not been cleared) this will lead to an immediate retrigger, at which point the irq-core will mask the irq. So having an irq_disable callback in the irqchip will save us the interrupt firing a 2nd time for nothing. Drivers using disable / enable_irq like this, will call enable_irq when they finally have cleared the interrupt source, without an enable_irq callback, this will turn into an unmask, at which point the irq will trigger immediately because when it was originally acked the level was still high, so the ack was a nop. Signed-off-by: Hans de Goede Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index c1f053014dd6..c641566c6efd 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -643,6 +643,12 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d) spin_unlock_irqrestore(&pctl->lock, flags); } +static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d) +{ + sunxi_pinctrl_irq_ack(d); + sunxi_pinctrl_irq_unmask(d); +} + static struct irq_chip sunxi_pinctrl_edge_irq_chip = { .irq_ack = sunxi_pinctrl_irq_ack, .irq_mask = sunxi_pinctrl_irq_mask, @@ -656,6 +662,10 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip = { .irq_eoi = sunxi_pinctrl_irq_ack, .irq_mask = sunxi_pinctrl_irq_mask, .irq_unmask = sunxi_pinctrl_irq_unmask, + /* Define irq_enable / disable to avoid spurious irqs for drivers + * using these to suppress irqs while they clear the irq source */ + .irq_enable = sunxi_pinctrl_irq_ack_unmask, + .irq_disable = sunxi_pinctrl_irq_mask, .irq_request_resources = sunxi_pinctrl_irq_request_resources, .irq_set_type = sunxi_pinctrl_irq_set_type, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED | From 0d3bafac658de2f8e267df805a61e597449699b5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 1 Jul 2014 00:04:59 +0800 Subject: [PATCH 13/61] pinctrl: sunxi: Fix multi bank interrupt support in gpio_to_irq When mapping the interrupts, the gpio_to_irq function did not consider the bank number of the gpio pin in question, only the offset or the interrupt number in the bank. As a result, requests for interrupts in the later banks get mapped to the first bank. This issue was discovered while enabling mmc on the new sun8i platform. The tablet I have uses a pin/interrupt from the second bank to do mmc card detection. Tested on this very device with register inspection and actual mmc card insertion/removal. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index c641566c6efd..47f5e1bc50d0 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -520,6 +520,7 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); struct sunxi_desc_function *desc; + unsigned irqnum; if (offset >= chip->ngpio) return -ENXIO; @@ -528,10 +529,12 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) if (!desc) return -EINVAL; - dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", - chip->label, offset + chip->base, desc->irqnum); + irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum; - return irq_find_mapping(pctl->domain, desc->irqnum); + dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", + chip->label, offset + chip->base, irqnum); + + return irq_find_mapping(pctl->domain, irqnum); } static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) From 4877e51ed791ac0098471d547f9f8f84c147e1c6 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 3 Jun 2014 20:33:49 +0400 Subject: [PATCH 14/61] pinctrl: Add i.MX1 pincontrol driver This patch adds pincontrol driver for Freescale i.MX1 SOCs. Acked-by: Shawn Guo Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 7 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-imx1.c | 279 +++++++++++++++++++++++++++++++++ 3 files changed, 287 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-imx1.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4af9e3519388..2744fa2825e0 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -130,6 +130,13 @@ config PINCTRL_IMX1_CORE select PINMUX select PINCONF +config PINCTRL_IMX1 + bool "IMX1 pinctrl driver" + depends on SOC_IMX1 + select PINCTRL_IMX1_CORE + help + Say Y here to enable the imx1 pinctrl driver + config PINCTRL_IMX27 bool "IMX27 pinctrl driver" depends on SOC_IMX27 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index c4b5d405b8f5..c7d8f1b7311f 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o +obj-$(CONFIG_PINCTRL_IMX1) += pinctrl-imx1.o obj-$(CONFIG_PINCTRL_IMX27) += pinctrl-imx27.o obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o obj-$(CONFIG_PINCTRL_IMX50) += pinctrl-imx50.o diff --git a/drivers/pinctrl/pinctrl-imx1.c b/drivers/pinctrl/pinctrl-imx1.c new file mode 100644 index 000000000000..533a6e519648 --- /dev/null +++ b/drivers/pinctrl/pinctrl-imx1.c @@ -0,0 +1,279 @@ +/* + * i.MX1 pinctrl driver based on imx pinmux core + * + * Copyright (C) 2014 Alexander Shiyan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include + +#include "pinctrl-imx1.h" + +#define PAD_ID(port, pin) ((port) * 32 + (pin)) +#define PA 0 +#define PB 1 +#define PC 2 +#define PD 3 + +enum imx1_pads { + MX1_PAD_A24 = PAD_ID(PA, 0), + MX1_PAD_TIN = PAD_ID(PA, 1), + MX1_PAD_PWMO = PAD_ID(PA, 2), + MX1_PAD_CSI_MCLK = PAD_ID(PA, 3), + MX1_PAD_CSI_D0 = PAD_ID(PA, 4), + MX1_PAD_CSI_D1 = PAD_ID(PA, 5), + MX1_PAD_CSI_D2 = PAD_ID(PA, 6), + MX1_PAD_CSI_D3 = PAD_ID(PA, 7), + MX1_PAD_CSI_D4 = PAD_ID(PA, 8), + MX1_PAD_CSI_D5 = PAD_ID(PA, 9), + MX1_PAD_CSI_D6 = PAD_ID(PA, 10), + MX1_PAD_CSI_D7 = PAD_ID(PA, 11), + MX1_PAD_CSI_VSYNC = PAD_ID(PA, 12), + MX1_PAD_CSI_HSYNC = PAD_ID(PA, 13), + MX1_PAD_CSI_PIXCLK = PAD_ID(PA, 14), + MX1_PAD_I2C_SDA = PAD_ID(PA, 15), + MX1_PAD_I2C_SCL = PAD_ID(PA, 16), + MX1_PAD_DTACK = PAD_ID(PA, 17), + MX1_PAD_BCLK = PAD_ID(PA, 18), + MX1_PAD_LBA = PAD_ID(PA, 19), + MX1_PAD_ECB = PAD_ID(PA, 20), + MX1_PAD_A0 = PAD_ID(PA, 21), + MX1_PAD_CS4 = PAD_ID(PA, 22), + MX1_PAD_CS5 = PAD_ID(PA, 23), + MX1_PAD_A16 = PAD_ID(PA, 24), + MX1_PAD_A17 = PAD_ID(PA, 25), + MX1_PAD_A18 = PAD_ID(PA, 26), + MX1_PAD_A19 = PAD_ID(PA, 27), + MX1_PAD_A20 = PAD_ID(PA, 28), + MX1_PAD_A21 = PAD_ID(PA, 29), + MX1_PAD_A22 = PAD_ID(PA, 30), + MX1_PAD_A23 = PAD_ID(PA, 31), + MX1_PAD_SD_DAT0 = PAD_ID(PB, 8), + MX1_PAD_SD_DAT1 = PAD_ID(PB, 9), + MX1_PAD_SD_DAT2 = PAD_ID(PB, 10), + MX1_PAD_SD_DAT3 = PAD_ID(PB, 11), + MX1_PAD_SD_SCLK = PAD_ID(PB, 12), + MX1_PAD_SD_CMD = PAD_ID(PB, 13), + MX1_PAD_SIM_SVEN = PAD_ID(PB, 14), + MX1_PAD_SIM_PD = PAD_ID(PB, 15), + MX1_PAD_SIM_TX = PAD_ID(PB, 16), + MX1_PAD_SIM_RX = PAD_ID(PB, 17), + MX1_PAD_SIM_RST = PAD_ID(PB, 18), + MX1_PAD_SIM_CLK = PAD_ID(PB, 19), + MX1_PAD_USBD_AFE = PAD_ID(PB, 20), + MX1_PAD_USBD_OE = PAD_ID(PB, 21), + MX1_PAD_USBD_RCV = PAD_ID(PB, 22), + MX1_PAD_USBD_SUSPND = PAD_ID(PB, 23), + MX1_PAD_USBD_VP = PAD_ID(PB, 24), + MX1_PAD_USBD_VM = PAD_ID(PB, 25), + MX1_PAD_USBD_VPO = PAD_ID(PB, 26), + MX1_PAD_USBD_VMO = PAD_ID(PB, 27), + MX1_PAD_UART2_CTS = PAD_ID(PB, 28), + MX1_PAD_UART2_RTS = PAD_ID(PB, 29), + MX1_PAD_UART2_TXD = PAD_ID(PB, 30), + MX1_PAD_UART2_RXD = PAD_ID(PB, 31), + MX1_PAD_SSI_RXFS = PAD_ID(PC, 3), + MX1_PAD_SSI_RXCLK = PAD_ID(PC, 4), + MX1_PAD_SSI_RXDAT = PAD_ID(PC, 5), + MX1_PAD_SSI_TXDAT = PAD_ID(PC, 6), + MX1_PAD_SSI_TXFS = PAD_ID(PC, 7), + MX1_PAD_SSI_TXCLK = PAD_ID(PC, 8), + MX1_PAD_UART1_CTS = PAD_ID(PC, 9), + MX1_PAD_UART1_RTS = PAD_ID(PC, 10), + MX1_PAD_UART1_TXD = PAD_ID(PC, 11), + MX1_PAD_UART1_RXD = PAD_ID(PC, 12), + MX1_PAD_SPI1_RDY = PAD_ID(PC, 13), + MX1_PAD_SPI1_SCLK = PAD_ID(PC, 14), + MX1_PAD_SPI1_SS = PAD_ID(PC, 15), + MX1_PAD_SPI1_MISO = PAD_ID(PC, 16), + MX1_PAD_SPI1_MOSI = PAD_ID(PC, 17), + MX1_PAD_BT13 = PAD_ID(PC, 19), + MX1_PAD_BT12 = PAD_ID(PC, 20), + MX1_PAD_BT11 = PAD_ID(PC, 21), + MX1_PAD_BT10 = PAD_ID(PC, 22), + MX1_PAD_BT9 = PAD_ID(PC, 23), + MX1_PAD_BT8 = PAD_ID(PC, 24), + MX1_PAD_BT7 = PAD_ID(PC, 25), + MX1_PAD_BT6 = PAD_ID(PC, 26), + MX1_PAD_BT5 = PAD_ID(PC, 27), + MX1_PAD_BT4 = PAD_ID(PC, 28), + MX1_PAD_BT3 = PAD_ID(PC, 29), + MX1_PAD_BT2 = PAD_ID(PC, 30), + MX1_PAD_BT1 = PAD_ID(PC, 31), + MX1_PAD_LSCLK = PAD_ID(PD, 6), + MX1_PAD_REV = PAD_ID(PD, 7), + MX1_PAD_CLS = PAD_ID(PD, 8), + MX1_PAD_PS = PAD_ID(PD, 9), + MX1_PAD_SPL_SPR = PAD_ID(PD, 10), + MX1_PAD_CONTRAST = PAD_ID(PD, 11), + MX1_PAD_ACD_OE = PAD_ID(PD, 12), + MX1_PAD_LP_HSYNC = PAD_ID(PD, 13), + MX1_PAD_FLM_VSYNC = PAD_ID(PD, 14), + MX1_PAD_LD0 = PAD_ID(PD, 15), + MX1_PAD_LD1 = PAD_ID(PD, 16), + MX1_PAD_LD2 = PAD_ID(PD, 17), + MX1_PAD_LD3 = PAD_ID(PD, 18), + MX1_PAD_LD4 = PAD_ID(PD, 19), + MX1_PAD_LD5 = PAD_ID(PD, 20), + MX1_PAD_LD6 = PAD_ID(PD, 21), + MX1_PAD_LD7 = PAD_ID(PD, 22), + MX1_PAD_LD8 = PAD_ID(PD, 23), + MX1_PAD_LD9 = PAD_ID(PD, 24), + MX1_PAD_LD10 = PAD_ID(PD, 25), + MX1_PAD_LD11 = PAD_ID(PD, 26), + MX1_PAD_LD12 = PAD_ID(PD, 27), + MX1_PAD_LD13 = PAD_ID(PD, 28), + MX1_PAD_LD14 = PAD_ID(PD, 29), + MX1_PAD_LD15 = PAD_ID(PD, 30), + MX1_PAD_TMR2OUT = PAD_ID(PD, 31), +}; + +/* Pad names for the pinmux subsystem */ +static const struct pinctrl_pin_desc imx1_pinctrl_pads[] = { + IMX_PINCTRL_PIN(MX1_PAD_A24), + IMX_PINCTRL_PIN(MX1_PAD_TIN), + IMX_PINCTRL_PIN(MX1_PAD_PWMO), + IMX_PINCTRL_PIN(MX1_PAD_CSI_MCLK), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D0), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D1), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D2), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D3), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D4), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D5), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D6), + IMX_PINCTRL_PIN(MX1_PAD_CSI_D7), + IMX_PINCTRL_PIN(MX1_PAD_CSI_VSYNC), + IMX_PINCTRL_PIN(MX1_PAD_CSI_HSYNC), + IMX_PINCTRL_PIN(MX1_PAD_CSI_PIXCLK), + IMX_PINCTRL_PIN(MX1_PAD_I2C_SDA), + IMX_PINCTRL_PIN(MX1_PAD_I2C_SCL), + IMX_PINCTRL_PIN(MX1_PAD_DTACK), + IMX_PINCTRL_PIN(MX1_PAD_BCLK), + IMX_PINCTRL_PIN(MX1_PAD_LBA), + IMX_PINCTRL_PIN(MX1_PAD_ECB), + IMX_PINCTRL_PIN(MX1_PAD_A0), + IMX_PINCTRL_PIN(MX1_PAD_CS4), + IMX_PINCTRL_PIN(MX1_PAD_CS5), + IMX_PINCTRL_PIN(MX1_PAD_A16), + IMX_PINCTRL_PIN(MX1_PAD_A17), + IMX_PINCTRL_PIN(MX1_PAD_A18), + IMX_PINCTRL_PIN(MX1_PAD_A19), + IMX_PINCTRL_PIN(MX1_PAD_A20), + IMX_PINCTRL_PIN(MX1_PAD_A21), + IMX_PINCTRL_PIN(MX1_PAD_A22), + IMX_PINCTRL_PIN(MX1_PAD_A23), + IMX_PINCTRL_PIN(MX1_PAD_SD_DAT0), + IMX_PINCTRL_PIN(MX1_PAD_SD_DAT1), + IMX_PINCTRL_PIN(MX1_PAD_SD_DAT2), + IMX_PINCTRL_PIN(MX1_PAD_SD_DAT3), + IMX_PINCTRL_PIN(MX1_PAD_SD_SCLK), + IMX_PINCTRL_PIN(MX1_PAD_SD_CMD), + IMX_PINCTRL_PIN(MX1_PAD_SIM_SVEN), + IMX_PINCTRL_PIN(MX1_PAD_SIM_PD), + IMX_PINCTRL_PIN(MX1_PAD_SIM_TX), + IMX_PINCTRL_PIN(MX1_PAD_SIM_RX), + IMX_PINCTRL_PIN(MX1_PAD_SIM_CLK), + IMX_PINCTRL_PIN(MX1_PAD_USBD_AFE), + IMX_PINCTRL_PIN(MX1_PAD_USBD_OE), + IMX_PINCTRL_PIN(MX1_PAD_USBD_RCV), + IMX_PINCTRL_PIN(MX1_PAD_USBD_SUSPND), + IMX_PINCTRL_PIN(MX1_PAD_USBD_VP), + IMX_PINCTRL_PIN(MX1_PAD_USBD_VM), + IMX_PINCTRL_PIN(MX1_PAD_USBD_VPO), + IMX_PINCTRL_PIN(MX1_PAD_USBD_VMO), + IMX_PINCTRL_PIN(MX1_PAD_UART2_CTS), + IMX_PINCTRL_PIN(MX1_PAD_UART2_RTS), + IMX_PINCTRL_PIN(MX1_PAD_UART2_TXD), + IMX_PINCTRL_PIN(MX1_PAD_UART2_RXD), + IMX_PINCTRL_PIN(MX1_PAD_SSI_RXFS), + IMX_PINCTRL_PIN(MX1_PAD_SSI_RXCLK), + IMX_PINCTRL_PIN(MX1_PAD_SSI_RXDAT), + IMX_PINCTRL_PIN(MX1_PAD_SSI_TXDAT), + IMX_PINCTRL_PIN(MX1_PAD_SSI_TXFS), + IMX_PINCTRL_PIN(MX1_PAD_SSI_TXCLK), + IMX_PINCTRL_PIN(MX1_PAD_UART1_CTS), + IMX_PINCTRL_PIN(MX1_PAD_UART1_RTS), + IMX_PINCTRL_PIN(MX1_PAD_UART1_TXD), + IMX_PINCTRL_PIN(MX1_PAD_UART1_RXD), + IMX_PINCTRL_PIN(MX1_PAD_SPI1_RDY), + IMX_PINCTRL_PIN(MX1_PAD_SPI1_SCLK), + IMX_PINCTRL_PIN(MX1_PAD_SPI1_SS), + IMX_PINCTRL_PIN(MX1_PAD_SPI1_MISO), + IMX_PINCTRL_PIN(MX1_PAD_SPI1_MOSI), + IMX_PINCTRL_PIN(MX1_PAD_BT13), + IMX_PINCTRL_PIN(MX1_PAD_BT12), + IMX_PINCTRL_PIN(MX1_PAD_BT11), + IMX_PINCTRL_PIN(MX1_PAD_BT10), + IMX_PINCTRL_PIN(MX1_PAD_BT9), + IMX_PINCTRL_PIN(MX1_PAD_BT8), + IMX_PINCTRL_PIN(MX1_PAD_BT7), + IMX_PINCTRL_PIN(MX1_PAD_BT6), + IMX_PINCTRL_PIN(MX1_PAD_BT5), + IMX_PINCTRL_PIN(MX1_PAD_BT4), + IMX_PINCTRL_PIN(MX1_PAD_BT3), + IMX_PINCTRL_PIN(MX1_PAD_BT2), + IMX_PINCTRL_PIN(MX1_PAD_BT1), + IMX_PINCTRL_PIN(MX1_PAD_LSCLK), + IMX_PINCTRL_PIN(MX1_PAD_REV), + IMX_PINCTRL_PIN(MX1_PAD_CLS), + IMX_PINCTRL_PIN(MX1_PAD_PS), + IMX_PINCTRL_PIN(MX1_PAD_SPL_SPR), + IMX_PINCTRL_PIN(MX1_PAD_CONTRAST), + IMX_PINCTRL_PIN(MX1_PAD_ACD_OE), + IMX_PINCTRL_PIN(MX1_PAD_LP_HSYNC), + IMX_PINCTRL_PIN(MX1_PAD_FLM_VSYNC), + IMX_PINCTRL_PIN(MX1_PAD_LD0), + IMX_PINCTRL_PIN(MX1_PAD_LD1), + IMX_PINCTRL_PIN(MX1_PAD_LD2), + IMX_PINCTRL_PIN(MX1_PAD_LD3), + IMX_PINCTRL_PIN(MX1_PAD_LD4), + IMX_PINCTRL_PIN(MX1_PAD_LD5), + IMX_PINCTRL_PIN(MX1_PAD_LD6), + IMX_PINCTRL_PIN(MX1_PAD_LD7), + IMX_PINCTRL_PIN(MX1_PAD_LD8), + IMX_PINCTRL_PIN(MX1_PAD_LD9), + IMX_PINCTRL_PIN(MX1_PAD_LD10), + IMX_PINCTRL_PIN(MX1_PAD_LD11), + IMX_PINCTRL_PIN(MX1_PAD_LD12), + IMX_PINCTRL_PIN(MX1_PAD_LD13), + IMX_PINCTRL_PIN(MX1_PAD_LD14), + IMX_PINCTRL_PIN(MX1_PAD_LD15), + IMX_PINCTRL_PIN(MX1_PAD_TMR2OUT), +}; + +static struct imx1_pinctrl_soc_info imx1_pinctrl_info = { + .pins = imx1_pinctrl_pads, + .npins = ARRAY_SIZE(imx1_pinctrl_pads), +}; + +static int __init imx1_pinctrl_probe(struct platform_device *pdev) +{ + return imx1_pinctrl_core_probe(pdev, &imx1_pinctrl_info); +} + +static const struct of_device_id imx1_pinctrl_of_match[] = { + { .compatible = "fsl,imx1-iomuxc", }, + { } +}; +MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match); + +static struct platform_driver imx1_pinctrl_driver = { + .driver = { + .name = "imx1-pinctrl", + .owner = THIS_MODULE, + .of_match_table = imx1_pinctrl_of_match, + }, + .remove = imx1_pinctrl_core_remove, +}; +module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe); + +MODULE_AUTHOR("Alexander Shiyan "); +MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver"); +MODULE_LICENSE("GPL"); From ae23f9b1afa718d7eaa52b111fa41f0ee31a0a33 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 3 Jun 2014 20:34:14 +0400 Subject: [PATCH 15/61] pinctrl: i.MX27: Remove unused structure definition struct imx27_pinctrl_private is not used in the driver. Remove this definition. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx27.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-imx27.c b/drivers/pinctrl/pinctrl-imx27.c index 417c99205bc2..27ae7ce1b0d4 100644 --- a/drivers/pinctrl/pinctrl-imx27.c +++ b/drivers/pinctrl/pinctrl-imx27.c @@ -440,12 +440,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = { { /* sentinel */ } }; -struct imx27_pinctrl_private { - int num_gpio_childs; - struct platform_device **gpio_dev; - struct mxc_gpio_platform_data *gpio_pdata; -}; - static int imx27_pinctrl_probe(struct platform_device *pdev) { return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info); From 607af165c0470e7297e1a04f528176222849b5a9 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 3 Jun 2014 20:34:15 +0400 Subject: [PATCH 16/61] pinctrl: i.MX27: Remove nonexistent pad definitions Pads for PB0-PB3, PC0-PC4, PE26-PE31 and PF24-PF31 does not exist on the i.MX27 SOC. There is no reason to define them, the presence of such definitions in the DTS files is a bug. This patch removes these nonexistent pad definitions. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- arch/arm/boot/dts/imx27-pinfunc.h | 46 ------------------------------- drivers/pinctrl/pinctrl-imx27.c | 46 ------------------------------- 2 files changed, 92 deletions(-) diff --git a/arch/arm/boot/dts/imx27-pinfunc.h b/arch/arm/boot/dts/imx27-pinfunc.h index f5387b4de577..597bb5f74dcc 100644 --- a/arch/arm/boot/dts/imx27-pinfunc.h +++ b/arch/arm/boot/dts/imx27-pinfunc.h @@ -101,14 +101,6 @@ #define MX27_PAD_CONTRAST__GPIO1_30 0x1e 0x032 #define MX27_PAD_OE_ACD__OE_ACD 0x1f 0x004 #define MX27_PAD_OE_ACD__GPIO1_31 0x1f 0x032 -#define MX27_PAD_UNUSED0__UNUSED0 0x20 0x004 -#define MX27_PAD_UNUSED0__GPIO2_0 0x20 0x032 -#define MX27_PAD_UNUSED1__UNUSED1 0x21 0x004 -#define MX27_PAD_UNUSED1__GPIO2_1 0x21 0x032 -#define MX27_PAD_UNUSED2__UNUSED2 0x22 0x004 -#define MX27_PAD_UNUSED2__GPIO2_2 0x22 0x032 -#define MX27_PAD_UNUSED3__UNUSED3 0x23 0x004 -#define MX27_PAD_UNUSED3__GPIO2_3 0x23 0x032 #define MX27_PAD_SD2_D0__SD2_D0 0x24 0x004 #define MX27_PAD_SD2_D0__MSHC_DATA0 0x24 0x005 #define MX27_PAD_SD2_D0__GPIO2_4 0x24 0x032 @@ -183,16 +175,6 @@ #define MX27_PAD_USBH1_RXDP__USBH1_RXDP 0x3f 0x004 #define MX27_PAD_USBH1_RXDP__UART4_RXD 0x3f 0x001 #define MX27_PAD_USBH1_RXDP__GPIO2_31 0x3f 0x032 -#define MX27_PAD_UNUSED4__UNUSED4 0x40 0x004 -#define MX27_PAD_UNUSED4__GPIO3_0 0x40 0x032 -#define MX27_PAD_UNUSED5__UNUSED5 0x41 0x004 -#define MX27_PAD_UNUSED5__GPIO3_1 0x41 0x032 -#define MX27_PAD_UNUSED6__UNUSED6 0x42 0x004 -#define MX27_PAD_UNUSED6__GPIO3_2 0x42 0x032 -#define MX27_PAD_UNUSED7__UNUSED7 0x43 0x004 -#define MX27_PAD_UNUSED7__GPIO3_3 0x43 0x032 -#define MX27_PAD_UNUSED8__UNUSED8 0x44 0x004 -#define MX27_PAD_UNUSED8__GPIO3_4 0x44 0x032 #define MX27_PAD_I2C2_SDA__I2C2_SDA 0x45 0x004 #define MX27_PAD_I2C2_SDA__GPIO3_5 0x45 0x032 #define MX27_PAD_I2C2_SCL__I2C2_SCL 0x46 0x004 @@ -422,18 +404,6 @@ #define MX27_PAD_USBOTG_CLK__GPIO5_24 0x98 0x032 #define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x99 0x004 #define MX27_PAD_USBOTG_DATA7__GPIO5_25 0x99 0x032 -#define MX27_PAD_UNUSED9__UNUSED9 0x9a 0x004 -#define MX27_PAD_UNUSED9__GPIO5_26 0x9a 0x032 -#define MX27_PAD_UNUSED10__UNUSED10 0x9b 0x004 -#define MX27_PAD_UNUSED10__GPIO5_27 0x9b 0x032 -#define MX27_PAD_UNUSED11__UNUSED11 0x9c 0x004 -#define MX27_PAD_UNUSED11__GPIO5_28 0x9c 0x032 -#define MX27_PAD_UNUSED12__UNUSED12 0x9d 0x004 -#define MX27_PAD_UNUSED12__GPIO5_29 0x9d 0x032 -#define MX27_PAD_UNUSED13__UNUSED13 0x9e 0x004 -#define MX27_PAD_UNUSED13__GPIO5_30 0x9e 0x032 -#define MX27_PAD_UNUSED14__UNUSED14 0x9f 0x004 -#define MX27_PAD_UNUSED14__GPIO5_31 0x9f 0x032 #define MX27_PAD_NFRB__NFRB 0xa0 0x000 #define MX27_PAD_NFRB__ETMTRACEPKT3 0xa0 0x005 #define MX27_PAD_NFRB__GPIO6_0 0xa0 0x032 @@ -506,21 +476,5 @@ #define MX27_PAD_ATA_DATA15__ETMTRACEPKT4 0xb7 0x005 #define MX27_PAD_ATA_DATA15__FEC_TX_EN 0xb7 0x006 #define MX27_PAD_ATA_DATA15__GPIO6_23 0xb7 0x032 -#define MX27_PAD_UNUSED15__UNUSED15 0xb8 0x004 -#define MX27_PAD_UNUSED15__GPIO6_24 0xb8 0x032 -#define MX27_PAD_UNUSED16__UNUSED16 0xb9 0x004 -#define MX27_PAD_UNUSED16__GPIO6_25 0xb9 0x032 -#define MX27_PAD_UNUSED17__UNUSED17 0xba 0x004 -#define MX27_PAD_UNUSED17__GPIO6_26 0xba 0x032 -#define MX27_PAD_UNUSED18__UNUSED18 0xbb 0x004 -#define MX27_PAD_UNUSED18__GPIO6_27 0xbb 0x032 -#define MX27_PAD_UNUSED19__UNUSED19 0xbc 0x004 -#define MX27_PAD_UNUSED19__GPIO6_28 0xbc 0x032 -#define MX27_PAD_UNUSED20__UNUSED20 0xbd 0x004 -#define MX27_PAD_UNUSED20__GPIO6_29 0xbd 0x032 -#define MX27_PAD_UNUSED21__UNUSED21 0xbe 0x004 -#define MX27_PAD_UNUSED21__GPIO6_30 0xbe 0x032 -#define MX27_PAD_UNUSED22__UNUSED22 0xbf 0x004 -#define MX27_PAD_UNUSED22__GPIO6_31 0xbf 0x032 #endif /* __DTS_IMX27_PINFUNC_H */ diff --git a/drivers/pinctrl/pinctrl-imx27.c b/drivers/pinctrl/pinctrl-imx27.c index 27ae7ce1b0d4..f8dfefb69968 100644 --- a/drivers/pinctrl/pinctrl-imx27.c +++ b/drivers/pinctrl/pinctrl-imx27.c @@ -63,10 +63,6 @@ enum imx27_pads { MX27_PAD_CONTRAST = PAD_ID(PA, 30), MX27_PAD_OE_ACD = PAD_ID(PA, 31), - MX27_PAD_UNUSED0 = PAD_ID(PB, 0), - MX27_PAD_UNUSED1 = PAD_ID(PB, 1), - MX27_PAD_UNUSED2 = PAD_ID(PB, 2), - MX27_PAD_UNUSED3 = PAD_ID(PB, 3), MX27_PAD_SD2_D0 = PAD_ID(PB, 4), MX27_PAD_SD2_D1 = PAD_ID(PB, 5), MX27_PAD_SD2_D2 = PAD_ID(PB, 6), @@ -96,11 +92,6 @@ enum imx27_pads { MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30), MX27_PAD_USBH1_RXDP = PAD_ID(PB, 31), - MX27_PAD_UNUSED4 = PAD_ID(PC, 0), - MX27_PAD_UNUSED5 = PAD_ID(PC, 1), - MX27_PAD_UNUSED6 = PAD_ID(PC, 2), - MX27_PAD_UNUSED7 = PAD_ID(PC, 3), - MX27_PAD_UNUSED8 = PAD_ID(PC, 4), MX27_PAD_I2C2_SDA = PAD_ID(PC, 5), MX27_PAD_I2C2_SCL = PAD_ID(PC, 6), MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7), @@ -188,12 +179,6 @@ enum imx27_pads { MX27_PAD_SD1_CLK = PAD_ID(PE, 23), MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24), MX27_PAD_USBOTG_DATA7 = PAD_ID(PE, 25), - MX27_PAD_UNUSED9 = PAD_ID(PE, 26), - MX27_PAD_UNUSED10 = PAD_ID(PE, 27), - MX27_PAD_UNUSED11 = PAD_ID(PE, 28), - MX27_PAD_UNUSED12 = PAD_ID(PE, 29), - MX27_PAD_UNUSED13 = PAD_ID(PE, 30), - MX27_PAD_UNUSED14 = PAD_ID(PE, 31), MX27_PAD_NFRB = PAD_ID(PF, 0), MX27_PAD_NFCLE = PAD_ID(PF, 1), @@ -219,14 +204,6 @@ enum imx27_pads { MX27_PAD_CS4_B = PAD_ID(PF, 21), MX27_PAD_CS5_B = PAD_ID(PF, 22), MX27_PAD_ATA_DATA15 = PAD_ID(PF, 23), - MX27_PAD_UNUSED15 = PAD_ID(PF, 24), - MX27_PAD_UNUSED16 = PAD_ID(PF, 25), - MX27_PAD_UNUSED17 = PAD_ID(PF, 26), - MX27_PAD_UNUSED18 = PAD_ID(PF, 27), - MX27_PAD_UNUSED19 = PAD_ID(PF, 28), - MX27_PAD_UNUSED20 = PAD_ID(PF, 29), - MX27_PAD_UNUSED21 = PAD_ID(PF, 30), - MX27_PAD_UNUSED22 = PAD_ID(PF, 31), }; /* Pad names for the pinmux subsystem */ @@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { IMX_PINCTRL_PIN(MX27_PAD_CONTRAST), IMX_PINCTRL_PIN(MX27_PAD_OE_ACD), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED0), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED1), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED2), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED3), IMX_PINCTRL_PIN(MX27_PAD_SD2_D0), IMX_PINCTRL_PIN(MX27_PAD_SD2_D1), IMX_PINCTRL_PIN(MX27_PAD_SD2_D2), @@ -297,11 +270,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDM), IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDP), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED4), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED5), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED6), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED7), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED8), IMX_PINCTRL_PIN(MX27_PAD_I2C2_SDA), IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL), IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5), @@ -389,12 +357,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { IMX_PINCTRL_PIN(MX27_PAD_SD1_CLK), IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK), IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA7), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED9), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED10), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED11), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED12), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED13), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED14), IMX_PINCTRL_PIN(MX27_PAD_NFRB), IMX_PINCTRL_PIN(MX27_PAD_NFCLE), @@ -420,14 +382,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = { IMX_PINCTRL_PIN(MX27_PAD_CS4_B), IMX_PINCTRL_PIN(MX27_PAD_CS5_B), IMX_PINCTRL_PIN(MX27_PAD_ATA_DATA15), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED15), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED16), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED17), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED18), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED19), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED20), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED21), - IMX_PINCTRL_PIN(MX27_PAD_UNUSED22), }; static struct imx1_pinctrl_soc_info imx27_pinctrl_info = { From 2243a87d90b42eb38bc281957df3e57c712b5e56 Mon Sep 17 00:00:00 2001 From: Fan Wu Date: Mon, 9 Jun 2014 09:37:56 +0800 Subject: [PATCH 17/61] pinctrl: avoid duplicated calling enable_pinmux_setting for a pin What the patch does: 1. Call pinmux_disable_setting ahead of pinmux_enable_setting each time pinctrl_select_state is called 2. Remove the HW disable operation in pinmux_disable_setting function. 3. Remove the disable ops in struct pinmux_ops 4. Remove all the disable ops users in current code base. Notes: 1. Great thanks for the suggestion from Linus, Tony Lindgren and Stephen Warren and Everyone that shared comments on this patch. 2. The patch also includes comment fixes from Stephen Warren. The reason why we do this: 1. To avoid duplicated calling of the enable_setting operation without disabling operation inbetween which will let the pin descriptor desc->mux_usecount increase monotonously. 2. The HW pin disable operation is not useful for any of the existing platforms. And this can be used to avoid the HW glitch after using the item #1 modification. In the following case, the issue can be reproduced: 1. There is a driver that need to switch pin state dynamically, e.g. between "sleep" and "default" state 2. The pin setting configuration in a DTS node may be like this: component a { pinctrl-names = "default", "sleep"; pinctrl-0 = <&a_grp_setting &c_grp_setting>; pinctrl-1 = <&b_grp_setting &c_grp_setting>; } The "c_grp_setting" config node is totally identical, maybe like following one: c_grp_setting: c_grp_setting { pinctrl-single,pins = ; } 3. When switching the pin state in the following official pinctrl sequence: pin = pinctrl_get(); state = pinctrl_lookup_state(wanted_state); pinctrl_select_state(state); pinctrl_put(); Test Result: 1. The switch is completed as expected, that is: the device's pin configuration is changed according to the description in the "wanted_state" group setting 2. The "desc->mux_usecount" of the corresponding pins in "c_group" is increased without being decreased, because the "desc" is for each physical pin while the setting is for each setting node in the DTS. Thus, if the "c_grp_setting" in pinctrl-0 is not disabled ahead of enabling "c_grp_setting" in pinctrl-1, the desc->mux_usecount will keep increasing without any chance to be decreased. According to the comments in the original code, only the setting, in old state but not in new state, will be "disabled" (calling pinmux_disable_setting), which is correct logic but not intact. We still need consider case that the setting is in both old state and new state. We can do this in the following two ways: 1. Avoid to "enable"(calling pinmux_enable_setting) the "same pin setting" repeatedly 2. "Disable"(calling pinmux_disable_setting) the "same pin setting", actually two setting instances, ahead of enabling them. Analysis: 1. The solution #2 is better because it can avoid too much iteration. 2. If we disable all of the settings in the old state and one of the setting(s) exist in the new state, the pins mux function change may happen when some SoC vendors defined the "pinctrl-single,function-off" in their DTS file. old_setting => disabled_setting => new_setting. 3. In the pinmux framework, when a pin state is switched, the setting in the old state should be marked as "disabled". Conclusion: 1. To Remove the HW disabling operation to above the glitch mentioned above. 2. Handle the issue mentioned above by disabling all of the settings in old state and then enable the all of the settings in new state. Signed-off-by: Fan Wu Acked-by: Stephen Warren Acked-by: Patrice Chotard Acked-by: Heiko Stuebner Acked-by: Maxime Coquelin Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 24 +++-------- drivers/pinctrl/pinctrl-abx500.c | 15 ------- drivers/pinctrl/pinctrl-adi2.c | 30 -------------- drivers/pinctrl/pinctrl-at91.c | 21 ---------- drivers/pinctrl/pinctrl-bcm2835.c | 11 ----- drivers/pinctrl/pinctrl-exynos5440.c | 8 ---- drivers/pinctrl/pinctrl-msm.c | 25 ------------ drivers/pinctrl/pinctrl-nomadik.c | 16 -------- drivers/pinctrl/pinctrl-rockchip.c | 18 --------- drivers/pinctrl/pinctrl-samsung.c | 8 ---- drivers/pinctrl/pinctrl-single.c | 56 -------------------------- drivers/pinctrl/pinctrl-st.c | 6 --- drivers/pinctrl/pinctrl-tb10x.c | 17 -------- drivers/pinctrl/pinctrl-tegra.c | 13 ------ drivers/pinctrl/pinctrl-tz1090-pdc.c | 28 ------------- drivers/pinctrl/pinctrl-tz1090.c | 58 --------------------------- drivers/pinctrl/pinctrl-u300.c | 14 ------- drivers/pinctrl/pinmux.c | 4 -- drivers/pinctrl/sh-pfc/pinctrl.c | 22 ---------- drivers/pinctrl/sirf/pinctrl-sirf.c | 10 ----- drivers/pinctrl/spear/pinctrl-spear.c | 7 ---- drivers/pinctrl/vt8500/pinctrl-wmt.c | 12 ------ include/linux/pinctrl/pinmux.h | 2 - 23 files changed, 5 insertions(+), 420 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e09474ecde23..e4f65510c87e 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -992,29 +992,15 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) if (p->state) { /* - * The set of groups with a mux configuration in the old state - * may not be identical to the set of groups with a mux setting - * in the new state. While this might be unusual, it's entirely - * possible for the "user"-supplied mapping table to be written - * that way. For each group that was configured in the old state - * but not in the new state, this code puts that group into a - * safe/disabled state. + * For each pinmux setting in the old state, forget SW's record + * of mux owner for that pingroup. Any pingroups which are + * still owned by the new state will be re-acquired by the call + * to pinmux_enable_setting() in the loop below. */ list_for_each_entry(setting, &p->state->settings, node) { - bool found = false; if (setting->type != PIN_MAP_TYPE_MUX_GROUP) continue; - list_for_each_entry(setting2, &state->settings, node) { - if (setting2->type != PIN_MAP_TYPE_MUX_GROUP) - continue; - if (setting2->data.mux.group == - setting->data.mux.group) { - found = true; - break; - } - } - if (!found) - pinmux_disable_setting(setting); + pinmux_disable_setting(setting); } } diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c index 163da9c3ea0e..f3f8b24efe54 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/pinctrl-abx500.c @@ -737,20 +737,6 @@ static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, return ret; } -static void abx500_pmx_disable(struct pinctrl_dev *pctldev, - unsigned function, unsigned group) -{ - struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev); - const struct abx500_pingroup *g; - - g = &pct->soc->groups[group]; - if (g->altsetting < 0) - return; - - /* FIXME: poke out the mux, set the pin to some default state? */ - dev_dbg(pct->dev, "disable group %s, %u pins\n", g->name, g->npins); -} - static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -799,7 +785,6 @@ static const struct pinmux_ops abx500_pinmux_ops = { .get_function_name = abx500_pmx_get_func_name, .get_function_groups = abx500_pmx_get_func_groups, .enable = abx500_pmx_enable, - .disable = abx500_pmx_disable, .gpio_request_enable = abx500_gpio_request_enable, .gpio_disable_free = abx500_gpio_disable_free, }; diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c index 5c44feb54ebb..b02ee4f882c0 100644 --- a/drivers/pinctrl/pinctrl-adi2.c +++ b/drivers/pinctrl/pinctrl-adi2.c @@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id, return 0; } -static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned func_id, - unsigned group_id) -{ - struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); - struct gpio_port *port; - struct pinctrl_gpio_range *range; - unsigned long flags; - unsigned short *mux, pin; - - mux = (unsigned short *)pinctrl->soc->groups[group_id].mux; - - while (*mux) { - pin = P_IDENT(*mux); - - range = pinctrl_find_gpio_range_from_pin(pctldev, pin); - if (range == NULL) /* should not happen */ - return; - - port = container_of(range->gc, struct gpio_port, chip); - - spin_lock_irqsave(&port->lock, flags); - - port_setup(port, pin_to_offset(range, pin), true); - mux++; - - spin_unlock_irqrestore(&port->lock, flags); - } -} - static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) { struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); @@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev, static struct pinmux_ops adi_pinmux_ops = { .enable = adi_pinmux_enable, - .disable = adi_pinmux_disable, .get_functions_count = adi_pinmux_get_funcs_count, .get_function_name = adi_pinmux_get_func_name, .get_function_groups = adi_pinmux_get_groups, diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 421493cb490c..bd57ab514aa4 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; - const struct at91_pmx_pin *pin; - uint32_t npins = info->groups[group].npins; - int i; - unsigned mask; - void __iomem *pio; - - for (i = 0; i < npins; i++) { - pin = &pins_conf[i]; - at91_pin_dbg(info->dev, pin); - pio = pin_to_controller(info, pin->bank); - mask = pin_to_mask(pin->pin); - at91_mux_gpio_enable(pio, mask, 1); - } -} - static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev) { struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); @@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = { .get_function_name = at91_pmx_get_func_name, .get_function_groups = at91_pmx_get_groups, .enable = at91_pmx_enable, - .disable = at91_pmx_disable, .gpio_request_enable = at91_gpio_request_enable, .gpio_disable_free = at91_gpio_disable_free, }; diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c index 3d907de9bc91..5bcfd7ace0cd 100644 --- a/drivers/pinctrl/pinctrl-bcm2835.c +++ b/drivers/pinctrl/pinctrl-bcm2835.c @@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev, return 0; } -static void bcm2835_pmx_disable(struct pinctrl_dev *pctldev, - unsigned func_selector, - unsigned group_selector) -{ - struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - - /* disable by setting to GPIO_IN */ - bcm2835_pinctrl_fsel_set(pc, group_selector, BCM2835_FSEL_GPIO_IN); -} - static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = { .get_function_name = bcm2835_pmx_get_function_name, .get_function_groups = bcm2835_pmx_get_function_groups, .enable = bcm2835_pmx_enable, - .disable = bcm2835_pmx_disable, .gpio_disable_free = bcm2835_pmx_gpio_disable_free, .gpio_set_direction = bcm2835_pmx_gpio_set_direction, }; diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c index 8fe2ab0a7698..4b145b5db7a6 100644 --- a/drivers/pinctrl/pinctrl-exynos5440.c +++ b/drivers/pinctrl/pinctrl-exynos5440.c @@ -371,13 +371,6 @@ static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned select return 0; } -/* disable a specified pinmux by writing to registers */ -static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev, - unsigned selector, unsigned group) -{ - exynos5440_pinmux_setup(pctldev, selector, group, false); -} - /* * The calls to gpio_direction_output() and gpio_direction_input() * leads to this function call (via the pinctrl_gpio_direction_{input|output}() @@ -395,7 +388,6 @@ static const struct pinmux_ops exynos5440_pinmux_ops = { .get_function_name = exynos5440_pinmux_get_fname, .get_function_groups = exynos5440_pinmux_get_groups, .enable = exynos5440_pinmux_enable, - .disable = exynos5440_pinmux_disable, .gpio_set_direction = exynos5440_pinmux_gpio_set_direction, }; diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c index df6dda4ce803..bdfaba4430f2 100644 --- a/drivers/pinctrl/pinctrl-msm.c +++ b/drivers/pinctrl/pinctrl-msm.c @@ -165,36 +165,11 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev, return 0; } -static void msm_pinmux_disable(struct pinctrl_dev *pctldev, - unsigned function, - unsigned group) -{ - struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - const struct msm_pingroup *g; - unsigned long flags; - u32 val; - - g = &pctrl->soc->groups[group]; - - if (WARN_ON(g->mux_bit < 0)) - return; - - spin_lock_irqsave(&pctrl->lock, flags); - - /* Clear the mux bits to select gpio mode */ - val = readl(pctrl->regs + g->ctl_reg); - val &= ~(0x7 << g->mux_bit); - writel(val, pctrl->regs + g->ctl_reg); - - spin_unlock_irqrestore(&pctrl->lock, flags); -} - static const struct pinmux_ops msm_pinmux_ops = { .get_functions_count = msm_get_functions_count, .get_function_name = msm_get_function_name, .get_function_groups = msm_get_function_groups, .enable = msm_pinmux_enable, - .disable = msm_pinmux_disable, }; static int msm_config_reg(struct msm_pinctrl *pctrl, diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 8f6f16ef73f3..a564251fe093 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1765,21 +1765,6 @@ out_glitch: return ret; } -static void nmk_pmx_disable(struct pinctrl_dev *pctldev, - unsigned function, unsigned group) -{ - struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - const struct nmk_pingroup *g; - - g = &npct->soc->groups[group]; - - if (g->altsetting < 0) - return; - - /* Poke out the mux, set the pin to some default state? */ - dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins); -} - static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -1826,7 +1811,6 @@ static const struct pinmux_ops nmk_pinmux_ops = { .get_function_name = nmk_pmx_get_func_name, .get_function_groups = nmk_pmx_get_func_groups, .enable = nmk_pmx_enable, - .disable = nmk_pmx_disable, .gpio_request_enable = nmk_gpio_request_enable, .gpio_disable_free = nmk_gpio_disable_free, }; diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index bb805d5e9ff0..51f67a6eadcb 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -657,23 +657,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static void rockchip_pmx_disable(struct pinctrl_dev *pctldev, - unsigned selector, unsigned group) -{ - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); - const unsigned int *pins = info->groups[group].pins; - struct rockchip_pin_bank *bank; - int cnt; - - dev_dbg(info->dev, "disable function %s group %s\n", - info->functions[selector].name, info->groups[group].name); - - for (cnt = 0; cnt < info->groups[group].npins; cnt++) { - bank = pin_to_bank(info, pins[cnt]); - rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); - } -} - /* * The calls to gpio_direction_output() and gpio_direction_input() * leads to this function call (via the pinctrl_gpio_direction_{input|output}() @@ -716,7 +699,6 @@ static const struct pinmux_ops rockchip_pmx_ops = { .get_function_name = rockchip_pmx_get_func_name, .get_function_groups = rockchip_pmx_get_groups, .enable = rockchip_pmx_enable, - .disable = rockchip_pmx_disable, .gpio_set_direction = rockchip_pmx_gpio_set_direction, }; diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 3e61d0f8f146..089abde35d44 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -333,13 +333,6 @@ static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -/* disable a specified pinmux by writing to registers */ -static void samsung_pinmux_disable(struct pinctrl_dev *pctldev, - unsigned selector, unsigned group) -{ - samsung_pinmux_setup(pctldev, selector, group, false); -} - /* * The calls to gpio_direction_output() and gpio_direction_input() * leads to this function call (via the pinctrl_gpio_direction_{input|output}() @@ -390,7 +383,6 @@ static const struct pinmux_ops samsung_pinmux_ops = { .get_function_name = samsung_pinmux_get_fname, .get_function_groups = samsung_pinmux_get_groups, .enable = samsung_pinmux_enable, - .disable = samsung_pinmux_disable, .gpio_set_direction = samsung_pinmux_gpio_set_direction, }; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 2960557bfed9..ff6a2bda52e5 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector, return 0; } -static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, - unsigned group) -{ - struct pcs_device *pcs; - struct pcs_function *func; - int i; - - pcs = pinctrl_dev_get_drvdata(pctldev); - /* If function mask is null, needn't disable it. */ - if (!pcs->fmask) - return; - - func = radix_tree_lookup(&pcs->ftree, fselector); - if (!func) { - dev_err(pcs->dev, "%s could not find function%i\n", - __func__, fselector); - return; - } - - /* - * Ignore disable if function-off is not specified. Some hardware - * does not have clearly defined disable function. For pin specific - * off modes, you can use alternate named states as described in - * pinctrl-bindings.txt. - */ - if (pcs->foff == PCS_OFF_DISABLED) { - dev_dbg(pcs->dev, "ignoring disable for %s function%i\n", - func->name, fselector); - return; - } - - dev_dbg(pcs->dev, "disabling function%i %s\n", - fselector, func->name); - - for (i = 0; i < func->nvals; i++) { - struct pcs_func_vals *vals; - unsigned long flags; - unsigned val, mask; - - vals = &func->vals[i]; - raw_spin_lock_irqsave(&pcs->lock, flags); - val = pcs->read(vals->reg); - - if (pcs->bits_per_mux) - mask = vals->mask; - else - mask = pcs->fmask; - - val &= ~mask; - val |= pcs->foff << pcs->fshift; - pcs->write(val, vals->reg); - raw_spin_unlock_irqrestore(&pcs->lock, flags); - } -} - static int pcs_request_gpio(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin) { @@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = { .get_function_name = pcs_get_function_name, .get_function_groups = pcs_get_function_groups, .enable = pcs_enable, - .disable = pcs_disable, .gpio_request_enable = pcs_request_gpio, }; diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 1bd6363bc95e..e1919cd43117 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector, return 0; } -static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ -} - static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned gpio, bool input) @@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = { .get_function_name = st_pmx_get_fname, .get_function_groups = st_pmx_get_groups, .enable = st_pmx_enable, - .disable = st_pmx_disable, .gpio_set_direction = st_pmx_set_gpio_direction, }; diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index 26ca6855f478..71c5d4f0c538 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c @@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl, return 0; } -static void tb10x_pctl_disable(struct pinctrl_dev *pctl, - unsigned func_selector, unsigned group_selector) -{ - struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl); - const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector]; - - if (grp->port < 0) - return; - - mutex_lock(&state->mutex); - - state->ports[grp->port].count--; - - mutex_unlock(&state->mutex); -} - static struct pinmux_ops tb10x_pinmux_ops = { .get_functions_count = tb10x_get_functions_count, .get_function_name = tb10x_get_function_name, @@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = { .gpio_request_enable = tb10x_gpio_request_enable, .gpio_disable_free = tb10x_gpio_disable_free, .enable = tb10x_pctl_enable, - .disable = tb10x_pctl_disable, }; static struct pinctrl_desc tb10x_pindesc = { diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index 2d43bff74f59..150af5503c09 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, return 0; } -static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, - unsigned function, unsigned group) -{ - struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - const struct tegra_pingroup *g; - - g = &pmx->soc->groups[group]; - - if (WARN_ON(g->mux_reg < 0)) - return; -} - static const struct pinmux_ops tegra_pinmux_ops = { .get_functions_count = tegra_pinctrl_get_funcs_count, .get_function_name = tegra_pinctrl_get_func_name, .get_function_groups = tegra_pinctrl_get_func_groups, .enable = tegra_pinctrl_enable, - .disable = tegra_pinctrl_disable, }; static int tegra_pinconf_reg(struct tegra_pmx *pmx, diff --git a/drivers/pinctrl/pinctrl-tz1090-pdc.c b/drivers/pinctrl/pinctrl-tz1090-pdc.c index 5bf01c28925e..41e81a35cabb 100644 --- a/drivers/pinctrl/pinctrl-tz1090-pdc.c +++ b/drivers/pinctrl/pinctrl-tz1090-pdc.c @@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev, return 0; } -static void tz1090_pdc_pinctrl_disable(struct pinctrl_dev *pctldev, - unsigned int function, - unsigned int group) -{ - struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group]; - - dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n", - __func__, - function, tz1090_pdc_functions[function].name, - group, tz1090_pdc_groups[group].name); - - /* is it even a mux? */ - if (grp->drv) - return; - - /* does this group even control the function? */ - if (function != grp->func) - return; - - /* record the pin being unmuxed and update mux bit */ - spin_lock(&pmx->lock); - pmx->mux_en &= ~BIT(grp->pins[0]); - tz1090_pdc_pinctrl_mux(pmx, grp); - spin_unlock(&pmx->lock); -} - static const struct tz1090_pdc_pingroup *find_mux_group( struct tz1090_pdc_pmx *pmx, unsigned int pin) @@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = { .get_function_name = tz1090_pdc_pinctrl_get_func_name, .get_function_groups = tz1090_pdc_pinctrl_get_func_groups, .enable = tz1090_pdc_pinctrl_enable, - .disable = tz1090_pdc_pinctrl_disable, .gpio_request_enable = tz1090_pdc_pinctrl_gpio_request_enable, .gpio_disable_free = tz1090_pdc_pinctrl_gpio_disable_free, }; diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c index bc9cd7a7602e..24082216842e 100644 --- a/drivers/pinctrl/pinctrl-tz1090.c +++ b/drivers/pinctrl/pinctrl-tz1090.c @@ -1478,63 +1478,6 @@ mux_pins: return 0; } -/** - * tz1090_pinctrl_disable() - Disable a function on a pin group. - * @pctldev: Pin control data - * @function: Function index to disable - * @group: Group index to disable - * - * Disable a particular function on a group of pins. The per GPIO pin pseudo pin - * groups can be used (in which case the pin will be taken out of peripheral - * mode. Some convenience pin groups can also be used in which case the effect - * is the same as enabling the function on each individual pin in the group. - */ -static void tz1090_pinctrl_disable(struct pinctrl_dev *pctldev, - unsigned int function, unsigned int group) -{ - struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - struct tz1090_pingroup *grp; - unsigned int pin_num, mux_group, i, npins; - const unsigned int *pins; - - /* group of pins? */ - if (group < ARRAY_SIZE(tz1090_groups)) { - grp = &tz1090_groups[group]; - npins = grp->npins; - pins = grp->pins; - /* - * All pins in the group must belong to the same mux group, - * which allows us to just use the mux group of the first pin. - * By explicitly listing permitted pingroups for each function - * the pinmux core should ensure this is always the case. - */ - } else { - pin_num = group - ARRAY_SIZE(tz1090_groups); - npins = 1; - pins = &pin_num; - } - mux_group = tz1090_mux_pins[*pins]; - - /* no mux group, but can still be individually muxed to peripheral */ - if (mux_group >= TZ1090_MUX_GROUP_MAX) { - if (function == TZ1090_MUX_PERIP) - goto unmux_pins; - return; - } - - /* mux group already set to a different function? */ - grp = &tz1090_mux_groups[mux_group]; - dev_dbg(pctldev->dev, "%s: unmuxing %u pin(s) in '%s' from '%s'\n", - __func__, npins, grp->name, tz1090_functions[function].name); - - /* subtract pins from ref count and unmux individually */ - WARN_ON(grp->func_count < npins); - grp->func_count -= npins; -unmux_pins: - for (i = 0; i < npins; ++i) - tz1090_pinctrl_perip_select(pmx, pins[i], false); -} - /** * tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode. * @pctldev: Pin control data @@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = { .get_function_name = tz1090_pinctrl_get_func_name, .get_function_groups = tz1090_pinctrl_get_func_groups, .enable = tz1090_pinctrl_enable, - .disable = tz1090_pinctrl_disable, .gpio_request_enable = tz1090_pinctrl_gpio_request_enable, .gpio_disable_free = tz1090_pinctrl_gpio_disable_free, }; diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 209a01b8bd3b..0959bb36450f 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct u300_pmx *upmx; - - /* There is nothing to do with the power pins */ - if (selector == 0) - return; - - upmx = pinctrl_dev_get_drvdata(pctldev); - u300_pmx_endisable(upmx, selector, false); -} - static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev) { return ARRAY_SIZE(u300_pmx_functions); @@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = { .get_function_name = u300_pmx_get_func_name, .get_function_groups = u300_pmx_get_groups, .enable = u300_pmx_enable, - .disable = u300_pmx_disable, }; static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 051e8592990e..c055daf9a80f 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const struct pinmux_ops *ops = pctldev->desc->pmxops; int ret = 0; const unsigned *pins = NULL; unsigned num_pins = 0; @@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) pins[i], desc->name, gname); } } - - if (ops->disable) - ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); } #ifdef CONFIG_DEBUG_FS diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index e758af95c209..11db3ee39d40 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -345,27 +345,6 @@ done: return ret; } -static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); - struct sh_pfc *pfc = pmx->pfc; - const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; - unsigned long flags; - unsigned int i; - - spin_lock_irqsave(&pfc->lock, flags); - - for (i = 0; i < grp->nr_pins; ++i) { - int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); - struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; - - cfg->type = PINMUX_TYPE_NONE; - } - - spin_unlock_irqrestore(&pfc->lock, flags); -} - static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = { .get_function_name = sh_pfc_get_function_name, .get_function_groups = sh_pfc_get_function_groups, .enable = sh_pfc_func_enable, - .disable = sh_pfc_func_disable, .gpio_request_enable = sh_pfc_gpio_request_enable, .gpio_disable_free = sh_pfc_gpio_disable_free, .gpio_set_direction = sh_pfc_gpio_set_direction, diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index 014f5b1fee55..4c1d7c68666d 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c @@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector, return 0; } -static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector, - unsigned group) -{ - struct sirfsoc_pmx *spmx; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - sirfsoc_pinmux_endisable(spmx, selector, false); -} - static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev) { return sirfsoc_pmxfunc_cnt; @@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, static struct pinmux_ops sirfsoc_pinmux_ops = { .enable = sirfsoc_pinmux_enable, - .disable = sirfsoc_pinmux_disable, .get_functions_count = sirfsoc_pinmux_get_funcs_count, .get_function_name = sirfsoc_pinmux_get_func_name, .get_function_groups = sirfsoc_pinmux_get_groups, diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 58bf6867aa17..f72cc4e192bd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, return spear_pinctrl_endisable(pctldev, function, group, true); } -static void spear_pinctrl_disable(struct pinctrl_dev *pctldev, - unsigned function, unsigned group) -{ - spear_pinctrl_endisable(pctldev, function, group, false); -} - /* gpio with pinmux */ static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, unsigned pin) @@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = { .get_function_name = spear_pinctrl_get_func_name, .get_function_groups = spear_pinctrl_get_func_groups, .enable = spear_pinctrl_enable, - .disable = spear_pinctrl_disable, .gpio_request_enable = gpio_request_enable, .gpio_disable_free = gpio_disable_free, }; diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index 2c61281bebd7..8c976c21eeee 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c @@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev, return wmt_set_pinmux(data, func_selector, pinnum); } -static void wmt_pmx_disable(struct pinctrl_dev *pctldev, - unsigned func_selector, - unsigned group_selector) -{ - struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); - u32 pinnum = data->pins[group_selector].number; - - /* disable by setting GPIO_IN */ - wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, pinnum); -} - static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) @@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = { .get_function_name = wmt_pmx_get_function_name, .get_function_groups = wmt_pmx_get_function_groups, .enable = wmt_pmx_enable, - .disable = wmt_pmx_disable, .gpio_disable_free = wmt_pmx_gpio_disable_free, .gpio_set_direction = wmt_pmx_gpio_set_direction, }; diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index c15395031cb3..3097aafbeb24 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -70,8 +70,6 @@ struct pinmux_ops { unsigned * const num_groups); int (*enable) (struct pinctrl_dev *pctldev, unsigned func_selector, unsigned group_selector); - void (*disable) (struct pinctrl_dev *pctldev, unsigned func_selector, - unsigned group_selector); int (*gpio_request_enable) (struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset); From fc72c923e50d5c0575faa5f6379bd55b900ed85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 16 Jun 2014 01:36:05 +0200 Subject: [PATCH 18/61] pinctrl: rockchip: generalize bank-quirks Upcoming Rockchip SoCs have additional quirks to handle. Currently they would be handled by giving the bank a special compatible property. But the nature of the new quirks would require a lot of them. Also as we want to move to the separate dw_gpio driver in the future, these bank-definitions should be extended at all. Describing the bank quirks this way also enables us to deprecate the special bank compatible string for bank0 on rk3188 and simplify the handling code. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- .../bindings/pinctrl/rockchip,pinctrl.txt | 3 +- drivers/pinctrl/pinctrl-rockchip.c | 58 +++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index cefef741a40b..eb0544f295ee 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt @@ -36,7 +36,7 @@ Deprecated properties for iomux controller: Use rockchip,grf and rockchip,pmu described above instead. Required properties for gpio sub nodes: - - compatible: "rockchip,gpio-bank", "rockchip,rk3188-gpio-bank0" + - compatible: "rockchip,gpio-bank" - reg: register of the gpio bank (different than the iomux registerset) - interrupts: base interrupt of the gpio bank in the interrupt controller - clocks: clock that drives this bank @@ -50,6 +50,7 @@ Required properties for gpio sub nodes: bindings/interrupt-controller/interrupts.txt Deprecated properties for gpio sub nodes: + - compatible: "rockchip,rk3188-gpio-bank0" - reg: second element: separate pull register for rk3188 bank0, use rockchip,pmu described above instead diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 51f67a6eadcb..2f5ba046232e 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -64,9 +64,16 @@ enum rockchip_pinctrl_type { RK3188, }; -enum rockchip_pin_bank_type { - COMMON_BANK, - RK3188_BANK0, +/** + * Encode variants of iomux registers into a type variable + */ +#define IOMUX_GPIO_ONLY BIT(0) + +/** + * @type: iomux variant using IOMUX_* constants + */ +struct rockchip_iomux { + int type; }; /** @@ -78,6 +85,7 @@ enum rockchip_pin_bank_type { * @nr_pins: number of pins in this bank * @name: name of the bank * @bank_num: number of the bank, to account for holes + * @iomux: array describing the 4 iomux sources of the bank * @valid: are all necessary informations present * @of_node: dt node of this bank * @drvdata: common pinctrl basedata @@ -95,7 +103,7 @@ struct rockchip_pin_bank { u8 nr_pins; char *name; u8 bank_num; - enum rockchip_pin_bank_type bank_type; + struct rockchip_iomux iomux[4]; bool valid; struct device_node *of_node; struct rockchip_pinctrl *drvdata; @@ -113,6 +121,19 @@ struct rockchip_pin_bank { .name = label, \ } +#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ + { \ + .bank_num = id, \ + .nr_pins = pins, \ + .name = label, \ + .iomux = { \ + { .type = iom0, }, \ + { .type = iom1, }, \ + { .type = iom2, }, \ + { .type = iom3, }, \ + }, \ + } + /** */ struct rockchip_pin_ctrl { @@ -343,17 +364,21 @@ static const struct pinctrl_ops rockchip_pctrl_ops = { static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) { struct rockchip_pinctrl *info = bank->drvdata; + int iomux_num = (pin / 8); unsigned int val; int reg, ret; u8 bit; - if (bank->bank_type == RK3188_BANK0 && pin < 16) + if (iomux_num > 3) + return -EINVAL; + + if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) return RK_FUNC_GPIO; /* get basic quadrupel of mux registers and the correct reg inside */ reg = info->ctrl->mux_offset; reg += bank->bank_num * 0x10; - reg += (pin / 8) * 4; + reg += iomux_num * 4; bit = (pin % 8) * 2; ret = regmap_read(info->regmap_base, reg, &val); @@ -379,16 +404,16 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) { struct rockchip_pinctrl *info = bank->drvdata; + int iomux_num = (pin / 8); int reg, ret; unsigned long flags; u8 bit; u32 data; - /* - * The first 16 pins of rk3188_bank0 are always gpios and do not have - * a mux register at all. - */ - if (bank->bank_type == RK3188_BANK0 && pin < 16) { + if (iomux_num > 3) + return -EINVAL; + + if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { if (mux != RK_FUNC_GPIO) { dev_err(info->dev, "pin %d only supports a gpio mux\n", pin); @@ -404,7 +429,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) /* get basic quadrupel of mux registers and the correct reg inside */ reg = info->ctrl->mux_offset; reg += bank->bank_num * 0x10; - reg += (pin / 8) * 4; + reg += iomux_num * 4; bit = (pin % 8) * 2; spin_lock_irqsave(&bank->slock, flags); @@ -449,7 +474,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, struct rockchip_pinctrl *info = bank->drvdata; /* The first 12 pins of the first bank are located elsewhere */ - if (bank->bank_type == RK3188_BANK0 && pin_num < 12) { + if (bank->bank_num == 0 && pin_num < 12) { *regmap = info->regmap_pmu ? info->regmap_pmu : bank->regmap_pull; *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; @@ -1448,8 +1473,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, "rockchip,rk3188-gpio-bank0")) { struct device_node *node; - bank->bank_type = RK3188_BANK0; - node = of_parse_phandle(bank->of_node->parent, "rockchip,pmu", 0); if (!node) { @@ -1469,9 +1492,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, base, &rockchip_regmap_config); } - - } else { - bank->bank_type = COMMON_BANK; } bank->irq = irq_of_parse_and_map(bank->of_node, 0); @@ -1664,7 +1684,7 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { }; static struct rockchip_pin_bank rk3188_pin_banks[] = { - PIN_BANK(0, 32, "gpio0"), + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), PIN_BANK(1, 32, "gpio1"), PIN_BANK(2, 32, "gpio2"), PIN_BANK(3, 32, "gpio3"), From 6bc0d121a95b31b0962bf6a3f89099059bde409e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 16 Jun 2014 01:36:33 +0200 Subject: [PATCH 19/61] pinctrl: rockchip: precalculate iomux offsets An upcoming SoC introduces an interesting quirk to iomux handling making the calculation of the iomux register-offset harder. To keep the complexity down when getting/setting the mux, precalculate the actual register offset at probe-time. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 56 ++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 2f5ba046232e..202ac82082d2 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -71,9 +71,13 @@ enum rockchip_pinctrl_type { /** * @type: iomux variant using IOMUX_* constants + * @offset: if initialized to -1 it will be autocalculated, by specifying + * an initial offset value the relevant source offset can be reset + * to a new value for autocalculating the following iomux registers. */ struct rockchip_iomux { int type; + int offset; }; /** @@ -119,6 +123,12 @@ struct rockchip_pin_bank { .bank_num = id, \ .nr_pins = pins, \ .name = label, \ + .iomux = { \ + { .offset = -1 }, \ + { .offset = -1 }, \ + { .offset = -1 }, \ + { .offset = -1 }, \ + }, \ } #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ @@ -127,10 +137,10 @@ struct rockchip_pin_bank { .nr_pins = pins, \ .name = label, \ .iomux = { \ - { .type = iom0, }, \ - { .type = iom1, }, \ - { .type = iom2, }, \ - { .type = iom3, }, \ + { .type = iom0, .offset = -1 }, \ + { .type = iom1, .offset = -1 }, \ + { .type = iom2, .offset = -1 }, \ + { .type = iom3, .offset = -1 }, \ }, \ } @@ -376,9 +386,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) return RK_FUNC_GPIO; /* get basic quadrupel of mux registers and the correct reg inside */ - reg = info->ctrl->mux_offset; - reg += bank->bank_num * 0x10; - reg += iomux_num * 4; + reg = bank->iomux[iomux_num].offset; bit = (pin % 8) * 2; ret = regmap_read(info->regmap_base, reg, &val); @@ -427,9 +435,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) bank->bank_num, pin, mux); /* get basic quadrupel of mux registers and the correct reg inside */ - reg = info->ctrl->mux_offset; - reg += bank->bank_num * 0x10; - reg += iomux_num * 4; + reg = bank->iomux[iomux_num].offset; bit = (pin % 8) * 2; spin_lock_irqsave(&bank->slock, flags); @@ -1515,7 +1521,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( struct device_node *np; struct rockchip_pin_ctrl *ctrl; struct rockchip_pin_bank *bank; - int i; + int grf_offs, i, j; match = of_match_node(rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data; @@ -1537,12 +1543,40 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( } } + grf_offs = ctrl->mux_offset; bank = ctrl->pin_banks; for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { + int bank_pins = 0; + spin_lock_init(&bank->slock); bank->drvdata = d; bank->pin_base = ctrl->nr_pins; ctrl->nr_pins += bank->nr_pins; + + /* calculate iomux offsets */ + for (j = 0; j < 4; j++) { + struct rockchip_iomux *iom = &bank->iomux[j]; + + if (bank_pins >= bank->nr_pins) + break; + + /* preset offset value, set new start value */ + if (iom->offset >= 0) { + grf_offs = iom->offset; + } else { /* set current offset */ + iom->offset = grf_offs; + } + + dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n", + i, j, iom->offset); + + /* + * Increase offset according to iomux width. + */ + grf_offs += 4; + + bank_pins += 8; + } } return ctrl; From 03716e1dd01b0e761a7db8f82c81f11746a0ef97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 16 Jun 2014 01:36:57 +0200 Subject: [PATCH 20/61] pinctrl: rockchip: add support for 4bit wide iomux settings In the upcoming rk3288 SoC some iomux settings are 4bit wide instead of the regular 2bit. Therefore add a flag to mark iomuxes as such and adapt the mux-access as well as the offset calculation accordingly. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 34 +++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 202ac82082d2..07c06e7171e7 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -68,6 +68,7 @@ enum rockchip_pinctrl_type { * Encode variants of iomux registers into a type variable */ #define IOMUX_GPIO_ONLY BIT(0) +#define IOMUX_WIDTH_4BIT BIT(1) /** * @type: iomux variant using IOMUX_* constants @@ -376,7 +377,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) struct rockchip_pinctrl *info = bank->drvdata; int iomux_num = (pin / 8); unsigned int val; - int reg, ret; + int reg, ret, mask; u8 bit; if (iomux_num > 3) @@ -386,14 +387,21 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) return RK_FUNC_GPIO; /* get basic quadrupel of mux registers and the correct reg inside */ + mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; reg = bank->iomux[iomux_num].offset; - bit = (pin % 8) * 2; + if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { + if ((pin % 8) >= 4) + reg += 0x4; + bit = (pin % 4) * 4; + } else { + bit = (pin % 8) * 2; + } ret = regmap_read(info->regmap_base, reg, &val); if (ret) return ret; - return ((val >> bit) & 3); + return ((val >> bit) & mask); } /* @@ -413,7 +421,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) { struct rockchip_pinctrl *info = bank->drvdata; int iomux_num = (pin / 8); - int reg, ret; + int reg, ret, mask; unsigned long flags; u8 bit; u32 data; @@ -435,13 +443,20 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) bank->bank_num, pin, mux); /* get basic quadrupel of mux registers and the correct reg inside */ + mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; reg = bank->iomux[iomux_num].offset; - bit = (pin % 8) * 2; + if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { + if ((pin % 8) >= 4) + reg += 0x4; + bit = (pin % 4) * 4; + } else { + bit = (pin % 8) * 2; + } spin_lock_irqsave(&bank->slock, flags); - data = (3 << (bit + 16)); - data |= (mux & 3) << bit; + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; ret = regmap_write(info->regmap_base, reg, data); spin_unlock_irqrestore(&bank->slock, flags); @@ -1556,6 +1571,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( /* calculate iomux offsets */ for (j = 0; j < 4; j++) { struct rockchip_iomux *iom = &bank->iomux[j]; + int inc; if (bank_pins >= bank->nr_pins) break; @@ -1572,8 +1588,10 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( /* * Increase offset according to iomux width. + * 4bit iomux'es are spread over two registers. */ - grf_offs += 4; + inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4; + grf_offs += inc; bank_pins += 8; } From 95ec8ae4498e99efaf319700e3e7b40fb4a4afd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 16 Jun 2014 01:37:23 +0200 Subject: [PATCH 21/61] pinctrl: rockchip: enable iomuxes from pmu space The upcoming rk3288 moves some iomux settings to the pmu register space. Therefore add a flag for this and adapt the mux functions accordingly. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 42 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 07c06e7171e7..cfdeb81035b6 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -69,6 +69,7 @@ enum rockchip_pinctrl_type { */ #define IOMUX_GPIO_ONLY BIT(0) #define IOMUX_WIDTH_4BIT BIT(1) +#define IOMUX_SOURCE_PMU BIT(2) /** * @type: iomux variant using IOMUX_* constants @@ -153,7 +154,8 @@ struct rockchip_pin_ctrl { u32 nr_pins; char *label; enum rockchip_pinctrl_type type; - int mux_offset; + int grf_mux_offset; + int pmu_mux_offset; void (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num, struct regmap **regmap, int *reg, u8 *bit); @@ -376,6 +378,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) { struct rockchip_pinctrl *info = bank->drvdata; int iomux_num = (pin / 8); + struct regmap *regmap; unsigned int val; int reg, ret, mask; u8 bit; @@ -386,6 +389,9 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) return RK_FUNC_GPIO; + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? info->regmap_pmu : info->regmap_base; + /* get basic quadrupel of mux registers and the correct reg inside */ mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; reg = bank->iomux[iomux_num].offset; @@ -397,7 +403,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) bit = (pin % 8) * 2; } - ret = regmap_read(info->regmap_base, reg, &val); + ret = regmap_read(regmap, reg, &val); if (ret) return ret; @@ -421,6 +427,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) { struct rockchip_pinctrl *info = bank->drvdata; int iomux_num = (pin / 8); + struct regmap *regmap; int reg, ret, mask; unsigned long flags; u8 bit; @@ -442,6 +449,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? info->regmap_pmu : info->regmap_base; + /* get basic quadrupel of mux registers and the correct reg inside */ mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; reg = bank->iomux[iomux_num].offset; @@ -457,7 +467,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) data = (mask << (bit + 16)); data |= (mux & mask) << bit; - ret = regmap_write(info->regmap_base, reg, data); + ret = regmap_write(regmap, reg, data); spin_unlock_irqrestore(&bank->slock, flags); @@ -1536,7 +1546,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( struct device_node *np; struct rockchip_pin_ctrl *ctrl; struct rockchip_pin_bank *bank; - int grf_offs, i, j; + int grf_offs, pmu_offs, i, j; match = of_match_node(rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data; @@ -1558,7 +1568,8 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( } } - grf_offs = ctrl->mux_offset; + grf_offs = ctrl->grf_mux_offset; + pmu_offs = ctrl->pmu_mux_offset; bank = ctrl->pin_banks; for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { int bank_pins = 0; @@ -1578,9 +1589,13 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( /* preset offset value, set new start value */ if (iom->offset >= 0) { - grf_offs = iom->offset; + if (iom->type & IOMUX_SOURCE_PMU) + pmu_offs = iom->offset; + else + grf_offs = iom->offset; } else { /* set current offset */ - iom->offset = grf_offs; + iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? + pmu_offs : grf_offs; } dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n", @@ -1591,7 +1606,10 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( * 4bit iomux'es are spread over two registers. */ inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4; - grf_offs += inc; + if (iom->type & IOMUX_SOURCE_PMU) + pmu_offs += inc; + else + grf_offs += inc; bank_pins += 8; } @@ -1698,7 +1716,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk2928_pin_banks), .label = "RK2928-GPIO", .type = RK2928, - .mux_offset = 0xa8, + .grf_mux_offset = 0xa8, .pull_calc_reg = rk2928_calc_pull_reg_and_bit, }; @@ -1716,7 +1734,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), .label = "RK3066a-GPIO", .type = RK2928, - .mux_offset = 0xa8, + .grf_mux_offset = 0xa8, .pull_calc_reg = rk2928_calc_pull_reg_and_bit, }; @@ -1732,7 +1750,7 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), .label = "RK3066b-GPIO", .type = RK3066B, - .mux_offset = 0x60, + .grf_mux_offset = 0x60, }; static struct rockchip_pin_bank rk3188_pin_banks[] = { @@ -1747,7 +1765,7 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3188_pin_banks), .label = "RK3188-GPIO", .type = RK3188, - .mux_offset = 0x60, + .grf_mux_offset = 0x60, .pull_calc_reg = rk3188_calc_pull_reg_and_bit, }; From 62f49226b03b6464b6fa71ad926932f9b3c8232a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 16 Jun 2014 01:37:49 +0200 Subject: [PATCH 22/61] pinctrl: rockchip: support unrouted iomuxes per bank On the upcoming RK3288 SoC contain some unrouted pins in their banks. So while for example pin8 of bank5 stays pin8 with all its settings (register offset etc), pins 0 to 7 are not routed outside the SoC at all. Therefore add a flag to mark these unrouted iomuxes to prevent people from using them. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index cfdeb81035b6..65b73217c2c3 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -70,6 +70,7 @@ enum rockchip_pinctrl_type { #define IOMUX_GPIO_ONLY BIT(0) #define IOMUX_WIDTH_4BIT BIT(1) #define IOMUX_SOURCE_PMU BIT(2) +#define IOMUX_UNROUTED BIT(3) /** * @type: iomux variant using IOMUX_* constants @@ -386,6 +387,11 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) if (iomux_num > 3) return -EINVAL; + if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { + dev_err(info->dev, "pin %d is unrouted\n", pin); + return -EINVAL; + } + if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) return RK_FUNC_GPIO; @@ -436,6 +442,11 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) if (iomux_num > 3) return -EINVAL; + if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { + dev_err(info->dev, "pin %d is unrouted\n", pin); + return -EINVAL; + } + if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { if (mux != RK_FUNC_GPIO) { dev_err(info->dev, From 304f077d4c07d315b9325cb101fc47ba2ffc5466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 16 Jun 2014 01:38:14 +0200 Subject: [PATCH 23/61] pinctrl: rockchip: add support for rk3288 pin-controller The pin-controller of the new RK3288 contains all the quirks just added in the previous patches. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- .../bindings/pinctrl/rockchip,pinctrl.txt | 1 + drivers/pinctrl/pinctrl-rockchip.c | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index eb0544f295ee..4658b69d4f4d 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt @@ -21,6 +21,7 @@ defined as gpio sub-nodes of the pinmux controller. Required properties for iomux controller: - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl" "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl" + "rockchip,rk3288-pinctrl" - rockchip,grf: phandle referencing a syscon providing the "general register files" diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 65b73217c2c3..192aaee8de07 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -543,6 +543,35 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, } } +#define RK3288_PULL_OFFSET 0x140 +static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3188_PULL_PMU_OFFSET; + + *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); + *bit = pin_num % RK3188_PULL_PINS_PER_REG; + *bit *= RK3188_PULL_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3288_PULL_OFFSET; + + /* correct the offset, as we're starting with the 2nd bank */ + *reg -= 0x10; + *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3188_PULL_PINS_PER_REG); + *bit *= RK3188_PULL_BITS_PER_PIN; + } +} + static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1780,6 +1809,48 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = { .pull_calc_reg = rk3188_calc_pull_reg_and_bit, }; +static struct rockchip_pin_bank rk3288_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_UNROUTED + ), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, + IOMUX_UNROUTED, + IOMUX_UNROUTED, + 0 + ), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0, + 0 + ), + PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, + 0, + 0, + IOMUX_UNROUTED + ), + PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), + PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, + 0, + IOMUX_WIDTH_4BIT, + IOMUX_UNROUTED + ), + PIN_BANK(8, 16, "gpio8"), +}; + +static struct rockchip_pin_ctrl rk3288_pin_ctrl = { + .pin_banks = rk3288_pin_banks, + .nr_banks = ARRAY_SIZE(rk3288_pin_banks), + .label = "RK3288-GPIO", + .type = RK3188, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x84, + .pull_calc_reg = rk3288_calc_pull_reg_and_bit, +}; + static const struct of_device_id rockchip_pinctrl_dt_match[] = { { .compatible = "rockchip,rk2928-pinctrl", .data = (void *)&rk2928_pin_ctrl }, @@ -1789,6 +1860,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = (void *)&rk3066b_pin_ctrl }, { .compatible = "rockchip,rk3188-pinctrl", .data = (void *)&rk3188_pin_ctrl }, + { .compatible = "rockchip,rk3288-pinctrl", + .data = (void *)&rk3288_pin_ctrl }, {}, }; MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); From c01607c7daa59ca9f9cd33c2421ccae98239ab54 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 1 Jul 2014 23:25:08 +0800 Subject: [PATCH 24/61] pinctrl: sunxi: Remove gpio_out function from sun5i-a13 PG0/1/2 pins The A13 user manual states pins PG0/1/2 only have GPIO input and interrupt functions. Remove the gpio_out functions for these pins. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c index 29c734a60b51..e47c33dbae3a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c @@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = { /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), SUNXI_FUNCTION(0x0, "gpio_in"), From d9ff081d9123af59144d3617668c8274b2cc3254 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sun, 29 Jun 2014 15:58:19 +0200 Subject: [PATCH 25/61] pinctrl: sunxi: Remove PINCTRL_SUNXI The PINCTRL_SUNXI configuration was kept only to deal with the introduction of per-machine symbols and the various pintrl drivers through different tree. Now that it's not useful anymore, we can just remove it. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- arch/arm/mach-sunxi/Kconfig | 1 - drivers/pinctrl/sunxi/Kconfig | 15 ++++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 0fbd4f156bfa..d46b9495cd55 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -4,7 +4,6 @@ menuconfig ARCH_SUNXI select CLKSRC_MMIO select GENERIC_IRQ_CHIP select PINCTRL - select PINCTRL_SUNXI select SUN4I_TIMER if ARCH_SUNXI diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index 73e0a305ea13..4cbf458579d5 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -1,36 +1,33 @@ if ARCH_SUNXI -config PINCTRL_SUNXI - bool - config PINCTRL_SUNXI_COMMON bool select PINMUX select GENERIC_PINCONF config PINCTRL_SUN4I_A10 - def_bool PINCTRL_SUNXI || MACH_SUN4I + def_bool MACH_SUN4I select PINCTRL_SUNXI_COMMON config PINCTRL_SUN5I_A10S - def_bool PINCTRL_SUNXI || MACH_SUN5I + def_bool MACH_SUN5I select PINCTRL_SUNXI_COMMON config PINCTRL_SUN5I_A13 - def_bool PINCTRL_SUNXI || MACH_SUN5I + def_bool MACH_SUN5I select PINCTRL_SUNXI_COMMON config PINCTRL_SUN6I_A31 - def_bool PINCTRL_SUNXI || MACH_SUN6I + def_bool MACH_SUN6I select PINCTRL_SUNXI_COMMON config PINCTRL_SUN6I_A31_R - def_bool PINCTRL_SUNXI || MACH_SUN6I + def_bool MACH_SUN6I depends on RESET_CONTROLLER select PINCTRL_SUNXI_COMMON config PINCTRL_SUN7I_A20 - def_bool PINCTRL_SUNXI || MACH_SUN7I + def_bool MACH_SUN7I select PINCTRL_SUNXI_COMMON endif From 4c821d1c934c741b995d37cab206b7fca5ffd6a5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 17 Jun 2014 22:52:51 +0800 Subject: [PATCH 26/61] pinctrl: sunxi: Add A23 PIO controller support The A23 uses the same pin controller as previous SoC's from Allwinner. Add support for the pins controlled by the main PIO controller. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- .../pinctrl/allwinner,sunxi-pinctrl.txt | 1 + drivers/pinctrl/sunxi/Kconfig | 4 + drivers/pinctrl/sunxi/Makefile | 1 + drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c | 593 ++++++++++++++++++ 4 files changed, 599 insertions(+) create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt index d8d065608ec0..44a78c1fee83 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt @@ -13,6 +13,7 @@ Required properties: "allwinner,sun6i-a31-pinctrl" "allwinner,sun6i-a31-r-pinctrl" "allwinner,sun7i-a20-pinctrl" + "allwinner,sun8i-a23-pinctrl" - reg: Should contain the register physical address and length for the pin controller. diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index 4cbf458579d5..7e6a2684949a 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -30,4 +30,8 @@ config PINCTRL_SUN7I_A20 def_bool MACH_SUN7I select PINCTRL_SUNXI_COMMON +config PINCTRL_SUN8I_A23 + def_bool MACH_SUN8I + select PINCTRL_SUNXI_COMMON + endif diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile index 0f4461cbe11d..850cd5014dd8 100644 --- a/drivers/pinctrl/sunxi/Makefile +++ b/drivers/pinctrl/sunxi/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_PINCTRL_SUN5I_A13) += pinctrl-sun5i-a13.o obj-$(CONFIG_PINCTRL_SUN6I_A31) += pinctrl-sun6i-a31.o obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o +obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c new file mode 100644 index 000000000000..ac71e8c5901b --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c @@ -0,0 +1,593 @@ +/* + * Allwinner A23 SoCs pinctrl driver. + * + * Copyright (C) 2014 Chen-Yu Tsai + * + * Chen-Yu Tsai + * + * Copyright (C) 2014 Maxime Ripard + * + * Maxime Ripard + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-sunxi.h" + +static const struct sunxi_desc_pin sun8i_a23_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CS */ + SUNXI_FUNCTION(0x3, "jtag"), /* MS0 */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PA_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ + SUNXI_FUNCTION(0x3, "jtag"), /* CKO */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PA_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ + SUNXI_FUNCTION(0x3, "jtag"), /* DOO */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PA_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ + SUNXI_FUNCTION(0x3, "jtag"), /* DIO */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PA_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PA_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PA_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PA_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PA_EINT7 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PB_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)), /* PB_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)), /* PB_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)), /* PB_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s0"), /* SYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)), /* PB_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s0"), /* DOUT */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)), /* PB_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s0"), /* DIN */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)), /* PB_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "i2s0"), /* DI */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)), /* PB_EINT7 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* WE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* ALE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CLE */ + SUNXI_FUNCTION(0x3, "spi0")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */ + SUNXI_FUNCTION(0x3, "spi0")), /* CS */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RE */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* RB1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand"), /* DQS */ + SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* CE2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* CE3 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */ + SUNXI_FUNCTION(0x3, "mmc1")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */ + SUNXI_FUNCTION(0x3, "mmc1")), /* CMD */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */ + SUNXI_FUNCTION(0x3, "mmc1")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */ + SUNXI_FUNCTION(0x3, "mmc1")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */ + SUNXI_FUNCTION(0x3, "mmc1")), /* D2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */ + SUNXI_FUNCTION(0x3, "mmc1")), /* D3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */ + SUNXI_FUNCTION(0x3, "uart3")), /* TX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */ + SUNXI_FUNCTION(0x3, "uart3")), /* RX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */ + SUNXI_FUNCTION(0x3, "uart1")), /* TX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */ + SUNXI_FUNCTION(0x3, "uart1")), /* RX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */ + SUNXI_FUNCTION(0x3, "uart1")), /* RTS */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */ + SUNXI_FUNCTION(0x3, "uart1")), /* CTS */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */ + SUNXI_FUNCTION(0x3, "i2s1")), /* SYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */ + SUNXI_FUNCTION(0x3, "i2s1")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */ + SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */ + SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* DE */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* PCLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* MCLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* HSYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* VSYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi")), /* D7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* SCK */ + SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* SDA */ + SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */ + SUNXI_FUNCTION(0x3, "jtag")), /* MS1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */ + SUNXI_FUNCTION(0x3, "jtag")), /* DI1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ + SUNXI_FUNCTION(0x3, "uart0")), /* TX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */ + SUNXI_FUNCTION(0x3, "jtag")), /* DO1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ + SUNXI_FUNCTION(0x3, "uart0")), /* RX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */ + SUNXI_FUNCTION(0x3, "jtag")), /* CK1 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 0)), /* PG_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 1)), /* PG_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 2)), /* PG_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 3)), /* PG_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 4)), /* PG_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 5)), /* PG_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart1"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 6)), /* PG_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart1"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 7)), /* PG_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)), /* PG_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)), /* PG_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s1"), /* SYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 10)), /* PG_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s1"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 11)), /* PG_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s1"), /* DOUT */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 12)), /* PG_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2s1"), /* DIN */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 13)), /* PG_EINT13 */ + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm0")), + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm1")), + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* CS */ + SUNXI_FUNCTION(0x3, "uart3")), /* TX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* CLK */ + SUNXI_FUNCTION(0x3, "uart3")), /* RX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* DOUT */ + SUNXI_FUNCTION(0x3, "uart3")), /* RTS */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi0"), /* DIN */ + SUNXI_FUNCTION(0x3, "uart3")), /* CTS */ +}; + +static const struct sunxi_pinctrl_desc sun8i_a23_pinctrl_data = { + .pins = sun8i_a23_pins, + .npins = ARRAY_SIZE(sun8i_a23_pins), + .irq_banks = 3, +}; + +static int sun8i_a23_pinctrl_probe(struct platform_device *pdev) +{ + return sunxi_pinctrl_init(pdev, + &sun8i_a23_pinctrl_data); +} + +static struct of_device_id sun8i_a23_pinctrl_match[] = { + { .compatible = "allwinner,sun8i-a23-pinctrl", }, + {} +}; +MODULE_DEVICE_TABLE(of, sun8i_a23_pinctrl_match); + +static struct platform_driver sun8i_a23_pinctrl_driver = { + .probe = sun8i_a23_pinctrl_probe, + .driver = { + .name = "sun8i-a23-pinctrl", + .owner = THIS_MODULE, + .of_match_table = sun8i_a23_pinctrl_match, + }, +}; +module_platform_driver(sun8i_a23_pinctrl_driver); + +MODULE_AUTHOR("Chen-Yu Tsai "); +MODULE_AUTHOR("Maxime Ripard Date: Tue, 17 Jun 2014 22:52:52 +0800 Subject: [PATCH 27/61] pinctrl: sunxi: Add A23 R_PIO controller support The A23 has a R_PIO pin controller, similar to the one found on the A31 SoC. Add support for the pins controlled by the R_PIO controller. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- .../pinctrl/allwinner,sunxi-pinctrl.txt | 1 + drivers/pinctrl/sunxi/Kconfig | 5 + drivers/pinctrl/sunxi/Makefile | 1 + drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c | 142 ++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt index 44a78c1fee83..93ce12eb422a 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt @@ -14,6 +14,7 @@ Required properties: "allwinner,sun6i-a31-r-pinctrl" "allwinner,sun7i-a20-pinctrl" "allwinner,sun8i-a23-pinctrl" + "allwinner,sun8i-a23-r-pinctrl" - reg: Should contain the register physical address and length for the pin controller. diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index 7e6a2684949a..a5e10f777ed2 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -34,4 +34,9 @@ config PINCTRL_SUN8I_A23 def_bool MACH_SUN8I select PINCTRL_SUNXI_COMMON +config PINCTRL_SUN8I_A23_R + def_bool MACH_SUN8I + depends on RESET_CONTROLLER + select PINCTRL_SUNXI_COMMON + endif diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile index 850cd5014dd8..e797efb02901 100644 --- a/drivers/pinctrl/sunxi/Makefile +++ b/drivers/pinctrl/sunxi/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_PINCTRL_SUN6I_A31) += pinctrl-sun6i-a31.o obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o +obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c new file mode 100644 index 000000000000..90f3b3a7c51e --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c @@ -0,0 +1,142 @@ +/* + * Allwinner A23 SoCs special pins pinctrl driver. + * + * Copyright (C) 2014 Chen-Yu Tsai + * Chen-Yu Tsai + * + * Copyright (C) 2014 Boris Brezillon + * Boris Brezillon + * + * Copyright (C) 2014 Maxime Ripard + * Maxime Ripard + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include + +#include "pinctrl-sunxi.h" + +static const struct sunxi_desc_pin sun8i_a23_r_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */ + SUNXI_FUNCTION(0x3, "s_twi"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PL_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */ + SUNXI_FUNCTION(0x3, "s_twi"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PL_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_uart"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PL_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_uart"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PL_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "s_jtag"), /* MS */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PL_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "s_jtag"), /* CK */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PL_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "s_jtag"), /* DO */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PL_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "s_jtag"), /* DI */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PL_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_twi"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 8)), /* PL_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_twi"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 9)), /* PL_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "s_pwm"), + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 10)), /* PL_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 11)), /* PL_EINT11 */ +}; + +static const struct sunxi_pinctrl_desc sun8i_a23_r_pinctrl_data = { + .pins = sun8i_a23_r_pins, + .npins = ARRAY_SIZE(sun8i_a23_r_pins), + .pin_base = PL_BASE, + .irq_banks = 1, +}; + +static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev) +{ + struct reset_control *rstc; + int ret; + + rstc = devm_reset_control_get(&pdev->dev, NULL); + if (IS_ERR(rstc)) { + dev_err(&pdev->dev, "Reset controller missing\n"); + return PTR_ERR(rstc); + } + + ret = reset_control_deassert(rstc); + if (ret) + return ret; + + ret = sunxi_pinctrl_init(pdev, + &sun8i_a23_r_pinctrl_data); + + if (ret) + reset_control_assert(rstc); + + return ret; +} + +static struct of_device_id sun8i_a23_r_pinctrl_match[] = { + { .compatible = "allwinner,sun8i-a23-r-pinctrl", }, + {} +}; +MODULE_DEVICE_TABLE(of, sun8i_a23_r_pinctrl_match); + +static struct platform_driver sun8i_a23_r_pinctrl_driver = { + .probe = sun8i_a23_r_pinctrl_probe, + .driver = { + .name = "sun8i-a23-r-pinctrl", + .owner = THIS_MODULE, + .of_match_table = sun8i_a23_r_pinctrl_match, + }, +}; +module_platform_driver(sun8i_a23_r_pinctrl_driver); + +MODULE_AUTHOR("Chen-Yu Tsai "); +MODULE_AUTHOR("Boris Brezillon Date: Tue, 17 Jun 2014 23:49:11 -0500 Subject: [PATCH 28/61] pinctrl: qcom: Add BUS_HOLD pin bias This patch adds the BUS_HOLD (Keeper) bias option for pins. Signed-off-by: Andy Gross Acked-by: Bjorn Andersson Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-msm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c index bdfaba4430f2..43d47b7cff92 100644 --- a/drivers/pinctrl/pinctrl-msm.c +++ b/drivers/pinctrl/pinctrl-msm.c @@ -181,6 +181,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, switch (param) { case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_BUS_HOLD: case PIN_CONFIG_BIAS_PULL_UP: *bit = g->pull_bit; *mask = 3; @@ -218,6 +219,7 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin, #define MSM_NO_PULL 0 #define MSM_PULL_DOWN 1 +#define MSM_KEEPER 2 #define MSM_PULL_UP 3 static unsigned msm_regval_to_drive(u32 val) @@ -255,6 +257,9 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_PULL_DOWN: arg = arg == MSM_PULL_DOWN; break; + case PIN_CONFIG_BIAS_BUS_HOLD: + arg = arg == MSM_KEEPER; + break; case PIN_CONFIG_BIAS_PULL_UP: arg = arg == MSM_PULL_UP; break; @@ -314,6 +319,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_PULL_DOWN: arg = MSM_PULL_DOWN; break; + case PIN_CONFIG_BIAS_BUS_HOLD: + arg = MSM_KEEPER; + break; case PIN_CONFIG_BIAS_PULL_UP: arg = MSM_PULL_UP; break; From 776667a8092d3c28c357191db595494349e83919 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 23 Jun 2014 17:08:18 +0530 Subject: [PATCH 29/61] pinctrl: bcm281xx: Staticize bcm281xx_pinctrl_probe bcm281xx_pinctrl_probe is local to this file. Make it static. Signed-off-by: Sachin Kamat Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-bcm281xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c index 3bed792b2c03..c5ca9e633fff 100644 --- a/drivers/pinctrl/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/pinctrl-bcm281xx.c @@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = { .owner = THIS_MODULE, }; -int __init bcm281xx_pinctrl_probe(struct platform_device *pdev) +static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev) { struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl; struct resource *res; From 8708ebca7464af80accd52c6e1a1cf882593a4ab Mon Sep 17 00:00:00 2001 From: David PARIS Date: Wed, 25 Jun 2014 17:49:04 +0200 Subject: [PATCH 30/61] pinctrl: st: add IRQCHIP_SKIP_SET_WAKE flag no .irq_set_wake API is available for pinctrl-st driver. Add the IRQCHIP_SKIP_SET_WAKE flag to inform irq handler not to call this API. Signed-off-by: David Paris Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-st.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index e1919cd43117..506561131d7f 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1448,6 +1448,7 @@ static struct irq_chip st_gpio_irqchip = { .irq_mask = st_gpio_irq_mask, .irq_unmask = st_gpio_irq_unmask, .irq_set_type = st_gpio_irq_set_type, + .flags = IRQCHIP_SKIP_SET_WAKE, }; static int st_gpiolib_register_bank(struct st_pinctrl *info, From ca7162add9dc0b361cbf51084591c64db37199d8 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 13:26:45 +0200 Subject: [PATCH 31/61] pinctrl: pinctrl-at91.c: Cleaning up if unsigned is less than zero Remove checking if a unsigned is less than zero This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index bd57ab514aa4..ec9744f33403 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -924,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np, /* Initialise function */ func->name = np->name; func->ngroups = of_get_child_count(np); - if (func->ngroups <= 0) { + if (func->ngroups == 0) { dev_err(info->dev, "no groups defined\n"); return -EINVAL; } From 9eedfd688cb267d0fee06f68cbbddaf94423482e Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 13:28:16 +0200 Subject: [PATCH 32/61] pinctrl: pinctrl-imx.c: Cleaning up if unsigned is less than zero Remove checking if a unsigned is less than zero This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index a24448e5d399..946d594a64dd 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np, /* Initialise function */ func->name = np->name; func->num_groups = of_get_child_count(np); - if (func->num_groups <= 0) { + if (func->num_groups == 0) { dev_err(info->dev, "no groups defined in %s\n", np->full_name); return -EINVAL; } From 5aa498b95496204d3d9918b5d9287f0a4910a2a1 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 13:29:49 +0200 Subject: [PATCH 33/61] pinctrl: pinctrl-imx1-core.c: Cleaning up if unsigned is less than zero Remove checking if a unsigned is less than zero This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx1-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-imx1-core.c b/drivers/pinctrl/pinctrl-imx1-core.c index 815384b377b5..483420757c9f 100644 --- a/drivers/pinctrl/pinctrl-imx1-core.c +++ b/drivers/pinctrl/pinctrl-imx1-core.c @@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np, /* Initialise function */ func->name = np->name; func->num_groups = of_get_child_count(np); - if (func->num_groups <= 0) + if (func->num_groups == 0) return -EINVAL; func->groups = devm_kzalloc(info->dev, From 8b0c107ce049ddaf0ca9d8cd4faac1cf5c1e9f20 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 13:32:49 +0200 Subject: [PATCH 34/61] pinctrl: pinctrl-st.c: Cleaning up if unsigned is less than zero Remove checking if a unsigned is less than zero This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Acked-by: Srinivas Kandagatla Acked-by: Maxime Coquelin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 506561131d7f..1845870413ea 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1250,7 +1250,7 @@ static int st_pctl_parse_functions(struct device_node *np, func = &info->functions[index]; func->name = np->name; func->ngroups = of_get_child_count(np); - if (func->ngroups <= 0) { + if (func->ngroups == 0) { dev_err(info->dev, "No groups defined\n"); return -EINVAL; } From 445d20260bb0a7633f9d7d46a3afb0d9ee4109a7 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 15:41:31 +0200 Subject: [PATCH 35/61] pinctrl: pinctrl-at91.c: Cleaning up values that are never used Remove variable that are never used This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index ec9744f33403..af1ba4fc150d 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -772,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin_id) { unsigned long config; - int ret, val, num_conf = 0; + int val, num_conf = 0; - ret = at91_pinconf_get(pctldev, pin_id, &config); + at91_pinconf_get(pctldev, pin_id, &config); DBG_SHOW_FLAG(MULTI_DRIVE); DBG_SHOW_FLAG(PULL_UP); From 849bfe0637fd45bf50aac3b12e7e56248c0b9031 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 15:43:01 +0200 Subject: [PATCH 36/61] pinctrl: pinctrl-single.c: Cleaning up values that are never used Remove variable that are never used This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index ff6a2bda52e5..efeb12ad7b19 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1683,11 +1683,10 @@ static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc) { struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc); struct irq_chip *chip; - int res; chip = irq_get_chip(irq); chained_irq_enter(chip, desc); - res = pcs_irq_handle(pcs_soc); + pcs_irq_handle(pcs_soc); /* REVISIT: export and add handle_bad_irq(irq, desc)? */ chained_irq_exit(chip, desc); From 719e231bed5b1c638c7f48a657547562fc2064a3 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 18:57:14 +0200 Subject: [PATCH 37/61] pinctrl: pinctrl-adi2.c: Cleaning up wrong format string usage %d in format string used, but the type is unsigned int This was found using a static code analysis program called cppcheck Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-adi2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c index b02ee4f882c0..46413e93d850 100644 --- a/drivers/pinctrl/pinctrl-adi2.c +++ b/drivers/pinctrl/pinctrl-adi2.c @@ -401,7 +401,7 @@ static int adi_gpio_irq_type(struct irq_data *d, unsigned int type) if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - snprintf(buf, 16, "gpio-irq%d", irq); + snprintf(buf, 16, "gpio-irq%u", irq); port_setup(port, d->hwirq, true); } else goto out; From bf4cef6c70258e1f771ebfe08558b77ad24700c2 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 18:58:46 +0200 Subject: [PATCH 38/61] pinctrl: pinctrl-single.c: Cleaning up wrong format string usage %d in format string used, but the type is unsigned int This was found using a static code analysis program called cppcheck Signed-off-by: Rickard Strandqvist Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index efeb12ad7b19..95dd9cf55cb3 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -780,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, pin = &pcs->pins.pa[i]; pn = &pcs->names[i]; - sprintf(pn->name, "%lx.%d", + sprintf(pn->name, "%lx.%u", (unsigned long)pcs->res->start + offset, pin_pos); pin->name = pn->name; pin->number = i; From 1f978217a0c687a4cfed6ad698a3173826be4c3f Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 26 Jun 2014 15:44:32 +0200 Subject: [PATCH 39/61] pinctrl: pinctrl-st.c: Cleaning up values that are never used Remove variable that are never used This was found using a static code analysis program called cppcheck. Signed-off-by: Rickard Strandqvist Acked-by: Patrice Chotard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-st.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 1845870413ea..d0fb44a095e9 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1172,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np, const __be32 *list; struct property *pp; struct st_pinconf *conf; - phandle phandle; struct device_node *pins; - u32 pin; int i = 0, npins = 0, nr_props; pins = of_get_child_by_name(np, "st,pins"); @@ -1212,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np, conf = &grp->pin_conf[i]; /* bank & offset */ - phandle = be32_to_cpup(list++); - pin = be32_to_cpup(list++); + be32_to_cpup(list++); + be32_to_cpup(list++); conf->pin = of_get_named_gpio(pins, pp->name, 0); conf->name = pp->name; grp->pins[i] = conf->pin; From ff998356b644ebe723127bd9eec6040b59a4a4f6 Mon Sep 17 00:00:00 2001 From: Eric Ernst Date: Thu, 12 Jun 2014 11:06:20 -0700 Subject: [PATCH 40/61] pinctrl: baytrail: Warn if direct IRQ GPIO set to output For Baytrail, you should never set a GPIO set to direct_irq to output mode. When direct_irq_en is set for a GPIO, it is tied directly to an APIC internally, and making the pad output does not make any sense. Assert a WARN() in the event this happens. Signed-off-by: Eric Ernst Acked-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-baytrail.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index 975572e2f260..701a646a3d10 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -44,6 +44,7 @@ /* BYT_CONF0_REG register bits */ #define BYT_IODEN BIT(31) +#define BYT_DIRECT_IRQ_EN BIT(27) #define BYT_TRIG_NEG BIT(26) #define BYT_TRIG_POS BIT(25) #define BYT_TRIG_LVL BIT(24) @@ -303,12 +304,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { struct byt_gpio *vg = to_byt_gpio(chip); + void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG); void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG); unsigned long flags; u32 reg_val; spin_lock_irqsave(&vg->lock, flags); + /* + * Before making any direction modifications, do a check if gpio + * is set for direct IRQ. On baytrail, setting GPIO to output does + * not make sense, so let's at least warn the caller before they shoot + * themselves in the foot. + */ + WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, + "Potential Error: Setting GPIO with direct_irq_en to output"); + reg_val = readl(reg) | BYT_DIR_MASK; reg_val &= ~BYT_OUTPUT_EN; From 0e9386752758b74fd42fda7cbdd6ccb5cb31033c Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 2 Jul 2014 00:58:16 +0400 Subject: [PATCH 41/61] sh-pfc: r8a7791: add CAN pin groups Add CAN0/1 data/clock pin groups to R8A7791 PFC driver. Signed-off-by: Sergei Shtylyov Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 167 +++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 394b234488cc..576d41b459e9 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c @@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = { AUDIO_CLKOUT_MARK, }; +/* - CAN -------------------------------------------------------------------- */ + +static const unsigned int can0_data_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 29), +}; + +static const unsigned int can0_data_mux[] = { + CAN0_TX_MARK, CAN0_RX_MARK, +}; + +static const unsigned int can0_data_b_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 3), +}; + +static const unsigned int can0_data_b_mux[] = { + CAN0_TX_B_MARK, CAN0_RX_B_MARK, +}; + +static const unsigned int can0_data_c_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 18), +}; + +static const unsigned int can0_data_c_mux[] = { + CAN0_TX_C_MARK, CAN0_RX_C_MARK, +}; + +static const unsigned int can0_data_d_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27), +}; + +static const unsigned int can0_data_d_mux[] = { + CAN0_TX_D_MARK, CAN0_RX_D_MARK, +}; + +static const unsigned int can0_data_e_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 28), +}; + +static const unsigned int can0_data_e_mux[] = { + CAN0_TX_E_MARK, CAN0_RX_E_MARK, +}; + +static const unsigned int can0_data_f_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6), +}; + +static const unsigned int can0_data_f_mux[] = { + CAN0_TX_F_MARK, CAN0_RX_F_MARK, +}; + +static const unsigned int can1_data_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 20), +}; + +static const unsigned int can1_data_mux[] = { + CAN1_TX_MARK, CAN1_RX_MARK, +}; + +static const unsigned int can1_data_b_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(7, 8), RCAR_GP_PIN(7, 9), +}; + +static const unsigned int can1_data_b_mux[] = { + CAN1_TX_B_MARK, CAN1_RX_B_MARK, +}; + +static const unsigned int can1_data_c_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 19), +}; + +static const unsigned int can1_data_c_mux[] = { + CAN1_TX_C_MARK, CAN1_RX_C_MARK, +}; + +static const unsigned int can1_data_d_pins[] = { + /* TX, RX */ + RCAR_GP_PIN(4, 29), RCAR_GP_PIN(4, 31), +}; + +static const unsigned int can1_data_d_mux[] = { + CAN1_TX_D_MARK, CAN1_RX_D_MARK, +}; + +static const unsigned int can_clk_pins[] = { + /* CLK */ + RCAR_GP_PIN(7, 2), +}; + +static const unsigned int can_clk_mux[] = { + CAN_CLK_MARK, +}; + +static const unsigned int can_clk_b_pins[] = { + /* CLK */ + RCAR_GP_PIN(5, 21), +}; + +static const unsigned int can_clk_b_mux[] = { + CAN_CLK_B_MARK, +}; + +static const unsigned int can_clk_c_pins[] = { + /* CLK */ + RCAR_GP_PIN(4, 30), +}; + +static const unsigned int can_clk_c_mux[] = { + CAN_CLK_C_MARK, +}; + +static const unsigned int can_clk_d_pins[] = { + /* CLK */ + RCAR_GP_PIN(7, 19), +}; + +static const unsigned int can_clk_d_mux[] = { + CAN_CLK_D_MARK, +}; /* - DU --------------------------------------------------------------------- */ static const unsigned int du_rgb666_pins[] = { @@ -4055,6 +4182,20 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(audio_clk_b_b), SH_PFC_PIN_GROUP(audio_clk_c), SH_PFC_PIN_GROUP(audio_clkout), + SH_PFC_PIN_GROUP(can0_data), + SH_PFC_PIN_GROUP(can0_data_b), + SH_PFC_PIN_GROUP(can0_data_c), + SH_PFC_PIN_GROUP(can0_data_d), + SH_PFC_PIN_GROUP(can0_data_e), + SH_PFC_PIN_GROUP(can0_data_f), + SH_PFC_PIN_GROUP(can1_data), + SH_PFC_PIN_GROUP(can1_data_b), + SH_PFC_PIN_GROUP(can1_data_c), + SH_PFC_PIN_GROUP(can1_data_d), + SH_PFC_PIN_GROUP(can_clk), + SH_PFC_PIN_GROUP(can_clk_b), + SH_PFC_PIN_GROUP(can_clk_c), + SH_PFC_PIN_GROUP(can_clk_d), SH_PFC_PIN_GROUP(du_rgb666), SH_PFC_PIN_GROUP(du_rgb888), SH_PFC_PIN_GROUP(du_clk_out_0), @@ -4367,6 +4508,30 @@ static const char * const audio_clk_groups[] = { "audio_clkout", }; +static const char * const can0_groups[] = { + "can0_data_a", + "can0_data_b", + "can0_data_c", + "can0_data_d", + "can0_data_e", + "can0_data_f", + "can_clk_a", + "can_clk_b", + "can_clk_c", + "can_clk_d", +}; + +static const char * const can1_groups[] = { + "can1_data_a", + "can1_data_b", + "can1_data_c", + "can1_data_d", + "can_clk_a", + "can_clk_b", + "can_clk_c", + "can_clk_d", +}; + static const char * const du_groups[] = { "du_rgb666", "du_rgb888", @@ -4790,6 +4955,8 @@ static const char * const vin2_groups[] = { static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(audio_clk), + SH_PFC_FUNCTION(can0), + SH_PFC_FUNCTION(can1), SH_PFC_FUNCTION(du), SH_PFC_FUNCTION(du0), SH_PFC_FUNCTION(du1), From 18c28caa17d7127e0391e100a919d9f6c156e974 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 2 Jul 2014 17:40:59 +0200 Subject: [PATCH 42/61] pinctrl: samsung: Decouple direction setting from pinctrl This patch makes the pinctrl-samsung driver configure GPIO direction on its own, without using the pinctrl_gpio_direction_*() "helpers". The rationale behind this change is as follows: - pinctrl-samsung does not need translation from GPIO namespace to pinctrl namespace to handle GPIO operations - GPIO chip and offset therein are enough to calculate necessary offsets and bit masks in constant time, - the pinctrl_gpio_direction_*() functions do not do anything useful other than translating the pin into pinctrl namespace and calling the .gpio_set_direction() from pinmux_ops of the controller, - the undesirable side effect of using those helpers is losing the ability to change GPIO direction in atomic context, because they explicitly use a mutex for synchronization, Results of this patch are: - fixed warnings about scheduling while atomic in code that needs to set GPIO direction in atomic context (e.g. interrupt handler), - reduced overhead of bitbanging drivers that use gpio_direction_*(), e.g. i2c-gpio. Signed-off-by: Tomasz Figa Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-samsung.c | 101 +++++++++++++----------------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 089abde35d44..5740f93d658c 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -333,57 +333,12 @@ static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -/* - * The calls to gpio_direction_output() and gpio_direction_input() - * leads to this function call (via the pinctrl_gpio_direction_{input|output}() - * function called from the gpiolib interface). - */ -static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset, bool input) -{ - struct samsung_pin_bank_type *type; - struct samsung_pin_bank *bank; - struct samsung_pinctrl_drv_data *drvdata; - void __iomem *reg; - u32 data, pin_offset, mask, shift; - unsigned long flags; - - bank = gc_to_pin_bank(range->gc); - type = bank->type; - drvdata = pinctrl_dev_get_drvdata(pctldev); - - pin_offset = offset - bank->pin_base; - reg = drvdata->virt_base + bank->pctl_offset + - type->reg_offset[PINCFG_TYPE_FUNC]; - - mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; - shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; - if (shift >= 32) { - /* Some banks have two config registers */ - shift -= 32; - reg += 4; - } - - spin_lock_irqsave(&bank->slock, flags); - - data = readl(reg); - data &= ~(mask << shift); - if (!input) - data |= FUNC_OUTPUT << shift; - writel(data, reg); - - spin_unlock_irqrestore(&bank->slock, flags); - - return 0; -} - /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ static const struct pinmux_ops samsung_pinmux_ops = { .get_functions_count = samsung_get_functions_count, .get_function_name = samsung_pinmux_get_fname, .get_function_groups = samsung_pinmux_get_groups, .enable = samsung_pinmux_enable, - .gpio_set_direction = samsung_pinmux_gpio_set_direction, }; /* set or get the pin config settings for a specified pin */ @@ -532,25 +487,59 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) } /* - * gpiolib gpio_direction_input callback function. The setting of the pin - * mux function as 'gpio input' will be handled by the pinctrl susbsystem - * interface. + * The calls to gpio_direction_output() and gpio_direction_input() + * leads to this function call. */ -static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +static int samsung_gpio_set_direction(struct gpio_chip *gc, + unsigned offset, bool input) { - return pinctrl_gpio_direction_input(gc->base + offset); + struct samsung_pin_bank_type *type; + struct samsung_pin_bank *bank; + struct samsung_pinctrl_drv_data *drvdata; + void __iomem *reg; + u32 data, mask, shift; + unsigned long flags; + + bank = gc_to_pin_bank(gc); + type = bank->type; + drvdata = bank->drvdata; + + reg = drvdata->virt_base + bank->pctl_offset + + type->reg_offset[PINCFG_TYPE_FUNC]; + + mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; + shift = offset * type->fld_width[PINCFG_TYPE_FUNC]; + if (shift >= 32) { + /* Some banks have two config registers */ + shift -= 32; + reg += 4; + } + + spin_lock_irqsave(&bank->slock, flags); + + data = readl(reg); + data &= ~(mask << shift); + if (!input) + data |= FUNC_OUTPUT << shift; + writel(data, reg); + + spin_unlock_irqrestore(&bank->slock, flags); + + return 0; } -/* - * gpiolib gpio_direction_output callback function. The setting of the pin - * mux function as 'gpio output' will be handled by the pinctrl susbsystem - * interface. - */ +/* gpiolib gpio_direction_input callback function. */ +static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + return samsung_gpio_set_direction(gc, offset, true); +} + +/* gpiolib gpio_direction_output callback function. */ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int value) { samsung_gpio_set(gc, offset, value); - return pinctrl_gpio_direction_output(gc->base + offset); + return samsung_gpio_set_direction(gc, offset, false); } /* From 6c6ce620e08f8764fd9884094afb274e6e85a47a Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 2 Jul 2014 17:41:00 +0200 Subject: [PATCH 43/61] pinctrl: samsung: Handle GPIO request and free using pinctrl helpers This patch adds .request() and .free() operations to gpio_chip of pinctrl-samsung driver, which call pinctrl request and free helpers to request and free pinctrl pin along with GPIO pin. Signed-off-by: Tomasz Figa Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-samsung.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 5740f93d658c..a09d8209ac2c 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -771,7 +771,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev, pin_bank = &drvdata->ctrl->pin_banks[bank]; pin_bank->grange.name = pin_bank->name; pin_bank->grange.id = bank; - pin_bank->grange.pin_base = pin_bank->pin_base; + pin_bank->grange.pin_base = drvdata->ctrl->base + + pin_bank->pin_base; pin_bank->grange.base = pin_bank->gpio_chip.base; pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; pin_bank->grange.gc = &pin_bank->gpio_chip; @@ -781,7 +782,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev, return 0; } +static int samsung_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + return pinctrl_request_gpio(chip->base + offset); +} + +static void samsung_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + pinctrl_free_gpio(chip->base + offset); +} + static const struct gpio_chip samsung_gpiolib_chip = { + .request = samsung_gpio_request, + .free = samsung_gpio_free, .set = samsung_gpio_set, .get = samsung_gpio_get, .direction_input = samsung_gpio_direction_input, From 2e4a4fda30fcf961f06573336db98cd460d3bf72 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 2 Jul 2014 17:41:01 +0200 Subject: [PATCH 44/61] pinctrl: exynos: Consolidate irq_chips of GPIO and WKUP EINTs Handling of irq_chip operations for GPIO and WKUP external interrupts is mostly the same, with the difference being offset of registers. However currently the driver has all the code duplicated for both EINT types, which is undesirable, because changes in irq_chip operations have to be done to both instances of the same code. This patch fixes this by creating exynos_irq_chip struct that has normal irq_chip struct embedded and contain differences between particular EINT types, which are three register offsets. One instance of code is removed and the new structure is used instead to fetch necessary data instead of samsung_pin_ctrl struct used previously. While at it, the patch removes Exynos-specific fields from aforementioned structure to improve layering of the driver. Signed-off-by: Tomasz Figa Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-exynos.c | 307 ++++++------------------------ drivers/pinctrl/pinctrl-samsung.h | 17 -- 2 files changed, 60 insertions(+), 264 deletions(-) diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 9609c23834ce..003bfd874a61 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -33,6 +33,18 @@ #include "pinctrl-samsung.h" #include "pinctrl-exynos.h" +struct exynos_irq_chip { + struct irq_chip chip; + + u32 eint_con; + u32 eint_mask; + u32 eint_pend; +}; + +static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip) +{ + return container_of(chip, struct exynos_irq_chip, chip); +} static struct samsung_pin_bank_type bank_type_off = { .fld_width = { 4, 1, 2, 2, 2, 2, }, @@ -50,11 +62,13 @@ static const struct of_device_id exynos_wkup_irq_ids[] = { { } }; -static void exynos_gpio_irq_mask(struct irq_data *irqd) +static void exynos_irq_mask(struct irq_data *irqd) { + struct irq_chip *chip = irq_data_get_irq_chip(irqd); + struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pinctrl_drv_data *d = bank->drvdata; - unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; + unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; unsigned long mask; unsigned long flags; @@ -67,20 +81,24 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd) spin_unlock_irqrestore(&bank->slock, flags); } -static void exynos_gpio_irq_ack(struct irq_data *irqd) +static void exynos_irq_ack(struct irq_data *irqd) { + struct irq_chip *chip = irq_data_get_irq_chip(irqd); + struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pinctrl_drv_data *d = bank->drvdata; - unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset; + unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset; writel(1 << irqd->hwirq, d->virt_base + reg_pend); } -static void exynos_gpio_irq_unmask(struct irq_data *irqd) +static void exynos_irq_unmask(struct irq_data *irqd) { + struct irq_chip *chip = irq_data_get_irq_chip(irqd); + struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pinctrl_drv_data *d = bank->drvdata; - unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset; + unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; unsigned long mask; unsigned long flags; @@ -93,7 +111,7 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd) * masked. */ if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK) - exynos_gpio_irq_ack(irqd); + exynos_irq_ack(irqd); spin_lock_irqsave(&bank->slock, flags); @@ -104,16 +122,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd) spin_unlock_irqrestore(&bank->slock, flags); } -static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) +static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) { + struct irq_chip *chip = irq_data_get_irq_chip(irqd); + struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank_type *bank_type = bank->type; struct samsung_pinctrl_drv_data *d = bank->drvdata; - struct samsung_pin_ctrl *ctrl = d->ctrl; unsigned int pin = irqd->hwirq; unsigned int shift = EXYNOS_EINT_CON_LEN * pin; unsigned int con, trig_type; - unsigned long reg_con = ctrl->geint_con + bank->eint_offset; + unsigned long reg_con = our_chip->eint_con + bank->eint_offset; unsigned long flags; unsigned int mask; @@ -167,12 +186,17 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) /* * irq_chip for gpio interrupts. */ -static struct irq_chip exynos_gpio_irq_chip = { - .name = "exynos_gpio_irq_chip", - .irq_unmask = exynos_gpio_irq_unmask, - .irq_mask = exynos_gpio_irq_mask, - .irq_ack = exynos_gpio_irq_ack, - .irq_set_type = exynos_gpio_irq_set_type, +static struct exynos_irq_chip exynos_gpio_irq_chip = { + .chip = { + .name = "exynos_gpio_irq_chip", + .irq_unmask = exynos_irq_unmask, + .irq_mask = exynos_irq_mask, + .irq_ack = exynos_irq_ack, + .irq_set_type = exynos_irq_set_type, + }, + .eint_con = EXYNOS_GPIO_ECON_OFFSET, + .eint_mask = EXYNOS_GPIO_EMASK_OFFSET, + .eint_pend = EXYNOS_GPIO_EPEND_OFFSET, }; static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, @@ -181,7 +205,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, struct samsung_pin_bank *b = h->host_data; irq_set_chip_data(virq, b); - irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip, + irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip, handle_level_irq); set_irq_flags(virq, IRQF_VALID); return 0; @@ -202,7 +226,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) struct samsung_pin_bank *bank = ctrl->pin_banks; unsigned int svc, group, pin, virq; - svc = readl(d->virt_base + ctrl->svc); + svc = readl(d->virt_base + EXYNOS_SVC_OFFSET); group = EXYNOS_SVC_GROUP(svc); pin = svc & EXYNOS_SVC_NUM_MASK; @@ -279,119 +303,6 @@ err_domains: return ret; } -static void exynos_wkup_irq_mask(struct irq_data *irqd) -{ - struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = b->drvdata; - unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; - unsigned long mask; - unsigned long flags; - - spin_lock_irqsave(&b->slock, flags); - - mask = readl(d->virt_base + reg_mask); - mask |= 1 << irqd->hwirq; - writel(mask, d->virt_base + reg_mask); - - spin_unlock_irqrestore(&b->slock, flags); -} - -static void exynos_wkup_irq_ack(struct irq_data *irqd) -{ - struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = b->drvdata; - unsigned long pend = d->ctrl->weint_pend + b->eint_offset; - - writel(1 << irqd->hwirq, d->virt_base + pend); -} - -static void exynos_wkup_irq_unmask(struct irq_data *irqd) -{ - struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = b->drvdata; - unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset; - unsigned long mask; - unsigned long flags; - - /* - * Ack level interrupts right before unmask - * - * If we don't do this we'll get a double-interrupt. Level triggered - * interrupts must not fire an interrupt if the level is not - * _currently_ active, even if it was active while the interrupt was - * masked. - */ - if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK) - exynos_wkup_irq_ack(irqd); - - spin_lock_irqsave(&b->slock, flags); - - mask = readl(d->virt_base + reg_mask); - mask &= ~(1 << irqd->hwirq); - writel(mask, d->virt_base + reg_mask); - - spin_unlock_irqrestore(&b->slock, flags); -} - -static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type) -{ - struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank_type *bank_type = bank->type; - struct samsung_pinctrl_drv_data *d = bank->drvdata; - unsigned int pin = irqd->hwirq; - unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset; - unsigned long shift = EXYNOS_EINT_CON_LEN * pin; - unsigned long con, trig_type; - unsigned long flags; - unsigned int mask; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - trig_type = EXYNOS_EINT_EDGE_RISING; - break; - case IRQ_TYPE_EDGE_FALLING: - trig_type = EXYNOS_EINT_EDGE_FALLING; - break; - case IRQ_TYPE_EDGE_BOTH: - trig_type = EXYNOS_EINT_EDGE_BOTH; - break; - case IRQ_TYPE_LEVEL_HIGH: - trig_type = EXYNOS_EINT_LEVEL_HIGH; - break; - case IRQ_TYPE_LEVEL_LOW: - trig_type = EXYNOS_EINT_LEVEL_LOW; - break; - default: - pr_err("unsupported external interrupt type\n"); - return -EINVAL; - } - - if (type & IRQ_TYPE_EDGE_BOTH) - __irq_set_handler_locked(irqd->irq, handle_edge_irq); - else - __irq_set_handler_locked(irqd->irq, handle_level_irq); - - con = readl(d->virt_base + reg_con); - con &= ~(EXYNOS_EINT_CON_MASK << shift); - con |= trig_type << shift; - writel(con, d->virt_base + reg_con); - - reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC]; - shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; - mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; - - spin_lock_irqsave(&bank->slock, flags); - - con = readl(d->virt_base + reg_con); - con &= ~(mask << shift); - con |= EXYNOS_EINT_FUNC << shift; - writel(con, d->virt_base + reg_con); - - spin_unlock_irqrestore(&bank->slock, flags); - - return 0; -} - static u32 exynos_eint_wake_mask = 0xffffffff; u32 exynos_get_eint_wake_mask(void) @@ -417,13 +328,18 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) /* * irq_chip for wakeup interrupts */ -static struct irq_chip exynos_wkup_irq_chip = { - .name = "exynos_wkup_irq_chip", - .irq_unmask = exynos_wkup_irq_unmask, - .irq_mask = exynos_wkup_irq_mask, - .irq_ack = exynos_wkup_irq_ack, - .irq_set_type = exynos_wkup_irq_set_type, - .irq_set_wake = exynos_wkup_irq_set_wake, +static struct exynos_irq_chip exynos_wkup_irq_chip = { + .chip = { + .name = "exynos_wkup_irq_chip", + .irq_unmask = exynos_irq_unmask, + .irq_mask = exynos_irq_mask, + .irq_ack = exynos_irq_ack, + .irq_set_type = exynos_irq_set_type, + .irq_set_wake = exynos_wkup_irq_set_wake, + }, + .eint_con = EXYNOS_WKUP_ECON_OFFSET, + .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, + .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, }; /* interrupt handler for wakeup interrupts 0..15 */ @@ -464,7 +380,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) struct irq_chip *chip = irq_get_chip(irq); struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq); struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata; - struct samsung_pin_ctrl *ctrl = d->ctrl; unsigned long pend; unsigned long mask; int i; @@ -473,8 +388,10 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) for (i = 0; i < eintd->nr_banks; ++i) { struct samsung_pin_bank *b = eintd->banks[i]; - pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset); - mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset); + pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET + + b->eint_offset); + mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET + + b->eint_offset); exynos_irq_demux_eint(pend & ~mask, b->irq_domain); } @@ -484,7 +401,8 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip, handle_level_irq); + irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip, + handle_level_irq); irq_set_chip_data(virq, h->host_data); set_irq_flags(virq, IRQF_VALID); return 0; @@ -703,13 +621,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = s5pv210_pin_bank, .nr_banks = ARRAY_SIZE(s5pv210_pin_bank), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, @@ -758,10 +669,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = exynos3250_pin_banks0, .nr_banks = ARRAY_SIZE(exynos3250_pin_banks0), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -770,13 +677,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { /* pin-controller instance 1 data */ .pin_banks = exynos3250_pin_banks1, .nr_banks = ARRAY_SIZE(exynos3250_pin_banks1), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, @@ -843,10 +743,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = exynos4210_pin_banks0, .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -855,13 +751,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { /* pin-controller instance 1 data */ .pin_banks = exynos4210_pin_banks1, .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, @@ -942,10 +831,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = exynos4x12_pin_banks0, .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -954,13 +839,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { /* pin-controller instance 1 data */ .pin_banks = exynos4x12_pin_banks1, .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, @@ -970,10 +848,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { /* pin-controller instance 2 data */ .pin_banks = exynos4x12_pin_banks2, .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -982,10 +856,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { /* pin-controller instance 3 data */ .pin_banks = exynos4x12_pin_banks3, .nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -1058,13 +928,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = exynos5250_pin_banks0, .nr_banks = ARRAY_SIZE(exynos5250_pin_banks0), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, @@ -1074,10 +937,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { /* pin-controller instance 1 data */ .pin_banks = exynos5250_pin_banks1, .nr_banks = ARRAY_SIZE(exynos5250_pin_banks1), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -1086,10 +945,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { /* pin-controller instance 2 data */ .pin_banks = exynos5250_pin_banks2, .nr_banks = ARRAY_SIZE(exynos5250_pin_banks2), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -1098,10 +953,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { /* pin-controller instance 3 data */ .pin_banks = exynos5250_pin_banks3, .nr_banks = ARRAY_SIZE(exynos5250_pin_banks3), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, @@ -1158,13 +1009,6 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = exynos5260_pin_banks0, .nr_banks = ARRAY_SIZE(exynos5260_pin_banks0), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .label = "exynos5260-gpio-ctrl0", @@ -1172,20 +1016,12 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { /* pin-controller instance 1 data */ .pin_banks = exynos5260_pin_banks1, .nr_banks = ARRAY_SIZE(exynos5260_pin_banks1), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .label = "exynos5260-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos5260_pin_banks2, .nr_banks = ARRAY_SIZE(exynos5260_pin_banks2), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .label = "exynos5260-gpio-ctrl2", }, @@ -1256,13 +1092,6 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { /* pin-controller instance 0 data */ .pin_banks = exynos5420_pin_banks0, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks0), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .weint_con = EXYNOS_WKUP_ECON_OFFSET, - .weint_mask = EXYNOS_WKUP_EMASK_OFFSET, - .weint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, .label = "exynos5420-gpio-ctrl0", @@ -1270,40 +1099,24 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { /* pin-controller instance 1 data */ .pin_banks = exynos5420_pin_banks1, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks1), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .label = "exynos5420-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos5420_pin_banks2, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks2), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .label = "exynos5420-gpio-ctrl2", }, { /* pin-controller instance 3 data */ .pin_banks = exynos5420_pin_banks3, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks3), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .label = "exynos5420-gpio-ctrl3", }, { /* pin-controller instance 4 data */ .pin_banks = exynos5420_pin_banks4, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks4), - .geint_con = EXYNOS_GPIO_ECON_OFFSET, - .geint_mask = EXYNOS_GPIO_EMASK_OFFSET, - .geint_pend = EXYNOS_GPIO_EPEND_OFFSET, - .svc = EXYNOS_SVC_OFFSET, .eint_gpio_init = exynos_eint_gpio_init, .label = "exynos5420-gpio-ctrl4", }, diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index b3e41fa5798b..e2dce4731a01 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h @@ -156,13 +156,6 @@ struct samsung_pin_bank { * @nr_banks: number of pin banks. * @base: starting system wide pin number. * @nr_pins: number of pins supported by the controller. - * @geint_con: offset of the ext-gpio controller registers. - * @geint_mask: offset of the ext-gpio interrupt mask registers. - * @geint_pend: offset of the ext-gpio interrupt pending registers. - * @weint_con: offset of the ext-wakeup controller registers. - * @weint_mask: offset of the ext-wakeup interrupt mask registers. - * @weint_pend: offset of the ext-wakeup interrupt pending registers. - * @svc: offset of the interrupt service register. * @eint_gpio_init: platform specific callback to setup the external gpio * interrupts for the controller. * @eint_wkup_init: platform specific callback to setup the external wakeup @@ -176,16 +169,6 @@ struct samsung_pin_ctrl { u32 base; u32 nr_pins; - u32 geint_con; - u32 geint_mask; - u32 geint_pend; - - u32 weint_con; - u32 weint_mask; - u32 weint_pend; - - u32 svc; - int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); void (*suspend)(struct samsung_pinctrl_drv_data *); From 9a2c1c3b91aae73ef7aa97cce1f88002d0a7cfe8 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 2 Jul 2014 17:41:03 +0200 Subject: [PATCH 45/61] pinctrl: samsung: Allow grouping multiple pinmux/pinconf nodes One of remaining limitations of current pinctrl-samsung driver was the inability to parse multiple pinmux/pinconf group nodes grouped inside a single device tree node. It made defining groups of pins for single purpose, but with different parameters very inconvenient. This patch implements Tegra-like support for grouping multiple pinctrl groups inside one device tree node, by completely changing the way pin groups and functions are parsed from device tree. The code creating pinctrl maps from DT nodes has been borrowed from pinctrl-tegra, while the initial creation of groups and functions has been completely rewritten with following assumptions: - each group consists of just one pin and does not depend on data from device tree, - each function is represented by a device tree child node of the pin controller, which in turn can contain multiple child nodes for pins that need to have different configuration values. Device Tree bindings are fully backwards compatible. New functionality can be used by defining a new pinctrl group consisting of several child nodes, as on following example: sd4_bus8: sd4-bus-width8 { part-1 { samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6"; samsung,pin-function = <3>; samsung,pin-pud = <3>; samsung,pin-drv = <3>; }; part-2 { samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6"; samsung,pin-function = <4>; samsung,pin-pud = <4>; samsung,pin-drv = <3>; }; }; Tested on Exynos4210-Trats board and a custom Exynos4212-based one. Signed-off-by: Tomasz Figa Acked-by: Kyungmin Park Reviewed-by: Stephen Warren Cc: devicetree@vger.kernel.org Cc: Rob Herring Cc: Mark Rutland Signed-off-by: Linus Walleij --- .../bindings/pinctrl/samsung-pinctrl.txt | 23 +- drivers/pinctrl/pinctrl-samsung.c | 663 ++++++++++-------- drivers/pinctrl/pinctrl-samsung.h | 1 + 3 files changed, 409 insertions(+), 278 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index 2b32783ba821..464b2bbc6284 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt @@ -44,7 +44,11 @@ Required Properties: - Pin mux/config groups as child nodes: The pin mux (selecting pin function mode) and pin config (pull up/down, driver strength) settings are represented as child nodes of the pin-controller node. There should be atleast one - child node and there is no limit on the count of these child nodes. + child node and there is no limit on the count of these child nodes. It is + also possible for a child node to consist of several further child nodes + to allow grouping multiple pinctrl groups into one. The format of second + level child nodes is exactly the same as for first level ones and is + described below. The child node should contain a list of pin(s) on which a particular pin function selection or pin configuration (or both) have to applied. This @@ -249,6 +253,23 @@ Example 1: A pin-controller node with pin groups. samsung,pin-pud = <3>; samsung,pin-drv = <0>; }; + + sd4_bus8: sd4-bus-width8 { + part-1 { + samsung,pins = "gpk0-3", "gpk0-4", + "gpk0-5", "gpk0-6"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + part-2 { + samsung,pins = "gpk1-3", "gpk1-4", + "gpk1-5", "gpk1-6"; + samsung,pin-function = <4>; + samsung,pin-pud = <4>; + samsung,pin-drv = <3>; + }; + }; }; Example 2: A pin-controller node with external wakeup interrupt controller node. diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index a09d8209ac2c..b7de66c3b51d 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -40,9 +40,9 @@ /* list of all possible config options supported */ static struct pin_config { - char *prop_cfg; - unsigned int cfg_type; -} pcfgs[] = { + const char *property; + enum pincfg_type param; +} cfg_params[] = { { "samsung,pin-pud", PINCFG_TYPE_PUD }, { "samsung,pin-drv", PINCFG_TYPE_DRV }, { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN }, @@ -59,165 +59,244 @@ static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) return container_of(gc, struct samsung_pin_bank, gpio_chip); } -/* check if the selector is a valid pin group selector */ static int samsung_get_group_count(struct pinctrl_dev *pctldev) { - struct samsung_pinctrl_drv_data *drvdata; + struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev); - drvdata = pinctrl_dev_get_drvdata(pctldev); - return drvdata->nr_groups; + return pmx->nr_groups; } -/* return the name of the group selected by the group selector */ static const char *samsung_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) + unsigned group) { - struct samsung_pinctrl_drv_data *drvdata; + struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev); - drvdata = pinctrl_dev_get_drvdata(pctldev); - return drvdata->pin_groups[selector].name; + return pmx->pin_groups[group].name; } -/* return the pin numbers associated with the specified group */ static int samsung_get_group_pins(struct pinctrl_dev *pctldev, - unsigned selector, const unsigned **pins, unsigned *num_pins) + unsigned group, + const unsigned **pins, + unsigned *num_pins) { - struct samsung_pinctrl_drv_data *drvdata; + struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev); + + *pins = pmx->pin_groups[group].pins; + *num_pins = pmx->pin_groups[group].num_pins; - drvdata = pinctrl_dev_get_drvdata(pctldev); - *pins = drvdata->pin_groups[selector].pins; - *num_pins = drvdata->pin_groups[selector].num_pins; return 0; } -/* create pinctrl_map entries by parsing device tree nodes */ -static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, struct pinctrl_map **maps, - unsigned *nmaps) +static int reserve_map(struct device *dev, struct pinctrl_map **map, + unsigned *reserved_maps, unsigned *num_maps, + unsigned reserve) { - struct device *dev = pctldev->dev; - struct pinctrl_map *map; - unsigned long *cfg = NULL; - char *gname, *fname; - int cfg_cnt = 0, map_cnt = 0, idx = 0; + unsigned old_num = *reserved_maps; + unsigned new_num = *num_maps + reserve; + struct pinctrl_map *new_map; - /* count the number of config options specfied in the node */ - for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) { - if (of_find_property(np, pcfgs[idx].prop_cfg, NULL)) - cfg_cnt++; - } + if (old_num >= new_num) + return 0; - /* - * Find out the number of map entries to create. All the config options - * can be accomadated into a single config map entry. - */ - if (cfg_cnt) - map_cnt = 1; - if (of_find_property(np, "samsung,pin-function", NULL)) - map_cnt++; - if (!map_cnt) { - dev_err(dev, "node %s does not have either config or function " - "configurations\n", np->name); - return -EINVAL; - } - - /* Allocate memory for pin-map entries */ - map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL); - if (!map) { - dev_err(dev, "could not alloc memory for pin-maps\n"); + new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL); + if (!new_map) { + dev_err(dev, "krealloc(map) failed\n"); return -ENOMEM; } - *nmaps = 0; - /* - * Allocate memory for pin group name. The pin group name is derived - * from the node name from which these map entries are be created. - */ - gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL); - if (!gname) { - dev_err(dev, "failed to alloc memory for group name\n"); - goto free_map; - } - sprintf(gname, "%s%s", np->name, GROUP_SUFFIX); + memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map)); - /* - * don't have config options? then skip over to creating function - * map entries. - */ - if (!cfg_cnt) - goto skip_cfgs; + *map = new_map; + *reserved_maps = new_num; - /* Allocate memory for config entries */ - cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL); - if (!cfg) { - dev_err(dev, "failed to alloc memory for configs\n"); - goto free_gname; - } - - /* Prepare a list of config settings */ - for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) { - u32 value; - if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value)) - cfg[cfg_cnt++] = - PINCFG_PACK(pcfgs[idx].cfg_type, value); - } - - /* create the config map entry */ - map[*nmaps].data.configs.group_or_pin = gname; - map[*nmaps].data.configs.configs = cfg; - map[*nmaps].data.configs.num_configs = cfg_cnt; - map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP; - *nmaps += 1; - -skip_cfgs: - /* create the function map entry */ - if (of_find_property(np, "samsung,pin-function", NULL)) { - fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL); - if (!fname) { - dev_err(dev, "failed to alloc memory for func name\n"); - goto free_cfg; - } - sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX); - - map[*nmaps].data.mux.group = gname; - map[*nmaps].data.mux.function = fname; - map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP; - *nmaps += 1; - } - - *maps = map; return 0; - -free_cfg: - kfree(cfg); -free_gname: - kfree(gname); -free_map: - kfree(map); - return -ENOMEM; } -/* free the memory allocated to hold the pin-map table */ -static void samsung_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) +static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps, + unsigned *num_maps, const char *group, + const char *function) { - int idx; + if (WARN_ON(*num_maps == *reserved_maps)) + return -ENOSPC; - for (idx = 0; idx < num_maps; idx++) { - if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) { - kfree(map[idx].data.mux.function); - if (!idx) - kfree(map[idx].data.mux.group); - } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) { - kfree(map[idx].data.configs.configs); - if (!idx) - kfree(map[idx].data.configs.group_or_pin); - } - }; + (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; + (*map)[*num_maps].data.mux.group = group; + (*map)[*num_maps].data.mux.function = function; + (*num_maps)++; + + return 0; +} + +static int add_map_configs(struct device *dev, struct pinctrl_map **map, + unsigned *reserved_maps, unsigned *num_maps, + const char *group, unsigned long *configs, + unsigned num_configs) +{ + unsigned long *dup_configs; + + if (WARN_ON(*num_maps == *reserved_maps)) + return -ENOSPC; + + dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs), + GFP_KERNEL); + if (!dup_configs) { + dev_err(dev, "kmemdup(configs) failed\n"); + return -ENOMEM; + } + + (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP; + (*map)[*num_maps].data.configs.group_or_pin = group; + (*map)[*num_maps].data.configs.configs = dup_configs; + (*map)[*num_maps].data.configs.num_configs = num_configs; + (*num_maps)++; + + return 0; +} + +static int add_config(struct device *dev, unsigned long **configs, + unsigned *num_configs, unsigned long config) +{ + unsigned old_num = *num_configs; + unsigned new_num = old_num + 1; + unsigned long *new_configs; + + new_configs = krealloc(*configs, sizeof(*new_configs) * new_num, + GFP_KERNEL); + if (!new_configs) { + dev_err(dev, "krealloc(configs) failed\n"); + return -ENOMEM; + } + + new_configs[old_num] = config; + + *configs = new_configs; + *num_configs = new_num; + + return 0; +} + +static void samsung_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, + unsigned num_maps) +{ + int i; + + for (i = 0; i < num_maps; i++) + if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) + kfree(map[i].data.configs.configs); kfree(map); } +static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata, + struct device *dev, + struct device_node *np, + struct pinctrl_map **map, + unsigned *reserved_maps, + unsigned *num_maps) +{ + int ret, i; + u32 val; + unsigned long config; + unsigned long *configs = NULL; + unsigned num_configs = 0; + unsigned reserve; + struct property *prop; + const char *group; + bool has_func = false; + + ret = of_property_read_u32(np, "samsung,pin-function", &val); + if (!ret) + has_func = true; + + for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { + ret = of_property_read_u32(np, cfg_params[i].property, &val); + if (!ret) { + config = PINCFG_PACK(cfg_params[i].param, val); + ret = add_config(dev, &configs, &num_configs, config); + if (ret < 0) + goto exit; + /* EINVAL=missing, which is fine since it's optional */ + } else if (ret != -EINVAL) { + dev_err(dev, "could not parse property %s\n", + cfg_params[i].property); + } + } + + reserve = 0; + if (has_func) + reserve++; + if (num_configs) + reserve++; + ret = of_property_count_strings(np, "samsung,pins"); + if (ret < 0) { + dev_err(dev, "could not parse property samsung,pins\n"); + goto exit; + } + reserve *= ret; + + ret = reserve_map(dev, map, reserved_maps, num_maps, reserve); + if (ret < 0) + goto exit; + + of_property_for_each_string(np, "samsung,pins", prop, group) { + if (has_func) { + ret = add_map_mux(map, reserved_maps, + num_maps, group, np->full_name); + if (ret < 0) + goto exit; + } + + if (num_configs) { + ret = add_map_configs(dev, map, reserved_maps, + num_maps, group, configs, + num_configs); + if (ret < 0) + goto exit; + } + } + + ret = 0; + +exit: + kfree(configs); + return ret; +} + +static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, + unsigned *num_maps) +{ + struct samsung_pinctrl_drv_data *drvdata; + unsigned reserved_maps; + struct device_node *np; + int ret; + + drvdata = pinctrl_dev_get_drvdata(pctldev); + + reserved_maps = 0; + *map = NULL; + *num_maps = 0; + + if (!of_get_child_count(np_config)) + return samsung_dt_subnode_to_map(drvdata, pctldev->dev, + np_config, map, + &reserved_maps, + num_maps); + + for_each_child_of_node(np_config, np) { + ret = samsung_dt_subnode_to_map(drvdata, pctldev->dev, np, map, + &reserved_maps, num_maps); + if (ret < 0) { + samsung_dt_free_map(pctldev, *map, *num_maps); + return ret; + } + } + + return 0; +} + /* list of pinctrl callbacks for the pinctrl core */ static const struct pinctrl_ops samsung_pctrl_ops = { .get_groups_count = samsung_get_group_count, @@ -286,43 +365,38 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, unsigned group, bool enable) { struct samsung_pinctrl_drv_data *drvdata; - const unsigned int *pins; + struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; void __iomem *reg; - u32 mask, shift, data, pin_offset, cnt; + u32 mask, shift, data, pin_offset; unsigned long flags; + const struct samsung_pmx_func *func; + const struct samsung_pin_group *grp; drvdata = pinctrl_dev_get_drvdata(pctldev); - pins = drvdata->pin_groups[group].pins; + func = &drvdata->pmx_functions[selector]; + grp = &drvdata->pin_groups[group]; - /* - * for each pin in the pin group selected, program the correspoding pin - * pin function number in the config register. - */ - for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { - struct samsung_pin_bank_type *type; - - pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base, - ®, &pin_offset, &bank); - type = bank->type; - mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; - shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; - if (shift >= 32) { - /* Some banks have two config registers */ - shift -= 32; - reg += 4; - } - - spin_lock_irqsave(&bank->slock, flags); - - data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); - data &= ~(mask << shift); - if (enable) - data |= drvdata->pin_groups[group].func << shift; - writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); - - spin_unlock_irqrestore(&bank->slock, flags); + pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base, + ®, &pin_offset, &bank); + type = bank->type; + mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; + shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; + if (shift >= 32) { + /* Some banks have two config registers */ + shift -= 32; + reg += 4; } + + spin_lock_irqsave(&bank->slock, flags); + + data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); + data &= ~(mask << shift); + if (enable) + data |= func->val << shift; + writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); + + spin_unlock_irqrestore(&bank->slock, flags); } /* enable a specified pinmux by writing to registers */ @@ -559,87 +633,115 @@ static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset) return (virq) ? : -ENXIO; } -/* - * Parse the pin names listed in the 'samsung,pins' property and convert it - * into a list of gpio numbers are create a pin group from it. - */ -static int samsung_pinctrl_parse_dt_pins(struct platform_device *pdev, - struct device_node *cfg_np, - struct pinctrl_desc *pctl, - unsigned int **pin_list, - unsigned int *npins) +static struct samsung_pin_group *samsung_pinctrl_create_groups( + struct device *dev, + struct samsung_pinctrl_drv_data *drvdata, + unsigned int *cnt) { - struct device *dev = &pdev->dev; - struct property *prop; - struct pinctrl_pin_desc const *pdesc = pctl->pins; - unsigned int idx = 0, cnt; - const char *pin_name; - - *npins = of_property_count_strings(cfg_np, "samsung,pins"); - if (IS_ERR_VALUE(*npins)) { - dev_err(dev, "invalid pin list in %s node", cfg_np->name); - return -EINVAL; - } - - *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL); - if (!*pin_list) { - dev_err(dev, "failed to allocate memory for pin list\n"); - return -ENOMEM; - } - - of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) { - for (cnt = 0; cnt < pctl->npins; cnt++) { - if (pdesc[cnt].name) { - if (!strcmp(pin_name, pdesc[cnt].name)) { - (*pin_list)[idx++] = pdesc[cnt].number; - break; - } - } - } - if (cnt == pctl->npins) { - dev_err(dev, "pin %s not valid in %s node\n", - pin_name, cfg_np->name); - devm_kfree(dev, *pin_list); - return -EINVAL; - } - } - - return 0; -} - -/* - * Parse the information about all the available pin groups and pin functions - * from device node of the pin-controller. A pin group is formed with all - * the pins listed in the "samsung,pins" property. - */ -static int samsung_pinctrl_parse_dt(struct platform_device *pdev, - struct samsung_pinctrl_drv_data *drvdata) -{ - struct device *dev = &pdev->dev; - struct device_node *dev_np = dev->of_node; - struct device_node *cfg_np; + struct pinctrl_desc *ctrldesc = &drvdata->pctl; struct samsung_pin_group *groups, *grp; - struct samsung_pmx_func *functions, *func; - unsigned *pin_list; - unsigned int npins, grp_cnt, func_idx = 0; - char *gname, *fname; - int ret; + const struct pinctrl_pin_desc *pdesc; + int i; - grp_cnt = of_get_child_count(dev_np); - if (!grp_cnt) - return -EINVAL; - - groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL); - if (!groups) { - dev_err(dev, "failed allocate memory for ping group list\n"); - return -EINVAL; - } + groups = devm_kzalloc(dev, ctrldesc->npins * sizeof(*groups), + GFP_KERNEL); + if (!groups) + return ERR_PTR(-EINVAL); grp = groups; - functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL); + pdesc = ctrldesc->pins; + for (i = 0; i < ctrldesc->npins; ++i, ++pdesc, ++grp) { + grp->name = pdesc->name; + grp->pins = &pdesc->number; + grp->num_pins = 1; + } + + *cnt = ctrldesc->npins; + return groups; +} + +static int samsung_pinctrl_create_function(struct device *dev, + struct samsung_pinctrl_drv_data *drvdata, + struct device_node *func_np, + struct samsung_pmx_func *func) +{ + int npins; + int ret; + int i; + + if (of_property_read_u32(func_np, "samsung,pin-function", &func->val)) + return 0; + + npins = of_property_count_strings(func_np, "samsung,pins"); + if (npins < 1) { + dev_err(dev, "invalid pin list in %s node", func_np->name); + return -EINVAL; + } + + func->name = func_np->full_name; + + func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL); + if (!func->groups) + return -ENOMEM; + + for (i = 0; i < npins; ++i) { + const char *gname; + + ret = of_property_read_string_index(func_np, "samsung,pins", + i, &gname); + if (ret) { + dev_err(dev, + "failed to read pin name %d from %s node\n", + i, func_np->name); + return ret; + } + + func->groups[i] = gname; + } + + func->num_groups = npins; + return 1; +} + +static struct samsung_pmx_func *samsung_pinctrl_create_functions( + struct device *dev, + struct samsung_pinctrl_drv_data *drvdata, + unsigned int *cnt) +{ + struct samsung_pmx_func *functions, *func; + struct device_node *dev_np = dev->of_node; + struct device_node *cfg_np; + unsigned int func_cnt = 0; + int ret; + + /* + * Iterate over all the child nodes of the pin controller node + * and create pin groups and pin function lists. + */ + for_each_child_of_node(dev_np, cfg_np) { + struct device_node *func_np; + + if (!of_get_child_count(cfg_np)) { + if (!of_find_property(cfg_np, + "samsung,pin-function", NULL)) + continue; + ++func_cnt; + continue; + } + + for_each_child_of_node(cfg_np, func_np) { + if (!of_find_property(func_np, + "samsung,pin-function", NULL)) + continue; + ++func_cnt; + } + } + + functions = devm_kzalloc(dev, func_cnt * sizeof(*functions), + GFP_KERNEL); if (!functions) { dev_err(dev, "failed to allocate memory for function list\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } func = functions; @@ -647,61 +749,68 @@ static int samsung_pinctrl_parse_dt(struct platform_device *pdev, * Iterate over all the child nodes of the pin controller node * and create pin groups and pin function lists. */ + func_cnt = 0; for_each_child_of_node(dev_np, cfg_np) { - u32 function; - if (!of_find_property(cfg_np, "samsung,pins", NULL)) + struct device_node *func_np; + + if (!of_get_child_count(cfg_np)) { + ret = samsung_pinctrl_create_function(dev, drvdata, + cfg_np, func); + if (ret < 0) + return ERR_PTR(ret); + if (ret > 0) { + ++func; + ++func_cnt; + } continue; - - ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np, - &drvdata->pctl, &pin_list, &npins); - if (ret) - return ret; - - /* derive pin group name from the node name */ - gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN, - GFP_KERNEL); - if (!gname) { - dev_err(dev, "failed to alloc memory for group name\n"); - return -ENOMEM; } - sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX); - grp->name = gname; - grp->pins = pin_list; - grp->num_pins = npins; - of_property_read_u32(cfg_np, "samsung,pin-function", &function); - grp->func = function; - grp++; - - if (!of_find_property(cfg_np, "samsung,pin-function", NULL)) - continue; - - /* derive function name from the node name */ - fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN, - GFP_KERNEL); - if (!fname) { - dev_err(dev, "failed to alloc memory for func name\n"); - return -ENOMEM; + for_each_child_of_node(cfg_np, func_np) { + ret = samsung_pinctrl_create_function(dev, drvdata, + func_np, func); + if (ret < 0) + return ERR_PTR(ret); + if (ret > 0) { + ++func; + ++func_cnt; + } } - sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX); + } - func->name = fname; - func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL); - if (!func->groups) { - dev_err(dev, "failed to alloc memory for group list " - "in pin function"); - return -ENOMEM; - } - func->groups[0] = gname; - func->num_groups = 1; - func++; - func_idx++; + *cnt = func_cnt; + return functions; +} + +/* + * Parse the information about all the available pin groups and pin functions + * from device node of the pin-controller. A pin group is formed with all + * the pins listed in the "samsung,pins" property. + */ + +static int samsung_pinctrl_parse_dt(struct platform_device *pdev, + struct samsung_pinctrl_drv_data *drvdata) +{ + struct device *dev = &pdev->dev; + struct samsung_pin_group *groups; + struct samsung_pmx_func *functions; + unsigned int grp_cnt = 0, func_cnt = 0; + + groups = samsung_pinctrl_create_groups(dev, drvdata, &grp_cnt); + if (IS_ERR(groups)) { + dev_err(dev, "failed to parse pin groups\n"); + return PTR_ERR(groups); + } + + functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt); + if (IS_ERR(functions)) { + dev_err(dev, "failed to parse pin functions\n"); + return PTR_ERR(groups); } drvdata->pin_groups = groups; drvdata->nr_groups = grp_cnt; drvdata->pmx_functions = functions; - drvdata->nr_functions = func_idx; + drvdata->nr_functions = func_cnt; return 0; } diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h index e2dce4731a01..2b882320e8e9 100644 --- a/drivers/pinctrl/pinctrl-samsung.h +++ b/drivers/pinctrl/pinctrl-samsung.h @@ -231,6 +231,7 @@ struct samsung_pmx_func { const char *name; const char **groups; u8 num_groups; + u32 val; }; /* list of all exported SoC specific data */ From 2700bc013572e3c07e3a28e3715f277fd94b678a Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 2 Jul 2014 17:41:04 +0200 Subject: [PATCH 46/61] pinctrl: samsung: Allow pin value to be initialized using pinfunc This patch extends the range of settings configurable via pinfunc API to cover pin value as well. This allows configuration of default values of pins, which is useful for pins that are not supposed to be used by any dedicated driver, but need certain board-specific setting. Signed-off-by: Tomasz Figa Acked-by: Kyungmin Park Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 + drivers/pinctrl/pinctrl-samsung.c | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index 464b2bbc6284..e82aaf492517 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt @@ -75,6 +75,7 @@ Required Properties: "samsung,pins" property of the child node. The following pin configuration properties are supported. + - samsung,pin-val: Initial value of pin output buffer. - samsung,pin-pud: Pull up/down configuration. - samsung,pin-drv: Drive strength configuration. - samsung,pin-pud-pdn: Pull up/down configuration in power down mode. diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index b7de66c3b51d..52f849ac06c1 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -47,6 +47,7 @@ static struct pin_config { { "samsung,pin-drv", PINCFG_TYPE_DRV }, { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN }, { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN }, + { "samsung,pin-val", PINCFG_TYPE_DAT }, }; /* Global list of devices (struct samsung_pinctrl_drv_data) */ From 14d40ff8f8b25a1ae6a273b62e239c7064e5bc9f Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 8 Jul 2014 21:59:31 -0700 Subject: [PATCH 47/61] pinctrl: msm: Add msm8960 definitions Signed-off-by: Bjorn Andersson Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,msm8960-pinctrl.txt | 181 +++ drivers/pinctrl/Kconfig | 8 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-msm8960.c | 1254 +++++++++++++++++ 4 files changed, 1444 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt create mode 100644 drivers/pinctrl/pinctrl-msm8960.c diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt new file mode 100644 index 000000000000..7dece8de54b6 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt @@ -0,0 +1,181 @@ +Qualcomm MSM8960 TLMM block + +This binding describes the Top Level Mode Multiplexer block found in the +MSM8960 platform. + +- compatible: + Usage: required + Value type: + Definition: must be "qcom,msm8960-pinctrl" + +- reg: + Usage: required + Value type: + Definition: the base address and size of the TLMM register space. + +- interrupts: + Usage: required + Value type: + Definition: should specify the TLMM summary IRQ. + +- interrupt-controller: + Usage: required + Value type: + Definition: identifies this node as an interrupt controller + +- #interrupt-cells: + Usage: required + Value type: + Definition: must be 2. Specifying the pin number and flags, as defined + in + +- gpio-controller: + Usage: required + Value type: + Definition: identifies this node as a gpio controller + +- #gpio-cells: + Usage: required + Value type: + Definition: must be 2. Specifying the pin number and flags, as defined + in + +Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for +a general description of GPIO and interrupt bindings. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +The pin configuration nodes act as a container for an abitrary number of +subnodes. Each of these subnodes represents some desired configuration for a +pin, a group, or a list of pins or groups. This configuration can include the +mux function to select on those pin(s)/group(s), and various pin configuration +parameters, such as pull-up, drive strength, etc. + + +PIN CONFIGURATION NODES: + +The name of each subnode is not important; all subnodes should be enumerated +and processed purely based on their content. + +Each subnode only affects those parameters that are explicitly listed. In +other words, a subnode that lists a mux function but no pin configuration +parameters implies no information about any pin configuration parameters. +Similarly, a pin subnode that describes a pullup parameter implies no +information about e.g. the mux function. + + +The following generic properties as defined in pinctrl-bindings.txt are valid +to specify in a pin configuration subnode: + +- pins: + Usage: required + Value type: + Definition: List of gpio pins affected by the properties specified in + this subnode. Valid pins are: + gpio0-gpio151, + sdc1_clk, + sdc1_cmd, + sdc1_data + sdc3_clk, + sdc3_cmd, + sdc3_data + +- function: + Usage: optional + Value type: + Definition: Specify the alternative function to be configured for the + specified pins. Functions are only valid for gpio pins. + Valid values are: + audio_pcm, bt, cam_mclk0, cam_mclk1, cam_mclk2, + codec_mic_i2s, codec_spkr_i2s, ext_gps, fm, gps_blanking, + gps_pps_in, gps_pps_out, gp_clk_0a, gp_clk_0b, gp_clk_1a, + gp_clk_1b, gp_clk_2a, gp_clk_2b, gp_mn, gp_pdm_0a, + gp_pdm_0b, gp_pdm_1a, gp_pdm_1b, gp_pdm_2a, gp_pdm_2b, + gsbi1, gsbi1_spi_cs1_n, gsbi1_spi_cs2a_n, gsbi1_spi_cs2b_n, + gsbi1_spi_cs3_n, gsbi2, gsbi2_spi_cs1_n, gsbi2_spi_cs2_n, + gsbi2_spi_cs3_n, gsbi3, gsbi4, gsbi4_3d_cam_i2c_l, + gsbi4_3d_cam_i2c_r, gsbi5, gsbi5_3d_cam_i2c_l, + gsbi5_3d_cam_i2c_r, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10, + gsbi11, gsbi11_spi_cs1a_n, gsbi11_spi_cs1b_n, + gsbi11_spi_cs2a_n, gsbi11_spi_cs2b_n, gsbi11_spi_cs3_n, + gsbi12, hdmi_cec, hdmi_ddc_clock, hdmi_ddc_data, + hdmi_hot_plug_detect, hsic, mdp_vsync, mi2s, mic_i2s, + pmb_clk, pmb_ext_ctrl, ps_hold, rpm_wdog, sdc2, sdc4, sdc5, + slimbus1, slimbus2, spkr_i2s, ssbi1, ssbi2, ssbi_ext_gps, + ssbi_pmic2, ssbi_qpa1, ssbi_ts, tsif1, tsif2, ts_eoc, + usb_fs1, usb_fs1_oe, usb_fs1_oe_n, usb_fs2, usb_fs2_oe, + usb_fs2_oe_n, vfe_camif_timer1_a, vfe_camif_timer1_b, + vfe_camif_timer2, vfe_camif_timer3_a, vfe_camif_timer3_b, + vfe_camif_timer4_a, vfe_camif_timer4_b, vfe_camif_timer4_c, + vfe_camif_timer5_a, vfe_camif_timer5_b, vfe_camif_timer6_a, + vfe_camif_timer6_b, vfe_camif_timer6_c, vfe_camif_timer7_a, + vfe_camif_timer7_b, vfe_camif_timer7_c, wlan + +- bias-disable: + Usage: optional + Value type: + Definition: The specified pins should be configued as no pull. + +- bias-pull-down: + Usage: optional + Value type: + Definition: The specified pins should be configued as pull down. + +- bias-pull-up: + Usage: optional + Value type: + Definition: The specified pins should be configued as pull up. + +- output-high: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + high. + Not valid for sdc pins. + +- output-low: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + low. + Not valid for sdc pins. + +- drive-strength: + Usage: optional + Value type: + Definition: Selects the drive strength for the specified pins, in mA. + Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16 + +Example: + + msmgpio: pinctrl@800000 { + compatible = "qcom,msm8960-pinctrl"; + reg = <0x800000 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 16 0x4>; + + gsbi8_uart: gsbi8-uart { + mux { + pins = "gpio34", "gpio35"; + function = "gsbi8"; + }; + + tx { + pins = "gpio34"; + drive-strength = <4>; + bias-disable; + }; + + rx { + pins = "gpio35"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 2744fa2825e0..c0f49fb3276c 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -256,6 +256,14 @@ config PINCTRL_IPQ8064 This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm TLMM block found in the Qualcomm IPQ8064 platform. +config PINCTRL_MSM8960 + tristate "Qualcomm 8960 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm 8960 platform. + config PINCTRL_MSM8X74 tristate "Qualcomm 8x74 pin controller driver" depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST) diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index c7d8f1b7311f..80bced77446a 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o +obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o diff --git a/drivers/pinctrl/pinctrl-msm8960.c b/drivers/pinctrl/pinctrl-msm8960.c new file mode 100644 index 000000000000..564543bb2c1c --- /dev/null +++ b/drivers/pinctrl/pinctrl-msm8960.c @@ -0,0 +1,1254 @@ +/* + * Copyright (c) 2014, Sony Mobile Communications AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-msm.h" + +static const struct pinctrl_pin_desc msm8960_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "GPIO_113"), + PINCTRL_PIN(114, "GPIO_114"), + PINCTRL_PIN(115, "GPIO_115"), + PINCTRL_PIN(116, "GPIO_116"), + PINCTRL_PIN(117, "GPIO_117"), + PINCTRL_PIN(118, "GPIO_118"), + PINCTRL_PIN(119, "GPIO_119"), + PINCTRL_PIN(120, "GPIO_120"), + PINCTRL_PIN(121, "GPIO_121"), + PINCTRL_PIN(122, "GPIO_122"), + PINCTRL_PIN(123, "GPIO_123"), + PINCTRL_PIN(124, "GPIO_124"), + PINCTRL_PIN(125, "GPIO_125"), + PINCTRL_PIN(126, "GPIO_126"), + PINCTRL_PIN(127, "GPIO_127"), + PINCTRL_PIN(128, "GPIO_128"), + PINCTRL_PIN(129, "GPIO_129"), + PINCTRL_PIN(130, "GPIO_130"), + PINCTRL_PIN(131, "GPIO_131"), + PINCTRL_PIN(132, "GPIO_132"), + PINCTRL_PIN(133, "GPIO_133"), + PINCTRL_PIN(134, "GPIO_134"), + PINCTRL_PIN(135, "GPIO_135"), + PINCTRL_PIN(136, "GPIO_136"), + PINCTRL_PIN(137, "GPIO_137"), + PINCTRL_PIN(138, "GPIO_138"), + PINCTRL_PIN(139, "GPIO_139"), + PINCTRL_PIN(140, "GPIO_140"), + PINCTRL_PIN(141, "GPIO_141"), + PINCTRL_PIN(142, "GPIO_142"), + PINCTRL_PIN(143, "GPIO_143"), + PINCTRL_PIN(144, "GPIO_144"), + PINCTRL_PIN(145, "GPIO_145"), + PINCTRL_PIN(146, "GPIO_146"), + PINCTRL_PIN(147, "GPIO_147"), + PINCTRL_PIN(148, "GPIO_148"), + PINCTRL_PIN(149, "GPIO_149"), + PINCTRL_PIN(150, "GPIO_150"), + PINCTRL_PIN(151, "GPIO_151"), + + PINCTRL_PIN(152, "SDC1_CLK"), + PINCTRL_PIN(153, "SDC1_CMD"), + PINCTRL_PIN(154, "SDC1_DATA"), + PINCTRL_PIN(155, "SDC3_CLK"), + PINCTRL_PIN(156, "SDC3_CMD"), + PINCTRL_PIN(157, "SDC3_DATA"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); +DECLARE_MSM_GPIO_PINS(88); +DECLARE_MSM_GPIO_PINS(89); +DECLARE_MSM_GPIO_PINS(90); +DECLARE_MSM_GPIO_PINS(91); +DECLARE_MSM_GPIO_PINS(92); +DECLARE_MSM_GPIO_PINS(93); +DECLARE_MSM_GPIO_PINS(94); +DECLARE_MSM_GPIO_PINS(95); +DECLARE_MSM_GPIO_PINS(96); +DECLARE_MSM_GPIO_PINS(97); +DECLARE_MSM_GPIO_PINS(98); +DECLARE_MSM_GPIO_PINS(99); +DECLARE_MSM_GPIO_PINS(100); +DECLARE_MSM_GPIO_PINS(101); +DECLARE_MSM_GPIO_PINS(102); +DECLARE_MSM_GPIO_PINS(103); +DECLARE_MSM_GPIO_PINS(104); +DECLARE_MSM_GPIO_PINS(105); +DECLARE_MSM_GPIO_PINS(106); +DECLARE_MSM_GPIO_PINS(107); +DECLARE_MSM_GPIO_PINS(108); +DECLARE_MSM_GPIO_PINS(109); +DECLARE_MSM_GPIO_PINS(110); +DECLARE_MSM_GPIO_PINS(111); +DECLARE_MSM_GPIO_PINS(112); +DECLARE_MSM_GPIO_PINS(113); +DECLARE_MSM_GPIO_PINS(114); +DECLARE_MSM_GPIO_PINS(115); +DECLARE_MSM_GPIO_PINS(116); +DECLARE_MSM_GPIO_PINS(117); +DECLARE_MSM_GPIO_PINS(118); +DECLARE_MSM_GPIO_PINS(119); +DECLARE_MSM_GPIO_PINS(120); +DECLARE_MSM_GPIO_PINS(121); +DECLARE_MSM_GPIO_PINS(122); +DECLARE_MSM_GPIO_PINS(123); +DECLARE_MSM_GPIO_PINS(124); +DECLARE_MSM_GPIO_PINS(125); +DECLARE_MSM_GPIO_PINS(126); +DECLARE_MSM_GPIO_PINS(127); +DECLARE_MSM_GPIO_PINS(128); +DECLARE_MSM_GPIO_PINS(129); +DECLARE_MSM_GPIO_PINS(130); +DECLARE_MSM_GPIO_PINS(131); +DECLARE_MSM_GPIO_PINS(132); +DECLARE_MSM_GPIO_PINS(133); +DECLARE_MSM_GPIO_PINS(134); +DECLARE_MSM_GPIO_PINS(135); +DECLARE_MSM_GPIO_PINS(136); +DECLARE_MSM_GPIO_PINS(137); +DECLARE_MSM_GPIO_PINS(138); +DECLARE_MSM_GPIO_PINS(139); +DECLARE_MSM_GPIO_PINS(140); +DECLARE_MSM_GPIO_PINS(141); +DECLARE_MSM_GPIO_PINS(142); +DECLARE_MSM_GPIO_PINS(143); +DECLARE_MSM_GPIO_PINS(144); +DECLARE_MSM_GPIO_PINS(145); +DECLARE_MSM_GPIO_PINS(146); +DECLARE_MSM_GPIO_PINS(147); +DECLARE_MSM_GPIO_PINS(148); +DECLARE_MSM_GPIO_PINS(149); +DECLARE_MSM_GPIO_PINS(150); +DECLARE_MSM_GPIO_PINS(151); + +static const unsigned int sdc1_clk_pins[] = { 152 }; +static const unsigned int sdc1_cmd_pins[] = { 153 }; +static const unsigned int sdc1_data_pins[] = { 154 }; +static const unsigned int sdc3_clk_pins[] = { 155 }; +static const unsigned int sdc3_cmd_pins[] = { 156 }; +static const unsigned int sdc3_data_pins[] = { 157 }; + +#define FUNCTION(fname) \ + [MSM_MUX_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + MSM_MUX_NA, /* gpio mode */ \ + MSM_MUX_##f1, \ + MSM_MUX_##f2, \ + MSM_MUX_##f3, \ + MSM_MUX_##f4, \ + MSM_MUX_##f5, \ + MSM_MUX_##f6, \ + MSM_MUX_##f7, \ + MSM_MUX_##f8, \ + MSM_MUX_##f9, \ + MSM_MUX_##f10, \ + MSM_MUX_##f11 \ + }, \ + .nfuncs = 12, \ + .ctl_reg = 0x1000 + 0x10 * id, \ + .io_reg = 0x1004 + 0x10 * id, \ + .intr_cfg_reg = 0x1008 + 0x10 * id, \ + .intr_status_reg = 0x100c + 0x10 * id, \ + .intr_target_reg = 0x400 + 0x4 * id, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_ack_high = 1, \ + .intr_target_bit = 0, \ + .intr_raw_status_bit = 3, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 1, \ + } + +#define SDC_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +enum msm8960_functions { + MSM_MUX_audio_pcm, + MSM_MUX_bt, + MSM_MUX_cam_mclk0, + MSM_MUX_cam_mclk1, + MSM_MUX_cam_mclk2, + MSM_MUX_codec_mic_i2s, + MSM_MUX_codec_spkr_i2s, + MSM_MUX_ext_gps, + MSM_MUX_fm, + MSM_MUX_gps_blanking, + MSM_MUX_gps_pps_in, + MSM_MUX_gps_pps_out, + MSM_MUX_gp_clk_0a, + MSM_MUX_gp_clk_0b, + MSM_MUX_gp_clk_1a, + MSM_MUX_gp_clk_1b, + MSM_MUX_gp_clk_2a, + MSM_MUX_gp_clk_2b, + MSM_MUX_gp_mn, + MSM_MUX_gp_pdm_0a, + MSM_MUX_gp_pdm_0b, + MSM_MUX_gp_pdm_1a, + MSM_MUX_gp_pdm_1b, + MSM_MUX_gp_pdm_2a, + MSM_MUX_gp_pdm_2b, + MSM_MUX_gsbi1, + MSM_MUX_gsbi1_spi_cs1_n, + MSM_MUX_gsbi1_spi_cs2a_n, + MSM_MUX_gsbi1_spi_cs2b_n, + MSM_MUX_gsbi1_spi_cs3_n, + MSM_MUX_gsbi2, + MSM_MUX_gsbi2_spi_cs1_n, + MSM_MUX_gsbi2_spi_cs2_n, + MSM_MUX_gsbi2_spi_cs3_n, + MSM_MUX_gsbi3, + MSM_MUX_gsbi4, + MSM_MUX_gsbi4_3d_cam_i2c_l, + MSM_MUX_gsbi4_3d_cam_i2c_r, + MSM_MUX_gsbi5, + MSM_MUX_gsbi5_3d_cam_i2c_l, + MSM_MUX_gsbi5_3d_cam_i2c_r, + MSM_MUX_gsbi6, + MSM_MUX_gsbi7, + MSM_MUX_gsbi8, + MSM_MUX_gsbi9, + MSM_MUX_gsbi10, + MSM_MUX_gsbi11, + MSM_MUX_gsbi11_spi_cs1a_n, + MSM_MUX_gsbi11_spi_cs1b_n, + MSM_MUX_gsbi11_spi_cs2a_n, + MSM_MUX_gsbi11_spi_cs2b_n, + MSM_MUX_gsbi11_spi_cs3_n, + MSM_MUX_gsbi12, + MSM_MUX_hdmi_cec, + MSM_MUX_hdmi_ddc_clock, + MSM_MUX_hdmi_ddc_data, + MSM_MUX_hdmi_hot_plug_detect, + MSM_MUX_hsic, + MSM_MUX_mdp_vsync, + MSM_MUX_mi2s, + MSM_MUX_mic_i2s, + MSM_MUX_pmb_clk, + MSM_MUX_pmb_ext_ctrl, + MSM_MUX_ps_hold, + MSM_MUX_rpm_wdog, + MSM_MUX_sdc2, + MSM_MUX_sdc4, + MSM_MUX_sdc5, + MSM_MUX_slimbus1, + MSM_MUX_slimbus2, + MSM_MUX_spkr_i2s, + MSM_MUX_ssbi1, + MSM_MUX_ssbi2, + MSM_MUX_ssbi_ext_gps, + MSM_MUX_ssbi_pmic2, + MSM_MUX_ssbi_qpa1, + MSM_MUX_ssbi_ts, + MSM_MUX_tsif1, + MSM_MUX_tsif2, + MSM_MUX_ts_eoc, + MSM_MUX_usb_fs1, + MSM_MUX_usb_fs1_oe, + MSM_MUX_usb_fs1_oe_n, + MSM_MUX_usb_fs2, + MSM_MUX_usb_fs2_oe, + MSM_MUX_usb_fs2_oe_n, + MSM_MUX_vfe_camif_timer1_a, + MSM_MUX_vfe_camif_timer1_b, + MSM_MUX_vfe_camif_timer2, + MSM_MUX_vfe_camif_timer3_a, + MSM_MUX_vfe_camif_timer3_b, + MSM_MUX_vfe_camif_timer4_a, + MSM_MUX_vfe_camif_timer4_b, + MSM_MUX_vfe_camif_timer4_c, + MSM_MUX_vfe_camif_timer5_a, + MSM_MUX_vfe_camif_timer5_b, + MSM_MUX_vfe_camif_timer6_a, + MSM_MUX_vfe_camif_timer6_b, + MSM_MUX_vfe_camif_timer6_c, + MSM_MUX_vfe_camif_timer7_a, + MSM_MUX_vfe_camif_timer7_b, + MSM_MUX_vfe_camif_timer7_c, + MSM_MUX_wlan, + MSM_MUX_NA, +}; + +static const char * const audio_pcm_groups[] = { + "gpio63", "gpio64", "gpio65", "gpio66" +}; + +static const char * const bt_groups[] = { + "gpio28", "gpio29", "gpio83" +}; + +static const char * const cam_mclk0_groups[] = { + "gpio5" +}; + +static const char * const cam_mclk1_groups[] = { + "gpio4" +}; + +static const char * const cam_mclk2_groups[] = { + "gpio2" +}; + +static const char * const codec_mic_i2s_groups[] = { + "gpio54", "gpio55", "gpio56", "gpio57", "gpio58" +}; + +static const char * const codec_spkr_i2s_groups[] = { + "gpio59", "gpio60", "gpio61", "gpio62" +}; + +static const char * const ext_gps_groups[] = { + "gpio22", "gpio23", "gpio24", "gpio25" +}; + +static const char * const fm_groups[] = { + "gpio26", "gpio27" +}; + +static const char * const gps_blanking_groups[] = { + "gpio137" +}; + +static const char * const gps_pps_in_groups[] = { + "gpio37" +}; + +static const char * const gps_pps_out_groups[] = { + "gpio37" +}; + +static const char * const gp_clk_0a_groups[] = { + "gpio3" +}; + +static const char * const gp_clk_0b_groups[] = { + "gpio54" +}; + +static const char * const gp_clk_1a_groups[] = { + "gpio4" +}; + +static const char * const gp_clk_1b_groups[] = { + "gpio70" +}; + +static const char * const gp_clk_2a_groups[] = { + "gpio52" +}; + +static const char * const gp_clk_2b_groups[] = { + "gpio37" +}; + +static const char * const gp_mn_groups[] = { + "gpio2" +}; + +static const char * const gp_pdm_0a_groups[] = { + "gpio58" +}; + +static const char * const gp_pdm_0b_groups[] = { + "gpio39" +}; + +static const char * const gp_pdm_1a_groups[] = { + "gpio94" +}; + +static const char * const gp_pdm_1b_groups[] = { + "gpio64" +}; + +static const char * const gp_pdm_2a_groups[] = { + "gpio69" +}; + +static const char * const gp_pdm_2b_groups[] = { + "gpio53" +}; + +static const char * const gsbi1_groups[] = { + "gpio6", "gpio7", "gpio8", "gpio9" +}; + +static const char * const gsbi1_spi_cs1_n_groups[] = { + "gpio14" +}; + +static const char * const gsbi1_spi_cs2a_n_groups[] = { + "gpio15" +}; + +static const char * const gsbi1_spi_cs2b_n_groups[] = { + "gpio17" +}; + +static const char * const gsbi1_spi_cs3_n_groups[] = { + "gpio16" +}; + +static const char * const gsbi2_groups[] = { + "gpio10", "gpio11", "gpio12", "gpio13" +}; + +static const char * const gsbi2_spi_cs1_n_groups[] = { + "gpio52" +}; + +static const char * const gsbi2_spi_cs2_n_groups[] = { + "gpio68" +}; + +static const char * const gsbi2_spi_cs3_n_groups[] = { + "gpio56" +}; + +static const char * const gsbi3_groups[] = { + "gpio14", "gpio15", "gpio16", "gpio17" +}; + +static const char * const gsbi4_groups[] = { + "gpio18", "gpio19", "gpio20", "gpio21" +}; + +static const char * const gsbi4_3d_cam_i2c_l_groups[] = { + "gpio18", "gpio19" +}; + +static const char * const gsbi4_3d_cam_i2c_r_groups[] = { + "gpio20", "gpio21" +}; + +static const char * const gsbi5_groups[] = { + "gpio22", "gpio23", "gpio24", "gpio25" +}; + +static const char * const gsbi5_3d_cam_i2c_l_groups[] = { + "gpio22", "gpio23" +}; + +static const char * const gsbi5_3d_cam_i2c_r_groups[] = { + "gpio24", "gpio25" +}; + +static const char * const gsbi6_groups[] = { + "gpio26", "gpio27", "gpio28", "gpio29" +}; + +static const char * const gsbi7_groups[] = { + "gpio30", "gpio31", "gpio32", "gpio33" +}; + +static const char * const gsbi8_groups[] = { + "gpio34", "gpio35", "gpio36", "gpio37" +}; + +static const char * const gsbi9_groups[] = { + "gpio93", "gpio94", "gpio95", "gpio96" +}; + +static const char * const gsbi10_groups[] = { + "gpio71", "gpio72", "gpio73", "gpio74" +}; + +static const char * const gsbi11_groups[] = { + "gpio38", "gpio39", "gpio40", "gpio41" +}; + +static const char * const gsbi11_spi_cs1a_n_groups[] = { + "gpio36" +}; + +static const char * const gsbi11_spi_cs1b_n_groups[] = { + "gpio18" +}; + +static const char * const gsbi11_spi_cs2a_n_groups[] = { + "gpio37" +}; + +static const char * const gsbi11_spi_cs2b_n_groups[] = { + "gpio19" +}; + +static const char * const gsbi11_spi_cs3_n_groups[] = { + "gpio76" +}; + +static const char * const gsbi12_groups[] = { + "gpio42", "gpio43", "gpio44", "gpio45" +}; + +static const char * const hdmi_cec_groups[] = { + "gpio99" +}; + +static const char * const hdmi_ddc_clock_groups[] = { + "gpio100" +}; + +static const char * const hdmi_ddc_data_groups[] = { + "gpio101" +}; + +static const char * const hdmi_hot_plug_detect_groups[] = { + "gpio102" +}; + +static const char * const hsic_groups[] = { + "gpio150", "gpio151" +}; + +static const char * const mdp_vsync_groups[] = { + "gpio0", "gpio1", "gpio19" +}; + +static const char * const mi2s_groups[] = { + "gpio47", "gpio48", "gpio49", "gpio50", "gpio51", "gpio52", "gpio53" +}; + +static const char * const mic_i2s_groups[] = { + "gpio71", "gpio72", "gpio73", "gpio74" +}; + +static const char * const pmb_clk_groups[] = { + "gpio21", "gpio86", "gpio112" +}; + +static const char * const pmb_ext_ctrl_groups[] = { + "gpio4", "gpio5" +}; + +static const char * const ps_hold_groups[] = { + "gpio108" +}; + +static const char * const rpm_wdog_groups[] = { + "gpio12" +}; + +static const char * const sdc2_groups[] = { + "gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", + "gpio96", "gpio97", "gpio98" +}; + +static const char * const sdc4_groups[] = { + "gpio83", "gpio84", "gpio85", "gpio86", "gpio87", "gpio88" +}; + +static const char * const sdc5_groups[] = { + "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82" +}; + +static const char * const slimbus1_groups[] = { + "gpio50", "gpio51", "gpio60", "gpio61" +}; + +static const char * const slimbus2_groups[] = { + "gpio42", "gpio43" +}; + +static const char * const spkr_i2s_groups[] = { + "gpio67", "gpio68", "gpio69", "gpio70" +}; + +static const char * const ssbi1_groups[] = { + "gpio141", "gpio143" +}; + +static const char * const ssbi2_groups[] = { + "gpio140", "gpio142" +}; + +static const char * const ssbi_ext_gps_groups[] = { + "gpio23" +}; + +static const char * const ssbi_pmic2_groups[] = { + "gpio149" +}; + +static const char * const ssbi_qpa1_groups[] = { + "gpio131" +}; + +static const char * const ssbi_ts_groups[] = { + "gpio10" +}; + +static const char * const tsif1_groups[] = { + "gpio75", "gpio76", "gpio77", "gpio82" +}; + +static const char * const tsif2_groups[] = { + "gpio78", "gpio79", "gpio80", "gpio81" +}; + +static const char * const ts_eoc_groups[] = { + "gpio11" +}; + +static const char * const usb_fs1_groups[] = { + "gpio32", "gpio33" +}; + +static const char * const usb_fs1_oe_groups[] = { + "gpio31" +}; + +static const char * const usb_fs1_oe_n_groups[] = { + "gpio31" +}; + +static const char * const usb_fs2_groups[] = { + "gpio34", "gpio35" +}; + +static const char * const usb_fs2_oe_groups[] = { + "gpio36" +}; + +static const char * const usb_fs2_oe_n_groups[] = { + "gpio36" +}; + +static const char * const vfe_camif_timer1_a_groups[] = { + "gpio2" +}; + +static const char * const vfe_camif_timer1_b_groups[] = { + "gpio38" +}; + +static const char * const vfe_camif_timer2_groups[] = { + "gpio3" +}; + +static const char * const vfe_camif_timer3_a_groups[] = { + "gpio4" +}; + +static const char * const vfe_camif_timer3_b_groups[] = { + "gpio151" +}; + +static const char * const vfe_camif_timer4_a_groups[] = { + "gpio65" +}; + +static const char * const vfe_camif_timer4_b_groups[] = { + "gpio150" +}; + +static const char * const vfe_camif_timer4_c_groups[] = { + "gpio10" +}; + +static const char * const vfe_camif_timer5_a_groups[] = { + "gpio66" +}; + +static const char * const vfe_camif_timer5_b_groups[] = { + "gpio39" +}; + +static const char * const vfe_camif_timer6_a_groups[] = { + "gpio71" +}; + +static const char * const vfe_camif_timer6_b_groups[] = { + "gpio0" +}; + +static const char * const vfe_camif_timer6_c_groups[] = { + "gpio18" +}; + +static const char * const vfe_camif_timer7_a_groups[] = { + "gpio67" +}; + +static const char * const vfe_camif_timer7_b_groups[] = { + "gpio1" +}; + +static const char * const vfe_camif_timer7_c_groups[] = { + "gpio19" +}; + +static const char * const wlan_groups[] = { + "gpio84", "gpio85", "gpio86", "gpio87", "gpio88" +}; + +static const struct msm_function msm8960_functions[] = { + FUNCTION(audio_pcm), + FUNCTION(bt), + FUNCTION(cam_mclk0), + FUNCTION(cam_mclk1), + FUNCTION(cam_mclk2), + FUNCTION(codec_mic_i2s), + FUNCTION(codec_spkr_i2s), + FUNCTION(ext_gps), + FUNCTION(fm), + FUNCTION(gps_blanking), + FUNCTION(gps_pps_in), + FUNCTION(gps_pps_out), + FUNCTION(gp_clk_0a), + FUNCTION(gp_clk_0b), + FUNCTION(gp_clk_1a), + FUNCTION(gp_clk_1b), + FUNCTION(gp_clk_2a), + FUNCTION(gp_clk_2b), + FUNCTION(gp_mn), + FUNCTION(gp_pdm_0a), + FUNCTION(gp_pdm_0b), + FUNCTION(gp_pdm_1a), + FUNCTION(gp_pdm_1b), + FUNCTION(gp_pdm_2a), + FUNCTION(gp_pdm_2b), + FUNCTION(gsbi1), + FUNCTION(gsbi1_spi_cs1_n), + FUNCTION(gsbi1_spi_cs2a_n), + FUNCTION(gsbi1_spi_cs2b_n), + FUNCTION(gsbi1_spi_cs3_n), + FUNCTION(gsbi2), + FUNCTION(gsbi2_spi_cs1_n), + FUNCTION(gsbi2_spi_cs2_n), + FUNCTION(gsbi2_spi_cs3_n), + FUNCTION(gsbi3), + FUNCTION(gsbi4), + FUNCTION(gsbi4_3d_cam_i2c_l), + FUNCTION(gsbi4_3d_cam_i2c_r), + FUNCTION(gsbi5), + FUNCTION(gsbi5_3d_cam_i2c_l), + FUNCTION(gsbi5_3d_cam_i2c_r), + FUNCTION(gsbi6), + FUNCTION(gsbi7), + FUNCTION(gsbi8), + FUNCTION(gsbi9), + FUNCTION(gsbi10), + FUNCTION(gsbi11), + FUNCTION(gsbi11_spi_cs1a_n), + FUNCTION(gsbi11_spi_cs1b_n), + FUNCTION(gsbi11_spi_cs2a_n), + FUNCTION(gsbi11_spi_cs2b_n), + FUNCTION(gsbi11_spi_cs3_n), + FUNCTION(gsbi12), + FUNCTION(hdmi_cec), + FUNCTION(hdmi_ddc_clock), + FUNCTION(hdmi_ddc_data), + FUNCTION(hdmi_hot_plug_detect), + FUNCTION(hsic), + FUNCTION(mdp_vsync), + FUNCTION(mi2s), + FUNCTION(mic_i2s), + FUNCTION(pmb_clk), + FUNCTION(pmb_ext_ctrl), + FUNCTION(ps_hold), + FUNCTION(rpm_wdog), + FUNCTION(sdc2), + FUNCTION(sdc4), + FUNCTION(sdc5), + FUNCTION(slimbus1), + FUNCTION(slimbus2), + FUNCTION(spkr_i2s), + FUNCTION(ssbi1), + FUNCTION(ssbi2), + FUNCTION(ssbi_ext_gps), + FUNCTION(ssbi_pmic2), + FUNCTION(ssbi_qpa1), + FUNCTION(ssbi_ts), + FUNCTION(tsif1), + FUNCTION(tsif2), + FUNCTION(ts_eoc), + FUNCTION(usb_fs1), + FUNCTION(usb_fs1_oe), + FUNCTION(usb_fs1_oe_n), + FUNCTION(usb_fs2), + FUNCTION(usb_fs2_oe), + FUNCTION(usb_fs2_oe_n), + FUNCTION(vfe_camif_timer1_a), + FUNCTION(vfe_camif_timer1_b), + FUNCTION(vfe_camif_timer2), + FUNCTION(vfe_camif_timer3_a), + FUNCTION(vfe_camif_timer3_b), + FUNCTION(vfe_camif_timer4_a), + FUNCTION(vfe_camif_timer4_b), + FUNCTION(vfe_camif_timer4_c), + FUNCTION(vfe_camif_timer5_a), + FUNCTION(vfe_camif_timer5_b), + FUNCTION(vfe_camif_timer6_a), + FUNCTION(vfe_camif_timer6_b), + FUNCTION(vfe_camif_timer6_c), + FUNCTION(vfe_camif_timer7_a), + FUNCTION(vfe_camif_timer7_b), + FUNCTION(vfe_camif_timer7_c), + FUNCTION(wlan), +}; + +static const struct msm_pingroup msm8960_groups[] = { + PINGROUP(0, mdp_vsync, vfe_camif_timer6_b, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(1, mdp_vsync, vfe_camif_timer7_b, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(2, vfe_camif_timer1_a, gp_mn, NA, cam_mclk2, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(3, vfe_camif_timer2, gp_clk_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(4, vfe_camif_timer3_a, cam_mclk1, gp_clk_1a, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(5, cam_mclk0, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(6, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(7, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(8, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(9, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(10, gsbi2, ssbi_ts, NA, vfe_camif_timer4_c, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(11, gsbi2, ts_eoc, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(12, gsbi2, rpm_wdog, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(13, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(14, gsbi3, gsbi1_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(15, gsbi3, gsbi1_spi_cs2a_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(16, gsbi3, gsbi1_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(17, gsbi3, gsbi1_spi_cs2b_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(18, gsbi4, gsbi11_spi_cs1b_n, NA, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer6_c, NA, NA, NA, NA, NA), + PINGROUP(19, gsbi4, gsbi11_spi_cs2b_n, NA, mdp_vsync, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer7_c, NA, NA, NA, NA), + PINGROUP(20, gsbi4, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(21, gsbi4, pmb_clk, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(22, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA), + PINGROUP(23, gsbi5, ssbi_ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA), + PINGROUP(24, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA), + PINGROUP(25, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA), + PINGROUP(26, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(27, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(28, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(29, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(30, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(31, gsbi7, usb_fs1_oe, usb_fs1_oe_n, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(32, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(33, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(34, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(35, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(36, gsbi8, usb_fs2_oe, usb_fs2_oe_n, gsbi11_spi_cs1a_n, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(37, gsbi8, gps_pps_out, gps_pps_in, gsbi11_spi_cs2a_n, gp_clk_2b, NA, NA, NA, NA, NA, NA), + PINGROUP(38, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer1_b, NA), + PINGROUP(39, gsbi11, gp_pdm_0b, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer5_b), + PINGROUP(40, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(41, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(42, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(43, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(44, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(45, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(47, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(48, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(49, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(50, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(51, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(52, mi2s, gp_clk_2a, gsbi2_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(53, mi2s, gp_pdm_2b, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(54, codec_mic_i2s, gp_clk_0b, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(55, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(56, codec_mic_i2s, gsbi2_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(57, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(58, codec_mic_i2s, gp_pdm_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(59, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(60, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(61, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(62, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(63, audio_pcm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(64, audio_pcm, gp_pdm_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(65, audio_pcm, vfe_camif_timer4_a, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(66, audio_pcm, vfe_camif_timer5_a, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(67, spkr_i2s, vfe_camif_timer7_a, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(68, spkr_i2s, gsbi2_spi_cs2_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(69, spkr_i2s, gp_pdm_2a, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(70, spkr_i2s, gp_clk_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(71, mic_i2s, gsbi10, vfe_camif_timer6_a, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(72, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(73, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(74, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(75, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(76, tsif1, gsbi11_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(77, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(78, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(79, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(80, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(81, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(82, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(83, bt, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(84, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(85, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(86, wlan, sdc4, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(87, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(88, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(89, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(90, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(91, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(92, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(93, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(94, sdc2, gsbi9, gp_pdm_1a, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(95, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(96, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(97, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(98, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(99, hdmi_cec, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(100, hdmi_ddc_clock, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(101, hdmi_ddc_data, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(102, hdmi_hot_plug_detect, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(103, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(104, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(105, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(106, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(107, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(108, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(109, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(110, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(112, NA, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(113, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(115, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(117, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(118, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(119, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(120, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(121, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(122, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(123, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(124, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(125, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(126, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(127, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(128, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(129, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(130, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(131, NA, ssbi_qpa1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(132, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(133, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(134, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(135, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(136, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(137, gps_blanking, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(138, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(139, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(140, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(141, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(142, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(143, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(144, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(145, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(146, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(147, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(148, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(149, ssbi_pmic2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(150, hsic, NA, vfe_camif_timer4_b, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(151, hsic, NA, vfe_camif_timer3_b, NA, NA, NA, NA, NA, NA, NA, NA), + + SDC_PINGROUP(sdc1_clk, 0x20a0, 13, 6), + SDC_PINGROUP(sdc1_cmd, 0x20a0, 11, 3), + SDC_PINGROUP(sdc1_data, 0x20a0, 9, 0), + + SDC_PINGROUP(sdc3_clk, 0x20a4, 14, 6), + SDC_PINGROUP(sdc3_cmd, 0x20a4, 11, 3), + SDC_PINGROUP(sdc3_data, 0x20a4, 9, 0), +}; + +#define NUM_GPIO_PINGROUPS 152 + +static const struct msm_pinctrl_soc_data msm8960_pinctrl = { + .pins = msm8960_pins, + .npins = ARRAY_SIZE(msm8960_pins), + .functions = msm8960_functions, + .nfunctions = ARRAY_SIZE(msm8960_functions), + .groups = msm8960_groups, + .ngroups = ARRAY_SIZE(msm8960_groups), + .ngpios = NUM_GPIO_PINGROUPS, +}; + +static int msm8960_pinctrl_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &msm8960_pinctrl); +} + +static const struct of_device_id msm8960_pinctrl_of_match[] = { + { .compatible = "qcom,msm8960-pinctrl", }, + { }, +}; + +static struct platform_driver msm8960_pinctrl_driver = { + .driver = { + .name = "msm8960-pinctrl", + .owner = THIS_MODULE, + .of_match_table = msm8960_pinctrl_of_match, + }, + .probe = msm8960_pinctrl_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init msm8960_pinctrl_init(void) +{ + return platform_driver_register(&msm8960_pinctrl_driver); +} +arch_initcall(msm8960_pinctrl_init); + +static void __exit msm8960_pinctrl_exit(void) +{ + platform_driver_unregister(&msm8960_pinctrl_driver); +} +module_exit(msm8960_pinctrl_exit); + +MODULE_AUTHOR("Bjorn Andersson "); +MODULE_DESCRIPTION("Qualcomm MSM8960 pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, msm8960_pinctrl_of_match); From 69b78b8de65b28f65f2e31029462521855c7c351 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Jul 2014 13:55:12 +0200 Subject: [PATCH 48/61] pinctrl: msm: move all qualcomm drivers to subdir We have four Qualcomm-related pin control drivers, and now there are drivers coming in for the PMICs on these systems, so let's create a qcom subdirectory to hold all the Qualcomm stuff. Acked-by: Ivan T. Ivanov Acked-by: Bjorn Andersson Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 40 +------------------ drivers/pinctrl/Makefile | 6 +-- drivers/pinctrl/qcom/Kconfig | 42 ++++++++++++++++++++ drivers/pinctrl/qcom/Makefile | 6 +++ drivers/pinctrl/{ => qcom}/pinctrl-apq8064.c | 0 drivers/pinctrl/{ => qcom}/pinctrl-ipq8064.c | 0 drivers/pinctrl/{ => qcom}/pinctrl-msm.c | 6 +-- drivers/pinctrl/{ => qcom}/pinctrl-msm.h | 0 drivers/pinctrl/{ => qcom}/pinctrl-msm8960.c | 0 drivers/pinctrl/{ => qcom}/pinctrl-msm8x74.c | 0 10 files changed, 53 insertions(+), 47 deletions(-) create mode 100644 drivers/pinctrl/qcom/Kconfig create mode 100644 drivers/pinctrl/qcom/Makefile rename drivers/pinctrl/{ => qcom}/pinctrl-apq8064.c (100%) rename drivers/pinctrl/{ => qcom}/pinctrl-ipq8064.c (100%) rename drivers/pinctrl/{ => qcom}/pinctrl-msm.c (99%) rename drivers/pinctrl/{ => qcom}/pinctrl-msm.h (100%) rename drivers/pinctrl/{ => qcom}/pinctrl-msm8960.c (100%) rename drivers/pinctrl/{ => qcom}/pinctrl-msm8x74.c (100%) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c0f49fb3276c..e2c7e09783fa 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -233,45 +233,6 @@ config PINCTRL_IMX28 bool select PINCTRL_MXS -config PINCTRL_MSM - bool - select PINMUX - select PINCONF - select GENERIC_PINCONF - select GPIOLIB_IRQCHIP - -config PINCTRL_APQ8064 - tristate "Qualcomm APQ8064 pin controller driver" - depends on GPIOLIB && OF - select PINCTRL_MSM - help - This is the pinctrl, pinmux, pinconf and gpiolib driver for the - Qualcomm TLMM block found in the Qualcomm APQ8064 platform. - -config PINCTRL_IPQ8064 - tristate "Qualcomm IPQ8064 pin controller driver" - depends on GPIOLIB && OF - select PINCTRL_MSM - help - This is the pinctrl, pinmux, pinconf and gpiolib driver for the - Qualcomm TLMM block found in the Qualcomm IPQ8064 platform. - -config PINCTRL_MSM8960 - tristate "Qualcomm 8960 pin controller driver" - depends on GPIOLIB && OF - select PINCTRL_MSM - help - This is the pinctrl, pinmux, pinconf and gpiolib driver for the - Qualcomm TLMM block found in the Qualcomm 8960 platform. - -config PINCTRL_MSM8X74 - tristate "Qualcomm 8x74 pin controller driver" - depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST) - select PINCTRL_MSM - help - This is the pinctrl, pinmux, pinconf and gpiolib driver for the - Qualcomm TLMM block found in the Qualcomm 8974 platform. - config PINCTRL_NOMADIK bool "Nomadik pin controller driver" depends on ARCH_U8500 || ARCH_NOMADIK @@ -410,6 +371,7 @@ config PINCTRL_S3C64XX source "drivers/pinctrl/berlin/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" +source "drivers/pinctrl/qcom/Kconfig" source "drivers/pinctrl/sh-pfc/Kconfig" source "drivers/pinctrl/spear/Kconfig" source "drivers/pinctrl/sunxi/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 80bced77446a..abe17724036c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -39,11 +39,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o -obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o -obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o -obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o -obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o -obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o @@ -74,6 +69,7 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-$(CONFIG_PLAT_ORION) += mvebu/ +obj-$(CONFIG_ARCH_QCOM) += qcom/ obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ obj-$(CONFIG_SUPERH) += sh-pfc/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig new file mode 100644 index 000000000000..d160a710d704 --- /dev/null +++ b/drivers/pinctrl/qcom/Kconfig @@ -0,0 +1,42 @@ +if (ARCH_QCOM || COMPILE_TEST) + +config PINCTRL_MSM + bool + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GPIOLIB_IRQCHIP + +config PINCTRL_APQ8064 + tristate "Qualcomm APQ8064 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm APQ8064 platform. + +config PINCTRL_IPQ8064 + tristate "Qualcomm IPQ8064 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm IPQ8064 platform. + +config PINCTRL_MSM8960 + tristate "Qualcomm 8960 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm 8960 platform. + +config PINCTRL_MSM8X74 + tristate "Qualcomm 8x74 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm 8974 platform. + +endif diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile new file mode 100644 index 000000000000..2a02602d715c --- /dev/null +++ b/drivers/pinctrl/qcom/Makefile @@ -0,0 +1,6 @@ +# Qualcomm pin control drivers +obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o +obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o +obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o +obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o +obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o diff --git a/drivers/pinctrl/pinctrl-apq8064.c b/drivers/pinctrl/qcom/pinctrl-apq8064.c similarity index 100% rename from drivers/pinctrl/pinctrl-apq8064.c rename to drivers/pinctrl/qcom/pinctrl-apq8064.c diff --git a/drivers/pinctrl/pinctrl-ipq8064.c b/drivers/pinctrl/qcom/pinctrl-ipq8064.c similarity index 100% rename from drivers/pinctrl/pinctrl-ipq8064.c rename to drivers/pinctrl/qcom/pinctrl-ipq8064.c diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c similarity index 99% rename from drivers/pinctrl/pinctrl-msm.c rename to drivers/pinctrl/qcom/pinctrl-msm.c index 43d47b7cff92..90d383d3ce17 100644 --- a/drivers/pinctrl/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -27,10 +27,10 @@ #include #include -#include "core.h" -#include "pinconf.h" +#include "../core.h" +#include "../pinconf.h" #include "pinctrl-msm.h" -#include "pinctrl-utils.h" +#include "../pinctrl-utils.h" #define MAX_NR_GPIO 300 diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h similarity index 100% rename from drivers/pinctrl/pinctrl-msm.h rename to drivers/pinctrl/qcom/pinctrl-msm.h diff --git a/drivers/pinctrl/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c similarity index 100% rename from drivers/pinctrl/pinctrl-msm8960.c rename to drivers/pinctrl/qcom/pinctrl-msm8960.c diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c similarity index 100% rename from drivers/pinctrl/pinctrl-msm8x74.c rename to drivers/pinctrl/qcom/pinctrl-msm8x74.c From 4281a16de2b1d8e715623afff0445bdce9d3ffe7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 9 Jul 2014 14:23:36 +0200 Subject: [PATCH 49/61] sh-pfc: Add renesas,pfc-r8a7791 to binding documentation The driver already supports the r8a7791 SoC, and "renesas,pfc-r8a7791" is already in use. Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index 35d2e1f186f0..daef6fad6a5f 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -15,6 +15,7 @@ Required Properties: - "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller. - "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller. - "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller. + - "renesas,pfc-r8a7791": for R8A7791 (R-Car M2) compatible pin-controller. - "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller. - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller. From aef1d0003d8c9f913fd66a0e06aeb292b29ab6dd Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Mon, 7 Jul 2014 21:39:16 +0530 Subject: [PATCH 50/61] sh-pfc: sh73a0: Introduce the use of devm_regulator_register This patch moves data allocated using regulator_register to devm_regulator_register and does away the calls to regulator_unregister. The sh73a0_pinmux_soc_exit function is no longer needed and is removed. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index ee370de4609a..0bd8f4401b42 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) cfg.init_data = &sh73a0_vccq_mc0_init_data; cfg.driver_data = pfc; - data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg); + data->vccq_mc0 = devm_regulator_register(pfc->dev, + &sh73a0_vccq_mc0_desc, &cfg); if (IS_ERR(data->vccq_mc0)) { ret = PTR_ERR(data->vccq_mc0); dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n", @@ -3855,16 +3856,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) return 0; } -static void sh73a0_pinmux_soc_exit(struct sh_pfc *pfc) -{ - struct sh73a0_pinmux_data *data = pfc->soc_data; - - regulator_unregister(data->vccq_mc0); -} - static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = { .init = sh73a0_pinmux_soc_init, - .exit = sh73a0_pinmux_soc_exit, .get_bias = sh73a0_pinmux_get_bias, .set_bias = sh73a0_pinmux_set_bias, }; From ebe629a39e04db3fe876d34833a2d8a6a6d4c134 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 10 Jul 2014 17:33:27 +0530 Subject: [PATCH 51/61] pinctrl: samsung: Group all drivers in a sub-dir Group all pin control drivers of Samsung platform together in a sub-directory for easy maintenance. Signed-off-by: Sachin Kamat Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 27 +----------------- drivers/pinctrl/Makefile | 8 ++---- drivers/pinctrl/samsung/Kconfig | 28 +++++++++++++++++++ drivers/pinctrl/samsung/Makefile | 7 +++++ .../pinctrl/{ => samsung}/pinctrl-exynos.c | 0 .../pinctrl/{ => samsung}/pinctrl-exynos.h | 0 .../{ => samsung}/pinctrl-exynos5440.c | 2 +- .../pinctrl/{ => samsung}/pinctrl-s3c24xx.c | 0 .../pinctrl/{ => samsung}/pinctrl-s3c64xx.c | 0 .../pinctrl/{ => samsung}/pinctrl-samsung.c | 2 +- .../pinctrl/{ => samsung}/pinctrl-samsung.h | 0 11 files changed, 40 insertions(+), 34 deletions(-) create mode 100644 drivers/pinctrl/samsung/Kconfig create mode 100644 drivers/pinctrl/samsung/Makefile rename drivers/pinctrl/{ => samsung}/pinctrl-exynos.c (100%) rename drivers/pinctrl/{ => samsung}/pinctrl-exynos.h (100%) rename drivers/pinctrl/{ => samsung}/pinctrl-exynos5440.c (99%) rename drivers/pinctrl/{ => samsung}/pinctrl-s3c24xx.c (100%) rename drivers/pinctrl/{ => samsung}/pinctrl-s3c64xx.c (100%) rename drivers/pinctrl/{ => samsung}/pinctrl-samsung.c (99%) rename drivers/pinctrl/{ => samsung}/pinctrl-samsung.h (100%) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e2c7e09783fa..53e07c70951f 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -332,22 +332,6 @@ config PINCTRL_COH901 COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 ports of 8 GPIO pins each. -config PINCTRL_SAMSUNG - bool - select PINMUX - select PINCONF - -config PINCTRL_EXYNOS - bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440" - depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210) - select PINCTRL_SAMSUNG - -config PINCTRL_EXYNOS5440 - bool "Samsung EXYNOS5440 SoC pinctrl driver" - depends on SOC_EXYNOS5440 - select PINMUX - select PINCONF - config PINCTRL_PALMAS bool "Pinctrl driver for the PALMAS Series MFD devices" depends on OF && MFD_PALMAS @@ -359,19 +343,10 @@ config PINCTRL_PALMAS open drain configuration for the Palmas series devices like TPS65913, TPS80036 etc. -config PINCTRL_S3C24XX - bool "Samsung S3C24XX SoC pinctrl driver" - depends on ARCH_S3C24XX - select PINCTRL_SAMSUNG - -config PINCTRL_S3C64XX - bool "Samsung S3C64XX SoC pinctrl driver" - depends on ARCH_S3C64XX - select PINCTRL_SAMSUNG - source "drivers/pinctrl/berlin/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/qcom/Kconfig" +source "drivers/pinctrl/samsung/Kconfig" source "drivers/pinctrl/sh-pfc/Kconfig" source "drivers/pinctrl/spear/Kconfig" source "drivers/pinctrl/sunxi/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index abe17724036c..df6099df7aad 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -56,11 +56,6 @@ obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o -obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o -obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o -obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o -obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o -obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o @@ -70,8 +65,9 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_ARCH_QCOM) += qcom/ +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ obj-$(CONFIG_SUPERH) += sh-pfc/ obj-$(CONFIG_PLAT_SPEAR) += spear/ -obj-$(CONFIG_ARCH_VT8500) += vt8500/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ +obj-$(CONFIG_ARCH_VT8500) += vt8500/ diff --git a/drivers/pinctrl/samsung/Kconfig b/drivers/pinctrl/samsung/Kconfig new file mode 100644 index 000000000000..d0461cd5d707 --- /dev/null +++ b/drivers/pinctrl/samsung/Kconfig @@ -0,0 +1,28 @@ +# +# Samsung Pin control drivers +# +config PINCTRL_SAMSUNG + bool + select PINMUX + select PINCONF + +config PINCTRL_EXYNOS + bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440" + depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210) + select PINCTRL_SAMSUNG + +config PINCTRL_EXYNOS5440 + bool "Samsung EXYNOS5440 SoC pinctrl driver" + depends on SOC_EXYNOS5440 + select PINMUX + select PINCONF + +config PINCTRL_S3C24XX + bool "Samsung S3C24XX SoC pinctrl driver" + depends on ARCH_S3C24XX + select PINCTRL_SAMSUNG + +config PINCTRL_S3C64XX + bool "Samsung S3C64XX SoC pinctrl driver" + depends on ARCH_S3C64XX + select PINCTRL_SAMSUNG diff --git a/drivers/pinctrl/samsung/Makefile b/drivers/pinctrl/samsung/Makefile new file mode 100644 index 000000000000..70160c059edd --- /dev/null +++ b/drivers/pinctrl/samsung/Makefile @@ -0,0 +1,7 @@ +# Samsung pin control drivers + +obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o +obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o +obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o +obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o +obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c similarity index 100% rename from drivers/pinctrl/pinctrl-exynos.c rename to drivers/pinctrl/samsung/pinctrl-exynos.c diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h similarity index 100% rename from drivers/pinctrl/pinctrl-exynos.h rename to drivers/pinctrl/samsung/pinctrl-exynos.h diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c similarity index 99% rename from drivers/pinctrl/pinctrl-exynos5440.c rename to drivers/pinctrl/samsung/pinctrl-exynos5440.c index 4b145b5db7a6..603da2f9dd95 100644 --- a/drivers/pinctrl/pinctrl-exynos5440.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c @@ -23,7 +23,7 @@ #include #include #include -#include "core.h" +#include "../core.h" /* EXYNOS5440 GPIO and Pinctrl register offsets */ #define GPIO_MUX 0x00 diff --git a/drivers/pinctrl/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c similarity index 100% rename from drivers/pinctrl/pinctrl-s3c24xx.c rename to drivers/pinctrl/samsung/pinctrl-s3c24xx.c diff --git a/drivers/pinctrl/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c similarity index 100% rename from drivers/pinctrl/pinctrl-s3c64xx.c rename to drivers/pinctrl/samsung/pinctrl-s3c64xx.c diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c similarity index 99% rename from drivers/pinctrl/pinctrl-samsung.c rename to drivers/pinctrl/samsung/pinctrl-samsung.c index 52f849ac06c1..b07406da333c 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -30,7 +30,7 @@ #include #include -#include "core.h" +#include "../core.h" #include "pinctrl-samsung.h" #define GROUP_SUFFIX "-grp" diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h similarity index 100% rename from drivers/pinctrl/pinctrl-samsung.h rename to drivers/pinctrl/samsung/pinctrl-samsung.h From 3a19805920f1b07401ea8a3ca00d7568dc2ce5e9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Jul 2014 14:57:06 +0200 Subject: [PATCH 52/61] pinctrl: nomadik: move all Nomadik drivers to subdir We have a bunch of Nomadik family pin control drivers, so let's move them into their own subdirectory. Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 45 +--------------- drivers/pinctrl/Makefile | 10 +--- drivers/pinctrl/nomadik/Kconfig | 51 +++++++++++++++++++ drivers/pinctrl/nomadik/Makefile | 10 ++++ .../pinctrl/{ => nomadik}/pinctrl-ab8500.c | 0 .../pinctrl/{ => nomadik}/pinctrl-ab8505.c | 0 .../pinctrl/{ => nomadik}/pinctrl-ab8540.c | 0 .../pinctrl/{ => nomadik}/pinctrl-ab9540.c | 0 .../pinctrl/{ => nomadik}/pinctrl-abx500.c | 4 +- .../pinctrl/{ => nomadik}/pinctrl-abx500.h | 0 .../{ => nomadik}/pinctrl-nomadik-db8500.c | 0 .../{ => nomadik}/pinctrl-nomadik-db8540.c | 0 .../{ => nomadik}/pinctrl-nomadik-stn8815.c | 0 .../pinctrl/{ => nomadik}/pinctrl-nomadik.c | 2 +- .../pinctrl/{ => nomadik}/pinctrl-nomadik.h | 0 15 files changed, 66 insertions(+), 56 deletions(-) create mode 100644 drivers/pinctrl/nomadik/Kconfig create mode 100644 drivers/pinctrl/nomadik/Makefile rename drivers/pinctrl/{ => nomadik}/pinctrl-ab8500.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-ab8505.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-ab8540.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-ab9540.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-abx500.c (99%) rename drivers/pinctrl/{ => nomadik}/pinctrl-abx500.h (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-nomadik-db8500.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-nomadik-db8540.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-nomadik-stn8815.c (100%) rename drivers/pinctrl/{ => nomadik}/pinctrl-nomadik.c (99%) rename drivers/pinctrl/{ => nomadik}/pinctrl-nomadik.h (100%) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 53e07c70951f..3d94e47546ec 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -26,29 +26,6 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. -config PINCTRL_ABX500 - bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions" - depends on AB8500_CORE - select GENERIC_PINCONF - help - Select this to enable the ABx500 family IC GPIO driver - -config PINCTRL_AB8500 - bool "AB8500 pin controller driver" - depends on PINCTRL_ABX500 && ARCH_U8500 - -config PINCTRL_AB8540 - bool "AB8540 pin controller driver" - depends on PINCTRL_ABX500 && ARCH_U8500 - -config PINCTRL_AB9540 - bool "AB9540 pin controller driver" - depends on PINCTRL_ABX500 && ARCH_U8500 - -config PINCTRL_AB8505 - bool "AB8505 pin controller driver" - depends on PINCTRL_ABX500 && ARCH_U8500 - config PINCTRL_ADI2 bool "ADI pin controller driver" depends on BLACKFIN @@ -233,27 +210,6 @@ config PINCTRL_IMX28 bool select PINCTRL_MXS -config PINCTRL_NOMADIK - bool "Nomadik pin controller driver" - depends on ARCH_U8500 || ARCH_NOMADIK - select PINMUX - select PINCONF - select GPIOLIB - select OF_GPIO - select GPIOLIB_IRQCHIP - -config PINCTRL_STN8815 - bool "STN8815 pin controller driver" - depends on PINCTRL_NOMADIK && ARCH_NOMADIK - -config PINCTRL_DB8500 - bool "DB8500 pin controller driver" - depends on PINCTRL_NOMADIK && ARCH_U8500 - -config PINCTRL_DB8540 - bool "DB8540 pin controller driver" - depends on PINCTRL_NOMADIK && ARCH_U8500 - config PINCTRL_ROCKCHIP bool select PINMUX @@ -345,6 +301,7 @@ config PINCTRL_PALMAS source "drivers/pinctrl/berlin/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" +source "drivers/pinctrl/nomadik/Kconfig" source "drivers/pinctrl/qcom/Kconfig" source "drivers/pinctrl/samsung/Kconfig" source "drivers/pinctrl/sh-pfc/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index df6099df7aad..e90817c1f584 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y) obj-$(CONFIG_PINCTRL) += devicetree.o endif obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o -obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o -obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o -obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o -obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o -obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o @@ -39,10 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o -obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o -obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o -obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o -obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o @@ -64,6 +55,7 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-$(CONFIG_PLAT_ORION) += mvebu/ +obj-y += nomadik/ obj-$(CONFIG_ARCH_QCOM) += qcom/ obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/ diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig new file mode 100644 index 000000000000..d48a5aa24a29 --- /dev/null +++ b/drivers/pinctrl/nomadik/Kconfig @@ -0,0 +1,51 @@ +if ARCH_U8500 + +config PINCTRL_ABX500 + bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions" + depends on AB8500_CORE + select GENERIC_PINCONF + help + Select this to enable the ABx500 family IC GPIO driver + +config PINCTRL_AB8500 + bool "AB8500 pin controller driver" + depends on PINCTRL_ABX500 && ARCH_U8500 + +config PINCTRL_AB8540 + bool "AB8540 pin controller driver" + depends on PINCTRL_ABX500 && ARCH_U8500 + +config PINCTRL_AB9540 + bool "AB9540 pin controller driver" + depends on PINCTRL_ABX500 && ARCH_U8500 + +config PINCTRL_AB8505 + bool "AB8505 pin controller driver" + depends on PINCTRL_ABX500 && ARCH_U8500 + +endif + +if (ARCH_U8500 || ARCH_NOMADIK) + +config PINCTRL_NOMADIK + bool "Nomadik pin controller driver" + depends on ARCH_U8500 || ARCH_NOMADIK + select PINMUX + select PINCONF + select GPIOLIB + select OF_GPIO + select GPIOLIB_IRQCHIP + +config PINCTRL_STN8815 + bool "STN8815 pin controller driver" + depends on PINCTRL_NOMADIK && ARCH_NOMADIK + +config PINCTRL_DB8500 + bool "DB8500 pin controller driver" + depends on PINCTRL_NOMADIK && ARCH_U8500 + +config PINCTRL_DB8540 + bool "DB8540 pin controller driver" + depends on PINCTRL_NOMADIK && ARCH_U8500 + +endif diff --git a/drivers/pinctrl/nomadik/Makefile b/drivers/pinctrl/nomadik/Makefile new file mode 100644 index 000000000000..30b27f18cd52 --- /dev/null +++ b/drivers/pinctrl/nomadik/Makefile @@ -0,0 +1,10 @@ +# Nomadik family pin control drivers +obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o +obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o +obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o +obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o +obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o +obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o +obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o +obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o +obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o diff --git a/drivers/pinctrl/pinctrl-ab8500.c b/drivers/pinctrl/nomadik/pinctrl-ab8500.c similarity index 100% rename from drivers/pinctrl/pinctrl-ab8500.c rename to drivers/pinctrl/nomadik/pinctrl-ab8500.c diff --git a/drivers/pinctrl/pinctrl-ab8505.c b/drivers/pinctrl/nomadik/pinctrl-ab8505.c similarity index 100% rename from drivers/pinctrl/pinctrl-ab8505.c rename to drivers/pinctrl/nomadik/pinctrl-ab8505.c diff --git a/drivers/pinctrl/pinctrl-ab8540.c b/drivers/pinctrl/nomadik/pinctrl-ab8540.c similarity index 100% rename from drivers/pinctrl/pinctrl-ab8540.c rename to drivers/pinctrl/nomadik/pinctrl-ab8540.c diff --git a/drivers/pinctrl/pinctrl-ab9540.c b/drivers/pinctrl/nomadik/pinctrl-ab9540.c similarity index 100% rename from drivers/pinctrl/pinctrl-ab9540.c rename to drivers/pinctrl/nomadik/pinctrl-ab9540.c diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c similarity index 99% rename from drivers/pinctrl/pinctrl-abx500.c rename to drivers/pinctrl/nomadik/pinctrl-abx500.c index f3f8b24efe54..a53a689a2bfa 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -32,8 +32,8 @@ #include #include "pinctrl-abx500.h" -#include "core.h" -#include "pinconf.h" +#include "../core.h" +#include "../pinconf.h" /* * The AB9540 and AB8540 GPIO support are extended versions diff --git a/drivers/pinctrl/pinctrl-abx500.h b/drivers/pinctrl/nomadik/pinctrl-abx500.h similarity index 100% rename from drivers/pinctrl/pinctrl-abx500.h rename to drivers/pinctrl/nomadik/pinctrl-abx500.h diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c similarity index 100% rename from drivers/pinctrl/pinctrl-nomadik-db8500.c rename to drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c similarity index 100% rename from drivers/pinctrl/pinctrl-nomadik-db8540.c rename to drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c diff --git a/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c similarity index 100% rename from drivers/pinctrl/pinctrl-nomadik-stn8815.c rename to drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c similarity index 99% rename from drivers/pinctrl/pinctrl-nomadik.c rename to drivers/pinctrl/nomadik/pinctrl-nomadik.c index a564251fe093..e7cab07eef47 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -31,7 +31,7 @@ /* Since we request GPIOs from ourself */ #include #include "pinctrl-nomadik.h" -#include "core.h" +#include "../core.h" /* * The GPIO module in the Nomadik family of Systems-on-Chip is an diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h similarity index 100% rename from drivers/pinctrl/pinctrl-nomadik.h rename to drivers/pinctrl/nomadik/pinctrl-nomadik.h From 144ef62645a7725a0a442129a8750baf257e88b9 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 11 Jul 2014 18:21:24 -0700 Subject: [PATCH 53/61] pinctrl: qcom: Make muxing of gpio function explicit Instead of relying on pinmux->disable(), make the gpio function an explicit function for all pins that supports it. Signed-off-by: Bjorn Andersson Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,apq8064-pinctrl.txt | 2 +- .../bindings/pinctrl/qcom,ipq8064-pinctrl.txt | 2 +- .../bindings/pinctrl/qcom,msm8960-pinctrl.txt | 4 +-- .../bindings/pinctrl/qcom,msm8974-pinctrl.txt | 2 +- drivers/pinctrl/qcom/pinctrl-apq8064.c | 19 +++++++++++- drivers/pinctrl/qcom/pinctrl-ipq8064.c | 17 ++++++++++- drivers/pinctrl/qcom/pinctrl-msm8960.c | 30 ++++++++++++++++++- drivers/pinctrl/qcom/pinctrl-msm8x74.c | 29 +++++++++++++++++- 8 files changed, 96 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt index 7181f925acaa..0211c6d8a522 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt @@ -46,7 +46,7 @@ Valid values for pins are: gpio0-gpio89 Valid values for function are: - cam_mclk, codec_mic_i2s, codec_spkr_i2s, gsbi1, gsbi2, gsbi3, gsbi4, + cam_mclk, codec_mic_i2s, codec_spkr_i2s, gpio, gsbi1, gsbi2, gsbi3, gsbi4, gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1, gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm, diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt index e0d35a40981b..e33e4dcdce79 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt @@ -51,7 +51,7 @@ Valid values for qcom,pins are: Valid values for function are: - mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gsbi1, gsbi2, gsbi4, gsbi5, + mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gpio, gsbi1, gsbi2, gsbi4, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1, spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata, pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt, diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt index 7dece8de54b6..93b7de91b9f6 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt @@ -83,7 +83,7 @@ to specify in a pin configuration subnode: sdc3_data - function: - Usage: optional + Usage: required Value type: Definition: Specify the alternative function to be configured for the specified pins. Functions are only valid for gpio pins. @@ -92,7 +92,7 @@ to specify in a pin configuration subnode: codec_mic_i2s, codec_spkr_i2s, ext_gps, fm, gps_blanking, gps_pps_in, gps_pps_out, gp_clk_0a, gp_clk_0b, gp_clk_1a, gp_clk_1b, gp_clk_2a, gp_clk_2b, gp_mn, gp_pdm_0a, - gp_pdm_0b, gp_pdm_1a, gp_pdm_1b, gp_pdm_2a, gp_pdm_2b, + gp_pdm_0b, gp_pdm_1a, gp_pdm_1b, gp_pdm_2a, gp_pdm_2b, gpio, gsbi1, gsbi1_spi_cs1_n, gsbi1_spi_cs2a_n, gsbi1_spi_cs2b_n, gsbi1_spi_cs3_n, gsbi2, gsbi2_spi_cs1_n, gsbi2_spi_cs2_n, gsbi2_spi_cs3_n, gsbi3, gsbi4, gsbi4_3d_cam_i2c_l, diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt index 73262b575dfc..d2ea80dc43eb 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt @@ -70,7 +70,7 @@ Valid values for function are: cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc, hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk, gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s, - ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus + ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio (Note that this is not yet the complete list of functions) diff --git a/drivers/pinctrl/qcom/pinctrl-apq8064.c b/drivers/pinctrl/qcom/pinctrl-apq8064.c index 519f7886b0f1..feb6f152f9b7 100644 --- a/drivers/pinctrl/qcom/pinctrl-apq8064.c +++ b/drivers/pinctrl/qcom/pinctrl-apq8064.c @@ -230,7 +230,7 @@ static const unsigned int sdc3_data_pins[] = { 95 }; .pins = gpio##id##_pins, \ .npins = ARRAY_SIZE(gpio##id##_pins), \ .funcs = (int[]){ \ - APQ_MUX_NA, /* gpio mode */ \ + APQ_MUX_gpio, \ APQ_MUX_##f1, \ APQ_MUX_##f2, \ APQ_MUX_##f3, \ @@ -293,6 +293,7 @@ enum apq8064_functions { APQ_MUX_cam_mclk, APQ_MUX_codec_mic_i2s, APQ_MUX_codec_spkr_i2s, + APQ_MUX_gpio, APQ_MUX_gsbi1, APQ_MUX_gsbi2, APQ_MUX_gsbi3, @@ -335,6 +336,21 @@ static const char * const codec_mic_i2s_groups[] = { static const char * const codec_spkr_i2s_groups[] = { "gpio39", "gpio40", "gpio41", "gpio42" }; +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89" +}; static const char * const gsbi1_groups[] = { "gpio18", "gpio19", "gpio20", "gpio21" }; @@ -430,6 +446,7 @@ static const struct msm_function apq8064_functions[] = { FUNCTION(cam_mclk), FUNCTION(codec_mic_i2s), FUNCTION(codec_spkr_i2s), + FUNCTION(gpio), FUNCTION(gsbi1), FUNCTION(gsbi2), FUNCTION(gsbi3), diff --git a/drivers/pinctrl/qcom/pinctrl-ipq8064.c b/drivers/pinctrl/qcom/pinctrl-ipq8064.c index acafea4c3a33..767cf1120b20 100644 --- a/drivers/pinctrl/qcom/pinctrl-ipq8064.c +++ b/drivers/pinctrl/qcom/pinctrl-ipq8064.c @@ -183,7 +183,7 @@ static const unsigned int sdc3_data_pins[] = { 71 }; .pins = gpio##id##_pins, \ .npins = ARRAY_SIZE(gpio##id##_pins), \ .funcs = (int[]){ \ - IPQ_MUX_NA, /* gpio mode */ \ + IPQ_MUX_gpio, \ IPQ_MUX_##f1, \ IPQ_MUX_##f2, \ IPQ_MUX_##f3, \ @@ -243,6 +243,7 @@ static const unsigned int sdc3_data_pins[] = { 71 }; } enum ipq8064_functions { + IPQ_MUX_gpio, IPQ_MUX_mdio, IPQ_MUX_mi2s, IPQ_MUX_pdm, @@ -291,6 +292,19 @@ enum ipq8064_functions { IPQ_MUX_NA, }; +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68" +}; + static const char * const mdio_groups[] = { "gpio0", "gpio1", "gpio10", "gpio11", }; @@ -481,6 +495,7 @@ static const char * const ps_hold_groups[] = { }; static const struct msm_function ipq8064_functions[] = { + FUNCTION(gpio), FUNCTION(mdio), FUNCTION(ssbi), FUNCTION(spmi), diff --git a/drivers/pinctrl/qcom/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c index 564543bb2c1c..35047036a053 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8960.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8960.c @@ -355,7 +355,7 @@ static const unsigned int sdc3_data_pins[] = { 157 }; .pins = gpio##id##_pins, \ .npins = ARRAY_SIZE(gpio##id##_pins), \ .funcs = (int[]){ \ - MSM_MUX_NA, /* gpio mode */ \ + MSM_MUX_gpio, \ MSM_MUX_##f1, \ MSM_MUX_##f2, \ MSM_MUX_##f3, \ @@ -441,6 +441,7 @@ enum msm8960_functions { MSM_MUX_gp_pdm_1b, MSM_MUX_gp_pdm_2a, MSM_MUX_gp_pdm_2b, + MSM_MUX_gpio, MSM_MUX_gsbi1, MSM_MUX_gsbi1_spi_cs1_n, MSM_MUX_gsbi1_spi_cs2a_n, @@ -622,6 +623,32 @@ static const char * const gp_pdm_2b_groups[] = { "gpio53" }; +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", + "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110", + "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116", + "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122", + "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128", + "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134", + "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", + "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146", + "gpio147", "gpio148", "gpio149", "gpio150", "gpio151" +}; + static const char * const gsbi1_groups[] = { "gpio6", "gpio7", "gpio8", "gpio9" }; @@ -961,6 +988,7 @@ static const struct msm_function msm8960_functions[] = { FUNCTION(gp_pdm_1b), FUNCTION(gp_pdm_2a), FUNCTION(gp_pdm_2b), + FUNCTION(gpio), FUNCTION(gsbi1), FUNCTION(gsbi1_spi_cs1_n), FUNCTION(gsbi1_spi_cs2a_n), diff --git a/drivers/pinctrl/qcom/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c index 418306911a6f..8c9720154d1e 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8x74.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c @@ -342,7 +342,7 @@ static const unsigned int sdc2_data_pins[] = { 151 }; .pins = gpio##id##_pins, \ .npins = ARRAY_SIZE(gpio##id##_pins), \ .funcs = (int[]){ \ - MSM_MUX_NA, /* gpio mode */ \ + MSM_MUX_gpio, \ MSM_MUX_##f1, \ MSM_MUX_##f2, \ MSM_MUX_##f3, \ @@ -402,6 +402,7 @@ static const unsigned int sdc2_data_pins[] = { 151 }; * the pingroup table below. */ enum msm8x74_functions { + MSM_MUX_gpio, MSM_MUX_cci_i2c0, MSM_MUX_cci_i2c1, MSM_MUX_blsp_i2c1, @@ -509,6 +510,31 @@ enum msm8x74_functions { MSM_MUX_NA, }; +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", + "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110", + "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116", + "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122", + "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128", + "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134", + "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", + "gpio141", "gpio142", "gpio143", "gpio144", "gpio145" +}; + static const char * const blsp_uart1_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3" }; @@ -728,6 +754,7 @@ static const char * const wlan_groups[] = { static const char * const slimbus_groups[] = { "gpio70", "gpio71" }; static const struct msm_function msm8x74_functions[] = { + FUNCTION(gpio), FUNCTION(cci_i2c0), FUNCTION(cci_i2c1), FUNCTION(uim1), From b4e7c55dabf611cf5cccd1554fec06f72e1c9faf Mon Sep 17 00:00:00 2001 From: abdoulaye berthe Date: Sat, 12 Jul 2014 22:30:13 +0200 Subject: [PATCH 54/61] pinctrl: remove all usage of gpio_remove ret val in driver/pinctl Signed-off-by: abdoulaye berthe Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-adi2.c | 9 ++++----- drivers/pinctrl/pinctrl-as3722.c | 11 ++--------- drivers/pinctrl/pinctrl-baytrail.c | 5 +---- drivers/pinctrl/pinctrl-coh901.c | 10 ++-------- drivers/pinctrl/pinctrl-rockchip.c | 16 ++++------------ drivers/pinctrl/sh-pfc/gpio.c | 9 +++------ drivers/pinctrl/spear/pinctrl-plgpio.c | 3 +-- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 3 +-- drivers/pinctrl/vt8500/pinctrl-wmt.c | 9 ++------- 9 files changed, 20 insertions(+), 55 deletions(-) diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c index 46413e93d850..b092b93c67a1 100644 --- a/drivers/pinctrl/pinctrl-adi2.c +++ b/drivers/pinctrl/pinctrl-adi2.c @@ -949,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev) struct gpio_port *port; char pinctrl_devname[DEVNAME_SIZE]; static int gpio; - int ret = 0, ret1; + int ret = 0; pdata = dev->platform_data; if (!pdata) @@ -1027,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev) return 0; out_remove_gpiochip: - ret1 = gpiochip_remove(&port->chip); + gpiochip_remove(&port->chip); out_remove_domain: if (port->pint) irq_domain_remove(port->domain); @@ -1038,12 +1038,11 @@ out_remove_domain: static int adi_gpio_remove(struct platform_device *pdev) { struct gpio_port *port = platform_get_drvdata(pdev); - int ret; u8 offset; list_del(&port->node); gpiochip_remove_pin_ranges(&port->chip); - ret = gpiochip_remove(&port->chip); + gpiochip_remove(&port->chip); if (port->pint) { for (offset = 0; offset < port->width; offset++) irq_dispose_mapping(irq_find_mapping(port->domain, @@ -1051,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev) irq_domain_remove(port->domain); } - return ret; + return 0; } static int adi_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c index c862f9c0e9ce..0e4ec91f4d49 100644 --- a/drivers/pinctrl/pinctrl-as3722.c +++ b/drivers/pinctrl/pinctrl-as3722.c @@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev) { struct as3722_pctrl_info *as_pci; int ret; - int tret; as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL); if (!as_pci) @@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev) return 0; fail_range_add: - tret = gpiochip_remove(&as_pci->gpio_chip); - if (tret < 0) - dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret); - + gpiochip_remove(&as_pci->gpio_chip); fail_chip_add: pinctrl_unregister(as_pci->pctl); return ret; @@ -623,11 +619,8 @@ fail_chip_add: static int as3722_pinctrl_remove(struct platform_device *pdev) { struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev); - int ret; - ret = gpiochip_remove(&as_pci->gpio_chip); - if (ret < 0) - return ret; + gpiochip_remove(&as_pci->gpio_chip); pinctrl_unregister(as_pci->pctl); return 0; } diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index 701a646a3d10..d8e946992323 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -638,12 +638,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); static int byt_gpio_remove(struct platform_device *pdev) { struct byt_gpio *vg = platform_get_drvdata(pdev); - int err; pm_runtime_disable(&pdev->dev); - err = gpiochip_remove(&vg->chip); - if (err) - dev_warn(&pdev->dev, "failed to remove gpio_chip.\n"); + gpiochip_remove(&vg->chip); return 0; } diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index d182fdd2e715..29cbbab8c3a6 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev) err_no_range: err_no_irqchip: - if (gpiochip_remove(&gpio->chip)) - dev_err(&pdev->dev, "failed to remove gpio chip\n"); + gpiochip_remove(&gpio->chip); err_no_chip: clk_disable_unprepare(gpio->clk); dev_err(&pdev->dev, "module ERROR:%d\n", err); @@ -767,16 +766,11 @@ err_no_chip: static int __exit u300_gpio_remove(struct platform_device *pdev) { struct u300_gpio *gpio = platform_get_drvdata(pdev); - int err; /* Turn off the GPIO block */ writel(0x00000000U, gpio->base + U300_GPIO_CR); - err = gpiochip_remove(&gpio->chip); - if (err < 0) { - dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err); - return err; - } + gpiochip_remove(&gpio->chip); clk_disable_unprepare(gpio->clk); return 0; } diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 192aaee8de07..e2e66c8ccf03 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1492,10 +1492,7 @@ fail: for (--i, --bank; i >= 0; --i, --bank) { if (!bank->valid) continue; - - if (gpiochip_remove(&bank->gpio_chip)) - dev_err(&pdev->dev, "gpio chip %s remove failed\n", - bank->gpio_chip.label); + gpiochip_remove(&bank->gpio_chip); } return ret; } @@ -1505,20 +1502,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev, { struct rockchip_pin_ctrl *ctrl = info->ctrl; struct rockchip_pin_bank *bank = ctrl->pin_banks; - int ret = 0; int i; - for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) { + for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { if (!bank->valid) continue; - - ret = gpiochip_remove(&bank->gpio_chip); + gpiochip_remove(&bank->gpio_chip); } - if (ret) - dev_err(&pdev->dev, "gpio chip remove failed\n"); - - return ret; + return 0; } static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index a9288ab01f7b..80f641ee4dea 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc) { - int err; - int ret; + gpiochip_remove(&pfc->gpio->gpio_chip); + gpiochip_remove(&pfc->func->gpio_chip); - ret = gpiochip_remove(&pfc->gpio->gpio_chip); - err = gpiochip_remove(&pfc->func->gpio_chip); - - return ret < 0 ? ret : err; + return 0; } diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index 3a20cdc65810..bddb79105d67 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -606,8 +606,7 @@ static int plgpio_probe(struct platform_device *pdev) remove_gpiochip: dev_info(&pdev->dev, "Remove gpiochip\n"); - if (gpiochip_remove(&plgpio->chip)) - dev_err(&pdev->dev, "unable to remove gpiochip\n"); + gpiochip_remove(&plgpio->chip); unprepare_clk: if (!IS_ERR(plgpio->clk)) clk_unprepare(plgpio->clk); diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 47f5e1bc50d0..96ee6bb0fad5 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -983,8 +983,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev, clk_error: clk_disable_unprepare(clk); gpiochip_error: - if (gpiochip_remove(pctl->chip)) - dev_err(&pdev->dev, "failed to remove gpio chip\n"); + gpiochip_remove(pctl->chip); pinctrl_error: pinctrl_unregister(pctl->pctl_dev); return ret; diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index 8c976c21eeee..8cea355f9a81 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c @@ -615,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev, return 0; fail_range: - if (gpiochip_remove(&data->gpio_chip)) - dev_err(&pdev->dev, "failed to remove gpio chip\n"); + gpiochip_remove(&data->gpio_chip); fail_gpio: pinctrl_unregister(data->pctl_dev); return err; @@ -625,12 +624,8 @@ fail_gpio: int wmt_pinctrl_remove(struct platform_device *pdev) { struct wmt_pinctrl_data *data = platform_get_drvdata(pdev); - int err; - - err = gpiochip_remove(&data->gpio_chip); - if (err) - dev_err(&pdev->dev, "failed to remove gpio chip\n"); + gpiochip_remove(&data->gpio_chip); pinctrl_unregister(data->pctl_dev); return 0; From 1c349551027fadc9cfe1ec01068f6f8ac5b9331d Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Thu, 17 Jul 2014 19:29:39 +0300 Subject: [PATCH 55/61] pinctrl: msm: drop negativity check on unsigned value [linux-3.16-rc5/drivers/pinctrl/pinctrl-msm.c:145]: (style) Checking if unsigned variable 'mux_bit' is less than zero. if (WARN_ON(g->mux_bit < 0)) return -EINVAL; Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=80491 Reported-by: David Binderman Signed-off-by: Andrey Utkin Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 90d383d3ce17..2738108caff2 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -142,9 +142,6 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev, g = &pctrl->soc->groups[group]; - if (WARN_ON(g->mux_bit < 0)) - return -EINVAL; - for (i = 0; i < g->nfuncs; i++) { if (g->funcs[i] == function) break; From ed62f2f25547ea9a25394087470a5816ee4db71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 20 Jul 2014 01:48:45 +0200 Subject: [PATCH 56/61] pinctrl: rockchip: set is_generic in pinconf_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rockchip pinctrl driver implements the generic pinconfig, therefore also state this, so that the default pinconf dump functions work. Signed-off-by: Heiko Stübner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index e2e66c8ccf03..337c1844f276 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -928,6 +928,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, static const struct pinconf_ops rockchip_pinconf_ops = { .pin_config_get = rockchip_pinconf_get, .pin_config_set = rockchip_pinconf_set, + .is_generic = true, }; static const struct of_device_id rockchip_bank_match[] = { From 66d750e1d03875512dec38993b4cac3640a85e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 20 Jul 2014 01:49:17 +0200 Subject: [PATCH 57/61] pinctrl: rockchip: add separate type for rk3288 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An upcoming pinctrl function of the rk3288 differs again from everything else, so we'll need a separate type for it. Signed-off-by: Heiko Stübner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 337c1844f276..3e239c75f52c 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -62,6 +62,7 @@ enum rockchip_pinctrl_type { RK2928, RK3066B, RK3188, + RK3288, }; /** @@ -597,6 +598,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT : PIN_CONFIG_BIAS_DISABLE; case RK3188: + case RK3288: data >>= bit; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; @@ -651,6 +653,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, spin_unlock_irqrestore(&bank->slock, flags); break; case RK3188: + case RK3288: spin_lock_irqsave(&bank->slock, flags); /* enable the write to the equivalent lower bits */ @@ -812,6 +815,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, case RK3066B: return pull ? false : true; case RK3188: + case RK3288: return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); } @@ -1838,7 +1842,7 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .pin_banks = rk3288_pin_banks, .nr_banks = ARRAY_SIZE(rk3288_pin_banks), .label = "RK3288-GPIO", - .type = RK3188, + .type = RK3288, .grf_mux_offset = 0x0, .pmu_mux_offset = 0x84, .pull_calc_reg = rk3288_calc_pull_reg_and_bit, From b547c8007e83a476b946237d09227668fe286a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 20 Jul 2014 01:50:11 +0200 Subject: [PATCH 58/61] pinctrl: rockchip: add drive-strength control for rk3288 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rk3288 is the first Rockchip soc handling the drive strength on a per-pin basis, while the older ones can set the drive-strength only for specific pin-groups. Therefore limit setting the drive-strength to this soc for now. Signed-off-by: Heiko Stübner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 112 +++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 3e239c75f52c..5e8b2e04cd7a 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -573,6 +573,98 @@ static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, } } +#define RK3288_DRV_PMU_OFFSET 0x70 +#define RK3288_DRV_GRF_OFFSET 0x1c0 +#define RK3288_DRV_BITS_PER_PIN 2 +#define RK3288_DRV_PINS_PER_REG 8 +#define RK3288_DRV_BANK_STRIDE 16 +static int rk3288_drv_list[] = { 2, 4, 8, 12 }; + +static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3288_DRV_PMU_OFFSET; + + *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RK3288_DRV_PINS_PER_REG; + *bit *= RK3288_DRV_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3288_DRV_GRF_OFFSET; + + /* correct the offset, as we're starting with the 2nd bank */ + *reg -= 0x10; + *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; + *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3288_DRV_PINS_PER_REG); + *bit *= RK3288_DRV_BITS_PER_PIN; + } +} + +static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num) +{ + struct regmap *regmap; + int reg, ret; + u32 data; + u8 bit; + + rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + ret = regmap_read(regmap, reg, &data); + if (ret) + return ret; + + data >>= bit; + data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1; + + return rk3288_drv_list[data]; +} + +static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num, + int strength) +{ + struct rockchip_pinctrl *info = bank->drvdata; + struct regmap *regmap; + unsigned long flags; + int reg, ret, i; + u32 data; + u8 bit; + + rk3288_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + ret = -EINVAL; + for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) { + if (rk3288_drv_list[i] == strength) { + ret = i; + break; + } + } + + if (ret < 0) { + dev_err(info->dev, "unsupported driver strength %d\n", + strength); + return ret; + } + + spin_lock_irqsave(&bank->slock, flags); + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + + ret = regmap_write(regmap, reg, data); + spin_unlock_irqrestore(&bank->slock, flags); + + return ret; +} + static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) { struct rockchip_pinctrl *info = bank->drvdata; @@ -870,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, if (rc) return rc; break; + case PIN_CONFIG_DRIVE_STRENGTH: + /* rk3288 is the first with per-pin drive-strength */ + if (info->ctrl->type != RK3288) + return -ENOTSUPP; + + rc = rk3288_set_drive(bank, pin - bank->pin_base, arg); + if (rc < 0) + return rc; + break; default: return -ENOTSUPP; break; @@ -919,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, arg = rc ? 1 : 0; break; + case PIN_CONFIG_DRIVE_STRENGTH: + /* rk3288 is the first with per-pin drive-strength */ + if (info->ctrl->type != RK3288) + return -ENOTSUPP; + + rc = rk3288_get_drive(bank, pin - bank->pin_base); + if (rc < 0) + return rc; + + arg = rc; + break; default: return -ENOTSUPP; break; From f83549d61d6de28ea8cbbef9f8d12b697c6ed1dd Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 15 Jul 2014 01:24:36 +0800 Subject: [PATCH 59/61] pinctrl: sunxi: use gpiolib API to mark a GPIO used as an IRQ When an IRQ is started on a GPIO line, mark this GPIO as IRQ in the gpiolib so we can keep track of the usage centrally. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 96ee6bb0fad5..9dba7afe94d6 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -541,18 +541,33 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); struct sunxi_desc_function *func; + int ret; func = sunxi_pinctrl_desc_find_function_by_pin(pctl, pctl->irq_array[d->hwirq], "irq"); if (!func) return -EINVAL; + ret = gpio_lock_as_irq(pctl->chip, pctl->irq_array[d->hwirq]); + if (ret) { + dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n", + irqd_to_hwirq(d)); + return ret; + } + /* Change muxing to INT mode */ sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); return 0; } +static void sunxi_pinctrl_irq_release_resources(struct irq_data *d) +{ + struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); + + gpio_unlock_as_irq(pctl->chip, pctl->irq_array[d->hwirq]); +} + static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); @@ -657,6 +672,7 @@ static struct irq_chip sunxi_pinctrl_edge_irq_chip = { .irq_mask = sunxi_pinctrl_irq_mask, .irq_unmask = sunxi_pinctrl_irq_unmask, .irq_request_resources = sunxi_pinctrl_irq_request_resources, + .irq_release_resources = sunxi_pinctrl_irq_release_resources, .irq_set_type = sunxi_pinctrl_irq_set_type, .flags = IRQCHIP_SKIP_SET_WAKE, }; @@ -670,6 +686,7 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip = { .irq_enable = sunxi_pinctrl_irq_ack_unmask, .irq_disable = sunxi_pinctrl_irq_mask, .irq_request_resources = sunxi_pinctrl_irq_request_resources, + .irq_release_resources = sunxi_pinctrl_irq_release_resources, .irq_set_type = sunxi_pinctrl_irq_set_type, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, From 343f132752bede1dc3a740ba469b665ffb111500 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 15 Jul 2014 01:24:37 +0800 Subject: [PATCH 60/61] pinctrl: sunxi: number gpio ranges starting from 0 The pinctrl-sunxi driver originally used the pin number as the gpio range offset. This resulted in large, bogus gpio numbers for the new sun6i-a31-r pinctrl devices. This patch makes the driver number the gpios ranges starting from an offset of 0, by subtracting the pin_base number from the pin number. This also makes the system-wide gpio number match the pin number. Tested on sun8i with sysfs exported gpios. This patch also changes the GPIO bindings for R_PIO: gpios = <&r_pio B N flag>; Where B originally was the pinbank label (L or M) counted from A, with this patch it becomes (L or M) counted from its pinbank base (L). Thus gpios = <&r_pio 10 11 0>; /* PL11 */ becomes gpios = <&r_pio 0 11 0>; /* PL11 */ IMO this is correct, as the binding shows the bank offset and pin offset within the bank for the GPIO controller. But I'm worried it might be a bit confusing. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 9dba7afe94d6..b24b5ecbe290 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -507,7 +507,7 @@ static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc, base = PINS_PER_BANK * gpiospec->args[0]; pin = base + gpiospec->args[1]; - if (pin > (gc->base + gc->ngpio)) + if (pin > gc->ngpio) return -EINVAL; if (flags) @@ -520,12 +520,13 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); struct sunxi_desc_function *desc; + unsigned pinnum = pctl->desc->pin_base + offset; unsigned irqnum; if (offset >= chip->ngpio) return -ENXIO; - desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq"); + desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pinnum, "irq"); if (!desc) return -EINVAL; @@ -548,7 +549,8 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) if (!func) return -EINVAL; - ret = gpio_lock_as_irq(pctl->chip, pctl->irq_array[d->hwirq]); + ret = gpio_lock_as_irq(pctl->chip, + pctl->irq_array[d->hwirq] - pctl->desc->pin_base); if (ret) { dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n", irqd_to_hwirq(d)); @@ -565,7 +567,8 @@ static void sunxi_pinctrl_irq_release_resources(struct irq_data *d) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(pctl->chip, pctl->irq_array[d->hwirq]); + gpio_unlock_as_irq(pctl->chip, + pctl->irq_array[d->hwirq] - pctl->desc->pin_base); } static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) @@ -931,7 +934,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev, const struct sunxi_desc_pin *pin = pctl->desc->pins + i; ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev), - pin->pin.number, + pin->pin.number - pctl->desc->pin_base, pin->pin.number, 1); if (ret) goto gpiochip_error; From e1ee5c578fb1fa24b7ccaf1a11237a2bd70b6f9a Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 25 Jul 2014 09:54:47 +0300 Subject: [PATCH 61/61] pinctrl: baytrail: Convert to use gpiolib irqchip Instead of open-coding irqchip handling in the driver we can take advantage of the new irqchip helpers provided by the gpiolib core. While doing this we also make sure that we call gpiochip_irqchip_add() after the gpiochip itself is registered as required. Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 2 +- drivers/pinctrl/pinctrl-baytrail.c | 89 +++++++----------------------- 2 files changed, 21 insertions(+), 70 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 3d94e47546ec..4e3231ad03cd 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -70,7 +70,7 @@ config PINCTRL_AT91 config PINCTRL_BAYTRAIL bool "Intel Baytrail GPIO pin control" depends on GPIOLIB && ACPI && X86 - select IRQ_DOMAIN + select GPIOLIB_IRQCHIP help driver for memory mapped GPIO functionality on Intel Baytrail platforms. Supports 3 banks with 102, 28 and 44 gpios. diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index d8e946992323..9ca59a018743 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -25,9 +25,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -138,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = { struct byt_gpio { struct gpio_chip chip; - struct irq_domain *domain; struct platform_device *pdev; spinlock_t lock; void __iomem *reg_base; @@ -218,7 +215,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) static int byt_irq_type(struct irq_data *d, unsigned type) { - struct byt_gpio *vg = irq_data_get_irq_chip_data(d); + struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d)); u32 offset = irqd_to_hwirq(d); u32 value; unsigned long flags; @@ -404,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) spin_unlock_irqrestore(&vg->lock, flags); } -static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct byt_gpio *vg = to_byt_gpio(chip); - return irq_create_mapping(vg->domain, offset); -} - static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); - struct byt_gpio *vg = irq_data_get_irq_handler_data(data); + struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc)); struct irq_chip *chip = irq_data_get_irq_chip(data); u32 base, pin, mask; void __iomem *reg; @@ -432,7 +423,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) /* Clear before handling so we can't lose an edge */ writel(mask, reg); - virq = irq_find_mapping(vg->domain, base + pin); + virq = irq_find_mapping(vg->chip.irqdomain, base + pin); generic_handle_irq(virq); /* In case bios or user sets triggering incorretly a pin @@ -465,33 +456,11 @@ static void byt_irq_mask(struct irq_data *d) { } -static int byt_irq_reqres(struct irq_data *d) -{ - struct byt_gpio *vg = irq_data_get_irq_chip_data(d); - - if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d))) { - dev_err(vg->chip.dev, - "unable to lock HW IRQ %lu for IRQ\n", - irqd_to_hwirq(d)); - return -EINVAL; - } - return 0; -} - -static void byt_irq_relres(struct irq_data *d) -{ - struct byt_gpio *vg = irq_data_get_irq_chip_data(d); - - gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d)); -} - static struct irq_chip byt_irqchip = { .name = "BYT-GPIO", .irq_mask = byt_irq_mask, .irq_unmask = byt_irq_unmask, .irq_set_type = byt_irq_type, - .irq_request_resources = byt_irq_reqres, - .irq_release_resources = byt_irq_relres, }; static void byt_gpio_irq_init_hw(struct byt_gpio *vg) @@ -512,23 +481,6 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) } } -static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) -{ - struct byt_gpio *vg = d->host_data; - - irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq, - "demux"); - irq_set_chip_data(virq, vg); - irq_set_irq_type(virq, IRQ_TYPE_NONE); - - return 0; -} - -static const struct irq_domain_ops byt_gpio_irq_ops = { - .map = byt_gpio_irq_map, -}; - static int byt_gpio_probe(struct platform_device *pdev) { struct byt_gpio *vg; @@ -538,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev) struct acpi_device *acpi_dev; struct pinctrl_gpio_range *range; acpi_handle handle = ACPI_HANDLE(dev); - unsigned hwirq; int ret; if (acpi_bus_get_device(handle, &acpi_dev)) @@ -585,29 +536,29 @@ static int byt_gpio_probe(struct platform_device *pdev) gc->can_sleep = false; gc->dev = dev; - /* set up interrupts */ - irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq_rc && irq_rc->start) { - hwirq = irq_rc->start; - gc->to_irq = byt_gpio_to_irq; - - vg->domain = irq_domain_add_linear(NULL, gc->ngpio, - &byt_gpio_irq_ops, vg); - if (!vg->domain) - return -ENXIO; - - byt_gpio_irq_init_hw(vg); - - irq_set_handler_data(hwirq, vg); - irq_set_chained_handler(hwirq, byt_gpio_irq_handler); - } - ret = gpiochip_add(gc); if (ret) { dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); return ret; } + /* set up interrupts */ + irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (irq_rc && irq_rc->start) { + byt_gpio_irq_init_hw(vg); + ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, + handle_simple_irq, IRQ_TYPE_NONE); + if (ret) { + dev_err(dev, "failed to add irqchip\n"); + gpiochip_remove(gc); + return ret; + } + + gpiochip_set_chained_irqchip(gc, &byt_irqchip, + (unsigned)irq_rc->start, + byt_gpio_irq_handler); + } + pm_runtime_enable(dev); return 0;