Merge tag 'char-misc-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[linux-block.git] / drivers / fpga / xilinx-spi.c
CommitLineData
75a6faf6 1// SPDX-License-Identifier: GPL-2.0-only
061c97d1 2/*
d1ddca78 3 * Xilinx Spartan6 and 7 Series Slave Serial SPI Driver
061c97d1
AG
4 *
5 * Copyright (C) 2017 DENX Software Engineering
6 *
7 * Anatolij Gustschin <agust@denx.de>
8 *
061c97d1
AG
9 * Manage Xilinx FPGA firmware that is loaded over SPI using
10 * the slave serial configuration interface.
11 */
12
a52e3a9d
CP
13#include "xilinx-core.h"
14
061c97d1
AG
15#include <linux/module.h>
16#include <linux/mod_devicetable.h>
17#include <linux/of.h>
18#include <linux/spi/spi.h>
061c97d1 19
a52e3a9d 20static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf,
061c97d1
AG
21 size_t count)
22{
a52e3a9d 23 struct spi_device *spi = to_spi_device(core->dev);
061c97d1
AG
24 const char *fw_data = buf;
25 const char *fw_data_end = fw_data + count;
26
27 while (fw_data < fw_data_end) {
28 size_t remaining, stride;
29 int ret;
30
31 remaining = fw_data_end - fw_data;
32 stride = min_t(size_t, remaining, SZ_4K);
33
a52e3a9d 34 ret = spi_write(spi, fw_data, stride);
061c97d1 35 if (ret) {
a52e3a9d 36 dev_err(core->dev, "SPI error in firmware write: %d\n",
061c97d1
AG
37 ret);
38 return ret;
39 }
40 fw_data += stride;
41 }
42
43 return 0;
44}
45
061c97d1
AG
46static int xilinx_spi_probe(struct spi_device *spi)
47{
a52e3a9d 48 struct xilinx_fpga_core *core;
061c97d1 49
a52e3a9d
CP
50 core = devm_kzalloc(&spi->dev, sizeof(*core), GFP_KERNEL);
51 if (!core)
061c97d1
AG
52 return -ENOMEM;
53
a52e3a9d
CP
54 core->dev = &spi->dev;
55 core->write = xilinx_spi_write;
061c97d1 56
a52e3a9d 57 return xilinx_core_probe(core);
061c97d1
AG
58}
59
1aa3fc69 60#ifdef CONFIG_OF
061c97d1 61static const struct of_device_id xlnx_spi_of_match[] = {
a52e3a9d
CP
62 {
63 .compatible = "xlnx,fpga-slave-serial",
64 },
061c97d1
AG
65 {}
66};
67MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
1aa3fc69 68#endif
061c97d1
AG
69
70static struct spi_driver xilinx_slave_spi_driver = {
71 .driver = {
72 .name = "xlnx-slave-spi",
73 .of_match_table = of_match_ptr(xlnx_spi_of_match),
74 },
75 .probe = xilinx_spi_probe,
061c97d1
AG
76};
77
78module_spi_driver(xilinx_slave_spi_driver)
79
80MODULE_LICENSE("GPL v2");
81MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
82MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SPI");