diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-omap2/usb-host.c | 644 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/usb.h | 5 |
5 files changed, 527 insertions, 145 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 303fda6..a346871 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -149,6 +149,7 @@ #include "prm2xxx_3xxx.h" #include "prm44xx.h" #include "mux.h" +#include "pm.h" /* Maximum microseconds to wait for OMAP module to softreset */ #define MAX_MODULE_SOFTRESET_WAIT 10000 @@ -1326,8 +1327,11 @@ static int _idle(struct omap_hwmod *oh) _disable_clocks(oh); /* Mux pins for device idle if populated */ - if (oh->mux && oh->mux->pads_dynamic) + if (oh->mux && oh->mux->pads_dynamic) { omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); + if (cpu_is_omap44xx()) + omap4_trigger_ioctrl(); + } oh->_state = _HWMOD_STATE_IDLE; diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 47fc925..4ba5e44 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -25,6 +25,7 @@ #include <asm/hardware/gic.h> #include <mach/omap4-common.h> #include <plat/common.h> +#include <plat/usb.h> #include "powerdomain.h" #include "clockdomain.h" @@ -66,6 +67,14 @@ void omap4_trigger_ioctrl(void) { int i = 0; + /* Enable GLOBAL_WUEN */ + if (!omap4_cminst_read_inst_reg_bits(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET, + OMAP4430_GLOBAL_WUEN_MASK)) + omap4_prminst_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, + OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET); + /* Trigger WUCLKIN enable */ omap4_prminst_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, OMAP4430_WUCLK_CTRL_MASK, OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET); @@ -135,7 +144,6 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend) OMAP_VC_CHANNEL_AUTO_TRANSITION_RETENTION); omap2_gpio_prepare_for_idle(0); - omap4_trigger_ioctrl(); } } @@ -456,9 +464,6 @@ static void __init prcm_setup_regs(void) omap4_prminst_rmw_inst_reg_bits(OMAP4430_IO_ST_MASK, OMAP4430_IO_ST_MASK, OMAP4430_PRM_PARTITION, OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET); - /* Enable GLOBAL_WUEN */ - omap4_prminst_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_GLOBAL_WUEN_MASK, - OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET); /* * Errata ID: i608 Impacted OMAP4430 ES 1.0,2.0,2.1,2.2 * On OMAP4, Retention-Till-Access Memory feature is not working @@ -512,6 +517,7 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) omap_writel( (1<<3) | (1<<12), HSI_SYSCONFIG); } omap_uart_resume_idle(); + usbhs_wakeup(); omap4_trigger_ioctrl(); } diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index d62613c..69771b0 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -22,6 +22,8 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/dma-mapping.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> #include <asm/io.h> @@ -52,7 +54,401 @@ static struct omap_device_pm_latency omap_uhhtll_latency[] = { }, }; +static struct usbhs_wakeup { + struct device *dev; + struct omap_hwmod *oh_ehci; + struct omap_hwmod *oh_ohci; + struct work_struct wakeup_work; + int wakeup_ehci:1; + int wakeup_ohci:1; +} *usbhs_wake; + /* MUX settings for EHCI pins */ +static struct omap_device_pad port1_phy_pads[] __initdata = { + { + .name = "usbb1_ulpitll_stp.usbb1_ulpiphy_stp", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_clk.usbb1_ulpiphy_clk", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dir.usbb1_ulpiphy_dir", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~OMAP_WAKEUP_EN, + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~OMAP_WAKEUP_EN, + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, +}; + +static struct omap_device_pad port1_tll_pads[] __initdata = { + { + .name = "usbb1_ulpitll_stp.usbb1_ulpitll_stp", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_clk.usbb1_ulpitll_clk", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dir.usbb1_ulpitll_dir", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_nxt.usbb1_ulpitll_nxt", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat0.usbb1_ulpitll_dat0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat1.usbb1_ulpitll_dat1", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat2.usbb1_ulpitll_dat2", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat3.usbb1_ulpitll_dat3", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat4.usbb1_ulpitll_dat4", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat5.usbb1_ulpitll_dat5", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat6.usbb1_ulpitll_dat6", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb1_ulpitll_dat7.usbb1_ulpitll_dat7", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad port2_phy_pads[] __initdata = { + { + .name = "usbb2_ulpitll_stp.usbb2_ulpiphy_stp", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_clk.usbb2_ulpiphy_clk", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dir.usbb2_ulpiphy_dir", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_WAKEUP_EN + | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_nxt.usbb2_ulpiphy_nxt", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat0.usbb2_ulpiphy_dat0", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_WAKEUP_EN + | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat1.usbb2_ulpiphy_dat1", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat2.usbb2_ulpiphy_dat2", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat3.usbb2_ulpiphy_dat3", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat4.usbb2_ulpiphy_dat4", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat5.usbb2_ulpiphy_dat5", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat6.usbb2_ulpiphy_dat6", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "usbb2_ulpitll_dat7.usbb2_ulpiphy_dat7", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, +}; + +static struct omap_device_pad port2_tll_pads[] __initdata = { + { + .name = "usbb2_ulpitll_stp.usbb2_ulpitll_stp", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_clk.usbb2_ulpitll_clk", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dir.usbb2_ulpitll_dir", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_nxt.usbb2_ulpitll_nxt", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat0.usbb2_ulpitll_dat0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat1.usbb2_ulpitll_dat1", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat2.usbb2_ulpitll_dat2", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat3.usbb2_ulpitll_dat3", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat4.usbb2_ulpitll_dat4", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat5.usbb2_ulpitll_dat5", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat6.usbb2_ulpitll_dat6", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, + { + .name = "usbb2_ulpitll_dat7.usbb2_ulpitll_dat7", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad port1_6pin_pads[] __initdata = { + { + .name = "usbb1_ulpitll_stp.usbb1_mm_rxdp", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_nxt.usbb1_mm_rxdm", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat0.usbb1_mm_rxrcv", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat3.usbb1_mm_txen", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat1.usbb1_mm_txdat", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat2.usbb1_mm_txse0", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, +}; + +static struct omap_device_pad port1_4pin_pads[] __initdata = { + { + .name = "usbb1_ulpitll_dat0.usbb1_mm_rxrcv", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat3.usbb1_mm_txen", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat1.usbb1_mm_txdat", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat2.usbb1_mm_txse0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, +}; + +static struct omap_device_pad port1_3pin_pads[] __initdata = { + { + .name = "usbb1_ulpitll_dat3.usbb1_mm_txen", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat1.usbb1_mm_txdat", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat2.usbb1_mm_txse0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, +}; + +static struct omap_device_pad port1_2pin_pads[] __initdata = { + { + .name = "usbb1_ulpitll_dat1.usbb1_mm_txdat", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, + { + .name = "usbb1_ulpitll_dat2.usbb1_mm_txse0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE5, + }, +}; + +static struct omap_device_pad port2_6pin_pads[] __initdata = { + { + .name = "abe_mcbsp2_dr.usbb2_mm_rxdp", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_mcbsp2_clkx.usbb2_mm_rxdm", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_mcbsp2_dx.usbb2_mm_rxrcv", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_mcbsp2_fsx.usbb2_mm_txen", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_din1.usbb2_mm_txdat", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_clk1.usbb2_mm_txse0", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = (OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4) & ~(OMAP_WAKEUP_EN), + .idle = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, +}; + +static struct omap_device_pad port2_4pin_pads[] __initdata = { + { + .name = "abe_mcbsp2_dx.usbb2_mm_rxrcv", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_mcbsp2_fsx.usbb2_mm_txen", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_din1.usbb2_mm_txdat", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_clk1.usbb2_mm_txse0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, +}; + +static struct omap_device_pad port2_3pin_pads[] __initdata = { + { + .name = "abe_mcbsp2_fsx.usbb2_mm_txen", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_din1.usbb2_mm_txdat", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_clk1.usbb2_mm_txse0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, +}; + +static struct omap_device_pad port2_2pin_pads[] __initdata = { + { + .name = "abe_mcbsp2_fsx.usbb2_mm_txen", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_din1.usbb2_mm_txdat", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, + { + .name = "abe_dmic_clk1.usbb2_mm_txse0", + .enable = OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE4, + }, +}; /* * setup_ehci_io_mux - initialize IO pad mux for USBHOST */ @@ -199,60 +595,20 @@ static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) return; } -static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static struct omap_hwmod_mux_info * +setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { + struct omap_device_pad *pads; + int pads_cnt; + switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: - omap_mux_init_signal("usbb1_ulpiphy_stp", - OMAP_PIN_OUTPUT); - omap_mux_init_signal("usbb1_ulpiphy_clk", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dir", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_nxt", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat0", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat1", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat2", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat3", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat4", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat5", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat6", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpiphy_dat7", - OMAP_PIN_INPUT_PULLDOWN); + pads = port1_phy_pads; + pads_cnt = ARRAY_SIZE(port1_phy_pads); break; case OMAP_EHCI_PORT_MODE_TLL: - omap_mux_init_signal("usbb1_ulpitll_stp", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("usbb1_ulpitll_clk", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dir", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_nxt", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat0", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat1", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat2", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat3", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat4", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat5", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat6", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_ulpitll_dat7", - OMAP_PIN_INPUT_PULLDOWN); + pads = port1_tll_pads; + pads_cnt = ARRAY_SIZE(port1_tll_pads); break; case OMAP_USBHS_PORT_MODE_UNUSED: default: @@ -260,61 +616,19 @@ static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) } switch (port_mode[1]) { case OMAP_EHCI_PORT_MODE_PHY: - omap_mux_init_signal("usbb2_ulpiphy_stp", - OMAP_PIN_OUTPUT); - omap_mux_init_signal("usbb2_ulpiphy_clk", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dir", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_nxt", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat0", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat1", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat2", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat3", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat4", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat5", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat6", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpiphy_dat7", - OMAP_PIN_INPUT_PULLDOWN); + pads = port2_phy_pads; + pads_cnt = ARRAY_SIZE(port2_phy_pads); break; case OMAP_EHCI_PORT_MODE_TLL: - omap_mux_init_signal("usbb2_ulpitll_stp", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("usbb2_ulpitll_clk", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dir", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_nxt", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat0", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat1", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat2", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat3", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat4", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat5", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat6", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_ulpitll_dat7", - OMAP_PIN_INPUT_PULLDOWN); + pads = port2_tll_pads; + pads_cnt = ARRAY_SIZE(port2_tll_pads); break; case OMAP_USBHS_PORT_MODE_UNUSED: default: break; } + + return omap_hwmod_mux_init(pads, pads_cnt); } static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) @@ -414,37 +728,35 @@ static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) } } -static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static struct omap_hwmod_mux_info * +setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) { + struct omap_device_pad *pads; + int pads_cnt; + switch (port_mode[0]) { case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: - omap_mux_init_signal("usbb1_mm_rxdp", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_mm_rxdm", - OMAP_PIN_INPUT_PULLDOWN); - + pads = port1_6pin_pads; + pads_cnt = ARRAY_SIZE(port1_6pin_pads); + break; case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: - omap_mux_init_signal("usbb1_mm_rxrcv", - OMAP_PIN_INPUT_PULLDOWN); - + pads = port1_4pin_pads; + pads_cnt = ARRAY_SIZE(port1_4pin_pads); + break; case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: - omap_mux_init_signal("usbb1_mm_txen", - OMAP_PIN_INPUT_PULLDOWN); - - + pads = port1_3pin_pads; + pads_cnt = ARRAY_SIZE(port1_3pin_pads); + break; case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: - omap_mux_init_signal("usbb1_mm_txdat", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb1_mm_txse0", - OMAP_PIN_INPUT_PULLDOWN); + pads = port1_2pin_pads; + pads_cnt = ARRAY_SIZE(port1_2pin_pads); break; - case OMAP_USBHS_PORT_MODE_UNUSED: default: break; @@ -455,34 +767,71 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: - omap_mux_init_signal("usbb2_mm_rxdp", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_mm_rxdm", - OMAP_PIN_INPUT_PULLDOWN); - + pads = port2_6pin_pads; + pads_cnt = ARRAY_SIZE(port2_6pin_pads); + break; case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: - omap_mux_init_signal("usbb2_mm_rxrcv", - OMAP_PIN_INPUT_PULLDOWN); - + pads = port2_4pin_pads; + pads_cnt = ARRAY_SIZE(port2_4pin_pads); + break; case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: - omap_mux_init_signal("usbb2_mm_txen", - OMAP_PIN_INPUT_PULLDOWN); - - + pads = port2_3pin_pads; + pads_cnt = ARRAY_SIZE(port2_3pin_pads); + break; case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: - omap_mux_init_signal("usbb2_mm_txdat", - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal("usbb2_mm_txse0", - OMAP_PIN_INPUT_PULLDOWN); + pads = port2_2pin_pads; + pads_cnt = ARRAY_SIZE(port2_3pin_pads); break; - case OMAP_USBHS_PORT_MODE_UNUSED: default: break; } + + return omap_hwmod_mux_init(pads, pads_cnt); +} + +void usbhs_wakeup() +{ + int workq = 0; + + if (!usbhs_wake) + return; + + if (test_bit(USB_OHCI_LOADED, &usb_hcds_loaded) && + omap_hwmod_pad_get_wakeup_status(usbhs_wake->oh_ohci)) { + usbhs_wake->wakeup_ohci = 1; + workq = 1; + } + + if (test_bit(USB_EHCI_LOADED, &usb_hcds_loaded) && + omap_hwmod_pad_get_wakeup_status(usbhs_wake->oh_ehci)) { + usbhs_wake->wakeup_ehci = 1; + workq = 1; + } + + if (workq) + queue_work(pm_wq, &usbhs_wake->wakeup_work); +} + +static void usbhs_resume_work(struct work_struct *work) +{ + dev_dbg(usbhs_wake->dev, "USB IO PAD Wakeup event triggered\n"); + + if (usbhs_wake->wakeup_ehci) { + usbhs_wake->wakeup_ehci = 0; + omap_hwmod_disable_ioring_wakeup(usbhs_wake->oh_ehci); + } + + if (usbhs_wake->wakeup_ohci) { + usbhs_wake->wakeup_ohci = 0; + omap_hwmod_disable_ioring_wakeup(usbhs_wake->oh_ohci); + } + + pm_runtime_get_sync(usbhs_wake->dev); + pm_runtime_put_sync(usbhs_wake->dev); } void __init usbhs_init(const struct usbhs_omap_board_data *pdata) @@ -504,14 +853,6 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) usbhs_data.ehci_data = &ehci_data; usbhs_data.ohci_data = &ohci_data; - if (cpu_is_omap34xx()) { - setup_ehci_io_mux(pdata->port_mode); - setup_ohci_io_mux(pdata->port_mode); - } else if (cpu_is_omap44xx()) { - setup_4430ehci_io_mux(pdata->port_mode); - setup_4430ohci_io_mux(pdata->port_mode); - } - oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME); if (!oh[0]) { pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME); @@ -536,6 +877,14 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) return; } + if (cpu_is_omap34xx()) { + setup_ehci_io_mux(pdata->port_mode); + setup_ohci_io_mux(pdata->port_mode); + } else if (cpu_is_omap44xx()) { + oh[2]->mux = setup_4430ehci_io_mux(pdata->port_mode); + oh[1]->mux = setup_4430ohci_io_mux(pdata->port_mode); + } + od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 4, (void *)&usbhs_data, sizeof(usbhs_data), omap_uhhtll_latency, @@ -546,10 +895,25 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME); return; } + + usbhs_wake = kmalloc(sizeof(*usbhs_wake), GFP_KERNEL); + if (!usbhs_wake) { + pr_err("Could not allocate usbhs_wake\n"); + return; + } + + INIT_WORK(&usbhs_wake->wakeup_work, usbhs_resume_work); + usbhs_wake->oh_ehci = oh[2]; + usbhs_wake->oh_ohci = oh[1]; + usbhs_wake->dev = &od->pdev.dev; } #else +void usbhs_wakeup() +{ +} + void __init usbhs_init(const struct usbhs_omap_board_data *pdata) { } diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 019845f..5a05566 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -601,6 +601,9 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh); int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh); + +int omap_hwmod_disable_ioring_wakeup(struct omap_hwmod *oh); +int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh); /* * Chip variant-specific hwmod init routines - XXX should be converted * to use initcalls once the initial boot ordering is straightened out diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 2b66dc2..0869454 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -290,4 +290,9 @@ static inline u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup) } #endif +extern void usbhs_wakeup(void); +extern void omap4_trigger_ioctrl(void); + +#define USBHS_EHCI_HWMODNAME "usbhs_ehci" + #endif /* __ASM_ARCH_OMAP_USB_H */ |