Commit e710d7d5 authored by Samuel Ortiz's avatar Samuel Ortiz

mfd: Fetch cell pointer from platform_device->mfd_cell

In order for MFD drivers to fetch their cell pointer but also their
platform data one, an mfd cell pointer is added to the platform_device
structure.
That allows all MFD sub devices drivers to be MFD agnostic, unless
they really need to access their MFD cell data. Most of them don't,
especially the ones for IPs used by both MFD and non MFD SoCs.

Cc: Grant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarGreg KH <gregkh@suse.de>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent a6360dd3
...@@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev) ...@@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev)
of_device_node_put(&pa->pdev.dev); of_device_node_put(&pa->pdev.dev);
kfree(pa->pdev.dev.platform_data); kfree(pa->pdev.dev.platform_data);
kfree(pa->pdev.mfd_cell);
kfree(pa->pdev.resource); kfree(pa->pdev.resource);
kfree(pa); kfree(pa);
} }
......
...@@ -55,6 +55,19 @@ int mfd_cell_disable(struct platform_device *pdev) ...@@ -55,6 +55,19 @@ int mfd_cell_disable(struct platform_device *pdev)
} }
EXPORT_SYMBOL(mfd_cell_disable); EXPORT_SYMBOL(mfd_cell_disable);
static int mfd_platform_add_cell(struct platform_device *pdev,
const struct mfd_cell *cell)
{
if (!cell)
return 0;
pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL);
if (!pdev->mfd_cell)
return -ENOMEM;
return 0;
}
static int mfd_add_device(struct device *parent, int id, static int mfd_add_device(struct device *parent, int id,
const struct mfd_cell *cell, const struct mfd_cell *cell,
struct resource *mem_base, struct resource *mem_base,
...@@ -75,7 +88,7 @@ static int mfd_add_device(struct device *parent, int id, ...@@ -75,7 +88,7 @@ static int mfd_add_device(struct device *parent, int id,
pdev->dev.parent = parent; pdev->dev.parent = parent;
ret = platform_device_add_data(pdev, cell, sizeof(*cell)); ret = mfd_platform_add_cell(pdev, cell);
if (ret) if (ret)
goto fail_res; goto fail_res;
...@@ -123,7 +136,6 @@ static int mfd_add_device(struct device *parent, int id, ...@@ -123,7 +136,6 @@ static int mfd_add_device(struct device *parent, int id,
return 0; return 0;
/* platform_device_del(pdev); */
fail_res: fail_res:
kfree(res); kfree(res);
fail_device: fail_device:
......
...@@ -86,16 +86,25 @@ extern int mfd_clone_cell(const char *cell, const char **clones, ...@@ -86,16 +86,25 @@ extern int mfd_clone_cell(const char *cell, const char **clones,
*/ */
static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
{ {
return pdev->dev.platform_data; return pdev->mfd_cell;
} }
/* /*
* Given a platform device that's been created by mfd_add_devices(), fetch * Given a platform device that's been created by mfd_add_devices(), fetch
* the .mfd_data entry from the mfd_cell that created it. * the .mfd_data entry from the mfd_cell that created it.
* Otherwise just return the platform_data pointer.
* This maintains compatibility with platform drivers whose devices aren't
* created by the mfd layer, and expect platform_data to contain what would've
* otherwise been in mfd_data.
*/ */
static inline void *mfd_get_data(struct platform_device *pdev) static inline void *mfd_get_data(struct platform_device *pdev)
{ {
return mfd_get_cell(pdev)->mfd_data; const struct mfd_cell *cell = mfd_get_cell(pdev);
if (cell)
return cell->mfd_data;
else
return pdev->dev.platform_data;
} }
extern int mfd_add_devices(struct device *parent, int id, extern int mfd_add_devices(struct device *parent, int id,
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
struct mfd_cell;
struct platform_device { struct platform_device {
const char * name; const char * name;
int id; int id;
...@@ -23,6 +25,9 @@ struct platform_device { ...@@ -23,6 +25,9 @@ struct platform_device {
const struct platform_device_id *id_entry; const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */ /* arch specific additions */
struct pdev_archdata archdata; struct pdev_archdata archdata;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment