From patchwork Wed Aug 12 19:00:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 7003641 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id ED01EC05AC for ; Wed, 12 Aug 2015 19:03:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E44CC20678 for ; Wed, 12 Aug 2015 19:03:40 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5553220612 for ; Wed, 12 Aug 2015 19:03:38 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZPbHN-00069o-TX; Wed, 12 Aug 2015 19:01:37 +0000 Received: from mail-pd0-f171.google.com ([209.85.192.171]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZPbGr-0005c1-EZ for linux-arm-kernel@lists.infradead.org; Wed, 12 Aug 2015 19:01:14 +0000 Received: by pdrh1 with SMTP id h1so10287698pdr.0 for ; Wed, 12 Aug 2015 12:00:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=xuXfO665rI21yswB+DsKPDM1MSAz3VI7C+EGJOA4LzM=; b=SxNjYErWVVzLP4od5yFUbVuju9s8tCPQ4K0EPD2U2y0NbvM7T01nxGzt3bUzLoz1nJ /JF6GIhSKRyTmyeuJaPEMGEyYYTmw2F2w1oPrXYkM+GhUvSehzPeACQdpRAMj/oBdinG 8DaIcvFBi10OO6qo1V+gorm25kwiXSfrRQ7NhOMR1OB+xgBS9jIjNzciN99DyGmlQySe sGxHx7CLaz5dTx/EYFXEJoX/qi2LsqVoESuBnk9A0QOViBYH9OPAHao+a9hkv8Jl/TyU Z0/mqUeotMH8taZptBaFb9Fp+gMInT1VWamUjuLiA5VPb5hIMxvF/57BFD2jgGw9vU4Y Kjvg== X-Gm-Message-State: ALoCoQk1Ib5UOfHi7q37fMhtcbxzLT8C1yj8IuHJXQyStTOThrr97nGtnKtPnFIU881S1OFBdd0B X-Received: by 10.70.46.161 with SMTP id w1mr71016829pdm.66.1439406044487; Wed, 12 Aug 2015 12:00:44 -0700 (PDT) Received: from ubuntu.localdomain (i-global254.qualcomm.com. [199.106.103.254]) by smtp.gmail.com with ESMTPSA id pj3sm7343297pdb.6.2015.08.12.12.00.42 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 12 Aug 2015 12:00:43 -0700 (PDT) From: Lina Iyer To: rjw@rjwysocki.net, ulf.hansson@linaro.org, khilman@linaro.org Subject: [PATCH v2 2/2] ARM: domain: Add platform handlers for CPU PM domains Date: Wed, 12 Aug 2015 13:00:24 -0600 Message-Id: <1439406024-41893-2-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1439406024-41893-1-git-send-email-lina.iyer@linaro.org> References: <1439406024-41893-1-git-send-email-lina.iyer@linaro.org> In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150812_120105_892729_DDDFC158 X-CRM114-Status: GOOD ( 18.90 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Rob Herring , k.kozlowski@samsung.com, Lorenzo Pieralisi , linux-pm@vger.kernel.org, Catalin Marinas , sboyd@codeaurora.org, msivasub@codeaurora.org, geert@linux-m68k.org, Lina Iyer , agross@codeaurora.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In addition to the common power up/down actions of CPU PM domain core, platforms may have additional configuration before the CPU domain can b powered off or considered active. Allow platform drivers to register handlers for CPU PM domains. Platform drivers may register their callbacks against a compatible string defined by their PM domain provider device node in the DT. At domain init, the platform driver can initialize the platform specific genpd attributes. The init callback would need to return successfully, for the platform power_on/off handlers to be registered with the CPU PM domain. The code uses __init section to reduce memory needed for platform handlers and therefore can be freed after the driver is initialized, a desirable outcome for single kernel image. Cc: Rob Herring Cc: Stephen Boyd Cc: Kevin Hilman Cc: Ulf Hansson Cc: Catalin Marinas Cc: Mark Rutland Cc: Lorenzo Pieralisi Signed-off-by: Lina Iyer --- Changes since v1: - Removed references to ARM - Use OF_DECLARE_1 for __init section tables --- arch/arm/common/domains.c | 38 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/cpu-pd.h | 11 +++++++++++ include/asm-generic/vmlinux.lds.h | 2 ++ 3 files changed, 51 insertions(+) diff --git a/arch/arm/common/domains.c b/arch/arm/common/domains.c index 4bc32a5..b1d9cc0 100644 --- a/arch/arm/common/domains.c +++ b/arch/arm/common/domains.c @@ -26,8 +26,28 @@ /* List of CPU PM domains we care about */ static LIST_HEAD(of_cpu_pd_list); +static const struct of_device_id __cpu_pd_of_table_sentinel + __used __section(__cpu_pd_of_table_end); + +static inline +struct cpu_pm_domain *to_cpu_pd(struct generic_pm_domain *d) +{ + struct cpu_pm_domain *pd; + + list_for_each_entry(pd, &of_cpu_pd_list, link) { + if (pd->genpd == d) + return pd; + } + + return NULL; +} + static int cpu_pd_power_down(struct generic_pm_domain *genpd) { + struct cpu_pm_domain *pd = to_cpu_pd(genpd); + + if (pd->platform_ops.power_off) + pd->platform_ops.power_off(genpd); /* * Notify CPU PM domain power down * TODO: Call the notificated directly from here. @@ -39,6 +59,11 @@ static int cpu_pd_power_down(struct generic_pm_domain *genpd) static int cpu_pd_power_up(struct generic_pm_domain *genpd) { + struct cpu_pm_domain *pd = to_cpu_pd(genpd); + + if (pd->platform_ops.power_on) + pd->platform_ops.power_on(genpd); + /* Notify CPU PM domain power up */ cpu_cluster_pm_exit(); @@ -203,6 +228,8 @@ static int __init of_cpu_pd_init(void) { struct device_node *dn; struct cpu_pm_domain *pd; + const struct of_device_id *m = &__cpu_pd_of_table; + void (*pd_init)(struct device_node *) = NULL; for_each_compatible_node(dn, NULL, "cpu,pd") { @@ -213,6 +240,17 @@ static int __init of_cpu_pd_init(void) if (!pd) return -ENOMEM; + /* Find a compatible platform driver */ + for (; m->compatible; m++) { + if (of_device_is_compatible(dn, m->compatible)) { + pd_init = m->data; + break; + } + } + + if (pd_init) + pd_init(dn); + of_register_cpu_pd(dn, pd); } diff --git a/arch/arm/include/asm/cpu-pd.h b/arch/arm/include/asm/cpu-pd.h index 4785260..65db517 100644 --- a/arch/arm/include/asm/cpu-pd.h +++ b/arch/arm/include/asm/cpu-pd.h @@ -15,13 +15,24 @@ #include #include +struct cpu_pd_ops { + int (*power_on)(struct generic_pm_domain *d); + int (*power_off)(struct generic_pm_domain *d); +}; + struct cpu_pm_domain { struct list_head link; struct generic_pm_domain *genpd; + struct cpu_pd_ops platform_ops; struct device_node *dn; }; extern int of_init_cpu_domain(struct device_node *dn, struct cpu_pm_domain *pd); extern struct cpu_pm_domain *of_get_cpu_domain(struct device_node *dn); +extern const struct of_device_id __cpu_pd_of_table; + +#define CPU_PD_METHOD_OF_DECLARE(name, compat, fn) \ + OF_DECLARE_1(cpu_pd, name, compat, fn) + #endif /* __CPU_PD_H__ */ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8bd374d..f952933 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -179,6 +179,7 @@ #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) +#define CPU_PD_OF_TABLES() OF_TABLE(CONFIG_PM_GENERIC_DOMAINS, cpu_pd) #define EARLYCON_OF_TABLES() OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon) #define KERNEL_DTB() \ @@ -514,6 +515,7 @@ IOMMU_OF_TABLES() \ CPU_METHOD_OF_TABLES() \ CPUIDLE_METHOD_OF_TABLES() \ + CPU_PD_OF_TABLES() \ KERNEL_DTB() \ IRQCHIP_OF_MATCH_TABLE() \ EARLYCON_TABLE() \