diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-05 21:13:35 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-05 21:13:35 -0500 |
| commit | 7671c14e6aca7a816a29a85eba47d9bccb7d23ae (patch) | |
| tree | 381c65c9669735d856d22d333967c3a8dcfdfb37 /drivers/i2c | |
| parent | 926b02d3eb547daa1d56cf9b586f31b270488b77 (diff) | |
| parent | 81482d13f37b1c9354d9bf5491699d993b193246 (diff) | |
Merge branch 'i2c/for-5.0' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"I2C has only driver updates for you this time.
Mostly new IDs/DT compatibles, also SPDX conversions, small cleanups.
STM32F7 got FastMode+ and PM support, Axxia some reliabilty
improvements"
* 'i2c/for-5.0' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (26 commits)
i2c: Add Actions Semiconductor Owl family S700 I2C support
dt-bindings: i2c: Add S700 support for Actions Semi Soc's
i2c: ismt: Add support for Intel Cedar Fork
i2c: tegra: Switch to SPDX identifier
i2c: tegra: Add missing kerneldoc for some fields
i2c: tegra: Cleanup kerneldoc comments
i2c: axxia: support sequence command mode
dt-bindings: i2c: rcar: Add r8a774c0 support
dt-bindings: i2c: sh_mobile: Add r8a774c0 support
i2c: sh_mobile: Add support for r8a774c0 (RZ/G2E)
i2c: i2c-cros-ec-tunnel: Switch to SPDX identifier.
i2c: powermac: Use of_node_name_eq for node name comparisons
i2c-axxia: check for error conditions first
i2c-axxia: dedicated function to set client addr
dt-bindings: i2c: Use correct vendor prefix for Atmel
i2c: tegra: replace spin_lock_irqsave with spin_lock in ISR
eeprom: at24: add support for 24c2048
dt-bindings: eeprom: at24: add "atmel,24c2048" compatible string
i2c: i2c-stm32f7: add PM Runtime support
i2c: sh_mobile: add support for r8a77990 (R-Car E3)
...
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-axxia.c | 168 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-bcm2835.c | 10 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-cros-ec-tunnel.c | 14 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-imx.c | 3 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ismt.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-owl.c | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-powermac.c | 8 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f7.c | 182 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 54 |
11 files changed, 317 insertions, 129 deletions
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c index 51d34959709b..bf564391091f 100644 --- a/drivers/i2c/busses/i2c-axxia.c +++ b/drivers/i2c/busses/i2c-axxia.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | */ | 12 | */ |
| 13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
| 14 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
| 15 | #include <linux/delay.h> | ||
| 15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 16 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
| 17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| @@ -25,6 +26,7 @@ | |||
| 25 | #define I2C_XFER_TIMEOUT (msecs_to_jiffies(250)) | 26 | #define I2C_XFER_TIMEOUT (msecs_to_jiffies(250)) |
| 26 | #define I2C_STOP_TIMEOUT (msecs_to_jiffies(100)) | 27 | #define I2C_STOP_TIMEOUT (msecs_to_jiffies(100)) |
| 27 | #define FIFO_SIZE 8 | 28 | #define FIFO_SIZE 8 |
| 29 | #define SEQ_LEN 2 | ||
| 28 | 30 | ||
| 29 | #define GLOBAL_CONTROL 0x00 | 31 | #define GLOBAL_CONTROL 0x00 |
| 30 | #define GLOBAL_MST_EN BIT(0) | 32 | #define GLOBAL_MST_EN BIT(0) |
| @@ -51,6 +53,7 @@ | |||
| 51 | #define CMD_BUSY (1<<3) | 53 | #define CMD_BUSY (1<<3) |
| 52 | #define CMD_MANUAL (0x00 | CMD_BUSY) | 54 | #define CMD_MANUAL (0x00 | CMD_BUSY) |
| 53 | #define CMD_AUTO (0x01 | CMD_BUSY) | 55 | #define CMD_AUTO (0x01 | CMD_BUSY) |
| 56 | #define CMD_SEQUENCE (0x02 | CMD_BUSY) | ||
| 54 | #define MST_RX_XFER 0x2c | 57 | #define MST_RX_XFER 0x2c |
| 55 | #define MST_TX_XFER 0x30 | 58 | #define MST_TX_XFER 0x30 |
| 56 | #define MST_ADDR_1 0x34 | 59 | #define MST_ADDR_1 0x34 |
| @@ -87,7 +90,9 @@ | |||
| 87 | * axxia_i2c_dev - I2C device context | 90 | * axxia_i2c_dev - I2C device context |
| 88 | * @base: pointer to register struct | 91 | * @base: pointer to register struct |
| 89 | * @msg: pointer to current message | 92 | * @msg: pointer to current message |
| 90 | * @msg_xfrd: number of bytes transferred in msg | 93 | * @msg_r: pointer to current read message (sequence transfer) |
| 94 | * @msg_xfrd: number of bytes transferred in tx_fifo | ||
| 95 | * @msg_xfrd_r: number of bytes transferred in rx_fifo | ||
| 91 | * @msg_err: error code for completed message | 96 | * @msg_err: error code for completed message |
| 92 | * @msg_complete: xfer completion object | 97 | * @msg_complete: xfer completion object |
| 93 | * @dev: device reference | 98 | * @dev: device reference |
| @@ -98,7 +103,9 @@ | |||
| 98 | struct axxia_i2c_dev { | 103 | struct axxia_i2c_dev { |
| 99 | void __iomem *base; | 104 | void __iomem *base; |
| 100 | struct i2c_msg *msg; | 105 | struct i2c_msg *msg; |
| 106 | struct i2c_msg *msg_r; | ||
| 101 | size_t msg_xfrd; | 107 | size_t msg_xfrd; |
| 108 | size_t msg_xfrd_r; | ||
| 102 | int msg_err; | 109 | int msg_err; |
| 103 | struct completion msg_complete; | 110 | struct completion msg_complete; |
| 104 | struct device *dev; | 111 | struct device *dev; |
| @@ -227,14 +234,14 @@ static int i2c_m_recv_len(const struct i2c_msg *msg) | |||
| 227 | */ | 234 | */ |
| 228 | static int axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev) | 235 | static int axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev) |
| 229 | { | 236 | { |
| 230 | struct i2c_msg *msg = idev->msg; | 237 | struct i2c_msg *msg = idev->msg_r; |
| 231 | size_t rx_fifo_avail = readl(idev->base + MST_RX_FIFO); | 238 | size_t rx_fifo_avail = readl(idev->base + MST_RX_FIFO); |
| 232 | int bytes_to_transfer = min(rx_fifo_avail, msg->len - idev->msg_xfrd); | 239 | int bytes_to_transfer = min(rx_fifo_avail, msg->len - idev->msg_xfrd_r); |
| 233 | 240 | ||
| 234 | while (bytes_to_transfer-- > 0) { | 241 | while (bytes_to_transfer-- > 0) { |
| 235 | int c = readl(idev->base + MST_DATA); | 242 | int c = readl(idev->base + MST_DATA); |
| 236 | 243 | ||
| 237 | if (idev->msg_xfrd == 0 && i2c_m_recv_len(msg)) { | 244 | if (idev->msg_xfrd_r == 0 && i2c_m_recv_len(msg)) { |
| 238 | /* | 245 | /* |
| 239 | * Check length byte for SMBus block read | 246 | * Check length byte for SMBus block read |
| 240 | */ | 247 | */ |
| @@ -247,7 +254,7 @@ static int axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev) | |||
| 247 | msg->len = 1 + c; | 254 | msg->len = 1 + c; |
| 248 | writel(msg->len, idev->base + MST_RX_XFER); | 255 | writel(msg->len, idev->base + MST_RX_XFER); |
| 249 | } | 256 | } |
| 250 | msg->buf[idev->msg_xfrd++] = c; | 257 | msg->buf[idev->msg_xfrd_r++] = c; |
| 251 | } | 258 | } |
| 252 | 259 | ||
| 253 | return 0; | 260 | return 0; |
| @@ -287,7 +294,7 @@ static irqreturn_t axxia_i2c_isr(int irq, void *_dev) | |||
| 287 | } | 294 | } |
| 288 | 295 | ||
| 289 | /* RX FIFO needs service? */ | 296 | /* RX FIFO needs service? */ |
| 290 | if (i2c_m_rd(idev->msg) && (status & MST_STATUS_RFL)) | 297 | if (i2c_m_rd(idev->msg_r) && (status & MST_STATUS_RFL)) |
| 291 | axxia_i2c_empty_rx_fifo(idev); | 298 | axxia_i2c_empty_rx_fifo(idev); |
| 292 | 299 | ||
| 293 | /* TX FIFO needs service? */ | 300 | /* TX FIFO needs service? */ |
| @@ -296,22 +303,7 @@ static irqreturn_t axxia_i2c_isr(int irq, void *_dev) | |||
| 296 | i2c_int_disable(idev, MST_STATUS_TFL); | 303 | i2c_int_disable(idev, MST_STATUS_TFL); |
| 297 | } | 304 | } |
| 298 | 305 | ||
| 299 | if (status & MST_STATUS_SCC) { | 306 | if (unlikely(status & MST_STATUS_ERR)) { |
| 300 | /* Stop completed */ | ||
| 301 | i2c_int_disable(idev, ~MST_STATUS_TSS); | ||
| 302 | complete(&idev->msg_complete); | ||
| 303 | } else if (status & MST_STATUS_SNS) { | ||
| 304 | /* Transfer done */ | ||
| 305 | i2c_int_disable(idev, ~MST_STATUS_TSS); | ||
| 306 | if (i2c_m_rd(idev->msg) && idev->msg_xfrd < idev->msg->len) | ||
| 307 | axxia_i2c_empty_rx_fifo(idev); | ||
| 308 | complete(&idev->msg_complete); | ||
| 309 | } else if (status & MST_STATUS_TSS) { | ||
| 310 | /* Transfer timeout */ | ||
| 311 | idev->msg_err = -ETIMEDOUT; | ||
| 312 | i2c_int_disable(idev, ~MST_STATUS_TSS); | ||
| 313 | complete(&idev->msg_complete); | ||
| 314 | } else if (unlikely(status & MST_STATUS_ERR)) { | ||
| 315 | /* Transfer error */ | 307 | /* Transfer error */ |
| 316 | i2c_int_disable(idev, ~0); | 308 | i2c_int_disable(idev, ~0); |
| 317 | if (status & MST_STATUS_AL) | 309 | if (status & MST_STATUS_AL) |
| @@ -328,6 +320,24 @@ static irqreturn_t axxia_i2c_isr(int irq, void *_dev) | |||
| 328 | readl(idev->base + MST_TX_BYTES_XFRD), | 320 | readl(idev->base + MST_TX_BYTES_XFRD), |
| 329 | readl(idev->base + MST_TX_XFER)); | 321 | readl(idev->base + MST_TX_XFER)); |
| 330 | complete(&idev->msg_complete); | 322 | complete(&idev->msg_complete); |
| 323 | } else if (status & MST_STATUS_SCC) { | ||
| 324 | /* Stop completed */ | ||
| 325 | i2c_int_disable(idev, ~MST_STATUS_TSS); | ||
| 326 | complete(&idev->msg_complete); | ||
| 327 | } else if (status & MST_STATUS_SNS) { | ||
| 328 | /* Transfer done */ | ||
| 329 | i2c_int_disable(idev, ~MST_STATUS_TSS); | ||
| 330 | if (i2c_m_rd(idev->msg_r) && idev->msg_xfrd_r < idev->msg_r->len) | ||
| 331 | axxia_i2c_empty_rx_fifo(idev); | ||
| 332 | complete(&idev->msg_complete); | ||
| 333 | } else if (status & MST_STATUS_SS) { | ||
| 334 | /* Auto/Sequence transfer done */ | ||
| 335 | complete(&idev->msg_complete); | ||
| 336 | } else if (status & MST_STATUS_TSS) { | ||
| 337 | /* Transfer timeout */ | ||
| 338 | idev->msg_err = -ETIMEDOUT; | ||
| 339 | i2c_int_disable(idev, ~MST_STATUS_TSS); | ||
| 340 | complete(&idev->msg_complete); | ||
| 331 | } | 341 | } |
| 332 | 342 | ||
| 333 | out: | 343 | out: |
| @@ -337,17 +347,9 @@ out: | |||
| 337 | return IRQ_HANDLED; | 347 | return IRQ_HANDLED; |
| 338 | } | 348 | } |
| 339 | 349 | ||
| 340 | static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) | 350 | static void axxia_i2c_set_addr(struct axxia_i2c_dev *idev, struct i2c_msg *msg) |
| 341 | { | 351 | { |
| 342 | u32 int_mask = MST_STATUS_ERR | MST_STATUS_SNS; | ||
| 343 | u32 rx_xfer, tx_xfer; | ||
| 344 | u32 addr_1, addr_2; | 352 | u32 addr_1, addr_2; |
| 345 | unsigned long time_left; | ||
| 346 | unsigned int wt_value; | ||
| 347 | |||
| 348 | idev->msg = msg; | ||
| 349 | idev->msg_xfrd = 0; | ||
| 350 | reinit_completion(&idev->msg_complete); | ||
| 351 | 353 | ||
| 352 | if (i2c_m_ten(msg)) { | 354 | if (i2c_m_ten(msg)) { |
| 353 | /* 10-bit address | 355 | /* 10-bit address |
| @@ -367,6 +369,90 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) | |||
| 367 | addr_2 = 0; | 369 | addr_2 = 0; |
| 368 | } | 370 | } |
| 369 | 371 | ||
| 372 | writel(addr_1, idev->base + MST_ADDR_1); | ||
| 373 | writel(addr_2, idev->base + MST_ADDR_2); | ||
| 374 | } | ||
| 375 | |||
| 376 | /* The NAK interrupt will be sent _before_ issuing STOP command | ||
| 377 | * so the controller might still be busy processing it. No | ||
| 378 | * interrupt will be sent at the end so we have to poll for it | ||
| 379 | */ | ||
| 380 | static int axxia_i2c_handle_seq_nak(struct axxia_i2c_dev *idev) | ||
| 381 | { | ||
| 382 | unsigned long timeout = jiffies + I2C_XFER_TIMEOUT; | ||
| 383 | |||
| 384 | do { | ||
| 385 | if ((readl(idev->base + MST_COMMAND) & CMD_BUSY) == 0) | ||
| 386 | return 0; | ||
| 387 | usleep_range(1, 100); | ||
| 388 | } while (time_before(jiffies, timeout)); | ||
| 389 | |||
| 390 | return -ETIMEDOUT; | ||
| 391 | } | ||
| 392 | |||
| 393 | static int axxia_i2c_xfer_seq(struct axxia_i2c_dev *idev, struct i2c_msg msgs[]) | ||
| 394 | { | ||
| 395 | u32 int_mask = MST_STATUS_ERR | MST_STATUS_SS | MST_STATUS_RFL; | ||
| 396 | u32 rlen = i2c_m_recv_len(&msgs[1]) ? I2C_SMBUS_BLOCK_MAX : msgs[1].len; | ||
| 397 | unsigned long time_left; | ||
| 398 | |||
| 399 | axxia_i2c_set_addr(idev, &msgs[0]); | ||
| 400 | |||
| 401 | writel(msgs[0].len, idev->base + MST_TX_XFER); | ||
| 402 | writel(rlen, idev->base + MST_RX_XFER); | ||
| 403 | |||
| 404 | idev->msg = &msgs[0]; | ||
| 405 | idev->msg_r = &msgs[1]; | ||
| 406 | idev->msg_xfrd = 0; | ||
| 407 | idev->msg_xfrd_r = 0; | ||
| 408 | axxia_i2c_fill_tx_fifo(idev); | ||
| 409 | |||
| 410 | writel(CMD_SEQUENCE, idev->base + MST_COMMAND); | ||
| 411 | |||
| 412 | reinit_completion(&idev->msg_complete); | ||
| 413 | i2c_int_enable(idev, int_mask); | ||
| 414 | |||
| 415 | time_left = wait_for_completion_timeout(&idev->msg_complete, | ||
| 416 | I2C_XFER_TIMEOUT); | ||
| 417 | |||
| 418 | i2c_int_disable(idev, int_mask); | ||
| 419 | |||
| 420 | axxia_i2c_empty_rx_fifo(idev); | ||
| 421 | |||
| 422 | if (idev->msg_err == -ENXIO) { | ||
| 423 | if (axxia_i2c_handle_seq_nak(idev)) | ||
| 424 | axxia_i2c_init(idev); | ||
| 425 | } else if (readl(idev->base + MST_COMMAND) & CMD_BUSY) { | ||
| 426 | dev_warn(idev->dev, "busy after xfer\n"); | ||
| 427 | } | ||
| 428 | |||
| 429 | if (time_left == 0) { | ||
| 430 | idev->msg_err = -ETIMEDOUT; | ||
| 431 | i2c_recover_bus(&idev->adapter); | ||
| 432 | axxia_i2c_init(idev); | ||
| 433 | } | ||
| 434 | |||
| 435 | if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO) | ||
| 436 | axxia_i2c_init(idev); | ||
| 437 | |||
| 438 | return idev->msg_err; | ||
| 439 | } | ||
| 440 | |||
| 441 | static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) | ||
| 442 | { | ||
| 443 | u32 int_mask = MST_STATUS_ERR | MST_STATUS_SNS; | ||
| 444 | u32 rx_xfer, tx_xfer; | ||
| 445 | unsigned long time_left; | ||
| 446 | unsigned int wt_value; | ||
| 447 | |||
| 448 | idev->msg = msg; | ||
| 449 | idev->msg_r = msg; | ||
| 450 | idev->msg_xfrd = 0; | ||
| 451 | idev->msg_xfrd_r = 0; | ||
| 452 | reinit_completion(&idev->msg_complete); | ||
| 453 | |||
| 454 | axxia_i2c_set_addr(idev, msg); | ||
| 455 | |||
| 370 | if (i2c_m_rd(msg)) { | 456 | if (i2c_m_rd(msg)) { |
| 371 | /* I2C read transfer */ | 457 | /* I2C read transfer */ |
| 372 | rx_xfer = i2c_m_recv_len(msg) ? I2C_SMBUS_BLOCK_MAX : msg->len; | 458 | rx_xfer = i2c_m_recv_len(msg) ? I2C_SMBUS_BLOCK_MAX : msg->len; |
| @@ -379,8 +465,6 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) | |||
| 379 | 465 | ||
| 380 | writel(rx_xfer, idev->base + MST_RX_XFER); | 466 | writel(rx_xfer, idev->base + MST_RX_XFER); |
| 381 | writel(tx_xfer, idev->base + MST_TX_XFER); | 467 | writel(tx_xfer, idev->base + MST_TX_XFER); |
| 382 | writel(addr_1, idev->base + MST_ADDR_1); | ||
| 383 | writel(addr_2, idev->base + MST_ADDR_2); | ||
| 384 | 468 | ||
| 385 | if (i2c_m_rd(msg)) | 469 | if (i2c_m_rd(msg)) |
| 386 | int_mask |= MST_STATUS_RFL; | 470 | int_mask |= MST_STATUS_RFL; |
| @@ -445,6 +529,18 @@ static int axxia_i2c_stop(struct axxia_i2c_dev *idev) | |||
| 445 | return 0; | 529 | return 0; |
| 446 | } | 530 | } |
| 447 | 531 | ||
| 532 | /* This function checks if the msgs[] array contains messages compatible with | ||
| 533 | * Sequence mode of operation. This mode assumes there will be exactly one | ||
| 534 | * write of non-zero length followed by exactly one read of non-zero length, | ||
| 535 | * both targeted at the same client device. | ||
| 536 | */ | ||
| 537 | static bool axxia_i2c_sequence_ok(struct i2c_msg msgs[], int num) | ||
| 538 | { | ||
| 539 | return num == SEQ_LEN && !i2c_m_rd(&msgs[0]) && i2c_m_rd(&msgs[1]) && | ||
| 540 | msgs[0].len > 0 && msgs[0].len <= FIFO_SIZE && | ||
| 541 | msgs[1].len > 0 && msgs[0].addr == msgs[1].addr; | ||
| 542 | } | ||
| 543 | |||
| 448 | static int | 544 | static int |
| 449 | axxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | 545 | axxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) |
| 450 | { | 546 | { |
| @@ -453,6 +549,12 @@ axxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
| 453 | int ret = 0; | 549 | int ret = 0; |
| 454 | 550 | ||
| 455 | idev->msg_err = 0; | 551 | idev->msg_err = 0; |
| 552 | |||
| 553 | if (axxia_i2c_sequence_ok(msgs, num)) { | ||
| 554 | ret = axxia_i2c_xfer_seq(idev, msgs); | ||
| 555 | return ret ? : SEQ_LEN; | ||
| 556 | } | ||
| 557 | |||
| 456 | i2c_int_enable(idev, MST_STATUS_TSS); | 558 | i2c_int_enable(idev, MST_STATUS_TSS); |
| 457 | 559 | ||
| 458 | for (i = 0; ret == 0 && i < num; ++i) | 560 | for (i = 0; ret == 0 && i < num; ++i) |
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 44deae78913e..ec6e69aa3a8e 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c | |||
| @@ -1,14 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * BCM2835 master mode driver | 3 | * BCM2835 master mode driver |
| 3 | * | ||
| 4 | * This software is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2, as published by the Free Software Foundation, and | ||
| 6 | * may be copied, distributed, and modified under those terms. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | 4 | */ |
| 13 | 5 | ||
| 14 | #include <linux/clk.h> | 6 | #include <linux/clk.h> |
diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index eb76b76f4754..82bcd9a78759 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c | |||
| @@ -1,13 +1,7 @@ | |||
| 1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | * Copyright (C) 2013 Google, Inc | 2 | // Expose an I2C passthrough to the ChromeOS EC. |
| 3 | * | 3 | // |
| 4 | * This program is free software; you can redistribute it and/or modify | 4 | // Copyright (C) 2013 Google, Inc. |
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * Expose an I2C passthrough to the ChromeOS EC. | ||
| 10 | */ | ||
| 11 | 5 | ||
| 12 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 13 | #include <linux/i2c.h> | 7 | #include <linux/i2c.h> |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 6f6e1dfe7cce..d78023d42a35 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
| @@ -437,7 +437,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){ | |||
| 437 | break; | 437 | break; |
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | if (unlikely(signal_pending(current))){ | 440 | if (signal_pending(current)){ |
| 441 | DBG("%d: poll interrupted\n", dev->idx); | 441 | DBG("%d: poll interrupted\n", dev->idx); |
| 442 | ret = -ERESTARTSYS; | 442 | ret = -ERESTARTSYS; |
| 443 | break; | 443 | break; |
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index c406700789e1..fa9ad53845d9 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c | |||
| @@ -1090,7 +1090,8 @@ static int i2c_imx_probe(struct platform_device *pdev) | |||
| 1090 | /* Get I2C clock */ | 1090 | /* Get I2C clock */ |
| 1091 | i2c_imx->clk = devm_clk_get(&pdev->dev, NULL); | 1091 | i2c_imx->clk = devm_clk_get(&pdev->dev, NULL); |
| 1092 | if (IS_ERR(i2c_imx->clk)) { | 1092 | if (IS_ERR(i2c_imx->clk)) { |
| 1093 | dev_err(&pdev->dev, "can't get I2C clock\n"); | 1093 | if (PTR_ERR(i2c_imx->clk) != -EPROBE_DEFER) |
| 1094 | dev_err(&pdev->dev, "can't get I2C clock\n"); | ||
| 1094 | return PTR_ERR(i2c_imx->clk); | 1095 | return PTR_ERR(i2c_imx->clk); |
| 1095 | } | 1096 | } |
| 1096 | 1097 | ||
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 0d1c3ec8cb40..02d23edb2fb1 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c | |||
| @@ -75,6 +75,7 @@ | |||
| 75 | /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ | 75 | /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ |
| 76 | #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 | 76 | #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 |
| 77 | #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a | 77 | #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a |
| 78 | #define PCI_DEVICE_ID_INTEL_CDF_SMT 0x18ac | ||
| 78 | #define PCI_DEVICE_ID_INTEL_DNV_SMT 0x19ac | 79 | #define PCI_DEVICE_ID_INTEL_DNV_SMT 0x19ac |
| 79 | #define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 | 80 | #define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 |
| 80 | 81 | ||
| @@ -181,6 +182,7 @@ struct ismt_priv { | |||
| 181 | static const struct pci_device_id ismt_ids[] = { | 182 | static const struct pci_device_id ismt_ids[] = { |
| 182 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, | 183 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, |
| 183 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, | 184 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, |
| 185 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMT) }, | ||
| 184 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMT) }, | 186 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMT) }, |
| 185 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, | 187 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, |
| 186 | { 0, } | 188 | { 0, } |
diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c index 96b4572e6d9c..b6b5a495118b 100644 --- a/drivers/i2c/busses/i2c-owl.c +++ b/drivers/i2c/busses/i2c-owl.c | |||
| @@ -475,6 +475,7 @@ disable_clk: | |||
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | static const struct of_device_id owl_i2c_of_match[] = { | 477 | static const struct of_device_id owl_i2c_of_match[] = { |
| 478 | { .compatible = "actions,s700-i2c" }, | ||
| 478 | { .compatible = "actions,s900-i2c" }, | 479 | { .compatible = "actions,s900-i2c" }, |
| 479 | { /* sentinel */ } | 480 | { /* sentinel */ } |
| 480 | }; | 481 | }; |
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index f6f4ed8afc93..281113c28314 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c | |||
| @@ -229,9 +229,9 @@ static u32 i2c_powermac_get_addr(struct i2c_adapter *adap, | |||
| 229 | return (be32_to_cpup(prop) & 0xff) >> 1; | 229 | return (be32_to_cpup(prop) & 0xff) >> 1; |
| 230 | 230 | ||
| 231 | /* Now handle some devices with missing "reg" properties */ | 231 | /* Now handle some devices with missing "reg" properties */ |
| 232 | if (!strcmp(node->name, "cereal")) | 232 | if (of_node_name_eq(node, "cereal")) |
| 233 | return 0x60; | 233 | return 0x60; |
| 234 | else if (!strcmp(node->name, "deq")) | 234 | else if (of_node_name_eq(node, "deq")) |
| 235 | return 0x34; | 235 | return 0x34; |
| 236 | 236 | ||
| 237 | dev_warn(&adap->dev, "No i2c address for %pOF\n", node); | 237 | dev_warn(&adap->dev, "No i2c address for %pOF\n", node); |
| @@ -304,7 +304,7 @@ static bool i2c_powermac_get_type(struct i2c_adapter *adap, | |||
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | /* Now look for known workarounds */ | 306 | /* Now look for known workarounds */ |
| 307 | if (!strcmp(node->name, "deq")) { | 307 | if (of_node_name_eq(node, "deq")) { |
| 308 | /* Apple uses address 0x34 for TAS3001 and 0x35 for TAS3004 */ | 308 | /* Apple uses address 0x34 for TAS3001 and 0x35 for TAS3004 */ |
| 309 | if (addr == 0x34) { | 309 | if (addr == 0x34) { |
| 310 | snprintf(type, type_size, "MAC,tas3001"); | 310 | snprintf(type, type_size, "MAC,tas3001"); |
| @@ -331,7 +331,7 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap, | |||
| 331 | * case we skip this function completely as the device-tree will | 331 | * case we skip this function completely as the device-tree will |
| 332 | * not contain anything useful. | 332 | * not contain anything useful. |
| 333 | */ | 333 | */ |
| 334 | if (!strcmp(adap->dev.of_node->name, "via-pmu")) | 334 | if (of_node_name_eq(adap->dev.of_node, "via-pmu")) |
| 335 | return; | 335 | return; |
| 336 | 336 | ||
| 337 | for_each_child_of_node(adap->dev.of_node, node) { | 337 | for_each_child_of_node(adap->dev.of_node, node) { |
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index a7a7a9c3bc7c..a64f2ff3cb49 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
| @@ -800,6 +800,7 @@ static const struct sh_mobile_dt_config r8a7740_dt_config = { | |||
| 800 | static const struct of_device_id sh_mobile_i2c_dt_ids[] = { | 800 | static const struct of_device_id sh_mobile_i2c_dt_ids[] = { |
| 801 | { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config }, | 801 | { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config }, |
| 802 | { .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config }, | 802 | { .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config }, |
| 803 | { .compatible = "renesas,iic-r8a774c0", .data = &fast_clock_dt_config }, | ||
| 803 | { .compatible = "renesas,iic-r8a7790", .data = &v2_freq_calc_dt_config }, | 804 | { .compatible = "renesas,iic-r8a7790", .data = &v2_freq_calc_dt_config }, |
| 804 | { .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config }, | 805 | { .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config }, |
| 805 | { .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config }, | 806 | { .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config }, |
| @@ -808,6 +809,7 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = { | |||
| 808 | { .compatible = "renesas,rcar-gen2-iic", .data = &fast_clock_dt_config }, | 809 | { .compatible = "renesas,rcar-gen2-iic", .data = &fast_clock_dt_config }, |
| 809 | { .compatible = "renesas,iic-r8a7795", .data = &fast_clock_dt_config }, | 810 | { .compatible = "renesas,iic-r8a7795", .data = &fast_clock_dt_config }, |
| 810 | { .compatible = "renesas,rcar-gen3-iic", .data = &fast_clock_dt_config }, | 811 | { .compatible = "renesas,rcar-gen3-iic", .data = &fast_clock_dt_config }, |
| 812 | { .compatible = "renesas,iic-r8a77990", .data = &fast_clock_dt_config }, | ||
| 811 | { .compatible = "renesas,iic-sh73a0", .data = &fast_clock_dt_config }, | 813 | { .compatible = "renesas,iic-sh73a0", .data = &fast_clock_dt_config }, |
| 812 | { .compatible = "renesas,rmobile-iic", .data = &default_dt_config }, | 814 | { .compatible = "renesas,rmobile-iic", .data = &default_dt_config }, |
| 813 | {}, | 815 | {}, |
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 62d023e737d9..13e1213561d4 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c | |||
| @@ -21,12 +21,16 @@ | |||
| 21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| 22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <linux/iopoll.h> | 23 | #include <linux/iopoll.h> |
| 24 | #include <linux/mfd/syscon.h> | ||
| 24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 25 | #include <linux/of.h> | 26 | #include <linux/of.h> |
| 26 | #include <linux/of_address.h> | 27 | #include <linux/of_address.h> |
| 27 | #include <linux/of_irq.h> | 28 | #include <linux/of_irq.h> |
| 28 | #include <linux/of_platform.h> | 29 | #include <linux/of_platform.h> |
| 29 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
| 31 | #include <linux/pinctrl/consumer.h> | ||
| 32 | #include <linux/pm_runtime.h> | ||
| 33 | #include <linux/regmap.h> | ||
| 30 | #include <linux/reset.h> | 34 | #include <linux/reset.h> |
| 31 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 32 | 36 | ||
| @@ -163,6 +167,8 @@ | |||
| 163 | #define STM32F7_SCLH_MAX BIT(8) | 167 | #define STM32F7_SCLH_MAX BIT(8) |
| 164 | #define STM32F7_SCLL_MAX BIT(8) | 168 | #define STM32F7_SCLL_MAX BIT(8) |
| 165 | 169 | ||
| 170 | #define STM32F7_AUTOSUSPEND_DELAY (HZ / 100) | ||
| 171 | |||
| 166 | /** | 172 | /** |
| 167 | * struct stm32f7_i2c_spec - private i2c specification timing | 173 | * struct stm32f7_i2c_spec - private i2c specification timing |
| 168 | * @rate: I2C bus speed (Hz) | 174 | * @rate: I2C bus speed (Hz) |
| @@ -276,6 +282,7 @@ struct stm32f7_i2c_msg { | |||
| 276 | * slave) | 282 | * slave) |
| 277 | * @dma: dma data | 283 | * @dma: dma data |
| 278 | * @use_dma: boolean to know if dma is used in the current transfer | 284 | * @use_dma: boolean to know if dma is used in the current transfer |
| 285 | * @regmap: holds SYSCFG phandle for Fast Mode Plus bits | ||
| 279 | */ | 286 | */ |
| 280 | struct stm32f7_i2c_dev { | 287 | struct stm32f7_i2c_dev { |
| 281 | struct i2c_adapter adap; | 288 | struct i2c_adapter adap; |
| @@ -296,6 +303,7 @@ struct stm32f7_i2c_dev { | |||
| 296 | bool master_mode; | 303 | bool master_mode; |
| 297 | struct stm32_i2c_dma *dma; | 304 | struct stm32_i2c_dma *dma; |
| 298 | bool use_dma; | 305 | bool use_dma; |
| 306 | struct regmap *regmap; | ||
| 299 | }; | 307 | }; |
| 300 | 308 | ||
| 301 | /** | 309 | /** |
| @@ -1545,15 +1553,13 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 1545 | i2c_dev->msg_id = 0; | 1553 | i2c_dev->msg_id = 0; |
| 1546 | f7_msg->smbus = false; | 1554 | f7_msg->smbus = false; |
| 1547 | 1555 | ||
| 1548 | ret = clk_enable(i2c_dev->clk); | 1556 | ret = pm_runtime_get_sync(i2c_dev->dev); |
| 1549 | if (ret) { | 1557 | if (ret < 0) |
| 1550 | dev_err(i2c_dev->dev, "Failed to enable clock\n"); | ||
| 1551 | return ret; | 1558 | return ret; |
| 1552 | } | ||
| 1553 | 1559 | ||
| 1554 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); | 1560 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); |
| 1555 | if (ret) | 1561 | if (ret) |
| 1556 | goto clk_free; | 1562 | goto pm_free; |
| 1557 | 1563 | ||
| 1558 | stm32f7_i2c_xfer_msg(i2c_dev, msgs); | 1564 | stm32f7_i2c_xfer_msg(i2c_dev, msgs); |
| 1559 | 1565 | ||
| @@ -1569,8 +1575,9 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 1569 | ret = -ETIMEDOUT; | 1575 | ret = -ETIMEDOUT; |
| 1570 | } | 1576 | } |
| 1571 | 1577 | ||
| 1572 | clk_free: | 1578 | pm_free: |
| 1573 | clk_disable(i2c_dev->clk); | 1579 | pm_runtime_mark_last_busy(i2c_dev->dev); |
| 1580 | pm_runtime_put_autosuspend(i2c_dev->dev); | ||
| 1574 | 1581 | ||
| 1575 | return (ret < 0) ? ret : num; | 1582 | return (ret < 0) ? ret : num; |
| 1576 | } | 1583 | } |
| @@ -1592,39 +1599,37 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, | |||
| 1592 | f7_msg->read_write = read_write; | 1599 | f7_msg->read_write = read_write; |
| 1593 | f7_msg->smbus = true; | 1600 | f7_msg->smbus = true; |
| 1594 | 1601 | ||
| 1595 | ret = clk_enable(i2c_dev->clk); | 1602 | ret = pm_runtime_get_sync(dev); |
| 1596 | if (ret) { | 1603 | if (ret < 0) |
| 1597 | dev_err(i2c_dev->dev, "Failed to enable clock\n"); | ||
| 1598 | return ret; | 1604 | return ret; |
| 1599 | } | ||
| 1600 | 1605 | ||
| 1601 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); | 1606 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); |
| 1602 | if (ret) | 1607 | if (ret) |
| 1603 | goto clk_free; | 1608 | goto pm_free; |
| 1604 | 1609 | ||
| 1605 | ret = stm32f7_i2c_smbus_xfer_msg(i2c_dev, flags, command, data); | 1610 | ret = stm32f7_i2c_smbus_xfer_msg(i2c_dev, flags, command, data); |
| 1606 | if (ret) | 1611 | if (ret) |
| 1607 | goto clk_free; | 1612 | goto pm_free; |
| 1608 | 1613 | ||
| 1609 | timeout = wait_for_completion_timeout(&i2c_dev->complete, | 1614 | timeout = wait_for_completion_timeout(&i2c_dev->complete, |
| 1610 | i2c_dev->adap.timeout); | 1615 | i2c_dev->adap.timeout); |
| 1611 | ret = f7_msg->result; | 1616 | ret = f7_msg->result; |
| 1612 | if (ret) | 1617 | if (ret) |
| 1613 | goto clk_free; | 1618 | goto pm_free; |
| 1614 | 1619 | ||
| 1615 | if (!timeout) { | 1620 | if (!timeout) { |
| 1616 | dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); | 1621 | dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); |
| 1617 | if (i2c_dev->use_dma) | 1622 | if (i2c_dev->use_dma) |
| 1618 | dmaengine_terminate_all(dma->chan_using); | 1623 | dmaengine_terminate_all(dma->chan_using); |
| 1619 | ret = -ETIMEDOUT; | 1624 | ret = -ETIMEDOUT; |
| 1620 | goto clk_free; | 1625 | goto pm_free; |
| 1621 | } | 1626 | } |
| 1622 | 1627 | ||
| 1623 | /* Check PEC */ | 1628 | /* Check PEC */ |
| 1624 | if ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && read_write) { | 1629 | if ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && read_write) { |
| 1625 | ret = stm32f7_i2c_smbus_check_pec(i2c_dev); | 1630 | ret = stm32f7_i2c_smbus_check_pec(i2c_dev); |
| 1626 | if (ret) | 1631 | if (ret) |
| 1627 | goto clk_free; | 1632 | goto pm_free; |
| 1628 | } | 1633 | } |
| 1629 | 1634 | ||
| 1630 | if (read_write && size != I2C_SMBUS_QUICK) { | 1635 | if (read_write && size != I2C_SMBUS_QUICK) { |
| @@ -1649,8 +1654,9 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, | |||
| 1649 | } | 1654 | } |
| 1650 | } | 1655 | } |
| 1651 | 1656 | ||
| 1652 | clk_free: | 1657 | pm_free: |
| 1653 | clk_disable(i2c_dev->clk); | 1658 | pm_runtime_mark_last_busy(dev); |
| 1659 | pm_runtime_put_autosuspend(dev); | ||
| 1654 | return ret; | 1660 | return ret; |
| 1655 | } | 1661 | } |
| 1656 | 1662 | ||
| @@ -1676,13 +1682,9 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) | |||
| 1676 | if (ret) | 1682 | if (ret) |
| 1677 | return ret; | 1683 | return ret; |
| 1678 | 1684 | ||
| 1679 | if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) { | 1685 | ret = pm_runtime_get_sync(dev); |
| 1680 | ret = clk_enable(i2c_dev->clk); | 1686 | if (ret < 0) |
| 1681 | if (ret) { | 1687 | return ret; |
| 1682 | dev_err(dev, "Failed to enable clock\n"); | ||
| 1683 | return ret; | ||
| 1684 | } | ||
| 1685 | } | ||
| 1686 | 1688 | ||
| 1687 | if (id == 0) { | 1689 | if (id == 0) { |
| 1688 | /* Configure Own Address 1 */ | 1690 | /* Configure Own Address 1 */ |
| @@ -1703,7 +1705,7 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) | |||
| 1703 | oar2 &= ~STM32F7_I2C_OAR2_MASK; | 1705 | oar2 &= ~STM32F7_I2C_OAR2_MASK; |
| 1704 | if (slave->flags & I2C_CLIENT_TEN) { | 1706 | if (slave->flags & I2C_CLIENT_TEN) { |
| 1705 | ret = -EOPNOTSUPP; | 1707 | ret = -EOPNOTSUPP; |
| 1706 | goto exit; | 1708 | goto pm_free; |
| 1707 | } | 1709 | } |
| 1708 | 1710 | ||
| 1709 | oar2 |= STM32F7_I2C_OAR2_OA2_7(slave->addr); | 1711 | oar2 |= STM32F7_I2C_OAR2_OA2_7(slave->addr); |
| @@ -1712,7 +1714,7 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) | |||
| 1712 | writel_relaxed(oar2, i2c_dev->base + STM32F7_I2C_OAR2); | 1714 | writel_relaxed(oar2, i2c_dev->base + STM32F7_I2C_OAR2); |
| 1713 | } else { | 1715 | } else { |
| 1714 | ret = -ENODEV; | 1716 | ret = -ENODEV; |
| 1715 | goto exit; | 1717 | goto pm_free; |
| 1716 | } | 1718 | } |
| 1717 | 1719 | ||
| 1718 | /* Enable ACK */ | 1720 | /* Enable ACK */ |
| @@ -1723,11 +1725,10 @@ static int stm32f7_i2c_reg_slave(struct i2c_client *slave) | |||
| 1723 | STM32F7_I2C_CR1_PE; | 1725 | STM32F7_I2C_CR1_PE; |
| 1724 | stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask); | 1726 | stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask); |
| 1725 | 1727 | ||
| 1726 | return 0; | 1728 | ret = 0; |
| 1727 | 1729 | pm_free: | |
| 1728 | exit: | 1730 | pm_runtime_mark_last_busy(dev); |
| 1729 | if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) | 1731 | pm_runtime_put_autosuspend(dev); |
| 1730 | clk_disable(i2c_dev->clk); | ||
| 1731 | 1732 | ||
| 1732 | return ret; | 1733 | return ret; |
| 1733 | } | 1734 | } |
| @@ -1745,6 +1746,10 @@ static int stm32f7_i2c_unreg_slave(struct i2c_client *slave) | |||
| 1745 | 1746 | ||
| 1746 | WARN_ON(!i2c_dev->slave[id]); | 1747 | WARN_ON(!i2c_dev->slave[id]); |
| 1747 | 1748 | ||
| 1749 | ret = pm_runtime_get_sync(i2c_dev->dev); | ||
| 1750 | if (ret < 0) | ||
| 1751 | return ret; | ||
| 1752 | |||
| 1748 | if (id == 0) { | 1753 | if (id == 0) { |
| 1749 | mask = STM32F7_I2C_OAR1_OA1EN; | 1754 | mask = STM32F7_I2C_OAR1_OA1EN; |
| 1750 | stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR1, mask); | 1755 | stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR1, mask); |
| @@ -1755,14 +1760,39 @@ static int stm32f7_i2c_unreg_slave(struct i2c_client *slave) | |||
| 1755 | 1760 | ||
| 1756 | i2c_dev->slave[id] = NULL; | 1761 | i2c_dev->slave[id] = NULL; |
| 1757 | 1762 | ||
| 1758 | if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) { | 1763 | if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) |
| 1759 | stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); | 1764 | stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); |
| 1760 | clk_disable(i2c_dev->clk); | 1765 | |
| 1761 | } | 1766 | pm_runtime_mark_last_busy(i2c_dev->dev); |
| 1767 | pm_runtime_put_autosuspend(i2c_dev->dev); | ||
| 1762 | 1768 | ||
| 1763 | return 0; | 1769 | return 0; |
| 1764 | } | 1770 | } |
| 1765 | 1771 | ||
| 1772 | static int stm32f7_i2c_setup_fm_plus_bits(struct platform_device *pdev, | ||
| 1773 | struct stm32f7_i2c_dev *i2c_dev) | ||
| 1774 | { | ||
| 1775 | struct device_node *np = pdev->dev.of_node; | ||
| 1776 | int ret; | ||
| 1777 | u32 reg, mask; | ||
| 1778 | |||
| 1779 | i2c_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg-fmp"); | ||
| 1780 | if (IS_ERR(i2c_dev->regmap)) { | ||
| 1781 | /* Optional */ | ||
| 1782 | return 0; | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | ret = of_property_read_u32_index(np, "st,syscfg-fmp", 1, ®); | ||
| 1786 | if (ret) | ||
| 1787 | return ret; | ||
| 1788 | |||
| 1789 | ret = of_property_read_u32_index(np, "st,syscfg-fmp", 2, &mask); | ||
| 1790 | if (ret) | ||
| 1791 | return ret; | ||
| 1792 | |||
| 1793 | return regmap_update_bits(i2c_dev->regmap, reg, mask, mask); | ||
| 1794 | } | ||
| 1795 | |||
| 1766 | static u32 stm32f7_i2c_func(struct i2c_adapter *adap) | 1796 | static u32 stm32f7_i2c_func(struct i2c_adapter *adap) |
| 1767 | { | 1797 | { |
| 1768 | return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SLAVE | | 1798 | return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SLAVE | |
| @@ -1819,6 +1849,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) | |||
| 1819 | dev_err(&pdev->dev, "Error: Missing controller clock\n"); | 1849 | dev_err(&pdev->dev, "Error: Missing controller clock\n"); |
| 1820 | return PTR_ERR(i2c_dev->clk); | 1850 | return PTR_ERR(i2c_dev->clk); |
| 1821 | } | 1851 | } |
| 1852 | |||
| 1822 | ret = clk_prepare_enable(i2c_dev->clk); | 1853 | ret = clk_prepare_enable(i2c_dev->clk); |
| 1823 | if (ret) { | 1854 | if (ret) { |
| 1824 | dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); | 1855 | dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); |
| @@ -1828,12 +1859,16 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) | |||
| 1828 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; | 1859 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; |
| 1829 | ret = device_property_read_u32(&pdev->dev, "clock-frequency", | 1860 | ret = device_property_read_u32(&pdev->dev, "clock-frequency", |
| 1830 | &clk_rate); | 1861 | &clk_rate); |
| 1831 | if (!ret && clk_rate >= 1000000) | 1862 | if (!ret && clk_rate >= 1000000) { |
| 1832 | i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; | 1863 | i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; |
| 1833 | else if (!ret && clk_rate >= 400000) | 1864 | ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev); |
| 1865 | if (ret) | ||
| 1866 | goto clk_free; | ||
| 1867 | } else if (!ret && clk_rate >= 400000) { | ||
| 1834 | i2c_dev->speed = STM32_I2C_SPEED_FAST; | 1868 | i2c_dev->speed = STM32_I2C_SPEED_FAST; |
| 1835 | else if (!ret && clk_rate >= 100000) | 1869 | } else if (!ret && clk_rate >= 100000) { |
| 1836 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; | 1870 | i2c_dev->speed = STM32_I2C_SPEED_STANDARD; |
| 1871 | } | ||
| 1837 | 1872 | ||
| 1838 | rst = devm_reset_control_get(&pdev->dev, NULL); | 1873 | rst = devm_reset_control_get(&pdev->dev, NULL); |
| 1839 | if (IS_ERR(rst)) { | 1874 | if (IS_ERR(rst)) { |
| @@ -1888,8 +1923,6 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) | |||
| 1888 | if (ret) | 1923 | if (ret) |
| 1889 | goto clk_free; | 1924 | goto clk_free; |
| 1890 | 1925 | ||
| 1891 | stm32f7_i2c_hw_config(i2c_dev); | ||
| 1892 | |||
| 1893 | adap = &i2c_dev->adap; | 1926 | adap = &i2c_dev->adap; |
| 1894 | i2c_set_adapdata(adap, i2c_dev); | 1927 | i2c_set_adapdata(adap, i2c_dev); |
| 1895 | snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", | 1928 | snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)", |
| @@ -1908,18 +1941,35 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) | |||
| 1908 | STM32F7_I2C_TXDR, | 1941 | STM32F7_I2C_TXDR, |
| 1909 | STM32F7_I2C_RXDR); | 1942 | STM32F7_I2C_RXDR); |
| 1910 | 1943 | ||
| 1911 | ret = i2c_add_adapter(adap); | ||
| 1912 | if (ret) | ||
| 1913 | goto clk_free; | ||
| 1914 | |||
| 1915 | platform_set_drvdata(pdev, i2c_dev); | 1944 | platform_set_drvdata(pdev, i2c_dev); |
| 1916 | 1945 | ||
| 1917 | clk_disable(i2c_dev->clk); | 1946 | pm_runtime_set_autosuspend_delay(i2c_dev->dev, |
| 1947 | STM32F7_AUTOSUSPEND_DELAY); | ||
| 1948 | pm_runtime_use_autosuspend(i2c_dev->dev); | ||
| 1949 | pm_runtime_set_active(i2c_dev->dev); | ||
| 1950 | pm_runtime_enable(i2c_dev->dev); | ||
| 1951 | |||
| 1952 | pm_runtime_get_noresume(&pdev->dev); | ||
| 1953 | |||
| 1954 | stm32f7_i2c_hw_config(i2c_dev); | ||
| 1955 | |||
| 1956 | ret = i2c_add_adapter(adap); | ||
| 1957 | if (ret) | ||
| 1958 | goto pm_disable; | ||
| 1918 | 1959 | ||
| 1919 | dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); | 1960 | dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); |
| 1920 | 1961 | ||
| 1962 | pm_runtime_mark_last_busy(i2c_dev->dev); | ||
| 1963 | pm_runtime_put_autosuspend(i2c_dev->dev); | ||
| 1964 | |||
| 1921 | return 0; | 1965 | return 0; |
| 1922 | 1966 | ||
| 1967 | pm_disable: | ||
| 1968 | pm_runtime_put_noidle(i2c_dev->dev); | ||
| 1969 | pm_runtime_disable(i2c_dev->dev); | ||
| 1970 | pm_runtime_set_suspended(i2c_dev->dev); | ||
| 1971 | pm_runtime_dont_use_autosuspend(i2c_dev->dev); | ||
| 1972 | |||
| 1923 | clk_free: | 1973 | clk_free: |
| 1924 | clk_disable_unprepare(i2c_dev->clk); | 1974 | clk_disable_unprepare(i2c_dev->clk); |
| 1925 | 1975 | ||
| @@ -1936,11 +1986,50 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) | |||
| 1936 | } | 1986 | } |
| 1937 | 1987 | ||
| 1938 | i2c_del_adapter(&i2c_dev->adap); | 1988 | i2c_del_adapter(&i2c_dev->adap); |
| 1989 | pm_runtime_get_sync(i2c_dev->dev); | ||
| 1939 | 1990 | ||
| 1940 | clk_unprepare(i2c_dev->clk); | 1991 | clk_disable_unprepare(i2c_dev->clk); |
| 1992 | |||
| 1993 | pm_runtime_put_noidle(i2c_dev->dev); | ||
| 1994 | pm_runtime_disable(i2c_dev->dev); | ||
| 1995 | pm_runtime_set_suspended(i2c_dev->dev); | ||
| 1996 | pm_runtime_dont_use_autosuspend(i2c_dev->dev); | ||
| 1997 | |||
| 1998 | return 0; | ||
| 1999 | } | ||
| 2000 | |||
| 2001 | #ifdef CONFIG_PM | ||
| 2002 | static int stm32f7_i2c_runtime_suspend(struct device *dev) | ||
| 2003 | { | ||
| 2004 | struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); | ||
| 2005 | |||
| 2006 | if (!stm32f7_i2c_is_slave_registered(i2c_dev)) | ||
| 2007 | clk_disable_unprepare(i2c_dev->clk); | ||
| 2008 | |||
| 2009 | return 0; | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | static int stm32f7_i2c_runtime_resume(struct device *dev) | ||
| 2013 | { | ||
| 2014 | struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); | ||
| 2015 | int ret; | ||
| 2016 | |||
| 2017 | if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { | ||
| 2018 | ret = clk_prepare_enable(i2c_dev->clk); | ||
| 2019 | if (ret) { | ||
| 2020 | dev_err(dev, "failed to prepare_enable clock\n"); | ||
| 2021 | return ret; | ||
| 2022 | } | ||
| 2023 | } | ||
| 1941 | 2024 | ||
| 1942 | return 0; | 2025 | return 0; |
| 1943 | } | 2026 | } |
| 2027 | #endif | ||
| 2028 | |||
| 2029 | static const struct dev_pm_ops stm32f7_i2c_pm_ops = { | ||
| 2030 | SET_RUNTIME_PM_OPS(stm32f7_i2c_runtime_suspend, | ||
| 2031 | stm32f7_i2c_runtime_resume, NULL) | ||
| 2032 | }; | ||
| 1944 | 2033 | ||
| 1945 | static const struct of_device_id stm32f7_i2c_match[] = { | 2034 | static const struct of_device_id stm32f7_i2c_match[] = { |
| 1946 | { .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup}, | 2035 | { .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup}, |
| @@ -1952,6 +2041,7 @@ static struct platform_driver stm32f7_i2c_driver = { | |||
| 1952 | .driver = { | 2041 | .driver = { |
| 1953 | .name = "stm32f7-i2c", | 2042 | .name = "stm32f7-i2c", |
| 1954 | .of_match_table = stm32f7_i2c_match, | 2043 | .of_match_table = stm32f7_i2c_match, |
| 2044 | .pm = &stm32f7_i2c_pm_ops, | ||
| 1955 | }, | 2045 | }, |
| 1956 | .probe = stm32f7_i2c_probe, | 2046 | .probe = stm32f7_i2c_probe, |
| 1957 | .remove = stm32f7_i2c_remove, | 2047 | .remove = stm32f7_i2c_remove, |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 437294ea2f0a..e417ebf7628c 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
| @@ -1,18 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * drivers/i2c/busses/i2c-tegra.c | 3 | * drivers/i2c/busses/i2c-tegra.c |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2010 Google, Inc. | 5 | * Copyright (C) 2010 Google, Inc. |
| 5 | * Author: Colin Cross <ccross@android.com> | 6 | * Author: Colin Cross <ccross@android.com> |
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | 7 | */ |
| 17 | 8 | ||
| 18 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| @@ -145,8 +136,8 @@ enum msg_end_type { | |||
| 145 | * @has_continue_xfer_support: Continue transfer supports. | 136 | * @has_continue_xfer_support: Continue transfer supports. |
| 146 | * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer | 137 | * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer |
| 147 | * complete interrupt per packet basis. | 138 | * complete interrupt per packet basis. |
| 148 | * @has_single_clk_source: The i2c controller has single clock source. Tegra30 | 139 | * @has_single_clk_source: The I2C controller has single clock source. Tegra30 |
| 149 | * and earlier Socs has two clock sources i.e. div-clk and | 140 | * and earlier SoCs have two clock sources i.e. div-clk and |
| 150 | * fast-clk. | 141 | * fast-clk. |
| 151 | * @has_config_load_reg: Has the config load register to load the new | 142 | * @has_config_load_reg: Has the config load register to load the new |
| 152 | * configuration. | 143 | * configuration. |
| @@ -154,8 +145,17 @@ enum msg_end_type { | |||
| 154 | * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is | 145 | * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is |
| 155 | * applicable if there is no fast clock source i.e. single clock | 146 | * applicable if there is no fast clock source i.e. single clock |
| 156 | * source. | 147 | * source. |
| 148 | * @clk_divisor_fast_plus_mode: Clock divisor in fast mode plus. It is | ||
| 149 | * applicable if there is no fast clock source (i.e. single | ||
| 150 | * clock source). | ||
| 151 | * @has_multi_master_mode: The I2C controller supports running in single-master | ||
| 152 | * or multi-master mode. | ||
| 153 | * @has_slcg_override_reg: The I2C controller supports a register that | ||
| 154 | * overrides the second level clock gating. | ||
| 155 | * @has_mst_fifo: The I2C controller contains the new MST FIFO interface that | ||
| 156 | * provides additional features and allows for longer messages to | ||
| 157 | * be transferred in one go. | ||
| 157 | */ | 158 | */ |
| 158 | |||
| 159 | struct tegra_i2c_hw_feature { | 159 | struct tegra_i2c_hw_feature { |
| 160 | bool has_continue_xfer_support; | 160 | bool has_continue_xfer_support; |
| 161 | bool has_per_pkt_xfer_complete_irq; | 161 | bool has_per_pkt_xfer_complete_irq; |
| @@ -170,22 +170,27 @@ struct tegra_i2c_hw_feature { | |||
| 170 | }; | 170 | }; |
| 171 | 171 | ||
| 172 | /** | 172 | /** |
| 173 | * struct tegra_i2c_dev - per device i2c context | 173 | * struct tegra_i2c_dev - per device I2C context |
| 174 | * @dev: device reference for power management | 174 | * @dev: device reference for power management |
| 175 | * @hw: Tegra i2c hw feature. | 175 | * @hw: Tegra I2C HW feature |
| 176 | * @adapter: core i2c layer adapter information | 176 | * @adapter: core I2C layer adapter information |
| 177 | * @div_clk: clock reference for div clock of i2c controller. | 177 | * @div_clk: clock reference for div clock of I2C controller |
| 178 | * @fast_clk: clock reference for fast clock of i2c controller. | 178 | * @fast_clk: clock reference for fast clock of I2C controller |
| 179 | * @rst: reset control for the I2C controller | ||
| 179 | * @base: ioremapped registers cookie | 180 | * @base: ioremapped registers cookie |
| 180 | * @cont_id: i2c controller id, used for for packet header | 181 | * @cont_id: I2C controller ID, used for packet header |
| 181 | * @irq: irq number of transfer complete interrupt | 182 | * @irq: IRQ number of transfer complete interrupt |
| 182 | * @is_dvc: identifies the DVC i2c controller, has a different register layout | 183 | * @irq_disabled: used to track whether or not the interrupt is enabled |
| 184 | * @is_dvc: identifies the DVC I2C controller, has a different register layout | ||
| 183 | * @msg_complete: transfer completion notifier | 185 | * @msg_complete: transfer completion notifier |
| 184 | * @msg_err: error code for completed message | 186 | * @msg_err: error code for completed message |
| 185 | * @msg_buf: pointer to current message data | 187 | * @msg_buf: pointer to current message data |
| 186 | * @msg_buf_remaining: size of unsent data in the message buffer | 188 | * @msg_buf_remaining: size of unsent data in the message buffer |
| 187 | * @msg_read: identifies read transfers | 189 | * @msg_read: identifies read transfers |
| 188 | * @bus_clk_rate: current i2c bus clock rate | 190 | * @bus_clk_rate: current I2C bus clock rate |
| 191 | * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes | ||
| 192 | * @is_multimaster_mode: track if I2C controller is in multi-master mode | ||
| 193 | * @xfer_lock: lock to serialize transfer submission and processing | ||
| 189 | */ | 194 | */ |
| 190 | struct tegra_i2c_dev { | 195 | struct tegra_i2c_dev { |
| 191 | struct device *dev; | 196 | struct device *dev; |
| @@ -608,11 +613,10 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id) | |||
| 608 | u32 status; | 613 | u32 status; |
| 609 | const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; | 614 | const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; |
| 610 | struct tegra_i2c_dev *i2c_dev = dev_id; | 615 | struct tegra_i2c_dev *i2c_dev = dev_id; |
| 611 | unsigned long flags; | ||
| 612 | 616 | ||
| 613 | status = i2c_readl(i2c_dev, I2C_INT_STATUS); | 617 | status = i2c_readl(i2c_dev, I2C_INT_STATUS); |
| 614 | 618 | ||
| 615 | spin_lock_irqsave(&i2c_dev->xfer_lock, flags); | 619 | spin_lock(&i2c_dev->xfer_lock); |
| 616 | if (status == 0) { | 620 | if (status == 0) { |
| 617 | dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n", | 621 | dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n", |
| 618 | i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), | 622 | i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), |
| @@ -670,7 +674,7 @@ err: | |||
| 670 | 674 | ||
| 671 | complete(&i2c_dev->msg_complete); | 675 | complete(&i2c_dev->msg_complete); |
| 672 | done: | 676 | done: |
| 673 | spin_unlock_irqrestore(&i2c_dev->xfer_lock, flags); | 677 | spin_unlock(&i2c_dev->xfer_lock); |
| 674 | return IRQ_HANDLED; | 678 | return IRQ_HANDLED; |
| 675 | } | 679 | } |
| 676 | 680 | ||
