Commit a94cb7ee authored by Rafał Miłecki's avatar Rafał Miłecki Committed by Eduardo Valentin

thermal: broadcom: add Northstar thermal driver

Northstar is a SoC family commonly used in home routers. This commit
adds a driver for checking CPU temperature. As Northstar Plus seems to
also have this IP block this new symbol gets ARCH_BCM_IPROC dependency.
Signed-off-by: default avatarRafał Miłecki <rafal@milecki.pl>
Signed-off-by: default avatarJon Mason <jon.mason@broadcom.com>
Signed-off-by: default avatarEduardo Valentin <edubezval@gmail.com>
parent ee7cdbec
...@@ -392,6 +392,11 @@ config MTK_THERMAL ...@@ -392,6 +392,11 @@ config MTK_THERMAL
Enable this option if you want to have support for thermal management Enable this option if you want to have support for thermal management
controller present in Mediatek SoCs controller present in Mediatek SoCs
menu "Broadcom thermal drivers"
depends on ARCH_BCM || COMPILE_TEST
source "drivers/thermal/broadcom/Kconfig"
endmenu
menu "Texas Instruments thermal drivers" menu "Texas Instruments thermal drivers"
depends on ARCH_HAS_BANDGAP || COMPILE_TEST depends on ARCH_HAS_BANDGAP || COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
......
...@@ -27,6 +27,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o ...@@ -27,6 +27,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
# platform thermal drivers # platform thermal drivers
obj-y += broadcom/
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
......
config BCM_NS_THERMAL
tristate "Northstar thermal driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
help
Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
with a thermal sensor that allows checking CPU temperature. This
driver provides support for it.
obj-$(CONFIG_BCM_NS_THERMAL) += ns-thermal.o
/*
* Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#define PVTMON_CONTROL0 0x00
#define PVTMON_CONTROL0_SEL_MASK 0x0000000e
#define PVTMON_CONTROL0_SEL_TEMP_MONITOR 0x00000000
#define PVTMON_CONTROL0_SEL_TEST_MODE 0x0000000e
#define PVTMON_STATUS 0x08
struct ns_thermal {
struct thermal_zone_device *tz;
void __iomem *pvtmon;
};
static int ns_thermal_get_temp(void *data, int *temp)
{
struct ns_thermal *ns_thermal = data;
int offset = thermal_zone_get_offset(ns_thermal->tz);
int slope = thermal_zone_get_slope(ns_thermal->tz);
u32 val;
val = readl(ns_thermal->pvtmon + PVTMON_CONTROL0);
if ((val & PVTMON_CONTROL0_SEL_MASK) != PVTMON_CONTROL0_SEL_TEMP_MONITOR) {
/* Clear current mode selection */
val &= ~PVTMON_CONTROL0_SEL_MASK;
/* Set temp monitor mode (it's the default actually) */
val |= PVTMON_CONTROL0_SEL_TEMP_MONITOR;
writel(val, ns_thermal->pvtmon + PVTMON_CONTROL0);
}
val = readl(ns_thermal->pvtmon + PVTMON_STATUS);
*temp = slope * val + offset;
return 0;
}
static const struct thermal_zone_of_device_ops ns_thermal_ops = {
.get_temp = ns_thermal_get_temp,
};
static int ns_thermal_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ns_thermal *ns_thermal;
ns_thermal = devm_kzalloc(dev, sizeof(*ns_thermal), GFP_KERNEL);
if (!ns_thermal)
return -ENOMEM;
ns_thermal->pvtmon = of_iomap(dev_of_node(dev), 0);
if (WARN_ON(!ns_thermal->pvtmon))
return -ENOENT;
ns_thermal->tz = devm_thermal_zone_of_sensor_register(dev, 0,
ns_thermal,
&ns_thermal_ops);
if (IS_ERR(ns_thermal->tz)) {
iounmap(ns_thermal->pvtmon);
return PTR_ERR(ns_thermal->tz);
}
platform_set_drvdata(pdev, ns_thermal);
return 0;
}
static int ns_thermal_remove(struct platform_device *pdev)
{
struct ns_thermal *ns_thermal = platform_get_drvdata(pdev);
iounmap(ns_thermal->pvtmon);
return 0;
}
static const struct of_device_id ns_thermal_of_match[] = {
{ .compatible = "brcm,ns-thermal", },
{},
};
MODULE_DEVICE_TABLE(of, ns_thermal_of_match);
static struct platform_driver ns_thermal_driver = {
.probe = ns_thermal_probe,
.remove = ns_thermal_remove,
.driver = {
.name = "ns-thermal",
.of_match_table = ns_thermal_of_match,
},
};
module_platform_driver(ns_thermal_driver);
MODULE_DESCRIPTION("Northstar thermal driver");
MODULE_LICENSE("GPL v2");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment