mfd: intel_quark_i2c_gpio: Adjust IOT2000 matching
[linux-2.6-microblaze.git] / drivers / mfd / cros_ec.c
index 6acfe03..bd2bcdd 100644 (file)
@@ -75,20 +75,49 @@ static irqreturn_t ec_irq_thread(int irq, void *data)
 
 static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
 {
+       int ret;
        struct {
                struct cros_ec_command msg;
-               struct ec_params_host_sleep_event req;
+               union {
+                       struct ec_params_host_sleep_event req0;
+                       struct ec_params_host_sleep_event_v1 req1;
+                       struct ec_response_host_sleep_event_v1 resp1;
+               } u;
        } __packed buf;
 
        memset(&buf, 0, sizeof(buf));
 
-       buf.req.sleep_event = sleep_event;
+       if (ec_dev->host_sleep_v1) {
+               buf.u.req1.sleep_event = sleep_event;
+               buf.u.req1.suspend_params.sleep_timeout_ms =
+                               EC_HOST_SLEEP_TIMEOUT_DEFAULT;
+
+               buf.msg.outsize = sizeof(buf.u.req1);
+               if ((sleep_event == HOST_SLEEP_EVENT_S3_RESUME) ||
+                   (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME))
+                       buf.msg.insize = sizeof(buf.u.resp1);
+
+               buf.msg.version = 1;
+
+       } else {
+               buf.u.req0.sleep_event = sleep_event;
+               buf.msg.outsize = sizeof(buf.u.req0);
+       }
 
        buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
-       buf.msg.version = 0;
-       buf.msg.outsize = sizeof(buf.req);
 
-       return cros_ec_cmd_xfer(ec_dev, &buf.msg);
+       ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
+
+       /* For now, report failure to transition to S0ix with a warning. */
+       if (ret >= 0 && ec_dev->host_sleep_v1 &&
+           (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME))
+               WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
+                         EC_HOST_RESUME_SLEEP_TIMEOUT,
+                         "EC detected sleep transition timeout. Total slp_s0 transitions: %d",
+                         buf.u.resp1.resume_response.sleep_transitions &
+                         EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
+
+       return ret;
 }
 
 int cros_ec_register(struct cros_ec_device *ec_dev)