719 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * This is i.MX low power i2c controller driver.4 *5 * Copyright 2016 Freescale Semiconductor, Inc.6 */7 8#include <linux/clk.h>9#include <linux/completion.h>10#include <linux/delay.h>11#include <linux/err.h>12#include <linux/errno.h>13#include <linux/i2c.h>14#include <linux/init.h>15#include <linux/interrupt.h>16#include <linux/io.h>17#include <linux/kernel.h>18#include <linux/module.h>19#include <linux/of.h>20#include <linux/pinctrl/consumer.h>21#include <linux/platform_device.h>22#include <linux/pm_runtime.h>23#include <linux/sched.h>24#include <linux/slab.h>25 26#define DRIVER_NAME "imx-lpi2c"27 28#define LPI2C_PARAM 0x04 /* i2c RX/TX FIFO size */29#define LPI2C_MCR 0x10 /* i2c contrl register */30#define LPI2C_MSR 0x14 /* i2c status register */31#define LPI2C_MIER 0x18 /* i2c interrupt enable */32#define LPI2C_MCFGR0 0x20 /* i2c master configuration */33#define LPI2C_MCFGR1 0x24 /* i2c master configuration */34#define LPI2C_MCFGR2 0x28 /* i2c master configuration */35#define LPI2C_MCFGR3 0x2C /* i2c master configuration */36#define LPI2C_MCCR0 0x48 /* i2c master clk configuration */37#define LPI2C_MCCR1 0x50 /* i2c master clk configuration */38#define LPI2C_MFCR 0x58 /* i2c master FIFO control */39#define LPI2C_MFSR 0x5C /* i2c master FIFO status */40#define LPI2C_MTDR 0x60 /* i2c master TX data register */41#define LPI2C_MRDR 0x70 /* i2c master RX data register */42 43/* i2c command */44#define TRAN_DATA 0X0045#define RECV_DATA 0X0146#define GEN_STOP 0X0247#define RECV_DISCARD 0X0348#define GEN_START 0X0449#define START_NACK 0X0550#define START_HIGH 0X0651#define START_HIGH_NACK 0X0752 53#define MCR_MEN BIT(0)54#define MCR_RST BIT(1)55#define MCR_DOZEN BIT(2)56#define MCR_DBGEN BIT(3)57#define MCR_RTF BIT(8)58#define MCR_RRF BIT(9)59#define MSR_TDF BIT(0)60#define MSR_RDF BIT(1)61#define MSR_SDF BIT(9)62#define MSR_NDF BIT(10)63#define MSR_ALF BIT(11)64#define MSR_MBF BIT(24)65#define MSR_BBF BIT(25)66#define MIER_TDIE BIT(0)67#define MIER_RDIE BIT(1)68#define MIER_SDIE BIT(9)69#define MIER_NDIE BIT(10)70#define MCFGR1_AUTOSTOP BIT(8)71#define MCFGR1_IGNACK BIT(9)72#define MRDR_RXEMPTY BIT(14)73 74#define I2C_CLK_RATIO 275#define CHUNK_DATA 25676 77#define I2C_PM_TIMEOUT 10 /* ms */78 79enum lpi2c_imx_mode {80 STANDARD, /* 100+Kbps */81 FAST, /* 400+Kbps */82 FAST_PLUS, /* 1.0+Mbps */83 HS, /* 3.4+Mbps */84 ULTRA_FAST, /* 5.0+Mbps */85};86 87enum lpi2c_imx_pincfg {88 TWO_PIN_OD,89 TWO_PIN_OO,90 TWO_PIN_PP,91 FOUR_PIN_PP,92};93 94struct lpi2c_imx_struct {95 struct i2c_adapter adapter;96 int num_clks;97 struct clk_bulk_data *clks;98 void __iomem *base;99 __u8 *rx_buf;100 __u8 *tx_buf;101 struct completion complete;102 unsigned long rate_per;103 unsigned int msglen;104 unsigned int delivered;105 unsigned int block_data;106 unsigned int bitrate;107 unsigned int txfifosize;108 unsigned int rxfifosize;109 enum lpi2c_imx_mode mode;110 struct i2c_bus_recovery_info rinfo;111};112 113static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx,114 unsigned int enable)115{116 writel(enable, lpi2c_imx->base + LPI2C_MIER);117}118 119static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx)120{121 unsigned long orig_jiffies = jiffies;122 unsigned int temp;123 124 while (1) {125 temp = readl(lpi2c_imx->base + LPI2C_MSR);126 127 /* check for arbitration lost, clear if set */128 if (temp & MSR_ALF) {129 writel(temp, lpi2c_imx->base + LPI2C_MSR);130 return -EAGAIN;131 }132 133 if (temp & (MSR_BBF | MSR_MBF))134 break;135 136 if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {137 dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n");138 if (lpi2c_imx->adapter.bus_recovery_info)139 i2c_recover_bus(&lpi2c_imx->adapter);140 return -ETIMEDOUT;141 }142 schedule();143 }144 145 return 0;146}147 148static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx)149{150 unsigned int bitrate = lpi2c_imx->bitrate;151 enum lpi2c_imx_mode mode;152 153 if (bitrate < I2C_MAX_FAST_MODE_FREQ)154 mode = STANDARD;155 else if (bitrate < I2C_MAX_FAST_MODE_PLUS_FREQ)156 mode = FAST;157 else if (bitrate < I2C_MAX_HIGH_SPEED_MODE_FREQ)158 mode = FAST_PLUS;159 else if (bitrate < I2C_MAX_ULTRA_FAST_MODE_FREQ)160 mode = HS;161 else162 mode = ULTRA_FAST;163 164 lpi2c_imx->mode = mode;165}166 167static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx,168 struct i2c_msg *msgs)169{170 unsigned int temp;171 172 temp = readl(lpi2c_imx->base + LPI2C_MCR);173 temp |= MCR_RRF | MCR_RTF;174 writel(temp, lpi2c_imx->base + LPI2C_MCR);175 writel(0x7f00, lpi2c_imx->base + LPI2C_MSR);176 177 temp = i2c_8bit_addr_from_msg(msgs) | (GEN_START << 8);178 writel(temp, lpi2c_imx->base + LPI2C_MTDR);179 180 return lpi2c_imx_bus_busy(lpi2c_imx);181}182 183static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx)184{185 unsigned long orig_jiffies = jiffies;186 unsigned int temp;187 188 writel(GEN_STOP << 8, lpi2c_imx->base + LPI2C_MTDR);189 190 do {191 temp = readl(lpi2c_imx->base + LPI2C_MSR);192 if (temp & MSR_SDF)193 break;194 195 if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {196 dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n");197 if (lpi2c_imx->adapter.bus_recovery_info)198 i2c_recover_bus(&lpi2c_imx->adapter);199 break;200 }201 schedule();202 203 } while (1);204}205 206/* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */207static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)208{209 u8 prescale, filt, sethold, datavd;210 unsigned int clk_rate, clk_cycle, clkhi, clklo;211 enum lpi2c_imx_pincfg pincfg;212 unsigned int temp;213 214 lpi2c_imx_set_mode(lpi2c_imx);215 216 clk_rate = lpi2c_imx->rate_per;217 218 if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)219 filt = 0;220 else221 filt = 2;222 223 for (prescale = 0; prescale <= 7; prescale++) {224 clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate)225 - 3 - (filt >> 1);226 clkhi = DIV_ROUND_UP(clk_cycle, I2C_CLK_RATIO + 1);227 clklo = clk_cycle - clkhi;228 if (clklo < 64)229 break;230 }231 232 if (prescale > 7)233 return -EINVAL;234 235 /* set MCFGR1: PINCFG, PRESCALE, IGNACK */236 if (lpi2c_imx->mode == ULTRA_FAST)237 pincfg = TWO_PIN_OO;238 else239 pincfg = TWO_PIN_OD;240 temp = prescale | pincfg << 24;241 242 if (lpi2c_imx->mode == ULTRA_FAST)243 temp |= MCFGR1_IGNACK;244 245 writel(temp, lpi2c_imx->base + LPI2C_MCFGR1);246 247 /* set MCFGR2: FILTSDA, FILTSCL */248 temp = (filt << 16) | (filt << 24);249 writel(temp, lpi2c_imx->base + LPI2C_MCFGR2);250 251 /* set MCCR: DATAVD, SETHOLD, CLKHI, CLKLO */252 sethold = clkhi;253 datavd = clkhi >> 1;254 temp = datavd << 24 | sethold << 16 | clkhi << 8 | clklo;255 256 if (lpi2c_imx->mode == HS)257 writel(temp, lpi2c_imx->base + LPI2C_MCCR1);258 else259 writel(temp, lpi2c_imx->base + LPI2C_MCCR0);260 261 return 0;262}263 264static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx)265{266 unsigned int temp;267 int ret;268 269 ret = pm_runtime_resume_and_get(lpi2c_imx->adapter.dev.parent);270 if (ret < 0)271 return ret;272 273 temp = MCR_RST;274 writel(temp, lpi2c_imx->base + LPI2C_MCR);275 writel(0, lpi2c_imx->base + LPI2C_MCR);276 277 ret = lpi2c_imx_config(lpi2c_imx);278 if (ret)279 goto rpm_put;280 281 temp = readl(lpi2c_imx->base + LPI2C_MCR);282 temp |= MCR_MEN;283 writel(temp, lpi2c_imx->base + LPI2C_MCR);284 285 return 0;286 287rpm_put:288 pm_runtime_mark_last_busy(lpi2c_imx->adapter.dev.parent);289 pm_runtime_put_autosuspend(lpi2c_imx->adapter.dev.parent);290 291 return ret;292}293 294static int lpi2c_imx_master_disable(struct lpi2c_imx_struct *lpi2c_imx)295{296 u32 temp;297 298 temp = readl(lpi2c_imx->base + LPI2C_MCR);299 temp &= ~MCR_MEN;300 writel(temp, lpi2c_imx->base + LPI2C_MCR);301 302 pm_runtime_mark_last_busy(lpi2c_imx->adapter.dev.parent);303 pm_runtime_put_autosuspend(lpi2c_imx->adapter.dev.parent);304 305 return 0;306}307 308static int lpi2c_imx_msg_complete(struct lpi2c_imx_struct *lpi2c_imx)309{310 unsigned long time_left;311 312 time_left = wait_for_completion_timeout(&lpi2c_imx->complete, HZ);313 314 return time_left ? 0 : -ETIMEDOUT;315}316 317static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx)318{319 unsigned long orig_jiffies = jiffies;320 u32 txcnt;321 322 do {323 txcnt = readl(lpi2c_imx->base + LPI2C_MFSR) & 0xff;324 325 if (readl(lpi2c_imx->base + LPI2C_MSR) & MSR_NDF) {326 dev_dbg(&lpi2c_imx->adapter.dev, "NDF detected\n");327 return -EIO;328 }329 330 if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {331 dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n");332 if (lpi2c_imx->adapter.bus_recovery_info)333 i2c_recover_bus(&lpi2c_imx->adapter);334 return -ETIMEDOUT;335 }336 schedule();337 338 } while (txcnt);339 340 return 0;341}342 343static void lpi2c_imx_set_tx_watermark(struct lpi2c_imx_struct *lpi2c_imx)344{345 writel(lpi2c_imx->txfifosize >> 1, lpi2c_imx->base + LPI2C_MFCR);346}347 348static void lpi2c_imx_set_rx_watermark(struct lpi2c_imx_struct *lpi2c_imx)349{350 unsigned int temp, remaining;351 352 remaining = lpi2c_imx->msglen - lpi2c_imx->delivered;353 354 if (remaining > (lpi2c_imx->rxfifosize >> 1))355 temp = lpi2c_imx->rxfifosize >> 1;356 else357 temp = 0;358 359 writel(temp << 16, lpi2c_imx->base + LPI2C_MFCR);360}361 362static void lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx)363{364 unsigned int data, txcnt;365 366 txcnt = readl(lpi2c_imx->base + LPI2C_MFSR) & 0xff;367 368 while (txcnt < lpi2c_imx->txfifosize) {369 if (lpi2c_imx->delivered == lpi2c_imx->msglen)370 break;371 372 data = lpi2c_imx->tx_buf[lpi2c_imx->delivered++];373 writel(data, lpi2c_imx->base + LPI2C_MTDR);374 txcnt++;375 }376 377 if (lpi2c_imx->delivered < lpi2c_imx->msglen)378 lpi2c_imx_intctrl(lpi2c_imx, MIER_TDIE | MIER_NDIE);379 else380 complete(&lpi2c_imx->complete);381}382 383static void lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx)384{385 unsigned int blocklen, remaining;386 unsigned int temp, data;387 388 do {389 data = readl(lpi2c_imx->base + LPI2C_MRDR);390 if (data & MRDR_RXEMPTY)391 break;392 393 lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff;394 } while (1);395 396 /*397 * First byte is the length of remaining packet in the SMBus block398 * data read. Add it to msgs->len.399 */400 if (lpi2c_imx->block_data) {401 blocklen = lpi2c_imx->rx_buf[0];402 lpi2c_imx->msglen += blocklen;403 }404 405 remaining = lpi2c_imx->msglen - lpi2c_imx->delivered;406 407 if (!remaining) {408 complete(&lpi2c_imx->complete);409 return;410 }411 412 /* not finished, still waiting for rx data */413 lpi2c_imx_set_rx_watermark(lpi2c_imx);414 415 /* multiple receive commands */416 if (lpi2c_imx->block_data) {417 lpi2c_imx->block_data = 0;418 temp = remaining;419 temp |= (RECV_DATA << 8);420 writel(temp, lpi2c_imx->base + LPI2C_MTDR);421 } else if (!(lpi2c_imx->delivered & 0xff)) {422 temp = (remaining > CHUNK_DATA ? CHUNK_DATA : remaining) - 1;423 temp |= (RECV_DATA << 8);424 writel(temp, lpi2c_imx->base + LPI2C_MTDR);425 }426 427 lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE);428}429 430static void lpi2c_imx_write(struct lpi2c_imx_struct *lpi2c_imx,431 struct i2c_msg *msgs)432{433 lpi2c_imx->tx_buf = msgs->buf;434 lpi2c_imx_set_tx_watermark(lpi2c_imx);435 lpi2c_imx_write_txfifo(lpi2c_imx);436}437 438static void lpi2c_imx_read(struct lpi2c_imx_struct *lpi2c_imx,439 struct i2c_msg *msgs)440{441 unsigned int temp;442 443 lpi2c_imx->rx_buf = msgs->buf;444 lpi2c_imx->block_data = msgs->flags & I2C_M_RECV_LEN;445 446 lpi2c_imx_set_rx_watermark(lpi2c_imx);447 temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1;448 temp |= (RECV_DATA << 8);449 writel(temp, lpi2c_imx->base + LPI2C_MTDR);450 451 lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE);452}453 454static int lpi2c_imx_xfer(struct i2c_adapter *adapter,455 struct i2c_msg *msgs, int num)456{457 struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(adapter);458 unsigned int temp;459 int i, result;460 461 result = lpi2c_imx_master_enable(lpi2c_imx);462 if (result)463 return result;464 465 for (i = 0; i < num; i++) {466 result = lpi2c_imx_start(lpi2c_imx, &msgs[i]);467 if (result)468 goto disable;469 470 /* quick smbus */471 if (num == 1 && msgs[0].len == 0)472 goto stop;473 474 lpi2c_imx->rx_buf = NULL;475 lpi2c_imx->tx_buf = NULL;476 lpi2c_imx->delivered = 0;477 lpi2c_imx->msglen = msgs[i].len;478 init_completion(&lpi2c_imx->complete);479 480 if (msgs[i].flags & I2C_M_RD)481 lpi2c_imx_read(lpi2c_imx, &msgs[i]);482 else483 lpi2c_imx_write(lpi2c_imx, &msgs[i]);484 485 result = lpi2c_imx_msg_complete(lpi2c_imx);486 if (result)487 goto stop;488 489 if (!(msgs[i].flags & I2C_M_RD)) {490 result = lpi2c_imx_txfifo_empty(lpi2c_imx);491 if (result)492 goto stop;493 }494 }495 496stop:497 lpi2c_imx_stop(lpi2c_imx);498 499 temp = readl(lpi2c_imx->base + LPI2C_MSR);500 if ((temp & MSR_NDF) && !result)501 result = -EIO;502 503disable:504 lpi2c_imx_master_disable(lpi2c_imx);505 506 dev_dbg(&lpi2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,507 (result < 0) ? "error" : "success msg",508 (result < 0) ? result : num);509 510 return (result < 0) ? result : num;511}512 513static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)514{515 struct lpi2c_imx_struct *lpi2c_imx = dev_id;516 unsigned int enabled;517 unsigned int temp;518 519 enabled = readl(lpi2c_imx->base + LPI2C_MIER);520 521 lpi2c_imx_intctrl(lpi2c_imx, 0);522 temp = readl(lpi2c_imx->base + LPI2C_MSR);523 temp &= enabled;524 525 if (temp & MSR_NDF)526 complete(&lpi2c_imx->complete);527 else if (temp & MSR_RDF)528 lpi2c_imx_read_rxfifo(lpi2c_imx);529 else if (temp & MSR_TDF)530 lpi2c_imx_write_txfifo(lpi2c_imx);531 532 return IRQ_HANDLED;533}534 535static int lpi2c_imx_init_recovery_info(struct lpi2c_imx_struct *lpi2c_imx,536 struct platform_device *pdev)537{538 struct i2c_bus_recovery_info *bri = &lpi2c_imx->rinfo;539 540 bri->pinctrl = devm_pinctrl_get(&pdev->dev);541 if (IS_ERR(bri->pinctrl))542 return PTR_ERR(bri->pinctrl);543 544 lpi2c_imx->adapter.bus_recovery_info = bri;545 546 return 0;547}548 549static u32 lpi2c_imx_func(struct i2c_adapter *adapter)550{551 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |552 I2C_FUNC_SMBUS_READ_BLOCK_DATA;553}554 555static const struct i2c_algorithm lpi2c_imx_algo = {556 .master_xfer = lpi2c_imx_xfer,557 .functionality = lpi2c_imx_func,558};559 560static const struct of_device_id lpi2c_imx_of_match[] = {561 { .compatible = "fsl,imx7ulp-lpi2c" },562 { }563};564MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match);565 566static int lpi2c_imx_probe(struct platform_device *pdev)567{568 struct lpi2c_imx_struct *lpi2c_imx;569 unsigned int temp;570 int irq, ret;571 572 lpi2c_imx = devm_kzalloc(&pdev->dev, sizeof(*lpi2c_imx), GFP_KERNEL);573 if (!lpi2c_imx)574 return -ENOMEM;575 576 lpi2c_imx->base = devm_platform_ioremap_resource(pdev, 0);577 if (IS_ERR(lpi2c_imx->base))578 return PTR_ERR(lpi2c_imx->base);579 580 irq = platform_get_irq(pdev, 0);581 if (irq < 0)582 return irq;583 584 lpi2c_imx->adapter.owner = THIS_MODULE;585 lpi2c_imx->adapter.algo = &lpi2c_imx_algo;586 lpi2c_imx->adapter.dev.parent = &pdev->dev;587 lpi2c_imx->adapter.dev.of_node = pdev->dev.of_node;588 strscpy(lpi2c_imx->adapter.name, pdev->name,589 sizeof(lpi2c_imx->adapter.name));590 591 ret = devm_clk_bulk_get_all(&pdev->dev, &lpi2c_imx->clks);592 if (ret < 0)593 return dev_err_probe(&pdev->dev, ret, "can't get I2C peripheral clock\n");594 lpi2c_imx->num_clks = ret;595 596 ret = of_property_read_u32(pdev->dev.of_node,597 "clock-frequency", &lpi2c_imx->bitrate);598 if (ret)599 lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ;600 601 ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, 0,602 pdev->name, lpi2c_imx);603 if (ret)604 return dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", irq);605 606 i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx);607 platform_set_drvdata(pdev, lpi2c_imx);608 609 ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);610 if (ret)611 return ret;612 613 /*614 * Lock the parent clock rate to avoid getting parent clock upon615 * each transfer616 */617 ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);618 if (ret)619 return dev_err_probe(&pdev->dev, ret,620 "can't lock I2C peripheral clock rate\n");621 622 lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);623 if (!lpi2c_imx->rate_per)624 return dev_err_probe(&pdev->dev, -EINVAL,625 "can't get I2C peripheral clock rate\n");626 627 pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);628 pm_runtime_use_autosuspend(&pdev->dev);629 pm_runtime_get_noresume(&pdev->dev);630 pm_runtime_set_active(&pdev->dev);631 pm_runtime_enable(&pdev->dev);632 633 temp = readl(lpi2c_imx->base + LPI2C_PARAM);634 lpi2c_imx->txfifosize = 1 << (temp & 0x0f);635 lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);636 637 /* Init optional bus recovery function */638 ret = lpi2c_imx_init_recovery_info(lpi2c_imx, pdev);639 /* Give it another chance if pinctrl used is not ready yet */640 if (ret == -EPROBE_DEFER)641 goto rpm_disable;642 643 ret = i2c_add_adapter(&lpi2c_imx->adapter);644 if (ret)645 goto rpm_disable;646 647 pm_runtime_mark_last_busy(&pdev->dev);648 pm_runtime_put_autosuspend(&pdev->dev);649 650 dev_info(&lpi2c_imx->adapter.dev, "LPI2C adapter registered\n");651 652 return 0;653 654rpm_disable:655 pm_runtime_put(&pdev->dev);656 pm_runtime_disable(&pdev->dev);657 pm_runtime_dont_use_autosuspend(&pdev->dev);658 659 return ret;660}661 662static void lpi2c_imx_remove(struct platform_device *pdev)663{664 struct lpi2c_imx_struct *lpi2c_imx = platform_get_drvdata(pdev);665 666 i2c_del_adapter(&lpi2c_imx->adapter);667 668 pm_runtime_disable(&pdev->dev);669 pm_runtime_dont_use_autosuspend(&pdev->dev);670}671 672static int __maybe_unused lpi2c_runtime_suspend(struct device *dev)673{674 struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev);675 676 clk_bulk_disable(lpi2c_imx->num_clks, lpi2c_imx->clks);677 pinctrl_pm_select_sleep_state(dev);678 679 return 0;680}681 682static int __maybe_unused lpi2c_runtime_resume(struct device *dev)683{684 struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev);685 int ret;686 687 pinctrl_pm_select_default_state(dev);688 ret = clk_bulk_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);689 if (ret) {690 dev_err(dev, "failed to enable I2C clock, ret=%d\n", ret);691 return ret;692 }693 694 return 0;695}696 697static const struct dev_pm_ops lpi2c_pm_ops = {698 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,699 pm_runtime_force_resume)700 SET_RUNTIME_PM_OPS(lpi2c_runtime_suspend,701 lpi2c_runtime_resume, NULL)702};703 704static struct platform_driver lpi2c_imx_driver = {705 .probe = lpi2c_imx_probe,706 .remove_new = lpi2c_imx_remove,707 .driver = {708 .name = DRIVER_NAME,709 .of_match_table = lpi2c_imx_of_match,710 .pm = &lpi2c_pm_ops,711 },712};713 714module_platform_driver(lpi2c_imx_driver);715 716MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");717MODULE_DESCRIPTION("I2C adapter driver for LPI2C bus");718MODULE_LICENSE("GPL");719