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

Commit 60f8509f authored by Min Guo's avatar Min Guo Committed by Macpaul Lin
Browse files

UPSTREAM: usb: musb: Add get/set toggle hooks



Add get/set toggle hooks in struct musb_io and struct musb_platform_ops
for special platform; remove function musb_save_toggle, use the set/get
callback to handle toggle.

Bug: 158724613
Signed-off-by: default avatarMin Guo <min.guo@mediatek.com>
Signed-off-by: default avatarBin Liu <b-liu@ti.com>
Link: https://lore.kernel.org/r/20200115132547.364-21-b-liu@ti.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarMacpaul Lin <macpaul.lin@mediatek.com>
(cherry picked from commit fe3bbd6b383fbc62128fd1fe850105080cb4c9da)
Change-Id: Ib7ee071a4ce879ed70d546f88321117b645d52bb
parent 45ca0dad
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -274,6 +274,38 @@ static void musb_default_writew(void __iomem *addr, unsigned offset, u16 data)
	__raw_writew(data, addr + offset);
}

static u16 musb_default_get_toggle(struct musb_qh *qh, int is_out)
{
	void __iomem *epio = qh->hw_ep->regs;
	u16 csr;

	if (is_out)
		csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;
	else
		csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;

	return csr;
}

static u16 musb_default_set_toggle(struct musb_qh *qh, int is_out,
				   struct urb *urb)
{
	u16 csr;
	u16 toggle;

	toggle = usb_gettoggle(urb->dev, qh->epnum, is_out);

	if (is_out)
		csr = toggle ? (MUSB_TXCSR_H_WR_DATATOGGLE
				| MUSB_TXCSR_H_DATATOGGLE)
				: MUSB_TXCSR_CLRDATATOG;
	else
		csr = toggle ? (MUSB_RXCSR_H_WR_DATATOGGLE
				| MUSB_RXCSR_H_DATATOGGLE) : 0;

	return csr;
}

/*
 * Load an endpoint's FIFO
 */
