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-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux

Pull i3c updates from Boris Brezillon:

- Fix DAA for the pre-reserved address case

- Fix an error path in the cadence driver

* tag 'i3c/for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
i3c: master: Fix error return in cdns_i3c_master_probe()
i3c: master: fix for SETDASA and DAA process
i3c: master add i3c_master_attach_boardinfo to preserve boardinfo

+94 -54
+91 -53
drivers/i3c/master.c
··· 1373 1373 enum i3c_addr_slot_status status; 1374 1374 int ret; 1375 1375 1376 - if (dev->info.dyn_addr != old_dyn_addr) { 1376 + if (dev->info.dyn_addr != old_dyn_addr && 1377 + (!dev->boardinfo || 1378 + dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) { 1377 1379 status = i3c_bus_get_addr_slot_status(&master->bus, 1378 1380 dev->info.dyn_addr); 1379 1381 if (status != I3C_ADDR_SLOT_FREE) ··· 1434 1432 master->ops->detach_i2c_dev(dev); 1435 1433 } 1436 1434 1437 - static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev) 1435 + static int i3c_master_early_i3c_dev_add(struct i3c_master_controller *master, 1436 + struct i3c_dev_boardinfo *boardinfo) 1438 1437 { 1439 - struct i3c_master_controller *master = i3c_dev_get_master(dev); 1438 + struct i3c_device_info info = { 1439 + .static_addr = boardinfo->static_addr, 1440 + }; 1441 + struct i3c_dev_desc *i3cdev; 1440 1442 int ret; 1441 1443 1442 - if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr || 1443 - !dev->boardinfo->static_addr) 1444 - return; 1444 + i3cdev = i3c_master_alloc_i3c_dev(master, &info); 1445 + if (IS_ERR(i3cdev)) 1446 + return -ENOMEM; 1445 1447 1446 - ret = i3c_master_setdasa_locked(master, dev->info.static_addr, 1447 - dev->boardinfo->init_dyn_addr); 1448 + i3cdev->boardinfo = boardinfo; 1449 + 1450 + ret = i3c_master_attach_i3c_dev(master, i3cdev); 1448 1451 if (ret) 1449 - return; 1452 + goto err_free_dev; 1450 1453 1451 - dev->info.dyn_addr = dev->boardinfo->init_dyn_addr; 1452 - ret = i3c_master_reattach_i3c_dev(dev, 0); 1454 + ret = i3c_master_setdasa_locked(master, i3cdev->info.static_addr, 1455 + i3cdev->boardinfo->init_dyn_addr); 1456 + if (ret) 1457 + goto err_detach_dev; 1458 + 1459 + i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr; 1460 + ret = i3c_master_reattach_i3c_dev(i3cdev, 0); 1453 1461 if (ret) 1454 1462 goto err_rstdaa; 1455 1463 1456 - ret = i3c_master_retrieve_dev_info(dev); 1464 + ret = i3c_master_retrieve_dev_info(i3cdev); 1457 1465 if (ret) 1458 1466 goto err_rstdaa; 1459 1467 1460 - return; 1468 + return 0; 1461 1469 1462 1470 err_rstdaa: 1463 - i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr); 1471 + i3c_master_rstdaa_locked(master, i3cdev->boardinfo->init_dyn_addr); 1472 + err_detach_dev: 1473 + i3c_master_detach_i3c_dev(i3cdev); 1474 + err_free_dev: 1475 + i3c_master_free_i3c_dev(i3cdev); 1476 + 1477 + return ret; 1464 1478 } 1465 1479 1466 1480 static void ··· 1643 1625 * This function is following all initialisation steps described in the I3C 1644 1626 * specification: 1645 1627 * 1646 - * 1. Attach I2C and statically defined I3C devs to the master so that the 1647 - * master can fill its internal device table appropriately 1628 + * 1. Attach I2C devs to the master so that the master can fill its internal 1629 + * device table appropriately 1648 1630 * 1649 1631 * 2. Call &i3c_master_controller_ops->bus_init() method to initialize 1650 1632 * the master controller. That's usually where the bus mode is selected ··· 1656 1638 * 1657 1639 * 4. Disable all slave events. 1658 1640 * 1659 - * 5. Pre-assign dynamic addresses requested by the FW with SETDASA for I3C 1660 - * devices that have a static address 1641 + * 5. Reserve address slots for I3C devices with init_dyn_addr. And if devices 1642 + * also have static_addr, try to pre-assign dynamic addresses requested by 1643 + * the FW with SETDASA and attach corresponding statically defined I3C 1644 + * devices to the master. 1661 1645 * 1662 1646 * 6. Do a DAA (Dynamic Address Assignment) to assign dynamic addresses to all 1663 1647 * remaining I3C devices ··· 1673 1653 enum i3c_addr_slot_status status; 1674 1654 struct i2c_dev_boardinfo *i2cboardinfo; 1675 1655 struct i3c_dev_boardinfo *i3cboardinfo; 1676 - struct i3c_dev_desc *i3cdev; 1677 1656 struct i2c_dev_desc *i2cdev; 1678 1657 int ret; 1679 1658 ··· 1701 1682 ret = i3c_master_attach_i2c_dev(master, i2cdev); 1702 1683 if (ret) { 1703 1684 i3c_master_free_i2c_dev(i2cdev); 1704 - goto err_detach_devs; 1705 - } 1706 - } 1707 - list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) { 1708 - struct i3c_device_info info = { 1709 - .static_addr = i3cboardinfo->static_addr, 1710 - }; 1711 - 1712 - if (i3cboardinfo->init_dyn_addr) { 1713 - status = i3c_bus_get_addr_slot_status(&master->bus, 1714 - i3cboardinfo->init_dyn_addr); 1715 - if (status != I3C_ADDR_SLOT_FREE) { 1716 - ret = -EBUSY; 1717 - goto err_detach_devs; 1718 - } 1719 - } 1720 - 1721 - i3cdev = i3c_master_alloc_i3c_dev(master, &info); 1722 - if (IS_ERR(i3cdev)) { 1723 - ret = PTR_ERR(i3cdev); 1724 - goto err_detach_devs; 1725 - } 1726 - 1727 - i3cdev->boardinfo = i3cboardinfo; 1728 - 1729 - ret = i3c_master_attach_i3c_dev(master, i3cdev); 1730 - if (ret) { 1731 - i3c_master_free_i3c_dev(i3cdev); 1732 1685 goto err_detach_devs; 1733 1686 } 1734 1687 } ··· 1740 1749 goto err_bus_cleanup; 1741 1750 1742 1751 /* 1743 - * Pre-assign dynamic address and retrieve device information if 1744 - * needed. 1752 + * Reserve init_dyn_addr first, and then try to pre-assign dynamic 1753 + * address and retrieve device information if needed. 1754 + * In case pre-assign dynamic address fails, setting dynamic address to 1755 + * the requested init_dyn_addr is retried after DAA is done in 1756 + * i3c_master_add_i3c_dev_locked(). 1745 1757 */ 1746 - i3c_bus_for_each_i3cdev(&master->bus, i3cdev) 1747 - i3c_master_pre_assign_dyn_addr(i3cdev); 1758 + list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) { 1759 + 1760 + /* 1761 + * We don't reserve a dynamic address for devices that 1762 + * don't explicitly request one. 1763 + */ 1764 + if (!i3cboardinfo->init_dyn_addr) 1765 + continue; 1766 + 1767 + ret = i3c_bus_get_addr_slot_status(&master->bus, 1768 + i3cboardinfo->init_dyn_addr); 1769 + if (ret != I3C_ADDR_SLOT_FREE) { 1770 + ret = -EBUSY; 1771 + goto err_rstdaa; 1772 + } 1773 + 1774 + i3c_bus_set_addr_slot_status(&master->bus, 1775 + i3cboardinfo->init_dyn_addr, 1776 + I3C_ADDR_SLOT_I3C_DEV); 1777 + 1778 + /* 1779 + * Only try to create/attach devices that have a static 1780 + * address. Other devices will be created/attached when 1781 + * DAA happens, and the requested dynamic address will 1782 + * be set using SETNEWDA once those devices become 1783 + * addressable. 1784 + */ 1785 + 1786 + if (i3cboardinfo->static_addr) 1787 + i3c_master_early_i3c_dev_add(master, i3cboardinfo); 1788 + } 1748 1789 1749 1790 ret = i3c_master_do_daa(master); 1750 1791 if (ret) ··· 1803 1780 master->ops->bus_cleanup(master); 1804 1781 1805 1782 i3c_master_detach_free_devs(master); 1783 + } 1784 + 1785 + static void i3c_master_attach_boardinfo(struct i3c_dev_desc *i3cdev) 1786 + { 1787 + struct i3c_master_controller *master = i3cdev->common.master; 1788 + struct i3c_dev_boardinfo *i3cboardinfo; 1789 + 1790 + list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) { 1791 + if (i3cdev->info.pid != i3cboardinfo->pid) 1792 + continue; 1793 + 1794 + i3cdev->boardinfo = i3cboardinfo; 1795 + i3cdev->info.static_addr = i3cboardinfo->static_addr; 1796 + return; 1797 + } 1806 1798 } 1807 1799 1808 1800 static struct i3c_dev_desc * ··· 1875 1837 if (ret) 1876 1838 goto err_detach_dev; 1877 1839 1840 + i3c_master_attach_boardinfo(newdev); 1841 + 1878 1842 olddev = i3c_master_search_i3c_dev_duplicate(newdev); 1879 1843 if (olddev) { 1880 - newdev->boardinfo = olddev->boardinfo; 1881 - newdev->info.static_addr = olddev->info.static_addr; 1882 1844 newdev->dev = olddev->dev; 1883 1845 if (newdev->dev) 1884 1846 newdev->dev->desc = newdev;
+3 -1
drivers/i3c/master/i3c-master-cdns.c
··· 1635 1635 master->ibi.slots = devm_kcalloc(&pdev->dev, master->ibi.num_slots, 1636 1636 sizeof(*master->ibi.slots), 1637 1637 GFP_KERNEL); 1638 - if (!master->ibi.slots) 1638 + if (!master->ibi.slots) { 1639 + ret = -ENOMEM; 1639 1640 goto err_disable_sysclk; 1641 + } 1640 1642 1641 1643 writel(IBIR_THR(1), master->regs + CMD_IBI_THR_CTRL); 1642 1644 writel(MST_INT_IBIR_THR, master->regs + MST_IER);