Commit 9f01d30ee191a74f1e7a2ac0710f064f472d000a

Authored by Tony Prisk
Committed by Grant Likely
1 parent 362432aed5

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>

Showing 1 changed file with 49 additions and 12 deletions Side-by-side Diff

drivers/gpio/gpio-vt8500.c
... ... @@ -127,7 +127,13 @@
127 127 void __iomem *base;
128 128 };
129 129  
  130 +struct vt8500_data {
  131 + struct vt8500_gpio_chip *chip;
  132 + void __iomem *iobase;
  133 + int num_banks;
  134 +};
130 135  
  136 +
131 137 #define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
132 138  
133 139 static int vt8500_gpio_request(struct gpio_chip *chip, unsigned offset)
134 140  
135 141  
136 142  
... ... @@ -224,19 +230,32 @@
224 230 static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base,
225 231 const struct vt8500_gpio_data *data)
226 232 {
  233 + struct vt8500_data *priv;
227 234 struct vt8500_gpio_chip *vtchip;
228 235 struct gpio_chip *chip;
229 236 int i;
230 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 246 sizeof(struct vt8500_gpio_chip) * data->num_banks,
234 247 GFP_KERNEL);
235   - if (!vtchip) {
236   - pr_err("%s: failed to allocate chip memory\n", __func__);
  248 + if (!priv->chip) {
  249 + dev_err(&pdev->dev, "failed to allocate chip memory\n");
237 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 259 for (i = 0; i < data->num_banks; i++) {
241 260 vtchip[i].base = base;
242 261 vtchip[i].regs = &data->banks[i];
243 262  
244 263  
245 264  
246 265  
247 266  
248 267  
249 268  
250 269  
... ... @@ -273,36 +292,54 @@
273 292  
274 293 static int vt8500_gpio_probe(struct platform_device *pdev)
275 294 {
  295 + int ret;
276 296 void __iomem *gpio_base;
277   - struct device_node *np;
  297 + struct resource *res;
278 298 const struct of_device_id *of_id =
279 299 of_match_device(vt8500_gpio_dt_ids, &pdev->dev);
280 300  
281 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 303 return -ENODEV;
284 304 }
285 305  
286   - np = pdev->dev.of_node;
287   - if (!np) {
288   - dev_err(&pdev->dev, "Missing GPIO description in devicetree\n");
289   - return -EFAULT;
  306 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  307 + if (!res) {
  308 + dev_err(&pdev->dev, "Unable to get IO resource\n");
  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 313 if (!gpio_base) {
294 314 dev_err(&pdev->dev, "Unable to map GPIO registers\n");
295   - of_node_put(np);
296 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);
300 319  
  320 + return ret;
  321 +}
  322 +
  323 +static 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 + }
  336 +
301 337 return 0;
302 338 }
303 339  
304 340 static struct platform_driver vt8500_gpio_driver = {
305 341 .probe = vt8500_gpio_probe,
  342 + .remove = vt8500_gpio_remove,
306 343 .driver = {
307 344 .name = "vt8500-gpio",
308 345 .owner = THIS_MODULE,