greybus: interface: add power_state attribute

User space needs the capability of powering ON or OFF an Interface for
multiple use cases. For example, userspace may want an Interface
currently in its S3 boot stage, to boot into its S2 Loader stage to
update the bridge SPI flash. Or the Interface is running its S2 Loader
stage and updated the SPI flash with the new S2 Loader firmware and
wants to boot into the new S2 Loader firmware.

Another use case can be, Android wants to disable (not eject) a
misbehaving module.

Add a 'power_state' sysfs file within the interface directory. It can be
read to know the current power state of the Interface and can be written
to power ON or power OFF an Interface. Possible values that can be
written or read from it are: "on" and "off".

Testing Done: Tested by enabling/disabling camera module on EVT 2.0.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
CC: David Lin <dtwlin@google.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
[johan: drop es3-quirk duplication, add to power attribute group, fix
return value, drop tags ]
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Sandeep Patil <sspatil@google.com>
Reviewed-by: Patrick Titiano <ptitiano@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Viresh Kumar 2016-07-20 16:40:25 +02:00 committed by Greg Kroah-Hartman
parent 12169bc914
commit 93e29c8530
2 changed files with 75 additions and 0 deletions

View File

@ -97,6 +97,23 @@ Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
Power measurement of the interface in microwatts (uW)
What: /sys/bus/greybus/devices/N-M.I/power_state
Date: March 2016
KernelVersion: 4.XX
Contact: Greg Kroah-Hartman <greg@kroah.com>
Description:
This reflects the power state of a Greybus Interface. If the
value read from it is "on", then power is currently supplied to
the Interface. Otherwise this will read "off" and the power is
currently not supplied to the Interface.
If the value read is "off", then writing "on" (or '1', 'y',
'Y') to it will enable power to the Interface. If the value
read is "on", then writing "off" (or '0', 'n', 'N') to it will
disable power to the Interface.
Writing the currently read value to it has no effect.
What: /sys/bus/greybus/devices/N-M.I/product_id
Date: October 2015
KernelVersion: 4.XX

View File

@ -501,6 +501,63 @@ static ssize_t power_now_show(struct device *dev,
}
static DEVICE_ATTR_RO(power_now);
static ssize_t power_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct gb_interface *intf = to_gb_interface(dev);
if (intf->active)
return scnprintf(buf, PAGE_SIZE, "on\n");
else
return scnprintf(buf, PAGE_SIZE, "off\n");
}
static ssize_t power_state_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t len)
{
struct gb_interface *intf = to_gb_interface(dev);
bool activate;
int ret = 0;
if (kstrtobool(buf, &activate))
return -EINVAL;
mutex_lock(&intf->mutex);
if (activate == intf->active)
goto unlock;
if (activate) {
ret = gb_interface_activate(intf);
if (ret) {
dev_err(&intf->dev,
"failed to activate interface: %d\n", ret);
goto unlock;
}
ret = gb_interface_enable(intf);
if (ret) {
dev_err(&intf->dev,
"failed to enable interface: %d\n", ret);
gb_interface_deactivate(intf);
goto unlock;
}
} else {
gb_interface_disable(intf);
gb_interface_deactivate(intf);
}
unlock:
mutex_unlock(&intf->mutex);
if (ret)
return ret;
return len;
}
static DEVICE_ATTR_RW(power_state);
static const char *gb_interface_type_string(struct gb_interface *intf)
{
static const char * const types[] = {
@ -541,6 +598,7 @@ static struct attribute *interface_power_attrs[] = {
&dev_attr_voltage_now.attr,
&dev_attr_current_now.attr,
&dev_attr_power_now.attr,
&dev_attr_power_state.attr,
NULL
};