]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/mailbox/mailbox-test.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[karo-tx-linux.git] / drivers / mailbox / mailbox-test.c
1 /*
2  * Copyright (C) 2015 ST Microelectronics
3  *
4  * Author: Lee Jones <lee.jones@linaro.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <linux/debugfs.h>
13 #include <linux/err.h>
14 #include <linux/fs.h>
15 #include <linux/io.h>
16 #include <linux/kernel.h>
17 #include <linux/mailbox_client.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/platform_device.h>
21 #include <linux/poll.h>
22 #include <linux/slab.h>
23 #include <linux/uaccess.h>
24
25 #define MBOX_MAX_SIG_LEN        8
26 #define MBOX_MAX_MSG_LEN        128
27 #define MBOX_BYTES_PER_LINE     16
28 #define MBOX_HEXDUMP_LINE_LEN   ((MBOX_BYTES_PER_LINE * 4) + 2)
29 #define MBOX_HEXDUMP_MAX_LEN    (MBOX_HEXDUMP_LINE_LEN *                \
30                                  (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
31
32 static struct dentry *root_debugfs_dir;
33
34 struct mbox_test_device {
35         struct device           *dev;
36         void __iomem            *tx_mmio;
37         void __iomem            *rx_mmio;
38         struct mbox_chan        *tx_channel;
39         struct mbox_chan        *rx_channel;
40         char                    *rx_buffer;
41         char                    *signal;
42         char                    *message;
43         spinlock_t              lock;
44         wait_queue_head_t       waitq;
45         struct fasync_struct    *async_queue;
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         void *data;
101         int ret;
102
103         if (!tdev->tx_channel) {
104                 dev_err(tdev->dev, "Channel cannot do Tx\n");
105                 return -EINVAL;
106         }
107
108         if (count > MBOX_MAX_MSG_LEN) {
109                 dev_err(tdev->dev,
110                         "Message length %zd greater than max allowed %d\n",
111                         count, MBOX_MAX_MSG_LEN);
112                 return -EINVAL;
113         }
114
115         tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
116         if (!tdev->message)
117                 return -ENOMEM;
118
119         ret = copy_from_user(tdev->message, userbuf, count);
120         if (ret) {
121                 ret = -EFAULT;
122                 goto out;
123         }
124
125         /*
126          * A separate signal is only of use if there is
127          * MMIO to subsequently pass the message through
128          */
129         if (tdev->tx_mmio && tdev->signal) {
130                 print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
131                                      tdev->signal, MBOX_MAX_SIG_LEN);
132
133                 data = tdev->signal;
134         } else
135                 data = tdev->message;
136
137         print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
138                              tdev->message, MBOX_MAX_MSG_LEN);
139
140         ret = mbox_send_message(tdev->tx_channel, data);
141         if (ret < 0)
142                 dev_err(tdev->dev, "Failed to send message via mailbox\n");
143
144 out:
145         kfree(tdev->signal);
146         kfree(tdev->message);
147         tdev->signal = NULL;
148
149         return ret < 0 ? ret : count;
150 }
151
152 static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
153 {
154         unsigned char data;
155         unsigned long flags;
156
157         spin_lock_irqsave(&tdev->lock, flags);
158         data = tdev->rx_buffer[0];
159         spin_unlock_irqrestore(&tdev->lock, flags);
160
161         if (data != '\0')
162                 return true;
163         return false;
164 }
165
166 static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
167                                       size_t count, loff_t *ppos)
168 {
169         struct mbox_test_device *tdev = filp->private_data;
170         unsigned long flags;
171         char *touser, *ptr;
172         int l = 0;
173         int ret;
174
175         DECLARE_WAITQUEUE(wait, current);
176
177         touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
178         if (!touser)
179                 return -ENOMEM;
180
181         if (!tdev->rx_channel) {
182                 ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
183                 ret = simple_read_from_buffer(userbuf, count, ppos,
184                                               touser, ret);
185                 goto kfree_err;
186         }
187
188         add_wait_queue(&tdev->waitq, &wait);
189
190         do {
191                 __set_current_state(TASK_INTERRUPTIBLE);
192
193                 if (mbox_test_message_data_ready(tdev))
194                         break;
195
196                 if (filp->f_flags & O_NONBLOCK) {
197                         ret = -EAGAIN;
198                         goto waitq_err;
199                 }
200
201                 if (signal_pending(current)) {
202                         ret = -ERESTARTSYS;
203                         goto waitq_err;
204                 }
205                 schedule();
206
207         } while (1);
208
209         spin_lock_irqsave(&tdev->lock, flags);
210
211         ptr = tdev->rx_buffer;
212         while (l < MBOX_HEXDUMP_MAX_LEN) {
213                 hex_dump_to_buffer(ptr,
214                                    MBOX_BYTES_PER_LINE,
215                                    MBOX_BYTES_PER_LINE, 1, touser + l,
216                                    MBOX_HEXDUMP_LINE_LEN, true);
217
218                 ptr += MBOX_BYTES_PER_LINE;
219                 l += MBOX_HEXDUMP_LINE_LEN;
220                 *(touser + (l - 1)) = '\n';
221         }
222         *(touser + l) = '\0';
223
224         memset(tdev->rx_buffer, 0, MBOX_MAX_MSG_LEN);
225
226         spin_unlock_irqrestore(&tdev->lock, flags);
227
228         ret = simple_read_from_buffer(userbuf, count, ppos, touser, MBOX_HEXDUMP_MAX_LEN);
229 waitq_err:
230         __set_current_state(TASK_RUNNING);
231         remove_wait_queue(&tdev->waitq, &wait);
232 kfree_err:
233         kfree(touser);
234         return ret;
235 }
236
237 static unsigned int
238 mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
239 {
240         struct mbox_test_device *tdev = filp->private_data;
241
242         poll_wait(filp, &tdev->waitq, wait);
243
244         if (mbox_test_message_data_ready(tdev))
245                 return POLLIN | POLLRDNORM;
246         return 0;
247 }
248
249 static const struct file_operations mbox_test_message_ops = {
250         .write  = mbox_test_message_write,
251         .read   = mbox_test_message_read,
252         .fasync = mbox_test_message_fasync,
253         .poll   = mbox_test_message_poll,
254         .open   = simple_open,
255         .llseek = generic_file_llseek,
256 };
257
258 static int mbox_test_add_debugfs(struct platform_device *pdev,
259                                  struct mbox_test_device *tdev)
260 {
261         if (!debugfs_initialized())
262                 return 0;
263
264         root_debugfs_dir = debugfs_create_dir("mailbox", NULL);
265         if (!root_debugfs_dir) {
266                 dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
267                 return -EINVAL;
268         }
269
270         debugfs_create_file("message", 0600, root_debugfs_dir,
271                             tdev, &mbox_test_message_ops);
272
273         debugfs_create_file("signal", 0200, root_debugfs_dir,
274                             tdev, &mbox_test_signal_ops);
275
276         return 0;
277 }
278
279 static void mbox_test_receive_message(struct mbox_client *client, void *message)
280 {
281         struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
282         unsigned long flags;
283
284         spin_lock_irqsave(&tdev->lock, flags);
285         if (tdev->rx_mmio) {
286                 memcpy_fromio(tdev->rx_buffer, tdev->rx_mmio, MBOX_MAX_MSG_LEN);
287                 print_hex_dump_bytes("Client: Received [MMIO]: ", DUMP_PREFIX_ADDRESS,
288                                      tdev->rx_buffer, MBOX_MAX_MSG_LEN);
289         } else if (message) {
290                 print_hex_dump_bytes("Client: Received [API]: ", DUMP_PREFIX_ADDRESS,
291                                      message, MBOX_MAX_MSG_LEN);
292                 memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
293         }
294         spin_unlock_irqrestore(&tdev->lock, flags);
295
296         wake_up_interruptible(&tdev->waitq);
297
298         kill_fasync(&tdev->async_queue, SIGIO, POLL_IN);
299 }
300
301 static void mbox_test_prepare_message(struct mbox_client *client, void *message)
302 {
303         struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
304
305         if (tdev->tx_mmio) {
306                 if (tdev->signal)
307                         memcpy_toio(tdev->tx_mmio, tdev->message, MBOX_MAX_MSG_LEN);
308                 else
309                         memcpy_toio(tdev->tx_mmio, message, MBOX_MAX_MSG_LEN);
310         }
311 }
312
313 static void mbox_test_message_sent(struct mbox_client *client,
314                                    void *message, int r)
315 {
316         if (r)
317                 dev_warn(client->dev,
318                          "Client: Message could not be sent: %d\n", r);
319         else
320                 dev_info(client->dev,
321                          "Client: Message sent\n");
322 }
323
324 static struct mbox_chan *
325 mbox_test_request_channel(struct platform_device *pdev, const char *name)
326 {
327         struct mbox_client *client;
328         struct mbox_chan *channel;
329
330         client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
331         if (!client)
332                 return ERR_PTR(-ENOMEM);
333
334         client->dev             = &pdev->dev;
335         client->rx_callback     = mbox_test_receive_message;
336         client->tx_prepare      = mbox_test_prepare_message;
337         client->tx_done         = mbox_test_message_sent;
338         client->tx_block        = true;
339         client->knows_txdone    = false;
340         client->tx_tout         = 500;
341
342         channel = mbox_request_channel_byname(client, name);
343         if (IS_ERR(channel)) {
344                 dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
345                 return NULL;
346         }
347
348         return channel;
349 }
350
351 static int mbox_test_probe(struct platform_device *pdev)
352 {
353         struct mbox_test_device *tdev;
354         struct resource *res;
355         resource_size_t size;
356         int ret;
357
358         tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
359         if (!tdev)
360                 return -ENOMEM;
361
362         /* It's okay for MMIO to be NULL */
363         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
364         size = resource_size(res);
365         tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
366         if (PTR_ERR(tdev->tx_mmio) == -EBUSY)
367                 /* if reserved area in SRAM, try just ioremap */
368                 tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
369         else if (IS_ERR(tdev->tx_mmio))
370                 tdev->tx_mmio = NULL;
371
372         /* If specified, second reg entry is Rx MMIO */
373         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
374         size = resource_size(res);
375         tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
376         if (PTR_ERR(tdev->rx_mmio) == -EBUSY)
377                 tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
378         else if (IS_ERR(tdev->rx_mmio))
379                 tdev->rx_mmio = tdev->tx_mmio;
380
381         tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
382         tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
383
384         if (!tdev->tx_channel && !tdev->rx_channel)
385                 return -EPROBE_DEFER;
386
387         /* If Rx is not specified but has Rx MMIO, then Rx = Tx */
388         if (!tdev->rx_channel && (tdev->rx_mmio != tdev->tx_mmio))
389                 tdev->rx_channel = tdev->tx_channel;
390
391         tdev->dev = &pdev->dev;
392         platform_set_drvdata(pdev, tdev);
393
394         spin_lock_init(&tdev->lock);
395
396         if (tdev->rx_channel) {
397                 tdev->rx_buffer = devm_kzalloc(&pdev->dev,
398                                                MBOX_MAX_MSG_LEN, GFP_KERNEL);
399                 if (!tdev->rx_buffer)
400                         return -ENOMEM;
401         }
402
403         ret = mbox_test_add_debugfs(pdev, tdev);
404         if (ret)
405                 return ret;
406
407         init_waitqueue_head(&tdev->waitq);
408         dev_info(&pdev->dev, "Successfully registered\n");
409
410         return 0;
411 }
412
413 static int mbox_test_remove(struct platform_device *pdev)
414 {
415         struct mbox_test_device *tdev = platform_get_drvdata(pdev);
416
417         debugfs_remove_recursive(root_debugfs_dir);
418
419         if (tdev->tx_channel)
420                 mbox_free_channel(tdev->tx_channel);
421         if (tdev->rx_channel)
422                 mbox_free_channel(tdev->rx_channel);
423
424         return 0;
425 }
426
427 static const struct of_device_id mbox_test_match[] = {
428         { .compatible = "mailbox-test" },
429         {},
430 };
431 MODULE_DEVICE_TABLE(of, mbox_test_match);
432
433 static struct platform_driver mbox_test_driver = {
434         .driver = {
435                 .name = "mailbox_test",
436                 .of_match_table = mbox_test_match,
437         },
438         .probe  = mbox_test_probe,
439         .remove = mbox_test_remove,
440 };
441 module_platform_driver(mbox_test_driver);
442
443 MODULE_DESCRIPTION("Generic Mailbox Testing Facility");
444 MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
445 MODULE_LICENSE("GPL v2");