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 'phy-fix-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy

Pull phy fixes from Vinod Koul:
"Core:

- use per-PHY lockdep keys, in order to fix a phy using internal phys

Drivers:

- tegra:
- fixes for unbalanced regulator
- decouple pad calibration fix
- disable periodic updates

- qualcomm:
- error code fix for driver probe"

* tag 'phy-fix-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy:
phy: qcom: fix error code in snps_eusb2_hsphy_probe()
phy: use per-PHY lockdep keys
phy: tegra: xusb: Fix unbalanced regulator disable in UTMI PHY mode
phy: tegra: xusb: Disable periodic tracking on Tegra234
phy: tegra: xusb: Decouple CYA_TRK_CODE_UPDATE_ON_IDLE from trk_hw_mode

+58 -33
+4 -1
drivers/phy/phy-core.c
··· 994 994 } 995 995 996 996 device_initialize(&phy->dev); 997 - mutex_init(&phy->mutex); 997 + lockdep_register_key(&phy->lockdep_key); 998 + mutex_init_with_key(&phy->mutex, &phy->lockdep_key); 998 999 999 1000 phy->dev.class = &phy_class; 1000 1001 phy->dev.parent = dev; ··· 1260 1259 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); 1261 1260 debugfs_remove_recursive(phy->debugfs); 1262 1261 regulator_put(phy->pwr); 1262 + mutex_destroy(&phy->mutex); 1263 + lockdep_unregister_key(&phy->lockdep_key); 1263 1264 ida_free(&phy_ida, phy->id); 1264 1265 kfree(phy); 1265 1266 }
+4 -2
drivers/phy/phy-snps-eusb2.c
··· 567 567 } 568 568 } 569 569 570 - if (IS_ERR_OR_NULL(phy->ref_clk)) 571 - return dev_err_probe(dev, PTR_ERR(phy->ref_clk), 570 + if (IS_ERR_OR_NULL(phy->ref_clk)) { 571 + ret = phy->ref_clk ? PTR_ERR(phy->ref_clk) : -ENOENT; 572 + return dev_err_probe(dev, ret, 572 573 "failed to get ref clk\n"); 574 + } 573 575 574 576 num = ARRAY_SIZE(phy->vregs); 575 577 for (i = 0; i < num; i++)
+47 -30
drivers/phy/tegra/xusb-tegra186.c
··· 648 648 udelay(100); 649 649 } 650 650 651 - if (padctl->soc->trk_hw_mode) { 652 - value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 653 - value |= USB2_TRK_HW_MODE; 651 + value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 652 + if (padctl->soc->trk_update_on_idle) 654 653 value &= ~CYA_TRK_CODE_UPDATE_ON_IDLE; 655 - padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 656 - } else { 654 + if (padctl->soc->trk_hw_mode) 655 + value |= USB2_TRK_HW_MODE; 656 + padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL2); 657 + 658 + if (!padctl->soc->trk_hw_mode) 657 659 clk_disable_unprepare(priv->usb2_trk_clk); 658 - } 659 660 } 660 661 661 662 static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl) ··· 783 782 } 784 783 785 784 static int tegra186_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl, 786 - bool status) 785 + struct tegra_xusb_usb2_port *port, bool status) 787 786 { 788 - u32 value; 787 + u32 value, id_override; 788 + int err = 0; 789 789 790 790 dev_dbg(padctl->dev, "%s id override\n", status ? "set" : "clear"); 791 791 792 792 value = padctl_readl(padctl, USB2_VBUS_ID); 793 + id_override = value & ID_OVERRIDE(~0); 793 794 794 795 if (status) { 795 796 if (value & VBUS_OVERRIDE) { ··· 802 799 value = padctl_readl(padctl, USB2_VBUS_ID); 803 800 } 804 801 805 - value &= ~ID_OVERRIDE(~0); 806 - value |= ID_OVERRIDE_GROUNDED; 807 - } else { 808 - value &= ~ID_OVERRIDE(~0); 809 - value |= ID_OVERRIDE_FLOATING; 810 - } 802 + if (id_override != ID_OVERRIDE_GROUNDED) { 803 + value &= ~ID_OVERRIDE(~0); 804 + value |= ID_OVERRIDE_GROUNDED; 805 + padctl_writel(padctl, value, USB2_VBUS_ID); 811 806 812 - padctl_writel(padctl, value, USB2_VBUS_ID); 807 + err = regulator_enable(port->supply); 808 + if (err) { 809 + dev_err(padctl->dev, "Failed to enable regulator: %d\n", err); 810 + return err; 811 + } 812 + } 813 + } else { 814 + if (id_override == ID_OVERRIDE_GROUNDED) { 815 + /* 816 + * The regulator is disabled only when the role transitions 817 + * from USB_ROLE_HOST to USB_ROLE_NONE. 818 + */ 819 + err = regulator_disable(port->supply); 820 + if (err) { 821 + dev_err(padctl->dev, "Failed to disable regulator: %d\n", err); 822 + return err; 823 + } 824 + 825 + value &= ~ID_OVERRIDE(~0); 826 + value |= ID_OVERRIDE_FLOATING; 827 + padctl_writel(padctl, value, USB2_VBUS_ID); 828 + } 829 + } 813 830 814 831 return 0; 815 832 } ··· 849 826 850 827 if (mode == PHY_MODE_USB_OTG) { 851 828 if (submode == USB_ROLE_HOST) { 852 - tegra186_xusb_padctl_id_override(padctl, true); 853 - 854 - err = regulator_enable(port->supply); 829 + err = tegra186_xusb_padctl_id_override(padctl, port, true); 830 + if (err) 831 + goto out; 855 832 } else if (submode == USB_ROLE_DEVICE) { 856 833 tegra186_xusb_padctl_vbus_override(padctl, true); 857 834 } else if (submode == USB_ROLE_NONE) { 858 - /* 859 - * When port is peripheral only or role transitions to 860 - * USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not 861 - * enabled. 862 - */ 863 - if (regulator_is_enabled(port->supply)) 864 - regulator_disable(port->supply); 865 - 866 - tegra186_xusb_padctl_id_override(padctl, false); 835 + err = tegra186_xusb_padctl_id_override(padctl, port, false); 836 + if (err) 837 + goto out; 867 838 tegra186_xusb_padctl_vbus_override(padctl, false); 868 839 } 869 840 } 870 - 841 + out: 871 842 mutex_unlock(&padctl->lock); 872 - 873 843 return err; 874 844 } 875 845 ··· 1726 1710 .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names), 1727 1711 .supports_gen2 = true, 1728 1712 .poll_trk_completed = true, 1729 - .trk_hw_mode = true, 1713 + .trk_hw_mode = false, 1714 + .trk_update_on_idle = true, 1730 1715 .supports_lp_cfg_en = true, 1731 1716 }; 1732 1717 EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc);
+1
drivers/phy/tegra/xusb.h
··· 434 434 bool need_fake_usb3_port; 435 435 bool poll_trk_completed; 436 436 bool trk_hw_mode; 437 + bool trk_update_on_idle; 437 438 bool supports_lp_cfg_en; 438 439 }; 439 440
+2
include/linux/phy/phy.h
··· 154 154 * @id: id of the phy device 155 155 * @ops: function pointers for performing phy operations 156 156 * @mutex: mutex to protect phy_ops 157 + * @lockdep_key: lockdep information for this mutex 157 158 * @init_count: used to protect when the PHY is used by multiple consumers 158 159 * @power_count: used to protect when the PHY is used by multiple consumers 159 160 * @attrs: used to specify PHY specific attributes ··· 166 165 int id; 167 166 const struct phy_ops *ops; 168 167 struct mutex mutex; 168 + struct lock_class_key lockdep_key; 169 169 int init_count; 170 170 int power_count; 171 171 struct phy_attrs attrs;