2021-03-25 01:22:42

by Jianqun Xu

[permalink] [raw]
Subject: [PATCH RESEND 0/7] gpio-rockchip driver

Separate gpio driver from pinctrl driver, and support v2 controller.

Jianqun Xu (7):
pinctrl/rockchip: separate struct rockchip_pin_bank to a head file
pinctrl/pinctrl-rockchip.h: add pinctrl device to gpio bank struct
gpio: separate gpio driver from pinctrl-rockchip driver
gpio/rockchip: use struct rockchip_gpio_regs for gpio controller
gpio/rockchip: support next version gpio controller
gpio/rockchip: always enable clock for gpio controller
gpio/rockchip: drop irq_gc_lock/irq_gc_unlock for irq set type

drivers/gpio/Kconfig | 8 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-rockchip.c | 758 ++++++++++++++++++++++++
drivers/pinctrl/pinctrl-rockchip.c | 909 +----------------------------
drivers/pinctrl/pinctrl-rockchip.h | 286 +++++++++
5 files changed, 1072 insertions(+), 890 deletions(-)
create mode 100644 drivers/gpio/gpio-rockchip.c
create mode 100644 drivers/pinctrl/pinctrl-rockchip.h

--
2.25.1




2021-03-25 01:23:14

by Jianqun Xu

[permalink] [raw]
Subject: [PATCH 4/7] gpio/rockchip: use struct rockchip_gpio_regs for gpio controller

Store register offsets in the struct rockchip_gpio_regs, this patch
prepare for the driver update for new gpio controller.

Signed-off-by: Jianqun Xu <[email protected]>
---
drivers/gpio/gpio-rockchip.c | 85 ++++++++++++++++--------------
drivers/pinctrl/pinctrl-rockchip.h | 38 +++++++++++++
2 files changed, 84 insertions(+), 39 deletions(-)

diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 03a3d251faae..b12db3a523d0 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -24,19 +24,21 @@
#include "../pinctrl/core.h"
#include "../pinctrl/pinctrl-rockchip.h"

-/* GPIO control registers */
-#define GPIO_SWPORT_DR 0x00
-#define GPIO_SWPORT_DDR 0x04
-#define GPIO_INTEN 0x30
-#define GPIO_INTMASK 0x34
-#define GPIO_INTTYPE_LEVEL 0x38
-#define GPIO_INT_POLARITY 0x3c
-#define GPIO_INT_STATUS 0x40
-#define GPIO_INT_RAWSTATUS 0x44
-#define GPIO_DEBOUNCE 0x48
-#define GPIO_PORTS_EOI 0x4c
-#define GPIO_EXT_PORT 0x50
-#define GPIO_LS_SYNC 0x60
+#define GPIO_TYPE_V1 (0) /* GPIO Version ID reserved */
+
+static const struct rockchip_gpio_regs gpio_regs_v1 = {
+ .port_dr = 0x00,
+ .port_ddr = 0x04,
+ .int_en = 0x30,
+ .int_mask = 0x34,
+ .int_type = 0x38,
+ .int_polarity = 0x3c,
+ .int_status = 0x40,
+ .int_rawstatus = 0x44,
+ .debounce = 0x48,
+ .port_eoi = 0x4c,
+ .ext_port = 0x50,
+};

static int rockchip_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
@@ -51,7 +53,7 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip,
"failed to enable clock for bank %s\n", bank->name);
return ret;
}
- data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+ data = readl_relaxed(bank->reg_base + bank->gpio_regs->port_ddr);
clk_disable(bank->clk);

if (data & BIT(offset))
@@ -70,13 +72,13 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
clk_enable(bank->clk);
raw_spin_lock_irqsave(&bank->slock, flags);

- data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+ data = readl_relaxed(bank->reg_base + bank->gpio_regs->port_ddr);
/* set bit to 1 for output, 0 for input */
if (!input)
data |= BIT(offset);
else
data &= ~BIT(offset);
- writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+ writel_relaxed(data, bank->reg_base + bank->gpio_regs->port_ddr);

raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
@@ -88,7 +90,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned int offset,
int value)
{
struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
- void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR;
+ void __iomem *reg = bank->reg_base + bank->gpio_regs->port_dr;
unsigned long flags;
u32 data;

@@ -111,7 +113,7 @@ static int rockchip_gpio_get(struct gpio_chip *gc, unsigned int offset)
u32 data;

clk_enable(bank->clk);
- data = readl(bank->reg_base + GPIO_EXT_PORT);
+ data = readl(bank->reg_base + bank->gpio_regs->ext_port);
clk_disable(bank->clk);
data >>= offset;
data &= 1;
@@ -122,7 +124,7 @@ static void rockchip_gpio_set_debounce(struct gpio_chip *gc,
unsigned int offset, bool enable)
{
struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
- void __iomem *reg = bank->reg_base + GPIO_DEBOUNCE;
+ void __iomem *reg = bank->reg_base + bank->gpio_regs->debounce;
unsigned long flags;
u32 data;

@@ -226,7 +228,7 @@ static void rockchip_irq_demux(struct irq_desc *desc)

chained_irq_enter(chip, desc);

- pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
+ pend = readl_relaxed(bank->reg_base + bank->gpio_regs->int_status);

while (pend) {
unsigned int irq, virq;
@@ -250,24 +252,26 @@ static void rockchip_irq_demux(struct irq_desc *desc)
u32 data, data_old, polarity;
unsigned long flags;

- data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
+ data = readl_relaxed(bank->reg_base +
+ bank->gpio_regs->ext_port);
do {
raw_spin_lock_irqsave(&bank->slock, flags);

polarity = readl_relaxed(bank->reg_base +
- GPIO_INT_POLARITY);
+ bank->gpio_regs->int_polarity);
if (data & BIT(irq))
polarity &= ~BIT(irq);
else
polarity |= BIT(irq);
writel(polarity,
- bank->reg_base + GPIO_INT_POLARITY);
+ bank->reg_base +
+ bank->gpio_regs->int_polarity);

raw_spin_unlock_irqrestore(&bank->slock, flags);

data_old = data;
data = readl_relaxed(bank->reg_base +
- GPIO_EXT_PORT);
+ bank->gpio_regs->ext_port);
} while ((data & BIT(irq)) != (data_old & BIT(irq)));
}

@@ -290,9 +294,9 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
clk_enable(bank->clk);
raw_spin_lock_irqsave(&bank->slock, flags);

- data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+ data = readl_relaxed(bank->reg_base + bank->gpio_regs->port_ddr);
data &= ~mask;
- writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+ writel_relaxed(data, bank->reg_base + bank->gpio_regs->port_ddr);

raw_spin_unlock_irqrestore(&bank->slock, flags);

@@ -304,8 +308,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
raw_spin_lock_irqsave(&bank->slock, flags);
irq_gc_lock(gc);

- level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
- polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY);
+ level = readl_relaxed(gc->reg_base + bank->gpio_regs->int_type);
+ polarity = readl_relaxed(gc->reg_base + bank->gpio_regs->int_polarity);

switch (type) {
case IRQ_TYPE_EDGE_BOTH:
@@ -316,7 +320,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
* Determine gpio state. If 1 next interrupt should be falling
* otherwise rising.
*/
- data = readl(bank->reg_base + GPIO_EXT_PORT);
+ data = readl(bank->reg_base + bank->gpio_regs->ext_port);
if (data & mask)
polarity &= ~mask;
else
@@ -349,8 +353,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}

- writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL);
- writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
+ writel_relaxed(level, gc->reg_base + bank->gpio_regs->int_type);
+ writel_relaxed(polarity, gc->reg_base + bank->gpio_regs->int_polarity);

irq_gc_unlock(gc);
raw_spin_unlock_irqrestore(&bank->slock, flags);
@@ -365,8 +369,8 @@ static void rockchip_irq_suspend(struct irq_data *d)
struct rockchip_pin_bank *bank = gc->private;

