]> git.karo-electronics.de Git - linux-beck.git/commitdiff
greybus: control: add interface suspend prepare operation
authorDavid Lin <dtwlin@google.com>
Fri, 8 Jul 2016 03:07:00 +0000 (22:07 -0500)
committerAlex Elder <elder@linaro.org>
Fri, 8 Jul 2016 19:56:28 +0000 (14:56 -0500)
Add the AP implementation for the Greybus Control Interface Suspend
Prepare Operation. AP uses this Operation during the Suspend transition
to request the Interface to enter a low-power mode after it detects a
subsequent UniPro link hibernation.

Signed-off-by: David Lin <dtwlin@google.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Alex Elder <elder@linaro.org>
drivers/staging/greybus/control.c
drivers/staging/greybus/control.h
drivers/staging/greybus/greybus_protocols.h

index a53fa3d68280de2886e7085983cd757790f1f455..252352ce366459300f83206ceda524b3a6d4038b 100644 (file)
@@ -348,6 +348,41 @@ int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id)
        return 0;
 }
 
+static int gb_control_interface_pm_status_map(u8 status)
+{
+       switch (status) {
+       case GB_CONTROL_INTF_PM_BUSY:
+               return -EBUSY;
+       case GB_CONTROL_INTF_PM_NA:
+               return -ENOMSG;
+       default:
+               return -EREMOTEIO;
+       }
+}
+
+int gb_control_interface_suspend_prepare(struct gb_control *control)
+{
+       struct gb_control_intf_pm_response response;
+       int ret;
+
+       ret = gb_operation_sync(control->connection,
+                               GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE, NULL, 0,
+                               &response, sizeof(response));
+       if (ret) {
+               dev_err(&control->dev,
+                       "failed to send interface suspend prepare: %d\n", ret);
+               return ret;
+       }
+
+       if (response.status != GB_CONTROL_INTF_PM_OK) {
+               dev_err(&control->dev, "interface error while preparing suspend: %d\n",
+                       response.status);
+               return gb_control_interface_pm_status_map(response.status);
+       }
+
+       return 0;
+}
+
 static ssize_t vendor_string_show(struct device *dev,
                        struct device_attribute *attr, char *buf)
 {
index 5ddf0138c6c5538895bd982c446f2b829c54baca..bc32ca78d2256e7d33b62484abc72e963fb72a47 100644 (file)
@@ -56,4 +56,5 @@ int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id);
 int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id);
 int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id);
 int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id);
+int gb_control_interface_suspend_prepare(struct gb_control *control);
 #endif /* __CONTROL_H */
index 1ae335040139854c31aefc12e545476a4bbff8d4..cd64a99debfa113d692be44dccedf93794a27a07 100644 (file)
@@ -130,6 +130,7 @@ struct gb_protocol_version_response {
 #define GB_CONTROL_TYPE_BUNDLE_RESUME          0x10
 #define GB_CONTROL_TYPE_BUNDLE_DEACTIVATE      0x11
 #define GB_CONTROL_TYPE_BUNDLE_ACTIVATE                0x12
+#define GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE           0x13
 
 struct gb_control_version_request {
        __u8    major;
@@ -214,6 +215,20 @@ struct gb_control_bundle_pm_response {
        __u8    status;
 } __packed;
 
+/*
+ * Interface Suspend Prepare and Deactivate Prepare operations use the same
+ * response layout and error codes. Define a single response structure and reuse
+ * it. Both operations have no payload.
+ */
+
+#define GB_CONTROL_INTF_PM_OK          0x00
+#define GB_CONTROL_INTF_PM_BUSY                0x01
+#define GB_CONTROL_INTF_PM_NA          0x02
+
+struct gb_control_intf_pm_response {
+       __u8    status;
+} __packed;
+
 /* APBridge protocol */
 
 /* request APB1 log */