Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: core: rework phy_set_mode to accept phy mode and submode

Currently the attempt to add support for Ethernet interface mode PHY
(MII/GMII/RGMII) will lead to the necessity of extending enum phy_mode and
duplicate there values from phy_interface_t enum (or introduce more PHY
callbacks) [1]. Both approaches are ineffective and would lead to fast
bloating of enum phy_mode or struct phy_ops in the process of adding more
PHYs for different subsystems which will make them unmaintainable.

As discussed in [1] the solution could be to introduce dual level PHYs mode
configuration - PHY mode and PHY submode. The PHY mode will define generic
PHY type (subsystem - PCIE/ETHERNET/USB_) while the PHY submode - subsystem
specific interface mode. The last is usually already defined in
corresponding subsystem headers (phy_interface_t for Ethernet, enum
usb_device_speed for USB).

This patch is cumulative change which refactors PHY framework code to
support dual level PHYs mode configuration - PHY mode and PHY submode. It
extends .set_mode() callback to support additional parameter "int submode"
and converts all corresponding PHY drivers to support new .set_mode()
callback declaration.
The new extended PHY API
int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
is introduced to support dual level PHYs mode configuration and existing
phy_set_mode() API is converted to macros, so PHY framework consumers do
not need to be changed (~21 matches).

[1] http://lkml.kernel.org/r/d63588f6-9ab0-848a-5ad4-8073143bd95d@ti.com
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

authored by

Grygorii Strashko and committed by
Kishon Vijay Abraham I
79a5a18a 640ac147

