Skip to content

Commit

Permalink
samples/rpmsg: add an rpmsg driver sample
Browse files Browse the repository at this point in the history
Add an rpmsg driver sample, which demonstrates how to communicate with
an AMP-configured remote processor over the rpmsg bus.

Note how once probed, the driver can immediately start sending messages
using the rpmsg_send() API, without having to worry about creating endpoints
or allocating rpmsg addresses: all that work is done by the rpmsg bus,
and the required information is already embedded in the rpmsg channel
that the driver is probed with.

In this sample, the driver simply sends a "Hello World!" message to the remote
processor repeatedly.

Designed with Brian Swetland <[email protected]>.

Signed-off-by: Ohad Ben-Cohen <[email protected]>
Cc: Brian Swetland <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Tony Lindgren <[email protected]>
Cc: Russell King <[email protected]>
Cc: Rusty Russell <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Greg KH <[email protected]>
Cc: Stephen Boyd <[email protected]>
  • Loading branch information
ohadbc committed Feb 8, 2012
1 parent bcabbcc commit 779b96d
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 1 deletion.
8 changes: 8 additions & 0 deletions samples/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ config SAMPLE_KDB
Build an example of how to dynamically add the hello
command to the kdb shell.

config SAMPLE_RPMSG_CLIENT
tristate "Build rpmsg client sample -- loadable modules only"
depends on RPMSG && m
help
Build an rpmsg client sample driver, which demonstrates how
to communicate with an AMP-configured remote processor over
the rpmsg bus.

endif # SAMPLES
2 changes: 1 addition & 1 deletion samples/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Makefile for Linux samples code

obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \
hw_breakpoint/ kfifo/ kdb/ hidraw/
hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/
1 change: 1 addition & 0 deletions samples/rpmsg/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-$(CONFIG_SAMPLE_RPMSG_CLIENT) += rpmsg_client_sample.o
100 changes: 100 additions & 0 deletions samples/rpmsg/rpmsg_client_sample.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Remote processor messaging - sample client driver
*
* Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2011 Google, Inc.
*
* Ohad Ben-Cohen <[email protected]>
* Brian Swetland <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/rpmsg.h>

#define MSG "hello world!"
#define MSG_LIMIT 100

static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
void *priv, u32 src)
{
int ret;
static int rx_count;

dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src);

print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
data, len, true);

/* samples should not live forever */
if (rx_count >= MSG_LIMIT) {
dev_info(&rpdev->dev, "goodbye!\n");
return;
}

/* send a new message now */
ret = rpmsg_send(rpdev, MSG, strlen(MSG));
if (ret)
dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
}

static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
{
int ret;

dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
rpdev->src, rpdev->dst);

/* send a message to our remote processor */
ret = rpmsg_send(rpdev, MSG, strlen(MSG));
if (ret) {
dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
return ret;
}

return 0;
}

static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev)
{
dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
}

static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
{ .name = "rpmsg-client-sample" },
{ },
};
MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);

static struct rpmsg_driver rpmsg_sample_client = {
.drv.name = KBUILD_MODNAME,
.drv.owner = THIS_MODULE,
.id_table = rpmsg_driver_sample_id_table,
.probe = rpmsg_sample_probe,
.callback = rpmsg_sample_cb,
.remove = __devexit_p(rpmsg_sample_remove),
};

static int __init rpmsg_client_sample_init(void)
{
return register_rpmsg_driver(&rpmsg_sample_client);
}
module_init(rpmsg_client_sample_init);

static void __exit rpmsg_client_sample_fini(void)
{
unregister_rpmsg_driver(&rpmsg_sample_client);
}
module_exit(rpmsg_client_sample_fini);

MODULE_DESCRIPTION("Remote processor messaging sample client driver");
MODULE_LICENSE("GPL v2");

0 comments on commit 779b96d

Please sign in to comment.