Commit dc0092ce authored by Ladislav Michl's avatar Ladislav Michl Committed by Greg Kroah-Hartman

usb: dwc3: dwc3-octeon: Move node parsing into driver probe

Parse and verify device tree node first, then setup UCTL bridge
using verified values. This avoids needless allocations
in case DT misconfiguration was found in the middle of setup.
Signed-off-by: default avatarLadislav Michl <ladis@linux-mips.org>
Acked-by: default avatarThinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/ZMd/x3MHA4/QowMO@lenochSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c6110163
......@@ -261,69 +261,15 @@ static int dwc3_octeon_get_divider(void)
}
static int dwc3_octeon_setup(struct dwc3_octeon *octeon,
int ref_clk_sel, int ref_clk_fsel, int mpll_mul,
int power_gpio, int power_active_low)
{
int i, div, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
u32 clock_rate;
u64 val;
int div;
struct device *dev = octeon->dev;
void __iomem *uctl_ctl_reg = octeon->base + USBDRD_UCTL_CTL;
void __iomem *uctl_host_cfg_reg = octeon->base + USBDRD_UCTL_HOST_CFG;
if (dev->of_node) {
const char *ss_clock_type;
const char *hs_clock_type;
i = of_property_read_u32(dev->of_node,
"refclk-frequency", &clock_rate);
if (i) {
dev_err(dev, "No UCTL \"refclk-frequency\"\n");
return -EINVAL;
}
i = of_property_read_string(dev->of_node,
"refclk-type-ss", &ss_clock_type);
if (i) {
dev_err(dev, "No UCTL \"refclk-type-ss\"\n");
return -EINVAL;
}
i = of_property_read_string(dev->of_node,
"refclk-type-hs", &hs_clock_type);
if (i) {
dev_err(dev, "No UCTL \"refclk-type-hs\"\n");
return -EINVAL;
}
if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
ref_clk_sel = 0;
else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
ref_clk_sel = 2;
else
dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
hs_clock_type);
} else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0)
ref_clk_sel = 1;
else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
ref_clk_sel = 3;
else {
dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
hs_clock_type);
ref_clk_sel = 3;
}
} else
dev_warn(dev, "Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
ss_clock_type);
if ((ref_clk_sel == 0 || ref_clk_sel == 1) &&
(clock_rate != 100000000))
dev_warn(dev, "Invalid UCTL clock rate of %u, using 100000000 instead\n",
clock_rate);
} else {
dev_err(dev, "No USB UCTL device node\n");
return -EINVAL;
}
/*
* Step 1: Wait for all voltages to be stable...that surely
* happened before starting the kernel. SKIP
......@@ -367,24 +313,6 @@ static int dwc3_octeon_setup(struct dwc3_octeon *octeon,
val &= ~USBDRD_UCTL_CTL_REF_CLK_SEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_SEL, ref_clk_sel);
ref_clk_fsel = 0x07;
switch (clock_rate) {
default:
dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
clock_rate);
fallthrough;
case 100000000:
mpll_mul = 0x19;
if (ref_clk_sel < 2)
ref_clk_fsel = 0x27;
break;
case 50000000:
mpll_mul = 0x32;
break;
case 125000000:
mpll_mul = 0x28;
break;
}
val &= ~USBDRD_UCTL_CTL_REF_CLK_FSEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_REF_CLK_FSEL, ref_clk_fsel);
......@@ -483,8 +411,64 @@ static int dwc3_octeon_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct dwc3_octeon *octeon;
const char *hs_clock_type, *ss_clock_type;
int ref_clk_sel, ref_clk_fsel, mpll_mul;
int power_active_low, power_gpio;
int err, len;
u32 clock_rate;
if (of_property_read_u32(node, "refclk-frequency", &clock_rate)) {
dev_err(dev, "No UCTL \"refclk-frequency\"\n");
return -EINVAL;
}
if (of_property_read_string(node, "refclk-type-ss", &ss_clock_type)) {
dev_err(dev, "No UCTL \"refclk-type-ss\"\n");
return -EINVAL;
}
if (of_property_read_string(node, "refclk-type-hs", &hs_clock_type)) {
dev_err(dev, "No UCTL \"refclk-type-hs\"\n");
return -EINVAL;
}
ref_clk_sel = 2;
if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
ref_clk_sel = 0;
else if (strcmp(hs_clock_type, "pll_ref_clk"))
dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
hs_clock_type);
} else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0) {
ref_clk_sel = 1;
} else {
ref_clk_sel = 3;
if (strcmp(hs_clock_type, "pll_ref_clk"))
dev_warn(dev, "Invalid HS clock type %s, using pll_ref_clk instead\n",
hs_clock_type);
}
} else {
dev_warn(dev, "Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
ss_clock_type);
}
ref_clk_fsel = 0x07;
switch (clock_rate) {
default:
dev_warn(dev, "Invalid ref_clk %u, using 100000000 instead\n",
clock_rate);
fallthrough;
case 100000000:
mpll_mul = 0x19;
if (ref_clk_sel < 2)
ref_clk_fsel = 0x27;
break;
case 50000000:
mpll_mul = 0x32;
break;
case 125000000:
mpll_mul = 0x28;
break;
}
power_gpio = DWC3_GPIO_POWER_NONE;
power_active_low = 0;
......@@ -515,7 +499,8 @@ static int dwc3_octeon_probe(struct platform_device *pdev)
if (IS_ERR(octeon->base))
return PTR_ERR(octeon->base);
err = dwc3_octeon_setup(octeon, power_gpio, power_active_low);
err = dwc3_octeon_setup(octeon, ref_clk_sel, ref_clk_fsel, mpll_mul,
power_gpio, power_active_low);
if (err)
return err;
......
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