diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.1/0018-Added-hwmon-thermal-driver-for-reporting-core-temper.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.1/0018-Added-hwmon-thermal-driver-for-reporting-core-temper.patch | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.1/0018-Added-hwmon-thermal-driver-for-reporting-core-temper.patch b/target/linux/brcm2708/patches-4.1/0018-Added-hwmon-thermal-driver-for-reporting-core-temper.patch new file mode 100644 index 0000000..572bad3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.1/0018-Added-hwmon-thermal-driver-for-reporting-core-temper.patch @@ -0,0 +1,288 @@ +From b7e45ce253f9aa6f3f4b33967b124198d3e2b74f Mon Sep 17 00:00:00 2001 +From: popcornmix <popcornmix@gmail.com> +Date: Tue, 26 Mar 2013 19:24:24 +0000 +Subject: [PATCH 018/121] Added hwmon/thermal driver for reporting core + temperature. Thanks Dorian +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BCM270x: Move thermal sensor to Device Tree + +Add Device Tree support to bcm2835-thermal driver. +Add thermal sensor device to Device Tree. +Don't add platform device when booting in DT mode. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +--- + arch/arm/mach-bcm2708/bcm2708.c | 6 ++ + arch/arm/mach-bcm2709/bcm2709.c | 6 ++ + drivers/thermal/Kconfig | 7 ++ + drivers/thermal/Makefile | 1 + + drivers/thermal/bcm2835-thermal.c | 190 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 210 insertions(+) + create mode 100644 drivers/thermal/bcm2835-thermal.c + +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -505,6 +505,10 @@ static struct platform_device bcm2708_al + }, + }; + ++static struct platform_device bcm2835_thermal_device = { ++ .name = "bcm2835_thermal", ++}; ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -651,6 +655,8 @@ void __init bcm2708_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device_dt(&bcm2708_alsa_devices[i]); + ++ bcm_register_device_dt(&bcm2835_thermal_device); ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -525,6 +525,10 @@ static struct platform_device bcm2708_al + }, + }; + ++static struct platform_device bcm2835_thermal_device = { ++ .name = "bcm2835_thermal", ++}; ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -671,6 +675,8 @@ void __init bcm2709_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device_dt(&bcm2708_alsa_devices[i]); + ++ bcm_register_device_dt(&bcm2835_thermal_device); ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +--- a/drivers/thermal/Kconfig ++++ b/drivers/thermal/Kconfig +@@ -238,6 +238,13 @@ config INTEL_POWERCLAMP + enforce idle time which results in more package C-state residency. The + user interface is exposed via generic thermal framework. + ++config THERMAL_BCM2835 ++ depends on BCM2708_MBOX ++ tristate "BCM2835 Thermal Driver" ++ help ++ This will enable temperature monitoring for the Broadcom BCM2835 ++ chip. If built as a module, it will be called 'bcm2835-thermal'. ++ + config X86_PKG_TEMP_THERMAL + tristate "X86 package temperature thermal driver" + depends on X86_THERMAL_VECTOR +--- a/drivers/thermal/Makefile ++++ b/drivers/thermal/Makefile +@@ -33,6 +33,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_t + obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o + obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o + obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o ++obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o + obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o + obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o + obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ +--- /dev/null ++++ b/drivers/thermal/bcm2835-thermal.c +@@ -0,0 +1,190 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/platform_data/mailbox-bcm2708.h> ++#include <linux/platform_device.h> ++#include <linux/slab.h> ++#include <linux/sysfs.h> ++#include <linux/thermal.h> ++ ++ ++/* --- DEFINITIONS --- */ ++#define MODULE_NAME "bcm2835_thermal" ++ ++/*#define THERMAL_DEBUG_ENABLE*/ ++ ++#ifdef THERMAL_DEBUG_ENABLE ++#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) ++#else ++#define print_debug(fmt,...) ++#endif ++#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) ++ ++#define VC_TAG_GET_TEMP 0x00030006 ++#define VC_TAG_GET_MAX_TEMP 0x0003000A ++ ++typedef enum { ++ TEMP, ++ MAX_TEMP, ++} temp_type; ++ ++/* --- STRUCTS --- */ ++/* tag part of the message */ ++struct vc_msg_tag { ++ uint32_t tag_id; /* the tag ID for the temperature */ ++ uint32_t buffer_size; /* size of the buffer (should be 8) */ ++ uint32_t request_code; /* identifies message as a request (should be 0) */ ++ uint32_t id; /* extra ID field (should be 0) */ ++ uint32_t val; /* returned value of the temperature */ ++}; ++ ++/* message structure to be sent to videocore */ ++struct vc_msg { ++ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ ++ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ ++ struct vc_msg_tag tag; /* the tag structure above to make */ ++ uint32_t end_tag; /* an end identifier, should be set to NULL */ ++}; ++ ++struct bcm2835_thermal_data { ++ struct thermal_zone_device *thermal_dev; ++ struct vc_msg msg; ++}; ++ ++/* --- GLOBALS --- */ ++static struct bcm2835_thermal_data bcm2835_data; ++ ++/* Thermal Device Operations */ ++static struct thermal_zone_device_ops ops; ++ ++/* --- FUNCTIONS --- */ ++ ++static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id) ++{ ++ int result = -1, retry = 3; ++ print_debug("IN"); ++ ++ *temp = 0; ++ while (result != 0 && retry-- > 0) { ++ /* wipe all previous message data */ ++ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg); ++ ++ /* prepare message */ ++ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg; ++ bcm2835_data.msg.tag.buffer_size = 8; ++ bcm2835_data.msg.tag.tag_id = tag_id; ++ ++ /* send the message */ ++ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg); ++ print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code); ++ if (!(bcm2835_data.msg.request_code & 0x80000000)) ++ result = -1; ++ } ++ ++ /* check if it was all ok and return the rate in milli degrees C */ ++ if (result == 0) ++ *temp = (uint)bcm2835_data.msg.tag.val; ++ else ++ print_err("Failed to get temperature! (%x:%d)\n", tag_id, result); ++ print_debug("OUT"); ++ return result; ++} ++ ++static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp) ++{ ++ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP); ++} ++ ++static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp) ++{ ++ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP); ++} ++ ++static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type) ++{ ++ *trip_type = THERMAL_TRIP_HOT; ++ return 0; ++} ++ ++ ++static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode) ++{ ++ *dev_mode = THERMAL_DEVICE_ENABLED; ++ return 0; ++} ++ ++ ++static int bcm2835_thermal_probe(struct platform_device *pdev) ++{ ++ print_debug("IN"); ++ print_debug("THERMAL Driver has been probed!"); ++ ++ /* check that the device isn't null!*/ ++ if(pdev == NULL) ++ { ++ print_debug("Platform device is empty!"); ++ return -ENODEV; ++ } ++ ++ if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0))) ++ { ++ print_debug("Unable to register the thermal device!"); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++ ++static int bcm2835_thermal_remove(struct platform_device *pdev) ++{ ++ print_debug("IN"); ++ ++ thermal_zone_device_unregister(bcm2835_data.thermal_dev); ++ ++ print_debug("OUT"); ++ ++ return 0; ++} ++ ++static struct thermal_zone_device_ops ops = { ++ .get_temp = bcm2835_get_temp, ++ .get_trip_temp = bcm2835_get_max_temp, ++ .get_trip_type = bcm2835_get_trip_type, ++ .get_mode = bcm2835_get_mode, ++}; ++ ++static const struct of_device_id bcm2835_thermal_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-thermal", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); ++ ++static struct platform_driver bcm2835_thermal_driver = { ++ .probe = bcm2835_thermal_probe, ++ .remove = bcm2835_thermal_remove, ++ .driver = { ++ .name = "bcm2835_thermal", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_thermal_of_match_table, ++ }, ++}; ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Dorian Peake"); ++MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); ++ ++module_platform_driver(bcm2835_thermal_driver); |