This patch re-structures davinci.c file to use the USB VBUS, PHY controls from platform specific implementation. All DaVinci related platform dependancies w.r.t USB VBUS, PHY controls have been moved out of this file into "arch/arm/ mach-davinci" paltform specific implementation. Signed-off-by: Swaminathan S <swami.iyer@xxxxxx> --- drivers/usb/musb/davinci.c | 162 ++++++------------------------------------ drivers/usb/musb/davinci.h | 17 ----- drivers/usb/musb/musb_core.h | 3 +- 3 files changed, 23 insertions(+), 159 deletions(-) diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index e16ff60..06ec835 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -30,58 +30,16 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> -#include <linux/gpio.h> #include <mach/hardware.h> #include <mach/memory.h> -#include <mach/gpio.h> -#include <mach/cputype.h> - -#include <asm/mach-types.h> #include "musb_core.h" -#ifdef CONFIG_MACH_DAVINCI_EVM -#define GPIO_nVBUS_DRV 144 -#endif - #include "davinci.h" #include "cppi_dma.h" -#define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) -#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) - -/* REVISIT (PM) we should be able to keep the PHY in low power mode most - * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 - * and, when in host mode, autosuspending idle root ports... PHYPLLON - * (overriding SUSPENDM?) then likely needs to stay off. - */ - -static inline void phy_on(void) -{ - u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); - - /* power everything up; start the on-chip PHY and its PLL */ - phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN); - phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON; - __raw_writel(phy_ctrl, USB_PHY_CTRL); - - /* wait for PLL to lock before proceeding */ - while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0) - cpu_relax(); -} - -static inline void phy_off(void) -{ - u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); - - /* powerdown the on-chip PHY, its PLL, and the OTG block */ - phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON); - phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN; - __raw_writel(phy_ctrl, USB_PHY_CTRL); -} - static int dma_off = 1; void musb_platform_enable(struct musb *musb) @@ -142,62 +100,6 @@ void musb_platform_disable(struct musb *musb) #define portstate(stmt) #endif - -/* - * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM, - * which doesn't wire DRVVBUS to the FET that switches it. Unclear - * if that's a problem with the DM6446 chip or just with that board. - * - * In either case, the DM355 EVM automates DRVVBUS the normal way, - * when J10 is out, and TI documents it as handling OTG. - */ - -#ifdef CONFIG_MACH_DAVINCI_EVM - -static int vbus_state = -1; - -/* I2C operations are always synchronous, and require a task context. - * With unloaded systems, using the shared workqueue seems to suffice - * to satisfy the 100msec A_WAIT_VRISE timeout... - */ -static void evm_deferred_drvvbus(struct work_struct *ignored) -{ - gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); - vbus_state = !vbus_state; -} - -#endif /* EVM */ - -static void davinci_source_power(struct musb *musb, int is_on, int immediate) -{ -#ifdef CONFIG_MACH_DAVINCI_EVM - if (is_on) - is_on = 1; - - if (vbus_state == is_on) - return; - vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ - - if (machine_is_davinci_evm()) { - static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); - - if (immediate) - gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); - else - schedule_work(&evm_vbus_work); - } - if (immediate) - vbus_state = is_on; -#endif -} - -static void davinci_set_vbus(struct musb *musb, int is_on) -{ - WARN_ON(is_on && is_peripheral_active(musb)); - davinci_source_power(musb, is_on, 0); -} - - #define POLL_SECONDS 2 static struct timer_list otg_workaround; @@ -346,7 +248,8 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) /* NOTE: this must complete poweron within 100 msec * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. */ - davinci_source_power(musb, drvvbus, 0); + if (musb->board_set_vbus) + musb->board_set_vbus(musb, drvvbus); DBG(2, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", otg_state_string(musb), @@ -381,6 +284,8 @@ int __init musb_platform_init(struct musb *musb) { void __iomem *tibase = musb->ctrl_base; u32 revision; + struct device *dev = musb->controller; + struct musb_hdrc_platform_data *plat = dev->platform_data; usb_nop_xceiv_register(); musb->xceiv = otg_get_transceiver(); @@ -399,47 +304,25 @@ int __init musb_platform_init(struct musb *musb) if (is_host_enabled(musb)) setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); - musb->board_set_vbus = davinci_set_vbus; - davinci_source_power(musb, 0, 1); + /* Subscribe VBUS handler to the platform specific VBUs handler */ + musb->board_set_vbus = (void *) plat->set_vbus; - /* dm355 EVM swaps D+/D- for signal integrity, and - * is clocked from the main 24 MHz crystal. - */ - if (machine_is_davinci_dm355_evm()) { - u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); - - phy_ctrl &= ~(3 << 9); - phy_ctrl |= USBPHY_DATAPOL; - __raw_writel(phy_ctrl, USB_PHY_CTRL); - } - - /* On dm355, the default-A state machine needs DRVVBUS control. - * If we won't be a host, there's no need to turn it on. - */ - if (cpu_is_davinci_dm355()) { - u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); - - if (is_host_enabled(musb)) { - deepsleep &= ~DRVVBUS_OVERRIDE; - } else { - deepsleep &= ~DRVVBUS_FORCE; - deepsleep |= DRVVBUS_OVERRIDE; - } - __raw_writel(deepsleep, DM355_DEEPSLEEP); - } + /* Turn off the VBUS by default */ + if (musb->board_set_vbus) + musb->board_set_vbus(musb, 0); /* reset the controller */ musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); /* start the on-chip PHY and its PLL */ - phy_on(); + if (plat->phy_config) + plat->phy_config(dev, musb->board_mode, 1); msleep(5); /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ - pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", - revision, __raw_readl(USB_PHY_CTRL), - musb_readb(tibase, DAVINCI_USB_CTRL_REG)); + pr_debug("DaVinci OTG revision %08x control %02x\n", + revision, musb_readb(tibase, DAVINCI_USB_CTRL_REG)); musb->isr = davinci_interrupt; return 0; @@ -451,19 +334,14 @@ fail: int musb_platform_exit(struct musb *musb) { + struct device *dev = musb->controller; + struct musb_hdrc_platform_data *plat = dev->platform_data; + if (is_host_enabled(musb)) del_timer_sync(&otg_workaround); - /* force VBUS off */ - if (cpu_is_davinci_dm355()) { - u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); - - deepsleep &= ~DRVVBUS_FORCE; - deepsleep |= DRVVBUS_OVERRIDE; - __raw_writel(deepsleep, DM355_DEEPSLEEP); - } - - davinci_source_power(musb, 0 /*off*/, 1); + if (musb->board_set_vbus) + musb->board_set_vbus(musb, 0); /* delay, to avoid problems with module reload */ if (is_host_enabled(musb) && musb->xceiv->default_a) { @@ -491,7 +369,9 @@ int musb_platform_exit(struct musb *musb) DBG(1, "VBUS off timeout (devctl %02x)\n", devctl); } - phy_off(); + /* Turn off the PHY */ + if (plat->phy_config) + plat->phy_config(dev, musb->board_mode, 0); clk_disable(musb->clock); diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h index 046c844..27fdc14 100644 --- a/drivers/usb/musb/davinci.h +++ b/drivers/usb/musb/davinci.h @@ -14,23 +14,6 @@ * DaVinci-specific definitions */ -/* Integrated highspeed/otg PHY */ -#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) -#define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ -#define USBPHY_PHYCLKGD BIT(8) -#define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ -#define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */ -#define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */ -#define USBPHY_PHYPLLON BIT(4) /* override pll suspend */ -#define USBPHY_CLKO1SEL BIT(3) -#define USBPHY_OSCPDWN BIT(2) -#define USBPHY_OTGPDWN BIT(1) -#define USBPHY_PHYPDWN BIT(0) - -#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) -#define DRVVBUS_FORCE BIT(2) -#define DRVVBUS_OVERRIDE BIT(1) - /* For now include usb OTG module registers here */ #define DAVINCI_USB_VERSION_REG 0x00 #define DAVINCI_USB_CTRL_REG 0x04 diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 381d648..b7c3544 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -448,7 +448,8 @@ struct musb { static inline void musb_set_vbus(struct musb *musb, int is_on) { - musb->board_set_vbus(musb, is_on); + if (musb->board_set_vbus) + musb->board_set_vbus(musb, is_on); } #ifdef CONFIG_USB_GADGET_MUSB_HDRC -- 1.6.0.rc1.64.g61192 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html