]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: brcmstb: Check return value of all reset_control_* calls
authorJim Quinlan <james.quinlan@broadcom.com>
Thu, 15 Aug 2024 22:57:24 +0000 (18:57 -0400)
committerKrzysztof Wilczyński <kwilczynski@kernel.org>
Sat, 7 Sep 2024 16:37:44 +0000 (16:37 +0000)
Always check the return value for invocations of reset_control_xxx() and
propagate the error to the next level.

Although the current functions in reset-brcmstb.c cannot fail, this may
someday change.

Link: https://lore.kernel.org/linux-pci/20240815225731.40276-12-james.quinlan@broadcom.com
Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
[kwilczynski: commit log]
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Stanimir Varbanov <svarbanov@suse.de>
drivers/pci/controller/pcie-brcmstb.c

index 9bbef10fed0da26bd9ef389108efd9f7942ff675..ffb79c40e92590186de0627a3b8994219074cba6 100644 (file)
@@ -239,8 +239,8 @@ struct pcie_cfg_data {
        const enum pcie_type type;
        const bool has_phy;
        u8 num_inbound_wins;
-       void (*perst_set)(struct brcm_pcie *pcie, u32 val);
-       void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
+       int (*perst_set)(struct brcm_pcie *pcie, u32 val);
+       int (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
 };
 
 struct subdev_regulators {
@@ -285,8 +285,8 @@ struct brcm_pcie {
        int                     num_memc;
        u64                     memc_size[PCIE_BRCM_MAX_MEMC];
        u32                     hw_rev;
-       void                    (*perst_set)(struct brcm_pcie *pcie, u32 val);
-       void                    (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
+       int                     (*perst_set)(struct brcm_pcie *pcie, u32 val);
+       int                     (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
        struct subdev_regulators *sr;
        bool                    ep_wakeup_capable;
        bool                    has_phy;
@@ -749,26 +749,33 @@ static void __iomem *brcm7425_pcie_map_bus(struct pci_bus *bus,
        return base + DATA_ADDR(pcie);
 }
 
-static void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)
+static int brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)
 {
        u32 tmp, mask = RGR1_SW_INIT_1_INIT_GENERIC_MASK;
        u32 shift = RGR1_SW_INIT_1_INIT_GENERIC_SHIFT;
+       int ret = 0;
 
        if (pcie->bridge_reset) {
                if (val)
-                       reset_control_assert(pcie->bridge_reset);
+                       ret = reset_control_assert(pcie->bridge_reset);
                else
-                       reset_control_deassert(pcie->bridge_reset);
+                       ret = reset_control_deassert(pcie->bridge_reset);
 
-               return;
+               if (ret)
+                       dev_err(pcie->dev, "failed to %s 'bridge' reset, err=%d\n",
+                               val ? "assert" : "deassert", ret);
+
+               return ret;
        }
 
        tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
        tmp = (tmp & ~mask) | ((val << shift) & mask);
        writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+
+       return ret;
 }
 
-static void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val)
+static int brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val)
 {
        u32 tmp, mask =  RGR1_SW_INIT_1_INIT_7278_MASK;
        u32 shift = RGR1_SW_INIT_1_INIT_7278_SHIFT;
@@ -776,20 +783,29 @@ static void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val)
        tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
        tmp = (tmp & ~mask) | ((val << shift) & mask);
        writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+
+       return 0;
 }
 
-static void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
+static int brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
 {
+       int ret;
+
        if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
-               return;
+               return -EINVAL;
 
        if (val)
-               reset_control_assert(pcie->perst_reset);
+               ret = reset_control_assert(pcie->perst_reset);
        else
-               reset_control_deassert(pcie->perst_reset);
+               ret = reset_control_deassert(pcie->perst_reset);
+
+       if (ret)
+               dev_err(pcie->dev, "failed to %s 'perst' reset, err=%d\n",
+                       val ? "assert" : "deassert", ret);
+       return ret;
 }
 
-static void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
+static int brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
 {
        u32 tmp;
 
@@ -797,15 +813,19 @@ static void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
        tmp = readl(pcie->base + PCIE_MISC_PCIE_CTRL);
        u32p_replace_bits(&tmp, !val, PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK);
        writel(tmp, pcie->base +  PCIE_MISC_PCIE_CTRL);
+
+       return 0;
 }
 
-static void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
+static int brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
 {
        u32 tmp;
 
        tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
        u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK);
        writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
