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