]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/open-amp.git/blob - apps/samples/master/linux/kernelspace/rpmsg_mat_mul_kern_app/rpmsg_mat_mul_kern_app.c
apps:func_test_suite:generic:zynq7:remoteproc master
[processor-sdk/open-amp.git] / apps / samples / master / linux / kernelspace / rpmsg_mat_mul_kern_app / rpmsg_mat_mul_kern_app.c
1 /*
2  * RPMSG Matrix Multiplication Kernel Driver
3  *
4  * Copyright (C) 2014 Mentor Graphics Corporation
5  * Copyright (C) 2015 Xilinx, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms 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 that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/rpmsg.h>
20 #include <linux/slab.h>
21 #include <linux/device.h>
22 #include <linux/mutex.h>
23 #include <linux/uaccess.h>
24 #include <linux/errno.h>
25 #include <linux/random.h>
27 #define MAX_RPMSG_BUFF_SIZE             512
29 #define MATRIX_SIZE                     6
30 #define NUM_MATRIX                      2
32 /* Shutdown message ID */
33 #define SHUTDOWN_MSG                    0xEF56A55A
35 static const char init_msg[] = "init_msg";
37 static const char *const shutdown_argv[]
38 = { "/sbin/shutdown", "-h", "-P", "now", NULL };
40 struct _matrix {
41         unsigned int size;
42         unsigned int elements[MATRIX_SIZE][MATRIX_SIZE];
43 };
45 static struct _matrix p_matrix[NUM_MATRIX];
47 static void matrix_print(struct _matrix *m)
48 {
49         int i, j;
51         /* Generate two random matrices */
52         pr_err(" \r\n Master : Linux : Printing results \r\n");
54         for (i = 0; i < m->size; ++i) {
55                 for (j = 0; j < m->size; ++j)
56                         pr_cont(" %d ", (unsigned int)m->elements[i][j]);
57                 pr_info("\r\n");
58         }
59 }
61 static void generate_matrices(int num_matrices, unsigned int matrix_size,
62                               void *p_data)
63 {
64         int i, j, k, val;
65         struct _matrix *p_matrix = p_data;
67         /* Generate two random matrices */
68         pr_err(" \r\n Master : Linux : Generating random matrices \r\n");
70         for (i = 0; i < num_matrices; i++) {
72                 /* Initialize workload */
73                 p_matrix[i].size = matrix_size;
75                 pr_err(" \r\n Master : Linux : Input matrix %d \r\n", i);
76                 for (j = 0; j < matrix_size; j++) {
78                         pr_info("\r\n");
79                         for (k = 0; k < matrix_size; k++) {
80                                 get_random_bytes(&val, sizeof(val));
81                                 p_matrix[i].elements[j][k] =
82                                     ((val & 0x7F) % 10);
83                                 pr_cont(" %d ",
84                                         (unsigned int)p_matrix[i].
85                                         elements[j][k]);
86                         }
87                 }
88                 pr_err("\r\n");
89         }
91 }
93 static void rpmsg_mat_mul_kern_app_cb(struct rpmsg_channel *rpdev, void *data,
94                                       int len, void *priv, u32 src)
95 {
96         int err = 0;
97         int shutdown_msg = SHUTDOWN_MSG;
99         if (!data) {
100                 return;
101         }
103         if ((*(int *)data) == SHUTDOWN_MSG) {
104                 /* Shutdown Linux if such a message is received. Only applicable
105                    when Linux is a remoteproc remote. */
106                 dev_info(&rpdev->dev,
107                          "shutdown message is received. Shutting down...\n");
108                 call_usermodehelper(shutdown_argv[0], shutdown_argv, NULL,
109                                     UMH_NO_WAIT);
110         } else {
111                 /* print results */
112                 matrix_print((struct _matrix *)data);
114                 /* Send payload to remote. */
115                 err =
116                     rpmsg_sendto(rpdev, &shutdown_msg, sizeof(int), rpdev->dst);
118                 if (err)
119                         pr_err(" Shutdown send failed!\r\n");
120         }
123 static int rpmsg_mat_mul_kern_app_probe(struct rpmsg_channel *rpdev)
125         int err = 0;
126         dev_info(&rpdev->dev, "%s", __func__);
128         err = rpmsg_sendto(rpdev, init_msg, sizeof(init_msg), rpdev->dst);
130         if (err) {
131                 pr_err(" Init messages send failed!\r\n");
132                 return err;
133         }
134         dev_info(&rpdev->dev, "Sent init_msg to target 0x%x.", rpdev->dst);
136         dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
137                  rpdev->src, rpdev->dst);
139         /* Generate random matrices */
140         generate_matrices(NUM_MATRIX, MATRIX_SIZE, p_matrix);
142         /* Send matrices to remote for computation */
143         err =
144             rpmsg_sendto(rpdev, p_matrix, sizeof(struct _matrix) * 2,
145                          rpdev->dst);
147         pr_info
148             ("\r\n Master : Linux : Sent %d bytes of data over rpmsg channel to remote \r\n",
149              sizeof(struct _matrix) * 2);
151         if (err) {
152                 pr_err(" send failed!\r\n");
153                 return err;
154         }
155         return 0;
158 static void rpmsg_mat_mul_kern_app_remove(struct rpmsg_channel *rpdev)
160         return;
163 static struct rpmsg_device_id rpmsg_mat_mul_kern_app_id_table[] = {
164         {.name = "rpmsg-openamp-demo-channel"},
165         {},
166 };
168 static struct rpmsg_driver rpmsg_mat_mul_kern_app_drv = {
169         .drv.name = "rpmsg_mat_mul_kern_app",
170         .drv.owner = THIS_MODULE,
171         .id_table = rpmsg_mat_mul_kern_app_id_table,
172         .probe = rpmsg_mat_mul_kern_app_probe,
173         .remove = rpmsg_mat_mul_kern_app_remove,
174         .callback = rpmsg_mat_mul_kern_app_cb,
175 };
177 static int __init init(void)
179         return register_rpmsg_driver(&rpmsg_mat_mul_kern_app_drv);
182 static void __exit fini(void)
184         unregister_rpmsg_driver(&rpmsg_mat_mul_kern_app_drv);
187 module_init(init);
188 module_exit(fini);
190 MODULE_DESCRIPTION
191     ("Sample driver to exposes rpmsg svcs to userspace via a char device");
192 MODULE_LICENSE("GPL v2");