Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4741986pxj; Tue, 25 May 2021 15:31:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwbE8W8GcN3c0eCgNxyhPuQA8Hz52q1/m3YZRtZ2L5Hh8K9rkwvIebXOF6bfrQETcChmkxt X-Received: by 2002:a02:cb04:: with SMTP id j4mr33486694jap.45.1621981883051; Tue, 25 May 2021 15:31:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621981883; cv=none; d=google.com; s=arc-20160816; b=BuThSZo6hUU/7AsPxKP6cbcdjSaNrSHRtkRX4ULmfvy1YUCVBRZ7HK++SGSRSsf1dX KWTKURdB4yARZ1dsH7WmhEMn97i/IGJmkmnidzcDux/S4A29EUuZpoaAGukt18cFHL2C VeIwCvs8AvCGWGYEygiuJI++ajSiNVFKJ7R0odXk3nNn6NXVSqEAHal38hTk55b9r1EY w8ZkKYi1cAi/94cLI6GPtYiOnB3RZYCAYGkZJDSctvW6kptjq6HbUpvGWeSVjGnf19MR a6gR9krJi/5j/UD8LGT77aFRWJuClY+LoDVDUjEs+jTuH97u3YN0tgnM74geTzqSIkKX R5dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=AW4KK5NxL5Vki2SStOswm1rH7Sy9qQB6K1SWAOdenIw=; b=uWSIG/ZoMfj19K30g+kAoHTR/7netp/glIQH5bQFZx7TLMSke1uwvJj9vM30RywYYA 5UOnEYhpR3z93AC7VdlwMNQZIw9huMR7fgJOGVDqowzt/AnOHH9w0ZLU4gPTkFxob0UN N7QJgadrBFzdZiFKm5YMpkoH9ZMjAJD4GlQQdVc6fahQs7N5bNKLsQu3vvdNdRTWxX/y yTV9XalOD9ceu78EtimRdjYXDvy4XUsEheUlPfE59cz4Rd7Lc9PuLtEXlHTmCYUMNZma oZxrmN60/Vezi87b+6mV/notQOUBsX5ZcdxuucxrgorAp440pS8+AYQSE+gcRbeun/+A IRiw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t3si17106221jaj.67.2021.05.25.15.31.09; Tue, 25 May 2021 15:31:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233389AbhEYUtv (ORCPT + 99 others); Tue, 25 May 2021 16:49:51 -0400 Received: from mga18.intel.com ([134.134.136.126]:9161 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233379AbhEYUtt (ORCPT ); Tue, 25 May 2021 16:49:49 -0400 IronPort-SDR: RFdR6mbXcJmGT16cvMjfWoByGfSRZ3n/O6KhDDElfD3equm4Mrf1o4DcpRyvAgaJJAh75Q3Hqr VkugyAn4TKnw== X-IronPort-AV: E=McAfee;i="6200,9189,9995"; a="189676393" X-IronPort-AV: E=Sophos;i="5.82,329,1613462400"; d="scan'208";a="189676393" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 May 2021 13:48:18 -0700 IronPort-SDR: xhio9hcG7LNJx5tQnfSHkGfRI10f9jFdCEH8uxKFGQFhZxRVO579ZmKzhnGYZpr69LUsczxSL/ CbuUT+rcxjNg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,329,1613462400"; d="scan'208";a="435842395" Received: from spandruv-desk.jf.intel.com ([10.54.75.21]) by orsmga007.jf.intel.com with ESMTP; 25 May 2021 13:48:18 -0700 From: Srinivas Pandruvada To: daniel.lezcano@linaro.org, rui.zhang@intel.com, amitk@kernel.org Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Srinivas Pandruvada Subject: [PATCH 1/2] thermal: int340x: processor_thermal: Split enumeration and processing part Date: Tue, 25 May 2021 13:48:10 -0700 Message-Id: <20210525204811.3793651-2-srinivas.pandruvada@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210525204811.3793651-1-srinivas.pandruvada@linux.intel.com> References: <20210525204811.3793651-1-srinivas.pandruvada@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Remove enumeration part from the processor_thermal_device to two different modules. One for ACPI and one for PCI: ACPI enumeration: int3401_thermal PCI part: processor_thermal_device_pci_legacy The current processor_thermal_device now just implements interface functions to be used by the ACPI and PCI enumeration module. This is done by: 1. Make functions proc_thermal_add() and proc_thermal_remove() non static and export them for usage in other processor_thermal_device_pci_legacy.c and in int3401_thermal.c. 2. Move the sysfs file creation for TCC offset and power limit attribute group to the proc_thermal_add() from the individual enumeration callbacks for PCI and ACPI. 3. Create new interface functions proc_thermal_mmio_add() and proc_thermal_mmio_remove() which will be called from the processor_thermal_device_pci_legacy module. 4. Export proc_thermal_resume(), so that it can be used by power management callbacks. 5. Remove special check for double enumeration as it never happens. While here, fix some cleanup on error conditions in proc_thermal_add(). No functional changes are expected with this change. Signed-off-by: Srinivas Pandruvada --- .../thermal/intel/int340x_thermal/Makefile | 2 + .../intel/int340x_thermal/int3401_thermal.c | 82 +++++ .../processor_thermal_device.c | 289 ++---------------- .../processor_thermal_device.h | 8 +- .../processor_thermal_device_pci_legacy.c | 164 ++++++++++ 5 files changed, 286 insertions(+), 259 deletions(-) create mode 100644 drivers/thermal/intel/int340x_thermal/int3401_thermal.c create mode 100644 drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c diff --git a/drivers/thermal/intel/int340x_thermal/Makefile b/drivers/thermal/intel/int340x_thermal/Makefile index 38a2731e503c..aaf02d5deed5 100644 --- a/drivers/thermal/intel/int340x_thermal/Makefile +++ b/drivers/thermal/intel/int340x_thermal/Makefile @@ -4,6 +4,8 @@ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal_zone.o obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device.o +obj-$(CONFIG_INT340X_THERMAL) += int3401_thermal.o +obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device_pci_legacy.o obj-$(CONFIG_PROC_THERMAL_MMIO_RAPL) += processor_thermal_rapl.o obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_rfim.o obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_mbox.o diff --git a/drivers/thermal/intel/int340x_thermal/int3401_thermal.c b/drivers/thermal/intel/int340x_thermal/int3401_thermal.c new file mode 100644 index 000000000000..acebc8ba94e2 --- /dev/null +++ b/drivers/thermal/intel/int340x_thermal/int3401_thermal.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * INT3401 processor thermal device + * Copyright (c) 2020, Intel Corporation. + */ +#include +#include +#include +#include +#include + +#include "int340x_thermal_zone.h" +#include "processor_thermal_device.h" + +static const struct acpi_device_id int3401_device_ids[] = { + {"INT3401", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, int3401_device_ids); + +static int int3401_add(struct platform_device *pdev) +{ + struct proc_thermal_device *proc_priv; + int ret; + + proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL); + if (!proc_priv) + return -ENOMEM; + + ret = proc_thermal_add(&pdev->dev, proc_priv); + if (ret) + return ret; + + platform_set_drvdata(pdev, proc_priv); + + return ret; +} + +static int int3401_remove(struct platform_device *pdev) +{ + proc_thermal_remove(platform_get_drvdata(pdev)); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int int3401_thermal_resume(struct device *dev) +{ + return proc_thermal_resume(dev); +} +#else +#define int3401_thermal_resume NULL +#endif + +static SIMPLE_DEV_PM_OPS(int3401_proc_thermal_pm, NULL, int3401_thermal_resume); + +static struct platform_driver int3401_driver = { + .probe = int3401_add, + .remove = int3401_remove, + .driver = { + .name = "int3401 thermal", + .acpi_match_table = int3401_device_ids, + .pm = &int3401_proc_thermal_pm, + }, +}; + +static int __init proc_thermal_init(void) +{ + return platform_driver_register(&int3401_driver); +} + +static void __exit proc_thermal_exit(void) +{ + platform_driver_unregister(&int3401_driver); +} + +module_init(proc_thermal_init); +module_exit(proc_thermal_exit); + +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index 9e6f2a895a23..de4fc640deb0 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -3,34 +3,17 @@ * processor_thermal_device.c * Copyright (c) 2014, Intel Corporation. */ +#include #include #include -#include #include -#include -#include -#include #include -#include #include "int340x_thermal_zone.h" #include "processor_thermal_device.h" #include "../intel_soc_dts_iosf.h" #define DRV_NAME "proc_thermal" -enum proc_thermal_emum_mode_type { - PROC_THERMAL_NONE, - PROC_THERMAL_PCI, - PROC_THERMAL_PLATFORM_DEV -}; - -/* - * We can have only one type of enumeration, PCI or Platform, - * not both. So we don't need instance specific data. - */ -static enum proc_thermal_emum_mode_type proc_thermal_emum_mode = - PROC_THERMAL_NONE; - #define POWER_LIMIT_SHOW(index, suffix) \ static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \ struct device_attribute *attr, \ @@ -38,11 +21,6 @@ static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \ { \ struct proc_thermal_device *proc_dev = dev_get_drvdata(dev); \ \ - if (proc_thermal_emum_mode == PROC_THERMAL_NONE) { \ - dev_warn(dev, "Attempted to get power limit before device was initialized!\n"); \ - return 0; \ - } \ - \ return sprintf(buf, "%lu\n",\ (unsigned long)proc_dev->power_limits[index].suffix * 1000); \ } @@ -291,11 +269,8 @@ static void proc_thermal_notify(acpi_handle handle, u32 event, void *data) } } - -static int proc_thermal_add(struct device *dev, - struct proc_thermal_device **priv) +int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) { - struct proc_thermal_device *proc_priv; struct acpi_device *adev; acpi_status status; unsigned long long tmp; @@ -306,13 +281,8 @@ static int proc_thermal_add(struct device *dev, if (!adev) return -ENODEV; - proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL); - if (!proc_priv) - return -ENOMEM; - proc_priv->dev = dev; proc_priv->adev = adev; - *priv = proc_priv; ret = proc_thermal_read_ppcc(proc_priv); if (ret) @@ -338,15 +308,29 @@ static int proc_thermal_add(struct device *dev, if (ret) goto remove_zone; + ret = sysfs_create_file(&dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr); + if (ret) + goto remove_notify; + + ret = sysfs_create_group(&dev->kobj, &power_limit_attribute_group); + if (ret) { + sysfs_remove_file(&dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr); + goto remove_notify; + } + return 0; +remove_notify: + acpi_remove_notify_handler(adev->handle, + ACPI_DEVICE_NOTIFY, proc_thermal_notify); remove_zone: int340x_thermal_zone_remove(proc_priv->int340x_zone); return ret; } +EXPORT_SYMBOL_GPL(proc_thermal_add); -static void proc_thermal_remove(struct proc_thermal_device *proc_priv) +void proc_thermal_remove(struct proc_thermal_device *proc_priv) { acpi_remove_notify_handler(proc_priv->adev->handle, ACPI_DEVICE_NOTIFY, proc_thermal_notify); @@ -355,60 +339,24 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv) sysfs_remove_group(&proc_priv->dev->kobj, &power_limit_attribute_group); } +EXPORT_SYMBOL_GPL(proc_thermal_remove); -static int int3401_add(struct platform_device *pdev) +int proc_thermal_resume(struct device *dev) { - struct proc_thermal_device *proc_priv; - int ret; - - if (proc_thermal_emum_mode == PROC_THERMAL_PCI) { - dev_err(&pdev->dev, "error: enumerated as PCI dev\n"); - return -ENODEV; - } - - ret = proc_thermal_add(&pdev->dev, &proc_priv); - if (ret) - return ret; - - platform_set_drvdata(pdev, proc_priv); - proc_thermal_emum_mode = PROC_THERMAL_PLATFORM_DEV; - - dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n"); - - ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr); - if (ret) - return ret; - - ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group); - if (ret) - sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr); + struct proc_thermal_device *proc_dev; - return ret; -} + proc_dev = dev_get_drvdata(dev); + proc_thermal_read_ppcc(proc_dev); -static int int3401_remove(struct platform_device *pdev) -{ - proc_thermal_remove(platform_get_drvdata(pdev)); + tcc_offset_update(tcc_offset_save); return 0; } - -static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid) -{ - struct proc_thermal_device *proc_priv; - struct pci_dev *pdev = devid; - - proc_priv = pci_get_drvdata(pdev); - - intel_soc_dts_iosf_interrupt_handler(proc_priv->soc_dts); - - return IRQ_HANDLED; -} +EXPORT_SYMBOL_GPL(proc_thermal_resume); #define MCHBAR 0 -static int proc_thermal_set_mmio_base(struct pci_dev *pdev, - struct proc_thermal_device *proc_priv) +static int proc_thermal_set_mmio_base(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) { int ret; @@ -423,9 +371,9 @@ static int proc_thermal_set_mmio_base(struct pci_dev *pdev, return 0; } -static int proc_thermal_mmio_add(struct pci_dev *pdev, - struct proc_thermal_device *proc_priv, - kernel_ulong_t feature_mask) +int proc_thermal_mmio_add(struct pci_dev *pdev, + struct proc_thermal_device *proc_priv, + kernel_ulong_t feature_mask) { int ret; @@ -471,11 +419,10 @@ static int proc_thermal_mmio_add(struct pci_dev *pdev, return ret; } +EXPORT_SYMBOL_GPL(proc_thermal_mmio_add); -static void proc_thermal_mmio_remove(struct pci_dev *pdev) +void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) { - struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev); - if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_RAPL) proc_thermal_rapl_remove(); @@ -486,181 +433,7 @@ static void proc_thermal_mmio_remove(struct pci_dev *pdev) if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MBOX) proc_thermal_mbox_remove(pdev); } - -static int proc_thermal_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct proc_thermal_device *proc_priv; - int ret; - - if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { - dev_err(&pdev->dev, "error: enumerated as platform dev\n"); - return -ENODEV; - } - - ret = pcim_enable_device(pdev); - if (ret < 0) { - dev_err(&pdev->dev, "error: could not enable device\n"); - return ret; - } - - ret = proc_thermal_add(&pdev->dev, &proc_priv); - if (ret) - return ret; - - pci_set_drvdata(pdev, proc_priv); - proc_thermal_emum_mode = PROC_THERMAL_PCI; - - if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) { - /* - * Enumerate additional DTS sensors available via IOSF. - * But we are not treating as a failure condition, if - * there are no aux DTSs enabled or fails. This driver - * already exposes sensors, which can be accessed via - * ACPI/MSR. So we don't want to fail for auxiliary DTSs. - */ - proc_priv->soc_dts = intel_soc_dts_iosf_init( - INTEL_SOC_DTS_INTERRUPT_MSI, 2, 0); - - if (!IS_ERR(proc_priv->soc_dts) && pdev->irq) { - ret = pci_enable_msi(pdev); - if (!ret) { - ret = request_threaded_irq(pdev->irq, NULL, - proc_thermal_pci_msi_irq, - IRQF_ONESHOT, "proc_thermal", - pdev); - if (ret) { - intel_soc_dts_iosf_exit( - proc_priv->soc_dts); - pci_disable_msi(pdev); - proc_priv->soc_dts = NULL; - } - } - } else - dev_err(&pdev->dev, "No auxiliary DTSs enabled\n"); - } - - dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n"); - - ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr); - if (ret) - return ret; - - ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group); - if (ret) { - sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr); - return ret; - } - - ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data); - if (ret) { - proc_thermal_remove(proc_priv); - return ret; - } - - return 0; -} - -static void proc_thermal_pci_remove(struct pci_dev *pdev) -{ - struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev); - - if (proc_priv->soc_dts) { - intel_soc_dts_iosf_exit(proc_priv->soc_dts); - if (pdev->irq) { - free_irq(pdev->irq, pdev); - pci_disable_msi(pdev); - } - } - - proc_thermal_mmio_remove(pdev); - proc_thermal_remove(proc_priv); -} - -#ifdef CONFIG_PM_SLEEP -static int proc_thermal_resume(struct device *dev) -{ - struct proc_thermal_device *proc_dev; - - proc_dev = dev_get_drvdata(dev); - proc_thermal_read_ppcc(proc_dev); - - tcc_offset_update(tcc_offset_save); - - return 0; -} -#else -#define proc_thermal_resume NULL -#endif - -static SIMPLE_DEV_PM_OPS(proc_thermal_pm, NULL, proc_thermal_resume); - -static const struct pci_device_id proc_thermal_pci_ids[] = { - { PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) }, - { PCI_DEVICE_DATA(INTEL, BDW_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, ICL_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, - { PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) }, - { PCI_DEVICE_DATA(INTEL, SKL_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, - { PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_MBOX) }, - { }, -}; - -MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids); - -static struct pci_driver proc_thermal_pci_driver = { - .name = DRV_NAME, - .probe = proc_thermal_pci_probe, - .remove = proc_thermal_pci_remove, - .id_table = proc_thermal_pci_ids, - .driver.pm = &proc_thermal_pm, -}; - -static const struct acpi_device_id int3401_device_ids[] = { - {"INT3401", 0}, - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, int3401_device_ids); - -static struct platform_driver int3401_driver = { - .probe = int3401_add, - .remove = int3401_remove, - .driver = { - .name = "int3401 thermal", - .acpi_match_table = int3401_device_ids, - .pm = &proc_thermal_pm, - }, -}; - -static int __init proc_thermal_init(void) -{ - int ret; - - ret = platform_driver_register(&int3401_driver); - if (ret) - return ret; - - ret = pci_register_driver(&proc_thermal_pci_driver); - - return ret; -} - -static void __exit proc_thermal_exit(void) -{ - platform_driver_unregister(&int3401_driver); - pci_unregister_driver(&proc_thermal_pci_driver); -} - -module_init(proc_thermal_init); -module_exit(proc_thermal_exit); +EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove); MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h index 3161607424f5..5e51f1173d00 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h @@ -80,5 +80,11 @@ int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc void proc_thermal_mbox_remove(struct pci_dev *pdev); int processor_thermal_send_mbox_cmd(struct pci_dev *pdev, u16 cmd_id, u32 cmd_data, u32 *cmd_resp); - +int proc_thermal_add(struct device *dev, struct proc_thermal_device *priv); +void proc_thermal_remove(struct proc_thermal_device *proc_priv); +int proc_thermal_resume(struct device *dev); +int proc_thermal_mmio_add(struct pci_dev *pdev, + struct proc_thermal_device *proc_priv, + kernel_ulong_t feature_mask); +void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *proc_priv); #endif diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c new file mode 100644 index 000000000000..21cf7511d376 --- /dev/null +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci_legacy.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * B0D4 processor thermal device + * Copyright (c) 2020, Intel Corporation. + */ + +#include +#include +#include +#include +#include + +#include "int340x_thermal_zone.h" +#include "processor_thermal_device.h" +#include "../intel_soc_dts_iosf.h" + +#define DRV_NAME "proc_thermal" + +static irqreturn_t proc_thermal_pci_msi_irq(int irq, void *devid) +{ + struct proc_thermal_device *proc_priv; + struct pci_dev *pdev = devid; + + proc_priv = pci_get_drvdata(pdev); + + intel_soc_dts_iosf_interrupt_handler(proc_priv->soc_dts); + + return IRQ_HANDLED; +} + +static int proc_thermal_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct proc_thermal_device *proc_priv; + int ret; + + ret = pcim_enable_device(pdev); + if (ret < 0) { + dev_err(&pdev->dev, "error: could not enable device\n"); + return ret; + } + + proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL); + if (!proc_priv) + return -ENOMEM; + + ret = proc_thermal_add(&pdev->dev, proc_priv); + if (ret) + return ret; + + pci_set_drvdata(pdev, proc_priv); + + if (pdev->device == PCI_DEVICE_ID_INTEL_BSW_THERMAL) { + /* + * Enumerate additional DTS sensors available via IOSF. + * But we are not treating as a failure condition, if + * there are no aux DTSs enabled or fails. This driver + * already exposes sensors, which can be accessed via + * ACPI/MSR. So we don't want to fail for auxiliary DTSs. + */ + proc_priv->soc_dts = intel_soc_dts_iosf_init( + INTEL_SOC_DTS_INTERRUPT_MSI, 2, 0); + + if (!IS_ERR(proc_priv->soc_dts) && pdev->irq) { + ret = pci_enable_msi(pdev); + if (!ret) { + ret = request_threaded_irq(pdev->irq, NULL, + proc_thermal_pci_msi_irq, + IRQF_ONESHOT, "proc_thermal", + pdev); + if (ret) { + intel_soc_dts_iosf_exit( + proc_priv->soc_dts); + pci_disable_msi(pdev); + proc_priv->soc_dts = NULL; + } + } + } else + dev_err(&pdev->dev, "No auxiliary DTSs enabled\n"); + } else { + + } + + ret = proc_thermal_mmio_add(pdev, proc_priv, id->driver_data); + if (ret) { + proc_thermal_remove(proc_priv); + return ret; + } + + return 0; +} + +static void proc_thermal_pci_remove(struct pci_dev *pdev) +{ + struct proc_thermal_device *proc_priv = pci_get_drvdata(pdev); + + if (proc_priv->soc_dts) { + intel_soc_dts_iosf_exit(proc_priv->soc_dts); + if (pdev->irq) { + free_irq(pdev->irq, pdev); + pci_disable_msi(pdev); + } + } + + proc_thermal_mmio_remove(pdev, proc_priv); + proc_thermal_remove(proc_priv); +} + +#ifdef CONFIG_PM_SLEEP +static int proc_thermal_pci_resume(struct device *dev) +{ + return proc_thermal_resume(dev); +} +#else +#define proc_thermal_pci_resume NULL +#endif + +static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, NULL, proc_thermal_pci_resume); + +static const struct pci_device_id proc_thermal_pci_ids[] = { + { PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) }, + { PCI_DEVICE_DATA(INTEL, BDW_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, BSW_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, BXT0_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, BXT1_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, BXTX_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, BXTP_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, CNL_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, CFL_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, GLK_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, HSB_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, ICL_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, + { PCI_DEVICE_DATA(INTEL, JSL_THERMAL, 0) }, + { PCI_DEVICE_DATA(INTEL, SKL_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, + { PCI_DEVICE_DATA(INTEL, TGL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_MBOX) }, + { }, +}; + +MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids); + +static struct pci_driver proc_thermal_pci_driver = { + .name = DRV_NAME, + .probe = proc_thermal_pci_probe, + .remove = proc_thermal_pci_remove, + .id_table = proc_thermal_pci_ids, + .driver.pm = &proc_thermal_pci_pm, +}; + +static int __init proc_thermal_init(void) +{ + return pci_register_driver(&proc_thermal_pci_driver); +} + +static void __exit proc_thermal_exit(void) +{ + pci_unregister_driver(&proc_thermal_pci_driver); +} + +module_init(proc_thermal_init); +module_exit(proc_thermal_exit); + +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); +MODULE_LICENSE("GPL v2"); -- 2.27.0