clk_enable(bank->clk);
- bank->saved_masks = irq_reg_readl(gc, GPIO_INTMASK);
- irq_reg_writel(gc, ~gc->wake_active, GPIO_INTMASK);
+ bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask);
+ irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask);
clk_disable(bank->clk);
}

@@ -376,7 +380,7 @@ static void rockchip_irq_resume(struct irq_data *d)
struct rockchip_pin_bank *bank = gc->private;

clk_enable(bank->clk);
- irq_reg_writel(gc, bank->saved_masks, GPIO_INTMASK);
+ irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask);
clk_disable(bank->clk);
}

@@ -435,8 +439,8 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
gc = irq_get_domain_generic_chip(bank->domain, 0);
gc->reg_base = bank->reg_base;
gc->private = bank;
- gc->chip_types[0].regs.mask = GPIO_INTMASK;
- gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
+ gc->chip_types[0].regs.mask = bank->gpio_regs->int_mask;
+ gc->chip_types[0].regs.ack = bank->gpio_regs->port_eoi;
gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
@@ -453,9 +457,9 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
* Our driver only uses the concept of masked and always keeps
* things enabled, so for us that's all masked and all enabled.
*/
- writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTMASK);
- writel_relaxed(0xffffffff, bank->reg_base + GPIO_PORTS_EOI);
- writel_relaxed(0xffffffff, bank->reg_base + GPIO_INTEN);
+ writel_relaxed(0xffffffff, bank->reg_base + bank->gpio_regs->int_mask);
+ writel_relaxed(0xffffffff, bank->reg_base + bank->gpio_regs->port_eoi);
+ writel_relaxed(0xffffffff, bank->reg_base + bank->gpio_regs->int_en);
gc->mask_cache = 0xffffffff;

irq_set_chained_handler_and_data(bank->irq,
@@ -546,6 +550,9 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)

bank->irq = irq_of_parse_and_map(bank->of_node, 0);

+ bank->gpio_regs = &gpio_regs_v1;
+ bank->gpio_type = GPIO_TYPE_V1;
+
bank->clk = of_clk_get(bank->of_node, 0);
if (!IS_ERR(bank->clk))
return clk_prepare(bank->clk);
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 20f734ce3933..9b8f653627ac 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -31,6 +31,42 @@ enum rockchip_pinctrl_type {
RK3399,
};

