Skip to content

Commit 1c41041

Browse files
committed
Merge tag 'i3c/for-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux
Pull i3c updates from Alexandre Belloni: "There are now more fixes because as stated in my previous pull request, people now have access to actual hardware. Core: - handle IBI in the proper order Drivers: - cdns: fix status register access - mipi-i3c-hci: many fixes now that the driver has been actually tested - svc: many IBI fixes, correct compatible string, fix hot join corner cases" * tag 'i3c/for-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (29 commits) i3c: master: handle IBIs in order they came i3c: master: mipi-i3c-hci: Fix a kernel panic for accessing DAT_data. i3c: master: svc: fix compatibility string mismatch with binding doc i3c: master: svc: fix random hot join failure since timeout error i3c: master: svc: fix SDA keep low when polling IBIWON timeout happen i3c: master: svc: fix check wrong status register in irq handler i3c: master: svc: fix ibi may not return mandatory data byte i3c: master: svc: fix wrong data return when IBI happen during start frame i3c: master: svc: fix race condition in ibi work thread i3c: Fix typo "Provisional ID" to "Provisioned ID" i3c: Fix potential refcount leak in i3c_master_register_new_i3c_devs i3c: mipi-i3c-hci: Resume controller after aborted transfer i3c: mipi-i3c-hci: Resume controller explicitly i3c: mipi-i3c-hci: Fix missing xfer->completion in hci_cmd_v1_daa() i3c: mipi-i3c-hci: Do not unmap region not mapped for transfer i3c: mipi-i3c-hci: Set number of SW enabled Ring Bundles earlier i3c: mipi-i3c-hci: Fix race between bus cleanup and interrupt i3c: mipi-i3c-hci: Set ring start request together with enable i3c: mipi-i3c-hci: Remove BUG() when Ring Abort request times out i3c: mipi-i3c-hci: Fix out of bounds access in hci_dma_irq_handler ...
2 parents b8cc56d + 9fd00df commit 1c41041

File tree

13 files changed

+134
-45
lines changed

13 files changed

+134
-45
lines changed

Documentation/ABI/testing/sysfs-bus-i3c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ What: /sys/bus/i3c/devices/i3c-<bus-id>/pid
6767
KernelVersion: 5.0
6868
6969
Description:
70-
PID stands for Provisional ID and is used to uniquely identify
70+
PID stands for Provisioned ID and is used to uniquely identify
7171
a device on a bus. This PID contains information about the
7272
vendor, the part and an instance ID so that several devices of
7373
the same type can be connected on the same bus.
@@ -123,7 +123,7 @@ What: /sys/bus/i3c/devices/i3c-<bus-id>/<bus-id>-<device-pid>/pid
123123
KernelVersion: 5.0
124124
125125
Description:
126-
PID stands for Provisional ID and is used to uniquely identify
126+
PID stands for Provisioned ID and is used to uniquely identify
127127
a device on a bus. This PID contains information about the
128128
vendor, the part and an instance ID so that several devices of
129129
the same type can be connected on the same bus.

Documentation/devicetree/bindings/i3c/i3c.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ patternProperties:
125125
minimum: 0
126126
maximum: 0x7f
127127
- description: |
128-
First half of the Provisional ID (following the PID
128+
First half of the Provisioned ID (following the PID
129129
definition provided by the I3C specification).
130130
131131
Contains the manufacturer ID left-shifted by 1.
132132
- description: |
133-
Second half of the Provisional ID (following the PID
133+
Second half of the Provisioned ID (following the PID
134134
definition provided by the I3C specification).
135135
136136
Contains the ORing of the part ID left-shifted by 16,

Documentation/driver-api/i3c/protocol.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ During DAA, each I3C device reports 3 important things:
7171
related capabilities
7272
* DCR: Device Characteristic Register. This 8-bit register describes the
7373
functionalities provided by the device
74-
* Provisional ID: A 48-bit unique identifier. On a given bus there should be no
75-
Provisional ID collision, otherwise the discovery mechanism may fail.
74+
* Provisioned ID: A 48-bit unique identifier. On a given bus there should be no
75+
Provisioned ID collision, otherwise the discovery mechanism may fail.
7676

7777
I3C slave events
7878
================

drivers/i3c/master.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,9 +1556,11 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
15561556
desc->dev->dev.of_node = desc->boardinfo->of_node;
15571557

15581558
ret = device_register(&desc->dev->dev);
1559-
if (ret)
1559+
if (ret) {
15601560
dev_err(&master->dev,
15611561
"Failed to add I3C device (err = %d)\n", ret);
1562+
put_device(&desc->dev->dev);
1563+
}
15621564
}
15631565
}
15641566

