Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp204121imm; Thu, 30 Aug 2018 20:57:02 -0700 (PDT) X-Google-Smtp-Source: ANB0VdY75EWpE8ZYYqbhq+fmbaO1et+AwOPZtyb2bl2T/t2YL9NykometiHyC6NNzFJm3iMTvPMd X-Received: by 2002:a62:9ed1:: with SMTP id f78-v6mr13808434pfk.206.1535687822337; Thu, 30 Aug 2018 20:57:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535687822; cv=none; d=google.com; s=arc-20160816; b=lLo9CEqcwDyyR0jw1q61qerk98A5i4xr9AkB8mWfK4fLUDy9DakBew4Wgj80CN/heP KBR1KG213qx7VmJKObnkWA095r5kP9gIXe9j3mzcqphRhBJcwisPt77/YOxumoohxybS hP7oZv0DrnpwBJ5MeZId0RE1pdvAxBicx+N6XFMlMZftFbObbD1WfSOBe3OZ3CKP94j9 Rxp+O4IU8nX664NVK9wdk3EUrYT1jL0N12eCdNYma3TMmUnFRpw/yMZB0RyIAKnEbB1u mw/SestmkWVOIzPBvU8Ot/ghix+UDhJZCC3PnBxRwEQNS9p1OxtZp7EzSixL/FZhvO7u hhUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=/uFzqkvwxiYgdzdVhmDix7qJU8tjNGzcty+XFRPBXmw=; b=vfyyxJF+1cxrYdqvUnapmdSd2YEiVVinsCko8MIEN4mBCrh9z6/A2s9ypa5AxgBZhZ OWkwmQsaMHVmPj61MbLqoLZmVoFQ2EVNX3VS3WY8pVIwkYCcAzx9UU/xr7aISg9DguX8 PHiKDDdSVLa98iONO0SKbAeHwMmskiZ4YKMXCrcvI/DMZ43KVi5F51jNrv0qcVdU1CgS +clO4Zc9YxHlf2QSFH9xcfFqlMITPNB2rtTYZKiHXZVMqp2fjRKHLXUBomwfPzYymxcb jvRjoT73dnhTP1ewebSmWwx1kPo2f1UHcBoHj3v5WZy2PAz7FyWrSfBKPvPB6/7bwrx+ XfEQ== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t127-v6si9248769pfc.118.2018.08.30.20.56.46; Thu, 30 Aug 2018 20:57:02 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727394AbeHaIBF (ORCPT + 99 others); Fri, 31 Aug 2018 04:01:05 -0400 Received: from inva021.nxp.com ([92.121.34.21]:46402 "EHLO inva021.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727123AbeHaIBF (ORCPT ); Fri, 31 Aug 2018 04:01:05 -0400 Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 45AC2200063; Fri, 31 Aug 2018 05:55:40 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 4EE042000A0; Fri, 31 Aug 2018 05:55:36 +0200 (CEST) Received: from titan.ap.freescale.net (TITAN.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 53AFE4030C; Fri, 31 Aug 2018 11:55:31 +0800 (SGT) From: Ran Wang To: Leo Li , Rob Herring , Mark Rutland Cc: linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Ran Wang Subject: [PATCH 3/3] soc: fsl: add RCPM driver Date: Fri, 31 Aug 2018 11:52:19 +0800 Message-Id: <20180831035219.31619-3-ran.wang_1@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180831035219.31619-1-ran.wang_1@nxp.com> References: <20180831035219.31619-1-ran.wang_1@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on FSL platform PM driver framework which help to isolate user and PM service provider (such as RCPM driver). Signed-off-by: Chenhui Zhao Signed-off-by: Ying Zhang Signed-off-by: Ran Wang --- drivers/soc/fsl/Kconfig | 6 ++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/ls-rcpm.c | 153 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/ls-rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 6517412..882330d 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -30,3 +30,9 @@ config FSL_PLAT_PM have to know the implement details of wakeup function it require. Besides, it is also easy for service side to upgrade its logic when design changed and remain user side unchanged. + +config LS_RCPM + bool "Freescale RCPM support" + depends on (FSL_PLAT_PM) + help + This feature is to enable specified wakeup source for system sleep. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 8f9db23..43ff71a 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_PLAT_PM) += plat_pm.o +obj-$(CONFIG_LS_RCPM) += ls-rcpm.o diff --git a/drivers/soc/fsl/ls-rcpm.c b/drivers/soc/fsl/ls-rcpm.c new file mode 100644 index 0000000..b0feb88 --- /dev/null +++ b/drivers/soc/fsl/ls-rcpm.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// plat_pm.c - Freescale Layerscape RCPM driver +// +// Copyright 2018 NXP +// +// Author: Ran Wang , + +#include +#include +#include +#include +#include +#include + +#define MAX_COMPATIBLE_NUM 10 + +struct rcpm_t { + struct device *dev; + void __iomem *ippdexpcr_addr; + bool big_endian; /* Big/Little endian of RCPM module */ +}; + +// rcpm_handle - Configure RCPM reg according to wake up source request +// @user_dev: pointer to user's device struct +// @flag: to enable(true) or disable(false) wakeup source +// @handle_priv: pointer to struct rcpm_t instance +// +// Return 0 on success other negative errno +static int rcpm_handle(struct device *user_dev, bool flag, void *handle_priv) +{ + struct rcpm_t *rcpm; + bool big_endian; + const char *dev_compatible_array[MAX_COMPATIBLE_NUM]; + void __iomem *ippdexpcr_addr; + u32 ippdexpcr; + u32 set_bit; + int ret, num, i; + + rcpm = handle_priv; + big_endian = rcpm->big_endian; + ippdexpcr_addr = rcpm->ippdexpcr_addr; + + num = device_property_read_string_array(user_dev, "compatible", + dev_compatible_array, MAX_COMPATIBLE_NUM); + if (num < 0) + return num; + + for (i = 0; i < num; i++) { + if (!device_property_present(rcpm->dev, + dev_compatible_array[i])) + continue; + else { + ret = device_property_read_u32(rcpm->dev, + dev_compatible_array[i], &set_bit); + if (ret) + return ret; + + if (!device_property_present(rcpm->dev, + dev_compatible_array[i])) + return -ENODEV; + else { + ret = device_property_read_u32(rcpm->dev, + dev_compatible_array[i], &set_bit); + if (ret) + return ret; + + if (big_endian) + ippdexpcr = ioread32be(ippdexpcr_addr); + else + ippdexpcr = ioread32(ippdexpcr_addr); + + if (flag) + ippdexpcr |= set_bit; + else + ippdexpcr &= ~set_bit; + + if (big_endian) { + iowrite32be(ippdexpcr, ippdexpcr_addr); + ippdexpcr = ioread32be(ippdexpcr_addr); + } else + iowrite32(ippdexpcr, ippdexpcr_addr); + + return 0; + } + } + } + + return -ENODEV; +} + +static int ls_rcpm_probe(struct platform_device *pdev) +{ + struct resource *r; + struct rcpm_t *rcpm; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + rcpm = kmalloc(sizeof(*rcpm), GFP_KERNEL); + if (!rcpm) + return -ENOMEM; + + rcpm->big_endian = device_property_read_bool(&pdev->dev, "big-endian"); + + rcpm->ippdexpcr_addr = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(rcpm->ippdexpcr_addr)) + return PTR_ERR(rcpm->ippdexpcr_addr); + + rcpm->dev = &pdev->dev; + platform_set_drvdata(pdev, rcpm); + + return register_fsl_platform_wakeup_source(rcpm_handle, rcpm); +} + +static int ls_rcpm_remove(struct platform_device *pdev) +{ + struct rcpm_t *rcpm; + + rcpm = platform_get_drvdata(pdev); + deregister_fsl_platform_wakeup_source(rcpm); + kfree(rcpm); + + return 0; +} + +static const struct of_device_id ls_rcpm_of_match[] = { + { .compatible = "fsl,qoriq-rcpm-2.1", }, + {} +}; +MODULE_DEVICE_TABLE(of, ls_rcpm_of_match); + +static struct platform_driver ls_rcpm_driver = { + .driver = { + .name = "ls-rcpm", + .of_match_table = ls_rcpm_of_match, + }, + .probe = ls_rcpm_probe, + .remove = ls_rcpm_remove, +}; + +static int __init ls_rcpm_init(void) +{ + return platform_driver_register(&ls_rcpm_driver); +} +subsys_initcall(ls_rcpm_init); + +static void __exit ls_rcpm_exit(void) +{ + platform_driver_unregister(&ls_rcpm_driver); +} +module_exit(ls_rcpm_exit); -- 1.7.1