diff options
author | Paul Walmsley <paul@pwsan.com> | 2010-09-21 10:07:15 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-11-09 12:31:10 -0500 |
commit | 4d17aeb1c5b2375769446d13012a98e6d265ec13 (patch) | |
tree | 1d74a8df0af5d774d27b4bffe2728d0f9ac7abfe /arch/arm/plat-omap | |
parent | f776471f620a07be234f40288a1fd9932d039e26 (diff) |
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>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/i2c.c | 124 |
1 files changed, 49 insertions, 75 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a5ce4f0aad35..a5bff9ce7cbe 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c | |||
@@ -27,18 +27,18 @@ | |||
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/i2c-omap.h> | 29 | #include <linux/i2c-omap.h> |
30 | #include <linux/slab.h> | ||
31 | #include <linux/err.h> | ||
32 | #include <linux/clk.h> | ||
30 | 33 | ||
31 | #include <mach/irqs.h> | 34 | #include <mach/irqs.h> |
32 | #include <plat/mux.h> | 35 | #include <plat/mux.h> |
33 | #include <plat/i2c.h> | 36 | #include <plat/i2c.h> |
34 | #include <plat/omap-pm.h> | 37 | #include <plat/omap-pm.h> |
38 | #include <plat/omap_device.h> | ||
35 | 39 | ||
36 | #define OMAP_I2C_SIZE 0x3f | 40 | #define OMAP_I2C_SIZE 0x3f |
37 | #define OMAP1_I2C_BASE 0xfffb3800 | 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 | static const char name[] = "i2c_omap"; | 43 | static const char name[] = "i2c_omap"; |
44 | 44 | ||
@@ -55,15 +55,6 @@ static const char name[] = "i2c_omap"; | |||
55 | 55 | ||
56 | static struct resource i2c_resources[][2] = { | 56 | static struct resource i2c_resources[][2] = { |
57 | { I2C_RESOURCE_BUILDER(0, 0) }, | 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 | #define I2C_DEV_BUILDER(bus_id, res, data) \ | 60 | #define I2C_DEV_BUILDER(bus_id, res, data) \ |
@@ -77,18 +68,11 @@ static struct resource i2c_resources[][2] = { | |||
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 | static struct platform_device omap_i2c_devices[] = { | 74 | static struct platform_device omap_i2c_devices[] = { |
82 | I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]), | 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 | #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) | 78 | #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) |
@@ -109,35 +93,20 @@ static int __init omap_i2c_nr_ports(void) | |||
109 | return ports; | 93 | return ports; |
110 | } | 94 | } |
111 | 95 | ||
112 | /* Shared between omap2 and 3 */ | 96 | static inline int omap1_i2c_add_bus(int bus_id) |
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) | ||
127 | { | 97 | { |
128 | struct omap_i2c_bus_platform_data *pd; | 98 | struct platform_device *pdev; |
129 | struct resource *res; | 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 | omap1_i2c_mux_pins(bus_id); | 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 | return platform_device_register(pdev); | 106 | return platform_device_register(pdev); |
139 | } | 107 | } |
140 | 108 | ||
109 | |||
141 | /* | 110 | /* |
142 | * XXX This function is a temporary compatibility wrapper - only | 111 | * XXX This function is a temporary compatibility wrapper - only |
143 | * needed until the I2C driver can be converted to call | 112 | * needed until the I2C driver can be converted to call |
@@ -148,52 +117,57 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) | |||
148 | omap_pm_set_max_mpu_wakeup_lat(dev, t); | 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[] = { |
152 | { | 121 | [0] = { |
153 | struct resource *res; | 122 | .deactivate_func = omap_device_idle_hwmods, |
154 | resource_size_t *irq; | 123 | .activate_func = omap_device_enable_hwmods, |
124 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
125 | }, | ||
126 | }; | ||
155 | 127 | ||
156 | res = pdev->resource; | 128 | static inline int omap2_i2c_add_bus(int bus_id) |
129 | { | ||
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; | ||
157 | 135 | ||
158 | if (!cpu_is_omap44xx()) | 136 | omap2_i2c_mux_pins(bus_id); |
159 | irq = omap2_i2c_irq; | ||
160 | else | ||
161 | irq = omap4_i2c_irq; | ||
162 | 137 | ||
163 | if (bus_id == 1) { | 138 | l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id); |
164 | res[0].start = OMAP2_I2C_BASE1; | 139 | WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN, |
165 | res[0].end = res[0].start + OMAP_I2C_SIZE; | 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]; | 147 | pdata = &i2c_pdata[bus_id - 1]; |
169 | omap2_i2c_mux_pins(bus_id); | ||
170 | |||
171 | /* | 148 | /* |
172 | * When waiting for completion of a i2c transfer, we need to | 149 | * When waiting for completion of a i2c transfer, we need to |
173 | * set a wake up latency constraint for the MPU. This is to | 150 | * set a wake up latency constraint for the MPU. This is to |
174 | * ensure quick enough wakeup from idle, when transfer | 151 | * ensure quick enough wakeup from idle, when transfer |
175 | * completes. | 152 | * completes. |
153 | * Only omap3 has support for constraints | ||
176 | */ | 154 | */ |
177 | if (cpu_is_omap34xx()) { | 155 | if (cpu_is_omap34xx()) |
178 | struct omap_i2c_bus_platform_data *pd; | 156 | pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; |
179 | 157 | od = omap_device_build(name, bus_id, oh, pdata, | |
180 | pd = pdev->dev.platform_data; | 158 | sizeof(struct omap_i2c_bus_platform_data), |
181 | pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; | 159 | omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0); |
182 | } | 160 | WARN(IS_ERR(od), "Could not build omap_device for %s\n", name); |
183 | 161 | ||
184 | return platform_device_register(pdev); | 162 | return PTR_ERR(od); |
185 | } | 163 | } |
186 | 164 | ||
187 | static int __init omap_i2c_add_bus(int bus_id) | 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 | if (cpu_class_is_omap1()) | 167 | if (cpu_class_is_omap1()) |
194 | return omap1_i2c_add_bus(pdev, bus_id); | 168 | return omap1_i2c_add_bus(bus_id); |
195 | else | 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 | /** |