mailbox:starfive: use clk/rst API.
[platform/kernel/linux-starfive.git] / drivers / mailbox / starfive_mailbox-test.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2015 ST Microelectronics
4  *
5  * Author: Lee Jones <lee.jones@linaro.org>
6  */
7
8 #include <linux/debugfs.h>
9 #include <linux/err.h>
10 #include <linux/fs.h>
11 #include <linux/io.h>
12 #include <linux/kernel.h>
13 #include <linux/mailbox_client.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <linux/poll.h>
18 #include <linux/slab.h>
19 #include <linux/uaccess.h>
20 #include <linux/sched/signal.h>
21
22 #include <linux/mailbox_controller.h>
23
24 #define MBOX_MAX_SIG_LEN        8
25 #define MBOX_MAX_MSG_LEN        16
26 #define MBOX_BYTES_PER_LINE     16
27 #define MBOX_HEXDUMP_LINE_LEN   ((MBOX_BYTES_PER_LINE * 4) + 2)
28 #define MBOX_HEXDUMP_MAX_LEN    (MBOX_HEXDUMP_LINE_LEN * (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
29
30 static bool mbox_data_ready;
31
32 struct mbox_test_device {
33         struct device           *dev;
34         void __iomem            *tx_mmio;
35         void __iomem            *rx_mmio;
36         struct mbox_chan        *tx_channel;
37         struct mbox_chan        *rx_channel;
38         char                    *rx_buffer;
39         char                    *signal;
40         char                    *message;
41         spinlock_t              lock;
42         wait_queue_head_t       waitq;
43         struct fasync_struct    *async_queue;
44         struct dentry           *root_debugfs_dir;
45 };
46
47 static ssize_t mbox_test_signal_write(struct file *filp,
48                 const char __user *userbuf,
49                 size_t count, loff_t *ppos)
50 {
51         struct mbox_test_device *tdev = filp->private_data;
52
53         if (!tdev->tx_channel) {
54                 dev_err(tdev->dev, "Channel cannot do Tx\n");
55                 return -EINVAL;
56         }
57
58         if (count > MBOX_MAX_SIG_LEN) {
59                 dev_err(tdev->dev,
60                         "Signal length %zd greater than max allowed %d\n",
61                         count, MBOX_MAX_SIG_LEN);
62                 return -EINVAL;
63         }
64
65         /* Only allocate memory if we need to */
66         if (!tdev->signal) {
67                 tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
68                 if (!tdev->signal)
69                         return -ENOMEM;
70         }
71
72         if (copy_from_user(tdev->signal, userbuf, count)) {
73                 kfree(tdev->signal);
74                 tdev->signal = NULL;
75                 return -EFAULT;
76         }
77
78         return count;
79 }
80
81 static const struct file_operations mbox_test_signal_ops = {
82         .write = mbox_test_signal_write,
83         .open = simple_open,
84         .llseek = generic_file_llseek,
85 };
86
87 static int mbox_test_message_fasync(int fd, struct file *filp, int on)
88 {
89         struct mbox_test_device *tdev = filp->private_data;
90
91         return fasync_helper(fd, filp, on, &tdev->async_queue);
92 }
93
94 static ssize_t mbox_test_message_write(struct file *filp,
95                 const char __user *userbuf,
96                 size_t count, loff_t *ppos)
97 {
98         struct mbox_test_device *tdev = filp->private_data;
99         void *data;
100         int ret;
101
102         if (!tdev->tx_channel) {
103                 dev_err(tdev->dev, "Channel cannot do Tx\n");
104                 return -EINVAL;
105         }
106
107         if (count > MBOX_MAX_MSG_LEN) {
108                 dev_err(tdev->dev,
109                         "Message length %zd greater than max allowed %d\n",
110                         count, MBOX_MAX_MSG_LEN);
111                 return -EINVAL;
112         }
113
114         tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
115         if (!tdev->message)
116                 return -ENOMEM;
117
118         ret = copy_from_user(tdev->message, userbuf, count);
119         if (ret) {
120                 ret = -EFAULT;
121                 goto out;
122         }
123
124         if (tdev->tx_mmio && tdev->signal) {
125                 print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
126                         tdev->signal, MBOX_MAX_SIG_LEN);
127
128                 data = tdev->signal;
129         } else
130                 data = tdev->message;
131
132         print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
133                 tdev->message, MBOX_MAX_MSG_LEN);
134
135         ret = mbox_send_message(tdev->tx_channel, data);
136         mbox_chan_txdone(tdev->tx_channel, ret);
137         if (ret < 0)
138                 dev_err(tdev->dev, "Failed to send message via mailbox\n");
139
140 out:
141         kfree(tdev->signal);
142         kfree(tdev->message);
143         tdev->signal = NULL;
144
145         return ret < 0 ? ret : count;
146 }
147
148 static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
149 {
150         bool data_ready;
151         unsigned long flags;
152
153         spin_lock_irqsave(&tdev->lock, flags);
154         data_ready = mbox_data_ready;
155         spin_unlock_irqrestore(&tdev->lock, flags);
156
157         return data_ready;
158 }
159
160 static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
161                 size_t count, loff_t *ppos)
162 {
163         struct mbox_test_device *tdev = filp->private_data;
164         unsigned long flags;
165         char *touser, *ptr;
166         int ret;
167
168         touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
169         if (!touser)
170                 return -ENOMEM;
171
172         if (!tdev->rx_channel) {
173                 ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
174                 ret = simple_read_from_buffer(userbuf, count, ppos,
175                         touser, ret);
176                 goto kfree_err;
177         }
178
179         do {
180                 if (mbox_test_message_data_ready(tdev))
181                         break;
182
183                 if (filp->f_flags & O_NONBLOCK) {
184                         ret = -EAGAIN;
185                         goto waitq_err;
186                 }
187
188                 if (signal_pending(current)) {
189                         ret = -ERESTARTSYS;
190                         goto waitq_err;
191                 }
192                 schedule();
193
194         } while (1);
195
196         spin_lock_irqsave(&tdev->lock, flags);
197
198         ptr = tdev->rx_buffer;
199
200         mbox_data_ready = false;
201
202         spin_unlock_irqrestore(&tdev->lock, flags);
203         if (copy_to_user((void __user *)userbuf, ptr, 4))
204                 ret = -EFAULT;
205
206 waitq_err:
207         __set_current_state(TASK_RUNNING);
208 kfree_err:
209         kfree(touser);
210         return ret;
211 }
212
213 static __poll_t
214 mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
215 {
216         struct mbox_test_device *tdev = filp->private_data;
217
218         poll_wait(filp, &tdev->waitq, wait);
219
220         if (mbox_test_message_data_ready(tdev))
221                 return EPOLLIN | EPOLLRDNORM;
222         return 0;
223 }
224
225 static const struct file_operations mbox_test_message_ops = {
226         .write = mbox_test_message_write,
227         .read = mbox_test_message_read,
228         .fasync = mbox_test_message_fasync,
229         .poll = mbox_test_message_poll,
230         .open = simple_open,
231         .llseek = generic_file_llseek,
232 };
233
234 static int mbox_test_add_debugfs(struct platform_device *pdev,
235                 struct mbox_test_device *tdev)
236 {
237         if (!debugfs_initialized())
238                 return 0;
239
240         tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
241         if (!tdev->root_debugfs_dir) {
242                 dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
243                 return -EINVAL;
244         }
245
246         debugfs_create_file("message", 0600, tdev->root_debugfs_dir,
247                 tdev, &mbox_test_message_ops);
248
249         debugfs_create_file("signal", 0200, tdev->root_debugfs_dir,
250                 tdev, &mbox_test_signal_ops);
251
252         return 0;
253 }
254
255 static void mbox_test_receive_message(struct mbox_client *client, void *message)
256 {
257         struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
258         unsigned long flags;
259
260         spin_lock_irqsave(&tdev->lock, flags);
261         if (tdev->rx_mmio) {
262                 memcpy_fromio(tdev->rx_buffer, tdev->rx_mmio, MBOX_MAX_MSG_LEN);
263                 print_hex_dump_bytes("Client: Received [MMIO]: ", DUMP_PREFIX_ADDRESS,
264                         tdev->rx_buffer, MBOX_MAX_MSG_LEN);
265         } else if (message) {
266                 print_hex_dump_bytes("Client: Received [API]: ", DUMP_PREFIX_ADDRESS,
267                         message, MBOX_MAX_MSG_LEN);
268                 memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
269         }
270         mbox_data_ready = true;
271         spin_unlock_irqrestore(&tdev->lock, flags);
272 }
273
274 static void mbox_test_prepare_message(struct mbox_client *client, void *message)
275 {
276         struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
277
278         if (tdev->tx_mmio) {
279                 if (tdev->signal)
280                         memcpy_toio(tdev->tx_mmio, tdev->message, MBOX_MAX_MSG_LEN);
281                 else
282                         memcpy_toio(tdev->tx_mmio, message, MBOX_MAX_MSG_LEN);
283         }
284 }
285
286 static void mbox_test_message_sent(struct mbox_client *client,
287                 void *message, int r)
288 {
289         if (r)
290                 dev_warn(client->dev,
291                         "Client: Message could not be sent: %d\n", r);
292         else
293                 dev_info(client->dev,
294                         "Client: Message sent\n");
295 }
296
297 static struct mbox_chan *
298 mbox_test_request_channel(struct platform_device *pdev, const char *name)
299 {
300         struct mbox_client *client;
301         struct mbox_chan *channel;
302
303         client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
304         if (!client)
305                 return ERR_PTR(-ENOMEM);
306
307         client->dev        = &pdev->dev;
308         client->rx_callback    = mbox_test_receive_message;
309         client->tx_prepare    = mbox_test_prepare_message;
310         client->tx_done        = mbox_test_message_sent;
311         client->tx_block    = false;
312         client->knows_txdone    = false;
313         client->tx_tout        = 500;
314
315         channel = mbox_request_channel_byname(client, name);
316         if (IS_ERR(channel)) {
317                 dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
318                 return NULL;
319         }
320
321         return channel;
322 }
323
324 static int mbox_test_probe(struct platform_device *pdev)
325 {
326         struct mbox_test_device *tdev;
327         struct resource *res;
328         resource_size_t size;
329         int ret;
330
331         tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
332         if (!tdev)
333                 return -ENOMEM;
334
335         /* It's okay for MMIO to be NULL */
336         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337         tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
338         if (PTR_ERR(tdev->tx_mmio) == -EBUSY) {
339                 /* if reserved area in SRAM, try just ioremap */
340                 size = resource_size(res);
341                 tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
342         } else if (IS_ERR(tdev->tx_mmio)) {
343                 tdev->tx_mmio = NULL;
344         }
345
346         /* If specified, second reg entry is Rx MMIO */
347         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
348         tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
349         if (PTR_ERR(tdev->rx_mmio) == -EBUSY) {
350                 size = resource_size(res);
351                 tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
352         } else if (IS_ERR(tdev->rx_mmio)) {
353                 tdev->rx_mmio = tdev->tx_mmio;
354         }
355
356         tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
357         tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
358
359         if (!tdev->tx_channel && !tdev->rx_channel)
360                 return -EPROBE_DEFER;
361
362         /* If Rx is not specified but has Rx MMIO, then Rx = Tx */
363         if (!tdev->rx_channel && (tdev->rx_mmio != tdev->tx_mmio))
364                 tdev->rx_channel = tdev->tx_channel;
365
366         tdev->dev = &pdev->dev;
367         platform_set_drvdata(pdev, tdev);
368
369         spin_lock_init(&tdev->lock);
370
371         if (tdev->rx_channel) {
372                 tdev->rx_buffer = devm_kzalloc(&pdev->dev,
373                         MBOX_MAX_MSG_LEN, GFP_KERNEL);
374                 if (!tdev->rx_buffer)
375                         return -ENOMEM;
376         }
377
378         ret = mbox_test_add_debugfs(pdev, tdev);
379         if (ret)
380                 return ret;
381
382         dev_info(&pdev->dev, "Successfully registered\n");
383
384         return 0;
385 }
386
387 static int mbox_test_remove(struct platform_device *pdev)
388 {
389         struct mbox_test_device *tdev = platform_get_drvdata(pdev);
390
391         debugfs_remove_recursive(tdev->root_debugfs_dir);
392
393         if (tdev->tx_channel)
394                 mbox_free_channel(tdev->tx_channel);
395         if (tdev->rx_channel)
396                 mbox_free_channel(tdev->rx_channel);
397
398         return 0;
399 }
400
401 static const struct of_device_id mbox_test_match[] = {
402         { .compatible = "starfive,mailbox-test" },
403         {},
404 };
405 MODULE_DEVICE_TABLE(of, mbox_test_match);
406
407 static struct platform_driver mbox_test_driver = {
408         .driver = {
409                 .name = "mailbox_test",
410                 .of_match_table = mbox_test_match,
411         },
412         .probe  = mbox_test_probe,
413         .remove = mbox_test_remove,
414 };
415 module_platform_driver(mbox_test_driver);
416
417 MODULE_DESCRIPTION("mailbox test driver");
418 MODULE_AUTHOR("StarFive Technology Co. Ltd.");
419 MODULE_LICENSE("GPL");