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.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index bf45ac450954..d3f7d1434657 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/of_platform.h> 15#include <linux/of_platform.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/slab.h>
17#include <soc/bcm2835/raspberrypi-firmware.h> 18#include <soc/bcm2835/raspberrypi-firmware.h>
18 19
19#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) 20#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
@@ -21,8 +22,6 @@
21#define MBOX_DATA28(msg) ((msg) & ~0xf) 22#define MBOX_DATA28(msg) ((msg) & ~0xf)
22#define MBOX_CHAN_PROPERTY 8 23#define MBOX_CHAN_PROPERTY 8
23 24
24#define MAX_RPI_FW_PROP_BUF_SIZE 32
25
26static struct platform_device *rpi_hwmon; 25static struct platform_device *rpi_hwmon;
27 26
28struct rpi_firmware { 27struct rpi_firmware {
@@ -148,28 +147,30 @@ EXPORT_SYMBOL_GPL(rpi_firmware_property_list);
148int rpi_firmware_property(struct rpi_firmware *fw, 147int rpi_firmware_property(struct rpi_firmware *fw,
149 u32 tag, void *tag_data, size_t buf_size) 148 u32 tag, void *tag_data, size_t buf_size)
150{ 149{
151 /* Single tags are very small (generally 8 bytes), so the 150 struct rpi_firmware_property_tag_header *header;
152 * stack should be safe.
153 */
154 u8 data[sizeof(struct rpi_firmware_property_tag_header) +
155 MAX_RPI_FW_PROP_BUF_SIZE];
156 struct rpi_firmware_property_tag_header *header =
157 (struct rpi_firmware_property_tag_header *)data;
158 int ret; 151 int ret;
159 152
160 if (WARN_ON(buf_size > sizeof(data) - sizeof(*header))) 153 /* Some mailboxes can use over 1k bytes. Rather than checking
161 return -EINVAL; 154 * size and using stack or kmalloc depending on requirements,
155 * just use kmalloc. Mailboxes don't get called enough to worry
156 * too much about the time taken in the allocation.
157 */
158 void *data = kmalloc(sizeof(*header) + buf_size, GFP_KERNEL);
162 159
160 if (!data)
161 return -ENOMEM;
162
163 header = data;
163 header->tag = tag; 164 header->tag = tag;
164 header->buf_size = buf_size; 165 header->buf_size = buf_size;
165 header->req_resp_size = 0; 166 header->req_resp_size = 0;
166 memcpy(data + sizeof(struct rpi_firmware_property_tag_header), 167 memcpy(data + sizeof(*header), tag_data, buf_size);
167 tag_data, buf_size); 168
169 ret = rpi_firmware_property_list(fw, data, buf_size + sizeof(*header));
170
171 memcpy(tag_data, data + sizeof(*header), buf_size);
168 172
169 ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header)); 173 kfree(data);
170 memcpy(tag_data,
171 data + sizeof(struct rpi_firmware_property_tag_header),
172 buf_size);
173 174
174 return ret; 175 return ret;
175} 176}