diff mbox

[v7,15/22] mfd: omap-usb-host: Manage HSIC clocks for HSIC mode

Message ID 1358422231-24736-16-git-send-email-rogerq@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Roger Quadros Jan. 17, 2013, 11:30 a.m. UTC
Enable the optional HSIC clocks (60MHz and 480MHz) for the ports
that are configured in HSIC mode.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mfd/omap-usb-host.c |   77 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 71 insertions(+), 6 deletions(-)

Comments

Felipe Balbi Jan. 17, 2013, 11:45 a.m. UTC | #1
Hi,

On Thu, Jan 17, 2013 at 01:30:24PM +0200, Roger Quadros wrote:
> @@ -598,6 +639,24 @@ static int usbhs_omap_probe(struct platform_device *pdev)
>  				clkname, PTR_ERR(pclk));
>  		else
>  			omap->utmi_clk[i] = pclk;
> +
> +		snprintf(clkname, sizeof(clkname),
> +				"usb_host_hs_hsic480m_p%d_clk", i + 1);

do we really need to know the exact clock node name ?
Roger Quadros Jan. 17, 2013, 12:10 p.m. UTC | #2
On 01/17/2013 01:45 PM, Felipe Balbi wrote:
> Hi,
> 
> On Thu, Jan 17, 2013 at 01:30:24PM +0200, Roger Quadros wrote:
>> @@ -598,6 +639,24 @@ static int usbhs_omap_probe(struct platform_device *pdev)
>>  				clkname, PTR_ERR(pclk));
>>  		else
>>  			omap->utmi_clk[i] = pclk;
>> +
>> +		snprintf(clkname, sizeof(clkname),
>> +				"usb_host_hs_hsic480m_p%d_clk", i + 1);
> 
> do we really need to know the exact clock node name ?
> 
I think so. Do you have a better suggestion?

--
cheers,
-roger
Felipe Balbi Jan. 17, 2013, 12:27 p.m. UTC | #3
On Thu, Jan 17, 2013 at 02:10:18PM +0200, Roger Quadros wrote:
> On 01/17/2013 01:45 PM, Felipe Balbi wrote:
> > Hi,
> > 
> > On Thu, Jan 17, 2013 at 01:30:24PM +0200, Roger Quadros wrote:
> >> @@ -598,6 +639,24 @@ static int usbhs_omap_probe(struct platform_device *pdev)
> >>  				clkname, PTR_ERR(pclk));
> >>  		else
> >>  			omap->utmi_clk[i] = pclk;
> >> +
> >> +		snprintf(clkname, sizeof(clkname),
> >> +				"usb_host_hs_hsic480m_p%d_clk", i + 1);
> > 
> > do we really need to know the exact clock node name ?
> > 
> I think so. Do you have a better suggestion?

update CLKDEV entries ? I mean, what if we have a new OMAP or AMxxxx
device with a different clock name ? That will be a big bummer.
Roger Quadros Jan. 17, 2013, 12:45 p.m. UTC | #4
On 01/17/2013 02:27 PM, Felipe Balbi wrote:
> On Thu, Jan 17, 2013 at 02:10:18PM +0200, Roger Quadros wrote:
>> On 01/17/2013 01:45 PM, Felipe Balbi wrote:
>>> Hi,
>>>
>>> On Thu, Jan 17, 2013 at 01:30:24PM +0200, Roger Quadros wrote:
>>>> @@ -598,6 +639,24 @@ static int usbhs_omap_probe(struct platform_device *pdev)
>>>>  				clkname, PTR_ERR(pclk));
>>>>  		else
>>>>  			omap->utmi_clk[i] = pclk;
>>>> +
>>>> +		snprintf(clkname, sizeof(clkname),
>>>> +				"usb_host_hs_hsic480m_p%d_clk", i + 1);
>>>
>>> do we really need to know the exact clock node name ?
>>>
>> I think so. Do you have a better suggestion?
> 
> update CLKDEV entries ? I mean, what if we have a new OMAP or AMxxxx
> device with a different clock name ? That will be a big bummer.
> 

In that case we simply need to add the relevant CLKDEV entries/aliases
for the new platform. I don't think anything needs to be changed in the
driver. We are still using clk_get(dev, clk_name), so the CLKDEV
framework will return the best matching clock for the device.

--
cheers,
-roger
Felipe Balbi Jan. 17, 2013, 12:48 p.m. UTC | #5
On Thu, Jan 17, 2013 at 02:45:16PM +0200, Roger Quadros wrote:
> On 01/17/2013 02:27 PM, Felipe Balbi wrote:
> > On Thu, Jan 17, 2013 at 02:10:18PM +0200, Roger Quadros wrote:
> >> On 01/17/2013 01:45 PM, Felipe Balbi wrote:
> >>> Hi,
> >>>
> >>> On Thu, Jan 17, 2013 at 01:30:24PM +0200, Roger Quadros wrote:
> >>>> @@ -598,6 +639,24 @@ static int usbhs_omap_probe(struct platform_device *pdev)
> >>>>  				clkname, PTR_ERR(pclk));
> >>>>  		else
> >>>>  			omap->utmi_clk[i] = pclk;
> >>>> +
> >>>> +		snprintf(clkname, sizeof(clkname),
> >>>> +				"usb_host_hs_hsic480m_p%d_clk", i + 1);
> >>>
> >>> do we really need to know the exact clock node name ?
> >>>
> >> I think so. Do you have a better suggestion?
> > 
> > update CLKDEV entries ? I mean, what if we have a new OMAP or AMxxxx
> > device with a different clock name ? That will be a big bummer.
> > 
> 
> In that case we simply need to add the relevant CLKDEV entries/aliases
> for the new platform. I don't think anything needs to be changed in the
> driver. We are still using clk_get(dev, clk_name), so the CLKDEV
> framework will return the best matching clock for the device.

