mirror of
https://github.com/torvalds/linux
synced 2024-10-08 04:12:40 +00:00
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. Signed-off-by: Min Guo <min.guo@mediatek.com> Signed-off-by: Bin Liu <b-liu@ti.com> Link: https://lore.kernel.org/r/20200115132547.364-21-b-liu@ti.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8d817d7934
commit
fe3bbd6b38
|
@ -275,6 +275,38 @@ static void musb_default_writew(void __iomem *addr, unsigned offset, u16 data)
|
||||||
__raw_writew(data, addr + offset);
|
__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
|
* Load an endpoint's FIFO
|
||||||
*/
|
*/
|
||||||
|
@ -2381,6 +2413,16 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||||
else
|
else
|
||||||
musb->io.write_fifo = musb_default_write_fifo;
|
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) {
|
if (!musb->xceiv->io_ops) {
|
||||||
musb->xceiv->io_dev = musb->controller;
|
musb->xceiv->io_dev = musb->controller;
|
||||||
musb->xceiv->io_priv = musb->mregs;
|
musb->xceiv->io_priv = musb->mregs;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
struct musb;
|
struct musb;
|
||||||
struct musb_hw_ep;
|
struct musb_hw_ep;
|
||||||
struct musb_ep;
|
struct musb_ep;
|
||||||
|
struct musb_qh;
|
||||||
|
|
||||||
/* Helper defines for struct musb->hwvers */
|
/* Helper defines for struct musb->hwvers */
|
||||||
#define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f)
|
#define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f)
|
||||||
|
@ -123,6 +124,8 @@ struct musb_io;
|
||||||
* @writew: write 16 bits
|
* @writew: write 16 bits
|
||||||
* @read_fifo: reads the fifo
|
* @read_fifo: reads the fifo
|
||||||
* @write_fifo: writes to 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_init: platform specific dma init function
|
||||||
* @dma_exit: platform specific dma exit function
|
* @dma_exit: platform specific dma exit function
|
||||||
* @init: turns on clocks, sets up platform-specific registers, etc
|
* @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 (*writew)(void __iomem *addr, unsigned offset, u16 data);
|
||||||
void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
|
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);
|
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 *
|
struct dma_controller *
|
||||||
(*dma_init) (struct musb *musb, void __iomem *base);
|
(*dma_init) (struct musb *musb, void __iomem *base);
|
||||||
void (*dma_exit)(struct dma_controller *c);
|
void (*dma_exit)(struct dma_controller *c);
|
||||||
|
|
|
@ -286,26 +286,6 @@ __acquires(musb->lock)
|
||||||
spin_lock(&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
|
* Advance this hardware endpoint's queue, completing the specified URB and
|
||||||
* advancing to either the next URB queued to that qh, or else invalidating
|
* 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;
|
struct musb_hw_ep *ep = qh->hw_ep;
|
||||||
int ready = qh->is_ready;
|
int ready = qh->is_ready;
|
||||||
int status;
|
int status;
|
||||||
|
u16 toggle;
|
||||||
|
|
||||||
status = (urb->status == -EINPROGRESS) ? 0 : urb->status;
|
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) {
|
switch (qh->type) {
|
||||||
case USB_ENDPOINT_XFER_BULK:
|
case USB_ENDPOINT_XFER_BULK:
|
||||||
case USB_ENDPOINT_XFER_INT:
|
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;
|
break;
|
||||||
case USB_ENDPOINT_XFER_ISOC:
|
case USB_ENDPOINT_XFER_ISOC:
|
||||||
if (status == 0 && urb->error_count)
|
if (status == 0 && urb->error_count)
|
||||||
|
@ -772,13 +754,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
|
||||||
);
|
);
|
||||||
csr |= MUSB_TXCSR_MODE;
|
csr |= MUSB_TXCSR_MODE;
|
||||||
|
|
||||||
if (!hw_ep->tx_double_buffered) {
|
if (!hw_ep->tx_double_buffered)
|
||||||
if (usb_gettoggle(urb->dev, qh->epnum, 1))
|
csr |= musb->io.set_toggle(qh, is_out, urb);
|
||||||
csr |= MUSB_TXCSR_H_WR_DATATOGGLE
|
|
||||||
| MUSB_TXCSR_H_DATATOGGLE;
|
|
||||||
else
|
|
||||||
csr |= MUSB_TXCSR_CLRDATATOG;
|
|
||||||
}
|
|
||||||
|
|
||||||
musb_writew(epio, MUSB_TXCSR, csr);
|
musb_writew(epio, MUSB_TXCSR, csr);
|
||||||
/* REVISIT may need to clear FLUSHFIFO ... */
|
/* REVISIT may need to clear FLUSHFIFO ... */
|
||||||
|
@ -860,17 +837,12 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
|
||||||
|
|
||||||
/* IN/receive */
|
/* IN/receive */
|
||||||
} else {
|
} else {
|
||||||
u16 csr;
|
u16 csr = 0;
|
||||||
|
|
||||||
if (hw_ep->rx_reinit) {
|
if (hw_ep->rx_reinit) {
|
||||||
musb_rx_reinit(musb, qh, epnum);
|
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)
|
if (qh->type == USB_ENDPOINT_XFER_INT)
|
||||||
csr |= MUSB_RXCSR_DISNYET;
|
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;
|
void __iomem *epio = ep->regs;
|
||||||
struct musb_qh *cur_qh, *next_qh;
|
struct musb_qh *cur_qh, *next_qh;
|
||||||
u16 rx_csr, tx_csr;
|
u16 rx_csr, tx_csr;
|
||||||
|
u16 toggle;
|
||||||
|
|
||||||
musb_ep_select(mbase, ep->epnum);
|
musb_ep_select(mbase, ep->epnum);
|
||||||
if (is_in) {
|
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;
|
urb->actual_length += dma->actual_len;
|
||||||
dma->actual_len = 0L;
|
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) {
|
if (is_in) {
|
||||||
/* move cur_qh to end of queue */
|
/* move cur_qh to end of queue */
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
* @read_fifo: platform specific function to read fifo
|
* @read_fifo: platform specific function to read fifo
|
||||||
* @write_fifo: platform specific function to write fifo
|
* @write_fifo: platform specific function to write fifo
|
||||||
* @busctl_offset: platform specific function to get busctl offset
|
* @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 {
|
struct musb_io {
|
||||||
u32 (*ep_offset)(u8 epnum, u16 offset);
|
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 (*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);
|
void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
|
||||||
u32 (*busctl_offset)(u8 epnum, u16 offset);
|
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 */
|
/* Do not add new entries here, add them the struct musb_io instead */
|
||||||
|
|
Loading…
Reference in a new issue