Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'i3c/for-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux

Pull i3c updates from Alexandre Belloni:
"There is not much this this, mostly fixes around interrupt and IBI
handling:

- mipi-i3c-hci: interrupt handling fixes

- svc: i.MX94 and i.MX95 support, IBI handling fixes"

* tag 'i3c/for-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
i3c: controllers do not need to depend on I3C
i3c: master: svc: switch to bulk clk API for flexible clock support
dt-bindings: i3c: silvaco,i3c-master: add i.MX94 and i.MX95 I3C
i3c: master: svc: skip address resend on repeat START
i3c: master: svc: Emit STOP asap in the IBI transaction
i3c: master: svc: Receive IBI requests in interrupt context
i3c: mipi-i3c-hci: Move unexpected INTR_STATUS print before IO handler
i3c: mipi-i3c-hci: Change name of INTR_STATUS bit 11
i3c: mipi-i3c-hci: Clear INTR_STATUS unconditionally
i3c: mipi-i3c-hci: Fix handling status of i3c_hci_irq_handler()
i3c: mipi-i3c-hci: Allow only relevant INTR_STATUS bit updates

+98 -92
+39 -6
Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml
··· 9 9 maintainers: 10 10 - Conor Culhane <conor.culhane@silvaco.com> 11 11 12 - allOf: 13 - - $ref: i3c.yaml# 14 - 15 12 properties: 16 13 compatible: 17 - enum: 18 - - nuvoton,npcm845-i3c 19 - - silvaco,i3c-master-v1 14 + oneOf: 15 + - enum: 16 + - nuvoton,npcm845-i3c 17 + - silvaco,i3c-master-v1 18 + - items: 19 + - enum: 20 + - nxp,imx94-i3c 21 + - nxp,imx95-i3c 22 + - const: silvaco,i3c-master-v1 20 23 21 24 reg: 22 25 maxItems: 1 ··· 28 25 maxItems: 1 29 26 30 27 clocks: 28 + minItems: 2 31 29 items: 32 30 - description: system clock 33 31 - description: bus clock 34 32 - description: other (slower) events clock 35 33 36 34 clock-names: 35 + minItems: 2 37 36 items: 38 37 - const: pclk 39 38 - const: fast_clk ··· 50 45 - interrupts 51 46 - clock-names 52 47 - clocks 48 + 49 + allOf: 50 + - $ref: i3c.yaml# 51 + - if: 52 + properties: 53 + compatible: 54 + enum: 55 + - nuvoton,npcm845-i3c 56 + - silvaco,i3c-master-v1 57 + then: 58 + properties: 59 + clocks: 60 + minItems: 3 61 + clock-names: 62 + minItems: 3 63 + - if: 64 + properties: 65 + compatible: 66 + contains: 67 + enum: 68 + - nxp,imx94-i3c 69 + - nxp,imx95-i3c 70 + then: 71 + properties: 72 + clocks: 73 + maxItems: 2 74 + clock-names: 75 + maxItems: 2 53 76 54 77 unevaluatedProperties: false 55 78
-4
drivers/i3c/master/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 config CDNS_I3C_MASTER 3 3 tristate "Cadence I3C master driver" 4 - depends on I3C 5 4 depends on HAS_IOMEM 6 5 depends on !(ALPHA || PARISC) 7 6 help ··· 8 9 9 10 config DW_I3C_MASTER 10 11 tristate "Synospsys DesignWare I3C master driver" 11 - depends on I3C 12 12 depends on HAS_IOMEM 13 13 depends on !(ALPHA || PARISC) 14 14 # ALPHA and PARISC needs {read,write}sl() ··· 36 38 37 39 config SVC_I3C_MASTER 38 40 tristate "Silvaco I3C Dual-Role Master driver" 39 - depends on I3C 40 41 depends on HAS_IOMEM 41 42 depends on !(ALPHA || PARISC) 42 43 help ··· 43 46 44 47 config MIPI_I3C_HCI 45 48 tristate "MIPI I3C Host Controller Interface driver (EXPERIMENTAL)" 46 - depends on I3C 47 49 depends on HAS_IOMEM 48 50 help 49 51 Support for hardware following the MIPI Aliance's I3C Host Controller
+19 -13
drivers/i3c/master/mipi-i3c-hci/core.c
··· 78 78 #define INTR_SIGNAL_ENABLE 0x28 79 79 #define INTR_FORCE 0x2c 80 80 #define INTR_HC_CMD_SEQ_UFLOW_STAT BIT(12) /* Cmd Sequence Underflow */ 81 - #define INTR_HC_RESET_CANCEL BIT(11) /* HC Cancelled Reset */ 81 + #define INTR_HC_SEQ_CANCEL BIT(11) /* HC Cancelled Transaction Sequence */ 82 82 #define INTR_HC_INTERNAL_ERR BIT(10) /* HC Internal Error */ 83 83 84 84 #define DAT_SECTION 0x30 /* Device Address Table */ ··· 590 590 u32 val; 591 591 592 592 val = reg_read(INTR_STATUS); 593 + reg_write(INTR_STATUS, val); 593 594 DBG("INTR_STATUS = %#x", val); 594 595 595 - if (val) { 596 - reg_write(INTR_STATUS, val); 597 - } 596 + if (val) 597 + result = IRQ_HANDLED; 598 598 599 - if (val & INTR_HC_RESET_CANCEL) { 600 - DBG("cancelled reset"); 601 - val &= ~INTR_HC_RESET_CANCEL; 599 + if (val & INTR_HC_SEQ_CANCEL) { 600 + dev_dbg(&hci->master.dev, 601 + "Host Controller Cancelled Transaction Sequence\n"); 602 + val &= ~INTR_HC_SEQ_CANCEL; 602 603 } 603 604 if (val & INTR_HC_INTERNAL_ERR) { 604 605 dev_err(&hci->master.dev, "Host Controller Internal Error\n"); 605 606 val &= ~INTR_HC_INTERNAL_ERR; 606 607 } 607 608 608 - hci->io->irq_handler(hci); 609 - 610 609 if (val) 611 - dev_err(&hci->master.dev, "unexpected INTR_STATUS %#x\n", val); 612 - else 610 + dev_warn_once(&hci->master.dev, 611 + "unexpected INTR_STATUS %#x\n", val); 612 + 613 + if (hci->io->irq_handler(hci)) 613 614 result = IRQ_HANDLED; 614 615 615 616 return result; ··· 700 699 if (ret) 701 700 return -ENXIO; 702 701 703 - /* Disable all interrupts and allow all signal updates */ 702 + /* Disable all interrupts */ 704 703 reg_write(INTR_SIGNAL_ENABLE, 0x0); 705 - reg_write(INTR_STATUS_ENABLE, 0xffffffff); 704 + /* 705 + * Only allow bit 31:10 signal updates because 706 + * Bit 0:9 are reserved in IP version >= 0.8 707 + * Bit 0:5 are defined in IP version < 0.8 but not handled by PIO code 708 + */ 709 + reg_write(INTR_STATUS_ENABLE, GENMASK(31, 10)); 706 710 707 711 /* Make sure our data ordering fits the host's */ 708 712 regval = reg_read(HC_CONTROL);
+40 -69
drivers/i3c/master/svc-i3c-master.c
··· 201 201 * @addrs: Array containing the dynamic addresses of each attached device 202 202 * @descs: Array of descriptors, one per attached device 203 203 * @hj_work: Hot-join work 204 - * @ibi_work: IBI work 205 204 * @irq: Main interrupt 206 - * @pclk: System clock 205 + * @num_clks: I3C clock number 207 206 * @fclk: Fast clock (bus) 208 - * @sclk: Slow clock (other events) 207 + * @clks: I3C clock array 209 208 * @xferqueue: Transfer queue structure 210 209 * @xferqueue.list: List member 211 210 * @xferqueue.cur: Current ongoing transfer ··· 228 229 u8 addrs[SVC_I3C_MAX_DEVS]; 229 230 struct i3c_dev_desc *descs[SVC_I3C_MAX_DEVS]; 230 231 struct work_struct hj_work; 231 - struct work_struct ibi_work; 232 232 int irq; 233 - struct clk *pclk; 233 + int num_clks; 234 234 struct clk *fclk; 235 - struct clk *sclk; 235 + struct clk_bulk_data *clks; 236 236 struct { 237 237 struct list_head list; 238 238 struct svc_i3c_xfer *cur; ··· 485 487 return ret; 486 488 } 487 489 488 - static void svc_i3c_master_ibi_work(struct work_struct *work) 490 + static void svc_i3c_master_ibi_isr(struct svc_i3c_master *master) 489 491 { 490 - struct svc_i3c_master *master = container_of(work, struct svc_i3c_master, ibi_work); 491 492 struct svc_i3c_i2c_dev_data *data; 492 493 unsigned int ibitype, ibiaddr; 493 494 struct i3c_dev_desc *dev; ··· 501 504 * schedule during the whole I3C transaction, otherwise, the I3C bus timeout may happen if 502 505 * any irq or schedule happen during transaction. 503 506 */ 504 - guard(spinlock_irqsave)(&master->xferqueue.lock); 507 + guard(spinlock)(&master->xferqueue.lock); 505 508 506 509 /* 507 510 * IBIWON may be set before SVC_I3C_MCTRL_REQUEST_AUTO_IBI, causing ··· 527 530 if (ret) { 528 531 dev_err(master->dev, "Timeout when polling for IBIWON\n"); 529 532 svc_i3c_master_emit_stop(master); 530 - goto reenable_ibis; 533 + return; 531 534 } 532 535 533 536 status = readl(master->regs + SVC_I3C_MSTATUS); ··· 571 574 572 575 svc_i3c_master_emit_stop(master); 573 576 574 - goto reenable_ibis; 577 + return; 575 578 } 576 579 577 580 /* Handle the non critical tasks */ 578 581 switch (ibitype) { 579 582 case SVC_I3C_MSTATUS_IBITYPE_IBI: 583 + svc_i3c_master_emit_stop(master); 580 584 if (dev) { 581 585 i3c_master_queue_ibi(dev, master->ibi.tbq_slot); 582 586 master->ibi.tbq_slot = NULL; 583 587 } 584 - svc_i3c_master_emit_stop(master); 585 588 break; 586 589 case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN: 587 590 svc_i3c_master_emit_stop(master); ··· 594 597 default: 595 598 break; 596 599 } 597 - 598 - reenable_ibis: 599 - svc_i3c_master_enable_interrupts(master, SVC_I3C_MINT_SLVSTART); 600 600 } 601 601 602 602 static irqreturn_t svc_i3c_master_irq_handler(int irq, void *dev_id) ··· 612 618 !SVC_I3C_MSTATUS_STATE_SLVREQ(active)) 613 619 return IRQ_HANDLED; 614 620 615 - svc_i3c_master_disable_interrupts(master); 616 - 617 - /* Handle the interrupt in a non atomic context */ 618 - queue_work(master->base.wq, &master->ibi_work); 621 + /* 622 + * The SDA line remains low until the request is processed. 623 + * Receive the request in the interrupt context to respond promptly 624 + * and restore the bus to idle state. 625 + */ 626 + svc_i3c_master_ibi_isr(master); 619 627 620 628 return IRQ_HANDLED; 621 629 } ··· 1277 1281 static int svc_i3c_master_xfer(struct svc_i3c_master *master, 1278 1282 bool rnw, unsigned int xfer_type, u8 addr, 1279 1283 u8 *in, const u8 *out, unsigned int xfer_len, 1280 - unsigned int *actual_len, bool continued) 1284 + unsigned int *actual_len, bool continued, bool repeat_start) 1281 1285 { 1282 - int retry = 2; 1286 + int retry = repeat_start ? 1 : 2; 1283 1287 u32 reg; 1284 1288 int ret; 1285 1289 ··· 1464 1468 ret = svc_i3c_master_xfer(master, cmd->rnw, xfer->type, 1465 1469 cmd->addr, cmd->in, cmd->out, 1466 1470 cmd->len, &cmd->actual_len, 1467 - cmd->continued); 1471 + cmd->continued, i > 0); 1468 1472 /* cmd->xfer is NULL if I2C or CCC transfer */ 1469 1473 if (cmd->xfer) 1470 1474 cmd->xfer->actual_len = cmd->actual_len; ··· 1871 1875 .set_speed = svc_i3c_master_set_speed, 1872 1876 }; 1873 1877 1874 - static int svc_i3c_master_prepare_clks(struct svc_i3c_master *master) 1875 - { 1876 - int ret = 0; 1877 - 1878 - ret = clk_prepare_enable(master->pclk); 1879 - if (ret) 1880 - return ret; 1881 - 1882 - ret = clk_prepare_enable(master->fclk); 1883 - if (ret) { 1884 - clk_disable_unprepare(master->pclk); 1885 - return ret; 1886 - } 1887 - 1888 - ret = clk_prepare_enable(master->sclk); 1889 - if (ret) { 1890 - clk_disable_unprepare(master->pclk); 1891 - clk_disable_unprepare(master->fclk); 1892 - return ret; 1893 - } 1894 - 1895 - return 0; 1896 - } 1897 - 1898 - static void svc_i3c_master_unprepare_clks(struct svc_i3c_master *master) 1899 - { 1900 - clk_disable_unprepare(master->pclk); 1901 - clk_disable_unprepare(master->fclk); 1902 - clk_disable_unprepare(master->sclk); 1903 - } 1904 - 1905 1878 static int svc_i3c_master_probe(struct platform_device *pdev) 1906 1879 { 1907 1880 struct device *dev = &pdev->dev; 1908 1881 struct svc_i3c_master *master; 1909 - int ret; 1882 + int ret, i; 1910 1883 1911 1884 master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL); 1912 1885 if (!master) ··· 1889 1924 if (IS_ERR(master->regs)) 1890 1925 return PTR_ERR(master->regs); 1891 1926 1892 - master->pclk = devm_clk_get(dev, "pclk"); 1893 - if (IS_ERR(master->pclk)) 1894 - return PTR_ERR(master->pclk); 1927 + master->num_clks = devm_clk_bulk_get_all(dev, &master->clks); 1928 + if (master->num_clks < 0) 1929 + return dev_err_probe(dev, -EINVAL, "can't get I3C clocks\n"); 1895 1930 1896 - master->fclk = devm_clk_get(dev, "fast_clk"); 1931 + for (i = 0; i < master->num_clks; i++) { 1932 + if (!strcmp(master->clks[i].id, "fast_clk")) 1933 + break; 1934 + } 1935 + 1936 + if (i == master->num_clks) 1937 + return dev_err_probe(dev, -EINVAL, 1938 + "can't get I3C peripheral clock\n"); 1939 + 1940 + master->fclk = master->clks[i].clk; 1897 1941 if (IS_ERR(master->fclk)) 1898 1942 return PTR_ERR(master->fclk); 1899 - 1900 - master->sclk = devm_clk_get(dev, "slow_clk"); 1901 - if (IS_ERR(master->sclk)) 1902 - return PTR_ERR(master->sclk); 1903 1943 1904 1944 master->irq = platform_get_irq(pdev, 0); 1905 1945 if (master->irq < 0) 1906 1946 return master->irq; 1907 1947 1908 1948 master->dev = dev; 1909 - 1910 - ret = svc_i3c_master_prepare_clks(master); 1949 + ret = clk_bulk_prepare_enable(master->num_clks, master->clks); 1911 1950 if (ret) 1912 - return ret; 1951 + return dev_err_probe(dev, ret, "can't enable I3C clocks\n"); 1913 1952 1914 1953 INIT_WORK(&master->hj_work, svc_i3c_master_hj_work); 1915 - INIT_WORK(&master->ibi_work, svc_i3c_master_ibi_work); 1916 1954 mutex_init(&master->lock); 1917 1955 1918 1956 ret = devm_request_irq(dev, master->irq, svc_i3c_master_irq_handler, ··· 1966 1998 pm_runtime_set_suspended(&pdev->dev); 1967 1999 1968 2000 err_disable_clks: 1969 - svc_i3c_master_unprepare_clks(master); 2001 + clk_bulk_disable_unprepare(master->num_clks, master->clks); 1970 2002 1971 2003 return ret; 1972 2004 } ··· 2004 2036 struct svc_i3c_master *master = dev_get_drvdata(dev); 2005 2037 2006 2038 svc_i3c_save_regs(master); 2007 - svc_i3c_master_unprepare_clks(master); 2039 + clk_bulk_disable_unprepare(master->num_clks, master->clks); 2008 2040 pinctrl_pm_select_sleep_state(dev); 2009 2041 2010 2042 return 0; ··· 2013 2045 static int __maybe_unused svc_i3c_runtime_resume(struct device *dev) 2014 2046 { 2015 2047 struct svc_i3c_master *master = dev_get_drvdata(dev); 2048 + int ret; 2016 2049 2017 2050 pinctrl_pm_select_default_state(dev); 2018 - svc_i3c_master_prepare_clks(master); 2051 + ret = clk_bulk_prepare_enable(master->num_clks, master->clks); 2052 + if (ret) 2053 + return ret; 2019 2054 2020 2055 svc_i3c_restore_regs(master); 2021 2056