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

Commit 51cb226b authored by Laurent Pinchart's avatar Laurent Pinchart
Browse files

sh-pfc: Don't modify pinmux_data_reg SoC data



The pinmux_data_reg structure supplied in SoC data contains information
about data registers. It's abused to store per-device mapped iomem and
shadow values. Move those fields out of the pinmux_data_reg structure
into the per-device sh_pfc_chip structure.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent bee9f22b
Loading
Loading
Loading
Loading
+40 −18
Original line number Diff line number Diff line
@@ -21,11 +21,17 @@

#include "core.h"

struct sh_pfc_gpio_data_reg {
	const struct pinmux_data_reg *info;
	unsigned long shadow;
};

struct sh_pfc_chip {
	struct sh_pfc		*pfc;
	struct gpio_chip	gpio_chip;

	struct sh_pfc_window	*mem;
	struct sh_pfc_gpio_data_reg	*regs;
};

static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc)
@@ -38,13 +44,16 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc)
	return gpio_to_pfc_chip(gc)->pfc;
}

static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio,
			      struct pinmux_data_reg **dr, unsigned int *bit)
static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int gpio,
			      struct sh_pfc_gpio_data_reg **reg,
			      unsigned int *bit)
{
	struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio);
	struct sh_pfc_pin *gpiop = sh_pfc_get_pin(chip->pfc, gpio);
	unsigned int reg_idx;

	*dr = pfc->info->data_regs
	    + ((gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT);
	reg_idx = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;

	*reg = &chip->regs[reg_idx];
	*bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
}

@@ -91,7 +100,7 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip)
{
	struct sh_pfc *pfc = chip->pfc;
	unsigned long addr = pfc->info->data_regs[0].reg;
	struct pinmux_data_reg *dreg;
	const struct pinmux_data_reg *dreg;
	unsigned int i;

	/* Find the window that contain the GPIO registers. */
@@ -108,8 +117,21 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip)
	/* GPIO data registers must be in the first memory resource. */
	chip->mem = &pfc->window[i];

	for (dreg = pfc->info->data_regs; dreg->reg; ++dreg)
		dreg->reg_shadow = gpio_read_data_reg(chip, dreg);
	/* Count the number of data registers, allocate memory and initialize
	 * them.
	 */
	for (i = 0; pfc->info->data_regs[i].reg_width; ++i)
		;

	chip->regs = devm_kzalloc(pfc->dev, i * sizeof(*chip->regs),
				  GFP_KERNEL);
	if (chip->regs == NULL)
		return -ENOMEM;

	for (i = 0, dreg = pfc->info->data_regs; dreg->reg_width; ++i, ++dreg) {
		chip->regs[i].info = dreg;
		chip->regs[i].shadow = gpio_read_data_reg(chip, dreg);
	}

	for (i = 0; i < pfc->info->nr_pins; i++) {
		if (pfc->info->pins[i].enum_id == 0)
@@ -144,20 +166,20 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset)
static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset,
			       int value)
{
	struct pinmux_data_reg *dreg;
	struct sh_pfc_gpio_data_reg *reg;
	unsigned long pos;
	unsigned int bit;

	gpio_get_data_reg(chip->pfc, offset, &dreg, &bit);
	gpio_get_data_reg(chip, offset, &reg, &bit);

	pos = dreg->reg_width - (bit + 1);
	pos = reg->info->reg_width - (bit + 1);

	if (value)
		set_bit(pos, &dreg->reg_shadow);
		set_bit(pos, &reg->shadow);
	else
		clear_bit(pos, &dreg->reg_shadow);
		clear_bit(pos, &reg->shadow);

	gpio_write_data_reg(chip, dreg, dreg->reg_shadow);
	gpio_write_data_reg(chip, reg->info, reg->shadow);
}

static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset)
@@ -176,15 +198,15 @@ static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset,
static int gpio_pin_get(struct gpio_chip *gc, unsigned offset)
{
	struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc);
	struct pinmux_data_reg *dreg;
	struct sh_pfc_gpio_data_reg *reg;
	unsigned long pos;
	unsigned int bit;

	gpio_get_data_reg(chip->pfc, offset, &dreg, &bit);
	gpio_get_data_reg(chip, offset, &reg, &bit);

	pos = dreg->reg_width - (bit + 1);
	pos = reg->info->reg_width - (bit + 1);

	return (gpio_read_data_reg(chip, dreg) >> pos) & 1;
	return (gpio_read_data_reg(chip, reg->info) >> pos) & 1;
}

static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value)
+1 −1
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ struct pinmux_cfg_reg {
	.enum_ids = (pinmux_enum_t [])

struct pinmux_data_reg {
	unsigned long reg, reg_width, reg_shadow;
	unsigned long reg, reg_width;
	pinmux_enum_t *enum_ids;
};