[RFC PATCH 03/16] ARM: OMAP2+: gmpc: add gpmc_generic_init()

Roger Quadros
2014-05-21T11:22:31Z

This function populates platform data for the specified Chip Select.
It should be called by board init code.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
arch/arm/mach-omap2/gpmc.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/gpmc.h | 6 ++++
2 files changed, 75 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 9fe8c94..6b4a322 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -115,6 +115,8 @@
*/
#define GPMC_NR_IRQ 2

+static struct gpmc_omap_platform_data gpmc_pdata;
+
struct gpmc_client_irq {
unsigned irq;
u32 bitmask;
@@ -1787,6 +1789,73 @@ static int __init omap_gpmc_init(void)
}
omap_postcore_initcall(omap_gpmc_init);

+/**
+ * gpmc_generic_init - Initialize platform data for a Chip Select
+ *
+ * @cs chip select number
+ * @type GPMC_OMAP_TYPE
+ * @settings GPMC settings
+ * @device_timings device timings for device on this CS
+ * @gpmc_timings GPMC timings
+ * @pdev platform device for the device on this CS
+ * @pdata_size platform data size for the platform device
+ */
+int gpmc_generic_init(int cs, enum gpmc_omap_type type,
+ struct gpmc_settings *settings,
+ struct gpmc_device_timings *device_timings,
+ struct gpmc_timings *gpmc_timings,
+ struct platform_device *pdev, unsigned pdata_size)
+{
+ struct gpmc_settings *gpmc_s;
+ struct gpmc_device_timings *gpmc_dev_t;
+ struct gpmc_timings *gpmc_t;
+
+ if (cs >= GPMC_CS_NUM) {
+ pr_err("%s: Invalid cs specified. Max CS = %d\n",
+ __func__, GPMC_CS_NUM);
+ return -EINVAL;
+ }
+
+ if (gpmc_pdata.cs[cs].valid) {
+ pr_err("%s: cs %d already requested, ignoring new request\n",
+ __func__, cs);
+ return -EINVAL;
+ }
+
+ if (settings) {
+ gpmc_s = kmemdup(settings, sizeof(*settings), GFP_KERNEL);
+ if (!gpmc_s)
+ return -ENOMEM;
+
+ gpmc_pdata.cs[cs].settings = gpmc_s;
+ }
+
+ if (device_timings) {
+ gpmc_dev_t = kmemdup(device_timings, sizeof(*device_timings),
+ GFP_KERNEL);
+ if (!gpmc_dev_t)
+ return -ENOMEM;
+
+ gpmc_pdata.cs[cs].device_timings = gpmc_dev_t;
+ }
+
+ if (gpmc_timings) {
+ gpmc_t = kmemdup(gpmc_timings, sizeof(*gpmc_timings),
+ GFP_KERNEL);
+ if (!gpmc_t)
+ return -ENOMEM;
+
+ gpmc_pdata.cs[cs].gpmc_timings = gpmc_t;
+ }
+
+ gpmc_pdata.cs[cs].type = type;
+ gpmc_pdata.cs[cs].pdev = pdev;
+ gpmc_pdata.cs[cs].pdata_size = pdata_size;
+ gpmc_pdata.cs[cs].valid = true;
+
+ return 0;
+}
+
static irqreturn_t gpmc_handle_irq(int irq, void *dev)
{
int i;
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 681977f..c18b022 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -100,5 +100,11 @@ extern void omap3_gpmc_restore_context(void);
extern int gpmc_configure(int cmd, int wval);
extern void gpmc_read_settings_dt(struct device_node *np,
struct gpmc_settings *p);
+extern int gpmc_generic_init(int cs, enum gpmc_omap_type type,
+ struct gpmc_settings *settings,
+ struct gpmc_device_timings *device_timings,
+ struct gpmc_timings *gpmc_timings,
+ struct platform_device *pdev,
+ unsigned pdata_size);

#endif
--
1.8.3.2