Skip to content

Commit 750909d

Browse files
committed
Merge tag 'i3c/for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux
Pull i3c updates from Alexandre Belloni: "Core: - avoid possible deadlock on probe - ensured preferred address is used on hot-join Drivers: - dw: add AMD I3C controller support - mipi-i3c-hci: fix SETDASA, DMA interrupts fixes - svc: many fixes for IBI and hotjoin" * tag 'i3c/for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock i3c: mipi-i3c-hci: Support SETDASA CCC i3c: dw: Add quirk to address OD/PP timing issue on AMD platform i3c: dw: Add support for AMDI0015 ACPI ID i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter i3c: Document I3C_ADDR_SLOT_EXT_STATUS_MASK i3c: master: svc: Fix pm_runtime_set_suspended() with runtime pm enabled i3c: mipi-i3c-hci: Handle interrupts according to current specifications i3c: mipi-i3c-hci: Mask ring interrupts before ring stop request i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs() i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin i3c: master: svc: fix possible assignment of the same address to two devices i3c: master: svc: wait for Manual ACK/NACK Done before next step i3c: master: svc: use spin_lock_irqsave at svc_i3c_master_ibi_work() i3c: master: svc: need check IBIWON for dynamic address assignment i3c: master: svc: manually emit NACK/ACK for hotjoin i3c: master: svc: use repeat start when IBI WIN happens i3c: master: Fix dynamic address leak when 'assigned-address' is present i3c: master: Extend address status bit to 4 and add I3C_ADDR_SLOT_EXT_DESIRED i3c: master: Replace hard code 2 with macro I3C_ADDR_SLOT_STATUS_BITS
2 parents 1746db2 + 6cf7b65 commit 750909d

File tree

9 files changed

+225
-89
lines changed

9 files changed

+225
-89
lines changed

drivers/i3c/master.c

+72-28
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ static int i3c_device_uevent(const struct device *dev, struct kobj_uevent_env *e
282282
struct i3c_device_info devinfo;
283283
u16 manuf, part, ext;
284284

285-
i3c_device_get_info(i3cdev, &devinfo);
285+
if (i3cdev->desc)
286+
devinfo = i3cdev->desc->info;
286287
manuf = I3C_PID_MANUF_ID(devinfo.pid);
287288
part = I3C_PID_PART_ID(devinfo.pid);
288289
ext = I3C_PID_EXTRA_INFO(devinfo.pid);
@@ -345,33 +346,44 @@ const struct bus_type i3c_bus_type = {
345346
EXPORT_SYMBOL_GPL(i3c_bus_type);
346347

347348
static enum i3c_addr_slot_status
348-
i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
349+
i3c_bus_get_addr_slot_status_mask(struct i3c_bus *bus, u16 addr, u32 mask)
349350
{
350351
unsigned long status;
351-
int bitpos = addr * 2;
352+
int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
352353

353354
if (addr > I2C_MAX_ADDR)
354355
return I3C_ADDR_SLOT_RSVD;
355356

356357
status = bus->addrslots[bitpos / BITS_PER_LONG];
357358
status >>= bitpos % BITS_PER_LONG;
358359

359-
return status & I3C_ADDR_SLOT_STATUS_MASK;
360+
return status & mask;
360361
}
361362

362-
static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
363-
enum i3c_addr_slot_status status)
363+
static enum i3c_addr_slot_status
364+
i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
365+
{
366+
return i3c_bus_get_addr_slot_status_mask(bus, addr, I3C_ADDR_SLOT_STATUS_MASK);
367+
}
368+
369+
static void i3c_bus_set_addr_slot_status_mask(struct i3c_bus *bus, u16 addr,
370+
enum i3c_addr_slot_status status, u32 mask)
364371
{
365-
int bitpos = addr * 2;
372+
int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
366373
unsigned long *ptr;
367374

368375
if (addr > I2C_MAX_ADDR)
369376
return;
370377

371378
ptr = bus->addrslots + (bitpos / BITS_PER_LONG);
372-
*ptr &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK <<
373-
(bitpos % BITS_PER_LONG));
374-
*ptr |= (unsigned long)status << (bitpos % BITS_PER_LONG);
379+
*ptr &= ~((unsigned long)mask << (bitpos % BITS_PER_LONG));
380+
*ptr |= ((unsigned long)status & mask) << (bitpos % BITS_PER_LONG);
381+
}
382+
383+
static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
384+
enum i3c_addr_slot_status status)
385+
{
386+
i3c_bus_set_addr_slot_status_mask(bus, addr, status, I3C_ADDR_SLOT_STATUS_MASK);
375387
}
376388

377389
static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)
@@ -383,13 +395,44 @@ static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)
383395
return status == I3C_ADDR_SLOT_FREE;
384396
}
385397

