1*052cafd2SGuochun Mao // SPDX-License-Identifier: GPL-2.0
2*052cafd2SGuochun Mao /*
3*052cafd2SGuochun Mao * Copyright (c) 2018 MediaTek, Inc.
4*052cafd2SGuochun Mao * Author : Guochun.Mao@mediatek.com
5*052cafd2SGuochun Mao */
6*052cafd2SGuochun Mao
7*052cafd2SGuochun Mao #include <common.h>
8*052cafd2SGuochun Mao #include <dm.h>
9*052cafd2SGuochun Mao #include <malloc.h>
10*052cafd2SGuochun Mao #include <spi.h>
11*052cafd2SGuochun Mao #include <asm/io.h>
12*052cafd2SGuochun Mao #include <linux/iopoll.h>
13*052cafd2SGuochun Mao #include <linux/ioport.h>
14*052cafd2SGuochun Mao
15*052cafd2SGuochun Mao /* Register Offset */
16*052cafd2SGuochun Mao struct mtk_qspi_regs {
17*052cafd2SGuochun Mao u32 cmd;
18*052cafd2SGuochun Mao u32 cnt;
19*052cafd2SGuochun Mao u32 rdsr;
20*052cafd2SGuochun Mao u32 rdata;
21*052cafd2SGuochun Mao u32 radr[3];
22*052cafd2SGuochun Mao u32 wdata;
23*052cafd2SGuochun Mao u32 prgdata[6];
24*052cafd2SGuochun Mao u32 shreg[10];
25*052cafd2SGuochun Mao u32 cfg[2];
26*052cafd2SGuochun Mao u32 shreg10;
27*052cafd2SGuochun Mao u32 mode_mon;
28*052cafd2SGuochun Mao u32 status[4];
29*052cafd2SGuochun Mao u32 flash_time;
30*052cafd2SGuochun Mao u32 flash_cfg;
31*052cafd2SGuochun Mao u32 reserved_0[3];
32*052cafd2SGuochun Mao u32 sf_time;
33*052cafd2SGuochun Mao u32 pp_dw_data;
34*052cafd2SGuochun Mao u32 reserved_1;
35*052cafd2SGuochun Mao u32 delsel_0[2];
36*052cafd2SGuochun Mao u32 intrstus;
37*052cafd2SGuochun Mao u32 intren;
38*052cafd2SGuochun Mao u32 reserved_2;
39*052cafd2SGuochun Mao u32 cfg3;
40*052cafd2SGuochun Mao u32 reserved_3;
41*052cafd2SGuochun Mao u32 chksum;
42*052cafd2SGuochun Mao u32 aaicmd;
43*052cafd2SGuochun Mao u32 wrprot;
44*052cafd2SGuochun Mao u32 radr3;
45*052cafd2SGuochun Mao u32 dual;
46*052cafd2SGuochun Mao u32 delsel_1[3];
47*052cafd2SGuochun Mao };
48*052cafd2SGuochun Mao
49*052cafd2SGuochun Mao struct mtk_qspi_platdata {
50*052cafd2SGuochun Mao fdt_addr_t reg_base;
51*052cafd2SGuochun Mao fdt_addr_t mem_base;
52*052cafd2SGuochun Mao };
53*052cafd2SGuochun Mao
54*052cafd2SGuochun Mao struct mtk_qspi_priv {
55*052cafd2SGuochun Mao struct mtk_qspi_regs *regs;
56*052cafd2SGuochun Mao unsigned long *mem_base;
57*052cafd2SGuochun Mao u8 op;
58*052cafd2SGuochun Mao u8 tx[3]; /* only record max 3 bytes paras, when it's address. */
59*052cafd2SGuochun Mao u32 txlen; /* dout buffer length - op code length */
60*052cafd2SGuochun Mao u8 *rx;
61*052cafd2SGuochun Mao u32 rxlen;
62*052cafd2SGuochun Mao };
63*052cafd2SGuochun Mao
64*052cafd2SGuochun Mao #define MTK_QSPI_CMD_POLLINGREG_US 500000
65*052cafd2SGuochun Mao #define MTK_QSPI_WRBUF_SIZE 256
66*052cafd2SGuochun Mao #define MTK_QSPI_COMMAND_ENABLE 0x30
67*052cafd2SGuochun Mao
68*052cafd2SGuochun Mao /* NOR flash controller commands */
69*052cafd2SGuochun Mao #define MTK_QSPI_RD_TRIGGER BIT(0)
70*052cafd2SGuochun Mao #define MTK_QSPI_READSTATUS BIT(1)
71*052cafd2SGuochun Mao #define MTK_QSPI_PRG_CMD BIT(2)
72*052cafd2SGuochun Mao #define MTK_QSPI_WR_TRIGGER BIT(4)
73*052cafd2SGuochun Mao #define MTK_QSPI_WRITESTATUS BIT(5)
74*052cafd2SGuochun Mao #define MTK_QSPI_AUTOINC BIT(7)
75*052cafd2SGuochun Mao
76*052cafd2SGuochun Mao #define MTK_QSPI_MAX_RX_TX_SHIFT 0x6
77*052cafd2SGuochun Mao #define MTK_QSPI_MAX_SHIFT 0x8
78*052cafd2SGuochun Mao
79*052cafd2SGuochun Mao #define MTK_QSPI_WR_BUF_ENABLE 0x1
80*052cafd2SGuochun Mao #define MTK_QSPI_WR_BUF_DISABLE 0x0
81*052cafd2SGuochun Mao
mtk_qspi_execute_cmd(struct mtk_qspi_priv * priv,u8 cmd)82*052cafd2SGuochun Mao static int mtk_qspi_execute_cmd(struct mtk_qspi_priv *priv, u8 cmd)
83*052cafd2SGuochun Mao {
84*052cafd2SGuochun Mao u8 tmp;
85*052cafd2SGuochun Mao u8 val = cmd & ~MTK_QSPI_AUTOINC;
86*052cafd2SGuochun Mao
87*052cafd2SGuochun Mao writeb(cmd, &priv->regs->cmd);
88*052cafd2SGuochun Mao
89*052cafd2SGuochun Mao return readb_poll_timeout(&priv->regs->cmd, tmp, !(val & tmp),
90*052cafd2SGuochun Mao MTK_QSPI_CMD_POLLINGREG_US);
91*052cafd2SGuochun Mao }
92*052cafd2SGuochun Mao
mtk_qspi_tx_rx(struct mtk_qspi_priv * priv)93*052cafd2SGuochun Mao static int mtk_qspi_tx_rx(struct mtk_qspi_priv *priv)
94*052cafd2SGuochun Mao {
95*052cafd2SGuochun Mao int len = 1 + priv->txlen + priv->rxlen;
96*052cafd2SGuochun Mao int i, ret, idx;
97*052cafd2SGuochun Mao
98*052cafd2SGuochun Mao if (len > MTK_QSPI_MAX_SHIFT)
99*052cafd2SGuochun Mao return -ERR_INVAL;
100*052cafd2SGuochun Mao
101*052cafd2SGuochun Mao writeb(len * 8, &priv->regs->cnt);
102*052cafd2SGuochun Mao
103*052cafd2SGuochun Mao /* start at PRGDATA5, go down to PRGDATA0 */
104*052cafd2SGuochun Mao idx = MTK_QSPI_MAX_RX_TX_SHIFT - 1;
105*052cafd2SGuochun Mao
106*052cafd2SGuochun Mao /* opcode */
107*052cafd2SGuochun Mao writeb(priv->op, &priv->regs->prgdata[idx]);
108*052cafd2SGuochun Mao idx--;
109*052cafd2SGuochun Mao
110*052cafd2SGuochun Mao /* program TX data */
111*052cafd2SGuochun Mao for (i = 0; i < priv->txlen; i++, idx--)
112*052cafd2SGuochun Mao writeb(priv->tx[i], &priv->regs->prgdata[idx]);
113*052cafd2SGuochun Mao
114*052cafd2SGuochun Mao /* clear out rest of TX registers */
115*052cafd2SGuochun Mao while (idx >= 0) {
116*052cafd2SGuochun Mao writeb(0, &priv->regs->prgdata[idx]);
117*052cafd2SGuochun Mao idx--;
118*052cafd2SGuochun Mao }
119*052cafd2SGuochun Mao
120*052cafd2SGuochun Mao ret = mtk_qspi_execute_cmd(priv, MTK_QSPI_PRG_CMD);
121*052cafd2SGuochun Mao if (ret)
122*052cafd2SGuochun Mao return ret;
123*052cafd2SGuochun Mao
124*052cafd2SGuochun Mao /* restart at first RX byte */
125*052cafd2SGuochun Mao idx = priv->rxlen - 1;
126*052cafd2SGuochun Mao
127*052cafd2SGuochun Mao /* read out RX data */
128*052cafd2SGuochun Mao for (i = 0; i < priv->rxlen; i++, idx--)
129*052cafd2SGuochun Mao priv->rx[i] = readb(&priv->regs->shreg[idx]);
130*052cafd2SGuochun Mao
131*052cafd2SGuochun Mao return 0;
132*052cafd2SGuochun Mao }
133*052cafd2SGuochun Mao
mtk_qspi_read(struct mtk_qspi_priv * priv,u32 addr,u8 * buf,u32 len)134*052cafd2SGuochun Mao static int mtk_qspi_read(struct mtk_qspi_priv *priv,
135*052cafd2SGuochun Mao u32 addr, u8 *buf, u32 len)
136*052cafd2SGuochun Mao {
137*052cafd2SGuochun Mao memcpy(buf, (u8 *)priv->mem_base + addr, len);
138*052cafd2SGuochun Mao return 0;
139*052cafd2SGuochun Mao }
140*052cafd2SGuochun Mao
mtk_qspi_set_addr(struct mtk_qspi_priv * priv,u32 addr)141*052cafd2SGuochun Mao static void mtk_qspi_set_addr(struct mtk_qspi_priv *priv, u32 addr)
142*052cafd2SGuochun Mao {
143*052cafd2SGuochun Mao int i;
144*052cafd2SGuochun Mao
145*052cafd2SGuochun Mao for (i = 0; i < 3; i++) {
146*052cafd2SGuochun Mao writeb(addr & 0xff, &priv->regs->radr[i]);
147*052cafd2SGuochun Mao addr >>= 8;
148*052cafd2SGuochun Mao }
149*052cafd2SGuochun Mao }
150*052cafd2SGuochun Mao
mtk_qspi_write_single_byte(struct mtk_qspi_priv * priv,u32 addr,u32 length,const u8 * data)151*052cafd2SGuochun Mao static int mtk_qspi_write_single_byte(struct mtk_qspi_priv *priv,
152*052cafd2SGuochun Mao u32 addr, u32 length, const u8 *data)
153*052cafd2SGuochun Mao {
154*052cafd2SGuochun Mao int i, ret;
155*052cafd2SGuochun Mao
156*052cafd2SGuochun Mao mtk_qspi_set_addr(priv, addr);
157*052cafd2SGuochun Mao
158*052cafd2SGuochun Mao for (i = 0; i < length; i++) {
159*052cafd2SGuochun Mao writeb(*data++, &priv->regs->wdata);
160*052cafd2SGuochun Mao ret = mtk_qspi_execute_cmd(priv, MTK_QSPI_WR_TRIGGER);
161*052cafd2SGuochun Mao if (ret < 0)
162*052cafd2SGuochun Mao return ret;
163*052cafd2SGuochun Mao }
164*052cafd2SGuochun Mao return 0;
165*052cafd2SGuochun Mao }
166*052cafd2SGuochun Mao
mtk_qspi_write_buffer(struct mtk_qspi_priv * priv,u32 addr,const u8 * buf)167*052cafd2SGuochun Mao static int mtk_qspi_write_buffer(struct mtk_qspi_priv *priv, u32 addr,
168*052cafd2SGuochun Mao const u8 *buf)
169*052cafd2SGuochun Mao {
170*052cafd2SGuochun Mao int i, data;
171*052cafd2SGuochun Mao
172*052cafd2SGuochun Mao mtk_qspi_set_addr(priv, addr);
173*052cafd2SGuochun Mao
174*052cafd2SGuochun Mao for (i = 0; i < MTK_QSPI_WRBUF_SIZE; i += 4) {
175*052cafd2SGuochun Mao data = buf[i + 3] << 24 | buf[i + 2] << 16 |
176*052cafd2SGuochun Mao buf[i + 1] << 8 | buf[i];
177*052cafd2SGuochun Mao writel(data, &priv->regs->pp_dw_data);
178*052cafd2SGuochun Mao }
179*052cafd2SGuochun Mao
180*052cafd2SGuochun Mao return mtk_qspi_execute_cmd(priv, MTK_QSPI_WR_TRIGGER);
181*052cafd2SGuochun Mao }
182*052cafd2SGuochun Mao
mtk_qspi_write(struct mtk_qspi_priv * priv,u32 addr,const u8 * buf,u32 len)183*052cafd2SGuochun Mao static int mtk_qspi_write(struct mtk_qspi_priv *priv,
184*052cafd2SGuochun Mao u32 addr, const u8 *buf, u32 len)
185*052cafd2SGuochun Mao {
186*052cafd2SGuochun Mao int ret;
187*052cafd2SGuochun Mao
188*052cafd2SGuochun Mao /* setting pre-fetch buffer for page program */
189*052cafd2SGuochun Mao writel(MTK_QSPI_WR_BUF_ENABLE, &priv->regs->cfg[1]);
190*052cafd2SGuochun Mao while (len >= MTK_QSPI_WRBUF_SIZE) {
191*052cafd2SGuochun Mao ret = mtk_qspi_write_buffer(priv, addr, buf);
192*052cafd2SGuochun Mao if (ret < 0)
193*052cafd2SGuochun Mao return ret;
194*052cafd2SGuochun Mao
195*052cafd2SGuochun Mao len -= MTK_QSPI_WRBUF_SIZE;
196*052cafd2SGuochun Mao addr += MTK_QSPI_WRBUF_SIZE;
197*052cafd2SGuochun Mao buf += MTK_QSPI_WRBUF_SIZE;
198*052cafd2SGuochun Mao }
199*052cafd2SGuochun Mao /* disable pre-fetch buffer for page program */
200*052cafd2SGuochun Mao writel(MTK_QSPI_WR_BUF_DISABLE, &priv->regs->cfg[1]);
201*052cafd2SGuochun Mao
202*052cafd2SGuochun Mao if (len)
203*052cafd2SGuochun Mao return mtk_qspi_write_single_byte(priv, addr, len, buf);
204*052cafd2SGuochun Mao
205*052cafd2SGuochun Mao return 0;
206*052cafd2SGuochun Mao }
207*052cafd2SGuochun Mao
mtk_qspi_claim_bus(struct udevice * dev)208*052cafd2SGuochun Mao static int mtk_qspi_claim_bus(struct udevice *dev)
209*052cafd2SGuochun Mao {
210*052cafd2SGuochun Mao /* nothing to do */
211*052cafd2SGuochun Mao return 0;
212*052cafd2SGuochun Mao }
213*052cafd2SGuochun Mao
mtk_qspi_release_bus(struct udevice * dev)214*052cafd2SGuochun Mao static int mtk_qspi_release_bus(struct udevice *dev)
215*052cafd2SGuochun Mao {
216*052cafd2SGuochun Mao /* nothing to do */
217*052cafd2SGuochun Mao return 0;
218*052cafd2SGuochun Mao }
219*052cafd2SGuochun Mao
mtk_qspi_transfer(struct mtk_qspi_priv * priv,unsigned int bitlen,const void * dout,void * din,unsigned long flags)220*052cafd2SGuochun Mao static int mtk_qspi_transfer(struct mtk_qspi_priv *priv, unsigned int bitlen,
221*052cafd2SGuochun Mao const void *dout, void *din, unsigned long flags)
222*052cafd2SGuochun Mao {
223*052cafd2SGuochun Mao u32 bytes = DIV_ROUND_UP(bitlen, 8);
224*052cafd2SGuochun Mao u32 addr;
225*052cafd2SGuochun Mao
226*052cafd2SGuochun Mao if (!bytes)
227*052cafd2SGuochun Mao return -ERR_INVAL;
228*052cafd2SGuochun Mao
229*052cafd2SGuochun Mao if (dout) {
230*052cafd2SGuochun Mao if (flags & SPI_XFER_BEGIN) {
231*052cafd2SGuochun Mao /* parse op code and potential paras first */
232*052cafd2SGuochun Mao priv->op = *(u8 *)dout;
233*052cafd2SGuochun Mao if (bytes > 1)
234*052cafd2SGuochun Mao memcpy(priv->tx, (u8 *)dout + 1,
235*052cafd2SGuochun Mao bytes <= 4 ? bytes - 1 : 3);
236*052cafd2SGuochun Mao priv->txlen = bytes - 1;
237*052cafd2SGuochun Mao }
238*052cafd2SGuochun Mao
239*052cafd2SGuochun Mao if (flags == SPI_XFER_ONCE) {
240*052cafd2SGuochun Mao /* operations without receiving or sending data.
241*052cafd2SGuochun Mao * for example: erase, write flash register or write
242*052cafd2SGuochun Mao * enable...
243*052cafd2SGuochun Mao */
244*052cafd2SGuochun Mao priv->rx = NULL;
245*052cafd2SGuochun Mao priv->rxlen = 0;
246*052cafd2SGuochun Mao return mtk_qspi_tx_rx(priv);
247*052cafd2SGuochun Mao }
248*052cafd2SGuochun Mao
249*052cafd2SGuochun Mao if (flags & SPI_XFER_END) {
250*052cafd2SGuochun Mao /* here, dout should be data to be written.
251*052cafd2SGuochun Mao * and priv->tx should be filled 3Bytes address.
252*052cafd2SGuochun Mao */
253*052cafd2SGuochun Mao addr = priv->tx[0] << 16 | priv->tx[1] << 8 |
254*052cafd2SGuochun Mao priv->tx[2];
255*052cafd2SGuochun Mao return mtk_qspi_write(priv, addr, (u8 *)dout, bytes);
256*052cafd2SGuochun Mao }
257*052cafd2SGuochun Mao }
258*052cafd2SGuochun Mao
259*052cafd2SGuochun Mao if (din) {
260*052cafd2SGuochun Mao if (priv->txlen >= 3) {
261*052cafd2SGuochun Mao /* if run to here, priv->tx[] should be the address
262*052cafd2SGuochun Mao * where read data from,
263*052cafd2SGuochun Mao * and, din is the buf to receive data.
264*052cafd2SGuochun Mao */
265*052cafd2SGuochun Mao addr = priv->tx[0] << 16 | priv->tx[1] << 8 |
266*052cafd2SGuochun Mao priv->tx[2];
267*052cafd2SGuochun Mao return mtk_qspi_read(priv, addr, (u8 *)din, bytes);
268*052cafd2SGuochun Mao }
269*052cafd2SGuochun Mao
270*052cafd2SGuochun Mao /* should be reading flash's register */
271*052cafd2SGuochun Mao priv->rx = (u8 *)din;
272*052cafd2SGuochun Mao priv->rxlen = bytes;
273*052cafd2SGuochun Mao return mtk_qspi_tx_rx(priv);
274*052cafd2SGuochun Mao }
275*052cafd2SGuochun Mao
276*052cafd2SGuochun Mao return 0;
277*052cafd2SGuochun Mao }
278*052cafd2SGuochun Mao
mtk_qspi_xfer(struct udevice * dev,unsigned int bitlen,const void * dout,void * din,unsigned long flags)279*052cafd2SGuochun Mao static int mtk_qspi_xfer(struct udevice *dev, unsigned int bitlen,
280*052cafd2SGuochun Mao const void *dout, void *din, unsigned long flags)
281*052cafd2SGuochun Mao {
282*052cafd2SGuochun Mao struct udevice *bus = dev->parent;
283*052cafd2SGuochun Mao struct mtk_qspi_priv *priv = dev_get_priv(bus);
284*052cafd2SGuochun Mao
285*052cafd2SGuochun Mao return mtk_qspi_transfer(priv, bitlen, dout, din, flags);
286*052cafd2SGuochun Mao }
287*052cafd2SGuochun Mao
mtk_qspi_set_speed(struct udevice * bus,uint speed)288*052cafd2SGuochun Mao static int mtk_qspi_set_speed(struct udevice *bus, uint speed)
289*052cafd2SGuochun Mao {
290*052cafd2SGuochun Mao /* nothing to do */
291*052cafd2SGuochun Mao return 0;
292*052cafd2SGuochun Mao }
293*052cafd2SGuochun Mao
mtk_qspi_set_mode(struct udevice * bus,uint mode)294*052cafd2SGuochun Mao static int mtk_qspi_set_mode(struct udevice *bus, uint mode)
295*052cafd2SGuochun Mao {
296*052cafd2SGuochun Mao /* nothing to do */
297*052cafd2SGuochun Mao return 0;
298*052cafd2SGuochun Mao }
299*052cafd2SGuochun Mao
mtk_qspi_ofdata_to_platdata(struct udevice * bus)300*052cafd2SGuochun Mao static int mtk_qspi_ofdata_to_platdata(struct udevice *bus)
301*052cafd2SGuochun Mao {
302*052cafd2SGuochun Mao struct resource res_reg, res_mem;
303*052cafd2SGuochun Mao struct mtk_qspi_platdata *plat = bus->platdata;
304*052cafd2SGuochun Mao int ret;
305*052cafd2SGuochun Mao
306*052cafd2SGuochun Mao ret = dev_read_resource_byname(bus, "reg_base", &res_reg);
307*052cafd2SGuochun Mao if (ret) {
308*052cafd2SGuochun Mao debug("can't get reg_base resource(ret = %d)\n", ret);
309*052cafd2SGuochun Mao return -ENOMEM;
310*052cafd2SGuochun Mao }
311*052cafd2SGuochun Mao
312*052cafd2SGuochun Mao ret = dev_read_resource_byname(bus, "mem_base", &res_mem);
313*052cafd2SGuochun Mao if (ret) {
314*052cafd2SGuochun Mao debug("can't get map_base resource(ret = %d)\n", ret);
315*052cafd2SGuochun Mao return -ENOMEM;
316*052cafd2SGuochun Mao }
317*052cafd2SGuochun Mao
318*052cafd2SGuochun Mao plat->mem_base = res_mem.start;
319*052cafd2SGuochun Mao plat->reg_base = res_reg.start;
320*052cafd2SGuochun Mao
321*052cafd2SGuochun Mao return 0;
322*052cafd2SGuochun Mao }
323*052cafd2SGuochun Mao
mtk_qspi_probe(struct udevice * bus)324*052cafd2SGuochun Mao static int mtk_qspi_probe(struct udevice *bus)
325*052cafd2SGuochun Mao {
326*052cafd2SGuochun Mao struct mtk_qspi_platdata *plat = dev_get_platdata(bus);
327*052cafd2SGuochun Mao struct mtk_qspi_priv *priv = dev_get_priv(bus);
328*052cafd2SGuochun Mao
329*052cafd2SGuochun Mao priv->regs = (struct mtk_qspi_regs *)plat->reg_base;
330*052cafd2SGuochun Mao priv->mem_base = (unsigned long *)plat->mem_base;
331*052cafd2SGuochun Mao
332*052cafd2SGuochun Mao writel(MTK_QSPI_COMMAND_ENABLE, &priv->regs->wrprot);
333*052cafd2SGuochun Mao
334*052cafd2SGuochun Mao return 0;
335*052cafd2SGuochun Mao }
336*052cafd2SGuochun Mao
337*052cafd2SGuochun Mao static const struct dm_spi_ops mtk_qspi_ops = {
338*052cafd2SGuochun Mao .claim_bus = mtk_qspi_claim_bus,
339*052cafd2SGuochun Mao .release_bus = mtk_qspi_release_bus,
340*052cafd2SGuochun Mao .xfer = mtk_qspi_xfer,
341*052cafd2SGuochun Mao .set_speed = mtk_qspi_set_speed,
342*052cafd2SGuochun Mao .set_mode = mtk_qspi_set_mode,
343*052cafd2SGuochun Mao };
344*052cafd2SGuochun Mao
345*052cafd2SGuochun Mao static const struct udevice_id mtk_qspi_ids[] = {
346*052cafd2SGuochun Mao { .compatible = "mediatek,mt7629-qspi" },
347*052cafd2SGuochun Mao { }
348*052cafd2SGuochun Mao };
349*052cafd2SGuochun Mao
350*052cafd2SGuochun Mao U_BOOT_DRIVER(mtk_qspi) = {
351*052cafd2SGuochun Mao .name = "mtk_qspi",
352*052cafd2SGuochun Mao .id = UCLASS_SPI,
353*052cafd2SGuochun Mao .of_match = mtk_qspi_ids,
354*052cafd2SGuochun Mao .ops = &mtk_qspi_ops,
355*052cafd2SGuochun Mao .ofdata_to_platdata = mtk_qspi_ofdata_to_platdata,
356*052cafd2SGuochun Mao .platdata_auto_alloc_size = sizeof(struct mtk_qspi_platdata),
357*052cafd2SGuochun Mao .priv_auto_alloc_size = sizeof(struct mtk_qspi_priv),
358*052cafd2SGuochun Mao .probe = mtk_qspi_probe,
359*052cafd2SGuochun Mao };
360