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

mfd: cs5535-mfd: Request shared IO regions centrally

Prior to this patch, IO regions were requested via an MFD subsytem-level
.enable() call-back and similarly released by a .disable() call-back.
Double requests/releases were avoided by a centrally handled usage count
mechanism.

This complexity can all be avoided by handling IO regions only once during
.probe() and .remove() of the parent device. Since this is the only
legitimate user of the aforementioned usage count mechanism, this patch
will allow it to be removed from MFD core in subsequent steps.

Suggested-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>

+33 -41
+33 -41
drivers/mfd/cs5535-mfd.c
··· 27 27 NR_BARS, 28 28 }; 29 29 30 - static int cs5535_mfd_res_enable(struct platform_device *pdev) 31 - { 32 - struct resource *res; 33 - 34 - res = platform_get_resource(pdev, IORESOURCE_IO, 0); 35 - if (!res) { 36 - dev_err(&pdev->dev, "can't fetch device resource info\n"); 37 - return -EIO; 38 - } 39 - 40 - if (!request_region(res->start, resource_size(res), DRV_NAME)) { 41 - dev_err(&pdev->dev, "can't request region\n"); 42 - return -EIO; 43 - } 44 - 45 - return 0; 46 - } 47 - 48 - static int cs5535_mfd_res_disable(struct platform_device *pdev) 49 - { 50 - struct resource *res; 51 - 52 - res = platform_get_resource(pdev, IORESOURCE_IO, 0); 53 - if (!res) { 54 - dev_err(&pdev->dev, "can't fetch device resource info\n"); 55 - return -EIO; 56 - } 57 - 58 - release_region(res->start, resource_size(res)); 59 - return 0; 60 - } 61 - 62 30 static struct resource cs5535_mfd_resources[NR_BARS]; 63 31 64 32 static struct mfd_cell cs5535_mfd_cells[] = { ··· 49 81 .name = "cs5535-pms", 50 82 .num_resources = 1, 51 83 .resources = &cs5535_mfd_resources[PMS_BAR], 52 - 53 - .enable = cs5535_mfd_res_enable, 54 - .disable = cs5535_mfd_res_disable, 55 84 }, 56 85 { 57 86 .name = "cs5535-acpi", 58 87 .num_resources = 1, 59 88 .resources = &cs5535_mfd_resources[ACPI_BAR], 60 - 61 - .enable = cs5535_mfd_res_enable, 62 - .disable = cs5535_mfd_res_disable, 63 89 }, 64 90 }; 65 91 ··· 79 117 r->end = pci_resource_end(pdev, bar); 80 118 } 81 119 120 + err = pci_request_region(pdev, PMS_BAR, DRV_NAME); 121 + if (err) { 122 + dev_err(&pdev->dev, "Failed to request PMS_BAR's IO region\n"); 123 + goto err_disable; 124 + } 125 + 82 126 err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, cs5535_mfd_cells, 83 127 ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL); 84 128 if (err) { 85 129 dev_err(&pdev->dev, 86 130 "Failed to add CS5535 sub-devices: %d\n", err); 87 - goto err_disable; 131 + goto err_release_pms; 88 132 } 89 133 90 - if (machine_is_olpc()) 91 - mfd_clone_cell("cs5535-acpi", olpc_acpi_clones, ARRAY_SIZE(olpc_acpi_clones)); 134 + if (machine_is_olpc()) { 135 + err = pci_request_region(pdev, ACPI_BAR, DRV_NAME); 136 + if (err) { 137 + dev_err(&pdev->dev, 138 + "Failed to request ACPI_BAR's IO region\n"); 139 + goto err_remove_devices; 140 + } 141 + 142 + err = mfd_clone_cell("cs5535-acpi", olpc_acpi_clones, 143 + ARRAY_SIZE(olpc_acpi_clones)); 144 + if (err) { 145 + dev_err(&pdev->dev, "Failed to clone MFD cell\n"); 146 + goto err_release_acpi; 147 + } 148 + } 92 149 93 150 dev_info(&pdev->dev, "%zu devices registered.\n", 94 151 ARRAY_SIZE(cs5535_mfd_cells)); 95 152 96 153 return 0; 97 154 155 + err_release_acpi: 156 + pci_release_region(pdev, ACPI_BAR); 157 + err_remove_devices: 158 + mfd_remove_devices(&pdev->dev); 159 + err_release_pms: 160 + pci_release_region(pdev, PMS_BAR); 98 161 err_disable: 99 162 pci_disable_device(pdev); 100 163 return err; ··· 128 141 static void cs5535_mfd_remove(struct pci_dev *pdev) 129 142 { 130 143 mfd_remove_devices(&pdev->dev); 144 + 145 + if (machine_is_olpc()) 146 + pci_release_region(pdev, ACPI_BAR); 147 + 148 + pci_release_region(pdev, PMS_BAR); 131 149 pci_disable_device(pdev); 132 150 } 133 151