398+
/*
399+
* ┌────┬─────────────┬───┬─────────┬───┐
400+
* │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐
401+
* └────┴─────────────┴───┴─────────┴───┘ │
402+
* ┌─────────────────────────────────────────┘
403+
* │ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐
404+
* └─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│
405+
* └──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘
406+
* Some master controllers (such as HCI) need to prepare the entire above transaction before
407+
* sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated
408+
* before knowing the target device's UID information.
409+
*
410+
* However, some I3C targets may request specific addresses (called as "init_dyn_addr"), which is
411+
* typically specified by the DT-'s assigned-address property. Lower addresses having higher IBI
412+
* priority. If it is available, i3c_bus_get_free_addr() preferably return a free address that is
413+
* not in the list of desired addresses (called as "init_dyn_addr"). This allows the device with
414+
* the "init_dyn_addr" to switch to its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise,
415+
* if the "init_dyn_addr" is already in use by another I3C device, the target device will not be
416+
* able to switch to its desired address.
417+
*
418+
* If the previous step fails, fallback returning one of the remaining unassigned address,
419+
* regardless of its state in the desired list.
420+
*/
386421
static int i3c_bus_get_free_addr(struct i3c_bus *bus, u8 start_addr)
387422
{
388423
enum i3c_addr_slot_status status;
389424
u8 addr;
390425

391426
for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) {
392-
status = i3c_bus_get_addr_slot_status(bus, addr);
427+
status = i3c_bus_get_addr_slot_status_mask(bus, addr,
428+
I3C_ADDR_SLOT_EXT_STATUS_MASK);
429+
if (status == I3C_ADDR_SLOT_FREE)
430+
return addr;
431+
}
432+
433+
for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) {
434+
status = i3c_bus_get_addr_slot_status_mask(bus, addr,
435+
I3C_ADDR_SLOT_STATUS_MASK);
393436
if (status == I3C_ADDR_SLOT_FREE)
394437
return addr;
395438
}
@@ -1417,7 +1460,7 @@ static void i3c_master_put_i3c_addrs(struct i3c_dev_desc *dev)
14171460
I3C_ADDR_SLOT_FREE);
14181461

14191462
if (dev->boardinfo && dev->boardinfo->init_dyn_addr)
1420-
i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr,
1463+
i3c_bus_set_addr_slot_status(&master->bus, dev->boardinfo->init_dyn_addr,
14211464
I3C_ADDR_SLOT_FREE);
14221465
}
14231466

