Message ID | 20210303132619.3938128-4-geert+renesas@glider.be |
---|---|
State | Accepted |
Commit | ec0794a122db146ac58984afd198062d0349b92a |
Headers | show |
Series | pinctrl: renesas: Bias improvements and r8a7791 support | expand |
Hi Geert, Patches like these are enjoyable to review. On 2021-03-03 14:26:16 +0100, Geert Uytterhoeven wrote: > The pin control sub-drivers for SH/R-Mobile SoCs contain almost > identical bias handling. The only SoC-specific part is the mapping from > pin numbers to PORTnCR registers. > > Reduce code duplication by factoring out the bias handling to the common > pinctrl.c code. Use a callback to handle the pin/register mapping. > > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > --- > drivers/pinctrl/renesas/pfc-r8a73a4.c | 48 +++------------------------ > drivers/pinctrl/renesas/pfc-r8a7740.c | 46 +++---------------------- > drivers/pinctrl/renesas/pfc-sh73a0.c | 46 +++---------------------- > drivers/pinctrl/renesas/pinctrl.c | 40 ++++++++++++++++++++++ > drivers/pinctrl/renesas/sh_pfc.h | 5 +++ > 5 files changed, 59 insertions(+), 126 deletions(-) > > diff --git a/drivers/pinctrl/renesas/pfc-r8a73a4.c b/drivers/pinctrl/renesas/pfc-r8a73a4.c > index b21f5afe610fb430..b26ff9d6ead4bb6c 100644 > --- a/drivers/pinctrl/renesas/pfc-r8a73a4.c > +++ b/drivers/pinctrl/renesas/pfc-r8a73a4.c > @@ -2649,59 +2649,21 @@ static const struct pinmux_irq pinmux_irqs[] = { > PINMUX_IRQ(329), /* IRQ57 */ > }; > > -#define PORTCR_PULMD_OFF (0 << 6) > -#define PORTCR_PULMD_DOWN (2 << 6) > -#define PORTCR_PULMD_UP (3 << 6) > -#define PORTCR_PULMD_MASK (3 << 6) > - > static const unsigned int r8a73a4_portcr_offsets[] = { > 0x00000000, 0x00001000, 0x00000000, 0x00001000, > 0x00001000, 0x00002000, 0x00002000, 0x00002000, > 0x00002000, 0x00003000, 0x00003000, > }; > > -static unsigned int r8a73a4_pinmux_get_bias(struct sh_pfc *pfc, > - unsigned int pin) > -{ > - void __iomem *addr; > - > - addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; > - > - switch (ioread8(addr) & PORTCR_PULMD_MASK) { > - case PORTCR_PULMD_UP: > - return PIN_CONFIG_BIAS_PULL_UP; > - case PORTCR_PULMD_DOWN: > - return PIN_CONFIG_BIAS_PULL_DOWN; > - case PORTCR_PULMD_OFF: > - default: > - return PIN_CONFIG_BIAS_DISABLE; > - } > -} > - > -static void r8a73a4_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > - unsigned int bias) > +static void __iomem *r8a73a4_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) > { > - void __iomem *addr; > - u32 value; > - > - addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; > - value = ioread8(addr) & ~PORTCR_PULMD_MASK; > - > - switch (bias) { > - case PIN_CONFIG_BIAS_PULL_UP: > - value |= PORTCR_PULMD_UP; > - break; > - case PIN_CONFIG_BIAS_PULL_DOWN: > - value |= PORTCR_PULMD_DOWN; > - break; > - } > - > - iowrite8(value, addr); > + return pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; > } > > static const struct sh_pfc_soc_operations r8a73a4_pfc_ops = { > - .get_bias = r8a73a4_pinmux_get_bias, > - .set_bias = r8a73a4_pinmux_set_bias, > + .get_bias = rmobile_pinmux_get_bias, > + .set_bias = rmobile_pinmux_set_bias, > + .pin_to_portcr = r8a73a4_pin_to_portcr, > }; > > const struct sh_pfc_soc_info r8a73a4_pinmux_info = { > diff --git a/drivers/pinctrl/renesas/pfc-r8a7740.c b/drivers/pinctrl/renesas/pfc-r8a7740.c > index fdf1b0f09f57e693..4eac3899d69bc488 100644 > --- a/drivers/pinctrl/renesas/pfc-r8a7740.c > +++ b/drivers/pinctrl/renesas/pfc-r8a7740.c > @@ -3672,11 +3672,6 @@ static const struct pinmux_irq pinmux_irqs[] = { > PINMUX_IRQ(41, 167), /* IRQ31A */ > }; > > -#define PORTnCR_PULMD_OFF (0 << 6) > -#define PORTnCR_PULMD_DOWN (2 << 6) > -#define PORTnCR_PULMD_UP (3 << 6) > -#define PORTnCR_PULMD_MASK (3 << 6) > - > struct r8a7740_portcr_group { > unsigned int end_pin; > unsigned int offset; > @@ -3686,7 +3681,7 @@ static const struct r8a7740_portcr_group r8a7740_portcr_offsets[] = { > { 83, 0x0000 }, { 114, 0x1000 }, { 209, 0x2000 }, { 211, 0x3000 }, > }; > > -static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) > +static void __iomem *r8a7740_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) > { > unsigned int i; > > @@ -3701,43 +3696,10 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) > return NULL; > } > > -static unsigned int r8a7740_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) > -{ > - void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin); > - u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; > - > - switch (value) { > - case PORTnCR_PULMD_UP: > - return PIN_CONFIG_BIAS_PULL_UP; > - case PORTnCR_PULMD_DOWN: > - return PIN_CONFIG_BIAS_PULL_DOWN; > - case PORTnCR_PULMD_OFF: > - default: > - return PIN_CONFIG_BIAS_DISABLE; > - } > -} > - > -static void r8a7740_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > - unsigned int bias) > -{ > - void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin); > - u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; > - > - switch (bias) { > - case PIN_CONFIG_BIAS_PULL_UP: > - value |= PORTnCR_PULMD_UP; > - break; > - case PIN_CONFIG_BIAS_PULL_DOWN: > - value |= PORTnCR_PULMD_DOWN; > - break; > - } > - > - iowrite8(value, addr); > -} > - > static const struct sh_pfc_soc_operations r8a7740_pfc_ops = { > - .get_bias = r8a7740_pinmux_get_bias, > - .set_bias = r8a7740_pinmux_set_bias, > + .get_bias = rmobile_pinmux_get_bias, > + .set_bias = rmobile_pinmux_set_bias, > + .pin_to_portcr = r8a7740_pin_to_portcr, > }; > > const struct sh_pfc_soc_info r8a7740_pinmux_info = { > diff --git a/drivers/pinctrl/renesas/pfc-sh73a0.c b/drivers/pinctrl/renesas/pfc-sh73a0.c > index 96b91e95b1e14de1..ed6db809e80de3b7 100644 > --- a/drivers/pinctrl/renesas/pfc-sh73a0.c > +++ b/drivers/pinctrl/renesas/pfc-sh73a0.c > @@ -13,7 +13,6 @@ > #include <linux/regulator/machine.h> > #include <linux/slab.h> > > -#include "core.h" > #include "sh_pfc.h" > > #define CPU_ALL_PORT(fn, pfx, sfx) \ > @@ -4310,50 +4309,14 @@ static const struct regulator_init_data sh73a0_vccq_mc0_init_data = { > * Pin bias > */ > > -#define PORTnCR_PULMD_OFF (0 << 6) > -#define PORTnCR_PULMD_DOWN (2 << 6) > -#define PORTnCR_PULMD_UP (3 << 6) > -#define PORTnCR_PULMD_MASK (3 << 6) > - > static const unsigned int sh73a0_portcr_offsets[] = { > 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, > 0x00002000, 0x00002000, 0x00003000, 0x00003000, 0x00002000, > }; > > -static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) > +static void __iomem *sh73a0_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) > { > - void __iomem *addr = pfc->windows->virt > - + sh73a0_portcr_offsets[pin >> 5] + pin; > - u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; > - > - switch (value) { > - case PORTnCR_PULMD_UP: > - return PIN_CONFIG_BIAS_PULL_UP; > - case PORTnCR_PULMD_DOWN: > - return PIN_CONFIG_BIAS_PULL_DOWN; > - case PORTnCR_PULMD_OFF: > - default: > - return PIN_CONFIG_BIAS_DISABLE; > - } > -} > - > -static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > - unsigned int bias) > -{ > - void __iomem *addr = pfc->windows->virt > - + sh73a0_portcr_offsets[pin >> 5] + pin; > - u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; > - > - switch (bias) { > - case PIN_CONFIG_BIAS_PULL_UP: > - value |= PORTnCR_PULMD_UP; > - break; > - case PIN_CONFIG_BIAS_PULL_DOWN: > - value |= PORTnCR_PULMD_DOWN; > - break; > - } > - > - iowrite8(value, addr); > + return pfc->windows->virt + sh73a0_portcr_offsets[pin >> 5] + pin; > } > > /* ----------------------------------------------------------------------------- > @@ -4383,8 +4346,9 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) > > static const struct sh_pfc_soc_operations sh73a0_pfc_ops = { > .init = sh73a0_pinmux_soc_init, > - .get_bias = sh73a0_pinmux_get_bias, > - .set_bias = sh73a0_pinmux_set_bias, > + .get_bias = rmobile_pinmux_get_bias, > + .set_bias = rmobile_pinmux_set_bias, > + .pin_to_portcr = sh73a0_pin_to_portcr, > }; > > const struct sh_pfc_soc_info sh73a0_pinmux_info = { > diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c > index 963d217b940372b9..b7ebbc877b544305 100644 > --- a/drivers/pinctrl/renesas/pinctrl.c > +++ b/drivers/pinctrl/renesas/pinctrl.c > @@ -10,6 +10,7 @@ > #include <linux/device.h> > #include <linux/err.h> > #include <linux/init.h> > +#include <linux/io.h> > #include <linux/module.h> > #include <linux/of.h> > #include <linux/pinctrl/consumer.h> > @@ -902,3 +903,42 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > > sh_pfc_write(pfc, reg->puen, enable); > } > + > +#define PORTnCR_PULMD_OFF (0 << 6) > +#define PORTnCR_PULMD_DOWN (2 << 6) > +#define PORTnCR_PULMD_UP (3 << 6) > +#define PORTnCR_PULMD_MASK (3 << 6) > + > +unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) > +{ > + void __iomem *reg = pfc->info->ops->pin_to_portcr(pfc, pin); > + u32 value = ioread8(reg) & PORTnCR_PULMD_MASK; > + > + switch (value) { > + case PORTnCR_PULMD_UP: > + return PIN_CONFIG_BIAS_PULL_UP; > + case PORTnCR_PULMD_DOWN: > + return PIN_CONFIG_BIAS_PULL_DOWN; > + case PORTnCR_PULMD_OFF: > + default: > + return PIN_CONFIG_BIAS_DISABLE; > + } > +} > + > +void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > + unsigned int bias) > +{ > + void __iomem *reg = pfc->info->ops->pin_to_portcr(pfc, pin); > + u32 value = ioread8(reg) & ~PORTnCR_PULMD_MASK; > + > + switch (bias) { > + case PIN_CONFIG_BIAS_PULL_UP: > + value |= PORTnCR_PULMD_UP; > + break; > + case PIN_CONFIG_BIAS_PULL_DOWN: > + value |= PORTnCR_PULMD_DOWN; > + break; > + } > + > + iowrite8(value, reg); > +} > diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h > index 2d511c7280fa49e3..8dc0fbb012b0c970 100644 > --- a/drivers/pinctrl/renesas/sh_pfc.h > +++ b/drivers/pinctrl/renesas/sh_pfc.h > @@ -273,6 +273,7 @@ struct sh_pfc_soc_operations { > void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, > unsigned int bias); > int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl); > + void __iomem * (*pin_to_portcr)(struct sh_pfc *pfc, unsigned int pin); > }; > > struct sh_pfc_soc_info { > @@ -780,4 +781,8 @@ unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); > void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > unsigned int bias); > > +unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); > +void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > + unsigned int bias); > + > #endif /* __SH_PFC_H */ > -- > 2.25.1 > -- Regards, Niklas Söderlund
diff --git a/drivers/pinctrl/renesas/pfc-r8a73a4.c b/drivers/pinctrl/renesas/pfc-r8a73a4.c index b21f5afe610fb430..b26ff9d6ead4bb6c 100644 --- a/drivers/pinctrl/renesas/pfc-r8a73a4.c +++ b/drivers/pinctrl/renesas/pfc-r8a73a4.c @@ -2649,59 +2649,21 @@ static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(329), /* IRQ57 */ }; -#define PORTCR_PULMD_OFF (0 << 6) -#define PORTCR_PULMD_DOWN (2 << 6) -#define PORTCR_PULMD_UP (3 << 6) -#define PORTCR_PULMD_MASK (3 << 6) - static const unsigned int r8a73a4_portcr_offsets[] = { 0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00003000, 0x00003000, }; -static unsigned int r8a73a4_pinmux_get_bias(struct sh_pfc *pfc, - unsigned int pin) -{ - void __iomem *addr; - - addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; - - switch (ioread8(addr) & PORTCR_PULMD_MASK) { - case PORTCR_PULMD_UP: - return PIN_CONFIG_BIAS_PULL_UP; - case PORTCR_PULMD_DOWN: - return PIN_CONFIG_BIAS_PULL_DOWN; - case PORTCR_PULMD_OFF: - default: - return PIN_CONFIG_BIAS_DISABLE; - } -} - -static void r8a73a4_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias) +static void __iomem *r8a73a4_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) { - void __iomem *addr; - u32 value; - - addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; - value = ioread8(addr) & ~PORTCR_PULMD_MASK; - - switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: - value |= PORTCR_PULMD_UP; - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - value |= PORTCR_PULMD_DOWN; - break; - } - - iowrite8(value, addr); + return pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin; } static const struct sh_pfc_soc_operations r8a73a4_pfc_ops = { - .get_bias = r8a73a4_pinmux_get_bias, - .set_bias = r8a73a4_pinmux_set_bias, + .get_bias = rmobile_pinmux_get_bias, + .set_bias = rmobile_pinmux_set_bias, + .pin_to_portcr = r8a73a4_pin_to_portcr, }; const struct sh_pfc_soc_info r8a73a4_pinmux_info = { diff --git a/drivers/pinctrl/renesas/pfc-r8a7740.c b/drivers/pinctrl/renesas/pfc-r8a7740.c index fdf1b0f09f57e693..4eac3899d69bc488 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7740.c +++ b/drivers/pinctrl/renesas/pfc-r8a7740.c @@ -3672,11 +3672,6 @@ static const struct pinmux_irq pinmux_irqs[] = { PINMUX_IRQ(41, 167), /* IRQ31A */ }; -#define PORTnCR_PULMD_OFF (0 << 6) -#define PORTnCR_PULMD_DOWN (2 << 6) -#define PORTnCR_PULMD_UP (3 << 6) -#define PORTnCR_PULMD_MASK (3 << 6) - struct r8a7740_portcr_group { unsigned int end_pin; unsigned int offset; @@ -3686,7 +3681,7 @@ static const struct r8a7740_portcr_group r8a7740_portcr_offsets[] = { { 83, 0x0000 }, { 114, 0x1000 }, { 209, 0x2000 }, { 211, 0x3000 }, }; -static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) +static void __iomem *r8a7740_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) { unsigned int i; @@ -3701,43 +3696,10 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) return NULL; } -static unsigned int r8a7740_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) -{ - void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin); - u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; - - switch (value) { - case PORTnCR_PULMD_UP: - return PIN_CONFIG_BIAS_PULL_UP; - case PORTnCR_PULMD_DOWN: - return PIN_CONFIG_BIAS_PULL_DOWN; - case PORTnCR_PULMD_OFF: - default: - return PIN_CONFIG_BIAS_DISABLE; - } -} - -static void r8a7740_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias) -{ - void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin); - u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; - - switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: - value |= PORTnCR_PULMD_UP; - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - value |= PORTnCR_PULMD_DOWN; - break; - } - - iowrite8(value, addr); -} - static const struct sh_pfc_soc_operations r8a7740_pfc_ops = { - .get_bias = r8a7740_pinmux_get_bias, - .set_bias = r8a7740_pinmux_set_bias, + .get_bias = rmobile_pinmux_get_bias, + .set_bias = rmobile_pinmux_set_bias, + .pin_to_portcr = r8a7740_pin_to_portcr, }; const struct sh_pfc_soc_info r8a7740_pinmux_info = { diff --git a/drivers/pinctrl/renesas/pfc-sh73a0.c b/drivers/pinctrl/renesas/pfc-sh73a0.c index 96b91e95b1e14de1..ed6db809e80de3b7 100644 --- a/drivers/pinctrl/renesas/pfc-sh73a0.c +++ b/drivers/pinctrl/renesas/pfc-sh73a0.c @@ -13,7 +13,6 @@ #include <linux/regulator/machine.h> #include <linux/slab.h> -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_PORT(fn, pfx, sfx) \ @@ -4310,50 +4309,14 @@ static const struct regulator_init_data sh73a0_vccq_mc0_init_data = { * Pin bias */ -#define PORTnCR_PULMD_OFF (0 << 6) -#define PORTnCR_PULMD_DOWN (2 << 6) -#define PORTnCR_PULMD_UP (3 << 6) -#define PORTnCR_PULMD_MASK (3 << 6) - static const unsigned int sh73a0_portcr_offsets[] = { 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00003000, 0x00003000, 0x00002000, }; -static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) +static void __iomem *sh73a0_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin) { - void __iomem *addr = pfc->windows->virt - + sh73a0_portcr_offsets[pin >> 5] + pin; - u32 value = ioread8(addr) & PORTnCR_PULMD_MASK; - - switch (value) { - case PORTnCR_PULMD_UP: - return PIN_CONFIG_BIAS_PULL_UP; - case PORTnCR_PULMD_DOWN: - return PIN_CONFIG_BIAS_PULL_DOWN; - case PORTnCR_PULMD_OFF: - default: - return PIN_CONFIG_BIAS_DISABLE; - } -} - -static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, - unsigned int bias) -{ - void __iomem *addr = pfc->windows->virt - + sh73a0_portcr_offsets[pin >> 5] + pin; - u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK; - - switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: - value |= PORTnCR_PULMD_UP; - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - value |= PORTnCR_PULMD_DOWN; - break; - } - - iowrite8(value, addr); + return pfc->windows->virt + sh73a0_portcr_offsets[pin >> 5] + pin; } /* ----------------------------------------------------------------------------- @@ -4383,8 +4346,9 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) static const struct sh_pfc_soc_operations sh73a0_pfc_ops = { .init = sh73a0_pinmux_soc_init, - .get_bias = sh73a0_pinmux_get_bias, - .set_bias = sh73a0_pinmux_set_bias, + .get_bias = rmobile_pinmux_get_bias, + .set_bias = rmobile_pinmux_set_bias, + .pin_to_portcr = sh73a0_pin_to_portcr, }; const struct sh_pfc_soc_info sh73a0_pinmux_info = { diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index 963d217b940372b9..b7ebbc877b544305 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -10,6 +10,7 @@ #include <linux/device.h> #include <linux/err.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/pinctrl/consumer.h> @@ -902,3 +903,42 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, sh_pfc_write(pfc, reg->puen, enable); } + +#define PORTnCR_PULMD_OFF (0 << 6) +#define PORTnCR_PULMD_DOWN (2 << 6) +#define PORTnCR_PULMD_UP (3 << 6) +#define PORTnCR_PULMD_MASK (3 << 6) + +unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) +{ + void __iomem *reg = pfc->info->ops->pin_to_portcr(pfc, pin); + u32 value = ioread8(reg) & PORTnCR_PULMD_MASK; + + switch (value) { + case PORTnCR_PULMD_UP: + return PIN_CONFIG_BIAS_PULL_UP; + case PORTnCR_PULMD_DOWN: + return PIN_CONFIG_BIAS_PULL_DOWN; + case PORTnCR_PULMD_OFF: + default: + return PIN_CONFIG_BIAS_DISABLE; + } +} + +void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias) +{ + void __iomem *reg = pfc->info->ops->pin_to_portcr(pfc, pin); + u32 value = ioread8(reg) & ~PORTnCR_PULMD_MASK; + + switch (bias) { + case PIN_CONFIG_BIAS_PULL_UP: + value |= PORTnCR_PULMD_UP; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + value |= PORTnCR_PULMD_DOWN; + break; + } + + iowrite8(value, reg); +} diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 2d511c7280fa49e3..8dc0fbb012b0c970 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -273,6 +273,7 @@ struct sh_pfc_soc_operations { void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl); + void __iomem * (*pin_to_portcr)(struct sh_pfc *pfc, unsigned int pin); }; struct sh_pfc_soc_info { @@ -780,4 +781,8 @@ unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); +unsigned int rmobile_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); +void rmobile_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias); + #endif /* __SH_PFC_H */
The pin control sub-drivers for SH/R-Mobile SoCs contain almost identical bias handling. The only SoC-specific part is the mapping from pin numbers to PORTnCR registers. Reduce code duplication by factoring out the bias handling to the common pinctrl.c code. Use a callback to handle the pin/register mapping. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> --- drivers/pinctrl/renesas/pfc-r8a73a4.c | 48 +++------------------------ drivers/pinctrl/renesas/pfc-r8a7740.c | 46 +++---------------------- drivers/pinctrl/renesas/pfc-sh73a0.c | 46 +++---------------------- drivers/pinctrl/renesas/pinctrl.c | 40 ++++++++++++++++++++++ drivers/pinctrl/renesas/sh_pfc.h | 5 +++ 5 files changed, 59 insertions(+), 126 deletions(-)