diff options
Diffstat (limited to 'drivers/pinctrl/pinconf.c')
-rw-r--r-- | drivers/pinctrl/pinconf.c | 107 |
1 files changed, 79 insertions, 28 deletions
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 3f018a1cc14b..e0a453790a40 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c | |||
@@ -64,15 +64,23 @@ int pin_config_get(const char *dev_name, const char *name, | |||
64 | struct pinctrl_dev *pctldev; | 64 | struct pinctrl_dev *pctldev; |
65 | int pin; | 65 | int pin; |
66 | 66 | ||
67 | mutex_lock(&pinctrl_mutex); | ||
68 | |||
67 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 69 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
68 | if (!pctldev) | 70 | if (!pctldev) { |
69 | return -EINVAL; | 71 | pin = -EINVAL; |
72 | goto unlock; | ||
73 | } | ||
70 | 74 | ||
71 | pin = pin_get_from_name(pctldev, name); | 75 | pin = pin_get_from_name(pctldev, name); |
72 | if (pin < 0) | 76 | if (pin < 0) |
73 | return pin; | 77 | goto unlock; |
74 | 78 | ||
75 | return pin_config_get_for_pin(pctldev, pin, config); | 79 | pin = pin_config_get_for_pin(pctldev, pin, config); |
80 | |||
81 | unlock: | ||
82 | mutex_unlock(&pinctrl_mutex); | ||
83 | return pin; | ||
76 | } | 84 | } |
77 | EXPORT_SYMBOL(pin_config_get); | 85 | EXPORT_SYMBOL(pin_config_get); |
78 | 86 | ||
@@ -110,17 +118,27 @@ int pin_config_set(const char *dev_name, const char *name, | |||
110 | unsigned long config) | 118 | unsigned long config) |
111 | { | 119 | { |
112 | struct pinctrl_dev *pctldev; | 120 | struct pinctrl_dev *pctldev; |
113 | int pin; | 121 | int pin, ret; |
122 | |||
123 | mutex_lock(&pinctrl_mutex); | ||
114 | 124 | ||
115 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 125 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
116 | if (!pctldev) | 126 | if (!pctldev) { |
117 | return -EINVAL; | 127 | ret = -EINVAL; |
128 | goto unlock; | ||
129 | } | ||
118 | 130 | ||
119 | pin = pin_get_from_name(pctldev, name); | 131 | pin = pin_get_from_name(pctldev, name); |
120 | if (pin < 0) | 132 | if (pin < 0) { |
121 | return pin; | 133 | ret = pin; |
134 | goto unlock; | ||
135 | } | ||
136 | |||
137 | ret = pin_config_set_for_pin(pctldev, pin, config); | ||
122 | 138 | ||
123 | return pin_config_set_for_pin(pctldev, pin, config); | 139 | unlock: |
140 | mutex_unlock(&pinctrl_mutex); | ||
141 | return ret; | ||
124 | } | 142 | } |
125 | EXPORT_SYMBOL(pin_config_set); | 143 | EXPORT_SYMBOL(pin_config_set); |
126 | 144 | ||
@@ -129,25 +147,36 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, | |||
129 | { | 147 | { |
130 | struct pinctrl_dev *pctldev; | 148 | struct pinctrl_dev *pctldev; |
131 | const struct pinconf_ops *ops; | 149 | const struct pinconf_ops *ops; |
132 | int selector; | 150 | int selector, ret; |
151 | |||
152 | mutex_lock(&pinctrl_mutex); | ||
133 | 153 | ||
134 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 154 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
135 | if (!pctldev) | 155 | if (!pctldev) { |
136 | return -EINVAL; | 156 | ret = -EINVAL; |
157 | goto unlock; | ||
158 | } | ||
137 | ops = pctldev->desc->confops; | 159 | ops = pctldev->desc->confops; |
138 | 160 | ||
139 | if (!ops || !ops->pin_config_group_get) { | 161 | if (!ops || !ops->pin_config_group_get) { |
140 | dev_err(pctldev->dev, "cannot get configuration for pin " | 162 | dev_err(pctldev->dev, "cannot get configuration for pin " |
141 | "group, missing group config get function in " | 163 | "group, missing group config get function in " |
142 | "driver\n"); | 164 | "driver\n"); |
143 | return -EINVAL; | 165 | ret = -EINVAL; |
166 | goto unlock; | ||
144 | } | 167 | } |
145 | 168 | ||
146 | selector = pinctrl_get_group_selector(pctldev, pin_group); | 169 | selector = pinctrl_get_group_selector(pctldev, pin_group); |
147 | if (selector < 0) | 170 | if (selector < 0) { |
148 | return selector; | 171 | ret = selector; |
172 | goto unlock; | ||
173 | } | ||
149 | 174 | ||
150 | return ops->pin_config_group_get(pctldev, selector, config); | 175 | ret = ops->pin_config_group_get(pctldev, selector, config); |
176 | |||
177 | unlock: | ||
178 | mutex_unlock(&pinctrl_mutex); | ||
179 | return ret; | ||
151 | } | 180 | } |
152 | EXPORT_SYMBOL(pin_config_group_get); | 181 | EXPORT_SYMBOL(pin_config_group_get); |
153 | 182 | ||
@@ -163,27 +192,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, | |||
163 | int ret; | 192 | int ret; |
164 | int i; | 193 | int i; |
165 | 194 | ||
195 | mutex_lock(&pinctrl_mutex); | ||
196 | |||
166 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 197 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
167 | if (!pctldev) | 198 | if (!pctldev) { |
168 | return -EINVAL; | 199 | ret = -EINVAL; |
200 | goto unlock; | ||
201 | } | ||
169 | ops = pctldev->desc->confops; | 202 | ops = pctldev->desc->confops; |
170 | pctlops = pctldev->desc->pctlops; | 203 | pctlops = pctldev->desc->pctlops; |
171 | 204 | ||
172 | if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { | 205 | if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { |
173 | dev_err(pctldev->dev, "cannot configure pin group, missing " | 206 | dev_err(pctldev->dev, "cannot configure pin group, missing " |
174 | "config function in driver\n"); | 207 | "config function in driver\n"); |
175 | return -EINVAL; | 208 | ret = -EINVAL; |
209 | goto unlock; | ||
176 | } | 210 | } |
177 | 211 | ||
178 | selector = pinctrl_get_group_selector(pctldev, pin_group); | 212 | selector = pinctrl_get_group_selector(pctldev, pin_group); |
179 | if (selector < 0) | 213 | if (selector < 0) { |
180 | return selector; | 214 | ret = selector; |
215 | goto unlock; | ||
216 | } | ||
181 | 217 | ||
182 | ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); | 218 | ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); |
183 | if (ret) { | 219 | if (ret) { |
184 | dev_err(pctldev->dev, "cannot configure pin group, error " | 220 | dev_err(pctldev->dev, "cannot configure pin group, error " |
185 | "getting pins\n"); | 221 | "getting pins\n"); |
186 | return ret; | 222 | goto unlock; |
187 | } | 223 | } |
188 | 224 | ||
189 | /* | 225 | /* |
@@ -197,23 +233,30 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, | |||
197 | * pin-by-pin as well, it returns -EAGAIN. | 233 | * pin-by-pin as well, it returns -EAGAIN. |
198 | */ | 234 | */ |
199 | if (ret != -EAGAIN) | 235 | if (ret != -EAGAIN) |
200 | return ret; | 236 | goto unlock; |
201 | } | 237 | } |
202 | 238 | ||
203 | /* | 239 | /* |
204 | * If the controller cannot handle entire groups, we configure each pin | 240 | * If the controller cannot handle entire groups, we configure each pin |
205 | * individually. | 241 | * individually. |
206 | */ | 242 | */ |
207 | if (!ops->pin_config_set) | 243 | if (!ops->pin_config_set) { |
208 | return 0; | 244 | ret = 0; |
245 | goto unlock; | ||
246 | } | ||
209 | 247 | ||
210 | for (i = 0; i < num_pins; i++) { | 248 | for (i = 0; i < num_pins; i++) { |
211 | ret = ops->pin_config_set(pctldev, pins[i], config); | 249 | ret = ops->pin_config_set(pctldev, pins[i], config); |
212 | if (ret < 0) | 250 | if (ret < 0) |
213 | return ret; | 251 | goto unlock; |
214 | } | 252 | } |
215 | 253 | ||
216 | return 0; | 254 | ret = 0; |
255 | |||
256 | unlock: | ||
257 | mutex_unlock(&pinctrl_mutex); | ||
258 | |||
259 | return ret; | ||
217 | } | 260 | } |
218 | EXPORT_SYMBOL(pin_config_group_set); | 261 | EXPORT_SYMBOL(pin_config_group_set); |
219 | 262 | ||
@@ -236,6 +279,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) | |||
236 | seq_puts(s, "Pin config settings per pin\n"); | 279 | seq_puts(s, "Pin config settings per pin\n"); |
237 | seq_puts(s, "Format: pin (name): pinmux setting array\n"); | 280 | seq_puts(s, "Format: pin (name): pinmux setting array\n"); |
238 | 281 | ||
282 | mutex_lock(&pinctrl_mutex); | ||
283 | |||
239 | /* The pin number can be retrived from the pin controller descriptor */ | 284 | /* The pin number can be retrived from the pin controller descriptor */ |
240 | for (i = 0; i < pctldev->desc->npins; i++) { | 285 | for (i = 0; i < pctldev->desc->npins; i++) { |
241 | struct pin_desc *desc; | 286 | struct pin_desc *desc; |
@@ -254,6 +299,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) | |||
254 | seq_printf(s, "\n"); | 299 | seq_printf(s, "\n"); |
255 | } | 300 | } |
256 | 301 | ||
302 | mutex_unlock(&pinctrl_mutex); | ||
303 | |||
257 | return 0; | 304 | return 0; |
258 | } | 305 | } |
259 | 306 | ||
@@ -280,6 +327,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) | |||
280 | seq_puts(s, "Pin config settings per pin group\n"); | 327 | seq_puts(s, "Pin config settings per pin group\n"); |
281 | seq_puts(s, "Format: group (name): pinmux setting array\n"); | 328 | seq_puts(s, "Format: group (name): pinmux setting array\n"); |
282 | 329 | ||
330 | mutex_lock(&pinctrl_mutex); | ||
331 | |||
283 | while (pctlops->list_groups(pctldev, selector) >= 0) { | 332 | while (pctlops->list_groups(pctldev, selector) >= 0) { |
284 | const char *gname = pctlops->get_group_name(pctldev, selector); | 333 | const char *gname = pctlops->get_group_name(pctldev, selector); |
285 | 334 | ||
@@ -290,6 +339,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) | |||
290 | selector++; | 339 | selector++; |
291 | } | 340 | } |
292 | 341 | ||
342 | mutex_unlock(&pinctrl_mutex); | ||
343 | |||
293 | return 0; | 344 | return 0; |
294 | } | 345 | } |
295 | 346 | ||