drivers/spi/spi.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi.c- Extension
.c- Size
- 141339 bytes
- Lines
- 5140
- Domain
- Driver Families
- Bucket
- drivers/spi
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/cache.hlinux/clk/clk-conf.hlinux/delay.hlinux/device.hlinux/dmaengine.hlinux/dma-mapping.hlinux/export.hlinux/gpio/consumer.hlinux/highmem.hlinux/idr.hlinux/init.hlinux/ioport.hlinux/kernel.hlinux/kthread.hlinux/mod_devicetable.hlinux/mutex.hlinux/of_device.hlinux/of_irq.hlinux/percpu.hlinux/platform_data/x86/apple.hlinux/pm_domain.hlinux/pm_runtime.hlinux/property.hlinux/ptp_clock_kernel.hlinux/sched/rt.hlinux/slab.hlinux/spi/offload/types.hlinux/spi/spi.hlinux/spi/spi-mem.huapi/linux/sched/types.htrace/events/spi.h
Detected Declarations
struct boardinfostruct spi_dev_check_infostruct acpi_spi_lookupfunction spidev_releasefunction modalias_showfunction driver_override_storefunction driver_override_showfunction for_each_possible_cpufunction spi_emit_pcpu_statsfunction for_each_possible_cpufunction spi_statistics_add_transfer_statsfunction spi_match_devicefunction spi_ueventfunction spi_probefunction spi_removefunction spi_shutdownfunction __spi_register_driverfunction spi_add_devicefunction spi_dev_set_namefunction Zerofunction spi_dev_checkfunction spi_cleanupfunction __spi_add_devicefunction spi_add_devicefunction devicesfunction spi_unregister_controllerfunction spi_match_controller_to_boardinfofunction controllerfunction spi_res_freefunction spi_res_addfunction spi_res_releasefunction list_for_each_entry_safe_reversefunction spi_for_each_valid_csfunction spi_toggle_csgpiodfunction spi_set_csfunction spi_map_buf_attrsfunction spi_map_buffunction spi_unmap_buf_attrsfunction spi_unmap_buffunction __spi_map_msgfunction __spi_unmap_msgfunction list_for_each_entryfunction spi_dma_sync_for_devicefunction spi_dma_sync_for_cpufunction __spi_map_msgfunction __spi_unmap_msgfunction spi_dma_sync_for_devicefunction list_for_each_entry
Annotated Snippet
static int spi_match_device(struct device *dev, const struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);
const struct spi_driver *sdrv = to_spi_driver(drv);
int ret;
/* Check override first, and if set, only use the named driver */
ret = device_match_driver_override(dev, drv);
if (ret >= 0)
return ret;
/* Attempt an OF style match */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try ACPI */
if (acpi_driver_match_device(dev, drv))
return 1;
if (sdrv->id_table)
return !!spi_match_id(sdrv->id_table, spi->modalias);
return strcmp(spi->modalias, drv->name) == 0;
}
static int spi_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct spi_device *spi = to_spi_device(dev);
int rc;
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
return add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);
}
static int spi_probe(struct device *dev)
{
const struct spi_driver *sdrv = to_spi_driver(dev->driver);
struct spi_device *spi = to_spi_device(dev);
struct fwnode_handle *fwnode = dev_fwnode(dev);
int ret;
ret = of_clk_set_defaults(dev->of_node, false);
if (ret)
return ret;
if (is_of_node(fwnode))
spi->irq = of_irq_get(dev->of_node, 0);
else if (is_acpi_device_node(fwnode) && spi->irq < 0)
spi->irq = acpi_dev_gpio_irq_get(to_acpi_device_node(fwnode), 0);
if (spi->irq == -EPROBE_DEFER)
return dev_err_probe(dev, spi->irq, "Failed to get irq\n");
if (spi->irq < 0)
spi->irq = 0;
ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON |
PD_FLAG_DETACH_POWER_OFF);
if (ret)
return ret;
if (sdrv->probe)
ret = sdrv->probe(spi);
return ret;
}
static void spi_remove(struct device *dev)
{
const struct spi_driver *sdrv = to_spi_driver(dev->driver);
if (sdrv->remove)
sdrv->remove(to_spi_device(dev));
}
static void spi_shutdown(struct device *dev)
{
if (dev->driver) {
const struct spi_driver *sdrv = to_spi_driver(dev->driver);
if (sdrv->shutdown)
sdrv->shutdown(to_spi_device(dev));
}
}
const struct bus_type spi_bus_type = {
.name = "spi",
.dev_groups = spi_dev_groups,
.match = spi_match_device,
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/cache.h`, `linux/clk/clk-conf.h`, `linux/delay.h`, `linux/device.h`, `linux/dmaengine.h`, `linux/dma-mapping.h`, `linux/export.h`.
- Detected declarations: `struct boardinfo`, `struct spi_dev_check_info`, `struct acpi_spi_lookup`, `function spidev_release`, `function modalias_show`, `function driver_override_store`, `function driver_override_show`, `function for_each_possible_cpu`, `function spi_emit_pcpu_stats`, `function for_each_possible_cpu`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.