drivers/spi/spi-amlogic-spifc-a4.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-amlogic-spifc-a4.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-amlogic-spifc-a4.c- Extension
.c- Size
- 31207 bytes
- Lines
- 1202
- 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 user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/platform_device.hlinux/clk-provider.hlinux/dma-mapping.hlinux/bitfield.hlinux/module.hlinux/slab.hlinux/of.hlinux/clk.hlinux/delay.hlinux/bitops.hlinux/regmap.hlinux/mtd/spinand.hlinux/spi/spi-mem.h
Detected Declarations
struct aml_sfc_ecc_cfgstruct aml_ecc_statsstruct aml_sfc_capsstruct aml_sfcfunction aml_sfc_wait_cmd_finishfunction aml_sfc_pre_transferfunction aml_sfc_end_transferfunction aml_sfc_set_bus_widthfunction aml_sfc_send_cmdfunction aml_sfc_send_addrfunction aml_sfc_is_xio_opfunction aml_sfc_send_cmd_addr_dummyfunction aml_sfc_is_snand_hwecc_page_opfunction aml_sfc_dma_buffer_setupfunction aml_sfc_dma_buffer_releasefunction aml_sfc_dma_buffer_is_safefunction aml_sfc_put_dma_safe_input_buffunction aml_sfc_put_dma_safe_output_buffunction aml_sfc_cal_timeout_cyclefunction aml_sfc_check_ecc_pages_validfunction aml_sfc_raw_io_opfunction aml_sfc_set_user_bytefunction aml_sfc_get_user_bytefunction aml_sfc_check_hwecc_statusfunction aml_sfc_read_page_hweccfunction aml_sfc_write_page_hweccfunction aml_sfc_exec_opfunction aml_sfc_adjust_op_sizefunction aml_sfc_layout_eccfunction aml_sfc_ooblayout_freefunction aml_spi_settingsfunction aml_set_spi_clkfunction aml_sfc_setupfunction aml_sfc_ecc_init_ctxfunction aml_sfc_ecc_cleanup_ctxfunction aml_sfc_ecc_prepare_io_reqfunction aml_sfc_ecc_finish_io_reqfunction aml_sfc_unregister_ecc_enginefunction aml_sfc_clk_initfunction aml_sfc_probe
Annotated Snippet
struct aml_sfc_ecc_cfg {
u32 stepsize;
u32 nsteps;
u32 strength;
u32 oobsize;
u32 bch;
};
struct aml_ecc_stats {
u32 corrected;
u32 bitflips;
u32 failed;
};
struct aml_sfc_caps {
struct aml_sfc_ecc_cfg *ecc_caps;
u32 num_ecc_caps;
};
struct aml_sfc {
struct device *dev;
struct clk *gate_clk;
struct clk *core_clk;
struct spi_controller *ctrl;
struct regmap *regmap_base;
const struct aml_sfc_caps *caps;
struct nand_ecc_engine ecc_eng;
struct aml_ecc_stats ecc_stats;
dma_addr_t daddr;
dma_addr_t iaddr;
u32 info_bytes;
u32 bus_rate;
u32 flags;
u32 rx_adj;
u32 cs_sel;
u8 *data_buf;
__le64 *info_buf;
u8 *priv;
};
#define AML_ECC_DATA(sz, s, b) { .stepsize = (sz), .strength = (s), .bch = (b) }
static struct aml_sfc_ecc_cfg aml_a113l2_ecc_caps[] = {
AML_ECC_DATA(512, 8, ECC_BCH8_512),
AML_ECC_DATA(1024, 8, ECC_BCH8_1K),
};
static const struct aml_sfc_caps aml_a113l2_sfc_caps = {
.ecc_caps = aml_a113l2_ecc_caps,
.num_ecc_caps = ARRAY_SIZE(aml_a113l2_ecc_caps)
};
static struct aml_sfc *nand_to_aml_sfc(struct nand_device *nand)
{
struct nand_ecc_engine *eng = nand->ecc.engine;
return container_of(eng, struct aml_sfc, ecc_eng);
}
static inline void *aml_sfc_to_ecc_ctx(struct aml_sfc *sfc)
{
return sfc->priv;
}
static int aml_sfc_wait_cmd_finish(struct aml_sfc *sfc, u64 timeout_ms)
{
u32 cmd_size = 0;
int ret;
/*
* The SPINAND flash controller employs a two-stage pipeline:
* 1) command prefetch; 2) command execution.
*
* All commands are stored in the FIFO, with one prefetched for execution.
*
* There are cases where the FIFO is detected as empty, yet a command may
* still be in execution and a prefetched command pending execution.
*
* So, send two idle commands to ensure all previous commands have
* been executed.
*/
regmap_write(sfc->regmap_base, SFC_CMD, CMD_IDLE(sfc->cs_sel, 0));
regmap_write(sfc->regmap_base, SFC_CMD, CMD_IDLE(sfc->cs_sel, 0));
/* Wait for the FIFO to empty. */
ret = regmap_read_poll_timeout(sfc->regmap_base, SFC_CMD, cmd_size,
!GET_CMD_SIZE(cmd_size),
10, timeout_ms * 1000);
if (ret)
dev_err(sfc->dev, "wait for empty CMD FIFO time out\n");
Annotation
- Immediate include surface: `linux/platform_device.h`, `linux/clk-provider.h`, `linux/dma-mapping.h`, `linux/bitfield.h`, `linux/module.h`, `linux/slab.h`, `linux/of.h`, `linux/clk.h`.
- Detected declarations: `struct aml_sfc_ecc_cfg`, `struct aml_ecc_stats`, `struct aml_sfc_caps`, `struct aml_sfc`, `function aml_sfc_wait_cmd_finish`, `function aml_sfc_pre_transfer`, `function aml_sfc_end_transfer`, `function aml_sfc_set_bus_width`, `function aml_sfc_send_cmd`, `function aml_sfc_send_addr`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.