mailbox: rk3868 change max_chan_num attribute to static
[firefly-linux-kernel-4.4.55.git] / drivers / mailbox / scpi_protocol.c
1 /*
2  * System Control and Power Interface (SCPI) Message Protocol driver
3  *
4  * Copyright (C) 2014 ARM Ltd.
5  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/err.h>
22 #include <linux/export.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/printk.h>
26 #include <linux/mailbox_client.h>
27 #include <linux/scpi_protocol.h>
28 #include <linux/slab.h>
29 #include <linux/rockchip-mailbox.h>
30 #include <linux/rockchip/common.h>
31
32 #include "scpi_cmd.h"
33
34 #define CMD_ID_SHIFT            0
35 #define CMD_ID_MASK             0xff
36 #define CMD_SENDER_ID_SHIFT     8
37 #define CMD_SENDER_ID_MASK      0xff
38 #define CMD_DATA_SIZE_SHIFT     20
39 #define CMD_DATA_SIZE_MASK      0x1ff
40 #define PACK_SCPI_CMD(cmd, sender, txsz)                                \
41         ((((cmd) & CMD_ID_MASK) << CMD_ID_SHIFT) |                      \
42         (((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) |      \
43         (((txsz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
44 #define SCPI_CMD_DEFAULT_TIMEOUT_MS  1000
45
46 #define MAX_DVFS_DOMAINS        3
47 #define MAX_DVFS_OPPS           8
48 #define DVFS_LATENCY(hdr)       ((hdr) >> 16)
49 #define DVFS_OPP_COUNT(hdr)     (((hdr) >> 8) & 0xff)
50
51 static int max_chan_num = 0;
52 static DECLARE_BITMAP(bm_mbox_chans, 4);
53 static DEFINE_MUTEX(scpi_mtx);
54
55 struct scpi_data_buf {
56         int client_id;
57         struct rockchip_mbox_msg *data;
58         struct completion complete;
59         int timeout_ms;
60 };
61
62 static int high_priority_cmds[] = {
63         SCPI_CMD_GET_CSS_PWR_STATE,
64         SCPI_CMD_CFG_PWR_STATE_STAT,
65         SCPI_CMD_GET_PWR_STATE_STAT,
66         SCPI_CMD_SET_DVFS,
67         SCPI_CMD_GET_DVFS,
68         SCPI_CMD_SET_RTC,
69         SCPI_CMD_GET_RTC,
70         SCPI_CMD_SET_CLOCK_INDEX,
71         SCPI_CMD_SET_CLOCK_VALUE,
72         SCPI_CMD_GET_CLOCK_VALUE,
73         SCPI_CMD_SET_PSU,
74         SCPI_CMD_GET_PSU,
75         SCPI_CMD_SENSOR_CFG_PERIODIC,
76         SCPI_CMD_SENSOR_CFG_BOUNDS,
77 };
78
79 static struct scpi_opp *scpi_opps[MAX_DVFS_DOMAINS];
80
81 static struct device *the_scpi_device;
82
83 static int scpi_linux_errmap[SCPI_ERR_MAX] = {
84         0, -EINVAL, -ENOEXEC, -EMSGSIZE,
85         -EINVAL, -EACCES, -ERANGE, -ETIMEDOUT,
86         -ENOMEM, -EINVAL, -EOPNOTSUPP, -EIO,
87 };
88
89 static inline int scpi_to_linux_errno(int errno)
90 {
91         if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
92                 return scpi_linux_errmap[errno];
93         return -EIO;
94 }
95
96 static bool __maybe_unused high_priority_chan_supported(int cmd)
97 {
98         int idx;
99
100         for (idx = 0; idx < ARRAY_SIZE(high_priority_cmds); idx++)
101                 if (cmd == high_priority_cmds[idx])
102                         return true;
103         return false;
104 }
105
106 static int scpi_alloc_mbox_chan(void)
107 {
108         int index;
109
110         mutex_lock(&scpi_mtx);
111
112         index = find_first_zero_bit(bm_mbox_chans, max_chan_num);
113         if (index >= max_chan_num) {
114                 pr_err("alloc mailbox channel failed\n");
115                 mutex_unlock(&scpi_mtx);
116                 return -EBUSY;
117         }
118
119         set_bit(index, bm_mbox_chans);
120
121         mutex_unlock(&scpi_mtx);
122         return index;
123 }
124
125 static void scpi_free_mbox_chan(int chan)
126 {
127         int index = chan;
128
129         mutex_lock(&scpi_mtx);
130
131         if (index < max_chan_num && index >= 0)
132                 clear_bit(index, bm_mbox_chans);
133
134         mutex_unlock(&scpi_mtx);
135 }
136
137 static void scpi_rx_callback(struct mbox_client *cl, void *msg)
138 {
139         struct rockchip_mbox_msg *data = (struct rockchip_mbox_msg *)msg;
140         struct scpi_data_buf *scpi_buf = data->cl_data;
141
142         complete(&scpi_buf->complete);
143 }
144
145 static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int index)
146 {
147         struct mbox_chan *chan;
148         struct mbox_client cl;
149         struct rockchip_mbox_msg *data = scpi_buf->data;
150         u32 status;
151         int ret;
152         int timeout = msecs_to_jiffies(scpi_buf->timeout_ms);
153
154         if (!the_scpi_device) {
155                 pr_err("Scpi initializes unsuccessfully\n");
156                 return -EIO;
157         }
158
159         cl.dev = the_scpi_device;
160         cl.rx_callback = scpi_rx_callback;
161         cl.tx_done = NULL;
162         cl.tx_block = false;
163         cl.knows_txdone = false;
164
165         chan = mbox_request_channel(&cl, index);
166         if (IS_ERR(chan)) {
167                 scpi_free_mbox_chan(index);
168                 return PTR_ERR(chan);
169         }
170
171         init_completion(&scpi_buf->complete);
172         if (mbox_send_message(chan, (void *)data) < 0) {
173                 status = SCPI_ERR_TIMEOUT;
174                 goto free_channel;
175         }
176
177         ret = wait_for_completion_timeout(&scpi_buf->complete, timeout);
178         if (ret == 0) {
179                 status = SCPI_ERR_TIMEOUT;
180                 goto free_channel;
181         }
182         status = *(u32 *)(data->rx_buf); /* read first word */
183
184 free_channel:
185         mbox_free_channel(chan);
186         scpi_free_mbox_chan(index);
187
188         return scpi_to_linux_errno(status);
189 }
190
191 #define SCPI_SETUP_DBUF(scpi_buf, mbox_buf, _client_id,\
192                         _cmd, _tx_buf, _rx_buf) \
193 do {                                            \
194         struct rockchip_mbox_msg *pdata = &mbox_buf;    \
195         pdata->cmd = _cmd;                      \
196         pdata->tx_buf = &_tx_buf;               \
197         pdata->tx_size = sizeof(_tx_buf);       \
198         pdata->rx_buf = &_rx_buf;               \
199         pdata->rx_size = sizeof(_rx_buf);       \
200         scpi_buf.client_id = _client_id;        \
201         scpi_buf.data = pdata;                  \
202         scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
203 } while (0)
204
205 static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
206 {
207         struct rockchip_mbox_msg *data;
208         int index;
209
210         if (!scpi_buf || !scpi_buf->data)
211                 return -EINVAL;
212
213         index = scpi_alloc_mbox_chan();
214         if (index < 0)
215                 return -EBUSY;
216
217         data = scpi_buf->data;
218         data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
219                                   data->tx_size);
220         data->cl_data = scpi_buf;
221
222         return send_scpi_cmd(scpi_buf, index);
223 }
224
225 unsigned long scpi_clk_get_val(u16 clk_id)
226 {
227         struct scpi_data_buf sdata;
228         struct rockchip_mbox_msg mdata;
229         struct __packed {
230                 u32 status;
231                 u32 clk_rate;
232         } buf;
233
234         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
235                         SCPI_CMD_GET_CLOCK_VALUE, clk_id, buf);
236         if (scpi_execute_cmd(&sdata))
237                 return 0;
238
239         return buf.clk_rate;
240 }
241 EXPORT_SYMBOL_GPL(scpi_clk_get_val);
242
243 int scpi_clk_set_val(u16 clk_id, unsigned long rate)
244 {
245         struct scpi_data_buf sdata;
246         struct rockchip_mbox_msg mdata;
247         int stat;
248         struct __packed {
249                 u32 clk_rate;
250                 u16 clk_id;
251         } buf;
252
253         buf.clk_rate = (u32)rate;
254         buf.clk_id = clk_id;
255
256         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_CLOCKS,
257                         SCPI_CMD_SET_CLOCK_VALUE, buf, stat);
258         return scpi_execute_cmd(&sdata);
259 }
260 EXPORT_SYMBOL_GPL(scpi_clk_set_val);
261
262 struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
263 {
264         struct scpi_data_buf sdata;
265         struct rockchip_mbox_msg mdata;
266         struct __packed {
267                 u32 status;
268                 u32 header;
269                 struct scpi_opp_entry opp[MAX_DVFS_OPPS];
270         } buf;
271         struct scpi_opp *opps;
272         size_t opps_sz;
273         int count, ret;
274
275         if (domain >= MAX_DVFS_DOMAINS)
276                 return ERR_PTR(-EINVAL);
277
278         if (scpi_opps[domain])  /* data already populated */
279                 return scpi_opps[domain];
280
281         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
282                         SCPI_CMD_GET_DVFS_INFO, domain, buf);
283         ret = scpi_execute_cmd(&sdata);
284         if (ret)
285                 return ERR_PTR(ret);
286
287         opps = kmalloc(sizeof(*opps), GFP_KERNEL);
288         if (!opps)
289                 return ERR_PTR(-ENOMEM);
290
291         count = DVFS_OPP_COUNT(buf.header);
292         opps_sz = count * sizeof(*(opps->opp));
293
294         opps->count = count;
295         opps->latency = DVFS_LATENCY(buf.header);
296         opps->opp = kmalloc(opps_sz, GFP_KERNEL);
297         if (!opps->opp) {
298                 kfree(opps);
299                 return ERR_PTR(-ENOMEM);
300         }
301
302         memcpy(opps->opp, &buf.opp[0], opps_sz);
303         scpi_opps[domain] = opps;
304
305         return opps;
306 }
307 EXPORT_SYMBOL_GPL(scpi_dvfs_get_opps);
308
309 int scpi_dvfs_get_idx(u8 domain)
310 {
311         struct scpi_data_buf sdata;
312         struct rockchip_mbox_msg mdata;
313         struct __packed {
314                 u32 status;
315                 u8 dvfs_idx;
316         } buf;
317         int ret;
318
319         if (domain >= MAX_DVFS_DOMAINS)
320                 return -EINVAL;
321
322         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
323                         SCPI_CMD_GET_DVFS, domain, buf);
324         ret = scpi_execute_cmd(&sdata);
325
326         if (!ret)
327                 ret = buf.dvfs_idx;
328         return ret;
329 }
330 EXPORT_SYMBOL_GPL(scpi_dvfs_get_idx);
331
332 int scpi_dvfs_set_idx(u8 domain, u8 idx)
333 {
334         struct scpi_data_buf sdata;
335         struct rockchip_mbox_msg mdata;
336         struct __packed {
337                 u8 dvfs_domain;
338                 u8 dvfs_idx;
339         } buf;
340         int stat;
341
342         buf.dvfs_idx = idx;
343         buf.dvfs_domain = domain;
344
345         if (domain >= MAX_DVFS_DOMAINS)
346                 return -EINVAL;
347
348         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DVFS,
349                         SCPI_CMD_SET_DVFS, buf, stat);
350         return scpi_execute_cmd(&sdata);
351 }
352 EXPORT_SYMBOL_GPL(scpi_dvfs_set_idx);
353
354 int scpi_get_sensor(char *name)
355 {
356         struct scpi_data_buf sdata;
357         struct rockchip_mbox_msg mdata;
358         struct __packed {
359                 u32 status;
360                 u16 sensors;
361         } cap_buf;
362         struct __packed {
363                 u32 status;
364                 u16 sensor;
365                 u8 class;
366                 u8 trigger;
367                 char name[20];
368         } info_buf;
369         int ret;
370         u16 sensor_id;
371
372         /* This should be handled by a generic macro */
373         do {
374                 struct rockchip_mbox_msg *pdata = &mdata;
375
376                 pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
377                 pdata->tx_size = 0;
378                 pdata->rx_buf = &cap_buf;
379                 pdata->rx_size = sizeof(cap_buf);
380                 sdata.client_id = SCPI_CL_THERMAL;
381                 sdata.data = pdata;
382         } while (0);
383
384         ret = scpi_execute_cmd(&sdata);
385         if (ret)
386                 goto out;
387
388         ret = -ENODEV;
389         for (sensor_id = 0; sensor_id < cap_buf.sensors; sensor_id++) {
390                 SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
391                                 SCPI_CMD_SENSOR_INFO, sensor_id, info_buf);
392                 ret = scpi_execute_cmd(&sdata);
393                 if (ret)
394                         break;
395
396                 if (!strcmp(name, info_buf.name)) {
397                         ret = sensor_id;
398                         break;
399                 }
400         }
401 out:
402         return ret;
403 }
404 EXPORT_SYMBOL_GPL(scpi_get_sensor);
405
406 int scpi_get_sensor_value(u16 sensor, u32 *val)
407 {
408         struct scpi_data_buf sdata;
409         struct rockchip_mbox_msg mdata;
410         struct __packed {
411                 u32 status;
412                 u32 val;
413         } buf;
414         int ret;
415
416         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL, SCPI_CMD_SENSOR_VALUE,
417                         sensor, buf);
418
419         ret = scpi_execute_cmd(&sdata);
420         if (ret)
421                 *val = buf.val;
422
423         return ret;
424 }
425 EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
426
427 static int scpi_get_version(u32 old, u32 *ver)
428 {
429         struct scpi_data_buf sdata;
430         struct rockchip_mbox_msg mdata;
431         struct __packed {
432                 u32 status;
433                 u32 ver;
434         } buf;
435         int ret;
436
437         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
438                         old, buf);
439
440         ret = scpi_execute_cmd(&sdata);
441         if (ret)
442                 *ver = buf.ver;
443
444         return ret;
445 }
446
447 int scpi_sys_set_mcu_state_suspend(void)
448 {
449         struct scpi_data_buf sdata;
450         struct rockchip_mbox_msg mdata;
451         struct __packed1 {
452                 u32 status;
453         } tx_buf;
454         struct __packed2 {
455                 u32 status;
456         } rx_buf;
457
458         tx_buf.status = 0;
459         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
460                         SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
461         return scpi_execute_cmd(&sdata);
462 }
463 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
464
465 int scpi_sys_set_mcu_state_resume(void)
466 {
467         struct scpi_data_buf sdata;
468         struct rockchip_mbox_msg mdata;
469         struct __packed1 {
470                 u32 status;
471         } tx_buf;
472         struct __packed2 {
473                 u32 status;
474         } rx_buf;
475
476         tx_buf.status = 0;
477
478         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
479                         SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
480         return scpi_execute_cmd(&sdata);
481 }
482 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
483
484 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
485 {
486         struct scpi_data_buf sdata;
487         struct rockchip_mbox_msg mdata;
488         struct __packed1 {
489                 u32 dram_speed_bin;
490                 u32 freq;
491                 u32 lcdc_type;
492         } tx_buf;
493         struct __packed2 {
494                 u32 status;
495         } rx_buf;
496
497         tx_buf.dram_speed_bin = (u32)dram_speed_bin;
498         tx_buf.freq = (u32)freq;
499         tx_buf.lcdc_type = (u32)lcdc_type;
500
501         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
502                         SCPI_DDR_INIT, tx_buf, rx_buf);
503         return scpi_execute_cmd(&sdata);
504 }
505 EXPORT_SYMBOL_GPL(scpi_ddr_init);
506
507 int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
508 {
509         struct scpi_data_buf sdata;
510         struct rockchip_mbox_msg mdata;
511         struct __packed1 {
512                 u32 clk_rate;
513                 u32 lcdc_type;
514         } tx_buf;
515         struct __packed2 {
516                 u32 status;
517         } rx_buf;
518
519         tx_buf.clk_rate = (u32)rate;
520         tx_buf.lcdc_type = (u32)lcdc_type;
521         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
522                         SCPI_DDR_SET_FREQ, tx_buf, rx_buf);
523         return scpi_execute_cmd(&sdata);
524 }
525 EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
526
527 int scpi_ddr_round_rate(u32 m_hz)
528 {
529         struct scpi_data_buf sdata;
530         struct rockchip_mbox_msg mdata;
531         struct __packed1 {
532                 u32 clk_rate;
533         } tx_buf;
534         struct __packed2 {
535                 u32 status;
536                 u32 round_rate;
537         } rx_buf;
538
539         tx_buf.clk_rate = (u32)m_hz;
540
541         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
542                         SCPI_DDR_ROUND_RATE, tx_buf, rx_buf);
543         if (scpi_execute_cmd(&sdata))
544                 return 0;
545
546         return rx_buf.round_rate;
547 }
548 EXPORT_SYMBOL_GPL(scpi_ddr_round_rate);
549
550 int scpi_ddr_set_auto_self_refresh(u32 en)
551 {
552         struct scpi_data_buf sdata;
553         struct rockchip_mbox_msg mdata;
554         struct __packed1 {
555                 u32 enable;
556         } tx_buf;
557         struct __packed2 {
558                 u32 status;
559         } rx_buf;
560
561         tx_buf.enable = (u32)en;
562
563         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
564                         SCPI_DDR_AUTO_SELF_REFRESH, tx_buf, rx_buf);
565         return scpi_execute_cmd(&sdata);
566 }
567 EXPORT_SYMBOL_GPL(scpi_ddr_set_auto_self_refresh);
568
569 int scpi_ddr_bandwidth_get(struct ddr_bw_info *ddr_bw_ch0,
570                            struct ddr_bw_info *ddr_bw_ch1)
571 {
572         struct scpi_data_buf sdata;
573         struct rockchip_mbox_msg mdata;
574         struct __packed1 {
575                 u32 status;
576         } tx_buf;
577         struct __packed2 {
578                 u32 status;
579                 struct ddr_bw_info ddr_bw_ch0;
580                 struct ddr_bw_info ddr_bw_ch1;
581         } rx_buf;
582
583         tx_buf.status = 0;
584
585         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
586                         SCPI_DDR_BANDWIDTH_GET, tx_buf, rx_buf);
587         if (scpi_execute_cmd(&sdata))
588                 return 0;
589
590         memcpy(ddr_bw_ch0, &(rx_buf.ddr_bw_ch0), sizeof(rx_buf.ddr_bw_ch0));
591         memcpy(ddr_bw_ch1, &(rx_buf.ddr_bw_ch1), sizeof(rx_buf.ddr_bw_ch1));
592
593         return 0;
594 }
595 EXPORT_SYMBOL_GPL(scpi_ddr_bandwidth_get);
596
597 int scpi_ddr_get_clk_rate(void)
598 {
599         struct scpi_data_buf sdata;
600         struct rockchip_mbox_msg mdata;
601         struct __packed1 {
602                 u32 status;
603         } tx_buf;
604         struct __packed2 {
605                 u32 status;
606                 u32 clk_rate;
607         } rx_buf;
608
609         tx_buf.status = 0;
610         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
611                         SCPI_DDR_GET_FREQ, tx_buf, rx_buf);
612         if (scpi_execute_cmd(&sdata))
613                 return 0;
614
615         return rx_buf.clk_rate;
616 }
617 EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
618
619 int scpi_thermal_get_temperature(void)
620 {
621         int ret;
622         struct scpi_data_buf sdata;
623         struct rockchip_mbox_msg mdata;
624         struct __packed1 {
625                 u32 status;
626         } tx_buf;
627
628         struct __packed2 {
629                 u32 status;
630                 u32 tsadc_data;
631         } rx_buf;
632
633         tx_buf.status = 0;
634         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
635                         SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
636
637         ret = scpi_execute_cmd(&sdata);
638         if (ret) {
639                 pr_err("get temperature from MCU failed, ret=%d\n", ret);
640                 return ret;
641         }
642
643         return rx_buf.tsadc_data;
644 }
645 EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
646
647 int scpi_thermal_set_clk_cycle(u32 cycle)
648 {
649         struct scpi_data_buf sdata;
650         struct rockchip_mbox_msg mdata;
651         struct __packed1 {
652                 u32 clk_cycle;
653         } tx_buf;
654
655         struct __packed2 {
656                 u32 status;
657         } rx_buf;
658
659         tx_buf.clk_cycle = cycle;
660         SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
661                         SCPI_THERMAL_SET_TSADC_CYCLE, tx_buf, rx_buf);
662
663         return scpi_execute_cmd(&sdata);
664 }
665 EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
666
667 static struct of_device_id mobx_scpi_of_match[] = {
668         { .compatible = "rockchip,mbox-scpi"},
669         { },
670 };
671 MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
672
673 static int mobx_scpi_probe(struct platform_device *pdev)
674 {
675         int ret = 0;
676         int retry = 3;
677         u32 ver = 0;
678         int check_version = 0; /*0: not check version, 1: check version*/
679         int val = 0;
680
681         the_scpi_device = &pdev->dev;
682
683         while ((retry--) && (check_version != 0)) {
684                 ret = scpi_get_version(SCPI_VERSION, &ver);
685                 if ((ret == 0) && (ver == SCPI_VERSION))
686                         break;
687         }
688
689         if ((retry <= 0) && (check_version != 0)) {
690                 dev_err(&pdev->dev, "Failed to get scpi version\n");
691                 ret = -EIO;
692                 goto exit;
693         }
694
695         /* try to get mboxes chan nums from DT */
696         if (of_property_read_u32((&pdev->dev)->of_node, "chan-nums", &val)) {
697                 dev_err(&pdev->dev, "parse mboxes chan-nums failed\n");
698                 ret = -EINVAL;
699                 goto exit;
700         }
701
702         max_chan_num = val;
703
704         dev_info(&pdev->dev,
705                  "Scpi initialize, version: 0x%x, chan nums: %d\n", ver, val);
706         return 0;
707 exit:
708         the_scpi_device = NULL;
709         return ret;
710 }
711
712 static struct platform_driver mbox_scpi_driver = {
713         .probe  = mobx_scpi_probe,
714         .driver = {
715                 .name = "mbox-scpi",
716                 .of_match_table = of_match_ptr(mobx_scpi_of_match),
717         },
718 };
719
720 static int __init rockchip_mbox_scpi_init(void)
721 {
722         return platform_driver_register(&mbox_scpi_driver);
723 }
724 subsys_initcall(rockchip_mbox_scpi_init);