Merge branch 'for-6.9/amd-sfh' into for-linus
[sfrench/cifs-2.6.git] / drivers / spmi / spmi-mtk-pmif.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (c) 2021 MediaTek Inc.
4
5 #include <linux/clk.h>
6 #include <linux/iopoll.h>
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/platform_device.h>
10 #include <linux/property.h>
11 #include <linux/spmi.h>
12
13 #define SWINF_IDLE      0x00
14 #define SWINF_WFVLDCLR  0x06
15
16 #define GET_SWINF(x)    (((x) >> 1) & 0x7)
17
18 #define PMIF_CMD_REG_0          0
19 #define PMIF_CMD_REG            1
20 #define PMIF_CMD_EXT_REG        2
21 #define PMIF_CMD_EXT_REG_LONG   3
22
23 #define PMIF_DELAY_US   10
24 #define PMIF_TIMEOUT_US (10 * 1000)
25
26 #define PMIF_CHAN_OFFSET 0x5
27
28 #define PMIF_MAX_CLKS   3
29
30 #define SPMI_OP_ST_BUSY 1
31
32 struct ch_reg {
33         u32 ch_sta;
34         u32 wdata;
35         u32 rdata;
36         u32 ch_send;
37         u32 ch_rdy;
38 };
39
40 struct pmif_data {
41         const u32       *regs;
42         const u32       *spmimst_regs;
43         u32     soc_chan;
44 };
45
46 struct pmif {
47         void __iomem    *base;
48         void __iomem    *spmimst_base;
49         struct ch_reg   chan;
50         struct clk_bulk_data clks[PMIF_MAX_CLKS];
51         size_t nclks;
52         const struct pmif_data *data;
53         raw_spinlock_t lock;
54 };
55
56 static const char * const pmif_clock_names[] = {
57         "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux",
58 };
59
60 enum pmif_regs {
61         PMIF_INIT_DONE,
62         PMIF_INF_EN,
63         PMIF_ARB_EN,
64         PMIF_CMDISSUE_EN,
65         PMIF_TIMER_CTRL,
66         PMIF_SPI_MODE_CTRL,
67         PMIF_IRQ_EVENT_EN_0,
68         PMIF_IRQ_FLAG_0,
69         PMIF_IRQ_CLR_0,
70         PMIF_IRQ_EVENT_EN_1,
71         PMIF_IRQ_FLAG_1,
72         PMIF_IRQ_CLR_1,
73         PMIF_IRQ_EVENT_EN_2,
74         PMIF_IRQ_FLAG_2,
75         PMIF_IRQ_CLR_2,
76         PMIF_IRQ_EVENT_EN_3,
77         PMIF_IRQ_FLAG_3,
78         PMIF_IRQ_CLR_3,
79         PMIF_IRQ_EVENT_EN_4,
80         PMIF_IRQ_FLAG_4,
81         PMIF_IRQ_CLR_4,
82         PMIF_WDT_EVENT_EN_0,
83         PMIF_WDT_FLAG_0,
84         PMIF_WDT_EVENT_EN_1,
85         PMIF_WDT_FLAG_1,
86         PMIF_SWINF_0_STA,
87         PMIF_SWINF_0_WDATA_31_0,
88         PMIF_SWINF_0_RDATA_31_0,
89         PMIF_SWINF_0_ACC,
90         PMIF_SWINF_0_VLD_CLR,
91         PMIF_SWINF_1_STA,
92         PMIF_SWINF_1_WDATA_31_0,
93         PMIF_SWINF_1_RDATA_31_0,
94         PMIF_SWINF_1_ACC,
95         PMIF_SWINF_1_VLD_CLR,
96         PMIF_SWINF_2_STA,
97         PMIF_SWINF_2_WDATA_31_0,
98         PMIF_SWINF_2_RDATA_31_0,
99         PMIF_SWINF_2_ACC,
100         PMIF_SWINF_2_VLD_CLR,
101         PMIF_SWINF_3_STA,
102         PMIF_SWINF_3_WDATA_31_0,
103         PMIF_SWINF_3_RDATA_31_0,
104         PMIF_SWINF_3_ACC,
105         PMIF_SWINF_3_VLD_CLR,
106 };
107
108 static const u32 mt6873_regs[] = {
109         [PMIF_INIT_DONE] = 0x0000,
110         [PMIF_INF_EN] = 0x0024,
111         [PMIF_ARB_EN] = 0x0150,
112         [PMIF_CMDISSUE_EN] = 0x03B4,
113         [PMIF_TIMER_CTRL] = 0x03E0,
114         [PMIF_SPI_MODE_CTRL] = 0x0400,
115         [PMIF_IRQ_EVENT_EN_0] = 0x0418,
116         [PMIF_IRQ_FLAG_0] = 0x0420,
117         [PMIF_IRQ_CLR_0] = 0x0424,
118         [PMIF_IRQ_EVENT_EN_1] = 0x0428,
119         [PMIF_IRQ_FLAG_1] = 0x0430,
120         [PMIF_IRQ_CLR_1] = 0x0434,
121         [PMIF_IRQ_EVENT_EN_2] = 0x0438,
122         [PMIF_IRQ_FLAG_2] = 0x0440,
123         [PMIF_IRQ_CLR_2] = 0x0444,
124         [PMIF_IRQ_EVENT_EN_3] = 0x0448,
125         [PMIF_IRQ_FLAG_3] = 0x0450,
126         [PMIF_IRQ_CLR_3] = 0x0454,
127         [PMIF_IRQ_EVENT_EN_4] = 0x0458,
128         [PMIF_IRQ_FLAG_4] = 0x0460,
129         [PMIF_IRQ_CLR_4] = 0x0464,
130         [PMIF_WDT_EVENT_EN_0] = 0x046C,
131         [PMIF_WDT_FLAG_0] = 0x0470,
132         [PMIF_WDT_EVENT_EN_1] = 0x0474,
133         [PMIF_WDT_FLAG_1] = 0x0478,
134         [PMIF_SWINF_0_ACC] = 0x0C00,
135         [PMIF_SWINF_0_WDATA_31_0] = 0x0C04,
136         [PMIF_SWINF_0_RDATA_31_0] = 0x0C14,
137         [PMIF_SWINF_0_VLD_CLR] = 0x0C24,
138         [PMIF_SWINF_0_STA] = 0x0C28,
139         [PMIF_SWINF_1_ACC] = 0x0C40,
140         [PMIF_SWINF_1_WDATA_31_0] = 0x0C44,
141         [PMIF_SWINF_1_RDATA_31_0] = 0x0C54,
142         [PMIF_SWINF_1_VLD_CLR] = 0x0C64,
143         [PMIF_SWINF_1_STA] = 0x0C68,
144         [PMIF_SWINF_2_ACC] = 0x0C80,
145         [PMIF_SWINF_2_WDATA_31_0] = 0x0C84,
146         [PMIF_SWINF_2_RDATA_31_0] = 0x0C94,
147         [PMIF_SWINF_2_VLD_CLR] = 0x0CA4,
148         [PMIF_SWINF_2_STA] = 0x0CA8,
149         [PMIF_SWINF_3_ACC] = 0x0CC0,
150         [PMIF_SWINF_3_WDATA_31_0] = 0x0CC4,
151         [PMIF_SWINF_3_RDATA_31_0] = 0x0CD4,
152         [PMIF_SWINF_3_VLD_CLR] = 0x0CE4,
153         [PMIF_SWINF_3_STA] = 0x0CE8,
154 };
155
156 static const u32 mt8195_regs[] = {
157         [PMIF_INIT_DONE] = 0x0000,
158         [PMIF_INF_EN] = 0x0024,
159         [PMIF_ARB_EN] = 0x0150,
160         [PMIF_CMDISSUE_EN] = 0x03B8,
161         [PMIF_TIMER_CTRL] = 0x03E4,
162         [PMIF_SPI_MODE_CTRL] = 0x0408,
163         [PMIF_IRQ_EVENT_EN_0] = 0x0420,
164         [PMIF_IRQ_FLAG_0] = 0x0428,
165         [PMIF_IRQ_CLR_0] = 0x042C,
166         [PMIF_IRQ_EVENT_EN_1] = 0x0430,
167         [PMIF_IRQ_FLAG_1] = 0x0438,
168         [PMIF_IRQ_CLR_1] = 0x043C,
169         [PMIF_IRQ_EVENT_EN_2] = 0x0440,
170         [PMIF_IRQ_FLAG_2] = 0x0448,
171         [PMIF_IRQ_CLR_2] = 0x044C,
172         [PMIF_IRQ_EVENT_EN_3] = 0x0450,
173         [PMIF_IRQ_FLAG_3] = 0x0458,
174         [PMIF_IRQ_CLR_3] = 0x045C,
175         [PMIF_IRQ_EVENT_EN_4] = 0x0460,
176         [PMIF_IRQ_FLAG_4] = 0x0468,
177         [PMIF_IRQ_CLR_4] = 0x046C,
178         [PMIF_WDT_EVENT_EN_0] = 0x0474,
179         [PMIF_WDT_FLAG_0] = 0x0478,
180         [PMIF_WDT_EVENT_EN_1] = 0x047C,
181         [PMIF_WDT_FLAG_1] = 0x0480,
182         [PMIF_SWINF_0_ACC] = 0x0800,
183         [PMIF_SWINF_0_WDATA_31_0] = 0x0804,
184         [PMIF_SWINF_0_RDATA_31_0] = 0x0814,
185         [PMIF_SWINF_0_VLD_CLR] = 0x0824,
186         [PMIF_SWINF_0_STA] = 0x0828,
187         [PMIF_SWINF_1_ACC] = 0x0840,
188         [PMIF_SWINF_1_WDATA_31_0] = 0x0844,
189         [PMIF_SWINF_1_RDATA_31_0] = 0x0854,
190         [PMIF_SWINF_1_VLD_CLR] = 0x0864,
191         [PMIF_SWINF_1_STA] = 0x0868,
192         [PMIF_SWINF_2_ACC] = 0x0880,
193         [PMIF_SWINF_2_WDATA_31_0] = 0x0884,
194         [PMIF_SWINF_2_RDATA_31_0] = 0x0894,
195         [PMIF_SWINF_2_VLD_CLR] = 0x08A4,
196         [PMIF_SWINF_2_STA] = 0x08A8,
197         [PMIF_SWINF_3_ACC] = 0x08C0,
198         [PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
199         [PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
200         [PMIF_SWINF_3_VLD_CLR] = 0x08E4,
201         [PMIF_SWINF_3_STA] = 0x08E8,
202 };
203
204 enum spmi_regs {
205         SPMI_OP_ST_CTRL,
206         SPMI_GRP_ID_EN,
207         SPMI_OP_ST_STA,
208         SPMI_MST_SAMPL,
209         SPMI_MST_REQ_EN,
210         SPMI_REC_CTRL,
211         SPMI_REC0,
212         SPMI_REC1,
213         SPMI_REC2,
214         SPMI_REC3,
215         SPMI_REC4,
216         SPMI_MST_DBG,
217
218         /* MT8195 spmi regs */
219         SPMI_MST_RCS_CTRL,
220         SPMI_SLV_3_0_EINT,
221         SPMI_SLV_7_4_EINT,
222         SPMI_SLV_B_8_EINT,
223         SPMI_SLV_F_C_EINT,
224         SPMI_REC_CMD_DEC,
225         SPMI_DEC_DBG,
226 };
227
228 static const u32 mt6873_spmi_regs[] = {
229         [SPMI_OP_ST_CTRL] = 0x0000,
230         [SPMI_GRP_ID_EN] = 0x0004,
231         [SPMI_OP_ST_STA] = 0x0008,
232         [SPMI_MST_SAMPL] = 0x000c,
233         [SPMI_MST_REQ_EN] = 0x0010,
234         [SPMI_REC_CTRL] = 0x0040,
235         [SPMI_REC0] = 0x0044,
236         [SPMI_REC1] = 0x0048,
237         [SPMI_REC2] = 0x004c,
238         [SPMI_REC3] = 0x0050,
239         [SPMI_REC4] = 0x0054,
240         [SPMI_MST_DBG] = 0x00fc,
241 };
242
243 static const u32 mt8195_spmi_regs[] = {
244         [SPMI_OP_ST_CTRL] = 0x0000,
245         [SPMI_GRP_ID_EN] = 0x0004,
246         [SPMI_OP_ST_STA] = 0x0008,
247         [SPMI_MST_SAMPL] = 0x000C,
248         [SPMI_MST_REQ_EN] = 0x0010,
249         [SPMI_MST_RCS_CTRL] = 0x0014,
250         [SPMI_SLV_3_0_EINT] = 0x0020,
251         [SPMI_SLV_7_4_EINT] = 0x0024,
252         [SPMI_SLV_B_8_EINT] = 0x0028,
253         [SPMI_SLV_F_C_EINT] = 0x002C,
254         [SPMI_REC_CTRL] = 0x0040,
255         [SPMI_REC0] = 0x0044,
256         [SPMI_REC1] = 0x0048,
257         [SPMI_REC2] = 0x004C,
258         [SPMI_REC3] = 0x0050,
259         [SPMI_REC4] = 0x0054,
260         [SPMI_REC_CMD_DEC] = 0x005C,
261         [SPMI_DEC_DBG] = 0x00F8,
262         [SPMI_MST_DBG] = 0x00FC,
263 };
264
265 static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg)
266 {
267         return readl(arb->base + arb->data->regs[reg]);
268 }
269
270 static void pmif_writel(struct pmif *arb, u32 val, enum pmif_regs reg)
271 {
272         writel(val, arb->base + arb->data->regs[reg]);
273 }
274
275 static void mtk_spmi_writel(struct pmif *arb, u32 val, enum spmi_regs reg)
276 {
277         writel(val, arb->spmimst_base + arb->data->spmimst_regs[reg]);
278 }
279
280 static bool pmif_is_fsm_vldclr(struct pmif *arb)
281 {
282         u32 reg_rdata;
283
284         reg_rdata = pmif_readl(arb, arb->chan.ch_sta);
285
286         return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR;
287 }
288
289 static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
290 {
291         struct pmif *arb = spmi_controller_get_drvdata(ctrl);
292         u32 rdata, cmd;
293         int ret;
294
295         /* Check the opcode */
296         if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
297                 return -EINVAL;
298
299         cmd = opc - SPMI_CMD_RESET;
300
301         mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL);
302         ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA],
303                                         rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY,
304                                         PMIF_DELAY_US, PMIF_TIMEOUT_US);
305         if (ret < 0)
306                 dev_err(&ctrl->dev, "timeout, err = %d\n", ret);
307
308         return ret;
309 }
310
311 static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
312                               u16 addr, u8 *buf, size_t len)
313 {
314         struct pmif *arb = spmi_controller_get_drvdata(ctrl);
315         struct ch_reg *inf_reg;
316         int ret;
317         u32 data, cmd;
318         unsigned long flags;
319
320         /* Check for argument validation. */
321         if (sid & ~0xf) {
322                 dev_err(&ctrl->dev, "exceed the max slv id\n");
323                 return -EINVAL;
324         }
325
326         if (len > 4) {
327                 dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
328
329                 return -EINVAL;
330         }
331
332         if (opc >= 0x60 && opc <= 0x7f)
333                 opc = PMIF_CMD_REG;
334         else if ((opc >= 0x20 && opc <= 0x2f) || (opc >= 0x38 && opc <= 0x3f))
335                 opc = PMIF_CMD_EXT_REG_LONG;
336         else
337                 return -EINVAL;
338
339         raw_spin_lock_irqsave(&arb->lock, flags);
340         /* Wait for Software Interface FSM state to be IDLE. */
341         inf_reg = &arb->chan;
342         ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
343                                         data, GET_SWINF(data) == SWINF_IDLE,
344                                         PMIF_DELAY_US, PMIF_TIMEOUT_US);
345         if (ret < 0) {
346                 /* set channel ready if the data has transferred */
347                 if (pmif_is_fsm_vldclr(arb))
348                         pmif_writel(arb, 1, inf_reg->ch_rdy);
349                 raw_spin_unlock_irqrestore(&arb->lock, flags);
350                 dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
351                 return ret;
352         }
353
354         /* Send the command. */
355         cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr;
356         pmif_writel(arb, cmd, inf_reg->ch_send);
357         raw_spin_unlock_irqrestore(&arb->lock, flags);
358
359         /*
360          * Wait for Software Interface FSM state to be WFVLDCLR,
361          * read the data and clear the valid flag.
362          */
363         ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
364                                         data, GET_SWINF(data) == SWINF_WFVLDCLR,
365                                         PMIF_DELAY_US, PMIF_TIMEOUT_US);
366         if (ret < 0) {
367                 dev_err(&ctrl->dev, "failed to wait for SWINF_WFVLDCLR\n");
368                 return ret;
369         }
370
371         data = pmif_readl(arb, inf_reg->rdata);
372         memcpy(buf, &data, len);
373         pmif_writel(arb, 1, inf_reg->ch_rdy);
374
375         return 0;
376 }
377
378 static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
379                                u16 addr, const u8 *buf, size_t len)
380 {
381         struct pmif *arb = spmi_controller_get_drvdata(ctrl);
382         struct ch_reg *inf_reg;
383         int ret;
384         u32 data, wdata, cmd;
385         unsigned long flags;
386
387         /* Check for argument validation. */
388         if (unlikely(sid & ~0xf)) {
389                 dev_err(&ctrl->dev, "exceed the max slv id\n");
390                 return -EINVAL;
391         }
392
393         if (len > 4) {
394                 dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
395
396                 return -EINVAL;
397         }
398
399         /* Check the opcode */
400         if (opc >= 0x40 && opc <= 0x5F)
401                 opc = PMIF_CMD_REG;
402         else if ((opc <= 0xF) || (opc >= 0x30 && opc <= 0x37))
403                 opc = PMIF_CMD_EXT_REG_LONG;
404         else if (opc >= 0x80)
405                 opc = PMIF_CMD_REG_0;
406         else
407                 return -EINVAL;
408
409         /* Set the write data. */
410         memcpy(&wdata, buf, len);
411
412         raw_spin_lock_irqsave(&arb->lock, flags);
413         /* Wait for Software Interface FSM state to be IDLE. */
414         inf_reg = &arb->chan;
415         ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
416                                         data, GET_SWINF(data) == SWINF_IDLE,
417                                         PMIF_DELAY_US, PMIF_TIMEOUT_US);
418         if (ret < 0) {
419                 /* set channel ready if the data has transferred */
420                 if (pmif_is_fsm_vldclr(arb))
421                         pmif_writel(arb, 1, inf_reg->ch_rdy);
422                 raw_spin_unlock_irqrestore(&arb->lock, flags);
423                 dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
424                 return ret;
425         }
426
427         pmif_writel(arb, wdata, inf_reg->wdata);
428
429         /* Send the command. */
430         cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr;
431         pmif_writel(arb, cmd, inf_reg->ch_send);
432         raw_spin_unlock_irqrestore(&arb->lock, flags);
433
434         return 0;
435 }
436
437 static const struct pmif_data mt6873_pmif_arb = {
438         .regs = mt6873_regs,
439         .spmimst_regs = mt6873_spmi_regs,
440         .soc_chan = 2,
441 };
442
443 static const struct pmif_data mt8195_pmif_arb = {
444         .regs = mt8195_regs,
445         .spmimst_regs = mt8195_spmi_regs,
446         .soc_chan = 2,
447 };
448
449 static int mtk_spmi_probe(struct platform_device *pdev)
450 {
451         struct pmif *arb;
452         struct spmi_controller *ctrl;
453         int err, i;
454         u32 chan_offset;
455
456         ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*arb));
457         if (IS_ERR(ctrl))
458                 return PTR_ERR(ctrl);
459
460         arb = spmi_controller_get_drvdata(ctrl);
461         arb->data = device_get_match_data(&pdev->dev);
462         if (!arb->data) {
463                 dev_err(&pdev->dev, "Cannot get drv_data\n");
464                 return -EINVAL;
465         }
466
467         arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif");
468         if (IS_ERR(arb->base))
469                 return PTR_ERR(arb->base);
470
471         arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst");
472         if (IS_ERR(arb->spmimst_base))
473                 return PTR_ERR(arb->spmimst_base);
474
475         arb->nclks = ARRAY_SIZE(pmif_clock_names);
476         for (i = 0; i < arb->nclks; i++)
477                 arb->clks[i].id = pmif_clock_names[i];
478
479         err = clk_bulk_get(&pdev->dev, arb->nclks, arb->clks);
480         if (err) {
481                 dev_err(&pdev->dev, "Failed to get clocks: %d\n", err);
482                 return err;
483         }
484
485         err = clk_bulk_prepare_enable(arb->nclks, arb->clks);
486         if (err) {
487                 dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err);
488                 goto err_put_clks;
489         }
490
491         ctrl->cmd = pmif_arb_cmd;
492         ctrl->read_cmd = pmif_spmi_read_cmd;
493         ctrl->write_cmd = pmif_spmi_write_cmd;
494
495         chan_offset = PMIF_CHAN_OFFSET * arb->data->soc_chan;
496         arb->chan.ch_sta = PMIF_SWINF_0_STA + chan_offset;
497         arb->chan.wdata = PMIF_SWINF_0_WDATA_31_0 + chan_offset;
498         arb->chan.rdata = PMIF_SWINF_0_RDATA_31_0 + chan_offset;
499         arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset;
500         arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset;
501
502         raw_spin_lock_init(&arb->lock);
503
504         platform_set_drvdata(pdev, ctrl);
505
506         err = spmi_controller_add(ctrl);
507         if (err)
508                 goto err_domain_remove;
509
510         return 0;
511
512 err_domain_remove:
513         clk_bulk_disable_unprepare(arb->nclks, arb->clks);
514 err_put_clks:
515         clk_bulk_put(arb->nclks, arb->clks);
516         return err;
517 }
518
519 static void mtk_spmi_remove(struct platform_device *pdev)
520 {
521         struct spmi_controller *ctrl = platform_get_drvdata(pdev);
522         struct pmif *arb = spmi_controller_get_drvdata(ctrl);
523
524         spmi_controller_remove(ctrl);
525         clk_bulk_disable_unprepare(arb->nclks, arb->clks);
526         clk_bulk_put(arb->nclks, arb->clks);
527 }
528
529 static const struct of_device_id mtk_spmi_match_table[] = {
530         {
531                 .compatible = "mediatek,mt6873-spmi",
532                 .data = &mt6873_pmif_arb,
533         }, {
534                 .compatible = "mediatek,mt8195-spmi",
535                 .data = &mt8195_pmif_arb,
536         }, {
537                 /* sentinel */
538         },
539 };
540 MODULE_DEVICE_TABLE(of, mtk_spmi_match_table);
541
542 static struct platform_driver mtk_spmi_driver = {
543         .driver         = {
544                 .name   = "spmi-mtk",
545                 .of_match_table = mtk_spmi_match_table,
546         },
547         .probe          = mtk_spmi_probe,
548         .remove_new     = mtk_spmi_remove,
549 };
550 module_platform_driver(mtk_spmi_driver);
551
552 MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
553 MODULE_DESCRIPTION("MediaTek SPMI Driver");
554 MODULE_LICENSE("GPL");