* [PATCH v7 phy-next 20/27] media: sunxi: a83-mips-csi2: include PHY provider header
From: Vladimir Oltean @ 2026-04-30 11:06 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, Chen-Yu Tsai, Mauro Carvalho Chehab,
Jernej Skrabec, Samuel Holland
In-Reply-To: <20260430110652.558622-1-vladimir.oltean@nxp.com>
The introduction commit 576d196c522b ("media: sunxi: Add support for the
A83T MIPI CSI-2 controller") says:
This implementation splits the protocol and D-PHY registers and
uses the PHY framework internally. The D-PHY is not registered as a
standalone PHY driver since it cannot be used with any other
controller.
However, this does not matter, and is not the only instance of tight PHY
provider <-> consumer pairing. According to Vinod Koul, having PHY
provider drivers outside of drivers/phy/ is discouraged, although it
would be difficult for me to address a proper movement here.
So just include the private provider API header from drivers/phy/ and
leave a FIXME in place.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Chen-Yu Tsai <wens@kernel.org>
---
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Chen-Yu Tsai <wens@kernel.org>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Samuel Holland <samuel@sholland.org>
v4->v7: none
v3->v4: collect tag
v1->v3: none
---
.../media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c
index 24bbcc85013d..1143feeb4fcb 100644
--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c
+++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c
@@ -4,9 +4,9 @@
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+#include "../../../../phy/phy-provider.h" /* FIXME */
#include "sun8i_a83t_dphy.h"
#include "sun8i_a83t_mipi_csi2.h"
--
2.34.1
^ permalink raw reply related
* [PATCH v7 phy-next 21/27] net: renesas: rswitch: include PHY provider header
From: Vladimir Oltean @ 2026-04-30 11:06 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, Geert Uytterhoeven, Yoshihiro Shimoda,
Michael Dege, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Russell King (Oracle)
In-Reply-To: <20260430110652.558622-1-vladimir.oltean@nxp.com>
As a PHY consumer driver, the Renesas rswitch dereferences internal
fields of struct phy, something which shouldn't be done, as that is
going to be made an opaque pointer.
It is quite clearly visible that the driver is tightly coupled with the
drivers/phy/renesas/r8a779f0-ether-serdes.c, which puts heavy pressure
on the Generic PHY subsystem.
This was discussed before here:
https://lore.kernel.org/linux-phy/20260211194541.cdmibrpfn6ej6e74@skbuf/
but to summarize, it is generally expected that when a Generic PHY
function is called, it takes effect immediately. When this doesn't
happen, the PHY provider driver must change its implementation rather
than the consumer be made to work around it. PHY providers which rely on
a hardcoded call sequence in the consumer are just lazy and wrong.
The most obvious example is commit 5cb630925b49 ("net: renesas: rswitch:
Add phy_power_{on,off}() calling"). Problem description:
- Ethernet PHYs may change phydev->interface. When this happens, the
SerDes must learn of the new phydev->interface using phy_set_mode_ext().
- drivers/phy/renesas/r8a779f0-ether-serdes.c implements phy_set_mode_ext(),
but this only caches the mode and submode into channel->phy_interface
and applies this to hardware during phy_power_on().
The commit author decided to work around this at the consumer site, by
power cycling the PHY for the configuration to take effect.
This had a worse implication from an API perspective in subsequent
commit 053f13f67be6 ("rswitch: Fix imbalance phy_power_off() calling").
It was observed that phy_power_on() and phy_power_off() calls need to be
balanced, and so, the consumer decided to start looking at the struct
phy :: power_count (the technical reason why I'm making this change).
This is also wrong from an API perspective because
- a consumer should only care about its own vote on the PHY power state.
If this is a multi-port submode like QSGMII, a single phy_power_off()
call will not actually turn the PHY off (nor should it).
- the power_count is written under the &phy->mutex, but read unlocked
here.
The rswitch and r8a779f0-ether-serdes drivers both need to be completely
rethought in terms of Generic PHY API call sequence. There is no quick
fix to apply. Just include the PHY provider API along with the consumer
one, to keep working as before when struct phy will be made an opaque
pointer to normal PHY consumers. But this is a bad offender (and it's
not even a provider) so add a FIXME.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: Michael Dege <michael.dege@renesas.com>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
v2->v7: none
v1->v2: collect tag
---
drivers/net/ethernet/renesas/rswitch_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
index 6fe964816322..132be5f15073 100644
--- a/drivers/net/ethernet/renesas/rswitch_main.c
+++ b/drivers/net/ethernet/renesas/rswitch_main.c
@@ -27,6 +27,7 @@
#include <linux/spinlock.h>
#include <linux/sys_soc.h>
+#include "../../../phy/phy-provider.h" /* FIXME */
#include "rswitch.h"
#include "rswitch_l2.h"
--
2.34.1
^ permalink raw reply related
* [PATCH v7 phy-next 25/27] phy: include PHY provider header (2/2)
From: Vladimir Oltean @ 2026-04-30 11:06 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, Dmitry Baryshkov, Shawn Lin
In-Reply-To: <20260430110652.558622-1-vladimir.oltean@nxp.com>
The majority of PHY drivers are PHY providers (obviously).
Some are chained PHY provider+consumer (phy-qcom-m31-eusb2.c,
phy-exynos5-usbdrd.c).
Others include <linux/phy/phy.h> because they call consumer functions
such as phy_pm_runtime_get() - phy-mapphone-mdm6600.c. See commit
2ad2af081622 ("phy: mapphone-mdm6600: Improve phy related runtime PM
calls") for the story behind that. My understanding is it's a pragmatic
shortcut, but it doesn't bother much.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> #phy/qualcomm
Acked-by: Shawn Lin <shawn.lin@rock-chips.com>
---
v6->v7:
- manually resolved conflict in
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c with commit 4ff5801f45b4
("phy: qcom-sgmii-eth: add .set_mode() and .validate() methods"), now
present in linux-phy/next.
v4->v6: none
v3->v4:
- fix phy-provider.h path from drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c
- make sure include/linux/phy/tegra/xusb.h is not reliant upon an
external "struct phy" definition
v2->v3: none
v1->v2: split in two parts to pass through linux-phy mailing list
moderation. The split is at letter 'q' (Qualcomm)
---
drivers/phy/qualcomm/phy-ath79-usb.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-apq8064-sata.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-edp.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 ++
drivers/phy/qualcomm/phy-qcom-m31.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-pcie2.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 ++--
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 3 ++-
drivers/phy/qualcomm/phy-qcom-usb-ss.c | 3 ++-
drivers/phy/ralink/phy-mt7621-pci.c | 3 ++-
drivers/phy/ralink/phy-ralink-usb.c | 3 ++-
drivers/phy/realtek/phy-rtk-usb2.c | 3 ++-
drivers/phy/realtek/phy-rtk-usb3.c | 3 ++-
drivers/phy/renesas/phy-rcar-gen2.c | 3 ++-
drivers/phy/renesas/phy-rcar-gen3-pcie.c | 3 ++-
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 3 ++-
drivers/phy/renesas/phy-rcar-gen3-usb3.c | 3 ++-
drivers/phy/renesas/phy-rzg3e-usb3.c | 3 ++-
drivers/phy/renesas/r8a779f0-ether-serdes.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-dp.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-emmc.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-inno-csidphy.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 4 ++--
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 2 ++
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-pcie.c | 2 +-
drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 2 ++
drivers/phy/rockchip/phy-rockchip-snps-pcie3.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-typec.c | 4 ++--
drivers/phy/rockchip/phy-rockchip-usb.c | 3 ++-
drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 ++
drivers/phy/samsung/phy-exynos-dp-video.c | 3 ++-
drivers/phy/samsung/phy-exynos-mipi-video.c | 3 ++-
drivers/phy/samsung/phy-exynos-pcie.c | 3 ++-
drivers/phy/samsung/phy-exynos4210-usb2.c | 3 ++-
drivers/phy/samsung/phy-exynos4x12-usb2.c | 3 ++-
drivers/phy/samsung/phy-exynos5-usbdrd.c | 2 ++
drivers/phy/samsung/phy-exynos5250-sata.c | 3 ++-
drivers/phy/samsung/phy-exynos5250-usb2.c | 3 ++-
drivers/phy/samsung/phy-s5pv210-usb2.c | 3 ++-
drivers/phy/samsung/phy-samsung-ufs.c | 2 +-
drivers/phy/samsung/phy-samsung-ufs.h | 3 ++-
drivers/phy/samsung/phy-samsung-usb2.c | 2 ++
drivers/phy/samsung/phy-samsung-usb2.h | 3 ++-
drivers/phy/socionext/phy-uniphier-ahci.c | 3 ++-
drivers/phy/socionext/phy-uniphier-pcie.c | 3 ++-
drivers/phy/socionext/phy-uniphier-usb2.c | 3 ++-
drivers/phy/socionext/phy-uniphier-usb3hs.c | 3 ++-
drivers/phy/socionext/phy-uniphier-usb3ss.c | 3 ++-
drivers/phy/sophgo/phy-cv1800-usb2.c | 3 ++-
drivers/phy/spacemit/phy-k1-pcie.c | 4 ++--
drivers/phy/spacemit/phy-k1-usb2.c | 3 ++-
drivers/phy/st/phy-miphy28lp.c | 4 ++--
drivers/phy/st/phy-spear1310-miphy.c | 3 ++-
drivers/phy/st/phy-spear1340-miphy.c | 3 ++-
drivers/phy/st/phy-stih407-usb.c | 3 ++-
drivers/phy/st/phy-stm32-combophy.c | 3 ++-
drivers/phy/st/phy-stm32-usbphyc.c | 2 ++
drivers/phy/starfive/phy-jh7110-dphy-rx.c | 3 ++-
drivers/phy/starfive/phy-jh7110-dphy-tx.c | 3 ++-
drivers/phy/starfive/phy-jh7110-pcie.c | 3 ++-
drivers/phy/starfive/phy-jh7110-usb.c | 3 ++-
drivers/phy/sunplus/phy-sunplus-usb2.c | 3 ++-
drivers/phy/tegra/phy-tegra194-p2u.c | 3 ++-
drivers/phy/tegra/xusb-tegra124.c | 2 +-
drivers/phy/tegra/xusb-tegra186.c | 2 +-
drivers/phy/tegra/xusb-tegra210.c | 2 +-
drivers/phy/tegra/xusb.c | 2 +-
drivers/phy/ti/phy-am654-serdes.c | 3 ++-
drivers/phy/ti/phy-da8xx-usb.c | 3 ++-
drivers/phy/ti/phy-dm816x-usb.c | 3 ++-
drivers/phy/ti/phy-gmii-sel.c | 3 ++-
drivers/phy/ti/phy-omap-usb2.c | 3 ++-
drivers/phy/ti/phy-ti-pipe3.c | 3 ++-
drivers/phy/ti/phy-twl4030-usb.c | 3 ++-
drivers/phy/xilinx/phy-zynqmp.c | 4 ++--
include/linux/phy/phy-sun4i-usb.h | 2 +-
include/linux/phy/tegra/xusb.h | 1 +
include/linux/phy/ulpi_phy.h | 2 +-
98 files changed, 187 insertions(+), 96 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-ath79-usb.c b/drivers/phy/qualcomm/phy-ath79-usb.c
index f8d0199c6e78..2f07241be600 100644
--- a/drivers/phy/qualcomm/phy-ath79-usb.c
+++ b/drivers/phy/qualcomm/phy-ath79-usb.c
@@ -8,9 +8,10 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
struct ath79_usb_phy {
struct reset_control *reset;
/* The suspend override logic is inverted, hence the no prefix
diff --git a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
index cae290a6e19f..dd73ecbb6c1e 100644
--- a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
+++ b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
@@ -13,7 +13,8 @@
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
/* PHY registers */
#define UNIPHY_PLL_REFCLK_CFG 0x000
diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index 7372de05a0b8..faddba0f20c7 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/phy/phy-dp.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
@@ -22,6 +21,8 @@
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-dp-phy.h"
#include "phy-qcom-qmp-qserdes-com-v4.h"
#include "phy-qcom-qmp-qserdes-com-v6.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index efeec4709a15..5783bdabc287 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -8,7 +8,8 @@
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
/* eUSB2 status registers */
#define EUSB2_RPTR_STATUS 0x08
diff --git a/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c b/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c
index da6f290af722..f1c1c2969e37 100644
--- a/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c
@@ -14,10 +14,11 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
struct ipq4019_usb_phy {
struct device *dev;
struct phy *phy;
diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c
index f5eb0bdac418..d5407784c18f 100644
--- a/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c
+++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c
@@ -13,7 +13,8 @@
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
struct qcom_ipq806x_sata_phy {
void __iomem *mmio;
diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
index f22c0000479f..54144f0547f0 100644
--- a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
@@ -5,13 +5,14 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/bitfield.h>
+#include "../phy-provider.h"
+
/* USB QSCRATCH Hardware registers */
#define QSCRATCH_GENERAL_CFG (0x08)
#define HSUSB_PHY_CTRL_REG (0x10)
diff --git a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
index 68f1ba8fec4a..9e3a911023cd 100644
--- a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
@@ -18,6 +18,8 @@
#include <linux/regulator/consumer.h>
+#include "../phy-provider.h"
+
#define USB_PHY_UTMI_CTRL0 (0x3c)
#define SLEEPM BIT(0)
diff --git a/drivers/phy/qualcomm/phy-qcom-m31.c b/drivers/phy/qualcomm/phy-qcom-m31.c
index 168ea980fda0..1a63a5807d37 100644
--- a/drivers/phy/qualcomm/phy-qcom-m31.c
+++ b/drivers/phy/qualcomm/phy-qcom-m31.c
@@ -10,11 +10,12 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#define USB2PHY_PORT_UTMI_CTRL1 0x40
#define USB2PHY_PORT_UTMI_CTRL2 0x44
diff --git a/drivers/phy/qualcomm/phy-qcom-pcie2.c b/drivers/phy/qualcomm/phy-qcom-pcie2.c
index 11a2bb958681..4c74d8e7722d 100644
--- a/drivers/phy/qualcomm/phy-qcom-pcie2.c
+++ b/drivers/phy/qualcomm/phy-qcom-pcie2.c
@@ -8,11 +8,12 @@
#include <linux/clk.h>
#include <linux/iopoll.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#include <dt-bindings/phy/phy.h>
#define PCIE20_PARF_PHY_STTS 0x3c
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index b9ea7d058e93..04c54c229f08 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -14,7 +14,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
@@ -28,6 +27,8 @@
#include <dt-bindings/phy/phy-qcom-qmp.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
index a7c65cfe31df..df38d5b6d5be 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
@@ -13,12 +13,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index fed2fc9bb311..06680151360e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -15,7 +15,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/phy/pcie.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -24,6 +23,8 @@
#include <dt-bindings/phy/phy-qcom-qmp.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 771bc7c2ab50..8fda189774e6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
@@ -21,6 +20,8 @@
#include <ufs/unipro.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 2bd5862c5ba8..a682b30db03e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -14,13 +14,14 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp.h"
#include "phy-qcom-qmp-pcs-misc-v3.h"
#include "phy-qcom-qmp-pcs-usb-v4.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index d88b8a415e85..3db0a5282dbf 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -13,13 +13,14 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index f62e1f6ecc07..b77007f8fee3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@@ -25,6 +24,8 @@
#include <linux/usb/typec_mux.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index 191040f6d60f..e5516099b911 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -3,6 +3,7 @@
* Copyright (c) 2017, 2019, The Linux Foundation. All rights reserved.
*/
+#include <dt-bindings/phy/phy-qcom-qusb2.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
@@ -12,7 +13,6 @@
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@@ -20,7 +20,7 @@
#include <linux/reset.h>
#include <linux/slab.h>
-#include <dt-bindings/phy/phy-qcom-qusb2.h>
+#include "../phy-provider.h"
#define QUSB2PHY_PLL 0x0
#define QUSB2PHY_PLL_TEST 0x04
diff --git a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
index f48faa2929a6..9886500e0272 100644
--- a/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
+++ b/drivers/phy/qualcomm/phy-qcom-sgmii-eth.c
@@ -8,10 +8,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#include "phy-qcom-qmp-pcs-sgmii.h"
#include "phy-qcom-qmp-qserdes-com-v5.h"
#include "phy-qcom-qmp-qserdes-txrx-v5.h"
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
index 8915fa250e81..17a33e545008 100644
--- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
+++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@@ -18,6 +17,8 @@
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c)
#define SLEEPM BIT(0)
#define OPMODE_MASK GENMASK(4, 3)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
index 324c0a5d658e..13828d4f788e 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
@@ -12,12 +12,13 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/units.h>
+#include "../phy-provider.h"
+
#define RST_ASSERT_DELAY_MIN_US 100
#define RST_ASSERT_DELAY_MAX_US 150
#define PIPE_CLK_DELAY_MIN_US 5000
diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c b/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c
index a52a9bf13b75..ce317deaeacb 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c
@@ -11,12 +11,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
/* PHY register and bit definitions */
#define PHY_CTRL_COMMON0 0x078
#define SIDDQ BIT(2)
diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs.c b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
index 98a18987f1be..95581926023f 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hs.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
@@ -8,11 +8,12 @@
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/reset.h>
#include <linux/extcon.h>
#include <linux/notifier.h>
+#include "../phy-provider.h"
+
#define ULPI_PWR_CLK_MNG_REG 0x88
# define ULPI_PWR_OTG_COMP_DISABLE BIT(0)
diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
index 20f6dd37c7c1..fe9315a2f207 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
@@ -5,12 +5,13 @@
#include <linux/module.h>
#include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h>
-#include <linux/phy/phy.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinctrl-state.h>
#include <linux/delay.h>
#include <linux/clk.h>
+#include "../phy-provider.h"
+
#define ULPI_HSIC_CFG 0x30
#define ULPI_HSIC_IO_CAL 0x33
diff --git a/drivers/phy/qualcomm/phy-qcom-usb-ss.c b/drivers/phy/qualcomm/phy-qcom-usb-ss.c
index a3a6d3ce7ea1..17ca14a0b34d 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-ss.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-ss.c
@@ -11,12 +11,13 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#define PHY_CTRL0 0x6C
#define PHY_CTRL1 0x70
#define PHY_CTRL2 0x74
diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c
index a591ad95347c..4865a264136d 100644
--- a/drivers/phy/ralink/phy-mt7621-pci.c
+++ b/drivers/phy/ralink/phy-mt7621-pci.c
@@ -10,11 +10,12 @@
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/sys_soc.h>
+#include "../phy-provider.h"
+
#define RG_PE1_PIPE_REG 0x02c
#define RG_PE1_PIPE_RST BIT(12)
#define RG_PE1_PIPE_CMD_FRC BIT(4)
diff --git a/drivers/phy/ralink/phy-ralink-usb.c b/drivers/phy/ralink/phy-ralink-usb.c
index 0ff07e210769..cc61139ce157 100644
--- a/drivers/phy/ralink/phy-ralink-usb.c
+++ b/drivers/phy/ralink/phy-ralink-usb.c
@@ -14,11 +14,12 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define RT_SYSC_REG_SYSCFG1 0x014
#define RT_SYSC_REG_CLKCFG1 0x030
#define RT_SYSC_REG_USB_PHY_CFG 0x05c
diff --git a/drivers/phy/realtek/phy-rtk-usb2.c b/drivers/phy/realtek/phy-rtk-usb2.c
index 248550ef98ca..a0431f11972e 100644
--- a/drivers/phy/realtek/phy-rtk-usb2.c
+++ b/drivers/phy/realtek/phy-rtk-usb2.c
@@ -16,9 +16,10 @@
#include <linux/regmap.h>
#include <linux/sys_soc.h>
#include <linux/mfd/syscon.h>
-#include <linux/phy/phy.h>
#include <linux/usb.h>
+#include "../phy-provider.h"
+
/* GUSB2PHYACCn register */
#define PHY_NEW_REG_REQ BIT(25)
#define PHY_VSTS_BUSY BIT(23)
diff --git a/drivers/phy/realtek/phy-rtk-usb3.c b/drivers/phy/realtek/phy-rtk-usb3.c
index cce453686db2..3f565c4d96be 100644
--- a/drivers/phy/realtek/phy-rtk-usb3.c
+++ b/drivers/phy/realtek/phy-rtk-usb3.c
@@ -16,9 +16,10 @@
#include <linux/regmap.h>
#include <linux/sys_soc.h>
#include <linux/mfd/syscon.h>
-#include <linux/phy/phy.h>
#include <linux/usb.h>
+#include "../phy-provider.h"
+
#define USB_MDIO_CTRL_PHY_BUSY BIT(7)
#define USB_MDIO_CTRL_PHY_WRITE BIT(0)
#define USB_MDIO_CTRL_PHY_ADDR_SHIFT 8
diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c
index 6c671254c625..ca5498986120 100644
--- a/drivers/phy/renesas/phy-rcar-gen2.c
+++ b/drivers/phy/renesas/phy-rcar-gen2.c
@@ -12,11 +12,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
+#include "../phy-provider.h"
+
#define USBHS_LPSTS 0x02
#define USBHS_UGCTRL 0x80
#define USBHS_UGCTRL2 0x84
diff --git a/drivers/phy/renesas/phy-rcar-gen3-pcie.c b/drivers/phy/renesas/phy-rcar-gen3-pcie.c
index 3e2cf59ad480..747a1cd74639 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-pcie.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-pcie.c
@@ -9,11 +9,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
+#include "../phy-provider.h"
+
#define PHY_CTRL 0x4000 /* R8A77980 only */
/* PHY control register (PHY_CTRL) */
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 79e820e2fe55..88b4a47677a5 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -19,7 +19,6 @@
#include <linux/mutex.h>
#include <linux/mux/consumer.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
@@ -29,6 +28,8 @@
#include <linux/usb/of.h>
#include <linux/workqueue.h>
+#include "../phy-provider.h"
+
/******* USB2.0 Host registers (original offset is +0x200) *******/
#define USB2_INT_ENABLE 0x000
#define USB2_AHB_BUS_CTR 0x008
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb3.c b/drivers/phy/renesas/phy-rcar-gen3-usb3.c
index 0420f5b283ce..3511831e95d2 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb3.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb3.c
@@ -10,10 +10,11 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include "../phy-provider.h"
+
#define USB30_CLKSET0 0x034
#define USB30_CLKSET1 0x036
#define USB30_SSC_SET 0x038
diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c b/drivers/phy/renesas/phy-rzg3e-usb3.c
index 6b3453ea0004..1c9e2276bb73 100644
--- a/drivers/phy/renesas/phy-rzg3e-usb3.c
+++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
@@ -11,11 +11,12 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define USB3_TEST_RESET 0x0000
#define USB3_TEST_UTMICTRL2 0x0b04
#define USB3_TEST_PRMCTRL5_R 0x0c10
diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c
index c34427ac4fdb..807af518aeda 100644
--- a/drivers/phy/renesas/r8a779f0-ether-serdes.c
+++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c
@@ -10,11 +10,12 @@
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define R8A779F0_ETH_SERDES_NUM 3
#define R8A779F0_ETH_SERDES_OFFSET 0x0400
#define R8A779F0_ETH_SERDES_BANK_SELECT 0x03fc
diff --git a/drivers/phy/rockchip/phy-rockchip-dp.c b/drivers/phy/rockchip/phy-rockchip-dp.c
index 592aa956eead..63e972969379 100644
--- a/drivers/phy/rockchip/phy-rockchip-dp.c
+++ b/drivers/phy/rockchip/phy-rockchip-dp.c
@@ -10,10 +10,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define GRF_SOC_CON12 0x0274
#define GRF_EDP_REF_CLK_SEL_INTER_HIWORD_MASK BIT(20)
diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
index e6a768bbb9b3..de7e00580e20 100644
--- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
+++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
@@ -21,11 +21,12 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define RK3399_GRF_SOC_CON9 0x6224
#define RK3399_GRF_SOC_CON21 0x6254
#define RK3399_GRF_SOC_CON22 0x6258
diff --git a/drivers/phy/rockchip/phy-rockchip-emmc.c b/drivers/phy/rockchip/phy-rockchip-emmc.c
index 5187983c58e5..fd292f063f48 100644
--- a/drivers/phy/rockchip/phy-rockchip-emmc.c
+++ b/drivers/phy/rockchip/phy-rockchip-emmc.c
@@ -13,10 +13,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/*
* The higher 16-bit of this register is used for write protection
* only if BIT(x + 16) set to 1 the BIT(x) can be written.
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
index c79fb53d8ee5..3b5d86b07564 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
@@ -13,13 +13,14 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
/* GRF */
#define RK1808_GRF_PD_VI_CON_OFFSET 0x0430
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 30d5e5ddff4a..5613b34958fe 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -15,13 +15,13 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/time64.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
+#include "../phy-provider.h"
#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 1483907413fa..82b5e7434f83 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -20,6 +20,8 @@
#include <linux/phy/phy.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
/* REG: 0x00 */
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 8f4c08e599aa..f88e09f61994 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -18,7 +18,6 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_irq.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
@@ -27,6 +26,8 @@
#include <linux/usb/of.h>
#include <linux/usb/otg.h>
+#include "../phy-provider.h"
+
#define BIT_WRITEABLE_SHIFT 16
#define SCHEDULE_DELAY (60 * HZ)
#define OTG_SCHEDULE_DELAY (2 * HZ)
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index b60d6bf3f33c..2deb2666acb1 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -9,12 +9,13 @@
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/units.h>
+#include "../phy-provider.h"
+
#define BIT_WRITEABLE_SHIFT 16
#define REF_CLOCK_24MHz (24 * HZ_PER_MHZ)
#define REF_CLOCK_25MHz (25 * HZ_PER_MHZ)
diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
index 126306c01454..604ff00653b0 100644
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
@@ -13,12 +13,12 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
#define PHY_MAX_LANE_NUM 4
#define PHY_CFG_DATA_MASK GENMASK(10, 7)
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
index 0f69060aa5d5..78a0446b81df 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
@@ -15,12 +15,13 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define BIAS_CON0 0x0000
#define I_RES_CNTL_MASK GENMASK(6, 4)
#define I_RES_CNTL(x) FIELD_PREP(I_RES_CNTL_MASK, x)
diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 2d973bc37f07..01801a4dc436 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -21,6 +21,8 @@
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define GRF_HDPTX_CON0 0x00
#define LC_REF_CLK_SEL BIT(11)
#define HDPTX_I_PLL_EN BIT(7)
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
index 4e8ffd173096..029566330aa0 100644
--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
@@ -14,11 +14,12 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/pcie.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
/* Register for RK3568 */
#define GRF_PCIE30PHY_CON1 0x4
#define GRF_PCIE30PHY_CON6 0x18
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 0a318ccf1bbf..4a9756ca4f68 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -43,6 +43,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
@@ -53,8 +54,7 @@
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <linux/mfd/syscon.h>
-#include <linux/phy/phy.h>
+#include "../phy-provider.h"
#define CMN_SSM_BANDGAP (0x21 << 2)
#define CMN_SSM_BIAS (0x22 << 2)
diff --git a/drivers/phy/rockchip/phy-rockchip-usb.c b/drivers/phy/rockchip/phy-rockchip-usb.c
index cef96739cf3f..0652f821332b 100644
--- a/drivers/phy/rockchip/phy-rockchip-usb.c
+++ b/drivers/phy/rockchip/phy-rockchip-usb.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
@@ -23,6 +22,8 @@
#include <linux/mfd/syscon.h>
#include <linux/delay.h>
+#include "../phy-provider.h"
+
static int enable_usb_uart;
#define UOC_CON0 0x00
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index fba35510d88c..cf2abf29512f 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -25,6 +25,8 @@
#include <linux/usb/typec_dp.h>
#include <linux/usb/typec_mux.h>
+#include "../phy-provider.h"
+
/* USBDP PHY Register Definitions */
#define UDPHY_PCS 0x4000
#define UDPHY_PMA 0x8000
diff --git a/drivers/phy/samsung/phy-exynos-dp-video.c b/drivers/phy/samsung/phy-exynos-dp-video.c
index a636dee07585..00d0ed82a620 100644
--- a/drivers/phy/samsung/phy-exynos-dp-video.c
+++ b/drivers/phy/samsung/phy-exynos-dp-video.c
@@ -12,11 +12,12 @@
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
+#include "../phy-provider.h"
+
struct exynos_dp_video_phy_drvdata {
u32 phy_ctrl_offset;
};
diff --git a/drivers/phy/samsung/phy-exynos-mipi-video.c b/drivers/phy/samsung/phy-exynos-mipi-video.c
index be925508ed97..ce8a258a104e 100644
--- a/drivers/phy/samsung/phy-exynos-mipi-video.c
+++ b/drivers/phy/samsung/phy-exynos-mipi-video.c
@@ -11,13 +11,14 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>
#include <linux/mfd/syscon.h>
+#include "../phy-provider.h"
+
enum exynos_mipi_phy_id {
EXYNOS_MIPI_PHY_ID_NONE = -1,
EXYNOS_MIPI_PHY_ID_CSIS0,
diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c
index 53c9230c2907..9dd3a4a90fa7 100644
--- a/drivers/phy/samsung/phy-exynos-pcie.c
+++ b/drivers/phy/samsung/phy-exynos-pcie.c
@@ -12,9 +12,10 @@
#include <linux/mfd/syscon.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PCIE_PHY_OFFSET(x) ((x) * 0x4)
/* Sysreg FSYS register offsets and bits for Exynos5433 */
diff --git a/drivers/phy/samsung/phy-exynos4210-usb2.c b/drivers/phy/samsung/phy-exynos4210-usb2.c
index 3898a7f58217..beb2f96bebbf 100644
--- a/drivers/phy/samsung/phy-exynos4210-usb2.c
+++ b/drivers/phy/samsung/phy-exynos4210-usb2.c
@@ -8,8 +8,9 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+
+#include "../phy-provider.h"
#include "phy-samsung-usb2.h"
/* Exynos USB PHY registers */
diff --git a/drivers/phy/samsung/phy-exynos4x12-usb2.c b/drivers/phy/samsung/phy-exynos4x12-usb2.c
index b528a5d037fe..a402f80d0aab 100644
--- a/drivers/phy/samsung/phy-exynos4x12-usb2.c
+++ b/drivers/phy/samsung/phy-exynos4x12-usb2.c
@@ -8,8 +8,9 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+
+#include "../phy-provider.h"
#include "phy-samsung-usb2.h"
/* Exynos USB PHY registers */
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 5a181cb4597e..cb476d007e3f 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -26,6 +26,8 @@
#include <linux/usb/typec.h>
#include <linux/usb/typec_mux.h>
+#include "../phy-provider.h"
+
/* Exynos USB PHY registers */
#define EXYNOS5_FSEL_9MHZ6 0x0
#define EXYNOS5_FSEL_10MHZ 0x1
diff --git a/drivers/phy/samsung/phy-exynos5250-sata.c b/drivers/phy/samsung/phy-exynos5250-sata.c
index 595adba5fb8f..0f85ae0a5901 100644
--- a/drivers/phy/samsung/phy-exynos5250-sata.c
+++ b/drivers/phy/samsung/phy-exynos5250-sata.c
@@ -15,12 +15,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/mfd/syscon.h>
+#include "../phy-provider.h"
+
#define SATAPHY_CONTROL_OFFSET 0x0724
#define EXYNOS5_SATAPHY_PMU_ENABLE BIT(0)
#define EXYNOS5_SATA_RESET 0x4
diff --git a/drivers/phy/samsung/phy-exynos5250-usb2.c b/drivers/phy/samsung/phy-exynos5250-usb2.c
index 21b06072f866..04815633f290 100644
--- a/drivers/phy/samsung/phy-exynos5250-usb2.c
+++ b/drivers/phy/samsung/phy-exynos5250-usb2.c
@@ -8,8 +8,9 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+
+#include "../phy-provider.h"
#include "phy-samsung-usb2.h"
/* Exynos USB PHY registers */
diff --git a/drivers/phy/samsung/phy-s5pv210-usb2.c b/drivers/phy/samsung/phy-s5pv210-usb2.c
index 32be62e49804..4d72559d29a9 100644
--- a/drivers/phy/samsung/phy-s5pv210-usb2.c
+++ b/drivers/phy/samsung/phy-s5pv210-usb2.c
@@ -8,7 +8,8 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
#include "phy-samsung-usb2.h"
/* Exynos USB PHY registers */
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index ee665f26c236..b55a726cd44e 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -15,10 +15,10 @@
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
#include "phy-samsung-ufs.h"
#define for_each_phy_lane(phy, i) \
diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h
index f2c2e744e5ba..90f4d4cef631 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.h
+++ b/drivers/phy/samsung/phy-samsung-ufs.h
@@ -10,9 +10,10 @@
#ifndef _PHY_SAMSUNG_UFS_
#define _PHY_SAMSUNG_UFS_
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PHY_COMN_BLK 1
#define PHY_TRSV_BLK 2
#define END_UFS_PHY_CFG { 0 }
diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c
index d2749b67cf8f..362dd4ae3cab 100644
--- a/drivers/phy/samsung/phy-samsung-usb2.c
+++ b/drivers/phy/samsung/phy-samsung-usb2.c
@@ -13,6 +13,8 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
+
+#include "../phy-provider.h"
#include "phy-samsung-usb2.h"
static int samsung_usb2_phy_power_on(struct phy *phy)
diff --git a/drivers/phy/samsung/phy-samsung-usb2.h b/drivers/phy/samsung/phy-samsung-usb2.h
index ebaf43bfc5a2..515c7938fccd 100644
--- a/drivers/phy/samsung/phy-samsung-usb2.h
+++ b/drivers/phy/samsung/phy-samsung-usb2.h
@@ -10,12 +10,13 @@
#define _PHY_EXYNOS_USB2_H
#include <linux/clk.h>
-#include <linux/phy/phy.h>
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/regulator/consumer.h>
+#include "../phy-provider.h"
+
#define KHZ 1000
#define MHZ (KHZ * KHZ)
diff --git a/drivers/phy/socionext/phy-uniphier-ahci.c b/drivers/phy/socionext/phy-uniphier-ahci.c
index 28cf3efe0695..6b3ce56c7f0c 100644
--- a/drivers/phy/socionext/phy-uniphier-ahci.c
+++ b/drivers/phy/socionext/phy-uniphier-ahci.c
@@ -12,10 +12,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
struct uniphier_ahciphy_priv {
struct device *dev;
void __iomem *base;
diff --git a/drivers/phy/socionext/phy-uniphier-pcie.c b/drivers/phy/socionext/phy-uniphier-pcie.c
index c19173492b79..00f6cdf846f1 100644
--- a/drivers/phy/socionext/phy-uniphier-pcie.c
+++ b/drivers/phy/socionext/phy-uniphier-pcie.c
@@ -12,12 +12,13 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/resource.h>
+#include "../phy-provider.h"
+
/* PHY */
#define PCL_PHY_CLKCTRL 0x0000
#define PORT_SEL_MASK GENMASK(11, 9)
diff --git a/drivers/phy/socionext/phy-uniphier-usb2.c b/drivers/phy/socionext/phy-uniphier-usb2.c
index c49d432e526b..6ee566478be0 100644
--- a/drivers/phy/socionext/phy-uniphier-usb2.c
+++ b/drivers/phy/socionext/phy-uniphier-usb2.c
@@ -10,11 +10,12 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include "../phy-provider.h"
+
#define SG_USBPHY1CTRL 0x500
#define SG_USBPHY1CTRL2 0x504
#define SG_USBPHY2CTRL 0x508
diff --git a/drivers/phy/socionext/phy-uniphier-usb3hs.c b/drivers/phy/socionext/phy-uniphier-usb3hs.c
index 8c8673df0084..a08db863223f 100644
--- a/drivers/phy/socionext/phy-uniphier-usb3hs.c
+++ b/drivers/phy/socionext/phy-uniphier-usb3hs.c
@@ -17,12 +17,13 @@
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#define HSPHY_CFG0 0x0
#define HSPHY_CFG0_HS_I_MASK GENMASK(31, 28)
#define HSPHY_CFG0_HSDISC_MASK GENMASK(27, 26)
diff --git a/drivers/phy/socionext/phy-uniphier-usb3ss.c b/drivers/phy/socionext/phy-uniphier-usb3ss.c
index f402ed8732fd..8829305e9d4c 100644
--- a/drivers/phy/socionext/phy-uniphier-usb3ss.c
+++ b/drivers/phy/socionext/phy-uniphier-usb3ss.c
@@ -16,11 +16,12 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define SSPHY_TESTI 0x0
#define TESTI_DAT_MASK GENMASK(13, 6)
#define TESTI_ADR_MASK GENMASK(5, 1)
diff --git a/drivers/phy/sophgo/phy-cv1800-usb2.c b/drivers/phy/sophgo/phy-cv1800-usb2.c
index 6fe846534e9c..1fd7bba498ad 100644
--- a/drivers/phy/sophgo/phy-cv1800-usb2.c
+++ b/drivers/phy/sophgo/phy-cv1800-usb2.c
@@ -12,10 +12,11 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
+#include "../phy-provider.h"
+
#define REG_USB_PHY_CTRL 0x048
#define PHY_VBUS_POWER_EN BIT(0)
diff --git a/drivers/phy/spacemit/phy-k1-pcie.c b/drivers/phy/spacemit/phy-k1-pcie.c
index 75477bea7f70..6f8f2f39f7f8 100644
--- a/drivers/phy/spacemit/phy-k1-pcie.c
+++ b/drivers/phy/spacemit/phy-k1-pcie.c
@@ -5,6 +5,7 @@
* Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved.
*/
+#include <dt-bindings/phy/phy.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
@@ -12,12 +13,11 @@
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
/*
* Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver
diff --git a/drivers/phy/spacemit/phy-k1-usb2.c b/drivers/phy/spacemit/phy-k1-usb2.c
index 01af310d6683..c897d80de41a 100644
--- a/drivers/phy/spacemit/phy-k1-usb2.c
+++ b/drivers/phy/spacemit/phy-k1-usb2.c
@@ -9,11 +9,12 @@
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iopoll.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/usb/of.h>
+#include "../phy-provider.h"
+
#define PHY_RST_MODE_CTRL 0x04
#define PHY_PLL_RDY BIT(0)
#define PHY_CLK_CDR_EN BIT(1)
diff --git a/drivers/phy/st/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c
index 43cef89af55e..e9792deb629a 100644
--- a/drivers/phy/st/phy-miphy28lp.c
+++ b/drivers/phy/st/phy-miphy28lp.c
@@ -7,6 +7,7 @@
* Author: Alexandre Torgue <alexandre.torgue@st.com>
*/
+#include <dt-bindings/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@@ -16,13 +17,12 @@
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/clk.h>
-#include <linux/phy/phy.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
/* MiPHY registers */
#define MIPHY_CONF_RESET 0x00
diff --git a/drivers/phy/st/phy-spear1310-miphy.c b/drivers/phy/st/phy-spear1310-miphy.c
index c661ab63505f..86acc2412c46 100644
--- a/drivers/phy/st/phy-spear1310-miphy.c
+++ b/drivers/phy/st/phy-spear1310-miphy.c
@@ -14,10 +14,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* SPEAr1310 Registers */
#define SPEAR1310_PCIE_SATA_CFG 0x3A4
#define SPEAR1310_PCIE_SATA2_SEL_PCIE (0 << 31)
diff --git a/drivers/phy/st/phy-spear1340-miphy.c b/drivers/phy/st/phy-spear1340-miphy.c
index 85a60d64ebb7..4dbd3158c060 100644
--- a/drivers/phy/st/phy-spear1340-miphy.c
+++ b/drivers/phy/st/phy-spear1340-miphy.c
@@ -14,10 +14,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* SPEAr1340 Registers */
/* Power Management Registers */
#define SPEAR1340_PCM_CFG 0x100
diff --git a/drivers/phy/st/phy-stih407-usb.c b/drivers/phy/st/phy-stih407-usb.c
index 7a3e4584895c..497f9aa4139d 100644
--- a/drivers/phy/st/phy-stih407-usb.c
+++ b/drivers/phy/st/phy-stih407-usb.c
@@ -16,7 +16,8 @@
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/mfd/syscon.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
#define PHYPARAM_REG 0
#define PHYCTRL_REG 1
diff --git a/drivers/phy/st/phy-stm32-combophy.c b/drivers/phy/st/phy-stm32-combophy.c
index 607b4d607eb5..8757b1993e90 100644
--- a/drivers/phy/st/phy-stm32-combophy.c
+++ b/drivers/phy/st/phy-stm32-combophy.c
@@ -10,12 +10,13 @@
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#define SYSCFG_COMBOPHY_CR1 0x4c00
#define SYSCFG_COMBOPHY_CR2 0x4c04
#define SYSCFG_COMBOPHY_CR4 0x4c0c
diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
index b44afbff8616..647fbbe5c734 100644
--- a/drivers/phy/st/phy-stm32-usbphyc.c
+++ b/drivers/phy/st/phy-stm32-usbphyc.c
@@ -18,6 +18,8 @@
#include <linux/reset.h>
#include <linux/units.h>
+#include "../phy-provider.h"
+
#define STM32_USBPHYC_PLL 0x0
#define STM32_USBPHYC_MISC 0x8
#define STM32_USBPHYC_MONITOR(X) (0x108 + ((X) * 0x100))
diff --git a/drivers/phy/starfive/phy-jh7110-dphy-rx.c b/drivers/phy/starfive/phy-jh7110-dphy-rx.c
index 0b039e1f71c5..099a1ebf6194 100644
--- a/drivers/phy/starfive/phy-jh7110-dphy-rx.c
+++ b/drivers/phy/starfive/phy-jh7110-dphy-rx.c
@@ -13,11 +13,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define STF_DPHY_APBCFGSAIF_SYSCFG(x) (x)
#define STF_DPHY_ENABLE_CLK BIT(6)
diff --git a/drivers/phy/starfive/phy-jh7110-dphy-tx.c b/drivers/phy/starfive/phy-jh7110-dphy-tx.c
index c64d1c91b130..a5faf06b6d14 100644
--- a/drivers/phy/starfive/phy-jh7110-dphy-tx.c
+++ b/drivers/phy/starfive/phy-jh7110-dphy-tx.c
@@ -15,12 +15,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/phy/phy.h>
#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define STF_DPHY_APBIFSAIF_SYSCFG(x) (x)
#define STF_DPHY_AON_POWER_READY_N_ACTIVE 0
diff --git a/drivers/phy/starfive/phy-jh7110-pcie.c b/drivers/phy/starfive/phy-jh7110-pcie.c
index 734c8e007727..d68d396ac3cc 100644
--- a/drivers/phy/starfive/phy-jh7110-pcie.c
+++ b/drivers/phy/starfive/phy-jh7110-pcie.c
@@ -12,10 +12,11 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PCIE_KVCO_LEVEL_OFF 0x28
#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c
#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80
diff --git a/drivers/phy/starfive/phy-jh7110-usb.c b/drivers/phy/starfive/phy-jh7110-usb.c
index b505d89860b4..5762586e5c7d 100644
--- a/drivers/phy/starfive/phy-jh7110-usb.c
+++ b/drivers/phy/starfive/phy-jh7110-usb.c
@@ -12,11 +12,12 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/usb/of.h>
+#include "../phy-provider.h"
+
#define USB_125M_CLK_RATE 125000000
#define USB_CLK_MODE_OFF 0x0
#define USB_CLK_MODE_RX_NORMAL_PWR BIT(1)
diff --git a/drivers/phy/sunplus/phy-sunplus-usb2.c b/drivers/phy/sunplus/phy-sunplus-usb2.c
index 637a5fbae6d9..2ddbc37d09ee 100644
--- a/drivers/phy/sunplus/phy-sunplus-usb2.c
+++ b/drivers/phy/sunplus/phy-sunplus-usb2.c
@@ -17,10 +17,11 @@
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define HIGH_MASK_BITS GENMASK(31, 16)
#define LOW_MASK_BITS GENMASK(15, 0)
#define OTP_DISC_LEVEL_DEFAULT 0xd
diff --git a/drivers/phy/tegra/phy-tegra194-p2u.c b/drivers/phy/tegra/phy-tegra194-p2u.c
index f49b417c9eb6..467b6b97e53d 100644
--- a/drivers/phy/tegra/phy-tegra194-p2u.c
+++ b/drivers/phy/tegra/phy-tegra194-p2u.c
@@ -11,9 +11,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define P2U_CONTROL_CMN 0x74
#define P2U_CONTROL_CMN_ENABLE_L2_EXIT_RATE_CHANGE BIT(13)
#define P2U_CONTROL_CMN_SKP_SIZE_PROTECTION_EN BIT(20)
diff --git a/drivers/phy/tegra/xusb-tegra124.c b/drivers/phy/tegra/xusb-tegra124.c
index 70b6213370a8..21686c6fb2d7 100644
--- a/drivers/phy/tegra/xusb-tegra124.c
+++ b/drivers/phy/tegra/xusb-tegra124.c
@@ -8,7 +8,6 @@
#include <linux/mailbox_client.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
@@ -16,6 +15,7 @@
#include <soc/tegra/fuse.h>
+#include "../phy-provider.h"
#include "xusb.h"
#define FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) ((x) ? 15 : 0)
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index 1ddf11265974..e017cb1ff484 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -7,7 +7,6 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/regulator/consumer.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -15,6 +14,7 @@
#include <soc/tegra/fuse.h>
+#include "../phy-provider.h"
#include "xusb.h"
/* FUSE USB_CALIB registers */
diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
index 1abc5913ec49..006aba47b93d 100644
--- a/drivers/phy/tegra/xusb-tegra210.c
+++ b/drivers/phy/tegra/xusb-tegra210.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -21,6 +20,7 @@
#include <soc/tegra/fuse.h>
+#include "../phy-provider.h"
#include "xusb.h"
#define FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) \
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 9d74c0ecc31b..07a2f5a4dbee 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/phy/tegra/xusb.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
@@ -19,6 +18,7 @@
#include <soc/tegra/fuse.h>
+#include "../phy-provider.h"
#include "xusb.h"
static struct phy *tegra_xusb_pad_of_xlate(struct device *dev,
diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c
index 5b6c27aa7e8b..8990b715525e 100644
--- a/drivers/phy/ti/phy-am654-serdes.c
+++ b/drivers/phy/ti/phy-am654-serdes.c
@@ -15,11 +15,12 @@
#include <linux/mfd/syscon.h>
#include <linux/mux/consumer.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define CMU_R004 0x4
#define CMU_R060 0x60
#define CMU_R07C 0x7c
diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c
index 62fa6f89c0e6..261b65abd38b 100644
--- a/drivers/phy/ti/phy-da8xx-usb.c
+++ b/drivers/phy/ti/phy-da8xx-usb.c
@@ -11,12 +11,13 @@
#include <linux/mfd/da8xx-cfgchip.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_data/phy-da8xx-usb.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PHY_INIT_BITS (CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN)
struct da8xx_usb_phy {
diff --git a/drivers/phy/ti/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c
index d274831b731c..515ef7812bde 100644
--- a/drivers/phy/ti/phy-dm816x-usb.c
+++ b/drivers/phy/ti/phy-dm816x-usb.c
@@ -12,10 +12,11 @@
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/delay.h>
-#include <linux/phy/phy.h>
#include <linux/mfd/syscon.h>
+#include "../phy-provider.h"
+
/*
* TRM has two sets of USB_CTRL registers.. The correct register bits
* are in TRM section 24.9.8.2 USB_CTRL Register. The TRM documents the
diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
index 6213c2b6005a..ce7dc692d7be 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -14,9 +14,10 @@
#include <linux/of_address.h>
#include <linux/of_net.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* AM33xx SoC specific definitions for the CONTROL port */
#define AM33XX_GMII_SEL_MODE_MII 0
#define AM33XX_GMII_SEL_MODE_RMII 1
diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c
index 1eb252604441..318f51d09c28 100644
--- a/drivers/phy/ti/phy-omap-usb2.c
+++ b/drivers/phy/ti/phy-omap-usb2.c
@@ -16,7 +16,6 @@
#include <linux/of_platform.h>
#include <linux/phy/omap_control_phy.h>
#include <linux/phy/omap_usb.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
@@ -25,6 +24,8 @@
#include <linux/sys_soc.h>
#include <linux/usb/phy_companion.h>
+#include "../phy-provider.h"
+
#define USB2PHY_ANA_CONFIG1 0x4c
#define USB2PHY_DISCON_BYP_LATCH BIT(31)
diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c
index b5543b5c674c..d63c8e872d5b 100644
--- a/drivers/phy/ti/phy-ti-pipe3.c
+++ b/drivers/phy/ti/phy-ti-pipe3.c
@@ -10,7 +10,6 @@
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
-#include <linux/phy/phy.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -22,6 +21,8 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PLL_STATUS 0x00000004
#define PLL_GO 0x00000008
#define PLL_CONFIGURATION1 0x0000000C
diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c
index a26aec3ab29e..67c9883691fc 100644
--- a/drivers/phy/ti/phy-twl4030-usb.c
+++ b/drivers/phy/ti/phy-twl4030-usb.c
@@ -20,7 +20,6 @@
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/usb/otg.h>
-#include <linux/phy/phy.h>
#include <linux/pm_runtime.h>
#include <linux/usb/musb.h>
#include <linux/usb/ulpi.h>
@@ -29,6 +28,8 @@
#include <linux/err.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
/* Register defines */
#define MCPC_CTRL 0x30
diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c
index fe6b4925d166..db40594622da 100644
--- a/drivers/phy/xilinx/phy-zynqmp.c
+++ b/drivers/phy/xilinx/phy-zynqmp.c
@@ -12,6 +12,7 @@
* PCIe should also work but that is experimental as of now.
*/
+#include <dt-bindings/phy/phy.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -19,12 +20,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
-#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
/*
* Lane Registers
diff --git a/include/linux/phy/phy-sun4i-usb.h b/include/linux/phy/phy-sun4i-usb.h
index f3e7b13608e4..66612be0dac5 100644
--- a/include/linux/phy/phy-sun4i-usb.h
+++ b/include/linux/phy/phy-sun4i-usb.h
@@ -6,7 +6,7 @@
#ifndef PHY_SUN4I_USB_H_
#define PHY_SUN4I_USB_H_
-#include "phy.h"
+struct phy;
/**
* sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect
diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
index 6ca51e0080ec..e6c613f9bef2 100644
--- a/include/linux/phy/tegra/xusb.h
+++ b/include/linux/phy/tegra/xusb.h
@@ -8,6 +8,7 @@
struct tegra_xusb_padctl;
struct device;
+struct phy;
enum usb_device_speed;
struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev);
diff --git a/include/linux/phy/ulpi_phy.h b/include/linux/phy/ulpi_phy.h
index 7054b440347c..0f9e8430d398 100644
--- a/include/linux/phy/ulpi_phy.h
+++ b/include/linux/phy/ulpi_phy.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#include <linux/phy/phy.h>
+#include "../../drivers/phy/phy-provider.h"
/**
* Helper that registers PHY for a ULPI device and adds a lookup for binding it
--
2.34.1
^ permalink raw reply related
* [PATCH v7 phy-next 27/27] MAINTAINERS: add regexes for linux-phy
From: Vladimir Oltean @ 2026-04-30 11:06 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, Joe Perches
In-Reply-To: <20260430110652.558622-1-vladimir.oltean@nxp.com>
Some pragmatic shortcuts are being taken by PHY consumer driver authors,
which put a burden on the framework. A lot of these can be caught during
review.
Make sure the linux-phy list is copied on as many keywords that regexes
can reasonably catch.
Some considerations that led to this solution and not a simpler one:
- Consumers may be located anywhere, and their file naming provides no
indication whatsoever that they are PHY API consumers.
- The network PHY API has similarly sounding API: phy_start(),
phy_connect(), etc. Similarly, matching on "phy" would hit
phys_addr_t, "cryptography", etc.
- The header files themselves need attention to avoid matching on
include/linux/phy.h (network PHY), include/linux/usb/phy.h,
drivers/net/vendor/device/phy.h, etc.
- At least for a transitional period, I suppose developers will still
try to add PHY providers outside the subsystem (which is discouraged).
So I used \b to try to match on actual word boundaries and I went for
listing all markers of PHY API use as they may appear in patch contexts.
Bit rot is a valid concern. I will add a test to the build automation
that newly introduced struct and function names in include/linux/phy.h,
include/linux/phy-props.h and drivers/phy/phy-provider.h are matched by
the MAINTAINERS entry K: patterns.
The keyword patterns were written with great help from Joe Perches
<joe@perches.com>.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Cc: Joe Perches <joe@perches.com>
v3->v7: none
v2->v3:
- escape forward slash in linux/phy/phy.h in regex pattern:
https://lore.kernel.org/linux-phy/9fd14d166e860f26febfbc9061a6dcae6a166961.camel@perches.com/
v1->v2:
- split into multiple regex patterns
- use matching-only (insted of capturing) regex patterns
- adjust commit message to reflect the Q&A from v1
---
MAINTAINERS | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2fb1c75afd16..032be68cc326 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10799,6 +10799,17 @@ F: Documentation/devicetree/bindings/phy/
F: drivers/phy/
F: include/dt-bindings/phy/
F: include/linux/phy/
+K: (?:linux\/phy\/phy\.h|phy-props\.h|phy-provider\.h)
+K: \b(?:__)?(?:devm_)?(?:of_)?phy_(?:create|destroy|provider_(?:un)?register)\b
+K: \bphy_(?:create|remove)_lookup\b
+K: \bphy_(?:get|set)_drvdata\b
+K: \b(?:devm_)?(?:of_)?phy_(?:optional_)?(?:get|put)(?:_by_index)?\b
+K: \bphy_pm_runtime_(?:get|put)(?:_sync)?\b
+K: \bphy_(?:init|exit|power_(?:on|off))\b
+K: \bphy_(?:get|set)_(?:mode(?:_ext)?|media|speed|bus_width|max_link_rate)\b
+K: \bphy_(?:reset|configure|validate|calibrate)\b
+K: \bphy_notify_(?:connect|disconnect|state)\b
+K: \bstruct\s+phy(?:_ops|_attrs|_lookup|_provider)?\b
GENERIC PINCTRL I2C DEMULTIPLEXER DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
--
2.34.1
^ permalink raw reply related
* [PATCH v7 phy-next 24/27] phy: include PHY provider header (1/2)
From: Vladimir Oltean @ 2026-04-30 11:06 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, Chen-Yu Tsai
In-Reply-To: <20260430110652.558622-1-vladimir.oltean@nxp.com>
The majority of PHY drivers are PHY providers (obviously).
Some are providers *and* consumers (phy-meson-axg-mipi-dphy,
phy-meson-axg-pcie). These are the Amlogic AXG SoCs, which split the
physical layer into two chained PHYs: the digital layer and the analog
layer. The DSI or PCIe controller interacts only with the digital PHY,
presumably for simplicity.
The rest of PHY drivers which include <linux/phy/phy.h> do so because
they call phy_set_bus_width(), a consumer function.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Chen-Yu Tsai <wens@kernel.org> # allwinner
---
v6->v7: removed conflict resolution details, conflicting patches are now
in linux-phy/next
v3->v6: none
v2->v3: add conflict resolution details
v1->v2: split in two parts to pass through linux-phy mailing list
moderation
---
drivers/phy/allwinner/phy-sun4i-usb.c | 3 ++-
drivers/phy/allwinner/phy-sun50i-usb3.c | 3 ++-
drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 4 ++--
drivers/phy/allwinner/phy-sun9i-usb.c | 3 ++-
drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c | 2 ++
drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 3 ++-
drivers/phy/amlogic/phy-meson-axg-pcie.c | 2 ++
drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c | 3 ++-
drivers/phy/amlogic/phy-meson-g12a-usb2.c | 2 ++
drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 3 ++-
drivers/phy/amlogic/phy-meson-gxl-usb2.c | 3 ++-
drivers/phy/amlogic/phy-meson8-hdmi-tx.c | 3 ++-
drivers/phy/amlogic/phy-meson8b-usb2.c | 3 ++-
drivers/phy/apple/atc.c | 3 ++-
drivers/phy/broadcom/phy-bcm-cygnus-pcie.c | 3 ++-
drivers/phy/broadcom/phy-bcm-kona-usb2.c | 4 +++-
drivers/phy/broadcom/phy-bcm-ns-usb2.c | 3 ++-
drivers/phy/broadcom/phy-bcm-ns-usb3.c | 3 ++-
drivers/phy/broadcom/phy-bcm-ns2-pcie.c | 3 ++-
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c | 3 ++-
drivers/phy/broadcom/phy-bcm-sr-pcie.c | 3 ++-
drivers/phy/broadcom/phy-bcm-sr-usb.c | 3 ++-
drivers/phy/broadcom/phy-bcm63xx-usbh.c | 3 ++-
drivers/phy/broadcom/phy-brcm-sata.c | 3 ++-
drivers/phy/broadcom/phy-brcm-usb.c | 2 +-
drivers/phy/cadence/cdns-dphy-rx.c | 3 ++-
drivers/phy/cadence/cdns-dphy.c | 4 ++--
drivers/phy/cadence/phy-cadence-salvo.c | 3 ++-
drivers/phy/cadence/phy-cadence-sierra.c | 3 ++-
drivers/phy/cadence/phy-cadence-torrent.c | 3 ++-
drivers/phy/canaan/phy-k230-usb.c | 3 ++-
drivers/phy/eswin/phy-eic7700-sata.c | 3 ++-
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c | 3 ++-
drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 4 ++--
drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 3 ++-
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 6 +++---
drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c | 3 ++-
drivers/phy/freescale/phy-fsl-lynx-28g.c | 3 ++-
drivers/phy/hisilicon/phy-hi3660-usb3.c | 3 ++-
drivers/phy/hisilicon/phy-hi3670-pcie.c | 3 ++-
drivers/phy/hisilicon/phy-hi3670-usb3.c | 3 ++-
drivers/phy/hisilicon/phy-hi6220-usb.c | 3 ++-
drivers/phy/hisilicon/phy-hisi-inno-usb2.c | 4 +++-
drivers/phy/hisilicon/phy-histb-combphy.c | 3 ++-
drivers/phy/hisilicon/phy-hix5hd2-sata.c | 3 ++-
drivers/phy/ingenic/phy-ingenic-usb.c | 3 ++-
drivers/phy/intel/phy-intel-keembay-emmc.c | 3 ++-
drivers/phy/intel/phy-intel-keembay-usb.c | 3 ++-
drivers/phy/intel/phy-intel-lgm-combo.c | 4 ++--
drivers/phy/intel/phy-intel-lgm-emmc.c | 3 ++-
drivers/phy/lantiq/phy-lantiq-rcu-usb2.c | 3 ++-
drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c | 4 ++--
drivers/phy/marvell/phy-armada375-usb2.c | 3 ++-
drivers/phy/marvell/phy-armada38x-comphy.c | 3 ++-
drivers/phy/marvell/phy-berlin-sata.c | 3 ++-
drivers/phy/marvell/phy-berlin-usb.c | 3 ++-
drivers/phy/marvell/phy-mmp3-hsic.c | 3 ++-
drivers/phy/marvell/phy-mmp3-usb.c | 3 ++-
drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 3 ++-
drivers/phy/marvell/phy-mvebu-a3700-utmi.c | 3 ++-
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 ++-
drivers/phy/marvell/phy-mvebu-cp110-utmi.c | 3 ++-
drivers/phy/marvell/phy-mvebu-sata.c | 3 ++-
drivers/phy/marvell/phy-pxa-28nm-hsic.c | 3 ++-
drivers/phy/marvell/phy-pxa-28nm-usb2.c | 3 ++-
drivers/phy/marvell/phy-pxa-usb.c | 3 ++-
drivers/phy/mediatek/phy-mtk-dp.c | 3 ++-
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 1 -
drivers/phy/mediatek/phy-mtk-hdmi.h | 3 ++-
drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c | 2 +-
drivers/phy/mediatek/phy-mtk-mipi-dsi.h | 3 ++-
drivers/phy/mediatek/phy-mtk-pcie.c | 2 +-
drivers/phy/mediatek/phy-mtk-tphy.c | 2 +-
drivers/phy/mediatek/phy-mtk-ufs.c | 2 +-
drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 2 +-
drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +-
drivers/phy/microchip/lan966x_serdes.c | 4 ++--
drivers/phy/microchip/sparx5_serdes.c | 2 +-
drivers/phy/motorola/phy-cpcap-usb.c | 3 ++-
drivers/phy/motorola/phy-mapphone-mdm6600.c | 4 +++-
drivers/phy/mscc/phy-ocelot-serdes.c | 3 ++-
drivers/phy/nuvoton/phy-ma35d1-usb2.c | 3 ++-
drivers/phy/phy-airoha-pcie.c | 2 +-
drivers/phy/phy-can-transceiver.c | 3 ++-
drivers/phy/phy-core-mipi-dphy.c | 4 ++--
drivers/phy/phy-core.c | 2 ++
drivers/phy/phy-google-usb.c | 3 ++-
drivers/phy/phy-lpc18xx-usb-otg.c | 3 ++-
drivers/phy/phy-nxp-ptn3222.c | 3 ++-
drivers/phy/phy-pistachio-usb.c | 4 ++--
drivers/phy/phy-snps-eusb2.c | 2 ++
drivers/phy/phy-xgene.c | 3 ++-
92 files changed, 177 insertions(+), 97 deletions(-)
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index e2fbf8ccf99e..9a03b5944b98 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/phy/phy-sun4i-usb.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
@@ -33,6 +32,8 @@
#include <linux/usb/of.h>
#include <linux/workqueue.h>
+#include "../phy-provider.h"
+
#define REG_ISCR 0x00
#define REG_PHYCTL_A10 0x04
#define REG_PHYBIST 0x08
diff --git a/drivers/phy/allwinner/phy-sun50i-usb3.c b/drivers/phy/allwinner/phy-sun50i-usb3.c
index 363f9a0df503..d38b26e4bf95 100644
--- a/drivers/phy/allwinner/phy-sun50i-usb3.c
+++ b/drivers/phy/allwinner/phy-sun50i-usb3.c
@@ -18,10 +18,11 @@
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
/* Interface Status and Control Registers */
#define SUNXI_ISCR 0x00
#define SUNXI_PIPE_CLOCK_CONTROL 0x14
diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
index 36eab95271b2..e96162d078eb 100644
--- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
+++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
@@ -10,12 +10,12 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of_address.h>
+#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
+#include "../phy-provider.h"
#define SUN6I_DPHY_GCTL_REG 0x00
#define SUN6I_DPHY_GCTL_LANE_NUM(n) ((((n) - 1) & 3) << 4)
diff --git a/drivers/phy/allwinner/phy-sun9i-usb.c b/drivers/phy/allwinner/phy-sun9i-usb.c
index 2f9e60c188b8..f667f3f4b307 100644
--- a/drivers/phy/allwinner/phy-sun9i-usb.c
+++ b/drivers/phy/allwinner/phy-sun9i-usb.c
@@ -15,11 +15,12 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/usb/of.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define SUNXI_AHB_INCR16_BURST_EN BIT(11)
#define SUNXI_AHB_INCR8_BURST_EN BIT(10)
#define SUNXI_AHB_INCR4_BURST_EN BIT(9)
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index c4a56b9d3289..60d17973a38f 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -20,6 +20,8 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
/* [31] soft reset for the phy.
* 1: reset. 0: dessert the reset.
* [30] clock lane soft reset.
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
index c0ba2852dbb8..21e8e2a5563a 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
@@ -7,7 +7,6 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
@@ -15,6 +14,8 @@
#include <linux/platform_device.h>
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#define HHI_MIPI_CNTL0 0x00
#define HHI_MIPI_CNTL0_COMMON_BLOCK GENMASK(31, 28)
#define HHI_MIPI_CNTL0_ENABLE BIT(29)
diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c
index 14dee73f9cb5..c4d9faf3a805 100644
--- a/drivers/phy/amlogic/phy-meson-axg-pcie.c
+++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c
@@ -13,6 +13,8 @@
#include <linux/bitfield.h>
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#define MESON_PCIE_REG0 0x00
#define MESON_PCIE_COMMON_CLK BIT(4)
#define MESON_PCIE_PORT_SEL GENMASK(3, 2)
diff --git a/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c b/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
index 46e5f7e7eb6c..11626f4528dd 100644
--- a/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
+++ b/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
@@ -9,7 +9,6 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
@@ -17,6 +16,8 @@
#include <linux/platform_device.h>
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#define HHI_MIPI_CNTL0 0x00
#define HHI_MIPI_CNTL0_DIF_REF_CTL1 GENMASK(31, 16)
#define HHI_MIPI_CNTL0_DIF_REF_CTL0 GENMASK(15, 0)
diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb2.c b/drivers/phy/amlogic/phy-meson-g12a-usb2.c
index 66bf0b7ef8ed..6e599b933153 100644
--- a/drivers/phy/amlogic/phy-meson-g12a-usb2.c
+++ b/drivers/phy/amlogic/phy-meson-g12a-usb2.c
@@ -20,6 +20,8 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define PHY_CTRL_R0 0x0
#define PHY_CTRL_R1 0x4
#define PHY_CTRL_R2 0x8
diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
index 5468831d6ab9..60e9c3c1c449 100644
--- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
+++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
@@ -12,12 +12,13 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/platform_device.h>
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#define PHY_R0 0x00
#define PHY_R0_PCIE_POWER_STATE GENMASK(4, 0)
#define PHY_R0_PCIE_USB3_SWITCH GENMASK(6, 5)
diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
index 6b390304f723..b8d5b12cffc8 100644
--- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c
+++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c
@@ -12,9 +12,10 @@
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
/* bits [31:27] are read-only */
#define U2P_R0 0x0
#define U2P_R0_BYPASS_SEL BIT(0)
diff --git a/drivers/phy/amlogic/phy-meson8-hdmi-tx.c b/drivers/phy/amlogic/phy-meson8-hdmi-tx.c
index 2617f7f6c2ec..2a8c93dcda7e 100644
--- a/drivers/phy/amlogic/phy-meson8-hdmi-tx.c
+++ b/drivers/phy/amlogic/phy-meson8-hdmi-tx.c
@@ -11,11 +11,12 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/*
* Unfortunately there is no detailed documentation available for the
* HHI_HDMI_PHY_CNTL0 register. CTL0 and CTL1 is all we know about.
diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index a553231a9f7c..b288868b2d9e 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -14,10 +14,11 @@
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb/of.h>
+#include "../phy-provider.h"
+
#define REG_CONFIG 0x00
#define REG_CONFIG_CLK_EN BIT(0)
#define REG_CONFIG_CLK_SEL_MASK GENMASK(3, 1)
diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c
index e9d106f135c5..de9453d13c0e 100644
--- a/drivers/phy/apple/atc.c
+++ b/drivers/phy/apple/atc.c
@@ -32,7 +32,6 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/soc/apple/tunable.h>
@@ -44,6 +43,8 @@
#include <linux/usb/typec_mux.h>
#include <linux/usb/typec_tbt.h>
+#include "../phy-provider.h"
+
#define AUSPLL_FSM_CTRL 0x1014
#define AUSPLL_APB_CMD_OVERRIDE 0x2000
diff --git a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c
index 462c61a24ec5..e10274f53c10 100644
--- a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c
+++ b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c
@@ -5,9 +5,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define PCIE_CFG_OFFSET 0x00
#define PCIE1_PHY_IDDQ_SHIFT 10
#define PCIE0_PHY_IDDQ_SHIFT 2
diff --git a/drivers/phy/broadcom/phy-bcm-kona-usb2.c b/drivers/phy/broadcom/phy-bcm-kona-usb2.c
index e9cc5f2cb89a..356f42a08941 100644
--- a/drivers/phy/broadcom/phy-bcm-kona-usb2.c
+++ b/drivers/phy/broadcom/phy-bcm-kona-usb2.c
@@ -12,9 +12,11 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
+#include <linux/phy/phy.h> /* for phy_set_bus_width() */
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define OTGCTL (0)
#define OTGCTL_OTGSTAT2 BIT(31)
#define OTGCTL_OTGSTAT1 BIT(30)
diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb2.c b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
index c5d35031b398..95331d08b367 100644
--- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c
+++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
@@ -13,11 +13,12 @@
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
struct bcm_ns_usb2 {
struct device *dev;
struct clk *ref_clk;
diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb3.c b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
index 6e56498d0644..f2aa4014f197 100644
--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c
+++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
@@ -19,10 +19,11 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/property.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
#define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f
#define BCM_NS_USB3_PHY_PLL30_BLOCK 0x8000
#define BCM_NS_USB3_PHY_TX_PMD_BLOCK 0x8040
diff --git a/drivers/phy/broadcom/phy-bcm-ns2-pcie.c b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c
index 67a6ae5ecba0..9c2c603426ca 100644
--- a/drivers/phy/broadcom/phy-bcm-ns2-pcie.c
+++ b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c
@@ -6,7 +6,8 @@
#include <linux/of_mdio.h>
#include <linux/mdio.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
#define BLK_ADDR_REG_OFFSET 0x1f
#define PLL_AFE1_100MHZ_BLK 0x2100
diff --git a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
index 8473fa574529..7543211fb998 100644
--- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
+++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
@@ -14,12 +14,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
+#include "../phy-provider.h"
+
#define ICFG_DRD_AFE 0x0
#define ICFG_MISC_STAT 0x18
#define ICFG_DRD_P0CTL 0x1C
diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
index 706e1d83b4ce..8f4e44d1dea6 100644
--- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c
+++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
@@ -9,10 +9,11 @@
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* we have up to 8 PAXB based RC. The 9th one is always PAXC */
#define SR_NR_PCIE_PHYS 9
#define SR_PAXC_PHY_IDX (SR_NR_PCIE_PHYS - 1)
diff --git a/drivers/phy/broadcom/phy-bcm-sr-usb.c b/drivers/phy/broadcom/phy-bcm-sr-usb.c
index 6bcfe83609c8..4c863738bdca 100644
--- a/drivers/phy/broadcom/phy-bcm-sr-usb.c
+++ b/drivers/phy/broadcom/phy-bcm-sr-usb.c
@@ -8,9 +8,10 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
enum bcm_usb_phy_version {
BCM_SR_USB_COMBO_PHY,
BCM_SR_USB_HS_PHY,
diff --git a/drivers/phy/broadcom/phy-bcm63xx-usbh.c b/drivers/phy/broadcom/phy-bcm63xx-usbh.c
index 29fd6791bae6..63099da486c6 100644
--- a/drivers/phy/broadcom/phy-bcm63xx-usbh.c
+++ b/drivers/phy/broadcom/phy-bcm63xx-usbh.c
@@ -18,10 +18,11 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
/* USBH control register offsets */
enum usbh_regs {
USBH_BRT_CONTROL1 = 0,
diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c
index fb69e21a0292..ab826f9c8678 100644
--- a/drivers/phy/broadcom/phy-brcm-sata.c
+++ b/drivers/phy/broadcom/phy-brcm-sata.c
@@ -13,9 +13,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define SATA_PCB_BANK_OFFSET 0x23c
#define SATA_PCB_REG_OFFSET(ofs) ((ofs) * 4)
diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
index 59d756a10d6c..d660a0ed03ee 100644
--- a/drivers/phy/broadcom/phy-brcm-usb.c
+++ b/drivers/phy/broadcom/phy-brcm-usb.c
@@ -11,7 +11,6 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/soc/brcmstb/brcmstb.h>
@@ -19,6 +18,7 @@
#include <linux/mfd/syscon.h>
#include <linux/suspend.h>
+#include "../phy-provider.h"
#include "phy-brcm-usb-init.h"
static DEFINE_MUTEX(sysfs_lock);
diff --git a/drivers/phy/cadence/cdns-dphy-rx.c b/drivers/phy/cadence/cdns-dphy-rx.c
index 3ac80141189c..7097ac17443f 100644
--- a/drivers/phy/cadence/cdns-dphy-rx.c
+++ b/drivers/phy/cadence/cdns-dphy-rx.c
@@ -9,12 +9,13 @@
#include <linux/iopoll.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/sys_soc.h>
+#include "../phy-provider.h"
+
#define DPHY_PMA_CMN(reg) (reg)
#define DPHY_PCS(reg) (0xb00 + (reg))
#define DPHY_ISO(reg) (0xc00 + (reg))
diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index d5b0e516b93c..40bc18405082 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -10,11 +10,11 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
+#include "../phy-provider.h"
#define REG_WAKEUP_TIME_NS 800
#define DPHY_PLL_RATE_HZ 108000000
diff --git a/drivers/phy/cadence/phy-cadence-salvo.c b/drivers/phy/cadence/phy-cadence-salvo.c
index f461585c84c6..8ed74db50dfa 100644
--- a/drivers/phy/cadence/phy-cadence-salvo.c
+++ b/drivers/phy/cadence/phy-cadence-salvo.c
@@ -10,12 +10,13 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include "../phy-provider.h"
+
#define USB3_PHY_OFFSET 0x0
#define USB2_PHY_OFFSET 0x38000
/* USB3 PHY register definition */
diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 92ab1a31646a..fb44b8fc5e3f 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -12,7 +12,6 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@@ -23,6 +22,8 @@
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/phy/phy-cadence.h>
+#include "../phy-provider.h"
+
#define NUM_SSC_MODE 3
#define NUM_PHY_TYPE 5
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index d446a0f97688..974e12e34ae1 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -17,11 +17,12 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define REF_CLK_19_2MHZ 19200000
#define REF_CLK_25MHZ 25000000
#define REF_CLK_100MHZ 100000000
diff --git a/drivers/phy/canaan/phy-k230-usb.c b/drivers/phy/canaan/phy-k230-usb.c
index 52dad35fc6cf..4305763a5456 100644
--- a/drivers/phy/canaan/phy-k230-usb.c
+++ b/drivers/phy/canaan/phy-k230-usb.c
@@ -8,9 +8,10 @@
#include <linux/bitfield.h>
#include <linux/io.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define MAX_PHYS 2
/* Register offsets within the HiSysConfig system controller */
diff --git a/drivers/phy/eswin/phy-eic7700-sata.c b/drivers/phy/eswin/phy-eic7700-sata.c
index c33653d48daa..387d5c8c11d9 100644
--- a/drivers/phy/eswin/phy-eic7700-sata.c
+++ b/drivers/phy/eswin/phy-eic7700-sata.c
@@ -14,11 +14,12 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define SATA_AXI_LP_CTRL 0x08
#define SATA_MPLL_CTRL 0x20
#define SATA_P0_PHY_STAT 0x24
diff --git a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
index 0928a526e2ab..314aa227f753 100644
--- a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
+++ b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
@@ -16,11 +16,12 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/firmware/imx/rsrc.h>
+#include "../phy-provider.h"
+
/* Control and Status Registers(CSR) */
#define PHY_CTRL 0x00
#define CCM_MASK GENMASK(7, 5)
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
index 7f5600103a00..6197cfc9b9a4 100644
--- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -3,6 +3,7 @@
* Copyright 2021 NXP
*/
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -12,12 +13,11 @@
#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include "../phy-provider.h"
#define IMX8MM_PCIE_PHY_CMN_REG061 0x184
#define ANA_PLL_CLK_OUT_TO_EXT_IO_EN BIT(0)
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index b05d80e849a1..9b938b446996 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -7,11 +7,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/usb/typec_mux.h>
+#include "../phy-provider.h"
+
#define PHY_CTRL0 0x0
#define PHY_CTRL0_REF_SSP_EN BIT(2)
#define PHY_CTRL0_FSEL_MASK GENMASK(10, 5)
diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
index 279b8ac7822d..b274fd24b59a 100644
--- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
+++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
@@ -3,6 +3,8 @@
* Copyright 2024 NXP
*/
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -11,13 +13,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pci_regs.h>
-#include <linux/phy/phy.h>
#include <linux/phy/pcie.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
-#include <dt-bindings/phy/phy.h>
-#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include "../phy-provider.h"
#define MAX_NUM_LANE 3
#define LANE_NUM_CLKS 5
diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
index ece357443521..55c23bef5121 100644
--- a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
+++ b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
@@ -9,12 +9,13 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/units.h>
+#include "../phy-provider.h"
+
#define REG_SET 0x4
#define REG_CLR 0x8
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 63427fc34e26..38862c9c6c94 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -5,10 +5,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
+#include "../phy-provider.h"
+
#define LYNX_28G_NUM_LANE 8
#define LYNX_28G_NUM_PLL 2
diff --git a/drivers/phy/hisilicon/phy-hi3660-usb3.c b/drivers/phy/hisilicon/phy-hi3660-usb3.c
index e2a09d67faed..b66ff3be1aed 100644
--- a/drivers/phy/hisilicon/phy-hi3660-usb3.c
+++ b/drivers/phy/hisilicon/phy-hi3660-usb3.c
@@ -12,10 +12,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PERI_CRG_CLK_EN4 0x40
#define PERI_CRG_CLK_DIS4 0x44
#define GT_CLK_USB3OTG_REF BIT(0)
diff --git a/drivers/phy/hisilicon/phy-hi3670-pcie.c b/drivers/phy/hisilicon/phy-hi3670-pcie.c
index dbc7dcce682b..b7cf44078e0d 100644
--- a/drivers/phy/hisilicon/phy-hi3670-pcie.c
+++ b/drivers/phy/hisilicon/phy-hi3670-pcie.c
@@ -26,11 +26,12 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/types.h>
+#include "../phy-provider.h"
+
#define AXI_CLK_FREQ 207500000
#define REF_CLK_FREQ 100000000
diff --git a/drivers/phy/hisilicon/phy-hi3670-usb3.c b/drivers/phy/hisilicon/phy-hi3670-usb3.c
index 40d3cf128b44..004c51500597 100644
--- a/drivers/phy/hisilicon/phy-hi3670-usb3.c
+++ b/drivers/phy/hisilicon/phy-hi3670-usb3.c
@@ -14,10 +14,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define SCTRL_SCDEEPSLEEPED (0x0)
#define USB_CLK_SELECTED BIT(20)
diff --git a/drivers/phy/hisilicon/phy-hi6220-usb.c b/drivers/phy/hisilicon/phy-hi6220-usb.c
index 22d8d8a8dabe..1b5a2d3e3e44 100644
--- a/drivers/phy/hisilicon/phy-hi6220-usb.c
+++ b/drivers/phy/hisilicon/phy-hi6220-usb.c
@@ -8,9 +8,10 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define SC_PERIPH_CTRL4 0x00c
#define CTRL4_PICO_SIDDQ BIT(6)
diff --git a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
index c843923252aa..4a4701d0fc9c 100644
--- a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
+++ b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c
@@ -10,10 +10,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
+#include <linux/phy/phy.h> /* for phy_set_bus_width() */
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define INNO_PHY_PORT_NUM 2
#define REF_CLK_STABLE_TIME 100 /* unit:us */
#define UTMI_CLK_STABLE_TIME 200 /* unit:us */
diff --git a/drivers/phy/hisilicon/phy-histb-combphy.c b/drivers/phy/hisilicon/phy-histb-combphy.c
index 9dd0bd00b4e4..9b6ed1644d74 100644
--- a/drivers/phy/hisilicon/phy-histb-combphy.c
+++ b/drivers/phy/hisilicon/phy-histb-combphy.c
@@ -14,12 +14,13 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
+
#define COMBPHY_MODE_PCIE 0
#define COMBPHY_MODE_USB3 1
#define COMBPHY_MODE_SATA 2
diff --git a/drivers/phy/hisilicon/phy-hix5hd2-sata.c b/drivers/phy/hisilicon/phy-hix5hd2-sata.c
index 1b26ddb4c8a7..57994f69417d 100644
--- a/drivers/phy/hisilicon/phy-hix5hd2-sata.c
+++ b/drivers/phy/hisilicon/phy-hix5hd2-sata.c
@@ -9,10 +9,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define SATA_PHY0_CTLL 0xa0
#define MPLL_MULTIPLIER_SHIFT 1
#define MPLL_MULTIPLIER_MASK 0xfe
diff --git a/drivers/phy/ingenic/phy-ingenic-usb.c b/drivers/phy/ingenic/phy-ingenic-usb.c
index 7e62d46850fd..d656f97729c4 100644
--- a/drivers/phy/ingenic/phy-ingenic-usb.c
+++ b/drivers/phy/ingenic/phy-ingenic-usb.c
@@ -12,10 +12,11 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include "../phy-provider.h"
+
/* OTGPHY register offsets */
#define REG_USBPCR_OFFSET 0x00
#define REG_USBRDT_OFFSET 0x04
diff --git a/drivers/phy/intel/phy-intel-keembay-emmc.c b/drivers/phy/intel/phy-intel-keembay-emmc.c
index 0eb11ac7c2e2..fdba1d050439 100644
--- a/drivers/phy/intel/phy-intel-keembay-emmc.c
+++ b/drivers/phy/intel/phy-intel-keembay-emmc.c
@@ -11,10 +11,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* eMMC/SD/SDIO core/phy configuration registers */
#define PHY_CFG_0 0x24
#define SEL_DLY_TXCLK_MASK BIT(29)
diff --git a/drivers/phy/intel/phy-intel-keembay-usb.c b/drivers/phy/intel/phy-intel-keembay-usb.c
index c8b05f7b2445..4e690f3eb560 100644
--- a/drivers/phy/intel/phy-intel-keembay-usb.c
+++ b/drivers/phy/intel/phy-intel-keembay-usb.c
@@ -10,10 +10,11 @@
#include <linux/delay.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* USS (USB Subsystem) clock control registers */
#define USS_CPR_CLK_EN 0x00
#define USS_CPR_CLK_SET 0x04
diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c
index 9ee3cf61cdd0..2a8b0caa0e59 100644
--- a/drivers/phy/intel/phy-intel-lgm-combo.c
+++ b/drivers/phy/intel/phy-intel-lgm-combo.c
@@ -5,6 +5,7 @@
* Copyright (C) 2019-2020 Intel Corporation.
*/
+#include <dt-bindings/phy/phy.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iopoll.h>
@@ -12,12 +13,11 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <dt-bindings/phy/phy.h>
+#include "../phy-provider.h"
#define PCIE_PHY_GEN_CTRL 0x00
#define PCIE_PHY_CLK_PAD BIT(17)
diff --git a/drivers/phy/intel/phy-intel-lgm-emmc.c b/drivers/phy/intel/phy-intel-lgm-emmc.c
index 703aeb122541..479a530dd630 100644
--- a/drivers/phy/intel/phy-intel-lgm-emmc.c
+++ b/drivers/phy/intel/phy-intel-lgm-emmc.c
@@ -11,10 +11,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* eMMC phy register definitions */
#define EMMC_PHYCTRL0_REG 0xa8
#define DR_TY_MASK GENMASK(30, 28)
diff --git a/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c b/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c
index 82f1ffc0b0ad..eb6c201f7c87 100644
--- a/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c
+++ b/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c
@@ -12,12 +12,13 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
/* Transmitter HS Pre-Emphasis Enable */
#define RCU_CFG1_TX_PEE BIT(0)
/* Disconnect Threshold */
diff --git a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
index 406a87c8b759..70da76399e30 100644
--- a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
+++ b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
@@ -11,6 +11,7 @@
* TODO: PHY modes other than 36MHz (without "SSC")
*/
+#include <dt-bindings/phy/phy-lantiq-vrx200-pcie.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
@@ -18,13 +19,12 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
-#include <dt-bindings/phy/phy-lantiq-vrx200-pcie.h>
+#include "../phy-provider.h"
#define PCIE_PHY_PLL_CTRL1 0x44
diff --git a/drivers/phy/marvell/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c
index 3731f9b25655..d5c100096c3d 100644
--- a/drivers/phy/marvell/phy-armada375-usb2.c
+++ b/drivers/phy/marvell/phy-armada375-usb2.c
@@ -16,9 +16,10 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define USB2_PHY_CONFIG_DISABLE BIT(0)
struct armada375_cluster_phy {
diff --git a/drivers/phy/marvell/phy-armada38x-comphy.c b/drivers/phy/marvell/phy-armada38x-comphy.c
index 5063361b0120..9653863f90bb 100644
--- a/drivers/phy/marvell/phy-armada38x-comphy.c
+++ b/drivers/phy/marvell/phy-armada38x-comphy.c
@@ -9,10 +9,11 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define MAX_A38X_COMPHY 6
#define MAX_A38X_PORTS 3
diff --git a/drivers/phy/marvell/phy-berlin-sata.c b/drivers/phy/marvell/phy-berlin-sata.c
index c90e2867900c..4d4013d115ca 100644
--- a/drivers/phy/marvell/phy-berlin-sata.c
+++ b/drivers/phy/marvell/phy-berlin-sata.c
@@ -10,10 +10,11 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define HOST_VSA_ADDR 0x0
#define HOST_VSA_DATA 0x4
#define PORT_SCR_CTL 0x2c
diff --git a/drivers/phy/marvell/phy-berlin-usb.c b/drivers/phy/marvell/phy-berlin-usb.c
index f26bf630da2c..a3e58deaaa74 100644
--- a/drivers/phy/marvell/phy-berlin-usb.c
+++ b/drivers/phy/marvell/phy-berlin-usb.c
@@ -9,11 +9,12 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/reset.h>
+#include "../phy-provider.h"
+
#define USB_PHY_PLL 0x04
#define USB_PHY_PLL_CONTROL 0x08
#define USB_PHY_TX_CTRL0 0x10
diff --git a/drivers/phy/marvell/phy-mmp3-hsic.c b/drivers/phy/marvell/phy-mmp3-hsic.c
index 72ab6da0ebc3..90498211431b 100644
--- a/drivers/phy/marvell/phy-mmp3-hsic.c
+++ b/drivers/phy/marvell/phy-mmp3-hsic.c
@@ -7,9 +7,10 @@
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
#define HSIC_CTRL 0x08
#define HSIC_ENABLE BIT(7)
#define PLL_BYPASS BIT(4)
diff --git a/drivers/phy/marvell/phy-mmp3-usb.c b/drivers/phy/marvell/phy-mmp3-usb.c
index 5b71deb08851..ba67bcc2c3f9 100644
--- a/drivers/phy/marvell/phy-mmp3-usb.c
+++ b/drivers/phy/marvell/phy-mmp3-usb.c
@@ -8,10 +8,11 @@
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/soc/mmp/cputype.h>
+#include "../phy-provider.h"
+
#define USB2_PLL_REG0 0x4
#define USB2_PLL_REG1 0x8
#define USB2_TX_REG0 0x10
diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
index 1d1db1737422..3acfd74c3eca 100644
--- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
@@ -21,10 +21,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
+#include "../phy-provider.h"
+
#define PLL_SET_DELAY_US 600
#define COMPHY_PLL_SLEEP 1000
#define COMPHY_PLL_TIMEOUT 150000
diff --git a/drivers/phy/marvell/phy-mvebu-a3700-utmi.c b/drivers/phy/marvell/phy-mvebu-a3700-utmi.c
index 04f4fb4bed70..c17ce28ceb0b 100644
--- a/drivers/phy/marvell/phy-mvebu-a3700-utmi.c
+++ b/drivers/phy/marvell/phy-mvebu-a3700-utmi.c
@@ -14,10 +14,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* Armada 3700 UTMI PHY registers */
#define USB2_PHY_PLL_CTRL_REG0 0x0
#define PLL_REF_DIV_OFF 0
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index 71f9c14fb50d..18ad172135ea 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -13,10 +13,11 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* Relative to priv->base */
#define MVEBU_COMPHY_SERDES_CFG0(n) (0x0 + (n) * 0x1000)
#define MVEBU_COMPHY_SERDES_CFG0_PU_PLL BIT(1)
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
index dd3e515a8e86..f3e2ef54c37b 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
@@ -13,12 +13,13 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/usb/of.h>
#include <linux/usb/otg.h>
+#include "../phy-provider.h"
+
#define UTMI_PHY_PORTS 2
/* CP110 UTMI register macro definetions */
diff --git a/drivers/phy/marvell/phy-mvebu-sata.c b/drivers/phy/marvell/phy-mvebu-sata.c
index 89a5a2b69d80..b9a9eca74789 100644
--- a/drivers/phy/marvell/phy-mvebu-sata.c
+++ b/drivers/phy/marvell/phy-mvebu-sata.c
@@ -8,11 +8,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
-#include <linux/phy/phy.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
struct priv {
struct clk *clk;
void __iomem *base;
diff --git a/drivers/phy/marvell/phy-pxa-28nm-hsic.c b/drivers/phy/marvell/phy-pxa-28nm-hsic.c
index eff6dd6b2dd0..6feee8d1ca70 100644
--- a/drivers/phy/marvell/phy-pxa-28nm-hsic.c
+++ b/drivers/phy/marvell/phy-pxa-28nm-hsic.c
@@ -17,7 +17,8 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
#define PHY_28NM_HSIC_CTRL 0x08
#define PHY_28NM_HSIC_IMPCAL_CAL 0x18
diff --git a/drivers/phy/marvell/phy-pxa-28nm-usb2.c b/drivers/phy/marvell/phy-pxa-28nm-usb2.c
index 64afb82cf70e..39b8344803cb 100644
--- a/drivers/phy/marvell/phy-pxa-28nm-usb2.c
+++ b/drivers/phy/marvell/phy-pxa-28nm-usb2.c
@@ -17,7 +17,8 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
+
+#include "../phy-provider.h"
/* USB PXA1928 PHY mapping */
#define PHY_28NM_PLL_REG0 0x0
diff --git a/drivers/phy/marvell/phy-pxa-usb.c b/drivers/phy/marvell/phy-pxa-usb.c
index c0bb71f80c04..9a8ab813d001 100644
--- a/drivers/phy/marvell/phy-pxa-usb.c
+++ b/drivers/phy/marvell/phy-pxa-usb.c
@@ -10,9 +10,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
+
/* phy regs */
#define UTMI_REVISION 0x0
#define UTMI_CTRL 0x4
diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
index d7024a144335..ab3778447570 100644
--- a/drivers/phy/mediatek/phy-mtk-dp.c
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -10,10 +10,11 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
#define PHY_OFFSET 0x1000
#define MTK_DP_PHY_DIG_PLL_CTL_1 (PHY_OFFSET + 0x14)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index 1426a2db984d..30015bac3f73 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -7,7 +7,6 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy-mtk-hdmi.h
index 99d917e0036a..bfddd8dbe9dd 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
@@ -11,12 +11,13 @@
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/types.h>
+#include "../phy-provider.h"
+
struct mtk_hdmi_phy;
struct mtk_hdmi_phy_conf {
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
index 058e1d926630..5e008204ecca 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
@@ -12,10 +12,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
#include "phy-mtk-io.h"
#include "phy-mtk-mipi-csi-0-5-rx-reg.h"
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
index 5d4876f1dc95..676c8f78d9d6 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
@@ -13,9 +13,10 @@
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
-#include <linux/phy/phy.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
+
struct mtk_mipitx_data {
const u32 mppll_preserve;
const struct clk_ops *mipi_tx_clk_ops;
diff --git a/drivers/phy/mediatek/phy-mtk-pcie.c b/drivers/phy/mediatek/phy-mtk-pcie.c
index a2f69d6c72f0..1ab7c1dc2753 100644
--- a/drivers/phy/mediatek/phy-mtk-pcie.c
+++ b/drivers/phy/mediatek/phy-mtk-pcie.c
@@ -8,10 +8,10 @@
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include "../phy-provider.h"
#include "phy-mtk-io.h"
#define PEXTP_ANA_GLB_00_REG 0x9000
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index acf506529507..6f98de067327 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -15,10 +15,10 @@
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
#include "phy-mtk-io.h"
/* version V1 sub-banks offset base address */
diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c
index 0cb5a25b1b7a..de517fcc4f3e 100644
--- a/drivers/phy/mediatek/phy-mtk-ufs.c
+++ b/drivers/phy/mediatek/phy-mtk-ufs.c
@@ -9,9 +9,9 @@
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include "../phy-provider.h"
#include "phy-mtk-io.h"
/* mphy register and offsets */
diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
index 100a50d0e861..036a4bb58dcf 100644
--- a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
@@ -17,8 +17,8 @@
#include <linux/clk.h>
#include <linux/reset.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
+#include "../phy-provider.h"
#include "phy-mtk-io.h"
#define MTK_XFI_TPHY_NUM_CLOCKS 2
diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c
index c0ddb9273cc3..5e61abddaf54 100644
--- a/drivers/phy/mediatek/phy-mtk-xsphy.c
+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
@@ -14,10 +14,10 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
#include "phy-mtk-io.h"
/* u2 phy banks */
diff --git a/drivers/phy/microchip/lan966x_serdes.c b/drivers/phy/microchip/lan966x_serdes.c
index 835e369cdfc5..8769518f9708 100644
--- a/drivers/phy/microchip/lan966x_serdes.c
+++ b/drivers/phy/microchip/lan966x_serdes.c
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <dt-bindings/phy/phy-lan966x-serdes.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
-#include <dt-bindings/phy/phy-lan966x-serdes.h>
#include "lan966x_serdes_regs.h"
+#include "../phy-provider.h"
#define PLL_CONF_MASK GENMASK(4, 3)
#define PLL_CONF_25MHZ 0
diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 320cf5b50a8c..09c22a6a2639 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -17,8 +17,8 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
+#include "../phy-provider.h"
#include "sparx5_serdes.h"
#define SPX5_SERDES_10G_START 13
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
index 7cb020dd3423..66a834c208fc 100644
--- a/drivers/phy/motorola/phy-cpcap-usb.c
+++ b/drivers/phy/motorola/phy-cpcap-usb.c
@@ -24,10 +24,11 @@
#include <linux/gpio/consumer.h>
#include <linux/mfd/motorola-cpcap.h>
#include <linux/phy/omap_usb.h>
-#include <linux/phy/phy.h>
#include <linux/regulator/consumer.h>
#include <linux/usb/musb.h>
+#include "../phy-provider.h"
+
/* CPCAP_REG_USBC1 register bits */
#define CPCAP_BIT_IDPULSE BIT(15)
#define CPCAP_BIT_ID100KPU BIT(14)
diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c
index ce1dad8c438d..92f63e52bd1d 100644
--- a/drivers/phy/motorola/phy-mapphone-mdm6600.c
+++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c
@@ -15,10 +15,12 @@
#include <linux/gpio/consumer.h>
#include <linux/of_platform.h>
-#include <linux/phy/phy.h>
+#include <linux/phy/phy.h> /* for phy_pm_runtime_*() */
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
+#include "../phy-provider.h"
+
#define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */
#define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */
#define PHY_MDM6600_WAKE_KICK_MS 600 /* time on after GPIO toggle */
diff --git a/drivers/phy/mscc/phy-ocelot-serdes.c b/drivers/phy/mscc/phy-ocelot-serdes.c
index 1cd1b5db2ad7..13f83876d954 100644
--- a/drivers/phy/mscc/phy-ocelot-serdes.c
+++ b/drivers/phy/mscc/phy-ocelot-serdes.c
@@ -12,12 +12,13 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <soc/mscc/ocelot_hsio.h>
#include <dt-bindings/phy/phy-ocelot-serdes.h>
+#include "../phy-provider.h"
+
struct serdes_ctrl {
struct regmap *regs;
struct device *dev;
diff --git a/drivers/phy/nuvoton/phy-ma35d1-usb2.c b/drivers/phy/nuvoton/phy-ma35d1-usb2.c
index 9a459b700ed4..520c86188fe2 100644
--- a/drivers/phy/nuvoton/phy-ma35d1-usb2.c
+++ b/drivers/phy/nuvoton/phy-ma35d1-usb2.c
@@ -10,10 +10,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "../phy-provider.h"
+
/* USB PHY Miscellaneous Control Register */
#define MA35_SYS_REG_USBPMISCR 0x60
#define PHY0POR BIT(0) /* PHY Power-On Reset Control Bit */
diff --git a/drivers/phy/phy-airoha-pcie.c b/drivers/phy/phy-airoha-pcie.c
index 56e9ade8a9fd..d9817eed2631 100644
--- a/drivers/phy/phy-airoha-pcie.c
+++ b/drivers/phy/phy-airoha-pcie.c
@@ -9,11 +9,11 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "phy-airoha-pcie-regs.h"
+#include "phy-provider.h"
#define LEQ_LEN_CTRL_MAX_VAL 7
#define FREQ_LOCK_MAX_ATTEMPT 10
diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 2b52e47f247a..68f771a7bad7 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -6,13 +6,14 @@
*
*/
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/mux/consumer.h>
+#include "phy-provider.h"
+
struct can_transceiver_data {
u32 flags;
#define CAN_TRANSCEIVER_STB_PRESENT BIT(0)
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index f4956a417a47..770cfe2a2279 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -4,13 +4,13 @@
* Copyright (C) 2018 Cadence Design Systems Inc.
*/
+#include <linux/phy/phy-mipi-dphy.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/time64.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
+#include "phy-provider.h"
/*
* Minimum D-PHY timings based on MIPI D-PHY specification. Derived
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 737a760d97d1..02af89ee64a3 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -20,6 +20,8 @@
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include "phy-provider.h"
+
#define to_phy(a) (container_of((a), struct phy, dev))
/**
diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
index 48cfa2e28347..539732f4869e 100644
--- a/drivers/phy/phy-google-usb.c
+++ b/drivers/phy/phy-google-usb.c
@@ -14,13 +14,14 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/usb/typec_mux.h>
+#include "phy-provider.h"
+
#define USBCS_USB2PHY_CFG19_OFFSET 0x0
#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
diff --git a/drivers/phy/phy-lpc18xx-usb-otg.c b/drivers/phy/phy-lpc18xx-usb-otg.c
index f905d3c64584..554dfa55fe7e 100644
--- a/drivers/phy/phy-lpc18xx-usb-otg.c
+++ b/drivers/phy/phy-lpc18xx-usb-otg.c
@@ -10,10 +10,11 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include "phy-provider.h"
+
/* USB OTG PHY register offset and bit in CREG */
#define LPC18XX_CREG_CREG0 0x004
#define LPC18XX_CREG_CREG0_USB0PHY BIT(5)
diff --git a/drivers/phy/phy-nxp-ptn3222.c b/drivers/phy/phy-nxp-ptn3222.c
index c6179d8701e6..ae75b760a30d 100644
--- a/drivers/phy/phy-nxp-ptn3222.c
+++ b/drivers/phy/phy-nxp-ptn3222.c
@@ -7,10 +7,11 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include "phy-provider.h"
+
#define NUM_SUPPLIES 2
struct ptn3222 {
diff --git a/drivers/phy/phy-pistachio-usb.c b/drivers/phy/phy-pistachio-usb.c
index 231792f48ced..8eed6f505a31 100644
--- a/drivers/phy/phy-pistachio-usb.c
+++ b/drivers/phy/phy-pistachio-usb.c
@@ -5,6 +5,7 @@
* Copyright (C) 2015 Google, Inc.
*/
+#include <dt-bindings/phy/phy-pistachio-usb.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -12,11 +13,10 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
-#include <dt-bindings/phy/phy-pistachio-usb.h>
+#include "phy-provider.h"
#define USB_PHY_CONTROL1 0x04
#define USB_PHY_CONTROL1_FSEL_SHIFT 2
diff --git a/drivers/phy/phy-snps-eusb2.c b/drivers/phy/phy-snps-eusb2.c
index f90bf7e95463..9062737bfad4 100644
--- a/drivers/phy/phy-snps-eusb2.c
+++ b/drivers/phy/phy-snps-eusb2.c
@@ -13,6 +13,8 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
+#include "phy-provider.h"
+
#define EXYNOS_USB_PHY_HS_PHY_CTRL_RST (0x0)
#define USB_PHY_RST_MASK GENMASK(1, 0)
#define UTMI_PORT_RST_MASK GENMASK(5, 4)
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c
index 5007dc7a357c..90a00498ec0a 100644
--- a/drivers/phy/phy-xgene.c
+++ b/drivers/phy/phy-xgene.c
@@ -43,9 +43,10 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/delay.h>
-#include <linux/phy/phy.h>
#include <linux/clk.h>
+#include "phy-provider.h"
+
/* Max 2 lanes per a PHY unit */
#define MAX_LANE 2
--
2.34.1
^ permalink raw reply related
* [PATCH v7 phy-next 22/27] pinctrl: tegra-xusb: include PHY provider header
From: Vladimir Oltean @ 2026-04-30 11:06 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, Linus Walleij, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski
In-Reply-To: <20260430110652.558622-1-vladimir.oltean@nxp.com>
The tegra-xusb pinctrl driver is also a PHY provider (calls
devm_phy_create() for PCIe and SATA). However, according to Vinod Koul,
having PHY provider drivers outside of drivers/phy/ is discouraged,
although it would be difficult for me to address a proper movement here.
Include the private provider API header from drivers/phy/, but leave a
FIXME in place. It will have to be moved, eventually.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
---
Cc: Linus Walleij <linusw@kernel.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
v2->v7: none
v1->v2: collect tag
---
drivers/pinctrl/tegra/pinctrl-tegra-xusb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
index c6a51bb21215..6b609bf685c7 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
@@ -7,7 +7,6 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/seq_file.h>
@@ -19,6 +18,7 @@
#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+#include "../../phy/phy-provider.h" /* FIXME */
#include "../core.h"
#include "../pinctrl-utils.h"
--
2.34.1
^ permalink raw reply related
* [PATCH] mailbox: exynos: Drop unused register definitions
From: Tudor Ambarus @ 2026-04-30 11:12 UTC (permalink / raw)
To: Jassi Brar, Krzysztof Kozlowski, Alim Akhtar
Cc: alexey.klimov, linux-kernel, linux-samsung-soc, linux-arm-kernel,
Tudor Ambarus
Leaving these dead definitions in place hides which registers are
actually being used by the hardware, making the driver harder to read
and maintain. Remove them to clean up the file.
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/mailbox/exynos-mailbox.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
index 5f2d3b81c1db..953e715a89b1 100644
--- a/drivers/mailbox/exynos-mailbox.c
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -16,15 +16,8 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
-#define EXYNOS_MBOX_MCUCTRL 0x0 /* Mailbox Control Register */
-#define EXYNOS_MBOX_INTCR0 0x24 /* Interrupt Clear Register 0 */
#define EXYNOS_MBOX_INTMR0 0x28 /* Interrupt Mask Register 0 */
-#define EXYNOS_MBOX_INTSR0 0x2c /* Interrupt Status Register 0 */
-#define EXYNOS_MBOX_INTMSR0 0x30 /* Interrupt Mask Status Register 0 */
#define EXYNOS_MBOX_INTGR1 0x40 /* Interrupt Generation Register 1 */
-#define EXYNOS_MBOX_INTMR1 0x48 /* Interrupt Mask Register 1 */
-#define EXYNOS_MBOX_INTSR1 0x4c /* Interrupt Status Register 1 */
-#define EXYNOS_MBOX_INTMSR1 0x50 /* Interrupt Mask Status Register 1 */
#define EXYNOS_MBOX_INTMR0_MASK GENMASK(15, 0)
#define EXYNOS_MBOX_INTGR1_MASK GENMASK(15, 0)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260430-exynos-mbox-dead-def-e019a9ccce3f
Best regards,
--
Tudor Ambarus <tudor.ambarus@linaro.org>
^ permalink raw reply related
* [PATCH v1 00/12] KVM Dirty-bit cleaning accelerator (HACDBS)
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
This patchset intends to create an arm64-specific dirty-bit cleaning
accelerator based on HACDBS. To do so, it's needed to add a few
snippets in arch-generic kvm code, and to do so properly, it makes
them compile-out if the arch does not implement them.
Patch 1 & 2 are here just to make this testable, as this patchset
depends on bits from HDBSS that are not upstream yet.
Patch 1 should be included in the HDBSS patchset, and patch 2
is a bunch of bits that I collected across other patches so this can
work. So few free to ignore them.
To be able to properly use HACDBS, it requires a PPI IRQ that triggers
either on error, or when processing is complete. It's called
HACDBSIRQ, and there is currently no upstream way of announcing it on
ACPI tables, so it uses the suggested table/index in [1].
It is able to accelerate the cleaning on both dirty-bitmap and
dirty-ring tracking mechanisms on KVM, and that require different
functions to be made accessible outside KVM code.
On top of finding issues, there are a few questions I would like help with:
a - Is the distribution between patches ok? should I merge or split
any of them?
b - checkpatch.pl keeps bothering me to add an entry in MAINTAINERS file,
and I like the idea of maintaining this. Is there any rule or
common sense on this? Should I add this entry, or should I leave it
in the arch/arm64/kvm/ general rule?
c - There are some trace_prink() I have left in the code, as they could
be helpful to check when HACDBS is not performing as well as it
should. Should I introduce a tracepoint instead? or just ignore it?
(it's triggered on HACDBS error, but as it falls back to software in
that case, it should not impact correctness, only performance).
d - In __kvm_arch_dirty_log_clear() there is no way to predict how long
should be the buffer, so I used 1x PAGE_SIZE, and when it gets full
it's cleaned and reused. Should I let users configure that over a
parameter, or is it overthinking?
Kernel v7.0.0 + this patchset builds properly, passing both kvm selftests
for dirty-bit tracking[2], on HW HACDBS enabled or disabled.
Please let me know of any question :)
Thanks for reviewing!
Leo
[1]: https://github.com/tianocore/edk2/issues/12409
[2]: dirty_log_test && dirty_log_perf_test
Leonardo Bras (12):
KVM: arm64: Enable eager hugepage splitting if HDBSS is available
KVM: arm64: HDBSS bits
arm64/cpufeature: Add system-wide FEAT_HACDBS detection
arm64/sysreg: Add HACDBS consumer and base registers
KVM: arm64: Detect (via ACPI) and initialize HACDBSIRQ
KVM: arm64: dirty_bit: Add base FEAT_HACDBS cleaning routine
kvm: Add arch-generic interface for hw-accelerated dirty-bitmap
cleaning
KVM: arm64: Add hardware-accelerated dirty-bitmap cleaning routine
kvm/dirty_ring: Introduce get_memslot and move helpers to header
kvm/dirty_ring: Add arch-generic interface for hw-accelerated
dirty-ring cleaning
KVM: arm64: Add hardware-accelerated dirty-ring cleaning routine
KVM: arm64: Enable KVM_HW_DIRTY_BIT
MAINTAINERS | 7 +
arch/arm64/include/asm/acpi.h | 3 +
arch/arm64/include/asm/cpufeature.h | 10 +
arch/arm64/include/asm/kvm_dirty_bit.h | 67 ++++
arch/arm64/include/asm/kvm_pgtable.h | 3 +
include/acpi/actbl2.h | 1 +
include/linux/kvm_dirty_bit.h | 34 ++
include/linux/kvm_dirty_ring.h | 12 +
include/linux/kvm_host.h | 3 +
arch/arm64/kernel/cpufeature.c | 20 ++
arch/arm64/kvm/arm.c | 5 +
arch/arm64/kvm/dirty_bit.c | 418 +++++++++++++++++++++++++
arch/arm64/kvm/hyp/pgtable.c | 15 +-
arch/arm64/kvm/mmu.c | 12 +-
virt/kvm/dirty_ring.c | 34 +-
virt/kvm/kvm_main.c | 13 +-
arch/arm64/kvm/Kconfig | 1 +
arch/arm64/kvm/Makefile | 2 +-
arch/arm64/tools/cpucaps | 2 +
arch/arm64/tools/sysreg | 30 ++
virt/kvm/Kconfig | 3 +
21 files changed, 673 insertions(+), 22 deletions(-)
create mode 100644 arch/arm64/include/asm/kvm_dirty_bit.h
create mode 100644 include/linux/kvm_dirty_bit.h
create mode 100644 arch/arm64/kvm/dirty_bit.c
--
2.54.0
^ permalink raw reply
* [PATCH v1 01/12] KVM: arm64: Enable eager hugepage splitting if HDBSS is available
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
FEAT_HDBSS speeds up guest memory dirty tracking by avoiding a page fault
and saving the entry in a tracking structure.
That may be a problem when we have guest memory backed by hugepages or
transparent huge pages, as it's not possible to do on-demand hugepage
splitting, relying only on eager hugepage splitting.
So, at stage2 initialization, enable eager hugepage splitting with
chunk = PAGE_SIZE if the system supports HDBSS.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/kvm/mmu.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d089c107d9b7..42c734423253 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -993,22 +993,26 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
mmu->last_vcpu_ran = alloc_percpu(typeof(*mmu->last_vcpu_ran));
if (!mmu->last_vcpu_ran) {
err = -ENOMEM;
goto out_destroy_pgtable;
}
for_each_possible_cpu(cpu)
*per_cpu_ptr(mmu->last_vcpu_ran, cpu) = -1;
- /* The eager page splitting is disabled by default */
- mmu->split_page_chunk_size = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
+ /* The eager page splitting is disabled by default if system has no HDBSS */
+ if (system_supports_hacdbs())
+ mmu->split_page_chunk_size = PAGE_SIZE;
+ else
+ mmu->split_page_chunk_size = KVM_ARM_EAGER_SPLIT_CHUNK_SIZE_DEFAULT;
+
mmu->split_page_cache.gfp_zero = __GFP_ZERO;
mmu->pgd_phys = __pa(pgt->pgd);
if (kvm_is_nested_s2_mmu(kvm, mmu))
kvm_init_nested_s2_mmu(mmu);
return 0;
out_destroy_pgtable:
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] pinctrl: mediatek: eint: Drop base from mtk_eint_chip_write_mask()
From: Linus Walleij @ 2026-04-30 11:15 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Sean Wang, Matthias Brugger, AngeloGioacchino Del Regno,
linux-mediatek, linux-gpio, linux-arm-kernel, linux-kernel,
Hao Chang, Qingliang Li
In-Reply-To: <20260427021148.2049555-1-wenst@chromium.org>
On Mon, Apr 27, 2026 at 4:11 AM Chen-Yu Tsai <wenst@chromium.org> wrote:
> When support for multiple EINT base addresses was added in commit
> 3ef9f710efcb ("pinctrl: mediatek: Add EINT support for multiple
> addresses"), mtk_eint_chip_write_mask() was changed to write interrupt
> masks for all base addresses in one call. However the "base" parameter
> was left around and now causes sparse warnings:
>
> mtk-eint.c:428:44: warning: incorrect type in argument 2 (different address spaces)
> mtk-eint.c:428:44: expected void [noderef] __iomem *base
> mtk-eint.c:428:44: got void [noderef] __iomem **base
> mtk-eint.c:436:44: warning: incorrect type in argument 2 (different address spaces)
> mtk-eint.c:436:44: expected void [noderef] __iomem *base
> mtk-eint.c:436:44: got void [noderef] __iomem **base
>
> Since the "base" parameter is no longer needed, just drop it.
>
> Fixes: 3ef9f710efcb ("pinctrl: mediatek: Add EINT support for multiple addresses")
> Cc: Hao Chang <ot_chhao.chang@mediatek.com>
> Cc: Qingliang Li <qingliang.li@mediatek.com>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Patch applied because looks correct!
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v1 02/12] KVM: arm64: HDBSS bits
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
All those bits should come from a future version of HDBSS patchset:
https://lore.kernel.org/lkml/20260225040421.2683931-1-zhengtian10@huawei.com
I added them here in order to fulfill the dependencies and be able to
easily build this patchset, but this particular patch should not be merged
upstream.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 5 +++++
arch/arm64/include/asm/kvm_dirty_bit.h | 12 ++++++++++++
arch/arm64/include/asm/kvm_pgtable.h | 3 +++
arch/arm64/kernel/cpufeature.c | 12 ++++++++++++
arch/arm64/kvm/dirty_bit.c | 23 +++++++++++++++++++++++
arch/arm64/kvm/hyp/pgtable.c | 15 +++++++++++++--
arch/arm64/kvm/Makefile | 2 +-
arch/arm64/tools/cpucaps | 1 +
8 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 arch/arm64/include/asm/kvm_dirty_bit.h
create mode 100644 arch/arm64/kvm/dirty_bit.c
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 4de51f8d92cb..dcc2e2cad5ad 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -849,20 +849,25 @@ static inline bool system_supports_poe(void)
static inline bool system_supports_gcs(void)
{
return alternative_has_cap_unlikely(ARM64_HAS_GCS);
}
static inline bool system_supports_haft(void)
{
return cpus_have_final_cap(ARM64_HAFT);
}
+static inline bool system_supports_hdbss(void)
+{
+ return cpus_have_final_cap(ARM64_HAS_HDBSS);
+}
+
static __always_inline bool system_supports_mpam(void)
{
return alternative_has_cap_unlikely(ARM64_MPAM);
}
static __always_inline bool system_supports_mpam_hcr(void)
{
return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
}
diff --git a/arch/arm64/include/asm/kvm_dirty_bit.h b/arch/arm64/include/asm/kvm_dirty_bit.h
new file mode 100644
index 000000000000..dd16438f0651
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_dirty_bit.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 ARM Ltd.
+ * Author: Leonardo Bras <leo.bras@arm.com>
+ */
+
+#ifndef __ARM64_KVM_DIRTY_BIT_H__
+#define __ARM64_KVM_DIRTY_BIT_H__
+
+#include <asm/kvm_pgtable.h>
+
+#endif /* __ARM64_KVM_DIRTY_BIT_H__ */
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 41a8687938eb..646ff88e0258 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -86,20 +86,22 @@ typedef u64 kvm_pte_t;
#define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 50)
#define KVM_PTE_LEAF_ATTR_HI_SW GENMASK(58, 55)
#define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54)
#define KVM_PTE_LEAF_ATTR_HI_S1_UXN BIT(54)
#define KVM_PTE_LEAF_ATTR_HI_S1_PXN BIT(53)
#define KVM_PTE_LEAF_ATTR_HI_S2_XN GENMASK(54, 53)
+#define KVM_PTE_LEAF_ATTR_HI_S2_DBM BIT(51)
+
#define KVM_PTE_LEAF_ATTR_HI_S1_GP BIT(50)
#define KVM_PTE_LEAF_ATTR_S2_PERMS (KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
KVM_PTE_LEAF_ATTR_HI_S2_XN)
/* pKVM invalid pte encodings */
#define KVM_INVALID_PTE_TYPE_MASK GENMASK(63, 60)
#define KVM_INVALID_PTE_ANNOT_MASK ~(KVM_PTE_VALID | \
KVM_INVALID_PTE_TYPE_MASK)
@@ -246,20 +248,21 @@ struct kvm_pgtable_mm_ops {
};
/**
* enum kvm_pgtable_stage2_flags - Stage-2 page-table flags.
* @KVM_PGTABLE_S2_IDMAP: Only use identity mappings.
* @KVM_PGTABLE_S2_AS_S1: Final memory attributes are that of Stage-1.
*/
enum kvm_pgtable_stage2_flags {
KVM_PGTABLE_S2_IDMAP = BIT(0),
KVM_PGTABLE_S2_AS_S1 = BIT(1),
+ KVM_PGTABLE_S2_DBM = BIT(2),
};
/**
* enum kvm_pgtable_prot - Page-table permissions and attributes.
* @KVM_PGTABLE_PROT_UX: Unprivileged execute permission.
* @KVM_PGTABLE_PROT_PX: Privileged execute permission.
* @KVM_PGTABLE_PROT_X: Privileged and unprivileged execute permission.
* @KVM_PGTABLE_PROT_W: Write permission.
* @KVM_PGTABLE_PROT_R: Read permission.
* @KVM_PGTABLE_PROT_DEVICE: Device attributes.
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6d53bb15cf7b..eac7784463e3 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2112,20 +2112,25 @@ static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap,
return true;
}
static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
int __unused)
{
return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE);
}
+static bool has_vhe_hdbss(const struct arm64_cpu_capabilities *entry, int cope)
+{
+ return is_kernel_in_hyp_mode() && has_cpuid_feature(entry, cope);
+}
+
bool cpu_supports_bbml2_noabort(void)
{
/*
* We want to allow usage of BBML2 in as wide a range of kernel contexts
* as possible. This list is therefore an allow-list of known-good
* implementations that both support BBML2 and additionally, fulfill the
* extra constraint of never generating TLB conflict aborts when using
* the relaxed BBML2 semantics (such aborts make use of BBML2 in certain
* kernel contexts difficult to prove safe against recursive aborts).
*
@@ -2762,20 +2767,27 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
* cannot be emulated in software (no access fault will occur).
* Therefore this should be used only if it's supported system
* wide.
*/
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.capability = ARM64_HAFT,
.matches = has_cpuid_feature,
ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HAFT)
},
#endif
+ {
+ .desc = "Hardware Dirty state tracking structure (HDBSS)",
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .capability = ARM64_HAS_HDBSS,
+ .matches = has_vhe_hdbss,
+ ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, HDBSS)
+ },
{
.desc = "CRC32 instructions",
.capability = ARM64_HAS_CRC32,
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.matches = has_cpuid_feature,
ARM64_CPUID_FIELDS(ID_AA64ISAR0_EL1, CRC32, IMP)
},
{
.desc = "Speculative Store Bypassing Safe (SSBS)",
.capability = ARM64_SSBS,
diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
new file mode 100644
index 000000000000..31ef35f3b72f
--- /dev/null
+++ b/arch/arm64/kvm/dirty_bit.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 ARM Ltd.
+ * Author: Leonardo Bras <leo.bras@arm.com>
+ */
+
+#include <asm/kvm_dirty_bit.h>
+
+/* HDBSS entry field definitions */
+#define HDBSS_ENTRY_VALID BIT(0)
+#define HDBSS_ENTRY_TTWL_SHIFT (1)
+#define HDBSS_ENTRY_TTWL_MASK (GENMASK(3, 1))
+#define HDBSS_ENTRY_TTWL(x) \
+ (((x) << HDBSS_ENTRY_TTWL_SHIFT) & HDBSS_ENTRY_TTWL_MASK)
+#define HDBSS_ENTRY_TTWL_RESV HDBSS_ENTRY_TTWL(-4)
+#define HDBSS_ENTRY_IPA GENMASK_ULL(55, 12)
+
+inline u64 hdbss_get_ttwl(u64 chunk_size)
+{
+ u64 hw_lvl = ARM64_HW_PGTABLE_LEVELS(ilog2(chunk_size));
+
+ return HDBSS_ENTRY_TTWL(3 - hw_lvl);
+}
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 0c1defa5fb0f..68ade2623748 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -724,23 +724,27 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
attr = KVM_S2_MEMATTR(pgt, NORMAL);
}
r = stage2_set_xn_attr(prot, &attr);
if (r)
return r;
if (prot & KVM_PGTABLE_PROT_R)
attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
- if (prot & KVM_PGTABLE_PROT_W)
+ if (prot & KVM_PGTABLE_PROT_W) {
attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
+ if (pgt->flags & KVM_PGTABLE_S2_DBM)
+ attr |= KVM_PTE_LEAF_ATTR_HI_S2_DBM;
+ }
+
if (!kvm_lpa2_is_enabled())
attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh);
attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF;
attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW;
*ptep = attr;
return 0;
}
@@ -1358,23 +1362,27 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
kvm_pte_t xn = 0, set = 0, clr = 0;
s8 level;
int ret;
if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
return -EINVAL;
if (prot & KVM_PGTABLE_PROT_R)
set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
- if (prot & KVM_PGTABLE_PROT_W)
+ if (prot & KVM_PGTABLE_PROT_W) {
set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
+ if (pgt->flags & KVM_PGTABLE_S2_DBM)
+ set |= KVM_PTE_LEAF_ATTR_HI_S2_DBM;
+ }
+
ret = stage2_set_xn_attr(prot, &xn);
if (ret)
return ret;
set |= xn & KVM_PTE_LEAF_ATTR_HI_S2_XN;
clr |= ~xn & KVM_PTE_LEAF_ATTR_HI_S2_XN;
ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags);
if (!ret || ret == -EAGAIN)
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr, level);
@@ -1576,20 +1584,23 @@ int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
u64 vtcr = mmu->vtcr;
u32 ia_bits = VTCR_EL2_IPA(vtcr);
u32 sl0 = FIELD_GET(VTCR_EL2_SL0_MASK, vtcr);
s8 start_level = VTCR_EL2_TGRAN_SL0_BASE - sl0;
pgd_sz = kvm_pgd_pages(ia_bits, start_level) * PAGE_SIZE;
pgt->pgd = (kvm_pteref_t)mm_ops->zalloc_pages_exact(pgd_sz);
if (!pgt->pgd)
return -ENOMEM;
+ if (system_supports_hdbss())
+ flags |= KVM_PGTABLE_S2_DBM;
+
pgt->ia_bits = ia_bits;
pgt->start_level = start_level;
pgt->mm_ops = mm_ops;
pgt->mmu = mmu;
pgt->flags = flags;
pgt->force_pte_cb = force_pte_cb;
/* Ensure zeroed PGD pages are visible to the hardware walker */
dsb(ishst);
return 0;
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 59612d2f277c..6faacd857346 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -17,21 +17,21 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
inject_fault.o va_layout.o handle_exit.o config.o \
guest.o debug.o reset.o sys_regs.o stacktrace.o \
vgic-sys-reg-v3.o fpsimd.o pkvm.o \
arch_timer.o trng.o vmid.o emulate-nested.o nested.o at.o \
vgic/vgic.o vgic/vgic-init.o \
vgic/vgic-irqfd.o vgic/vgic-v2.o \
vgic/vgic-v3.o vgic/vgic-v4.o \
vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
vgic/vgic-its.o vgic/vgic-debug.o vgic/vgic-v3-nested.o \
- vgic/vgic-v5.o
+ vgic/vgic-v5.o dirty_bit.o
kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o pmu.o
kvm-$(CONFIG_ARM64_PTR_AUTH) += pauth.o
kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
kvm-$(CONFIG_NVHE_EL2_TRACING) += hyp_trace.o
always-y := hyp_constants.h hyp-constants.s
define rule_gen_hyp_constants
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 811c2479e82d..6bd563e0bc62 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -62,20 +62,21 @@ HAS_RASV1P1_EXTN
HAS_RNG
HAS_SB
HAS_STAGE2_FWB
HAS_TCR2
HAS_TIDCP1
HAS_TLB_RANGE
HAS_VA52
HAS_VIRT_HOST_EXTN
HAS_WFXT
HAS_XNX
+HAS_HDBSS
HAFT
HW_DBM
KVM_HVHE
KVM_PROTECTED_MODE
MISMATCHED_CACHE_TYPE
MPAM
MPAM_HCR
MTE
MTE_ASYMM
MTE_FAR
--
2.54.0
^ permalink raw reply related
* [PATCH v1 03/12] arm64/cpufeature: Add system-wide FEAT_HACDBS detection
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
FEAT_HACDBS will only be used for dirty-bit cleaning if it is detected in
all running cpus.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 5 +++++
arch/arm64/kernel/cpufeature.c | 8 ++++++++
arch/arm64/tools/cpucaps | 1 +
3 files changed, 14 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index dcc2e2cad5ad..5d438a00e0ff 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -854,20 +854,25 @@ static inline bool system_supports_gcs(void)
static inline bool system_supports_haft(void)
{
return cpus_have_final_cap(ARM64_HAFT);
}
static inline bool system_supports_hdbss(void)
{
return cpus_have_final_cap(ARM64_HAS_HDBSS);
}
+static inline bool system_supports_hacdbs(void)
+{
+ return cpus_have_final_cap(ARM64_HACDBS);
+}
+
static __always_inline bool system_supports_mpam(void)
{
return alternative_has_cap_unlikely(ARM64_MPAM);
}
static __always_inline bool system_supports_mpam_hcr(void)
{
return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
}
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index eac7784463e3..95b92060cae1 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -512,20 +512,21 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {
FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_S1POE_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_S1PIE_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_SCTLRX_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_TCRX_SHIFT, 4, 0),
ARM64_FTR_END,
};
static const struct arm64_ftr_bits ftr_id_aa64mmfr4[] = {
S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_E2H0_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_NV_frac_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_HACDBS_SHIFT, 4, 0),
ARM64_FTR_END,
};
static const struct arm64_ftr_bits ftr_ctr[] = {
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_EL0_DIC_SHIFT, 1, 1),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_EL0_IDC_SHIFT, 1, 1),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, CTR_EL0_CWG_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, CTR_EL0_ERG_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_EL0_DminLine_SHIFT, 4, 1),
@@ -2752,20 +2753,27 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "Hardware dirty bit management",
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
.capability = ARM64_HW_DBM,
.matches = has_hw_dbm,
.cpu_enable = cpu_enable_hw_dbm,
.cpus = &dbm_cpus,
ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, HAFDBS, DBM)
},
#endif
+ {
+ .desc = "Hardware dirty bit Cleaning",
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .capability = ARM64_HACDBS,
+ .matches = has_cpuid_feature,
+ ARM64_CPUID_FIELDS(ID_AA64MMFR4_EL1, HACDBS, IMP)
+ },
#ifdef CONFIG_ARM64_HAFT
{
.desc = "Hardware managed Access Flag for Table Descriptors",
/*
* Contrary to the page/block access flag, the table access flag
* cannot be emulated in software (no access fault will occur).
* Therefore this should be used only if it's supported system
* wide.
*/
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 6bd563e0bc62..cd53cec79d34 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -65,20 +65,21 @@ HAS_STAGE2_FWB
HAS_TCR2
HAS_TIDCP1
HAS_TLB_RANGE
HAS_VA52
HAS_VIRT_HOST_EXTN
HAS_WFXT
HAS_XNX
HAS_HDBSS
HAFT
HW_DBM
+HACDBS
KVM_HVHE
KVM_PROTECTED_MODE
MISMATCHED_CACHE_TYPE
MPAM
MPAM_HCR
MTE
MTE_ASYMM
MTE_FAR
MTE_STORE_ONLY
SME
--
2.54.0
^ permalink raw reply related
* [PATCH v1 04/12] arm64/sysreg: Add HACDBS consumer and base registers
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
They will be used on a later commit to make use of the FEAT_HACDBS
mechanism if available.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/tools/sysreg | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 6c3ff14e561e..7ad392a5c436 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -4582,20 +4582,50 @@ EndEnum
Enum 9:8 IRGN0
0b00 NC
0b01 WBWA
0b10 WT
0b11 WBnWA
EndEnum
Field 7:6 SL0
Field 5:0 T0SZ
EndSysreg
+Sysreg HACDBSBR_EL2 3 4 2 3 4
+Res0 63:56
+Field 55:12 BADDR
+Field 11 EN
+Res0 10:4
+UnsignedEnum 3:0 SZ
+ 0b0000 4K
+ 0b0001 8K
+ 0b0010 16K
+ 0b0011 32K
+ 0b0100 64K
+ 0b0101 128K
+ 0b0110 256K
+ 0b0111 512K
+ 0b1000 1M
+ 0b1001 2M
+EndEnum
+EndSysreg
+
+Sysreg HACDBSCONS_EL2 3 4 2 3 5
+UnsignedEnum 63:62 ERR_REASON
+ 0b00 NOF
+ 0b01 STRUCTF
+ 0b10 IPAF
+ 0b11 IPAHACF
+EndEnum
+Res0 61:19
+Field 18:0 INDEX
+EndSysreg
+
Sysreg GCSCR_EL2 3 4 2 5 0
Fields GCSCR_ELx
EndSysreg
Sysreg GCSPR_EL2 3 4 2 5 1
Fields GCSPR_ELx
EndSysreg
Sysreg DACR32_EL2 3 4 3 0 0
Res0 63:32
--
2.54.0
^ permalink raw reply related
* [PATCH v1 06/12] KVM: arm64: dirty_bit: Add base FEAT_HACDBS cleaning routine
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Introduce the basic cleaning routine that is going to be used for both
dirty-bitmap and dirty-ring routines.
It sets the required registers with the input buffer, and wait for
HACDBSIRQ to happen, which means either the task is done, or there was some
error during processing.
It is ran with preemption disabled, as a task being scheduled in could
change the translation registers used by HACDBS and end up corrupting the
current dirty-bit tracking and the sched-in task's S2 pagetables.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/kvm/dirty_bit.c | 86 ++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
index 765ef609ff70..22e3ed07256a 100644
--- a/arch/arm64/kvm/dirty_bit.c
+++ b/arch/arm64/kvm/dirty_bit.c
@@ -1,17 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2026 ARM Ltd.
* Author: Leonardo Bras <leo.bras@arm.com>
*/
#include <asm/kvm_dirty_bit.h>
+#include <asm/kvm_mmu.h>
#include <linux/kconfig.h>
#include <linux/acpi.h>
DEFINE_PER_CPU(struct hacdbs, hacdbs_pcp) = {
.status = HACDBS_OFF,
.size = 0,
};
/* HDBSS entry field definitions */
#define HDBSS_ENTRY_VALID BIT(0)
@@ -24,20 +25,105 @@ DEFINE_PER_CPU(struct hacdbs, hacdbs_pcp) = {
inline u64 hdbss_get_ttwl(u64 chunk_size)
{
u64 hw_lvl = ARM64_HW_PGTABLE_LEVELS(ilog2(chunk_size));
return HDBSS_ENTRY_TTWL(3 - hw_lvl);
}
static __ro_after_init int hacdbsirq = -1;
+static void hacdbs_start(u64 *hw_entries, int size)
+{
+ u64 br;
+ /* Each entry is 8 bytes */
+ int size_b = size * sizeof(hw_entries[0]);
+ int size_p2 = max(roundup_pow_of_two(size_b), PAGE_SIZE);
+
+ /* If not using the full size of the array, put a stop entry at the end */
+ if (size_b < size_p2)
+ hw_entries[size] = HDBSS_ENTRY_VALID | HDBSS_ENTRY_TTWL_RESV;
+
+ sysreg_clear_set_s(SYS_HACDBSCONS_EL2,
+ HACDBSCONS_EL2_ERR_REASON | HACDBSCONS_EL2_INDEX, 0);
+
+ br = (virt_to_phys(hw_entries) & HACDBSBR_EL2_BADDR_MASK) |
+ FIELD_PREP(HACDBSBR_EL2_SZ, ilog2(size_p2) - 12) |
+ FIELD_PREP(HACDBSBR_EL2_EN, 1);
+
+ this_cpu_write(hacdbs_pcp.status, HACDBS_RUNNING);
+ this_cpu_write(hacdbs_pcp.size, size);
+ write_sysreg_s(br, SYS_HACDBSBR_EL2);
+ isb();
+}
+
+static int hacdbs_stop(void)
+{
+ write_sysreg_s(0, SYS_HACDBSBR_EL2);
+ isb();
+
+ if (this_cpu_read(hacdbs_pcp.status) == HACDBS_ERROR) {
+ /* In case of error, HACDBSCONS_EL2.INDEX should point the faulty entry */
+ u64 cons = read_sysreg_s(SYS_HACDBSCONS_EL2);
+ int idx = FIELD_GET(HACDBSCONS_EL2_INDEX, cons);
+
+ trace_printk("HACDBS found error %lu in index %d / %d\n",
+ FIELD_GET(HACDBSCONS_EL2_ERR_REASON, cons), idx,
+ this_cpu_read(hacdbs_pcp.size));
+
+ this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
+
+ return idx;
+ }
+
+ return this_cpu_read(hacdbs_pcp.size);
+}
+
+/*
+ * Clears dirty-bits for an array of pages (hw_entries) using HACDBS
+ * Returns the number of items cleaned from the array. If returns value < size,
+ * there was an error in the processing.
+ */
+static int dirty_bit_clear(struct kvm *kvm, u64 *hw_entries, int size)
+{
+ enum hacdbs_status st;
+ u64 hcr_el2;
+ int ret;
+
+ preempt_disable();
+
+ hcr_el2 = read_sysreg(HCR_EL2);
+ write_sysreg(hcr_el2 | HCR_EL2_VM, HCR_EL2);
+ __load_stage2(&kvm->arch.mmu, kvm->arch.mmu.arch);
+
+ hacdbs_start(hw_entries, size);
+
+ do {
+ wfi();
+ } while ((st = this_cpu_read(hacdbs_pcp.status)) == HACDBS_RUNNING);
+
+ ret = hacdbs_stop();
+
+ write_sysreg(hcr_el2, HCR_EL2);
+ isb();
+
+ /*
+ * No DSB is needed here, as kvm_flush_remote_tlbs_memslot() that happens
+ * later in generic dirty-cleaning code already performs a DSB before
+ * doing the TLBI.
+ */
+
+ preempt_enable();
+
+ return ret;
+}
+
static irqreturn_t hacdbsirq_handler(int irq, void *pcpu)
{
u64 cons = read_sysreg_s(SYS_HACDBSCONS_EL2);
unsigned long err = FIELD_GET(HACDBSCONS_EL2_ERR_REASON, cons);
switch (err) {
case HACDBSCONS_EL2_ERR_REASON_NOF:
this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
break;
case HACDBSCONS_EL2_ERR_REASON_IPAHACF:
--
2.54.0
^ permalink raw reply related
* [PATCH v1 05/12] KVM: arm64: Detect (via ACPI) and initialize HACDBSIRQ
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Find via ACPI [1] the Id for HACDBSIRQ, initialize it as a per-cpu IRQ
and make sure any cpu able to run virtualization has it active.
Introduce a per-cpu structure used by the HACDBSIRQ handler to keep track
of entries size and the status of HACDBS. Size is used to detect end of
processing in case the number of entries being processed is different of
the supported entries size.
Status may look easily replaceable by checking HACDBS registers now, but
will make the OFF/IDLE detection easier in next patches.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
[1] https://github.com/tianocore/edk2/issues/12409
---
arch/arm64/include/asm/acpi.h | 3 +
arch/arm64/include/asm/kvm_dirty_bit.h | 18 +++++
include/acpi/actbl2.h | 1 +
arch/arm64/kvm/arm.c | 5 ++
arch/arm64/kvm/dirty_bit.c | 97 ++++++++++++++++++++++++++
5 files changed, 124 insertions(+)
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 8a54ca6ba602..883315e9d79d 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -38,20 +38,23 @@
#define BAD_MADT_GICC_ENTRY(entry, end) \
(!(entry) || (entry)->header.length < ACPI_MADT_GICC_MIN_LENGTH || \
(unsigned long)(entry) + (entry)->header.length > (end))
#define ACPI_MADT_GICC_SPE (offsetof(struct acpi_madt_generic_interrupt, \
spe_interrupt) + sizeof(u16))
#define ACPI_MADT_GICC_TRBE (offsetof(struct acpi_madt_generic_interrupt, \
trbe_interrupt) + sizeof(u16))
+
+#define ACPI_MADT_GICC_HACDBSIRQ (offsetof(struct acpi_madt_generic_interrupt, \
+ hacdbsirq_gsi) + sizeof(u32))
/*
* Arm® Functional Fixed Hardware Specification Version 1.2.
* Table 2: Arm Architecture context loss flags
*/
#define CPUIDLE_CORE_CTXT BIT(0) /* Core context Lost */
static inline unsigned int arch_get_idle_state_flags(u32 arch_flags)
{
if (arch_flags & CPUIDLE_CORE_CTXT)
return CPUIDLE_FLAG_TIMER_STOP;
diff --git a/arch/arm64/include/asm/kvm_dirty_bit.h b/arch/arm64/include/asm/kvm_dirty_bit.h
index dd16438f0651..904e59f95b7e 100644
--- a/arch/arm64/include/asm/kvm_dirty_bit.h
+++ b/arch/arm64/include/asm/kvm_dirty_bit.h
@@ -2,11 +2,29 @@
/*
* Copyright (C) 2026 ARM Ltd.
* Author: Leonardo Bras <leo.bras@arm.com>
*/
#ifndef __ARM64_KVM_DIRTY_BIT_H__
#define __ARM64_KVM_DIRTY_BIT_H__
#include <asm/kvm_pgtable.h>
+enum hacdbs_status {
+ HACDBS_OFF,
+ HACDBS_IDLE,
+ HACDBS_RUNNING,
+ HACDBS_ERROR
+};
+
+struct hacdbs {
+ enum hacdbs_status status;
+ int size;
+};
+
+DECLARE_PER_CPU(struct hacdbs, hacdbs_pcp);
+
+void __init kvm_hacdbs_init(void);
+void kvm_hacdbs_cpu_up(void);
+void kvm_hacdbs_cpu_down(void);
+
#endif /* __ARM64_KVM_DIRTY_BIT_H__ */
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 5c0b55e7b3e4..96b664dde9c2 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -1442,20 +1442,21 @@ struct acpi_madt_generic_interrupt {
u64 gich_base_address;
u32 vgic_interrupt;
u64 gicr_base_address;
u64 arm_mpidr;
u8 efficiency_class;
u8 reserved2[1];
u16 spe_interrupt; /* ACPI 6.3 */
u16 trbe_interrupt; /* ACPI 6.5 */
u16 iaffid; /* ACPI 6.7 */
u32 irs_id;
+ u32 hacdbsirq_gsi; /* ACPI 6.X */
};
/* Masks for Flags field above */
/* ACPI_MADT_ENABLED (1) Processor is usable if set */
#define ACPI_MADT_PERFORMANCE_IRQ_MODE (1<<1) /* 01: Performance Interrupt Mode */
#define ACPI_MADT_VGIC_IRQ_MODE (1<<2) /* 02: VGIC Maintenance Interrupt mode */
#define ACPI_MADT_GICC_ONLINE_CAPABLE (1<<3) /* 03: Processor is online capable */
#define ACPI_MADT_GICC_NON_COHERENT (1<<4) /* 04: GIC redistributor is not coherent */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 176cbe8baad3..aae230c33c41 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -34,20 +34,21 @@
#include <asm/cpufeature.h>
#include <asm/virt.h>
#include <asm/kvm_arm.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_nested.h>
#include <asm/kvm_pkvm.h>
#include <asm/kvm_ptrauth.h>
+#include <asm/kvm_dirty_bit.h>
#include <asm/sections.h>
#include <asm/stacktrace/nvhe.h>
#include <kvm/arm_hypercalls.h>
#include <kvm/arm_pmu.h>
#include <kvm/arm_psci.h>
#include <kvm/arm_vgic.h>
#include <linux/irqchip/arm-gic-v5.h>
@@ -2278,28 +2279,30 @@ int kvm_arch_enable_virtualization_cpu(void)
* disabled, but not with preemption disabled. The former is
* enough to ensure correctness, but most of the helpers
* expect the later and will throw a tantrum otherwise.
*/
preempt_disable();
cpu_hyp_init(NULL);
kvm_vgic_cpu_up();
kvm_timer_cpu_up();
+ kvm_hacdbs_cpu_up();
preempt_enable();
return 0;
}
void kvm_arch_disable_virtualization_cpu(void)
{
+ kvm_hacdbs_cpu_down();
kvm_timer_cpu_down();
kvm_vgic_cpu_down();
if (!is_protected_kvm_enabled())
cpu_hyp_uninit(NULL);
}
#ifdef CONFIG_CPU_PM
static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
unsigned long cmd,
@@ -2450,20 +2453,22 @@ static int __init init_subsystems(void)
goto out;
}
/*
* Init HYP architected timer support
*/
err = kvm_timer_hyp_init(vgic_present);
if (err)
goto out;
+ kvm_hacdbs_init();
+
kvm_register_perf_callbacks();
err = kvm_hyp_trace_init();
if (err)
kvm_err("Failed to initialize Hyp tracing\n");
out:
if (err)
hyp_cpu_pm_exit();
diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
index 31ef35f3b72f..765ef609ff70 100644
--- a/arch/arm64/kvm/dirty_bit.c
+++ b/arch/arm64/kvm/dirty_bit.c
@@ -1,23 +1,120 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2026 ARM Ltd.
* Author: Leonardo Bras <leo.bras@arm.com>
*/
#include <asm/kvm_dirty_bit.h>
+#include <linux/kconfig.h>
+#include <linux/acpi.h>
+
+DEFINE_PER_CPU(struct hacdbs, hacdbs_pcp) = {
+ .status = HACDBS_OFF,
+ .size = 0,
+};
/* HDBSS entry field definitions */
#define HDBSS_ENTRY_VALID BIT(0)
#define HDBSS_ENTRY_TTWL_SHIFT (1)
#define HDBSS_ENTRY_TTWL_MASK (GENMASK(3, 1))
#define HDBSS_ENTRY_TTWL(x) \
(((x) << HDBSS_ENTRY_TTWL_SHIFT) & HDBSS_ENTRY_TTWL_MASK)
#define HDBSS_ENTRY_TTWL_RESV HDBSS_ENTRY_TTWL(-4)
#define HDBSS_ENTRY_IPA GENMASK_ULL(55, 12)
inline u64 hdbss_get_ttwl(u64 chunk_size)
{
u64 hw_lvl = ARM64_HW_PGTABLE_LEVELS(ilog2(chunk_size));
return HDBSS_ENTRY_TTWL(3 - hw_lvl);
}
+
+static __ro_after_init int hacdbsirq = -1;
+
+static irqreturn_t hacdbsirq_handler(int irq, void *pcpu)
+{
+ u64 cons = read_sysreg_s(SYS_HACDBSCONS_EL2);
+ unsigned long err = FIELD_GET(HACDBSCONS_EL2_ERR_REASON, cons);
+
+ switch (err) {
+ case HACDBSCONS_EL2_ERR_REASON_NOF:
+ this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
+ break;
+ case HACDBSCONS_EL2_ERR_REASON_IPAHACF:
+ /* When size not a power of two >= 4k, exit with reserved TTLW */
+ int index = FIELD_GET(HACDBSCONS_EL2_INDEX, cons);
+
+ if (index >= this_cpu_read(hacdbs_pcp.size)) {
+ this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
+ break;
+ }
+ fallthrough;
+ case HACDBSCONS_EL2_ERR_REASON_STRUCTF:
+ case HACDBSCONS_EL2_ERR_REASON_IPAF:
+ this_cpu_write(hacdbs_pcp.status, HACDBS_ERROR);
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+void kvm_hacdbs_cpu_up(void)
+{
+ if (hacdbsirq < 0)
+ return;
+
+ enable_percpu_irq(hacdbsirq, IRQ_TYPE_LEVEL_HIGH);
+ this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
+}
+
+void kvm_hacdbs_cpu_down(void)
+{
+ if (hacdbsirq < 0)
+ return;
+
+ disable_percpu_irq(hacdbsirq);
+ this_cpu_write(hacdbs_pcp.status, HACDBS_OFF);
+}
+
+#ifdef CONFIG_ACPI
+static int __init hacdbs_acpi_get_irq(void)
+{
+ struct acpi_madt_generic_interrupt *gicc;
+ u32 gsi;
+ int irq;
+
+ gicc = acpi_cpu_get_madt_gicc(smp_processor_id());
+ if (gicc->header.length < ACPI_MADT_GICC_HACDBSIRQ)
+ return -ENXIO;
+
+ gsi = gicc->hacdbsirq_gsi;
+
+ irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
+ if (irq < 0) {
+ pr_warn("ACPI: Unable to register HACDBS interrupt: %d\n", gsi);
+ return -ENXIO;
+ }
+
+ return irq;
+}
+#else
+#define hacdbs_acpi_get_irq() (-ENXIO)
+#endif
+
+void __init kvm_hacdbs_init(void)
+{
+ int irq;
+
+ /* FEAT_HACDBS is only supported if Linux runs in EL2 (VHE) */
+ if (!system_supports_hacdbs() || !is_kernel_in_hyp_mode())
+ return;
+
+ irq = hacdbs_acpi_get_irq();
+ if (irq < 0)
+ return;
+
+ if (request_percpu_irq(irq, hacdbsirq_handler, "HACDBSIRQ", &hacdbs_pcp) < 0)
+ return;
+
+ hacdbsirq = irq;
+}
--
2.54.0
^ permalink raw reply related
* [PATCH v1 07/12] kvm: Add arch-generic interface for hw-accelerated dirty-bitmap cleaning
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Introduce kvm_arch_dirty_log_clear() that allow implementation of
arch-specific hardware-accelerated dirty-log routines.
A call to that is added on both kvm_get_dirty_log_protect() and
kvm_clear_dirty_log_protect() and will fall back to software version if
not implemented, or any error was detected in the arch-specific routine.
For an arch to implement this function, it's required to provide an
asm/kvm_dirty_bit.h and have CONFIG_HAVE_KVM_HW_DIRTY_BIT=y on building.
If the arch does not implement it, and thus lack above config, the
introduced snippet is expected to be compiled-out and have zero impact at
runtime.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
include/linux/kvm_dirty_bit.h | 27 +++++++++++++++++++++++++++
virt/kvm/kvm_main.c | 13 ++++++++++++-
virt/kvm/Kconfig | 3 +++
3 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 include/linux/kvm_dirty_bit.h
diff --git a/include/linux/kvm_dirty_bit.h b/include/linux/kvm_dirty_bit.h
new file mode 100644
index 000000000000..fa4f6b67b623
--- /dev/null
+++ b/include/linux/kvm_dirty_bit.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 ARM Ltd.
+ * Author: Leonardo Bras <leo.bras@arm.com>
+ */
+
+#ifndef __KVM_DIRTY_BIT_H__
+#define __KVM_DIRTY_BIT_H__
+
+#ifndef CONFIG_HAVE_KVM_HW_DIRTY_BIT
+
+static inline int kvm_arch_dirty_log_clear(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_clear_dirty_log *log,
+ unsigned long *bitmap,
+ bool *flush)
+{
+ return -ENXIO;
+}
+
+#else /* CONFIG_HAVE_KVM_HW_DIRTY_BIT */
+
+#include <asm/kvm_dirty_bit.h>
+
+#endif /* CONFIG_HAVE_KVM_HW_DIRTY_BIT */
+
+#endif /* __KVM_DIRTY_BIT_H__ */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 89489996fbc1..7f5048ca9a25 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -58,20 +58,21 @@
#include "async_pf.h"
#include "kvm_mm.h"
#include "vfio.h"
#include <trace/events/ipi.h>
#define CREATE_TRACE_POINTS
#include <trace/events/kvm.h>
#include <linux/kvm_dirty_ring.h>
+#include <linux/kvm_dirty_bit.h>
/* Worst case buffer size needed for holding an integer. */
#define ITOA_MAX_LEN 12
MODULE_AUTHOR("Qumranet");
MODULE_DESCRIPTION("Kernel-based Virtual Machine (KVM) Hypervisor");
MODULE_LICENSE("GPL");
/* Architectures should define their poll value according to the halt latency */
@@ -2255,39 +2256,44 @@ static int kvm_get_dirty_log_protect(struct kvm *kvm, struct kvm_dirty_log *log)
* is some code duplication between this function and
* kvm_get_dirty_log, but hopefully all architecture
* transition to kvm_get_dirty_log_protect and kvm_get_dirty_log
* can be eliminated.
*/
dirty_bitmap_buffer = dirty_bitmap;
} else {
dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot);
memset(dirty_bitmap_buffer, 0, n);
+ if (kvm_arch_dirty_log_clear(kvm, memslot, NULL,
+ dirty_bitmap_buffer, &flush) >= 0)
+ goto out;
+
KVM_MMU_LOCK(kvm);
for (i = 0; i < n / sizeof(long); i++) {
unsigned long mask;
gfn_t offset;
if (!dirty_bitmap[i])
continue;
flush = true;
mask = xchg(&dirty_bitmap[i], 0);
dirty_bitmap_buffer[i] = mask;
offset = i * BITS_PER_LONG;
kvm_arch_mmu_enable_log_dirty_pt_masked(kvm, memslot,
offset, mask);
}
KVM_MMU_UNLOCK(kvm);
}
+out:
if (flush)
kvm_flush_remote_tlbs_memslot(kvm, memslot);
if (copy_to_user(log->dirty_bitmap, dirty_bitmap_buffer, n))
return -EFAULT;
return 0;
}
/**
@@ -2366,45 +2372,50 @@ static int kvm_clear_dirty_log_protect(struct kvm *kvm,
(log->num_pages < memslot->npages - log->first_page && (log->num_pages & 63)))
return -EINVAL;
kvm_arch_sync_dirty_log(kvm, memslot);
flush = false;
dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot);
if (copy_from_user(dirty_bitmap_buffer, log->dirty_bitmap, n))
return -EFAULT;
+ if (kvm_arch_dirty_log_clear(kvm, memslot, log, dirty_bitmap_buffer,
+ &flush) >= 0)
+ goto out;
+
KVM_MMU_LOCK(kvm);
for (offset = log->first_page, i = offset / BITS_PER_LONG,
n = DIV_ROUND_UP(log->num_pages, BITS_PER_LONG); n--;
i++, offset += BITS_PER_LONG) {
unsigned long mask = *dirty_bitmap_buffer++;
atomic_long_t *p = (atomic_long_t *) &dirty_bitmap[i];
if (!mask)
continue;
mask &= atomic_long_fetch_andnot(mask, p);
/*
* mask contains the bits that really have been cleared. This
* never includes any bits beyond the length of the memslot (if
* the length is not aligned to 64 pages), therefore it is not
* a problem if userspace sets them in log->dirty_bitmap.
*/
if (mask) {
flush = true;
+
kvm_arch_mmu_enable_log_dirty_pt_masked(kvm, memslot,
offset, mask);
}
}
KVM_MMU_UNLOCK(kvm);
-
+out:
if (flush)
kvm_flush_remote_tlbs_memslot(kvm, memslot);
return 0;
}
static int kvm_vm_ioctl_clear_dirty_log(struct kvm *kvm,
struct kvm_clear_dirty_log *log)
{
int r;
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 794976b88c6f..f8757b5b84b3 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -13,20 +13,23 @@ config HAVE_KVM_PFNCACHE
config HAVE_KVM_IRQCHIP
bool
config HAVE_KVM_IRQ_ROUTING
bool
config HAVE_KVM_DIRTY_RING
bool
+config HAVE_KVM_HW_DIRTY_BIT
+ bool
+
# Only strongly ordered architectures can select this, as it doesn't
# put any explicit constraint on userspace ordering. They can also
# select the _ACQ_REL version.
config HAVE_KVM_DIRTY_RING_TSO
bool
select HAVE_KVM_DIRTY_RING
depends on X86
# Weakly ordered architectures can only select this, advertising
# to userspace the additional ordering requirements.
--
2.54.0
^ permalink raw reply related
* [PATCH v1 10/12] kvm/dirty_ring: Add arch-generic interface for hw-accelerated dirty-ring cleaning
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Introduce kvm_arch_dirty_ring_clear() that allow implementation of
arch-specific hardware-accelerated dirty-ring routines.
A call to that is added on kvm_dirty_ring_reset() and will fall back to
software version if not implemented, or any error was detected in the
arch-specific routine.
For an arch to implement this function, it's required to provide it in a
asm/kvm_dirty_bit.h and have CONFIG_HAVE_KVM_HW_DIRTY_BIT=y on building.
If the arch does not implement it, and thus lack above config, the
introduced snippet is expected to be compiled-out and have zero impact at
runtime.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
include/linux/kvm_dirty_bit.h | 7 +++++++
virt/kvm/dirty_ring.c | 4 ++++
2 files changed, 11 insertions(+)
diff --git a/include/linux/kvm_dirty_bit.h b/include/linux/kvm_dirty_bit.h
index fa4f6b67b623..8492979d694e 100644
--- a/include/linux/kvm_dirty_bit.h
+++ b/include/linux/kvm_dirty_bit.h
@@ -11,17 +11,24 @@
static inline int kvm_arch_dirty_log_clear(struct kvm *kvm,
struct kvm_memory_slot *memslot,
struct kvm_clear_dirty_log *log,
unsigned long *bitmap,
bool *flush)
{
return -ENXIO;
}
+static inline int kvm_arch_dirty_ring_clear(struct kvm *kvm,
+ struct kvm_dirty_ring *ring,
+ int *nr_entries_reset)
+{
+ return -ENXIO;
+}
+
#else /* CONFIG_HAVE_KVM_HW_DIRTY_BIT */
#include <asm/kvm_dirty_bit.h>
#endif /* CONFIG_HAVE_KVM_HW_DIRTY_BIT */
#endif /* __KVM_DIRTY_BIT_H__ */
diff --git a/virt/kvm/dirty_ring.c b/virt/kvm/dirty_ring.c
index 83ac5ac907c1..a58c811dd461 100644
--- a/virt/kvm/dirty_ring.c
+++ b/virt/kvm/dirty_ring.c
@@ -1,20 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* KVM dirty ring implementation
*
* Copyright 2019 Red Hat, Inc.
*/
#include <linux/kvm_host.h>
#include <linux/kvm.h>
#include <linux/vmalloc.h>
#include <linux/kvm_dirty_ring.h>
+#include <linux/kvm_dirty_bit.h>
#include <trace/events/kvm.h>
#include "kvm_mm.h"
int __weak kvm_cpu_dirty_log_size(struct kvm *kvm)
{
return 0;
}
u32 kvm_dirty_ring_get_rsvd_entries(struct kvm *kvm)
{
@@ -125,20 +126,23 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
struct kvm_dirty_gfn *entry;
/*
* Ensure concurrent calls to KVM_RESET_DIRTY_RINGS are serialized,
* e.g. so that KVM fully resets all entries processed by a given call
* before returning to userspace. Holding slots_lock also protects
* the various memslot accesses.
*/
lockdep_assert_held(&kvm->slots_lock);
+ if (kvm_arch_dirty_ring_clear(kvm, ring, nr_entries_reset) >= 0)
+ return 0;
+
while (likely((*nr_entries_reset) < INT_MAX)) {
if (signal_pending(current))
return -EINTR;
entry = &ring->dirty_gfns[ring->reset_index & (ring->size - 1)];
if (!kvm_dirty_gfn_harvested(entry))
break;
next_slot = READ_ONCE(entry->slot);
--
2.54.0
^ permalink raw reply related
* [PATCH v1 08/12] KVM: arm64: Add hardware-accelerated dirty-bitmap cleaning routine
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Implement arm64 version of kvm_arch_dirty_log_clear() making use of
FEAT_HACDBS.
It works by transversing the dirty-bitmap and converting the set bits into
HDBSS entries in a 64-page blocks granularity.
The resulting HDBSS array is then fed to the HACDBS mechanism that walks
the pagetable marking writable-dirty pages as writable-clean.
In case of error, rewrite all unprocessed entries, including the faulting
one, to the dirty-bitmap and fall back to generic software cleaning.
In case of the options to "manual protect + init set" are enabled, do
the hugepage splitting in the same fashion as the generic software
cleaning, i.e. in 64-page blocks. For that, remove the static qualifier
from kvm_mmu_split_huge_pages() and make the function available on
kvm_host.h.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/include/asm/kvm_dirty_bit.h | 24 ++++
include/linux/kvm_host.h | 3 +
arch/arm64/kvm/dirty_bit.c | 146 +++++++++++++++++++++++++
arch/arm64/kvm/mmu.c | 4 +-
4 files changed, 175 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_dirty_bit.h b/arch/arm64/include/asm/kvm_dirty_bit.h
index 904e59f95b7e..3d749f979c67 100644
--- a/arch/arm64/include/asm/kvm_dirty_bit.h
+++ b/arch/arm64/include/asm/kvm_dirty_bit.h
@@ -20,11 +20,35 @@ struct hacdbs {
enum hacdbs_status status;
int size;
};
DECLARE_PER_CPU(struct hacdbs, hacdbs_pcp);
void __init kvm_hacdbs_init(void);
void kvm_hacdbs_cpu_up(void);
void kvm_hacdbs_cpu_down(void);
+int __kvm_arch_dirty_log_clear(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_clear_dirty_log *log,
+ unsigned long *bitmap,
+ bool *flush);
+
+static inline bool kvm_arch_dirty_clear_enabled(struct kvm *kvm)
+{
+ return this_cpu_read(hacdbs_pcp.status) == HACDBS_IDLE &&
+ (kvm->arch.mmu.pgt->flags & KVM_PGTABLE_S2_DBM);
+}
+
+static inline int kvm_arch_dirty_log_clear(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_clear_dirty_log *log,
+ unsigned long *bitmap,
+ bool *flush)
+{
+ if (!kvm_arch_dirty_clear_enabled(kvm))
+ return -EPERM;
+
+ return __kvm_arch_dirty_log_clear(kvm, memslot, log, bitmap, flush);
+}
+
#endif /* __ARM64_KVM_DIRTY_BIT_H__ */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4c14aee1fb06..5e3a3c484dd4 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1662,20 +1662,23 @@ void kvm_arch_disable_virtualization_cpu(void);
bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);
bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu);
bool kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu *vcpu);
bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu);
void kvm_arch_pre_destroy_vm(struct kvm *kvm);
void kvm_arch_create_vm_debugfs(struct kvm *kvm);
+int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
+ phys_addr_t end);
+
#ifndef __KVM_HAVE_ARCH_VM_ALLOC
/*
* All architectures that want to use vzalloc currently also
* need their own kvm_arch_alloc_vm implementation.
*/
static inline struct kvm *kvm_arch_alloc_vm(void)
{
return kzalloc_obj(struct kvm, GFP_KERNEL_ACCOUNT);
}
#endif
diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
index 22e3ed07256a..0b7dcb8467c0 100644
--- a/arch/arm64/kvm/dirty_bit.c
+++ b/arch/arm64/kvm/dirty_bit.c
@@ -110,20 +110,166 @@ static int dirty_bit_clear(struct kvm *kvm, u64 *hw_entries, int size)
* No DSB is needed here, as kvm_flush_remote_tlbs_memslot() that happens
* later in generic dirty-cleaning code already performs a DSB before
* doing the TLBI.
*/
preempt_enable();
return ret;
}
+static inline void hdbss_to_bitmap(u64 *hdbss_array, int start, int end,
+ unsigned long *dirty_bitmap,
+ unsigned long long offset)
+{
+ u64 w = (gpa_to_gfn(hdbss_array[start]) - offset) / BITS_PER_LONG;
+ u64 mask = 0;
+ int idx = start;
+
+ do {
+ u64 entry = (gpa_to_gfn(hdbss_array[idx]) - offset);
+
+ if (entry / BITS_PER_LONG == w) {
+ mask |= BIT(entry % BITS_PER_LONG);
+ } else {
+ atomic_long_or(mask, (atomic_long_t *)&dirty_bitmap[w]);
+ w = entry / BITS_PER_LONG;
+ mask = BIT(entry % BITS_PER_LONG);
+ }
+ } while (++idx < end);
+ atomic_long_or(mask, (atomic_long_t *)&dirty_bitmap[w]);
+}
+
+static inline int mask_to_hdbss(unsigned long *mask, u64 *hw_entries, const gfn_t offset,
+ u64 ttwl, int idx, int entries_sz)
+{
+ while (idx < entries_sz) {
+ int j = __ffs(*mask);
+ u64 a = gfn_to_gpa(offset + j);
+
+ hw_entries[idx++] = (a & HDBSS_ENTRY_IPA) |
+ ttwl |
+ HDBSS_ENTRY_VALID;
+
+ *mask &= ~BIT(j);
+ if (!*mask)
+ break;
+ }
+
+ return idx;
+}
+
+int __kvm_arch_dirty_log_clear(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_clear_dirty_log *log,
+ unsigned long *bitmap,
+ bool *flush)
+{
+ int ret = 0;
+ int idx = 0;
+ unsigned long *dirty_bitmap = memslot->dirty_bitmap;
+ u64 *hw_entries;
+ const int entries_sz = PAGE_SIZE / sizeof(*hw_entries);
+ u64 ttwl;
+ u64 start, end;
+ gfn_t base_gfn;
+
+ hw_entries = kmalloc_objs(u64, entries_sz, GFP_KERNEL);
+ if (!hw_entries)
+ return -ENOMEM;
+
+ ttwl = hdbss_get_ttwl(kvm->arch.mmu.split_page_chunk_size);
+
+ if (log) {
+ start = log->first_page / BITS_PER_LONG;
+ end = start + DIV_ROUND_UP(log->num_pages, BITS_PER_LONG);
+ base_gfn = memslot->base_gfn + log->first_page % BITS_PER_LONG;
+ } else {
+ start = 0;
+ end = kvm_dirty_bitmap_bytes(memslot) / sizeof(long);
+ base_gfn = memslot->base_gfn;
+ }
+
+ write_lock(&kvm->mmu_lock);
+
+ for (unsigned long i = start; i < end; i++) {
+ unsigned long mask;
+ gfn_t offset;
+ atomic_long_t *p;
+
+ if (log) { /* Clean only what is in the input bitmap */
+ mask = bitmap[i];
+ if (!mask)
+ continue;
+
+ p = (atomic_long_t *)&dirty_bitmap[i];
+ mask &= atomic_long_fetch_andnot(mask, p);
+ } else { /* Clean everything */
+ if (!dirty_bitmap[i])
+ continue;
+
+ mask = xchg(&dirty_bitmap[i], 0);
+ bitmap[i] = mask;
+ }
+
+ if (!mask)
+ continue;
+
+ offset = base_gfn + i * BITS_PER_LONG;
+
+ if (kvm_dirty_log_manual_protect_and_init_set(kvm))
+ kvm_mmu_split_huge_pages(kvm,
+ gfn_to_gpa(offset + __ffs(mask)),
+ gfn_to_gpa(offset + __fls(mask) + 1));
+
+ do {
+ idx = mask_to_hdbss(&mask, hw_entries, offset, ttwl, idx, entries_sz);
+ if (idx >= entries_sz) {
+ ret = dirty_bit_clear(kvm, hw_entries, idx);
+ *flush = *flush || ret > 0;
+ if (ret != idx) {
+ /* Save bits not converted back to bitmap */
+ atomic_long_or(mask, (atomic_long_t *)&dirty_bitmap[i]);
+ goto out_err;
+ }
+ idx = 0;
+ }
+ } while (mask);
+ }
+
+ if (idx != 0) {
+ ret = dirty_bit_clear(kvm, hw_entries, idx);
+ *flush = *flush || ret > 0;
+ }
+out_err:
+ if (unlikely(ret != idx)) {
+ /*
+ * In case there is an error and not all entries in HACDBS get
+ * cleaned, we have to mark the dirty bits back in the bitmap,
+ * as that will be used by the software routine.
+ *
+ * Entries should be in order, since they were extraxed from
+ * the dirty-bitmap, so batching the atomic writes is efficient.
+ */
+
+ if (ret < idx)
+ hdbss_to_bitmap(hw_entries, ret, idx, dirty_bitmap, memslot->base_gfn);
+
+ ret = -EAGAIN;
+ }
+
+ write_unlock(&kvm->mmu_lock);
+ kfree(hw_entries);
+
+ return ret;
+}
+
static irqreturn_t hacdbsirq_handler(int irq, void *pcpu)
{
u64 cons = read_sysreg_s(SYS_HACDBSCONS_EL2);
unsigned long err = FIELD_GET(HACDBSCONS_EL2_ERR_REASON, cons);
switch (err) {
case HACDBSCONS_EL2_ERR_REASON_NOF:
this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
break;
case HACDBSCONS_EL2_ERR_REASON_IPAHACF:
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 42c734423253..166720f29138 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -110,22 +110,22 @@ static bool need_split_memcache_topup_or_resched(struct kvm *kvm)
if (need_resched() || rwlock_needbreak(&kvm->mmu_lock))
return true;
chunk_size = kvm->arch.mmu.split_page_chunk_size;
min = kvm_mmu_split_nr_page_tables(chunk_size);
cache = &kvm->arch.mmu.split_page_cache;
return kvm_mmu_memory_cache_nr_free_objects(cache) < min;
}
-static int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
- phys_addr_t end)
+int kvm_mmu_split_huge_pages(struct kvm *kvm, phys_addr_t addr,
+ phys_addr_t end)
{
struct kvm_mmu_memory_cache *cache;
struct kvm_pgtable *pgt;
int ret, cache_capacity;
u64 next, chunk_size;
lockdep_assert_held_write(&kvm->mmu_lock);
chunk_size = kvm->arch.mmu.split_page_chunk_size;
cache_capacity = kvm_mmu_split_nr_page_tables(chunk_size);
--
2.54.0
^ permalink raw reply related
* [PATCH v1 09/12] kvm/dirty_ring: Introduce get_memslot and move helpers to header
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Dirty-ring entry struct carries a slot number which is used to return
a struct memslot*. That struct carry important information such as
memory offset of that memory slot, which is used to calculate the guest
physical address of the page which needs to be marked clean.
In order to fetch that memslot information without duplicating code, split
that part of kvm_reset_dirty_gfn() into a new helper
kvm_dirty_ring_get_memslot().
Along with that, make it available on kvm_dirty_ring.h other helpers such
as kvm_dirty_gfn_harvested() and kvm_dirty_gfn_set_invalid() which will be
useful on implementing arch specific dirty-ring cleaning accelerators.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
include/linux/kvm_dirty_ring.h | 12 ++++++++++++
virt/kvm/dirty_ring.c | 30 ++++++++++++++++--------------
2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/include/linux/kvm_dirty_ring.h b/include/linux/kvm_dirty_ring.h
index eb10d87adf7d..190d97fce4a4 100644
--- a/include/linux/kvm_dirty_ring.h
+++ b/include/linux/kvm_dirty_ring.h
@@ -77,18 +77,30 @@ bool kvm_use_dirty_bitmap(struct kvm *kvm);
bool kvm_arch_allow_write_without_running_vcpu(struct kvm *kvm);
u32 kvm_dirty_ring_get_rsvd_entries(struct kvm *kvm);
int kvm_dirty_ring_alloc(struct kvm *kvm, struct kvm_dirty_ring *ring,
int index, u32 size);
int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
int *nr_entries_reset);
void kvm_dirty_ring_push(struct kvm_vcpu *vcpu, u32 slot, u64 offset);
bool kvm_dirty_ring_check_request(struct kvm_vcpu *vcpu);
+static inline bool kvm_dirty_gfn_harvested(struct kvm_dirty_gfn *gfn)
+{
+ return smp_load_acquire(&gfn->flags) & KVM_DIRTY_GFN_F_RESET;
+}
+
+static inline void kvm_dirty_gfn_set_invalid(struct kvm_dirty_gfn *gfn)
+{
+ smp_store_release(&gfn->flags, 0);
+}
+
+struct kvm_memory_slot *kvm_dirty_ring_get_memslot(struct kvm *kvm, u32 slot);
+
/* for use in vm_operations_struct */
struct page *kvm_dirty_ring_get_page(struct kvm_dirty_ring *ring, u32 offset);
void kvm_dirty_ring_free(struct kvm_dirty_ring *ring);
#endif /* CONFIG_HAVE_KVM_DIRTY_RING */
#endif /* KVM_DIRTY_RING_H */
diff --git a/virt/kvm/dirty_ring.c b/virt/kvm/dirty_ring.c
index 02bc6b00d76c..83ac5ac907c1 100644
--- a/virt/kvm/dirty_ring.c
+++ b/virt/kvm/dirty_ring.c
@@ -43,32 +43,44 @@ static u32 kvm_dirty_ring_used(struct kvm_dirty_ring *ring)
static bool kvm_dirty_ring_soft_full(struct kvm_dirty_ring *ring)
{
return kvm_dirty_ring_used(ring) >= ring->soft_limit;
}
static bool kvm_dirty_ring_full(struct kvm_dirty_ring *ring)
{
return kvm_dirty_ring_used(ring) >= ring->size;
}
-static void kvm_reset_dirty_gfn(struct kvm *kvm, u32 slot, u64 offset, u64 mask)
+static inline struct kvm_memory_slot *
+__kvm_dirty_ring_get_memslot(struct kvm *kvm, u32 slot)
{
- struct kvm_memory_slot *memslot;
int as_id, id;
as_id = slot >> 16;
id = (u16)slot;
if (as_id >= kvm_arch_nr_memslot_as_ids(kvm) || id >= KVM_USER_MEM_SLOTS)
- return;
+ return 0;
- memslot = id_to_memslot(__kvm_memslots(kvm, as_id), id);
+ return id_to_memslot(__kvm_memslots(kvm, as_id), id);
+}
+
+struct kvm_memory_slot *kvm_dirty_ring_get_memslot(struct kvm *kvm, u32 slot)
+{
+ return __kvm_dirty_ring_get_memslot(kvm, slot);
+}
+
+static void kvm_reset_dirty_gfn(struct kvm *kvm, u32 slot, u64 offset, u64 mask)
+{
+ struct kvm_memory_slot *memslot;
+
+ memslot = __kvm_dirty_ring_get_memslot(kvm, slot);
if (!memslot || (offset + __fls(mask)) >= memslot->npages)
return;
KVM_MMU_LOCK(kvm);
kvm_arch_mmu_enable_log_dirty_pt_masked(kvm, memslot, offset, mask);
KVM_MMU_UNLOCK(kvm);
}
int kvm_dirty_ring_alloc(struct kvm *kvm, struct kvm_dirty_ring *ring,
@@ -80,35 +92,25 @@ int kvm_dirty_ring_alloc(struct kvm *kvm, struct kvm_dirty_ring *ring,
ring->size = size / sizeof(struct kvm_dirty_gfn);
ring->soft_limit = ring->size - kvm_dirty_ring_get_rsvd_entries(kvm);
ring->dirty_index = 0;
ring->reset_index = 0;
ring->index = index;
return 0;
}
-static inline void kvm_dirty_gfn_set_invalid(struct kvm_dirty_gfn *gfn)
-{
- smp_store_release(&gfn->flags, 0);
-}
-
static inline void kvm_dirty_gfn_set_dirtied(struct kvm_dirty_gfn *gfn)
{
gfn->flags = KVM_DIRTY_GFN_F_DIRTY;
}
-static inline bool kvm_dirty_gfn_harvested(struct kvm_dirty_gfn *gfn)
-{
- return smp_load_acquire(&gfn->flags) & KVM_DIRTY_GFN_F_RESET;
-}
-
int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
int *nr_entries_reset)
{
/*
* To minimize mmu_lock contention, batch resets for harvested entries
* whose gfns are in the same slot, and are within N frame numbers of
* each other, where N is the number of bits in an unsigned long. For
* simplicity, process the current set of entries when the next entry
* can't be included in the batch.
*
--
2.54.0
^ permalink raw reply related
* [PATCH v1 11/12] KVM: arm64: Add hardware-accelerated dirty-ring cleaning routine
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Implement arm64 version of kvm_arch_dirty_ring_clear() making use of
FEAT_HACDBS.
It works by transversing the dirty-ring and converting its entries into
HDBSS entries based on the slot offset.
The resulting HDBSS array is then fed to the HACDBS mechanism that walks
the pagetable marking writable-dirty pages as writable-clean.
Only successfully cleaned entries are set as invalid on the dirty-ring, so
in case of error, falling back to generic software cleaning will take care
of any remaining entry in the dirty-ring.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
arch/arm64/include/asm/kvm_dirty_bit.h | 13 +++++
arch/arm64/kvm/dirty_bit.c | 66 ++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_dirty_bit.h b/arch/arm64/include/asm/kvm_dirty_bit.h
index 3d749f979c67..d76c109937d8 100644
--- a/arch/arm64/include/asm/kvm_dirty_bit.h
+++ b/arch/arm64/include/asm/kvm_dirty_bit.h
@@ -26,29 +26,42 @@ DECLARE_PER_CPU(struct hacdbs, hacdbs_pcp);
void __init kvm_hacdbs_init(void);
void kvm_hacdbs_cpu_up(void);
void kvm_hacdbs_cpu_down(void);
int __kvm_arch_dirty_log_clear(struct kvm *kvm,
struct kvm_memory_slot *memslot,
struct kvm_clear_dirty_log *log,
unsigned long *bitmap,
bool *flush);
+int __kvm_arch_dirty_ring_clear(struct kvm *kvm, struct kvm_dirty_ring *ring,
+ int *nr_entries_reset);
+
static inline bool kvm_arch_dirty_clear_enabled(struct kvm *kvm)
{
return this_cpu_read(hacdbs_pcp.status) == HACDBS_IDLE &&
(kvm->arch.mmu.pgt->flags & KVM_PGTABLE_S2_DBM);
}
static inline int kvm_arch_dirty_log_clear(struct kvm *kvm,
struct kvm_memory_slot *memslot,
struct kvm_clear_dirty_log *log,
unsigned long *bitmap,
bool *flush)
{
if (!kvm_arch_dirty_clear_enabled(kvm))
return -EPERM;
return __kvm_arch_dirty_log_clear(kvm, memslot, log, bitmap, flush);
}
+static inline int kvm_arch_dirty_ring_clear(struct kvm *kvm,
+ struct kvm_dirty_ring *ring,
+ int *nr_entries_reset)
+{
+ if (!kvm_arch_dirty_clear_enabled(kvm))
+ return -EPERM;
+
+ return __kvm_arch_dirty_ring_clear(kvm, ring, nr_entries_reset);
+}
+
#endif /* __ARM64_KVM_DIRTY_BIT_H__ */
diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
index 0b7dcb8467c0..b99808a36469 100644
--- a/arch/arm64/kvm/dirty_bit.c
+++ b/arch/arm64/kvm/dirty_bit.c
@@ -256,20 +256,86 @@ int __kvm_arch_dirty_log_clear(struct kvm *kvm,
ret = -EAGAIN;
}
write_unlock(&kvm->mmu_lock);
kfree(hw_entries);
return ret;
}
+int __kvm_arch_dirty_ring_clear(struct kvm *kvm, struct kvm_dirty_ring *ring,
+ int *nr_entries_reset)
+{
+ u64 *hw_entries;
+ u64 slot_offset = 0;
+ u64 ttwl;
+ int i, ret;
+ u32 slot = -1;
+
+ if (signal_pending(current))
+ return -EINTR;
+
+ ttwl = hdbss_get_ttwl(kvm->arch.mmu.split_page_chunk_size);
+
+ hw_entries = kmalloc(max(ring->size * sizeof(u64), PAGE_SIZE), GFP_KERNEL);
+ if (!hw_entries)
+ return -ENOMEM;
+
+ for (i = 0; i < ring->size; i++) {
+ struct kvm_dirty_gfn *entry;
+ gfn_t gfn;
+
+ entry = &ring->dirty_gfns[(ring->reset_index + i) &
+ (ring->size - 1)];
+
+ if (!kvm_dirty_gfn_harvested(entry))
+ break;
+
+ if (entry->slot != slot) {
+ struct kvm_memory_slot *memslot;
+
+ memslot = kvm_dirty_ring_get_memslot(kvm, entry->slot);
+ slot = entry->slot;
+ slot_offset = memslot->base_gfn;
+ }
+
+ gfn = slot_offset + entry->offset;
+
+ hw_entries[i] = (gfn_to_gpa(gfn) & HDBSS_ENTRY_IPA) |
+ ttwl | HDBSS_ENTRY_VALID;
+ }
+
+ ret = dirty_bit_clear(kvm, hw_entries, i);
+
+ /* Set as invalid all successfully cleaned entries */
+ for (int j = 0; j < ret; j++) {
+ struct kvm_dirty_gfn *entry;
+
+ entry = &ring->dirty_gfns[(ring->reset_index + j) &
+ (ring->size - 1)];
+
+ kvm_dirty_gfn_set_invalid(entry);
+ }
+
+ /* In case of error, try software cleaning from the faulting entry */
+ ring->reset_index += ret;
+ *nr_entries_reset += ret;
+
+ kfree(hw_entries);
+
+ if (ret < i)
+ return -EFAULT;
+
+ return ret;
+}
+
static irqreturn_t hacdbsirq_handler(int irq, void *pcpu)
{
u64 cons = read_sysreg_s(SYS_HACDBSCONS_EL2);
unsigned long err = FIELD_GET(HACDBSCONS_EL2_ERR_REASON, cons);
switch (err) {
case HACDBSCONS_EL2_ERR_REASON_NOF:
this_cpu_write(hacdbs_pcp.status, HACDBS_IDLE);
break;
case HACDBSCONS_EL2_ERR_REASON_IPAHACF:
--
2.54.0
^ permalink raw reply related
* [PATCH v1 12/12] KVM: arm64: Enable KVM_HW_DIRTY_BIT
From: Leonardo Bras @ 2026-04-30 11:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Leonardo Bras, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Rafael J. Wysocki, Len Brown, Saket Dumbre, Paolo Bonzini,
Chengwen Feng, Jonathan Cameron, Kees Cook,
Mikołaj Lenczewski, Ryan Roberts, Yang Shi, Thomas Huth,
mrigendrachaubey, Yeoreum Yun, Mark Brown, Kevin Brodsky,
James Clark, Ard Biesheuvel, Fuad Tabba, Raghavendra Rao Ananta,
Nathan Chancellor, Vincent Donnefort, Lorenzo Pieralisi,
Sascha Bischoff, Anshuman Khandual, Tian Zheng, Wei-Lin Chang
Cc: linux-kernel, linux-arm-kernel, kvmarm, linux-acpi, acpica-devel,
kvm
In-Reply-To: <20260430111424.3479613-2-leo.bras@arm.com>
Set the corresponding bit to enable hardware accelerated dirty-bitmap and
dirty-ring cleaning for arm64. Actually using acceleration depends on the
cpus enabling FEAT_HACDBS as well as the pre-requisite features for it,
such as FEAT_HDBSS and FEAT_HAFDBS.
Also, add myself as maintainer for the new bits introduced.
Signed-off-by: Leonardo Bras <leo.bras@arm.com>
---
MAINTAINERS | 7 +++++++
arch/arm64/kvm/Kconfig | 1 +
2 files changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d25342ca8aa1..4b8a2b05b916 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2069,20 +2069,27 @@ F: arch/arm64/boot/dts/Makefile
ARM ARCHITECTED TIMER DRIVER
M: Mark Rutland <mark.rutland@arm.com>
M: Marc Zyngier <maz@kernel.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/include/asm/arch_timer.h
F: arch/arm64/include/asm/arch_timer.h
F: drivers/clocksource/arm_arch_timer.c
F: drivers/clocksource/arm_arch_timer_mmio.c
+ARM STAGE-2 DIRTY-BIT TRACKER/CLEANER ACCELERATOR
+M: Leonardo Bras <leo.bras@arm.com>
+L: kvmarm@lists.linux.dev
+S: Maintained
+F: arch/arm64/include/asm/kvm_dirty_bit.h
+F: arch/arm64/kvm/dirty_bit.c
+
ARM ETHOS-U NPU DRIVER
M: Rob Herring (Arm) <robh@kernel.org>
M: Tomeu Vizoso <tomeu@tomeuvizoso.net>
L: dri-devel@lists.freedesktop.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/accel/ethosu/
F: include/uapi/drm/ethosu_accel.h
ARM GENERIC INTERRUPT CONTROLLER DRIVERS
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 449154f9a485..db8487bf738b 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -27,20 +27,21 @@ menuconfig KVM
select VIRT_XFER_TO_GUEST_WORK
select KVM_VFIO
select HAVE_KVM_DIRTY_RING_ACQ_REL
select NEED_KVM_DIRTY_RING_WITH_BITMAP
select HAVE_KVM_MSI
select HAVE_KVM_IRQCHIP
select HAVE_KVM_IRQ_ROUTING
select HAVE_KVM_IRQ_BYPASS
select HAVE_KVM_READONLY_MEM
select HAVE_KVM_VCPU_RUN_PID_CHANGE
+ select HAVE_KVM_HW_DIRTY_BIT if ACPI
select SCHED_INFO
select GUEST_PERF_EVENTS if PERF_EVENTS
select KVM_GUEST_MEMFD
help
Support hosting virtualized guest machines.
If unsure, say N.
if KVM
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] EDAC/xilinx: Fix stack off-by-one in debugfs UE injection handlers
From: Datta, Shubhrajyoti @ 2026-04-30 11:16 UTC (permalink / raw)
To: Shengzhuo Wei, Shubhrajyoti Datta, Sai Krishna Potthuri,
Borislav Petkov, Tony Luck, Michal Simek
Cc: linux-edac, linux-kernel, linux-arm-kernel
In-Reply-To: <20260425-edac-stack-off-by-one-v1-1-4b2dd2b9c7df@cherr.cc>
On 4/25/2026 12:19 AM, Shengzhuo Wei wrote:
> [You don't often get email from me@cherr.cc. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> Two EDAC debugfs write handlers copy up to sizeof(buf) bytes into a
> fixed-size stack buffer and then unconditionally NUL-terminate it via
> buf[len] = '\0'. When userspace writes >= sizeof(buf) bytes, len
> becomes sizeof(buf) and the NUL write lands 1 byte past the end of the
> stack buffer.
>
> Fix by clamping the copy length to sizeof(buf) - 1 so that the NUL
> terminator is always in-bounds.
>
> Fixes: 3bd2706c910f ("EDAC/zynqmp: Add EDAC support for Xilinx ZynqMP OCM")
> Fixes: 83bf24051a60 ("EDAC/versal: Make the bit position of injected errors configurable")
> Signed-off-by: Shengzhuo Wei <me@cherr.cc>
> ---
Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
^ permalink raw reply
* [PATCH] fbdev: Consistently define pci_device_ids using named initializers
From: Uwe Kleine-König (The Capable Hub) @ 2026-04-30 11:16 UTC (permalink / raw)
To: Helge Deller
Cc: Benjamin Herrenschmidt, Russell King, Andres Salomon,
Antonino Daplas, linux-fbdev, dri-devel, linux-kernel,
linux-arm-kernel, linux-geode, Markus Schneider-Pargmann
... and PCI device helpers.
The various struct pci_device_id arrays were initialized mostly by list
expressions. This isn't easily readable if you're not into PCI. Using
named initializers is more explicit and thus easier to parse. Also use
PCI_DEVICE* helper macros to assign .vendor, .device, .subvendor and
.subdevice where appropriate and skip explicit assignments of 0 (which
the compiler takes care of).
The secret plan is to make struct pci_device_id::driver_data an
anonymous union (similar to
https://lore.kernel.org/all/cover.1776579304.git.u.kleine-koenig@baylibre.com/)
and that requires named initializers. But it's also a nice cleanup on
its own.
This change doesn't introduce changes to the compiled pci_device_id
array. Tested on x86 and arm64.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
Hello,
There is no benefit for radeon of the mentioned follow up quest as it
doesn't use pointers in .driver_data. Other drivers benefit from
- { PCI_VDEVICE(TTI, 0x3220), .driver_data = (kernel_ulong_t)&hptiop_itl_ops },
+ { PCI_VDEVICE(TTI, 0x3220), .driver_data_ptr = &hptiop_itl_ops },
which gets rid of a bunch of casts and so brings a little bit more type
safety. This patch is a preparation for that.
I assume a single patch for all of drivers/video/fbdev is fine. If not I
can split per driver.
drivers/video/fbdev/arkfb.c | 4 +-
drivers/video/fbdev/aty/aty128fb.c | 143 +++++++------------
drivers/video/fbdev/aty/radeon_base.c | 2 +-
drivers/video/fbdev/carminefb.c | 5 +-
drivers/video/fbdev/cirrusfb.c | 2 +-
drivers/video/fbdev/cyber2000fb.c | 24 ++--
drivers/video/fbdev/geode/gx1fb_core.c | 10 +-
drivers/video/fbdev/kyro/fbdev.c | 5 +-
drivers/video/fbdev/matrox/matroxfb_base.c | 38 ++---
drivers/video/fbdev/neofb.c | 29 ++--
drivers/video/fbdev/nvidia/nvidia.c | 9 +-
drivers/video/fbdev/pm2fb.c | 11 +-
drivers/video/fbdev/pm3fb.c | 5 +-
drivers/video/fbdev/pvr2fb.c | 5 +-
drivers/video/fbdev/riva/fbdev.c | 128 ++++++-----------
drivers/video/fbdev/s3fb.c | 32 ++---
drivers/video/fbdev/savage/savagefb_driver.c | 140 +++++++++---------
drivers/video/fbdev/sis/sis_main.h | 26 ++--
drivers/video/fbdev/tdfxfb.c | 21 +--
drivers/video/fbdev/tridentfb.c | 44 +++---
drivers/video/fbdev/vt8623fb.c | 4 +-
21 files changed, 292 insertions(+), 395 deletions(-)
diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
index 866c1165704e..195dbf4a5142 100644
--- a/drivers/video/fbdev/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
@@ -1167,8 +1167,8 @@ static const struct dev_pm_ops ark_pci_pm_ops = {
/* List of boards that we are trying to support */
static const struct pci_device_id ark_devices[] = {
- {PCI_DEVICE(0xEDD8, 0xA099)},
- {0, 0, 0, 0, 0, 0, 0}
+ { PCI_DEVICE(0xEDD8, 0xA099) },
+ { }
};
diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index f55b4c7609a8..bcb10e66221c 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -180,101 +180,54 @@ static const struct dev_pm_ops aty128_pci_pm_ops = {
/* supported Rage128 chipsets */
static const struct pci_device_id aty128_pci_tbl[] = {
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_MF,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_ML,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PB,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PC,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PD,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PE,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PG,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PH,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PI,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PJ,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PK,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PM,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PN,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PP,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PQ,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PS,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PT,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PU,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PV,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PW,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PX,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RG,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SE,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SF,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SG,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SH,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SK,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SM,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SN,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TF,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TS,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TT,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TU,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
- { 0, }
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_LE), .driver_data = rage_M3_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_LF), .driver_data = rage_M3 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_MF), .driver_data = rage_M4 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_ML), .driver_data = rage_M4 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PA), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PB), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PC), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PD), .driver_data = rage_128_pro_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PE), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PF), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PG), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PH), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PI), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PJ), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PK), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PL), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PM), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PN), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PO), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PP), .driver_data = rage_128_pro_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PQ), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PR), .driver_data = rage_128_pro_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PS), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PT), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PU), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PV), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PW), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_PX), .driver_data = rage_128_pro },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_RE), .driver_data = rage_128_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_RF), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_RG), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_RK), .driver_data = rage_128_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_RL), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SE), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SF), .driver_data = rage_128_pci },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SG), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SH), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SK), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SL), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SM), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_SN), .driver_data = rage_128 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_TF), .driver_data = rage_128_ultra },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_TL), .driver_data = rage_128_ultra },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_TR), .driver_data = rage_128_ultra },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_TS), .driver_data = rage_128_ultra },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_TT), .driver_data = rage_128_ultra },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_RAGE128_TU), .driver_data = rage_128_ultra },
+ { }
};
MODULE_DEVICE_TABLE(pci, aty128_pci_tbl);
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index cb006484831b..adb03489bedf 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -95,7 +95,7 @@
#define MIN_MAPPED_VRAM (1024*768*1)
#define CHIP_DEF(id, family, flags) \
- { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, id), .driver_data = (flags) | (CHIP_FAMILY_##family) }
static const struct pci_device_id radeonfb_pci_table[] = {
/* Radeon Xpress 200m */
diff --git a/drivers/video/fbdev/carminefb.c b/drivers/video/fbdev/carminefb.c
index bd4bff6a2484..5f13f1cc79d3 100644
--- a/drivers/video/fbdev/carminefb.c
+++ b/drivers/video/fbdev/carminefb.c
@@ -753,9 +753,8 @@ static void carminefb_remove(struct pci_dev *dev)
#define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf
static struct pci_device_id carmine_devices[] = {
-{
- PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED, 0x202b)},
- {0, 0, 0, 0, 0, 0, 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED, 0x202b) },
+ { }
};
MODULE_DEVICE_TABLE(pci, carmine_devices);
diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index e29217e476ea..2693b5cc053f 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -253,7 +253,7 @@ static const struct cirrusfb_board_info_rec {
#ifdef CONFIG_PCI
#define CHIP(id, btype) \
- { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
+ { PCI_VDEVICE(CIRRUS, id), .driver_data = (btype) }
static struct pci_device_id cirrusfb_pci_table[] = {
CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index 2d12f8e96c7e..3daba94c6c13 100644
--- a/drivers/video/fbdev/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
@@ -1796,16 +1796,22 @@ static int __maybe_unused cyberpro_pci_resume(struct device *dev)
static struct pci_device_id cyberpro_pci_table[] = {
/* Not yet
- * { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
- * PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+ * {
+ * PCI_VDEVICE(INTERG, PCI_DEVICE_ID_INTERG_1682),
+ * .driver_data = ID_IGA_1682,
+ * },
*/
- { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
- { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 },
- { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 },
- { 0, }
+ {
+ PCI_VDEVICE(INTERG, PCI_DEVICE_ID_INTERG_2000),
+ .driver_data = ID_CYBERPRO_2000,
+ }, {
+ PCI_VDEVICE(INTERG, PCI_DEVICE_ID_INTERG_2010),
+ .driver_data = ID_CYBERPRO_2010,
+ }, {
+ PCI_VDEVICE(INTERG, PCI_DEVICE_ID_INTERG_5000),
+ .driver_data = ID_CYBERPRO_5000,
+ },
+ { }
};
MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
diff --git a/drivers/video/fbdev/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
index a1919c1934ac..7cca46891aef 100644
--- a/drivers/video/fbdev/geode/gx1fb_core.c
+++ b/drivers/video/fbdev/geode/gx1fb_core.c
@@ -423,10 +423,12 @@ static void __init gx1fb_setup(char *options)
#endif
static struct pci_device_id gx1fb_id_table[] = {
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_VIDEO,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
- { 0, }
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_VIDEO),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff0000,
+ },
+ { }
};
MODULE_DEVICE_TABLE(pci, gx1fb_id_table);
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index c8b1dfa456a3..d756b3603fa6 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -645,9 +645,8 @@ static int kyrofb_ioctl(struct fb_info *info,
}
static const struct pci_device_id kyrofb_pci_tbl[] = {
- { PCI_VENDOR_ID_ST, PCI_DEVICE_ID_STG4000,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0, }
+ { PCI_DEVICE(PCI_VENDOR_ID_ST, PCI_DEVICE_ID_STG4000) },
+ { }
};
MODULE_DEVICE_TABLE(pci, kyrofb_pci_tbl);
diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
index e1a4bc7c2318..22774eb1b14c 100644
--- a/drivers/video/fbdev/matrox/matroxfb_base.c
+++ b/drivers/video/fbdev/matrox/matroxfb_base.c
@@ -1642,7 +1642,7 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
int err;
static const struct pci_device_id intel_82437[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82437) },
{ },
};
@@ -2135,35 +2135,23 @@ static void pci_remove_matrox(struct pci_dev* pdev) {
static const struct pci_device_id matroxfb_devices[] = {
#ifdef CONFIG_FB_MATROX_MILLENIUM
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_MIL) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_MIL_2) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP) },
#endif
#ifdef CONFIG_FB_MATROX_MYSTIQUE
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_MYS) },
#endif
#ifdef CONFIG_FB_MATROX_G
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, 0x0532,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_G100_MM) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_G100_AGP) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_G200_PCI) },
+ { PCI_VDEVICE(MATROX, 0x0532) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_G200_AGP) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_G400) },
+ { PCI_VDEVICE(MATROX, PCI_DEVICE_ID_MATROX_G550) },
#endif
- {0, 0,
- 0, 0, 0, 0, 0}
+ { }
};
MODULE_DEVICE_TABLE(pci, matroxfb_devices);
diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c
index c1cd028b8991..e0b8d4d6ce79 100644
--- a/drivers/video/fbdev/neofb.c
+++ b/drivers/video/fbdev/neofb.c
@@ -2126,34 +2126,25 @@ static void neofb_remove(struct pci_dev *dev)
}
static const struct pci_device_id neofb_devices[] = {
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2070,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2070},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2070), .driver_data = FB_ACCEL_NEOMAGIC_NM2070 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2090,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2090},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2090), .driver_data = FB_ACCEL_NEOMAGIC_NM2090 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2093,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2093},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2093), .driver_data = FB_ACCEL_NEOMAGIC_NM2093 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2097,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2097},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2097), .driver_data = FB_ACCEL_NEOMAGIC_NM2097 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2160,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2160},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2160), .driver_data = FB_ACCEL_NEOMAGIC_NM2160 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2200,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2200},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2200), .driver_data = FB_ACCEL_NEOMAGIC_NM2200 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2230,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2230},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2230), .driver_data = FB_ACCEL_NEOMAGIC_NM2230 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2360,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2360},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2360), .driver_data = FB_ACCEL_NEOMAGIC_NM2360 },
- {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2380,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2380},
+ { PCI_VDEVICE(NEOMAGIC, PCI_CHIP_NM2380), .driver_data = FB_ACCEL_NEOMAGIC_NM2380 },
- {0, 0, 0, 0, 0, 0, 0}
+ { }
};
MODULE_DEVICE_TABLE(pci, neofb_devices);
diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index 72b85f475605..da2d486022e8 100644
--- a/drivers/video/fbdev/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
@@ -58,9 +58,12 @@
#define MAX_CURS 32
static const struct pci_device_id nvidiafb_pci_tbl[] = {
- {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
- PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0},
- { 0, }
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff0000
+ },
+ { }
};
MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index f34429829b7d..412ff249b5c7 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -1748,13 +1748,10 @@ static void pm2fb_remove(struct pci_dev *pdev)
}
static const struct pci_device_id pm2fb_id_table[] = {
- { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0, }
+ { PCI_VDEVICE(TI, PCI_DEVICE_ID_TI_TVP4020) },
+ { PCI_VDEVICE(3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2) },
+ { PCI_VDEVICE(3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V) },
+ { }
};
static struct pci_driver pm2fb_driver = {
diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c
index 6e55e42514d6..6f552ae36219 100644
--- a/drivers/video/fbdev/pm3fb.c
+++ b/drivers/video/fbdev/pm3fb.c
@@ -1486,9 +1486,8 @@ static void pm3fb_remove(struct pci_dev *dev)
}
static const struct pci_device_id pm3fb_id_table[] = {
- { PCI_VENDOR_ID_3DLABS, 0x0a,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0, }
+ { PCI_VDEVICE(3DLABS, 0x000a) },
+ { }
};
/* For PCI drivers */
diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index 3f6384e631b1..06aefad75f46 100644
--- a/drivers/video/fbdev/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
@@ -993,9 +993,8 @@ static void pvr2fb_pci_remove(struct pci_dev *pdev)
}
static const struct pci_device_id pvr2fb_pci_tbl[] = {
- { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NEON250,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0, },
+ { PCI_VDEVICE(NEC, PCI_DEVICE_ID_NEC_NEON250), },
+ { },
};
MODULE_DEVICE_TABLE(pci, pvr2fb_pci_tbl);
diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 1e377b2ec089..2268fea4d807 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -103,92 +103,50 @@ static int rivafb_blank(int blank, struct fb_info *info);
* ------------------------------------------------------------------------- */
static const struct pci_device_id rivafb_pci_tbl[] = {
- { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440) },
// NF2/IGP version, GeForce 4 MX, NV18
- { PCI_VENDOR_ID_NVIDIA, 0x01f0,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0, } /* terminate list */
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x01f0) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200) },
+ { } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index ba30e5568cab..831e9e6861b1 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -1563,24 +1563,24 @@ static const struct dev_pm_ops s3_pci_pm_ops = {
/* List of boards that we are trying to support */
static const struct pci_device_id s3_devices[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8810), .driver_data = CHIP_XXX_TRIO},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8811), .driver_data = CHIP_XXX_TRIO},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8812), .driver_data = CHIP_M65_AURORA64VP},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8814), .driver_data = CHIP_767_TRIO64UVP},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8901), .driver_data = CHIP_XXX_TRIO64V2_DXGX},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8902), .driver_data = CHIP_551_PLATO_PX},
+ { PCI_VDEVICE(S3, 0x8810), .driver_data = CHIP_XXX_TRIO },
+ { PCI_VDEVICE(S3, 0x8811), .driver_data = CHIP_XXX_TRIO },
+ { PCI_VDEVICE(S3, 0x8812), .driver_data = CHIP_M65_AURORA64VP },
+ { PCI_VDEVICE(S3, 0x8814), .driver_data = CHIP_767_TRIO64UVP },
+ { PCI_VDEVICE(S3, 0x8901), .driver_data = CHIP_XXX_TRIO64V2_DXGX },
+ { PCI_VDEVICE(S3, 0x8902), .driver_data = CHIP_551_PLATO_PX },
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_357_VIRGE_GX2},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_359_VIRGE_GX2P},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
- {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8C01), .driver_data = CHIP_260_VIRGE_MX},
+ { PCI_VDEVICE(S3, 0x5631), .driver_data = CHIP_325_VIRGE },
+ { PCI_VDEVICE(S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX },
+ { PCI_VDEVICE(S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX },
+ { PCI_VDEVICE(S3, 0x8A10), .driver_data = CHIP_357_VIRGE_GX2 },
+ { PCI_VDEVICE(S3, 0x8A11), .driver_data = CHIP_359_VIRGE_GX2P },
+ { PCI_VDEVICE(S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P },
+ { PCI_VDEVICE(S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X },
+ { PCI_VDEVICE(S3, 0x8904), .driver_data = CHIP_365_TRIO3D },
+ { PCI_VDEVICE(S3, 0x8C01), .driver_data = CHIP_260_VIRGE_MX },
- {0, 0, 0, 0, 0, 0, 0}
+ { }
};
diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index c2f79357c8da..7789196d2eb5 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -2449,76 +2449,78 @@ static const struct dev_pm_ops savagefb_pm_ops = {
};
static const struct pci_device_id savagefb_devices[] = {
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_MX128,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
+ {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_MX128),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_MX64),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_MX64C),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_IX128SDR),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_IX128DDR),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_IX64SDR),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_IX64DDR),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_IXCSDR),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SUPSAV_IXCDDR),
+ .driver_data = FB_ACCEL_SUPERSAVAGE,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE4),
+ .driver_data = FB_ACCEL_SAVAGE4,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE3D),
+ .driver_data = FB_ACCEL_SAVAGE3D,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE3D_MV),
+ .driver_data = FB_ACCEL_SAVAGE3D_MV,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE2000),
+ .driver_data = FB_ACCEL_SAVAGE2000,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE_MX_MV),
+ .driver_data = FB_ACCEL_SAVAGE_MX_MV,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE_MX),
+ .driver_data = FB_ACCEL_SAVAGE_MX,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE_IX_MV),
+ .driver_data = FB_ACCEL_SAVAGE_IX_MV,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_SAVAGE_IX),
+ .driver_data = FB_ACCEL_SAVAGE_IX,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_PROSAVAGE_PM),
+ .driver_data = FB_ACCEL_PROSAVAGE_PM,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_PROSAVAGE_KM),
+ .driver_data = FB_ACCEL_PROSAVAGE_KM,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_S3TWISTER_P),
+ .driver_data = FB_ACCEL_S3TWISTER_P,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_S3TWISTER_K),
+ .driver_data = FB_ACCEL_S3TWISTER_K,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_PROSAVAGE_DDR),
+ .driver_data = FB_ACCEL_PROSAVAGE_DDR,
+ }, {
+ PCI_VDEVICE(S3, PCI_CHIP_PROSAVAGE_DDRK),
+ .driver_data = FB_ACCEL_PROSAVAGE_DDRK,
+ },
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_MX64,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_MX64C,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_IX128SDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_IX128DDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_IX64SDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_IX64DDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_IXCSDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SUPSAV_IXCDDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SUPERSAVAGE},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE4},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE3D,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE3D},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE3D_MV,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE3D_MV},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE2000},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE_MX_MV,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE_MX_MV},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE_MX,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE_MX},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE_IX_MV,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE_IX_MV},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE_IX,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_SAVAGE_IX},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_PROSAVAGE_PM,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_PROSAVAGE_PM},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_PROSAVAGE_KM,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_PROSAVAGE_KM},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_S3TWISTER_P,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_S3TWISTER_P},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_S3TWISTER_K,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_S3TWISTER_K},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_PROSAVAGE_DDR,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_PROSAVAGE_DDR},
-
- {PCI_VENDOR_ID_S3, PCI_CHIP_PROSAVAGE_DDRK,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_PROSAVAGE_DDRK},
-
- {0, 0, 0, 0, 0, 0, 0}
+ { }
};
MODULE_DEVICE_TABLE(pci, savagefb_devices);
diff --git a/drivers/video/fbdev/sis/sis_main.h b/drivers/video/fbdev/sis/sis_main.h
index 0965db9fad6a..4ca487f48205 100644
--- a/drivers/video/fbdev/sis/sis_main.h
+++ b/drivers/video/fbdev/sis/sis_main.h
@@ -102,22 +102,22 @@ static struct sisfb_chip_info {
static struct pci_device_id sisfb_pci_table[] = {
#ifdef CONFIG_FB_SIS_300
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_300), .driver_data = 0 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_540_VGA), .driver_data = 1 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_630_VGA), .driver_data = 2 },
#endif
#ifdef CONFIG_FB_SIS_315
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
- { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0,10},
- { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0,11},
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_315H), .driver_data = 3 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_315), .driver_data = 4 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_315PRO), .driver_data = 5 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_550_VGA), .driver_data = 6 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_650_VGA), .driver_data = 7 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_330), .driver_data = 8 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_660_VGA), .driver_data = 9 },
+ { PCI_VDEVICE(XGI, PCI_DEVICE_ID_XGI_20), .driver_data = 10 },
+ { PCI_VDEVICE(XGI, PCI_DEVICE_ID_XGI_40), .driver_data = 11 },
#endif
- { 0 }
+ { }
};
MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index 4c4e53aaea3a..a6b63c09b48f 100644
--- a/drivers/video/fbdev/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
@@ -124,16 +124,17 @@ static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id);
static void tdfxfb_remove(struct pci_dev *pdev);
static const struct pci_device_id tdfxfb_id_table[] = {
- { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
- { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
- { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
- { 0, }
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE),
+ .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff0000,
+ }, {
+ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3),
+ .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff0000,
+ }, {
+ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5),
+ .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff0000,
+ },
+ { }
};
static struct pci_driver tdfxfb_driver = {
diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c
index 17b7253b8fbe..a8fdbae83a80 100644
--- a/drivers/video/fbdev/tridentfb.c
+++ b/drivers/video/fbdev/tridentfb.c
@@ -1736,28 +1736,28 @@ static void trident_pci_remove(struct pci_dev *dev)
/* List of boards that we are trying to support */
static const struct pci_device_id trident_devices[] = {
- {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, TGUI9440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
+ { PCI_VDEVICE(TRIDENT, BLADE3D) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEi7) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEi7D) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEi1) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEi1D) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEAi1) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEAi1D) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEE4) },
+ { PCI_VDEVICE(TRIDENT, TGUI9440) },
+ { PCI_VDEVICE(TRIDENT, TGUI9660) },
+ { PCI_VDEVICE(TRIDENT, IMAGE975) },
+ { PCI_VDEVICE(TRIDENT, IMAGE985) },
+ { PCI_VDEVICE(TRIDENT, CYBER9320) },
+ { PCI_VDEVICE(TRIDENT, CYBER9388) },
+ { PCI_VDEVICE(TRIDENT, CYBER9520) },
+ { PCI_VDEVICE(TRIDENT, CYBER9525DVD) },
+ { PCI_VDEVICE(TRIDENT, CYBER9397) },
+ { PCI_VDEVICE(TRIDENT, CYBER9397DVD) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEXPAi1) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEXPm8) },
+ { PCI_VDEVICE(TRIDENT, CYBERBLADEXPm16) },
+ { }
};
MODULE_DEVICE_TABLE(pci, trident_devices);
diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index df984f3a7ff6..9708d968970a 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -900,8 +900,8 @@ static const struct dev_pm_ops vt8623_pci_pm_ops = {
/* List of boards that we are trying to support */
static const struct pci_device_id vt8623_devices[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_VIA, 0x3122)},
- {0, 0, 0, 0, 0, 0, 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, 0x3122) },
+ { }
};
MODULE_DEVICE_TABLE(pci, vt8623_devices);
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
--
2.47.3
^ permalink raw reply related
* [PATCH net-next v5 0/2] Add Frame Preemption MAC Merge support for ICSSG
From: Meghana Malladi @ 2026-04-30 11:17 UTC (permalink / raw)
To: vadim.fedorenko, haokexin, jacob.e.keller, horms, m-malladi, arnd,
parvathi, afd, basharath, vladimir.oltean, rogerq, danishanwar,
pabeni, kuba, edumazet, davem, andrew+netdev
Cc: linux-arm-kernel, netdev, linux-kernel, srk, Vignesh Raghavendra
This patch series adds QoS support to the ICSSG PRUETH driver.
The first patch implements mqprio qdisc handling and TC offload hooks
so userspace can request TC mappings and queue counts.
It also integrates a driver-side mechanism to program the firmware
with the IET/FPE preemption mask and to kick the firmware verify state
machine when frame preemption is enabled. The second patch adds ethtool
perations for the MAC Merge (Frame Preemption) sublayer, exposing .get_mm,
.set_mm and .get_mm_stats so admins can view and change MAC Merge
parameters and retrieve preemption statistics.
v4: https://lore.kernel.org/all/20260224124803.3634808-1-m-malladi@ti.com/
MD Danish Anwar (2):
net: ti: icssg-prueth: Add Frame Preemption MAC Merge support
net: ti: icssg-prueth: Add ethtool ops for Frame Preemption MAC Merge
drivers/net/ethernet/ti/Makefile | 3 +-
drivers/net/ethernet/ti/icssg/icssg_config.h | 9 -
drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 107 +++++++-
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 7 +
drivers/net/ethernet/ti/icssg/icssg_prueth.h | 9 +-
drivers/net/ethernet/ti/icssg/icssg_qos.c | 232 ++++++++++++++++++
drivers/net/ethernet/ti/icssg/icssg_qos.h | 106 ++++++++
drivers/net/ethernet/ti/icssg/icssg_stats.c | 5 +-
drivers/net/ethernet/ti/icssg/icssg_stats.h | 5 +
.../net/ethernet/ti/icssg/icssg_switch_map.h | 5 +
10 files changed, 471 insertions(+), 17 deletions(-)
create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.c
create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.h
base-commit: 790ead9394860e7d70c5e0e50a35b243e909a618
--
2.43.0
^ permalink raw reply
* [PATCH net-next v5 1/2] net: ti: icssg-prueth: Add Frame Preemption MAC Merge support
From: Meghana Malladi @ 2026-04-30 11:17 UTC (permalink / raw)
To: vadim.fedorenko, haokexin, jacob.e.keller, horms, m-malladi, arnd,
parvathi, afd, basharath, vladimir.oltean, rogerq, danishanwar,
pabeni, kuba, edumazet, davem, andrew+netdev
Cc: linux-arm-kernel, netdev, linux-kernel, srk, Vignesh Raghavendra
In-Reply-To: <20260430111723.497113-1-m-malladi@ti.com>
From: MD Danish Anwar <danishanwar@ti.com>
Introduce QoS infrastructure for Frame Preemption (FPE) support in
the ICSSG Ethernet driver.
prueth_qos_iet tracks FPE enable/active state and verify state machine
status via firmware-reported enum icssg_ietfpe_verify_states.
icssg_config_ietfpe() configures IET FPE in firmware, triggers
verify state machine based on ethtool MAC Merge parameters.
Polls firmware verify status up to 3 times with verify_time_ms intervals
and driver handles timeout by logging error and returning.
For MQPRIO qdisc support all queues are express by default later
gets override by user-provided preemptible_tcs bitmask via tc qdisc mask
Preempt mask configuration: Maps traffic classes to queue express/preemptible
state and applied only when FPE is active (Tx enabled)
Verify state machine re-triggers on link up/down events based on
fpe_enabled and fpe_active flags, and for memory protection, fpe_lock
serializes all FPE state mutations, preventing races between ethtool
config, qdisc setup, and link events
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
changes from v4(v5-v4):
- preemptible TCs are committed to hardware only when FPE is active
- Removed workqueue implementation with direct call to configure FPE
- Changed MAC verification logic to poll at verify_time_ms intervals
instead of 5 seconds.
- Used mutex_lock whenever necessary to ensure proper synchronization
All the above changes are addressed as part of Vladimir Oltean <vladimir.oltean@nxp.com>
comments for this patch
drivers/net/ethernet/ti/Makefile | 3 +-
drivers/net/ethernet/ti/icssg/icssg_config.h | 9 -
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 7 +
drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 +
drivers/net/ethernet/ti/icssg/icssg_qos.c | 232 +++++++++++++++++++
drivers/net/ethernet/ti/icssg/icssg_qos.h | 68 ++++++
6 files changed, 311 insertions(+), 10 deletions(-)
create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.c
create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.h
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index f4276c9a77620..d19bcd25c9d07 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -46,6 +46,7 @@ icssg-y := icssg/icssg_common.o \
icssg/icssg_config.o \
icssg/icssg_mii_cfg.o \
icssg/icssg_stats.o \
- icssg/icssg_ethtool.o
+ icssg/icssg_ethtool.o \
+ icssg/icssg_qos.o
obj-$(CONFIG_TI_ICSS_IEP) += icssg/icss_iep.o
diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
index 60d69744ffae2..1ac202f855ed4 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
@@ -323,13 +323,4 @@ struct prueth_fdb_slot {
u8 fid;
u8 fid_c2;
} __packed;
-
-enum icssg_ietfpe_verify_states {
- ICSSG_IETFPE_STATE_UNKNOWN = 0,
- ICSSG_IETFPE_STATE_INITIAL,
- ICSSG_IETFPE_STATE_VERIFYING,
- ICSSG_IETFPE_STATE_SUCCEEDED,
- ICSSG_IETFPE_STATE_FAILED,
- ICSSG_IETFPE_STATE_DISABLED
-};
#endif /* __NET_TI_ICSSG_CONFIG_H */
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 591be5c8056b4..7657dc1015f0a 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -392,6 +392,8 @@ static void emac_adjust_link(struct net_device *ndev)
} else {
icssg_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE);
}
+
+ icssg_qos_link_state_update(ndev);
}
if (emac->link) {
@@ -1652,6 +1654,7 @@ static const struct net_device_ops emac_netdev_ops = {
.ndo_hwtstamp_get = icssg_ndo_get_ts_config,
.ndo_hwtstamp_set = icssg_ndo_set_ts_config,
.ndo_xsk_wakeup = prueth_xsk_wakeup,
+ .ndo_setup_tc = icssg_qos_ndo_setup_tc,
};
static int prueth_netdev_init(struct prueth *prueth,
@@ -1686,6 +1689,8 @@ static int prueth_netdev_init(struct prueth *prueth,
INIT_DELAYED_WORK(&emac->stats_work, icssg_stats_work_handler);
+ icssg_qos_init(ndev);
+
ret = pruss_request_mem_region(prueth->pruss,
port == PRUETH_PORT_MII0 ?
PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1,
@@ -2461,6 +2466,7 @@ static int prueth_probe(struct platform_device *pdev)
}
unregister_netdev(prueth->registered_netdevs[i]);
disable_work_sync(&prueth->emac[i]->rx_mode_work);
+ mutex_destroy(&prueth->emac[i]->qos.iet.fpe_lock);
}
netdev_exit:
@@ -2521,6 +2527,7 @@ static void prueth_remove(struct platform_device *pdev)
prueth->emac[i]->ndev->phydev = NULL;
unregister_netdev(prueth->registered_netdevs[i]);
disable_work_sync(&prueth->emac[i]->rx_mode_work);
+ mutex_destroy(&prueth->emac[i]->qos.iet.fpe_lock);
}
for (i = 0; i < PRUETH_NUM_MACS; i++) {
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index df93d15c5b786..85f7017d2c8e7 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -44,6 +44,7 @@
#include "icssg_config.h"
#include "icss_iep.h"
#include "icssg_switch_map.h"
+#include "icssg_qos.h"
#define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN)
#define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN)
@@ -254,6 +255,7 @@ struct prueth_emac {
struct bpf_prog *xdp_prog;
struct xdp_attachment_info xdpi;
int xsk_qid;
+ struct prueth_qos qos;
};
/* The buf includes headroom compatible with both skb and xdpf */
diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.c b/drivers/net/ethernet/ti/icssg/icssg_qos.c
new file mode 100644
index 0000000000000..fc4b0ebc7d683
--- /dev/null
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Texas Instruments ICSSG PRUETH QoS submodule
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "icssg_prueth.h"
+#include "icssg_switch_map.h"
+
+static void icssg_iet_set_preempt_mask(struct prueth_emac *emac)
+{
+ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+ struct prueth_qos_mqprio *p_mqprio = &emac->qos.mqprio;
+ struct tc_mqprio_qopt *qopt = &p_mqprio->mqprio.qopt;
+ u8 preemptible_tcs = p_mqprio->preemptible_tcs;
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int prempt_mask = 0, i;
+ u8 tc;
+
+ /* The preemptible traffic classes should only be committed to hardware
+ * once TX is active.
+ */
+ if (!iet->fpe_active) {
+ netdev_dbg(emac->ndev, "FPE not active, skipping preempt mask config\n");
+ return;
+ }
+
+ /* Configure the queues based on the preemptible tc map set by the user */
+ for (tc = 0; tc < p_mqprio->mqprio.qopt.num_tc; tc++) {
+ /* check if the tc is preemptive or not */
+ if (preemptible_tcs & BIT(tc)) {
+ for (i = qopt->offset[tc]; i < qopt->offset[tc] + qopt->count[tc]; i++) {
+ /* Set all the queues in this tc as preemptive queues */
+ writeb(BIT(4), config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+ prempt_mask &= ~BIT(i);
+ }
+ } else {
+ /* Set all the queues in this tc as express queues */
+ for (i = qopt->offset[tc]; i < qopt->offset[tc] + qopt->count[tc]; i++) {
+ writeb(0, config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+ prempt_mask |= BIT(i);
+ }
+ }
+ netdev_set_tc_queue(emac->ndev, tc, qopt->count[tc], qopt->offset[tc]);
+ }
+ writeb(prempt_mask, config + EXPRESS_PRE_EMPTIVE_Q_MASK);
+}
+
+static int icssg_iet_verify_wait(struct prueth_emac *emac)
+{
+ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int try = 3;
+
+ do {
+ msleep(iet->verify_time_ms);
+ iet->verify_status = readb(config + PRE_EMPTION_VERIFY_STATUS);
+ if (iet->verify_status == ICSSG_IETFPE_STATE_SUCCEEDED)
+ return 0;
+ } while (--try > 0);
+
+ netdev_err(emac->ndev, "MAC Verify timeout\n");
+ return -ETIMEDOUT;
+}
+
+/* Direct synchronous configuration of IET FPE.
+ * Caller must hold iet->fpe_lock.
+ */
+void icssg_config_ietfpe(struct prueth_emac *emac, bool enable)
+{
+ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int ret;
+ u8 val;
+
+ /* return early if FPE is not active and need not be enabled */
+ if (!iet->fpe_enabled && !iet->fpe_active)
+ return;
+
+ if (!netif_running(emac->ndev)) {
+ netdev_dbg(emac->ndev, "cannot change IET/FPE state when interface is down\n");
+ return;
+ }
+
+ /* Update FPE Tx enable bit (PRE_EMPTION_ENABLE_TX) if
+ * fpe_enabled is set to enable MM in Tx direction
+ */
+ writeb(enable ? 1 : 0, config + PRE_EMPTION_ENABLE_TX);
+
+ /* If FPE is to be enabled, first configure MAC Verify state
+ * machine in firmware as firmware kicks the Verify process
+ * as soon as ICSSG_EMAC_PORT_PREMPT_TX_ENABLE command is
+ * received.
+ */
+ if (enable && iet->mac_verify_configure) {
+ writeb(1, config + PRE_EMPTION_ENABLE_VERIFY);
+ writew(iet->tx_min_frag_size, config + PRE_EMPTION_ADD_FRAG_SIZE_LOCAL);
+ writel(iet->verify_time_ms, config + PRE_EMPTION_VERIFY_TIME);
+ } else {
+ iet->verify_status = ICSSG_IETFPE_STATE_DISABLED;
+ }
+
+ /* Send command to enable FPE Tx side. Rx is always enabled */
+ ret = icssg_set_port_state(emac,
+ enable ? ICSSG_EMAC_PORT_PREMPT_TX_ENABLE :
+ ICSSG_EMAC_PORT_PREMPT_TX_DISABLE);
+ if (ret) {
+ netdev_err(emac->ndev, "TX preempt %s command failed\n",
+ str_enable_disable(enable));
+ writeb(0, config + PRE_EMPTION_ENABLE_VERIFY);
+ iet->verify_status = ICSSG_IETFPE_STATE_DISABLED;
+ return;
+ }
+
+ if (enable && iet->mac_verify_configure) {
+ ret = icssg_iet_verify_wait(emac);
+ if (ret) {
+ netdev_err(emac->ndev, "MAC Verification failed with timeout\n");
+ return;
+ }
+ } else if (enable) {
+ /* Give firmware some time to update PRE_EMPTION_ACTIVE_TX state */
+ usleep_range(100, 200);
+ }
+
+ if (enable) {
+ val = readb(config + PRE_EMPTION_ACTIVE_TX);
+ if (val != 1) {
+ netdev_err(emac->ndev,
+ "Firmware fails to activate IET/FPE\n");
+ return;
+ }
+ iet->fpe_active = true;
+ } else {
+ iet->fpe_active = false;
+ }
+
+ icssg_iet_set_preempt_mask(emac);
+ netdev_err(emac->ndev, "IET FPE %s successfully\n",
+ str_enable_disable(iet->fpe_active));
+}
+EXPORT_SYMBOL_GPL(icssg_config_ietfpe);
+
+void icssg_qos_init(struct net_device *ndev)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+
+ iet->emac = emac;
+ mutex_init(&iet->fpe_lock);
+}
+
+static void icssg_iet_change_preemptible_tcs(struct prueth_emac *emac)
+{
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+
+ mutex_lock(&iet->fpe_lock);
+ icssg_config_ietfpe(emac, iet->fpe_enabled);
+ mutex_unlock(&iet->fpe_lock);
+}
+
+static int emac_tc_query_caps(struct net_device *ndev, void *type_data)
+{
+ struct tc_query_caps_base *base = type_data;
+
+ switch (base->type) {
+ case TC_SETUP_QDISC_MQPRIO: {
+ struct tc_mqprio_caps *caps = base->caps;
+
+ caps->validate_queue_counts = true;
+ return 0;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int emac_tc_setup_mqprio(struct net_device *ndev, void *type_data)
+{
+ struct tc_mqprio_qopt_offload *mqprio = type_data;
+ struct prueth_emac *emac = netdev_priv(ndev);
+ struct tc_mqprio_qopt *qopt = &mqprio->qopt;
+ struct prueth_qos_mqprio *p_mqprio;
+ u8 num_tc = mqprio->qopt.num_tc;
+ int tc, offset, count;
+
+ p_mqprio = &emac->qos.mqprio;
+
+ if (!num_tc) {
+ netdev_reset_tc(ndev);
+ p_mqprio->preemptible_tcs = 0;
+ p_mqprio->mqprio.qopt.num_tc = 0;
+ goto reset_tcs;
+ }
+
+ memcpy(&p_mqprio->mqprio, mqprio, sizeof(*mqprio));
+ p_mqprio->preemptible_tcs = mqprio->preemptible_tcs;
+ netdev_set_num_tc(ndev, mqprio->qopt.num_tc);
+
+ for (tc = 0; tc < num_tc; tc++) {
+ count = qopt->count[tc];
+ offset = qopt->offset[tc];
+ netdev_set_tc_queue(ndev, tc, count, offset);
+ }
+
+reset_tcs:
+ icssg_iet_change_preemptible_tcs(emac);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(icssg_qos_init);
+
+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+ void *type_data)
+{
+ switch (type) {
+ case TC_QUERY_CAPS:
+ return emac_tc_query_caps(ndev, type_data);
+ case TC_SETUP_QDISC_MQPRIO:
+ return emac_tc_setup_mqprio(ndev, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+EXPORT_SYMBOL_GPL(icssg_qos_ndo_setup_tc);
+
+void icssg_qos_link_state_update(struct net_device *ndev)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+
+ icssg_iet_change_preemptible_tcs(emac);
+}
+EXPORT_SYMBOL_GPL(icssg_qos_link_state_update);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.h b/drivers/net/ethernet/ti/icssg/icssg_qos.h
new file mode 100644
index 0000000000000..083f248c557de
--- /dev/null
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#ifndef __NET_TI_ICSSG_QOS_H
+#define __NET_TI_ICSSG_QOS_H
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+#include <net/pkt_sched.h>
+
+/**
+ * enum icssg_ietfpe_verify_states - status of MAC Merge Verify returned by firmware
+ * @ICSSG_IETFPE_STATE_UNKNOWN:
+ * verification status is unknown
+ * @ICSSG_IETFPE_STATE_INITIAL:
+ * Firmware returns this if verify state diagram is idle
+ * @ICSSG_IETFPE_STATE_VERIFYING:
+ * Firmware returns this if verification is ongoing
+ * @ICSSG_IETFPE_STATE_SUCCEEDED:
+ * Firmware returns this if verify state diagram completes verification
+ * @ICSSG_IETFPE_STATE_FAILED:
+ * Firmware returns this if verify state diagram fails during verification
+ * @ICSSG_IETFPE_STATE_DISABLED:
+ * verification is disabled by the driver
+ */
+enum icssg_ietfpe_verify_states {
+ ICSSG_IETFPE_STATE_UNKNOWN = 0,
+ ICSSG_IETFPE_STATE_INITIAL,
+ ICSSG_IETFPE_STATE_VERIFYING,
+ ICSSG_IETFPE_STATE_SUCCEEDED,
+ ICSSG_IETFPE_STATE_FAILED,
+ ICSSG_IETFPE_STATE_DISABLED
+};
+
+struct prueth_qos_mqprio {
+ struct tc_mqprio_qopt_offload mqprio;
+ u8 preemptible_tcs;
+};
+
+struct prueth_qos_iet {
+ struct prueth_emac *emac;
+
+ /* Configuration state - protected by fpe_lock */
+ bool fpe_enabled;
+ bool mac_verify_configure;
+ u32 tx_min_frag_size;
+ u32 verify_time_ms;
+
+ /* Runtime state - protected by fpe_lock */
+ bool fpe_active;
+ enum icssg_ietfpe_verify_states verify_status;
+
+ /* Synchronization: single mutex protects all FPE operations */
+ struct mutex fpe_lock;
+};
+
+struct prueth_qos {
+ struct prueth_qos_iet iet;
+ struct prueth_qos_mqprio mqprio;
+};
+
+void icssg_qos_init(struct net_device *ndev);
+void icssg_qos_link_state_update(struct net_device *ndev);
+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+ void *type_data);
+void icssg_config_ietfpe(struct prueth_emac *emac, bool enable);
+#endif /* __NET_TI_ICSSG_QOS_H */
--
2.43.0
^ 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