Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bde3e9f authored by Roger Quadros's avatar Roger Quadros
Browse files

mfd: omap-usb-tll: Clean up clock handling



Every channel has a functional clock that is similarly named.
It makes sense to use a for loop to manage these clocks as OMAPs
can come with up to 3 channels.

Dynamically allocate and get channel clocks depending on the
number of clocks avaiable on the platform.

Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
Reviewed-by: default avatarFelipe Balbi <balbi@ti.com>
Acked-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 1a7a8d70
Loading
Loading
Loading
Loading
+54 −33
Original line number Diff line number Diff line
@@ -96,10 +96,9 @@
#define is_ehci_tll_mode(x)	(x == OMAP_EHCI_PORT_MODE_TLL)

struct usbtll_omap {
	struct clk				*usbtll_p1_fck;
	struct clk				*usbtll_p2_fck;
	int					nch;	/* num. of channels */
	struct usbhs_omap_platform_data		*pdata;
	struct clk				**ch_clk;
	/* secure the register updates */
	spinlock_t				lock;
};
@@ -225,26 +224,12 @@ static int usbtll_omap_probe(struct platform_device *pdev)

	tll->pdata = pdata;

	tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
	if (IS_ERR(tll->usbtll_p1_fck)) {
		ret = PTR_ERR(tll->usbtll_p1_fck);
		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
		return ret;
	}

	tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
	if (IS_ERR(tll->usbtll_p2_fck)) {
		ret = PTR_ERR(tll->usbtll_p2_fck);
		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
		goto err_p2_fck;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_request_and_ioremap(dev, res);
	if (!base) {
		ret = -EADDRNOTAVAIL;
		dev_err(dev, "Resource request/ioremap failed:%d\n", ret);
		goto err_res;
		return ret;
	}

	platform_set_drvdata(pdev, tll);
@@ -270,6 +255,29 @@ static int usbtll_omap_probe(struct platform_device *pdev)
		break;
	}

	spin_unlock_irqrestore(&tll->lock, flags);

	tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
						GFP_KERNEL);
	if (!tll->ch_clk) {
		ret = -ENOMEM;
		dev_err(dev, "Couldn't allocate memory for channel clocks\n");
		goto err_clk_alloc;
	}

	for (i = 0; i < tll->nch; i++) {
		char clkname[] = "usb_tll_hs_usb_chx_clk";

		snprintf(clkname, sizeof(clkname),
					"usb_tll_hs_usb_ch%d_clk", i);
		tll->ch_clk[i] = clk_get(dev, clkname);

		if (IS_ERR(tll->ch_clk[i]))
			dev_dbg(dev, "can't get clock : %s\n", clkname);
	}

	spin_lock_irqsave(&tll->lock, flags);

	if (is_ehci_tll_mode(pdata->port_mode[0]) ||
	    is_ehci_tll_mode(pdata->port_mode[1]) ||
	    is_ehci_tll_mode(pdata->port_mode[2]) ||
@@ -321,11 +329,9 @@ static int usbtll_omap_probe(struct platform_device *pdev)

	return 0;

err_res:
	clk_put(tll->usbtll_p2_fck);

err_p2_fck:
	clk_put(tll->usbtll_p1_fck);
err_clk_alloc:
	pm_runtime_put_sync(dev);
	pm_runtime_disable(dev);

	return ret;
}
@@ -339,9 +345,12 @@ err_p2_fck:
static int usbtll_omap_remove(struct platform_device *pdev)
{
	struct usbtll_omap *tll = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < tll->nch; i++)
		if (!IS_ERR(tll->ch_clk[i]))
			clk_put(tll->ch_clk[i]);

	clk_put(tll->usbtll_p2_fck);
	clk_put(tll->usbtll_p1_fck);
	pm_runtime_disable(&pdev->dev);
	return 0;
}
@@ -351,6 +360,7 @@ static int usbtll_runtime_resume(struct device *dev)
	struct usbtll_omap			*tll = dev_get_drvdata(dev);
	struct usbhs_omap_platform_data		*pdata = tll->pdata;
	unsigned long				flags;
	int i;

	dev_dbg(dev, "usbtll_runtime_resume\n");

@@ -361,11 +371,20 @@ static int usbtll_runtime_resume(struct device *dev)

	spin_lock_irqsave(&tll->lock, flags);

	if (is_ehci_tll_mode(pdata->port_mode[0]))
		clk_enable(tll->usbtll_p1_fck);
	for (i = 0; i < tll->nch; i++) {
		if (is_ehci_tll_mode(pdata->port_mode[i])) {
			int r;

	if (is_ehci_tll_mode(pdata->port_mode[1]))
		clk_enable(tll->usbtll_p2_fck);
			if (IS_ERR(tll->ch_clk[i]))
				continue;

			r = clk_enable(tll->ch_clk[i]);
			if (r) {
				dev_err(dev,
				 "Error enabling ch %d clock: %d\n", i, r);
			}
		}
	}

	spin_unlock_irqrestore(&tll->lock, flags);

@@ -377,6 +396,7 @@ static int usbtll_runtime_suspend(struct device *dev)
	struct usbtll_omap			*tll = dev_get_drvdata(dev);
	struct usbhs_omap_platform_data		*pdata = tll->pdata;
	unsigned long				flags;
	int i;

	dev_dbg(dev, "usbtll_runtime_suspend\n");

@@ -387,11 +407,12 @@ static int usbtll_runtime_suspend(struct device *dev)

	spin_lock_irqsave(&tll->lock, flags);

	if (is_ehci_tll_mode(pdata->port_mode[0]))
		clk_disable(tll->usbtll_p1_fck);

	if (is_ehci_tll_mode(pdata->port_mode[1]))
		clk_disable(tll->usbtll_p2_fck);
	for (i = 0; i < tll->nch; i++) {
		if (is_ehci_tll_mode(pdata->port_mode[i])) {
			if (!IS_ERR(tll->ch_clk[i]))
				clk_disable(tll->ch_clk[i]);
		}
	}

	spin_unlock_irqrestore(&tll->lock, flags);