diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-02-14 20:04:55 -0500 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-15 08:33:52 -0400 |
commit | 41f1219fae987f97787677d3a91c2f33ca9bab98 (patch) | |
tree | 67bb0a15d45ae5100395a3c5248ebee10d5cdd8b /drivers/pinctrl/sh-pfc/gpio.c | |
parent | fd9d05b0fdb0a8a2bbe2451b9e520547813d0562 (diff) |
sh-pfc: Move GPIO registers access functions to gpio.c
Move the sh_pfc_setup_data_regs(), sh_pfc_setup_data_reg(),
sh_pfc_get_data_reg(), sh_pfc_read_bit() and sh_pfc_write_bit()
function to gpio.c as they belong to the GPIO implementation. Inline
sh_pfc_read_bit() and sh_pfc_write_bit() in their only call location.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/sh-pfc/gpio.c')
-rw-r--r-- | drivers/pinctrl/sh-pfc/gpio.c | 92 |
1 files changed, 86 insertions, 6 deletions
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 806e2dd62137..027c77762d8f 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c | |||
@@ -36,6 +36,71 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) | |||
36 | return gpio_to_pfc_chip(gc)->pfc; | 36 | return gpio_to_pfc_chip(gc)->pfc; |
37 | } | 37 | } |
38 | 38 | ||
39 | static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio, | ||
40 | struct pinmux_data_reg **dr, unsigned int *bit) | ||
41 | { | ||
42 | struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio); | ||
43 | |||
44 | *dr = pfc->info->data_regs | ||
45 | + ((gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT); | ||
46 | *bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; | ||
47 | } | ||
48 | |||
49 | static void gpio_setup_data_reg(struct sh_pfc *pfc, unsigned gpio) | ||
50 | { | ||
51 | struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio]; | ||
52 | struct pinmux_data_reg *data_reg; | ||
53 | int k, n; | ||
54 | |||
55 | k = 0; | ||
56 | while (1) { | ||
57 | data_reg = pfc->info->data_regs + k; | ||
58 | |||
59 | if (!data_reg->reg_width) | ||
60 | break; | ||
61 | |||
62 | data_reg->mapped_reg = sh_pfc_phys_to_virt(pfc, data_reg->reg); | ||
63 | |||
64 | for (n = 0; n < data_reg->reg_width; n++) { | ||
65 | if (data_reg->enum_ids[n] == gpiop->enum_id) { | ||
66 | gpiop->flags &= ~PINMUX_FLAG_DREG; | ||
67 | gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT); | ||
68 | gpiop->flags &= ~PINMUX_FLAG_DBIT; | ||
69 | gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT); | ||
70 | return; | ||
71 | } | ||
72 | } | ||
73 | k++; | ||
74 | } | ||
75 | |||
76 | BUG(); | ||
77 | } | ||
78 | |||
79 | static void gpio_setup_data_regs(struct sh_pfc *pfc) | ||
80 | { | ||
81 | struct pinmux_data_reg *drp; | ||
82 | int k; | ||
83 | |||
84 | for (k = 0; k < pfc->info->nr_pins; k++) { | ||
85 | if (pfc->info->pins[k].enum_id == 0) | ||
86 | continue; | ||
87 | |||
88 | gpio_setup_data_reg(pfc, k); | ||
89 | } | ||
90 | |||
91 | k = 0; | ||
92 | while (1) { | ||
93 | drp = pfc->info->data_regs + k; | ||
94 | |||
95 | if (!drp->reg_width) | ||
96 | break; | ||
97 | |||
98 | drp->reg_shadow = sh_pfc_read_raw_reg(drp->mapped_reg, | ||
99 | drp->reg_width); | ||
100 | k++; | ||
101 | } | ||
102 | } | ||
103 | |||
39 | /* ----------------------------------------------------------------------------- | 104 | /* ----------------------------------------------------------------------------- |
40 | * Pin GPIOs | 105 | * Pin GPIOs |
41 | */ | 106 | */ |
@@ -59,10 +124,19 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) | |||
59 | static void gpio_pin_set_value(struct sh_pfc *pfc, unsigned offset, int value) | 124 | static void gpio_pin_set_value(struct sh_pfc *pfc, unsigned offset, int value) |
60 | { | 125 | { |
61 | struct pinmux_data_reg *dr; | 126 | struct pinmux_data_reg *dr; |
62 | int bit; | 127 | unsigned long pos; |
128 | unsigned int bit; | ||
63 | 129 | ||
64 | sh_pfc_get_data_reg(pfc, offset, &dr, &bit); | 130 | gpio_get_data_reg(pfc, offset, &dr, &bit); |
65 | sh_pfc_write_bit(dr, bit, value); | 131 | |
132 | pos = dr->reg_width - (bit + 1); | ||
133 | |||
134 | if (value) | ||
135 | set_bit(pos, &dr->reg_shadow); | ||
136 | else | ||
137 | clear_bit(pos, &dr->reg_shadow); | ||
138 | |||
139 | sh_pfc_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow); | ||
66 | } | 140 | } |
67 | 141 | ||
68 | static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) | 142 | static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) |
@@ -82,10 +156,14 @@ static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) | |||
82 | { | 156 | { |
83 | struct sh_pfc *pfc = gpio_to_pfc(gc); | 157 | struct sh_pfc *pfc = gpio_to_pfc(gc); |
84 | struct pinmux_data_reg *dr; | 158 | struct pinmux_data_reg *dr; |
85 | int bit; | 159 | unsigned long pos; |
160 | unsigned int bit; | ||
86 | 161 | ||
87 | sh_pfc_get_data_reg(pfc, offset, &dr, &bit); | 162 | gpio_get_data_reg(pfc, offset, &dr, &bit); |
88 | return sh_pfc_read_bit(dr, bit); | 163 | |
164 | pos = dr->reg_width - (bit + 1); | ||
165 | |||
166 | return (sh_pfc_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1; | ||
89 | } | 167 | } |
90 | 168 | ||
91 | static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) | 169 | static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) |
@@ -226,6 +304,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | |||
226 | unsigned int i; | 304 | unsigned int i; |
227 | int ret; | 305 | int ret; |
228 | 306 | ||
307 | gpio_setup_data_regs(pfc); | ||
308 | |||
229 | /* Register the real GPIOs chip. */ | 309 | /* Register the real GPIOs chip. */ |
230 | chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); | 310 | chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup); |
231 | if (IS_ERR(chip)) | 311 | if (IS_ERR(chip)) |