summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/raspberrypi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/raspberrypi.c')
-rw-r--r--drivers/firmware/raspberrypi.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 6692888f04cf..a200a2174611 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -21,6 +21,10 @@
21#define MBOX_DATA28(msg) ((msg) & ~0xf) 21#define MBOX_DATA28(msg) ((msg) & ~0xf)
22#define MBOX_CHAN_PROPERTY 8 22#define MBOX_CHAN_PROPERTY 8
23 23
24#define MAX_RPI_FW_PROP_BUF_SIZE 32
25
26static struct platform_device *rpi_hwmon;
27
24struct rpi_firmware { 28struct rpi_firmware {
25 struct mbox_client cl; 29 struct mbox_client cl;
26 struct mbox_chan *chan; /* The property channel. */ 30 struct mbox_chan *chan; /* The property channel. */
@@ -143,18 +147,22 @@ int rpi_firmware_property(struct rpi_firmware *fw,
143 /* Single tags are very small (generally 8 bytes), so the 147 /* Single tags are very small (generally 8 bytes), so the
144 * stack should be safe. 148 * stack should be safe.
145 */ 149 */
146 u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)]; 150 u8 data[sizeof(struct rpi_firmware_property_tag_header) +
151 MAX_RPI_FW_PROP_BUF_SIZE];
147 struct rpi_firmware_property_tag_header *header = 152 struct rpi_firmware_property_tag_header *header =
148 (struct rpi_firmware_property_tag_header *)data; 153 (struct rpi_firmware_property_tag_header *)data;
149 int ret; 154 int ret;
150 155
156 if (WARN_ON(buf_size > sizeof(data) - sizeof(*header)))
157 return -EINVAL;
158
151 header->tag = tag; 159 header->tag = tag;
152 header->buf_size = buf_size; 160 header->buf_size = buf_size;
153 header->req_resp_size = 0; 161 header->req_resp_size = 0;
154 memcpy(data + sizeof(struct rpi_firmware_property_tag_header), 162 memcpy(data + sizeof(struct rpi_firmware_property_tag_header),
155 tag_data, buf_size); 163 tag_data, buf_size);
156 164
157 ret = rpi_firmware_property_list(fw, &data, sizeof(data)); 165 ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header));
158 memcpy(tag_data, 166 memcpy(tag_data,
159 data + sizeof(struct rpi_firmware_property_tag_header), 167 data + sizeof(struct rpi_firmware_property_tag_header),
160 buf_size); 168 buf_size);
@@ -183,6 +191,20 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
183 } 191 }
184} 192}
185 193
194static void
195rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
196{
197 u32 packet;
198 int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
199 &packet, sizeof(packet));
200
201 if (ret)
202 return;
203
204 rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon",
205 -1, NULL, 0);
206}
207
186static int rpi_firmware_probe(struct platform_device *pdev) 208static int rpi_firmware_probe(struct platform_device *pdev)
187{ 209{
188 struct device *dev = &pdev->dev; 210 struct device *dev = &pdev->dev;
@@ -209,6 +231,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
209 platform_set_drvdata(pdev, fw); 231 platform_set_drvdata(pdev, fw);
210 232
211 rpi_firmware_print_firmware_revision(fw); 233 rpi_firmware_print_firmware_revision(fw);
234 rpi_register_hwmon_driver(dev, fw);
212 235
213 return 0; 236 return 0;
214} 237}
@@ -217,6 +240,8 @@ static int rpi_firmware_remove(struct platform_device *pdev)
217{ 240{
218 struct rpi_firmware *fw = platform_get_drvdata(pdev); 241 struct rpi_firmware *fw = platform_get_drvdata(pdev);
219 242
243 platform_device_unregister(rpi_hwmon);
244 rpi_hwmon = NULL;
220 mbox_free_channel(fw->chan); 245 mbox_free_channel(fw->chan);
221 246
222 return 0; 247 return 0;