| .. | .. |
|---|
| 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 | + * Return: 0 on success, -ETIMEDOUT on timeout |
|---|
| 348 | + */ |
|---|
| 349 | +static int ocores_process_polling(struct ocores_i2c *i2c) |
|---|
| 350 | +{ |
|---|
| 351 | + irqreturn_t ret; |
|---|
| 352 | + int err = 0; |
|---|
| 353 | + |
|---|
| 354 | + while (1) { |
|---|
| 355 | + err = ocores_poll_wait(i2c); |
|---|
| 356 | + if (err) |
|---|
| 357 | + break; /* timeout */ |
|---|
| 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 | + return err; |
|---|
| 370 | +} |
|---|
| 371 | + |
|---|
| 372 | +static int ocores_xfer_core(struct ocores_i2c *i2c, |
|---|
| 373 | + struct i2c_msg *msgs, int num, |
|---|
| 374 | + bool polling) |
|---|
| 375 | +{ |
|---|
| 376 | + int ret = 0; |
|---|
| 377 | + u8 ctrl; |
|---|
| 378 | + |
|---|
| 379 | + ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
|---|
| 380 | + if (polling) |
|---|
| 381 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~OCI2C_CTRL_IEN); |
|---|
| 382 | + else |
|---|
| 383 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN); |
|---|
| 219 | 384 | |
|---|
| 220 | 385 | i2c->msg = msgs; |
|---|
| 221 | 386 | i2c->pos = 0; |
|---|
| .. | .. |
|---|
| 225 | 390 | oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); |
|---|
| 226 | 391 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); |
|---|
| 227 | 392 | |
|---|
| 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; |
|---|
| 393 | + if (polling) { |
|---|
| 394 | + ret = ocores_process_polling(i2c); |
|---|
| 395 | + } else { |
|---|
| 396 | + if (wait_event_timeout(i2c->wait, |
|---|
| 397 | + (i2c->state == STATE_ERROR) || |
|---|
| 398 | + (i2c->state == STATE_DONE), HZ) == 0) |
|---|
| 399 | + ret = -ETIMEDOUT; |
|---|
| 400 | + } |
|---|
| 401 | + if (ret) { |
|---|
| 402 | + ocores_process_timeout(i2c); |
|---|
| 403 | + return ret; |
|---|
| 404 | + } |
|---|
| 405 | + |
|---|
| 406 | + return (i2c->state == STATE_DONE) ? num : -EIO; |
|---|
| 407 | +} |
|---|
| 408 | + |
|---|
| 409 | +static int ocores_xfer_polling(struct i2c_adapter *adap, |
|---|
| 410 | + struct i2c_msg *msgs, int num) |
|---|
| 411 | +{ |
|---|
| 412 | + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, true); |
|---|
| 413 | +} |
|---|
| 414 | + |
|---|
| 415 | +static int ocores_xfer(struct i2c_adapter *adap, |
|---|
| 416 | + struct i2c_msg *msgs, int num) |
|---|
| 417 | +{ |
|---|
| 418 | + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, false); |
|---|
| 233 | 419 | } |
|---|
| 234 | 420 | |
|---|
| 235 | 421 | static int ocores_init(struct device *dev, struct ocores_i2c *i2c) |
|---|
| .. | .. |
|---|
| 239 | 425 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
|---|
| 240 | 426 | |
|---|
| 241 | 427 | /* make sure the device is disabled */ |
|---|
| 242 | | - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
|---|
| 428 | + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); |
|---|
| 429 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl); |
|---|
| 243 | 430 | |
|---|
| 244 | 431 | prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; |
|---|
| 245 | 432 | prescale = clamp(prescale, 0, 0xffff); |
|---|
| .. | .. |
|---|
| 257 | 444 | |
|---|
| 258 | 445 | /* Init the device */ |
|---|
| 259 | 446 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); |
|---|
| 260 | | - oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); |
|---|
| 447 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); |
|---|
| 261 | 448 | |
|---|
| 262 | 449 | return 0; |
|---|
| 263 | 450 | } |
|---|
| .. | .. |
|---|
| 268 | 455 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
|---|
| 269 | 456 | } |
|---|
| 270 | 457 | |
|---|
| 271 | | -static const struct i2c_algorithm ocores_algorithm = { |
|---|
| 458 | +static struct i2c_algorithm ocores_algorithm = { |
|---|
| 272 | 459 | .master_xfer = ocores_xfer, |
|---|
| 460 | + .master_xfer_atomic = ocores_xfer_polling, |
|---|
| 273 | 461 | .functionality = ocores_func, |
|---|
| 274 | 462 | }; |
|---|
| 275 | 463 | |
|---|
| .. | .. |
|---|
| 289 | 477 | .compatible = "aeroflexgaisler,i2cmst", |
|---|
| 290 | 478 | .data = (void *)TYPE_GRLIB, |
|---|
| 291 | 479 | }, |
|---|
| 480 | + { |
|---|
| 481 | + .compatible = "sifive,fu540-c000-i2c", |
|---|
| 482 | + .data = (void *)TYPE_SIFIVE_REV0, |
|---|
| 483 | + }, |
|---|
| 484 | + { |
|---|
| 485 | + .compatible = "sifive,i2c0", |
|---|
| 486 | + .data = (void *)TYPE_SIFIVE_REV0, |
|---|
| 487 | + }, |
|---|
| 292 | 488 | {}, |
|---|
| 293 | 489 | }; |
|---|
| 294 | 490 | MODULE_DEVICE_TABLE(of, ocores_i2c_match); |
|---|
| 295 | 491 | |
|---|
| 296 | 492 | #ifdef CONFIG_OF |
|---|
| 297 | | -/* Read and write functions for the GRLIB port of the controller. Registers are |
|---|
| 493 | +/* |
|---|
| 494 | + * Read and write functions for the GRLIB port of the controller. Registers are |
|---|
| 298 | 495 | * 32-bit big endian and the PRELOW and PREHIGH registers are merged into one |
|---|
| 299 | | - * register. The subsequent registers has their offset decreased accordingly. */ |
|---|
| 496 | + * register. The subsequent registers have their offsets decreased accordingly. |
|---|
| 497 | + */ |
|---|
| 300 | 498 | static u8 oc_getreg_grlib(struct ocores_i2c *i2c, int reg) |
|---|
| 301 | 499 | { |
|---|
| 302 | 500 | u32 rd; |
|---|
| 303 | 501 | int rreg = reg; |
|---|
| 502 | + |
|---|
| 304 | 503 | if (reg != OCI2C_PRELOW) |
|---|
| 305 | 504 | rreg--; |
|---|
| 306 | 505 | rd = ioread32be(i2c->base + (rreg << i2c->reg_shift)); |
|---|
| .. | .. |
|---|
| 314 | 513 | { |
|---|
| 315 | 514 | u32 curr, wr; |
|---|
| 316 | 515 | int rreg = reg; |
|---|
| 516 | + |
|---|
| 317 | 517 | if (reg != OCI2C_PRELOW) |
|---|
| 318 | 518 | rreg--; |
|---|
| 319 | 519 | if (reg == OCI2C_PRELOW || reg == OCI2C_PREHIGH) { |
|---|
| .. | .. |
|---|
| 402 | 602 | return 0; |
|---|
| 403 | 603 | } |
|---|
| 404 | 604 | #else |
|---|
| 405 | | -#define ocores_i2c_of_probe(pdev,i2c) -ENODEV |
|---|
| 605 | +#define ocores_i2c_of_probe(pdev, i2c) -ENODEV |
|---|
| 406 | 606 | #endif |
|---|
| 407 | 607 | |
|---|
| 408 | 608 | static int ocores_i2c_probe(struct platform_device *pdev) |
|---|
| 409 | 609 | { |
|---|
| 410 | 610 | struct ocores_i2c *i2c; |
|---|
| 411 | 611 | struct ocores_i2c_platform_data *pdata; |
|---|
| 612 | + const struct of_device_id *match; |
|---|
| 412 | 613 | struct resource *res; |
|---|
| 413 | 614 | int irq; |
|---|
| 414 | 615 | int ret; |
|---|
| 415 | 616 | int i; |
|---|
| 416 | 617 | |
|---|
| 417 | | - irq = platform_get_irq(pdev, 0); |
|---|
| 418 | | - if (irq < 0) |
|---|
| 419 | | - return irq; |
|---|
| 420 | | - |
|---|
| 421 | 618 | i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); |
|---|
| 422 | 619 | if (!i2c) |
|---|
| 423 | 620 | return -ENOMEM; |
|---|
| 424 | 621 | |
|---|
| 622 | + spin_lock_init(&i2c->process_lock); |
|---|
| 623 | + |
|---|
| 425 | 624 | 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); |
|---|
| 625 | + if (res) { |
|---|
| 626 | + i2c->base = devm_ioremap_resource(&pdev->dev, res); |
|---|
| 627 | + if (IS_ERR(i2c->base)) |
|---|
| 628 | + return PTR_ERR(i2c->base); |
|---|
| 629 | + } else { |
|---|
| 630 | + res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
|---|
| 631 | + if (!res) |
|---|
| 632 | + return -EINVAL; |
|---|
| 633 | + i2c->iobase = res->start; |
|---|
| 634 | + if (!devm_request_region(&pdev->dev, res->start, |
|---|
| 635 | + resource_size(res), |
|---|
| 636 | + pdev->name)) { |
|---|
| 637 | + dev_err(&pdev->dev, "Can't get I/O resource.\n"); |
|---|
| 638 | + return -EBUSY; |
|---|
| 639 | + } |
|---|
| 640 | + i2c->setreg = oc_setreg_io_8; |
|---|
| 641 | + i2c->getreg = oc_getreg_io_8; |
|---|
| 642 | + } |
|---|
| 429 | 643 | |
|---|
| 430 | 644 | pdata = dev_get_platdata(&pdev->dev); |
|---|
| 431 | 645 | if (pdata) { |
|---|
| 432 | 646 | i2c->reg_shift = pdata->reg_shift; |
|---|
| 433 | 647 | i2c->reg_io_width = pdata->reg_io_width; |
|---|
| 434 | 648 | i2c->ip_clock_khz = pdata->clock_khz; |
|---|
| 435 | | - i2c->bus_clock_khz = 100; |
|---|
| 649 | + if (pdata->bus_khz) |
|---|
| 650 | + i2c->bus_clock_khz = pdata->bus_khz; |
|---|
| 651 | + else |
|---|
| 652 | + i2c->bus_clock_khz = 100; |
|---|
| 436 | 653 | } else { |
|---|
| 437 | 654 | ret = ocores_i2c_of_probe(pdev, i2c); |
|---|
| 438 | 655 | if (ret) |
|---|
| .. | .. |
|---|
| 470 | 687 | } |
|---|
| 471 | 688 | } |
|---|
| 472 | 689 | |
|---|
| 690 | + init_waitqueue_head(&i2c->wait); |
|---|
| 691 | + |
|---|
| 692 | + irq = platform_get_irq(pdev, 0); |
|---|
| 693 | + if (irq == -ENXIO) { |
|---|
| 694 | + ocores_algorithm.master_xfer = ocores_xfer_polling; |
|---|
| 695 | + |
|---|
| 696 | + /* |
|---|
| 697 | + * Set in OCORES_FLAG_BROKEN_IRQ to enable workaround for |
|---|
| 698 | + * FU540-C000 SoC in polling mode. |
|---|
| 699 | + */ |
|---|
| 700 | + match = of_match_node(ocores_i2c_match, pdev->dev.of_node); |
|---|
| 701 | + if (match && (long)match->data == TYPE_SIFIVE_REV0) |
|---|
| 702 | + i2c->flags |= OCORES_FLAG_BROKEN_IRQ; |
|---|
| 703 | + } else { |
|---|
| 704 | + if (irq < 0) |
|---|
| 705 | + return irq; |
|---|
| 706 | + } |
|---|
| 707 | + |
|---|
| 708 | + if (ocores_algorithm.master_xfer != ocores_xfer_polling) { |
|---|
| 709 | + ret = devm_request_any_context_irq(&pdev->dev, irq, |
|---|
| 710 | + ocores_isr, 0, |
|---|
| 711 | + pdev->name, i2c); |
|---|
| 712 | + if (ret) { |
|---|
| 713 | + dev_err(&pdev->dev, "Cannot claim IRQ\n"); |
|---|
| 714 | + goto err_clk; |
|---|
| 715 | + } |
|---|
| 716 | + } |
|---|
| 717 | + |
|---|
| 473 | 718 | ret = ocores_init(&pdev->dev, i2c); |
|---|
| 474 | 719 | if (ret) |
|---|
| 475 | 720 | 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 | 721 | |
|---|
| 485 | 722 | /* hook up driver to tree */ |
|---|
| 486 | 723 | platform_set_drvdata(pdev, i2c); |
|---|
| .. | .. |
|---|
| 497 | 734 | /* add in known devices to the bus */ |
|---|
| 498 | 735 | if (pdata) { |
|---|
| 499 | 736 | for (i = 0; i < pdata->num_devices; i++) |
|---|
| 500 | | - i2c_new_device(&i2c->adap, pdata->devices + i); |
|---|
| 737 | + i2c_new_client_device(&i2c->adap, pdata->devices + i); |
|---|
| 501 | 738 | } |
|---|
| 502 | 739 | |
|---|
| 503 | 740 | return 0; |
|---|
| .. | .. |
|---|
| 510 | 747 | static int ocores_i2c_remove(struct platform_device *pdev) |
|---|
| 511 | 748 | { |
|---|
| 512 | 749 | struct ocores_i2c *i2c = platform_get_drvdata(pdev); |
|---|
| 750 | + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
|---|
| 513 | 751 | |
|---|
| 514 | 752 | /* disable i2c logic */ |
|---|
| 515 | | - oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) |
|---|
| 516 | | - & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
|---|
| 753 | + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); |
|---|
| 754 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl); |
|---|
| 517 | 755 | |
|---|
| 518 | 756 | /* remove adapter & data */ |
|---|
| 519 | 757 | i2c_del_adapter(&i2c->adap); |
|---|
| .. | .. |
|---|
| 531 | 769 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); |
|---|
| 532 | 770 | |
|---|
| 533 | 771 | /* make sure the device is disabled */ |
|---|
| 534 | | - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); |
|---|
| 772 | + ctrl &= ~(OCI2C_CTRL_EN | OCI2C_CTRL_IEN); |
|---|
| 773 | + oc_setreg(i2c, OCI2C_CONTROL, ctrl); |
|---|
| 535 | 774 | |
|---|
| 536 | 775 | if (!IS_ERR(i2c->clk)) |
|---|
| 537 | 776 | clk_disable_unprepare(i2c->clk); |
|---|