2019-06-01 11:08:37 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2017-03-24 03:34:26 +03:00
/*
2020-06-12 00:11:41 +03:00
* Xilinx Spartan6 and 7 Series Slave Serial SPI Driver
2017-03-24 03:34:26 +03:00
*
* Copyright ( C ) 2017 DENX Software Engineering
*
* Anatolij Gustschin < agust @ denx . de >
*
* Manage Xilinx FPGA firmware that is loaded over SPI using
* the slave serial configuration interface .
*/
2024-03-22 01:04:33 +03:00
# include "xilinx-core.h"
2017-03-24 03:34:26 +03:00
# include <linux/module.h>
# include <linux/mod_devicetable.h>
# include <linux/of.h>
# include <linux/spi/spi.h>
2024-03-22 01:04:33 +03:00
static int xilinx_spi_write ( struct xilinx_fpga_core * core , const char * buf ,
2017-03-24 03:34:26 +03:00
size_t count )
{
2024-03-22 01:04:33 +03:00
struct spi_device * spi = to_spi_device ( core - > dev ) ;
2017-03-24 03:34:26 +03:00
const char * fw_data = buf ;
const char * fw_data_end = fw_data + count ;
while ( fw_data < fw_data_end ) {
size_t remaining , stride ;
int ret ;
remaining = fw_data_end - fw_data ;
stride = min_t ( size_t , remaining , SZ_4K ) ;
2024-03-22 01:04:33 +03:00
ret = spi_write ( spi , fw_data , stride ) ;
2017-03-24 03:34:26 +03:00
if ( ret ) {
2024-03-22 01:04:33 +03:00
dev_err ( core - > dev , " SPI error in firmware write: %d \n " ,
2017-03-24 03:34:26 +03:00
ret ) ;
return ret ;
}
fw_data + = stride ;
}
return 0 ;
}
static int xilinx_spi_probe ( struct spi_device * spi )
{
2024-03-22 01:04:33 +03:00
struct xilinx_fpga_core * core ;
2017-03-24 03:34:26 +03:00
2024-03-22 01:04:33 +03:00
core = devm_kzalloc ( & spi - > dev , sizeof ( * core ) , GFP_KERNEL ) ;
if ( ! core )
2017-03-24 03:34:26 +03:00
return - ENOMEM ;
2024-03-22 01:04:33 +03:00
core - > dev = & spi - > dev ;
core - > write = xilinx_spi_write ;
2017-03-24 03:34:26 +03:00
2024-03-22 01:04:33 +03:00
return xilinx_core_probe ( core ) ;
2017-03-24 03:34:26 +03:00
}
2021-07-02 06:54:02 +03:00
# ifdef CONFIG_OF
2017-03-24 03:34:26 +03:00
static const struct of_device_id xlnx_spi_of_match [ ] = {
2024-03-22 01:04:33 +03:00
{
. compatible = " xlnx,fpga-slave-serial " ,
} ,
2017-03-24 03:34:26 +03:00
{ }
} ;
MODULE_DEVICE_TABLE ( of , xlnx_spi_of_match ) ;
2021-07-02 06:54:02 +03:00
# endif
2017-03-24 03:34:26 +03:00
static struct spi_driver xilinx_slave_spi_driver = {
. driver = {
. name = " xlnx-slave-spi " ,
. of_match_table = of_match_ptr ( xlnx_spi_of_match ) ,
} ,
. probe = xilinx_spi_probe ,
} ;
module_spi_driver ( xilinx_slave_spi_driver )
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Anatolij Gustschin <agust@denx.de> " ) ;
MODULE_DESCRIPTION ( " Load Xilinx FPGA firmware over SPI " ) ;