From patchwork Thu Jun 7 18:12:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Kaehlcke X-Patchwork-Id: 10453321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D137660146 for ; Thu, 7 Jun 2018 18:13:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C0ABB205FD for ; Thu, 7 Jun 2018 18:13:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B4C3B22B26; Thu, 7 Jun 2018 18:13:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2B402205FD for ; Thu, 7 Jun 2018 18:13:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936101AbeFGSNO (ORCPT ); Thu, 7 Jun 2018 14:13:14 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:43799 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934476AbeFGSNJ (ORCPT ); Thu, 7 Jun 2018 14:13:09 -0400 Received: by mail-pl0-f67.google.com with SMTP id c41-v6so6624601plj.10 for ; Thu, 07 Jun 2018 11:13:09 -0700 (PDT) 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; bh=yNTPVOc9itsgSGXJtTCwKhZik/oC0KXvCOU82jh0Sag=; b=V7f8OfR+ImK4uPe6E5ZRmZKKSe60Pzij/dI/7I4cPjnZDuwi3DtYdtyGCacGk+F39T oTJOTx9RRPQTUpglTap5o5HUJOFcqVl//nm0WfAx9oT8yFpYig7d6/FgnFF0+Qhi1pi8 J6SqxwFq5wDPMNawstT780AfQUJ5HzTwbhDPCISGmEsGxMwd+Z6NOsuo204nTdYxP87S IBtLYDDob5fEY+niPR9g7cTCPsNQTFSezIC11aNAslz0Xe5LKrszMiMiDXf2KoJ8RHn4 7z4zASv1fAUnzCUjykIT+hn1GJ8Dd02ifNO4T/xOgQxk/yeuRObXrWBslrVS7XxxlYV9 gaxA== X-Gm-Message-State: APt69E0Yqwpdw0bj2FUkUGWpcw9TSAW2iCmLUCzVG8w8wrFnqb+vhb73 3uqi5MuZWyzMjq07bc8ek/VMsg== X-Google-Smtp-Source: ADUXVKJmSi2pmqwPqO9jyFwKIogQQcJZlX/BELdGceJVIiPoVGjjYoI4OopvrSvpanmx4+T8Aj+1Bg== X-Received: by 2002:a17:902:6bc1:: with SMTP id m1-v6mr3080106plt.91.1528395188432; Thu, 07 Jun 2018 11:13:08 -0700 (PDT) Received: from mka.mtv.corp.google.com ([2620:0:1000:1501:8e2d:4727:1211:622]) by smtp.gmail.com with ESMTPSA id z3-v6sm5029002pfn.36.2018.06.07.11.13.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Jun 2018 11:13:07 -0700 (PDT) From: Matthias Kaehlcke To: MyungJoo Ham Cc: Kyungmin Park , Chanwoo Choi , Arnd Bergmann , Greg Kroah-Hartman , Rob Herring , Mark Rutland , linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Brian Norris , Douglas Anderson , Enric Balletbo i Serra , Matthias Kaehlcke Subject: [PATCH v2 11/11] misc: throttler: Add Chrome OS EC throttler Date: Thu, 7 Jun 2018 11:12:14 -0700 Message-Id: <20180607181214.30338-12-mka@chromium.org> X-Mailer: git-send-email 2.18.0.rc1.242.g61856ae69a-goog In-Reply-To: <20180607181214.30338-1-mka@chromium.org> References: <20180607181214.30338-1-mka@chromium.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The driver subscribes to throttling events from the Chrome OS embedded controller and enables/disables system throttling based on these events. Signed-off-by: Matthias Kaehlcke Reviewed-by: Enric Balletbo i Serra --- Changes in v2: - added SPDX line instead of license boiler-plate - use macro to avoid splitting line - changed variable name for throttler from 'cte' to 'ce_thr' - formatting fixes - Kconfig: removed odd dashes around 'help' - added 'Reviewed-by' tag Note: I finally decided to keep 'Chrome OS' instead of changing it to 'ChromeOS'. Both are currently used in the kernel, the latter is currently more prevalent, however the official name is 'Chrome OS', so there is no good reason to keep introducing the 'alternative' name. drivers/misc/throttler/Kconfig | 14 +++ drivers/misc/throttler/Makefile | 1 + drivers/misc/throttler/cros_ec_throttler.c | 116 +++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 drivers/misc/throttler/cros_ec_throttler.c diff --git a/drivers/misc/throttler/Kconfig b/drivers/misc/throttler/Kconfig index e561f1df5085..da6fb70b96d9 100644 --- a/drivers/misc/throttler/Kconfig +++ b/drivers/misc/throttler/Kconfig @@ -12,3 +12,17 @@ menuconfig THROTTLER Note that you also need a event monitor module usually called *_throttler. +if THROTTLER + +config CROS_EC_THROTTLER + tristate "Throttler event monitor for the Chrome OS Embedded Controller" + depends on MFD_CROS_EC + help + This driver adds support to throttle the system in reaction to + Chrome OS EC events. + + To compile this driver as a module, choose M here: the + module will be called cros_ec_throttler. + +endif # THROTTLER + diff --git a/drivers/misc/throttler/Makefile b/drivers/misc/throttler/Makefile index c8d920cee315..d9b2a77dabc9 100644 --- a/drivers/misc/throttler/Makefile +++ b/drivers/misc/throttler/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_THROTTLER) += core.o +obj-$(CONFIG_CROS_EC_THROTTLER) += cros_ec_throttler.o diff --git a/drivers/misc/throttler/cros_ec_throttler.c b/drivers/misc/throttler/cros_ec_throttler.c new file mode 100644 index 000000000000..432135c55600 --- /dev/null +++ b/drivers/misc/throttler/cros_ec_throttler.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for throttling triggered by events from the Chrome OS Embedded + * Controller. + * + * Copyright (C) 2018 Google, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define nb_to_ce_thr(nb) container_of(nb, struct cros_ec_throttler, nb) + +struct cros_ec_throttler { + struct cros_ec_device *ec; + struct throttler *throttler; + struct notifier_block nb; +}; + +static int cros_ec_throttler_event(struct notifier_block *nb, + unsigned long queued_during_suspend, void *_notify) +{ + struct cros_ec_throttler *ce_thr = nb_to_ce_thr(nb); + u32 host_event; + + host_event = cros_ec_get_host_event(ce_thr->ec); + if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_THROTTLE_START)) { + throttler_set_level(ce_thr->throttler, 1); + + return NOTIFY_OK; + } else if (host_event & + EC_HOST_EVENT_MASK(EC_HOST_EVENT_THROTTLE_STOP)) { + throttler_set_level(ce_thr->throttler, 0); + + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static int cros_ec_throttler_probe(struct platform_device *pdev) +{ + struct cros_ec_throttler *ce_thr; + struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + int ret; + + if (!np) { + /* should never happen */ + return -EINVAL; + } + + ce_thr = devm_kzalloc(dev, sizeof(*ce_thr), GFP_KERNEL); + if (!ce_thr) + return -ENOMEM; + + ce_thr->ec = dev_get_drvdata(pdev->dev.parent); + + ce_thr->throttler = throttler_setup(dev); + if (IS_ERR(ce_thr->throttler)) + return PTR_ERR(ce_thr->throttler); + + dev_set_drvdata(dev, ce_thr); + + ce_thr->nb.notifier_call = cros_ec_throttler_event; + ret = blocking_notifier_chain_register(&ce_thr->ec->event_notifier, + &ce_thr->nb); + if (ret < 0) { + dev_err(dev, "failed to register notifier\n"); + throttler_teardown(ce_thr->throttler); + return ret; + } + + return 0; +} + +static int cros_ec_throttler_remove(struct platform_device *pdev) +{ + struct cros_ec_throttler *ce_thr = platform_get_drvdata(pdev); + + blocking_notifier_chain_unregister(&ce_thr->ec->event_notifier, + &ce_thr->nb); + + throttler_teardown(ce_thr->throttler); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id cros_ec_throttler_of_match[] = { + { .compatible = "google,cros-ec-throttler" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, cros_ec_throttler_of_match); +#endif /* CONFIG_OF */ + +static struct platform_driver cros_ec_throttler_driver = { + .driver = { + .name = "cros-ec-throttler", + .of_match_table = of_match_ptr(cros_ec_throttler_of_match), + }, + .probe = cros_ec_throttler_probe, + .remove = cros_ec_throttler_remove, +}; + +module_platform_driver(cros_ec_throttler_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Matthias Kaehlcke "); +MODULE_DESCRIPTION("Chrome OS EC Throttler");