{"id":809932,"url":"http://patchwork.ozlabs.org/api/patches/809932/?format=json","web_url":"http://patchwork.ozlabs.org/project/rtc-linux/patch/5286489131571f149c6b75a8367ceb93cfe6e6be.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com/","project":{"id":9,"url":"http://patchwork.ozlabs.org/api/projects/9/?format=json","name":"Linux RTC development","link_name":"rtc-linux","list_id":"linux-rtc.vger.kernel.org","list_email":"linux-rtc@vger.kernel.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<5286489131571f149c6b75a8367ceb93cfe6e6be.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>","list_archive_url":null,"date":"2017-09-05T05:37:23","name":"[RFC,v3,3/7] platform/x86: intel_pmc_ipc: Use regmap calls for GCR updates","commit_ref":null,"pull_url":null,"state":"not-applicable","archived":false,"hash":"9a239ab89c5a5e31142cec66442ed82940f59b8a","submitter":{"id":66129,"url":"http://patchwork.ozlabs.org/api/people/66129/?format=json","name":"Kuppuswamy Sathyanarayanan","email":"sathyanarayanan.kuppuswamy@linux.intel.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/rtc-linux/patch/5286489131571f149c6b75a8367ceb93cfe6e6be.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com/mbox/","series":[{"id":1490,"url":"http://patchwork.ozlabs.org/api/series/1490/?format=json","web_url":"http://patchwork.ozlabs.org/project/rtc-linux/list/?series=1490","date":"2017-09-05T05:37:20","name":"PMC/PUNIT IPC driver cleanup","version":3,"mbox":"http://patchwork.ozlabs.org/series/1490/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/809932/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/809932/checks/","tags":{},"related":[],"headers":{"Return-Path":"<linux-rtc-owner@vger.kernel.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-rtc-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xmbBj4cQzz9sP3\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue,  5 Sep 2017 15:39:41 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754031AbdIEFjl (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tTue, 5 Sep 2017 01:39:41 -0400","from mga01.intel.com ([192.55.52.88]:42427 \"EHLO mga01.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751246AbdIEFiO (ORCPT <rfc822;linux-rtc@vger.kernel.org>);\n\tTue, 5 Sep 2017 01:38:14 -0400","from orsmga005.jf.intel.com ([10.7.209.41])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t04 Sep 2017 22:38:13 -0700","from skuppusw-desk.jf.intel.com ([10.7.198.92])\n\tby orsmga005.jf.intel.com with ESMTP; 04 Sep 2017 22:38:12 -0700"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos;i=\"5.41,478,1498546800\"; d=\"scan'208\";a=\"145505100\"","From":"sathyanarayanan.kuppuswamy@linux.intel.com","To":"a.zummo@towertech.it, x86@kernel.org, wim@iguana.be,\n\tmingo@redhat.com, alexandre.belloni@free-electrons.com,\n\tqipeng.zha@intel.com, hpa@zytor.com, dvhart@infradead.org,\n\ttglx@linutronix.de, lee.jones@linaro.org, andy@infradead.org,\n\tsouvik.k.chakravarty@intel.com","Cc":"linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org,\n\tsathyaosid@gmail.com, Kuppuswamy Sathyanarayanan \n\t<sathyanarayanan.kuppuswamy@linux.intel.com>","Subject":"[RFC v3 3/7] platform/x86: intel_pmc_ipc: Use regmap calls for GCR\n\tupdates","Date":"Mon,  4 Sep 2017 22:37:23 -0700","Message-Id":"<5286489131571f149c6b75a8367ceb93cfe6e6be.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>","X-Mailer":"git-send-email 2.7.4","In-Reply-To":"<cover.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>","References":"<cover.1504588701.git.sathyanarayanan.kuppuswamy@linux.intel.com>","Sender":"linux-rtc-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<linux-rtc.vger.kernel.org>","X-Mailing-List":"linux-rtc@vger.kernel.org"},"content":"From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>\n\nCurrently, update_no_reboot_bit() function implemented in this driver\nuses mutex_lock to protect its register updates. But this function is\ncalled with in atomic context in iTCO_wdt_start() and iTCO_wdt_stop()\nfunctions in iTCO_wdt.c driver, which in turn causes \"sleeping into\natomic context\" issue. This patch fixes this issue by refactoring the\ncurrent GCR read/write/update functions with regmap APIs.\n\nSigned-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>\n---\n drivers/platform/x86/Kconfig         |   1 +\n drivers/platform/x86/intel_pmc_ipc.c | 115 ++++++++++++-----------------------\n 2 files changed, 40 insertions(+), 76 deletions(-)","diff":"diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig\nindex 80b8795..45f4e79 100644\n--- a/drivers/platform/x86/Kconfig\n+++ b/drivers/platform/x86/Kconfig\n@@ -1054,6 +1054,7 @@ config PVPANIC\n config INTEL_PMC_IPC\n \ttristate \"Intel PMC IPC Driver\"\n \tdepends on ACPI\n+\tselect REGMAP_MMIO\n \t---help---\n \tThis driver provides support for PMC control on some Intel platforms.\n \tThe PMC is an ARC processor which defines IPC commands for communication\ndiff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c\nindex 021dcf6..40a25f8 100644\n--- a/drivers/platform/x86/intel_pmc_ipc.c\n+++ b/drivers/platform/x86/intel_pmc_ipc.c\n@@ -31,9 +31,11 @@\n #include <linux/atomic.h>\n #include <linux/notifier.h>\n #include <linux/suspend.h>\n+#include <linux/spinlock.h>\n #include <linux/acpi.h>\n #include <linux/io-64-nonatomic-lo-hi.h>\n #include <linux/mfd/core.h>\n+#include <linux/regmap.h>\n \n #include <asm/intel_pmc_ipc.h>\n \n@@ -125,7 +127,7 @@ static struct intel_pmc_ipc_dev {\n \n \t/* gcr */\n \tvoid __iomem *gcr_mem_base;\n-\tbool has_gcr_regs;\n+\tstruct regmap *gcr_regs;\n \n \t/* Telemetry */\n \tu8 telem_res_inval;\n@@ -150,6 +152,14 @@ static char *ipc_err_sources[] = {\n \t\t\"Unsigned kernel\",\n };\n \n+static struct regmap_config gcr_regmap_config = {\n+        .reg_bits = 32,\n+        .reg_stride = 4,\n+        .val_bits = 32,\n+\t.fast_io = true,\n+\t.max_register = PLAT_RESOURCE_GCR_SIZE,\n+};\n+\n /* Prevent concurrent calls to the PMC */\n static DEFINE_MUTEX(ipclock);\n \n@@ -183,21 +193,6 @@ static inline u32 ipc_data_readl(u32 offset)\n \treturn readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);\n }\n \n-static inline u64 gcr_data_readq(u32 offset)\n-{\n-\treturn readq(ipcdev.gcr_mem_base + offset);\n-}\n-\n-static inline int is_gcr_valid(u32 offset)\n-{\n-\tif (!ipcdev.has_gcr_regs)\n-\t\treturn -EACCES;\n-\n-\tif (offset > PLAT_RESOURCE_GCR_SIZE)\n-\t\treturn -EINVAL;\n-\n-\treturn 0;\n-}\n \n /**\n  * intel_pmc_gcr_read() - Read PMC GCR register\n@@ -210,21 +205,10 @@ static inline int is_gcr_valid(u32 offset)\n  */\n int intel_pmc_gcr_read(u32 offset, u32 *data)\n {\n-\tint ret;\n-\n-\tmutex_lock(&ipclock);\n-\n-\tret = is_gcr_valid(offset);\n-\tif (ret < 0) {\n-\t\tmutex_unlock(&ipclock);\n-\t\treturn ret;\n-\t}\n-\n-\t*data = readl(ipcdev.gcr_mem_base + offset);\n-\n-\tmutex_unlock(&ipclock);\n+\tif (!ipcdev.gcr_regs)\n+\t\treturn -EACCES;\n \n-\treturn 0;\n+\treturn regmap_read(ipcdev.gcr_regs, offset, data);\n }\n EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);\n \n@@ -240,21 +224,10 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);\n  */\n int intel_pmc_gcr_write(u32 offset, u32 data)\n {\n-\tint ret;\n-\n-\tmutex_lock(&ipclock);\n-\n-\tret = is_gcr_valid(offset);\n-\tif (ret < 0) {\n-\t\tmutex_unlock(&ipclock);\n-\t\treturn ret;\n-\t}\n-\n-\twritel(data, ipcdev.gcr_mem_base + offset);\n-\n-\tmutex_unlock(&ipclock);\n+\tif (!ipcdev.gcr_regs)\n+\t\treturn -EACCES;\n \n-\treturn 0;\n+\treturn regmap_write(ipcdev.gcr_regs, offset, data);\n }\n EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);\n \n@@ -271,33 +244,10 @@ EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);\n  */\n int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)\n {\n-\tu32 new_val;\n-\tint ret = 0;\n-\n-\tmutex_lock(&ipclock);\n-\n-\tret = is_gcr_valid(offset);\n-\tif (ret < 0)\n-\t\tgoto gcr_ipc_unlock;\n-\n-\tnew_val = readl(ipcdev.gcr_mem_base + offset);\n-\n-\tnew_val &= ~mask;\n-\tnew_val |= val & mask;\n-\n-\twritel(new_val, ipcdev.gcr_mem_base + offset);\n-\n-\tnew_val = readl(ipcdev.gcr_mem_base + offset);\n-\n-\t/* check whether the bit update is successful */\n-\tif ((new_val & mask) != (val & mask)) {\n-\t\tret = -EIO;\n-\t\tgoto gcr_ipc_unlock;\n-\t}\n+\tif (!ipcdev.gcr_regs)\n+\t\treturn -EACCES;\n \n-gcr_ipc_unlock:\n-\tmutex_unlock(&ipclock);\n-\treturn ret;\n+\treturn regmap_update_bits(ipcdev.gcr_regs, offset, mask, val);\n }\n EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);\n \n@@ -776,16 +726,24 @@ static int ipc_plat_get_res(struct platform_device *pdev)\n int intel_pmc_s0ix_counter_read(u64 *data)\n {\n \tu64 deep, shlw;\n+\tint ret;\n \n-\tif (!ipcdev.has_gcr_regs)\n+\tif (!ipcdev.gcr_regs)\n \t\treturn -EACCES;\n \n-\tdeep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG);\n-\tshlw = gcr_data_readq(PMC_GCR_TELEM_SHLW_S0IX_REG);\n+\tret = regmap_bulk_read(ipcdev.gcr_regs, PMC_GCR_TELEM_DEEP_S0IX_REG,\n+\t\t\t&deep, 2);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = regmap_bulk_read(ipcdev.gcr_regs, PMC_GCR_TELEM_SHLW_S0IX_REG,\n+\t\t\t&shlw, 2);\n+\tif (ret)\n+\t\treturn ret;\n \n \t*data = S0IX_RESIDENCY_IN_USECS(deep, shlw);\n \n-\treturn 0;\n+\treturn ret;\n }\n EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read);\n \n@@ -817,6 +775,13 @@ static int ipc_plat_probe(struct platform_device *pdev)\n \t\treturn ret;\n \t}\n \n+        ipcdev.gcr_regs = devm_regmap_init_mmio_clk(ipcdev.dev, NULL,\n+\t\t\tipcdev.gcr_mem_base, &gcr_regmap_config);\n+        if (IS_ERR(ipcdev.gcr_regs)) {\n+                dev_err(ipcdev.dev, \"gcr_regs regmap init failed\\n\");\n+                return PTR_ERR(ipcdev.gcr_regs);;\n+        }\n+\n \tret = ipc_create_pmc_devices(pdev);\n \tif (ret) {\n \t\tdev_err(&pdev->dev, \"Failed to create pmc devices\\n\");\n@@ -836,8 +801,6 @@ static int ipc_plat_probe(struct platform_device *pdev)\n \t\treturn ret;\n \t}\n \n-\tipcdev.has_gcr_regs = true;\n-\n \treturn 0;\n }\n \n","prefixes":["RFC","v3","3/7"]}