Received: by 2002:a25:b323:0:0:0:0:0 with SMTP id l35csp2769519ybj; Mon, 23 Sep 2019 09:07:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqyoP4LNzyZ+OgQTb2pjKtzuJHBVJcFHjh9thUriULWeAa/bRy8UU9r1WlbpaBLqiBcCes+V X-Received: by 2002:a17:906:d8a9:: with SMTP id qc9mr554613ejb.199.1569254820591; Mon, 23 Sep 2019 09:07:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569254820; cv=none; d=google.com; s=arc-20160816; b=x6d4qS2/TmVnDk98xBtuWCfwuc5O5LTp1QBJSNTj+lEl2V6sGT5GsnAyXmxcF6E1jY z9x/sWHz8Sv+i8VJyOhoHMuzQBpu+lSqfTLXDrosTvzHOGRHd3Y7UDy6TeS7vZpEk//G b3MYMGjjXh3PZ56tn/fl9e08qzoLstKTokvjbkfsjrM6IHGg36Qw39DAb0gQV7e9/AOg MU3cGM0qIsjZFyAmj3hdFYcvoHEudQ10y0SUD9UqBdpuqnQcuVGf9Rsi2saCtbw7V7/F cDORgEaqLXU/8ua3f0WbU3SyEJqIGh70zQ9iQB7lgTGx3ezzRa7fGoGY5PTmD4eAZFSb 7AeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=l7hNi5D/ZJN0kVpa71JImctObcmY7ytKQRt7LHXZ63k=; b=Tv82dnMnxtFL+Ik3Jt8yTaHNqa2eEHZIAzi9f3KhqVgyG1e+0AkEieF0IqjW0ACPpc b3BgCISpFlAvoCnxzMRVfgCb/Aa17nUL2bRKRraWS4EtIE6wOwX2czHG/AsR9XpleB0v M/sSZNciotDHiAQFVTqkdAbdvWPlle+Y3nTkZm4pcC1TyDLk76TL1MwOpsEJz58IlG/m Gob3rjoDjP7iuVTnmu9dTvqq1wfSQ9QtY8Nx3oWBwa4AfuzDXmh86d4q4wXwhPk7p0jD NyAnOfn1edsJEuRlNFuPaJi4lG2Wea0soYOuOE2arTkXT51L4r0IOWKGRUgm9kS1xm7V uZCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=P4JQLK9m; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z4si5165541eji.316.2019.09.23.09.06.36; Mon, 23 Sep 2019 09:07:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=P4JQLK9m; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388355AbfIVRv0 (ORCPT + 99 others); Sun, 22 Sep 2019 13:51:26 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:40142 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388245AbfIVRvM (ORCPT ); Sun, 22 Sep 2019 13:51:12 -0400 Received: by mail-pg1-f194.google.com with SMTP id w10so6552247pgj.7 for ; Sun, 22 Sep 2019 10:51:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=l7hNi5D/ZJN0kVpa71JImctObcmY7ytKQRt7LHXZ63k=; b=P4JQLK9mbCyUdt4Ia4YwRkZEpMegMyS4gVNxeA2hKVAj+f5Yoo0iu6Tjy/MiwMrJA0 H4WlYzRbqQo06+PNTu7t63DtS77WG3T+cI3ihSCCrVIAE2ZT4Ahw8tmLBFaQ3NRB1tog wM+rpgr+HNaplYdiQQV/ZqXa7cFdh0ui2v2Po= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l7hNi5D/ZJN0kVpa71JImctObcmY7ytKQRt7LHXZ63k=; b=iLB1atFk0CJK2qGCa5+LmbQWwI36QXy23r4kKiXfIaXKsCLMt2KOrESiPyk3NlhCJt fMNS3IdTbehFlJ6LduDifDtrwLTWsxF2qxAFxxAeZOhT4KBtgbhUrkucVKAj/xZooCAi qUwW5gqIccgypfm3QY1BP8VxI3qVjnvWI6Rifufv+yISrrqtBDPyVqa5d3QvnyzjL+pL u9Df3JyWppNb+yt94U6bKeBV2RUngL/x5IHP/JysXKXdrBxlHXpunwoajuI7LX6Zrhko woWppllJro/iWrHCow+gxCqoIqaCXmvTEXqpqPg6GVdtrNNOtSWSjLgVuo+pVxlofwrP IOCg== X-Gm-Message-State: APjAAAWw8EwZTEvStDY/Z8IM59iJQiHrz8QOrd7ghAv4EqFm3uxhNM3l SrTpP/hkwXAk+pXzgOq0jPiFTw== X-Received: by 2002:a62:583:: with SMTP id 125mr30466432pff.69.1569174670438; Sun, 22 Sep 2019 10:51:10 -0700 (PDT) Received: from localhost ([2620:15c:202:1:3c8f:512b:3522:dfaf]) by smtp.gmail.com with ESMTPSA id n8sm14159523pgt.40.2019.09.22.10.51.09 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 22 Sep 2019 10:51:09 -0700 (PDT) From: Gwendal Grignou To: jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net, lee.jones@linaro.org, bleung@chromium.org, enric.balletbo@collabora.com, dianders@chromium.org, groeck@chromium.org, fabien.lahoudere@collabora.com Cc: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, Enrico Granata , Gwendal Grignou Subject: [PATCH 06/13] platform: chrome: cros_ec: handle MKBP more events flag Date: Sun, 22 Sep 2019 10:50:14 -0700 Message-Id: <20190922175021.53449-7-gwendal@chromium.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190922175021.53449-1-gwendal@chromium.org> References: <20190922175021.53449-1-gwendal@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Enrico Granata The ChromeOS EC has support for signaling to the host that a single IRQ can serve multiple MKBP events. Doing this serves an optimization purpose, as it minimizes the number of round-trips into the interrupt handling machinery, and it proves beneficial to sensor timestamping as it keeps the desired synchronization of event times between the two processors. This patch adds kernel support for this EC feature, allowing the ec_irq to loop until all events have been served. Signed-off-by: Enrico Granata Signed-off-by: Gwendal Grignou --- drivers/platform/chrome/cros_ec.c | 33 +++++++++---- drivers/platform/chrome/cros_ec_proto.c | 51 ++++++++++++--------- include/linux/platform_data/cros_ec_proto.h | 7 ++- 3 files changed, 57 insertions(+), 34 deletions(-) diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index 9c8dc7cdb2b7..4adc007c357c 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -46,25 +46,38 @@ static irqreturn_t ec_irq_handler(int irq, void *data) return IRQ_WAKE_THREAD; } -static irqreturn_t ec_irq_thread(int irq, void *data) +static bool ec_handle_event(struct cros_ec_device *ec_dev) { - struct cros_ec_device *ec_dev = data; bool wake_event = true; - int ret; + bool ec_has_more_events = false; + int ret = cros_ec_get_next_event(ec_dev, &wake_event); - ret = cros_ec_get_next_event(ec_dev, &wake_event); + if (ec_dev->mkbp_event_supported) { + ec_has_more_events = (ret > 0) && + (ec_dev->event_data.event_type & + EC_MKBP_HAS_MORE_EVENTS); + } - /* - * Signal only if wake host events or any interrupt if - * cros_ec_get_next_event() returned an error (default value for - * wake_event is true) - */ - if (wake_event && device_may_wakeup(ec_dev->dev)) + if (device_may_wakeup(ec_dev->dev) && wake_event) pm_wakeup_event(ec_dev->dev, 0); if (ret > 0) blocking_notifier_call_chain(&ec_dev->event_notifier, 0, ec_dev); + + return ec_has_more_events; + +} + +static irqreturn_t ec_irq_thread(int irq, void *data) +{ + struct cros_ec_device *ec_dev = data; + bool ec_has_more_events; + + do { + ec_has_more_events = ec_handle_event(ec_dev); + } while (ec_has_more_events); + return IRQ_HANDLED; } diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index f659f96bda12..70e6d6c93b8d 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -425,10 +425,14 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_GET_NEXT_EVENT, &ver_mask); - if (ret < 0 || ver_mask == 0) + if (ret < 0 || ver_mask == 0) { ec_dev->mkbp_event_supported = 0; - else - ec_dev->mkbp_event_supported = 1; + dev_info(ec_dev->dev, "MKBP not supported\n"); + } else { + ec_dev->mkbp_event_supported = fls(ver_mask); + dev_info(ec_dev->dev, "MKBP support version %u\n", + ec_dev->mkbp_event_supported - 1); + } /* Probe if host sleep v1 is supported for S0ix failure detection. */ ret = cros_ec_get_host_command_version_mask(ec_dev, @@ -519,6 +523,7 @@ EXPORT_SYMBOL(cros_ec_cmd_xfer_status); static int get_next_event_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg, + struct ec_response_get_next_event_v1 *event, int version, uint32_t size) { int ret; @@ -531,7 +536,7 @@ static int get_next_event_xfer(struct cros_ec_device *ec_dev, ret = cros_ec_cmd_xfer(ec_dev, msg); if (ret > 0) { ec_dev->event_size = ret - 1; - memcpy(&ec_dev->event_data, msg->data, ret); + ec_dev->event_data = *event; } return ret; @@ -539,30 +544,29 @@ static int get_next_event_xfer(struct cros_ec_device *ec_dev, static int get_next_event(struct cros_ec_device *ec_dev) { - u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)]; - struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; - static int cmd_version = 1; - int ret; + struct { + struct cros_ec_command msg; + struct ec_response_get_next_event_v1 event; + } __packed buf; + struct cros_ec_command *msg = &buf.msg; + struct ec_response_get_next_event_v1 *event = &buf.event; + const int cmd_version = ec_dev->mkbp_event_supported - 1; + + BUILD_BUG_ON(sizeof(union ec_response_get_next_data_v1) != 16); + + memset(&buf, 0, sizeof(buf)); if (ec_dev->suspended) { dev_dbg(ec_dev->dev, "Device suspended.\n"); return -EHOSTDOWN; } - if (cmd_version == 1) { - ret = get_next_event_xfer(ec_dev, msg, cmd_version, - sizeof(struct ec_response_get_next_event_v1)); - if (ret < 0 || msg->result != EC_RES_INVALID_VERSION) - return ret; - - /* Fallback to version 0 for future send attempts */ - cmd_version = 0; - } - - ret = get_next_event_xfer(ec_dev, msg, cmd_version, + if (cmd_version == 0) + return get_next_event_xfer(ec_dev, msg, event, 0, sizeof(struct ec_response_get_next_event)); - return ret; + return get_next_event_xfer(ec_dev, msg, event, cmd_version, + sizeof(struct ec_response_get_next_event_v1)); } static int get_keyboard_state_event(struct cros_ec_device *ec_dev) @@ -606,7 +610,8 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event) return ret; if (wake_event) { - event_type = ec_dev->event_data.event_type; + event_type = + ec_dev->event_data.event_type & EC_MKBP_EVENT_TYPE_MASK; host_event = cros_ec_get_host_event(ec_dev); /* @@ -631,10 +636,12 @@ EXPORT_SYMBOL(cros_ec_get_next_event); u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev) { u32 host_event; + const u8 event_type = + ec_dev->event_data.event_type & EC_MKBP_EVENT_TYPE_MASK; BUG_ON(!ec_dev->mkbp_event_supported); - if (ec_dev->event_data.event_type != EC_MKBP_EVENT_HOST_EVENT) + if (event_type != EC_MKBP_EVENT_HOST_EVENT) return 0; if (ec_dev->event_size != sizeof(host_event)) { diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index ab12e28f2107..63b5597294e7 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -115,7 +115,9 @@ struct cros_ec_command { * code. * @pkt_xfer: Send packet to EC and get response. * @lock: One transaction at a time. - * @mkbp_event_supported: True if this EC supports the MKBP event protocol. + * @mkbp_event_supported: 0 if MKBP not supported. Otherwise its value is + * the maximum supported version of the MKBP host event + * command + 1. * @host_sleep_v1: True if this EC supports the sleep v1 command. * @event_notifier: Interrupt event notifier for transport devices. * @event_data: Raw payload transferred with the MKBP event. @@ -155,7 +157,8 @@ struct cros_ec_device { int (*pkt_xfer)(struct cros_ec_device *ec, struct cros_ec_command *msg); struct mutex lock; - bool mkbp_event_supported; + /* 0 == not supported, otherwise it supports version x - 1 */ + u8 mkbp_event_supported; bool host_sleep_v1; struct blocking_notifier_head event_notifier; -- 2.23.0.351.gc4317032e6-goog