@@ -1506,16 +1549,9 @@ static int i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
15061549
u8 old_dyn_addr)
15071550
{
15081551
struct i3c_master_controller *master = i3c_dev_get_master(dev);
1509-
enum i3c_addr_slot_status status;
15101552
int ret;
15111553

1512-
if (dev->info.dyn_addr != old_dyn_addr &&
1513-
(!dev->boardinfo ||
1514-
dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) {
1515-
status = i3c_bus_get_addr_slot_status(&master->bus,
1516-
dev->info.dyn_addr);
1517-
if (status != I3C_ADDR_SLOT_FREE)
1518-
return -EBUSY;
1554+
if (dev->info.dyn_addr != old_dyn_addr) {
15191555
i3c_bus_set_addr_slot_status(&master->bus,
15201556
dev->info.dyn_addr,
15211557
I3C_ADDR_SLOT_I3C_DEV);
@@ -1918,9 +1954,11 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
19181954
goto err_rstdaa;
19191955
}
19201956

1921-
i3c_bus_set_addr_slot_status(&master->bus,
1922-
i3cboardinfo->init_dyn_addr,
1923-
I3C_ADDR_SLOT_I3C_DEV);
1957+
/* Do not mark as occupied until real device exist in bus */
1958+
i3c_bus_set_addr_slot_status_mask(&master->bus,
1959+
i3cboardinfo->init_dyn_addr,
1960+
I3C_ADDR_SLOT_EXT_DESIRED,
1961+
I3C_ADDR_SLOT_EXT_STATUS_MASK);
19241962

19251963
/*
19261964
* Only try to create/attach devices that have a static
@@ -2051,11 +2089,16 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
20512089
ibireq.max_payload_len = olddev->ibi->max_payload_len;
20522090
ibireq.num_slots = olddev->ibi->num_slots;
20532091

2054-
if (olddev->ibi->enabled) {
2092+
if (olddev->ibi->enabled)
20552093
enable_ibi = true;
2056-
i3c_dev_disable_ibi_locked(olddev);
2057-
}
2058-
2094+
/*
2095+
* The olddev should not receive any commands on the
2096+
* i3c bus as it does not exist and has been assigned
2097+
* a new address. This will result in NACK or timeout.
2098+
* So, update the olddev->ibi->enabled flag to false
2099+
* to avoid DISEC with OldAddr.
2100+
*/
2101+
olddev->ibi->enabled = false;
20592102
i3c_dev_free_ibi_locked(olddev);
20602103
}
20612104
mutex_unlock(&olddev->ibi_lock);
@@ -2083,7 +2126,8 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
20832126
else
20842127
expected_dyn_addr = newdev->info.dyn_addr;
20852128

2086-
if (newdev->info.dyn_addr != expected_dyn_addr) {
2129+
if (newdev->info.dyn_addr != expected_dyn_addr &&
2130+
i3c_bus_get_addr_slot_status(&master->bus, expected_dyn_addr) == I3C_ADDR_SLOT_FREE) {
20872131
/*
20882132
* Try to apply the expected dynamic address. If it fails, keep
20892133
* the address assigned by the master.

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

+34
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@
220220

221221
#define XFER_TIMEOUT (msecs_to_jiffies(1000))
222222
#define RPM_AUTOSUSPEND_TIMEOUT 1000 /* ms */
223+
224+
/* Timing values to configure 12.5MHz frequency */
225+
#define AMD_I3C_OD_TIMING 0x4C007C
226+
#define AMD_I3C_PP_TIMING 0x8001A
227+
228+
/* List of quirks */
229+
#define AMD_I3C_OD_PP_TIMING BIT(1)
230+
223231
struct dw_i3c_cmd {
224232
u32 cmd_lo;
225233
u32 cmd_hi;
@@ -794,6 +802,12 @@ static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc)
794802
return ret;
795803
}
796804

805+
static void amd_configure_od_pp_quirk(struct dw_i3c_master *master)
806+
{
807+
master->i3c_od_timing = AMD_I3C_OD_TIMING;
808+
master->i3c_pp_timing = AMD_I3C_PP_TIMING;
809+
}
810+
797811
static int dw_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
798812
struct i3c_ccc_cmd *ccc)
799813
{
@@ -803,6 +817,13 @@ static int dw_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
803817
if (ccc->id == I3C_CCC_ENTDAA)
804818
return -EINVAL;
805819

820+
/* AMD platform specific OD and PP timings */
821+
if (master->quirks & AMD_I3C_OD_PP_TIMING) {
822+
amd_configure_od_pp_quirk(master);
823+
writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING);
824+
writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING);
825+
}
826+
806827
ret = pm_runtime_resume_and_get(master->dev);
807828
if (ret < 0) {
808829
dev_err(master->dev,
@@ -1602,6 +1623,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
16021623
master->maxdevs = ret >> 16;
16031624
master->free_pos = GENMASK(master->maxdevs - 1, 0);
16041625

1626+
master->quirks = (unsigned long)device_get_match_data(&pdev->dev);
1627+
16051628
INIT_WORK(&master->hj_work, dw_i3c_hj_work);
16061629
ret = i3c_master_register(&master->base, &pdev->dev,
16071630
&dw_mipi_i3c_ops, false);
@@ -1675,6 +1698,10 @@ static void dw_i3c_master_restore_addrs(struct dw_i3c_master *master)
16751698

16761699
static void dw_i3c_master_restore_timing_regs(struct dw_i3c_master *master)
16771700
{
1701+
/* AMD platform specific OD and PP timings */
1702+
if (master->quirks & AMD_I3C_OD_PP_TIMING)
1703+
amd_configure_od_pp_quirk(master);
1704+
16781705
writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING);
16791706
writel(master->bus_free_timing, master->regs + BUS_FREE_TIMING);
16801707
writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING);
@@ -1748,12 +1775,19 @@ static const struct of_device_id dw_i3c_master_of_match[] = {
17481775
};
17491776
MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
17501777

1778+
static const struct acpi_device_id amd_i3c_device_match[] = {
1779+
{ "AMDI0015", AMD_I3C_OD_PP_TIMING },
1780+
{ }
1781+
};
1782+
MODULE_DEVICE_TABLE(acpi, amd_i3c_device_match);
1783+
17511784
static struct platform_driver dw_i3c_driver = {
17521785
.probe = dw_i3c_probe,
17531786
.remove_new = dw_i3c_remove,
17541787
.driver = {
17551788
.name = "dw-i3c-master",
17561789
.of_match_table = dw_i3c_master_of_match,
1790+
.acpi_match_table = amd_i3c_device_match,
17571791
.pm = &dw_i3c_pm_ops,
17581792
},
17591793
};

drivers/i3c/master/dw-i3c-master.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct dw_i3c_master {
5050
u32 bus_free_timing;
5151
u32 i2c_fm_timing;
5252
u32 i2c_fmp_timing;
53+
u32 quirks;
5354
/*
5455
* Per-device hardware data, used to manage the device address table
5556
* (DAT)

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

+5-14
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@
8080
#define INTR_HC_CMD_SEQ_UFLOW_STAT BIT(12) /* Cmd Sequence Underflow */
8181
#define INTR_HC_RESET_CANCEL BIT(11) /* HC Cancelled Reset */
8282
#define INTR_HC_INTERNAL_ERR BIT(10) /* HC Internal Error */
83-
#define INTR_HC_PIO BIT(8) /* cascaded PIO interrupt */
84-
#define INTR_HC_RINGS GENMASK(7, 0)
8583

8684
#define DAT_SECTION 0x30 /* Device Address Table */
8785
#define DAT_ENTRY_SIZE GENMASK(31, 28)
@@ -438,7 +436,8 @@ static int i3c_hci_attach_i3c_dev(struct i3c_dev_desc *dev)
438436
kfree(dev_data);
439437
return ret;
440438
}
441-
mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, ret, dev->info.dyn_addr);
439+
mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, ret,
440+
dev->info.dyn_addr ?: dev->info.static_addr);
442441
dev_data->dat_idx = ret;
443442
}
444443
i3c_dev_set_master_data(dev, dev_data);
@@ -597,9 +596,6 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
597596

