Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: ml-ioh: Convert to use managed functions pcim* and devm_*

When removing the module, we will get the following flaw:

[ 14.204955] remove_proc_entry: removing non-empty directory 'irq/21', leaking at least 'gpio_ml_ioh'
[ 14.205827] WARNING: CPU: 0 PID: 305 at fs/proc/generic.c:717 remove_proc_entry+0x389/0x3f0
...
[ 14.220613] ioh_gpio_remove+0xc5/0xe0 [gpio_ml_ioh]
[ 14.221075] pci_device_remove+0x92/0x240

Fix this by using managed functions, this makes the error handling more
simpler.

Fixes: e971ac9a564a ("gpio: ml-ioh: use resource management for irqs")
Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>

authored by

Zheyu Ma and committed by
Bartosz Golaszewski
7869b481 a998ec3d

+16 -60
+16 -60
drivers/gpio/gpio-ml-ioh.c
··· 409 409 void *chip_save; 410 410 int irq_base; 411 411 412 - ret = pci_enable_device(pdev); 412 + ret = pcim_enable_device(pdev); 413 413 if (ret) { 414 - dev_err(dev, "%s : pci_enable_device failed", __func__); 415 - goto err_pci_enable; 414 + dev_err(dev, "%s : pcim_enable_device failed", __func__); 415 + return ret; 416 416 } 417 417 418 - ret = pci_request_regions(pdev, KBUILD_MODNAME); 418 + ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME); 419 419 if (ret) { 420 - dev_err(dev, "pci_request_regions failed-%d", ret); 421 - goto err_request_regions; 420 + dev_err(dev, "pcim_iomap_regions failed-%d", ret); 421 + return ret; 422 422 } 423 423 424 - base = pci_iomap(pdev, 1, 0); 424 + base = pcim_iomap_table(pdev)[1]; 425 425 if (!base) { 426 - dev_err(dev, "%s : pci_iomap failed", __func__); 427 - ret = -ENOMEM; 428 - goto err_iomap; 426 + dev_err(dev, "%s : pcim_iomap_table failed", __func__); 427 + return -ENOMEM; 429 428 } 430 429 431 - chip_save = kcalloc(8, sizeof(*chip), GFP_KERNEL); 430 + chip_save = devm_kcalloc(dev, 8, sizeof(*chip), GFP_KERNEL); 432 431 if (chip_save == NULL) { 433 - ret = -ENOMEM; 434 - goto err_kzalloc; 432 + return -ENOMEM; 435 433 } 436 434 437 435 chip = chip_save; ··· 440 442 chip->ch = i; 441 443 spin_lock_init(&chip->spinlock); 442 444 ioh_gpio_setup(chip, num_ports[i]); 443 - ret = gpiochip_add_data(&chip->gpio, chip); 445 + ret = devm_gpiochip_add_data(dev, &chip->gpio, chip); 444 446 if (ret) { 445 447 dev_err(dev, "IOH gpio: Failed to register GPIO\n"); 446 - goto err_gpiochip_add; 448 + return ret; 447 449 } 448 450 } 449 451 ··· 454 456 if (irq_base < 0) { 455 457 dev_warn(dev, 456 458 "ml_ioh_gpio: Failed to get IRQ base num\n"); 457 - ret = irq_base; 458 - goto err_gpiochip_add; 459 + return irq_base; 459 460 } 460 461 chip->irq_base = irq_base; 461 462 462 463 ret = ioh_gpio_alloc_generic_chip(chip, 463 464 irq_base, num_ports[j]); 464 465 if (ret) 465 - goto err_gpiochip_add; 466 + return ret; 466 467 } 467 468 468 469 chip = chip_save; ··· 469 472 IRQF_SHARED, KBUILD_MODNAME, chip); 470 473 if (ret != 0) { 471 474 dev_err(dev, "%s request_irq failed\n", __func__); 472 - goto err_gpiochip_add; 475 + return ret; 473 476 } 474 477 475 478 pci_set_drvdata(pdev, chip); 476 479 477 480 return 0; 478 - 479 - err_gpiochip_add: 480 - chip = chip_save; 481 - while (--i >= 0) { 482 - gpiochip_remove(&chip->gpio); 483 - chip++; 484 - } 485 - kfree(chip_save); 486 - 487 - err_kzalloc: 488 - pci_iounmap(pdev, base); 489 - 490 - err_iomap: 491 - pci_release_regions(pdev); 492 - 493 - err_request_regions: 494 - pci_disable_device(pdev); 495 - 496 - err_pci_enable: 497 - 498 - dev_err(dev, "%s Failed returns %d\n", __func__, ret); 499 - return ret; 500 - } 501 - 502 - static void ioh_gpio_remove(struct pci_dev *pdev) 503 - { 504 - int i; 505 - struct ioh_gpio *chip = pci_get_drvdata(pdev); 506 - void *chip_save; 507 - 508 - chip_save = chip; 509 - 510 - for (i = 0; i < 8; i++, chip++) 511 - gpiochip_remove(&chip->gpio); 512 - 513 - chip = chip_save; 514 - pci_iounmap(pdev, chip->base); 515 - pci_release_regions(pdev); 516 - pci_disable_device(pdev); 517 - kfree(chip); 518 481 } 519 482 520 483 static int __maybe_unused ioh_gpio_suspend(struct device *dev) ··· 515 558 .name = "ml_ioh_gpio", 516 559 .id_table = ioh_gpio_pcidev_id, 517 560 .probe = ioh_gpio_probe, 518 - .remove = ioh_gpio_remove, 519 561 .driver = { 520 562 .pm = &ioh_gpio_pm_ops, 521 563 },