Commit 4d17aeb1c5b2375769446d13012a98e6d265ec13
Committed by
Kevin Hilman
1 parent
f776471f62
Exists in
master
and in
4 other branches
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 |
-
mentioned in commit af504e