cregit-Linux how code gets into the kernel

Release 4.7 drivers/thermal/intel_pch_thermal.c

Directory: drivers/thermal
/* intel_pch_thermal.c - Intel PCH Thermal driver
 *
 * Copyright (c) 2015, Intel Corporation.
 *
 * Authors:
 *     Tushar Dave <tushar.n.dave@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/thermal.h>

/* Intel PCH thermal Device IDs */

#define PCH_THERMAL_DID_WPT	0x9CA4 
/* Wildcat Point */

#define PCH_THERMAL_DID_SKL	0x9D31 
/* Skylake PCH */

/* Wildcat Point-LP  PCH Thermal registers */

#define WPT_TEMP	0x0000	
/* Temperature */

#define WPT_TSC	0x04	
/* Thermal Sensor Control */

#define WPT_TSS	0x06	
/* Thermal Sensor Status */

#define WPT_TSEL	0x08	
/* Thermal Sensor Enable and Lock */

#define WPT_TSREL	0x0A	
/* Thermal Sensor Report Enable and Lock */

#define WPT_TSMIC	0x0C	
/* Thermal Sensor SMI Control */

#define WPT_CTT	0x0010	
/* Catastrophic Trip Point */

#define WPT_TAHV	0x0014	
/* Thermal Alert High Value */

#define WPT_TALV	0x0018	
/* Thermal Alert Low Value */

#define WPT_TL		0x00000040	
/* Throttle Value */

#define WPT_PHL	0x0060	
/* PCH Hot Level */

#define WPT_PHLC	0x62	
/* PHL Control */

#define WPT_TAS	0x80	
/* Thermal Alert Status */

#define WPT_TSPIEN	0x82	
/* PCI Interrupt Event Enables */

#define WPT_TSGPEN	0x84	
/* General Purpose Event Enables */

/*  Wildcat Point-LP  PCH Thermal Register bit definitions */

#define WPT_TEMP_TSR	0x00ff	
/* Temp TS Reading */

#define WPT_TSC_CPDE	0x01	
/* Catastrophic Power-Down Enable */

#define WPT_TSS_TSDSS	0x10	
/* Thermal Sensor Dynamic Shutdown Status */

#define WPT_TSS_GPES	0x08	
/* GPE status */

#define WPT_TSEL_ETS	0x01    
/* Enable TS */

#define WPT_TSEL_PLDB	0x80	
/* TSEL Policy Lock-Down Bit */

#define WPT_TL_TOL	0x000001FF	
/* T0 Level */

#define WPT_TL_T1L	0x1ff00000	
/* T1 Level */

#define WPT_TL_TTEN	0x20000000	
/* TT Enable */


static char driver_name[] = "Intel PCH thermal driver";


struct pch_thermal_device {
	
void __iomem *hw_base;
	
const struct pch_dev_ops *ops;
	
struct pci_dev *pdev;
	
struct thermal_zone_device *tzd;
	
int crt_trip_id;
	
unsigned long crt_temp;
	
int hot_trip_id;
	
unsigned long hot_temp;
};


