Commit 4d17aeb1c5b2375769446d13012a98e6d265ec13

Authored by Paul Walmsley
Committed by Kevin Hilman
1 parent f776471f62

OMAP: I2C: split device registration and convert OMAP2+ to omap_device

Split the OMAP1 and OMAP2+ platform_device build and register code.
Convert the OMAP2+ variant to use omap_device.

This patch was developed in collaboration with Rajendra Nayak
<rnayak@ti.com>.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>

Showing 2 changed files with 54 additions and 75 deletions Side-by-side Diff

arch/arm/plat-omap/i2c.c
... ... @@ -27,18 +27,18 @@
27 27 #include <linux/platform_device.h>
28 28 #include <linux/i2c.h>
29 29 #include <linux/i2c-omap.h>
  30 +#include <linux/slab.h>
  31 +#include <linux/err.h>
  32 +#include <linux/clk.h>
30 33  
31 34 #include <mach/irqs.h>
32 35 #include <plat/mux.h>
33 36 #include <plat/i2c.h>
34 37 #include <plat/omap-pm.h>
  38 +#include <plat/omap_device.h>
35 39  
36 40 #define OMAP_I2C_SIZE 0x3f
37 41 #define OMAP1_I2C_BASE 0xfffb3800
38   -#define OMAP2_I2C_BASE1 0x48070000
39   -#define OMAP2_I2C_BASE2 0x48072000
40   -#define OMAP2_I2C_BASE3 0x48060000
41   -#define OMAP4_I2C_BASE4 0x48350000
42 42  
43 43 static const char name[] = "i2c_omap";
44 44  
... ... @@ -55,15 +55,6 @@
55 55  
56 56 static struct resource i2c_resources[][2] = {
57 57 { I2C_RESOURCE_BUILDER(0, 0) },
58   -#if defined(CONFIG_ARCH_OMAP2PLUS)
59   - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) },
60   -#endif
61   -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
62   - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) },
63   -#endif
64   -#if defined(CONFIG_ARCH_OMAP4)
65   - { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) },
66   -#endif
67 58 };
68 59  
69 60 #define I2C_DEV_BUILDER(bus_id, res, data) \
70 61  
... ... @@ -77,18 +68,11 @@
77 68 }, \
78 69 }
79 70  
80   -static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)];
  71 +#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
  72 +#define OMAP_I2C_MAX_CONTROLLERS 4
  73 +static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
81 74 static struct platform_device omap_i2c_devices[] = {
82 75 I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
83   -#if defined(CONFIG_ARCH_OMAP2PLUS)
84   - I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]),
85   -#endif
86   -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
87   - I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]),
88   -#endif
89   -#if defined(CONFIG_ARCH_OMAP4)
90   - I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]),
91   -#endif
92 76 };
93 77  
94 78 #define OMAP_I2C_CMDLINE_SETUP (BIT(31))
95 79  
96 80  
97 81  
98 82  
... ... @@ -109,35 +93,20 @@
109 93 return ports;
110 94 }
111 95  
112   -/* Shared between omap2 and 3 */
113   -static resource_size_t omap2_i2c_irq[3] __initdata = {
114   - INT_24XX_I2C1_IRQ,
115   - INT_24XX_I2C2_IRQ,
116   - INT_34XX_I2C3_IRQ,
117   -};
118   -
119   -static resource_size_t omap4_i2c_irq[4] __initdata = {
120   - OMAP44XX_IRQ_I2C1,
121   - OMAP44XX_IRQ_I2C2,
122   - OMAP44XX_IRQ_I2C3,
123   - OMAP44XX_IRQ_I2C4,
124   -};
125   -
126   -static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
  96 +static inline int omap1_i2c_add_bus(int bus_id)
127 97 {
128   - struct omap_i2c_bus_platform_data *pd;
129   - struct resource *res;
  98 + struct platform_device *pdev;
  99 + struct omap_i2c_bus_platform_data *pdata;
130 100  
131   - pd = pdev->dev.platform_data;
132   - res = pdev->resource;
133   - res[0].start = OMAP1_I2C_BASE;
134   - res[0].end = res[0].start + OMAP_I2C_SIZE;
135   - res[1].start = INT_I2C;
136 101 omap1_i2c_mux_pins(bus_id);
137 102  
  103 + pdev = &omap_i2c_devices[bus_id - 1];
  104 + pdata = &i2c_pdata[bus_id - 1];
  105 +
138 106 return platform_device_register(pdev);
139 107 }
140 108  
  109 +
