Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acac8ed5 authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

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
Loading
Loading
Loading
Loading
+62 −8
Original line number Diff line number Diff line
@@ -82,17 +82,14 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin)
	unsigned int offset;
	unsigned int i;

	if (pfc->info->ranges == NULL)
		return pin;

	for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) {
		const struct pinmux_range *range = &pfc->info->ranges[i];
	for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) {
		const struct sh_pfc_pin_range *range = &pfc->ranges[i];

		if (pin <= range->end)
			return pin >= range->begin
			     ? offset + pin - range->begin : -1;
			return pin >= range->start
			     ? offset + pin - range->start : -1;

		offset += range->end - range->begin + 1;
		offset += range->end - range->start + 1;
	}

	return -EINVAL;
@@ -341,6 +338,59 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
	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
static const struct of_device_id sh_pfc_of_table[] = {
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
@@ -431,6 +481,10 @@ static int sh_pfc_probe(struct platform_device *pdev)

	pinctrl_provide_dummies();

	ret = sh_pfc_init_ranges(pfc);
	if (ret < 0)
		return ret;

	/*
	 * Initialize pinctrl bindings first
	 */
+8 −0
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@ struct sh_pfc_window {
struct sh_pfc_chip;
struct sh_pfc_pinctrl;

struct sh_pfc_pin_range {
	u16 start;
	u16 end;
};

struct sh_pfc {
	struct device *dev;
	const struct sh_pfc_soc_info *info;
@@ -34,6 +39,9 @@ struct sh_pfc {
	unsigned int num_windows;
	struct sh_pfc_window *window;

	struct sh_pfc_pin_range *ranges;
	unsigned int nr_ranges;

	unsigned int nr_gpio_pins;

	struct sh_pfc_chip *gpio;
+4 −17
Original line number Diff line number Diff line
@@ -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)
{
	const struct pinmux_range *ranges;
	struct pinmux_range def_range;
	struct sh_pfc_chip *chip;
	unsigned int nr_ranges;
	unsigned int i;
	int ret;

@@ -368,23 +365,13 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
	pfc->gpio = chip;

	/* Register the GPIO to pin mappings. */
	if (pfc->info->ranges == NULL) {
		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;
	}

	for (i = 0; i < nr_ranges; ++i) {
		const struct pinmux_range *range = &ranges[i];
	for (i = 0; i < pfc->nr_ranges; ++i) {
		const struct sh_pfc_pin_range *range = &pfc->ranges[i];

		ret = gpiochip_add_pin_range(&chip->gpio_chip,
					     dev_name(pfc->dev),
					     range->begin, range->begin,
					     range->end - range->begin + 1);
					     range->start, range->start,
					     range->end - range->start + 1);
		if (ret < 0)
			return ret;
	}
+0 −17
Original line number Diff line number Diff line
@@ -1398,20 +1398,6 @@ static struct sh_pfc_pin pinmux_pins[] = {
	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 ------------------------------------------------------------------- */
#define IRQC_PINS_MUX(pin, irq_mark)				\
static const unsigned int irqc_irq##irq_mark##_pins[] = {	\
@@ -2756,9 +2742,6 @@ const struct sh_pfc_soc_info r8a73a4_pinmux_info = {
	.pins = pinmux_pins,
	.nr_pins = ARRAY_SIZE(pinmux_pins),

	.ranges = pinmux_ranges,
	.nr_ranges = ARRAY_SIZE(pinmux_ranges),

	.groups = pinmux_groups,
	.nr_groups = ARRAY_SIZE(pinmux_groups),
	.functions = pinmux_functions,
+0 −9
Original line number Diff line number Diff line
@@ -1446,13 +1446,6 @@ static struct sh_pfc_pin pinmux_pins[] = {
	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
 * from the row and column numbers with a 1000 offset to avoid collisions with
 * GPIO port numbers.
@@ -3894,8 +3887,6 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = {

	.pins = pinmux_pins,
	.nr_pins = ARRAY_SIZE(pinmux_pins),
	.ranges = pinmux_ranges,
	.nr_ranges = ARRAY_SIZE(pinmux_ranges),
	.groups = pinmux_groups,
	.nr_groups = ARRAY_SIZE(pinmux_groups),
	.functions = pinmux_functions,
Loading