Commit acac8ed5 authored by Laurent Pinchart's avatar Laurent Pinchart

sh-pfc: Compute pin ranges automatically

Remove the manually specified ranges from PFC SoC data and compute the
ranges automatically. This prevents ranges from being out-of-sync with
pins definitions.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: default avatarYusuke Goda <yusuke.goda.sx@renesas.com>
parent 28818fa5
...@@ -82,17 +82,14 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) ...@@ -82,17 +82,14 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin)
unsigned int offset; unsigned int offset;
unsigned int i; unsigned int i;
if (pfc->info->ranges == NULL) for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) {
return pin; const struct sh_pfc_pin_range *range = &pfc->ranges[i];
for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) {
const struct pinmux_range *range = &pfc->info->ranges[i];
if (pin <= range->end) if (pin <= range->end)
return pin >= range->begin return pin >= range->start
? offset + pin - range->begin : -1; ? offset + pin - range->start : -1;
offset += range->end - range->begin + 1; offset += range->end - range->start + 1;
} }
return -EINVAL; return -EINVAL;
...@@ -341,6 +338,59 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) ...@@ -341,6 +338,59 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
return 0; return 0;
} }
static int sh_pfc_init_ranges(struct sh_pfc *pfc)
{
struct sh_pfc_pin_range *range;
unsigned int nr_ranges;
unsigned int i;
if (pfc->info->pins[0].pin == (u16)-1) {
/* Pin number -1 denotes that the SoC doesn't report pin numbers
* in its pin arrays yet. Consider the pin numbers range as
* continuous and allocate a single range.
*/
pfc->nr_ranges = 1;
pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges),
GFP_KERNEL);
if (pfc->ranges == NULL)
return -ENOMEM;
pfc->ranges->start = 0;
pfc->ranges->end = pfc->info->nr_pins - 1;
pfc->nr_gpio_pins = pfc->info->nr_pins;
return 0;
}
/* Count, allocate and fill the ranges. */
for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) {
if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1)
nr_ranges++;
}
pfc->nr_ranges = nr_ranges;
pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges) * nr_ranges,
GFP_KERNEL);
if (pfc->ranges == NULL)
return -ENOMEM;
range = pfc->ranges;
range->start = pfc->info->pins[0].pin;
for (i = 1; i < pfc->info->nr_pins; ++i) {
if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) {
range->end = pfc->info->pins[i-1].pin;
range++;
range->start = pfc->info->pins[i].pin;
}
}
range->end = pfc->info->pins[i-1].pin;
pfc->nr_gpio_pins = range->end + 1;
return 0;
}
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id sh_pfc_of_table[] = { static const struct of_device_id sh_pfc_of_table[] = {
#ifdef CONFIG_PINCTRL_PFC_R8A73A4 #ifdef CONFIG_PINCTRL_PFC_R8A73A4
...@@ -431,6 +481,10 @@ static int sh_pfc_probe(struct platform_device *pdev) ...@@ -431,6 +481,10 @@ static int sh_pfc_probe(struct platform_device *pdev)
pinctrl_provide_dummies(); pinctrl_provide_dummies();
ret = sh_pfc_init_ranges(pfc);
if (ret < 0)
return ret;
/* /*
* Initialize pinctrl bindings first * Initialize pinctrl bindings first
*/ */
......
...@@ -25,6 +25,11 @@ struct sh_pfc_window { ...@@ -25,6 +25,11 @@ struct sh_pfc_window {
struct sh_pfc_chip; struct sh_pfc_chip;
struct sh_pfc_pinctrl; struct sh_pfc_pinctrl;
struct sh_pfc_pin_range {
u16 start;
u16 end;
};
struct sh_pfc { struct sh_pfc {
struct device *dev; struct device *dev;
const struct sh_pfc_soc_info *info; const struct sh_pfc_soc_info *info;
...@@ -34,6 +39,9 @@ struct sh_pfc { ...@@ -34,6 +39,9 @@ struct sh_pfc {
unsigned int num_windows; unsigned int num_windows;
struct sh_pfc_window *window; struct sh_pfc_window *window;
struct sh_pfc_pin_range *ranges;
unsigned int nr_ranges;
unsigned int nr_gpio_pins; unsigned int nr_gpio_pins;
struct sh_pfc_chip *gpio; struct sh_pfc_chip *gpio;
......
...@@ -334,10 +334,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *), ...@@ -334,10 +334,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *),
int sh_pfc_register_gpiochip(struct sh_pfc *pfc) int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
{ {
const struct pinmux_range *ranges;
struct pinmux_range def_range;
struct sh_pfc_chip *chip; struct sh_pfc_chip *chip;
unsigned int nr_ranges;
unsigned int i; unsigned int i;
int ret; int ret;
...@@ -368,23 +365,13 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) ...@@ -368,23 +365,13 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
pfc->gpio = chip; pfc->gpio = chip;
/* Register the GPIO to pin mappings. */ /* Register the GPIO to pin mappings. */
if (pfc->info->ranges == NULL) { for (i = 0; i < pfc->nr_ranges; ++i) {
def_range.begin = 0; const struct sh_pfc_pin_range *range = &pfc->ranges[i];
def_range.end = pfc->info->nr_pins - 1;
ranges = &def_range;
nr_ranges = 1;
} else {
ranges = pfc->info->ranges;
nr_ranges = pfc->info->nr_ranges;
}
for (i = 0; i < nr_ranges; ++i) {
const struct pinmux_range *range = &ranges[i];
ret = gpiochip_add_pin_range(&chip->gpio_chip, ret = gpiochip_add_pin_range(&chip->gpio_chip,
dev_name(pfc->dev), dev_name(pfc->dev),
range->begin, range->begin, range->start, range->start,
range->end - range->begin + 1); range->end - range->start + 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
......
...@@ -1398,20 +1398,6 @@ static struct sh_pfc_pin pinmux_pins[] = { ...@@ -1398,20 +1398,6 @@ static struct sh_pfc_pin pinmux_pins[] = {
R8A73A4_PIN_IO_PU_PD(328), R8A73A4_PIN_IO_PU_PD(329), R8A73A4_PIN_IO_PU_PD(328), R8A73A4_PIN_IO_PU_PD(329),
}; };
static const struct pinmux_range pinmux_ranges[] = {
{.begin = 0, .end = 30,},
{.begin = 32, .end = 40,},
{.begin = 64, .end = 85,},
{.begin = 96, .end = 126,},
{.begin = 128, .end = 134,},
{.begin = 160, .end = 178,},
{.begin = 192, .end = 222,},
{.begin = 224, .end = 250,},
{.begin = 256, .end = 283,},
{.begin = 288, .end = 308,},
{.begin = 320, .end = 329,},
};
/* - IRQC ------------------------------------------------------------------- */ /* - IRQC ------------------------------------------------------------------- */
#define IRQC_PINS_MUX(pin, irq_mark) \ #define IRQC_PINS_MUX(pin, irq_mark) \
static const unsigned int irqc_irq##irq_mark##_pins[] = { \ static const unsigned int irqc_irq##irq_mark##_pins[] = { \
...@@ -2756,9 +2742,6 @@ const struct sh_pfc_soc_info r8a73a4_pinmux_info = { ...@@ -2756,9 +2742,6 @@ const struct sh_pfc_soc_info r8a73a4_pinmux_info = {
.pins = pinmux_pins, .pins = pinmux_pins,
.nr_pins = ARRAY_SIZE(pinmux_pins), .nr_pins = ARRAY_SIZE(pinmux_pins),
.ranges = pinmux_ranges,
.nr_ranges = ARRAY_SIZE(pinmux_ranges),
.groups = pinmux_groups, .groups = pinmux_groups,
.nr_groups = ARRAY_SIZE(pinmux_groups), .nr_groups = ARRAY_SIZE(pinmux_groups),
.functions = pinmux_functions, .functions = pinmux_functions,
......
...@@ -1446,13 +1446,6 @@ static struct sh_pfc_pin pinmux_pins[] = { ...@@ -1446,13 +1446,6 @@ static struct sh_pfc_pin pinmux_pins[] = {
SH73A0_PIN_O(309), SH73A0_PIN_O(309),
}; };
static const struct pinmux_range pinmux_ranges[] = {
{.begin = 0, .end = 118,},
{.begin = 128, .end = 164,},
{.begin = 192, .end = 282,},
{.begin = 288, .end = 309,},
};
/* Pin numbers for pins without a corresponding GPIO port number are computed /* Pin numbers for pins without a corresponding GPIO port number are computed
* from the row and column numbers with a 1000 offset to avoid collisions with * from the row and column numbers with a 1000 offset to avoid collisions with
* GPIO port numbers. * GPIO port numbers.
...@@ -3894,8 +3887,6 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = { ...@@ -3894,8 +3887,6 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = {
.pins = pinmux_pins, .pins = pinmux_pins,
.nr_pins = ARRAY_SIZE(pinmux_pins), .nr_pins = ARRAY_SIZE(pinmux_pins),
.ranges = pinmux_ranges,
.nr_ranges = ARRAY_SIZE(pinmux_ranges),
.groups = pinmux_groups, .groups = pinmux_groups,
.nr_groups = ARRAY_SIZE(pinmux_groups), .nr_groups = ARRAY_SIZE(pinmux_groups),
.functions = pinmux_functions, .functions = pinmux_functions,
......
...@@ -587,22 +587,9 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = { ...@@ -587,22 +587,9 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = {
/* PFC ranges -> pinctrl pin descs */ /* PFC ranges -> pinctrl pin descs */
static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
{ {
const struct pinmux_range *ranges;
struct pinmux_range def_range;
unsigned int nr_ranges;
unsigned int nr_pins;
unsigned int i; unsigned int i;
if (pfc->info->ranges == NULL) { /* Allocate and initialize the pins and configs arrays. */
def_range.begin = 0;
def_range.end = pfc->info->nr_pins - 1;
ranges = &def_range;
nr_ranges = 1;
} else {
ranges = pfc->info->ranges;
nr_ranges = pfc->info->nr_ranges;
}
pmx->pins = devm_kzalloc(pfc->dev, pmx->pins = devm_kzalloc(pfc->dev,
sizeof(*pmx->pins) * pfc->info->nr_pins, sizeof(*pmx->pins) * pfc->info->nr_pins,
GFP_KERNEL); GFP_KERNEL);
...@@ -615,32 +602,24 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) ...@@ -615,32 +602,24 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
if (unlikely(!pmx->configs)) if (unlikely(!pmx->configs))
return -ENOMEM; return -ENOMEM;
for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { for (i = 0; i < pfc->info->nr_pins; ++i) {
const struct pinmux_range *range = &ranges[i]; const struct sh_pfc_pin *info = &pfc->info->pins[i];
unsigned int number; struct sh_pfc_pin_config *cfg = &pmx->configs[i];
struct pinctrl_pin_desc *pin = &pmx->pins[i];
for (number = range->begin; number <= range->end; /* If the pin number is equal to -1 all pins are considered */
number++, nr_pins++) { pin->number = info->pin != (u16)-1 ? info->pin : i;
struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins]; pin->name = info->name;
struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; cfg->type = PINMUX_TYPE_NONE;
const struct sh_pfc_pin *info =
&pfc->info->pins[nr_pins];
pin->number = number;
pin->name = info->name;
cfg->type = PINMUX_TYPE_NONE;
}
} }
pfc->nr_gpio_pins = ranges[nr_ranges-1].end + 1; return 0;
return nr_ranges;
} }
int sh_pfc_register_pinctrl(struct sh_pfc *pfc) int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
{ {
struct sh_pfc_pinctrl *pmx; struct sh_pfc_pinctrl *pmx;
int nr_ranges; int ret;
pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL);
if (unlikely(!pmx)) if (unlikely(!pmx))
...@@ -649,9 +628,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) ...@@ -649,9 +628,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
pmx->pfc = pfc; pmx->pfc = pfc;
pfc->pinctrl = pmx; pfc->pinctrl = pmx;
nr_ranges = sh_pfc_map_pins(pfc, pmx); ret = sh_pfc_map_pins(pfc, pmx);
if (unlikely(nr_ranges < 0)) if (ret < 0)
return nr_ranges; return ret;
pmx->pctl_desc.name = DRV_NAME; pmx->pctl_desc.name = DRV_NAME;
pmx->pctl_desc.owner = THIS_MODULE; pmx->pctl_desc.owner = THIS_MODULE;
......
...@@ -125,8 +125,6 @@ struct sh_pfc_soc_info { ...@@ -125,8 +125,6 @@ struct sh_pfc_soc_info {
const struct sh_pfc_pin *pins; const struct sh_pfc_pin *pins;
unsigned int nr_pins; unsigned int nr_pins;
const struct pinmux_range *ranges;
unsigned int nr_ranges;
const struct sh_pfc_pin_group *groups; const struct sh_pfc_pin_group *groups;
unsigned int nr_groups; unsigned int nr_groups;
const struct sh_pfc_function *functions; const struct sh_pfc_function *functions;
......
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