diff options
author | Tony Lindgren <tony@atomide.com> | 2010-11-30 17:45:49 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-11-30 17:45:49 -0500 |
commit | 55a4e78952286d498d89a399d845e7cfaa8ddd56 (patch) | |
tree | f5d67bdaa07b36009476d2e1bdcde8b7dc0c6e3d /arch/arm/plat-omap | |
parent | 9c7bc451e41abf78b0fd856a9f916f7d39e26297 (diff) | |
parent | 27b1fec2caa668c162cd1a862c69e087df277fae (diff) |
Merge branch 'pm-hwmod-i2c' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/i2c.c | 124 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/i2c.h | 13 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/l4_3xxx.h | 24 |
3 files changed, 86 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 | /** |
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h index 36a0befd6168..878d632c4092 100644 --- a/arch/arm/plat-omap/include/plat/i2c.h +++ b/arch/arm/plat-omap/include/plat/i2c.h | |||
@@ -36,6 +36,19 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, | |||
36 | } | 36 | } |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | /** | ||
40 | * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod | ||
41 | * @fifo_depth: total controller FIFO size (in bytes) | ||
42 | * @flags: differences in hardware support capability | ||
43 | * | ||
44 | * @fifo_depth represents what exists on the hardware, not what is | ||
45 | * actually configured at runtime by the device driver. | ||
46 | */ | ||
47 | struct omap_i2c_dev_attr { | ||
48 | u8 fifo_depth; | ||
49 | u8 flags; | ||
50 | }; | ||
51 | |||
39 | void __init omap1_i2c_mux_pins(int bus_id); | 52 | void __init omap1_i2c_mux_pins(int bus_id); |
40 | void __init omap2_i2c_mux_pins(int bus_id); | 53 | void __init omap2_i2c_mux_pins(int bus_id); |
41 | 54 | ||
diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h new file mode 100644 index 000000000000..5e1949375422 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H | ||
14 | #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H | ||
15 | |||
16 | /* L4 CORE */ | ||
17 | #define OMAP3_L4_CORE_FW_I2C1_REGION 21 | ||
18 | #define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22 | ||
19 | #define OMAP3_L4_CORE_FW_I2C2_REGION 23 | ||
20 | #define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24 | ||
21 | #define OMAP3_L4_CORE_FW_I2C3_REGION 73 | ||
22 | #define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74 | ||
23 | |||
24 | #endif | ||