@@ -2285,6 +2317,16 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
	else
		musb->io.write_fifo = musb_default_write_fifo;

	if (musb->ops->get_toggle)
		musb->io.get_toggle = musb->ops->get_toggle;
	else
		musb->io.get_toggle = musb_default_get_toggle;

	if (musb->ops->set_toggle)
		musb->io.set_toggle = musb->ops->set_toggle;
	else
		musb->io.set_toggle = musb_default_set_toggle;

	if (!musb->xceiv->io_ops) {
		musb->xceiv->io_dev = musb->controller;
		musb->xceiv->io_priv = musb->mregs;
+5 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
struct musb;
struct musb_hw_ep;
struct musb_ep;
struct musb_qh;

/* Helper defines for struct musb->hwvers */
#define MUSB_HWVERS_MAJOR(x)	((x >> 10) & 0x1f)
@@ -123,6 +124,8 @@ struct musb_io;
 * @writew:	write 16 bits
 * @read_fifo:	reads the fifo
 * @write_fifo:	writes to fifo
 * @get_toggle:	platform specific get toggle function
 * @set_toggle:	platform specific set toggle function
 * @dma_init:	platform specific dma init function
 * @dma_exit:	platform specific dma exit function
 * @init:	turns on clocks, sets up platform-specific registers, etc
@@ -167,6 +170,8 @@ struct musb_platform_ops {
	void	(*writew)(void __iomem *addr, unsigned offset, u16 data);
	void	(*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
	void	(*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
	u16	(*get_toggle)(struct musb_qh *qh, int is_out);
	u16	(*set_toggle)(struct musb_qh *qh, int is_out, struct urb *urb);
	struct dma_controller *
		(*dma_init) (struct musb *musb, void __iomem *base);
	void	(*dma_exit)(struct dma_controller *c);
+10 −36
Original line number Diff line number Diff line
@@ -286,26 +286,6 @@ __acquires(musb->lock)
	spin_lock(&musb->lock);
}

/* For bulk/interrupt endpoints only */
static inline void musb_save_toggle(struct musb_qh *qh, int is_in,
				    struct urb *urb)
{
	void __iomem		*epio = qh->hw_ep->regs;
	u16			csr;

	/*
	 * FIXME: the current Mentor DMA code seems to have
	 * problems getting toggle correct.
	 */

	if (is_in)
		csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;
	else
		csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;

	usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0);
}

/*
 * Advance this hardware endpoint's queue, completing the specified URB and
 * advancing to either the next URB queued to that qh, or else invalidating
@@ -320,6 +300,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
	struct musb_hw_ep	*ep = qh->hw_ep;
	int			ready = qh->is_ready;
	int			status;
	u16			toggle;

	status = (urb->status == -EINPROGRESS) ? 0 : urb->status;

@@ -327,7 +308,8 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
	switch (qh->type) {
	case USB_ENDPOINT_XFER_BULK:
	case USB_ENDPOINT_XFER_INT:
		musb_save_toggle(qh, is_in, urb);
		toggle = musb->io.get_toggle(qh, !is_in);
		usb_settoggle(urb->dev, qh->epnum, !is_in, toggle ? 1 : 0);
		break;
	case USB_ENDPOINT_XFER_ISOC:
		if (status == 0 && urb->error_count)
@@ -772,13 +754,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
					);
			csr |= MUSB_TXCSR_MODE;

			if (!hw_ep->tx_double_buffered) {
				if (usb_gettoggle(urb->dev, qh->epnum, 1))
					csr |= MUSB_TXCSR_H_WR_DATATOGGLE
						| MUSB_TXCSR_H_DATATOGGLE;
				else
					csr |= MUSB_TXCSR_CLRDATATOG;
			}
			if (!hw_ep->tx_double_buffered)
				csr |= musb->io.set_toggle(qh, is_out, urb);

			musb_writew(epio, MUSB_TXCSR, csr);
			/* REVISIT may need to clear FLUSHFIFO ... */
@@ -860,17 +837,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum,

	/* IN/receive */
	} else {
		u16	csr;
		u16 csr = 0;

		if (hw_ep->rx_reinit) {
			musb_rx_reinit(musb, qh, epnum);
			csr |= musb->io.set_toggle(qh, is_out, urb);

			/* init new state: toggle and NYET, maybe DMA later */
			if (usb_gettoggle(urb->dev, qh->epnum, 0))
				csr = MUSB_RXCSR_H_WR_DATATOGGLE
					| MUSB_RXCSR_H_DATATOGGLE;
			else
				csr = 0;
			if (qh->type == USB_ENDPOINT_XFER_INT)
				csr |= MUSB_RXCSR_DISNYET;

@@ -933,6 +905,7 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep,
	void __iomem		*epio = ep->regs;
	struct musb_qh		*cur_qh, *next_qh;
	u16			rx_csr, tx_csr;
	u16			toggle;

	musb_ep_select(mbase, ep->epnum);
	if (is_in) {
@@ -970,7 +943,8 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep,
			urb->actual_length += dma->actual_len;
			dma->actual_len = 0L;
		}
		musb_save_toggle(cur_qh, is_in, urb);
		toggle = musb->io.get_toggle(cur_qh, !is_in);
		usb_settoggle(urb->dev, cur_qh->epnum, !is_in, toggle ? 1 : 0);

		if (is_in) {
			/* move cur_qh to end of queue */
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
 * @read_fifo:	platform specific function to read fifo
 * @write_fifo:	platform specific function to write fifo
 * @busctl_offset: platform specific function to get busctl offset
 * @get_toggle: platform specific function to get toggle
 * @set_toggle: platform specific function to set toggle
 */
struct musb_io {
	u32	(*ep_offset)(u8 epnum, u16 offset);
@@ -30,6 +32,8 @@ struct musb_io {
	void	(*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
	void	(*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
	u32	(*busctl_offset)(u8 epnum, u16 offset);
	u16	(*get_toggle)(struct musb_qh *qh, int is_out);
	u16	(*set_toggle)(struct musb_qh *qh, int is_out, struct urb *urb);
};

/* Do not add new entries here, add them the struct musb_io instead */