+/**
+ * struct rockchip_gpio_regs
+ * @port_dr: data register
+ * @port_ddr: data direction register
+ * @int_en: interrupt enable
+ * @int_mask: interrupt mask
+ * @int_type: interrupt trigger type, such as high, low, edge trriger type.
+ * @int_polarity: interrupt polarity enable register
+ * @int_bothedge: interrupt bothedge enable register
+ * @int_status: interrupt status register
+ * @int_rawstatus: int_status = int_rawstatus & int_mask
+ * @debounce: enable debounce for interrupt signal
+ * @dbclk_div_en: enable divider for debounce clock
+ * @dbclk_div_con: setting for divider of debounce clock
+ * @port_eoi: end of interrupt of the port
+ * @ext_port: port data from external
+ * @version_id: controller version register
+ */
+struct rockchip_gpio_regs {
+ u32 port_dr;
+ u32 port_ddr;
+ u32 int_en;
+ u32 int_mask;
+ u32 int_type;
+ u32 int_polarity;
+ u32 int_bothedge;
+ u32 int_status;
+ u32 int_rawstatus;
+ u32 debounce;
+ u32 dbclk_div_en;
+ u32 dbclk_div_con;
+ u32 port_eoi;
+ u32 ext_port;
+ u32 version_id;
+};
+
/**
* struct rockchip_iomux
* @type: iomux variant using IOMUX_* constants
@@ -125,6 +161,8 @@ struct rockchip_pin_bank {
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range grange;
raw_spinlock_t slock;
+ const struct rockchip_gpio_regs *gpio_regs;
+ u32 gpio_type;
u32 toggle_edge_mode;
u32 recalced_mask;
u32 route_mask;
--
2.25.1



2021-03-25 01:24:12

by Jianqun Xu

[permalink] [raw]
Subject: [PATCH 6/7] gpio/rockchip: always enable clock for gpio controller

Since gate and ungate pclk of gpio has very litte benifit for system
power consumption, just keep it always ungate.

Signed-off-by: Jianqun Xu <[email protected]>
---
drivers/gpio/gpio-rockchip.c | 68 +++++-------------------------------
1 file changed, 9 insertions(+), 59 deletions(-)

diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 92aaf1848449..048e7eecddba 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -139,17 +139,8 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip,
{
struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
u32 data;
- int ret;

- ret = clk_enable(bank->clk);
- if (ret < 0) {
- dev_err(bank->drvdata->dev,
- "failed to enable clock for bank %s\n", bank->name);
- return ret;
- }
data = rockchip_gpio_readl_bit(bank, offset, bank->gpio_regs->port_ddr);
- clk_disable(bank->clk);
-
if (data & BIT(offset))
return GPIO_LINE_DIRECTION_OUT;

@@ -163,11 +154,9 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
unsigned long flags;
u32 data = input ? 0 : 1;

- clk_enable(bank->clk);
raw_spin_lock_irqsave(&bank->slock, flags);
rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
raw_spin_unlock_irqrestore(&bank->slock, flags);
- clk_disable(bank->clk);

return 0;
}
@@ -178,11 +167,9 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned int offset,
struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
unsigned long flags;

- clk_enable(bank->clk);
raw_spin_lock_irqsave(&bank->slock, flags);
rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr);
raw_spin_unlock_irqrestore(&bank->slock, flags);
- clk_disable(bank->clk);
}

static int rockchip_gpio_get(struct gpio_chip *gc, unsigned int offset)
@@ -190,11 +177,10 @@ static int rockchip_gpio_get(struct gpio_chip *gc, unsigned int offset)
struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
u32 data;

- clk_enable(bank->clk);
data = readl(bank->reg_base + bank->gpio_regs->ext_port);
- clk_disable(bank->clk);
data >>= offset;
data &= 1;
+
return data;
}

@@ -315,9 +301,7 @@ static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
if (!bank->domain)
return -ENXIO;

- clk_enable(bank->clk);
virq = irq_create_mapping(bank->domain, offset);
- clk_disable(bank->clk);

return (virq) ? : -ENXIO;
}
@@ -409,7 +393,6 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
unsigned long flags;
int ret = 0;

- clk_enable(bank->clk);
raw_spin_lock_irqsave(&bank->slock, flags);

rockchip_gpio_writel_bit(bank, d->hwirq, 0,
@@ -480,7 +463,6 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
out:
irq_gc_unlock(gc);
raw_spin_unlock_irqrestore(&bank->slock, flags);
- clk_disable(bank->clk);

return ret;
}
@@ -490,10 +472,8 @@ static void rockchip_irq_suspend(struct irq_data *d)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;

- clk_enable(bank->clk);
bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask);
irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask);
- clk_disable(bank->clk);
}

static void rockchip_irq_resume(struct irq_data *d)
@@ -501,27 +481,7 @@ static void rockchip_irq_resume(struct irq_data *d)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct rockchip_pin_bank *bank = gc->private;

- clk_enable(bank->clk);
irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask);
- clk_disable(bank->clk);
-}
-
-static void rockchip_irq_enable(struct irq_data *d)
-{
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- struct rockchip_pin_bank *bank = gc->private;
-
- clk_enable(bank->clk);
- irq_gc_mask_clr_bit(d);
-}
-
-static void rockchip_irq_disable(struct irq_data *d)
-{
- struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- struct rockchip_pin_bank *bank = gc->private;
-
- irq_gc_mask_set_bit(d);
- clk_disable(bank->clk);
}

static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
@@ -530,19 +490,11 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
struct irq_chip_generic *gc;
int ret;

- ret = clk_enable(bank->clk);
- if (ret) {
- dev_err(bank->dev, "failed to enable clock for bank %s\n",
- bank->name);
- return -EINVAL;
- }
-
bank->domain = irq_domain_add_linear(bank->of_node, 32,
&irq_generic_chip_ops, NULL);
if (!bank->domain) {
dev_warn(bank->dev, "could not init irq domain for bank %s\n",
bank->name);
- clk_disable(bank->clk);
return -EINVAL;
}

@@ -554,7 +506,6 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
dev_err(bank->dev, "could not alloc generic chips for bank %s\n",
bank->name);
irq_domain_remove(bank->domain);
- clk_disable(bank->clk);
return -EINVAL;
}

@@ -571,8 +522,8 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)
gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
- gc->chip_types[0].chip.irq_enable = rockchip_irq_enable;
- gc->chip_types[0].chip.irq_disable = rockchip_irq_disable;
+ gc->chip_types[0].chip.irq_enable = irq_gc_mask_clr_bit;
+ gc->chip_types[0].chip.irq_disable = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
@@ -591,7 +542,6 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank)

irq_set_chained_handler_and_data(bank->irq,
rockchip_irq_demux, bank);
- clk_disable(bank->clk);

return 0;
}
@@ -695,7 +645,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
if (IS_ERR(bank->db_clk)) {
dev_err(bank->dev, "cannot find debounce clk\n");
bank->db_clk = NULL;
- clk_disable(bank->clk);
return -EINVAL;
}
} else {
@@ -703,7 +652,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
bank->gpio_type = GPIO_TYPE_V1;
}

- clk_disable(bank->clk);
return 0;
}

@@ -756,15 +704,17 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
return ret;

ret = rockchip_gpiolib_register(bank);
- if (ret) {
- clk_disable_unprepare(bank->clk);
- return ret;
- }
+ if (ret)
+ goto err_clk;

platform_set_drvdata(pdev, bank);
dev_info(dev, "probed %pOF\n", np);

return 0;
+err_clk:
+ clk_disable_unprepare(bank->clk);
+
+ return ret;
}

static int rockchip_gpio_remove(struct platform_device *pdev)
--
2.25.1



2021-04-10 20:45:57

by Ezequiel Garcia

[permalink] [raw]
Subject: Re: [PATCH RESEND 0/7] gpio-rockchip driver

Hi Jianqun,

I tried applying this on top of "pinctrl: rockchip: add support for rk3568",
but I got some conflicts. If you could add some information about
how patches should be applied to the cover letter, that'd be really helpful :-)

Also, I've noticed several of these GPIOs patches, is this the most up to date?
You can add some information about superseeding patches
in the cover letter as well.

Thanks,
Ezequiel


On Wed, 24 Mar 2021 at 03:46, Jianqun Xu <[email protected]> wrote:
>
> Separate gpio driver from pinctrl driver, and support v2 controller.
>
> Jianqun Xu (7):
> pinctrl/rockchip: separate struct rockchip_pin_bank to a head file
> pinctrl/pinctrl-rockchip.h: add pinctrl device to gpio bank struct
> gpio: separate gpio driver from pinctrl-rockchip driver
> gpio/rockchip: use struct rockchip_gpio_regs for gpio controller
> gpio/rockchip: support next version gpio controller
> gpio/rockchip: always enable clock for gpio controller
> gpio/rockchip: drop irq_gc_lock/irq_gc_unlock for irq set type
>
> drivers/gpio/Kconfig | 8 +
> drivers/gpio/Makefile | 1 +
> drivers/gpio/gpio-rockchip.c | 758 ++++++++++++++++++++++++
> drivers/pinctrl/pinctrl-rockchip.c | 909 +----------------------------
> drivers/pinctrl/pinctrl-rockchip.h | 286 +++++++++
> 5 files changed, 1072 insertions(+), 890 deletions(-)
> create mode 100644 drivers/gpio/gpio-rockchip.c
> create mode 100644 drivers/pinctrl/pinctrl-rockchip.h
>
> --
> 2.25.1
>
>
>