+39 -22
+2 -1
drivers/phy/allwinner/phy-sun4i-usb.c
··· 478 478 return 0; 479 479 } 480 480 481 - static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode) 481 + static int sun4i_usb_phy_set_mode(struct phy *_phy, 482 + enum phy_mode mode, int submode) 482 483 { 483 484 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 484 485 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+3 -2
drivers/phy/amlogic/phy-meson-gxl-usb2.c
··· 152 152 return 0; 153 153 } 154 154 155 - static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode) 155 + static int phy_meson_gxl_usb2_set_mode(struct phy *phy, 156 + enum phy_mode mode, int submode) 156 157 { 157 158 struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); 158 159 ··· 210 209 /* power on the PHY by taking it out of reset mode */ 211 210 regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0); 212 211 213 - ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode); 212 + ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode, 0); 214 213 if (ret) { 215 214 phy_meson_gxl_usb2_power_off(phy); 216 215
+3 -2
drivers/phy/amlogic/phy-meson-gxl-usb3.c
··· 119 119 return 0; 120 120 } 121 121 122 - static int phy_meson_gxl_usb3_set_mode(struct phy *phy, enum phy_mode mode) 122 + static int phy_meson_gxl_usb3_set_mode(struct phy *phy, 123 + enum phy_mode mode, int submode) 123 124 { 124 125 struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); 125 126 ··· 165 164 if (ret) 166 165 goto err_disable_clk_phy; 167 166 168 - ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode); 167 + ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode, 0); 169 168 if (ret) 170 169 goto err_disable_clk_peripheral; 171 170
+2 -1
drivers/phy/marvell/phy-mvebu-cp110-comphy.c
··· 512 512 return ret; 513 513 } 514 514 515 - static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) 515 + static int mvebu_comphy_set_mode(struct phy *phy, 516 + enum phy_mode mode, int submode) 516 517 { 517 518 struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); 518 519
+1 -1
drivers/phy/mediatek/phy-mtk-tphy.c
··· 971 971 return 0; 972 972 } 973 973 974 - static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode) 974 + static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) 975 975 { 976 976 struct mtk_phy_instance *instance = phy_get_drvdata(phy); 977 977 struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+1 -1
drivers/phy/mediatek/phy-mtk-xsphy.c
··· 426 426 return 0; 427 427 } 428 428 429 - static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode) 429 + static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) 430 430 { 431 431 struct xsphy_instance *inst = phy_get_drvdata(phy); 432 432 struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
+1 -1
drivers/phy/mscc/phy-ocelot-serdes.c
··· 158 158 HSIO_HW_CFG_PCIE_ENA), 159 159 }; 160 160 161 - static int serdes_set_mode(struct phy *phy, enum phy_mode mode) 161 + static int serdes_set_mode(struct phy *phy, enum phy_mode mode, int submode) 162 162 { 163 163 struct serdes_macro *macro = phy_get_drvdata(phy); 164 164 unsigned int i;
+3 -3
drivers/phy/phy-core.c
··· 360 360 } 361 361 EXPORT_SYMBOL_GPL(phy_power_off); 362 362 363 - int phy_set_mode(struct phy *phy, enum phy_mode mode) 363 + int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) 364 364 { 365 365 int ret; 366 366 ··· 368 368 return 0; 369 369 370 370 mutex_lock(&phy->mutex); 371 - ret = phy->ops->set_mode(phy, mode); 371 + ret = phy->ops->set_mode(phy, mode, submode); 372 372 if (!ret) 373 373 phy->attrs.mode = mode; 374 374 mutex_unlock(&phy->mutex); 375 375 376 376 return ret; 377 377 } 378 - EXPORT_SYMBOL_GPL(phy_set_mode); 378 + EXPORT_SYMBOL_GPL(phy_set_mode_ext); 379 379 380 380 int phy_reset(struct phy *phy) 381 381 {
+2 -1
drivers/phy/qualcomm/phy-qcom-qmp.c
··· 1365 1365 return ret; 1366 1366 } 1367 1367 1368 - static int qcom_qmp_phy_set_mode(struct phy *phy, enum phy_mode mode) 1368 + static int qcom_qmp_phy_set_mode(struct phy *phy, 1369 + enum phy_mode mode, int submode) 1369 1370 { 1370 1371 struct qmp_phy *qphy = phy_get_drvdata(phy); 1371 1372 struct qcom_qmp *qmp = qphy->qmp;
+2 -1
drivers/phy/qualcomm/phy-qcom-qusb2.c
··· 425 425 HSTX_TRIM_MASK); 426 426 } 427 427 428 - static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode) 428 + static int qusb2_phy_set_mode(struct phy *phy, 429 + enum phy_mode mode, int submode) 429 430 { 430 431 struct qusb2_phy *qphy = phy_get_drvdata(phy); 431 432
+2 -1
drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c
··· 65 65 } 66 66 67 67 static 68 - int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy, enum phy_mode mode) 68 + int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy, 69 + enum phy_mode mode, int submode) 69 70 { 70 71 struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); 71 72
+2 -1
drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c
··· 84 84 } 85 85 86 86 static 87 - int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy, enum phy_mode mode) 87 + int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy, 88 + enum phy_mode mode, int submode) 88 89 { 89 90 struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); 90 91
+2 -1
drivers/phy/qualcomm/phy-qcom-usb-hs.c
··· 42 42 struct notifier_block vbus_notify; 43 43 }; 44 44 45 - static int qcom_usb_hs_phy_set_mode(struct phy *phy, enum phy_mode mode) 45 + static int qcom_usb_hs_phy_set_mode(struct phy *phy, 46 + enum phy_mode mode, int submode) 46 47 { 47 48 struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy); 48 49 u8 addr;
+2 -1
drivers/phy/ti/phy-da8xx-usb.c
··· 93 93 return 0; 94 94 } 95 95 96 - static int da8xx_usb20_phy_set_mode(struct phy *phy, enum phy_mode mode) 96 + static int da8xx_usb20_phy_set_mode(struct phy *phy, 97 + enum phy_mode mode, int submode) 97 98 { 98 99 struct da8xx_usb_phy *d_phy = phy_get_drvdata(phy); 99 100 u32 val;
+1 -1
drivers/phy/ti/phy-tusb1210.c
··· 53 53 return 0; 54 54 } 55 55 56 - static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode) 56 + static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode) 57 57 { 58 58 struct tusb1210 *tusb = phy_get_drvdata(phy); 59 59 int ret;
+10 -3
include/linux/phy/phy.h
··· 60 60 int (*exit)(struct phy *phy); 61 61 int (*power_on)(struct phy *phy); 62 62 int (*power_off)(struct phy *phy); 63 - int (*set_mode)(struct phy *phy, enum phy_mode mode); 63 + int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode); 64 64 int (*reset)(struct phy *phy); 65 65 int (*calibrate)(struct phy *phy); 66 66 struct module *owner; ··· 164 164 int phy_exit(struct phy *phy); 165 165 int phy_power_on(struct phy *phy); 166 166 int phy_power_off(struct phy *phy); 167 - int phy_set_mode(struct phy *phy, enum phy_mode mode); 167 + int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); 168 + #define phy_set_mode(phy, mode) \ 169 + phy_set_mode_ext(phy, mode, 0) 170 + 168 171 static inline enum phy_mode phy_get_mode(struct phy *phy) 169 172 { 170 173 return phy->attrs.mode; ··· 281 278 return -ENOSYS; 282 279 } 283 280 284 - static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) 281 + static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, 282 + int submode) 285 283 { 286 284 if (!phy) 287 285 return 0; 288 286 return -ENOSYS; 289 287 } 288 + 289 + #define phy_set_mode(phy, mode) \ 290 + phy_set_mode_ext(phy, mode, 0) 290 291 291 292 static inline enum phy_mode phy_get_mode(struct phy *phy) 292 293 {