drivers/spi/spi-hisi-kunpeng.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-hisi-kunpeng.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-hisi-kunpeng.c- Extension
.c- Size
- 14408 bytes
- Lines
- 566
- 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/acpi.hlinux/bitfield.hlinux/debugfs.hlinux/delay.hlinux/err.hlinux/interrupt.hlinux/module.hlinux/property.hlinux/platform_device.hlinux/slab.hlinux/spi/spi.h
Detected Declarations
struct hisi_chip_datastruct hisi_spienum hisi_spi_rx_level_trigenum hisi_spi_tx_level_trigenum hisi_spi_frame_n_bytesfunction hisi_spi_debugfs_initfunction hisi_spi_busyfunction hisi_spi_rx_not_emptyfunction hisi_spi_tx_not_fullfunction hisi_spi_flush_fifofunction hisi_spi_disablefunction hisi_spi_n_bytesfunction hisi_spi_readerfunction hisi_spi_writerfunction __hisi_calc_div_regfunction hisi_calc_effective_speedfunction hisi_spi_prepare_crfunction hisi_spi_hw_initfunction hisi_spi_irqfunction hisi_spi_transfer_onefunction hisi_spi_handle_errfunction hisi_spi_setupfunction hisi_spi_cleanupfunction hisi_spi_probefunction hisi_spi_remove
Annotated Snippet
struct hisi_chip_data {
u32 cr;
u32 speed_hz; /* baud rate */
u16 clk_div; /* baud rate divider */
/* clk_div = (1 + div_post) * div_pre */
u8 div_post; /* value from 0 to 255 */
u8 div_pre; /* value from 2 to 254 (even only!) */
};
struct hisi_spi {
struct device *dev;
void __iomem *regs;
int irq;
u32 fifo_len; /* depth of the FIFO buffer */
/* Current message transfer state info */
const void *tx;
unsigned int tx_len;
void *rx;
unsigned int rx_len;
u8 n_bytes; /* current is a 1/2/4 bytes op */
struct dentry *debugfs;
struct debugfs_regset32 regset;
};
#define HISI_SPI_DBGFS_REG(_name, _off) \
{ \
.name = _name, \
.offset = _off, \
}
static const struct debugfs_reg32 hisi_spi_regs[] = {
HISI_SPI_DBGFS_REG("CSCR", HISI_SPI_CSCR),
HISI_SPI_DBGFS_REG("CR", HISI_SPI_CR),
HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR),
HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC),
HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR),
HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR),
HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR),
HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR),
HISI_SPI_DBGFS_REG("ICR", HISI_SPI_ICR),
HISI_SPI_DBGFS_REG("VERSION", HISI_SPI_VERSION),
};
static int hisi_spi_debugfs_init(struct hisi_spi *hs)
{
char name[32];
struct spi_controller *host = dev_get_drvdata(hs->dev);
snprintf(name, 32, "hisi_spi%d", host->bus_num);
hs->debugfs = debugfs_create_dir(name, NULL);
if (IS_ERR(hs->debugfs))
return -ENOMEM;
hs->regset.regs = hisi_spi_regs;
hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs);
hs->regset.base = hs->regs;
debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset);
return 0;
}
static u32 hisi_spi_busy(struct hisi_spi *hs)
{
return readl(hs->regs + HISI_SPI_SR) & SR_BUSY;
}
static u32 hisi_spi_rx_not_empty(struct hisi_spi *hs)
{
return readl(hs->regs + HISI_SPI_SR) & SR_RXNE;
}
static u32 hisi_spi_tx_not_full(struct hisi_spi *hs)
{
return readl(hs->regs + HISI_SPI_SR) & SR_TXNF;
}
static void hisi_spi_flush_fifo(struct hisi_spi *hs)
{
unsigned long limit = loops_per_jiffy << 1;
do {
unsigned long inner_limit = loops_per_jiffy;
while (hisi_spi_rx_not_empty(hs) && --inner_limit) {
readl(hs->regs + HISI_SPI_DOUT);
cpu_relax();
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/bitfield.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/err.h`, `linux/interrupt.h`, `linux/module.h`, `linux/property.h`.
- Detected declarations: `struct hisi_chip_data`, `struct hisi_spi`, `enum hisi_spi_rx_level_trig`, `enum hisi_spi_tx_level_trig`, `enum hisi_spi_frame_n_bytes`, `function hisi_spi_debugfs_init`, `function hisi_spi_busy`, `function hisi_spi_rx_not_empty`, `function hisi_spi_tx_not_full`, `function hisi_spi_flush_fifo`.
- 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.