hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/i2c/busses/i2c-omap.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * TI OMAP I2C master mode driver
34 *
....@@ -12,16 +13,6 @@
1213 * Juha Yrjölä <juha.yrjola@solidboot.com>
1314 * Syed Khasim <x0khasim@ti.com>
1415 * Nishant Menon <nm@ti.com>
15
- *
16
- * This program is free software; you can redistribute it and/or modify
17
- * it under the terms of the GNU General Public License as published by
18
- * the Free Software Foundation; either version 2 of the License, or
19
- * (at your option) any later version.
20
- *
21
- * This program is distributed in the hope that it will be useful,
22
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
- * GNU General Public License for more details.
2516 */
2617
2718 #include <linux/module.h>
....@@ -268,6 +259,8 @@
268259 [OMAP_I2C_IP_V2_IRQENABLE_SET] = 0x2c,
269260 [OMAP_I2C_IP_V2_IRQENABLE_CLR] = 0x30,
270261 };
262
+
263
+static int omap_i2c_xfer_data(struct omap_i2c_dev *omap);
271264
272265 static inline void omap_i2c_write_reg(struct omap_i2c_dev *omap,
273266 int reg, u16 val)
....@@ -648,15 +641,28 @@
648641 (1000 * omap->speed / 8);
649642 }
650643
644
+static void omap_i2c_wait(struct omap_i2c_dev *omap)
645
+{
646
+ u16 stat;
647
+ u16 mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG);
648
+ int count = 0;
649
+
650
+ do {
651
+ stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);
652
+ count++;
653
+ } while (!(stat & mask) && count < 5);
654
+}
655
+
651656 /*
652657 * Low level master read/write transaction.
653658 */
654659 static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
655
- struct i2c_msg *msg, int stop)
660
+ struct i2c_msg *msg, int stop, bool polling)
656661 {
657662 struct omap_i2c_dev *omap = i2c_get_adapdata(adap);
658663 unsigned long timeout;
659664 u16 w;
665
+ int ret;
660666
661667 dev_dbg(omap->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
662668 msg->addr, msg->len, msg->flags, stop);
....@@ -680,7 +686,8 @@
680686 w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
681687 omap_i2c_write_reg(omap, OMAP_I2C_BUF_REG, w);
682688
683
- reinit_completion(&omap->cmd_complete);
689
+ if (!polling)
690
+ reinit_completion(&omap->cmd_complete);
684691 omap->cmd_err = 0;
685692
686693 w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
....@@ -732,8 +739,18 @@
732739 * REVISIT: We should abort the transfer on signals, but the bus goes
733740 * into arbitration and we're currently unable to recover from it.
734741 */
735
- timeout = wait_for_completion_timeout(&omap->cmd_complete,
736
- OMAP_I2C_TIMEOUT);
742
+ if (!polling) {
743
+ timeout = wait_for_completion_timeout(&omap->cmd_complete,
744
+ OMAP_I2C_TIMEOUT);
745
+ } else {
746
+ do {
747
+ omap_i2c_wait(omap);
748
+ ret = omap_i2c_xfer_data(omap);
749
+ } while (ret == -EAGAIN);
750
+
751
+ timeout = !ret;
752
+ }
753
+
737754 if (timeout == 0) {
738755 dev_err(omap->dev, "controller timed out\n");
739756 omap_i2c_reset(omap);
....@@ -772,7 +789,8 @@
772789 * to do the work during IRQ processing.
773790 */
774791 static int
775
-omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
792
+omap_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg msgs[], int num,
793
+ bool polling)
776794 {
777795 struct omap_i2c_dev *omap = i2c_get_adapdata(adap);
778796 int i;
....@@ -794,7 +812,8 @@
794812 omap->set_mpu_wkup_lat(omap->dev, omap->latency);
795813
796814 for (i = 0; i < num; i++) {
797
- r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
815
+ r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)),
816
+ polling);
798817 if (r != 0)
799818 break;
800819 }
....@@ -811,6 +830,18 @@
811830 pm_runtime_mark_last_busy(omap->dev);
812831 pm_runtime_put_autosuspend(omap->dev);
813832 return r;
833
+}
834
+
835
+static int
836
+omap_i2c_xfer_irq(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
837
+{
838
+ return omap_i2c_xfer_common(adap, msgs, num, false);
839
+}
840
+
841
+static int
842
+omap_i2c_xfer_polling(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
843
+{
844
+ return omap_i2c_xfer_common(adap, msgs, num, true);
814845 }
815846
816847 static u32
....@@ -1027,7 +1058,7 @@
10271058 u16 stat;
10281059
10291060 stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);
1030
- mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG);
1061
+ mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;
10311062
10321063 if (stat & mask)
10331064 ret = IRQ_WAKE_THREAD;
....@@ -1035,10 +1066,8 @@
10351066 return ret;
10361067 }
10371068
1038
-static irqreturn_t
1039
-omap_i2c_isr_thread(int this_irq, void *dev_id)
1069
+static int omap_i2c_xfer_data(struct omap_i2c_dev *omap)
10401070 {
1041
- struct omap_i2c_dev *omap = dev_id;
10421071 u16 bits;
10431072 u16 stat;
10441073 int err = 0, count = 0;
....@@ -1056,7 +1085,8 @@
10561085
10571086 if (!stat) {
10581087 /* my work here is done */
1059
- goto out;
1088
+ err = -EAGAIN;
1089
+ break;
10601090 }
10611091
10621092 dev_dbg(omap->dev, "IRQ (ISR = 0x%04x)\n", stat);
....@@ -1165,14 +1195,25 @@
11651195 }
11661196 } while (stat);
11671197
1168
- omap_i2c_complete_cmd(omap, err);
1198
+ return err;
1199
+}
11691200
1170
-out:
1201
+static irqreturn_t
1202
+omap_i2c_isr_thread(int this_irq, void *dev_id)
1203
+{
1204
+ int ret;
1205
+ struct omap_i2c_dev *omap = dev_id;
1206
+
1207
+ ret = omap_i2c_xfer_data(omap);
1208
+ if (ret != -EAGAIN)
1209
+ omap_i2c_complete_cmd(omap, ret);
1210
+
11711211 return IRQ_HANDLED;
11721212 }
11731213
11741214 static const struct i2c_algorithm omap_i2c_algo = {
1175
- .master_xfer = omap_i2c_xfer,
1215
+ .master_xfer = omap_i2c_xfer_irq,
1216
+ .master_xfer_atomic = omap_i2c_xfer_polling,
11761217 .functionality = omap_i2c_func,
11771218 };
11781219
....@@ -1314,7 +1355,6 @@
13141355 {
13151356 struct omap_i2c_dev *omap;
13161357 struct i2c_adapter *adap;
1317
- struct resource *mem;
13181358 const struct omap_i2c_bus_platform_data *pdata =
13191359 dev_get_platdata(&pdev->dev);
13201360 struct device_node *node = pdev->dev.of_node;
....@@ -1325,23 +1365,20 @@
13251365 u16 minor, major;
13261366
13271367 irq = platform_get_irq(pdev, 0);
1328
- if (irq < 0) {
1329
- dev_err(&pdev->dev, "no irq resource?\n");
1368
+ if (irq < 0)
13301369 return irq;
1331
- }
13321370
13331371 omap = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
13341372 if (!omap)
13351373 return -ENOMEM;
13361374
1337
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1338
- omap->base = devm_ioremap_resource(&pdev->dev, mem);
1375
+ omap->base = devm_platform_ioremap_resource(pdev, 0);
13391376 if (IS_ERR(omap->base))
13401377 return PTR_ERR(omap->base);
13411378
13421379 match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
13431380 if (match) {
1344
- u32 freq = 100000; /* default to 100000 Hz */
1381
+ u32 freq = I2C_MAX_STANDARD_MODE_FREQ;
13451382
13461383 pdata = match->data;
13471384 omap->flags = pdata->flags;
....@@ -1367,9 +1404,9 @@
13671404 pm_runtime_set_autosuspend_delay(omap->dev, OMAP_I2C_PM_TIMEOUT);
13681405 pm_runtime_use_autosuspend(omap->dev);
13691406
1370
- r = pm_runtime_get_sync(omap->dev);
1407
+ r = pm_runtime_resume_and_get(omap->dev);
13711408 if (r < 0)
1372
- goto err_free_mem;
1409
+ goto err_disable_pm;
13731410
13741411 /*
13751412 * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.
....@@ -1388,7 +1425,6 @@
13881425 major = OMAP_I2C_REV_SCHEME_0_MAJOR(omap->rev);
13891426 break;
13901427 case OMAP_I2C_SCHEME_1:
1391
- /* FALLTHROUGH */
13921428 default:
13931429 omap->regs = (u8 *)reg_map_ip_v2;
13941430 rev = (rev << 16) |
....@@ -1477,8 +1513,8 @@
14771513 omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
14781514 pm_runtime_dont_use_autosuspend(omap->dev);
14791515 pm_runtime_put_sync(omap->dev);
1516
+err_disable_pm:
14801517 pm_runtime_disable(&pdev->dev);
1481
-err_free_mem:
14821518
14831519 return r;
14841520 }
....@@ -1489,7 +1525,7 @@
14891525 int ret;
14901526
14911527 i2c_del_adapter(&omap->adapter);
1492
- ret = pm_runtime_get_sync(&pdev->dev);
1528
+ ret = pm_runtime_resume_and_get(&pdev->dev);
14931529 if (ret < 0)
14941530 return ret;
14951531