Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp8151419ybi; Thu, 6 Jun 2019 07:32:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqzksp0MUmd1SM2DykvvVUz7PyFYHgy0jPJ47CoqMcwcOw4vMi9jkcAnYyfdKeAVYdHTlGSB X-Received: by 2002:a17:90a:ca09:: with SMTP id x9mr161807pjt.105.1559831552183; Thu, 06 Jun 2019 07:32:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559831552; cv=none; d=google.com; s=arc-20160816; b=DO3l75DOayLw5B7/ISgla1jTIz7dTHTlWHRnz7II2bCqNHa20WGBtkchwj/+WePTad CwmvOsVHGP5RRsdj/r/pupl8dHIUa4oyMmsc4WWr3Ti9ZOIhhJJTlJgpdsjofF6qcwTk Z0vpqKPavO2kdCNx18IBUa2AWE/n4PFnGgUmR8L5I1QPynWGLUM9l616a7EU3wgpfCQ9 /w+jgbhK+RaaFk5ownBxqtSKMs2KSxJam0A/FMjygaWN8N2/qM3xYgkox1DCS4+QezYJ NlsurxUvVrtElSImvFnwmP+ba7PMTOUJe/t0QqzqKinTC/wWMt6+CxqknR8m0by85WW0 Iasw== 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; bh=oZyfIfqGH83IrEJuwRmk8TVRefmEttkfJQeS02bJUtA=; b=AmvIQvoObQ+KK0JupPwvRX6pCXkfFCmnD/9df21U2ZxHE/oKZGJgIoeL4lLkcpmZCq H666RYAvuwpkg2ZjffzM4AdL6ZU0ksBSzDexR7ZlvnhWmBpoE8327yJaoYYSPGJpZtqW zCdrL9iS0CNlT8WQ2TlmAAw4wP/O4PM8jAvyvkdQ6ydQd+jwiBUFfoXXwekpWEeS0ZQ/ FtO/eVIFrXC1y8nEELp93/kbrJ1qczO/5rsB6Q5AmVvdOiEUSaiTdp89fVQD+wguZfWo BQ1f/PgeAUwqnirYp6kMCOTvWJoTP79yFnB1Mr92ZdJxwXCUth1dQIxg1xns44MAcy8Y yFtQ== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j93si1901078plb.32.2019.06.06.07.32.15; Thu, 06 Jun 2019 07:32:32 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728968AbfFFObD (ORCPT + 99 others); Thu, 6 Jun 2019 10:31:03 -0400 Received: from mx2.suse.de ([195.135.220.15]:49832 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727133AbfFFObD (ORCPT ); Thu, 6 Jun 2019 10:31:03 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id E4583AFE3; Thu, 6 Jun 2019 14:31:01 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, "Rafael J. Wysocki" , Viresh Kumar Cc: mbrugger@suse.de, sboyd@kernel.org, eric@anholt.net, f.fainelli@gmail.com, bcm-kernel-feedback-list@broadcom.com, ptesarik@suse.com, linux-rpi-kernel@lists.infradead.org, ssuloev@orpaltech.com, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, mturquette@baylibre.com, linux-pm@vger.kernel.org, Nicolas Saenz Julienne , linux-kernel@vger.kernel.org Subject: [PATCH v2 4/7] cpufreq: add driver for Raspbery Pi Date: Thu, 6 Jun 2019 16:22:56 +0200 Message-Id: <20190606142255.29454-5-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190606142255.29454-1-nsaenzjulienne@suse.de> References: <20190606142255.29454-1-nsaenzjulienne@suse.de> 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 Raspberry Pi's firmware offers and interface though which update it's performance requirements. It allows us to request for specific runtime frequencies, which the firmware might or might not respect, depending on the firmware configuration and thermals. As the maximum and minimum frequencies are configurable in the firmware there is no way to know in advance their values. So the Raspberry Pi cpufreq driver queries them, builds an opp frequency table to then launch cpufreq-dt. Also, as the firmware interface might be configured as a module, making the cpu clock unavailable during init, this implements a full fledged driver, as opposed to most drivers registering cpufreq-dt, which only make use of an init routine. Signed-off-by: Nicolas Saenz Julienne Acked-by: Eric Anholt --- Changes since v1: - Remove compatible checks - Add module support, now full fledged driver - Use NULL in clk_get() drivers/cpufreq/Kconfig.arm | 8 +++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/raspberrypi-cpufreq.c | 100 ++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 drivers/cpufreq/raspberrypi-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index f8129edc145e..5e9204d443ff 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -133,6 +133,14 @@ config ARM_QCOM_CPUFREQ_HW The driver implements the cpufreq interface for this HW engine. Say Y if you want to support CPUFreq HW. +config ARM_RASPBERRYPI_CPUFREQ + tristate "Raspberry Pi cpufreq support" + depends on CLK_RASPBERRYPI || COMPILE_TEST + help + This adds the CPUFreq driver for Raspberry Pi + + If in doubt, say N. + config ARM_S3C_CPUFREQ bool help diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 689b26c6f949..121c1acb66c0 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRYO) += qcom-cpufreq-kryo.o +obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o diff --git a/drivers/cpufreq/raspberrypi-cpufreq.c b/drivers/cpufreq/raspberrypi-cpufreq.c new file mode 100644 index 000000000000..99b59d5a50aa --- /dev/null +++ b/drivers/cpufreq/raspberrypi-cpufreq.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Raspberry Pi cpufreq driver + * + * Copyright (C) 2019, Nicolas Saenz Julienne + */ + +#include +#include +#include +#include +#include +#include + +static struct platform_device *cpufreq_dt; + +static int raspberrypi_cpufreq_probe(struct platform_device *pdev) +{ + struct device *cpu_dev; + unsigned long min, max; + unsigned long rate; + struct clk *clk; + int ret; + + cpu_dev = get_cpu_device(0); + if (!cpu_dev) { + pr_err("Cannot get CPU for cpufreq driver\n"); + return -ENODEV; + } + + clk = clk_get(cpu_dev, NULL); + if (IS_ERR(clk)) { + dev_err(cpu_dev, "Cannot get clock for CPU0\n"); + return PTR_ERR(clk); + } + + /* + * The max and min frequencies are configurable in the Raspberry Pi + * firmware, so we query them at runtime + */ + min = clk_round_rate(clk, 0); + max = clk_round_rate(clk, ULONG_MAX); + clk_put(clk); + + for (rate = min; rate < max; rate += 100000000) { + ret = dev_pm_opp_add(cpu_dev, rate, 0); + if (ret) + goto remove_opp; + } + + ret = dev_pm_opp_add(cpu_dev, max, 0); + if (ret) + goto remove_opp; + + cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); + ret = PTR_ERR_OR_ZERO(cpufreq_dt); + if (ret) { + dev_err(cpu_dev, "Failed to create platform device, %d\n", ret); + goto remove_opp; + } + + return 0; + +remove_opp: + dev_pm_opp_remove_all_dynamic(cpu_dev); + + return ret; +} + +static int raspberrypi_cpufreq_remove(struct platform_device *pdev) +{ + struct device *cpu_dev; + + cpu_dev = get_cpu_device(0); + if (cpu_dev) + dev_pm_opp_remove_all_dynamic(cpu_dev); + + platform_device_unregister(cpufreq_dt); + cpufreq_dt = NULL; + + return 0; +} + +/* + * Since the driver depends on clk-raspberrypi, which may return EPROBE_DEFER, + * all the activity is performed in the probe, which may be defered as well. + */ +static struct platform_driver raspberrypi_cpufreq_driver = { + .driver = { + .name = "raspberrypi-cpufreq", + }, + .probe = raspberrypi_cpufreq_probe, + .remove = raspberrypi_cpufreq_remove, +}; +module_platform_driver(raspberrypi_cpufreq_driver); + +MODULE_AUTHOR("Nicolas Saenz Julienne