Commit ec0794a1 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven

pinctrl: renesas: Factor out common R-Mobile bias handling

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: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: default avatarNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Link: https://lore.kernel.org/r/20210303132619.3938128-4-geert+renesas@glider.be
parent 4b6e6c19
...@@ -2649,59 +2649,21 @@ static const struct pinmux_irq pinmux_irqs[] = { ...@@ -2649,59 +2649,21 @@ static const struct pinmux_irq pinmux_irqs[] = {
PINMUX_IRQ(329), /* IRQ57 */ 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[] = { static const unsigned int r8a73a4_portcr_offsets[] = {
0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000000, 0x00001000,
0x00001000, 0x00002000, 0x00002000, 0x00002000, 0x00001000, 0x00002000, 0x00002000, 0x00002000,
0x00002000, 0x00003000, 0x00003000, 0x00002000, 0x00003000, 0x00003000,
}; };
static unsigned int r8a73a4_pinmux_get_bias(struct sh_pfc *pfc, static void __iomem *r8a73a4_pin_to_portcr(struct sh_pfc *pfc, unsigned int pin)
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)
{ {
void __iomem *addr; return pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
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);
} }
static const struct sh_pfc_soc_operations r8a73a4_pfc_ops = { static const struct sh_pfc_soc_operations r8a73a4_pfc_ops = {
.get_bias = r8a73a4_pinmux_get_bias, .get_bias = rmobile_pinmux_get_bias,
.set_bias = r8a73a4_pinmux_set_bias, .set_bias = rmobile_pinmux_set_bias,
.pin_to_portcr = r8a73a4_pin_to_portcr,
}; };
const struct sh_pfc_soc_info r8a73a4_pinmux_info = { const struct sh_pfc_soc_info r8a73a4_pinmux_info = {
......
...@@ -3672,11 +3672,6 @@ static const struct pinmux_irq pinmux_irqs[] = { ...@@ -3672,11 +3672,6 @@ static const struct pinmux_irq pinmux_irqs[] = {
PINMUX_IRQ(41, 167), /* IRQ31A */ 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 { struct r8a7740_portcr_group {
unsigned int end_pin; unsigned int end_pin;
unsigned int offset; unsigned int offset;
...@@ -3686,7 +3681,7 @@ static const struct r8a7740_portcr_group r8a7740_portcr_offsets[] = { ...@@ -3686,7 +3681,7 @@ static const struct r8a7740_portcr_group r8a7740_portcr_offsets[] = {
{ 83, 0x0000 }, { 114, 0x1000 }, { 209, 0x2000 }, { 211, 0x3000 }, { 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; unsigned int i;
...@@ -3701,43 +3696,10 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) ...@@ -3701,43 +3696,10 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
return NULL; 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 = { static const struct sh_pfc_soc_operations r8a7740_pfc_ops = {
.get_bias = r8a7740_pinmux_get_bias, .get_bias = rmobile_pinmux_get_bias,
.set_bias = r8a7740_pinmux_set_bias, .set_bias = rmobile_pinmux_set_bias,
.pin_to_portcr = r8a7740_pin_to_portcr,
}; };
const struct sh_pfc_soc_info r8a7740_pinmux_info = { const struct sh_pfc_soc_info r8a7740_pinmux_info = {
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "core.h"
#include "sh_pfc.h" #include "sh_pfc.h"
#define CPU_ALL_PORT(fn, pfx, sfx) \ #define CPU_ALL_PORT(fn, pfx, sfx) \
...@@ -4310,50 +4309,14 @@ static const struct regulator_init_data sh73a0_vccq_mc0_init_data = { ...@@ -4310,50 +4309,14 @@ static const struct regulator_init_data sh73a0_vccq_mc0_init_data = {
* Pin bias * 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[] = { static const unsigned int sh73a0_portcr_offsets[] = {
0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000, 0x00000000, 0x00001000, 0x00001000, 0x00002000, 0x00002000,
0x00002000, 0x00002000, 0x00003000, 0x00003000, 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 return pfc->windows->virt + sh73a0_portcr_offsets[pin >> 5] + pin;
+ 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);
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
...@@ -4383,8 +4346,9 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc) ...@@ -4383,8 +4346,9 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
static const struct sh_pfc_soc_operations sh73a0_pfc_ops = { static const struct sh_pfc_soc_operations sh73a0_pfc_ops = {
.init = sh73a0_pinmux_soc_init, .init = sh73a0_pinmux_soc_init,
.get_bias = sh73a0_pinmux_get_bias, .get_bias = rmobile_pinmux_get_bias,
.set_bias = sh73a0_pinmux_set_bias, .set_bias = rmobile_pinmux_set_bias,
.pin_to_portcr = sh73a0_pin_to_portcr,
}; };
const struct sh_pfc_soc_info sh73a0_pinmux_info = { const struct sh_pfc_soc_info sh73a0_pinmux_info = {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
...@@ -902,3 +903,42 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, ...@@ -902,3 +903,42 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
sh_pfc_write(pfc, reg->puen, enable); 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);
}
...@@ -273,6 +273,7 @@ struct sh_pfc_soc_operations { ...@@ -273,6 +273,7 @@ struct sh_pfc_soc_operations {
void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias); unsigned int bias);
int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl); 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 { struct sh_pfc_soc_info {
...@@ -780,4 +781,8 @@ unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); ...@@ -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, void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias); 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 */ #endif /* __SH_PFC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment