Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0fd7a820 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'fixes-for-v3.14-rc4' of...

Merge tag 'fixes-for-v3.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb

 into usb-linus

Felipe writes:

usb: fixes for v3.14-rc4

Here are 10 fixes for our current -rc cycle. It's likely
the last round of fixes for this merge window. All patches
have soaked for a long time and have all been tested in real
HW.

The most interesting fixes are a fix for enumeration of superspeed
hubs when MUSB is acting as host, and a remote-wakeup fix also on
MUSB.

Signed-of-by: default avatarFelipe Balbi <balbi@ti.com>
parents 64fe1891 9ccfaf74
Loading
Loading
Loading
Loading
+32 −26
Original line number Diff line number Diff line
@@ -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);

+6 −1
Original line number Diff line number Diff line
@@ -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.
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);
	}
}

+9 −1
Original line number Diff line number Diff line
@@ -2160,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);
Loading