From patchwork Fri Aug 8 04:00:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 35078 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ig0-f199.google.com (mail-ig0-f199.google.com [209.85.213.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id D18E821F5F for ; Fri, 8 Aug 2014 04:01:17 +0000 (UTC) Received: by mail-ig0-f199.google.com with SMTP id l13sf1699772iga.10 for ; Thu, 07 Aug 2014 21:01:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=KDoIIVB8JY3qwiEbJQmgybQd2sxe6jBGxx5xgUp2WWk=; b=Ifw0ox2FlRzS4BuplnIt56jqxdbkFEB7cjF6y4xjrU8456noR7hszrVOsTI0AVDS/D 2QgTRqvgJrsjJZR6jmSilmCkPtw71deeSdPZNXFIlZEx511jJHWRzSsPXoRIYes4edj/ Q24X4h7Q/bICVnrYXRFyiO0AbyHT1/9nsJ1XgpSF+7vrpwuMfm73D389ZSlY9P+H59LO /J0GNdKlgeC0+B7PjKgl73QeFTAZWGc/n23GHcC80Z4FfMSvdmndd6yKfD6Thymj4FAL 0QPyzUAwzrzWBQ/u6G3ai/wFUnnnX8Gv/mEtRM5acjQXraM9q5G1vs/5eoTvtKScfMPW UUvA== X-Gm-Message-State: ALoCoQmNn0Ldu5f+Tx51SdAYO0AA2GJmwAfiGeAupZZbw3WNti1/yW/iH1HCugsTtGd08PH3kp0i X-Received: by 10.182.81.161 with SMTP id b1mr10552021oby.1.1407470477376; Thu, 07 Aug 2014 21:01:17 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.16.171 with SMTP id 40ls399916qgb.10.gmail; Thu, 07 Aug 2014 21:01:17 -0700 (PDT) X-Received: by 10.52.61.136 with SMTP id p8mr5018430vdr.15.1407470477297; Thu, 07 Aug 2014 21:01:17 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id wk17si2499701vcb.9.2014.08.07.21.01.17 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 07 Aug 2014 21:01:17 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id lf12so7624923vcb.12 for ; Thu, 07 Aug 2014 21:01:17 -0700 (PDT) X-Received: by 10.52.185.72 with SMTP id fa8mr5077762vdc.4.1407470477193; Thu, 07 Aug 2014 21:01:17 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp86907vcb; Thu, 7 Aug 2014 21:01:16 -0700 (PDT) X-Received: by 10.68.229.166 with SMTP id sr6mr6026433pbc.33.1407470475528; Thu, 07 Aug 2014 21:01:15 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b11si1450465pdj.25.2014.08.07.21.01.14 for ; Thu, 07 Aug 2014 21:01:15 -0700 (PDT) Received-SPF: none (google.com: linux-arm-msm-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751030AbaHHEBO (ORCPT + 4 others); Fri, 8 Aug 2014 00:01:14 -0400 Received: from mail-ig0-f178.google.com ([209.85.213.178]:46772 "EHLO mail-ig0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750842AbaHHEBN (ORCPT ); Fri, 8 Aug 2014 00:01:13 -0400 Received: by mail-ig0-f178.google.com with SMTP id uq10so431391igb.11 for ; Thu, 07 Aug 2014 21:01:12 -0700 (PDT) X-Received: by 10.50.8.65 with SMTP id p1mr1405344iga.46.1407470472756; Thu, 07 Aug 2014 21:01:12 -0700 (PDT) Received: from localhost.localdomain (c-24-8-37-141.hsd1.co.comcast.net. [24.8.37.141]) by mx.google.com with ESMTPSA id yt6sm4062230igb.10.2014.08.07.21.01.11 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Aug 2014 21:01:12 -0700 (PDT) From: Lina Iyer To: daniel.lezcano@linaro.org, khilman@linaro.org, amit.kucheria@linaro.org, sboyd@codeaurora.org, davidb@codeaurora.org, galak@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@vger.kernel.org Cc: msivasub@codeaurora.org, bryanh@codeaurora.org, Lina Iyer Subject: [RFC] [PATCH 07/13] qcom: sleep-status: Add ability to recognize cpu power down state Date: Thu, 7 Aug 2014 22:00:52 -0600 Message-Id: <1407470458-22900-8-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1407470458-22900-1-git-send-email-lina.iyer@linaro.org> References: <1407470458-22900-1-git-send-email-lina.iyer@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lina.iyer@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , QCOM processors get notified by the processor subsystem logic that recognizes when a processor has entered the low power state. This is used by PM to guarantee that the processor is indeed in its low power state, before powering down the associated resources. Signed-off-by: Mahesh Sivasubramanian Signed-off-by: Lina Iyer --- .../bindings/arm/msm/qcom,cpu-sleep-status.txt | 41 +++++ drivers/soc/qcom/Makefile | 2 +- drivers/soc/qcom/sleep-status.c | 178 +++++++++++++++++++++ include/soc/qcom/pm.h | 2 + 4 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,cpu-sleep-status.txt create mode 100644 drivers/soc/qcom/sleep-status.c diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,cpu-sleep-status.txt b/Documentation/devicetree/bindings/arm/msm/qcom,cpu-sleep-status.txt new file mode 100644 index 0000000..3d2974e --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/qcom,cpu-sleep-status.txt @@ -0,0 +1,41 @@ +* MSM Sleep Status + +MSM Sleep status device is used to check the power collapsed status of a +offlined core. The core that initiates the hotplug would wait on the +sleep status device before CPU_DEAD notifications are sent out. Some hardware +devices require that the offlined core is power collapsed before turning off +the resources that are used by the offlined core. + + +PROPERTIES + +- compatible: + Usage: required + Value type: + Definition: Should be "qcom,cpu-sleep-status" + +- reg: + Usage: required + Value type: + Definition: The physical address of the sleep status register for + core0, the second element is the size of the register. + +- qcom,cpu-alias-addr: + Usage: required + Value type: + Definition: On MSM chipset, the each cores registers are at a + fixed offset each other. + +- qcom,cpu-sleep-status-mask: + Usage: required + Value type: + Definition: The bit mask within the status register that + indicates the Core's sleep state. + +Example: + qcom,cpu-sleep-status@f9088008 { + compatible = "qcom,cpu-sleep-status"; + reg = <0xf9088008 0x4>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask = <0x80000>; + }; diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 87c3b9704..d2cc9c0 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o -obj-$(CONFIG_QCOM_PM) += spm_devices.o spm.o msm-pm.o +obj-$(CONFIG_QCOM_PM) += spm_devices.o spm.o msm-pm.o sleep-status.o CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o diff --git a/drivers/soc/qcom/sleep-status.c b/drivers/soc/qcom/sleep-status.c new file mode 100644 index 0000000..aa6340c --- /dev/null +++ b/drivers/soc/qcom/sleep-status.c @@ -0,0 +1,178 @@ +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct msm_pm_sleep_status_data { + void *base_addr; + uint32_t cpu_offset; + uint32_t mask; +}; + +static struct msm_pm_sleep_status_data *msm_pm_slp_sts; + +/** + * msm_pm_wait_cpu_shutdown() - Wait for a core to be power collapsed during + * hotplug + * + * @ cpu - cpu to wait on. + * + * Blocking function call that waits on the core to be power collapsed. This + * function is called from platform_cpu_die to ensure that a core is power + * collapsed before sending the CPU_DEAD notification so the drivers could + * remove the resource votes for this CPU(regulator and clock) + */ +int msm_pm_wait_cpu_shutdown(unsigned int cpu) +{ + int timeout = 0; + + if (!msm_pm_slp_sts) + return 0; + + if (!msm_pm_slp_sts[cpu].base_addr) + return 0; + + while (1) { + /* + * Check for the SPM of the core being hotplugged to set + * its sleep state.The SPM sleep state indicates that the + * core has been power collapsed. + */ + int acc_sts = __raw_readl(msm_pm_slp_sts[cpu].base_addr); + + if (acc_sts & msm_pm_slp_sts[cpu].mask) + return 0; + + udelay(100); + /* + * Dump spm registers for debugging + */ + if (++timeout == 20) { + msm_spm_dump_regs(cpu); + __WARN_printf( + "CPU%u didn't collapse in 2ms, sleep status: 0x%x\n", + cpu, acc_sts); + } + } + + return -EBUSY; +} + +static int msm_cpu_status_probe(struct platform_device *pdev) +{ + struct msm_pm_sleep_status_data *pdata; + char *key; + u32 cpu; + + if (!pdev) + return -EFAULT; + + msm_pm_slp_sts = devm_kcalloc(&pdev->dev, num_possible_cpus(), + sizeof(*msm_pm_slp_sts), GFP_KERNEL); + + if (!msm_pm_slp_sts) + return -ENOMEM; + + if (pdev->dev.of_node) { + struct resource *res; + u32 offset; + int rc; + u32 mask; + bool offset_available = true; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + key = "qcom,cpu-alias-addr"; + rc = of_property_read_u32(pdev->dev.of_node, key, &offset); + + if (rc) + offset_available = false; + + key = "qcom,sleep-status-mask"; + rc = of_property_read_u32(pdev->dev.of_node, key, &mask); + + if (rc) + return -ENODEV; + + for_each_possible_cpu(cpu) { + phys_addr_t base_c; + + if (offset_available) + base_c = res->start + cpu * offset; + else { + res = platform_get_resource(pdev, + IORESOURCE_MEM, cpu); + if (!res) + return -ENODEV; + base_c = res->start; + } + + msm_pm_slp_sts[cpu].base_addr = + devm_ioremap(&pdev->dev, base_c, + resource_size(res)); + msm_pm_slp_sts[cpu].mask = mask; + + if (!msm_pm_slp_sts[cpu].base_addr) + return -ENOMEM; + } + } else { + pdata = pdev->dev.platform_data; + if (!pdev->dev.platform_data) + return -EINVAL; + + for_each_possible_cpu(cpu) { + msm_pm_slp_sts[cpu].base_addr = + pdata->base_addr + cpu * pdata->cpu_offset; + msm_pm_slp_sts[cpu].mask = pdata->mask; + } + } + + return 0; +}; + +static struct of_device_id msm_slp_sts_match_tbl[] = { + {.compatible = "qcom,cpu-sleep-status"}, + {}, +}; + +static struct platform_driver msm_cpu_status_driver = { + .probe = msm_cpu_status_probe, + .driver = { + .name = "qcom,cpu-sleep-status", + .owner = THIS_MODULE, + .of_match_table = msm_slp_sts_match_tbl, + }, +}; + +int __init msm_pm_sleep_status_init(void) +{ + static bool registered; + + if (registered) + return 0; + registered = true; + + return platform_driver_register(&msm_cpu_status_driver); +} +arch_initcall(msm_pm_sleep_status_init); diff --git a/include/soc/qcom/pm.h b/include/soc/qcom/pm.h index ed6124a..3de04b8 100644 --- a/include/soc/qcom/pm.h +++ b/include/soc/qcom/pm.h @@ -32,12 +32,14 @@ enum msm_pm_l2_scm_flag { bool msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle); int msm_pm_cpu_hotplug_enter(unsigned int cpu); int msm_pm_secondary_startup(unsigned int cpu); +int msm_pm_wait_cpu_shutdown(unsigned int cpu); #else static inline bool msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle) { return true; } static inline int msm_pm_cpu_hotplug_enter(unsigned int cpu) { return 0; } static inline int msm_pm_secondary_startup(unsigned int cpu) { return 0; } +static inline int msm_pm_wait_cpu_shutdown(unsigned int cpu) { return 0; } #endif #endif /* __QCOM_PM_H */