Commit e710d7d5a9cab1041b7a3cf9e655b75d92786857

Authored by Samuel Ortiz
1 parent a6360dd37e

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: Greg KH <gregkh@suse.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 4 changed files with 31 additions and 4 deletions Side-by-side Diff

drivers/base/platform.c
... ... @@ -149,6 +149,7 @@
149 149  
150 150 of_device_node_put(&pa->pdev.dev);
151 151 kfree(pa->pdev.dev.platform_data);
  152 + kfree(pa->pdev.mfd_cell);
152 153 kfree(pa->pdev.resource);
153 154 kfree(pa);
154 155 }
drivers/mfd/mfd-core.c
... ... @@ -55,6 +55,19 @@
55 55 }
56 56 EXPORT_SYMBOL(mfd_cell_disable);
57 57  
  58 +static int mfd_platform_add_cell(struct platform_device *pdev,
  59 + const struct mfd_cell *cell)
  60 +{
  61 + if (!cell)
  62 + return 0;
  63 +
  64 + pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL);
  65 + if (!pdev->mfd_cell)
  66 + return -ENOMEM;
  67 +
  68 + return 0;
  69 +}
  70 +
58 71 static int mfd_add_device(struct device *parent, int id,
59 72 const struct mfd_cell *cell,
60 73 struct resource *mem_base,
... ... @@ -75,7 +88,7 @@
75 88  
76 89 pdev->dev.parent = parent;
77 90  
78   - ret = platform_device_add_data(pdev, cell, sizeof(*cell));
  91 + ret = mfd_platform_add_cell(pdev, cell);
79 92 if (ret)
80 93 goto fail_res;
81 94  
... ... @@ -123,7 +136,6 @@
123 136  
124 137 return 0;
125 138  
126   -/* platform_device_del(pdev); */
127 139 fail_res:
128 140 kfree(res);
129 141 fail_device:
include/linux/mfd/core.h
... ... @@ -86,16 +86,25 @@
86 86 */
87 87 static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
88 88 {
89   - return pdev->dev.platform_data;
  89 + return pdev->mfd_cell;
90 90 }
91 91  
92 92 /*
93 93 * Given a platform device that's been created by mfd_add_devices(), fetch
94 94 * the .mfd_data entry from the mfd_cell that created it.
  95 + * Otherwise just return the platform_data pointer.
  96 + * This maintains compatibility with platform drivers whose devices aren't
  97 + * created by the mfd layer, and expect platform_data to contain what would've
  98 + * otherwise been in mfd_data.
95 99 */
96 100 static inline void *mfd_get_data(struct platform_device *pdev)
97 101 {
98   - return mfd_get_cell(pdev)->mfd_data;
  102 + const struct mfd_cell *cell = mfd_get_cell(pdev);
  103 +
  104 + if (cell)
  105 + return cell->mfd_data;
  106 + else
  107 + return pdev->dev.platform_data;
99 108 }
100 109  
101 110 extern int mfd_add_devices(struct device *parent, int id,
include/linux/platform_device.h
... ... @@ -14,6 +14,8 @@
14 14 #include <linux/device.h>
15 15 #include <linux/mod_devicetable.h>
16 16  
  17 +struct mfd_cell;
  18 +
17 19 struct platform_device {
18 20 const char * name;
19 21 int id;
... ... @@ -22,6 +24,9 @@
22 24 struct resource * resource;
23 25  
24 26 const struct platform_device_id *id_entry;
  27 +
  28 + /* MFD cell pointer */
  29 + struct mfd_cell *mfd_cell;
25 30  
26 31 /* arch specific additions */
27 32 struct pdev_archdata archdata;