aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorTony Prisk <linux@prisktech.co.nz>2013-01-17 23:58:22 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-02-11 17:21:29 -0500
commit9f01d30ee191a74f1e7a2ac0710f064f472d000a (patch)
tree7be3599e3068977c27a1cb0052d38f0fdb895f2f /drivers/gpio
parent362432aed5e5b497a8cf7b20c268ba71df93c045 (diff)
gpio/vt8500: memory cleanup missing
This driver is missing a .remove callback, and the fail path on probe is incomplete. If an error occurs in vt8500_add_chips, gpio_base is not unmapped. The driver is also ignoring the return value from this function so if a chip fails to register it completes as successful. Replaced pr_err with dev_err in vt8500_add_chips since the device is available. There is also no .remove callback defined so the function is added. Signed-off-by: Tony Prisk <linux@prisktech.co.nz> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-vt8500.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c
index 9a7c434d2947..81683ca35ac1 100644
--- a/drivers/gpio/gpio-vt8500.c
+++ b/drivers/gpio/gpio-vt8500.c
@@ -127,6 +127,12 @@ struct vt8500_gpio_chip {
127 void __iomem *base; 127 void __iomem *base;
128}; 128};
129 129
130struct vt8500_data {
131 struct vt8500_gpio_chip *chip;
132 void __iomem *iobase;
133 int num_banks;
134};
135
130 136
131#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip) 137#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
132 138
@@ -224,19 +230,32 @@ static int vt8500_of_xlate(struct gpio_chip *gc,
224static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base, 230static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base,
225 const struct vt8500_gpio_data *data) 231 const struct vt8500_gpio_data *data)
226{ 232{
233 struct vt8500_data *priv;
227 struct vt8500_gpio_chip *vtchip; 234 struct vt8500_gpio_chip *vtchip;
228 struct gpio_chip *chip; 235 struct gpio_chip *chip;
229 int i; 236 int i;
230 int pin_cnt = 0; 237 int pin_cnt = 0;
231 238
232 vtchip = devm_kzalloc(&pdev->dev, 239 priv = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_data), GFP_KERNEL);
240 if (!priv) {
241 dev_err(&pdev->dev, "failed to allocate memory\n");
242 return -ENOMEM;
243 }
244
245 priv->chip = devm_kzalloc(&pdev->dev,
233 sizeof(struct vt8500_gpio_chip) * data->num_banks, 246 sizeof(struct vt8500_gpio_chip) * data->num_banks,
234 GFP_KERNEL); 247 GFP_KERNEL);
235 if (!vtchip) { 248 if (!priv->chip) {
236 pr_err("%s: failed to allocate chip memory\n", __func__); 249 dev_err(&pdev->dev, "failed to allocate chip memory\n");
237 return -ENOMEM; 250 return -ENOMEM;
238 } 251 }
239 252
253 priv->iobase = base;
254 priv->num_banks = data->num_banks;
255 platform_set_drvdata(pdev, priv);
256
257 vtchip = priv->chip;
258
240 for (i = 0; i < data->num_banks; i++) { 259 for (i = 0; i < data->num_banks; i++) {
241 vtchip[i].base = base; 260 vtchip[i].base = base;
242 vtchip[i].regs = &data->banks[i]; 261 vtchip[i].regs = &data->banks[i];
@@ -273,36 +292,54 @@ static struct of_device_id vt8500_gpio_dt_ids[] = {
273 292
274static int vt8500_gpio_probe(struct platform_device *pdev) 293static int vt8500_gpio_probe(struct platform_device *pdev)
275{ 294{
295 int ret;
276 void __iomem *gpio_base; 296 void __iomem *gpio_base;
277 struct device_node *np; 297 struct resource *res;
278 const struct of_device_id *of_id = 298 const struct of_device_id *of_id =
279 of_match_device(vt8500_gpio_dt_ids, &pdev->dev); 299 of_match_device(vt8500_gpio_dt_ids, &pdev->dev);
280 300
281 if (!of_id) { 301 if (!of_id) {
282 dev_err(&pdev->dev, "Failed to find gpio controller\n"); 302 dev_err(&pdev->dev, "No matching driver data\n");
283 return -ENODEV; 303 return -ENODEV;
284 } 304 }
285 305
286 np = pdev->dev.of_node; 306 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
287 if (!np) { 307 if (!res) {
288 dev_err(&pdev->dev, "Missing GPIO description in devicetree\n"); 308 dev_err(&pdev->dev, "Unable to get IO resource\n");
289 return -EFAULT; 309 return -ENODEV;
290 } 310 }
291 311
292 gpio_base = of_iomap(np, 0); 312 gpio_base = devm_request_and_ioremap(&pdev->dev, res);
293 if (!gpio_base) { 313 if (!gpio_base) {
294 dev_err(&pdev->dev, "Unable to map GPIO registers\n"); 314 dev_err(&pdev->dev, "Unable to map GPIO registers\n");
295 of_node_put(np);
296 return -ENOMEM; 315 return -ENOMEM;
297 } 316 }
298 317
299 vt8500_add_chips(pdev, gpio_base, of_id->data); 318 ret = vt8500_add_chips(pdev, gpio_base, of_id->data);
319
320 return ret;
321}
322
323static int vt8500_gpio_remove(struct platform_device *pdev)
324{
325 int i;
326 int ret;
327 struct vt8500_data *priv = platform_get_drvdata(pdev);
328 struct vt8500_gpio_chip *vtchip = priv->chip;
329
330 for (i = 0; i < priv->num_banks; i++) {
331 ret = gpiochip_remove(&vtchip[i].chip);
332 if (ret)
333 dev_warn(&pdev->dev, "gpiochip_remove returned %d\n",
334 ret);
335 }
300 336
301 return 0; 337 return 0;
302} 338}
303 339
304static struct platform_driver vt8500_gpio_driver = { 340static struct platform_driver vt8500_gpio_driver = {
305 .probe = vt8500_gpio_probe, 341 .probe = vt8500_gpio_probe,
342 .remove = vt8500_gpio_remove,
306 .driver = { 343 .driver = {
307 .name = "vt8500-gpio", 344 .name = "vt8500-gpio",
308 .owner = THIS_MODULE, 345 .owner = THIS_MODULE,