mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 10:57:46 +00:00
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: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
bee9f22ba1
commit
51cb226b35
2 changed files with 41 additions and 19 deletions
|
@ -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, ®, &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, ®->shadow);
|
||||
else
|
||||
clear_bit(pos, &dreg->reg_shadow);
|
||||
clear_bit(pos, ®->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, ®, &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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue