Commit 79a5a18a authored by Grygorii Strashko's avatar Grygorii Strashko Committed by Kishon Vijay Abraham I

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.comSigned-off-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent 640ac147
...@@ -478,7 +478,8 @@ static int sun4i_usb_phy_power_off(struct phy *_phy) ...@@ -478,7 +478,8 @@ static int sun4i_usb_phy_power_off(struct phy *_phy)
return 0; return 0;
} }
static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode) static int sun4i_usb_phy_set_mode(struct phy *_phy,
enum phy_mode mode, int submode)
{ {
struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
......
...@@ -152,7 +152,8 @@ static int phy_meson_gxl_usb2_reset(struct phy *phy) ...@@ -152,7 +152,8 @@ static int phy_meson_gxl_usb2_reset(struct phy *phy)
return 0; return 0;
} }
static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode) static int phy_meson_gxl_usb2_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
...@@ -209,7 +210,7 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy) ...@@ -209,7 +210,7 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
/* power on the PHY by taking it out of reset mode */ /* power on the PHY by taking it out of reset mode */
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0); regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode); ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode, 0);
if (ret) { if (ret) {
phy_meson_gxl_usb2_power_off(phy); phy_meson_gxl_usb2_power_off(phy);
......
...@@ -119,7 +119,8 @@ static int phy_meson_gxl_usb3_power_off(struct phy *phy) ...@@ -119,7 +119,8 @@ static int phy_meson_gxl_usb3_power_off(struct phy *phy)
return 0; return 0;
} }
static int phy_meson_gxl_usb3_set_mode(struct phy *phy, enum phy_mode mode) static int phy_meson_gxl_usb3_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy); struct phy_meson_gxl_usb3_priv *priv = phy_get_drvdata(phy);
...@@ -164,7 +165,7 @@ static int phy_meson_gxl_usb3_init(struct phy *phy) ...@@ -164,7 +165,7 @@ static int phy_meson_gxl_usb3_init(struct phy *phy)
if (ret) if (ret)
goto err_disable_clk_phy; goto err_disable_clk_phy;
ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode); ret = phy_meson_gxl_usb3_set_mode(phy, priv->mode, 0);
if (ret) if (ret)
goto err_disable_clk_peripheral; goto err_disable_clk_peripheral;
......
...@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct phy *phy) ...@@ -512,7 +512,8 @@ static int mvebu_comphy_power_on(struct phy *phy)
return ret; return ret;
} }
static int mvebu_comphy_set_mode(struct phy *phy, enum phy_mode mode) static int mvebu_comphy_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
......
...@@ -971,7 +971,7 @@ static int mtk_phy_exit(struct phy *phy) ...@@ -971,7 +971,7 @@ static int mtk_phy_exit(struct phy *phy)
return 0; return 0;
} }
static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode) static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{ {
struct mtk_phy_instance *instance = phy_get_drvdata(phy); struct mtk_phy_instance *instance = phy_get_drvdata(phy);
struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
......
...@@ -426,7 +426,7 @@ static int mtk_phy_exit(struct phy *phy) ...@@ -426,7 +426,7 @@ static int mtk_phy_exit(struct phy *phy)
return 0; return 0;
} }
static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode) static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{ {
struct xsphy_instance *inst = phy_get_drvdata(phy); struct xsphy_instance *inst = phy_get_drvdata(phy);
struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent); struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
......
...@@ -158,7 +158,7 @@ static const struct serdes_mux ocelot_serdes_muxes[] = { ...@@ -158,7 +158,7 @@ static const struct serdes_mux ocelot_serdes_muxes[] = {
HSIO_HW_CFG_PCIE_ENA), HSIO_HW_CFG_PCIE_ENA),
}; };
static int serdes_set_mode(struct phy *phy, enum phy_mode mode) static int serdes_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{ {
struct serdes_macro *macro = phy_get_drvdata(phy); struct serdes_macro *macro = phy_get_drvdata(phy);
unsigned int i; unsigned int i;
......
...@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy) ...@@ -360,7 +360,7 @@ int phy_power_off(struct phy *phy)
} }
EXPORT_SYMBOL_GPL(phy_power_off); EXPORT_SYMBOL_GPL(phy_power_off);
int phy_set_mode(struct phy *phy, enum phy_mode mode) int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
{ {
int ret; int ret;
...@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode) ...@@ -368,14 +368,14 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode)
return 0; return 0;
mutex_lock(&phy->mutex); mutex_lock(&phy->mutex);
ret = phy->ops->set_mode(phy, mode); ret = phy->ops->set_mode(phy, mode, submode);
if (!ret) if (!ret)
phy->attrs.mode = mode; phy->attrs.mode = mode;
mutex_unlock(&phy->mutex); mutex_unlock(&phy->mutex);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(phy_set_mode); EXPORT_SYMBOL_GPL(phy_set_mode_ext);
int phy_reset(struct phy *phy) int phy_reset(struct phy *phy)
{ {
......
...@@ -1365,7 +1365,8 @@ static int qcom_qmp_phy_poweron(struct phy *phy) ...@@ -1365,7 +1365,8 @@ static int qcom_qmp_phy_poweron(struct phy *phy)
return ret; return ret;
} }
static int qcom_qmp_phy_set_mode(struct phy *phy, enum phy_mode mode) static int qcom_qmp_phy_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct qmp_phy *qphy = phy_get_drvdata(phy); struct qmp_phy *qphy = phy_get_drvdata(phy);
struct qcom_qmp *qmp = qphy->qmp; struct qcom_qmp *qmp = qphy->qmp;
......
...@@ -425,7 +425,8 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy) ...@@ -425,7 +425,8 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
HSTX_TRIM_MASK); HSTX_TRIM_MASK);
} }
static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode) static int qusb2_phy_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct qusb2_phy *qphy = phy_get_drvdata(phy); struct qusb2_phy *qphy = phy_get_drvdata(phy);
......
...@@ -65,7 +65,8 @@ static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy) ...@@ -65,7 +65,8 @@ static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy)
} }
static static
int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy, enum phy_mode mode) int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy,
enum phy_mode mode, int submode)
{ {
struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
......
...@@ -84,7 +84,8 @@ static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy) ...@@ -84,7 +84,8 @@ static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy)
} }
static static
int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy, enum phy_mode mode) int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy,
enum phy_mode mode, int submode)
{ {
struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
......
...@@ -42,7 +42,8 @@ struct qcom_usb_hs_phy { ...@@ -42,7 +42,8 @@ struct qcom_usb_hs_phy {
struct notifier_block vbus_notify; struct notifier_block vbus_notify;
}; };
static int qcom_usb_hs_phy_set_mode(struct phy *phy, enum phy_mode mode) static int qcom_usb_hs_phy_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy); struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
u8 addr; u8 addr;
......
...@@ -93,7 +93,8 @@ static int da8xx_usb20_phy_power_off(struct phy *phy) ...@@ -93,7 +93,8 @@ static int da8xx_usb20_phy_power_off(struct phy *phy)
return 0; return 0;
} }
static int da8xx_usb20_phy_set_mode(struct phy *phy, enum phy_mode mode) static int da8xx_usb20_phy_set_mode(struct phy *phy,
enum phy_mode mode, int submode)
{ {
struct da8xx_usb_phy *d_phy = phy_get_drvdata(phy); struct da8xx_usb_phy *d_phy = phy_get_drvdata(phy);
u32 val; u32 val;
......
...@@ -53,7 +53,7 @@ static int tusb1210_power_off(struct phy *phy) ...@@ -53,7 +53,7 @@ static int tusb1210_power_off(struct phy *phy)
return 0; return 0;
} }
static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode) static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{ {
struct tusb1210 *tusb = phy_get_drvdata(phy); struct tusb1210 *tusb = phy_get_drvdata(phy);
int ret; int ret;
......
...@@ -60,7 +60,7 @@ struct phy_ops { ...@@ -60,7 +60,7 @@ struct phy_ops {
int (*exit)(struct phy *phy); int (*exit)(struct phy *phy);
int (*power_on)(struct phy *phy); int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy); int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode); int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
int (*reset)(struct phy *phy); int (*reset)(struct phy *phy);
int (*calibrate)(struct phy *phy); int (*calibrate)(struct phy *phy);
struct module *owner; struct module *owner;
...@@ -164,7 +164,10 @@ int phy_init(struct phy *phy); ...@@ -164,7 +164,10 @@ int phy_init(struct phy *phy);
int phy_exit(struct phy *phy); int phy_exit(struct phy *phy);
int phy_power_on(struct phy *phy); int phy_power_on(struct phy *phy);
int phy_power_off(struct phy *phy); int phy_power_off(struct phy *phy);
int phy_set_mode(struct phy *phy, enum phy_mode mode); int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode);
#define phy_set_mode(phy, mode) \
phy_set_mode_ext(phy, mode, 0)
static inline enum phy_mode phy_get_mode(struct phy *phy) static inline enum phy_mode phy_get_mode(struct phy *phy)
{ {
return phy->attrs.mode; return phy->attrs.mode;
...@@ -278,13 +281,17 @@ static inline int phy_power_off(struct phy *phy) ...@@ -278,13 +281,17 @@ static inline int phy_power_off(struct phy *phy)
return -ENOSYS; return -ENOSYS;
} }
static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode,
int submode)
{ {
if (!phy) if (!phy)
return 0; return 0;
return -ENOSYS; return -ENOSYS;
} }
#define phy_set_mode(phy, mode) \
phy_set_mode_ext(phy, mode, 0)
static inline enum phy_mode phy_get_mode(struct phy *phy) static inline enum phy_mode phy_get_mode(struct phy *phy)
{ {
return PHY_MODE_INVALID; return PHY_MODE_INVALID;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment