From mboxrd@z Thu Jan 1 00:00:00 1970 From: patrice.chotard at st.com Date: Wed, 24 May 2017 15:01:55 +0200 Subject: [U-Boot] [PATCH v4 09/11] usb: host: ohci-generic: add CLOCK support In-Reply-To: <1495630917-25272-1-git-send-email-patrice.chotard@st.com> References: <1495630917-25272-1-git-send-email-patrice.chotard@st.com> Message-ID: <1495630917-25272-10-git-send-email-patrice.chotard@st.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de From: Patrice Chotard use array to save enabled clocks reference in order to disabled them in case of error during probe() or during driver removal. Signed-off-by: Patrice Chotard --- v4: _ use generic_phy_valid() before generic_phy_exit() call v3: _ extract in this patch the CLOCK support add-on from previous patch 5 _ keep enabled clocks reference in list in order to disable clocks in error path or in .remove callback v2: _ add error path management _ add .remove callback drivers/usb/host/ohci-generic.c | 53 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index f3307f4..404fc98 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -5,6 +5,7 @@ */ #include +#include #include #include "ohci.h" @@ -14,18 +15,66 @@ struct generic_ohci { ohci_t ohci; + struct clk *clocks; + int clock_count; }; static int ohci_usb_probe(struct udevice *dev) { struct ohci_regs *regs = (struct ohci_regs *)dev_get_addr(dev); + struct generic_ohci *priv = dev_get_priv(dev); + int i, err, ret, clock_nb; - return ohci_register(dev, regs); + err = 0; + priv->clock_count = 0; + clock_nb = clk_count(dev); + + if (clock_nb) { + priv->clocks = devm_kmalloc(dev, sizeof(struct clk) * clock_nb, + GFP_KERNEL); + if (!priv->clocks) { + error("Can't allocate resource\n"); + return -ENOMEM; + } + + for (i = 0; i < clock_nb; i++) { + err = clk_get_by_index(dev, i, &priv->clocks[i]); + if (err < 0) + break; + + priv->clock_count++; + + if (clk_enable(&priv->clocks[i])) { + error("failed to enable clock %d\n", i); + clk_free(&priv->clocks[i]); + goto clk_err; + } + clk_free(&priv->clocks[i]); + } + } + + err = ohci_register(dev, regs); + if (!err) + return err; + +clk_err: + ret = clk_disable_all(priv->clocks, priv->clock_count); + if (ret) + return ret; + + return err; } static int ohci_usb_remove(struct udevice *dev) { - return ohci_deregister(dev); + struct generic_ohci *priv = dev_get_priv(dev); + int ret; + + ret = ohci_deregister(dev); + if (ret) + return ret; + + return clk_disable_all(priv->clocks, priv->clock_count); } static const struct udevice_id ohci_usb_ids[] = { -- 1.9.1