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

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
...@@ -21,11 +21,17 @@ ...@@ -21,11 +21,17 @@
#include "core.h" #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_chip {
struct sh_pfc *pfc; struct sh_pfc *pfc;
struct gpio_chip gpio_chip; struct gpio_chip gpio_chip;
struct sh_pfc_window *mem; 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) 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) ...@@ -38,13 +44,16 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc)
return gpio_to_pfc_chip(gc)->pfc; return gpio_to_pfc_chip(gc)->pfc;
} }
static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio, static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int gpio,
struct pinmux_data_reg **dr, unsigned int *bit) 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 reg_idx = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
+ ((gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT);
*reg = &chip->regs[reg_idx];
*bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; *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) ...@@ -91,7 +100,7 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip)
{ {
struct sh_pfc *pfc = chip->pfc; struct sh_pfc *pfc = chip->pfc;
unsigned long addr = pfc->info->data_regs[0].reg; unsigned long addr = pfc->info->data_regs[0].reg;
struct pinmux_data_reg *dreg; const struct pinmux_data_reg *dreg;
unsigned int i; unsigned int i;
/* Find the window that contain the GPIO registers. */ /* Find the window that contain the GPIO registers. */
...@@ -108,8 +117,21 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) ...@@ -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. */ /* GPIO data registers must be in the first memory resource. */
chip->mem = &pfc->window[i]; chip->mem = &pfc->window[i];
for (dreg = pfc->info->data_regs; dreg->reg; ++dreg) /* Count the number of data registers, allocate memory and initialize
dreg->reg_shadow = gpio_read_data_reg(chip, dreg); * 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++) { for (i = 0; i < pfc->info->nr_pins; i++) {
if (pfc->info->pins[i].enum_id == 0) if (pfc->info->pins[i].enum_id == 0)
...@@ -144,20 +166,20 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) ...@@ -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, static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset,
int value) int value)
{ {
struct pinmux_data_reg *dreg; struct sh_pfc_gpio_data_reg *reg;
unsigned long pos; unsigned long pos;
unsigned int bit; 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) if (value)
set_bit(pos, &dreg->reg_shadow); set_bit(pos, &reg->shadow);
else 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) 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, ...@@ -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) static int gpio_pin_get(struct gpio_chip *gc, unsigned offset)
{ {
struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc); 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 long pos;
unsigned int bit; 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) static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value)
......
...@@ -108,7 +108,7 @@ struct pinmux_cfg_reg { ...@@ -108,7 +108,7 @@ struct pinmux_cfg_reg {
.enum_ids = (pinmux_enum_t []) .enum_ids = (pinmux_enum_t [])
struct pinmux_data_reg { struct pinmux_data_reg {
unsigned long reg, reg_width, reg_shadow; unsigned long reg, reg_width;
pinmux_enum_t *enum_ids; pinmux_enum_t *enum_ids;
}; };
......
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