drivers/spi/spi-dw-mmio.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-dw-mmio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-dw-mmio.c- Extension
.c- Size
- 13251 bytes
- Lines
- 478
- 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/err.hlinux/platform_device.hlinux/pm_runtime.hlinux/slab.hlinux/spi/spi.hlinux/scatterlist.hlinux/mfd/syscon.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/acpi.hlinux/property.hlinux/regmap.hlinux/reset.hspi-dw.h
Detected Declarations
struct dw_spi_mmiostruct dw_spi_msccfunction controllerfunction dw_spi_mscc_initfunction dw_spi_mscc_ocelot_initfunction dw_spi_mscc_jaguar2_initfunction controllerfunction dw_spi_mscc_sparx5_initfunction dw_spi_alpine_initfunction dw_spi_pssi_initfunction dw_spi_hssi_initfunction dw_spi_hssi_no_dma_initfunction dw_spi_mountevans_imc_initfunction dw_spi_canaan_k210_initfunction dw_spi_elba_override_csfunction dw_spi_elba_set_csfunction dw_spi_elba_initfunction dw_spi_mmio_probefunction dw_spi_mmio_suspendfunction dw_spi_mmio_resumefunction dw_spi_mmio_remove
Annotated Snippet
struct dw_spi_mmio {
struct dw_spi dws;
struct clk *clk;
struct clk *pclk;
void *priv;
struct reset_control *rstc;
};
#define MSCC_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24
#define OCELOT_IF_SI_OWNER_OFFSET 4
#define JAGUAR2_IF_SI_OWNER_OFFSET 6
#define MSCC_IF_SI_OWNER_MASK GENMASK(1, 0)
#define MSCC_IF_SI_OWNER_SISL 0
#define MSCC_IF_SI_OWNER_SIBM 1
#define MSCC_IF_SI_OWNER_SIMC 2
#define MSCC_SPI_MST_SW_MODE 0x14
#define MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE BIT(13)
#define MSCC_SPI_MST_SW_MODE_SW_SPI_CS(x) (x << 5)
#define SPARX5_FORCE_ENA 0xa4
#define SPARX5_FORCE_VAL 0xa8
struct dw_spi_mscc {
struct regmap *syscon;
void __iomem *spi_mst; /* Not sparx5 */
};
/*
* Elba SoC does not use ssi, pin override is used for cs 0,1 and
* gpios for cs 2,3 as defined in the device tree.
*
* cs: | 1 0
* bit: |---3-------2-------1-------0
* | cs1 cs1_ovr cs0 cs0_ovr
*/
#define ELBA_SPICS_REG 0x2468
#define ELBA_SPICS_OFFSET(cs) ((cs) << 1)
#define ELBA_SPICS_MASK(cs) (GENMASK(1, 0) << ELBA_SPICS_OFFSET(cs))
#define ELBA_SPICS_SET(cs, val) \
((((val) << 1) | BIT(0)) << ELBA_SPICS_OFFSET(cs))
/*
* The Designware SPI controller (referred to as master in the documentation)
* automatically deasserts chip select when the tx fifo is empty. The chip
* selects then needs to be either driven as GPIOs or, for the first 4 using
* the SPI boot controller registers. the final chip select is an OR gate
* between the Designware SPI controller and the SPI boot controller.
*/
static void dw_spi_mscc_set_cs(struct spi_device *spi, bool enable)
{
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
struct dw_spi_mscc *dwsmscc = dwsmmio->priv;
u32 cs = spi_get_chipselect(spi, 0);
if (cs < 4) {
u32 sw_mode = MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE;
if (!enable)
sw_mode |= MSCC_SPI_MST_SW_MODE_SW_SPI_CS(BIT(cs));
writel(sw_mode, dwsmscc->spi_mst + MSCC_SPI_MST_SW_MODE);
}
dw_spi_set_cs(spi, enable);
}
static int dw_spi_mscc_init(struct platform_device *pdev,
struct dw_spi_mmio *dwsmmio,
const char *cpu_syscon, u32 if_si_owner_offset)
{
struct dw_spi_mscc *dwsmscc;
dwsmscc = devm_kzalloc(&pdev->dev, sizeof(*dwsmscc), GFP_KERNEL);
if (!dwsmscc)
return -ENOMEM;
dwsmscc->spi_mst = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(dwsmscc->spi_mst))
return PTR_ERR(dwsmscc->spi_mst);
dwsmscc->syscon = syscon_regmap_lookup_by_compatible(cpu_syscon);
if (IS_ERR(dwsmscc->syscon))
return PTR_ERR(dwsmscc->syscon);
/* Deassert all CS */
writel(0, dwsmscc->spi_mst + MSCC_SPI_MST_SW_MODE);
/* Select the owner of the SI interface */
Annotation
- Immediate include surface: `linux/clk.h`, `linux/err.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `linux/slab.h`, `linux/spi/spi.h`, `linux/scatterlist.h`, `linux/mfd/syscon.h`.
- Detected declarations: `struct dw_spi_mmio`, `struct dw_spi_mscc`, `function controller`, `function dw_spi_mscc_init`, `function dw_spi_mscc_ocelot_init`, `function dw_spi_mscc_jaguar2_init`, `function controller`, `function dw_spi_mscc_sparx5_init`, `function dw_spi_alpine_init`, `function dw_spi_pssi_init`.
- 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.