This blog explains the interconnection b/w client driver, controller driver & core driver.
Example: SPI-NOR FW, m25p80 client driver, SPI Xlnx controller driver
1) Client driver structure representation:-
Example: SPI-NOR FW, m25p80 client driver, SPI Xlnx controller driver
1) Client driver structure representation:-
struct m25p { struct spi_device *spi; struct spi_nor spi_nor; u8 command[MAX_CMD_SIZE]; };
static int m25p_probe(struct spi_device *spi) {
struct flash_platform_data *data;
struct m25p *flash;
struct spi_nor *nor;
data = dev_get_platdata(&spi->dev);
flash_platform_data = spi_device->dev->platform_data;
/* Allocate memeory for m25p80 driver*/
flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
/* SPI layer device & NOR FW layer device will be same */
nor->dev = &spi->dev;
spi_nor_set_flash_node(nor, spi->dev.of_node);
nor->mtd->dev.of_node = device_node
/* Read whatever is there in "label" & assign it to mtd->name; */
"label", &mtd->name
/* This way spi-nor FW can access client device */
nor->priv = m25p80;
/* Device core layer driver data points to client driver structure */
spi_set_drvdata(spi, flash);
spi_device->dev->driver_data = m25p80;
/* Connect the client driver with spi layer.
Assign the spi_device to client driver spi_device pointer */
flash->spi = spi;
m25p80->spi_device = spi_device (got as a param from **********)
}
struct spi_device *spi_new_device(struct spi_controller *ctlr,
struct spi_board_info *chip)
struct spi_device *proxy;
proxy = spi_alloc_device(ctlr);
proxy->dev.platform_data = (void *) chip->platform_data;
static int zynqmp_prepare_transfer_hardware(struct spi_master *master)
{
struct zynqmp_qspi *xqspi = spi_master_get_devdata(master);
static int zynqmp_qspi_probe(struct platform_device *pdev)
{
struct spi_master *master; struct zynqmp_qspi *xqspi;
xqspi = spi_master_get_devdata(master);
xqspi = ctlr->dev->driver_data;
master->dev.of_node = pdev->dev.of_node;
platform_set_drvdata(pdev, master);
pdev->dev->driver_data = master;
xqspi->dev = dev;