greybus: Added a sysfs entry to power down the SVC
authorGeorgi Dobrev <dobrev_georgi@projectara.com>
Thu, 24 Mar 2016 11:37:21 +0000 (13:37 +0200)
committerAkash Choudhari <akashtc@google.com>
Fri, 1 Apr 2016 21:41:49 +0000 (14:41 -0700)
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 <dobrev_georgi@projectara.com>
drivers/staging/greybus/greybus_protocols.h
drivers/staging/greybus/svc.c
drivers/staging/greybus/svc.h

index 06888e029473c6754d71413ae5e3b0c105531a2c..a160e73a76a906d7ac70b5ed639450686da6e1e7 100644 (file)
@@ -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
index a19e575de02989a2301e8d32064e43ee531c6015..f96c645558bea1f521fde57d5147d3ede95c8f75 100644 (file)
@@ -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;
index 8950baff9aef4365257293de68373c7bfc6fb6e4..09d868877c829aaf76b5ae503ea872f3341e975f 100644 (file)
@@ -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);