diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/i2c.c | 73 |
2 files changed, 54 insertions, 21 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index d775076d1563..ef9827f7c84e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -831,6 +831,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
831 | terminal devices. Valid values: 0..8 | 831 | terminal devices. Valid values: 0..8 |
832 | 832 | ||
833 | i2c_bus= [HW] Override the default board specific I2C bus speed | 833 | i2c_bus= [HW] Override the default board specific I2C bus speed |
834 | or register an additional I2C bus that is not | ||
835 | registered from board initialization code. | ||
834 | Format: | 836 | Format: |
835 | <bus_id>,<clkrate> | 837 | <bus_id>,<clkrate> |
836 | 838 | ||
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index aa70e435fa79..a303071d5e36 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c | |||
@@ -98,6 +98,8 @@ static const int omap34xx_pins[][2] = { | |||
98 | static const int omap34xx_pins[][2] = {}; | 98 | static const int omap34xx_pins[][2] = {}; |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) | ||
102 | |||
101 | static void __init omap_i2c_mux_pins(int bus) | 103 | static void __init omap_i2c_mux_pins(int bus) |
102 | { | 104 | { |
103 | int scl, sda; | 105 | int scl, sda; |
@@ -133,6 +135,31 @@ static int __init omap_i2c_nr_ports(void) | |||
133 | return ports; | 135 | return ports; |
134 | } | 136 | } |
135 | 137 | ||
138 | static int __init omap_i2c_add_bus(int bus_id) | ||
139 | { | ||
140 | struct platform_device *pdev; | ||
141 | struct resource *res; | ||
142 | resource_size_t base, irq; | ||
143 | |||
144 | pdev = &omap_i2c_devices[bus_id - 1]; | ||
145 | if (bus_id == 1) { | ||
146 | res = pdev->resource; | ||
147 | if (cpu_class_is_omap1()) { | ||
148 | base = OMAP1_I2C_BASE; | ||
149 | irq = INT_I2C; | ||
150 | } else { | ||
151 | base = OMAP2_I2C_BASE1; | ||
152 | irq = INT_24XX_I2C1_IRQ; | ||
153 | } | ||
154 | res[0].start = base; | ||
155 | res[0].end = base + OMAP_I2C_SIZE; | ||
156 | res[1].start = irq; | ||
157 | } | ||
158 | |||
159 | omap_i2c_mux_pins(bus_id - 1); | ||
160 | return platform_device_register(pdev); | ||
161 | } | ||
162 | |||
136 | /** | 163 | /** |
137 | * omap_i2c_bus_setup - Process command line options for the I2C bus speed | 164 | * omap_i2c_bus_setup - Process command line options for the I2C bus speed |
138 | * @str: String of options | 165 | * @str: String of options |
@@ -154,11 +181,33 @@ static int __init omap_i2c_bus_setup(char *str) | |||
154 | if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports) | 181 | if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports) |
155 | return 0; | 182 | return 0; |
156 | i2c_rate[ints[1] - 1] = ints[2]; | 183 | i2c_rate[ints[1] - 1] = ints[2]; |
184 | i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP; | ||
157 | 185 | ||
158 | return 1; | 186 | return 1; |
159 | } | 187 | } |
160 | __setup("i2c_bus=", omap_i2c_bus_setup); | 188 | __setup("i2c_bus=", omap_i2c_bus_setup); |
161 | 189 | ||
190 | /* | ||
191 | * Register busses defined in command line but that are not registered with | ||
192 | * omap_register_i2c_bus from board initialization code. | ||
193 | */ | ||
194 | static int __init omap_register_i2c_bus_cmdline(void) | ||
195 | { | ||
196 | int i, err = 0; | ||
197 | |||
198 | for (i = 0; i < ARRAY_SIZE(i2c_rate); i++) | ||
199 | if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) { | ||
200 | i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP; | ||
201 | err = omap_i2c_add_bus(i + 1); | ||
202 | if (err) | ||
203 | goto out; | ||
204 | } | ||
205 | |||
206 | out: | ||
207 | return err; | ||
208 | } | ||
209 | subsys_initcall(omap_register_i2c_bus_cmdline); | ||
210 | |||
162 | /** | 211 | /** |
163 | * omap_register_i2c_bus - register I2C bus with device descriptors | 212 | * omap_register_i2c_bus - register I2C bus with device descriptors |
164 | * @bus_id: bus id counting from number 1 | 213 | * @bus_id: bus id counting from number 1 |
@@ -173,9 +222,6 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, | |||
173 | unsigned len) | 222 | unsigned len) |
174 | { | 223 | { |
175 | int err; | 224 | int err; |
176 | struct platform_device *pdev; | ||
177 | struct resource *res; | ||
178 | resource_size_t base, irq; | ||
179 | 225 | ||
180 | BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports()); | 226 | BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports()); |
181 | 227 | ||
@@ -185,24 +231,9 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, | |||
185 | return err; | 231 | return err; |
186 | } | 232 | } |
187 | 233 | ||
188 | pdev = &omap_i2c_devices[bus_id - 1]; | 234 | if (!i2c_rate[bus_id - 1]) |
189 | if (i2c_rate[bus_id - 1] == 0) | ||
190 | i2c_rate[bus_id - 1] = clkrate; | 235 | i2c_rate[bus_id - 1] = clkrate; |
236 | i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP; | ||
191 | 237 | ||
192 | if (bus_id == 1) { | 238 | return omap_i2c_add_bus(bus_id); |
193 | res = pdev->resource; | ||
194 | if (cpu_class_is_omap1()) { | ||
195 | base = OMAP1_I2C_BASE; | ||
196 | irq = INT_I2C; | ||
197 | } else { | ||
198 | base = OMAP2_I2C_BASE1; | ||
199 | irq = INT_24XX_I2C1_IRQ; | ||
200 | } | ||
201 | res[0].start = base; | ||
202 | res[0].end = base + OMAP_I2C_SIZE; | ||
203 | res[1].start = irq; | ||
204 | } | ||
205 | |||
206 | omap_i2c_mux_pins(bus_id - 1); | ||
207 | return platform_device_register(pdev); | ||
208 | } | 239 | } |