]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/thermal/bcm2835-thermal.c
ARM: dts: bcm283x: Add VEC node in bcm283x.dtsi
[mirror_ubuntu-zesty-kernel.git] / drivers / thermal / bcm2835-thermal.c
1 /*****************************************************************************
2 * Copyright 2011 Broadcom Corporation. All rights reserved.
3 *
4 * Unless you and Broadcom execute a separate written software license
5 * agreement governing use of this software, this software is licensed to you
6 * under the terms of the GNU General Public License version 2, available at
7 * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8 *
9 * Notwithstanding the above, under no circumstances may you combine this
10 * software in any way with any other Broadcom software provided under a
11 * license other than the GPL, without Broadcom's express prior written
12 * consent.
13 *****************************************************************************/
14
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/thermal.h>
18 #include <soc/bcm2835/raspberrypi-firmware.h>
19
20 static int bcm2835_thermal_get_property(struct thermal_zone_device *tz,
21 int *temp, u32 tag)
22 {
23 struct rpi_firmware *fw = tz->devdata;
24 struct {
25 u32 id;
26 u32 val;
27 } packet;
28 int ret;
29
30 *temp = 0;
31 packet.id = 0;
32 ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet));
33 if (ret) {
34 dev_err(&tz->device, "Failed to get temperature\n");
35 return ret;
36 }
37
38 *temp = packet.val;
39 dev_dbg(&tz->device, "%stemp=%d\n",
40 tag == RPI_FIRMWARE_GET_MAX_TEMPERATURE ? "max" : "", *temp);
41
42 return 0;
43 }
44
45 static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz,
46 int *temp)
47 {
48 return bcm2835_thermal_get_property(tz, temp,
49 RPI_FIRMWARE_GET_TEMPERATURE);
50 }
51
52 static struct thermal_zone_device_ops ops = {
53 .get_temp = bcm2835_thermal_get_temp,
54 };
55
56 static int bcm2835_thermal_probe(struct platform_device *pdev)
57 {
58 struct device_node *fw_np;
59 struct rpi_firmware *fw;
60 struct thermal_zone_device *tz;
61
62 fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
63 if (!fw_np) {
64 dev_err(&pdev->dev, "Missing firmware node\n");
65 return -ENOENT;
66 }
67 fw = rpi_firmware_get(fw_np);
68 if (!fw)
69 return -EPROBE_DEFER;
70
71 tz = thermal_zone_device_register("bcm2835_thermal", 0, 0, fw, &ops,
72 NULL, 0, 0);
73 if (IS_ERR(tz)) {
74 dev_err(&pdev->dev, "Failed to register the thermal device\n");
75 return PTR_ERR(tz);
76 }
77
78 platform_set_drvdata(pdev, tz);
79
80 return 0;
81 }
82
83 static int bcm2835_thermal_remove(struct platform_device *pdev)
84 {
85 thermal_zone_device_unregister(platform_get_drvdata(pdev));
86
87 return 0;
88 }
89
90 static const struct of_device_id bcm2835_thermal_of_match_table[] = {
91 { .compatible = "brcm,bcm2835-thermal", },
92 {},
93 };
94 MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table);
95
96 static struct platform_driver bcm2835_thermal_driver = {
97 .probe = bcm2835_thermal_probe,
98 .remove = bcm2835_thermal_remove,
99 .driver = {
100 .name = "bcm2835_thermal",
101 .of_match_table = bcm2835_thermal_of_match_table,
102 },
103 };
104 module_platform_driver(bcm2835_thermal_driver);
105
106 MODULE_AUTHOR("Dorian Peake");
107 MODULE_AUTHOR("Noralf Trønnes");
108 MODULE_DESCRIPTION("Thermal driver for bcm2835 chip");
109 MODULE_LICENSE("GPL");