@@ -2340,7 +2342,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
23402342
adap->dev.parent = master->dev.parent;
23412343
adap->owner = master->dev.parent->driver->owner;
23422344
adap->algo = &i3c_master_i2c_algo;
2343-
strncpy(adap->name, dev_name(master->dev.parent), sizeof(adap->name));
2345+
strscpy(adap->name, dev_name(master->dev.parent), sizeof(adap->name));
23442346

23452347
/* FIXME: Should we allow i3c masters to override these values? */
23462348
adap->timeout = 1000;
@@ -2403,7 +2405,7 @@ static void i3c_master_unregister_i3c_devs(struct i3c_master_controller *master)
24032405
void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot)
24042406
{
24052407
atomic_inc(&dev->ibi->pending_ibis);
2406-
queue_work(dev->common.master->wq, &slot->work);
2408+
queue_work(dev->ibi->wq, &slot->work);
24072409
}
24082410
EXPORT_SYMBOL_GPL(i3c_master_queue_ibi);
24092411

@@ -2660,6 +2662,10 @@ int i3c_master_register(struct i3c_master_controller *master,
26602662
device_initialize(&master->dev);
26612663
dev_set_name(&master->dev, "i3c-%d", i3cbus->id);
26622664

2665+
master->dev.dma_mask = parent->dma_mask;
2666+
master->dev.coherent_dma_mask = parent->coherent_dma_mask;
2667+
master->dev.dma_parms = parent->dma_parms;
2668+
26632669
ret = of_populate_i3c_bus(master);
26642670
if (ret)
26652671
goto err_put_dev;
@@ -2848,6 +2854,12 @@ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,
28482854
if (!ibi)
28492855
return -ENOMEM;
28502856

2857+
ibi->wq = alloc_ordered_workqueue(dev_name(i3cdev_to_dev(dev->dev)), WQ_MEM_RECLAIM);
2858+
if (!ibi->wq) {
2859+
kfree(ibi);
2860+
return -ENOMEM;
2861+
}
2862+
28512863
atomic_set(&ibi->pending_ibis, 0);
28522864
init_completion(&ibi->all_ibis_handled);
28532865
ibi->handler = req->handler;
@@ -2875,6 +2887,12 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev)
28752887
WARN_ON(i3c_dev_disable_ibi_locked(dev));
28762888

28772889
master->ops->free_ibi(dev);
2890+
2891+
if (dev->ibi->wq) {
2892+
destroy_workqueue(dev->ibi->wq);
2893+
dev->ibi->wq = NULL;
2894+
}
2895+
28782896
kfree(dev->ibi);
28792897
dev->ibi = NULL;
28802898
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ struct dw_i3c_xfer {
233233
struct completion comp;
234234
int ret;
235235
unsigned int ncmds;
236-
struct dw_i3c_cmd cmds[];
236+
struct dw_i3c_cmd cmds[] __counted_by(ncmds);
237237
};
238238

