drivers/spi/spi-aspeed-smc.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-aspeed-smc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-aspeed-smc.c- Extension
.c- Size
- 45869 bytes
- Lines
- 1734
- 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.
- 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/io.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/spi/spi.hlinux/spi/spi-mem.h
Detected Declarations
struct aspeed_spistruct aspeed_spi_chipstruct aspeed_spi_datastruct aspeed_spienum aspeed_spi_ctl_reg_valuefunction aspeed_spi_get_io_modefunction aspeed_spi_set_io_modefunction aspeed_spi_start_userfunction aspeed_spi_stop_userfunction aspeed_spi_read_from_ahbfunction aspeed_spi_write_to_ahbfunction aspeed_spi_send_cmd_addrfunction aspeed_spi_read_regfunction aspeed_spi_write_regfunction aspeed_spi_read_userfunction aspeed_spi_write_userfunction aspeed_spi_supports_mem_opfunction do_aspeed_spi_exec_mem_opfunction aspeed_spi_exec_mem_opfunction aspeed_spi_set_windowfunction aspeed_spi_chip_set_default_windowfunction aspeed_spi_trim_window_sizefunction aspeed_adjust_window_ast2400function aspeed_adjust_window_ast2500function aspeed_adjust_window_ast2600function aspeed_spi_chip_adjust_windowfunction aspeed_spi_dirmap_createfunction aspeed_spi_dirmap_readfunction aspeed_spi_chip_set_typefunction aspeed_spi_chip_enablefunction aspeed_spi_setupfunction aspeed_spi_cleanupfunction aspeed_spi_enablefunction aspeed_spi_user_prepare_msgfunction aspeed_spi_user_unprepare_msgfunction aspeed_spi_user_transfer_txfunction aspeed_spi_user_transferfunction aspeed_spi_probefunction aspeed_spi_removefunction aspeed_spi_segment_startfunction aspeed_spi_segment_endfunction aspeed_spi_segment_regfunction aspeed_spi_segment_ast2600_startfunction aspeed_spi_segment_ast2600_endfunction aspeed_spi_segment_ast2600_regfunction aspeed_spi_segment_ast2700_startfunction aspeed_spi_segment_ast2700_endfunction aspeed_spi_segment_ast2700_reg
Annotated Snippet
struct aspeed_spi_chip {
struct aspeed_spi *aspi;
u32 cs;
void __iomem *ctl;
void __iomem *ahb_base;
u32 ahb_window_size;
u32 ctl_val[ASPEED_SPI_MAX];
u32 clk_freq;
bool force_user_mode;
};
struct aspeed_spi_data {
u32 ctl0;
u32 max_cs;
bool hastype;
u32 mode_bits;
u32 we0;
u32 timing;
u32 hclk_mask;
u32 hdiv_max;
u32 min_window_size;
bool full_duplex;
phys_addr_t (*segment_start)(struct aspeed_spi *aspi, u32 reg);
phys_addr_t (*segment_end)(struct aspeed_spi *aspi, u32 reg);
u32 (*segment_reg)(struct aspeed_spi *aspi, phys_addr_t start,
phys_addr_t end);
int (*adjust_window)(struct aspeed_spi *aspi);
u32 (*get_clk_div)(struct aspeed_spi_chip *chip, u32 hz);
int (*calibrate)(struct aspeed_spi_chip *chip, u32 hdiv,
const u8 *golden_buf, u8 *test_buf);
};
#define ASPEED_SPI_MAX_NUM_CS 5
struct aspeed_spi {
const struct aspeed_spi_data *data;
void __iomem *regs;
phys_addr_t ahb_base_phy;
u32 ahb_window_size;
u32 num_cs;
struct device *dev;
struct clk *clk;
u32 clk_freq;
u8 cs_change;
struct aspeed_spi_chip chips[ASPEED_SPI_MAX_NUM_CS];
};
static u32 aspeed_spi_get_io_mode(const struct spi_mem_op *op)
{
switch (op->data.buswidth) {
case 1:
return CTRL_IO_SINGLE_DATA;
case 2:
return CTRL_IO_DUAL_DATA;
case 4:
return CTRL_IO_QUAD_DATA;
default:
return CTRL_IO_SINGLE_DATA;
}
}
static void aspeed_spi_set_io_mode(struct aspeed_spi_chip *chip, u32 io_mode)
{
u32 ctl;
if (io_mode > 0) {
ctl = readl(chip->ctl) & ~CTRL_IO_MODE_MASK;
ctl |= io_mode;
writel(ctl, chip->ctl);
}
}
static void aspeed_spi_start_user(struct aspeed_spi_chip *chip)
{
u32 ctl = chip->ctl_val[ASPEED_SPI_BASE];
ctl |= CTRL_IO_MODE_USER | CTRL_CE_STOP_ACTIVE;
writel(ctl, chip->ctl);
ctl &= ~CTRL_CE_STOP_ACTIVE;
writel(ctl, chip->ctl);
}
static void aspeed_spi_stop_user(struct aspeed_spi_chip *chip)
{
u32 ctl = chip->ctl_val[ASPEED_SPI_READ] |
Annotation
- Immediate include surface: `linux/clk.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/spi/spi.h`, `linux/spi/spi-mem.h`.
- Detected declarations: `struct aspeed_spi`, `struct aspeed_spi_chip`, `struct aspeed_spi_data`, `struct aspeed_spi`, `enum aspeed_spi_ctl_reg_value`, `function aspeed_spi_get_io_mode`, `function aspeed_spi_set_io_mode`, `function aspeed_spi_start_user`, `function aspeed_spi_stop_user`, `function aspeed_spi_read_from_ahb`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: source implementation candidate.
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.