Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Min Guo and committed by
Greg Kroah-Hartman
fe3bbd6b 8d817d79

+61 -36
+42
drivers/usb/musb/musb_core.c
··· 275 275 __raw_writew(data, addr + offset); 276 276 } 277 277 278 + static u16 musb_default_get_toggle(struct musb_qh *qh, int is_out) 279 + { 280 + void __iomem *epio = qh->hw_ep->regs; 281 + u16 csr; 282 + 283 + if (is_out) 284 + csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE; 285 + else 286 + csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE; 287 + 288 + return csr; 289 + } 290 + 291 + static u16 musb_default_set_toggle(struct musb_qh *qh, int is_out, 292 + struct urb *urb) 293 + { 294 + u16 csr; 295 + u16 toggle; 296 + 297 + toggle = usb_gettoggle(urb->dev, qh->epnum, is_out); 298 + 299 + if (is_out) 300 + csr = toggle ? (MUSB_TXCSR_H_WR_DATATOGGLE 301 + | MUSB_TXCSR_H_DATATOGGLE) 302 + : MUSB_TXCSR_CLRDATATOG; 303 + else 304 + csr = toggle ? (MUSB_RXCSR_H_WR_DATATOGGLE 305 + | MUSB_RXCSR_H_DATATOGGLE) : 0; 306 + 307 + return csr; 308 + } 309 + 278 310 /* 279 311 * Load an endpoint's FIFO 280 312 */ ··· 2412 2380 musb->io.write_fifo = musb->ops->write_fifo; 2413 2381 else 2414 2382 musb->io.write_fifo = musb_default_write_fifo; 2383 + 2384 + if (musb->ops->get_toggle) 2385 + musb->io.get_toggle = musb->ops->get_toggle; 2386 + else 2387 + musb->io.get_toggle = musb_default_get_toggle; 2388 + 2389 + if (musb->ops->set_toggle) 2390 + musb->io.set_toggle = musb->ops->set_toggle; 2391 + else 2392 + musb->io.set_toggle = musb_default_set_toggle; 2415 2393 2416 2394 if (!musb->xceiv->io_ops) { 2417 2395 musb->xceiv->io_dev = musb->controller;
+5
drivers/usb/musb/musb_core.h
··· 27 27 struct musb; 28 28 struct musb_hw_ep; 29 29 struct musb_ep; 30 + struct musb_qh; 30 31 31 32 /* Helper defines for struct musb->hwvers */ 32 33 #define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f) ··· 124 123 * @writew: write 16 bits 125 124 * @read_fifo: reads the fifo 126 125 * @write_fifo: writes to fifo 126 + * @get_toggle: platform specific get toggle function 127 + * @set_toggle: platform specific set toggle function 127 128 * @dma_init: platform specific dma init function 128 129 * @dma_exit: platform specific dma exit function 129 130 * @init: turns on clocks, sets up platform-specific registers, etc ··· 170 167 void (*writew)(void __iomem *addr, unsigned offset, u16 data); 171 168 void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); 172 169 void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); 170 + u16 (*get_toggle)(struct musb_qh *qh, int is_out); 171 + u16 (*set_toggle)(struct musb_qh *qh, int is_out, struct urb *urb); 173 172 struct dma_controller * 174 173 (*dma_init) (struct musb *musb, void __iomem *base); 175 174 void (*dma_exit)(struct dma_controller *c);
+10 -36
drivers/usb/musb/musb_host.c
··· 286 286 spin_lock(&musb->lock); 287 287 } 288 288 289 - /* For bulk/interrupt endpoints only */ 290 - static inline void musb_save_toggle(struct musb_qh *qh, int is_in, 291 - struct urb *urb) 292 - { 293 - void __iomem *epio = qh->hw_ep->regs; 294 - u16 csr; 295 - 296 - /* 297 - * FIXME: the current Mentor DMA code seems to have 298 - * problems getting toggle correct. 299 - */ 300 - 301 - if (is_in) 302 - csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE; 303 - else 304 - csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE; 305 - 306 - usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0); 307 - } 308 - 309 289 /* 310 290 * Advance this hardware endpoint's queue, completing the specified URB and 311 291 * advancing to either the next URB queued to that qh, or else invalidating ··· 300 320 struct musb_hw_ep *ep = qh->hw_ep; 301 321 int ready = qh->is_ready; 302 322 int status; 323 + u16 toggle; 303 324 304 325 status = (urb->status == -EINPROGRESS) ? 0 : urb->status; 305 326 ··· 308 327 switch (qh->type) { 309 328 case USB_ENDPOINT_XFER_BULK: 310 329 case USB_ENDPOINT_XFER_INT: 311 - musb_save_toggle(qh, is_in, urb); 330 + toggle = musb->io.get_toggle(qh, !is_in); 331 + usb_settoggle(urb->dev, qh->epnum, !is_in, toggle ? 1 : 0); 312 332 break; 313 333 case USB_ENDPOINT_XFER_ISOC: 314 334 if (status == 0 && urb->error_count) ··· 754 772 ); 755 773 csr |= MUSB_TXCSR_MODE; 756 774 757 - if (!hw_ep->tx_double_buffered) { 758 - if (usb_gettoggle(urb->dev, qh->epnum, 1)) 759 - csr |= MUSB_TXCSR_H_WR_DATATOGGLE 760 - | MUSB_TXCSR_H_DATATOGGLE; 761 - else 762 - csr |= MUSB_TXCSR_CLRDATATOG; 763 - } 775 + if (!hw_ep->tx_double_buffered) 776 + csr |= musb->io.set_toggle(qh, is_out, urb); 764 777 765 778 musb_writew(epio, MUSB_TXCSR, csr); 766 779 /* REVISIT may need to clear FLUSHFIFO ... */ ··· 837 860 838 861 /* IN/receive */ 839 862 } else { 840 - u16 csr; 863 + u16 csr = 0; 841 864 842 865 if (hw_ep->rx_reinit) { 843 866 musb_rx_reinit(musb, qh, epnum); 867 + csr |= musb->io.set_toggle(qh, is_out, urb); 844 868 845 - /* init new state: toggle and NYET, maybe DMA later */ 846 - if (usb_gettoggle(urb->dev, qh->epnum, 0)) 847 - csr = MUSB_RXCSR_H_WR_DATATOGGLE 848 - | MUSB_RXCSR_H_DATATOGGLE; 849 - else 850 - csr = 0; 851 869 if (qh->type == USB_ENDPOINT_XFER_INT) 852 870 csr |= MUSB_RXCSR_DISNYET; 853 871 ··· 905 933 void __iomem *epio = ep->regs; 906 934 struct musb_qh *cur_qh, *next_qh; 907 935 u16 rx_csr, tx_csr; 936 + u16 toggle; 908 937 909 938 musb_ep_select(mbase, ep->epnum); 910 939 if (is_in) { ··· 943 970 urb->actual_length += dma->actual_len; 944 971 dma->actual_len = 0L; 945 972 } 946 - musb_save_toggle(cur_qh, is_in, urb); 973 + toggle = musb->io.get_toggle(cur_qh, !is_in); 974 + usb_settoggle(urb->dev, cur_qh->epnum, !is_in, toggle ? 1 : 0); 947 975 948 976 if (is_in) { 949 977 /* move cur_qh to end of queue */
+4
drivers/usb/musb/musb_io.h
··· 22 22 * @read_fifo: platform specific function to read fifo 23 23 * @write_fifo: platform specific function to write fifo 24 24 * @busctl_offset: platform specific function to get busctl offset 25 + * @get_toggle: platform specific function to get toggle 26 + * @set_toggle: platform specific function to set toggle 25 27 */ 26 28 struct musb_io { 27 29 u32 (*ep_offset)(u8 epnum, u16 offset); ··· 32 30 void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); 33 31 void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); 34 32 u32 (*busctl_offset)(u8 epnum, u16 offset); 33 + u16 (*get_toggle)(struct musb_qh *qh, int is_out); 34 + u16 (*set_toggle)(struct musb_qh *qh, int is_out, struct urb *urb); 35 35 }; 36 36 37 37 /* Do not add new entries here, add them the struct musb_io instead */