drivers/spi/spi-pic32-sqi.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-pic32-sqi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-pic32-sqi.c- Extension
.c- Size
- 17849 bytes
- Lines
- 687
- Domain
- Driver Families
- Bucket
- drivers/spi
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/clk.hlinux/dma-mapping.hlinux/interrupt.hlinux/io.hlinux/iopoll.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/slab.hlinux/spi/spi.h
Detected Declarations
struct buf_descstruct ring_descstruct pic32_sqifunction pic32_setbitsfunction pic32_clrbitsfunction pic32_sqi_set_clk_ratefunction pic32_sqi_enable_intfunction pic32_sqi_disable_intfunction pic32_sqi_isrfunction ring_desc_putfunction pic32_sqi_one_transferfunction for_each_sgfunction pic32_sqi_prepare_hardwarefunction pic32_sqi_can_dmafunction pic32_sqi_one_messagefunction pic32_sqi_unprepare_hardwarefunction ring_desc_ring_allocfunction ring_desc_ring_freefunction pic32_sqi_hw_initfunction pic32_sqi_probefunction pic32_sqi_remove
Annotated Snippet
struct buf_desc {
u32 bd_ctrl; /* control */
u32 bd_status; /* reserved */
u32 bd_addr; /* DMA buffer addr */
u32 bd_nextp; /* next item in chain */
};
/* bd_ctrl */
#define BD_BUFLEN 0x1ff
#define BD_CBD_INT_EN BIT(16) /* Current BD is processed */
#define BD_PKT_INT_EN BIT(17) /* All BDs of PKT processed */
#define BD_LIFM BIT(18) /* last data of pkt */
#define BD_LAST BIT(19) /* end of list */
#define BD_DATA_RECV BIT(20) /* receive data */
#define BD_DDR BIT(21) /* DDR mode */
#define BD_DUAL BIT(22) /* Dual SPI */
#define BD_QUAD BIT(23) /* Quad SPI */
#define BD_LSBF BIT(25) /* LSB First */
#define BD_STAT_CHECK BIT(27) /* Status poll */
#define BD_DEVSEL_SHIFT 28 /* CS */
#define BD_CS_DEASSERT BIT(30) /* de-assert CS after current BD */
#define BD_EN BIT(31) /* BD owned by H/W */
/**
* struct ring_desc - Representation of SQI ring descriptor
* @list: list element to add to free or used list.
* @bd: PESQI controller buffer descriptor
* @bd_dma: DMA address of PESQI controller buffer descriptor
* @xfer_len: transfer length
*/
struct ring_desc {
struct list_head list;
struct buf_desc *bd;
dma_addr_t bd_dma;
u32 xfer_len;
};
/* Global constants */
#define PESQI_BD_BUF_LEN_MAX 256
#define PESQI_BD_COUNT 256 /* max 64KB data per spi message */
struct pic32_sqi {
void __iomem *regs;
struct clk *sys_clk;
struct clk *base_clk; /* drives spi clock */
struct spi_controller *host;
int irq;
struct completion xfer_done;
struct ring_desc *ring;
void *bd;
dma_addr_t bd_dma;
struct list_head bd_list_free; /* free */
struct list_head bd_list_used; /* allocated */
struct spi_device *cur_spi;
u32 cur_speed;
u8 cur_mode;
};
static inline void pic32_setbits(void __iomem *reg, u32 set)
{
writel(readl(reg) | set, reg);
}
static inline void pic32_clrbits(void __iomem *reg, u32 clr)
{
writel(readl(reg) & ~clr, reg);
}
static int pic32_sqi_set_clk_rate(struct pic32_sqi *sqi, u32 sck)
{
u32 val, div;
/* div = base_clk / (2 * spi_clk) */
div = clk_get_rate(sqi->base_clk) / (2 * sck);
div &= PESQI_CLKDIV;
val = readl(sqi->regs + PESQI_CLK_CTRL_REG);
/* apply new divider */
val &= ~(PESQI_CLK_STABLE | (PESQI_CLKDIV << PESQI_CLKDIV_SHIFT));
val |= div << PESQI_CLKDIV_SHIFT;
writel(val, sqi->regs + PESQI_CLK_CTRL_REG);
/* wait for stability */
return readl_poll_timeout(sqi->regs + PESQI_CLK_CTRL_REG, val,
val & PESQI_CLK_STABLE, 1, 5000);
}
static inline void pic32_sqi_enable_int(struct pic32_sqi *sqi)
{
u32 mask = PESQI_DMAERR | PESQI_BDDONE | PESQI_PKTCOMP;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/dma-mapping.h`, `linux/interrupt.h`, `linux/io.h`, `linux/iopoll.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`.
- Detected declarations: `struct buf_desc`, `struct ring_desc`, `struct pic32_sqi`, `function pic32_setbits`, `function pic32_clrbits`, `function pic32_sqi_set_clk_rate`, `function pic32_sqi_enable_int`, `function pic32_sqi_disable_int`, `function pic32_sqi_isr`, `function ring_desc_put`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.