Skip to content

Commit 9a48d4a

Browse files
committed
Merge tag 'i3c/fixes-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux
Pull i3c fixes from Alexandre Belloni: "This introduces the I3C_OR_I2C symbol which is not a fix per se but is affecting multiple subsystems so it is included to ease synchronization. Apart from that, Adrian is mostly fixing the mipi-i3c-hci driver DMA handling, and I took the opportunity to add two fixes for the dw-i3c driver. Subsystem: - simplify combined i3c/i2c dependencies Drivers: - dw: handle 2C properly, fix possible race condition - mipi-i3c-hci: many DMA related fixes" * tag 'i3c/fixes-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and reattach i3c: master: dw-i3c: Fix missing of_node for virtual I2C adapter i3c: mipi-i3c-hci: Fallback to software reset when bus disable fails i3c: mipi-i3c-hci: Fix handling of shared IRQs during early initialization i3c: mipi-i3c-hci: Fix race in DMA error handling in interrupt context i3c: mipi-i3c-hci: Consolidate common xfer processing logic i3c: mipi-i3c-hci: Restart DMA ring correctly after dequeue abort i3c: mipi-i3c-hci: Add missing TID field to no-op command descriptor i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue i3c: mipi-i3c-hci: Fix race between DMA ring dequeue and interrupt handler i3c: mipi-i3c-hci: Fix race in DMA ring dequeue i3c: mipi-i3c-hci: Fix race in DMA ring enqueue for parallel xfers i3c: mipi-i3c-hci: Consolidate spinlocks i3c: mipi-i3c-hci: Factor out DMA mapping from queuing path i3c: mipi-i3c-hci: Fix Hot-Join NACK i3c: mipi-i3c-hci: Use ETIMEDOUT instead of ETIME for timeout errors i3c: simplify combined i3c/i2c dependencies
2 parents f26de90 + f311a05 commit 9a48d4a

12 files changed

Lines changed: 211 additions & 158 deletions

File tree

drivers/hwmon/Kconfig

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,8 +1493,7 @@ config SENSORS_LM73
14931493

14941494
config SENSORS_LM75
14951495
tristate "National Semiconductor LM75 and compatibles"
1496-
depends on I2C
1497-
depends on I3C || !I3C
1496+
depends on I3C_OR_I2C
14981497
select REGMAP_I2C
14991498
select REGMAP_I3C if I3C
15001499
help
@@ -2382,8 +2381,7 @@ config SENSORS_TMP103
23822381

23832382
config SENSORS_TMP108
23842383
tristate "Texas Instruments TMP108"
2385-
depends on I2C
2386-
depends on I3C || !I3C
2384+
depends on I3C_OR_I2C
23872385
select REGMAP_I2C
23882386
select REGMAP_I3C if I3C
23892387
help

drivers/i3c/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,15 @@ menuconfig I3C
2222
if I3C
2323
source "drivers/i3c/master/Kconfig"
2424
endif # I3C
25+
26+
config I3C_OR_I2C
27+
tristate
28+
default m if I3C=m
29+
default I2C
30+
help
31+
Device drivers using module_i3c_i2c_driver() can use either
32+
i2c or i3c hosts, but cannot be built-in for the kernel when
33+
CONFIG_I3C=m.
34+
35+
Add 'depends on I2C_OR_I3C' in Kconfig for those drivers to
36+
get the correct dependencies.

drivers/i3c/master/dw-i3c-master.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
10241024
master->free_pos &= ~BIT(pos);
10251025
}
10261026

1027-
writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
1027+
writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT,
10281028
master->regs +
10291029
DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
10301030

@@ -1053,7 +1053,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev)
10531053
master->free_pos &= ~BIT(pos);
10541054
i3c_dev_set_master_data(dev, data);
10551055

1056-
writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr),
1056+
writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT,
10571057
master->regs +
10581058
DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
10591059

@@ -1659,6 +1659,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
16591659
pm_runtime_get_noresume(&pdev->dev);
16601660

