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