a8db23cebb5c8d9898d8676bf3bccce48d7f9dce
[openwrt/staging/neocturne.git] /
1 From 6e46fe6d9428a41543bd19644de3c9f2611b73bf Mon Sep 17 00:00:00 2001
2 From: Han Xu <han.xu@nxp.com>
3 Date: Wed, 5 Jun 2019 16:43:30 -0500
4 Subject: [PATCH] MLK-21960-2: spi: fspi: dynamically alloc AHB memory
5
6 dynamically allocate AHB memory as needed.
7
8 Signed-off-by: Han Xu <han.xu@nxp.com>
9 ---
10 drivers/spi/spi-nxp-fspi.c | 40 ++++++++++++++++++++++++++++++++++------
11 1 file changed, 34 insertions(+), 6 deletions(-)
12
13 --- a/drivers/spi/spi-nxp-fspi.c
14 +++ b/drivers/spi/spi-nxp-fspi.c
15 @@ -307,6 +307,7 @@
16
17 #define POLL_TOUT 5000
18 #define NXP_FSPI_MAX_CHIPSELECT 4
19 +#define NXP_FSPI_MIN_IOMAP SZ_4M
20
21 struct nxp_fspi_devtype_data {
22 unsigned int rxfifo;
23 @@ -345,6 +346,8 @@ struct nxp_fspi {
24 void __iomem *ahb_addr;
25 u32 memmap_phy;
26 u32 memmap_phy_size;
27 + u32 memmap_start;
28 + u32 memmap_len;
29 struct clk *clk, *clk_en;
30 struct device *dev;
31 struct completion c;
32 @@ -657,12 +660,35 @@ static void nxp_fspi_select_mem(struct n
33 f->selected = spi->chip_select;
34 }
35
36 -static void nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
37 +static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
38 {
39 + u32 start = op->addr.val;
40 u32 len = op->data.nbytes;
41
42 + /* if necessary, ioremap before AHB read */
43 + if ((!f->ahb_addr) || start < f->memmap_start ||
44 + start + len > f->memmap_start + f->memmap_len) {
45 + if (f->ahb_addr)
46 + iounmap(f->ahb_addr);
47 +
48 + f->memmap_start = start;
49 + f->memmap_len = len > NXP_FSPI_MIN_IOMAP ?
50 + len : NXP_FSPI_MIN_IOMAP;
51 +
52 + f->ahb_addr = ioremap_wc(f->memmap_phy + f->memmap_start,
53 + f->memmap_len);
54 +
55 + if (!f->ahb_addr) {
56 + dev_err(f->dev, "failed to alloc memory\n");
57 + return -ENOMEM;
58 + }
59 + }
60 +
61 /* Read out the data directly from the AHB buffer. */
62 - memcpy_fromio(op->data.buf.in, (f->ahb_addr + op->addr.val), len);
63 + memcpy_fromio(op->data.buf.in,
64 + f->ahb_addr + start - f->memmap_start, len);
65 +
66 + return 0;
67 }
68
69 static void nxp_fspi_fill_txfifo(struct nxp_fspi *f,
70 @@ -822,7 +848,7 @@ static int nxp_fspi_exec_op(struct spi_m
71 */
72 if (op->data.nbytes > (f->devtype_data->rxfifo - 4) &&
73 op->data.dir == SPI_MEM_DATA_IN) {
74 - nxp_fspi_read_ahb(f, op);
75 + err = nxp_fspi_read_ahb(f, op);
76 } else {
77 if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
78 nxp_fspi_fill_txfifo(f, op);
79 @@ -999,9 +1025,8 @@ static int nxp_fspi_probe(struct platfor
80
81 /* find the resources - controller memory mapped space */
82 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_mmap");
83 - f->ahb_addr = devm_ioremap_resource(dev, res);
84 - if (IS_ERR(f->ahb_addr)) {
85 - ret = PTR_ERR(f->ahb_addr);
86 + if (IS_ERR(res)) {
87 + ret = PTR_ERR(res);
88 goto err_put_ctrl;
89 }
90
91 @@ -1080,6 +1105,9 @@ static int nxp_fspi_remove(struct platfo
92
93 mutex_destroy(&f->lock);
94
95 + if (f->ahb_addr)
96 + iounmap(f->ahb_addr);
97 +
98 return 0;
99 }
100