fair enough ;-)
diff mbox

Patch

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index c75b79d..d9a242b 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -93,6 +93,8 @@ 
 struct usbhs_hcd_omap {
 	int				nports;
 	struct clk			**utmi_clk;
+	struct clk			**hsic60m_clk;
+	struct clk			**hsic480m_clk;
 
 	struct clk			*xclk60mhsp1_ck;
 	struct clk			*xclk60mhsp2_ck;
@@ -286,7 +288,28 @@  static int usbhs_runtime_resume(struct device *dev)
 		clk_enable(omap->ehci_logic_fck);
 
 	for (i = 0; i < omap->nports; i++) {
-		if (is_ehci_tll_mode(pdata->port_mode[i])) {
+		switch (pdata->port_mode[i]) {
+		case OMAP_EHCI_PORT_MODE_HSIC:
+			if (omap->hsic60m_clk[i]) {
+				r = clk_enable(omap->hsic60m_clk[i]);
+				if (r) {
+					dev_err(dev,
+					 "Can't enable port %d hsic60m clk:%d\n",
+					 i, r);
+				}
+			}
+
+			if (omap->hsic480m_clk[i]) {
+				r = clk_enable(omap->hsic480m_clk[i]);
+				if (r) {
+					dev_err(dev,
+					 "Can't enable port %d hsic480m clk:%d\n",
+					 i, r);
+				}
+			}
+		/* Fall through as HSIC mode needs utmi_clk */
+
+		case OMAP_EHCI_PORT_MODE_TLL:
 			if (omap->utmi_clk[i]) {
 				r = clk_enable(omap->utmi_clk[i]);
 				if (r) {
@@ -295,6 +318,9 @@  static int usbhs_runtime_resume(struct device *dev)
 					 i, r);
 				}
 			}
+			break;
+		default:
+			break;
 		}
 	}
 
@@ -315,9 +341,21 @@  static int usbhs_runtime_suspend(struct device *dev)
 	spin_lock_irqsave(&omap->lock, flags);
 
 	for (i = 0; i < omap->nports; i++) {
-		if (is_ehci_tll_mode(pdata->port_mode[i])) {
+		switch (pdata->port_mode[i]) {
+		case OMAP_EHCI_PORT_MODE_HSIC:
+			if (omap->hsic60m_clk[i])
+				clk_disable(omap->hsic60m_clk[i]);
+
+			if (omap->hsic480m_clk[i])
+				clk_disable(omap->hsic480m_clk[i]);
+		/* Fall through as utmi_clks were used in HSIC mode */
+
+		case OMAP_EHCI_PORT_MODE_TLL:
 			if (omap->utmi_clk[i])
 				clk_disable(omap->utmi_clk[i]);
+			break;
+		default:
+			break;
 		}
 	}
 
@@ -524,7 +562,10 @@  static int usbhs_omap_probe(struct platform_device *pdev)
 
 	i = sizeof(struct clk *) * omap->nports;
 	omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
-	if (!omap->utmi_clk) {
+	omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
+	omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
+
+	if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) {
 		dev_err(dev, "Memory allocation failed\n");
 		ret = -ENOMEM;
 		goto err_mem;
@@ -582,7 +623,7 @@  static int usbhs_omap_probe(struct platform_device *pdev)
 
 	for (i = 0; i < omap->nports; i++) {
 		struct clk *pclk;
-		char clkname[] = "usb_host_hs_utmi_px_clk";
+		char clkname[] = "usb_host_hs_hsic480m_px_clk";
 
 		/* clock names are indexed from 1*/
 		snprintf(clkname, sizeof(clkname),
@@ -598,6 +639,24 @@  static int usbhs_omap_probe(struct platform_device *pdev)
 				clkname, PTR_ERR(pclk));
 		else
 			omap->utmi_clk[i] = pclk;
+
+		snprintf(clkname, sizeof(clkname),
+				"usb_host_hs_hsic480m_p%d_clk", i + 1);
+		pclk = clk_get(dev, clkname);
+		if (IS_ERR(pclk))
+			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
+				clkname, PTR_ERR(pclk));
+		else
+			omap->hsic480m_clk[i] = pclk;
+
+		snprintf(clkname, sizeof(clkname),
+				"usb_host_hs_hsic60m_p%d_clk", i + 1);
+		pclk = clk_get(dev, clkname);
+		if (IS_ERR(pclk))
+			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
+				clkname, PTR_ERR(pclk));
+		else
+			omap->hsic60m_clk[i] = pclk;
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
@@ -641,8 +700,11 @@  static int usbhs_omap_probe(struct platform_device *pdev)
 err_alloc:
 	omap_usbhs_deinit(&pdev->dev);
 
-	for (i = 0; i < omap->nports; i++)
+	for (i = 0; i < omap->nports; i++) {
 		clk_put(omap->utmi_clk[i]);
+		clk_put(omap->hsic60m_clk[i]);
+		clk_put(omap->hsic480m_clk[i]);
+	}
 
 	clk_put(omap->init_60m_fclk);
 
@@ -680,8 +742,11 @@  static int usbhs_omap_remove(struct platform_device *pdev)
 
 	omap_usbhs_deinit(&pdev->dev);
 
-	for (i = 0; i < omap->nports; i++)
+	for (i = 0; i < omap->nports; i++) {
 		clk_put(omap->utmi_clk[i]);
+		clk_put(omap->hsic60m_clk[i]);
+		clk_put(omap->hsic480m_clk[i]);
+	}
 
 	clk_put(omap->init_60m_fclk);
 	clk_put(omap->utmi_p1_gfclk);