+
+       return 0;
 }
 
 static void add_inbound_win(struct inbound_win *b, u8 *count, u64 size,
@@ -1020,19 +1040,28 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
        u32 tmp, burst, aspm_support;
        u8 num_out_wins = 0;
        int num_inbound_wins = 0;
-       int memc;
+       int memc, ret;
 
        /* Reset the bridge */
-       pcie->bridge_sw_init_set(pcie, 1);
+       ret = pcie->bridge_sw_init_set(pcie, 1);
+       if (ret)
+               return ret;
 
        /* Ensure that PERST# is asserted; some bootloaders may deassert it. */
-       if (pcie->type == BCM2711)
-               pcie->perst_set(pcie, 1);
+       if (pcie->type == BCM2711) {
+               ret = pcie->perst_set(pcie, 1);
+               if (ret) {
+                       pcie->bridge_sw_init_set(pcie, 0);
+                       return ret;
+               }
+       }
 
        usleep_range(100, 200);
 
        /* Take the bridge out of reset */
-       pcie->bridge_sw_init_set(pcie, 0);
+       ret = pcie->bridge_sw_init_set(pcie, 0);
+       if (ret)
+               return ret;
 
        tmp = readl(base + HARD_DEBUG(pcie));
        if (is_bmips(pcie))
@@ -1251,7 +1280,9 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
        int ret, i;
 
        /* Unassert the fundamental reset */
-       pcie->perst_set(pcie, 0);
+       ret = pcie->perst_set(pcie, 0);
+       if (ret)
+               return ret;
 
        /*
         * Wait for 100ms after PERST# deassertion; see PCIe CEM specification
@@ -1443,15 +1474,17 @@ static inline int brcm_phy_stop(struct brcm_pcie *pcie)
        return pcie->has_phy ? brcm_phy_cntl(pcie, 0) : 0;
 }
 
-static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
+static int brcm_pcie_turn_off(struct brcm_pcie *pcie)
 {
        void __iomem *base = pcie->base;
-       int tmp;
+       int tmp, ret;
 
        if (brcm_pcie_link_up(pcie))
                brcm_pcie_enter_l23(pcie);
        /* Assert fundamental reset */
-       pcie->perst_set(pcie, 1);
+       ret = pcie->perst_set(pcie, 1);
+       if (ret)
+               return ret;
 
        /* Deassert request for L23 in case it was asserted */
        tmp = readl(base + PCIE_MISC_PCIE_CTRL);
@@ -1464,7 +1497,9 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
        writel(tmp, base + HARD_DEBUG(pcie));
 
        /* Shutdown PCIe bridge */
-       pcie->bridge_sw_init_set(pcie, 1);
+       ret = pcie->bridge_sw_init_set(pcie, 1);
+
+       return ret;
 }
 
 static int pci_dev_may_wakeup(struct pci_dev *dev, void *data)
@@ -1482,9 +1517,12 @@ static int brcm_pcie_suspend_noirq(struct device *dev)
 {
        struct brcm_pcie *pcie = dev_get_drvdata(dev);
        struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
-       int ret;
+       int ret, rret;
+
+       ret = brcm_pcie_turn_off(pcie);
+       if (ret)
+               return ret;
 
-       brcm_pcie_turn_off(pcie);
        /*
         * If brcm_phy_stop() returns an error, just dev_err(). If we
         * return the error it will cause the suspend to fail and this is a
@@ -1513,7 +1551,10 @@ static int brcm_pcie_suspend_noirq(struct device *dev)
                                                     pcie->sr->supplies);
                        if (ret) {
                                dev_err(dev, "Could not turn off regulators\n");
-                               reset_control_reset(pcie->rescal);
+                               rret = reset_control_reset(pcie->rescal);
+                               if (rret)
+                                       dev_err(dev, "failed to reset 'rascal' controller ret=%d\n",
+                                               rret);
                                return ret;
                        }
                }
@@ -1528,7 +1569,7 @@ static int brcm_pcie_resume_noirq(struct device *dev)
        struct brcm_pcie *pcie = dev_get_drvdata(dev);
        void __iomem *base;
        u32 tmp;
-       int ret;
+       int ret, rret;
 
        base = pcie->base;
        ret = clk_prepare_enable(pcie->clk);
@@ -1590,7 +1631,9 @@ err_regulator:
        if (pcie->sr)
                regulator_bulk_disable(pcie->sr->num_supplies, pcie->sr->supplies);
 err_reset:
-       reset_control_rearm(pcie->rescal);
+       rret = reset_control_rearm(pcie->rescal);
+       if (rret)
+               dev_err(pcie->dev, "failed to rearm 'rescal' reset, err=%d\n", rret);
 err_disable_clk:
        clk_disable_unprepare(pcie->clk);
        return ret;