16611661
INIT_WORK(&master->hj_work, dw_i3c_hj_work);
1662+
1663+
device_set_of_node_from_dev(&master->base.i2c.dev, &pdev->dev);
16621664
ret = i3c_master_register(&master->base, &pdev->dev,
16631665
&dw_mipi_i3c_ops, false);
16641666
if (ret)

drivers/i3c/master/mipi-i3c-hci/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define CMD_0_TOC W0_BIT_(31)
1818
#define CMD_0_ROC W0_BIT_(30)
1919
#define CMD_0_ATTR W0_MASK(2, 0)
20+
#define CMD_0_TID W0_MASK(6, 3)
2021

2122
/*
2223
* Response Descriptor Structure

drivers/i3c/master/mipi-i3c-hci/cmd_v1.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,10 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci)
331331
CMD_A0_ROC | CMD_A0_TOC;
332332
xfer->cmd_desc[1] = 0;
333333
xfer->completion = &done;
334-
hci->io->queue_xfer(hci, xfer, 1);
335-
if (!wait_for_completion_timeout(&done, HZ) &&
336-
hci->io->dequeue_xfer(hci, xfer, 1)) {
337-
ret = -ETIME;
334+
xfer->timeout = HZ;
335+
ret = i3c_hci_process_xfer(hci, xfer, 1);
336+
if (ret)
338337
break;
339-
}
340338
if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER ||
341339
RESP_STATUS(xfer->response) == RESP_ERR_NACK) &&
342340
RESP_DATA_LENGTH(xfer->response) == 1) {

drivers/i3c/master/mipi-i3c-hci/cmd_v2.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ static int hci_cmd_v2_daa(struct i3c_hci *hci)
253253
xfer[0].rnw = true;
254254
xfer[0].cmd_desc[1] = CMD_A1_DATA_LENGTH(8);
255255
xfer[1].completion = &done;
256+
xfer[1].timeout = HZ;
256257

257258
for (;;) {
258259
ret = i3c_master_get_free_addr(&hci->master, next_addr);
@@ -272,12 +273,9 @@ static int hci_cmd_v2_daa(struct i3c_hci *hci)
272273
CMD_A0_ASSIGN_ADDRESS(next_addr) |
273274
CMD_A0_ROC |
274275
CMD_A0_TOC;
275-
hci->io->queue_xfer(hci, xfer, 2);
276-
if (!wait_for_completion_timeout(&done, HZ) &&
277-
hci->io->dequeue_xfer(hci, xfer, 2)) {
278-
ret = -ETIME;
276+
ret = i3c_hci_process_xfer(hci, xfer, 2);
277+
if (ret)
279278
break;
280-
}
281279
if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) {
282280
ret = 0; /* no more devices to be assigned */
283281
break;

drivers/i3c/master/mipi-i3c-hci/core.c

Lines changed: 90 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ static int i3c_hci_bus_init(struct i3c_master_controller *m)
152152
if (hci->quirks & HCI_QUIRK_RESP_BUF_THLD)
153153
amd_set_resp_buf_thld(hci);
154154

155-
reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE);
155+
scoped_guard(spinlock_irqsave, &hci->lock)
156+
hci->irq_inactive = false;
157+
158+
/* Enable bus with Hot-Join disabled */
159+
reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE | HC_CONTROL_HOT_JOIN_CTRL);
156160
dev_dbg(&hci->master.dev, "HC_CONTROL = %#x", reg_read(HC_CONTROL));
157161

158162
return 0;
@@ -177,21 +181,51 @@ static int i3c_hci_bus_disable(struct i3c_hci *hci)
177181
return ret;
178182
}
179183

184+
static int i3c_hci_software_reset(struct i3c_hci *hci)
185+
{
186+
u32 regval;
187+
int ret;
188+
189+
/*
190+
* SOFT_RST must be clear before we write to it.
191+
* Then we must wait until it clears again.
192+
*/
193+
ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval,
194+
!(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC);
195+
if (ret) {
196+
dev_err(&hci->master.dev, "%s: Software reset stuck\n", __func__);
197+
return ret;
198+
}
199+
200+
reg_write(RESET_CONTROL, SOFT_RST);
201+
202+
ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval,
203+
!(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC);
204+
if (ret) {
205+
dev_err(&hci->master.dev, "%s: Software reset failed\n", __func__);
206+
return ret;
207+
}
208+
209+
return 0;
210+
}
211+
180212
void i3c_hci_sync_irq_inactive(struct i3c_hci *hci)
181213
{
182214
struct platform_device *pdev = to_platform_device(hci->master.dev.parent);
183215
int irq = platform_get_irq(pdev, 0);
184216

185217
reg_write(INTR_SIGNAL_ENABLE, 0x0);
186-
hci->irq_inactive = true;
187218
synchronize_irq(irq);
219+
scoped_guard(spinlock_irqsave, &hci->lock)
220+
hci->irq_inactive = true;
188221
}
189222

