diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-31 17:32:35 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-31 17:32:35 -0800 |
commit | d36377c6eb071e3d0751e9e0e3c19198c58d9a5d (patch) | |
tree | bf1d28abd5fac5c826079c4b760ca34263f0fab4 /drivers/firmware/raspberrypi.c | |
parent | 0922275ef157ba8ac93e7e7857087eb0442d5397 (diff) | |
parent | a6f119a06960ef1dc30570401e43b71f9ebdd2c2 (diff) | |
download | linux-d36377c6eb071e3d0751e9e0e3c19198c58d9a5d.tar.bz2 |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson:
"Misc driver updates for platforms, many of them power related.
- Rockchip adds power domain support for rk3066 and rk3188
- Amlogic adds a power measurement driver
- Allwinner adds SRAM support for three platforms (F1C100, H5, A64
C1)
- Wakeup and ti-sysc (platform bus) fixes for OMAP/DRA7
- Broadcom fixes suspend/resume with Thumb2 kernels, and improves
stability of a handful of firmware/platform interfaces
- PXA completes their conversion to dmaengine framework
- Renesas does a bunch of PM cleanups across many platforms
- Tegra adds support for suspend/resume on T186/T194, which includes
some driver cleanups and addition of wake events
- Tegra also adds a driver for memory controller (EMC) on Tegra2
- i.MX tweaks power domain bindings, and adds support for i.MX8MQ in
GPC
- Atmel adds identifiers and LPDDR2 support for a new SoC, SAM9X60
and misc cleanups across several platforms"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (73 commits)
ARM: at91: add support in soc driver for new SAM9X60
ARM: at91: add support in soc driver for LPDDR2 SiP
memory: omap-gpmc: Use of_node_name_eq for node name comparisons
bus: ti-sysc: Check for no-reset and no-idle flags at the child level
ARM: OMAP2+: Check also the first dts child for hwmod flags
soc: amlogic: meson-clk-measure: Add missing REGMAP_MMIO dependency
soc: imx: gpc: Increase GPC_CLK_MAX to 7
soc: renesas: rcar-sysc: Fix power domain control after system resume
soc: renesas: rcar-sysc: Merge PM Domain registration and linking
soc: renesas: rcar-sysc: Remove rcar_sysc_power_{down,up}() helpers
soc: renesas: r8a77990-sysc: Fix initialization order of 3DG-{A,B}
dt-bindings: sram: sunxi: Add compatible for the A64 SRAM C1
dt-bindings: sram: sunxi: Add bindings for the H5 with SRAM C1
dt-bindings: sram: Add Allwinner suniv F1C100s
soc: sunxi: sram: Add support for the H5 SoC system control
soc: sunxi: sram: Enable EMAC clock access for H3 variant
soc: imx: gpcv2: add support for i.MX8MQ SoC
soc: imx: gpcv2: move register access table to domain data
soc: imx: gpcv2: prefix i.MX7 specific defines
dmaengine: pxa: make the filter function internal
...
Diffstat (limited to 'drivers/firmware/raspberrypi.c')
-rw-r--r-- | drivers/firmware/raspberrypi.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index a200a2174611..a13558154ac3 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Defines interfaces for interacting wtih the Raspberry Pi firmware's * property channel. * * Copyright © 2015 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/dma-mapping.h> @@ -14,6 +11,7 @@ #include <linux/module.h> #include <linux/of_platform.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <soc/bcm2835/raspberrypi-firmware.h> #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) @@ -21,8 +19,6 @@ #define MBOX_DATA28(msg) ((msg) & ~0xf) #define MBOX_CHAN_PROPERTY 8 -#define MAX_RPI_FW_PROP_BUF_SIZE 32 - static struct platform_device *rpi_hwmon; struct rpi_firmware { @@ -56,8 +52,12 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data) reinit_completion(&fw->c); ret = mbox_send_message(fw->chan, &message); if (ret >= 0) { - wait_for_completion(&fw->c); - ret = 0; + if (wait_for_completion_timeout(&fw->c, HZ)) { + ret = 0; + } else { + ret = -ETIMEDOUT; + WARN_ONCE(1, "Firmware transaction timeout"); + } } else { dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret); } @@ -144,28 +144,30 @@ EXPORT_SYMBOL_GPL(rpi_firmware_property_list); int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *tag_data, size_t buf_size) { - /* Single tags are very small (generally 8 bytes), so the - * stack should be safe. - */ - u8 data[sizeof(struct rpi_firmware_property_tag_header) + - MAX_RPI_FW_PROP_BUF_SIZE]; - struct rpi_firmware_property_tag_header *header = - (struct rpi_firmware_property_tag_header *)data; + struct rpi_firmware_property_tag_header *header; int ret; - if (WARN_ON(buf_size > sizeof(data) - sizeof(*header))) - return -EINVAL; + /* Some mailboxes can use over 1k bytes. Rather than checking + * size and using stack or kmalloc depending on requirements, + * just use kmalloc. Mailboxes don't get called enough to worry + * too much about the time taken in the allocation. + */ + void *data = kmalloc(sizeof(*header) + buf_size, GFP_KERNEL); + if (!data) + return -ENOMEM; + + header = data; header->tag = tag; header->buf_size = buf_size; header->req_resp_size = 0; - memcpy(data + sizeof(struct rpi_firmware_property_tag_header), - tag_data, buf_size); + memcpy(data + sizeof(*header), tag_data, buf_size); + + ret = rpi_firmware_property_list(fw, data, buf_size + sizeof(*header)); + + memcpy(tag_data, data + sizeof(*header), buf_size); - ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header)); - memcpy(tag_data, - data + sizeof(struct rpi_firmware_property_tag_header), - buf_size); + kfree(data); return ret; } |