Merge branch 'omap/ehci' into next/drivers
* omap/ehci: MFD: OMAP: USB: Runtime PM support ARM: OMAP: USBHOST: Replace usbhs core driver APIs by Runtime pm APIs ARM: OMAP: USB: device name change for the clk names of usbhs ARM: OMAP: USB: register hwmods of usbhs
This commit is contained in:
Коммит
9f9f265b0b
|
@ -3297,7 +3297,7 @@ static struct omap_clk omap3xxx_clks[] = {
|
|||
CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
|
||||
CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
|
||||
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
|
||||
|
@ -3333,7 +3333,7 @@ static struct omap_clk omap3xxx_clks[] = {
|
|||
CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
|
||||
CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX),
|
||||
CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX),
|
||||
|
@ -3379,20 +3379,18 @@ static struct omap_clk omap3xxx_clks[] = {
|
|||
CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
|
||||
CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX),
|
||||
CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX),
|
||||
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
|
||||
CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
|
||||
|
|
|
@ -3295,7 +3295,7 @@ static struct omap_clk omap44xx_clks[] = {
|
|||
CLK(NULL, "uart2_fck", &uart2_fck, CK_443X),
|
||||
CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
|
||||
CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
|
||||
CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X),
|
||||
CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X),
|
||||
CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
|
||||
CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
|
||||
CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
|
||||
|
@ -3306,7 +3306,7 @@ static struct omap_clk omap44xx_clks[] = {
|
|||
CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
|
||||
CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
|
||||
CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
|
||||
CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X),
|
||||
CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X),
|
||||
CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
|
||||
CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
|
||||
CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X),
|
||||
|
@ -3314,7 +3314,7 @@ static struct omap_clk omap44xx_clks[] = {
|
|||
CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X),
|
||||
CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
|
||||
CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
|
||||
CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
|
||||
CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
|
||||
CLK(NULL, "usim_ck", &usim_ck, CK_443X),
|
||||
CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
|
||||
CLK(NULL, "usim_fck", &usim_fck, CK_443X),
|
||||
|
@ -3374,8 +3374,8 @@ static struct omap_clk omap44xx_clks[] = {
|
|||
CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
|
||||
CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
|
||||
CLK(NULL, "uart4_ick", &dummy_ck, CK_443X),
|
||||
CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X),
|
||||
CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X),
|
||||
CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X),
|
||||
CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X),
|
||||
CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X),
|
||||
CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X),
|
||||
|
|
|
@ -28,51 +28,28 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/omap_device.h>
|
||||
|
||||
#include "mux.h"
|
||||
|
||||
#ifdef CONFIG_MFD_OMAP_USB_HOST
|
||||
|
||||
#define OMAP_USBHS_DEVICE "usbhs-omap"
|
||||
|
||||
static struct resource usbhs_resources[] = {
|
||||
{
|
||||
.name = "uhh",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "tll",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "ehci",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "ehci-irq",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "ohci",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "ohci-irq",
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device usbhs_device = {
|
||||
.name = OMAP_USBHS_DEVICE,
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(usbhs_resources),
|
||||
.resource = usbhs_resources,
|
||||
};
|
||||
#define OMAP_USBHS_DEVICE "usbhs_omap"
|
||||
#define USBHS_UHH_HWMODNAME "usb_host_hs"
|
||||
#define USBHS_TLL_HWMODNAME "usb_tll_hs"
|
||||
|
||||
static struct usbhs_omap_platform_data usbhs_data;
|
||||
static struct ehci_hcd_omap_platform_data ehci_data;
|
||||
static struct ohci_hcd_omap_platform_data ohci_data;
|
||||
|
||||
static struct omap_device_pm_latency omap_uhhtll_latency[] = {
|
||||
{
|
||||
.deactivate_func = omap_device_idle_hwmods,
|
||||
.activate_func = omap_device_enable_hwmods,
|
||||
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
|
||||
},
|
||||
};
|
||||
|
||||
/* MUX settings for EHCI pins */
|
||||
/*
|
||||
* setup_ehci_io_mux - initialize IO pad mux for USBHOST
|
||||
|
@ -508,6 +485,9 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
|
|||
|
||||
void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
|
||||
{
|
||||
struct omap_hwmod *oh[2];
|
||||
struct omap_device *od;
|
||||
int bus_id = -1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
|
||||
|
@ -523,44 +503,34 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
|
|||
usbhs_data.ohci_data = &ohci_data;
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
|
||||
usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
|
||||
usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
|
||||
usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
|
||||
usbhs_resources[2].start = OMAP34XX_EHCI_BASE;
|
||||
usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1;
|
||||
usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
|
||||
usbhs_resources[4].start = OMAP34XX_OHCI_BASE;
|
||||
usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1;
|
||||
usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
|
||||
setup_ehci_io_mux(pdata->port_mode);
|
||||
setup_ohci_io_mux(pdata->port_mode);
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
|
||||
usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
|
||||
usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
|
||||
usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
|
||||
usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
|
||||
usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
|
||||
usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
|
||||
usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
|
||||
usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
|
||||
usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
|
||||
setup_4430ehci_io_mux(pdata->port_mode);
|
||||
setup_4430ohci_io_mux(pdata->port_mode);
|
||||
}
|
||||
|
||||
if (platform_device_add_data(&usbhs_device,
|
||||
&usbhs_data, sizeof(usbhs_data)) < 0) {
|
||||
printk(KERN_ERR "USBHS platform_device_add_data failed\n");
|
||||
goto init_end;
|
||||
oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
|
||||
if (!oh[0]) {
|
||||
pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
|
||||
return;
|
||||
}
|
||||
|
||||
if (platform_device_register(&usbhs_device) < 0)
|
||||
printk(KERN_ERR "USBHS platform_device_register failed\n");
|
||||
|
||||
init_end:
|
||||
oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
|
||||
if (!oh[1]) {
|
||||
pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
|
||||
return;
|
||||
}
|
||||
|
||||
od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
|
||||
(void *)&usbhs_data, sizeof(usbhs_data),
|
||||
omap_uhhtll_latency,
|
||||
ARRAY_SIZE(omap_uhhtll_latency), false);
|
||||
if (IS_ERR(od)) {
|
||||
pr_err("Could not build hwmod devices %s,%s\n",
|
||||
USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -570,5 +540,3 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -100,9 +100,6 @@ extern void usb_musb_init(struct omap_musb_board_data *board_data);
|
|||
|
||||
extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
|
||||
|
||||
extern int omap_usbhs_enable(struct device *dev);
|
||||
extern void omap_usbhs_disable(struct device *dev);
|
||||
|
||||
extern int omap4430_phy_power(struct device *dev, int ID, int on);
|
||||
extern int omap4430_phy_set_clk(struct device *dev, int on);
|
||||
extern int omap4430_phy_init(struct device *dev);
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <plat/usb.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#define USBHS_DRIVER_NAME "usbhs-omap"
|
||||
#define USBHS_DRIVER_NAME "usbhs_omap"
|
||||
#define OMAP_EHCI_DEVICE "ehci-omap"
|
||||
#define OMAP_OHCI_DEVICE "ohci-omap3"
|
||||
|
||||
|
@ -147,9 +148,6 @@
|
|||
|
||||
|
||||
struct usbhs_hcd_omap {
|
||||
struct clk *usbhost_ick;
|
||||
struct clk *usbhost_hs_fck;
|
||||
struct clk *usbhost_fs_fck;
|
||||
struct clk *xclk60mhsp1_ck;
|
||||
struct clk *xclk60mhsp2_ck;
|
||||
struct clk *utmi_p1_fck;
|
||||
|
@ -159,8 +157,7 @@ struct usbhs_hcd_omap {
|
|||
struct clk *usbhost_p2_fck;
|
||||
struct clk *usbtll_p2_fck;
|
||||
struct clk *init_60m_fclk;
|
||||
struct clk *usbtll_fck;
|
||||
struct clk *usbtll_ick;
|
||||
struct clk *ehci_logic_fck;
|
||||
|
||||
void __iomem *uhh_base;
|
||||
void __iomem *tll_base;
|
||||
|
@ -169,7 +166,6 @@ struct usbhs_hcd_omap {
|
|||
|
||||
u32 usbhs_rev;
|
||||
spinlock_t lock;
|
||||
int count;
|
||||
};
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -319,269 +315,6 @@ err_end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhs_omap_probe - initialize TI-based HCDs
|
||||
*
|
||||
* Allocates basic resources for this USB host controller.
|
||||
*/
|
||||
static int __devinit usbhs_omap_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct usbhs_omap_platform_data *pdata = dev->platform_data;
|
||||
struct usbhs_hcd_omap *omap;
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(dev, "Missing platform data\n");
|
||||
ret = -ENOMEM;
|
||||
goto end_probe;
|
||||
}
|
||||
|
||||
omap = kzalloc(sizeof(*omap), GFP_KERNEL);
|
||||
if (!omap) {
|
||||
dev_err(dev, "Memory allocation failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto end_probe;
|
||||
}
|
||||
|
||||
spin_lock_init(&omap->lock);
|
||||
|
||||
for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
|
||||
omap->platdata.port_mode[i] = pdata->port_mode[i];
|
||||
|
||||
omap->platdata.ehci_data = pdata->ehci_data;
|
||||
omap->platdata.ohci_data = pdata->ohci_data;
|
||||
|
||||
omap->usbhost_ick = clk_get(dev, "usbhost_ick");
|
||||
if (IS_ERR(omap->usbhost_ick)) {
|
||||
ret = PTR_ERR(omap->usbhost_ick);
|
||||
dev_err(dev, "usbhost_ick failed error:%d\n", ret);
|
||||
goto err_end;
|
||||
}
|
||||
|
||||
omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
|
||||
if (IS_ERR(omap->usbhost_hs_fck)) {
|
||||
ret = PTR_ERR(omap->usbhost_hs_fck);
|
||||
dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_ick;
|
||||
}
|
||||
|
||||
omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
|
||||
if (IS_ERR(omap->usbhost_fs_fck)) {
|
||||
ret = PTR_ERR(omap->usbhost_fs_fck);
|
||||
dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_hs_fck;
|
||||
}
|
||||
|
||||
omap->usbtll_fck = clk_get(dev, "usbtll_fck");
|
||||
if (IS_ERR(omap->usbtll_fck)) {
|
||||
ret = PTR_ERR(omap->usbtll_fck);
|
||||
dev_err(dev, "usbtll_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_fs_fck;
|
||||
}
|
||||
|
||||
omap->usbtll_ick = clk_get(dev, "usbtll_ick");
|
||||
if (IS_ERR(omap->usbtll_ick)) {
|
||||
ret = PTR_ERR(omap->usbtll_ick);
|
||||
dev_err(dev, "usbtll_ick failed error:%d\n", ret);
|
||||
goto err_usbtll_fck;
|
||||
}
|
||||
|
||||
omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
|
||||
if (IS_ERR(omap->utmi_p1_fck)) {
|
||||
ret = PTR_ERR(omap->utmi_p1_fck);
|
||||
dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
|
||||
goto err_usbtll_ick;
|
||||
}
|
||||
|
||||
omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
|
||||
if (IS_ERR(omap->xclk60mhsp1_ck)) {
|
||||
ret = PTR_ERR(omap->xclk60mhsp1_ck);
|
||||
dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
|
||||
goto err_utmi_p1_fck;
|
||||
}
|
||||
|
||||
omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
|
||||
if (IS_ERR(omap->utmi_p2_fck)) {
|
||||
ret = PTR_ERR(omap->utmi_p2_fck);
|
||||
dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
|
||||
goto err_xclk60mhsp1_ck;
|
||||
}
|
||||
|
||||
omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
|
||||
if (IS_ERR(omap->xclk60mhsp2_ck)) {
|
||||
ret = PTR_ERR(omap->xclk60mhsp2_ck);
|
||||
dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
|
||||
goto err_utmi_p2_fck;
|
||||
}
|
||||
|
||||
omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
|
||||
if (IS_ERR(omap->usbhost_p1_fck)) {
|
||||
ret = PTR_ERR(omap->usbhost_p1_fck);
|
||||
dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
|
||||
goto err_xclk60mhsp2_ck;
|
||||
}
|
||||
|
||||
omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
|
||||
if (IS_ERR(omap->usbtll_p1_fck)) {
|
||||
ret = PTR_ERR(omap->usbtll_p1_fck);
|
||||
dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_p1_fck;
|
||||
}
|
||||
|
||||
omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
|
||||
if (IS_ERR(omap->usbhost_p2_fck)) {
|
||||
ret = PTR_ERR(omap->usbhost_p2_fck);
|
||||
dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
|
||||
goto err_usbtll_p1_fck;
|
||||
}
|
||||
|
||||
omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
|
||||
if (IS_ERR(omap->usbtll_p2_fck)) {
|
||||
ret = PTR_ERR(omap->usbtll_p2_fck);
|
||||
dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_p2_fck;
|
||||
}
|
||||
|
||||
omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
|
||||
if (IS_ERR(omap->init_60m_fclk)) {
|
||||
ret = PTR_ERR(omap->init_60m_fclk);
|
||||
dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
|
||||
goto err_usbtll_p2_fck;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
|
||||
if (!res) {
|
||||
dev_err(dev, "UHH EHCI get resource failed\n");
|
||||
ret = -ENODEV;
|
||||
goto err_init_60m_fclk;
|
||||
}
|
||||
|
||||
omap->uhh_base = ioremap(res->start, resource_size(res));
|
||||
if (!omap->uhh_base) {
|
||||
dev_err(dev, "UHH ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_init_60m_fclk;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
|
||||
if (!res) {
|
||||
dev_err(dev, "UHH EHCI get resource failed\n");
|
||||
ret = -ENODEV;
|
||||
goto err_tll;
|
||||
}
|
||||
|
||||
omap->tll_base = ioremap(res->start, resource_size(res));
|
||||
if (!omap->tll_base) {
|
||||
dev_err(dev, "TLL ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_tll;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, omap);
|
||||
|
||||
ret = omap_usbhs_alloc_children(pdev);
|
||||
if (ret) {
|
||||
dev_err(dev, "omap_usbhs_alloc_children failed\n");
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
goto end_probe;
|
||||
|
||||
err_alloc:
|
||||
iounmap(omap->tll_base);
|
||||
|
||||
err_tll:
|
||||
iounmap(omap->uhh_base);
|
||||
|
||||
err_init_60m_fclk:
|
||||
clk_put(omap->init_60m_fclk);
|
||||
|
||||
err_usbtll_p2_fck:
|
||||
clk_put(omap->usbtll_p2_fck);
|
||||
|
||||
err_usbhost_p2_fck:
|
||||
clk_put(omap->usbhost_p2_fck);
|
||||
|
||||
err_usbtll_p1_fck:
|
||||
clk_put(omap->usbtll_p1_fck);
|
||||
|
||||
err_usbhost_p1_fck:
|
||||
clk_put(omap->usbhost_p1_fck);
|
||||
|
||||
err_xclk60mhsp2_ck:
|
||||
clk_put(omap->xclk60mhsp2_ck);
|
||||
|
||||
err_utmi_p2_fck:
|
||||
clk_put(omap->utmi_p2_fck);
|
||||
|
||||
err_xclk60mhsp1_ck:
|
||||
clk_put(omap->xclk60mhsp1_ck);
|
||||
|
||||
err_utmi_p1_fck:
|
||||
clk_put(omap->utmi_p1_fck);
|
||||
|
||||
err_usbtll_ick:
|
||||
clk_put(omap->usbtll_ick);
|
||||
|
||||
err_usbtll_fck:
|
||||
clk_put(omap->usbtll_fck);
|
||||
|
||||
err_usbhost_fs_fck:
|
||||
clk_put(omap->usbhost_fs_fck);
|
||||
|
||||
err_usbhost_hs_fck:
|
||||
clk_put(omap->usbhost_hs_fck);
|
||||
|
||||
err_usbhost_ick:
|
||||
clk_put(omap->usbhost_ick);
|
||||
|
||||
err_end:
|
||||
kfree(omap);
|
||||
|
||||
end_probe:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
|
||||
* @pdev: USB Host Controller being removed
|
||||
*
|
||||
* Reverses the effect of usbhs_omap_probe().
|
||||
*/
|
||||
static int __devexit usbhs_omap_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
|
||||
|
||||
if (omap->count != 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Either EHCI or OHCI is still using usbhs core\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
iounmap(omap->tll_base);
|
||||
iounmap(omap->uhh_base);
|
||||
clk_put(omap->init_60m_fclk);
|
||||
clk_put(omap->usbtll_p2_fck);
|
||||
clk_put(omap->usbhost_p2_fck);
|
||||
clk_put(omap->usbtll_p1_fck);
|
||||
clk_put(omap->usbhost_p1_fck);
|
||||
clk_put(omap->xclk60mhsp2_ck);
|
||||
clk_put(omap->utmi_p2_fck);
|
||||
clk_put(omap->xclk60mhsp1_ck);
|
||||
clk_put(omap->utmi_p1_fck);
|
||||
clk_put(omap->usbtll_ick);
|
||||
clk_put(omap->usbtll_fck);
|
||||
clk_put(omap->usbhost_fs_fck);
|
||||
clk_put(omap->usbhost_hs_fck);
|
||||
clk_put(omap->usbhost_ick);
|
||||
kfree(omap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
|
||||
{
|
||||
switch (pmode) {
|
||||
|
@ -689,30 +422,85 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
|
|||
}
|
||||
}
|
||||
|
||||
static int usbhs_enable(struct device *dev)
|
||||
static int usbhs_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
|
||||
struct usbhs_omap_platform_data *pdata = &omap->platdata;
|
||||
unsigned long flags = 0;
|
||||
int ret = 0;
|
||||
unsigned long timeout;
|
||||
unsigned reg;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(dev, "usbhs_runtime_resume\n");
|
||||
|
||||
dev_dbg(dev, "starting TI HSUSB Controller\n");
|
||||
if (!pdata) {
|
||||
dev_dbg(dev, "missing platform_data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&omap->lock, flags);
|
||||
if (omap->count > 0)
|
||||
goto end_count;
|
||||
|
||||
clk_enable(omap->usbhost_ick);
|
||||
clk_enable(omap->usbhost_hs_fck);
|
||||
clk_enable(omap->usbhost_fs_fck);
|
||||
clk_enable(omap->usbtll_fck);
|
||||
clk_enable(omap->usbtll_ick);
|
||||
if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
|
||||
clk_enable(omap->ehci_logic_fck);
|
||||
|
||||
if (is_ehci_tll_mode(pdata->port_mode[0])) {
|
||||
clk_enable(omap->usbhost_p1_fck);
|
||||
clk_enable(omap->usbtll_p1_fck);
|
||||
}
|
||||
if (is_ehci_tll_mode(pdata->port_mode[1])) {
|
||||
clk_enable(omap->usbhost_p2_fck);
|
||||
clk_enable(omap->usbtll_p2_fck);
|
||||
}
|
||||
clk_enable(omap->utmi_p1_fck);
|
||||
clk_enable(omap->utmi_p2_fck);
|
||||
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbhs_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
|
||||
struct usbhs_omap_platform_data *pdata = &omap->platdata;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(dev, "usbhs_runtime_suspend\n");
|
||||
|
||||
if (!pdata) {
|
||||
dev_dbg(dev, "missing platform_data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&omap->lock, flags);
|
||||
|
||||
if (is_ehci_tll_mode(pdata->port_mode[0])) {
|
||||
clk_disable(omap->usbhost_p1_fck);
|
||||
clk_disable(omap->usbtll_p1_fck);
|
||||
}
|
||||
if (is_ehci_tll_mode(pdata->port_mode[1])) {
|
||||
clk_disable(omap->usbhost_p2_fck);
|
||||
clk_disable(omap->usbtll_p2_fck);
|
||||
}
|
||||
clk_disable(omap->utmi_p2_fck);
|
||||
clk_disable(omap->utmi_p1_fck);
|
||||
|
||||
if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
|
||||
clk_disable(omap->ehci_logic_fck);
|
||||
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_usbhs_init(struct device *dev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
|
||||
struct usbhs_omap_platform_data *pdata = &omap->platdata;
|
||||
unsigned long flags;
|
||||
unsigned reg;
|
||||
|
||||
dev_dbg(dev, "starting TI HSUSB Controller\n");
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
spin_lock_irqsave(&omap->lock, flags);
|
||||
|
||||
if (pdata->ehci_data->phy_reset) {
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
|
||||
|
@ -736,50 +524,6 @@ static int usbhs_enable(struct device *dev)
|
|||
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
|
||||
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
|
||||
|
||||
/* perform TLL soft reset, and wait until reset is complete */
|
||||
usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
|
||||
OMAP_USBTLL_SYSCONFIG_SOFTRESET);
|
||||
|
||||
/* Wait for TLL reset to complete */
|
||||
timeout = jiffies + msecs_to_jiffies(1000);
|
||||
while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
|
||||
& OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
|
||||
cpu_relax();
|
||||
|
||||
if (time_after(jiffies, timeout)) {
|
||||
dev_dbg(dev, "operation timed out\n");
|
||||
ret = -EINVAL;
|
||||
goto err_tll;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(dev, "TLL RESET DONE\n");
|
||||
|
||||
/* (1<<3) = no idle mode only for initial debugging */
|
||||
usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
|
||||
OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
|
||||
OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
|
||||
OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
|
||||
|
||||
/* Put UHH in NoIdle/NoStandby mode */
|
||||
reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
|
||||
if (is_omap_usbhs_rev1(omap)) {
|
||||
reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
|
||||
| OMAP_UHH_SYSCONFIG_SIDLEMODE
|
||||
| OMAP_UHH_SYSCONFIG_CACTIVITY
|
||||
| OMAP_UHH_SYSCONFIG_MIDLEMODE);
|
||||
reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
|
||||
|
||||
|
||||
} else if (is_omap_usbhs_rev2(omap)) {
|
||||
reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
|
||||
reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
|
||||
reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
|
||||
reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
|
||||
}
|
||||
|
||||
usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
|
||||
|
||||
reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
|
||||
/* setup ULPI bypass and burst configurations */
|
||||
reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
|
||||
|
@ -825,49 +569,6 @@ static int usbhs_enable(struct device *dev)
|
|||
reg &= ~OMAP4_P1_MODE_CLEAR;
|
||||
reg &= ~OMAP4_P2_MODE_CLEAR;
|
||||
|
||||
if (is_ehci_phy_mode(pdata->port_mode[0])) {
|
||||
ret = clk_set_parent(omap->utmi_p1_fck,
|
||||
omap->xclk60mhsp1_ck);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "xclk60mhsp1_ck set parent"
|
||||
"failed error:%d\n", ret);
|
||||
goto err_tll;
|
||||
}
|
||||
} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
|
||||
ret = clk_set_parent(omap->utmi_p1_fck,
|
||||
omap->init_60m_fclk);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "init_60m_fclk set parent"
|
||||
"failed error:%d\n", ret);
|
||||
goto err_tll;
|
||||
}
|
||||
clk_enable(omap->usbhost_p1_fck);
|
||||
clk_enable(omap->usbtll_p1_fck);
|
||||
}
|
||||
|
||||
if (is_ehci_phy_mode(pdata->port_mode[1])) {
|
||||
ret = clk_set_parent(omap->utmi_p2_fck,
|
||||
omap->xclk60mhsp2_ck);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "xclk60mhsp1_ck set parent"
|
||||
"failed error:%d\n", ret);
|
||||
goto err_tll;
|
||||
}
|
||||
} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
|
||||
ret = clk_set_parent(omap->utmi_p2_fck,
|
||||
omap->init_60m_fclk);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "init_60m_fclk set parent"
|
||||
"failed error:%d\n", ret);
|
||||
goto err_tll;
|
||||
}
|
||||
clk_enable(omap->usbhost_p2_fck);
|
||||
clk_enable(omap->usbtll_p2_fck);
|
||||
}
|
||||
|
||||
clk_enable(omap->utmi_p1_fck);
|
||||
clk_enable(omap->utmi_p2_fck);
|
||||
|
||||
if (is_ehci_tll_mode(pdata->port_mode[0]) ||
|
||||
(is_ohci_port(pdata->port_mode[0])))
|
||||
reg |= OMAP4_P1_MODE_TLL;
|
||||
|
@ -913,106 +614,14 @@ static int usbhs_enable(struct device *dev)
|
|||
(pdata->ehci_data->reset_gpio_port[1], 1);
|
||||
}
|
||||
|
||||
end_count:
|
||||
omap->count++;
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
return 0;
|
||||
|
||||
err_tll:
|
||||
if (pdata->ehci_data->phy_reset) {
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
||||
gpio_free(pdata->ehci_data->reset_gpio_port[0]);
|
||||
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
||||
gpio_free(pdata->ehci_data->reset_gpio_port[1]);
|
||||
}
|
||||
|
||||
clk_disable(omap->usbtll_ick);
|
||||
clk_disable(omap->usbtll_fck);
|
||||
clk_disable(omap->usbhost_fs_fck);
|
||||
clk_disable(omap->usbhost_hs_fck);
|
||||
clk_disable(omap->usbhost_ick);
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
return ret;
|
||||
pm_runtime_put_sync(dev);
|
||||
}
|
||||
|
||||
static void usbhs_disable(struct device *dev)
|
||||
static void omap_usbhs_deinit(struct device *dev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
|
||||
struct usbhs_omap_platform_data *pdata = &omap->platdata;
|
||||
unsigned long flags = 0;
|
||||
unsigned long timeout;
|
||||
|
||||
dev_dbg(dev, "stopping TI HSUSB Controller\n");
|
||||
|
||||
spin_lock_irqsave(&omap->lock, flags);
|
||||
|
||||
if (omap->count == 0)
|
||||
goto end_disble;
|
||||
|
||||
omap->count--;
|
||||
|
||||
if (omap->count != 0)
|
||||
goto end_disble;
|
||||
|
||||
/* Reset OMAP modules for insmod/rmmod to work */
|
||||
usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
|
||||
is_omap_usbhs_rev2(omap) ?
|
||||
OMAP4_UHH_SYSCONFIG_SOFTRESET :
|
||||
OMAP_UHH_SYSCONFIG_SOFTRESET);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(100);
|
||||
while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
|
||||
& (1 << 0))) {
|
||||
cpu_relax();
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
dev_dbg(dev, "operation timed out\n");
|
||||
}
|
||||
|
||||
while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
|
||||
& (1 << 1))) {
|
||||
cpu_relax();
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
dev_dbg(dev, "operation timed out\n");
|
||||
}
|
||||
|
||||
while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
|
||||
& (1 << 2))) {
|
||||
cpu_relax();
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
dev_dbg(dev, "operation timed out\n");
|
||||
}
|
||||
|
||||
usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
|
||||
|
||||
while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
|
||||
& (1 << 0))) {
|
||||
cpu_relax();
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
dev_dbg(dev, "operation timed out\n");
|
||||
}
|
||||
|
||||
if (is_omap_usbhs_rev2(omap)) {
|
||||
if (is_ehci_tll_mode(pdata->port_mode[0]))
|
||||
clk_disable(omap->usbtll_p1_fck);
|
||||
if (is_ehci_tll_mode(pdata->port_mode[1]))
|
||||
clk_disable(omap->usbtll_p2_fck);
|
||||
clk_disable(omap->utmi_p2_fck);
|
||||
clk_disable(omap->utmi_p1_fck);
|
||||
}
|
||||
|
||||
clk_disable(omap->usbtll_ick);
|
||||
clk_disable(omap->usbtll_fck);
|
||||
clk_disable(omap->usbhost_fs_fck);
|
||||
clk_disable(omap->usbhost_hs_fck);
|
||||
clk_disable(omap->usbhost_ick);
|
||||
|
||||
/* The gpio_free migh sleep; so unlock the spinlock */
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
|
||||
if (pdata->ehci_data->phy_reset) {
|
||||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
||||
|
@ -1021,28 +630,272 @@ static void usbhs_disable(struct device *dev)
|
|||
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
||||
gpio_free(pdata->ehci_data->reset_gpio_port[1]);
|
||||
}
|
||||
return;
|
||||
|
||||
end_disble:
|
||||
spin_unlock_irqrestore(&omap->lock, flags);
|
||||
}
|
||||
|
||||
int omap_usbhs_enable(struct device *dev)
|
||||
|
||||
/**
|
||||
* usbhs_omap_probe - initialize TI-based HCDs
|
||||
*
|
||||
* Allocates basic resources for this USB host controller.
|
||||
*/
|
||||
static int __devinit usbhs_omap_probe(struct platform_device *pdev)
|
||||
{
|
||||
return usbhs_enable(dev->parent);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_usbhs_enable);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct usbhs_omap_platform_data *pdata = dev->platform_data;
|
||||
struct usbhs_hcd_omap *omap;
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
void omap_usbhs_disable(struct device *dev)
|
||||
{
|
||||
usbhs_disable(dev->parent);
|
||||
if (!pdata) {
|
||||
dev_err(dev, "Missing platform data\n");
|
||||
ret = -ENOMEM;
|
||||
goto end_probe;
|
||||
}
|
||||
|
||||
omap = kzalloc(sizeof(*omap), GFP_KERNEL);
|
||||
if (!omap) {
|
||||
dev_err(dev, "Memory allocation failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto end_probe;
|
||||
}
|
||||
|
||||
spin_lock_init(&omap->lock);
|
||||
|
||||
for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
|
||||
omap->platdata.port_mode[i] = pdata->port_mode[i];
|
||||
|
||||
omap->platdata.ehci_data = pdata->ehci_data;
|
||||
omap->platdata.ohci_data = pdata->ohci_data;
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
|
||||
for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
|
||||
if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
|
||||
is_ehci_hsic_mode(i)) {
|
||||
omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
|
||||
if (IS_ERR(omap->ehci_logic_fck)) {
|
||||
ret = PTR_ERR(omap->ehci_logic_fck);
|
||||
dev_warn(dev, "ehci_logic_fck failed:%d\n",
|
||||
ret);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
|
||||
if (IS_ERR(omap->utmi_p1_fck)) {
|
||||
ret = PTR_ERR(omap->utmi_p1_fck);
|
||||
dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
|
||||
goto err_end;
|
||||
}
|
||||
|
||||
omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
|
||||
if (IS_ERR(omap->xclk60mhsp1_ck)) {
|
||||
ret = PTR_ERR(omap->xclk60mhsp1_ck);
|
||||
dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
|
||||
goto err_utmi_p1_fck;
|
||||
}
|
||||
|
||||
omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
|
||||
if (IS_ERR(omap->utmi_p2_fck)) {
|
||||
ret = PTR_ERR(omap->utmi_p2_fck);
|
||||
dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
|
||||
goto err_xclk60mhsp1_ck;
|
||||
}
|
||||
|
||||
omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
|
||||
if (IS_ERR(omap->xclk60mhsp2_ck)) {
|
||||
ret = PTR_ERR(omap->xclk60mhsp2_ck);
|
||||
dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
|
||||
goto err_utmi_p2_fck;
|
||||
}
|
||||
|
||||
omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
|
||||
if (IS_ERR(omap->usbhost_p1_fck)) {
|
||||
ret = PTR_ERR(omap->usbhost_p1_fck);
|
||||
dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
|
||||
goto err_xclk60mhsp2_ck;
|
||||
}
|
||||
|
||||
omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
|
||||
if (IS_ERR(omap->usbtll_p1_fck)) {
|
||||
ret = PTR_ERR(omap->usbtll_p1_fck);
|
||||
dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_p1_fck;
|
||||
}
|
||||
|
||||
omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
|
||||
if (IS_ERR(omap->usbhost_p2_fck)) {
|
||||
ret = PTR_ERR(omap->usbhost_p2_fck);
|
||||
dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
|
||||
goto err_usbtll_p1_fck;
|
||||
}
|
||||
|
||||
omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
|
||||
if (IS_ERR(omap->usbtll_p2_fck)) {
|
||||
ret = PTR_ERR(omap->usbtll_p2_fck);
|
||||
dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
|
||||
goto err_usbhost_p2_fck;
|
||||
}
|
||||
|
||||
omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
|
||||
if (IS_ERR(omap->init_60m_fclk)) {
|
||||
ret = PTR_ERR(omap->init_60m_fclk);
|
||||
dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
|
||||
goto err_usbtll_p2_fck;
|
||||
}
|
||||
|
||||
if (is_ehci_phy_mode(pdata->port_mode[0])) {
|
||||
/* for OMAP3 , the clk set paretn fails */
|
||||
ret = clk_set_parent(omap->utmi_p1_fck,
|
||||
omap->xclk60mhsp1_ck);
|
||||
if (ret != 0)
|
||||
dev_err(dev, "xclk60mhsp1_ck set parent"
|
||||
"failed error:%d\n", ret);
|
||||
} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
|
||||
ret = clk_set_parent(omap->utmi_p1_fck,
|
||||
omap->init_60m_fclk);
|
||||
if (ret != 0)
|
||||
dev_err(dev, "init_60m_fclk set parent"
|
||||
"failed error:%d\n", ret);
|
||||
}
|
||||
|
||||
if (is_ehci_phy_mode(pdata->port_mode[1])) {
|
||||
ret = clk_set_parent(omap->utmi_p2_fck,
|
||||
omap->xclk60mhsp2_ck);
|
||||
if (ret != 0)
|
||||
dev_err(dev, "xclk60mhsp2_ck set parent"
|
||||
"failed error:%d\n", ret);
|
||||
} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
|
||||
ret = clk_set_parent(omap->utmi_p2_fck,
|
||||
omap->init_60m_fclk);
|
||||
if (ret != 0)
|
||||
dev_err(dev, "init_60m_fclk set parent"
|
||||
"failed error:%d\n", ret);
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
|
||||
if (!res) {
|
||||
dev_err(dev, "UHH EHCI get resource failed\n");
|
||||
ret = -ENODEV;
|
||||
goto err_init_60m_fclk;
|
||||
}
|
||||
|
||||
omap->uhh_base = ioremap(res->start, resource_size(res));
|
||||
if (!omap->uhh_base) {
|
||||
dev_err(dev, "UHH ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_init_60m_fclk;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
|
||||
if (!res) {
|
||||
dev_err(dev, "UHH EHCI get resource failed\n");
|
||||
ret = -ENODEV;
|
||||
goto err_tll;
|
||||
}
|
||||
|
||||
omap->tll_base = ioremap(res->start, resource_size(res));
|
||||
if (!omap->tll_base) {
|
||||
dev_err(dev, "TLL ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_tll;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, omap);
|
||||
|
||||
ret = omap_usbhs_alloc_children(pdev);
|
||||
if (ret) {
|
||||
dev_err(dev, "omap_usbhs_alloc_children failed\n");
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
omap_usbhs_init(dev);
|
||||
|
||||
goto end_probe;
|
||||
|
||||
err_alloc:
|
||||
iounmap(omap->tll_base);
|
||||
|
||||
err_tll:
|
||||
iounmap(omap->uhh_base);
|
||||
|
||||
err_init_60m_fclk:
|
||||
clk_put(omap->init_60m_fclk);
|
||||
|
||||
err_usbtll_p2_fck:
|
||||
clk_put(omap->usbtll_p2_fck);
|
||||
|
||||
err_usbhost_p2_fck:
|
||||
clk_put(omap->usbhost_p2_fck);
|
||||
|
||||
err_usbtll_p1_fck:
|
||||
clk_put(omap->usbtll_p1_fck);
|
||||
|
||||
err_usbhost_p1_fck:
|
||||
clk_put(omap->usbhost_p1_fck);
|
||||
|
||||
err_xclk60mhsp2_ck:
|
||||
clk_put(omap->xclk60mhsp2_ck);
|
||||
|
||||
err_utmi_p2_fck:
|
||||
clk_put(omap->utmi_p2_fck);
|
||||
|
||||
err_xclk60mhsp1_ck:
|
||||
clk_put(omap->xclk60mhsp1_ck);
|
||||
|
||||
err_utmi_p1_fck:
|
||||
clk_put(omap->utmi_p1_fck);
|
||||
|
||||
err_end:
|
||||
clk_put(omap->ehci_logic_fck);
|
||||
pm_runtime_disable(dev);
|
||||
kfree(omap);
|
||||
|
||||
end_probe:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_usbhs_disable);
|
||||
|
||||
/**
|
||||
* usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
|
||||
* @pdev: USB Host Controller being removed
|
||||
*
|
||||
* Reverses the effect of usbhs_omap_probe().
|
||||
*/
|
||||
static int __devexit usbhs_omap_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
|
||||
|
||||
omap_usbhs_deinit(&pdev->dev);
|
||||
iounmap(omap->tll_base);
|
||||
iounmap(omap->uhh_base);
|
||||
clk_put(omap->init_60m_fclk);
|
||||
clk_put(omap->usbtll_p2_fck);
|
||||
clk_put(omap->usbhost_p2_fck);
|
||||
clk_put(omap->usbtll_p1_fck);
|
||||
clk_put(omap->usbhost_p1_fck);
|
||||
clk_put(omap->xclk60mhsp2_ck);
|
||||
clk_put(omap->utmi_p2_fck);
|
||||
clk_put(omap->xclk60mhsp1_ck);
|
||||
clk_put(omap->utmi_p1_fck);
|
||||
clk_put(omap->ehci_logic_fck);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
kfree(omap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
|
||||
.runtime_suspend = usbhs_runtime_suspend,
|
||||
.runtime_resume = usbhs_runtime_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver usbhs_omap_driver = {
|
||||
.driver = {
|
||||
.name = (char *)usbhs_driver_name,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &usbhsomap_dev_pm_ops,
|
||||
},
|
||||
.remove = __exit_p(usbhs_omap_remove),
|
||||
};
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <linux/usb/ulpi.h>
|
||||
#include <plat/usb.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
/* EHCI Register Set */
|
||||
#define EHCI_INSNREG04 (0xA0)
|
||||
|
@ -190,11 +191,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
ret = omap_usbhs_enable(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to start usbhs with err %d\n", ret);
|
||||
goto err_enable;
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
/*
|
||||
* An undocumented "feature" in the OMAP3 EHCI controller,
|
||||
|
@ -240,11 +238,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err_add_hcd:
|
||||
omap_usbhs_disable(dev);
|
||||
|
||||
err_enable:
|
||||
disable_put_regulator(pdata);
|
||||
usb_put_hcd(hcd);
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
err_io:
|
||||
iounmap(regs);
|
||||
|
@ -266,10 +261,12 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
|
|||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
omap_usbhs_disable(dev);
|
||||
disable_put_regulator(dev->platform_data);
|
||||
iounmap(hcd->regs);
|
||||
usb_put_hcd(hcd);
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <linux/platform_device.h>
|
||||
#include <plat/usb.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -134,7 +135,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
|
|||
int irq;
|
||||
|
||||
if (usb_disabled())
|
||||
goto err_end;
|
||||
return -ENODEV;
|
||||
|
||||
if (!dev->parent) {
|
||||
dev_err(dev, "Missing parent device\n");
|
||||
|
@ -172,11 +173,8 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
|
|||
hcd->rsrc_len = resource_size(res);
|
||||
hcd->regs = regs;
|
||||
|
||||
ret = omap_usbhs_enable(dev);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "failed to start ohci\n");
|
||||
goto err_end;
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
ohci_hcd_init(hcd_to_ohci(hcd));
|
||||
|
||||
|
@ -189,9 +187,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err_add_hcd:
|
||||
omap_usbhs_disable(dev);
|
||||
|
||||
err_end:
|
||||
pm_runtime_put_sync(dev);
|
||||
usb_put_hcd(hcd);
|
||||
|
||||
err_io:
|
||||
|
@ -220,9 +216,9 @@ static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev)
|
|||
|
||||
iounmap(hcd->regs);
|
||||
usb_remove_hcd(hcd);
|
||||
omap_usbhs_disable(dev);
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
usb_put_hcd(hcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче