Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03e361b2 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Lee Jones
Browse files

mfd: Stop setting refcounting pointers in original mfd_cell arrays



Commit 1e29af62 ("mfd: Add refcounting
support to mfd_cells") had to drop the "const" keyword on the "cell"
parameter of mfd_add_devices(), as it added the refcounting pointers
to the objects of the passed mfd_cell array itself.

However, the mfd core code operates on copies of the mfd_cell objects,
so there's no need to modify the originally passed objects.

Hence, move the setting of the refcounting pointers from mfd_add_devices()
to mfd_platform_add_cell(), where the copy of the mfd_cell objects is made.
mfd_clone_cell() can just pass (a copy of) the original usage_count
pointer.

This allows to make the "cell" parameter of mfd_add_devices() "const"
again, and avoids future race conditions when registering multiple
instances of the same device in parallel.

Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 24f76f37
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -63,7 +63,8 @@ int mfd_cell_disable(struct platform_device *pdev)
EXPORT_SYMBOL(mfd_cell_disable);

static int mfd_platform_add_cell(struct platform_device *pdev,
				 const struct mfd_cell *cell)
				 const struct mfd_cell *cell,
				 atomic_t *usage_count)
{
	if (!cell)
		return 0;
@@ -72,11 +73,12 @@ static int mfd_platform_add_cell(struct platform_device *pdev,
	if (!pdev->mfd_cell)
		return -ENOMEM;

	pdev->mfd_cell->usage_count = usage_count;
	return 0;
}

static int mfd_add_device(struct device *parent, int id,
			  const struct mfd_cell *cell,
			  const struct mfd_cell *cell, atomic_t *usage_count,
			  struct resource *mem_base,
			  int irq_base, struct irq_domain *domain)
{
@@ -115,7 +117,7 @@ static int mfd_add_device(struct device *parent, int id,
			goto fail_res;
	}

	ret = mfd_platform_add_cell(pdev, cell);
	ret = mfd_platform_add_cell(pdev, cell, usage_count);
	if (ret)
		goto fail_res;

@@ -180,7 +182,7 @@ static int mfd_add_device(struct device *parent, int id,
}

int mfd_add_devices(struct device *parent, int id,
		    struct mfd_cell *cells, int n_devs,
		    const struct mfd_cell *cells, int n_devs,
		    struct resource *mem_base,
		    int irq_base, struct irq_domain *domain)
{
@@ -195,8 +197,7 @@ int mfd_add_devices(struct device *parent, int id,

	for (i = 0; i < n_devs; i++) {
		atomic_set(&cnts[i], 0);
		cells[i].usage_count = &cnts[i];
		ret = mfd_add_device(parent, id, cells + i, mem_base,
		ret = mfd_add_device(parent, id, cells + i, cnts + i, mem_base,
				     irq_base, domain);
		if (ret)
			break;
@@ -259,8 +260,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
	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, NULL, 0,
				   NULL))
		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]);
	}
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
}

extern int mfd_add_devices(struct device *parent, int id,
			   struct mfd_cell *cells, int n_devs,
			   const struct mfd_cell *cells, int n_devs,
			   struct resource *mem_base,
			   int irq_base, struct irq_domain *irq_domain);