239239
struct dw_i3c_i2c_dev_data {

drivers/i3c/master/i3c-master-cdns.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
#define SLV_STATUS1_HJ_DIS BIT(18)
192192
#define SLV_STATUS1_MR_DIS BIT(17)
193193
#define SLV_STATUS1_PROT_ERR BIT(16)
194-
#define SLV_STATUS1_DA(x) (((s) & GENMASK(15, 9)) >> 9)
194+
#define SLV_STATUS1_DA(s) (((s) & GENMASK(15, 9)) >> 9)
195195
#define SLV_STATUS1_HAS_DA BIT(8)
196196
#define SLV_STATUS1_DDR_RX_FULL BIT(7)
197197
#define SLV_STATUS1_DDR_TX_FULL BIT(6)
@@ -387,7 +387,7 @@ struct cdns_i3c_xfer {
387387
struct completion comp;
388388
int ret;
389389
unsigned int ncmds;
390-
struct cdns_i3c_cmd cmds[];
390+
struct cdns_i3c_cmd cmds[] __counted_by(ncmds);
391391
};
392392

393393
struct cdns_i3c_data {
@@ -1623,13 +1623,13 @@ static int cdns_i3c_master_probe(struct platform_device *pdev)
16231623
/* Device ID0 is reserved to describe this master. */
16241624
master->maxdevs = CONF_STATUS0_DEVS_NUM(val);
16251625
master->free_rr_slots = GENMASK(master->maxdevs, 1);
1626+
master->caps.ibirfifodepth = CONF_STATUS0_IBIR_DEPTH(val);
1627+
master->caps.cmdrfifodepth = CONF_STATUS0_CMDR_DEPTH(val);
16261628

16271629
val = readl(master->regs + CONF_STATUS1);
16281630
master->caps.cmdfifodepth = CONF_STATUS1_CMD_DEPTH(val);
16291631
master->caps.rxfifodepth = CONF_STATUS1_RX_DEPTH(val);
16301632
master->caps.txfifodepth = CONF_STATUS1_TX_DEPTH(val);
1631-
master->caps.ibirfifodepth = CONF_STATUS0_IBIR_DEPTH(val);
1632-
master->caps.cmdrfifodepth = CONF_STATUS0_CMDR_DEPTH(val);
16331633

16341634
spin_lock_init(&master->ibi.lock);
16351635
master->ibi.num_slots = CONF_STATUS1_IBI_HW_RES(val);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci)
332332
CMD_A0_DEV_COUNT(1) |
333333
CMD_A0_ROC | CMD_A0_TOC;
334334
xfer->cmd_desc[1] = 0;
335+
xfer->completion = &done;
335336
hci->io->queue_xfer(hci, xfer, 1);
336337
if (!wait_for_completion_timeout(&done, HZ) &&
337338
hci->io->dequeue_xfer(hci, xfer, 1)) {

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,20 @@ static int i3c_hci_bus_init(struct i3c_master_controller *m)
161161
static void i3c_hci_bus_cleanup(struct i3c_master_controller *m)
162162
{
163163
struct i3c_hci *hci = to_i3c_hci(m);
164+
struct platform_device *pdev = to_platform_device(m->dev.parent);
164165

165166
DBG("");
166167

167168
reg_clear(HC_CONTROL, HC_CONTROL_BUS_ENABLE);
169+
synchronize_irq(platform_get_irq(pdev, 0));
168170
hci->io->cleanup(hci);
169171
if (hci->cmd == &mipi_i3c_hci_cmd_v1)
170172
mipi_i3c_hci_dat_v1.cleanup(hci);
171173
}
172174

173175
void mipi_i3c_hci_resume(struct i3c_hci *hci)
174176
{
175-
/* the HC_CONTROL_RESUME bit is R/W1C so just read and write back */
176-
reg_write(HC_CONTROL, reg_read(HC_CONTROL));
177+
reg_set(HC_CONTROL, HC_CONTROL_RESUME);
177178
}
178179

179180
/* located here rather than pio.c because needed bits are in core reg space */
@@ -610,17 +611,17 @@ static int i3c_hci_init(struct i3c_hci *hci)
610611
offset = FIELD_GET(DAT_TABLE_OFFSET, regval);
611612
hci->DAT_regs = offset ? hci->base_regs + offset : NULL;
612613
hci->DAT_entries = FIELD_GET(DAT_TABLE_SIZE, regval);
613-
hci->DAT_entry_size = FIELD_GET(DAT_ENTRY_SIZE, regval);
614+
hci->DAT_entry_size = FIELD_GET(DAT_ENTRY_SIZE, regval) ? 0 : 8;
614615
dev_info(&hci->master.dev, "DAT: %u %u-bytes entries at offset %#x\n",
615-
hci->DAT_entries, hci->DAT_entry_size * 4, offset);
616+
hci->DAT_entries, hci->DAT_entry_size, offset);
616617

617618
regval = reg_read(DCT_SECTION);
618619
offset = FIELD_GET(DCT_TABLE_OFFSET, regval);
619620
hci->DCT_regs = offset ? hci->base_regs + offset : NULL;
620621
hci->DCT_entries = FIELD_GET(DCT_TABLE_SIZE, regval);
621-
hci->DCT_entry_size = FIELD_GET(DCT_ENTRY_SIZE, regval);
622+
hci->DCT_entry_size = FIELD_GET(DCT_ENTRY_SIZE, regval) ? 0 : 16;
622623
dev_info(&hci->master.dev, "DCT: %u %u-bytes entries at offset %#x\n",
623-
hci->DCT_entries, hci->DCT_entry_size * 4, offset);
624+
hci->DCT_entries, hci->DCT_entry_size, offset);
624625

625626
regval = reg_read(RING_HEADERS_SECTION);
626627
offset = FIELD_GET(RING_HEADERS_OFFSET, regval);
@@ -787,6 +788,7 @@ static struct platform_driver i3c_hci_driver = {
787788
},
788789
};
789790
module_platform_driver(i3c_hci_driver);
791+
MODULE_ALIAS("platform:mipi-i3c-hci");
790792

791793
MODULE_AUTHOR("Nicolas Pitre <[email protected]>");
792794
MODULE_DESCRIPTION("MIPI I3C HCI driver");

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

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,17 @@ static int hci_dat_v1_init(struct i3c_hci *hci)
6464
return -EOPNOTSUPP;
6565
}
6666

