2019-10-19 08:25:34

by Lee Jones

[permalink] [raw]
Subject: [PATCH 0/4] Remove mfd_clone_cell() from the MFD API

mfd_clone_cell() only has one user and it quite easy to replicate
using the existing MFD registration API in the traditional way.
Here we convert the user and remove the superfluous helper.

Lee Jones (4):
mfd: cs5535-mfd: Use PLATFORM_DEVID_* defines and tidy error message
mfd: cs5535-mfd: Remove mfd_cell->id hack
mfd: cs5535-mfd: Register clients using their own dedicated MFD cell
entries
mfd: mfd-core: Remove mfd_clone_cell()

drivers/mfd/cs5535-mfd.c | 70 ++++++++++++++++++++++++++--------------
drivers/mfd/mfd-core.c | 33 -------------------
include/linux/mfd/core.h | 18 -----------
3 files changed, 45 insertions(+), 76 deletions(-)

--
2.17.1


2019-10-19 08:25:36

by Lee Jones

[permalink] [raw]
Subject: [PATCH 1/4] mfd: cs5535-mfd: Use PLATFORM_DEVID_* defines and tidy error message

In most contexts '-1' doesn't really mean much to the casual observer.
In almost all cases, it's better to use a human readable define. In
this case PLATFORM_DEVID_* defines have already been provided for this
purpose.

While we're here, let's be specific about the 'MFD devices' which
failed. It will help when trying to distinguish with of the 2 sets of
sub-devices we actually failed to register.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/cs5535-mfd.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index f1825c0ccbd0..2c47afc22d24 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -127,10 +127,11 @@ static int cs5535_mfd_probe(struct pci_dev *pdev,
cs5535_mfd_cells[i].id = 0;
}

- err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells,
+ err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, cs5535_mfd_cells,
ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL);
if (err) {
- dev_err(&pdev->dev, "MFD add devices failed: %d\n", err);
+ dev_err(&pdev->dev,
+ "Failed to add CS5532 sub-devices: %d\n", err);
goto err_disable;
}

--
2.17.1

2019-10-19 08:25:41

by Lee Jones

[permalink] [raw]
Subject: [PATCH 3/4] mfd: cs5535-mfd: Register clients using their own dedicated MFD cell entries

CS5535 is the only user of mfd_clone_cell(). It makes more sense to
register child devices in the traditional way and remove the quite
bespoke mfd_clone_cell() call from the MFD API.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/cs5535-mfd.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index b01e5bb4ed03..2711e6e42742 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -95,9 +95,23 @@ static struct mfd_cell cs5535_mfd_cells[] = {
},
};

-static const char *olpc_acpi_clones[] = {
- "olpc-xo1-pm-acpi",
- "olpc-xo1-sci-acpi"
+static struct mfd_cell cs5535_olpc_mfd_cells[] = {
+ {
+ .name = "olpc-xo1-pm-acpi",
+ .num_resources = 1,
+ .resources = &cs5535_mfd_resources[ACPI_BAR],
+
+ .enable = cs5535_mfd_res_enable,
+ .disable = cs5535_mfd_res_disable,
+ },
+ {
+ .name = "olpc-xo1-sci-acpi",
+ .num_resources = 1,
+ .resources = &cs5535_mfd_resources[ACPI_BAR],
+
+ .enable = cs5535_mfd_res_enable,
+ .disable = cs5535_mfd_res_disable,
+ },
};

static int cs5535_mfd_probe(struct pci_dev *pdev,
@@ -130,8 +144,18 @@ static int cs5535_mfd_probe(struct pci_dev *pdev,
goto err_disable;
}

- if (machine_is_olpc())
- mfd_clone_cell("cs5535-acpi", olpc_acpi_clones, ARRAY_SIZE(olpc_acpi_clones));
+ if (machine_is_olpc()) {
+ err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
+ cs5535_olpc_mfd_cells,
+ ARRAY_SIZE(cs5535_olpc_mfd_cells),
+ NULL, 0, NULL);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Failed to add CS5532 OLPC sub-devices: %d\n",
+ err);
+ goto err_disable;
+ }
+ }

dev_info(&pdev->dev, "%zu devices registered.\n",
ARRAY_SIZE(cs5535_mfd_cells));
--
2.17.1

2019-10-19 08:25:43

by Lee Jones

[permalink] [raw]
Subject: [PATCH 4/4] mfd: mfd-core: Remove mfd_clone_cell()

Providing an subsystem-level API helper seems over-kill just to save a
few lines of C-code. Previous commits saw us convert mfd_clone_cell()'s
only user over to use a more traditional style of MFD child-device
registration. Now we can remove the superfluous helper from the MFD API.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/mfd-core.c | 33 ---------------------------------
include/linux/mfd/core.h | 18 ------------------
2 files changed, 51 deletions(-)

diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 23276a80e3b4..8126665bb2d8 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -382,38 +382,5 @@ int devm_mfd_add_devices(struct device *dev, int id,
}
EXPORT_SYMBOL(devm_mfd_add_devices);

-int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
-{
- struct mfd_cell cell_entry;
- struct device *dev;
- struct platform_device *pdev;
- int i;
-
- /* fetch the parent cell's device (should already be registered!) */
- dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
- if (!dev) {
- printk(KERN_ERR "failed to find device for cell %s\n", cell);
- return -ENODEV;
- }
- pdev = to_platform_device(dev);
- memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry));
-
- WARN_ON(!cell_entry.enable);
-
- for (i = 0; i < n_clones; i++) {
- cell_entry.name = clones[i];
- /* don't give up if a single call fails; just report error */
- if (mfd_add_device(pdev->dev.parent, -1, &cell_entry,
- cell_entry.usage_count, NULL, 0, NULL))
- dev_err(dev, "failed to create platform device '%s'\n",
- clones[i]);
- }
-
- put_device(dev);
-
- return 0;
-}
-EXPORT_SYMBOL(mfd_clone_cell);
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index b43fc5773ad7..bd8c0e089164 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -86,24 +86,6 @@ struct mfd_cell {
extern int mfd_cell_enable(struct platform_device *pdev);
extern int mfd_cell_disable(struct platform_device *pdev);

-/*
- * "Clone" multiple platform devices for a single cell. This is to be used
- * for devices that have multiple users of a cell. For example, if an mfd
- * driver wants the cell "foo" to be used by a GPIO driver, an MTD driver,
- * and a platform driver, the following bit of code would be use after first
- * calling mfd_add_devices():
- *
- * const char *fclones[] = { "foo-gpio", "foo-mtd" };
- * err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones));
- *
- * Each driver (MTD, GPIO, and platform driver) would then register
- * platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively.
- * The cell's .enable/.disable hooks should be used to deal with hardware
- * resource contention.
- */
-extern int mfd_clone_cell(const char *cell, const char **clones,
- size_t n_clones);
-
/*
* Given a platform device that's been created by mfd_add_devices(), fetch
* the mfd_cell that created it.
--
2.17.1

2019-10-19 08:25:43

by Lee Jones

[permalink] [raw]
Subject: [PATCH 2/4] mfd: cs5535-mfd: Remove mfd_cell->id hack

The current implementation abuses the platform 'id' mfd_cell member
to index into the correct resources entry. If we place all cells
into their numbered slots, we can cycle through all the cell entries
and only process the populated ones which avoids this behaviour.

Signed-off-by: Lee Jones <[email protected]>
---
drivers/mfd/cs5535-mfd.c | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index 2c47afc22d24..b01e5bb4ed03 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -62,26 +62,22 @@ static int cs5535_mfd_res_disable(struct platform_device *pdev)
static struct resource cs5535_mfd_resources[NR_BARS];

static struct mfd_cell cs5535_mfd_cells[] = {
- {
- .id = SMB_BAR,
+ [SMB_BAR] = {
.name = "cs5535-smb",
.num_resources = 1,
.resources = &cs5535_mfd_resources[SMB_BAR],
},
- {
- .id = GPIO_BAR,
+ [GPIO_BAR] = {
.name = "cs5535-gpio",
.num_resources = 1,
.resources = &cs5535_mfd_resources[GPIO_BAR],
},
- {
- .id = MFGPT_BAR,
+ [MFGPT_BAR] = {
.name = "cs5535-mfgpt",
.num_resources = 1,
.resources = &cs5535_mfd_resources[MFGPT_BAR],
},
- {
- .id = PMS_BAR,
+ [PMS_BAR] = {
.name = "cs5535-pms",
.num_resources = 1,
.resources = &cs5535_mfd_resources[PMS_BAR],
@@ -89,8 +85,7 @@ static struct mfd_cell cs5535_mfd_cells[] = {
.enable = cs5535_mfd_res_enable,
.disable = cs5535_mfd_res_disable,
},
- {
- .id = ACPI_BAR,
+ [ACPI_BAR] = {
.name = "cs5535-acpi",
.num_resources = 1,
.resources = &cs5535_mfd_resources[ACPI_BAR],
@@ -115,16 +110,16 @@ static int cs5535_mfd_probe(struct pci_dev *pdev,
return err;

/* fill in IO range for each cell; subdrivers handle the region */
- for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) {
- int bar = cs5535_mfd_cells[i].id;
- struct resource *r = &cs5535_mfd_resources[bar];
+ for (i = 0; i < NR_BARS; i++) {
+ struct mfd_cell *cell = &cs5535_mfd_cells[i];
+ struct resource *r = &cs5535_mfd_resources[i];

- r->flags = IORESOURCE_IO;
- r->start = pci_resource_start(pdev, bar);
- r->end = pci_resource_end(pdev, bar);
+ if (!cell)
+ continue;

- /* id is used for temporarily storing BAR; unset it now */
- cs5535_mfd_cells[i].id = 0;
+ r->flags = IORESOURCE_IO;
+ r->start = pci_resource_start(pdev, i);
+ r->end = pci_resource_end(pdev, i);
}

err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, cs5535_mfd_cells,
--
2.17.1

2019-10-19 08:39:09

by Daniel Thompson

[permalink] [raw]
Subject: Re: [PATCH 3/4] mfd: cs5535-mfd: Register clients using their own dedicated MFD cell entries

On Fri, Oct 18, 2019 at 01:56:07PM +0100, Lee Jones wrote:
> CS5535 is the only user of mfd_clone_cell(). It makes more sense to
> register child devices in the traditional way and remove the quite
> bespoke mfd_clone_cell() call from the MFD API.

Like the other thread... this looks like it takes a shared (cloned)
reference counter and creates two independant ones instead.


Daniel.

>
> Signed-off-by: Lee Jones <[email protected]>
> ---
> drivers/mfd/cs5535-mfd.c | 34 +++++++++++++++++++++++++++++-----
> 1 file changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
> index b01e5bb4ed03..2711e6e42742 100644
> --- a/drivers/mfd/cs5535-mfd.c
> +++ b/drivers/mfd/cs5535-mfd.c
> @@ -95,9 +95,23 @@ static struct mfd_cell cs5535_mfd_cells[] = {
> },
> };
>
> -static const char *olpc_acpi_clones[] = {
> - "olpc-xo1-pm-acpi",
> - "olpc-xo1-sci-acpi"
> +static struct mfd_cell cs5535_olpc_mfd_cells[] = {
> + {
> + .name = "olpc-xo1-pm-acpi",
> + .num_resources = 1,
> + .resources = &cs5535_mfd_resources[ACPI_BAR],
> +
> + .enable = cs5535_mfd_res_enable,
> + .disable = cs5535_mfd_res_disable,
> + },
> + {
> + .name = "olpc-xo1-sci-acpi",
> + .num_resources = 1,
> + .resources = &cs5535_mfd_resources[ACPI_BAR],
> +
> + .enable = cs5535_mfd_res_enable,
> + .disable = cs5535_mfd_res_disable,
> + },
> };
>
> static int cs5535_mfd_probe(struct pci_dev *pdev,
> @@ -130,8 +144,18 @@ static int cs5535_mfd_probe(struct pci_dev *pdev,
> goto err_disable;
> }
>
> - if (machine_is_olpc())
> - mfd_clone_cell("cs5535-acpi", olpc_acpi_clones, ARRAY_SIZE(olpc_acpi_clones));
> + if (machine_is_olpc()) {
> + err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
> + cs5535_olpc_mfd_cells,
> + ARRAY_SIZE(cs5535_olpc_mfd_cells),
> + NULL, 0, NULL);
> + if (err) {
> + dev_err(&pdev->dev,
> + "Failed to add CS5532 OLPC sub-devices: %d\n",
> + err);
> + goto err_disable;
> + }
> + }
>
> dev_info(&pdev->dev, "%zu devices registered.\n",
> ARRAY_SIZE(cs5535_mfd_cells));
> --
> 2.17.1
>

2019-10-19 08:48:35

by Daniel Thompson

[permalink] [raw]
Subject: Re: [PATCH 2/4] mfd: cs5535-mfd: Remove mfd_cell->id hack

On Fri, Oct 18, 2019 at 01:56:06PM +0100, Lee Jones wrote:
> The current implementation abuses the platform 'id' mfd_cell member
> to index into the correct resources entry. If we place all cells
> into their numbered slots, we can cycle through all the cell entries
> and only process the populated ones which avoids this behaviour.
>
> Signed-off-by: Lee Jones <[email protected]>
> ---
> drivers/mfd/cs5535-mfd.c | 31 +++++++++++++------------------
> 1 file changed, 13 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
> index 2c47afc22d24..b01e5bb4ed03 100644
> --- a/drivers/mfd/cs5535-mfd.c
> +++ b/drivers/mfd/cs5535-mfd.c
> @@ -115,16 +110,16 @@ static int cs5535_mfd_probe(struct pci_dev *pdev,
> return err;
>
> /* fill in IO range for each cell; subdrivers handle the region */
> - for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) {
> - int bar = cs5535_mfd_cells[i].id;
> - struct resource *r = &cs5535_mfd_resources[bar];
> + for (i = 0; i < NR_BARS; i++) {
> + struct mfd_cell *cell = &cs5535_mfd_cells[i];
> + struct resource *r = &cs5535_mfd_resources[i];
>
> - r->flags = IORESOURCE_IO;
> - r->start = pci_resource_start(pdev, bar);
> - r->end = pci_resource_end(pdev, bar);
> + if (!cell)
> + continue;

cell will never be null. Should this be cell->num_resources instead?


Daniel.