mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Merge tag 'phy-fix-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
Pull generic phy driver fixes from Vinod Koul: - Qualcomm repeater override properties, qmp pcie bindings fix for clocks and initialization sequence for firmware power down case - Marvell comphy bindings clock and child node constraints - Tegra xusb device reference leaks fix - TI omap usb device ref leak on unbind and RGMII IS settings fix * tag 'phy-fix-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: phy: qcom: qmp-pcie: Fix PHY initialization when powered down by firmware phy: ti: gmii-sel: Always write the RGMII ID setting dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings phy: ti-pipe3: fix device leak at unbind phy: ti: omap-usb2: fix device leak at unbind phy: tegra: xusb: fix device and OF node leak at probe dt-bindings: phy: marvell,comphy-cp110: Fix clock and child node constraints phy: qualcomm: phy-qcom-eusb2-repeater: fix override properties
This commit is contained in:
@@ -47,21 +47,19 @@ properties:
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
description: Reference clocks for CP110; MG clock, MG Core clock, AXI clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mg_clk
|
||||
- const: mg_core_clk
|
||||
- const: axi_clk
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
marvell,system-controller:
|
||||
description: Phandle to the Marvell system controller (CP110 only)
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
patternProperties:
|
||||
'^phy@[0-2]$':
|
||||
'^phy@[0-5]$':
|
||||
description: A COMPHY lane child node
|
||||
type: object
|
||||
additionalProperties: false
|
||||
@@ -69,10 +67,14 @@ patternProperties:
|
||||
properties:
|
||||
reg:
|
||||
description: COMPHY lane number
|
||||
maximum: 5
|
||||
|
||||
'#phy-cells':
|
||||
const: 1
|
||||
|
||||
connector:
|
||||
type: object
|
||||
|
||||
required:
|
||||
- reg
|
||||
- '#phy-cells'
|
||||
@@ -91,13 +93,24 @@ allOf:
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks: false
|
||||
clock-names: false
|
||||
clocks:
|
||||
maxItems: 1
|
||||
clock-names:
|
||||
const: xtal
|
||||
|
||||
required:
|
||||
- reg-names
|
||||
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: mg_clk
|
||||
- const: mg_core_clk
|
||||
- const: axi_clk
|
||||
|
||||
required:
|
||||
- marvell,system-controller
|
||||
|
||||
|
||||
@@ -176,6 +176,8 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x4-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x1-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x2-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x4-pcie-phy
|
||||
@@ -197,8 +199,6 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcs8300-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x2-pcie-phy
|
||||
- qcom,sa8775p-qmp-gen4x4-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
||||
@@ -127,13 +127,13 @@ static int eusb2_repeater_init(struct phy *phy)
|
||||
rptr->cfg->init_tbl[i].value);
|
||||
|
||||
/* Override registers from devicetree values */
|
||||
if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
|
||||
if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
|
||||
regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, val);
|
||||
|
||||
if (!of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &val))
|
||||
regmap_write(regmap, base + EUSB2_TUNE_HSDISC, val);
|
||||
|
||||
if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
|
||||
if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
|
||||
regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val);
|
||||
|
||||
/* Wait for status OK */
|
||||
|
||||
@@ -3067,6 +3067,14 @@ struct qmp_pcie {
|
||||
struct clk_fixed_rate aux_clk_fixed;
|
||||
};
|
||||
|
||||
static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = readl(base + offset);
|
||||
return (reg & val) == val;
|
||||
}
|
||||
|
||||
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
|
||||
{
|
||||
u32 reg;
|
||||
@@ -4339,16 +4347,21 @@ static int qmp_pcie_init(struct phy *phy)
|
||||
struct qmp_pcie *qmp = phy_get_drvdata(phy);
|
||||
const struct qmp_phy_cfg *cfg = qmp->cfg;
|
||||
void __iomem *pcs = qmp->pcs;
|
||||
bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
|
||||
int ret;
|
||||
|
||||
qmp->skip_init = qmp->nocsr_reset && phy_initialized;
|
||||
/*
|
||||
* We need to check the existence of init sequences in two cases:
|
||||
* 1. The PHY doesn't support no_csr reset.
|
||||
* 2. The PHY supports no_csr reset but isn't initialized by bootloader.
|
||||
* As we can't skip init in these two cases.
|
||||
* We can skip PHY initialization if all of the following conditions
|
||||
* are met:
|
||||
* 1. The PHY supports the nocsr_reset that preserves the PHY config.
|
||||
* 2. The PHY was started (and not powered down again) by the
|
||||
* bootloader, with all of the expected bits set correctly.
|
||||
* In this case, we can continue without having the init sequence
|
||||
* defined in the driver.
|
||||
*/
|
||||
qmp->skip_init = qmp->nocsr_reset &&
|
||||
qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
|
||||
qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
|
||||
|
||||
if (!qmp->skip_init && !cfg->tbls.serdes_num) {
|
||||
dev_err(qmp->dev, "Init sequence not available\n");
|
||||
return -ENODATA;
|
||||
|
||||
@@ -3164,18 +3164,22 @@ tegra210_xusb_padctl_probe(struct device *dev,
|
||||
}
|
||||
|
||||
pdev = of_find_device_by_node(np);
|
||||
of_node_put(np);
|
||||
if (!pdev) {
|
||||
dev_warn(dev, "PMC device is not available\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!platform_get_drvdata(pdev))
|
||||
if (!platform_get_drvdata(pdev)) {
|
||||
put_device(&pdev->dev);
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
|
||||
padctl->regmap = dev_get_regmap(&pdev->dev, "usb_sleepwalk");
|
||||
if (!padctl->regmap)
|
||||
dev_info(dev, "failed to find PMC regmap\n");
|
||||
|
||||
put_device(&pdev->dev);
|
||||
out:
|
||||
return &padctl->base;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ enum {
|
||||
PHY_GMII_SEL_PORT_MODE = 0,
|
||||
PHY_GMII_SEL_RGMII_ID_MODE,
|
||||
PHY_GMII_SEL_RMII_IO_CLK_EN,
|
||||
PHY_GMII_SEL_FIXED_TX_DELAY,
|
||||
PHY_GMII_SEL_LAST,
|
||||
};
|
||||
|
||||
@@ -127,6 +128,11 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* With a fixed delay, some modes are not supported at all. */
|
||||
if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY) &&
|
||||
rgmii_id != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if_phy->phy_if_mode = submode;
|
||||
|
||||
dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
|
||||
@@ -210,25 +216,46 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
|
||||
|
||||
static const
|
||||
struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
|
||||
{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
|
||||
{
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x0, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
|
||||
}, {
|
||||
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
|
||||
[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
|
||||
},
|
||||
};
|
||||
|
||||
static const
|
||||
struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
|
||||
.use_of_data = true,
|
||||
.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
|
||||
BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
|
||||
.regfields = phy_gmii_sel_fields_am654,
|
||||
};
|
||||
|
||||
static const
|
||||
struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
|
||||
.use_of_data = true,
|
||||
.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
|
||||
BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
|
||||
.regfields = phy_gmii_sel_fields_am654,
|
||||
.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
|
||||
BIT(PHY_INTERFACE_MODE_USXGMII),
|
||||
@@ -239,6 +266,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
|
||||
static const
|
||||
struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
|
||||
.use_of_data = true,
|
||||
.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
|
||||
BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
|
||||
.regfields = phy_gmii_sel_fields_am654,
|
||||
.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
|
||||
.num_ports = 8,
|
||||
@@ -248,6 +277,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
|
||||
static const
|
||||
struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j784s4 = {
|
||||
.use_of_data = true,
|
||||
.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
|
||||
BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
|
||||
.regfields = phy_gmii_sel_fields_am654,
|
||||
.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
|
||||
BIT(PHY_INTERFACE_MODE_USXGMII),
|
||||
|
||||
@@ -363,6 +363,13 @@ static void omap_usb2_init_errata(struct omap_usb *phy)
|
||||
phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;
|
||||
}
|
||||
|
||||
static void omap_usb2_put_device(void *_dev)
|
||||
{
|
||||
struct device *dev = _dev;
|
||||
|
||||
put_device(dev);
|
||||
}
|
||||
|
||||
static int omap_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_usb *phy;
|
||||
@@ -373,6 +380,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
|
||||
struct device_node *control_node;
|
||||
struct platform_device *control_pdev;
|
||||
const struct usb_phy_data *phy_data;
|
||||
int ret;
|
||||
|
||||
phy_data = device_get_match_data(&pdev->dev);
|
||||
if (!phy_data)
|
||||
@@ -423,6 +431,11 @@ static int omap_usb2_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
phy->control_dev = &control_pdev->dev;
|
||||
|
||||
ret = devm_add_action_or_reset(&pdev->dev, omap_usb2_put_device,
|
||||
phy->control_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
if (of_property_read_u32_index(node,
|
||||
"syscon-phy-power", 1,
|
||||
|
||||
@@ -667,12 +667,20 @@ static int ti_pipe3_get_clk(struct ti_pipe3 *phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ti_pipe3_put_device(void *_dev)
|
||||
{
|
||||
struct device *dev = _dev;
|
||||
|
||||
put_device(dev);
|
||||
}
|
||||
|
||||
static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
|
||||
{
|
||||
struct device *dev = phy->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct device_node *control_node;
|
||||
struct platform_device *control_pdev;
|
||||
int ret;
|
||||
|
||||
phy->phy_power_syscon = syscon_regmap_lookup_by_phandle(node,
|
||||
"syscon-phy-power");
|
||||
@@ -704,6 +712,11 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
|
||||
}
|
||||
|
||||
phy->control_dev = &control_pdev->dev;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, ti_pipe3_put_device,
|
||||
phy->control_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (phy->mode == PIPE3_MODE_PCIE) {
|
||||
|
||||
Reference in New Issue
Block a user