static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) { u8 tsel; u16 trip_temp; *nr_trips = 0; /* Check if BIOS has already enabled thermal sensor */ if (WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS)) goto read_trips; tsel = readb(ptd->hw_base + WPT_TSEL); /* * When TSEL's Policy Lock-Down bit is 1, TSEL become RO. * If so, thermal sensor cannot enable. Bail out. */ if (tsel & WPT_TSEL_PLDB) { dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n"); return -ENODEV; } writeb(tsel|WPT_TSEL_ETS, ptd->hw_base + WPT_TSEL); if (!(WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS))) { dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n"); return -ENODEV; } read_trips: ptd->crt_trip_id = -1; trip_temp = readw(ptd->hw_base + WPT_CTT); trip_temp &= 0x1FF; if (trip_temp) { /* Resolution of 1/2 degree C and an offset of -50C */ ptd->crt_temp = trip_temp * 1000 / 2 - 50000; ptd->crt_trip_id = 0; ++(*nr_trips); } ptd->hot_trip_id = -1; trip_temp = readw(ptd->hw_base + WPT_PHL); trip_temp &= 0x1FF; if (trip_temp) { /* Resolution of 1/2 degree C and an offset of -50C */ ptd->hot_temp = trip_temp * 1000 / 2 - 50000; ptd->hot_trip_id = *nr_trips; ++(*nr_trips); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave238100.00%1100.00%
Total238100.00%1100.00%


static int pch_wpt_get_temp(struct pch_thermal_device *ptd, int *temp) { u8 wpt_temp; wpt_temp = WPT_TEMP_TSR & readl(ptd->hw_base + WPT_TEMP); /* Resolution of 1/2 degree C and an offset of -50C */ *temp = (wpt_temp * 1000 / 2 - 50000); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave4797.92%150.00%
linus torvaldslinus torvalds12.08%150.00%
Total48100.00%2100.00%

struct pch_dev_ops { int (*hw_init)(struct pch_thermal_device *ptd, int *nr_trips); int (*get_temp)(struct pch_thermal_device *ptd, int *temp); }; /* dev ops for Wildcat Point */ static const struct pch_dev_ops pch_dev_ops_wpt = { .hw_init = pch_wpt_init, .get_temp = pch_wpt_get_temp, };
static int pch_thermal_get_temp(struct thermal_zone_device *tzd, int *temp) { struct pch_thermal_device *ptd = tzd->devdata; return ptd->ops->get_temp(ptd, temp); }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave3597.22%150.00%
linus torvaldslinus torvalds12.78%150.00%
Total36100.00%2100.00%


static int pch_get_trip_type(struct thermal_zone_device *tzd, int trip, enum thermal_trip_type *type) { struct pch_thermal_device *ptd = tzd->devdata; if (ptd->crt_trip_id == trip) *type = THERMAL_TRIP_CRITICAL; else if (ptd->hot_trip_id == trip) *type = THERMAL_TRIP_HOT; else return -EINVAL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave63100.00%1100.00%
Total63100.00%1100.00%


static int pch_get_trip_temp(struct thermal_zone_device *tzd, int trip, int *temp) { struct pch_thermal_device *ptd = tzd->devdata; if (ptd->crt_trip_id == trip) *temp = ptd->crt_temp; else if (ptd->hot_trip_id == trip) *temp = ptd->hot_temp; else return -EINVAL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave6598.48%150.00%
linus torvaldslinus torvalds11.52%150.00%
Total66100.00%2100.00%

static struct thermal_zone_device_ops tzd_ops = { .get_temp = pch_thermal_get_temp, .get_trip_type = pch_get_trip_type, .get_trip_temp = pch_get_trip_temp, };
static int intel_pch_thermal_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct pch_thermal_device *ptd; int err; int nr_trips; char *dev_name; ptd = devm_kzalloc(&pdev->dev, sizeof(*ptd), GFP_KERNEL); if (!ptd) return -ENOMEM; switch (pdev->device) { case PCH_THERMAL_DID_WPT: ptd->ops = &pch_dev_ops_wpt; dev_name = "pch_wildcat_point"; break; case PCH_THERMAL_DID_SKL: ptd->ops = &pch_dev_ops_wpt; dev_name = "pch_skylake"; break; default: dev_err(&pdev->dev, "unknown pch thermal device\n"); return -ENODEV; } pci_set_drvdata(pdev, ptd); ptd->pdev = pdev; err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, "failed to enable pci device\n"); return err; } err = pci_request_regions(pdev, driver_name); if (err) { dev_err(&pdev->dev, "failed to request pci region\n"); goto error_disable; } ptd->hw_base = pci_ioremap_bar(pdev, 0); if (!ptd->hw_base) { err = -ENOMEM; dev_err(&pdev->dev, "failed to map mem base\n"); goto error_release; } err = ptd->ops->hw_init(ptd, &nr_trips); if (err) goto error_cleanup; ptd->tzd = thermal_zone_device_register(dev_name, nr_trips, 0, ptd, &tzd_ops, NULL, 0, 0); if (IS_ERR(ptd->tzd)) { dev_err(&pdev->dev, "Failed to register thermal zone %s\n", dev_name); err = PTR_ERR(ptd->tzd); goto error_cleanup; } return 0; error_cleanup: iounmap(ptd->hw_base); error_release: pci_release_regions(pdev); error_disable: pci_disable_device(pdev); dev_err(&pdev->dev, "pci device failed to probe\n"); return err; }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave32195.54%150.00%
srinivas pandruvadasrinivas pandruvada154.46%150.00%
Total336100.00%2100.00%


static void intel_pch_thermal_remove(struct pci_dev *pdev) { struct pch_thermal_device *ptd = pci_get_drvdata(pdev); thermal_zone_device_unregister(ptd->tzd); iounmap(ptd->hw_base); pci_set_drvdata(pdev, NULL); pci_release_region(pdev, 0); pci_disable_device(pdev); }

Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave54100.00%1100.00%
Total54100.00%1100.00%

static struct pci_device_id intel_pch_thermal_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_WPT) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL) }, { 0, }, }; MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id); static struct pci_driver intel_pch_thermal_driver = { .name = "intel_pch_thermal", .id_table = intel_pch_thermal_id, .probe = intel_pch_thermal_probe, .remove = intel_pch_thermal_remove, }; module_pci_driver(intel_pch_thermal_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Intel PCH Thermal driver");

Overall Contributors

PersonTokensPropCommitsCommitProp
tushar davetushar dave116097.15%125.00%
srinivas pandruvadasrinivas pandruvada292.43%125.00%
linus torvaldslinus torvalds40.34%125.00%
julia lawalljulia lawall10.08%125.00%
Total1194100.00%4100.00%
Directory: drivers/thermal
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}