mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
ASoC: Updates for v3.15
Quite a busy release for ASoC this time, more on janitorial work than
exciting new features but welcome nontheless:
- Lots of cleanups from Takashi for enumerations; the original API for
these was error prone so he's refactored lots of code to use more
modern APIs which avoid issues.
- Elimination of the ASoC level wrappers for I2C and SPI moving us
closer to converting to regmap completely and avoiding some
randconfig hassle.
- Provide both manually and transparently locked DAPM APIs rather than
a mix of the two fixing some concurrency issues.
- Start converting CODEC drivers to use separate bus interface drivers
rather than having them all in one file helping avoid dependency
issues.
- DPCM support for Intel Haswell and Bay Trail platforms.
- Lots of work on improvements for simple-card, DaVinci and the Renesas
rcar drivers.
- New drivers for Analog Devices ADAU1977, TI PCM512x and parts of the
CSR SiRF SoC.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJTIOhJAAoJELSic+t+oim90CoP/3CVTm9cWv1qhPSU6jjn6RJG
/djmhntJfHd/GXo+0TiiwNK9WmZjFrJUr+5ofkDTCqSzFz1Suc90B6oHxY4dFbgF
IyIpTexGwTLv3H6yDjadYAfmGDSsE9sM2dkID9oXy6aEzjNby/a1VEiBnRgx16X1
YGvMVK8AGFn/AyC/zOV6EcKJxUjdDogqZ5wkR2XHzwDoYjl9ufxK9BnSIygYABOW
ABAjyrZf3xx97AH82BB6iqcZMh5GxGNTvI3hQd/vjx0r7RFUDNLqmF2cPZAMTRW/
bXWxVmtNHie1+lCldyMFm8pV/Pv09zuqDAQKbPY2TeHj2zF8CM548NlkFHqwHlp0
S9K5E1N+/2wcXMjQa1wBELohUdl6dVh1OFOAz7M8o0TJdSOZyR6PJ9r0NprP8NgS
67FBU+ZqnWIK159m9rKkFfPhnaDuDzk+rpwyK0fQxQgpdGGjLyv7OK3GhS30oTnA
Z2GjEyUySM1BcEEWAtfUD5fHbjN28e1Icn53q5q4JK4gvx4DXBy08uY/vumvjXjO
8oum3q3RjRvqIhzMrJoVgs+c8RHwS/bZQhlu9Q3qNTsDNDyMnaZWHFAnP8RDqHjv
ojZiMJkJdpqceZ3z1k5ZG8GWJ2JaZBikSbeNk2Ltg17/0nackq2r8ekrIoEUPVk2
ph4DJNC2s1qCFtx7tzQj
=C5oo
-----END PGP SIGNATURE-----
Merge tag 'asoc-v3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v3.15
Quite a busy release for ASoC this time, more on janitorial work than
exciting new features but welcome nontheless:
- Lots of cleanups from Takashi for enumerations; the original API for
these was error prone so he's refactored lots of code to use more
modern APIs which avoid issues.
- Elimination of the ASoC level wrappers for I2C and SPI moving us
closer to converting to regmap completely and avoiding some
randconfig hassle.
- Provide both manually and transparently locked DAPM APIs rather than
a mix of the two fixing some concurrency issues.
- Start converting CODEC drivers to use separate bus interface drivers
rather than having them all in one file helping avoid dependency
issues.
- DPCM support for Intel Haswell and Bay Trail platforms.
- Lots of work on improvements for simple-card, DaVinci and the Renesas
rcar drivers.
- New drivers for Analog Devices ADAU1977, TI PCM512x and parts of the
CSR SiRF SoC.
This commit is contained in:
commit
5fdb83f190
993 changed files with 25529 additions and 9422 deletions
|
|
@ -105,7 +105,7 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir)
|
|||
|
||||
do {
|
||||
/* flush any pending transfer */
|
||||
hw_write(ci, OP_ENDPTFLUSH, BIT(n), BIT(n));
|
||||
hw_write(ci, OP_ENDPTFLUSH, ~0, BIT(n));
|
||||
while (hw_read(ci, OP_ENDPTFLUSH, BIT(n)))
|
||||
cpu_relax();
|
||||
} while (hw_read(ci, OP_ENDPTSTAT, BIT(n)));
|
||||
|
|
@ -205,7 +205,7 @@ static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl)
|
|||
if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num)))
|
||||
return -EAGAIN;
|
||||
|
||||
hw_write(ci, OP_ENDPTPRIME, BIT(n), BIT(n));
|
||||
hw_write(ci, OP_ENDPTPRIME, ~0, BIT(n));
|
||||
|
||||
while (hw_read(ci, OP_ENDPTPRIME, BIT(n)))
|
||||
cpu_relax();
|
||||
|
|
|
|||
|
|
@ -717,6 +717,10 @@ int usb_get_configuration(struct usb_device *dev)
|
|||
result = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dev->quirks & USB_QUIRK_DELAY_INIT)
|
||||
msleep(100);
|
||||
|
||||
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
|
||||
bigbuffer, length);
|
||||
if (result < 0) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
/* Microsoft LifeCam-VX700 v2.0 */
|
||||
{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech HD Pro Webcams C920 and C930e */
|
||||
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
{ USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Logitech Quickcam Fusion */
|
||||
{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
|
|
|
|||
|
|
@ -360,24 +360,30 @@ static inline void usb_dma_writel(struct bcm63xx_udc *udc, u32 val, u32 off)
|
|||
bcm_writel(val, udc->iudma_regs + off);
|
||||
}
|
||||
|
||||
static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off)
|
||||
static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off, int chan)
|
||||
{
|
||||
return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off);
|
||||
return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off +
|
||||
(ENETDMA_CHAN_WIDTH * chan));
|
||||
}
|
||||
|
||||
static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off)
|
||||
static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off,
|
||||
int chan)
|
||||
{
|
||||
bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off);
|
||||
bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off +
|
||||
(ENETDMA_CHAN_WIDTH * chan));
|
||||
}
|
||||
|
||||
static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off)
|
||||
static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off, int chan)
|
||||
{
|
||||
return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off);
|
||||
return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off +
|
||||
(ENETDMA_CHAN_WIDTH * chan));
|
||||
}
|
||||
|
||||
static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off)
|
||||
static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off,
|
||||
int chan)
|
||||
{
|
||||
bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off);
|
||||
bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off +
|
||||
(ENETDMA_CHAN_WIDTH * chan));
|
||||
}
|
||||
|
||||
static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled)
|
||||
|
|
@ -638,7 +644,7 @@ static void iudma_write(struct bcm63xx_udc *udc, struct iudma_ch *iudma,
|
|||
} while (!last_bd);
|
||||
|
||||
usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK,
|
||||
ENETDMAC_CHANCFG_REG(iudma->ch_idx));
|
||||
ENETDMAC_CHANCFG_REG, iudma->ch_idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -694,9 +700,9 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma)
|
|||
bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num));
|
||||
|
||||
/* stop DMA, then wait for the hardware to wrap up */
|
||||
usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG(ch_idx));
|
||||
usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG, ch_idx);
|
||||
|
||||
while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)) &
|
||||
while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx) &
|
||||
ENETDMAC_CHANCFG_EN_MASK) {
|
||||
udelay(1);
|
||||
|
||||
|
|
@ -713,10 +719,10 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma)
|
|||
dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n",
|
||||
ch_idx);
|
||||
usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK,
|
||||
ENETDMAC_CHANCFG_REG(ch_idx));
|
||||
ENETDMAC_CHANCFG_REG, ch_idx);
|
||||
}
|
||||
}
|
||||
usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG(ch_idx));
|
||||
usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG, ch_idx);
|
||||
|
||||
/* don't leave "live" HW-owned entries for the next guy to step on */
|
||||
for (d = iudma->bd_ring; d <= iudma->end_bd; d++)
|
||||
|
|
@ -728,11 +734,11 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma)
|
|||
|
||||
/* set up IRQs, UBUS burst size, and BD base for this channel */
|
||||
usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK,
|
||||
ENETDMAC_IRMASK_REG(ch_idx));
|
||||
usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG(ch_idx));
|
||||
ENETDMAC_IRMASK_REG, ch_idx);
|
||||
usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG, ch_idx);
|
||||
|
||||
usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG(ch_idx));
|
||||
usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG(ch_idx));
|
||||
usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG, ch_idx);
|
||||
usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG, ch_idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2035,7 +2041,7 @@ static irqreturn_t bcm63xx_udc_data_isr(int irq, void *dev_id)
|
|||
spin_lock(&udc->lock);
|
||||
|
||||
usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK,
|
||||
ENETDMAC_IR_REG(iudma->ch_idx));
|
||||
ENETDMAC_IR_REG, iudma->ch_idx);
|
||||
bep = iudma->bep;
|
||||
rc = iudma_read(udc, iudma);
|
||||
|
||||
|
|
@ -2175,18 +2181,18 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p)
|
|||
seq_printf(s, " [ep%d]:\n",
|
||||
max_t(int, iudma_defaults[ch_idx].ep_num, 0));
|
||||
seq_printf(s, " cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n",
|
||||
usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)),
|
||||
usb_dmac_readl(udc, ENETDMAC_IR_REG(ch_idx)),
|
||||
usb_dmac_readl(udc, ENETDMAC_IRMASK_REG(ch_idx)),
|
||||
usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG(ch_idx)));
|
||||
usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx),
|
||||
usb_dmac_readl(udc, ENETDMAC_IR_REG, ch_idx),
|
||||
usb_dmac_readl(udc, ENETDMAC_IRMASK_REG, ch_idx),
|
||||
usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG, ch_idx));
|
||||
|
||||
sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG(ch_idx));
|
||||
sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG(ch_idx));
|
||||
sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG, ch_idx);
|
||||
sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG, ch_idx);
|
||||
seq_printf(s, " base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n",
|
||||
usb_dmas_readl(udc, ENETDMAS_RSTART_REG(ch_idx)),
|
||||
usb_dmas_readl(udc, ENETDMAS_RSTART_REG, ch_idx),
|
||||
sram2 >> 16, sram2 & 0xffff,
|
||||
sram3 >> 16, sram3 & 0xffff,
|
||||
usb_dmas_readl(udc, ENETDMAS_SRAM4_REG(ch_idx)));
|
||||
usb_dmas_readl(udc, ENETDMAS_SRAM4_REG, ch_idx));
|
||||
seq_printf(s, " desc: %d/%d used", iudma->n_bds_used,
|
||||
iudma->n_bds);
|
||||
|
||||
|
|
|
|||
|
|
@ -585,7 +585,6 @@ static ssize_t ffs_epfile_io(struct file *file,
|
|||
char __user *buf, size_t len, int read)
|
||||
{
|
||||
struct ffs_epfile *epfile = file->private_data;
|
||||
struct usb_gadget *gadget = epfile->ffs->gadget;
|
||||
struct ffs_ep *ep;
|
||||
char *data = NULL;
|
||||
ssize_t ret, data_len;
|
||||
|
|
@ -621,6 +620,12 @@ static ssize_t ffs_epfile_io(struct file *file,
|
|||
|
||||
/* Allocate & copy */
|
||||
if (!halt) {
|
||||
/*
|
||||
* if we _do_ wait above, the epfile->ffs->gadget might be NULL
|
||||
* before the waiting completes, so do not assign to 'gadget' earlier
|
||||
*/
|
||||
struct usb_gadget *gadget = epfile->ffs->gadget;
|
||||
|
||||
/*
|
||||
* Controller may require buffer size to be aligned to
|
||||
* maxpacketsize of an out endpoint.
|
||||
|
|
|
|||
|
|
@ -1157,7 +1157,7 @@ static int __init printer_bind_config(struct usb_configuration *c)
|
|||
|
||||
usb_gadget_set_selfpowered(gadget);
|
||||
|
||||
if (gadget->is_otg) {
|
||||
if (gadget_is_otg(gadget)) {
|
||||
otg_descriptor.bmAttributes |= USB_OTG_HNP;
|
||||
printer_cfg_driver.descriptors = otg_desc;
|
||||
printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
|
||||
|
|
|
|||
|
|
@ -1629,7 +1629,7 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev)
|
|||
ep->ep.desc = NULL;
|
||||
ep->halted = 0;
|
||||
INIT_LIST_HEAD(&ep->queue);
|
||||
usb_ep_set_maxpacket_limit(&ep->ep, &ep->ep.maxpacket);
|
||||
usb_ep_set_maxpacket_limit(&ep->ep, ep->ep.maxpacket);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -685,8 +685,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
||||
u32 status, masked_status, pcd_status = 0, cmd;
|
||||
int bh;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock (&ehci->lock);
|
||||
/*
|
||||
* For threadirqs option we use spin_lock_irqsave() variant to prevent
|
||||
* deadlock with ehci hrtimer callback, because hrtimer callbacks run
|
||||
* in interrupt context even when threadirqs is specified. We can go
|
||||
* back to spin_lock() variant when hrtimer callbacks become threaded.
|
||||
*/
|
||||
spin_lock_irqsave(&ehci->lock, flags);
|
||||
|
||||
status = ehci_readl(ehci, &ehci->regs->status);
|
||||
|
||||
|
|
@ -704,7 +711,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||
|
||||
/* Shared IRQ? */
|
||||
if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
|
||||
spin_unlock(&ehci->lock);
|
||||
spin_unlock_irqrestore(&ehci->lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -815,7 +822,7 @@ dead:
|
|||
|
||||
if (bh)
|
||||
ehci_work (ehci);
|
||||
spin_unlock (&ehci->lock);
|
||||
spin_unlock_irqrestore(&ehci->lock, flags);
|
||||
if (pcd_status)
|
||||
usb_hcd_poll_rh_status(hcd);
|
||||
return IRQ_HANDLED;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
int port;
|
||||
int mask;
|
||||
int changed;
|
||||
bool fs_idle_delay;
|
||||
|
||||
ehci_dbg(ehci, "suspend root hub\n");
|
||||
|
||||
|
|
@ -272,6 +273,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
ehci->bus_suspended = 0;
|
||||
ehci->owned_ports = 0;
|
||||
changed = 0;
|
||||
fs_idle_delay = false;
|
||||
port = HCS_N_PORTS(ehci->hcs_params);
|
||||
while (port--) {
|
||||
u32 __iomem *reg = &ehci->regs->port_status [port];
|
||||
|
|
@ -300,16 +302,32 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
}
|
||||
|
||||
if (t1 != t2) {
|
||||
/*
|
||||
* On some controllers, Wake-On-Disconnect will
|
||||
* generate false wakeup signals until the bus
|
||||
* switches over to full-speed idle. For their
|
||||
* sake, add a delay if we need one.
|
||||
*/
|
||||
if ((t2 & PORT_WKDISC_E) &&
|
||||
ehci_port_speed(ehci, t2) ==
|
||||
USB_PORT_STAT_HIGH_SPEED)
|
||||
fs_idle_delay = true;
|
||||
ehci_writel(ehci, t2, reg);
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
|
||||
if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) {
|
||||
/*
|
||||
* Wait for HCD to enter low-power mode or for the bus
|
||||
* to switch to full-speed idle.
|
||||
*/
|
||||
usleep_range(5000, 5500);
|
||||
}
|
||||
|
||||
if (changed && ehci->has_tdi_phy_lpm) {
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
msleep(5); /* 5 ms for HCD to enter low-power mode */
|
||||
spin_lock_irq(&ehci->lock);
|
||||
|
||||
port = HCS_N_PORTS(ehci->hcs_params);
|
||||
while (port--) {
|
||||
u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
|
||||
|
|
@ -322,8 +340,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
port, (t3 & HOSTPC_PHCD) ?
|
||||
"succeeded" : "failed");
|
||||
}
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
}
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
|
||||
/* Apparently some devices need a >= 1-uframe delay here */
|
||||
if (ehci->bus_suspended)
|
||||
|
|
|
|||
|
|
@ -4733,6 +4733,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
|||
/* Accept arbitrarily long scatter-gather lists */
|
||||
hcd->self.sg_tablesize = ~0;
|
||||
|
||||
/* support to build packet from discontinuous buffers */
|
||||
hcd->self.no_sg_constraint = 1;
|
||||
|
||||
/* XHCI controllers don't stop the ep queue on short packets :| */
|
||||
hcd->self.no_stop_on_short = 1;
|
||||
|
||||
|
|
@ -4757,14 +4760,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
|||
/* xHCI private pointer was set in xhci_pci_probe for the second
|
||||
* registered roothub.
|
||||
*/
|
||||
xhci = hcd_to_xhci(hcd);
|
||||
/*
|
||||
* Support arbitrarily aligned sg-list entries on hosts without
|
||||
* TD fragment rules (which are currently unsupported).
|
||||
*/
|
||||
if (xhci->hci_version < 0x100)
|
||||
hcd->self.no_sg_constraint = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4793,9 +4788,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
|||
if (xhci->hci_version > 0x96)
|
||||
xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
|
||||
|
||||
if (xhci->hci_version < 0x100)
|
||||
hcd->self.no_sg_constraint = 1;
|
||||
|
||||
/* Make sure the HC is halted. */
|
||||
retval = xhci_halt(xhci);
|
||||
if (retval)
|
||||
|
|
|
|||
|
|
@ -477,8 +477,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
|||
musb->port1_status |=
|
||||
(USB_PORT_STAT_C_SUSPEND << 16)
|
||||
| MUSB_PORT_STAT_RESUME;
|
||||
musb->rh_timer = jiffies
|
||||
+ msecs_to_jiffies(20);
|
||||
schedule_delayed_work(
|
||||
&musb->finish_resume_work, 20);
|
||||
&musb->finish_resume_work,
|
||||
msecs_to_jiffies(20));
|
||||
|
||||
musb->xceiv->state = OTG_STATE_A_HOST;
|
||||
musb->is_active = 1;
|
||||
|
|
@ -2157,11 +2160,19 @@ static void musb_restore_context(struct musb *musb)
|
|||
void __iomem *musb_base = musb->mregs;
|
||||
void __iomem *ep_target_regs;
|
||||
void __iomem *epio;
|
||||
u8 power;
|
||||
|
||||
musb_writew(musb_base, MUSB_FRAME, musb->context.frame);
|
||||
musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode);
|
||||
musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl);
|
||||
musb_writeb(musb_base, MUSB_POWER, musb->context.power);
|
||||
|
||||
/* Don't affect SUSPENDM/RESUME bits in POWER reg */
|
||||
power = musb_readb(musb_base, MUSB_POWER);
|
||||
power &= MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME;
|
||||
musb->context.power &= ~(MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME);
|
||||
power |= musb->context.power;
|
||||
musb_writeb(musb_base, MUSB_POWER, power);
|
||||
|
||||
musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
|
||||
musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
|
||||
musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
|
||||
|
|
|
|||
|
|
@ -1183,6 +1183,9 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
|
|||
csr = MUSB_CSR0_H_STATUSPKT
|
||||
| MUSB_CSR0_TXPKTRDY;
|
||||
|
||||
/* disable ping token in status phase */
|
||||
csr |= MUSB_CSR0_H_DIS_PING;
|
||||
|
||||
/* flag status stage */
|
||||
musb->ep0_stage = MUSB_EP0_STATUS;
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,8 @@ void musb_port_suspend(struct musb *musb, bool do_suspend)
|
|||
|
||||
/* later, GetPortStatus will stop RESUME signaling */
|
||||
musb->port1_status |= MUSB_PORT_STAT_RESUME;
|
||||
schedule_delayed_work(&musb->finish_resume_work, 20);
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(20));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +159,6 @@ void musb_port_reset(struct musb *musb, bool do_reset)
|
|||
*/
|
||||
power = musb_readb(mbase, MUSB_POWER);
|
||||
if (do_reset) {
|
||||
|
||||
/*
|
||||
* If RESUME is set, we must make sure it stays minimum 20 ms.
|
||||
* Then we must clear RESUME and wait a bit to let musb start
|
||||
|
|
@ -167,11 +167,22 @@ void musb_port_reset(struct musb *musb, bool do_reset)
|
|||
* detected".
|
||||
*/
|
||||
if (power & MUSB_POWER_RESUME) {
|
||||
while (time_before(jiffies, musb->rh_timer))
|
||||
msleep(1);
|
||||
long remain = (unsigned long) musb->rh_timer - jiffies;
|
||||
|
||||
if (musb->rh_timer > 0 && remain > 0) {
|
||||
/* take into account the minimum delay after resume */
|
||||
schedule_delayed_work(
|
||||
&musb->deassert_reset_work, remain);
|
||||
return;
|
||||
}
|
||||
|
||||
musb_writeb(mbase, MUSB_POWER,
|
||||
power & ~MUSB_POWER_RESUME);
|
||||
msleep(1);
|
||||
power & ~MUSB_POWER_RESUME);
|
||||
|
||||
/* Give the core 1 ms to clear MUSB_POWER_RESUME */
|
||||
schedule_delayed_work(&musb->deassert_reset_work,
|
||||
msecs_to_jiffies(1));
|
||||
return;
|
||||
}
|
||||
|
||||
power &= 0xf0;
|
||||
|
|
@ -180,7 +191,8 @@ void musb_port_reset(struct musb *musb, bool do_reset)
|
|||
|
||||
musb->port1_status |= USB_PORT_STAT_RESET;
|
||||
musb->port1_status &= ~USB_PORT_STAT_ENABLE;
|
||||
schedule_delayed_work(&musb->deassert_reset_work, 50);
|
||||
schedule_delayed_work(&musb->deassert_reset_work,
|
||||
msecs_to_jiffies(50));
|
||||
} else {
|
||||
dev_dbg(musb->controller, "root port reset stopped\n");
|
||||
musb_writeb(mbase, MUSB_POWER,
|
||||
|
|
|
|||
|
|
@ -659,7 +659,6 @@ static int omap2430_runtime_suspend(struct device *dev)
|
|||
OTG_INTERFSEL);
|
||||
|
||||
omap2430_low_level_exit(musb);
|
||||
phy_power_off(musb->phy);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -674,7 +673,6 @@ static int omap2430_runtime_resume(struct device *dev)
|
|||
omap2430_low_level_init(musb);
|
||||
musb_writel(musb->mregs, OTG_INTERFSEL,
|
||||
musb->context.otg_interfsel);
|
||||
phy_power_on(musb->phy);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -159,32 +159,6 @@ put_3p3:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#define USB_PHY_SUSP_DIG_VOL 500000
|
||||
static int msm_hsusb_config_vddcx(int high)
|
||||
{
|
||||
int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
|
||||
int min_vol;
|
||||
int ret;
|
||||
|
||||
if (high)
|
||||
min_vol = USB_PHY_VDD_DIG_VOL_MIN;
|
||||
else
|
||||
min_vol = USB_PHY_SUSP_DIG_VOL;
|
||||
|
||||
ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
|
||||
if (ret) {
|
||||
pr_err("%s: unable to set the voltage for regulator "
|
||||
"HSUSB_VDDCX\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int msm_hsusb_ldo_set_mode(int on)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -440,7 +414,32 @@ static int msm_otg_reset(struct usb_phy *phy)
|
|||
#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000)
|
||||
#define PHY_RESUME_TIMEOUT_USEC (100 * 1000)
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
#define USB_PHY_SUSP_DIG_VOL 500000
|
||||
static int msm_hsusb_config_vddcx(int high)
|
||||
{
|
||||
int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
|
||||
int min_vol;
|
||||
int ret;
|
||||
|
||||
if (high)
|
||||
min_vol = USB_PHY_VDD_DIG_VOL_MIN;
|
||||
else
|
||||
min_vol = USB_PHY_SUSP_DIG_VOL;
|
||||
|
||||
ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
|
||||
if (ret) {
|
||||
pr_err("%s: unable to set the voltage for regulator "
|
||||
"HSUSB_VDDCX\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_otg_suspend(struct msm_otg *motg)
|
||||
{
|
||||
struct usb_phy *phy = &motg->phy;
|
||||
|
|
@ -1733,22 +1732,18 @@ static int msm_otg_pm_resume(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static const struct dev_pm_ops msm_otg_dev_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume)
|
||||
SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume,
|
||||
msm_otg_runtime_idle)
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_driver msm_otg_driver = {
|
||||
.remove = msm_otg_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &msm_otg_dev_pm_ops,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -907,6 +907,8 @@ static const struct usb_device_id id_table_combined[] = {
|
|||
/* Crucible Devices */
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
|
||||
/* Cressi Devices */
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1320,3 +1320,9 @@
|
|||
* Manufacturer: Smart GSM Team
|
||||
*/
|
||||
#define FTDI_Z3X_PID 0x0011
|
||||
|
||||
/*
|
||||
* Product: Cressi PC Interface
|
||||
* Manufacturer: Cressi
|
||||
*/
|
||||
#define FTDI_CRESSI_PID 0x87d0
|
||||
|
|
|
|||
|
|
@ -1526,7 +1526,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
/* Cinterion */
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) },
|
||||
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
|
|
|
|||
Loading…
Reference in a new issue