drivers/usb/musb/musb_cppi41.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/musb_cppi41.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/musb_cppi41.c- Extension
.c- Size
- 21853 bytes
- Lines
- 812
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/dma-mapping.hlinux/dmaengine.hlinux/sizes.hlinux/platform_device.hlinux/of.hcppi_dma.hmusb_core.hmusb_trace.h
Detected Declarations
struct cppi41_dma_controllerfunction save_rx_togglefunction update_rx_togglefunction musb_is_tx_fifo_emptyfunction cppi41_trans_donefunction cppi41_recheck_tx_reqfunction cppi41_dma_callbackfunction HSfunction update_ep_modefunction cppi41_set_dma_modefunction da8xx_set_dma_modefunction cppi41_set_autoreq_modefunction cppi41_configure_channelfunction cppi41_dma_channel_releasefunction cppi41_dma_channel_programfunction cppi41_is_compatiblefunction cppi41_dma_channel_abortfunction cppi41_release_all_dma_chansfunction cppi41_dma_controller_stopfunction cppi41_dma_controller_startfunction cppi41_dma_controller_destroyfunction cppi41_dma_controller_createexport cppi41_dma_controller_destroyexport cppi41_dma_controller_create
Annotated Snippet
struct cppi41_dma_controller {
struct dma_controller controller;
struct cppi41_dma_channel *rx_channel;
struct cppi41_dma_channel *tx_channel;
struct hrtimer early_tx;
struct list_head early_tx_list;
u32 rx_mode;
u32 tx_mode;
u32 auto_req;
u32 tdown_reg;
u32 autoreq_reg;
void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel,
unsigned int mode);
u8 num_channels;
};
static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
{
u16 csr;
u8 toggle;
if (cppi41_channel->is_tx)
return;
if (!is_host_active(cppi41_channel->controller->controller.musb))
return;
csr = musb_readw(cppi41_channel->hw_ep->regs, MUSB_RXCSR);
toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0;
cppi41_channel->usb_toggle = toggle;
}
static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
{
struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
struct musb *musb = hw_ep->musb;
u16 csr;
u8 toggle;
if (cppi41_channel->is_tx)
return;
if (!is_host_active(musb))
return;
musb_ep_select(musb->mregs, hw_ep->epnum);
csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0;
/*
* AM335x Advisory 1.0.13: Due to internal synchronisation error the
* data toggle may reset from DATA1 to DATA0 during receiving data from
* more than one endpoint.
*/
if (!toggle && toggle == cppi41_channel->usb_toggle) {
csr |= MUSB_RXCSR_H_DATATOGGLE | MUSB_RXCSR_H_WR_DATATOGGLE;
musb_writew(cppi41_channel->hw_ep->regs, MUSB_RXCSR, csr);
musb_dbg(musb, "Restoring DATA1 toggle.");
}
cppi41_channel->usb_toggle = toggle;
}
static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
{
u8 epnum = hw_ep->epnum;
struct musb *musb = hw_ep->musb;
void __iomem *epio = musb->endpoints[epnum].regs;
u16 csr;
musb_ep_select(musb->mregs, hw_ep->epnum);
csr = musb_readw(epio, MUSB_TXCSR);
if (csr & MUSB_TXCSR_TXPKTRDY)
return false;
return true;
}
static void cppi41_dma_callback(void *private_data,
const struct dmaengine_result *result);
static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
{
struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
struct musb *musb = hw_ep->musb;
void __iomem *epio = hw_ep->regs;
u16 csr;
if (!cppi41_channel->prog_len ||
(cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) {
Annotation
- Immediate include surface: `linux/device.h`, `linux/dma-mapping.h`, `linux/dmaengine.h`, `linux/sizes.h`, `linux/platform_device.h`, `linux/of.h`, `cppi_dma.h`, `musb_core.h`.
- Detected declarations: `struct cppi41_dma_controller`, `function save_rx_toggle`, `function update_rx_toggle`, `function musb_is_tx_fifo_empty`, `function cppi41_trans_done`, `function cppi41_recheck_tx_req`, `function cppi41_dma_callback`, `function HS`, `function update_ep_mode`, `function cppi41_set_dma_mode`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.