.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * i2c-ocores.c: I2C bus driver for OpenCores I2C controller |
---|
3 | 4 | * (https://opencores.org/project/i2c/overview) |
---|
.. | .. |
---|
6 | 7 | * |
---|
7 | 8 | * Support for the GRLIB port of the controller by |
---|
8 | 9 | * Andreas Larsson <andreas@gaisler.com> |
---|
9 | | - * |
---|
10 | | - * This file is licensed under the terms of the GNU General Public License |
---|
11 | | - * version 2. This program is licensed "as is" without any warranty of any |
---|
12 | | - * kind, whether express or implied. |
---|
13 | 10 | */ |
---|
14 | 11 | |
---|
15 | 12 | #include <linux/clk.h> |
---|
| 13 | +#include <linux/delay.h> |
---|
16 | 14 | #include <linux/err.h> |
---|
17 | 15 | #include <linux/kernel.h> |
---|
18 | 16 | #include <linux/module.h> |
---|
.. | .. |
---|
25 | 23 | #include <linux/slab.h> |
---|
26 | 24 | #include <linux/io.h> |
---|
27 | 25 | #include <linux/log2.h> |
---|
| 26 | +#include <linux/spinlock.h> |
---|
| 27 | +#include <linux/jiffies.h> |
---|
28 | 28 | |
---|
| 29 | +/* |
---|
| 30 | + * 'process_lock' exists because ocores_process() and ocores_process_timeout() |
---|
| 31 | + * can't run in parallel. |
---|
| 32 | + */ |
---|
29 | 33 | struct ocores_i2c { |
---|
30 | 34 | void __iomem *base; |
---|
| 35 | + int iobase; |
---|
31 | 36 | u32 reg_shift; |
---|
32 | 37 | u32 reg_io_width; |
---|
| 38 | + unsigned long flags; |
---|
33 | 39 | wait_queue_head_t wait; |
---|
34 | 40 | struct i2c_adapter adap; |
---|
35 | 41 | struct i2c_msg *msg; |
---|
36 | 42 | int pos; |
---|
37 | 43 | int nmsgs; |
---|
38 | 44 | int state; /* see STATE_ */ |
---|
| 45 | + spinlock_t process_lock; |
---|
39 | 46 | struct clk *clk; |
---|
40 | 47 | int ip_clock_khz; |
---|
41 | 48 | int bus_clock_khz; |
---|
.. | .. |
---|
76 | 83 | |
---|
77 | 84 | #define TYPE_OCORES 0 |
---|
78 | 85 | #define TYPE_GRLIB 1 |
---|
| 86 | +#define TYPE_SIFIVE_REV0 2 |
---|
| 87 | + |
---|
| 88 | +#define OCORES_FLAG_BROKEN_IRQ BIT(1) /* Broken IRQ for FU540-C000 SoC */ |
---|
79 | 89 | |
---|
80 | 90 | static void oc_setreg_8(struct ocores_i2c *i2c, int reg, u8 value) |
---|
81 | 91 | { |
---|
.. | .. |
---|
127 | 137 | return ioread32be(i2c->base + (reg << i2c->reg_shift)); |
---|
128 | 138 | } |
---|
129 | 139 | |
---|
| 140 | +static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value) |
---|
| 141 | +{ |
---|
| 142 | + outb(value, i2c->iobase + reg); |
---|
| 143 | +} |
---|
| 144 | + |
---|
| 145 | +static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg) |
---|
| 146 | +{ |
---|
| 147 | + return inb(i2c->iobase + reg); |
---|
| 148 | +} |
---|
| 149 | + |
---|
130 | 150 | static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) |
---|
131 | 151 | { |
---|
132 | 152 | i2c->setreg(i2c, reg, value); |
---|
.. | .. |
---|
137 | 157 | return i2c->getreg(i2c, reg); |
---|
138 | 158 | } |
---|
139 | 159 | |
---|
140 | | -static void ocores_process(struct ocores_i2c *i2c) |
---|
| 160 | +static void ocores_process(struct ocores_i2c *i2c, u8 stat) |
---|
141 | 161 | { |
---|
142 | 162 | struct i2c_msg *msg = i2c->msg; |
---|
143 | | - u8 stat = oc_getreg(i2c, OCI2C_STATUS); |
---|
| 163 | + unsigned long flags; |
---|
| 164 | + |
---|
| 165 | + /* |
---|
| 166 | + * If we spin here is because we are in timeout, so we are going |
---|
| 167 | + * to be in STATE_ERROR. See ocores_process_timeout() |
---|
| 168 | + */ |
---|
| 169 | + spin_lock_irqsave(&i2c->process_lock, flags); |
---|
144 | 170 | |
---|
145 | 171 | if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { |
---|
146 | 172 | /* stop has been sent */ |
---|
147 | 173 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); |
---|
148 | 174 | wake_up(&i2c->wait); |
---|
149 | | - return; |
---|
| 175 | + goto out; |
---|
150 | 176 | } |
---|
151 | 177 | |
---|
152 | 178 | /* error? */ |
---|
153 | 179 | if (stat & OCI2C_STAT_ARBLOST) { |
---|
154 | 180 | i2c->state = STATE_ERROR; |
---|
155 | 181 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); |
---|
156 | | - return; |
---|
| 182 | + goto out; |
---|
157 | 183 | } |
---|
158 | 184 | |
---|
159 | 185 | if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { |
---|
.. | .. |
---|
163 | 189 | if (stat & OCI2C_STAT_NACK) { |
---|
164 | 190 | i2c->state = STATE_ERROR; |
---|
165 | 191 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); |
---|
166 | | - return; |
---|
| 192 | + goto out; |
---|
167 | 193 | } |
---|
168 | | - } else |
---|
| 194 | + } else { |
---|
169 | 195 | msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); |
---|
| 196 | + } |
---|
170 | 197 | |
---|
171 | 198 | /* end of msg? */ |
---|
172 | 199 | if (i2c->pos == msg->len) { |
---|
.. | .. |
---|
183 | 210 | i2c->state = STATE_START; |
---|
184 | 211 | |
---|
185 | 212 | oc_setreg(i2c, OCI2C_DATA, addr); |
---|
186 | | - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); |
---|
187 | | - return; |
---|
188 | | - } else |
---|
189 | | - i2c->state = (msg->flags & I2C_M_RD) |
---|
190 | | - ? STATE_READ : STATE_WRITE; |
---|
| 213 | + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); |
---|
| 214 | + goto out; |
---|
| 215 | + } |
---|
| 216 | + i2c->state = (msg->flags & I2C_M_RD) |
---|
| 217 | + ? STATE_READ : STATE_WRITE; |
---|
191 | 218 | } else { |
---|
192 | 219 | i2c->state = STATE_DONE; |
---|
193 | 220 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); |
---|
194 | | - return; |
---|
| 221 | + goto out; |
---|
195 | 222 | } |
---|
196 | 223 | } |
---|
197 | 224 | |
---|
.. | .. |
---|
202 | 229 | oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); |
---|
203 | 230 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); |
---|
204 | 231 | } |
---|
| 232 | + |
---|
| 233 | +out: |
---|
| 234 | + spin_unlock_irqrestore(&i2c->process_lock, flags); |
---|
205 | 235 | } |
---|
206 | 236 | |
---|
207 | 237 | static irqreturn_t ocores_isr(int irq, void *dev_id) |
---|
208 | 238 | { |
---|
209 | 239 | struct ocores_i2c *i2c = dev_id; |
---|
| 240 | + u8 stat = oc_getreg(i2c, OCI2C_STATUS); |
---|
210 | 241 | |
---|
211 | | - ocores_process(i2c); |
---|
| 242 | + if (i2c->flags & OCORES_FLAG_BROKEN_IRQ) { |
---|
| 243 | + if ((stat & OCI2C_STAT_IF) && !(stat & OCI2C_STAT_BUSY)) |
---|
| 244 | + return IRQ_NONE; |
---|
| 245 | + } else if (!(stat & OCI2C_STAT_IF)) { |
---|
| 246 | + return IRQ_NONE; |
---|
| 247 | + } |
---|
| 248 | + ocores_process(i2c, stat); |
---|
212 | 249 | |
---|
213 | 250 | return IRQ_HANDLED; |
---|
214 | 251 | } |
---|
215 | 252 | |
---|
216 | | -static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) |
---|
| 253 | +/** |
---|
| 254 | + * Process timeout event |
---|
| 255 | + * @i2c: ocores I2C device instance |
---|
| 256 | + */ |
---|
| 257 | +static void ocores_process_timeout(struct ocores_i2c *i2c) |
---|
217 | 258 | { |
---|
218 | | - struct ocores_i2c *i2c = i2c_get_adapdata(adap); |
---|
| 259 | + unsigned long flags; |
---|
| 260 | + |
---|
| 261 | + spin_lock_irqsave(&i2c->process_lock, flags); |
---|
| 262 | + i2c->state = STATE_ERROR; |
---|
| 263 | + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); |
---|
| 264 | + spin_unlock_irqrestore(&i2c->process_lock, flags); |
---|
| 265 | +} |
---|
| 266 | + |
---|
| 267 | +/** |
---|
| 268 | + * Wait until something change in a given register |
---|
| 269 | + * @i2c: ocores I2C device instance |
---|
| 270 | + * @reg: register to query |
---|
| 271 | + * @mask: bitmask to apply on register value |
---|
| 272 | + * @val: expected result |
---|
| 273 | + * @timeout: timeout in jiffies |
---|
| 274 | + * |
---|
| 275 | + * Timeout is necessary to avoid to stay here forever when the chip |
---|
| 276 | + * does not answer correctly. |
---|
| 277 | + * |
---|
| 278 | + * Return: 0 on success, -ETIMEDOUT on timeout |
---|
| 279 | + */ |
---|
| 280 | +static int ocores_wait(struct ocores_i2c *i2c, |
---|
| 281 | + int reg, u8 mask, u8 val, |
---|
| 282 | + const unsigned long timeout) |
---|
| 283 | +{ |
---|
| 284 | + unsigned long j; |
---|
| 285 | + |
---|
| 286 | + j = jiffies + timeout; |
---|
| 287 | + while (1) { |
---|
| 288 | + u8 status = oc_getreg(i2c, reg); |
---|
| 289 | + |
---|
| 290 | + if ((status & mask) == val) |
---|
| 291 | + break; |
---|
| 292 | + |
---|
| 293 | + if (time_after(jiffies, j)) |
---|
| 294 | + return -ETIMEDOUT; |
---|
| 295 | + } |
---|
| 296 | + return 0; |
---|
| 297 | +} |
---|
| 298 | + |
---|
| 299 | +/** |
---|
| 300 | + * Wait until is possible to process some data |
---|
| 301 | + * @i2c: ocores I2C device instance |
---|
| 302 | + * |
---|
| 303 | + * Used when the device is in polling mode (interrupts disabled). |
---|
| 304 | + * |
---|
| 305 | + * Return: 0 on success, -ETIMEDOUT on timeout |
---|
| 306 | + */ |
---|
| 307 | +static int ocores_poll_wait(struct ocores_i2c *i2c) |
---|
| 308 | +{ |
---|
| 309 | + u8 mask; |
---|
| 310 | + int err; |
---|
| 311 | + |
---|
| 312 | + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { |
---|
| 313 | + /* transfer is over */ |
---|
| 314 | + mask = OCI2C_STAT_BUSY; |
---|
| 315 | + } else { |
---|
| 316 | + /* on going transfer */ |
---|
| 317 | + mask = OCI2C_STAT_TIP; |
---|
| 318 | + /* |
---|
| 319 | + * We wait for the data to be transferred (8bit), |
---|
| 320 | + * then we start polling on the ACK/NACK bit |
---|
| 321 | + */ |
---|
| 322 | + udelay((8 * 1000) / i2c->bus_clock_khz); |
---|
| 323 | + } |
---|
| 324 | + |
---|
| 325 | + /* |
---|
| 326 | + * once we are here we expect to get the expected result immediately |
---|
| 327 | + * so if after 1ms we timeout then something is broken. |
---|
| 328 | + */ |
---|
| 329 | + err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(1)); |
---|
| 330 | + if (err) |
---|
| 331 | + dev_warn(i2c->adap.dev.parent, |
---|
| 332 | + "%s: STATUS timeout, bit 0x%x did not clear in 1ms\n", |
---|
| 333 | + __func__, mask); |
---|
| 334 | + return err; |
---|
| 335 | +} |
---|
| 336 | + |
---|
| 337 | +/** |
---|
| 338 | + * It handles an IRQ-less transfer |
---|
| 339 | + * @i2c: ocores I2C device instance |
---|
| 340 | + * |
---|
| 341 | + * Even if IRQ are disabled, the I2C OpenCore IP behavior is exactly the same |
---|
| 342 | + * (only that IRQ are not produced). This means that we can re-use entirely |
---|
| 343 | + * ocores_isr(), we just add our polling code around it. |
---|
| 344 | + * |
---|
| 345 | + * It can run in atomic context |
---|
| 346 | + */ |
---|
| 347 | +static void ocores_process_polling(struct ocores_i2c *i2c) |
---|
| 348 | +{ |
---|
| 349 | + while (1) { |
---|
| 350 | + irqreturn_t ret; |
---|
| 351 | + int err; |
---|
| 352 | + |
---|
| 353 | + err = ocores_poll_wait(i2c); |
---|
| 354 | + if (err) { |
---|
| 355 | + i2c->state = STATE_ERROR; |
---|
| 356 | + break; /* timeout */ |
---|
| 357 | + } |
---|
| 358 | + |
---|
| 359 | + ret = ocores_isr(-1, i2c); |
---|
| 360 | + if (ret == IRQ_NONE) |
---|
| 361 | + break; /* all messages have been transferred */ |
---|
| 362 | + else { |
---|
| 363 | + if (i2c->flags & OCORES_FLAG_BROKEN_IRQ) |
---|
| 364 | + if (i2c->state == STATE_DONE) |
---|
| 365 | + break; |
---|
| 366 | + } |
---|
| 367 | + } |
---|
| 368 | +} |
---|
| 369 | + |
---|
| 370 | +static int ocores_xfer_core(struct ocores_i2c *i2c, |
---|
| 371 | + struct i2c_msg *msgs, int num, |
---|
| 372 | + bool polling) |
---|
| 373 | +{ |
---|
| 374 | + int ret; |
---|
| 375 | + u8 ctrl; |
---|
| 376 | + |
---|
| 377 | + ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
---|
| 378 | + if (polling) |
---|
| 379 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); |
---|
| 380 | + else |
---|
| 381 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); |
---|
219 | 382 | |
---|
220 | 383 | i2c->msg = msgs; |
---|
221 | 384 | i2c->pos = 0; |
---|
.. | .. |
---|
225 | 388 | oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); |
---|
226 | 389 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); |
---|
227 | 390 | |
---|
228 | | - if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || |
---|
229 | | - (i2c->state == STATE_DONE), HZ)) |
---|
230 | | - return (i2c->state == STATE_DONE) ? num : -EIO; |
---|
231 | | - else |
---|
232 | | - return -ETIMEDOUT; |
---|
| 391 | + if (polling) { |
---|
| 392 | + ocores_process_polling(i2c); |
---|
| 393 | + } else { |
---|
| 394 | + ret = wait_event_timeout(i2c->wait, |
---|
| 395 | + (i2c->state == STATE_ERROR) || |
---|
| 396 | + (i2c->state == STATE_DONE), HZ); |
---|
| 397 | + if (ret == 0) { |
---|
| 398 | + ocores_process_timeout(i2c); |
---|
| 399 | + return -ETIMEDOUT; |
---|
| 400 | + } |
---|
| 401 | + } |
---|
| 402 | + |
---|
| 403 | + return (i2c->state == STATE_DONE) ? num : -EIO; |
---|
| 404 | +} |
---|
| 405 | + |
---|
| 406 | +static int ocores_xfer_polling(struct i2c_adapter *adap, |
---|
| 407 | + struct i2c_msg *msgs, int num) |
---|
| 408 | +{ |
---|
| 409 | + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, true); |
---|
| 410 | +} |
---|
| 411 | + |
---|
| 412 | +static int ocores_xfer(struct i2c_adapter *adap, |
---|
| 413 | + struct i2c_msg *msgs, int num) |
---|
| 414 | +{ |
---|
| 415 | + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, false); |
---|
233 | 416 | } |
---|
234 | 417 | |
---|
235 | 418 | static int ocores_init(struct device *dev, struct ocores_i2c *i2c) |
---|
.. | .. |
---|
239 | 422 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
---|
240 | 423 | |
---|
241 | 424 | /* make sure the device is disabled */ |
---|
242 | | - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
---|
| 425 | + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); |
---|
| 426 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl); |
---|
243 | 427 | |
---|
244 | 428 | prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; |
---|
245 | 429 | prescale = clamp(prescale, 0, 0xffff); |
---|
.. | .. |
---|
257 | 441 | |
---|
258 | 442 | /* Init the device */ |
---|
259 | 443 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); |
---|
260 | | - oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); |
---|
| 444 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); |
---|
261 | 445 | |
---|
262 | 446 | return 0; |
---|
263 | 447 | } |
---|
.. | .. |
---|
268 | 452 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
---|
269 | 453 | } |
---|
270 | 454 | |
---|
271 | | -static const struct i2c_algorithm ocores_algorithm = { |
---|
| 455 | +static struct i2c_algorithm ocores_algorithm = { |
---|
272 | 456 | .master_xfer = ocores_xfer, |
---|
| 457 | + .master_xfer_atomic = ocores_xfer_polling, |
---|
273 | 458 | .functionality = ocores_func, |
---|
274 | 459 | }; |
---|
275 | 460 | |
---|
.. | .. |
---|
289 | 474 | .compatible = "aeroflexgaisler,i2cmst", |
---|
290 | 475 | .data = (void *)TYPE_GRLIB, |
---|
291 | 476 | }, |
---|
| 477 | + { |
---|
| 478 | + .compatible = "sifive,fu540-c000-i2c", |
---|
| 479 | + .data = (void *)TYPE_SIFIVE_REV0, |
---|
| 480 | + }, |
---|
| 481 | + { |
---|
| 482 | + .compatible = "sifive,i2c0", |
---|
| 483 | + .data = (void *)TYPE_SIFIVE_REV0, |
---|
| 484 | + }, |
---|
292 | 485 | {}, |
---|
293 | 486 | }; |
---|
294 | 487 | MODULE_DEVICE_TABLE(of, ocores_i2c_match); |
---|
295 | 488 | |
---|
296 | 489 | #ifdef CONFIG_OF |
---|
297 | | -/* Read and write functions for the GRLIB port of the controller. Registers are |
---|
| 490 | +/* |
---|
| 491 | + * Read and write functions for the GRLIB port of the controller. Registers are |
---|
298 | 492 | * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one |
---|
299 | | - * register. The subsequent registers has their offset decreased accordingly. */ |
---|
| 493 | + * register. The subsequent registers have their offsets decreased accordingly. |
---|
| 494 | + */ |
---|
300 | 495 | static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) |
---|
301 | 496 | { |
---|
302 | 497 | u32 rd; |
---|
303 | 498 | int rreg = reg; |
---|
| 499 | + |
---|
304 | 500 | if (reg != OCI2C_PRELOW) |
---|
305 | 501 | rreg--; |
---|
306 | 502 | rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); |
---|
.. | .. |
---|
314 | 510 | { |
---|
315 | 511 | u32 curr, wr; |
---|
316 | 512 | int rreg = reg; |
---|
| 513 | + |
---|
317 | 514 | if (reg != OCI2C_PRELOW) |
---|
318 | 515 | rreg--; |
---|
319 | 516 | if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { |
---|
.. | .. |
---|
402 | 599 | return 0; |
---|
403 | 600 | } |
---|
404 | 601 | #else |
---|
405 | | -#define ocores_i2c_of_probe(pdev,i2c) -ENODEV |
---|
| 602 | +#define ocores_i2c_of_probe(pdev, i2c) -ENODEV |
---|
406 | 603 | #endif |
---|
407 | 604 | |
---|
408 | 605 | static int ocores_i2c_probe(struct platform_device *pdev) |
---|
409 | 606 | { |
---|
410 | 607 | struct ocores_i2c *i2c; |
---|
411 | 608 | struct ocores_i2c_platform_data *pdata; |
---|
| 609 | + const struct of_device_id *match; |
---|
412 | 610 | struct resource *res; |
---|
413 | 611 | int irq; |
---|
414 | 612 | int ret; |
---|
415 | 613 | int i; |
---|
416 | 614 | |
---|
417 | | - irq = platform_get_irq(pdev, 0); |
---|
418 | | - if (irq < 0) |
---|
419 | | - return irq; |
---|
420 | | - |
---|
421 | 615 | i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); |
---|
422 | 616 | if (!i2c) |
---|
423 | 617 | return -ENOMEM; |
---|
424 | 618 | |
---|
| 619 | + spin_lock_init(&i2c->process_lock); |
---|
| 620 | + |
---|
425 | 621 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
426 | | - i2c->base = devm_ioremap_resource(&pdev->dev, res); |
---|
427 | | - if (IS_ERR(i2c->base)) |
---|
428 | | - return PTR_ERR(i2c->base); |
---|
| 622 | + if (res) { |
---|
| 623 | + i2c->base = devm_ioremap_resource(&pdev->dev, res); |
---|
| 624 | + if (IS_ERR(i2c->base)) |
---|
| 625 | + return PTR_ERR(i2c->base); |
---|
| 626 | + } else { |
---|
| 627 | + res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
---|
| 628 | + if (!res) |
---|
| 629 | + return -EINVAL; |
---|
| 630 | + i2c->iobase = res->start; |
---|
| 631 | + if (!devm_request_region(&pdev->dev, res->start, |
---|
| 632 | + resource_size(res), |
---|
| 633 | + pdev->name)) { |
---|
| 634 | + dev_err(&pdev->dev, "Can't get I/O resource.\n"); |
---|
| 635 | + return -EBUSY; |
---|
| 636 | + } |
---|
| 637 | + i2c->setreg = oc_setreg_io_8; |
---|
| 638 | + i2c->getreg = oc_getreg_io_8; |
---|
| 639 | + } |
---|
429 | 640 | |
---|
430 | 641 | pdata = dev_get_platdata(&pdev->dev); |
---|
431 | 642 | if (pdata) { |
---|
432 | 643 | i2c->reg_shift = pdata->reg_shift; |
---|
433 | 644 | i2c->reg_io_width = pdata->reg_io_width; |
---|
434 | 645 | i2c->ip_clock_khz = pdata->clock_khz; |
---|
435 | | - i2c->bus_clock_khz = 100; |
---|
| 646 | + if (pdata->bus_khz) |
---|
| 647 | + i2c->bus_clock_khz = pdata->bus_khz; |
---|
| 648 | + else |
---|
| 649 | + i2c->bus_clock_khz = 100; |
---|
436 | 650 | } else { |
---|
437 | 651 | ret = ocores_i2c_of_probe(pdev, i2c); |
---|
438 | 652 | if (ret) |
---|
.. | .. |
---|
470 | 684 | } |
---|
471 | 685 | } |
---|
472 | 686 | |
---|
| 687 | + init_waitqueue_head(&i2c->wait); |
---|
| 688 | + |
---|
| 689 | + irq = platform_get_irq(pdev, 0); |
---|
| 690 | + if (irq == -ENXIO) { |
---|
| 691 | + ocores_algorithm.master_xfer = ocores_xfer_polling; |
---|
| 692 | + |
---|
| 693 | + /* |
---|
| 694 | + * Set in OCORES_FLAG_BROKEN_IRQ to enable workaround for |
---|
| 695 | + * FU540-C000 SoC in polling mode. |
---|
| 696 | + */ |
---|
| 697 | + match = of_match_node(ocores_i2c_match, pdev->dev.of_node); |
---|
| 698 | + if (match && (long)match->data == TYPE_SIFIVE_REV0) |
---|
| 699 | + i2c->flags |= OCORES_FLAG_BROKEN_IRQ; |
---|
| 700 | + } else { |
---|
| 701 | + if (irq < 0) |
---|
| 702 | + return irq; |
---|
| 703 | + } |
---|
| 704 | + |
---|
| 705 | + if (ocores_algorithm.master_xfer != ocores_xfer_polling) { |
---|
| 706 | + ret = devm_request_any_context_irq(&pdev->dev, irq, |
---|
| 707 | + ocores_isr, 0, |
---|
| 708 | + pdev->name, i2c); |
---|
| 709 | + if (ret) { |
---|
| 710 | + dev_err(&pdev->dev, "Cannot claim IRQ\n"); |
---|
| 711 | + goto err_clk; |
---|
| 712 | + } |
---|
| 713 | + } |
---|
| 714 | + |
---|
473 | 715 | ret = ocores_init(&pdev->dev, i2c); |
---|
474 | 716 | if (ret) |
---|
475 | 717 | goto err_clk; |
---|
476 | | - |
---|
477 | | - init_waitqueue_head(&i2c->wait); |
---|
478 | | - ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, |
---|
479 | | - pdev->name, i2c); |
---|
480 | | - if (ret) { |
---|
481 | | - dev_err(&pdev->dev, "Cannot claim IRQ\n"); |
---|
482 | | - goto err_clk; |
---|
483 | | - } |
---|
484 | 718 | |
---|
485 | 719 | /* hook up driver to tree */ |
---|
486 | 720 | platform_set_drvdata(pdev, i2c); |
---|
.. | .. |
---|
497 | 731 | /* add in known devices to the bus */ |
---|
498 | 732 | if (pdata) { |
---|
499 | 733 | for (i = 0; i < pdata->num_devices; i++) |
---|
500 | | - i2c_new_device(&i2c->adap, pdata->devices + i); |
---|
| 734 | + i2c_new_client_device(&i2c->adap, pdata->devices + i); |
---|
501 | 735 | } |
---|
502 | 736 | |
---|
503 | 737 | return 0; |
---|
.. | .. |
---|
510 | 744 | static int ocores_i2c_remove(struct platform_device *pdev) |
---|
511 | 745 | { |
---|
512 | 746 | struct ocores_i2c *i2c = platform_get_drvdata(pdev); |
---|
| 747 | + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
---|
513 | 748 | |
---|
514 | 749 | /* disable i2c logic */ |
---|
515 | | - oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) |
---|
516 | | - & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
---|
| 750 | + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); |
---|
| 751 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl); |
---|
517 | 752 | |
---|
518 | 753 | /* remove adapter & data */ |
---|
519 | 754 | i2c_del_adapter(&i2c->adap); |
---|
.. | .. |
---|
531 | 766 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
---|
532 | 767 | |
---|
533 | 768 | /* make sure the device is disabled */ |
---|
534 | | - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
---|
| 769 | + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); |
---|
| 770 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl); |
---|
535 | 771 | |
---|
536 | 772 | if (!IS_ERR(i2c->clk)) |
---|
537 | 773 | clk_disable_unprepare(i2c->clk); |
---|