1 /* 2 * Remote processor messaging - sample client driver 3 * 4 * Copyright (C) 2011 Texas Instruments, Inc. 5 * Copyright (C) 2011 Google, Inc. 6 * 7 * Ohad Ben-Cohen <ohad@wizery.com> 8 * Brian Swetland <swetland@google.com> 9 * 10 * This software is licensed under the terms of the GNU General Public 11 * License version 2, as published by the Free Software Foundation, and 12 * may be copied, distributed, and modified under those terms. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 */ 19 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/rpmsg.h> 23 24 #define MSG "hello world!" 25 #define MSG_LIMIT 100 26 27 struct instance_data { 28 int rx_count; 29 }; 30 31 static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len, 32 void *priv, u32 src) 33 { 34 int ret; 35 struct instance_data *idata = dev_get_drvdata(&rpdev->dev); 36 37 dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", 38 ++idata->rx_count, src); 39 40 print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1, 41 data, len, true); 42 43 /* samples should not live forever */ 44 if (idata->rx_count >= MSG_LIMIT) { 45 dev_info(&rpdev->dev, "goodbye!\n"); 46 return; 47 } 48 49 /* send a new message now */ 50 ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG)); 51 if (ret) 52 dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); 53 } 54 55 static int rpmsg_sample_probe(struct rpmsg_channel *rpdev) 56 { 57 int ret; 58 struct instance_data *idata; 59 60 dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n", 61 rpdev->src, rpdev->dst); 62 63 idata = devm_kzalloc(&rpdev->dev, sizeof(*idata), GFP_KERNEL); 64 if (!idata) 65 return -ENOMEM; 66 67 dev_set_drvdata(&rpdev->dev, idata); 68 69 /* send a message to our remote processor */ 70 ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG)); 71 if (ret) { 72 dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret); 73 return ret; 74 } 75 76 return 0; 77 } 78 79 static void rpmsg_sample_remove(struct rpmsg_channel *rpdev) 80 { 81 dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n"); 82 } 83 84 static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = { 85 { .name = "rpmsg-client-sample" }, 86 { }, 87 }; 88 MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table); 89 90 static struct rpmsg_driver rpmsg_sample_client = { 91 .drv.name = KBUILD_MODNAME, 92 .id_table = rpmsg_driver_sample_id_table, 93 .probe = rpmsg_sample_probe, 94 .callback = rpmsg_sample_cb, 95 .remove = rpmsg_sample_remove, 96 }; 97 module_rpmsg_driver(rpmsg_sample_client); 98 99 MODULE_DESCRIPTION("Remote processor messaging sample client driver"); 100 MODULE_LICENSE("GPL v2"); 101