summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2015-04-13 19:48:37 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2015-04-17 16:12:49 +0200
commit75052a5504705aded68e544967fdd1d296470bcc (patch)
tree82f1f81a84cc473440ea22a89072fffc420c170f /drivers
parent1ffc12be5549085faac2d6116f666cb9cbcb2930 (diff)
downloadlinux-75052a5504705aded68e544967fdd1d296470bcc.tar.bz2
greybus: bundle: add state sysfs file
A bundle has a state file, that is managed by the endo userspace process. This file can be written to and any process that is polling on the file will be woken up and can read the new value. It's a "cheap" IPC for programs that are not allowed to do anything other than read/write to kernel sysfs files. Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/greybus/Documentation/sysfs-bus-greybus13
-rw-r--r--drivers/staging/greybus/bundle.c37
-rw-r--r--drivers/staging/greybus/bundle.h1
3 files changed, 49 insertions, 2 deletions
diff --git a/drivers/staging/greybus/Documentation/sysfs-bus-greybus b/drivers/staging/greybus/Documentation/sysfs-bus-greybus
index 4b511dbff0da..ab728a46e657 100644
--- a/drivers/staging/greybus/Documentation/sysfs-bus-greybus
+++ b/drivers/staging/greybus/Documentation/sysfs-bus-greybus
@@ -113,3 +113,16 @@ KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
The device id of a Greybus bundle.
+
+What: /sys/bus/greybus/device/.../state
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ A bundle has a state that is managed by the userspace
+ Endo process. This file allows that Endo to signal
+ other Android HALs that the state of the bundle has
+ changed to a specific value. When written to, any
+ process watching the file will be woken up, and the new
+ value can be read. It's a "poor-man's IPC", yes, but
+ simplifies the Android userspace code immensely.
diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c
index 3f1aa6490e48..e7b2199f39b4 100644
--- a/drivers/staging/greybus/bundle.c
+++ b/drivers/staging/greybus/bundle.c
@@ -1,8 +1,8 @@
/*
* Greybus bundles
*
- * Copyright 2014 Google Inc.
- * Copyright 2014 Linaro Ltd.
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
*
* Released under the GPLv2 only.
*/
@@ -31,9 +31,41 @@ static ssize_t class_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(class);
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ if (bundle->state == NULL)
+ return sprintf(buf, "\n");
+
+ return sprintf(buf, "%s\n", bundle->state);
+}
+
+static ssize_t state_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ kfree(bundle->state);
+ bundle->state = kzalloc(size + 1, GFP_KERNEL);
+ if (!bundle->state)
+ return -ENOMEM;
+
+ memcpy(bundle->state, buf, size);
+
+ /* Tell userspace that the file contents changed */
+ sysfs_notify(&bundle->dev.kobj, NULL, "state");
+
+ return size;
+}
+static DEVICE_ATTR_RW(state);
+
+
static struct attribute *bundle_attrs[] = {
&dev_attr_device_id.attr,
&dev_attr_class.attr,
+ &dev_attr_state.attr,
NULL,
};
@@ -43,6 +75,7 @@ static void gb_bundle_release(struct device *dev)
{
struct gb_bundle *bundle = to_gb_bundle(dev);
+ kfree(bundle->state);
kfree(bundle);
}
diff --git a/drivers/staging/greybus/bundle.h b/drivers/staging/greybus/bundle.h
index 3265a008e5df..5c12c72ddcec 100644
--- a/drivers/staging/greybus/bundle.h
+++ b/drivers/staging/greybus/bundle.h
@@ -20,6 +20,7 @@ struct gb_bundle {
u8 class;
u8 device_id;
struct list_head connections;
+ u8 *state;
struct list_head links; /* interface->bundles */
};