diff options
Diffstat (limited to 'drivers/firmware/raspberrypi.c')
| -rw-r--r-- | drivers/firmware/raspberrypi.c | 35 |
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 | |||
| 26 | static struct platform_device *rpi_hwmon; | 25 | static struct platform_device *rpi_hwmon; |
| 27 | 26 | ||
| 28 | struct rpi_firmware { | 27 | struct rpi_firmware { |
| @@ -148,28 +147,30 @@ EXPORT_SYMBOL_GPL(rpi_firmware_property_list); | |||
| 148 | int rpi_firmware_property(struct rpi_firmware *fw, | 147 | int 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 | } |
