diff options
-rw-r--r-- | drivers/staging/greybus/Documentation/sysfs-bus-greybus | 13 | ||||
-rw-r--r-- | drivers/staging/greybus/bundle.c | 37 | ||||
-rw-r--r-- | drivers/staging/greybus/bundle.h | 1 |
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 */ }; |