141 110 /*
142 111 * XXX This function is a temporary compatibility wrapper - only
143 112 * needed until the I2C driver can be converted to call
144 113  
145 114  
146 115  
147 116  
148 117  
149 118  
150 119  
151 120  
152 121  
153 122  
... ... @@ -148,52 +117,57 @@
148 117 omap_pm_set_max_mpu_wakeup_lat(dev, t);
149 118 }
150 119  
151   -static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
  120 +static struct omap_device_pm_latency omap_i2c_latency[] = {
  121 + [0] = {
  122 + .deactivate_func = omap_device_idle_hwmods,
  123 + .activate_func = omap_device_enable_hwmods,
  124 + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
  125 + },
  126 +};
  127 +
  128 +static inline int omap2_i2c_add_bus(int bus_id)
152 129 {
153   - struct resource *res;
154   - resource_size_t *irq;
  130 + int l;
  131 + struct omap_hwmod *oh;
  132 + struct omap_device *od;
  133 + char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
  134 + struct omap_i2c_bus_platform_data *pdata;
155 135  
156   - res = pdev->resource;
  136 + omap2_i2c_mux_pins(bus_id);
157 137  
158   - if (!cpu_is_omap44xx())
159   - irq = omap2_i2c_irq;
160   - else
161   - irq = omap4_i2c_irq;
162   -
163   - if (bus_id == 1) {
164   - res[0].start = OMAP2_I2C_BASE1;
165   - res[0].end = res[0].start + OMAP_I2C_SIZE;
  138 + l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
  139 + WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
  140 + "String buffer overflow in I2C%d device setup\n", bus_id);
  141 + oh = omap_hwmod_lookup(oh_name);
  142 + if (!oh) {
  143 + pr_err("Could not look up %s\n", oh_name);
  144 + return -EEXIST;
166 145 }
167 146  
168   - res[1].start = irq[bus_id - 1];
169   - omap2_i2c_mux_pins(bus_id);
170   -
  147 + pdata = &i2c_pdata[bus_id - 1];
171 148 /*
172 149 * When waiting for completion of a i2c transfer, we need to
173 150 * set a wake up latency constraint for the MPU. This is to
174 151 * ensure quick enough wakeup from idle, when transfer
175 152 * completes.
  153 + * Only omap3 has support for constraints
176 154 */
177   - if (cpu_is_omap34xx()) {
178   - struct omap_i2c_bus_platform_data *pd;
  155 + if (cpu_is_omap34xx())
  156 + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
  157 + od = omap_device_build(name, bus_id, oh, pdata,
  158 + sizeof(struct omap_i2c_bus_platform_data),
  159 + omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
  160 + WARN(IS_ERR(od), "Could not build omap_device for %s\n", name);
179 161  
180   - pd = pdev->dev.platform_data;
181   - pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
182   - }
183   -
184   - return platform_device_register(pdev);
  162 + return PTR_ERR(od);
185 163 }
186 164  
187 165 static int __init omap_i2c_add_bus(int bus_id)
188 166 {
189   - struct platform_device *pdev;
190   -
191   - pdev = &omap_i2c_devices[bus_id - 1];
192   -
193 167 if (cpu_class_is_omap1())
194   - return omap1_i2c_add_bus(pdev, bus_id);
  168 + return omap1_i2c_add_bus(bus_id);
195 169 else
196   - return omap2_i2c_add_bus(pdev, bus_id);
  170 + return omap2_i2c_add_bus(bus_id);
197 171 }
198 172  
199 173 /**
include/linux/i2c-omap.h
1 1 #ifndef __I2C_OMAP_H__
2 2 #define __I2C_OMAP_H__
3 3  
  4 +#include <linux/platform_device.h>
  5 +
4 6 struct omap_i2c_bus_platform_data {
5 7 u32 clkrate;
6 8 void (*set_mpu_wkup_lat)(struct device *dev, long set);
  9 + int (*device_enable) (struct platform_device *pdev);
  10 + int (*device_shutdown) (struct platform_device *pdev);
  11 + int (*device_idle) (struct platform_device *pdev);
7 12 };
8 13  
9 14 #endif