OSDN Git Service

usb: dwc3: dwc3-octeon: Move node parsing into driver probe
authorLadislav Michl <ladis@linux-mips.org>
Mon, 31 Jul 2023 09:32:55 +0000 (11:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Aug 2023 12:52:15 +0000 (14:52 +0200)
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: Ladislav Michl <ladis@linux-mips.org>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/ZMd/x3MHA4/QowMO@lenoch
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc3/dwc3-octeon.c

index 0dc45dd..330bcb5 100644 (file)
@@ -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;