Commit e5734beb authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'arm-soc/for-4.21/drivers' of https://github.com/Broadcom/stblinux into next/drivers

This pull request contains Broadcom ARM/ARM64/MIPS SoCs drivers changes
for 4.21, please pull the following changes:

- James fixes the firmware interface after a commit changed the use of
  VLA and broke large transfers

- Stefan adds a timeout check for Raspberry Pi firmware transactions and
  updates a bunch of SoC/firmware files to use SPDX tags

- Wolfram switches the GISB bus arbiter to use dev_get_drvdata()

- Yangtao provides a fix for a reference leak due to a call to
  of_find_node_by_path()

- Florian fixes the CPU re-entry point out of S3 suspend with kernels
  built in Thumb2 mode

* tag 'arm-soc/for-4.21/drivers' of https://github.com/Broadcom/stblinux

:
  soc: bcm: brcmstb: Don't leak device tree node reference
  firmware: raspberrypi: Switch to SPDX identifier
  firmware: raspberrypi: Fix firmware calls with large buffers
  soc: bcm: Switch raspberrypi-power to SPDX identifier
  firmware: raspberrypi: Define timeout for transactions
  bus: brcmstb_gisb: simplify getting .driver_data
  soc: bcm: brcmstb: Fix re-entry point with a THUMB2_KERNEL

Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 0277a623 1861a7f0
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -150,8 +150,7 @@ static ssize_t gisb_arb_get_timeout(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
	struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
	u32 timeout;

	mutex_lock(&gdev->lock);
@@ -165,8 +164,7 @@ static ssize_t gisb_arb_set_timeout(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
	struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
	int val, ret;

	ret = kstrtoint(buf, 10, &val);
@@ -418,8 +416,7 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int brcmstb_gisb_arb_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
	struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);

	gdev->saved_timeout = gisb_read(gdev, ARB_TIMER);

@@ -431,8 +428,7 @@ static int brcmstb_gisb_arb_suspend(struct device *dev)
 */
static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
	struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);

	gisb_write(gdev, gdev->saved_timeout, ARB_TIMER);

+25 −23
Original line number Diff line number Diff line
// 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);
		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;
}
+5 −1
Original line number Diff line number Diff line
@@ -31,13 +31,17 @@ static const struct of_device_id brcmstb_machine_match[] = {

bool soc_is_brcmstb(void)
{
	const struct of_device_id *match;
	struct device_node *root;

	root = of_find_node_by_path("/");
	if (!root)
		return false;

	return of_match_node(brcmstb_machine_match, root) != NULL;
	match = of_match_node(brcmstb_machine_match, root);
	of_node_put(root);

	return match != NULL;
}

u32 brcmstb_get_family_id(void)
+1 −1
Original line number Diff line number Diff line
@@ -404,7 +404,7 @@ noinline int brcmstb_pm_s3_finish(void)
{
	struct brcmstb_s3_params *params = ctrl.s3_params;
	dma_addr_t params_pa = ctrl.s3_params_pa;
	phys_addr_t reentry = virt_to_phys(&cpu_resume);
	phys_addr_t reentry = virt_to_phys(&cpu_resume_arm);
	enum bsp_initiate_command cmd;
	u32 flags;

+1 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
 *
 * 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.
 *
 * Authors:
 * Alexander Aring <aar@pengutronix.de>
Loading