From 88a3011e91f7c557798301d47f830320580795cf Mon Sep 17 00:00:00 2001 From: Georgi Dobrev Date: Thu, 24 Mar 2016 13:37:21 +0200 Subject: [PATCH] greybus: Added a sysfs entry to power down the SVC Added a sysfs entry called pwr_off. When a "1" is passed to it, it sends a GB_SVC_TYPE_PWR_DOWN command to the SVC, powering it down along with the switch and INA231 chips. Testing Done: Tested on EVT1_5, works. Signed-off-by: Georgi Dobrev --- drivers/staging/greybus/greybus_protocols.h | 1 + drivers/staging/greybus/svc.c | 28 ++++++++++++++++++++++++++++ drivers/staging/greybus/svc.h | 1 + 3 files changed, 30 insertions(+) diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 06888e0..a160e73 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -798,6 +798,7 @@ struct gb_spi_transfer_response { #define GB_SVC_TYPE_INTF_EJECT 0x11 #define GB_SVC_TYPE_KEY_EVENT 0x12 #define GB_SVC_TYPE_PING 0x13 +#define GB_SVC_TYPE_PWR_DOWN 0x1d /* * SVC version request/response has the same payload as diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c index a19e575..f96c645 100644 --- a/drivers/staging/greybus/svc.c +++ b/drivers/staging/greybus/svc.c @@ -99,11 +99,31 @@ static ssize_t watchdog_store(struct device *dev, } static DEVICE_ATTR_RW(watchdog); +static ssize_t pwr_off_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t len) +{ + struct gb_svc *svc = to_gb_svc(dev); + int retval; + bool user_request; + + retval = strtobool(buf, &user_request); + if (retval) { + return retval; + } + if (user_request) { + retval = gb_svc_pwr_off(svc); + } + return len; +} +static DEVICE_ATTR_WO(pwr_off); + static struct attribute *svc_attrs[] = { &dev_attr_endo_id.attr, &dev_attr_ap_intf_id.attr, &dev_attr_intf_eject.attr, &dev_attr_watchdog.attr, + &dev_attr_pwr_off.attr, NULL, }; ATTRIBUTE_GROUPS(svc); @@ -320,6 +340,14 @@ int gb_svc_ping(struct gb_svc *svc) } EXPORT_SYMBOL_GPL(gb_svc_ping); +int gb_svc_pwr_off(struct gb_svc *svc) +{ + return gb_operation_sync_timeout(svc->connection, GB_SVC_TYPE_PWR_DOWN, + NULL, 0, NULL, 0, + GB_OPERATION_TIMEOUT_DEFAULT * 2); +} +EXPORT_SYMBOL_GPL(gb_svc_pwr_off); + static int gb_svc_version_request(struct gb_operation *op) { struct gb_connection *connection = op->connection; diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h index 8950baf..09d8688 100644 --- a/drivers/staging/greybus/svc.h +++ b/drivers/staging/greybus/svc.h @@ -71,6 +71,7 @@ void gb_svc_watchdog_destroy(struct gb_svc *svc); bool gb_svc_watchdog_enabled(struct gb_svc *svc); int gb_svc_watchdog_enable(struct gb_svc *svc); int gb_svc_watchdog_disable(struct gb_svc *svc); +int gb_svc_pwr_off(struct gb_svc *svc); int gb_svc_protocol_init(void); void gb_svc_protocol_exit(void); -- 2.7.4