Skip to content

Commit 5b35eb8

Browse files
committed
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
2 parents a4e3703 + b7acfea commit 5b35eb8

File tree

5 files changed

+57
-32
lines changed

5 files changed

+57
-32
lines changed

drivers/phy/phy-core.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,8 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
994994
}
995995

996996
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);
998999

9991000
phy->dev.class = &phy_class;
10001001
phy->dev.parent = dev;
@@ -1259,6 +1260,8 @@ static void phy_release(struct device *dev)
12591260
dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
12601261
debugfs_remove_recursive(phy->debugfs);
12611262
regulator_put(phy->pwr);
1263+
mutex_destroy(&phy->mutex);
1264+
lockdep_unregister_key(&phy->lockdep_key);
12621265
ida_free(&phy_ida, phy->id);
12631266
kfree(phy);
12641267
}

drivers/phy/phy-snps-eusb2.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,9 +567,11 @@ static int snps_eusb2_hsphy_probe(struct platform_device *pdev)
567567
}
568568
}
569569

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,
572573
"failed to get ref clk\n");
574+
}
573575

574576
num = ARRAY_SIZE(phy->vregs);
575577
for (i = 0; i < num; i++)

drivers/phy/tegra/xusb-tegra186.c

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -648,14 +648,15 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl)
648648
udelay(100);
649649
}
650650

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)
654653
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)
657659
clk_disable_unprepare(priv->usb2_trk_clk);
658-
}
659660
}
660661

661662
static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
@@ -782,13 +783,15 @@ static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
782783
}
783784

784785
static int tegra186_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl,
785-
bool status)
786+
struct tegra_xusb_usb2_port *port, bool status)
786787
{
787-
u32 value;
788+
u32 value, id_override;
789+
int err = 0;
788790

789791
dev_dbg(padctl->dev, "%s id override\n", status ? "set" : "clear");
790792

791793
value = padctl_readl(padctl, USB2_VBUS_ID);
794+
id_override = value & ID_OVERRIDE(~0);
792795

793796
if (status) {
794797
if (value & VBUS_OVERRIDE) {
@@ -799,15 +802,35 @@ static int tegra186_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl,
799802
value = padctl_readl(padctl, USB2_VBUS_ID);
800803
}
801804

802-
value &= ~ID_OVERRIDE(~0);
803-
value |= ID_OVERRIDE_GROUNDED;
805+
if (id_override != ID_OVERRIDE_GROUNDED) {
806+
value &= ~ID_OVERRIDE(~0);
807+
value |= ID_OVERRIDE_GROUNDED;
808+
padctl_writel(padctl, value, USB2_VBUS_ID);
809+
810+
err = regulator_enable(port->supply);
811+
if (err) {
812+
dev_err(padctl->dev, "Failed to enable regulator: %d\n", err);
813+
return err;
814+
}
815+
}
804816
} else {
805-
value &= ~ID_OVERRIDE(~0);
806-
value |= ID_OVERRIDE_FLOATING;
817+
if (id_override == ID_OVERRIDE_GROUNDED) {
818+
/*
819+
* The regulator is disabled only when the role transitions
820+
* from USB_ROLE_HOST to USB_ROLE_NONE.
821+
*/
822+
err = regulator_disable(port->supply);
823+
if (err) {
824+
dev_err(padctl->dev, "Failed to disable regulator: %d\n", err);
825+
return err;
826+
}
827+
828+
value &= ~ID_OVERRIDE(~0);
829+
value |= ID_OVERRIDE_FLOATING;
830+
padctl_writel(padctl, value, USB2_VBUS_ID);
831+
}
807832
}
808833

809-
padctl_writel(padctl, value, USB2_VBUS_ID);
810-
811834
return 0;
812835
}
813836

@@ -826,27 +849,20 @@ static int tegra186_utmi_phy_set_mode(struct phy *phy, enum phy_mode mode,
826849

827850
if (mode == PHY_MODE_USB_OTG) {
828851
if (submode == USB_ROLE_HOST) {
829-
tegra186_xusb_padctl_id_override(padctl, true);
830-
831-
err = regulator_enable(port->supply);
852+
err = tegra186_xusb_padctl_id_override(padctl, port, true);
853+
if (err)
854+
goto out;
832855
} else if (submode == USB_ROLE_DEVICE) {
833856
tegra186_xusb_padctl_vbus_override(padctl, true);
834857
} else if (submode == USB_ROLE_NONE) {
835-
/*
836-
* When port is peripheral only or role transitions to
837-
* USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
838-
* enabled.
839-
*/
840-
if (regulator_is_enabled(port->supply))
841-
regulator_disable(port->supply);
842-
843-
tegra186_xusb_padctl_id_override(padctl, false);
858+
err = tegra186_xusb_padctl_id_override(padctl, port, false);
859+
if (err)
860+
goto out;
844861
tegra186_xusb_padctl_vbus_override(padctl, false);
845862
}
846863
}
847-
864+
out:
848865
mutex_unlock(&padctl->lock);
849-
850866
return err;
851867
}
852868

@@ -1710,7 +1726,8 @@ const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = {
17101726
.num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
17111727
.supports_gen2 = true,
17121728
.poll_trk_completed = true,
1713-
.trk_hw_mode = true,
1729+
.trk_hw_mode = false,
1730+
.trk_update_on_idle = true,
17141731
.supports_lp_cfg_en = true,
17151732
};
17161733
EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc);

drivers/phy/tegra/xusb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ struct tegra_xusb_padctl_soc {
434434
bool need_fake_usb3_port;
435435
bool poll_trk_completed;
436436
bool trk_hw_mode;
437+
bool trk_update_on_idle;
437438
bool supports_lp_cfg_en;
438439
};
439440

include/linux/phy/phy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ struct phy_attrs {
154154
* @id: id of the phy device
155155
* @ops: function pointers for performing phy operations
156156
* @mutex: mutex to protect phy_ops
157+
* @lockdep_key: lockdep information for this mutex
157158
* @init_count: used to protect when the PHY is used by multiple consumers
158159
* @power_count: used to protect when the PHY is used by multiple consumers
159160
* @attrs: used to specify PHY specific attributes
@@ -165,6 +166,7 @@ struct phy {
165166
int id;
166167
const struct phy_ops *ops;
167168
struct mutex mutex;
169+
struct lock_class_key lockdep_key;
168170
int init_count;
169171
int power_count;
170172
struct phy_attrs attrs;

0 commit comments

Comments
 (0)