67-
/* use a bitmap for faster free slot search */
68-
hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL);
69-
if (!hci->DAT_data)
70-
return -ENOMEM;
71-
72-
/* clear them */
73-
for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) {
74-
dat_w0_write(dat_idx, 0);
75-
dat_w1_write(dat_idx, 0);
67+
if (!hci->DAT_data) {
68+
/* use a bitmap for faster free slot search */
69+
hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL);
70+
if (!hci->DAT_data)
71+
return -ENOMEM;
72+
73+
/* clear them */
74+
for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) {
75+
dat_w0_write(dat_idx, 0);
76+
dat_w1_write(dat_idx, 0);
77+
}
7678
}
7779

7880
return 0;
@@ -87,7 +89,13 @@ static void hci_dat_v1_cleanup(struct i3c_hci *hci)
8789
static int hci_dat_v1_alloc_entry(struct i3c_hci *hci)
8890
{
8991
unsigned int dat_idx;
92+
int ret;
9093

94+
if (!hci->DAT_data) {
95+
ret = hci_dat_v1_init(hci);
96+
if (ret)
97+
return ret;
98+
}
9199
dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries);
92100
if (dat_idx >= hci->DAT_entries)
93101
return -ENOENT;
@@ -103,7 +111,8 @@ static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx)
103111
{
104112
dat_w0_write(dat_idx, 0);
105113
dat_w1_write(dat_idx, 0);
106-
__clear_bit(dat_idx, hci->DAT_data);
114+
if (hci->DAT_data)
115+
__clear_bit(dat_idx, hci->DAT_data);
107116
}
108117

109118
static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci,

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ struct hci_rh_data {
139139

140140
struct hci_rings_data {
141141
unsigned int total;
142-
struct hci_rh_data headers[];
142+
struct hci_rh_data headers[] __counted_by(total);
143143
};
144144

145145
struct hci_dma_dev_ibi_data {
@@ -229,6 +229,9 @@ static int hci_dma_init(struct i3c_hci *hci)
229229
hci->io_data = rings;
230230
rings->total = nr_rings;
231231

232+
regval = FIELD_PREP(MAX_HEADER_COUNT, rings->total);
233+
rhs_reg_write(CONTROL, regval);
234+
232235
for (i = 0; i < rings->total; i++) {
233236
u32 offset = rhs_reg_read(RHn_OFFSET(i));
234237

@@ -325,11 +328,10 @@ static int hci_dma_init(struct i3c_hci *hci)
325328
rh_reg_write(INTR_SIGNAL_ENABLE, regval);
326329

327330
ring_ready:
328-
rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE);
331+
rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE |
332+
RING_CTRL_RUN_STOP);
329333
}
330334

331-
regval = FIELD_PREP(MAX_HEADER_COUNT, rings->total);
332-
rhs_reg_write(CONTROL, regval);
333335
return 0;
334336

335337
err_out:
@@ -345,6 +347,8 @@ static void hci_dma_unmap_xfer(struct i3c_hci *hci,
345347

346348
for (i = 0; i < n; i++) {
347349
xfer = xfer_list + i;
350+
if (!xfer->data)
351+
continue;
348352
dma_unmap_single(&hci->master.dev,
349353
xfer->data_dma, xfer->data_len,
350354
xfer->rnw ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
@@ -450,10 +454,9 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,
450454
/*
451455
* We're deep in it if ever this condition is ever met.
452456
* Hardware might still be writing to memory, etc.
453-
* Better suspend the world than risking silent corruption.
454457
*/
455458
dev_crit(&hci->master.dev, "unable to abort the ring\n");
456-
BUG();
459+
WARN_ON(1);
457460
}
458461

459462
for (i = 0; i < n; i++) {
@@ -734,7 +737,7 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask)
734737
unsigned int i;
735738
bool handled = false;
736739

737-
for (i = 0; mask && i < 8; i++) {
740+
for (i = 0; mask && i < rings->total; i++) {
738741
struct hci_rh_data *rh;
739742
u32 status;
740743

@@ -756,9 +759,11 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask)
756759
if (status & INTR_RING_OP)
757760
complete(&rh->op_done);
758761

759-
if (status & INTR_TRANSFER_ABORT)
762+
if (status & INTR_TRANSFER_ABORT) {
760763
dev_notice_ratelimited(&hci->master.dev,
761764
"ring %d: Transfer Aborted\n", i);
765+
mipi_i3c_hci_resume(hci);
766+
}
762767
if (status & INTR_WARN_INS_STOP_MODE)
763768
dev_warn_ratelimited(&hci->master.dev,
764769
"ring %d: Inserted Stop on Mode Change\n", i);

0 commit comments

Comments
 (0)