diff options
Diffstat (limited to 'drivers/usb/host/ohci-nxp.c')
| -rw-r--r-- | drivers/usb/host/ohci-nxp.c | 88 | 
1 files changed, 55 insertions, 33 deletions
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 1e364ec962f..a446386bf77 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -43,16 +43,6 @@  #define USB_HOST_NEED_CLK_EN	(1 << 21)  #define PAD_CONTROL_LAST_DRIVEN	(1 << 19) -#define USB_OTG_CLK_CTRL	IO_ADDRESS(USB_CONFIG_BASE + 0xFF4) -#define USB_OTG_CLK_STAT	IO_ADDRESS(USB_CONFIG_BASE + 0xFF8) - -/* USB_OTG_CLK_CTRL bit defines */ -#define AHB_M_CLOCK_ON		(1 << 4) -#define OTG_CLOCK_ON		(1 << 3) -#define I2C_CLOCK_ON		(1 << 2) -#define DEV_CLOCK_ON		(1 << 1) -#define HOST_CLOCK_ON		(1 << 0) -  #define USB_OTG_STAT_CONTROL	IO_ADDRESS(USB_CONFIG_BASE + 0x110)  /* USB_OTG_STAT_CONTROL bit defines */ @@ -72,7 +62,9 @@ static struct i2c_client *isp1301_i2c_client;  extern int usb_disabled(void); -static struct clk *usb_clk; +static struct clk *usb_pll_clk; +static struct clk *usb_dev_clk; +static struct clk *usb_otg_clk;  static void isp1301_configure_pnx4008(void)  { @@ -249,8 +241,6 @@ static const struct hc_driver ohci_nxp_hc_driver = {  	.start_port_reset = ohci_start_port_reset,  }; -#define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON) -  static void nxp_set_usb_bits(void)  {  	if (machine_is_pnx4008()) { @@ -327,41 +317,63 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)  	/* Enable AHB slave USB clock, needed for further USB clock control */  	__raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL); -	isp1301_configure(); -  	/* Enable USB PLL */ -	usb_clk = clk_get(&pdev->dev, "ck_pll5"); -	if (IS_ERR(usb_clk)) { +	usb_pll_clk = clk_get(&pdev->dev, "ck_pll5"); +	if (IS_ERR(usb_pll_clk)) {  		dev_err(&pdev->dev, "failed to acquire USB PLL\n"); -		ret = PTR_ERR(usb_clk); +		ret = PTR_ERR(usb_pll_clk);  		goto out1;  	} -	ret = clk_enable(usb_clk); +	ret = clk_enable(usb_pll_clk);  	if (ret < 0) {  		dev_err(&pdev->dev, "failed to start USB PLL\n");  		goto out2;  	} -	ret = clk_set_rate(usb_clk, 48000); +	ret = clk_set_rate(usb_pll_clk, 48000);  	if (ret < 0) {  		dev_err(&pdev->dev, "failed to set USB clock rate\n");  		goto out3;  	} +	/* Enable USB device clock */ +	usb_dev_clk = clk_get(&pdev->dev, "ck_usbd"); +	if (IS_ERR(usb_dev_clk)) { +		dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); +		ret = PTR_ERR(usb_dev_clk); +		goto out4; +	} + +	ret = clk_enable(usb_dev_clk); +	if (ret < 0) { +		dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); +		goto out5; +	} + +	/* Enable USB otg clocks */ +	usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); +	if (IS_ERR(usb_otg_clk)) { +		dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); +		ret = PTR_ERR(usb_dev_clk); +		goto out6; +	} +  	__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); -	/* Set to enable all needed USB clocks */ -	__raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); +	ret = clk_enable(usb_otg_clk); +	if (ret < 0) { +		dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); +		goto out7; +	} -	while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != -	       USB_CLOCK_MASK) ; +	isp1301_configure();  	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));  	if (!hcd) {  		dev_err(&pdev->dev, "Failed to allocate HC buffer\n");  		ret = -ENOMEM; -		goto out3; +		goto out8;  	}  	/* Set all USB bits in the Start Enable register */ @@ -371,14 +383,14 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)  	if (!res) {  		dev_err(&pdev->dev, "Failed to get MEM resource\n");  		ret =  -ENOMEM; -		goto out4; +		goto out8;  	}  	hcd->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!hcd->regs) {  		dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n");  		ret =  -ENOMEM; -		goto out4; +		goto out8;  	}  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); @@ -386,7 +398,7 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) {  		ret = -ENXIO; -		goto out4; +		goto out8;  	}  	nxp_start_hc(); @@ -400,13 +412,21 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)  		return ret;  	nxp_stop_hc(); -out4: +out8:  	nxp_unset_usb_bits();  	usb_put_hcd(hcd); +out7: +	clk_disable(usb_otg_clk); +out6: +	clk_put(usb_otg_clk); +out5: +	clk_disable(usb_dev_clk); +out4: +	clk_put(usb_dev_clk);  out3: -	clk_disable(usb_clk); +	clk_disable(usb_pll_clk);  out2: -	clk_put(usb_clk); +	clk_put(usb_pll_clk);  out1:  	isp1301_i2c_client = NULL;  out: @@ -422,8 +442,10 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)  	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd);  	nxp_unset_usb_bits(); -	clk_disable(usb_clk); -	clk_put(usb_clk); +	clk_disable(usb_pll_clk); +	clk_put(usb_pll_clk); +	clk_disable(usb_dev_clk); +	clk_put(usb_dev_clk);  	i2c_unregister_device(isp1301_i2c_client);  	isp1301_i2c_client = NULL;  |