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

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

Pull i3c updates from Alexandre Belloni:
"The main change is the addition of PCI bus support for mipi-i3c-hci.

I'm also carrying an hwmon patch as it makes use of the bitops
addition that is then mainly used by i3c drivers.

Core:
- Improve initialization of numbered I2C adapters

Drivers:
- use parity8 helper
- dw: fix possible use-after-free
- mipi-i3c-hci: add support for PCI bus host
- svc: many fixes for IBI and hotjoin"

* tag 'i3c/for-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
i3c: master: Improve initialization of numbered I2C adapters
i3c: master: Fix missing 'ret' assignment in set_speed()
i3c: cdns: use parity8 helper instead of open coding it
i3c: mipi-i3c-hci: use parity8 helper instead of open coding it
i3c: dw: use parity8 helper instead of open coding it
hwmon: (spd5118) Use generic parity calculation
bitops: add generic parity calculation for u8
i3c: mipi-i3c-hci: Add support for MIPI I3C HCI on PCI bus
i3c: mipi-i3c-hci: Add Intel specific quirk to ring resuming
i3c: fix kdoc parameter description for module_i3c_i2c_driver()
i3c: dw: Fix use-after-free in dw_i3c_master driver due to race condition

+227 -34
+1 -7
drivers/hwmon/spd5118.c
··· 291 291 } 292 292 } 293 293 294 - static inline bool spd5118_parity8(u8 w) 295 - { 296 - w ^= w >> 4; 297 - return (0x6996 >> (w & 0xf)) & 1; 298 - } 299 - 300 294 /* 301 295 * Bank and vendor id are 8-bit fields with seven data bits and odd parity. 302 296 * Vendor IDs 0 and 0x7f are invalid. ··· 298 304 */ 299 305 static bool spd5118_vendor_valid(u8 bank, u8 id) 300 306 { 301 - if (!spd5118_parity8(bank) || !spd5118_parity8(id)) 307 + if (parity8(bank) == 0 || parity8(id) == 0) 302 308 return false; 303 309 304 310 id &= 0x7f;
+11 -3
drivers/i3c/master.c
··· 1919 1919 goto err_bus_cleanup; 1920 1920 1921 1921 if (master->ops->set_speed) { 1922 - master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); 1922 + ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED); 1923 1923 if (ret) 1924 1924 goto err_bus_cleanup; 1925 1925 } ··· 2486 2486 struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master); 2487 2487 struct i2c_dev_desc *i2cdev; 2488 2488 struct i2c_dev_boardinfo *i2cboardinfo; 2489 - int ret; 2489 + int ret, id = -ENODEV; 2490 2490 2491 2491 adap->dev.parent = master->dev.parent; 2492 2492 adap->owner = master->dev.parent->driver->owner; ··· 2497 2497 adap->timeout = 1000; 2498 2498 adap->retries = 3; 2499 2499 2500 - ret = i2c_add_adapter(adap); 2500 + if (master->dev.of_node) 2501 + id = of_alias_get_id(master->dev.of_node, "i2c"); 2502 + 2503 + if (id >= 0) { 2504 + adap->nr = id; 2505 + ret = i2c_add_numbered_adapter(adap); 2506 + } else { 2507 + ret = i2c_add_adapter(adap); 2508 + } 2501 2509 if (ret) 2502 2510 return ret; 2503 2511
+11
drivers/i3c/master/Kconfig
··· 57 57 58 58 This driver can also be built as a module. If so, the module will be 59 59 called mipi-i3c-hci. 60 + 61 + config MIPI_I3C_HCI_PCI 62 + tristate "MIPI I3C Host Controller Interface PCI support" 63 + depends on MIPI_I3C_HCI 64 + depends on PCI 65 + help 66 + Support for MIPI I3C Host Controller Interface compatible hardware 67 + on the PCI bus. 68 + 69 + This driver can also be built as a module. If so, the module will be 70 + called mipi-i3c-hci-pci.
+4 -11
drivers/i3c/master/dw-i3c-master.c
··· 251 251 struct i3c_generic_ibi_pool *ibi_pool; 252 252 }; 253 253 254 - static u8 even_parity(u8 p) 255 - { 256 - p ^= p >> 4; 257 - p &= 0xf; 258 - 259 - return (0x9669 >> p) & 1; 260 - } 261 - 262 254 static bool dw_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m, 263 255 const struct i3c_ccc_cmd *cmd) 264 256 { ··· 840 848 struct dw_i3c_xfer *xfer; 841 849 struct dw_i3c_cmd *cmd; 842 850 u32 olddevs, newdevs; 843 - u8 p, last_addr = 0; 851 + u8 last_addr = 0; 844 852 int ret, pos; 845 853 846 854 ret = pm_runtime_resume_and_get(master->dev); ··· 865 873 } 866 874 867 875 master->devs[pos].addr = ret; 868 - p = even_parity(ret); 869 876 last_addr = ret; 870 - ret |= (p << 7); 877 + 878 + ret |= parity8(ret) ? 0 : BIT(7); 871 879 872 880 writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret), 873 881 master->regs + ··· 1639 1647 1640 1648 void dw_i3c_common_remove(struct dw_i3c_master *master) 1641 1649 { 1650 + cancel_work_sync(&master->hj_work); 1642 1651 i3c_master_unregister(&master->base); 1643 1652 1644 1653 pm_runtime_disable(master->dev);
+1 -2
drivers/i3c/master/i3c-master-cdns.c
··· 889 889 ret |= (addr & GENMASK(9, 7)) << 6; 890 890 891 891 /* RR0[0] = ~XOR(addr[6:0]) */ 892 - if (!(hweight8(addr & 0x7f) & 1)) 893 - ret |= 1; 892 + ret |= parity8(addr & 0x7f) ? 0 : BIT(0); 894 893 895 894 return ret; 896 895 }
+1
drivers/i3c/master/mipi-i3c-hci/Makefile
··· 5 5 cmd_v1.o cmd_v2.o \ 6 6 dat_v1.o dct_v1.o \ 7 7 hci_quirks.o 8 + obj-$(CONFIG_MIPI_I3C_HCI_PCI) += mipi-i3c-hci-pci.o
+1 -10
drivers/i3c/master/mipi-i3c-hci/dat_v1.c
··· 40 40 #define dat_w0_write(i, v) writel(v, hci->DAT_regs + (i) * 8) 41 41 #define dat_w1_write(i, v) writel(v, hci->DAT_regs + (i) * 8 + 4) 42 42 43 - static inline bool dynaddr_parity(unsigned int addr) 44 - { 45 - addr |= 1 << 7; 46 - addr += addr >> 4; 47 - addr += addr >> 2; 48 - addr += addr >> 1; 49 - return (addr & 1); 50 - } 51 - 52 43 static int hci_dat_v1_init(struct i3c_hci *hci) 53 44 { 54 45 unsigned int dat_idx; ··· 114 123 dat_w0 = dat_w0_read(dat_idx); 115 124 dat_w0 &= ~(DAT_0_DYNAMIC_ADDRESS | DAT_0_DYNADDR_PARITY); 116 125 dat_w0 |= FIELD_PREP(DAT_0_DYNAMIC_ADDRESS, address) | 117 - (dynaddr_parity(address) ? DAT_0_DYNADDR_PARITY : 0); 126 + (parity8(address) ? 0 : DAT_0_DYNADDR_PARITY); 118 127 dat_w0_write(dat_idx, dat_w0); 119 128 } 120 129
+17
drivers/i3c/master/mipi-i3c-hci/dma.c
··· 758 758 complete(&rh->op_done); 759 759 760 760 if (status & INTR_TRANSFER_ABORT) { 761 + u32 ring_status; 762 + 761 763 dev_notice_ratelimited(&hci->master.dev, 762 764 "ring %d: Transfer Aborted\n", i); 763 765 mipi_i3c_hci_resume(hci); 766 + ring_status = rh_reg_read(RING_STATUS); 767 + if (!(ring_status & RING_STATUS_RUNNING) && 768 + status & INTR_TRANSFER_COMPLETION && 769 + status & INTR_TRANSFER_ERR) { 770 + /* 771 + * Ring stop followed by run is an Intel 772 + * specific required quirk after resuming the 773 + * halted controller. Do it only when the ring 774 + * is not in running state after a transfer 775 + * error. 776 + */ 777 + rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE); 778 + rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | 779 + RING_CTRL_RUN_STOP); 780 + } 764 781 } 765 782 if (status & INTR_WARN_INS_STOP_MODE) 766 783 dev_warn_ratelimited(&hci->master.dev,
+148
drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * PCI glue code for MIPI I3C HCI driver 4 + * 5 + * Copyright (C) 2024 Intel Corporation 6 + * 7 + * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com> 8 + */ 9 + #include <linux/acpi.h> 10 + #include <linux/idr.h> 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/pci.h> 14 + #include <linux/platform_device.h> 15 + 16 + struct mipi_i3c_hci_pci_info { 17 + int (*init)(struct pci_dev *pci); 18 + }; 19 + 20 + #define INTEL_PRIV_OFFSET 0x2b0 21 + #define INTEL_PRIV_SIZE 0x28 22 + #define INTEL_PRIV_RESETS 0x04 23 + #define INTEL_PRIV_RESETS_RESET BIT(0) 24 + #define INTEL_PRIV_RESETS_RESET_DONE BIT(1) 25 + 26 + static DEFINE_IDA(mipi_i3c_hci_pci_ida); 27 + 28 + static int mipi_i3c_hci_pci_intel_init(struct pci_dev *pci) 29 + { 30 + unsigned long timeout; 31 + void __iomem *priv; 32 + 33 + priv = devm_ioremap(&pci->dev, 34 + pci_resource_start(pci, 0) + INTEL_PRIV_OFFSET, 35 + INTEL_PRIV_SIZE); 36 + if (!priv) 37 + return -ENOMEM; 38 + 39 + /* Assert reset, wait for completion and release reset */ 40 + writel(0, priv + INTEL_PRIV_RESETS); 41 + timeout = jiffies + msecs_to_jiffies(10); 42 + while (!(readl(priv + INTEL_PRIV_RESETS) & 43 + INTEL_PRIV_RESETS_RESET_DONE)) { 44 + if (time_after(jiffies, timeout)) 45 + break; 46 + cpu_relax(); 47 + } 48 + writel(INTEL_PRIV_RESETS_RESET, priv + INTEL_PRIV_RESETS); 49 + 50 + return 0; 51 + } 52 + 53 + static struct mipi_i3c_hci_pci_info intel_info = { 54 + .init = mipi_i3c_hci_pci_intel_init, 55 + }; 56 + 57 + static int mipi_i3c_hci_pci_probe(struct pci_dev *pci, 58 + const struct pci_device_id *id) 59 + { 60 + struct mipi_i3c_hci_pci_info *info; 61 + struct platform_device *pdev; 62 + struct resource res[2]; 63 + int dev_id, ret; 64 + 65 + ret = pcim_enable_device(pci); 66 + if (ret) 67 + return ret; 68 + 69 + pci_set_master(pci); 70 + 71 + memset(&res, 0, sizeof(res)); 72 + 73 + res[0].flags = IORESOURCE_MEM; 74 + res[0].start = pci_resource_start(pci, 0); 75 + res[0].end = pci_resource_end(pci, 0); 76 + 77 + res[1].flags = IORESOURCE_IRQ; 78 + res[1].start = pci->irq; 79 + res[1].end = pci->irq; 80 + 81 + dev_id = ida_alloc(&mipi_i3c_hci_pci_ida, GFP_KERNEL); 82 + if (dev_id < 0) 83 + return dev_id; 84 + 85 + pdev = platform_device_alloc("mipi-i3c-hci", dev_id); 86 + if (!pdev) 87 + return -ENOMEM; 88 + 89 + pdev->dev.parent = &pci->dev; 90 + device_set_node(&pdev->dev, dev_fwnode(&pci->dev)); 91 + 92 + ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); 93 + if (ret) 94 + goto err; 95 + 96 + info = (struct mipi_i3c_hci_pci_info *)id->driver_data; 97 + if (info && info->init) { 98 + ret = info->init(pci); 99 + if (ret) 100 + goto err; 101 + } 102 + 103 + ret = platform_device_add(pdev); 104 + if (ret) 105 + goto err; 106 + 107 + pci_set_drvdata(pci, pdev); 108 + 109 + return 0; 110 + 111 + err: 112 + platform_device_put(pdev); 113 + ida_free(&mipi_i3c_hci_pci_ida, dev_id); 114 + return ret; 115 + } 116 + 117 + static void mipi_i3c_hci_pci_remove(struct pci_dev *pci) 118 + { 119 + struct platform_device *pdev = pci_get_drvdata(pci); 120 + int dev_id = pdev->id; 121 + 122 + platform_device_unregister(pdev); 123 + ida_free(&mipi_i3c_hci_pci_ida, dev_id); 124 + } 125 + 126 + static const struct pci_device_id mipi_i3c_hci_pci_devices[] = { 127 + /* Panther Lake-H */ 128 + { PCI_VDEVICE(INTEL, 0xe37c), (kernel_ulong_t)&intel_info}, 129 + { PCI_VDEVICE(INTEL, 0xe36f), (kernel_ulong_t)&intel_info}, 130 + /* Panther Lake-P */ 131 + { PCI_VDEVICE(INTEL, 0xe47c), (kernel_ulong_t)&intel_info}, 132 + { PCI_VDEVICE(INTEL, 0xe46f), (kernel_ulong_t)&intel_info}, 133 + { }, 134 + }; 135 + MODULE_DEVICE_TABLE(pci, mipi_i3c_hci_pci_devices); 136 + 137 + static struct pci_driver mipi_i3c_hci_pci_driver = { 138 + .name = "mipi_i3c_hci_pci", 139 + .id_table = mipi_i3c_hci_pci_devices, 140 + .probe = mipi_i3c_hci_pci_probe, 141 + .remove = mipi_i3c_hci_pci_remove, 142 + }; 143 + 144 + module_pci_driver(mipi_i3c_hci_pci_driver); 145 + 146 + MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@intel.com>"); 147 + MODULE_LICENSE("GPL"); 148 + MODULE_DESCRIPTION("MIPI I3C HCI driver on PCI bus");
+31
include/linux/bitops.h
··· 230 230 } 231 231 232 232 /** 233 + * parity8 - get the parity of an u8 value 234 + * @value: the value to be examined 235 + * 236 + * Determine the parity of the u8 argument. 237 + * 238 + * Returns: 239 + * 0 for even parity, 1 for odd parity 240 + * 241 + * Note: This function informs you about the current parity. Example to bail 242 + * out when parity is odd: 243 + * 244 + * if (parity8(val) == 1) 245 + * return -EBADMSG; 246 + * 247 + * If you need to calculate a parity bit, you need to draw the conclusion from 248 + * this result yourself. Example to enforce odd parity, parity bit is bit 7: 249 + * 250 + * if (parity8(val) == 0) 251 + * val ^= BIT(7); 252 + */ 253 + static inline int parity8(u8 val) 254 + { 255 + /* 256 + * One explanation of this algorithm: 257 + * https://funloop.org/codex/problem/parity/README.html 258 + */ 259 + val ^= val >> 4; 260 + return (0x6996 >> (val & 0xf)) & 1; 261 + } 262 + 263 + /** 233 264 * __ffs64 - find first set bit in a 64 bit word 234 265 * @word: The 64 bit word 235 266 *
+1 -1
include/linux/i3c/device.h
··· 283 283 * module_i3c_i2c_driver() - Register a module providing an I3C and an I2C 284 284 * driver 285 285 * @__i3cdrv: the I3C driver to register 286 - * @__i2cdrv: the I3C driver to register 286 + * @__i2cdrv: the I2C driver to register 287 287 * 288 288 * Provide generic init/exit functions that simply register/unregister an I3C 289 289 * and an I2C driver.