598597
if (val) {
599598
reg_write(INTR_STATUS, val);
600-
} else {
601-
/* v1.0 does not have PIO cascaded notification bits */
602-
val |= INTR_HC_PIO;
603599
}
604600

605601
if (val & INTR_HC_RESET_CANCEL) {
@@ -610,14 +606,9 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
610606
dev_err(&hci->master.dev, "Host Controller Internal Error\n");
611607
val &= ~INTR_HC_INTERNAL_ERR;
612608
}
613-
if (val & INTR_HC_PIO) {
614-
hci->io->irq_handler(hci, 0);
615-
val &= ~INTR_HC_PIO;
616-
}
617-
if (val & INTR_HC_RINGS) {
618-
hci->io->irq_handler(hci, val & INTR_HC_RINGS);
619-
val &= ~INTR_HC_RINGS;
620-
}
609+
610+
hci->io->irq_handler(hci);
611+
621612
if (val)
622613
dev_err(&hci->master.dev, "unexpected INTR_STATUS %#x\n", val);
623614
else

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

+3-7
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,10 @@ static void hci_dma_cleanup(struct i3c_hci *hci)
159159
for (i = 0; i < rings->total; i++) {
160160
rh = &rings->headers[i];
161161

162+
rh_reg_write(INTR_SIGNAL_ENABLE, 0);
162163
rh_reg_write(RING_CONTROL, 0);
163164
rh_reg_write(CR_SETUP, 0);
164165
rh_reg_write(IBI_SETUP, 0);
165-
rh_reg_write(INTR_SIGNAL_ENABLE, 0);
166166

167167
if (rh->xfer)
168168
dma_free_coherent(&hci->master.dev,
@@ -733,20 +733,16 @@ static void hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh)
733733
rh_reg_write(CHUNK_CONTROL, rh_reg_read(CHUNK_CONTROL) + ibi_chunks);
734734
}
735735

736-
static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask)
736+
static bool hci_dma_irq_handler(struct i3c_hci *hci)
737737
{
738738
struct hci_rings_data *rings = hci->io_data;
739739
unsigned int i;
740740
bool handled = false;
741741

742-
for (i = 0; mask && i < rings->total; i++) {
742+
for (i = 0; i < rings->total; i++) {
743743
struct hci_rh_data *rh;
744744
u32 status;
745745

746-
if (!(mask & BIT(i)))
747-
continue;
748-
mask &= ~BIT(i);
749-
750746
rh = &rings->headers[i];
751747
status = rh_reg_read(INTR_STATUS);
752748
DBG("rh%d status: %#x", i, status);

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ static inline void hci_free_xfer(struct hci_xfer *xfer, unsigned int n)
115115

116116
/* This abstracts PIO vs DMA operations */
117117
struct hci_io_ops {
118-
bool (*irq_handler)(struct i3c_hci *hci, unsigned int mask);
118+
bool (*irq_handler)(struct i3c_hci *hci);
119119
int (*queue_xfer)(struct i3c_hci *hci, struct hci_xfer *xfer, int n);
120120
bool (*dequeue_xfer)(struct i3c_hci *hci, struct hci_xfer *xfer, int n);
121121
int (*request_ibi)(struct i3c_hci *hci, struct i3c_dev_desc *dev,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ static void hci_pio_recycle_ibi_slot(struct i3c_hci *hci,
979979
i3c_generic_ibi_recycle_slot(dev_ibi->pool, slot);
980980
}
981981

982-
static bool hci_pio_irq_handler(struct i3c_hci *hci, unsigned int unused)
982+
static bool hci_pio_irq_handler(struct i3c_hci *hci)
983983
{
984984
struct hci_pio_data *pio = hci->io_data;
985985
u32 status;

0 commit comments

Comments
 (0)