diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-10 12:25:29 -0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-15 08:33:54 -0400 |
commit | 9fddc4a589c6d1bd9c935d445b1a1d216b1457ab (patch) | |
tree | 7d2c00beb3508a6502384ae9b7051712f3918f8f | |
parent | 0d00f00a1077ae89fb0ecbbba8da4c2c6bc93446 (diff) |
sh-pfc: Clean up pin configuration type handling
Set pin configuration type to
- PINMUX_TYPE_NONE at initialization time and when disabling a function
or freeing a GPIO
- PINMUX_TYPE_FUNCTION when enabling a function
- PINMUX_TYPE_INPUT or PINMUX_TYPE_OUTPUT when setting the GPIO
direction
Verify that the type is PINMUX_TYPE_NONE when enabling a function or
requesting a GPIO and return -EBUSY if it isn't.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 36f08f826a5e..82e4fb21853e 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c | |||
@@ -121,11 +121,22 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, | |||
121 | spin_lock_irqsave(&pfc->lock, flags); | 121 | spin_lock_irqsave(&pfc->lock, flags); |
122 | 122 | ||
123 | for (i = 0; i < grp->nr_pins; ++i) { | 123 | for (i = 0; i < grp->nr_pins; ++i) { |
124 | int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); | ||
125 | struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; | ||
126 | |||
127 | if (cfg->type != PINMUX_TYPE_NONE) { | ||
128 | ret = -EBUSY; | ||
129 | goto done; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | for (i = 0; i < grp->nr_pins; ++i) { | ||
124 | ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); | 134 | ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); |
125 | if (ret < 0) | 135 | if (ret < 0) |
126 | break; | 136 | break; |
127 | } | 137 | } |
128 | 138 | ||
139 | done: | ||
129 | spin_unlock_irqrestore(&pfc->lock, flags); | 140 | spin_unlock_irqrestore(&pfc->lock, flags); |
130 | return ret; | 141 | return ret; |
131 | } | 142 | } |
@@ -133,6 +144,22 @@ static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, | |||
133 | static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, | 144 | static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, |
134 | unsigned group) | 145 | unsigned group) |
135 | { | 146 | { |
147 | struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); | ||
148 | struct sh_pfc *pfc = pmx->pfc; | ||
149 | const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; | ||
150 | unsigned long flags; | ||
151 | unsigned int i; | ||
152 | |||
153 | spin_lock_irqsave(&pfc->lock, flags); | ||
154 | |||
155 | for (i = 0; i < grp->nr_pins; ++i) { | ||
156 | int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); | ||
157 | struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; | ||
158 | |||
159 | cfg->type = PINMUX_TYPE_NONE; | ||
160 | } | ||
161 | |||
162 | spin_unlock_irqrestore(&pfc->lock, flags); | ||
136 | } | 163 | } |
137 | 164 | ||
138 | static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, | 165 | static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, |
@@ -148,21 +175,17 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
148 | 175 | ||
149 | spin_lock_irqsave(&pfc->lock, flags); | 176 | spin_lock_irqsave(&pfc->lock, flags); |
150 | 177 | ||
151 | switch (cfg->type) { | 178 | if (cfg->type != PINMUX_TYPE_NONE) { |
152 | case PINMUX_TYPE_GPIO: | 179 | pr_err("Pin %u is busy, can't configure it as GPIO.\n", offset); |
153 | case PINMUX_TYPE_INPUT: | 180 | ret = -EBUSY; |
154 | case PINMUX_TYPE_OUTPUT: | 181 | goto done; |
155 | break; | ||
156 | case PINMUX_TYPE_FUNCTION: | ||
157 | default: | ||
158 | pr_err("Unsupported mux type (%d), bailing...\n", cfg->type); | ||
159 | ret = -ENOTSUPP; | ||
160 | goto err; | ||
161 | } | 182 | } |
162 | 183 | ||
184 | cfg->type = PINMUX_TYPE_GPIO; | ||
185 | |||
163 | ret = 0; | 186 | ret = 0; |
164 | 187 | ||
165 | err: | 188 | done: |
166 | spin_unlock_irqrestore(&pfc->lock, flags); | 189 | spin_unlock_irqrestore(&pfc->lock, flags); |
167 | 190 | ||
168 | return ret; | 191 | return ret; |
@@ -172,6 +195,15 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, | |||
172 | struct pinctrl_gpio_range *range, | 195 | struct pinctrl_gpio_range *range, |
173 | unsigned offset) | 196 | unsigned offset) |
174 | { | 197 | { |
198 | struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); | ||
199 | struct sh_pfc *pfc = pmx->pfc; | ||
200 | int idx = sh_pfc_get_pin_index(pfc, offset); | ||
201 | struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; | ||
202 | unsigned long flags; | ||
203 | |||
204 | spin_lock_irqsave(&pfc->lock, flags); | ||
205 | cfg->type = PINMUX_TYPE_NONE; | ||
206 | spin_unlock_irqrestore(&pfc->lock, flags); | ||
175 | } | 207 | } |
176 | 208 | ||
177 | static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, | 209 | static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, |
@@ -182,27 +214,14 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
182 | struct sh_pfc *pfc = pmx->pfc; | 214 | struct sh_pfc *pfc = pmx->pfc; |
183 | int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; | 215 | int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; |
184 | int idx = sh_pfc_get_pin_index(pfc, offset); | 216 | int idx = sh_pfc_get_pin_index(pfc, offset); |
185 | struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; | ||
186 | const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; | 217 | const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; |
187 | unsigned int mark = pin->enum_id; | 218 | struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; |
188 | unsigned long flags; | 219 | unsigned long flags; |
189 | int ret; | 220 | int ret; |
190 | 221 | ||
191 | spin_lock_irqsave(&pfc->lock, flags); | 222 | spin_lock_irqsave(&pfc->lock, flags); |
192 | 223 | ||
193 | switch (cfg->type) { | 224 | ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type); |
194 | case PINMUX_TYPE_GPIO: | ||
195 | case PINMUX_TYPE_OUTPUT: | ||
196 | case PINMUX_TYPE_INPUT: | ||
197 | case PINMUX_TYPE_INPUT_PULLUP: | ||
198 | case PINMUX_TYPE_INPUT_PULLDOWN: | ||
199 | break; | ||
200 | default: | ||
201 | ret = -EINVAL; | ||
202 | goto done; | ||
203 | } | ||
204 | |||
205 | ret = sh_pfc_config_mux(pfc, mark, new_type); | ||
206 | if (ret < 0) | 225 | if (ret < 0) |
207 | goto done; | 226 | goto done; |
208 | 227 | ||
@@ -210,7 +229,6 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, | |||
210 | 229 | ||
211 | done: | 230 | done: |
212 | spin_unlock_irqrestore(&pfc->lock, flags); | 231 | spin_unlock_irqrestore(&pfc->lock, flags); |
213 | |||
214 | return ret; | 232 | return ret; |
215 | } | 233 | } |
216 | 234 | ||
@@ -383,7 +401,7 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) | |||
383 | 401 | ||
384 | pin->number = number; | 402 | pin->number = number; |
385 | pin->name = info->name; | 403 | pin->name = info->name; |
386 | cfg->type = PINMUX_TYPE_GPIO; | 404 | cfg->type = PINMUX_TYPE_NONE; |
387 | } | 405 | } |
388 | } | 406 | } |
389 | 407 | ||