190223
static void i3c_hci_bus_cleanup(struct i3c_master_controller *m)
191224
{
192225
struct i3c_hci *hci = to_i3c_hci(m);
193226

194-
i3c_hci_bus_disable(hci);
227+
if (i3c_hci_bus_disable(hci))
228+
i3c_hci_software_reset(hci);
195229
hci->io->cleanup(hci);
196230
}
197231

@@ -212,6 +246,36 @@ void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci)
212246
reg_write(DCT_SECTION, FIELD_PREP(DCT_TABLE_INDEX, 0));
213247
}
214248

249+
int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n)
250+
{
251+
struct completion *done = xfer[n - 1].completion;
252+
unsigned long timeout = xfer[n - 1].timeout;
253+
int ret;
254+
255+
ret = hci->io->queue_xfer(hci, xfer, n);
256+
if (ret)
257+
return ret;
258+
259+
if (!wait_for_completion_timeout(done, timeout)) {
260+
if (hci->io->dequeue_xfer(hci, xfer, n)) {
261+
dev_err(&hci->master.dev, "%s: timeout error\n", __func__);
262+
return -ETIMEDOUT;
263+
}
264+
return 0;
265+
}
266+
267+
if (hci->io->handle_error) {
268+
bool error = false;
269+
270+
for (int i = 0; i < n && !error; i++)
271+
error = RESP_STATUS(xfer[i].response);
272+
if (error)
273+
return hci->io->handle_error(hci, xfer, n);
274+
}
275+
276+
return 0;
277+
}
278+
215279
static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
216280
struct i3c_ccc_cmd *ccc)
217281
{
@@ -252,18 +316,14 @@ static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
252316
last = i - 1;
253317
xfer[last].cmd_desc[0] |= CMD_0_TOC;
254318
xfer[last].completion = &done;
319+
xfer[last].timeout = HZ;
255320

256321
if (prefixed)
257322
xfer--;
258323

259-
ret = hci->io->queue_xfer(hci, xfer, nxfers);
324+
ret = i3c_hci_process_xfer(hci, xfer, nxfers);
260325
if (ret)
261326
goto out;
262-
if (!wait_for_completion_timeout(&done, HZ) &&
263-
hci->io->dequeue_xfer(hci, xfer, nxfers)) {
264-
ret = -ETIME;
265-
goto out;
266-
}
267327
for (i = prefixed; i < nxfers; i++) {
268328
if (ccc->rnw)
269329
ccc->dests[i - prefixed].payload.len =
@@ -334,15 +394,11 @@ static int i3c_hci_i3c_xfers(struct i3c_dev_desc *dev,
334394
last = i - 1;
335395
xfer[last].cmd_desc[0] |= CMD_0_TOC;
336396
xfer[last].completion = &done;
397+
xfer[last].timeout = HZ;
337398

338-
ret = hci->io->queue_xfer(hci, xfer, nxfers);
399+
ret = i3c_hci_process_xfer(hci, xfer, nxfers);
339400
if (ret)
340401
goto out;
341-
if (!wait_for_completion_timeout(&done, HZ) &&
342-
hci->io->dequeue_xfer(hci, xfer, nxfers)) {
343-
ret = -ETIME;
344-
goto out;
345-
}
346402
for (i = 0; i < nxfers; i++) {
347403
if (i3c_xfers[i].rnw)
348404
i3c_xfers[i].len = RESP_DATA_LENGTH(xfer[i].response);
@@ -382,15 +438,11 @@ static int i3c_hci_i2c_xfers(struct i2c_dev_desc *dev,
382438
last = i - 1;
383439
xfer[last].cmd_desc[0] |= CMD_0_TOC;
384440
xfer[last].completion = &done;
441+
xfer[last].timeout = m->i2c.timeout;
385442

386-
ret = hci->io->queue_xfer(hci, xfer, nxfers);
443+
ret = i3c_hci_process_xfer(hci, xfer, nxfers);
387444
if (ret)
388445
goto out;
389-
if (!wait_for_completion_timeout(&done, m->i2c.timeout) &&
390-
hci->io->dequeue_xfer(hci, xfer, nxfers)) {
391-
ret = -ETIME;
392-
goto out;
393-
}
394446
for (i = 0; i < nxfers; i++) {
395447
if (RESP_STATUS(xfer[i].response) != RESP_SUCCESS) {
396448
ret = -EIO;
@@ -566,6 +618,8 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
566618
irqreturn_t result = IRQ_NONE;
567619
u32 val;
568620

621+
guard(spinlock)(&hci->lock);
622+
569623
/*
570624
* The IRQ can be shared, so the handler may be called when the IRQ is
571625
* due to a different device. That could happen when runtime suspended,
@@ -601,34 +655,6 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
601655
return result;
602656
}
603657

604-
static int i3c_hci_software_reset(struct i3c_hci *hci)
605-
{
606-
u32 regval;
607-
int ret;
608-
609-
/*
610-
* SOFT_RST must be clear before we write to it.
611-
* Then we must wait until it clears again.
612-
*/
613-
ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval,
614-
!(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC);
615-
if (ret) {
616-
dev_err(&hci->master.dev, "%s: Software reset stuck\n", __func__);
617-
return ret;
618-
}
619-
620-
reg_write(RESET_CONTROL, SOFT_RST);
621-
622-
ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval,
623-
!(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC);
624-
if (ret) {
625-
dev_err(&hci->master.dev, "%s: Software reset failed\n", __func__);
626-
return ret;
627-
}
628-
629-
return 0;
630-
}
631-
632658
static inline bool is_version_1_1_or_newer(struct i3c_hci *hci)
633659
{
634660
return hci->version_major > 1 || (hci->version_major == 1 && hci->version_minor > 0);
@@ -739,8 +765,12 @@ static int i3c_hci_runtime_suspend(struct device *dev)
739765
int ret;
740766

741767
ret = i3c_hci_bus_disable(hci);
742-
if (ret)
768+
if (ret) {
769+
/* Fall back to software reset to disable the bus */
770+
ret = i3c_hci_software_reset(hci);
771+
i3c_hci_sync_irq_inactive(hci);
743772
return ret;
773+
}
744774

745775
hci->io->suspend(hci);
746776

@@ -760,11 +790,13 @@ static int i3c_hci_runtime_resume(struct device *dev)
760790

761791
mipi_i3c_hci_dat_v1.restore(hci);
762792

763-
hci->irq_inactive = false;
764-
765793
hci->io->resume(hci);
766794

767-
reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE);
795+
scoped_guard(spinlock_irqsave, &hci->lock)
796+
hci->irq_inactive = false;
797+
798+
/* Enable bus with Hot-Join disabled */
799+
reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE | HC_CONTROL_HOT_JOIN_CTRL);
768800

769801
return 0;
770802
}
@@ -924,6 +956,9 @@ static int i3c_hci_probe(struct platform_device *pdev)
924956
if (!hci)
925957
return -ENOMEM;
926958

959+
spin_lock_init(&hci->lock);
960+
mutex_init(&hci->control_mutex);
961+
927962
/*
928963
* Multi-bus instances share the same MMIO address range, but not
929964
* necessarily in separate contiguous sub-ranges. To avoid overlapping
@@ -950,6 +985,8 @@ static int i3c_hci_probe(struct platform_device *pdev)
950985
if (ret)
951986
return ret;
952987

988+
hci->irq_inactive = true;
989+
953990
irq = platform_get_irq(pdev, 0);
954991
ret = devm_request_irq(&pdev->dev, irq, i3c_hci_irq_handler,
955992
IRQF_SHARED, NULL, hci);

0 commit comments

Comments
 (0)