1 // SPDX-License-Identifier: GPL-2.0-only
3 * Xilinx Spartan6 and 7 Series Slave Serial SPI Driver
5 * Copyright (C) 2017 DENX Software Engineering
7 * Anatolij Gustschin <agust@denx.de>
9 * Manage Xilinx FPGA firmware that is loaded over SPI using
10 * the slave serial configuration interface.
13 #include "xilinx-core.h"
15 #include <linux/module.h>
16 #include <linux/mod_devicetable.h>
18 #include <linux/spi/spi.h>
20 static int xilinx_spi_write(struct xilinx_fpga_core
*core
, const char *buf
,
23 struct spi_device
*spi
= to_spi_device(core
->dev
);
24 const char *fw_data
= buf
;
25 const char *fw_data_end
= fw_data
+ count
;
27 while (fw_data
< fw_data_end
) {
28 size_t remaining
, stride
;
31 remaining
= fw_data_end
- fw_data
;
32 stride
= min_t(size_t, remaining
, SZ_4K
);
34 ret
= spi_write(spi
, fw_data
, stride
);
36 dev_err(core
->dev
, "SPI error in firmware write: %d\n",
46 static int xilinx_spi_probe(struct spi_device
*spi
)
48 struct xilinx_fpga_core
*core
;
50 core
= devm_kzalloc(&spi
->dev
, sizeof(*core
), GFP_KERNEL
);
54 core
->dev
= &spi
->dev
;
55 core
->write
= xilinx_spi_write
;
57 return xilinx_core_probe(core
);
61 static const struct of_device_id xlnx_spi_of_match
[] = {
63 .compatible
= "xlnx,fpga-slave-serial",
67 MODULE_DEVICE_TABLE(of
, xlnx_spi_of_match
);
70 static struct spi_driver xilinx_slave_spi_driver
= {
72 .name
= "xlnx-slave-spi",
73 .of_match_table
= of_match_ptr(xlnx_spi_of_match
),
75 .probe
= xilinx_spi_probe
,
78 module_spi_driver(xilinx_slave_spi_driver
)
80 MODULE_LICENSE("GPL v2");
81 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
82 MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SPI");