What is the difference between a platform driver and an I2C/SPI driver?
The difference lies in which bus subsystem manages the driver. A platform driver handles devices that are directly memory-mapped to the SoC's address space — they sit on an internal bus with no standard discovery protocol. UARTs, timers, GPIO controllers, and DMA engines are typical platform devices. The kernel creates platform_device objects from device tree nodes and matches them to platform_driver structures. The driver accesses hardware through ioremap() to map physical register addresses into kernel virtual memory.
An I2C or SPI driver handles devices attached to an external I2C or SPI bus — sensors, EEPROMs, display controllers, ADCs. These drivers register with the I2C or SPI subsystem (i2c_driver, spi_driver) and receive a handle to the bus controller. They access hardware through bus-specific transfer functions (i2c_smbus_read_byte(), spi_transfer()) rather than direct memory mapping. The bus controller itself is typically a platform driver.
The key architectural insight is that this is a layered model: the SoC's I2C controller is a platform device with memory-mapped registers, managed by a platform driver. That driver registers itself as an I2C adapter. External chips on the I2C bus are then managed by I2C client drivers that communicate through the adapter. This layered approach means you can swap the SoC (and its I2C controller driver) without changing the external device drivers, and vice versa.
Source: Embedded Linux Q&A
