diff options
Diffstat (limited to 'include/linux/mfd/core.h')
| -rw-r--r-- | include/linux/mfd/core.h | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 835996e167e1..aef23309a742 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h | |||
| @@ -25,22 +25,20 @@ struct mfd_cell { | |||
| 25 | const char *name; | 25 | const char *name; |
| 26 | int id; | 26 | int id; |
| 27 | 27 | ||
| 28 | /* refcounting for multiple drivers to use a single cell */ | ||
| 29 | atomic_t *usage_count; | ||
| 28 | int (*enable)(struct platform_device *dev); | 30 | int (*enable)(struct platform_device *dev); |
| 29 | int (*disable)(struct platform_device *dev); | 31 | int (*disable)(struct platform_device *dev); |
| 32 | |||
| 30 | int (*suspend)(struct platform_device *dev); | 33 | int (*suspend)(struct platform_device *dev); |
| 31 | int (*resume)(struct platform_device *dev); | 34 | int (*resume)(struct platform_device *dev); |
| 32 | 35 | ||
| 33 | /* driver-specific data for MFD-aware "cell" drivers */ | 36 | /* mfd_data can be used to pass data to client drivers */ |
| 34 | void *driver_data; | 37 | void *mfd_data; |
| 35 | |||
| 36 | /* platform_data can be used to either pass data to "generic" | ||
| 37 | driver or as a hook to mfd_cell for the "cell" drivers */ | ||
| 38 | void *platform_data; | ||
| 39 | size_t data_size; | ||
| 40 | 38 | ||
| 41 | /* | 39 | /* |
| 42 | * This resources can be specified relatively to the parent device. | 40 | * These resources can be specified relative to the parent device. |
| 43 | * For accessing device you should use resources from device | 41 | * For accessing hardware you should use resources from the platform dev |
| 44 | */ | 42 | */ |
| 45 | int num_resources; | 43 | int num_resources; |
| 46 | const struct resource *resources; | 44 | const struct resource *resources; |
| @@ -55,8 +53,62 @@ struct mfd_cell { | |||
| 55 | bool pm_runtime_no_callbacks; | 53 | bool pm_runtime_no_callbacks; |
| 56 | }; | 54 | }; |
| 57 | 55 | ||
| 56 | /* | ||
| 57 | * Convenience functions for clients using shared cells. Refcounting | ||
| 58 | * happens automatically, with the cell's enable/disable callbacks | ||
| 59 | * being called only when a device is first being enabled or no other | ||
| 60 | * clients are making use of it. | ||
| 61 | */ | ||
| 62 | extern int mfd_cell_enable(struct platform_device *pdev); | ||
| 63 | extern int mfd_cell_disable(struct platform_device *pdev); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * "Clone" multiple platform devices for a single cell. This is to be used | ||
| 67 | * for devices that have multiple users of a cell. For example, if an mfd | ||
| 68 | * driver wants the cell "foo" to be used by a GPIO driver, an MTD driver, | ||
| 69 | * and a platform driver, the following bit of code would be use after first | ||
| 70 | * calling mfd_add_devices(): | ||
| 71 | * | ||
| 72 | * const char *fclones[] = { "foo-gpio", "foo-mtd" }; | ||
| 73 | * err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones)); | ||
| 74 | * | ||
| 75 | * Each driver (MTD, GPIO, and platform driver) would then register | ||
| 76 | * platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively. | ||
| 77 | * The cell's .enable/.disable hooks should be used to deal with hardware | ||
| 78 | * resource contention. | ||
| 79 | */ | ||
| 80 | extern int mfd_clone_cell(const char *cell, const char **clones, | ||
| 81 | size_t n_clones); | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Given a platform device that's been created by mfd_add_devices(), fetch | ||
| 85 | * the mfd_cell that created it. | ||
| 86 | */ | ||
| 87 | static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) | ||
| 88 | { | ||
| 89 | return pdev->mfd_cell; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Given a platform device that's been created by mfd_add_devices(), fetch | ||
| 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. | ||
| 99 | */ | ||
| 100 | static inline void *mfd_get_data(struct platform_device *pdev) | ||
| 101 | { | ||
| 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; | ||
| 108 | } | ||
| 109 | |||
| 58 | extern int mfd_add_devices(struct device *parent, int id, | 110 | extern int mfd_add_devices(struct device *parent, int id, |
| 59 | const struct mfd_cell *cells, int n_devs, | 111 | struct mfd_cell *cells, int n_devs, |
| 60 | struct resource *mem_base, | 112 | struct resource *mem_base, |
| 61 | int irq_base); | 113 | int irq_base); |
| 62 | 114 | ||
