* RE: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
From: Ovidiu Panait @ 2026-05-04 12:11 UTC (permalink / raw)
To: geert
Cc: Vinod Koul, neil.armstrong@linaro.org, Biju Das,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <CAMuHMdWT+hv37gxi-5fbLVc16Fk4SKsXuBis5Fg6_zm7TS6hkQ@mail.gmail.com>
Hi Geert,
>
> Hi Ovidiu,
>
> On Mon, 4 May 2026 at 13:11, Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> wrote:
> > > On 27-04-26, 19:47, Ovidiu Panait wrote:
> > > > On the Renesas RZ/V2H platform, if the xhcd driver is unbound and
> the
> > > > system is suspended afterwards, a PM underflow error will occur:
> > > >
> > > > # echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-
> hcd/unbind
> > > > # systemctl suspend
> > > > 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq
> returns -
> > > 13
> > > > 15870000.usb-phy: PM: failed to resume noirq: error -13
> > > > 15870000.usb-phy: Runtime PM usage count underflow!
> > > >
> > > > Since the PHY framework is managing the runtime PM of the PHY via
> > > > phy_power_on()/phy_power_off(), there is no need for the PHY driver
> to
> > > > manipulate the runtime PM state during suspend.
> > > >
> > > > To fix this, remove the runtime PM calls from the suspend/resume
> paths
> > > > and add a get/put pair inside rzg3e_phy_usb3_init_helper() to make
> sure
> > > > the clock is enabled during init, even when there is no consumer for
> > > > the PHY.
> > >
> > > > Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to
> > > > SYSTEM_SLEEP_PM_OPS because runtime PM is disabled during the noirq
> > > phase
> > > > and pm_runtime_resume_and_get() would not actually enable the device
> > > clock.
> > >
> > > > Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY
> > > driver")
> > > > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
>
> > > > index 6b3453ea0004..055775e1a0f7 100644
> > > > --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> > > > +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
>
> > > > @@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device
> > > *dev)
> > > > if (ret)
> > > > return ret;
> > > >
> > > > - ret = pm_runtime_resume_and_get(dev);
> > > > + ret = rzg3e_phy_usb3_init_helper(r);
> > > > if (ret)
> > > > goto reset_assert;
> > > >
> > > > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > > > - if (ret)
> > > > - goto pm_put;
> > > > -
> > > > r->skip_reinit = true;
> > >
> > > https://sashiko.dev/#/patchset/20260427194741.161533-1-
> > > ovidiu.panait.rb%40renesas.com
> > >
> >
> > I think this is not applicable for our platforms, as the power domain
> only
> > gates the clock during runtime suspend, so the register state is not
> lost
> > across runtime suspend/resume.
> >
> > The power domain (drivers/clk/renesas/rzv2h-cpg.c) is marked as
> > GENPD_FLAG_ALWAYS_ON.
>
> Won't the SoC be powered down during s2ram?
>
Yes, the SoC will be powered down during s2ram and the USB3 PHY is
reinitialized in the resume callback:
static int rzg3e_phy_usb3_resume(struct device *dev)
{
...
ret = rzg3e_phy_usb3_init_helper(r->base);
if (ret)
goto pm_put;
My understanding is that Sashiko's comment ([1]) is about runtime PM and
whether the PM domain will be powered off after the refcount reaches 0,
destroying the PHY state. Which does not happen on our platforms, as the
CPG driver sets GENPD_FLAG_ALWAYS_ON and it only gates/ungates the clock
across runtime suspend/resume, preserving the state.
[1] https://sashiko.dev/#/patchset/20260427194741.161533-1-ovidiu.panait.rb%40renesas.com
Thanks,
Ovidiu
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
>
> In personal conversations with technical people, I call myself a hacker.
> But
> when I'm talking to journalists I just say "programmer" or something like
> that.
> -- Linus Torvalds
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v7 phy-next 09/27] scsi: ufs: exynos: stop poking into struct phy guts
From: Vladimir Oltean @ 2026-05-04 11:48 UTC (permalink / raw)
To: linux-phy
Cc: Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Bart Van Assche, Alim Akhtar, Martin K . Petersen,
Peter Griffin, James E.J. Bottomley, Krzysztof Kozlowski,
Chanho Park
In-Reply-To: <20260430110652.558622-10-vladimir.oltean@nxp.com>
[-- Attachment #1: Type: text/plain, Size: 1891 bytes --]
Sashiko says:
> commit 76ded6c0290bdb192c2ae1af9a2e6a47fc39c9a1
> Author: Vladimir Oltean <vladimir.oltean@nxp.com>
>
> scsi: ufs: exynos: stop poking into struct phy guts
> This commit modifies the Exynos UFS driver to stop directly accessing the
> generic PHY's power_count. Instead, it tracks the PHY power state internally
> using a new phy_powered_on flag to properly handle link retries and
> suspend/resume operations.
>
> > diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
> > --- a/drivers/ufs/host/ufs-exynos.c
> > +++ b/drivers/ufs/host/ufs-exynos.c
> [ ... ]
> > @@ -1513,6 +1516,9 @@ static void exynos_ufs_exit(struct ufs_hba *hba)
> > {
> > struct exynos_ufs *ufs = ufshcd_get_variant(hba);
> >
> > + if (!ufs->phy_powered_on)
> > + return;
> > +
> > phy_power_off(ufs->phy);
> > phy_exit(ufs->phy);
> > }
>
> Does this introduce a regression where initialization resources are leaked
> if the driver is unbound while suspended?
> Looking at exynos_ufs_suspend(), the PHY is powered off and phy_powered_on
> is set to false, but phy_exit() is intentionally not called so the PHY
> remains initialized:
> exynos_ufs_suspend()
> if (!ufshcd_is_link_active(hba) && ufs->phy_powered_on) {
> phy_power_off(ufs->phy);
> ufs->phy_powered_on = false;
> }
> If an unbind or fatal error occurs while in this suspended state,
> exynos_ufs_exit() will see phy_powered_on as false and return immediately.
> The initialization reference and any resources allocated by phy_init()
> would never be released since phy_exit() is completely skipped.
> [ ... ]
I think I've been looking at this issue all wrong, not considering why
the UFS HCD driver calls phy_exit() -> phy_init() at runtime and what
can be done about that.
I have replaced this patch with the one attached, which I will be sending
for v8.
[-- Attachment #2: 0001-scsi-ufs-exynos-use-dedicated-API-for-updating-PHY-b.patch --]
[-- Type: text/x-diff, Size: 9438 bytes --]
From c687a8568c6c7837bb0bd539bf14343d7d0c63a1 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Mon, 4 May 2026 14:00:51 +0300
Subject: [PATCH] scsi: ufs: exynos: use dedicated API for updating PHY bus
width
I am trying to get rid of code instances where PHY consumers (like the
Exynos UFS HCD) poke inside struct phy fields, in order to further turn
struct phy into an opaque data structure.
The ufs-exynos.c driver interacts with phy-samsung-ufs.c in order to
power it on and to update the lane count. For the later purpose, it
(ab)uses phy_set_bus_width().
The phy_set_bus_width() function is a PHY provider function, not a
consumer one, and I am calling its use from ufs-exynos.c an abuse
because
(1) commit 8feed347d33b ("phy: add phy_get_bus_width()/phy_set_bus_width()
calls") clearly states so.
(2) phy_set_bus_width() only alters phy->attrs.bus_width, and does not
call into phy_ops at all. So a consumer that makes a call to
phy_set_bus_width() will not produce any hardware change in the
provider at all.
This is where the Exynos UFS HCD driver decided to be creative and
hijacked phy_init() to pick up the bus_width attribute.
This requires a very careful dance where the PHY consumer needs to
simultaneously juggle two requirements:
- the UFS PHY needs to pick up the updated lane count in its
samsung_ufs_phy_init() handler for the phy_init() call
- phy_init() calls need to be balanced with phy_exit(), otherwise
subsequent phy_init() calls don't make it into samsung_ufs_phy_init()
and just leave the PHY with an elevated init_count
- phy_power_on() can't be called without phy_init()
This is why the following bug fix commits exist:
3d73b200f989 ("scsi: ufs: ufs-exynos: Change ufs phy control sequence")
7f05fd9a3b6f ("scsi: ufs: exynos: Ensure consistent phy reference counts")
Currently the UFS HCD driver tries to keep the PHY init_count and
power_count in tight lockstep, but even this is error-prone. For
example, if exynos_ufs_suspend() runs and then exynos_ufs_exit(),
the PHY power_count will underflow.
If we address the root issue first (phy_init() abused to pick up new
lane count) by introducing a new PHY consumer method which actually does
call into the PHY provider driver, then we are able to absorb the entire
UFS HCD dance and update the lane count without altering the PHY
init_count or power_count.
Then we are much more free to call phy_init() from wherever we want, and
same goes for phy_power_on().
It is typical to call phy_init() right after phy_get(), and doing so
will naturally balance it with phy_exit().
We can also leave the phy_power_on() call to be on demand, placed inside
exynos_ufs_pre_link(). Because this call can be made multiple times and
is not balanced with anything else, we need a consumer-specific "bool
phy_powered_on" which ensures that we call phy_power_on() at most once,
and that exynos_ufs_exit() only calls phy_power_off() if phy_power_on()
was previously called. Using the phy->power_count for this purpose is
undesirable because
(a) it is going away
(b) the PHY API supports multiple consumers for the same provider, so it
cannot offer an equivalent helper because it doesn't want consumers
to interfere with each other
Inside the new samsung_ufs_phy_request_bus_width(), I've sanity checked
that the bus width is either 1 or 2 lanes. This coincides with
samsung_ufs_phy_config() which only configures LANE_0 and LANE_1.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Peter Griffin <peter.griffin@linaro.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Chanho Park <chanho61.park@samsung.com>
v7->v8:
- rewrote commit after Sashiko pointed out the new handling is still
not correct:
https://sashiko.dev/#/patchset/20260430110652.558622-1-vladimir.oltean@nxp.com
- removed Reviewed-by, Tested-by and Acked-by tags from Alim, Bart and
Peter
v6->v7: collect tags from Martin and Peter
v5->v6: collect tags from Alim Akhtar
v4->v5: collect tag, add "scsi: " prefix to commit title
v3->v4: none
v2->v3:
- add Cc Chanho Park, author of commit 3d73b200f989 ("scsi: ufs:
ufs-exynos: Change ufs phy control sequence")
v1->v2:
- add better ufs->phy_powered_on handling in exynos_ufs_exit(),
exynos_ufs_suspend() and exynos_ufs_resume() which ensures we won't
enter a phy->power_count underrun condition
---
drivers/phy/phy-core.c | 18 +++++++++++
drivers/phy/samsung/phy-samsung-ufs.c | 30 ++++++++++++------
drivers/ufs/host/ufs-exynos.c | 45 ++++++++++++++++++++++-----
drivers/ufs/host/ufs-exynos.h | 1 +
4 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 21aaf2f76e53..6305efe210d6 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -606,6 +606,24 @@ int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
}
EXPORT_SYMBOL_GPL(phy_validate);
+int phy_request_bus_width(struct phy *phy, int bus_width)
+{
+ int ret;
+
+ if (!phy)
+ return -EINVAL;
+
+ if (!phy->ops->request_bus_width)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->request_bus_width(phy, bus_width);
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_request_bus_width);
+
/**
* _of_phy_get() - lookup and obtain a reference to a phy by phandle
* @np: device_node for which to get the phy
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index 00e570d699f3..5d7b842bff1a 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -161,16 +161,6 @@ static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy)
return devm_clk_bulk_get(phy->dev, num_clks, phy->clks);
}
-static int samsung_ufs_phy_request_bus_width(struct phy *phy, int bus_width)
-{
- if (bus_width != 1 && bus_width != 2)
- return -EINVAL;
-
- ss_phy->lane_cnt = phy->attrs.bus_width;
-
- return 0;
-}
-
static int samsung_ufs_phy_init(struct phy *phy)
{
struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
@@ -213,6 +203,26 @@ static int samsung_ufs_phy_power_off(struct phy *phy)
return 0;
}
+static int samsung_ufs_phy_request_bus_width(struct phy *phy, int bus_width)
+{
+ struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
+
+ if (bus_width != 1 && bus_width != 2)
+ return -EINVAL;
+
+ ss_phy->lane_cnt = phy->attrs.bus_width;
+
+ if (phy->init_count)
+ samsung_ufs_phy_init(phy);
+
+ if (phy->power_count) {
+ samsung_ufs_phy_power_off(phy);
+ return samsung_ufs_phy_power_on(phy);
+ }
+
+ return 0;
+}
+
static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
enum phy_mode mode, int submode)
{
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
index fb616d1599eb..b90876b268db 100644
--- a/drivers/ufs/host/ufs-exynos.c
+++ b/drivers/ufs/host/ufs-exynos.c
@@ -959,6 +959,40 @@ static void exynos_ufs_phy_exit(struct exynos_ufs *ufs)
phy_exit(ufs->phy);
}
+static int exynos_ufs_phy_power_on(struct exynos_ufs *ufs)
+{
+ int ret;
+
+ if (ufs->phy_powered_on)
+ return 0;
+
+ ret = phy_power_on(ufs->phy);
+ if (ret) {
+ dev_err(ufs->hba->dev, "Failed to power on PHY: %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+
+ ufs->phy_powered_on = true;
+
+ return 0;
+}
+
+static void exynos_ufs_phy_power_off(struct exynos_ufs *ufs)
+{
+ int ret;
+
+ if (!ufs->phy_powered_on)
+ return;
+
+ ret = phy_power_off(ufs->phy);
+ if (ret)
+ dev_warn(ufs->hba->dev, "Failed to power off PHY: %pe\n",
+ ERR_PTR(ret));
+
+ ufs->phy_powered_on = false;
+}
+
static int exynos_ufs_phy_update_bus_width(struct exynos_ufs *ufs)
{
struct ufs_hba *hba = ufs->hba;
@@ -979,10 +1013,7 @@ static int exynos_ufs_phy_update_bus_width(struct exynos_ufs *ufs)
if (ret)
return ret;
- if (generic_phy->power_count)
- phy_power_off(generic_phy);
-
- return phy_power_on(generic_phy);
+ return exynos_ufs_phy_power_on(ufs);
}
static void exynos_ufs_config_unipro(struct exynos_ufs *ufs)
@@ -1524,7 +1555,7 @@ static void exynos_ufs_exit(struct ufs_hba *hba)
{
struct exynos_ufs *ufs = ufshcd_get_variant(hba);
- phy_power_off(ufs->phy);
+ exynos_ufs_phy_power_off(ufs);
exynos_ufs_phy_exit(ufs);
}
@@ -1739,7 +1770,7 @@ static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
ufs->drv_data->suspend(ufs);
if (!ufshcd_is_link_active(hba))
- phy_power_off(ufs->phy);
+ exynos_ufs_phy_power_off(ufs);
return 0;
}
@@ -1749,7 +1780,7 @@ static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
struct exynos_ufs *ufs = ufshcd_get_variant(hba);
if (!ufshcd_is_link_active(hba))
- phy_power_on(ufs->phy);
+ exynos_ufs_phy_power_on(ufs);
exynos_ufs_config_smu(ufs);
exynos_ufs_fmp_resume(hba);
diff --git a/drivers/ufs/host/ufs-exynos.h b/drivers/ufs/host/ufs-exynos.h
index abe7e472759e..683b9150e2ba 100644
--- a/drivers/ufs/host/ufs-exynos.h
+++ b/drivers/ufs/host/ufs-exynos.h
@@ -227,6 +227,7 @@ struct exynos_ufs {
int avail_ln_rx;
int avail_ln_tx;
int rx_sel_idx;
+ bool phy_powered_on;
struct ufs_pa_layer_attr dev_req_params;
struct ufs_phy_time_cfg t_cfg;
ktime_t entry_hibern8_t;
--
2.34.1
[-- Attachment #3: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
From: Geert Uytterhoeven @ 2026-05-04 11:44 UTC (permalink / raw)
To: Ovidiu Panait
Cc: Vinod Koul, neil.armstrong@linaro.org, Biju Das,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <OSOP301MB19766FF764E6626FF1CD6771D3312@OSOP301MB1976.JPNP301.PROD.OUTLOOK.COM>
Hi Ovidiu,
On Mon, 4 May 2026 at 13:11, Ovidiu Panait <ovidiu.panait.rb@renesas.com> wrote:
> > On 27-04-26, 19:47, Ovidiu Panait wrote:
> > > On the Renesas RZ/V2H platform, if the xhcd driver is unbound and the
> > > system is suspended afterwards, a PM underflow error will occur:
> > >
> > > # echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
> > > # systemctl suspend
> > > 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq returns -
> > 13
> > > 15870000.usb-phy: PM: failed to resume noirq: error -13
> > > 15870000.usb-phy: Runtime PM usage count underflow!
> > >
> > > Since the PHY framework is managing the runtime PM of the PHY via
> > > phy_power_on()/phy_power_off(), there is no need for the PHY driver to
> > > manipulate the runtime PM state during suspend.
> > >
> > > To fix this, remove the runtime PM calls from the suspend/resume paths
> > > and add a get/put pair inside rzg3e_phy_usb3_init_helper() to make sure
> > > the clock is enabled during init, even when there is no consumer for
> > > the PHY.
> >
> > > Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to
> > > SYSTEM_SLEEP_PM_OPS because runtime PM is disabled during the noirq
> > phase
> > > and pm_runtime_resume_and_get() would not actually enable the device
> > clock.
> >
> > > Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY
> > driver")
> > > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > > index 6b3453ea0004..055775e1a0f7 100644
> > > --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> > > +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > > @@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device
> > *dev)
> > > if (ret)
> > > return ret;
> > >
> > > - ret = pm_runtime_resume_and_get(dev);
> > > + ret = rzg3e_phy_usb3_init_helper(r);
> > > if (ret)
> > > goto reset_assert;
> > >
> > > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > > - if (ret)
> > > - goto pm_put;
> > > -
> > > r->skip_reinit = true;
> >
> > https://sashiko.dev/#/patchset/20260427194741.161533-1-
> > ovidiu.panait.rb%40renesas.com
> >
>
> I think this is not applicable for our platforms, as the power domain only
> gates the clock during runtime suspend, so the register state is not lost
> across runtime suspend/resume.
>
> The power domain (drivers/clk/renesas/rzv2h-cpg.c) is marked as
> GENPD_FLAG_ALWAYS_ON.
Won't the SoC be powered down during s2ram?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
From: Ovidiu Panait @ 2026-05-04 11:09 UTC (permalink / raw)
To: Vinod Koul
Cc: neil.armstrong@linaro.org, Biju Das,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <afd-gj-F3OYDfCwJ@vaman>
Hi Vinod,
>
> On 27-04-26, 19:47, Ovidiu Panait wrote:
> > On the Renesas RZ/V2H platform, if the xhcd driver is unbound and the
> > system is suspended afterwards, a PM underflow error will occur:
> >
> > # echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
> > # systemctl suspend
> > 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq returns -
> 13
> > 15870000.usb-phy: PM: failed to resume noirq: error -13
> > 15870000.usb-phy: Runtime PM usage count underflow!
> >
> > Since the PHY framework is managing the runtime PM of the PHY via
> > phy_power_on()/phy_power_off(), there is no need for the PHY driver to
> > manipulate the runtime PM state during suspend.
> >
> > To fix this, remove the runtime PM calls from the suspend/resume paths
> > and add a get/put pair inside rzg3e_phy_usb3_init_helper() to make sure
> > the clock is enabled during init, even when there is no consumer for
> > the PHY.
>
> Ok
>
> >
> > Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to
> > SYSTEM_SLEEP_PM_OPS because runtime PM is disabled during the noirq
> phase
> > and pm_runtime_resume_and_get() would not actually enable the device
> clock.
>
> This is a fix, so split this up please
>
> >
> > Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY
> driver")
> > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> > ---
> > drivers/phy/renesas/phy-rzg3e-usb3.c | 31 ++++++++++++++++------------
> > 1 file changed, 18 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c
> b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > index 6b3453ea0004..055775e1a0f7 100644
> > --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> > +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
> > @@ -64,6 +64,7 @@
> > #define USB3_TEST_LANECONFIG0_DEFAULT (0xd)
> >
> > struct rz_usb3 {
> > + struct device *dev;
>
> This does not belong in a fix, please split
>
Thanks for your review, I'll split this up into multiple patches.
> > void __iomem *base;
> > struct reset_control *rstc;
> > bool skip_reinit;
> > @@ -130,11 +131,21 @@ static int rzg3e_phy_usb3test_phy_init(void
> __iomem *base)
> > return 0;
> > }
> >
> > -static int rzg3e_phy_usb3_init_helper(void __iomem *base)
> > +static int rzg3e_phy_usb3_init_helper(struct rz_usb3 *r)
> > {
> > - rzg3e_phy_usb2test_phy_init(base);
> > + int ret;
> > +
> > + ret = pm_runtime_resume_and_get(r->dev);
> > + if (ret)
> > + return ret;
> > +
> > + rzg3e_phy_usb2test_phy_init(r->base);
> >
> > - return rzg3e_phy_usb3test_phy_init(base);
> > + ret = rzg3e_phy_usb3test_phy_init(r->base);
> > +
> > + pm_runtime_put_sync(r->dev);
> > +
> > + return ret;
> > }
> >
> > static int rzg3e_phy_usb3_init(struct phy *p)
> > @@ -143,7 +154,7 @@ static int rzg3e_phy_usb3_init(struct phy *p)
> > int ret = 0;
> >
> > if (!r->skip_reinit)
> > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > + ret = rzg3e_phy_usb3_init_helper(r);
> >
> > return ret;
> > }
> > @@ -187,6 +198,7 @@ static int rzg3e_phy_usb3_probe(struct
> platform_device *pdev)
> >
> > platform_set_drvdata(pdev, r);
> > phy_set_drvdata(phy, r);
> > + r->dev = dev;
> >
> > provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > if (IS_ERR(provider))
> > @@ -199,7 +211,6 @@ static int rzg3e_phy_usb3_suspend(struct device
> *dev)
> > {
> > struct rz_usb3 *r = dev_get_drvdata(dev);
> >
> > - pm_runtime_put(dev);
> > reset_control_assert(r->rstc);
> > r->skip_reinit = false;
> >
> > @@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device
> *dev)
> > if (ret)
> > return ret;
> >
> > - ret = pm_runtime_resume_and_get(dev);
> > + ret = rzg3e_phy_usb3_init_helper(r);
> > if (ret)
> > goto reset_assert;
> >
> > - ret = rzg3e_phy_usb3_init_helper(r->base);
> > - if (ret)
> > - goto pm_put;
> > -
> > r->skip_reinit = true;
>
> https://sashiko.dev/#/patchset/20260427194741.161533-1-
> ovidiu.panait.rb%40renesas.com
>
I think this is not applicable for our platforms, as the power domain only
gates the clock during runtime suspend, so the register state is not lost
across runtime suspend/resume.
The power domain (drivers/clk/renesas/rzv2h-cpg.c) is marked as
GENPD_FLAG_ALWAYS_ON.
Thanks,
Ovidiu
>
> --
> ~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: phy: Add Spacemit K3 USB3/PCIe comb phy support
From: Inochi Amaoto @ 2026-05-04 10:20 UTC (permalink / raw)
To: Krzysztof Kozlowski, Inochi Amaoto
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yixun Lan, Kees Cook, Gustavo A. R. Silva,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Ze Huang, Alex Elder, linux-phy, devicetree, linux-riscv,
spacemit, linux-kernel, linux-hardening, Yixun Lan, Longbin Li
In-Reply-To: <20260504-logical-nice-python-1e1f43@quoll>
On Mon, May 04, 2026 at 11:54:11AM +0200, Krzysztof Kozlowski wrote:
> On Thu, Apr 30, 2026 at 10:28:40AM +0800, Inochi Amaoto wrote:
> > +properties:
> > + compatible:
> > + const: spacemit,k3-comb-phy
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + "#phy-cells":
> > + const: 2
> > + description:
> > + The first one is phy id, the second one is phy type.
>
> You could mention here the defines representing supported phy types.
>
OK.
> > +
> > + spacemit,apb-spare:
> > + $ref: /schemas/types.yaml#/definitions/phandle
> > + description:
> > + Phandle to APB SPARE system controller interface, used for
> > + PHY calibration.
> > +
> > + spacemit,apmu:
> > + $ref: /schemas/types.yaml#/definitions/phandle-array
> > + items:
> > + - items:
> > + - description: phandle of APMU syscon
> > + - description: configuration of the PHY lanes
> > + description: |
> > + Phandle to control PHY mux configuration. The configuration
> > + is described as follows:
> > + bit 4: 0 - PCIe A x8 mode, 1 - PCIe lane share mode
> > + bit 3: 0 - PCIe A x4 mode, 1 - PCIe A x2 and PCIe B x2 mode
> > + bit 2: 0 - PCIe C lane 0 is PCIe mode , 1 - USB mode
> > + bit 1: 0 - PCIe C lane 1 is PCIe mode , 1 - USB mode
> > + bit 0: 0 - PCIe D lane is PCIe mode , 1 - USB mode
>
> I assume this device k3-comb-phy handles phys for PCIe A, B, C and D?
>
In fact it handles phys for PCIe A-E. The mux for the phy of PCIe E
(the id is 5) is controlled by bit 4. If the comb PHY is in shared
mode, the PCIe E always got one lane.
I think it is good to add a public link for this configuration, but
Spacemit has no opened any document for this publicly....
> > +
> > + The bit[3:0] is only valid when bit 4 is 1.
> > +
> > +required:
> > + - compatible
>
> reg required.
>
It is fine for me
> > + - "#phy-cells"
> > + - spacemit,apb-spare
> > + - spacemit,apmu
> > +
> > +additionalProperties: false
>
> Best regards,
> Krzysztof
>
Regards,
Inochi
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/5] dt-bindings: phy: qcom,qusb2: Document QUSB2 Phy for Shikra
From: Krzysztof Kozlowski @ 2026-05-04 10:14 UTC (permalink / raw)
To: Komal Bajaj
Cc: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng, Vinod Koul, Neil Armstrong,
linux-arm-msm, linux-usb, devicetree, linux-kernel, linux-phy,
Krishna Kurapati
In-Reply-To: <20260430-shikra-usb-v1-2-c9c108536fdc@oss.qualcomm.com>
On Thu, Apr 30, 2026 at 05:20:27PM +0530, Komal Bajaj wrote:
> From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
>
> Update dt-bindings to add Shikra to QUSB2 Phy list.
>
> Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Incomplete DCO, incomplete description of hardware, mixing subsystems
without any need or explanation.
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/5] dt-bindings: usb: qcom,snps-dwc3: Add Shikra compatible
From: Krzysztof Kozlowski @ 2026-05-04 10:13 UTC (permalink / raw)
To: Komal Bajaj
Cc: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng, Vinod Koul, Neil Armstrong,
linux-arm-msm, linux-usb, devicetree, linux-kernel, linux-phy,
Krishna Kurapati
In-Reply-To: <20260430-shikra-usb-v1-1-c9c108536fdc@oss.qualcomm.com>
On Thu, Apr 30, 2026 at 05:20:26PM +0530, Komal Bajaj wrote:
> From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
>
> Introduce the compatible definition for Shikra QCOM SNPS DWC3.
>
> Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> ---
> Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml | 3 +++
> 1 file changed, 3 insertions(+)
Please do not mix subsystems.
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: phy: Add Spacemit K3 USB3/PCIe comb phy support
From: Krzysztof Kozlowski @ 2026-05-04 9:54 UTC (permalink / raw)
To: Inochi Amaoto
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yixun Lan, Kees Cook, Gustavo A. R. Silva,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Ze Huang, Alex Elder, linux-phy, devicetree, linux-riscv,
spacemit, linux-kernel, linux-hardening, Yixun Lan, Longbin Li
In-Reply-To: <20260430022843.1090138-2-inochiama@gmail.com>
On Thu, Apr 30, 2026 at 10:28:40AM +0800, Inochi Amaoto wrote:
> +properties:
> + compatible:
> + const: spacemit,k3-comb-phy
> +
> + reg:
> + maxItems: 1
> +
> + "#phy-cells":
> + const: 2
> + description:
> + The first one is phy id, the second one is phy type.
You could mention here the defines representing supported phy types.
> +
> + spacemit,apb-spare:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description:
> + Phandle to APB SPARE system controller interface, used for
> + PHY calibration.
> +
> + spacemit,apmu:
> + $ref: /schemas/types.yaml#/definitions/phandle-array
> + items:
> + - items:
> + - description: phandle of APMU syscon
> + - description: configuration of the PHY lanes
> + description: |
> + Phandle to control PHY mux configuration. The configuration
> + is described as follows:
> + bit 4: 0 - PCIe A x8 mode, 1 - PCIe lane share mode
> + bit 3: 0 - PCIe A x4 mode, 1 - PCIe A x2 and PCIe B x2 mode
> + bit 2: 0 - PCIe C lane 0 is PCIe mode , 1 - USB mode
> + bit 1: 0 - PCIe C lane 1 is PCIe mode , 1 - USB mode
> + bit 0: 0 - PCIe D lane is PCIe mode , 1 - USB mode
I assume this device k3-comb-phy handles phys for PCIe A, B, C and D?
> +
> + The bit[3:0] is only valid when bit 4 is 1.
> +
> +required:
> + - compatible
reg required.
> + - "#phy-cells"
> + - spacemit,apb-spare
> + - spacemit,apmu
> +
> +additionalProperties: false
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Document Nord QMP UFS PHY
From: Shawn Guo @ 2026-05-04 8:14 UTC (permalink / raw)
To: Vinod Koul
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio,
Dmitry Baryshkov, Bartosz Golaszewski, Deepti Jaggi, linux-phy,
devicetree, linux-arm-msm, linux-kernel, Shawn Guo
Document QMP UFS PHY on Qualcomm Nord SoC.
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
---
Changes in v3:
- Improve commit log to drop "compatible with" part
- Link to v2: https://lore.kernel.org/all/20260427012732.231611-1-shengchao.guo@oss.qualcomm.com/
Changes in v2:
- Add Nord compatible to existing qcom,sm8650-qmp-ufs-phy item instead
of duplicating (Thanks Krzysztof!)
- Link to v1: https://lore.kernel.org/all/20260420074942.1250414-1-shengchao.guo@oss.qualcomm.com/
.../devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
index 9616c736b6d4..b2c5c9a375a3 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -31,6 +31,7 @@ properties:
- items:
- enum:
- qcom,eliza-qmp-ufs-phy
+ - qcom,nord-qmp-ufs-phy
- const: qcom,sm8650-qmp-ufs-phy
- items:
- enum:
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v7 phy-next 08/27] PCI: Remove device links to PHY
From: Vladimir Oltean @ 2026-05-04 7:57 UTC (permalink / raw)
To: linux-phy, Bjorn Helgaas
Cc: Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Vignesh Raghavendra,
Siddharth Vadapalli
In-Reply-To: <20260430110652.558622-9-vladimir.oltean@nxp.com>
Sashiko says:
> commit e4f495a9118b40f8a77e8dc097821d2c846ed1fc
> Author: Vladimir Oltean <vladimir.oltean@nxp.com>
>
> PCI: Remove device links to PHY
> This commit removes device links between the PCIe controllers and PHY
> providers across several drivers, since the PHY core already creates consumer
> device links.
>
> > diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
> > index b067a3296dd37..fc39c01b79648 100644
> > --- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
> > +++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
> [ ... ]
> > @@ -122,9 +121,6 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
> > pm_runtime_put_sync(dev);
> > pm_runtime_disable(dev);
> > cdns_pcie_disable_phy(cdns_plat_pcie->pcie);
> > - phy_count = cdns_plat_pcie->pcie->phy_count;
> > - while (phy_count--)
> > - device_link_del(cdns_plat_pcie->pcie->link[phy_count]);
> >
> > return 0;
>
> This isn't a bug introduced by your patch, but I noticed the error path in
> cdns_plat_pcie_probe() returns 0.
> Does this cause the driver core to consider the probe successful even when
> host or endpoint setup steps fail? It looks like the device would be left
> in an uninitialized and disabled state while still being bound to the driver.
> Should this return ret instead?
>
The condition does not appear intentional. Commit bd22885aa188 ("PCI:
cadence: Refactor driver to use as a core library") changed
cdns_pcie_host_probe() which properly returned ret on error with
cdns_plat_pcie_probe() which doesn't.
I will add a preparatory patch which replaces "return 0" with "return ret"
in cdns_plat_pcie_probe(), blaming that commit.
> > }
> > diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
> > index cd904659c3216..9c1aef4d0bd1c 100644
> > --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> > +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> [ ... ]
> > @@ -852,10 +840,6 @@ static int dra7xx_pcie_probe(struct platform_device *pdev)
> > pm_runtime_disable(dev);
> > dra7xx_pcie_disable_phy(dra7xx);
> >
> > -err_link:
> > - while (--i >= 0)
> > - device_link_del(link[i]);
> > -
> > return ret;
> > }
>
> This isn't a bug introduced by your changes, but looking closely at the error
> path right above this hunk, there is a call to pm_runtime_put(dev) immediately
> followed by pm_runtime_disable(dev):
> err_gpio:
> err_get_sync:
> pm_runtime_put(dev);
> pm_runtime_disable(dev);
> Does this sequence create a power management race condition? The pending
> asynchronous idle/suspend work can be abruptly cancelled by
> pm_runtime_disable(), leaving the hardware in an incorrect or unpredictable
> power state.
> Should this use pm_runtime_put_sync() instead?
>
> > diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
> > index fe4836925c4e3..cab9fad212add 100644
> > --- a/drivers/pci/controller/dwc/pci-keystone.c
> > +++ b/drivers/pci/controller/dwc/pci-keystone.c
> [ ... ]
> > @@ -1337,25 +1321,18 @@ static int ks_pcie_probe(struct platform_device *pdev)
> > pm_runtime_disable(dev);
> > ks_pcie_disable_phy(ks_pcie);
> >
> > -err_link:
> > - while (--i >= 0 && link[i])
> > - device_link_del(link[i]);
> > -
> > +err:
> > return ret;
> > }
> >
> > static void ks_pcie_remove(struct platform_device *pdev)
> > {
> > struct keystone_pcie *ks_pcie = platform_get_drvdata(pdev);
> > - struct device_link **link = ks_pcie->link;
> > - int num_lanes = ks_pcie->num_lanes;
> > struct device *dev = &pdev->dev;
> >
> > pm_runtime_put(dev);
> > pm_runtime_disable(dev);
>
> Similar to the question above, is it possible this asynchronous put causes
> a race when immediately followed by pm_runtime_disable() during removal?
>
> > ks_pcie_disable_phy(ks_pcie);
> > - while (num_lanes--)
> > - device_link_del(link[num_lanes]);
> > }
It seems plausible that the pm_runtime_put() -> pm_runtime_disable()
pattern is ineffective, i.e. one of two things can happen: either
pm_runtime_put() runs to completion by chance, or pm_runtime_disable()
cancels it. However I am not very familiar with the runtime PM API and
its effects, and unless a maintainer tells me to, I would prefer leaving
these code paths alone.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 0/4] phy: phy-can-transceiver: Ad-hoc cleanups and refactoring
From: Andy Shevchenko @ 2026-05-04 7:01 UTC (permalink / raw)
To: Vinod Koul
Cc: linux-can, linux-phy, linux-kernel, Marc Kleine-Budde,
Vincent Mailhol, Neil Armstrong, Josua Mayer, Ulf Hansson
In-Reply-To: <afd_csl0eHFfVWLP@vaman>
On Sun, May 03, 2026 at 10:31:38PM +0530, Vinod Koul wrote:
> On 14-04-26, 21:43, Andy Shevchenko wrote:
> > On Tue, Mar 17, 2026 at 09:27:26PM +0100, Andy Shevchenko wrote:
> > > The driver does two things that need to be addressed:
> > > - includes subject to remove gpio.h
> > > - checks for error code from device property APIs when it can be done in
> > > a robust way
> > >
> > > This series addresses the above and adds a couple of additional refactoring.
> >
> > Any comments on this? Doesn't look like it being applied so far...
>
> Apart from stray delete, rest looks, fine. Can you fix that and rebase
Sent as 20260504070054.29508-1-andriy.shevchenko@linux.intel.com.
--
With Best Regards,
Andy Shevchenko
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 4/4] phy: phy-can-transceiver: Drop unused include
From: Andy Shevchenko @ 2026-05-04 6:58 UTC (permalink / raw)
To: Peng Fan, linux-can, linux-phy, linux-kernel
Cc: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
Josua Mayer, Ulf Hansson, Andy Shevchenko
In-Reply-To: <20260504070054.29508-1-andriy.shevchenko@linux.intel.com>
This file does not use the symbols from the legacy
<linux/gpio.h> header, so let's drop it.
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/phy/phy-can-transceiver.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 238c7963724b..eeaad41ab924 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -5,12 +5,11 @@
* Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com
*
*/
+#include <linux/gpio/consumer.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/gpio/consumer.h>
#include <linux/mux/consumer.h>
struct can_transceiver_data {
--
2.50.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 2/4] phy: phy-can-transceiver: Move OF ID table closer to their user
From: Andy Shevchenko @ 2026-05-04 6:58 UTC (permalink / raw)
To: Peng Fan, linux-can, linux-phy, linux-kernel
Cc: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
Josua Mayer, Ulf Hansson, Andy Shevchenko
In-Reply-To: <20260504070054.29508-1-andriy.shevchenko@linux.intel.com>
There is no code that uses ID table directly, except the
struct device_driver at the end of the file. Hence, move
table closer to its user. It's always possible to access
them via a pointer.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/phy/phy-can-transceiver.c | 58 +++++++++++++++----------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 80eece74f77d..8411d36b463b 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -97,35 +97,6 @@ static const struct can_transceiver_data tja1057_drvdata = {
.flags = CAN_TRANSCEIVER_SILENT_PRESENT,
};
-static const struct of_device_id can_transceiver_phy_ids[] = {
- {
- .compatible = "ti,tcan1042",
- .data = &tcan1042_drvdata
- },
- {
- .compatible = "ti,tcan1043",
- .data = &tcan1043_drvdata
- },
- {
- .compatible = "nxp,tja1048",
- .data = &tja1048_drvdata
- },
- {
- .compatible = "nxp,tja1051",
- .data = &tja1051_drvdata
- },
- {
- .compatible = "nxp,tja1057",
- .data = &tja1057_drvdata
- },
- {
- .compatible = "nxp,tjr1443",
- .data = &tcan1043_drvdata
- },
- { }
-};
-MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
-
static struct phy *can_transceiver_phy_xlate(struct device *dev,
const struct of_phandle_args *args)
{
@@ -229,6 +200,35 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
return PTR_ERR_OR_ZERO(phy_provider);
}
+static const struct of_device_id can_transceiver_phy_ids[] = {
+ {
+ .compatible = "ti,tcan1042",
+ .data = &tcan1042_drvdata
+ },
+ {
+ .compatible = "ti,tcan1043",
+ .data = &tcan1043_drvdata
+ },
+ {
+ .compatible = "nxp,tja1048",
+ .data = &tja1048_drvdata
+ },
+ {
+ .compatible = "nxp,tja1051",
+ .data = &tja1051_drvdata
+ },
+ {
+ .compatible = "nxp,tja1057",
+ .data = &tja1057_drvdata
+ },
+ {
+ .compatible = "nxp,tjr1443",
+ .data = &tcan1043_drvdata
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, can_transceiver_phy_ids);
+
static struct platform_driver can_transceiver_phy_driver = {
.probe = can_transceiver_phy_probe,
.driver = {
--
2.50.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 3/4] phy: phy-can-transceiver: Don't check for specific errors when parsing properties
From: Andy Shevchenko @ 2026-05-04 6:58 UTC (permalink / raw)
To: Peng Fan, linux-can, linux-phy, linux-kernel
Cc: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
Josua Mayer, Ulf Hansson, Andy Shevchenko
In-Reply-To: <20260504070054.29508-1-andriy.shevchenko@linux.intel.com>
Instead of checking for the specific error codes (that can be considered
a layering violation to some extent) check for the property existence first
and then either parse it, or apply a default value.
With that, return an error when parsing of the existing property fails.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/phy/phy-can-transceiver.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 8411d36b463b..238c7963724b 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -128,8 +128,9 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
struct gpio_desc *standby_gpio;
struct gpio_desc *enable_gpio;
struct mux_state *mux_state;
- u32 max_bitrate = 0;
int err, i, num_ch = 1;
+ const char *propname;
+ u32 max_bitrate;
drvdata = device_get_match_data(dev);
if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
@@ -148,8 +149,15 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
priv->mux_state = mux_state;
- err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
- if ((err != -EINVAL) && !max_bitrate)
+ propname = "max-bitrate";
+ if (device_property_present(dev, propname)) {
+ err = device_property_read_u32(dev, propname, &max_bitrate);
+ if (err)
+ return dev_err_probe(dev, err, "failed to parse %s\n", propname);
+ } else {
+ max_bitrate = 0;
+ }
+ if (max_bitrate == 0)
dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
for (i = 0; i < num_ch; i++) {
--
2.50.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 1/4] phy: phy-can-transceiver: use device_get_match_data()
From: Andy Shevchenko @ 2026-05-04 6:58 UTC (permalink / raw)
To: Peng Fan, linux-can, linux-phy, linux-kernel
Cc: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
Josua Mayer, Ulf Hansson, Andy Shevchenko
In-Reply-To: <20260504070054.29508-1-andriy.shevchenko@linux.intel.com>
Use the generic firmware node interface for retrieving
device match data instead of the OF-specific one.
While at it, drop unneeded argument to devm_phy_create() which
extracts device node from the given device by default.
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/phy/phy-can-transceiver.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 2b52e47f247a..80eece74f77d 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -5,9 +5,9 @@
* Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com
*
*/
-#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
@@ -152,7 +152,6 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
struct can_transceiver_phy *can_transceiver_phy;
struct can_transceiver_priv *priv;
const struct can_transceiver_data *drvdata;
- const struct of_device_id *match;
struct phy *phy;
struct gpio_desc *silent_gpio;
struct gpio_desc *standby_gpio;
@@ -161,8 +160,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
u32 max_bitrate = 0;
int err, i, num_ch = 1;
- match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
- drvdata = match->data;
+ drvdata = device_get_match_data(dev);
if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
num_ch = 2;
@@ -187,7 +185,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
can_transceiver_phy = &priv->can_transceiver_phy[i];
can_transceiver_phy->priv = priv;
- phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
+ phy = devm_phy_create(dev, NULL, &can_transceiver_phy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create can transceiver phy\n");
return PTR_ERR(phy);
--
2.50.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 0/4] phy: phy-can-transceiver: Ad-hoc cleanups and refactoring
From: Andy Shevchenko @ 2026-05-04 6:58 UTC (permalink / raw)
To: Peng Fan, linux-can, linux-phy, linux-kernel
Cc: Marc Kleine-Budde, Vincent Mailhol, Vinod Koul, Neil Armstrong,
Josua Mayer, Ulf Hansson, Andy Shevchenko
The driver does two things that need to be addressed:
- includes subject to remove gpio.h
- checks for error code from device property APIs when it can be done in
a robust way
This series addresses the above and adds a couple of additional refactoring.
Changelog v3:
- fixed commit message in patch 1 (Josua)
- dropped stray change (Vinod)
- collected tags (Josua)
v2: 20260317203001.2108568-1-andriy.shevchenko@linux.intel.com
Changelog v2:
- rebased on top of the latest changes in the driver
- Cc'ed to Ulf and Josua due to above
- elaborated dropping of_node parameter (Vladimir)
v1: 20260219202910.2304440-1-andriy.shevchenko@linux.intel.com
Andy Shevchenko (4):
phy: phy-can-transceiver: use device_get_match_data()
phy: phy-can-transceiver: Move OF ID table closer to their user
phy: phy-can-transceiver: Don't check for specific errors when parsing
properties
phy: phy-can-transceiver: Drop unused include
drivers/phy/phy-can-transceiver.c | 83 ++++++++++++++++---------------
1 file changed, 44 insertions(+), 39 deletions(-)
--
2.50.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 0/4] phy: phy-can-transceiver: Ad-hoc cleanups and refactoring
From: Andy Shevchenko @ 2026-05-04 6:58 UTC (permalink / raw)
To: Josua Mayer
Cc: linux-can@vger.kernel.org, linux-phy@lists.infradead.org,
linux-kernel@vger.kernel.org, Marc Kleine-Budde, Vincent Mailhol,
Vinod Koul, Neil Armstrong, Ulf Hansson
In-Reply-To: <ae-AJdSrnXiuc1mW@ashevche-desk.local>
On Mon, Apr 27, 2026 at 06:26:34PM +0300, Andy Shevchenko wrote:
> On Mon, Apr 27, 2026 at 01:41:43PM +0000, Josua Mayer wrote:
> > Am 27.04.26 um 15:34 schrieb Andy Shevchenko:
> > > On Mon, Apr 27, 2026 at 11:09:48AM +0000, Josua Mayer wrote:
> > >> Am 14.04.26 um 20:43 schrieb Andy Shevchenko:
> > >>> On Tue, Mar 17, 2026 at 09:27:26PM +0100, Andy Shevchenko wrote:
...
> > >> For unknown reason your patch-set did not arrive in my inbox.
> > >> Perhaps it went missing for others, too?
> > > Are you in the MAINTAINERS for this part of the kernel?
> > > The CAN NETWORK DRIVERS and GENERIC PHY FRAMEWORK do not list your name.
> > Correct. I touched can phy once related to mux only.
> > > If you think of mail delivery in general, it's delivered at least to the ML
> > > https://lore.kernel.org/all/20260317203001.2108568-1-andriy.shevchenko@linux.intel.com/
> > >
> > > TBH I don't know what to answer to your question as I don't know your expectations and
> > > how it should be fulfilled taking into account my above question...
> >
> > Changelog v2:
> > - Cc'ed to Ulf and Josua due to above
> >
> > This is why I expected it in my inbox.
> > Usually in this situation I blame my provider.
>
> Ah, blame me then. I most likely missed to add your name to the Cc list.
Hmm... I have checked and your address is in the Cc for the whole series,
so I withdraw that I admit earlier that problem is on my side. Please, check
if everything fine on yours. Note, I'm about to send a v3.
> > > But thanks for the reviewing! I will address the commit message in v3.
> > Great!
>
> And will try hard to make sure your address will be in the Cc list.
--
With Best Regards,
Andy Shevchenko
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v2] phy: tegra: xusb: Fix per-pad high-speed termination calibration
From: Wei-Cheng Chen @ 2026-05-04 3:33 UTC (permalink / raw)
To: Vinod Koul, Jonathan Hunter, JC Kuo, Neil Armstrong,
Thierry Reding
Cc: Wayne Chang, WK Tsai, linux-phy, linux-tegra, linux-kernel
From: Wayne Chang <waynec@nvidia.com>
The existing code reads a single hs_term_range_adj value from bit field
[10:7] of FUSE_SKU_CALIB_0 and applies it to all USB2 pads uniformly.
However, on SoCs that support per-pad termination, each pad has its own
hs_term_range_adj field: pad 0 in FUSE_SKU_CALIB_0[10:7], and pads 1-3
in FUSE_USB_CALIB_EXT_0 at bit offsets [8:5], [12:9], and [16:13]
respectively.
Fix the calibration by reading per-pad values from the appropriate fuse
registers. For SoCs that do not support per-pad termination, replicate
pad 0's value to all pads to maintain existing behavior.
Add a has_per_pad_term flag to the SoC data to indicate whether per-pad
termination values are available in FUSE_USB_CALIB_EXT_0.
Fixes: 1ef535c6ba8e ("phy: tegra: xusb: Add Tegra194 support")
Cc: stable@vger.kernel.org
Signed-off-by: Wayne Chang <waynec@nvidia.com>
Signed-off-by: Wei-Cheng Chen <weichengc@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
---
Changes in v2:
- Rebased on v7.1-rc1 per Vinod's request. No functional changes;
range-diff vs v1 confirms identical payload.
- Carried over Jon's Reviewed-by and Tested-by tags from v1
(https://lore.kernel.org/all/77285dd6-e240-4944-a034-a4bc3acf4052@nvidia.com/).
drivers/phy/tegra/xusb-tegra186.c | 33 ++++++++++++++++++++++++-------
drivers/phy/tegra/xusb.h | 1 +
2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index 1ddf1126597..60156aea270 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -20,8 +20,8 @@
/* FUSE USB_CALIB registers */
#define HS_CURR_LEVEL_PADX_SHIFT(x) ((x) ? (11 + (x - 1) * 6) : 0)
#define HS_CURR_LEVEL_PAD_MASK 0x3f
-#define HS_TERM_RANGE_ADJ_SHIFT 7
-#define HS_TERM_RANGE_ADJ_MASK 0xf
+#define HS_TERM_RANGE_ADJ_PADX_SHIFT(x) ((x) ? (5 + (x - 1) * 4) : 7)
+#define HS_TERM_RANGE_ADJ_PAD_MASK 0xf
#define HS_SQUELCH_SHIFT 29
#define HS_SQUELCH_MASK 0x7
@@ -253,7 +253,7 @@
struct tegra_xusb_fuse_calibration {
u32 *hs_curr_level;
u32 hs_squelch;
- u32 hs_term_range_adj;
+ u32 *hs_term_range_adj;
u32 rpd_ctrl;
};
@@ -930,7 +930,7 @@ static int tegra186_utmi_phy_power_on(struct phy *phy)
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
value &= ~TERM_RANGE_ADJ(~0);
- value |= TERM_RANGE_ADJ(priv->calib.hs_term_range_adj);
+ value |= TERM_RANGE_ADJ(priv->calib.hs_term_range_adj[index]);
value &= ~RPD_CTRL(~0);
value |= RPD_CTRL(priv->calib.rpd_ctrl);
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
@@ -1464,17 +1464,23 @@ static const char * const tegra186_usb3_functions[] = {
static int
tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
{
+ const struct tegra_xusb_padctl_soc *soc = padctl->base.soc;
struct device *dev = padctl->base.dev;
unsigned int i, count;
u32 value, *level;
+ u32 *hs_term_range_adj;
int err;
- count = padctl->base.soc->ports.usb2.count;
+ count = soc->ports.usb2.count;
level = devm_kcalloc(dev, count, sizeof(u32), GFP_KERNEL);
if (!level)
return -ENOMEM;
+ hs_term_range_adj = devm_kcalloc(dev, count, sizeof(u32), GFP_KERNEL);
+ if (!hs_term_range_adj)
+ return -ENOMEM;
+
err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value);
if (err)
return dev_err_probe(dev, err,
@@ -1490,8 +1496,8 @@ tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
padctl->calib.hs_squelch = (value >> HS_SQUELCH_SHIFT) &
HS_SQUELCH_MASK;
- padctl->calib.hs_term_range_adj = (value >> HS_TERM_RANGE_ADJ_SHIFT) &
- HS_TERM_RANGE_ADJ_MASK;
+ hs_term_range_adj[0] = (value >> HS_TERM_RANGE_ADJ_PADX_SHIFT(0)) &
+ HS_TERM_RANGE_ADJ_PAD_MASK;
err = tegra_fuse_readl(TEGRA_FUSE_USB_CALIB_EXT_0, &value);
if (err) {
@@ -1503,6 +1509,17 @@ tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
padctl->calib.rpd_ctrl = (value >> RPD_CTRL_SHIFT) & RPD_CTRL_MASK;
+ for (i = 1; i < count; i++) {
+ if (soc->has_per_pad_term)
+ hs_term_range_adj[i] =
+ (value >> HS_TERM_RANGE_ADJ_PADX_SHIFT(i)) &
+ HS_TERM_RANGE_ADJ_PAD_MASK;
+ else
+ hs_term_range_adj[i] = hs_term_range_adj[0];
+ }
+
+ padctl->calib.hs_term_range_adj = hs_term_range_adj;
+
return 0;
}
@@ -1708,6 +1725,7 @@ const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc = {
.num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
.supports_gen2 = true,
.poll_trk_completed = true,
+ .has_per_pad_term = true,
};
EXPORT_SYMBOL_GPL(tegra194_xusb_padctl_soc);
@@ -1732,6 +1750,7 @@ const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = {
.trk_hw_mode = false,
.trk_update_on_idle = true,
.supports_lp_cfg_en = true,
+ .has_per_pad_term = true,
};
EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc);
#endif
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index cd277d0ed9e..77609e54de6 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -435,6 +435,7 @@ struct tegra_xusb_padctl_soc {
bool trk_hw_mode;
bool trk_update_on_idle;
bool supports_lp_cfg_en;
+ bool has_per_pad_term;
};
struct tegra_xusb_padctl {
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RESEND v3 2/4] phy: axiado: add Axiado eMMC PHY driver
From: Tzu-Hao Wei @ 2026-05-04 1:38 UTC (permalink / raw)
To: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, openbmc,
Tzu-Hao Wei
In-Reply-To: <20260504-axiado-ax3000-add-emmc-phy-driver-support-v3-0-3ab7eb45b0c5@axiado.com>
From: SriNavmani A <srinavmani@axiado.com>
It provides the required configurations for Axiado eMMC PHY driver for
HS200 mode.
Signed-off-by: SriNavmani A <srinavmani@axiado.com>
Co-developed-by: Prasad Bolisetty <pbolisetty@axiado.com>
Signed-off-by: Prasad Bolisetty <pbolisetty@axiado.com>
Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
---
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/axiado/Kconfig | 11 ++
drivers/phy/axiado/Makefile | 1 +
drivers/phy/axiado/phy-axiado-emmc.c | 217 +++++++++++++++++++++++++++++++++++
5 files changed, 231 insertions(+)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 678dd0452f0aa0597773433f04d2a9ba77474d2a..b802274ea45a84bd36d7c0b7fb90e368a5c018b4 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -103,6 +103,7 @@ config PHY_NXP_PTN3222
source "drivers/phy/allwinner/Kconfig"
source "drivers/phy/amlogic/Kconfig"
+source "drivers/phy/axiado/Kconfig"
source "drivers/phy/broadcom/Kconfig"
source "drivers/phy/cadence/Kconfig"
source "drivers/phy/freescale/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index bfb27fb5a494283d7fd05dd670ebd1b12df8b1a1..f1b9e4a8673bcde3fdc0fdc06a3deddb5785ced1 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o
obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
obj-y += allwinner/ \
amlogic/ \
+ axiado/ \
broadcom/ \
cadence/ \
freescale/ \
diff --git a/drivers/phy/axiado/Kconfig b/drivers/phy/axiado/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..d159e0345345987c7f48dcd12d3237997735d2b5
--- /dev/null
+++ b/drivers/phy/axiado/Kconfig
@@ -0,0 +1,11 @@
+#
+# PHY drivers for Axiado platforms
+#
+
+config PHY_AX3000_EMMC
+ tristate "Axiado eMMC PHY driver"
+ depends on OF && (ARCH_AXIADO || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ Enables this to support for the AX3000 EMMC PHY driver.
+ If unsure, say N.
diff --git a/drivers/phy/axiado/Makefile b/drivers/phy/axiado/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1e2b1ba016092eaffdbd7acbd9cdc8577d79b35c
--- /dev/null
+++ b/drivers/phy/axiado/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PHY_AX3000_EMMC) += phy-axiado-emmc.o
diff --git a/drivers/phy/axiado/phy-axiado-emmc.c b/drivers/phy/axiado/phy-axiado-emmc.c
new file mode 100644
index 0000000000000000000000000000000000000000..e0e2174776ad027df0a10a8c4741b1b4ef9ef40e
--- /dev/null
+++ b/drivers/phy/axiado/phy-axiado-emmc.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Axiado eMMC PHY driver
+ *
+ * Copyright (C) 2017 Arasan Chip Systems Inc.
+ * Copyright (C) 2022-2026 Axiado Corporation (or its affiliates).
+ *
+ * Based on Arasan Driver (sdhci-pci-arasan.c)
+ * sdhci-pci-arasan.c - Driver for Arasan PCI Controller with integrated phy.
+ */
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* Arasan eMMC 5.1 - PHY configuration registers */
+#define CAP_REG_IN_S1_MSB 0x04
+#define PHY_CTRL_1 0x38
+#define PHY_CTRL_2 0x3c
+#define PHY_CTRL_3 0x40
+#define STATUS 0x50
+
+#define DLL_ENBL BIT(26)
+#define RTRIM_EN BIT(21)
+#define PDB_ENBL BIT(23)
+#define RETB_ENBL BIT(1)
+
+#define REN_STRB BIT(27)
+#define REN_CMD_EN GENMASK(20, 12)
+
+/* Pull-UP Enable on CMD Line */
+#define PU_CMD_EN GENMASK(11, 3)
+
+/* Selection value for the optimum delay from 1-32 output tap lines */
+#define OTAP_DLY 0x02
+/* DLL charge pump current trim default [1000] */
+#define DLL_TRM_ICP 0x08
+/* Select the frequency range of DLL Operation */
+#define FRQ_SEL 0x01
+
+#define OTAP_SEL_MASK GENMASK(10, 7)
+#define DLL_TRM_MASK GENMASK(25, 22)
+#define DLL_FRQSEL_MASK GENMASK(27, 25)
+
+#define OTAP_SEL(x) (FIELD_PREP(OTAP_SEL_MASK, x) | OTAPDLY_EN)
+#define DLL_TRM(x) (FIELD_PREP(DLL_TRM_MASK, x) | DLL_ENBL)
+#define DLL_FRQSEL(x) FIELD_PREP(DLL_FRQSEL_MASK, x)
+
+#define OTAPDLY_EN BIT(11)
+
+#define SEL_DLY_RXCLK BIT(18)
+#define SEL_DLY_TXCLK BIT(19)
+
+#define CALDONE_MASK 0x40
+#define DLL_RDY_MASK 0x1
+#define MAX_CLK_BUF0 BIT(20)
+#define MAX_CLK_BUF1 BIT(21)
+#define MAX_CLK_BUF2 BIT(22)
+
+#define CLK_MULTIPLIER 0xc008e
+#define POLL_TIMEOUT_MS 3000
+#define POLL_DELAY_US 100
+
+struct axiado_emmc_phy {
+ void __iomem *reg_base;
+ struct device *dev;
+};
+
+static int axiado_emmc_phy_init(struct phy *phy)
+{
+ struct axiado_emmc_phy *ax_phy = phy_get_drvdata(phy);
+ struct device *dev = ax_phy->dev;
+ u32 val;
+ int ret;
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_1);
+ writel(val | RETB_ENBL | RTRIM_EN, ax_phy->reg_base + PHY_CTRL_1);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_3);
+ writel(val | PDB_ENBL, ax_phy->reg_base + PHY_CTRL_3);
+
+ ret = readl_poll_timeout(ax_phy->reg_base + STATUS, val,
+ val & CALDONE_MASK, POLL_DELAY_US,
+ POLL_TIMEOUT_MS * 1000);
+ if (ret) {
+ dev_err(dev, "PHY calibration timeout\n");
+ return ret;
+ }
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_1);
+ writel(val | REN_CMD_EN | PU_CMD_EN, ax_phy->reg_base + PHY_CTRL_1);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_2);
+ writel(val | REN_STRB, ax_phy->reg_base + PHY_CTRL_2);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_3);
+ writel(val | MAX_CLK_BUF0 | MAX_CLK_BUF1 | MAX_CLK_BUF2,
+ ax_phy->reg_base + PHY_CTRL_3);
+
+ writel(CLK_MULTIPLIER, ax_phy->reg_base + CAP_REG_IN_S1_MSB);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_3);
+ writel(val | SEL_DLY_RXCLK | SEL_DLY_TXCLK,
+ ax_phy->reg_base + PHY_CTRL_3);
+
+ return 0;
+}
+
+static int axiado_emmc_phy_power_on(struct phy *phy)
+{
+ struct axiado_emmc_phy *ax_phy = phy_get_drvdata(phy);
+ struct device *dev = ax_phy->dev;
+ u32 val;
+ int ret;
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_1);
+ writel(val | RETB_ENBL, ax_phy->reg_base + PHY_CTRL_1);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_3);
+ writel(val | PDB_ENBL, ax_phy->reg_base + PHY_CTRL_3);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_2);
+ writel(val | OTAP_SEL(OTAP_DLY), ax_phy->reg_base + PHY_CTRL_2);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_1);
+ writel(val | DLL_TRM(DLL_TRM_ICP), ax_phy->reg_base + PHY_CTRL_1);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_3);
+ writel(val | DLL_FRQSEL(FRQ_SEL), ax_phy->reg_base + PHY_CTRL_3);
+
+ ret = read_poll_timeout(readl, val, val & DLL_RDY_MASK, POLL_DELAY_US,
+ POLL_TIMEOUT_MS * 1000, false,
+ ax_phy->reg_base + STATUS);
+ if (ret) {
+ dev_err(dev, "DLL ready timeout\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int axiado_emmc_phy_power_off(struct phy *phy)
+{
+ struct axiado_emmc_phy *ax_phy = phy_get_drvdata(phy);
+ u32 val;
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_1);
+ val &= ~(DLL_TRM_MASK | DLL_ENBL);
+ writel(val, ax_phy->reg_base + PHY_CTRL_1);
+
+ val = readl(ax_phy->reg_base + PHY_CTRL_3);
+ val &= ~(DLL_FRQSEL_MASK | PDB_ENBL);
+ writel(val, ax_phy->reg_base + PHY_CTRL_3);
+
+ return 0;
+}
+
+static const struct phy_ops axiado_emmc_phy_ops = {
+ .init = axiado_emmc_phy_init,
+ .power_on = axiado_emmc_phy_power_on,
+ .power_off = axiado_emmc_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static const struct of_device_id axiado_emmc_phy_of_match[] = {
+ { .compatible = "axiado,ax3000-emmc-phy" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, axiado_emmc_phy_of_match);
+
+static int axiado_emmc_phy_probe(struct platform_device *pdev)
+{
+ struct axiado_emmc_phy *ax_phy;
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct phy *generic_phy;
+
+ if (!dev->of_node)
+ return -ENODEV;
+
+ ax_phy = devm_kzalloc(dev, sizeof(*ax_phy), GFP_KERNEL);
+ if (!ax_phy)
+ return -ENOMEM;
+
+ ax_phy->reg_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ax_phy->reg_base))
+ return PTR_ERR(ax_phy->reg_base);
+
+ ax_phy->dev = dev;
+
+ generic_phy = devm_phy_create(dev, dev->of_node, &axiado_emmc_phy_ops);
+ if (IS_ERR(generic_phy))
+ return dev_err_probe(dev, PTR_ERR(generic_phy),
+ "failed to create PHY\n");
+
+ phy_set_drvdata(generic_phy, ax_phy);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver axiado_emmc_phy_driver = {
+ .probe = axiado_emmc_phy_probe,
+ .driver = {
+ .name = "axiado-emmc-phy",
+ .of_match_table = axiado_emmc_phy_of_match,
+ },
+};
+module_platform_driver(axiado_emmc_phy_driver);
+
+MODULE_DESCRIPTION("AX3000 eMMC PHY Driver");
+MODULE_AUTHOR("Axiado Corporation");
+MODULE_LICENSE("GPL");
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RESEND v3 0/4] Add eMMC PHY support for Axiado AX3000 SoC
From: Tzu-Hao Wei @ 2026-05-04 1:38 UTC (permalink / raw)
To: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, openbmc,
Tzu-Hao Wei
Axiado AX3000 SoC contains Arasan PHY which provides the interface to the
HS200 eMMC controller.
This series includes:
1. Add bindings for Axiado AX3000 eMMC PHY
2. Add Axiado AX3000 eMMC phy driver
3. Update MAINTAINERS for the new driver
4. Update Axiado AX3000 device tree
Changes in v3:
- Update year to 2026
- Use lowercase for addresses
- Remove redundant macros and use GENMASK
- Implement power_off function
- Link to v2: https://lore.kernel.org/r/20260206-axiado-ax3000-add-emmc-phy-driver-support-v2-0-a2f59e97a92d@axiado.com
Changes in v2:
- Fix dt-binding format
- Fix compilation error in m68k
- Use readl_poll_timeout instead of read_poll_timeout
- Link to v1: https://lore.kernel.org/r/20260109-axiado-ax3000-add-emmc-phy-driver-support-v1-0-dd43459dbfea@axiado.com
Changes: (The previous version was mixed with Host driver, so I separate
the PHY driver as a new thread)
- Fix property order in required section to match properties section
- Fixed example to use lowercase hex and proper node naming
- Removed wrapper functions, use readl/writel directly
- Replaced manual polling loops with read_poll_timeout macro
- Used devm_platform_ioremap_resource instead of separate calls
- Removed unnecessary of_match_node check
- Used dev_err_probe for error reporting
- Added proper Kconfig dependencies (ARCH_AXIADO || COMPILE_TEST)
- Fixed various coding style issues
- Link to previous patches: https://lore.kernel.org/all/20251222-axiado-ax3000-add-emmc-host-driver-support-v1-0-5457d0ebcdb4@axiado.com/
Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
---
SriNavmani A (3):
dt-bindings: phy: axiado,ax3000-emmc-phy: add Axiado eMMC PHY
phy: axiado: add Axiado eMMC PHY driver
arm64: dts: axiado: Add eMMC PHY node
Tzu-Hao Wei (1):
MAINTAINERS: Add Axiado AX3000 eMMC PHY driver
.../bindings/phy/axiado,ax3000-emmc-phy.yaml | 37 ++++
MAINTAINERS | 10 +
arch/arm64/boot/dts/axiado/ax3000.dtsi | 7 +
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/axiado/Kconfig | 11 ++
drivers/phy/axiado/Makefile | 1 +
drivers/phy/axiado/phy-axiado-emmc.c | 217 +++++++++++++++++++++
8 files changed, 285 insertions(+)
---
base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
change-id: 20260108-axiado-ax3000-add-emmc-phy-driver-support-d61aead8f622
Best regards,
--
Tzu-Hao Wei <twei@axiado.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH RESEND v3 1/4] dt-bindings: phy: axiado,ax3000-emmc-phy: add Axiado eMMC PHY
From: Tzu-Hao Wei @ 2026-05-04 1:38 UTC (permalink / raw)
To: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, openbmc,
Tzu-Hao Wei
In-Reply-To: <20260504-axiado-ax3000-add-emmc-phy-driver-support-v3-0-3ab7eb45b0c5@axiado.com>
From: SriNavmani A <srinavmani@axiado.com>
Axiado AX3000 SoC contains Arasan PHY which provides the interface to the
HS200 eMMC host controller.
Signed-off-by: SriNavmani A <srinavmani@axiado.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
---
.../bindings/phy/axiado,ax3000-emmc-phy.yaml | 37 ++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml b/Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..61700b80e93f7185e16ca9eab0922fe6bb29fe86
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/axiado,ax3000-emmc-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Axiado AX3000 Arasan eMMC PHY
+
+maintainers:
+ - SriNavmani A <srinavmani@axiado.com>
+ - Tzu-Hao Wei <twei@axiado.com>
+ - Prasad Bolisetty <pbolisetty@axiado.com>
+
+properties:
+ compatible:
+ const: axiado,ax3000-emmc-phy
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ phy@80801c00 {
+ compatible = "axiado,ax3000-emmc-phy";
+ reg = <0x80801c00 0x1000>;
+ #phy-cells = <0>;
+ };
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RESEND v3 3/4] MAINTAINERS: Add Axiado AX3000 eMMC PHY driver
From: Tzu-Hao Wei @ 2026-05-04 1:38 UTC (permalink / raw)
To: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, openbmc,
Tzu-Hao Wei
In-Reply-To: <20260504-axiado-ax3000-add-emmc-phy-driver-support-v3-0-3ab7eb45b0c5@axiado.com>
Add SriNavmani, Prasad and me as maintainers for Axiado AX3000 eMMC PHY
driver
Acked-by: Prasad Bolisetty <pbolisetty@axiado.com>
Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
---
MAINTAINERS | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 67db88b04537b431c927b73624993233eef43e3f..c33b0aa94de81c89b674e44d4813c4e3b95b7b2d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4254,6 +4254,16 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
F: drivers/hwmon/axi-fan-control.c
+AXIADO EMMC PHY DRIVER
+M: SriNavmani A <srinavmani@axiado.com>
+M: Tzu-Hao Wei <twei@axiado.com>
+M: Prasad Bolisetty <pbolisetty@axiado.com>
+L: linux-phy@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml
+F: drivers/phy/axiado/Kconfig
+F: drivers/phy/axiado/phy-axiado-emmc.c
+
AXI SPI ENGINE
M: Michael Hennerich <michael.hennerich@analog.com>
M: Nuno Sá <nuno.sa@analog.com>
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH RESEND v3 4/4] arm64: dts: axiado: Add eMMC PHY node
From: Tzu-Hao Wei @ 2026-05-04 1:38 UTC (permalink / raw)
To: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, openbmc,
Tzu-Hao Wei
In-Reply-To: <20260504-axiado-ax3000-add-emmc-phy-driver-support-v3-0-3ab7eb45b0c5@axiado.com>
From: SriNavmani A <srinavmani@axiado.com>
Add the eMMC PHY device tree node to the AX3000 SoC DTSI.
AX3000 has one eMMC PHY interface.
Signed-off-by: SriNavmani A <srinavmani@axiado.com>
Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
---
arch/arm64/boot/dts/axiado/ax3000.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/axiado/ax3000.dtsi b/arch/arm64/boot/dts/axiado/ax3000.dtsi
index 792f52e0c7dd42cbc54b0eb47e25b0fbf1a706b8..ccc8088bd8258cfb666268b14a3b0716a9ca69f4 100644
--- a/arch/arm64/boot/dts/axiado/ax3000.dtsi
+++ b/arch/arm64/boot/dts/axiado/ax3000.dtsi
@@ -507,6 +507,13 @@ uart3: serial@80520800 {
clocks = <&refclk &refclk>;
status = "disabled";
};
+
+ emmc_phy: phy@80801c00 {
+ compatible = "axiado,ax3000-emmc-phy";
+ reg = <0x0 0x80801c00 0x0 0x1000>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
};
timer {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v4 00/16] phy: rockchip: usbdp: Fixes, DP 1-lane support and cleanups
From: Heiko Stuebner @ 2026-05-03 19:12 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul
Cc: Neil Armstrong, Frank Wang, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Yan, Dmitry Baryshkov, Yubing Zhang,
Alexey Charkov, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, devicetree, William Wu
In-Reply-To: <afd8xMS2hz208Lcl@vaman>
Hi Vinod,
Am Sonntag, 3. Mai 2026, 18:50:12 Mitteleuropäische Sommerzeit schrieb Vinod Koul:
> Hi Sebastian,
>
> On 28-04-26, 18:13, Sebastian Reichel wrote:
> > This series overhauls the Rockchip USBDP driver; apart from a
> > a bunch of cleanups and small improvements the main goal is to
> > get the driver ready for proper USB-C DP AltMode support.
> >
> > Once this series has landed, it unblocks enabling proper USB-C
> > DP AltMode on the RK3588 and RK3576 platforms incl. runtime PM
> > for the Synopsys DesignWare DisplayPort controller.
> >
> > Apart from this series, further changes are required on the
> > DRM side. There are no compile-time dependencies between the
> > DRM side and the PHY side, but the PHY side must be applied
> > to avoid SErrors once runtime PM is added to the DisplayPort
> > controller driver. Thus it would be really good to land this
> > series in the next merge window.
>
> Looks like sasiko has flagged 8 high warning, can you please check them
(1) as mentioned in a different patch thread, review should be happening
on the lists. Tools regularly dump old results, so anyone looking at the
mailinglist thread might now be able to follow along with what happened
in 2 months or so.
Also other robot tools can reply on the lists just fine.
(2) if 1. is so hugely impossible, please at least provide some reference
to what you mean. Not everybody knows all the hype-tools-of-the-week and
simply searching for that mysterious "sasiko" [0] did not provide any
meaningful results for me, despite some amazon or youtube links for some
non-kernel uses of that term ;-)
So a link should be present at least please.
Thanks
Heiko
[0] https://duckduckgo.com/?q=%22sasiko%22
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH] phy: rockchip: inno-hdmi: Change TMDS rate handling to configure() ops
From: Jonas Karlman @ 2026-05-03 17:29 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner
Cc: Jonas Karlman, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel
The commit 10ed34d6eaaf ("phy: Add HDMI configuration options")
introduced a way for HDMI PHYs to be configured through the generic
phy_configure() function.
This driver currently derives the TMDS character rate from the pixel
clock and the PHY bus width setting. However, no in-tree consumer of
this PHY has ever called phy_set_bus_width() to change the TMDS rate.
Change the TMDS character rate handling to depend on the configure() ops
before any PHY consumer needs to configure a TMDS character rate that is
different from the pixel clock rate.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
A near future drm/rockchip: dw_hdmi: series plans to include a call to
phy_configure() to configure this HDMI PHYs TMDS character rate.
---
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 30 ++++++++++---------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 1483907413fa..7f0563d4d482 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -245,6 +245,7 @@ struct inno_hdmi_phy {
struct clk *phyclk;
unsigned long pixclock;
unsigned long tmdsclock;
+ struct phy_configure_opts_hdmi hdmi_cfg;
};
struct pre_pll_config {
@@ -554,19 +555,10 @@ static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
unsigned long rate)
{
- int bus_width = phy_get_bus_width(inno->phy);
-
- switch (bus_width) {
- case 4:
- case 5:
- case 6:
- case 10:
- case 12:
- case 16:
- return (u64)rate * bus_width / 8;
- default:
- return rate;
- }
+ if (inno->hdmi_cfg.tmds_char_rate)
+ return inno->hdmi_cfg.tmds_char_rate;
+
+ return rate;
}
static irqreturn_t inno_hdmi_phy_rk3328_hardirq(int irq, void *dev_id)
@@ -602,6 +594,16 @@ static irqreturn_t inno_hdmi_phy_rk3328_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int inno_hdmi_phy_configure(struct phy *phy,
+ union phy_configure_opts *opts)
+{
+ struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
+
+ inno->hdmi_cfg = opts->hdmi;
+
+ return 0;
+}
+
static int inno_hdmi_phy_power_on(struct phy *phy)
{
struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
@@ -668,6 +670,7 @@ static int inno_hdmi_phy_power_off(struct phy *phy)
static const struct phy_ops inno_hdmi_phy_ops = {
.owner = THIS_MODULE,
+ .configure = inno_hdmi_phy_configure,
.power_on = inno_hdmi_phy_power_on,
.power_off = inno_hdmi_phy_power_off,
};
@@ -1392,7 +1395,6 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev)
}
phy_set_drvdata(inno->phy, inno);
- phy_set_bus_width(inno->phy, 8);
if (inno->plat_data->ops->init) {
ret = inno->plat_data->ops->init(inno);
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox